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.c90
1 files changed, 47 insertions, 43 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index b83f8fb441e1..6bbefd06f10d 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -624,7 +624,7 @@ gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se)
624 cb->cb_ident = se->se_callback_ident; 624 cb->cb_ident = se->se_callback_ident;
625 return; 625 return;
626out_err: 626out_err:
627 printk(KERN_INFO "NFSD: this client (clientid %08x/%08x) " 627 dprintk(KERN_INFO "NFSD: this client (clientid %08x/%08x) "
628 "will not receive delegations\n", 628 "will not receive delegations\n",
629 clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id); 629 clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
630 630
@@ -678,13 +678,12 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid)
678 int status; 678 int status;
679 char dname[HEXDIR_LEN]; 679 char dname[HEXDIR_LEN];
680 680
681 status = nfserr_inval;
682 if (!check_name(clname)) 681 if (!check_name(clname))
683 goto out; 682 return nfserr_inval;
684 683
685 status = nfs4_make_rec_clidname(dname, &clname); 684 status = nfs4_make_rec_clidname(dname, &clname);
686 if (status) 685 if (status)
687 goto out; 686 return status;
688 687
689 /* 688 /*
690 * XXX The Duplicate Request Cache (DRC) has been checked (??) 689 * XXX The Duplicate Request Cache (DRC) has been checked (??)
@@ -2014,7 +2013,7 @@ STALE_STATEID(stateid_t *stateid)
2014{ 2013{
2015 if (stateid->si_boot == boot_time) 2014 if (stateid->si_boot == boot_time)
2016 return 0; 2015 return 0;
2017 printk("NFSD: stale stateid (%08x/%08x/%08x/%08x)!\n", 2016 dprintk("NFSD: stale stateid (%08x/%08x/%08x/%08x)!\n",
2018 stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid, 2017 stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid,
2019 stateid->si_generation); 2018 stateid->si_generation);
2020 return 1; 2019 return 1;
@@ -2275,7 +2274,7 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei
2275 2274
2276check_replay: 2275check_replay:
2277 if (seqid == sop->so_seqid - 1) { 2276 if (seqid == sop->so_seqid - 1) {
2278 printk("NFSD: preprocess_seqid_op: retransmission?\n"); 2277 dprintk("NFSD: preprocess_seqid_op: retransmission?\n");
2279 /* indicate replay to calling function */ 2278 /* indicate replay to calling function */
2280 return NFSERR_REPLAY_ME; 2279 return NFSERR_REPLAY_ME;
2281 } 2280 }
@@ -2286,7 +2285,7 @@ check_replay:
2286} 2285}
2287 2286
2288int 2287int
2289nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_confirm *oc) 2288nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_confirm *oc, struct nfs4_stateowner **replay_owner)
2290{ 2289{
2291 int status; 2290 int status;
2292 struct nfs4_stateowner *sop; 2291 struct nfs4_stateowner *sop;
@@ -2320,8 +2319,10 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfs
2320 2319
2321 nfsd4_create_clid_dir(sop->so_client); 2320 nfsd4_create_clid_dir(sop->so_client);
2322out: 2321out:
2323 if (oc->oc_stateowner) 2322 if (oc->oc_stateowner) {
2324 nfs4_get_stateowner(oc->oc_stateowner); 2323 nfs4_get_stateowner(oc->oc_stateowner);
2324 *replay_owner = oc->oc_stateowner;
2325 }
2325 nfs4_unlock_state(); 2326 nfs4_unlock_state();
2326 return status; 2327 return status;
2327} 2328}
@@ -2352,7 +2353,7 @@ reset_union_bmap_deny(unsigned long deny, unsigned long *bmap)
2352} 2353}
2353 2354
2354int 2355int
2355nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_downgrade *od) 2356nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_downgrade *od, struct nfs4_stateowner **replay_owner)
2356{ 2357{
2357 int status; 2358 int status;
2358 struct nfs4_stateid *stp; 2359 struct nfs4_stateid *stp;
@@ -2394,8 +2395,10 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct n
2394 memcpy(&od->od_stateid, &stp->st_stateid, sizeof(stateid_t)); 2395 memcpy(&od->od_stateid, &stp->st_stateid, sizeof(stateid_t));
2395 status = nfs_ok; 2396 status = nfs_ok;
2396out: 2397out:
2397 if (od->od_stateowner) 2398 if (od->od_stateowner) {
2398 nfs4_get_stateowner(od->od_stateowner); 2399 nfs4_get_stateowner(od->od_stateowner);
2400 *replay_owner = od->od_stateowner;
2401 }
2399 nfs4_unlock_state(); 2402 nfs4_unlock_state();
2400 return status; 2403 return status;
2401} 2404}
@@ -2404,7 +2407,7 @@ out:
2404 * nfs4_unlock_state() called after encode 2407 * nfs4_unlock_state() called after encode
2405 */ 2408 */
2406int 2409int
2407nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close) 2410nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close, struct nfs4_stateowner **replay_owner)
2408{ 2411{
2409 int status; 2412 int status;
2410 struct nfs4_stateid *stp; 2413 struct nfs4_stateid *stp;
@@ -2430,8 +2433,10 @@ nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_clos
2430 /* release_state_owner() calls nfsd_close() if needed */ 2433 /* release_state_owner() calls nfsd_close() if needed */
2431 release_state_owner(stp, OPEN_STATE); 2434 release_state_owner(stp, OPEN_STATE);
2432out: 2435out:
2433 if (close->cl_stateowner) 2436 if (close->cl_stateowner) {
2434 nfs4_get_stateowner(close->cl_stateowner); 2437 nfs4_get_stateowner(close->cl_stateowner);
2438 *replay_owner = close->cl_stateowner;
2439 }
2435 nfs4_unlock_state(); 2440 nfs4_unlock_state();
2436 return status; 2441 return status;
2437} 2442}
@@ -2500,8 +2505,7 @@ find_stateid(stateid_t *stid, int flags)
2500 (local->st_stateid.si_fileid == f_id)) 2505 (local->st_stateid.si_fileid == f_id))
2501 return local; 2506 return local;
2502 } 2507 }
2503 } else 2508 }
2504 printk("NFSD: find_stateid: ERROR: no state flag\n");
2505 return NULL; 2509 return NULL;
2506} 2510}
2507 2511
@@ -2624,7 +2628,9 @@ alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, str
2624 sop->so_is_open_owner = 0; 2628 sop->so_is_open_owner = 0;
2625 sop->so_id = current_ownerid++; 2629 sop->so_id = current_ownerid++;
2626 sop->so_client = clp; 2630 sop->so_client = clp;
2627 sop->so_seqid = lock->lk_new_lock_seqid; 2631 /* It is the openowner seqid that will be incremented in encode in the
2632 * case of new lockowners; so increment the lock seqid manually: */
2633 sop->so_seqid = lock->lk_new_lock_seqid + 1;
2628 sop->so_confirmed = 1; 2634 sop->so_confirmed = 1;
2629 rp = &sop->so_replay; 2635 rp = &sop->so_replay;
2630 rp->rp_status = NFSERR_SERVERFAULT; 2636 rp->rp_status = NFSERR_SERVERFAULT;
@@ -2676,9 +2682,10 @@ check_lock_length(u64 offset, u64 length)
2676 * LOCK operation 2682 * LOCK operation
2677 */ 2683 */
2678int 2684int
2679nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock) 2685nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock, struct nfs4_stateowner **replay_owner)
2680{ 2686{
2681 struct nfs4_stateowner *open_sop = NULL; 2687 struct nfs4_stateowner *open_sop = NULL;
2688 struct nfs4_stateowner *lock_sop = NULL;
2682 struct nfs4_stateid *lock_stp; 2689 struct nfs4_stateid *lock_stp;
2683 struct file *filp; 2690 struct file *filp;
2684 struct file_lock file_lock; 2691 struct file_lock file_lock;
@@ -2705,19 +2712,19 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2705 struct nfs4_file *fp; 2712 struct nfs4_file *fp;
2706 2713
2707 status = nfserr_stale_clientid; 2714 status = nfserr_stale_clientid;
2708 if (STALE_CLIENTID(&lock->lk_new_clientid)) { 2715 if (STALE_CLIENTID(&lock->lk_new_clientid))
2709 printk("NFSD: nfsd4_lock: clientid is stale!\n");
2710 goto out; 2716 goto out;
2711 }
2712 2717
2713 /* validate and update open stateid and open seqid */ 2718 /* validate and update open stateid and open seqid */
2714 status = nfs4_preprocess_seqid_op(current_fh, 2719 status = nfs4_preprocess_seqid_op(current_fh,
2715 lock->lk_new_open_seqid, 2720 lock->lk_new_open_seqid,
2716 &lock->lk_new_open_stateid, 2721 &lock->lk_new_open_stateid,
2717 CHECK_FH | OPEN_STATE, 2722 CHECK_FH | OPEN_STATE,
2718 &open_sop, &open_stp, lock); 2723 &lock->lk_stateowner, &open_stp,
2724 lock);
2719 if (status) 2725 if (status)
2720 goto out; 2726 goto out;
2727 open_sop = lock->lk_stateowner;
2721 /* create lockowner and lock stateid */ 2728 /* create lockowner and lock stateid */
2722 fp = open_stp->st_file; 2729 fp = open_stp->st_file;
2723 strhashval = lock_ownerstr_hashval(fp->fi_inode, 2730 strhashval = lock_ownerstr_hashval(fp->fi_inode,
@@ -2727,16 +2734,15 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2727 * the same file, or should they just be allowed (and 2734 * the same file, or should they just be allowed (and
2728 * create new stateids)? */ 2735 * create new stateids)? */
2729 status = nfserr_resource; 2736 status = nfserr_resource;
2730 if (!(lock->lk_stateowner = alloc_init_lock_stateowner(strhashval, open_sop->so_client, open_stp, lock))) 2737 lock_sop = alloc_init_lock_stateowner(strhashval,
2738 open_sop->so_client, open_stp, lock);
2739 if (lock_sop == NULL)
2731 goto out; 2740 goto out;
2732 if ((lock_stp = alloc_init_lock_stateid(lock->lk_stateowner, 2741 lock_stp = alloc_init_lock_stateid(lock_sop, fp, open_stp);
2733 fp, open_stp)) == NULL) { 2742 if (lock_stp == NULL) {
2734 release_stateowner(lock->lk_stateowner); 2743 release_stateowner(lock_sop);
2735 lock->lk_stateowner = NULL;
2736 goto out; 2744 goto out;
2737 } 2745 }
2738 /* bump the open seqid used to create the lock */
2739 open_sop->so_seqid++;
2740 } else { 2746 } else {
2741 /* lock (lock owner + lock stateid) already exists */ 2747 /* lock (lock owner + lock stateid) already exists */
2742 status = nfs4_preprocess_seqid_op(current_fh, 2748 status = nfs4_preprocess_seqid_op(current_fh,
@@ -2746,12 +2752,13 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2746 &lock->lk_stateowner, &lock_stp, lock); 2752 &lock->lk_stateowner, &lock_stp, lock);
2747 if (status) 2753 if (status)
2748 goto out; 2754 goto out;
2755 lock_sop = lock->lk_stateowner;
2749 } 2756 }
2750 /* lock->lk_stateowner and lock_stp have been created or found */ 2757 /* lock->lk_stateowner and lock_stp have been created or found */
2751 filp = lock_stp->st_vfs_file; 2758 filp = lock_stp->st_vfs_file;
2752 2759
2753 if ((status = fh_verify(rqstp, current_fh, S_IFREG, MAY_LOCK))) { 2760 if ((status = fh_verify(rqstp, current_fh, S_IFREG, MAY_LOCK))) {
2754 printk("NFSD: nfsd4_lock: permission denied!\n"); 2761 dprintk("NFSD: nfsd4_lock: permission denied!\n");
2755 goto out; 2762 goto out;
2756 } 2763 }
2757 2764
@@ -2776,7 +2783,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2776 status = nfserr_inval; 2783 status = nfserr_inval;
2777 goto out; 2784 goto out;
2778 } 2785 }
2779 file_lock.fl_owner = (fl_owner_t) lock->lk_stateowner; 2786 file_lock.fl_owner = (fl_owner_t)lock_sop;
2780 file_lock.fl_pid = current->tgid; 2787 file_lock.fl_pid = current->tgid;
2781 file_lock.fl_file = filp; 2788 file_lock.fl_file = filp;
2782 file_lock.fl_flags = FL_POSIX; 2789 file_lock.fl_flags = FL_POSIX;
@@ -2832,14 +2839,13 @@ out_destroy_new_stateid:
2832 * An error encountered after instantiation of the new 2839 * An error encountered after instantiation of the new
2833 * stateid has forced us to destroy it. 2840 * stateid has forced us to destroy it.
2834 */ 2841 */
2835 if (!seqid_mutating_err(status))
2836 open_sop->so_seqid--;
2837
2838 release_state_owner(lock_stp, LOCK_STATE); 2842 release_state_owner(lock_stp, LOCK_STATE);
2839 } 2843 }
2840out: 2844out:
2841 if (lock->lk_stateowner) 2845 if (lock->lk_stateowner) {
2842 nfs4_get_stateowner(lock->lk_stateowner); 2846 nfs4_get_stateowner(lock->lk_stateowner);
2847 *replay_owner = lock->lk_stateowner;
2848 }
2843 nfs4_unlock_state(); 2849 nfs4_unlock_state();
2844 return status; 2850 return status;
2845} 2851}
@@ -2866,13 +2872,11 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2866 nfs4_lock_state(); 2872 nfs4_lock_state();
2867 2873
2868 status = nfserr_stale_clientid; 2874 status = nfserr_stale_clientid;
2869 if (STALE_CLIENTID(&lockt->lt_clientid)) { 2875 if (STALE_CLIENTID(&lockt->lt_clientid))
2870 printk("NFSD: nfsd4_lockt: clientid is stale!\n");
2871 goto out; 2876 goto out;
2872 }
2873 2877
2874 if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0))) { 2878 if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0))) {
2875 printk("NFSD: nfsd4_lockt: fh_verify() failed!\n"); 2879 dprintk("NFSD: nfsd4_lockt: fh_verify() failed!\n");
2876 if (status == nfserr_symlink) 2880 if (status == nfserr_symlink)
2877 status = nfserr_inval; 2881 status = nfserr_inval;
2878 goto out; 2882 goto out;
@@ -2930,7 +2934,7 @@ out:
2930} 2934}
2931 2935
2932int 2936int
2933nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_locku *locku) 2937nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_locku *locku, struct nfs4_stateowner **replay_owner)
2934{ 2938{
2935 struct nfs4_stateid *stp; 2939 struct nfs4_stateid *stp;
2936 struct file *filp = NULL; 2940 struct file *filp = NULL;
@@ -2976,7 +2980,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2976 if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private) 2980 if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private)
2977 file_lock.fl_ops->fl_release_private(&file_lock); 2981 file_lock.fl_ops->fl_release_private(&file_lock);
2978 if (status) { 2982 if (status) {
2979 printk("NFSD: nfs4_locku: posix_lock_file failed!\n"); 2983 dprintk("NFSD: nfs4_locku: posix_lock_file failed!\n");
2980 goto out_nfserr; 2984 goto out_nfserr;
2981 } 2985 }
2982 /* 2986 /*
@@ -2986,8 +2990,10 @@ nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2986 memcpy(&locku->lu_stateid, &stp->st_stateid, sizeof(stateid_t)); 2990 memcpy(&locku->lu_stateid, &stp->st_stateid, sizeof(stateid_t));
2987 2991
2988out: 2992out:
2989 if (locku->lu_stateowner) 2993 if (locku->lu_stateowner) {
2990 nfs4_get_stateowner(locku->lu_stateowner); 2994 nfs4_get_stateowner(locku->lu_stateowner);
2995 *replay_owner = locku->lu_stateowner;
2996 }
2991 nfs4_unlock_state(); 2997 nfs4_unlock_state();
2992 return status; 2998 return status;
2993 2999
@@ -3036,10 +3042,8 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *
3036 /* XXX check for lease expiration */ 3042 /* XXX check for lease expiration */
3037 3043
3038 status = nfserr_stale_clientid; 3044 status = nfserr_stale_clientid;
3039 if (STALE_CLIENTID(clid)) { 3045 if (STALE_CLIENTID(clid))
3040 printk("NFSD: nfsd4_release_lockowner: clientid is stale!\n");
3041 return status; 3046 return status;
3042 }
3043 3047
3044 nfs4_lock_state(); 3048 nfs4_lock_state();
3045 3049