Page MenuHomeFreeBSD

D8988.id23423.diff
No OneTemporary

D8988.id23423.diff

Index: sbin/mount_nfs/mount_nfs.8
===================================================================
--- sbin/mount_nfs/mount_nfs.8
+++ sbin/mount_nfs/mount_nfs.8
@@ -28,7 +28,7 @@
.\" @(#)mount_nfs.8 8.3 (Berkeley) 3/29/95
.\" $FreeBSD: stable/11/sbin/mount_nfs/mount_nfs.8 281691 2015-04-18 16:08:06Z trasz $
.\"
-.Dd October 30, 2014
+.Dd December 29, 2016
.Dt MOUNT_NFS 8
.Os
.Sh NAME
@@ -201,6 +201,12 @@
This option is only meaningful when used with the
.Cm nfsv4
option.
+.It Cm oneopenown
+Make a minor version 1 of the NFS Version 4 protocol mount use a single OpenOwner
+for all Opens.
+This may be useful for a server with a very low limit on OpenOwners, such as
+AmazonEFS.
+It can only be used with an NFSv4.1 mount.
.It Cm pnfs
Enable support for parallel NFS (pNFS) for minor version 1 of the
NFS Version 4 protocol.
Index: sys/fs/nfs/nfs_commonsubs.c
===================================================================
--- sys/fs/nfs/nfs_commonsubs.c
+++ sys/fs/nfs/nfs_commonsubs.c
@@ -888,6 +888,14 @@
pc->pc_caseinsensitive = 0;
pc->pc_casepreserving = 1;
}
+ if (sfp != NULL) {
+ sfp->sf_ffiles = UINT64_MAX;
+ sfp->sf_tfiles = UINT64_MAX;
+ sfp->sf_afiles = UINT64_MAX;
+ sfp->sf_fbytes = UINT64_MAX;
+ sfp->sf_tbytes = UINT64_MAX;
+ sfp->sf_abytes = UINT64_MAX;
+ }
}
/*
Index: sys/fs/nfs/nfs_var.h
===================================================================
--- sys/fs/nfs/nfs_var.h
+++ sys/fs/nfs/nfs_var.h
@@ -502,8 +502,8 @@
int *, int *, int);
int nfscl_getstateid(vnode_t, u_int8_t *, int, u_int32_t, int, struct ucred *,
NFSPROC_T *, nfsv4stateid_t *, void **);
-void nfscl_ownerrelease(struct nfsclowner *, int, int, int);
-void nfscl_openrelease(struct nfsclopen *, int, int);
+void nfscl_ownerrelease(struct nfsmount *, struct nfsclowner *, int, int, int);
+void nfscl_openrelease(struct nfsmount *, struct nfsclopen *, int, int);
int nfscl_getcl(struct mount *, struct ucred *, NFSPROC_T *, int,
struct nfsclclient **);
struct nfsclclient *nfscl_findcl(struct nfsmount *);
Index: sys/fs/nfs/nfsport.h
===================================================================
--- sys/fs/nfs/nfsport.h
+++ sys/fs/nfs/nfsport.h
@@ -929,6 +929,8 @@
#define NFSHASNOLAYOUTCOMMIT(n) ((n)->nm_state & NFSSTA_NOLAYOUTCOMMIT)
#define NFSHASSESSPERSIST(n) ((n)->nm_state & NFSSTA_SESSPERSIST)
#define NFSHASPNFS(n) ((n)->nm_state & NFSSTA_PNFS)
+#define NFSHASONEOPENOWN(n) (((n)->nm_flag & NFSMNT_ONEOPENOWN) != 0 && \
+ (n)->nm_minorvers > 0)
/*
* Gets the stats field out of the mount structure.
Index: sys/fs/nfsclient/nfs_clport.c
===================================================================
--- sys/fs/nfsclient/nfs_clport.c
+++ sys/fs/nfsclient/nfs_clport.c
@@ -634,7 +634,7 @@
struct proc *p;
if (id == NULL) {
- printf("NULL id\n");
+ /* Return the single open_owner of all 0 bytes. */
bzero(cp, NFSV4CL_LOCKNAMELEN);
return;
}
@@ -1255,7 +1255,14 @@
} tl;
struct proc *p;
pid_t pid;
- int ret = 0;
+ int i, ret = 0;
+
+ /* For the single open_owner of all 0 bytes, just return 0. */
+ for (i = 0; i < NFSV4CL_LOCKNAMELEN; i++)
+ if (own[i] != 0)
+ break;
+ if (i == NFSV4CL_LOCKNAMELEN)
+ return (0);
tl.cval[0] = *own++;
tl.cval[1] = *own++;
Index: sys/fs/nfsclient/nfs_clrpcops.c
===================================================================
--- sys/fs/nfsclient/nfs_clrpcops.c
+++ sys/fs/nfsclient/nfs_clrpcops.c
@@ -347,7 +347,7 @@
*/
if (!error)
op->nfso_opencnt++;
- nfscl_openrelease(op, error, newone);
+ nfscl_openrelease(nmp, op, error, newone);
if (error == NFSERR_GRACE || error == NFSERR_STALECLIENTID ||
error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY ||
error == NFSERR_BADSESSION) {
@@ -1893,7 +1893,7 @@
if (dp != NULL)
(void) nfscl_deleg(nmp->nm_mountp, owp->nfsow_clp,
(*nfhpp)->nfh_fh, (*nfhpp)->nfh_len, cred, p, &dp);
- nfscl_ownerrelease(owp, error, newone, unlocked);
+ nfscl_ownerrelease(nmp, owp, error, newone, unlocked);
if (error == NFSERR_GRACE || error == NFSERR_STALECLIENTID ||
error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY ||
error == NFSERR_BADSESSION) {
@@ -2198,7 +2198,7 @@
error = ret;
}
}
- nfscl_openrelease(op, error, newone);
+ nfscl_openrelease(nmp, op, error, newone);
*unlockedp = 1;
}
if (nd->nd_repstat != 0 && error == 0)
Index: sys/fs/nfsclient/nfs_clstate.c
===================================================================
--- sys/fs/nfsclient/nfs_clstate.c
+++ sys/fs/nfsclient/nfs_clstate.c
@@ -247,7 +247,6 @@
* If none found, add the new one or return error, depending upon
* "create".
*/
- nfscl_filllockowner(p->td_proc, own, F_POSIX);
NFSLOCKCLSTATE();
dp = NULL;
/* First check the delegation list */
@@ -264,10 +263,17 @@
}
}
- if (dp != NULL)
+ if (dp != NULL) {
+ nfscl_filllockowner(p->td_proc, own, F_POSIX);
ohp = &dp->nfsdl_owner;
- else
+ } else {
+ /* For NFSv4.1 and this option, use a single open_owner. */
+ if (NFSHASONEOPENOWN(VFSTONFS(vnode_mount(vp))))
+ nfscl_filllockowner(NULL, own, F_POSIX);
+ else
+ nfscl_filllockowner(p->td_proc, own, F_POSIX);
ohp = &clp->nfsc_owner;
+ }
/* Now, search for an openowner */
LIST_FOREACH(owp, ohp, nfsow_list) {
if (!NFSBCMP(owp->nfsow_owner, own, NFSV4CL_LOCKNAMELEN))
@@ -300,9 +306,24 @@
/*
* Serialize modifications to the open owner for multiple threads
* within the same process using a read/write sleep lock.
+ * For NFSv4.1 and a single OpenOwner, allow concurrent open operations
+ * by acquiring a shared lock. The close operations still use an
+ * exclusive lock for this case.
*/
- if (lockit)
- nfscl_lockexcl(&owp->nfsow_rwlock, NFSCLSTATEMUTEXPTR);
+ if (lockit != 0) {
+ if (NFSHASONEOPENOWN(VFSTONFS(vnode_mount(vp)))) {
+ /*
+ * Get a shared lock on the OpenOwner, but first
+ * wait for any pending exclusive lock, so that the
+ * exclusive locker gets priority.
+ */
+ nfsv4_lock(&owp->nfsow_rwlock, 0, NULL,
+ NFSCLSTATEMUTEXPTR, NULL);
+ nfsv4_getref(&owp->nfsow_rwlock, NULL,
+ NFSCLSTATEMUTEXPTR, NULL);
+ } else
+ nfscl_lockexcl(&owp->nfsow_rwlock, NFSCLSTATEMUTEXPTR);
+ }
NFSUNLOCKCLSTATE();
if (nowp != NULL)
FREE((caddr_t)nowp, M_NFSCLOWNER);
@@ -545,7 +566,10 @@
* If p != NULL, we want to search the parentage tree
* for a matching OpenOwner and use that.
*/
- nfscl_filllockowner(p->td_proc, own, F_POSIX);
+ if (NFSHASONEOPENOWN(VFSTONFS(vnode_mount(vp))))
+ nfscl_filllockowner(NULL, own, F_POSIX);
+ else
+ nfscl_filllockowner(p->td_proc, own, F_POSIX);
lp = NULL;
error = nfscl_getopen(&clp->nfsc_owner, nfhp, fhlen, own, own,
mode, &lp, &op);
@@ -679,15 +703,19 @@
* with the open owner.
*/
APPLESTATIC void
-nfscl_ownerrelease(struct nfsclowner *owp, __unused int error,
- __unused int candelete, int unlocked)
+nfscl_ownerrelease(struct nfsmount *nmp, struct nfsclowner *owp,
+ __unused int error, __unused int candelete, int unlocked)
{
if (owp == NULL)
return;
NFSLOCKCLSTATE();
- if (!unlocked)
- nfscl_lockunlock(&owp->nfsow_rwlock);
+ if (unlocked == 0) {
+ if (NFSHASONEOPENOWN(nmp))
+ nfsv4_relref(&owp->nfsow_rwlock);
+ else
+ nfscl_lockunlock(&owp->nfsow_rwlock);
+ }
nfscl_clrelease(owp->nfsow_clp);
NFSUNLOCKCLSTATE();
}
@@ -696,7 +724,8 @@
* Release use of an open structure under an open owner.
*/
APPLESTATIC void
-nfscl_openrelease(struct nfsclopen *op, int error, int candelete)
+nfscl_openrelease(struct nfsmount *nmp, struct nfsclopen *op, int error,
+ int candelete)
{
struct nfsclclient *clp;
struct nfsclowner *owp;
@@ -705,7 +734,10 @@
return;
NFSLOCKCLSTATE();
owp = op->nfso_own;
- nfscl_lockunlock(&owp->nfsow_rwlock);
+ if (NFSHASONEOPENOWN(nmp))
+ nfsv4_relref(&owp->nfsow_rwlock);
+ else
+ nfscl_lockunlock(&owp->nfsow_rwlock);
clp = owp->nfsow_clp;
if (error && candelete && op->nfso_opencnt == 0)
nfscl_freeopen(op, 0);
@@ -797,8 +829,17 @@
(mp->mnt_kern_flag & MNTK_UNMOUNTF) == 0)
igotlock = nfsv4_lock(&clp->nfsc_lock, 1, NULL,
NFSCLSTATEMUTEXPTR, mp);
- if (!igotlock)
+ if (igotlock == 0) {
+ /*
+ * Call nfsv4_lock() with "iwantlock == 0" so that it will
+ * wait for a pending exclusive lock request. This gives the
+ * exclusive lock request priority over this shared lock
+ * request.
+ * An exclusive lock on nfsc_lock is used mainly for recoveries.
+ */
+ nfsv4_lock(&clp->nfsc_lock, 0, NULL, NFSCLSTATEMUTEXPTR, mp);
nfsv4_getref(&clp->nfsc_lock, NULL, NFSCLSTATEMUTEXPTR, mp);
+ }
if (igotlock == 0 && (mp->mnt_kern_flag & MNTK_UNMOUNTF) != 0) {
/*
* Both nfsv4_lock() and nfsv4_getref() know to check
@@ -987,7 +1028,10 @@
} else {
nfscl_filllockowner(id, own, flags);
ownp = own;
- nfscl_filllockowner(p->td_proc, openown, F_POSIX);
+ if (NFSHASONEOPENOWN(VFSTONFS(vnode_mount(vp))))
+ nfscl_filllockowner(NULL, openown, F_POSIX);
+ else
+ nfscl_filllockowner(p->td_proc, openown, F_POSIX);
openownp = openown;
}
if (!recovery) {
@@ -1715,6 +1759,7 @@
struct nfsclowner *owp, *nowp;
struct nfsclopen *op;
struct nfscllockowner *lp, *nlp;
+ struct nfscldeleg *dp;
NFSPROCLISTLOCK();
NFSLOCKCLSTATE();
@@ -1728,6 +1773,20 @@
if (nfscl_procdoesntexist(owp->nfsow_owner))
nfscl_cleanup_common(clp, owp->nfsow_owner);
}
+
+ /*
+ * For the single open_owner case, these lock owners need to be
+ * checked to see if they still exist separately.
+ * This is because nfscl_procdoesntexist() never returns true for
+ * the single open_owner so that the above doesn't ever call
+ * nfscl_cleanup_common().
+ */
+ TAILQ_FOREACH(dp, &clp->nfsc_deleg, nfsdl_list) {
+ LIST_FOREACH_SAFE(lp, &dp->nfsdl_lock, nfsl_list, nlp) {
+ if (nfscl_procdoesntexist(lp->nfsl_owner))
+ nfscl_cleanup_common(clp, lp->nfsl_owner);
+ }
+ }
NFSUNLOCKCLSTATE();
NFSPROCLISTUNLOCK();
}
Index: sys/fs/nfsclient/nfs_clvfsops.c
===================================================================
--- sys/fs/nfsclient/nfs_clvfsops.c
+++ sys/fs/nfsclient/nfs_clvfsops.c
@@ -600,6 +600,12 @@
nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
}
+ /* Clear ONEOPENOWN for NFSv2, 3 and 4.0. */
+ if (nmp->nm_minorvers == 0) {
+ argp->flags &= ~NFSMNT_ONEOPENOWN;
+ nmp->nm_flag &= ~NFSMNT_ONEOPENOWN;
+ }
+
/* Re-bind if rsrvd port requested and wasn't on one */
adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT)
&& (argp->flags & NFSMNT_RESVPORT);
@@ -736,7 +742,7 @@
"resvport", "readahead", "hostname", "timeo", "timeout", "addr", "fh",
"nfsv3", "sec", "principal", "nfsv4", "gssname", "allgssname", "dirpath",
"minorversion", "nametimeo", "negnametimeo", "nocto", "noncontigwr",
- "pnfs", "wcommitsize",
+ "pnfs", "wcommitsize", "oneopenown",
NULL };
/*
@@ -966,6 +972,8 @@
args.flags |= NFSMNT_NONCONTIGWR;
if (vfs_getopt(mp->mnt_optnew, "pnfs", NULL, NULL) == 0)
args.flags |= NFSMNT_PNFS;
+ if (vfs_getopt(mp->mnt_optnew, "oneopenown", NULL, NULL) == 0)
+ args.flags |= NFSMNT_ONEOPENOWN;
if (vfs_getopt(mp->mnt_optnew, "readdirsize", (void **)&opt, NULL) == 0) {
if (opt == NULL) {
vfs_mount_error(mp, "illegal readdirsize");
@@ -1176,8 +1184,8 @@
/*
* When doing an update, we can't change version,
- * security, switch lockd strategies or change cookie
- * translation
+ * security, switch lockd strategies, change cookie
+ * translation or switch oneopenown.
*/
args.flags = (args.flags &
~(NFSMNT_NFSV3 |
@@ -1185,6 +1193,7 @@
NFSMNT_KERB |
NFSMNT_INTEGRITY |
NFSMNT_PRIVACY |
+ NFSMNT_ONEOPENOWN |
NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) |
(nmp->nm_flag &
(NFSMNT_NFSV3 |
@@ -1192,6 +1201,7 @@
NFSMNT_KERB |
NFSMNT_INTEGRITY |
NFSMNT_PRIVACY |
+ NFSMNT_ONEOPENOWN |
NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/));
nfs_decode_args(mp, nmp, &args, NULL, td->td_ucred, td);
goto out;
@@ -1944,6 +1954,8 @@
&blen);
nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_PNFS) != 0, ",pnfs",
&buf, &blen);
+ nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_ONEOPENOWN) != 0 &&
+ nmp->nm_minorvers > 0, ",oneopenown", &buf, &blen);
}
nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NFSV3) != 0, "nfsv3", &buf,
&blen);
Index: sys/nfsclient/nfsargs.h
===================================================================
--- sys/nfsclient/nfsargs.h
+++ sys/nfsclient/nfsargs.h
@@ -76,7 +76,7 @@
#define NFSMNT_MAXGRPS 0x00000020 /* set maximum grouplist size */
#define NFSMNT_INT 0x00000040 /* allow interrupts on hard mount */
#define NFSMNT_NOCONN 0x00000080 /* Don't Connect the socket */
-/* 0x100 free, was NFSMNT_NQNFS */
+#define NFSMNT_ONEOPENOWN 0x00000100 /* Use one OpenOwner for NFSv4.1 */
#define NFSMNT_NFSV3 0x00000200 /* Use NFS Version 3 protocol */
#define NFSMNT_KERB 0x00000400 /* Use RPCSEC_GSS/Krb5 */
#define NFSMNT_DUMBTIMR 0x00000800 /* Don't estimate rtt dynamically */

File Metadata

Mime Type
text/plain
Expires
Fri, Oct 9, 10:43 PM (5 h, 44 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40509362
Default Alt Text
D8988.id23423.diff (12 KB)

Event Timeline