Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F112065451
D8988.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D8988.diff
View Options
Index: head/sys/fs/nfs/nfs_var.h
===================================================================
--- head/sys/fs/nfs/nfs_var.h
+++ head/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: head/sys/fs/nfs/nfsport.h
===================================================================
--- head/sys/fs/nfs/nfsport.h
+++ head/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: head/sys/fs/nfsclient/nfs_clport.c
===================================================================
--- head/sys/fs/nfsclient/nfs_clport.c
+++ head/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: head/sys/fs/nfsclient/nfs_clrpcops.c
===================================================================
--- head/sys/fs/nfsclient/nfs_clrpcops.c
+++ head/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: head/sys/fs/nfsclient/nfs_clstate.c
===================================================================
--- head/sys/fs/nfsclient/nfs_clstate.c
+++ head/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);
@@ -997,7 +1029,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) {
@@ -1725,6 +1760,7 @@
struct nfsclowner *owp, *nowp;
struct nfsclopen *op;
struct nfscllockowner *lp, *nlp;
+ struct nfscldeleg *dp;
NFSPROCLISTLOCK();
NFSLOCKCLSTATE();
@@ -1738,6 +1774,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: head/sys/fs/nfsclient/nfs_clvfsops.c
===================================================================
--- head/sys/fs/nfsclient/nfs_clvfsops.c
+++ head/sys/fs/nfsclient/nfs_clvfsops.c
@@ -592,6 +592,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);
@@ -727,7 +733,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 };
/*
@@ -962,6 +968,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");
@@ -1172,8 +1180,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 |
@@ -1181,6 +1189,7 @@
NFSMNT_KERB |
NFSMNT_INTEGRITY |
NFSMNT_PRIVACY |
+ NFSMNT_ONEOPENOWN |
NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) |
(nmp->nm_flag &
(NFSMNT_NFSV3 |
@@ -1188,6 +1197,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;
@@ -1946,6 +1956,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: head/sys/nfsclient/nfsargs.h
===================================================================
--- head/sys/nfsclient/nfsargs.h
+++ head/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
Thu, Mar 13, 8:13 AM (18 h, 34 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17132272
Default Alt Text
D8988.diff (10 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