Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F175184268
D8988.id23423.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D8988.id23423.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D8988: Add support to the NFSv4.1 client for use of a single OpenOwner for all Opens
Attached
Detach File
Event Timeline
Log In to Comment