diff options
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/export.c | 1 | ||||
-rw-r--r-- | fs/nfsd/lockd.c | 1 | ||||
-rw-r--r-- | fs/nfsd/nfs3xdr.c | 2 | ||||
-rw-r--r-- | fs/nfsd/nfs4idmap.c | 1 | ||||
-rw-r--r-- | fs/nfsd/nfs4proc.c | 4 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 170 | ||||
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 5 | ||||
-rw-r--r-- | fs/nfsd/nfsctl.c | 35 | ||||
-rw-r--r-- | fs/nfsd/nfsxdr.c | 2 | ||||
-rw-r--r-- | fs/nfsd/state.h | 12 | ||||
-rw-r--r-- | fs/nfsd/vfs.c | 11 |
11 files changed, 142 insertions, 102 deletions
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 8b31e5f8795d..ad000aeb21a2 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c | |||
@@ -299,7 +299,6 @@ svc_expkey_update(struct svc_expkey *new, struct svc_expkey *old) | |||
299 | 299 | ||
300 | #define EXPORT_HASHBITS 8 | 300 | #define EXPORT_HASHBITS 8 |
301 | #define EXPORT_HASHMAX (1<< EXPORT_HASHBITS) | 301 | #define EXPORT_HASHMAX (1<< EXPORT_HASHBITS) |
302 | #define EXPORT_HASHMASK (EXPORT_HASHMAX -1) | ||
303 | 302 | ||
304 | static struct cache_head *export_table[EXPORT_HASHMAX]; | 303 | static struct cache_head *export_table[EXPORT_HASHMAX]; |
305 | 304 | ||
diff --git a/fs/nfsd/lockd.c b/fs/nfsd/lockd.c index 0c6d81670137..7c831a2731fa 100644 --- a/fs/nfsd/lockd.c +++ b/fs/nfsd/lockd.c | |||
@@ -38,7 +38,6 @@ nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp) | |||
38 | exp_readlock(); | 38 | exp_readlock(); |
39 | nfserr = nfsd_open(rqstp, &fh, S_IFREG, NFSD_MAY_LOCK, filp); | 39 | nfserr = nfsd_open(rqstp, &fh, S_IFREG, NFSD_MAY_LOCK, filp); |
40 | fh_put(&fh); | 40 | fh_put(&fh); |
41 | rqstp->rq_client = NULL; | ||
42 | exp_readunlock(); | 41 | exp_readunlock(); |
43 | /* We return nlm error codes as nlm doesn't know | 42 | /* We return nlm error codes as nlm doesn't know |
44 | * about nfsd, but nfsd does know about nlm.. | 43 | * about nfsd, but nfsd does know about nlm.. |
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 7e84a852cdae..ad48faca20fc 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c | |||
@@ -702,7 +702,7 @@ nfs3svc_encode_readres(struct svc_rqst *rqstp, __be32 *p, | |||
702 | *p++ = htonl(resp->eof); | 702 | *p++ = htonl(resp->eof); |
703 | *p++ = htonl(resp->count); /* xdr opaque count */ | 703 | *p++ = htonl(resp->count); /* xdr opaque count */ |
704 | xdr_ressize_check(rqstp, p); | 704 | xdr_ressize_check(rqstp, p); |
705 | /* now update rqstp->rq_res to reflect data aswell */ | 705 | /* now update rqstp->rq_res to reflect data as well */ |
706 | rqstp->rq_res.page_len = resp->count; | 706 | rqstp->rq_res.page_len = resp->count; |
707 | if (resp->count & 3) { | 707 | if (resp->count & 3) { |
708 | /* need to pad the tail */ | 708 | /* need to pad the tail */ |
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c index 6d2c397d458b..55780a22fdbd 100644 --- a/fs/nfsd/nfs4idmap.c +++ b/fs/nfsd/nfs4idmap.c | |||
@@ -63,7 +63,6 @@ struct ent { | |||
63 | 63 | ||
64 | #define ENT_HASHBITS 8 | 64 | #define ENT_HASHBITS 8 |
65 | #define ENT_HASHMAX (1 << ENT_HASHBITS) | 65 | #define ENT_HASHMAX (1 << ENT_HASHBITS) |
66 | #define ENT_HASHMASK (ENT_HASHMAX - 1) | ||
67 | 66 | ||
68 | static void | 67 | static void |
69 | ent_init(struct cache_head *cnew, struct cache_head *citm) | 68 | ent_init(struct cache_head *cnew, struct cache_head *citm) |
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index db52546143d1..5fcb1396a7e3 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -984,8 +984,8 @@ typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *, | |||
984 | void *); | 984 | void *); |
985 | enum nfsd4_op_flags { | 985 | enum nfsd4_op_flags { |
986 | ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */ | 986 | ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */ |
987 | ALLOWED_ON_ABSENT_FS = 2 << 0, /* ops processed on absent fs */ | 987 | ALLOWED_ON_ABSENT_FS = 1 << 1, /* ops processed on absent fs */ |
988 | ALLOWED_AS_FIRST_OP = 3 << 0, /* ops reqired first in compound */ | 988 | ALLOWED_AS_FIRST_OP = 1 << 2, /* ops reqired first in compound */ |
989 | }; | 989 | }; |
990 | 990 | ||
991 | struct nfsd4_operation { | 991 | struct nfsd4_operation { |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 7b566ec14e18..4cf04e11c66c 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -148,7 +148,7 @@ static struct list_head ownerstr_hashtbl[OWNER_HASH_SIZE]; | |||
148 | /* hash table for nfs4_file */ | 148 | /* hash table for nfs4_file */ |
149 | #define FILE_HASH_BITS 8 | 149 | #define FILE_HASH_BITS 8 |
150 | #define FILE_HASH_SIZE (1 << FILE_HASH_BITS) | 150 | #define FILE_HASH_SIZE (1 << FILE_HASH_BITS) |
151 | #define FILE_HASH_MASK (FILE_HASH_SIZE - 1) | 151 | |
152 | /* hash table for (open)nfs4_stateid */ | 152 | /* hash table for (open)nfs4_stateid */ |
153 | #define STATEID_HASH_BITS 10 | 153 | #define STATEID_HASH_BITS 10 |
154 | #define STATEID_HASH_SIZE (1 << STATEID_HASH_BITS) | 154 | #define STATEID_HASH_SIZE (1 << STATEID_HASH_BITS) |
@@ -258,6 +258,7 @@ static void nfs4_put_deleg_lease(struct nfs4_file *fp) | |||
258 | if (atomic_dec_and_test(&fp->fi_delegees)) { | 258 | if (atomic_dec_and_test(&fp->fi_delegees)) { |
259 | vfs_setlease(fp->fi_deleg_file, F_UNLCK, &fp->fi_lease); | 259 | vfs_setlease(fp->fi_deleg_file, F_UNLCK, &fp->fi_lease); |
260 | fp->fi_lease = NULL; | 260 | fp->fi_lease = NULL; |
261 | fput(fp->fi_deleg_file); | ||
261 | fp->fi_deleg_file = NULL; | 262 | fp->fi_deleg_file = NULL; |
262 | } | 263 | } |
263 | } | 264 | } |
@@ -316,64 +317,6 @@ static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE]; | |||
316 | static struct list_head client_lru; | 317 | static struct list_head client_lru; |
317 | static struct list_head close_lru; | 318 | static struct list_head close_lru; |
318 | 319 | ||
319 | static void unhash_generic_stateid(struct nfs4_stateid *stp) | ||
320 | { | ||
321 | list_del(&stp->st_hash); | ||
322 | list_del(&stp->st_perfile); | ||
323 | list_del(&stp->st_perstateowner); | ||
324 | } | ||
325 | |||
326 | static void free_generic_stateid(struct nfs4_stateid *stp) | ||
327 | { | ||
328 | put_nfs4_file(stp->st_file); | ||
329 | kmem_cache_free(stateid_slab, stp); | ||
330 | } | ||
331 | |||
332 | static void release_lock_stateid(struct nfs4_stateid *stp) | ||
333 | { | ||
334 | struct file *file; | ||
335 | |||
336 | unhash_generic_stateid(stp); | ||
337 | file = find_any_file(stp->st_file); | ||
338 | if (file) | ||
339 | locks_remove_posix(file, (fl_owner_t)stp->st_stateowner); | ||
340 | free_generic_stateid(stp); | ||
341 | } | ||
342 | |||
343 | static void unhash_lockowner(struct nfs4_stateowner *sop) | ||
344 | { | ||
345 | struct nfs4_stateid *stp; | ||
346 | |||
347 | list_del(&sop->so_idhash); | ||
348 | list_del(&sop->so_strhash); | ||
349 | list_del(&sop->so_perstateid); | ||
350 | while (!list_empty(&sop->so_stateids)) { | ||
351 | stp = list_first_entry(&sop->so_stateids, | ||
352 | struct nfs4_stateid, st_perstateowner); | ||
353 | release_lock_stateid(stp); | ||
354 | } | ||
355 | } | ||
356 | |||
357 | static void release_lockowner(struct nfs4_stateowner *sop) | ||
358 | { | ||
359 | unhash_lockowner(sop); | ||
360 | nfs4_put_stateowner(sop); | ||
361 | } | ||
362 | |||
363 | static void | ||
364 | release_stateid_lockowners(struct nfs4_stateid *open_stp) | ||
365 | { | ||
366 | struct nfs4_stateowner *lock_sop; | ||
367 | |||
368 | while (!list_empty(&open_stp->st_lockowners)) { | ||
369 | lock_sop = list_entry(open_stp->st_lockowners.next, | ||
370 | struct nfs4_stateowner, so_perstateid); | ||
371 | /* list_del(&open_stp->st_lockowners); */ | ||
372 | BUG_ON(lock_sop->so_is_open_owner); | ||
373 | release_lockowner(lock_sop); | ||
374 | } | ||
375 | } | ||
376 | |||
377 | /* | 320 | /* |
378 | * We store the NONE, READ, WRITE, and BOTH bits separately in the | 321 | * We store the NONE, READ, WRITE, and BOTH bits separately in the |
379 | * st_{access,deny}_bmap field of the stateid, in order to track not | 322 | * st_{access,deny}_bmap field of the stateid, in order to track not |
@@ -446,13 +389,74 @@ static int nfs4_access_bmap_to_omode(struct nfs4_stateid *stp) | |||
446 | return nfs4_access_to_omode(access); | 389 | return nfs4_access_to_omode(access); |
447 | } | 390 | } |
448 | 391 | ||
449 | static void release_open_stateid(struct nfs4_stateid *stp) | 392 | static void unhash_generic_stateid(struct nfs4_stateid *stp) |
450 | { | 393 | { |
451 | int oflag = nfs4_access_bmap_to_omode(stp); | 394 | list_del(&stp->st_hash); |
395 | list_del(&stp->st_perfile); | ||
396 | list_del(&stp->st_perstateowner); | ||
397 | } | ||
452 | 398 | ||
399 | static void free_generic_stateid(struct nfs4_stateid *stp) | ||
400 | { | ||
401 | int oflag; | ||
402 | |||
403 | if (stp->st_access_bmap) { | ||
404 | oflag = nfs4_access_bmap_to_omode(stp); | ||
405 | nfs4_file_put_access(stp->st_file, oflag); | ||
406 | } | ||
407 | put_nfs4_file(stp->st_file); | ||
408 | kmem_cache_free(stateid_slab, stp); | ||
409 | } | ||
410 | |||
411 | static void release_lock_stateid(struct nfs4_stateid *stp) | ||
412 | { | ||
413 | struct file *file; | ||
414 | |||
415 | unhash_generic_stateid(stp); | ||
416 | file = find_any_file(stp->st_file); | ||
417 | if (file) | ||
418 | locks_remove_posix(file, (fl_owner_t)stp->st_stateowner); | ||
419 | free_generic_stateid(stp); | ||
420 | } | ||
421 | |||
422 | static void unhash_lockowner(struct nfs4_stateowner *sop) | ||
423 | { | ||
424 | struct nfs4_stateid *stp; | ||
425 | |||
426 | list_del(&sop->so_idhash); | ||
427 | list_del(&sop->so_strhash); | ||
428 | list_del(&sop->so_perstateid); | ||
429 | while (!list_empty(&sop->so_stateids)) { | ||
430 | stp = list_first_entry(&sop->so_stateids, | ||
431 | struct nfs4_stateid, st_perstateowner); | ||
432 | release_lock_stateid(stp); | ||
433 | } | ||
434 | } | ||
435 | |||
436 | static void release_lockowner(struct nfs4_stateowner *sop) | ||
437 | { | ||
438 | unhash_lockowner(sop); | ||
439 | nfs4_put_stateowner(sop); | ||
440 | } | ||
441 | |||
442 | static void | ||
443 | release_stateid_lockowners(struct nfs4_stateid *open_stp) | ||
444 | { | ||
445 | struct nfs4_stateowner *lock_sop; | ||
446 | |||
447 | while (!list_empty(&open_stp->st_lockowners)) { | ||
448 | lock_sop = list_entry(open_stp->st_lockowners.next, | ||
449 | struct nfs4_stateowner, so_perstateid); | ||
450 | /* list_del(&open_stp->st_lockowners); */ | ||
451 | BUG_ON(lock_sop->so_is_open_owner); | ||
452 | release_lockowner(lock_sop); | ||
453 | } | ||
454 | } | ||
455 | |||
456 | static void release_open_stateid(struct nfs4_stateid *stp) | ||
457 | { | ||
453 | unhash_generic_stateid(stp); | 458 | unhash_generic_stateid(stp); |
454 | release_stateid_lockowners(stp); | 459 | release_stateid_lockowners(stp); |
455 | nfs4_file_put_access(stp->st_file, oflag); | ||
456 | free_generic_stateid(stp); | 460 | free_generic_stateid(stp); |
457 | } | 461 | } |
458 | 462 | ||
@@ -608,7 +612,8 @@ static void init_forechannel_attrs(struct nfsd4_channel_attrs *new, struct nfsd4 | |||
608 | u32 maxrpc = nfsd_serv->sv_max_mesg; | 612 | u32 maxrpc = nfsd_serv->sv_max_mesg; |
609 | 613 | ||
610 | new->maxreqs = numslots; | 614 | new->maxreqs = numslots; |
611 | new->maxresp_cached = slotsize + NFSD_MIN_HDR_SEQ_SZ; | 615 | new->maxresp_cached = min_t(u32, req->maxresp_cached, |
616 | slotsize + NFSD_MIN_HDR_SEQ_SZ); | ||
612 | new->maxreq_sz = min_t(u32, req->maxreq_sz, maxrpc); | 617 | new->maxreq_sz = min_t(u32, req->maxreq_sz, maxrpc); |
613 | new->maxresp_sz = min_t(u32, req->maxresp_sz, maxrpc); | 618 | new->maxresp_sz = min_t(u32, req->maxresp_sz, maxrpc); |
614 | new->maxops = min_t(u32, req->maxops, NFSD_MAX_OPS_PER_COMPOUND); | 619 | new->maxops = min_t(u32, req->maxops, NFSD_MAX_OPS_PER_COMPOUND); |
@@ -3054,7 +3059,7 @@ check_special_stateids(svc_fh *current_fh, stateid_t *stateid, int flags) | |||
3054 | if (ONE_STATEID(stateid) && (flags & RD_STATE)) | 3059 | if (ONE_STATEID(stateid) && (flags & RD_STATE)) |
3055 | return nfs_ok; | 3060 | return nfs_ok; |
3056 | else if (locks_in_grace()) { | 3061 | else if (locks_in_grace()) { |
3057 | /* Answer in remaining cases depends on existance of | 3062 | /* Answer in remaining cases depends on existence of |
3058 | * conflicting state; so we must wait out the grace period. */ | 3063 | * conflicting state; so we must wait out the grace period. */ |
3059 | return nfserr_grace; | 3064 | return nfserr_grace; |
3060 | } else if (flags & WR_STATE) | 3065 | } else if (flags & WR_STATE) |
@@ -3674,7 +3679,7 @@ find_lockstateowner_str(struct inode *inode, clientid_t *clid, | |||
3674 | /* | 3679 | /* |
3675 | * Alloc a lock owner structure. | 3680 | * Alloc a lock owner structure. |
3676 | * Called in nfsd4_lock - therefore, OPEN and OPEN_CONFIRM (if needed) has | 3681 | * Called in nfsd4_lock - therefore, OPEN and OPEN_CONFIRM (if needed) has |
3677 | * occured. | 3682 | * occurred. |
3678 | * | 3683 | * |
3679 | * strhashval = lock_ownerstr_hashval | 3684 | * strhashval = lock_ownerstr_hashval |
3680 | */ | 3685 | */ |
@@ -3735,6 +3740,7 @@ alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struc | |||
3735 | stp->st_stateid.si_stateownerid = sop->so_id; | 3740 | stp->st_stateid.si_stateownerid = sop->so_id; |
3736 | stp->st_stateid.si_fileid = fp->fi_id; | 3741 | stp->st_stateid.si_fileid = fp->fi_id; |
3737 | stp->st_stateid.si_generation = 0; | 3742 | stp->st_stateid.si_generation = 0; |
3743 | stp->st_access_bmap = 0; | ||
3738 | stp->st_deny_bmap = open_stp->st_deny_bmap; | 3744 | stp->st_deny_bmap = open_stp->st_deny_bmap; |
3739 | stp->st_openstp = open_stp; | 3745 | stp->st_openstp = open_stp; |
3740 | 3746 | ||
@@ -3749,6 +3755,17 @@ check_lock_length(u64 offset, u64 length) | |||
3749 | LOFF_OVERFLOW(offset, length))); | 3755 | LOFF_OVERFLOW(offset, length))); |
3750 | } | 3756 | } |
3751 | 3757 | ||
3758 | static void get_lock_access(struct nfs4_stateid *lock_stp, u32 access) | ||
3759 | { | ||
3760 | struct nfs4_file *fp = lock_stp->st_file; | ||
3761 | int oflag = nfs4_access_to_omode(access); | ||
3762 | |||
3763 | if (test_bit(access, &lock_stp->st_access_bmap)) | ||
3764 | return; | ||
3765 | nfs4_file_get_access(fp, oflag); | ||
3766 | __set_bit(access, &lock_stp->st_access_bmap); | ||
3767 | } | ||
3768 | |||
3752 | /* | 3769 | /* |
3753 | * LOCK operation | 3770 | * LOCK operation |
3754 | */ | 3771 | */ |
@@ -3765,7 +3782,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3765 | struct file_lock conflock; | 3782 | struct file_lock conflock; |
3766 | __be32 status = 0; | 3783 | __be32 status = 0; |
3767 | unsigned int strhashval; | 3784 | unsigned int strhashval; |
3768 | unsigned int cmd; | ||
3769 | int err; | 3785 | int err; |
3770 | 3786 | ||
3771 | dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n", | 3787 | dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n", |
@@ -3847,22 +3863,18 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3847 | switch (lock->lk_type) { | 3863 | switch (lock->lk_type) { |
3848 | case NFS4_READ_LT: | 3864 | case NFS4_READ_LT: |
3849 | case NFS4_READW_LT: | 3865 | case NFS4_READW_LT: |
3850 | if (find_readable_file(lock_stp->st_file)) { | 3866 | filp = find_readable_file(lock_stp->st_file); |
3851 | nfs4_get_vfs_file(rqstp, fp, &cstate->current_fh, NFS4_SHARE_ACCESS_READ); | 3867 | if (filp) |
3852 | filp = find_readable_file(lock_stp->st_file); | 3868 | get_lock_access(lock_stp, NFS4_SHARE_ACCESS_READ); |
3853 | } | ||
3854 | file_lock.fl_type = F_RDLCK; | 3869 | file_lock.fl_type = F_RDLCK; |
3855 | cmd = F_SETLK; | 3870 | break; |
3856 | break; | ||
3857 | case NFS4_WRITE_LT: | 3871 | case NFS4_WRITE_LT: |
3858 | case NFS4_WRITEW_LT: | 3872 | case NFS4_WRITEW_LT: |
3859 | if (find_writeable_file(lock_stp->st_file)) { | 3873 | filp = find_writeable_file(lock_stp->st_file); |
3860 | nfs4_get_vfs_file(rqstp, fp, &cstate->current_fh, NFS4_SHARE_ACCESS_WRITE); | 3874 | if (filp) |
3861 | filp = find_writeable_file(lock_stp->st_file); | 3875 | get_lock_access(lock_stp, NFS4_SHARE_ACCESS_WRITE); |
3862 | } | ||
3863 | file_lock.fl_type = F_WRLCK; | 3876 | file_lock.fl_type = F_WRLCK; |
3864 | cmd = F_SETLK; | 3877 | break; |
3865 | break; | ||
3866 | default: | 3878 | default: |
3867 | status = nfserr_inval; | 3879 | status = nfserr_inval; |
3868 | goto out; | 3880 | goto out; |
@@ -3886,7 +3898,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3886 | * Note: locks.c uses the BKL to protect the inode's lock list. | 3898 | * Note: locks.c uses the BKL to protect the inode's lock list. |
3887 | */ | 3899 | */ |
3888 | 3900 | ||
3889 | err = vfs_lock_file(filp, cmd, &file_lock, &conflock); | 3901 | err = vfs_lock_file(filp, F_SETLK, &file_lock, &conflock); |
3890 | switch (-err) { | 3902 | switch (-err) { |
3891 | case 0: /* success! */ | 3903 | case 0: /* success! */ |
3892 | update_stateid(&lock_stp->st_stateid); | 3904 | update_stateid(&lock_stp->st_stateid); |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 615f0a9f0600..c6766af00d98 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -1142,7 +1142,7 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp, | |||
1142 | 1142 | ||
1143 | u32 dummy; | 1143 | u32 dummy; |
1144 | char *machine_name; | 1144 | char *machine_name; |
1145 | int i, j; | 1145 | int i; |
1146 | int nr_secflavs; | 1146 | int nr_secflavs; |
1147 | 1147 | ||
1148 | READ_BUF(16); | 1148 | READ_BUF(16); |
@@ -1215,8 +1215,6 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp, | |||
1215 | READ_BUF(4); | 1215 | READ_BUF(4); |
1216 | READ32(dummy); | 1216 | READ32(dummy); |
1217 | READ_BUF(dummy * 4); | 1217 | READ_BUF(dummy * 4); |
1218 | for (j = 0; j < dummy; ++j) | ||
1219 | READ32(dummy); | ||
1220 | break; | 1218 | break; |
1221 | case RPC_AUTH_GSS: | 1219 | case RPC_AUTH_GSS: |
1222 | dprintk("RPC_AUTH_GSS callback secflavor " | 1220 | dprintk("RPC_AUTH_GSS callback secflavor " |
@@ -1232,7 +1230,6 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp, | |||
1232 | READ_BUF(4); | 1230 | READ_BUF(4); |
1233 | READ32(dummy); | 1231 | READ32(dummy); |
1234 | READ_BUF(dummy); | 1232 | READ_BUF(dummy); |
1235 | p += XDR_QUADLEN(dummy); | ||
1236 | break; | 1233 | break; |
1237 | default: | 1234 | default: |
1238 | dprintk("Illegal callback secflavor\n"); | 1235 | dprintk("Illegal callback secflavor\n"); |
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 33b3e2b06779..1f5eae40f34e 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c | |||
@@ -12,13 +12,14 @@ | |||
12 | #include <linux/nfsd/syscall.h> | 12 | #include <linux/nfsd/syscall.h> |
13 | #include <linux/lockd/lockd.h> | 13 | #include <linux/lockd/lockd.h> |
14 | #include <linux/sunrpc/clnt.h> | 14 | #include <linux/sunrpc/clnt.h> |
15 | #include <linux/sunrpc/gss_api.h> | ||
15 | 16 | ||
16 | #include "idmap.h" | 17 | #include "idmap.h" |
17 | #include "nfsd.h" | 18 | #include "nfsd.h" |
18 | #include "cache.h" | 19 | #include "cache.h" |
19 | 20 | ||
20 | /* | 21 | /* |
21 | * We have a single directory with 9 nodes in it. | 22 | * We have a single directory with several nodes in it. |
22 | */ | 23 | */ |
23 | enum { | 24 | enum { |
24 | NFSD_Root = 1, | 25 | NFSD_Root = 1, |
@@ -42,6 +43,7 @@ enum { | |||
42 | NFSD_Versions, | 43 | NFSD_Versions, |
43 | NFSD_Ports, | 44 | NFSD_Ports, |
44 | NFSD_MaxBlkSize, | 45 | NFSD_MaxBlkSize, |
46 | NFSD_SupportedEnctypes, | ||
45 | /* | 47 | /* |
46 | * The below MUST come last. Otherwise we leave a hole in nfsd_files[] | 48 | * The below MUST come last. Otherwise we leave a hole in nfsd_files[] |
47 | * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops | 49 | * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops |
@@ -187,6 +189,34 @@ static struct file_operations export_features_operations = { | |||
187 | .release = single_release, | 189 | .release = single_release, |
188 | }; | 190 | }; |
189 | 191 | ||
192 | #ifdef CONFIG_SUNRPC_GSS | ||
193 | static int supported_enctypes_show(struct seq_file *m, void *v) | ||
194 | { | ||
195 | struct gss_api_mech *k5mech; | ||
196 | |||
197 | k5mech = gss_mech_get_by_name("krb5"); | ||
198 | if (k5mech == NULL) | ||
199 | goto out; | ||
200 | if (k5mech->gm_upcall_enctypes != NULL) | ||
201 | seq_printf(m, k5mech->gm_upcall_enctypes); | ||
202 | gss_mech_put(k5mech); | ||
203 | out: | ||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | static int supported_enctypes_open(struct inode *inode, struct file *file) | ||
208 | { | ||
209 | return single_open(file, supported_enctypes_show, NULL); | ||
210 | } | ||
211 | |||
212 | static struct file_operations supported_enctypes_ops = { | ||
213 | .open = supported_enctypes_open, | ||
214 | .read = seq_read, | ||
215 | .llseek = seq_lseek, | ||
216 | .release = single_release, | ||
217 | }; | ||
218 | #endif /* CONFIG_SUNRPC_GSS */ | ||
219 | |||
190 | extern int nfsd_pool_stats_open(struct inode *inode, struct file *file); | 220 | extern int nfsd_pool_stats_open(struct inode *inode, struct file *file); |
191 | extern int nfsd_pool_stats_release(struct inode *inode, struct file *file); | 221 | extern int nfsd_pool_stats_release(struct inode *inode, struct file *file); |
192 | 222 | ||
@@ -1397,6 +1427,9 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent) | |||
1397 | [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR}, | 1427 | [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR}, |
1398 | [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO}, | 1428 | [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO}, |
1399 | [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO}, | 1429 | [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO}, |
1430 | #ifdef CONFIG_SUNRPC_GSS | ||
1431 | [NFSD_SupportedEnctypes] = {"supported_krb5_enctypes", &supported_enctypes_ops, S_IRUGO}, | ||
1432 | #endif /* CONFIG_SUNRPC_GSS */ | ||
1400 | #ifdef CONFIG_NFSD_V4 | 1433 | #ifdef CONFIG_NFSD_V4 |
1401 | [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, | 1434 | [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, |
1402 | [NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR}, | 1435 | [NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR}, |
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c index 4ce005dbf3e6..65ec595e2226 100644 --- a/fs/nfsd/nfsxdr.c +++ b/fs/nfsd/nfsxdr.c | |||
@@ -451,7 +451,7 @@ nfssvc_encode_readres(struct svc_rqst *rqstp, __be32 *p, | |||
451 | *p++ = htonl(resp->count); | 451 | *p++ = htonl(resp->count); |
452 | xdr_ressize_check(rqstp, p); | 452 | xdr_ressize_check(rqstp, p); |
453 | 453 | ||
454 | /* now update rqstp->rq_res to reflect data aswell */ | 454 | /* now update rqstp->rq_res to reflect data as well */ |
455 | rqstp->rq_res.page_len = resp->count; | 455 | rqstp->rq_res.page_len = resp->count; |
456 | if (resp->count & 3) { | 456 | if (resp->count & 3) { |
457 | /* need to pad the tail */ | 457 | /* need to pad the tail */ |
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 2d31224b07bf..6bd2f3c21f2b 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h | |||
@@ -367,16 +367,12 @@ struct nfs4_file { | |||
367 | struct list_head fi_delegations; | 367 | struct list_head fi_delegations; |
368 | /* One each for O_RDONLY, O_WRONLY, O_RDWR: */ | 368 | /* One each for O_RDONLY, O_WRONLY, O_RDWR: */ |
369 | struct file * fi_fds[3]; | 369 | struct file * fi_fds[3]; |
370 | /* One each for O_RDONLY, O_WRONLY: */ | ||
371 | atomic_t fi_access[2]; | ||
372 | /* | 370 | /* |
373 | * Each open stateid contributes 1 to either fi_readers or | 371 | * Each open or lock stateid contributes 1 to either |
374 | * fi_writers, or both, depending on the open mode. A | 372 | * fi_access[O_RDONLY], fi_access[O_WRONLY], or both, depending |
375 | * delegation also takes an fi_readers reference. Lock | 373 | * on open or lock mode: |
376 | * stateid's take none. | ||
377 | */ | 374 | */ |
378 | atomic_t fi_readers; | 375 | atomic_t fi_access[2]; |
379 | atomic_t fi_writers; | ||
380 | struct file *fi_deleg_file; | 376 | struct file *fi_deleg_file; |
381 | struct file_lock *fi_lease; | 377 | struct file_lock *fi_lease; |
382 | atomic_t fi_delegees; | 378 | atomic_t fi_delegees; |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index ff93025ae2f7..129f3c9f62d5 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -1363,7 +1363,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1363 | goto out; | 1363 | goto out; |
1364 | if (!(iap->ia_valid & ATTR_MODE)) | 1364 | if (!(iap->ia_valid & ATTR_MODE)) |
1365 | iap->ia_mode = 0; | 1365 | iap->ia_mode = 0; |
1366 | err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE); | 1366 | err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_EXEC); |
1367 | if (err) | 1367 | if (err) |
1368 | goto out; | 1368 | goto out; |
1369 | 1369 | ||
@@ -1385,6 +1385,13 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1385 | if (IS_ERR(dchild)) | 1385 | if (IS_ERR(dchild)) |
1386 | goto out_nfserr; | 1386 | goto out_nfserr; |
1387 | 1387 | ||
1388 | /* If file doesn't exist, check for permissions to create one */ | ||
1389 | if (!dchild->d_inode) { | ||
1390 | err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE); | ||
1391 | if (err) | ||
1392 | goto out; | ||
1393 | } | ||
1394 | |||
1388 | err = fh_compose(resfhp, fhp->fh_export, dchild, fhp); | 1395 | err = fh_compose(resfhp, fhp->fh_export, dchild, fhp); |
1389 | if (err) | 1396 | if (err) |
1390 | goto out; | 1397 | goto out; |
@@ -1749,8 +1756,6 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, | |||
1749 | if (host_err) | 1756 | if (host_err) |
1750 | goto out_drop_write; | 1757 | goto out_drop_write; |
1751 | } | 1758 | } |
1752 | if (host_err) | ||
1753 | goto out_drop_write; | ||
1754 | host_err = vfs_rename(fdir, odentry, tdir, ndentry); | 1759 | host_err = vfs_rename(fdir, odentry, tdir, ndentry); |
1755 | if (!host_err) { | 1760 | if (!host_err) { |
1756 | host_err = commit_metadata(tfhp); | 1761 | host_err = commit_metadata(tfhp); |