nfs_clstate.c (222389) | nfs_clstate.c (222719) |
---|---|
1/*- 2 * Copyright (c) 2009 Rick Macklem, University of Guelph 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 12 unchanged lines hidden (view full) --- 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 */ 27 28#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2009 Rick Macklem, University of Guelph 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 12 unchanged lines hidden (view full) --- 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 */ 27 28#include <sys/cdefs.h> |
29__FBSDID("$FreeBSD: head/sys/fs/nfsclient/nfs_clstate.c 222389 2011-05-27 22:05:10Z rmacklem $"); | 29__FBSDID("$FreeBSD: head/sys/fs/nfsclient/nfs_clstate.c 222719 2011-06-05 18:17:37Z rmacklem $"); |
30 31/* 32 * These functions implement the client side state handling for NFSv4. 33 * NFSv4 state handling: 34 * - A lockowner is used to determine lock contention, so it 35 * corresponds directly to a Posix pid. (1 to 1 mapping) 36 * - The correct granularity of an OpenOwner is not nearly so 37 * obvious. An OpenOwner does the following: --- 183 unchanged lines hidden (view full) --- 221 return (ret); 222 } 223 224 /* 225 * Get the Open iff it already exists. 226 * If none found, add the new one or return error, depending upon 227 * "create". 228 */ | 30 31/* 32 * These functions implement the client side state handling for NFSv4. 33 * NFSv4 state handling: 34 * - A lockowner is used to determine lock contention, so it 35 * corresponds directly to a Posix pid. (1 to 1 mapping) 36 * - The correct granularity of an OpenOwner is not nearly so 37 * obvious. An OpenOwner does the following: --- 183 unchanged lines hidden (view full) --- 221 return (ret); 222 } 223 224 /* 225 * Get the Open iff it already exists. 226 * If none found, add the new one or return error, depending upon 227 * "create". 228 */ |
229 nfscl_filllockowner(p, own); | 229 nfscl_filllockowner(p->td_proc, own, F_POSIX); |
230 NFSLOCKCLSTATE(); 231 dp = NULL; 232 /* First check the delegation list */ 233 if (nfhp != NULL && usedeleg) { 234 LIST_FOREACH(dp, NFSCLDELEGHASH(clp, nfhp, fhlen), nfsdl_hash) { 235 if (dp->nfsdl_fhlen == fhlen && 236 !NFSBCMP(nfhp, dp->nfsdl_fh, fhlen)) { 237 if (!(amode & NFSV4OPEN_ACCESSWRITE) || --- 278 unchanged lines hidden (view full) --- 516 } 517 } 518 519 if (p != NULL) { 520 /* 521 * If p != NULL, we want to search the parentage tree 522 * for a matching OpenOwner and use that. 523 */ | 230 NFSLOCKCLSTATE(); 231 dp = NULL; 232 /* First check the delegation list */ 233 if (nfhp != NULL && usedeleg) { 234 LIST_FOREACH(dp, NFSCLDELEGHASH(clp, nfhp, fhlen), nfsdl_hash) { 235 if (dp->nfsdl_fhlen == fhlen && 236 !NFSBCMP(nfhp, dp->nfsdl_fh, fhlen)) { 237 if (!(amode & NFSV4OPEN_ACCESSWRITE) || --- 278 unchanged lines hidden (view full) --- 516 } 517 } 518 519 if (p != NULL) { 520 /* 521 * If p != NULL, we want to search the parentage tree 522 * for a matching OpenOwner and use that. 523 */ |
524 nfscl_filllockowner(p, own); | 524 nfscl_filllockowner(p->td_proc, own, F_POSIX); |
525 error = nfscl_getopen(&clp->nfsc_owner, nfhp, fhlen, NULL, p, 526 mode, NULL, &op); 527 if (error == 0) { 528 /* now look for a lockowner */ 529 LIST_FOREACH(lp, &op->nfso_lock, nfsl_list) { 530 if (!NFSBCMP(lp->nfsl_owner, own, 531 NFSV4CL_LOCKNAMELEN)) { 532 stateidp->seqid = --- 58 unchanged lines hidden (view full) --- 591 struct nfsclopen *op; 592 NFSPROC_T *nproc; 593 u_int8_t own[NFSV4CL_LOCKNAMELEN], *ownp; 594 595 nproc = p; 596 op = NULL; 597 while (op == NULL && (nproc != NULL || rown != NULL)) { 598 if (nproc != NULL) { | 525 error = nfscl_getopen(&clp->nfsc_owner, nfhp, fhlen, NULL, p, 526 mode, NULL, &op); 527 if (error == 0) { 528 /* now look for a lockowner */ 529 LIST_FOREACH(lp, &op->nfso_lock, nfsl_list) { 530 if (!NFSBCMP(lp->nfsl_owner, own, 531 NFSV4CL_LOCKNAMELEN)) { 532 stateidp->seqid = --- 58 unchanged lines hidden (view full) --- 591 struct nfsclopen *op; 592 NFSPROC_T *nproc; 593 u_int8_t own[NFSV4CL_LOCKNAMELEN], *ownp; 594 595 nproc = p; 596 op = NULL; 597 while (op == NULL && (nproc != NULL || rown != NULL)) { 598 if (nproc != NULL) { |
599 nfscl_filllockowner(nproc, own); | 599 nfscl_filllockowner(nproc->td_proc, own, F_POSIX); |
600 ownp = own; 601 } else { 602 ownp = rown; 603 } 604 /* Search the client list */ 605 LIST_FOREACH(owp, ohp, nfsow_list) { 606 if (!NFSBCMP(owp->nfsow_owner, ownp, 607 NFSV4CL_LOCKNAMELEN)) --- 268 unchanged lines hidden (view full) --- 876} 877 878/* 879 * Called when wanting to lock a byte region. 880 */ 881APPLESTATIC int 882nfscl_getbytelock(vnode_t vp, u_int64_t off, u_int64_t len, 883 short type, struct ucred *cred, NFSPROC_T *p, struct nfsclclient *rclp, | 600 ownp = own; 601 } else { 602 ownp = rown; 603 } 604 /* Search the client list */ 605 LIST_FOREACH(owp, ohp, nfsow_list) { 606 if (!NFSBCMP(owp->nfsow_owner, ownp, 607 NFSV4CL_LOCKNAMELEN)) --- 268 unchanged lines hidden (view full) --- 876} 877 878/* 879 * Called when wanting to lock a byte region. 880 */ 881APPLESTATIC int 882nfscl_getbytelock(vnode_t vp, u_int64_t off, u_int64_t len, 883 short type, struct ucred *cred, NFSPROC_T *p, struct nfsclclient *rclp, |
884 int recovery, u_int8_t *rownp, u_int8_t *ropenownp, | 884 int recovery, void *id, int flags, u_int8_t *rownp, u_int8_t *ropenownp, |
885 struct nfscllockowner **lpp, int *newonep, int *donelocallyp) 886{ 887 struct nfscllockowner *lp; 888 struct nfsclopen *op; 889 struct nfsclclient *clp; 890 struct nfscllockowner *nlp; 891 struct nfscllock *nlop, *otherlop; 892 struct nfscldeleg *dp = NULL, *ldp = NULL; --- 44 unchanged lines hidden (view full) --- 937 FREE((caddr_t)nlop, M_NFSCLLOCK); 938 return (error); 939 } 940 941 op = NULL; 942 if (recovery) { 943 ownp = rownp; 944 } else { | 885 struct nfscllockowner **lpp, int *newonep, int *donelocallyp) 886{ 887 struct nfscllockowner *lp; 888 struct nfsclopen *op; 889 struct nfsclclient *clp; 890 struct nfscllockowner *nlp; 891 struct nfscllock *nlop, *otherlop; 892 struct nfscldeleg *dp = NULL, *ldp = NULL; --- 44 unchanged lines hidden (view full) --- 937 FREE((caddr_t)nlop, M_NFSCLLOCK); 938 return (error); 939 } 940 941 op = NULL; 942 if (recovery) { 943 ownp = rownp; 944 } else { |
945 nfscl_filllockowner(p, own); | 945 nfscl_filllockowner(id, own, flags); |
946 ownp = own; 947 } 948 if (!recovery) { 949 NFSLOCKCLSTATE(); 950 /* 951 * First, search for a delegation. If one exists for this file, 952 * the lock can be done locally against it, so long as there 953 * isn't a local lock conflict. --- 120 unchanged lines hidden (view full) --- 1074} 1075 1076/* 1077 * Called to unlock a byte range, for LockU. 1078 */ 1079APPLESTATIC int 1080nfscl_relbytelock(vnode_t vp, u_int64_t off, u_int64_t len, 1081 __unused struct ucred *cred, NFSPROC_T *p, int callcnt, | 946 ownp = own; 947 } 948 if (!recovery) { 949 NFSLOCKCLSTATE(); 950 /* 951 * First, search for a delegation. If one exists for this file, 952 * the lock can be done locally against it, so long as there 953 * isn't a local lock conflict. --- 120 unchanged lines hidden (view full) --- 1074} 1075 1076/* 1077 * Called to unlock a byte range, for LockU. 1078 */ 1079APPLESTATIC int 1080nfscl_relbytelock(vnode_t vp, u_int64_t off, u_int64_t len, 1081 __unused struct ucred *cred, NFSPROC_T *p, int callcnt, |
1082 struct nfsclclient *clp, struct nfscllockowner **lpp, int *dorpcp) | 1082 struct nfsclclient *clp, void *id, int flags, 1083 struct nfscllockowner **lpp, int *dorpcp) |
1083{ 1084 struct nfscllockowner *lp; 1085 struct nfsclowner *owp; 1086 struct nfsclopen *op; 1087 struct nfscllock *nlop, *other_lop = NULL; 1088 struct nfscldeleg *dp; 1089 struct nfsnode *np; 1090 u_int8_t own[NFSV4CL_LOCKNAMELEN]; --- 20 unchanged lines hidden (view full) --- 1111 return (NFSERR_INVAL); 1112 } 1113 } 1114 if (callcnt == 0) { 1115 MALLOC(other_lop, struct nfscllock *, 1116 sizeof (struct nfscllock), M_NFSCLLOCK, M_WAITOK); 1117 *other_lop = *nlop; 1118 } | 1084{ 1085 struct nfscllockowner *lp; 1086 struct nfsclowner *owp; 1087 struct nfsclopen *op; 1088 struct nfscllock *nlop, *other_lop = NULL; 1089 struct nfscldeleg *dp; 1090 struct nfsnode *np; 1091 u_int8_t own[NFSV4CL_LOCKNAMELEN]; --- 20 unchanged lines hidden (view full) --- 1112 return (NFSERR_INVAL); 1113 } 1114 } 1115 if (callcnt == 0) { 1116 MALLOC(other_lop, struct nfscllock *, 1117 sizeof (struct nfscllock), M_NFSCLLOCK, M_WAITOK); 1118 *other_lop = *nlop; 1119 } |
1119 nfscl_filllockowner(p, own); | 1120 nfscl_filllockowner(id, own, flags); |
1120 dp = NULL; 1121 NFSLOCKCLSTATE(); 1122 if (callcnt == 0) 1123 dp = nfscl_finddeleg(clp, np->n_fhp->nfh_fh, 1124 np->n_fhp->nfh_len); 1125 1126 /* 1127 * First, unlock any local regions on a delegation. --- 55 unchanged lines hidden (view full) --- 1183 FREE((caddr_t)other_lop, M_NFSCLLOCK); 1184 return (0); 1185} 1186 1187/* 1188 * Release all lockowners marked in progess for this process and file. 1189 */ 1190APPLESTATIC void | 1121 dp = NULL; 1122 NFSLOCKCLSTATE(); 1123 if (callcnt == 0) 1124 dp = nfscl_finddeleg(clp, np->n_fhp->nfh_fh, 1125 np->n_fhp->nfh_len); 1126 1127 /* 1128 * First, unlock any local regions on a delegation. --- 55 unchanged lines hidden (view full) --- 1184 FREE((caddr_t)other_lop, M_NFSCLLOCK); 1185 return (0); 1186} 1187 1188/* 1189 * Release all lockowners marked in progess for this process and file. 1190 */ 1191APPLESTATIC void |
1191nfscl_releasealllocks(struct nfsclclient *clp, vnode_t vp, NFSPROC_T *p) | 1192nfscl_releasealllocks(struct nfsclclient *clp, vnode_t vp, NFSPROC_T *p, 1193 void *id, int flags) |
1192{ 1193 struct nfsclowner *owp; 1194 struct nfsclopen *op; 1195 struct nfscllockowner *lp; 1196 struct nfsnode *np; 1197 u_int8_t own[NFSV4CL_LOCKNAMELEN]; 1198 1199 np = VTONFS(vp); | 1194{ 1195 struct nfsclowner *owp; 1196 struct nfsclopen *op; 1197 struct nfscllockowner *lp; 1198 struct nfsnode *np; 1199 u_int8_t own[NFSV4CL_LOCKNAMELEN]; 1200 1201 np = VTONFS(vp); |
1200 nfscl_filllockowner(p, own); | 1202 nfscl_filllockowner(id, own, flags); |
1201 NFSLOCKCLSTATE(); 1202 LIST_FOREACH(owp, &clp->nfsc_owner, nfsow_list) { 1203 LIST_FOREACH(op, &owp->nfsow_open, nfso_list) { 1204 if (op->nfso_fhlen == np->n_fhp->nfh_len && 1205 !NFSBCMP(op->nfso_fh, np->n_fhp->nfh_fh, op->nfso_fhlen)) { 1206 LIST_FOREACH(lp, &op->nfso_lock, nfsl_list) { 1207 if (lp->nfsl_inprog == p && 1208 !NFSBCMP(lp->nfsl_owner, own, --- 12 unchanged lines hidden (view full) --- 1221/* 1222 * Called to find out if any bytes within the byte range specified are 1223 * write locked by the calling process. Used to determine if flushing 1224 * is required before a LockU. 1225 * If in doubt, return 1, so the flush will occur. 1226 */ 1227APPLESTATIC int 1228nfscl_checkwritelocked(vnode_t vp, struct flock *fl, | 1203 NFSLOCKCLSTATE(); 1204 LIST_FOREACH(owp, &clp->nfsc_owner, nfsow_list) { 1205 LIST_FOREACH(op, &owp->nfsow_open, nfso_list) { 1206 if (op->nfso_fhlen == np->n_fhp->nfh_len && 1207 !NFSBCMP(op->nfso_fh, np->n_fhp->nfh_fh, op->nfso_fhlen)) { 1208 LIST_FOREACH(lp, &op->nfso_lock, nfsl_list) { 1209 if (lp->nfsl_inprog == p && 1210 !NFSBCMP(lp->nfsl_owner, own, --- 12 unchanged lines hidden (view full) --- 1223/* 1224 * Called to find out if any bytes within the byte range specified are 1225 * write locked by the calling process. Used to determine if flushing 1226 * is required before a LockU. 1227 * If in doubt, return 1, so the flush will occur. 1228 */ 1229APPLESTATIC int 1230nfscl_checkwritelocked(vnode_t vp, struct flock *fl, |
1229 struct ucred *cred, NFSPROC_T *p) | 1231 struct ucred *cred, NFSPROC_T *p, void *id, int flags) |
1230{ 1231 struct nfsclowner *owp; 1232 struct nfscllockowner *lp; 1233 struct nfsclopen *op; 1234 struct nfsclclient *clp; 1235 struct nfscllock *lop; 1236 struct nfscldeleg *dp; 1237 struct nfsnode *np; --- 23 unchanged lines hidden (view full) --- 1261 return (1); 1262 } else { 1263 end = NFS64BITSSET; 1264 } 1265 1266 error = nfscl_getcl(vp, cred, p, &clp); 1267 if (error) 1268 return (1); | 1232{ 1233 struct nfsclowner *owp; 1234 struct nfscllockowner *lp; 1235 struct nfsclopen *op; 1236 struct nfsclclient *clp; 1237 struct nfscllock *lop; 1238 struct nfscldeleg *dp; 1239 struct nfsnode *np; --- 23 unchanged lines hidden (view full) --- 1263 return (1); 1264 } else { 1265 end = NFS64BITSSET; 1266 } 1267 1268 error = nfscl_getcl(vp, cred, p, &clp); 1269 if (error) 1270 return (1); |
1269 nfscl_filllockowner(p, own); | 1271 nfscl_filllockowner(id, own, flags); |
1270 NFSLOCKCLSTATE(); 1271 1272 /* 1273 * First check the delegation locks. 1274 */ 1275 dp = nfscl_finddeleg(clp, np->n_fhp->nfh_fh, np->n_fhp->nfh_len); 1276 if (dp != NULL) { 1277 LIST_FOREACH(lp, &dp->nfsdl_lock, nfsl_list) { --- 358 unchanged lines hidden (view full) --- 1636APPLESTATIC void 1637nfscl_cleanup(NFSPROC_T *p) 1638{ 1639 struct nfsclclient *clp; 1640 u_int8_t own[NFSV4CL_LOCKNAMELEN]; 1641 1642 if (!nfscl_inited) 1643 return; | 1272 NFSLOCKCLSTATE(); 1273 1274 /* 1275 * First check the delegation locks. 1276 */ 1277 dp = nfscl_finddeleg(clp, np->n_fhp->nfh_fh, np->n_fhp->nfh_len); 1278 if (dp != NULL) { 1279 LIST_FOREACH(lp, &dp->nfsdl_lock, nfsl_list) { --- 358 unchanged lines hidden (view full) --- 1638APPLESTATIC void 1639nfscl_cleanup(NFSPROC_T *p) 1640{ 1641 struct nfsclclient *clp; 1642 u_int8_t own[NFSV4CL_LOCKNAMELEN]; 1643 1644 if (!nfscl_inited) 1645 return; |
1644 nfscl_filllockowner(p, own); | 1646 nfscl_filllockowner(p->td_proc, own, F_POSIX); |
1645 1646 NFSLOCKCLSTATE(); 1647 /* 1648 * Loop through all the clientids, looking for the OpenOwners. 1649 */ 1650 LIST_FOREACH(clp, &nfsclhead, nfsc_list) 1651 nfscl_cleanup_common(clp, own); 1652 NFSUNLOCKCLSTATE(); --- 1664 unchanged lines hidden (view full) --- 3317 return (0); 3318} 3319 3320/* 3321 * Check for a local conflicting lock. 3322 */ 3323APPLESTATIC int 3324nfscl_lockt(vnode_t vp, struct nfsclclient *clp, u_int64_t off, | 1647 1648 NFSLOCKCLSTATE(); 1649 /* 1650 * Loop through all the clientids, looking for the OpenOwners. 1651 */ 1652 LIST_FOREACH(clp, &nfsclhead, nfsc_list) 1653 nfscl_cleanup_common(clp, own); 1654 NFSUNLOCKCLSTATE(); --- 1664 unchanged lines hidden (view full) --- 3319 return (0); 3320} 3321 3322/* 3323 * Check for a local conflicting lock. 3324 */ 3325APPLESTATIC int 3326nfscl_lockt(vnode_t vp, struct nfsclclient *clp, u_int64_t off, |
3325 u_int64_t len, struct flock *fl, NFSPROC_T *p) | 3327 u_int64_t len, struct flock *fl, NFSPROC_T *p, void *id, int flags) |
3326{ 3327 struct nfscllock *lop, nlck; 3328 struct nfscldeleg *dp; 3329 struct nfsnode *np; 3330 u_int8_t own[NFSV4CL_LOCKNAMELEN]; 3331 int error; 3332 3333 nlck.nfslo_type = fl->l_type; 3334 nlck.nfslo_first = off; 3335 if (len == NFS64BITSSET) { 3336 nlck.nfslo_end = NFS64BITSSET; 3337 } else { 3338 nlck.nfslo_end = off + len; 3339 if (nlck.nfslo_end <= nlck.nfslo_first) 3340 return (NFSERR_INVAL); 3341 } 3342 np = VTONFS(vp); | 3328{ 3329 struct nfscllock *lop, nlck; 3330 struct nfscldeleg *dp; 3331 struct nfsnode *np; 3332 u_int8_t own[NFSV4CL_LOCKNAMELEN]; 3333 int error; 3334 3335 nlck.nfslo_type = fl->l_type; 3336 nlck.nfslo_first = off; 3337 if (len == NFS64BITSSET) { 3338 nlck.nfslo_end = NFS64BITSSET; 3339 } else { 3340 nlck.nfslo_end = off + len; 3341 if (nlck.nfslo_end <= nlck.nfslo_first) 3342 return (NFSERR_INVAL); 3343 } 3344 np = VTONFS(vp); |
3343 nfscl_filllockowner(p, own); | 3345 nfscl_filllockowner(id, own, flags); |
3344 NFSLOCKCLSTATE(); 3345 dp = nfscl_finddeleg(clp, np->n_fhp->nfh_fh, np->n_fhp->nfh_len); 3346 error = nfscl_localconflict(clp, np->n_fhp->nfh_fh, np->n_fhp->nfh_len, 3347 &nlck, own, dp, &lop); 3348 if (error != 0) { 3349 fl->l_whence = SEEK_SET; 3350 fl->l_start = lop->nfslo_first; 3351 if (lop->nfslo_end == NFS64BITSSET) --- 258 unchanged lines hidden (view full) --- 3610 struct nfsfh *nfhp; 3611 u_int64_t off, len; 3612 u_int32_t clidrev = 0; 3613 int error, newone, donelocally; 3614 3615 off = lop->nfslo_first; 3616 len = lop->nfslo_end - lop->nfslo_first; 3617 error = nfscl_getbytelock(vp, off, len, lop->nfslo_type, cred, p, | 3346 NFSLOCKCLSTATE(); 3347 dp = nfscl_finddeleg(clp, np->n_fhp->nfh_fh, np->n_fhp->nfh_len); 3348 error = nfscl_localconflict(clp, np->n_fhp->nfh_fh, np->n_fhp->nfh_len, 3349 &nlck, own, dp, &lop); 3350 if (error != 0) { 3351 fl->l_whence = SEEK_SET; 3352 fl->l_start = lop->nfslo_first; 3353 if (lop->nfslo_end == NFS64BITSSET) --- 258 unchanged lines hidden (view full) --- 3612 struct nfsfh *nfhp; 3613 u_int64_t off, len; 3614 u_int32_t clidrev = 0; 3615 int error, newone, donelocally; 3616 3617 off = lop->nfslo_first; 3618 len = lop->nfslo_end - lop->nfslo_first; 3619 error = nfscl_getbytelock(vp, off, len, lop->nfslo_type, cred, p, |
3618 clp, 1, lp->nfsl_owner, lp->nfsl_openowner, &nlp, &newone, | 3620 clp, 1, NULL, 0, lp->nfsl_owner, lp->nfsl_openowner, &nlp, &newone, |
3619 &donelocally); 3620 if (error || donelocally) 3621 return (error); 3622 if (nmp->nm_clp != NULL) 3623 clidrev = nmp->nm_clp->nfsc_clientidrev; 3624 else 3625 clidrev = 0; 3626 nfhp = VTONFS(vp)->n_fhp; --- 637 unchanged lines hidden --- | 3621 &donelocally); 3622 if (error || donelocally) 3623 return (error); 3624 if (nmp->nm_clp != NULL) 3625 clidrev = nmp->nm_clp->nfsc_clientidrev; 3626 else 3627 clidrev = 0; 3628 nfhp = VTONFS(vp)->n_fhp; --- 637 unchanged lines hidden --- |