summaryrefslogtreecommitdiffstats
path: root/sys/cam/ctl/ctl_backend_block.c
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2015-10-05 08:09:34 +0000
committermav <mav@FreeBSD.org>2015-10-05 08:09:34 +0000
commit84502136f99100b423930b30c14fb8cb056f41f5 (patch)
tree7abca1eaafbe966bdcc1dcb4eac0dc23de1cac60 /sys/cam/ctl/ctl_backend_block.c
parent64e021919b03dda2b44cd09e886db97e5c6ac0f4 (diff)
downloadFreeBSD-src-84502136f99100b423930b30c14fb8cb056f41f5.zip
FreeBSD-src-84502136f99100b423930b30c14fb8cb056f41f5.tar.gz
MFC r285030: Fix couple panics on forced unmount of backing file.
Diffstat (limited to 'sys/cam/ctl/ctl_backend_block.c')
-rw-r--r--sys/cam/ctl/ctl_backend_block.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/sys/cam/ctl/ctl_backend_block.c b/sys/cam/ctl/ctl_backend_block.c
index 18e9dad..950c492 100644
--- a/sys/cam/ctl/ctl_backend_block.c
+++ b/sys/cam/ctl/ctl_backend_block.c
@@ -809,24 +809,27 @@ ctl_be_block_getattr_file(struct ctl_be_block_lun *be_lun, const char *attrname)
{
struct vattr vattr;
struct statfs statfs;
+ uint64_t val;
int error;
+ val = UINT64_MAX;
if (be_lun->vn == NULL)
- return (UINT64_MAX);
+ return (val);
+ vn_lock(be_lun->vn, LK_SHARED | LK_RETRY);
if (strcmp(attrname, "blocksused") == 0) {
error = VOP_GETATTR(be_lun->vn, &vattr, curthread->td_ucred);
- if (error != 0)
- return (UINT64_MAX);
- return (vattr.va_bytes >> be_lun->blocksize_shift);
+ if (error == 0)
+ val = vattr.va_bytes >> be_lun->blocksize_shift;
}
- if (strcmp(attrname, "blocksavail") == 0) {
+ if (strcmp(attrname, "blocksavail") == 0 &&
+ (be_lun->vn->v_iflag & VI_DOOMED) == 0) {
error = VFS_STATFS(be_lun->vn->v_mount, &statfs);
- if (error != 0)
- return (UINT64_MAX);
- return ((statfs.f_bavail * statfs.f_bsize) >>
- be_lun->blocksize_shift);
+ if (error == 0)
+ val = (statfs.f_bavail * statfs.f_bsize) >>
+ be_lun->blocksize_shift;
}
- return (UINT64_MAX);
+ VOP_UNLOCK(be_lun->vn, 0);
+ return (val);
}
static void
@@ -2657,10 +2660,12 @@ ctl_be_block_modify(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
oldsize = be_lun->size_bytes;
if (be_lun->vn == NULL)
error = ctl_be_block_open(softc, be_lun, req);
+ else if (vn_isdisk(be_lun->vn, &error))
+ error = ctl_be_block_modify_dev(be_lun, req);
else 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);
+ error = EINVAL;
if (error == 0 && be_lun->size_bytes != oldsize) {
be_lun->size_blocks = be_lun->size_bytes >>
OpenPOWER on IntegriCloud