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.c291
1 files changed, 241 insertions, 50 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index e98f3c2e949..6f8bcc733f7 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -37,6 +37,7 @@
37#include <linux/slab.h> 37#include <linux/slab.h>
38#include <linux/namei.h> 38#include <linux/namei.h>
39#include <linux/swap.h> 39#include <linux/swap.h>
40#include <linux/pagemap.h>
40#include <linux/sunrpc/svcauth_gss.h> 41#include <linux/sunrpc/svcauth_gss.h>
41#include <linux/sunrpc/clnt.h> 42#include <linux/sunrpc/clnt.h>
42#include "xdr4.h" 43#include "xdr4.h"
@@ -60,9 +61,12 @@ static u64 current_sessionid = 1;
60 61
61/* forward declarations */ 62/* forward declarations */
62static struct nfs4_stateid * find_stateid(stateid_t *stid, int flags); 63static struct nfs4_stateid * find_stateid(stateid_t *stid, int flags);
64static struct nfs4_stateid * search_for_stateid(stateid_t *stid);
65static struct nfs4_delegation * search_for_delegation(stateid_t *stid);
63static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid); 66static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid);
64static char user_recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery"; 67static char user_recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery";
65static void nfs4_set_recdir(char *recdir); 68static void nfs4_set_recdir(char *recdir);
69static int check_for_locks(struct nfs4_file *filp, struct nfs4_stateowner *lowner);
66 70
67/* Locking: */ 71/* Locking: */
68 72
@@ -188,8 +192,15 @@ static void nfs4_file_put_fd(struct nfs4_file *fp, int oflag)
188static void __nfs4_file_put_access(struct nfs4_file *fp, int oflag) 192static void __nfs4_file_put_access(struct nfs4_file *fp, int oflag)
189{ 193{
190 if (atomic_dec_and_test(&fp->fi_access[oflag])) { 194 if (atomic_dec_and_test(&fp->fi_access[oflag])) {
191 nfs4_file_put_fd(fp, O_RDWR);
192 nfs4_file_put_fd(fp, oflag); 195 nfs4_file_put_fd(fp, oflag);
196 /*
197 * It's also safe to get rid of the RDWR open *if*
198 * we no longer have need of the other kind of access
199 * or if we already have the other kind of open:
200 */
201 if (fp->fi_fds[1-oflag]
202 || atomic_read(&fp->fi_access[1 - oflag]) == 0)
203 nfs4_file_put_fd(fp, O_RDWR);
193 } 204 }
194} 205}
195 206
@@ -381,14 +392,6 @@ static int nfs4_access_to_omode(u32 access)
381 BUG(); 392 BUG();
382} 393}
383 394
384static int nfs4_access_bmap_to_omode(struct nfs4_stateid *stp)
385{
386 unsigned int access;
387
388 set_access(&access, stp->st_access_bmap);
389 return nfs4_access_to_omode(access);
390}
391
392static void unhash_generic_stateid(struct nfs4_stateid *stp) 395static void unhash_generic_stateid(struct nfs4_stateid *stp)
393{ 396{
394 list_del(&stp->st_hash); 397 list_del(&stp->st_hash);
@@ -398,11 +401,14 @@ static void unhash_generic_stateid(struct nfs4_stateid *stp)
398 401
399static void free_generic_stateid(struct nfs4_stateid *stp) 402static void free_generic_stateid(struct nfs4_stateid *stp)
400{ 403{
401 int oflag; 404 int i;
402 405
403 if (stp->st_access_bmap) { 406 if (stp->st_access_bmap) {
404 oflag = nfs4_access_bmap_to_omode(stp); 407 for (i = 1; i < 4; i++) {
405 nfs4_file_put_access(stp->st_file, oflag); 408 if (test_bit(i, &stp->st_access_bmap))
409 nfs4_file_put_access(stp->st_file,
410 nfs4_access_to_omode(i));
411 }
406 } 412 }
407 put_nfs4_file(stp->st_file); 413 put_nfs4_file(stp->st_file);
408 kmem_cache_free(stateid_slab, stp); 414 kmem_cache_free(stateid_slab, stp);
@@ -1507,6 +1513,29 @@ nfsd4_replay_create_session(struct nfsd4_create_session *cr_ses,
1507 return slot->sl_status; 1513 return slot->sl_status;
1508} 1514}
1509 1515
1516#define NFSD_MIN_REQ_HDR_SEQ_SZ ((\
1517 2 * 2 + /* credential,verifier: AUTH_NULL, length 0 */ \
1518 1 + /* MIN tag is length with zero, only length */ \
1519 3 + /* version, opcount, opcode */ \
1520 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \
1521 /* seqid, slotID, slotID, cache */ \
1522 4 ) * sizeof(__be32))
1523
1524#define NFSD_MIN_RESP_HDR_SEQ_SZ ((\
1525 2 + /* verifier: AUTH_NULL, length 0 */\
1526 1 + /* status */ \
1527 1 + /* MIN tag is length with zero, only length */ \
1528 3 + /* opcount, opcode, opstatus*/ \
1529 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \
1530 /* seqid, slotID, slotID, slotID, status */ \
1531 5 ) * sizeof(__be32))
1532
1533static __be32 check_forechannel_attrs(struct nfsd4_channel_attrs fchannel)
1534{
1535 return fchannel.maxreq_sz < NFSD_MIN_REQ_HDR_SEQ_SZ
1536 || fchannel.maxresp_sz < NFSD_MIN_RESP_HDR_SEQ_SZ;
1537}
1538
1510__be32 1539__be32
1511nfsd4_create_session(struct svc_rqst *rqstp, 1540nfsd4_create_session(struct svc_rqst *rqstp,
1512 struct nfsd4_compound_state *cstate, 1541 struct nfsd4_compound_state *cstate,
@@ -1575,6 +1604,10 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1575 cr_ses->flags &= ~SESSION4_PERSIST; 1604 cr_ses->flags &= ~SESSION4_PERSIST;
1576 cr_ses->flags &= ~SESSION4_RDMA; 1605 cr_ses->flags &= ~SESSION4_RDMA;
1577 1606
1607 status = nfserr_toosmall;
1608 if (check_forechannel_attrs(cr_ses->fore_channel))
1609 goto out;
1610
1578 status = nfserr_jukebox; 1611 status = nfserr_jukebox;
1579 new = alloc_init_session(rqstp, conf, cr_ses); 1612 new = alloc_init_session(rqstp, conf, cr_ses);
1580 if (!new) 1613 if (!new)
@@ -1736,6 +1769,14 @@ static bool nfsd4_session_too_many_ops(struct svc_rqst *rqstp, struct nfsd4_sess
1736 return args->opcnt > session->se_fchannel.maxops; 1769 return args->opcnt > session->se_fchannel.maxops;
1737} 1770}
1738 1771
1772static bool nfsd4_request_too_big(struct svc_rqst *rqstp,
1773 struct nfsd4_session *session)
1774{
1775 struct xdr_buf *xb = &rqstp->rq_arg;
1776
1777 return xb->len > session->se_fchannel.maxreq_sz;
1778}
1779
1739__be32 1780__be32
1740nfsd4_sequence(struct svc_rqst *rqstp, 1781nfsd4_sequence(struct svc_rqst *rqstp,
1741 struct nfsd4_compound_state *cstate, 1782 struct nfsd4_compound_state *cstate,
@@ -1768,6 +1809,10 @@ nfsd4_sequence(struct svc_rqst *rqstp,
1768 if (nfsd4_session_too_many_ops(rqstp, session)) 1809 if (nfsd4_session_too_many_ops(rqstp, session))
1769 goto out; 1810 goto out;
1770 1811
1812 status = nfserr_req_too_big;
1813 if (nfsd4_request_too_big(rqstp, session))
1814 goto out;
1815
1771 status = nfserr_badslot; 1816 status = nfserr_badslot;
1772 if (seq->slotid >= session->se_fchannel.maxreqs) 1817 if (seq->slotid >= session->se_fchannel.maxreqs)
1773 goto out; 1818 goto out;
@@ -1908,7 +1953,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1908 * of 5 bullet points, labeled as CASE0 - CASE4 below. 1953 * of 5 bullet points, labeled as CASE0 - CASE4 below.
1909 */ 1954 */
1910 unconf = find_unconfirmed_client_by_str(dname, strhashval); 1955 unconf = find_unconfirmed_client_by_str(dname, strhashval);
1911 status = nfserr_resource; 1956 status = nfserr_jukebox;
1912 if (!conf) { 1957 if (!conf) {
1913 /* 1958 /*
1914 * RFC 3530 14.2.33 CASE 4: 1959 * RFC 3530 14.2.33 CASE 4:
@@ -2337,15 +2382,6 @@ out:
2337 return ret; 2382 return ret;
2338} 2383}
2339 2384
2340static inline void
2341nfs4_file_downgrade(struct nfs4_file *fp, unsigned int share_access)
2342{
2343 if (share_access & NFS4_SHARE_ACCESS_WRITE)
2344 nfs4_file_put_access(fp, O_WRONLY);
2345 if (share_access & NFS4_SHARE_ACCESS_READ)
2346 nfs4_file_put_access(fp, O_RDONLY);
2347}
2348
2349static void nfsd_break_one_deleg(struct nfs4_delegation *dp) 2385static void nfsd_break_one_deleg(struct nfs4_delegation *dp)
2350{ 2386{
2351 /* We're assuming the state code never drops its reference 2387 /* We're assuming the state code never drops its reference
@@ -2396,8 +2432,8 @@ int nfsd_change_deleg_cb(struct file_lock **onlist, int arg)
2396} 2432}
2397 2433
2398static const struct lock_manager_operations nfsd_lease_mng_ops = { 2434static const struct lock_manager_operations nfsd_lease_mng_ops = {
2399 .fl_break = nfsd_break_deleg_cb, 2435 .lm_break = nfsd_break_deleg_cb,
2400 .fl_change = nfsd_change_deleg_cb, 2436 .lm_change = nfsd_change_deleg_cb,
2401}; 2437};
2402 2438
2403 2439
@@ -2454,7 +2490,7 @@ renew:
2454 if (open->op_stateowner == NULL) { 2490 if (open->op_stateowner == NULL) {
2455 sop = alloc_init_open_stateowner(strhashval, clp, open); 2491 sop = alloc_init_open_stateowner(strhashval, clp, open);
2456 if (sop == NULL) 2492 if (sop == NULL)
2457 return nfserr_resource; 2493 return nfserr_jukebox;
2458 open->op_stateowner = sop; 2494 open->op_stateowner = sop;
2459 } 2495 }
2460 list_del_init(&sop->so_close_lru); 2496 list_del_init(&sop->so_close_lru);
@@ -2556,12 +2592,18 @@ static inline int nfs4_access_to_access(u32 nfs4_access)
2556 return flags; 2592 return flags;
2557} 2593}
2558 2594
2559static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file 2595static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file *fp,
2560*fp, struct svc_fh *cur_fh, u32 nfs4_access) 2596 struct svc_fh *cur_fh, struct nfsd4_open *open)
2561{ 2597{
2562 __be32 status; 2598 __be32 status;
2563 int oflag = nfs4_access_to_omode(nfs4_access); 2599 int oflag = nfs4_access_to_omode(open->op_share_access);
2564 int access = nfs4_access_to_access(nfs4_access); 2600 int access = nfs4_access_to_access(open->op_share_access);
2601
2602 /* CLAIM_DELEGATE_CUR is used in response to a broken lease;
2603 * allowing it to break the lease and return EAGAIN leaves the
2604 * client unable to make progress in returning the delegation */
2605 if (open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR)
2606 access |= NFSD_MAY_NOT_BREAK_LEASE;
2565 2607
2566 if (!fp->fi_fds[oflag]) { 2608 if (!fp->fi_fds[oflag]) {
2567 status = nfsd_open(rqstp, cur_fh, S_IFREG, access, 2609 status = nfsd_open(rqstp, cur_fh, S_IFREG, access,
@@ -2584,9 +2626,9 @@ nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_stateid **stpp,
2584 2626
2585 stp = nfs4_alloc_stateid(); 2627 stp = nfs4_alloc_stateid();
2586 if (stp == NULL) 2628 if (stp == NULL)
2587 return nfserr_resource; 2629 return nfserr_jukebox;
2588 2630
2589 status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open->op_share_access); 2631 status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open);
2590 if (status) { 2632 if (status) {
2591 kmem_cache_free(stateid_slab, stp); 2633 kmem_cache_free(stateid_slab, stp);
2592 return status; 2634 return status;
@@ -2619,14 +2661,14 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *c
2619 2661
2620 new_access = !test_bit(op_share_access, &stp->st_access_bmap); 2662 new_access = !test_bit(op_share_access, &stp->st_access_bmap);
2621 if (new_access) { 2663 if (new_access) {
2622 status = nfs4_get_vfs_file(rqstp, fp, cur_fh, op_share_access); 2664 status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open);
2623 if (status) 2665 if (status)
2624 return status; 2666 return status;
2625 } 2667 }
2626 status = nfsd4_truncate(rqstp, cur_fh, open); 2668 status = nfsd4_truncate(rqstp, cur_fh, open);
2627 if (status) { 2669 if (status) {
2628 if (new_access) { 2670 if (new_access) {
2629 int oflag = nfs4_access_to_omode(new_access); 2671 int oflag = nfs4_access_to_omode(op_share_access);
2630 nfs4_file_put_access(fp, oflag); 2672 nfs4_file_put_access(fp, oflag);
2631 } 2673 }
2632 return status; 2674 return status;
@@ -2815,7 +2857,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
2815 status = nfserr_bad_stateid; 2857 status = nfserr_bad_stateid;
2816 if (open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR) 2858 if (open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR)
2817 goto out; 2859 goto out;
2818 status = nfserr_resource; 2860 status = nfserr_jukebox;
2819 fp = alloc_init_file(ino); 2861 fp = alloc_init_file(ino);
2820 if (fp == NULL) 2862 if (fp == NULL)
2821 goto out; 2863 goto out;
@@ -3137,6 +3179,37 @@ static int is_delegation_stateid(stateid_t *stateid)
3137 return stateid->si_fileid == 0; 3179 return stateid->si_fileid == 0;
3138} 3180}
3139 3181
3182static int is_open_stateid(struct nfs4_stateid *stateid)
3183{
3184 return stateid->st_openstp == NULL;
3185}
3186
3187__be32 nfs4_validate_stateid(stateid_t *stateid, int flags)
3188{
3189 struct nfs4_stateid *stp = NULL;
3190 __be32 status = nfserr_stale_stateid;
3191
3192 if (STALE_STATEID(stateid))
3193 goto out;
3194
3195 status = nfserr_expired;
3196 stp = search_for_stateid(stateid);
3197 if (!stp)
3198 goto out;
3199 status = nfserr_bad_stateid;
3200
3201 if (!stp->st_stateowner->so_confirmed)
3202 goto out;
3203
3204 status = check_stateid_generation(stateid, &stp->st_stateid, flags);
3205 if (status)
3206 goto out;
3207
3208 status = nfs_ok;
3209out:
3210 return status;
3211}
3212
3140/* 3213/*
3141* Checks for stateid operations 3214* Checks for stateid operations
3142*/ 3215*/
@@ -3216,6 +3289,81 @@ out:
3216 return status; 3289 return status;
3217} 3290}
3218 3291
3292static __be32
3293nfsd4_free_delegation_stateid(stateid_t *stateid)
3294{
3295 struct nfs4_delegation *dp = search_for_delegation(stateid);
3296 if (dp)
3297 return nfserr_locks_held;
3298 return nfserr_bad_stateid;
3299}
3300
3301static __be32
3302nfsd4_free_lock_stateid(struct nfs4_stateid *stp)
3303{
3304 if (check_for_locks(stp->st_file, stp->st_stateowner))
3305 return nfserr_locks_held;
3306 release_lock_stateid(stp);
3307 return nfs_ok;
3308}
3309
3310/*
3311 * Test if the stateid is valid
3312 */
3313__be32
3314nfsd4_test_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3315 struct nfsd4_test_stateid *test_stateid)
3316{
3317 test_stateid->ts_has_session = nfsd4_has_session(cstate);
3318 return nfs_ok;
3319}
3320
3321/*
3322 * Free a state id
3323 */
3324__be32
3325nfsd4_free_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3326 struct nfsd4_free_stateid *free_stateid)
3327{
3328 stateid_t *stateid = &free_stateid->fr_stateid;
3329 struct nfs4_stateid *stp;
3330 __be32 ret;
3331
3332 nfs4_lock_state();
3333 if (is_delegation_stateid(stateid)) {
3334 ret = nfsd4_free_delegation_stateid(stateid);
3335 goto out;
3336 }
3337
3338 stp = search_for_stateid(stateid);
3339 if (!stp) {
3340 ret = nfserr_bad_stateid;
3341 goto out;
3342 }
3343 if (stateid->si_generation != 0) {
3344 if (stateid->si_generation < stp->st_stateid.si_generation) {
3345 ret = nfserr_old_stateid;
3346 goto out;
3347 }
3348 if (stateid->si_generation > stp->st_stateid.si_generation) {
3349 ret = nfserr_bad_stateid;
3350 goto out;
3351 }
3352 }
3353
3354 if (is_open_stateid(stp)) {
3355 ret = nfserr_locks_held;
3356 goto out;
3357 } else {
3358 ret = nfsd4_free_lock_stateid(stp);
3359 goto out;
3360 }
3361
3362out:
3363 nfs4_unlock_state();
3364 return ret;
3365}
3366
3219static inline int 3367static inline int
3220setlkflg (int type) 3368setlkflg (int type)
3221{ 3369{
@@ -3384,18 +3532,16 @@ out:
3384 return status; 3532 return status;
3385} 3533}
3386 3534
3387 3535static inline void nfs4_file_downgrade(struct nfs4_stateid *stp, unsigned int to_access)
3388/*
3389 * unset all bits in union bitmap (bmap) that
3390 * do not exist in share (from successful OPEN_DOWNGRADE)
3391 */
3392static void
3393reset_union_bmap_access(unsigned long access, unsigned long *bmap)
3394{ 3536{
3395 int i; 3537 int i;
3538
3396 for (i = 1; i < 4; i++) { 3539 for (i = 1; i < 4; i++) {
3397 if ((i & access) != i) 3540 if (test_bit(i, &stp->st_access_bmap)
3398 __clear_bit(i, bmap); 3541 && ((i & to_access) != i)) {
3542 nfs4_file_put_access(stp->st_file, nfs4_access_to_omode(i));
3543 __clear_bit(i, &stp->st_access_bmap);
3544 }
3399 } 3545 }
3400} 3546}
3401 3547
@@ -3416,7 +3562,6 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
3416{ 3562{
3417 __be32 status; 3563 __be32 status;
3418 struct nfs4_stateid *stp; 3564 struct nfs4_stateid *stp;
3419 unsigned int share_access;
3420 3565
3421 dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n", 3566 dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n",
3422 (int)cstate->current_fh.fh_dentry->d_name.len, 3567 (int)cstate->current_fh.fh_dentry->d_name.len,
@@ -3425,6 +3570,8 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
3425 if (!access_valid(od->od_share_access, cstate->minorversion) 3570 if (!access_valid(od->od_share_access, cstate->minorversion)
3426 || !deny_valid(od->od_share_deny)) 3571 || !deny_valid(od->od_share_deny))
3427 return nfserr_inval; 3572 return nfserr_inval;
3573 /* We don't yet support WANT bits: */
3574 od->od_share_access &= NFS4_SHARE_ACCESS_MASK;
3428 3575
3429 nfs4_lock_state(); 3576 nfs4_lock_state();
3430 if ((status = nfs4_preprocess_seqid_op(cstate, 3577 if ((status = nfs4_preprocess_seqid_op(cstate,
@@ -3445,10 +3592,8 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
3445 stp->st_deny_bmap, od->od_share_deny); 3592 stp->st_deny_bmap, od->od_share_deny);
3446 goto out; 3593 goto out;
3447 } 3594 }
3448 set_access(&share_access, stp->st_access_bmap); 3595 nfs4_file_downgrade(stp, od->od_share_access);
3449 nfs4_file_downgrade(stp->st_file, share_access & ~od->od_share_access);
3450 3596
3451 reset_union_bmap_access(od->od_share_access, &stp->st_access_bmap);
3452 reset_union_bmap_deny(od->od_share_deny, &stp->st_deny_bmap); 3597 reset_union_bmap_deny(od->od_share_deny, &stp->st_deny_bmap);
3453 3598
3454 update_stateid(&stp->st_stateid); 3599 update_stateid(&stp->st_stateid);
@@ -3594,6 +3739,14 @@ static struct list_head lock_ownerid_hashtbl[LOCK_HASH_SIZE];
3594static struct list_head lock_ownerstr_hashtbl[LOCK_HASH_SIZE]; 3739static struct list_head lock_ownerstr_hashtbl[LOCK_HASH_SIZE];
3595static struct list_head lockstateid_hashtbl[STATEID_HASH_SIZE]; 3740static struct list_head lockstateid_hashtbl[STATEID_HASH_SIZE];
3596 3741
3742static int
3743same_stateid(stateid_t *id_one, stateid_t *id_two)
3744{
3745 if (id_one->si_stateownerid != id_two->si_stateownerid)
3746 return 0;
3747 return id_one->si_fileid == id_two->si_fileid;
3748}
3749
3597static struct nfs4_stateid * 3750static struct nfs4_stateid *
3598find_stateid(stateid_t *stid, int flags) 3751find_stateid(stateid_t *stid, int flags)
3599{ 3752{
@@ -3623,6 +3776,44 @@ find_stateid(stateid_t *stid, int flags)
3623 return NULL; 3776 return NULL;
3624} 3777}
3625 3778
3779static struct nfs4_stateid *
3780search_for_stateid(stateid_t *stid)
3781{
3782 struct nfs4_stateid *local;
3783 unsigned int hashval = stateid_hashval(stid->si_stateownerid, stid->si_fileid);
3784
3785 list_for_each_entry(local, &lockstateid_hashtbl[hashval], st_hash) {
3786 if (same_stateid(&local->st_stateid, stid))
3787 return local;
3788 }
3789
3790 list_for_each_entry(local, &stateid_hashtbl[hashval], st_hash) {
3791 if (same_stateid(&local->st_stateid, stid))
3792 return local;
3793 }
3794 return NULL;
3795}
3796
3797static struct nfs4_delegation *
3798search_for_delegation(stateid_t *stid)
3799{
3800 struct nfs4_file *fp;
3801 struct nfs4_delegation *dp;
3802 struct list_head *pos;
3803 int i;
3804
3805 for (i = 0; i < FILE_HASH_SIZE; i++) {
3806 list_for_each_entry(fp, &file_hashtbl[i], fi_hash) {
3807 list_for_each(pos, &fp->fi_delegations) {
3808 dp = list_entry(pos, struct nfs4_delegation, dl_perfile);
3809 if (same_stateid(&dp->dl_stateid, stid))
3810 return dp;
3811 }
3812 }
3813 }
3814 return NULL;
3815}
3816
3626static struct nfs4_delegation * 3817static struct nfs4_delegation *
3627find_delegation_stateid(struct inode *ino, stateid_t *stid) 3818find_delegation_stateid(struct inode *ino, stateid_t *stid)
3628{ 3819{
@@ -3854,7 +4045,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3854 /* XXX: Do we need to check for duplicate stateowners on 4045 /* XXX: Do we need to check for duplicate stateowners on
3855 * the same file, or should they just be allowed (and 4046 * the same file, or should they just be allowed (and
3856 * create new stateids)? */ 4047 * create new stateids)? */
3857 status = nfserr_resource; 4048 status = nfserr_jukebox;
3858 lock_sop = alloc_init_lock_stateowner(strhashval, 4049 lock_sop = alloc_init_lock_stateowner(strhashval,
3859 open_sop->so_client, open_stp, lock); 4050 open_sop->so_client, open_stp, lock);
3860 if (lock_sop == NULL) 4051 if (lock_sop == NULL)
@@ -3938,9 +4129,9 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3938 case (EDEADLK): 4129 case (EDEADLK):
3939 status = nfserr_deadlock; 4130 status = nfserr_deadlock;
3940 break; 4131 break;
3941 default: 4132 default:
3942 dprintk("NFSD: nfsd4_lock: vfs_lock_file() failed! status %d\n",err); 4133 dprintk("NFSD: nfsd4_lock: vfs_lock_file() failed! status %d\n",err);
3943 status = nfserr_resource; 4134 status = nfserrno(err);
3944 break; 4135 break;
3945 } 4136 }
3946out: 4137out: