From owner-svn-src-stable-10@FreeBSD.ORG Sun Sep 21 12:07:23 2014 Return-Path: Delivered-To: svn-src-stable-10@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 2D918985; Sun, 21 Sep 2014 12:07:23 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 184C5183; Sun, 21 Sep 2014 12:07:23 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id s8LC7Mkl048964; Sun, 21 Sep 2014 12:07:22 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id s8LC7McE048963; Sun, 21 Sep 2014 12:07:22 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201409211207.s8LC7McE048963@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Sun, 21 Sep 2014 12:07:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r271928 - stable/10/sys/cam/ctl X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 21 Sep 2014 12:07:23 -0000 Author: mav Date: Sun Sep 21 12:07:22 2014 New Revision: 271928 URL: http://svnweb.freebsd.org/changeset/base/271928 Log: MFC r271794: When updating device media size use cached cdevsw pointer. Using pointer from the cdev directly is dangerous since we have no reference on it, and it may change any time. That caused panic if device has gone. While there, report capacity change only if it really changed. Approved by: re (dephij) Modified: stable/10/sys/cam/ctl/ctl_backend_block.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cam/ctl/ctl_backend_block.c ============================================================================== --- stable/10/sys/cam/ctl/ctl_backend_block.c Sun Sep 21 10:34:15 2014 (r271927) +++ stable/10/sys/cam/ctl/ctl_backend_block.c Sun Sep 21 12:07:22 2014 (r271928) @@ -2310,7 +2310,9 @@ ctl_be_block_modify_file(struct ctl_be_b if (params->lun_size_bytes != 0) { be_lun->size_bytes = params->lun_size_bytes; } else { + vn_lock(be_lun->vn, LK_SHARED | LK_RETRY); error = VOP_GETATTR(be_lun->vn, &vattr, curthread->td_ucred); + VOP_UNLOCK(be_lun->vn, 0); if (error != 0) { snprintf(req->error_str, sizeof(req->error_str), "error calling VOP_GETATTR() for file %s", @@ -2328,24 +2330,22 @@ static int ctl_be_block_modify_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req) { - struct cdev *dev; - struct cdevsw *devsw; + struct ctl_be_block_devdata *dev_data; int error; struct ctl_lun_modify_params *params; uint64_t size_bytes; params = &req->reqdata.modify; - dev = be_lun->vn->v_rdev; - devsw = dev->si_devsw; - if (!devsw->d_ioctl) { + dev_data = &be_lun->backend.dev; + if (!dev_data->csw->d_ioctl) { snprintf(req->error_str, sizeof(req->error_str), "%s: no d_ioctl for device %s!", __func__, be_lun->dev_path); return (ENODEV); } - error = devsw->d_ioctl(dev, DIOCGMEDIASIZE, + error = dev_data->csw->d_ioctl(dev_data->cdev, DIOCGMEDIASIZE, (caddr_t)&size_bytes, FREAD, curthread); if (error) { @@ -2378,6 +2378,7 @@ ctl_be_block_modify(struct ctl_be_block_ { struct ctl_lun_modify_params *params; struct ctl_be_block_lun *be_lun; + uint64_t oldsize; int error; params = &req->reqdata.modify; @@ -2408,28 +2409,27 @@ ctl_be_block_modify(struct ctl_be_block_ } } - vn_lock(be_lun->vn, LK_SHARED | LK_RETRY); - + oldsize = be_lun->size_bytes; if (be_lun->vn->v_type == VREG) error = ctl_be_block_modify_file(be_lun, req); else error = ctl_be_block_modify_dev(be_lun, req); - - VOP_UNLOCK(be_lun->vn, 0); - if (error != 0) goto bailout_error; - be_lun->size_blocks = be_lun->size_bytes >> be_lun->blocksize_shift; + if (be_lun->size_bytes != oldsize) { + be_lun->size_blocks = be_lun->size_bytes >> + be_lun->blocksize_shift; - /* - * The maximum LBA is the size - 1. - * - * XXX: Note that this field is being updated without locking, - * which might cause problems on 32-bit architectures. - */ - be_lun->ctl_be_lun.maxlba = be_lun->size_blocks - 1; - ctl_lun_capacity_changed(&be_lun->ctl_be_lun); + /* + * The maximum LBA is the size - 1. + * + * XXX: Note that this field is being updated without locking, + * which might cause problems on 32-bit architectures. + */ + be_lun->ctl_be_lun.maxlba = be_lun->size_blocks - 1; + ctl_lun_capacity_changed(&be_lun->ctl_be_lun); + } /* Tell the user the exact size we ended up using */ params->lun_size_bytes = be_lun->size_bytes;