summaryrefslogtreecommitdiffstats
path: root/sys/sys/mount.h
diff options
context:
space:
mode:
authorrmacklem <rmacklem@FreeBSD.org>2013-09-01 23:02:59 +0000
committerrmacklem <rmacklem@FreeBSD.org>2013-09-01 23:02:59 +0000
commit8d06f831a7fd6d823c0aff22030a780f8b8fd05e (patch)
treed7581118dafcc5b29d5d01d4bb41cb2114a97168 /sys/sys/mount.h
parent09ec5c277c487bd53321f3f207be7a596ea08f65 (diff)
downloadFreeBSD-src-8d06f831a7fd6d823c0aff22030a780f8b8fd05e.zip
FreeBSD-src-8d06f831a7fd6d823c0aff22030a780f8b8fd05e.tar.gz
Forced dismounts of NFS mounts can fail when thread(s) are stuck
waiting for an RPC reply from the server while holding the mount point busy (mnt_lockref incremented). This happens because dounmount() msleep()s waiting for mnt_lockref to become 0, before calling VFS_UNMOUNT(). This patch adds a new VFS operation called VFS_PURGE(), which the NFS client implements as purging RPCs in progress. Making this call before checking mnt_lockref fixes the problem, by ensuring that the VOP_xxx() calls will fail and unbusy the mount point. Reported by: sbruno Reviewed by: kib MFC after: 2 weeks
Diffstat (limited to 'sys/sys/mount.h')
-rw-r--r--sys/sys/mount.h10
1 files changed, 10 insertions, 0 deletions
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index 1a835b7..8f94451 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -609,6 +609,7 @@ typedef int vfs_sysctl_t(struct mount *mp, fsctlop_t op,
struct sysctl_req *req);
typedef void vfs_susp_clean_t(struct mount *mp);
typedef void vfs_notify_lowervp_t(struct mount *mp, struct vnode *lowervp);
+typedef void vfs_purge_t(struct mount *mp);
struct vfsops {
vfs_mount_t *vfs_mount;
@@ -628,6 +629,7 @@ struct vfsops {
vfs_susp_clean_t *vfs_susp_clean;
vfs_notify_lowervp_t *vfs_reclaim_lowervp;
vfs_notify_lowervp_t *vfs_unlink_lowervp;
+ vfs_purge_t *vfs_purge;
vfs_mount_t *vfs_spare[6]; /* spares for ABI compat */
};
@@ -757,6 +759,14 @@ vfs_statfs_t __vfs_statfs;
} \
} while (0)
+#define VFS_PURGE(MP) do { \
+ if (*(MP)->mnt_op->vfs_purge != NULL) { \
+ VFS_PROLOGUE(MP); \
+ (*(MP)->mnt_op->vfs_purge)(MP); \
+ VFS_EPILOGUE(MP); \
+ } \
+} while (0)
+
#define VFS_KNOTE_LOCKED(vp, hint) do \
{ \
if (((vp)->v_vflag & VV_NOKNOTE) == 0) \
OpenPOWER on IntegriCloud