aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4state.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r--fs/nfsd/nfs4state.c97
1 files changed, 49 insertions, 48 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 3550a9c87616..f6b2a09f793f 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -48,6 +48,7 @@
48#include "current_stateid.h" 48#include "current_stateid.h"
49 49
50#include "netns.h" 50#include "netns.h"
51#include "pnfs.h"
51 52
52#define NFSDDBG_FACILITY NFSDDBG_PROC 53#define NFSDDBG_FACILITY NFSDDBG_PROC
53 54
@@ -150,16 +151,6 @@ renew_client_locked(struct nfs4_client *clp)
150 clp->cl_time = get_seconds(); 151 clp->cl_time = get_seconds();
151} 152}
152 153
153static inline void
154renew_client(struct nfs4_client *clp)
155{
156 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
157
158 spin_lock(&nn->client_lock);
159 renew_client_locked(clp);
160 spin_unlock(&nn->client_lock);
161}
162
163static void put_client_renew_locked(struct nfs4_client *clp) 154static void put_client_renew_locked(struct nfs4_client *clp)
164{ 155{
165 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id); 156 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
@@ -282,7 +273,7 @@ static void nfsd4_free_file_rcu(struct rcu_head *rcu)
282 kmem_cache_free(file_slab, fp); 273 kmem_cache_free(file_slab, fp);
283} 274}
284 275
285static inline void 276void
286put_nfs4_file(struct nfs4_file *fi) 277put_nfs4_file(struct nfs4_file *fi)
287{ 278{
288 might_lock(&state_lock); 279 might_lock(&state_lock);
@@ -295,12 +286,6 @@ put_nfs4_file(struct nfs4_file *fi)
295 } 286 }
296} 287}
297 288
298static inline void
299get_nfs4_file(struct nfs4_file *fi)
300{
301 atomic_inc(&fi->fi_ref);
302}
303
304static struct file * 289static struct file *
305__nfs4_get_fd(struct nfs4_file *f, int oflag) 290__nfs4_get_fd(struct nfs4_file *f, int oflag)
306{ 291{
@@ -358,7 +343,7 @@ find_readable_file(struct nfs4_file *f)
358 return ret; 343 return ret;
359} 344}
360 345
361static struct file * 346struct file *
362find_any_file(struct nfs4_file *f) 347find_any_file(struct nfs4_file *f)
363{ 348{
364 struct file *ret; 349 struct file *ret;
@@ -408,14 +393,6 @@ static unsigned int file_hashval(struct knfsd_fh *fh)
408 return nfsd_fh_hashval(fh) & (FILE_HASH_SIZE - 1); 393 return nfsd_fh_hashval(fh) & (FILE_HASH_SIZE - 1);
409} 394}
410 395
411static bool nfsd_fh_match(struct knfsd_fh *fh1, struct knfsd_fh *fh2)
412{
413 return fh1->fh_size == fh2->fh_size &&
414 !memcmp(fh1->fh_base.fh_pad,
415 fh2->fh_base.fh_pad,
416 fh1->fh_size);
417}
418
419static struct hlist_head file_hashtbl[FILE_HASH_SIZE]; 396static struct hlist_head file_hashtbl[FILE_HASH_SIZE];
420 397
421static void 398static void
@@ -494,7 +471,7 @@ static void nfs4_file_put_access(struct nfs4_file *fp, u32 access)
494 __nfs4_file_put_access(fp, O_RDONLY); 471 __nfs4_file_put_access(fp, O_RDONLY);
495} 472}
496 473
497static struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, 474struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl,
498 struct kmem_cache *slab) 475 struct kmem_cache *slab)
499{ 476{
500 struct nfs4_stid *stid; 477 struct nfs4_stid *stid;
@@ -688,17 +665,17 @@ static void nfs4_put_deleg_lease(struct nfs4_file *fp)
688 struct file *filp = NULL; 665 struct file *filp = NULL;
689 666
690 spin_lock(&fp->fi_lock); 667 spin_lock(&fp->fi_lock);
691 if (fp->fi_deleg_file && atomic_dec_and_test(&fp->fi_delegees)) 668 if (fp->fi_deleg_file && --fp->fi_delegees == 0)
692 swap(filp, fp->fi_deleg_file); 669 swap(filp, fp->fi_deleg_file);
693 spin_unlock(&fp->fi_lock); 670 spin_unlock(&fp->fi_lock);
694 671
695 if (filp) { 672 if (filp) {
696 vfs_setlease(filp, F_UNLCK, NULL, NULL); 673 vfs_setlease(filp, F_UNLCK, NULL, (void **)&fp);
697 fput(filp); 674 fput(filp);
698 } 675 }
699} 676}
700 677
701static void unhash_stid(struct nfs4_stid *s) 678void nfs4_unhash_stid(struct nfs4_stid *s)
702{ 679{
703 s->sc_type = 0; 680 s->sc_type = 0;
704} 681}
@@ -1006,7 +983,7 @@ static void unhash_lock_stateid(struct nfs4_ol_stateid *stp)
1006 983
1007 list_del_init(&stp->st_locks); 984 list_del_init(&stp->st_locks);
1008 unhash_ol_stateid(stp); 985 unhash_ol_stateid(stp);
1009 unhash_stid(&stp->st_stid); 986 nfs4_unhash_stid(&stp->st_stid);
1010} 987}
1011 988
1012static void release_lock_stateid(struct nfs4_ol_stateid *stp) 989static void release_lock_stateid(struct nfs4_ol_stateid *stp)
@@ -1518,7 +1495,12 @@ unhash_session(struct nfsd4_session *ses)
1518static int 1495static int
1519STALE_CLIENTID(clientid_t *clid, struct nfsd_net *nn) 1496STALE_CLIENTID(clientid_t *clid, struct nfsd_net *nn)
1520{ 1497{
1521 if (clid->cl_boot == nn->boot_time) 1498 /*
1499 * We're assuming the clid was not given out from a boot
1500 * precisely 2^32 (about 136 years) before this one. That seems
1501 * a safe assumption:
1502 */
1503 if (clid->cl_boot == (u32)nn->boot_time)
1522 return 0; 1504 return 0;
1523 dprintk("NFSD stale clientid (%08x/%08x) boot_time %08lx\n", 1505 dprintk("NFSD stale clientid (%08x/%08x) boot_time %08lx\n",
1524 clid->cl_boot, clid->cl_id, nn->boot_time); 1506 clid->cl_boot, clid->cl_id, nn->boot_time);
@@ -1558,6 +1540,9 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name)
1558 INIT_LIST_HEAD(&clp->cl_lru); 1540 INIT_LIST_HEAD(&clp->cl_lru);
1559 INIT_LIST_HEAD(&clp->cl_callbacks); 1541 INIT_LIST_HEAD(&clp->cl_callbacks);
1560 INIT_LIST_HEAD(&clp->cl_revoked); 1542 INIT_LIST_HEAD(&clp->cl_revoked);
1543#ifdef CONFIG_NFSD_PNFS
1544 INIT_LIST_HEAD(&clp->cl_lo_states);
1545#endif
1561 spin_lock_init(&clp->cl_lock); 1546 spin_lock_init(&clp->cl_lock);
1562 rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table"); 1547 rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table");
1563 return clp; 1548 return clp;
@@ -1662,6 +1647,7 @@ __destroy_client(struct nfs4_client *clp)
1662 nfs4_get_stateowner(&oo->oo_owner); 1647 nfs4_get_stateowner(&oo->oo_owner);
1663 release_openowner(oo); 1648 release_openowner(oo);
1664 } 1649 }
1650 nfsd4_return_all_client_layouts(clp);
1665 nfsd4_shutdown_callback(clp); 1651 nfsd4_shutdown_callback(clp);
1666 if (clp->cl_cb_conn.cb_xprt) 1652 if (clp->cl_cb_conn.cb_xprt)
1667 svc_xprt_put(clp->cl_cb_conn.cb_xprt); 1653 svc_xprt_put(clp->cl_cb_conn.cb_xprt);
@@ -2145,8 +2131,11 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
2145static void 2131static void
2146nfsd4_set_ex_flags(struct nfs4_client *new, struct nfsd4_exchange_id *clid) 2132nfsd4_set_ex_flags(struct nfs4_client *new, struct nfsd4_exchange_id *clid)
2147{ 2133{
2148 /* pNFS is not supported */ 2134#ifdef CONFIG_NFSD_PNFS
2135 new->cl_exchange_flags |= EXCHGID4_FLAG_USE_PNFS_MDS;
2136#else
2149 new->cl_exchange_flags |= EXCHGID4_FLAG_USE_NON_PNFS; 2137 new->cl_exchange_flags |= EXCHGID4_FLAG_USE_NON_PNFS;
2138#endif
2150 2139
2151 /* Referrals are supported, Migration is not. */ 2140 /* Referrals are supported, Migration is not. */
2152 new->cl_exchange_flags |= EXCHGID4_FLAG_SUPP_MOVED_REFER; 2141 new->cl_exchange_flags |= EXCHGID4_FLAG_SUPP_MOVED_REFER;
@@ -3074,6 +3063,10 @@ static void nfsd4_init_file(struct knfsd_fh *fh, unsigned int hashval,
3074 fp->fi_share_deny = 0; 3063 fp->fi_share_deny = 0;
3075 memset(fp->fi_fds, 0, sizeof(fp->fi_fds)); 3064 memset(fp->fi_fds, 0, sizeof(fp->fi_fds));
3076 memset(fp->fi_access, 0, sizeof(fp->fi_access)); 3065 memset(fp->fi_access, 0, sizeof(fp->fi_access));
3066#ifdef CONFIG_NFSD_PNFS
3067 INIT_LIST_HEAD(&fp->fi_lo_states);
3068 atomic_set(&fp->fi_lo_recalls, 0);
3069#endif
3077 hlist_add_head_rcu(&fp->fi_hash, &file_hashtbl[hashval]); 3070 hlist_add_head_rcu(&fp->fi_hash, &file_hashtbl[hashval]);
3078} 3071}
3079 3072
@@ -3300,7 +3293,7 @@ find_file_locked(struct knfsd_fh *fh, unsigned int hashval)
3300 struct nfs4_file *fp; 3293 struct nfs4_file *fp;
3301 3294
3302 hlist_for_each_entry_rcu(fp, &file_hashtbl[hashval], fi_hash) { 3295 hlist_for_each_entry_rcu(fp, &file_hashtbl[hashval], fi_hash) {
3303 if (nfsd_fh_match(&fp->fi_fhandle, fh)) { 3296 if (fh_match(&fp->fi_fhandle, fh)) {
3304 if (atomic_inc_not_zero(&fp->fi_ref)) 3297 if (atomic_inc_not_zero(&fp->fi_ref))
3305 return fp; 3298 return fp;
3306 } 3299 }
@@ -3308,7 +3301,7 @@ find_file_locked(struct knfsd_fh *fh, unsigned int hashval)
3308 return NULL; 3301 return NULL;
3309} 3302}
3310 3303
3311static struct nfs4_file * 3304struct nfs4_file *
3312find_file(struct knfsd_fh *fh) 3305find_file(struct knfsd_fh *fh)
3313{ 3306{
3314 struct nfs4_file *fp; 3307 struct nfs4_file *fp;
@@ -3477,7 +3470,8 @@ nfsd_break_deleg_cb(struct file_lock *fl)
3477} 3470}
3478 3471
3479static int 3472static int
3480nfsd_change_deleg_cb(struct file_lock **onlist, int arg, struct list_head *dispose) 3473nfsd_change_deleg_cb(struct file_lock *onlist, int arg,
3474 struct list_head *dispose)
3481{ 3475{
3482 if (arg & F_UNLCK) 3476 if (arg & F_UNLCK)
3483 return lease_modify(onlist, arg, dispose); 3477 return lease_modify(onlist, arg, dispose);
@@ -3855,12 +3849,12 @@ static int nfs4_setlease(struct nfs4_delegation *dp)
3855 /* Race breaker */ 3849 /* Race breaker */
3856 if (fp->fi_deleg_file) { 3850 if (fp->fi_deleg_file) {
3857 status = 0; 3851 status = 0;
3858 atomic_inc(&fp->fi_delegees); 3852 ++fp->fi_delegees;
3859 hash_delegation_locked(dp, fp); 3853 hash_delegation_locked(dp, fp);
3860 goto out_unlock; 3854 goto out_unlock;
3861 } 3855 }
3862 fp->fi_deleg_file = filp; 3856 fp->fi_deleg_file = filp;
3863 atomic_set(&fp->fi_delegees, 1); 3857 fp->fi_delegees = 1;
3864 hash_delegation_locked(dp, fp); 3858 hash_delegation_locked(dp, fp);
3865 spin_unlock(&fp->fi_lock); 3859 spin_unlock(&fp->fi_lock);
3866 spin_unlock(&state_lock); 3860 spin_unlock(&state_lock);
@@ -3897,11 +3891,11 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh,
3897 status = nfs4_setlease(dp); 3891 status = nfs4_setlease(dp);
3898 goto out; 3892 goto out;
3899 } 3893 }
3900 atomic_inc(&fp->fi_delegees);
3901 if (fp->fi_had_conflict) { 3894 if (fp->fi_had_conflict) {
3902 status = -EAGAIN; 3895 status = -EAGAIN;
3903 goto out_unlock; 3896 goto out_unlock;
3904 } 3897 }
3898 ++fp->fi_delegees;
3905 hash_delegation_locked(dp, fp); 3899 hash_delegation_locked(dp, fp);
3906 status = 0; 3900 status = 0;
3907out_unlock: 3901out_unlock:
@@ -4294,7 +4288,7 @@ laundromat_main(struct work_struct *laundry)
4294 4288
4295static inline __be32 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_ol_stateid *stp) 4289static inline __be32 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_ol_stateid *stp)
4296{ 4290{
4297 if (!nfsd_fh_match(&fhp->fh_handle, &stp->st_stid.sc_file->fi_fhandle)) 4291 if (!fh_match(&fhp->fh_handle, &stp->st_stid.sc_file->fi_fhandle))
4298 return nfserr_bad_stateid; 4292 return nfserr_bad_stateid;
4299 return nfs_ok; 4293 return nfs_ok;
4300} 4294}
@@ -4445,7 +4439,7 @@ out_unlock:
4445 return status; 4439 return status;
4446} 4440}
4447 4441
4448static __be32 4442__be32
4449nfsd4_lookup_stateid(struct nfsd4_compound_state *cstate, 4443nfsd4_lookup_stateid(struct nfsd4_compound_state *cstate,
4450 stateid_t *stateid, unsigned char typemask, 4444 stateid_t *stateid, unsigned char typemask,
4451 struct nfs4_stid **s, struct nfsd_net *nn) 4445 struct nfs4_stid **s, struct nfsd_net *nn)
@@ -4859,6 +4853,9 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4859 update_stateid(&stp->st_stid.sc_stateid); 4853 update_stateid(&stp->st_stid.sc_stateid);
4860 memcpy(&close->cl_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); 4854 memcpy(&close->cl_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
4861 4855
4856 nfsd4_return_all_file_layouts(stp->st_stateowner->so_client,
4857 stp->st_stid.sc_file);
4858
4862 nfsd4_close_open_stateid(stp); 4859 nfsd4_close_open_stateid(stp);
4863 4860
4864 /* put reference from nfs4_preprocess_seqid_op */ 4861 /* put reference from nfs4_preprocess_seqid_op */
@@ -5556,10 +5553,11 @@ out_nfserr:
5556static bool 5553static bool
5557check_for_locks(struct nfs4_file *fp, struct nfs4_lockowner *lowner) 5554check_for_locks(struct nfs4_file *fp, struct nfs4_lockowner *lowner)
5558{ 5555{
5559 struct file_lock **flpp; 5556 struct file_lock *fl;
5560 int status = false; 5557 int status = false;
5561 struct file *filp = find_any_file(fp); 5558 struct file *filp = find_any_file(fp);
5562 struct inode *inode; 5559 struct inode *inode;
5560 struct file_lock_context *flctx;
5563 5561
5564 if (!filp) { 5562 if (!filp) {
5565 /* Any valid lock stateid should have some sort of access */ 5563 /* Any valid lock stateid should have some sort of access */
@@ -5568,15 +5566,18 @@ check_for_locks(struct nfs4_file *fp, struct nfs4_lockowner *lowner)
5568 } 5566 }
5569 5567
5570 inode = file_inode(filp); 5568 inode = file_inode(filp);
5569 flctx = inode->i_flctx;
5571 5570
5572 spin_lock(&inode->i_lock); 5571 if (flctx && !list_empty_careful(&flctx->flc_posix)) {
5573 for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) { 5572 spin_lock(&flctx->flc_lock);
5574 if ((*flpp)->fl_owner == (fl_owner_t)lowner) { 5573 list_for_each_entry(fl, &flctx->flc_posix, fl_list) {
5575 status = true; 5574 if (fl->fl_owner == (fl_owner_t)lowner) {
5576 break; 5575 status = true;
5576 break;
5577 }
5577 } 5578 }
5579 spin_unlock(&flctx->flc_lock);
5578 } 5580 }
5579 spin_unlock(&inode->i_lock);
5580 fput(filp); 5581 fput(filp);
5581 return status; 5582 return status;
5582} 5583}