diff options
Diffstat (limited to 'fs/nfsd')
| -rw-r--r-- | fs/nfsd/export.c | 2 | ||||
| -rw-r--r-- | fs/nfsd/nfs4callback.c | 67 | ||||
| -rw-r--r-- | fs/nfsd/nfs4idmap.c | 4 | ||||
| -rw-r--r-- | fs/nfsd/nfs4proc.c | 8 | ||||
| -rw-r--r-- | fs/nfsd/nfs4recover.c | 21 | ||||
| -rw-r--r-- | fs/nfsd/nfs4state.c | 45 | ||||
| -rw-r--r-- | fs/nfsd/nfscache.c | 3 | ||||
| -rw-r--r-- | fs/nfsd/nfsctl.c | 1 | ||||
| -rw-r--r-- | fs/nfsd/nfsfh.c | 27 | ||||
| -rw-r--r-- | fs/nfsd/nfssvc.c | 1 | ||||
| -rw-r--r-- | fs/nfsd/stats.c | 10 | ||||
| -rw-r--r-- | fs/nfsd/vfs.c | 15 |
12 files changed, 106 insertions, 98 deletions
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 3eec30000f3f..01bc68c628ad 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c | |||
| @@ -126,7 +126,7 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen) | |||
| 126 | if (*ep) | 126 | if (*ep) |
| 127 | goto out; | 127 | goto out; |
| 128 | dprintk("found fsidtype %d\n", fsidtype); | 128 | dprintk("found fsidtype %d\n", fsidtype); |
| 129 | if (fsidtype > 2) | 129 | if (key_len(fsidtype)==0) /* invalid type */ |
| 130 | goto out; | 130 | goto out; |
| 131 | if ((len=qword_get(&mesg, buf, PAGE_SIZE)) <= 0) | 131 | if ((len=qword_get(&mesg, buf, PAGE_SIZE)) <= 0) |
| 132 | goto out; | 132 | goto out; |
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index dbaf3f93f328..8583d99ee740 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c | |||
| @@ -33,7 +33,6 @@ | |||
| 33 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 33 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 34 | */ | 34 | */ |
| 35 | 35 | ||
| 36 | #include <linux/config.h> | ||
| 37 | #include <linux/module.h> | 36 | #include <linux/module.h> |
| 38 | #include <linux/list.h> | 37 | #include <linux/list.h> |
| 39 | #include <linux/inet.h> | 38 | #include <linux/inet.h> |
| @@ -376,16 +375,28 @@ nfsd4_probe_callback(struct nfs4_client *clp) | |||
| 376 | { | 375 | { |
| 377 | struct sockaddr_in addr; | 376 | struct sockaddr_in addr; |
| 378 | struct nfs4_callback *cb = &clp->cl_callback; | 377 | struct nfs4_callback *cb = &clp->cl_callback; |
| 379 | struct rpc_timeout timeparms; | 378 | struct rpc_timeout timeparms = { |
| 380 | struct rpc_xprt * xprt; | 379 | .to_initval = (NFSD_LEASE_TIME/4) * HZ, |
| 380 | .to_retries = 5, | ||
| 381 | .to_maxval = (NFSD_LEASE_TIME/2) * HZ, | ||
| 382 | .to_exponential = 1, | ||
| 383 | }; | ||
| 381 | struct rpc_program * program = &cb->cb_program; | 384 | struct rpc_program * program = &cb->cb_program; |
| 382 | struct rpc_stat * stat = &cb->cb_stat; | 385 | struct rpc_create_args args = { |
| 383 | struct rpc_clnt * clnt; | 386 | .protocol = IPPROTO_TCP, |
| 387 | .address = (struct sockaddr *)&addr, | ||
| 388 | .addrsize = sizeof(addr), | ||
| 389 | .timeout = &timeparms, | ||
| 390 | .servername = clp->cl_name.data, | ||
| 391 | .program = program, | ||
| 392 | .version = nfs_cb_version[1]->number, | ||
| 393 | .authflavor = RPC_AUTH_UNIX, /* XXX: need AUTH_GSS... */ | ||
| 394 | .flags = (RPC_CLNT_CREATE_NOPING), | ||
| 395 | }; | ||
| 384 | struct rpc_message msg = { | 396 | struct rpc_message msg = { |
| 385 | .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL], | 397 | .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL], |
| 386 | .rpc_argp = clp, | 398 | .rpc_argp = clp, |
| 387 | }; | 399 | }; |
| 388 | char hostname[32]; | ||
| 389 | int status; | 400 | int status; |
| 390 | 401 | ||
| 391 | if (atomic_read(&cb->cb_set)) | 402 | if (atomic_read(&cb->cb_set)) |
| @@ -397,51 +408,27 @@ nfsd4_probe_callback(struct nfs4_client *clp) | |||
| 397 | addr.sin_port = htons(cb->cb_port); | 408 | addr.sin_port = htons(cb->cb_port); |
| 398 | addr.sin_addr.s_addr = htonl(cb->cb_addr); | 409 | addr.sin_addr.s_addr = htonl(cb->cb_addr); |
| 399 | 410 | ||
| 400 | /* Initialize timeout */ | ||
| 401 | timeparms.to_initval = (NFSD_LEASE_TIME/4) * HZ; | ||
| 402 | timeparms.to_retries = 0; | ||
| 403 | timeparms.to_maxval = (NFSD_LEASE_TIME/2) * HZ; | ||
| 404 | timeparms.to_exponential = 1; | ||
| 405 | |||
| 406 | /* Create RPC transport */ | ||
| 407 | xprt = xprt_create_proto(IPPROTO_TCP, &addr, &timeparms); | ||
| 408 | if (IS_ERR(xprt)) { | ||
| 409 | dprintk("NFSD: couldn't create callback transport!\n"); | ||
| 410 | goto out_err; | ||
| 411 | } | ||
| 412 | |||
| 413 | /* Initialize rpc_program */ | 411 | /* Initialize rpc_program */ |
| 414 | program->name = "nfs4_cb"; | 412 | program->name = "nfs4_cb"; |
| 415 | program->number = cb->cb_prog; | 413 | program->number = cb->cb_prog; |
| 416 | program->nrvers = ARRAY_SIZE(nfs_cb_version); | 414 | program->nrvers = ARRAY_SIZE(nfs_cb_version); |
| 417 | program->version = nfs_cb_version; | 415 | program->version = nfs_cb_version; |
| 418 | program->stats = stat; | 416 | program->stats = &cb->cb_stat; |
| 419 | 417 | ||
| 420 | /* Initialize rpc_stat */ | 418 | /* Initialize rpc_stat */ |
| 421 | memset(stat, 0, sizeof(struct rpc_stat)); | 419 | memset(program->stats, 0, sizeof(cb->cb_stat)); |
| 422 | stat->program = program; | 420 | program->stats->program = program; |
| 423 | 421 | ||
| 424 | /* Create RPC client | 422 | /* Create RPC client */ |
| 425 | * | 423 | cb->cb_client = rpc_create(&args); |
| 426 | * XXX AUTH_UNIX only - need AUTH_GSS.... | 424 | if (!cb->cb_client) { |
| 427 | */ | ||
| 428 | sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(addr.sin_addr.s_addr)); | ||
| 429 | clnt = rpc_new_client(xprt, hostname, program, 1, RPC_AUTH_UNIX); | ||
| 430 | if (IS_ERR(clnt)) { | ||
| 431 | dprintk("NFSD: couldn't create callback client\n"); | 425 | dprintk("NFSD: couldn't create callback client\n"); |
| 432 | goto out_err; | 426 | goto out_err; |
| 433 | } | 427 | } |
| 434 | clnt->cl_intr = 0; | ||
| 435 | clnt->cl_softrtry = 1; | ||
| 436 | 428 | ||
| 437 | /* Kick rpciod, put the call on the wire. */ | 429 | /* Kick rpciod, put the call on the wire. */ |
| 438 | 430 | if (rpciod_up() != 0) | |
| 439 | if (rpciod_up() != 0) { | ||
| 440 | dprintk("nfsd: couldn't start rpciod for callbacks!\n"); | ||
| 441 | goto out_clnt; | 431 | goto out_clnt; |
| 442 | } | ||
| 443 | |||
| 444 | cb->cb_client = clnt; | ||
| 445 | 432 | ||
| 446 | /* the task holds a reference to the nfs4_client struct */ | 433 | /* the task holds a reference to the nfs4_client struct */ |
| 447 | atomic_inc(&clp->cl_count); | 434 | atomic_inc(&clp->cl_count); |
| @@ -449,7 +436,7 @@ nfsd4_probe_callback(struct nfs4_client *clp) | |||
| 449 | msg.rpc_cred = nfsd4_lookupcred(clp,0); | 436 | msg.rpc_cred = nfsd4_lookupcred(clp,0); |
| 450 | if (IS_ERR(msg.rpc_cred)) | 437 | if (IS_ERR(msg.rpc_cred)) |
| 451 | goto out_rpciod; | 438 | goto out_rpciod; |
| 452 | status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, &nfs4_cb_null_ops, NULL); | 439 | status = rpc_call_async(cb->cb_client, &msg, RPC_TASK_ASYNC, &nfs4_cb_null_ops, NULL); |
| 453 | put_rpccred(msg.rpc_cred); | 440 | put_rpccred(msg.rpc_cred); |
| 454 | 441 | ||
| 455 | if (status != 0) { | 442 | if (status != 0) { |
| @@ -463,7 +450,7 @@ out_rpciod: | |||
| 463 | rpciod_down(); | 450 | rpciod_down(); |
| 464 | cb->cb_client = NULL; | 451 | cb->cb_client = NULL; |
| 465 | out_clnt: | 452 | out_clnt: |
| 466 | rpc_shutdown_client(clnt); | 453 | rpc_shutdown_client(cb->cb_client); |
| 467 | out_err: | 454 | out_err: |
| 468 | dprintk("NFSD: warning: no callback path to client %.*s\n", | 455 | dprintk("NFSD: warning: no callback path to client %.*s\n", |
| 469 | (int)clp->cl_name.len, clp->cl_name.data); | 456 | (int)clp->cl_name.len, clp->cl_name.data); |
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c index 4b6aa60dfceb..b1902ebaab41 100644 --- a/fs/nfsd/nfs4idmap.c +++ b/fs/nfsd/nfs4idmap.c | |||
| @@ -34,7 +34,6 @@ | |||
| 34 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 34 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 35 | */ | 35 | */ |
| 36 | 36 | ||
| 37 | #include <linux/config.h> | ||
| 38 | #include <linux/module.h> | 37 | #include <linux/module.h> |
| 39 | #include <linux/init.h> | 38 | #include <linux/init.h> |
| 40 | 39 | ||
| @@ -574,10 +573,9 @@ idmap_lookup(struct svc_rqst *rqstp, | |||
| 574 | struct idmap_defer_req *mdr; | 573 | struct idmap_defer_req *mdr; |
| 575 | int ret; | 574 | int ret; |
| 576 | 575 | ||
| 577 | mdr = kmalloc(sizeof(*mdr), GFP_KERNEL); | 576 | mdr = kzalloc(sizeof(*mdr), GFP_KERNEL); |
| 578 | if (!mdr) | 577 | if (!mdr) |
| 579 | return -ENOMEM; | 578 | return -ENOMEM; |
| 580 | memset(mdr, 0, sizeof(*mdr)); | ||
| 581 | atomic_set(&mdr->count, 1); | 579 | atomic_set(&mdr->count, 1); |
| 582 | init_waitqueue_head(&mdr->waitq); | 580 | init_waitqueue_head(&mdr->waitq); |
| 583 | mdr->req.defer = idmap_defer; | 581 | mdr->req.defer = idmap_defer; |
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index b0e095ea0c03..ee4eff27aedc 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
| @@ -721,6 +721,12 @@ nfsd4_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) | |||
| 721 | return nfs_ok; | 721 | return nfs_ok; |
| 722 | } | 722 | } |
| 723 | 723 | ||
| 724 | static inline void nfsd4_increment_op_stats(u32 opnum) | ||
| 725 | { | ||
| 726 | if (opnum >= FIRST_NFS4_OP && opnum <= LAST_NFS4_OP) | ||
| 727 | nfsdstats.nfs4_opcount[opnum]++; | ||
| 728 | } | ||
| 729 | |||
| 724 | 730 | ||
| 725 | /* | 731 | /* |
| 726 | * COMPOUND call. | 732 | * COMPOUND call. |
| @@ -930,6 +936,8 @@ encode_op: | |||
| 930 | /* XXX Ugh, we need to get rid of this kind of special case: */ | 936 | /* XXX Ugh, we need to get rid of this kind of special case: */ |
| 931 | if (op->opnum == OP_READ && op->u.read.rd_filp) | 937 | if (op->opnum == OP_READ && op->u.read.rd_filp) |
| 932 | fput(op->u.read.rd_filp); | 938 | fput(op->u.read.rd_filp); |
| 939 | |||
| 940 | nfsd4_increment_op_stats(op->opnum); | ||
| 933 | } | 941 | } |
| 934 | 942 | ||
| 935 | out: | 943 | out: |
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index 06da7506363c..e35d7e52fdeb 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c | |||
| @@ -33,7 +33,7 @@ | |||
| 33 | * | 33 | * |
| 34 | */ | 34 | */ |
| 35 | 35 | ||
| 36 | 36 | #include <linux/err.h> | |
| 37 | #include <linux/sunrpc/svc.h> | 37 | #include <linux/sunrpc/svc.h> |
| 38 | #include <linux/nfsd/nfsd.h> | 38 | #include <linux/nfsd/nfsd.h> |
| 39 | #include <linux/nfs4.h> | 39 | #include <linux/nfs4.h> |
| @@ -87,34 +87,35 @@ int | |||
| 87 | nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname) | 87 | nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname) |
| 88 | { | 88 | { |
| 89 | struct xdr_netobj cksum; | 89 | struct xdr_netobj cksum; |
| 90 | struct crypto_tfm *tfm; | 90 | struct hash_desc desc; |
| 91 | struct scatterlist sg[1]; | 91 | struct scatterlist sg[1]; |
| 92 | int status = nfserr_resource; | 92 | int status = nfserr_resource; |
| 93 | 93 | ||
| 94 | dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n", | 94 | dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n", |
| 95 | clname->len, clname->data); | 95 | clname->len, clname->data); |
| 96 | tfm = crypto_alloc_tfm("md5", CRYPTO_TFM_REQ_MAY_SLEEP); | 96 | desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; |
| 97 | if (tfm == NULL) | 97 | desc.tfm = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC); |
| 98 | goto out; | 98 | if (IS_ERR(desc.tfm)) |
| 99 | cksum.len = crypto_tfm_alg_digestsize(tfm); | 99 | goto out_no_tfm; |
| 100 | cksum.len = crypto_hash_digestsize(desc.tfm); | ||
| 100 | cksum.data = kmalloc(cksum.len, GFP_KERNEL); | 101 | cksum.data = kmalloc(cksum.len, GFP_KERNEL); |
| 101 | if (cksum.data == NULL) | 102 | if (cksum.data == NULL) |
| 102 | goto out; | 103 | goto out; |
| 103 | crypto_digest_init(tfm); | ||
| 104 | 104 | ||
| 105 | sg[0].page = virt_to_page(clname->data); | 105 | sg[0].page = virt_to_page(clname->data); |
| 106 | sg[0].offset = offset_in_page(clname->data); | 106 | sg[0].offset = offset_in_page(clname->data); |
| 107 | sg[0].length = clname->len; | 107 | sg[0].length = clname->len; |
| 108 | 108 | ||
| 109 | crypto_digest_update(tfm, sg, 1); | 109 | if (crypto_hash_digest(&desc, sg, sg->length, cksum.data)) |
| 110 | crypto_digest_final(tfm, cksum.data); | 110 | goto out; |
| 111 | 111 | ||
| 112 | md5_to_hex(dname, cksum.data); | 112 | md5_to_hex(dname, cksum.data); |
| 113 | 113 | ||
| 114 | kfree(cksum.data); | 114 | kfree(cksum.data); |
| 115 | status = nfs_ok; | 115 | status = nfs_ok; |
| 116 | out: | 116 | out: |
| 117 | crypto_free_tfm(tfm); | 117 | crypto_free_hash(desc.tfm); |
| 118 | out_no_tfm: | ||
| 118 | return status; | 119 | return status; |
| 119 | } | 120 | } |
| 120 | 121 | ||
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 96c7578cbe1e..ebcf226a9e4a 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
| @@ -123,7 +123,7 @@ static void release_stateid(struct nfs4_stateid *stp, int flags); | |||
| 123 | */ | 123 | */ |
| 124 | 124 | ||
| 125 | /* recall_lock protects the del_recall_lru */ | 125 | /* recall_lock protects the del_recall_lru */ |
| 126 | static spinlock_t recall_lock = SPIN_LOCK_UNLOCKED; | 126 | static DEFINE_SPINLOCK(recall_lock); |
| 127 | static struct list_head del_recall_lru; | 127 | static struct list_head del_recall_lru; |
| 128 | 128 | ||
| 129 | static void | 129 | static void |
| @@ -339,8 +339,7 @@ alloc_client(struct xdr_netobj name) | |||
| 339 | { | 339 | { |
| 340 | struct nfs4_client *clp; | 340 | struct nfs4_client *clp; |
| 341 | 341 | ||
| 342 | if ((clp = kmalloc(sizeof(struct nfs4_client), GFP_KERNEL))!= NULL) { | 342 | if ((clp = kzalloc(sizeof(struct nfs4_client), GFP_KERNEL))!= NULL) { |
| 343 | memset(clp, 0, sizeof(*clp)); | ||
| 344 | if ((clp->cl_name.data = kmalloc(name.len, GFP_KERNEL)) != NULL) { | 343 | if ((clp->cl_name.data = kmalloc(name.len, GFP_KERNEL)) != NULL) { |
| 345 | memcpy(clp->cl_name.data, name.data, name.len); | 344 | memcpy(clp->cl_name.data, name.data, name.len); |
| 346 | clp->cl_name.len = name.len; | 345 | clp->cl_name.len = name.len; |
| @@ -529,8 +528,7 @@ move_to_confirmed(struct nfs4_client *clp) | |||
| 529 | 528 | ||
| 530 | dprintk("NFSD: move_to_confirm nfs4_client %p\n", clp); | 529 | dprintk("NFSD: move_to_confirm nfs4_client %p\n", clp); |
| 531 | list_del_init(&clp->cl_strhash); | 530 | list_del_init(&clp->cl_strhash); |
| 532 | list_del_init(&clp->cl_idhash); | 531 | list_move(&clp->cl_idhash, &conf_id_hashtbl[idhashval]); |
| 533 | list_add(&clp->cl_idhash, &conf_id_hashtbl[idhashval]); | ||
| 534 | strhashval = clientstr_hashval(clp->cl_recdir); | 532 | strhashval = clientstr_hashval(clp->cl_recdir); |
| 535 | list_add(&clp->cl_strhash, &conf_str_hashtbl[strhashval]); | 533 | list_add(&clp->cl_strhash, &conf_str_hashtbl[strhashval]); |
| 536 | renew_client(clp); | 534 | renew_client(clp); |
| @@ -1007,13 +1005,10 @@ alloc_init_file(struct inode *ino) | |||
| 1007 | static void | 1005 | static void |
| 1008 | nfsd4_free_slab(kmem_cache_t **slab) | 1006 | nfsd4_free_slab(kmem_cache_t **slab) |
| 1009 | { | 1007 | { |
| 1010 | int status; | ||
| 1011 | |||
| 1012 | if (*slab == NULL) | 1008 | if (*slab == NULL) |
| 1013 | return; | 1009 | return; |
| 1014 | status = kmem_cache_destroy(*slab); | 1010 | kmem_cache_destroy(*slab); |
| 1015 | *slab = NULL; | 1011 | *slab = NULL; |
| 1016 | WARN_ON(status); | ||
| 1017 | } | 1012 | } |
| 1018 | 1013 | ||
| 1019 | static void | 1014 | static void |
| @@ -1238,8 +1233,15 @@ find_file(struct inode *ino) | |||
| 1238 | return NULL; | 1233 | return NULL; |
| 1239 | } | 1234 | } |
| 1240 | 1235 | ||
| 1241 | #define TEST_ACCESS(x) ((x > 0 || x < 4)?1:0) | 1236 | static int access_valid(u32 x) |
| 1242 | #define TEST_DENY(x) ((x >= 0 || x < 5)?1:0) | 1237 | { |
| 1238 | return (x > 0 && x < 4); | ||
| 1239 | } | ||
| 1240 | |||
| 1241 | static int deny_valid(u32 x) | ||
| 1242 | { | ||
| 1243 | return (x >= 0 && x < 5); | ||
| 1244 | } | ||
| 1243 | 1245 | ||
| 1244 | static void | 1246 | static void |
| 1245 | set_access(unsigned int *access, unsigned long bmap) { | 1247 | set_access(unsigned int *access, unsigned long bmap) { |
| @@ -1746,7 +1748,8 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf | |||
| 1746 | int status; | 1748 | int status; |
| 1747 | 1749 | ||
| 1748 | status = nfserr_inval; | 1750 | status = nfserr_inval; |
| 1749 | if (!TEST_ACCESS(open->op_share_access) || !TEST_DENY(open->op_share_deny)) | 1751 | if (!access_valid(open->op_share_access) |
| 1752 | || !deny_valid(open->op_share_deny)) | ||
| 1750 | goto out; | 1753 | goto out; |
| 1751 | /* | 1754 | /* |
| 1752 | * Lookup file; if found, lookup stateid and check open request, | 1755 | * Lookup file; if found, lookup stateid and check open request, |
| @@ -1783,10 +1786,10 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf | |||
| 1783 | } else { | 1786 | } else { |
| 1784 | /* Stateid was not found, this is a new OPEN */ | 1787 | /* Stateid was not found, this is a new OPEN */ |
| 1785 | int flags = 0; | 1788 | int flags = 0; |
| 1789 | if (open->op_share_access & NFS4_SHARE_ACCESS_READ) | ||
| 1790 | flags |= MAY_READ; | ||
| 1786 | if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) | 1791 | if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) |
| 1787 | flags = MAY_WRITE; | 1792 | flags |= MAY_WRITE; |
| 1788 | else | ||
| 1789 | flags = MAY_READ; | ||
| 1790 | status = nfs4_new_open(rqstp, &stp, dp, current_fh, flags); | 1793 | status = nfs4_new_open(rqstp, &stp, dp, current_fh, flags); |
| 1791 | if (status) | 1794 | if (status) |
| 1792 | goto out; | 1795 | goto out; |
| @@ -2071,16 +2074,12 @@ nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int fl | |||
| 2071 | if (!stateid->si_fileid) { /* delegation stateid */ | 2074 | if (!stateid->si_fileid) { /* delegation stateid */ |
| 2072 | if(!(dp = find_delegation_stateid(ino, stateid))) { | 2075 | if(!(dp = find_delegation_stateid(ino, stateid))) { |
| 2073 | dprintk("NFSD: delegation stateid not found\n"); | 2076 | dprintk("NFSD: delegation stateid not found\n"); |
| 2074 | if (nfs4_in_grace()) | ||
| 2075 | status = nfserr_grace; | ||
| 2076 | goto out; | 2077 | goto out; |
| 2077 | } | 2078 | } |
| 2078 | stidp = &dp->dl_stateid; | 2079 | stidp = &dp->dl_stateid; |
| 2079 | } else { /* open or lock stateid */ | 2080 | } else { /* open or lock stateid */ |
| 2080 | if (!(stp = find_stateid(stateid, flags))) { | 2081 | if (!(stp = find_stateid(stateid, flags))) { |
| 2081 | dprintk("NFSD: open or lock stateid not found\n"); | 2082 | dprintk("NFSD: open or lock stateid not found\n"); |
| 2082 | if (nfs4_in_grace()) | ||
| 2083 | status = nfserr_grace; | ||
| 2084 | goto out; | 2083 | goto out; |
| 2085 | } | 2084 | } |
| 2086 | if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp)) | 2085 | if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp)) |
| @@ -2253,8 +2252,9 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfs | |||
| 2253 | (int)current_fh->fh_dentry->d_name.len, | 2252 | (int)current_fh->fh_dentry->d_name.len, |
| 2254 | current_fh->fh_dentry->d_name.name); | 2253 | current_fh->fh_dentry->d_name.name); |
| 2255 | 2254 | ||
| 2256 | if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0))) | 2255 | status = fh_verify(rqstp, current_fh, S_IFREG, 0); |
| 2257 | goto out; | 2256 | if (status) |
| 2257 | return status; | ||
| 2258 | 2258 | ||
| 2259 | nfs4_lock_state(); | 2259 | nfs4_lock_state(); |
| 2260 | 2260 | ||
| @@ -2321,7 +2321,8 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct n | |||
| 2321 | (int)current_fh->fh_dentry->d_name.len, | 2321 | (int)current_fh->fh_dentry->d_name.len, |
| 2322 | current_fh->fh_dentry->d_name.name); | 2322 | current_fh->fh_dentry->d_name.name); |
| 2323 | 2323 | ||
| 2324 | if (!TEST_ACCESS(od->od_share_access) || !TEST_DENY(od->od_share_deny)) | 2324 | if (!access_valid(od->od_share_access) |
| 2325 | || !deny_valid(od->od_share_deny)) | ||
| 2325 | return nfserr_inval; | 2326 | return nfserr_inval; |
| 2326 | 2327 | ||
| 2327 | nfs4_lock_state(); | 2328 | nfs4_lock_state(); |
diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c index d852ebb538e3..fdf7cf3dfadc 100644 --- a/fs/nfsd/nfscache.c +++ b/fs/nfsd/nfscache.c | |||
| @@ -103,8 +103,7 @@ nfsd_cache_shutdown(void) | |||
| 103 | static void | 103 | static void |
| 104 | lru_put_end(struct svc_cacherep *rp) | 104 | lru_put_end(struct svc_cacherep *rp) |
| 105 | { | 105 | { |
| 106 | list_del(&rp->c_lru); | 106 | list_move_tail(&rp->c_lru, &lru_head); |
| 107 | list_add_tail(&rp->c_lru, &lru_head); | ||
| 108 | } | 107 | } |
| 109 | 108 | ||
| 110 | /* | 109 | /* |
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index a1810e6a93e5..7046ac9cf97f 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c | |||
| @@ -6,7 +6,6 @@ | |||
| 6 | * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> | 6 | * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/config.h> | ||
| 10 | #include <linux/module.h> | 9 | #include <linux/module.h> |
| 11 | 10 | ||
| 12 | #include <linux/linkage.h> | 11 | #include <linux/linkage.h> |
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 3f2ec2e6d06c..501d83884530 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c | |||
| @@ -188,11 +188,9 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
| 188 | } | 188 | } |
| 189 | 189 | ||
| 190 | /* Set user creds for this exportpoint */ | 190 | /* Set user creds for this exportpoint */ |
| 191 | error = nfsd_setuser(rqstp, exp); | 191 | error = nfserrno(nfsd_setuser(rqstp, exp)); |
| 192 | if (error) { | 192 | if (error) |
| 193 | error = nfserrno(error); | ||
| 194 | goto out; | 193 | goto out; |
| 195 | } | ||
| 196 | 194 | ||
| 197 | /* | 195 | /* |
| 198 | * Look up the dentry using the NFS file handle. | 196 | * Look up the dentry using the NFS file handle. |
| @@ -248,9 +246,18 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
| 248 | dprintk("nfsd: fh_verify - just checking\n"); | 246 | dprintk("nfsd: fh_verify - just checking\n"); |
| 249 | dentry = fhp->fh_dentry; | 247 | dentry = fhp->fh_dentry; |
| 250 | exp = fhp->fh_export; | 248 | exp = fhp->fh_export; |
| 249 | /* Set user creds for this exportpoint; necessary even | ||
| 250 | * in the "just checking" case because this may be a | ||
| 251 | * filehandle that was created by fh_compose, and that | ||
| 252 | * is about to be used in another nfsv4 compound | ||
| 253 | * operation */ | ||
| 254 | error = nfserrno(nfsd_setuser(rqstp, exp)); | ||
| 255 | if (error) | ||
| 256 | goto out; | ||
| 251 | } | 257 | } |
| 252 | cache_get(&exp->h); | 258 | cache_get(&exp->h); |
| 253 | 259 | ||
| 260 | |||
| 254 | error = nfsd_mode_check(rqstp, dentry->d_inode->i_mode, type); | 261 | error = nfsd_mode_check(rqstp, dentry->d_inode->i_mode, type); |
| 255 | if (error) | 262 | if (error) |
| 256 | goto out; | 263 | goto out; |
| @@ -312,8 +319,8 @@ int | |||
| 312 | fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, struct svc_fh *ref_fh) | 319 | fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, struct svc_fh *ref_fh) |
| 313 | { | 320 | { |
| 314 | /* ref_fh is a reference file handle. | 321 | /* ref_fh is a reference file handle. |
| 315 | * if it is non-null, then we should compose a filehandle which is | 322 | * if it is non-null and for the same filesystem, then we should compose |
| 316 | * of the same version, where possible. | 323 | * a filehandle which is of the same version, where possible. |
| 317 | * Currently, that means that if ref_fh->fh_handle.fh_version == 0xca | 324 | * Currently, that means that if ref_fh->fh_handle.fh_version == 0xca |
| 318 | * Then create a 32byte filehandle using nfs_fhbase_old | 325 | * Then create a 32byte filehandle using nfs_fhbase_old |
| 319 | * | 326 | * |
| @@ -332,7 +339,7 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st | |||
| 332 | parent->d_name.name, dentry->d_name.name, | 339 | parent->d_name.name, dentry->d_name.name, |
| 333 | (inode ? inode->i_ino : 0)); | 340 | (inode ? inode->i_ino : 0)); |
| 334 | 341 | ||
| 335 | if (ref_fh) { | 342 | if (ref_fh && ref_fh->fh_export == exp) { |
| 336 | ref_fh_version = ref_fh->fh_handle.fh_version; | 343 | ref_fh_version = ref_fh->fh_handle.fh_version; |
| 337 | if (ref_fh_version == 0xca) | 344 | if (ref_fh_version == 0xca) |
| 338 | ref_fh_fsid_type = 0; | 345 | ref_fh_fsid_type = 0; |
| @@ -461,7 +468,7 @@ fh_update(struct svc_fh *fhp) | |||
| 461 | } else { | 468 | } else { |
| 462 | int size; | 469 | int size; |
| 463 | if (fhp->fh_handle.fh_fileid_type != 0) | 470 | if (fhp->fh_handle.fh_fileid_type != 0) |
| 464 | goto out_uptodate; | 471 | goto out; |
| 465 | datap = fhp->fh_handle.fh_auth+ | 472 | datap = fhp->fh_handle.fh_auth+ |
| 466 | fhp->fh_handle.fh_size/4 -1; | 473 | fhp->fh_handle.fh_size/4 -1; |
| 467 | size = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4; | 474 | size = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4; |
| @@ -481,10 +488,6 @@ out_negative: | |||
| 481 | printk(KERN_ERR "fh_update: %s/%s still negative!\n", | 488 | printk(KERN_ERR "fh_update: %s/%s still negative!\n", |
| 482 | dentry->d_parent->d_name.name, dentry->d_name.name); | 489 | dentry->d_parent->d_name.name, dentry->d_name.name); |
| 483 | goto out; | 490 | goto out; |
| 484 | out_uptodate: | ||
| 485 | printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n", | ||
| 486 | dentry->d_parent->d_name.name, dentry->d_name.name); | ||
| 487 | goto out; | ||
| 488 | } | 491 | } |
| 489 | 492 | ||
| 490 | /* | 493 | /* |
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 3790727e5dfd..ec1decf29bab 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c | |||
| @@ -8,7 +8,6 @@ | |||
| 8 | * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de> | 8 | * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de> |
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include <linux/config.h> | ||
| 12 | #include <linux/module.h> | 11 | #include <linux/module.h> |
| 13 | 12 | ||
| 14 | #include <linux/time.h> | 13 | #include <linux/time.h> |
diff --git a/fs/nfsd/stats.c b/fs/nfsd/stats.c index 57265d563804..71944cddf680 100644 --- a/fs/nfsd/stats.c +++ b/fs/nfsd/stats.c | |||
| @@ -72,6 +72,16 @@ static int nfsd_proc_show(struct seq_file *seq, void *v) | |||
| 72 | /* show my rpc info */ | 72 | /* show my rpc info */ |
| 73 | svc_seq_show(seq, &nfsd_svcstats); | 73 | svc_seq_show(seq, &nfsd_svcstats); |
| 74 | 74 | ||
| 75 | #ifdef CONFIG_NFSD_V4 | ||
| 76 | /* Show count for individual nfsv4 operations */ | ||
| 77 | /* Writing operation numbers 0 1 2 also for maintaining uniformity */ | ||
| 78 | seq_printf(seq,"proc4ops %u", LAST_NFS4_OP + 1); | ||
| 79 | for (i = 0; i <= LAST_NFS4_OP; i++) | ||
| 80 | seq_printf(seq, " %u", nfsdstats.nfs4_opcount[i]); | ||
| 81 | |||
| 82 | seq_putc(seq, '\n'); | ||
| 83 | #endif | ||
| 84 | |||
| 75 | return 0; | 85 | return 0; |
| 76 | } | 86 | } |
| 77 | 87 | ||
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 245eaa1fb59b..c9e3b5a8fe07 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
| @@ -16,7 +16,6 @@ | |||
| 16 | * Zerocpy NFS support (C) 2002 Hirokazu Takahashi <taka@valinux.co.jp> | 16 | * Zerocpy NFS support (C) 2002 Hirokazu Takahashi <taka@valinux.co.jp> |
| 17 | */ | 17 | */ |
| 18 | 18 | ||
| 19 | #include <linux/config.h> | ||
| 20 | #include <linux/string.h> | 19 | #include <linux/string.h> |
| 21 | #include <linux/time.h> | 20 | #include <linux/time.h> |
| 22 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
| @@ -673,7 +672,10 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, | |||
| 673 | goto out_nfserr; | 672 | goto out_nfserr; |
| 674 | 673 | ||
| 675 | if (access & MAY_WRITE) { | 674 | if (access & MAY_WRITE) { |
| 676 | flags = O_WRONLY|O_LARGEFILE; | 675 | if (access & MAY_READ) |
| 676 | flags = O_RDWR|O_LARGEFILE; | ||
| 677 | else | ||
| 678 | flags = O_WRONLY|O_LARGEFILE; | ||
| 677 | 679 | ||
| 678 | DQUOT_INIT(inode); | 680 | DQUOT_INIT(inode); |
| 679 | } | 681 | } |
| @@ -834,7 +836,7 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | |||
| 834 | if (ra && ra->p_set) | 836 | if (ra && ra->p_set) |
| 835 | file->f_ra = ra->p_ra; | 837 | file->f_ra = ra->p_ra; |
| 836 | 838 | ||
| 837 | if (file->f_op->sendfile) { | 839 | if (file->f_op->sendfile && rqstp->rq_sendfile_ok) { |
| 838 | svc_pushback_unused_pages(rqstp); | 840 | svc_pushback_unused_pages(rqstp); |
| 839 | err = file->f_op->sendfile(file, &offset, *count, | 841 | err = file->f_op->sendfile(file, &offset, *count, |
| 840 | nfsd_read_actor, rqstp); | 842 | nfsd_read_actor, rqstp); |
| @@ -1517,14 +1519,15 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, | |||
| 1517 | err = nfserrno(err); | 1519 | err = nfserrno(err); |
| 1518 | } | 1520 | } |
| 1519 | 1521 | ||
| 1520 | fh_unlock(ffhp); | ||
| 1521 | dput(dnew); | 1522 | dput(dnew); |
| 1523 | out_unlock: | ||
| 1524 | fh_unlock(ffhp); | ||
| 1522 | out: | 1525 | out: |
| 1523 | return err; | 1526 | return err; |
| 1524 | 1527 | ||
| 1525 | out_nfserr: | 1528 | out_nfserr: |
| 1526 | err = nfserrno(err); | 1529 | err = nfserrno(err); |
| 1527 | goto out; | 1530 | goto out_unlock; |
| 1528 | } | 1531 | } |
| 1529 | 1532 | ||
| 1530 | /* | 1533 | /* |
| @@ -1553,7 +1556,7 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, | |||
| 1553 | tdir = tdentry->d_inode; | 1556 | tdir = tdentry->d_inode; |
| 1554 | 1557 | ||
| 1555 | err = (rqstp->rq_vers == 2) ? nfserr_acces : nfserr_xdev; | 1558 | err = (rqstp->rq_vers == 2) ? nfserr_acces : nfserr_xdev; |
| 1556 | if (fdir->i_sb != tdir->i_sb) | 1559 | if (ffhp->fh_export != tfhp->fh_export) |
| 1557 | goto out; | 1560 | goto out; |
| 1558 | 1561 | ||
| 1559 | err = nfserr_perm; | 1562 | err = nfserr_perm; |
