diff options
-rw-r--r-- | fs/nfsd/nfs4callback.c | 8 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 48 | ||||
-rw-r--r-- | fs/nfsd/state.h | 2 |
3 files changed, 31 insertions, 27 deletions
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 93b5e405ad38..de018ecadae6 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c | |||
@@ -787,7 +787,7 @@ static void nfsd4_cb_prepare(struct rpc_task *task, void *calldata) | |||
787 | { | 787 | { |
788 | struct nfsd4_callback *cb = calldata; | 788 | struct nfsd4_callback *cb = calldata; |
789 | struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall); | 789 | struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall); |
790 | struct nfs4_client *clp = dp->dl_client; | 790 | struct nfs4_client *clp = dp->dl_stid.sc_client; |
791 | u32 minorversion = clp->cl_minorversion; | 791 | u32 minorversion = clp->cl_minorversion; |
792 | 792 | ||
793 | cb->cb_minorversion = minorversion; | 793 | cb->cb_minorversion = minorversion; |
@@ -809,7 +809,7 @@ static void nfsd4_cb_done(struct rpc_task *task, void *calldata) | |||
809 | { | 809 | { |
810 | struct nfsd4_callback *cb = calldata; | 810 | struct nfsd4_callback *cb = calldata; |
811 | struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall); | 811 | struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall); |
812 | struct nfs4_client *clp = dp->dl_client; | 812 | struct nfs4_client *clp = dp->dl_stid.sc_client; |
813 | 813 | ||
814 | dprintk("%s: minorversion=%d\n", __func__, | 814 | dprintk("%s: minorversion=%d\n", __func__, |
815 | clp->cl_minorversion); | 815 | clp->cl_minorversion); |
@@ -832,7 +832,7 @@ static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata) | |||
832 | { | 832 | { |
833 | struct nfsd4_callback *cb = calldata; | 833 | struct nfsd4_callback *cb = calldata; |
834 | struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall); | 834 | struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall); |
835 | struct nfs4_client *clp = dp->dl_client; | 835 | struct nfs4_client *clp = dp->dl_stid.sc_client; |
836 | struct rpc_clnt *current_rpc_client = clp->cl_cb_client; | 836 | struct rpc_clnt *current_rpc_client = clp->cl_cb_client; |
837 | 837 | ||
838 | nfsd4_cb_done(task, calldata); | 838 | nfsd4_cb_done(task, calldata); |
@@ -1006,7 +1006,7 @@ void nfsd4_do_callback_rpc(struct work_struct *w) | |||
1006 | void nfsd4_cb_recall(struct nfs4_delegation *dp) | 1006 | void nfsd4_cb_recall(struct nfs4_delegation *dp) |
1007 | { | 1007 | { |
1008 | struct nfsd4_callback *cb = &dp->dl_recall; | 1008 | struct nfsd4_callback *cb = &dp->dl_recall; |
1009 | struct nfs4_client *clp = dp->dl_client; | 1009 | struct nfs4_client *clp = dp->dl_stid.sc_client; |
1010 | 1010 | ||
1011 | dp->dl_retries = 1; | 1011 | dp->dl_retries = 1; |
1012 | cb->cb_op = dp; | 1012 | cb->cb_op = dp; |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index edcced18caa8..cb36c9a2e8ca 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -224,6 +224,19 @@ static inline void hash_stid(struct nfs4_stid *stid) | |||
224 | list_add(&stid->sc_hash, &stateid_hashtbl[hashval]); | 224 | list_add(&stid->sc_hash, &stateid_hashtbl[hashval]); |
225 | } | 225 | } |
226 | 226 | ||
227 | static void init_stid(struct nfs4_stid *stid, struct nfs4_client *cl, unsigned char type) | ||
228 | { | ||
229 | stateid_t *s = &stid->sc_stateid; | ||
230 | |||
231 | stid->sc_type = type; | ||
232 | stid->sc_client = cl; | ||
233 | s->si_opaque.so_clid = cl->cl_clientid; | ||
234 | s->si_opaque.so_id = current_stateid++; | ||
235 | /* Will be incremented before return to client: */ | ||
236 | s->si_generation = 0; | ||
237 | hash_stid(stid); | ||
238 | } | ||
239 | |||
227 | static struct nfs4_delegation * | 240 | static struct nfs4_delegation * |
228 | alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct svc_fh *current_fh, u32 type) | 241 | alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct svc_fh *current_fh, u32 type) |
229 | { | 242 | { |
@@ -245,19 +258,20 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct sv | |||
245 | dp = kmem_cache_alloc(deleg_slab, GFP_KERNEL); | 258 | dp = kmem_cache_alloc(deleg_slab, GFP_KERNEL); |
246 | if (dp == NULL) | 259 | if (dp == NULL) |
247 | return dp; | 260 | return dp; |
261 | init_stid(&dp->dl_stid, clp, NFS4_DELEG_STID); | ||
262 | /* | ||
263 | * delegation seqid's are never incremented. The 4.1 special | ||
264 | * meaning of seqid 0 isn't really meaningful, really, but let's | ||
265 | * avoid 0 anyway just for consistency and use 1: | ||
266 | */ | ||
267 | dp->dl_stid.sc_stateid.si_generation = 1; | ||
248 | num_delegations++; | 268 | num_delegations++; |
249 | INIT_LIST_HEAD(&dp->dl_perfile); | 269 | INIT_LIST_HEAD(&dp->dl_perfile); |
250 | INIT_LIST_HEAD(&dp->dl_perclnt); | 270 | INIT_LIST_HEAD(&dp->dl_perclnt); |
251 | INIT_LIST_HEAD(&dp->dl_recall_lru); | 271 | INIT_LIST_HEAD(&dp->dl_recall_lru); |
252 | dp->dl_client = clp; | ||
253 | get_nfs4_file(fp); | 272 | get_nfs4_file(fp); |
254 | dp->dl_file = fp; | 273 | dp->dl_file = fp; |
255 | dp->dl_type = type; | 274 | dp->dl_type = type; |
256 | dp->dl_stid.sc_type = NFS4_DELEG_STID; | ||
257 | dp->dl_stid.sc_stateid.si_opaque.so_clid = clp->cl_clientid; | ||
258 | dp->dl_stid.sc_stateid.si_opaque.so_id = current_stateid++; | ||
259 | dp->dl_stid.sc_stateid.si_generation = 1; | ||
260 | hash_stid(&dp->dl_stid); | ||
261 | fh_copy_shallow(&dp->dl_fh, ¤t_fh->fh_handle); | 275 | fh_copy_shallow(&dp->dl_fh, ¤t_fh->fh_handle); |
262 | dp->dl_time = 0; | 276 | dp->dl_time = 0; |
263 | atomic_set(&dp->dl_count, 1); | 277 | atomic_set(&dp->dl_count, 1); |
@@ -2333,18 +2347,13 @@ init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp, struct nfsd | |||
2333 | struct nfs4_openowner *oo = open->op_openowner; | 2347 | struct nfs4_openowner *oo = open->op_openowner; |
2334 | struct nfs4_client *clp = oo->oo_owner.so_client; | 2348 | struct nfs4_client *clp = oo->oo_owner.so_client; |
2335 | 2349 | ||
2350 | init_stid(&stp->st_stid, clp, NFS4_OPEN_STID); | ||
2336 | INIT_LIST_HEAD(&stp->st_lockowners); | 2351 | INIT_LIST_HEAD(&stp->st_lockowners); |
2337 | list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids); | 2352 | list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids); |
2338 | list_add(&stp->st_perfile, &fp->fi_stateids); | 2353 | list_add(&stp->st_perfile, &fp->fi_stateids); |
2339 | stp->st_stid.sc_type = NFS4_OPEN_STID; | ||
2340 | stp->st_stateowner = &oo->oo_owner; | 2354 | stp->st_stateowner = &oo->oo_owner; |
2341 | get_nfs4_file(fp); | 2355 | get_nfs4_file(fp); |
2342 | stp->st_file = fp; | 2356 | stp->st_file = fp; |
2343 | stp->st_stid.sc_stateid.si_opaque.so_clid = clp->cl_clientid; | ||
2344 | stp->st_stid.sc_stateid.si_opaque.so_id = current_stateid++; | ||
2345 | /* note will be incremented before first return to client: */ | ||
2346 | stp->st_stid.sc_stateid.si_generation = 0; | ||
2347 | hash_stid(&stp->st_stid); | ||
2348 | stp->st_access_bmap = 0; | 2357 | stp->st_access_bmap = 0; |
2349 | stp->st_deny_bmap = 0; | 2358 | stp->st_deny_bmap = 0; |
2350 | __set_bit(open->op_share_access & ~NFS4_SHARE_WANT_MASK, | 2359 | __set_bit(open->op_share_access & ~NFS4_SHARE_WANT_MASK, |
@@ -2792,7 +2801,7 @@ static int nfs4_setlease(struct nfs4_delegation *dp, int flag) | |||
2792 | if (!fl) | 2801 | if (!fl) |
2793 | return -ENOMEM; | 2802 | return -ENOMEM; |
2794 | fl->fl_file = find_readable_file(fp); | 2803 | fl->fl_file = find_readable_file(fp); |
2795 | list_add(&dp->dl_perclnt, &dp->dl_client->cl_delegations); | 2804 | list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations); |
2796 | status = vfs_setlease(fl->fl_file, fl->fl_type, &fl); | 2805 | status = vfs_setlease(fl->fl_file, fl->fl_type, &fl); |
2797 | if (status) { | 2806 | if (status) { |
2798 | list_del_init(&dp->dl_perclnt); | 2807 | list_del_init(&dp->dl_perclnt); |
@@ -2821,7 +2830,7 @@ static int nfs4_set_delegation(struct nfs4_delegation *dp, int flag) | |||
2821 | atomic_inc(&fp->fi_delegees); | 2830 | atomic_inc(&fp->fi_delegees); |
2822 | list_add(&dp->dl_perfile, &fp->fi_delegations); | 2831 | list_add(&dp->dl_perfile, &fp->fi_delegations); |
2823 | spin_unlock(&recall_lock); | 2832 | spin_unlock(&recall_lock); |
2824 | list_add(&dp->dl_perclnt, &dp->dl_client->cl_delegations); | 2833 | list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations); |
2825 | return 0; | 2834 | return 0; |
2826 | } | 2835 | } |
2827 | 2836 | ||
@@ -3295,7 +3304,7 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate, | |||
3295 | status = nfs4_check_delegmode(dp, flags); | 3304 | status = nfs4_check_delegmode(dp, flags); |
3296 | if (status) | 3305 | if (status) |
3297 | goto out; | 3306 | goto out; |
3298 | renew_client(dp->dl_client); | 3307 | renew_client(dp->dl_stid.sc_client); |
3299 | if (filpp) { | 3308 | if (filpp) { |
3300 | *filpp = dp->dl_file->fi_deleg_file; | 3309 | *filpp = dp->dl_file->fi_deleg_file; |
3301 | BUG_ON(!*filpp); | 3310 | BUG_ON(!*filpp); |
@@ -3665,7 +3674,7 @@ nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3665 | status = check_stateid_generation(stateid, &dp->dl_stid.sc_stateid, nfsd4_has_session(cstate)); | 3674 | status = check_stateid_generation(stateid, &dp->dl_stid.sc_stateid, nfsd4_has_session(cstate)); |
3666 | if (status) | 3675 | if (status) |
3667 | goto out; | 3676 | goto out; |
3668 | renew_client(dp->dl_client); | 3677 | renew_client(dp->dl_stid.sc_client); |
3669 | 3678 | ||
3670 | unhash_delegation(dp); | 3679 | unhash_delegation(dp); |
3671 | out: | 3680 | out: |
@@ -3819,17 +3828,12 @@ alloc_init_lock_stateid(struct nfs4_lockowner *lo, struct nfs4_file *fp, struct | |||
3819 | stp = nfs4_alloc_stateid(); | 3828 | stp = nfs4_alloc_stateid(); |
3820 | if (stp == NULL) | 3829 | if (stp == NULL) |
3821 | goto out; | 3830 | goto out; |
3831 | init_stid(&stp->st_stid, clp, NFS4_LOCK_STID); | ||
3822 | list_add(&stp->st_perfile, &fp->fi_stateids); | 3832 | list_add(&stp->st_perfile, &fp->fi_stateids); |
3823 | list_add(&stp->st_perstateowner, &lo->lo_owner.so_stateids); | 3833 | list_add(&stp->st_perstateowner, &lo->lo_owner.so_stateids); |
3824 | stp->st_stateowner = &lo->lo_owner; | 3834 | stp->st_stateowner = &lo->lo_owner; |
3825 | stp->st_stid.sc_type = NFS4_LOCK_STID; | ||
3826 | get_nfs4_file(fp); | 3835 | get_nfs4_file(fp); |
3827 | stp->st_file = fp; | 3836 | stp->st_file = fp; |
3828 | stp->st_stid.sc_stateid.si_opaque.so_clid = clp->cl_clientid; | ||
3829 | stp->st_stid.sc_stateid.si_opaque.so_id = current_stateid++; | ||
3830 | /* note will be incremented before first return to client: */ | ||
3831 | stp->st_stid.sc_stateid.si_generation = 0; | ||
3832 | hash_stid(&stp->st_stid); | ||
3833 | stp->st_access_bmap = 0; | 3837 | stp->st_access_bmap = 0; |
3834 | stp->st_deny_bmap = open_stp->st_deny_bmap; | 3838 | stp->st_deny_bmap = open_stp->st_deny_bmap; |
3835 | stp->st_openstp = open_stp; | 3839 | stp->st_openstp = open_stp; |
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index da68bf66a3d7..70062b75e24a 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h | |||
@@ -81,6 +81,7 @@ struct nfs4_stid { | |||
81 | unsigned char sc_type; | 81 | unsigned char sc_type; |
82 | struct list_head sc_hash; | 82 | struct list_head sc_hash; |
83 | stateid_t sc_stateid; | 83 | stateid_t sc_stateid; |
84 | struct nfs4_client *sc_client; | ||
84 | }; | 85 | }; |
85 | 86 | ||
86 | struct nfs4_delegation { | 87 | struct nfs4_delegation { |
@@ -88,7 +89,6 @@ struct nfs4_delegation { | |||
88 | struct list_head dl_perclnt; | 89 | struct list_head dl_perclnt; |
89 | struct list_head dl_recall_lru; /* delegation recalled */ | 90 | struct list_head dl_recall_lru; /* delegation recalled */ |
90 | atomic_t dl_count; /* ref count */ | 91 | atomic_t dl_count; /* ref count */ |
91 | struct nfs4_client *dl_client; | ||
92 | struct nfs4_file *dl_file; | 92 | struct nfs4_file *dl_file; |
93 | u32 dl_type; | 93 | u32 dl_type; |
94 | time_t dl_time; | 94 | time_t dl_time; |