aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2011-09-09 09:06:12 -0400
committerJ. Bruce Fields <bfields@redhat.com>2011-09-13 18:30:34 -0400
commitf459e4535904e16ca9f0cc202c78345c332bbbad (patch)
tree274b39ad09a1a4241a72f55e17fbd4631020f176
parent36d44c6038f6d3f8786187a5558c2f3b39a7af95 (diff)
nfsd4: hash deleg stateid's like any other
It's simpler to look up delegation stateid's in the same hash table as any other stateid. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r--fs/nfsd/nfs4state.c112
-rw-r--r--fs/nfsd/state.h5
2 files changed, 51 insertions, 66 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 581a5d01b005..24685a02690f 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -60,8 +60,6 @@ static u64 current_sessionid = 1;
60#define ONE_STATEID(stateid) (!memcmp((stateid), &onestateid, sizeof(stateid_t))) 60#define ONE_STATEID(stateid) (!memcmp((stateid), &onestateid, sizeof(stateid_t)))
61 61
62/* forward declarations */ 62/* forward declarations */
63static struct nfs4_delegation * search_for_delegation(stateid_t *stid);
64static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid);
65static int check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner); 63static int check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner);
66 64
67/* Locking: */ 65/* Locking: */
@@ -256,10 +254,12 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct sv
256 get_nfs4_file(fp); 254 get_nfs4_file(fp);
257 dp->dl_file = fp; 255 dp->dl_file = fp;
258 dp->dl_type = type; 256 dp->dl_type = type;
257 dp->dl_stid.sc_type = NFS4_DELEG_STID;
259 dp->dl_stid.sc_stateid.si_boot = boot_time; 258 dp->dl_stid.sc_stateid.si_boot = boot_time;
260 dp->dl_stid.sc_stateid.si_stateownerid = current_delegid++; 259 dp->dl_stid.sc_stateid.si_stateownerid = current_delegid++;
261 dp->dl_stid.sc_stateid.si_fileid = 0; 260 dp->dl_stid.sc_stateid.si_fileid = 0;
262 dp->dl_stid.sc_stateid.si_generation = 1; 261 dp->dl_stid.sc_stateid.si_generation = 1;
262 hash_stid(&dp->dl_stid);
263 fh_copy_shallow(&dp->dl_fh, &current_fh->fh_handle); 263 fh_copy_shallow(&dp->dl_fh, &current_fh->fh_handle);
264 dp->dl_time = 0; 264 dp->dl_time = 0;
265 atomic_set(&dp->dl_count, 1); 265 atomic_set(&dp->dl_count, 1);
@@ -292,6 +292,7 @@ static void nfs4_put_deleg_lease(struct nfs4_file *fp)
292static void 292static void
293unhash_delegation(struct nfs4_delegation *dp) 293unhash_delegation(struct nfs4_delegation *dp)
294{ 294{
295 list_del_init(&dp->dl_stid.sc_hash);
295 list_del_init(&dp->dl_perclnt); 296 list_del_init(&dp->dl_perclnt);
296 spin_lock(&recall_lock); 297 spin_lock(&recall_lock);
297 list_del_init(&dp->dl_perfile); 298 list_del_init(&dp->dl_perfile);
@@ -1077,7 +1078,7 @@ same_stateid(stateid_t *id_one, stateid_t *id_two)
1077 return id_one->si_fileid == id_two->si_fileid; 1078 return id_one->si_fileid == id_two->si_fileid;
1078} 1079}
1079 1080
1080static struct nfs4_ol_stateid *find_stateid(stateid_t *t) 1081static struct nfs4_stid *find_stateid(stateid_t *t)
1081{ 1082{
1082 struct nfs4_stid *s; 1083 struct nfs4_stid *s;
1083 unsigned int hashval; 1084 unsigned int hashval;
@@ -1085,22 +1086,42 @@ static struct nfs4_ol_stateid *find_stateid(stateid_t *t)
1085 hashval = stateid_hashval(t->si_stateownerid, t->si_fileid); 1086 hashval = stateid_hashval(t->si_stateownerid, t->si_fileid);
1086 list_for_each_entry(s, &stateid_hashtbl[hashval], sc_hash) 1087 list_for_each_entry(s, &stateid_hashtbl[hashval], sc_hash)
1087 if (same_stateid(&s->sc_stateid, t)) 1088 if (same_stateid(&s->sc_stateid, t))
1088 return openlockstateid(s); 1089 return s;
1089 return NULL; 1090 return NULL;
1090} 1091}
1091 1092
1092static struct nfs4_ol_stateid *find_stateid_by_type(stateid_t *t, char typemask) 1093static struct nfs4_ol_stateid *find_ol_stateid(stateid_t *t)
1093{ 1094{
1094 struct nfs4_ol_stateid *s; 1095 struct nfs4_stid *s;
1096
1097 s = find_stateid(t);
1098 if (!s)
1099 return NULL;
1100 return openlockstateid(s);
1101}
1102
1103static struct nfs4_stid *find_stateid_by_type(stateid_t *t, char typemask)
1104{
1105 struct nfs4_stid *s;
1095 1106
1096 s = find_stateid(t); 1107 s = find_stateid(t);
1097 if (!s) 1108 if (!s)
1098 return NULL; 1109 return NULL;
1099 if (typemask & s->st_stid.sc_type) 1110 if (typemask & s->sc_type)
1100 return s; 1111 return s;
1101 return NULL; 1112 return NULL;
1102} 1113}
1103 1114
1115static struct nfs4_ol_stateid *find_ol_stateid_by_type(stateid_t *t, char typemask)
1116{
1117 struct nfs4_stid *s;
1118
1119 s = find_stateid_by_type(t, typemask);
1120 if (!s)
1121 return NULL;
1122 return openlockstateid(s);
1123}
1124
1104static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir, 1125static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir,
1105 struct svc_rqst *rqstp, nfs4_verifier *verf) 1126 struct svc_rqst *rqstp, nfs4_verifier *verf)
1106{ 1127{
@@ -2573,26 +2594,21 @@ nfs4_check_delegmode(struct nfs4_delegation *dp, int flags)
2573 return nfs_ok; 2594 return nfs_ok;
2574} 2595}
2575 2596
2576static struct nfs4_delegation * 2597static int share_access_to_flags(u32 share_access)
2577find_delegation_file(struct nfs4_file *fp, stateid_t *stid)
2578{ 2598{
2579 struct nfs4_delegation *dp; 2599 share_access &= ~NFS4_SHARE_WANT_MASK;
2580 2600
2581 spin_lock(&recall_lock); 2601 return share_access == NFS4_SHARE_ACCESS_READ ? RD_STATE : WR_STATE;
2582 list_for_each_entry(dp, &fp->fi_delegations, dl_perfile)
2583 if (dp->dl_stid.sc_stateid.si_stateownerid == stid->si_stateownerid) {
2584 spin_unlock(&recall_lock);
2585 return dp;
2586 }
2587 spin_unlock(&recall_lock);
2588 return NULL;
2589} 2602}
2590 2603
2591static int share_access_to_flags(u32 share_access) 2604static struct nfs4_delegation *find_deleg_stateid(stateid_t *s)
2592{ 2605{
2593 share_access &= ~NFS4_SHARE_WANT_MASK; 2606 struct nfs4_stid *ret;
2594 2607
2595 return share_access == NFS4_SHARE_ACCESS_READ ? RD_STATE : WR_STATE; 2608 ret = find_stateid_by_type(s, NFS4_DELEG_STID);
2609 if (!ret)
2610 return NULL;
2611 return delegstateid(ret);
2596} 2612}
2597 2613
2598static __be32 2614static __be32
@@ -2602,7 +2618,7 @@ nfs4_check_deleg(struct nfs4_file *fp, struct nfsd4_open *open,
2602 int flags; 2618 int flags;
2603 __be32 status = nfserr_bad_stateid; 2619 __be32 status = nfserr_bad_stateid;
2604 2620
2605 *dp = find_delegation_file(fp, &open->op_delegate_stateid); 2621 *dp = find_deleg_stateid(&open->op_delegate_stateid);
2606 if (*dp == NULL) 2622 if (*dp == NULL)
2607 goto out; 2623 goto out;
2608 flags = share_access_to_flags(open->op_share_access); 2624 flags = share_access_to_flags(open->op_share_access);
@@ -3252,7 +3268,7 @@ __be32 nfs4_validate_stateid(stateid_t *stateid, bool has_session)
3252 goto out; 3268 goto out;
3253 3269
3254 status = nfserr_expired; 3270 status = nfserr_expired;
3255 stp = find_stateid(stateid); 3271 stp = find_ol_stateid(stateid);
3256 if (!stp) 3272 if (!stp)
3257 goto out; 3273 goto out;
3258 status = nfserr_bad_stateid; 3274 status = nfserr_bad_stateid;
@@ -3301,7 +3317,7 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
3301 */ 3317 */
3302 status = nfserr_expired; 3318 status = nfserr_expired;
3303 if (is_delegation_stateid(stateid)) { 3319 if (is_delegation_stateid(stateid)) {
3304 dp = find_delegation_stateid(ino, stateid); 3320 dp = find_deleg_stateid(stateid);
3305 if (!dp) 3321 if (!dp)
3306 goto out; 3322 goto out;
3307 status = check_stateid_generation(stateid, &dp->dl_stid.sc_stateid, nfsd4_has_session(cstate)); 3323 status = check_stateid_generation(stateid, &dp->dl_stid.sc_stateid, nfsd4_has_session(cstate));
@@ -3316,7 +3332,7 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
3316 BUG_ON(!*filpp); 3332 BUG_ON(!*filpp);
3317 } 3333 }
3318 } else { /* open or lock stateid */ 3334 } else { /* open or lock stateid */
3319 stp = find_stateid(stateid); 3335 stp = find_ol_stateid(stateid);
3320 if (!stp) 3336 if (!stp)
3321 goto out; 3337 goto out;
3322 status = nfserr_bad_stateid; 3338 status = nfserr_bad_stateid;
@@ -3348,9 +3364,10 @@ out:
3348static __be32 3364static __be32