nfs_clstate.c (206880) | nfs_clstate.c (207082) |
---|---|
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 206880 2010-04-20 01:02:39Z rmacklem $"); | 29__FBSDID("$FreeBSD: head/sys/fs/nfsclient/nfs_clstate.c 207082 2010-04-22 23:51:01Z 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: --- 96 unchanged lines hidden (view full) --- 134 int, struct nfscllockowner *, int, int, u_int64_t, u_int64_t, short, 135 struct ucred *, NFSPROC_T *); 136static int nfsrpc_reopen(struct nfsmount *, u_int8_t *, int, u_int32_t, 137 struct nfsclopen *, struct nfscldeleg **, struct ucred *, NFSPROC_T *); 138static void nfscl_freedeleg(struct nfscldeleghead *, struct nfscldeleg *); 139static int nfscl_errmap(struct nfsrv_descript *); 140static void nfscl_cleanup_common(struct nfsclclient *, u_int8_t *); 141static int nfscl_recalldeleg(struct nfsclclient *, struct nfsmount *, | 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: --- 96 unchanged lines hidden (view full) --- 134 int, struct nfscllockowner *, int, int, u_int64_t, u_int64_t, short, 135 struct ucred *, NFSPROC_T *); 136static int nfsrpc_reopen(struct nfsmount *, u_int8_t *, int, u_int32_t, 137 struct nfsclopen *, struct nfscldeleg **, struct ucred *, NFSPROC_T *); 138static void nfscl_freedeleg(struct nfscldeleghead *, struct nfscldeleg *); 139static int nfscl_errmap(struct nfsrv_descript *); 140static void nfscl_cleanup_common(struct nfsclclient *, u_int8_t *); 141static int nfscl_recalldeleg(struct nfsclclient *, struct nfsmount *, |
142 struct nfscldeleg *, vnode_t, struct ucred *, NFSPROC_T *); | 142 struct nfscldeleg *, vnode_t, struct ucred *, NFSPROC_T *, int); |
143static void nfscl_freeopenowner(struct nfsclowner *, int); 144static void nfscl_cleandeleg(struct nfscldeleg *); 145static int nfscl_trydelegreturn(struct nfscldeleg *, struct ucred *, 146 struct nfsmount *, NFSPROC_T *); 147 148static short nfscberr_null[] = { 149 0, 150 0, --- 2313 unchanged lines hidden (view full) --- 2464 igotlock = nfsv4_lock(&clp->nfsc_lock, 1, 2465 &islept, NFSCLSTATEMUTEXPTR); 2466 if (islept) 2467 goto tryagain; 2468 } 2469 NFSUNLOCKCLSTATE(); 2470 newnfs_copycred(&dp->nfsdl_cred, cred); 2471 ret = nfscl_recalldeleg(clp, clp->nfsc_nmp, dp, | 143static void nfscl_freeopenowner(struct nfsclowner *, int); 144static void nfscl_cleandeleg(struct nfscldeleg *); 145static int nfscl_trydelegreturn(struct nfscldeleg *, struct ucred *, 146 struct nfsmount *, NFSPROC_T *); 147 148static short nfscberr_null[] = { 149 0, 150 0, --- 2313 unchanged lines hidden (view full) --- 2464 igotlock = nfsv4_lock(&clp->nfsc_lock, 1, 2465 &islept, NFSCLSTATEMUTEXPTR); 2466 if (islept) 2467 goto tryagain; 2468 } 2469 NFSUNLOCKCLSTATE(); 2470 newnfs_copycred(&dp->nfsdl_cred, cred); 2471 ret = nfscl_recalldeleg(clp, clp->nfsc_nmp, dp, |
2472 NULL, cred, p); | 2472 NULL, cred, p, 1); |
2473 if (!ret) { 2474 nfscl_cleandeleg(dp); 2475 TAILQ_REMOVE(&clp->nfsc_deleg, dp, 2476 nfsdl_list); 2477 LIST_REMOVE(dp, nfsdl_hash); 2478 TAILQ_INSERT_HEAD(&dh, dp, nfsdl_list); 2479 nfscl_delegcnt--; 2480 newnfsstats.cldelegates--; --- 823 unchanged lines hidden (view full) --- 3304} 3305 3306/* 3307 * Handle Recall of a delegation. 3308 * The clp must be exclusive locked when this is called. 3309 */ 3310static int 3311nfscl_recalldeleg(struct nfsclclient *clp, struct nfsmount *nmp, | 2473 if (!ret) { 2474 nfscl_cleandeleg(dp); 2475 TAILQ_REMOVE(&clp->nfsc_deleg, dp, 2476 nfsdl_list); 2477 LIST_REMOVE(dp, nfsdl_hash); 2478 TAILQ_INSERT_HEAD(&dh, dp, nfsdl_list); 2479 nfscl_delegcnt--; 2480 newnfsstats.cldelegates--; --- 823 unchanged lines hidden (view full) --- 3304} 3305 3306/* 3307 * Handle Recall of a delegation. 3308 * The clp must be exclusive locked when this is called. 3309 */ 3310static int 3311nfscl_recalldeleg(struct nfsclclient *clp, struct nfsmount *nmp, |
3312 struct nfscldeleg *dp, vnode_t vp, struct ucred *cred, NFSPROC_T *p) | 3312 struct nfscldeleg *dp, vnode_t vp, struct ucred *cred, NFSPROC_T *p, 3313 int called_from_renewthread) |
3313{ 3314 struct nfsclowner *owp, *lowp, *nowp; 3315 struct nfsclopen *op, *lop; 3316 struct nfscllockowner *lp; 3317 struct nfscllock *lckp; 3318 struct nfsnode *np; 3319 int error = 0, ret, gotvp = 0; 3320 --- 17 unchanged lines hidden (view full) --- 3338 } 3339 dp->nfsdl_flags &= ~NFSCLDL_MODTIMESET; 3340 NFSINVALATTRCACHE(np); 3341 3342 /* 3343 * Ok, if it's a write delegation, flush data to the server, so 3344 * that close/open consistency is retained. 3345 */ | 3314{ 3315 struct nfsclowner *owp, *lowp, *nowp; 3316 struct nfsclopen *op, *lop; 3317 struct nfscllockowner *lp; 3318 struct nfscllock *lckp; 3319 struct nfsnode *np; 3320 int error = 0, ret, gotvp = 0; 3321 --- 17 unchanged lines hidden (view full) --- 3339 } 3340 dp->nfsdl_flags &= ~NFSCLDL_MODTIMESET; 3341 NFSINVALATTRCACHE(np); 3342 3343 /* 3344 * Ok, if it's a write delegation, flush data to the server, so 3345 * that close/open consistency is retained. 3346 */ |
3347 ret = 0; |
|
3346 NFSLOCKNODE(np); 3347 if ((dp->nfsdl_flags & NFSCLDL_WRITE) && (np->n_flag & NMODIFIED)) { 3348#ifdef APPLE 3349 OSBitOrAtomic((u_int32_t)NDELEGRECALL, (UInt32 *)&np->n_flag); 3350#else 3351 np->n_flag |= NDELEGRECALL; 3352#endif 3353 NFSUNLOCKNODE(np); | 3348 NFSLOCKNODE(np); 3349 if ((dp->nfsdl_flags & NFSCLDL_WRITE) && (np->n_flag & NMODIFIED)) { 3350#ifdef APPLE 3351 OSBitOrAtomic((u_int32_t)NDELEGRECALL, (UInt32 *)&np->n_flag); 3352#else 3353 np->n_flag |= NDELEGRECALL; 3354#endif 3355 NFSUNLOCKNODE(np); |
3354 (void) ncl_flush(vp, MNT_WAIT, cred, p, 1); | 3356 ret = ncl_flush(vp, MNT_WAIT, cred, p, 1, 3357 called_from_renewthread); |
3355 NFSLOCKNODE(np); 3356#ifdef APPLE 3357 OSBitAndAtomic((int32_t)~(NMODIFIED | NDELEGRECALL), (UInt32 *)&np->n_flag); 3358#else 3359 np->n_flag &= ~(NMODIFIED | NDELEGRECALL); 3360#endif 3361 } 3362 NFSUNLOCKNODE(np); | 3358 NFSLOCKNODE(np); 3359#ifdef APPLE 3360 OSBitAndAtomic((int32_t)~(NMODIFIED | NDELEGRECALL), (UInt32 *)&np->n_flag); 3361#else 3362 np->n_flag &= ~(NMODIFIED | NDELEGRECALL); 3363#endif 3364 } 3365 NFSUNLOCKNODE(np); |
3366 if (ret == EIO && called_from_renewthread != 0) { 3367 /* 3368 * If the flush failed with EIO for the renew thread, 3369 * return now, so that the dirty buffer will be flushed 3370 * later. 3371 */ 3372 if (gotvp != 0) 3373 vrele(vp); 3374 return (ret); 3375 } |
|
3363 3364 /* 3365 * Now, for each openowner with opens issued locally, move them 3366 * over to state against the server. 3367 */ 3368 LIST_FOREACH(lowp, &dp->nfsdl_owner, nfsow_list) { 3369 lop = LIST_FIRST(&lowp->nfsow_open); 3370 if (lop != NULL) { --- 481 unchanged lines hidden (view full) --- 3852 if (islept) 3853 break; 3854 } 3855 if (islept) 3856 continue; 3857 NFSUNLOCKCLSTATE(); 3858 cred = newnfs_getcred(); 3859 newnfs_copycred(&dp->nfsdl_cred, cred); | 3376 3377 /* 3378 * Now, for each openowner with opens issued locally, move them 3379 * over to state against the server. 3380 */ 3381 LIST_FOREACH(lowp, &dp->nfsdl_owner, nfsow_list) { 3382 lop = LIST_FIRST(&lowp->nfsow_open); 3383 if (lop != NULL) { --- 481 unchanged lines hidden (view full) --- 3865 if (islept) 3866 break; 3867 } 3868 if (islept) 3869 continue; 3870 NFSUNLOCKCLSTATE(); 3871 cred = newnfs_getcred(); 3872 newnfs_copycred(&dp->nfsdl_cred, cred); |
3860 (void) nfscl_recalldeleg(clp, nmp, dp, vp, cred, p); | 3873 (void) nfscl_recalldeleg(clp, nmp, dp, vp, cred, p, 0); |
3861 NFSFREECRED(cred); 3862 triedrecall = 1; 3863 NFSLOCKCLSTATE(); 3864 nfsv4_unlock(&clp->nfsc_lock, 0); 3865 igotlock = 0; 3866 continue; 3867 } 3868 *stp = dp->nfsdl_stateid; --- 81 unchanged lines hidden (view full) --- 3950 if (islept) 3951 break; 3952 } 3953 if (islept) 3954 continue; 3955 NFSUNLOCKCLSTATE(); 3956 cred = newnfs_getcred(); 3957 newnfs_copycred(&dp->nfsdl_cred, cred); | 3874 NFSFREECRED(cred); 3875 triedrecall = 1; 3876 NFSLOCKCLSTATE(); 3877 nfsv4_unlock(&clp->nfsc_lock, 0); 3878 igotlock = 0; 3879 continue; 3880 } 3881 *stp = dp->nfsdl_stateid; --- 81 unchanged lines hidden (view full) --- 3963 if (islept) 3964 break; 3965 } 3966 if (islept) 3967 continue; 3968 NFSUNLOCKCLSTATE(); 3969 cred = newnfs_getcred(); 3970 newnfs_copycred(&dp->nfsdl_cred, cred); |
3958 (void) nfscl_recalldeleg(clp, nmp, dp, fvp, cred, p); | 3971 (void) nfscl_recalldeleg(clp, nmp, dp, fvp, cred, p, 0); |
3959 NFSFREECRED(cred); 3960 triedrecall = 1; 3961 NFSLOCKCLSTATE(); 3962 nfsv4_unlock(&clp->nfsc_lock, 0); 3963 igotlock = 0; 3964 continue; 3965 } 3966 *fstp = dp->nfsdl_stateid; --- 218 unchanged lines hidden --- | 3972 NFSFREECRED(cred); 3973 triedrecall = 1; 3974 NFSLOCKCLSTATE(); 3975 nfsv4_unlock(&clp->nfsc_lock, 0); 3976 igotlock = 0; 3977 continue; 3978 } 3979 *fstp = dp->nfsdl_stateid; --- 218 unchanged lines hidden --- |