summaryrefslogtreecommitdiff
path: root/sys/nfsclient
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2013-02-21 19:02:50 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2013-02-21 19:02:50 +0000
commit593efaf9f7ff8b4a961e61f55c333e63ee36495c (patch)
tree089655cb610bf1daca917a806eaed3dfb2554455 /sys/nfsclient
parentae40be8cf0ea07df25b46f95e47fb17a992edf4a (diff)
downloadsrc-test2-593efaf9f7ff8b4a961e61f55c333e63ee36495c.tar.gz
src-test2-593efaf9f7ff8b4a961e61f55c333e63ee36495c.zip
Further refine the handling of stop signals in the NFS client. The
changes in r246417 were incomplete as they did not add explicit calls to sigdeferstop() around all the places that previously passed SBDRY to _sleep(). In addition, nfs_getcacheblk() could trigger a write RPC from getblk() resulting in sigdeferstop() recursing. Rather than manually deferring stop signals in specific places, change the VFS_*() and VOP_*() methods to defer stop signals for filesystems which request this behavior via a new VFCF_SBDRY flag. Note that this has to be a VFC flag rather than a MNTK flag so that it works properly with VFS_MOUNT() when the mount is not yet fully constructed. For now, only the NFS clients are set this new flag in VFS_SET(). A few other related changes: - Add an assertion to ensure that TDF_SBDRY doesn't leak to userland. - When a lookup request uses VOP_READLINK() to follow a symlink, mark the request as being on behalf of the thread performing the lookup (cnp_thread) rather than using a NULL thread pointer. This causes NFS to properly handle signals during this VOP on an interruptible mount. PR: kern/176179 Reported by: Russell Cattelan (sigdeferstop() recursion) Reviewed by: kib MFC after: 1 month
Notes
Notes: svn path=/head/; revision=247116
Diffstat (limited to 'sys/nfsclient')
-rw-r--r--sys/nfsclient/nfs_krpc.c2
-rw-r--r--sys/nfsclient/nfs_vfsops.c2
2 files changed, 1 insertions, 3 deletions
diff --git a/sys/nfsclient/nfs_krpc.c b/sys/nfsclient/nfs_krpc.c
index 851b0b618389..d3082d8d914f 100644
--- a/sys/nfsclient/nfs_krpc.c
+++ b/sys/nfsclient/nfs_krpc.c
@@ -748,7 +748,6 @@ nfs_set_sigmask(struct thread *td, sigset_t *oldset)
SIGDELSET(newset, nfs_sig_set[i]);
}
mtx_unlock(&p->p_sigacts->ps_mtx);
- sigdeferstop(td);
kern_sigprocmask(td, SIG_SETMASK, &newset, oldset,
SIGPROCMASK_PROC_LOCKED);
PROC_UNLOCK(p);
@@ -760,7 +759,6 @@ nfs_restore_sigmask(struct thread *td, sigset_t *set)
if (td == NULL)
td = curthread; /* XXX */
kern_sigprocmask(td, SIG_SETMASK, set, NULL, 0);
- sigallowstop(td);
}
/*
diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c
index 63b5772f35ed..9cec3077fbcb 100644
--- a/sys/nfsclient/nfs_vfsops.c
+++ b/sys/nfsclient/nfs_vfsops.c
@@ -146,7 +146,7 @@ static struct vfsops nfs_vfsops = {
.vfs_unmount = nfs_unmount,
.vfs_sysctl = nfs_sysctl,
};
-VFS_SET(nfs_vfsops, oldnfs, VFCF_NETWORK);
+VFS_SET(nfs_vfsops, oldnfs, VFCF_NETWORK | VFCF_SBDRY);
/* So that loader and kldload(2) can find us, wherever we are.. */
MODULE_VERSION(oldnfs, 1);