diff options
-rw-r--r-- | fs/Kconfig | 2 | ||||
-rw-r--r-- | fs/nfs/callback_xdr.c | 10 | ||||
-rw-r--r-- | fs/nfs/dir.c | 8 | ||||
-rw-r--r-- | fs/nfs/nfs2xdr.c | 19 | ||||
-rw-r--r-- | fs/nfs/nfs3proc.c | 60 | ||||
-rw-r--r-- | fs/nfs/nfs3xdr.c | 24 | ||||
-rw-r--r-- | fs/nfs/nfs4_fs.h | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 122 | ||||
-rw-r--r-- | fs/nfs/nfs4xdr.c | 274 | ||||
-rw-r--r-- | fs/nfs/proc.c | 40 | ||||
-rw-r--r-- | fs/nfs/super.c | 7 | ||||
-rw-r--r-- | fs/nfs/unlink.c | 195 | ||||
-rw-r--r-- | include/linux/nfs_fs.h | 4 | ||||
-rw-r--r-- | include/linux/nfs_xdr.h | 32 | ||||
-rw-r--r-- | include/linux/sunrpc/xdr.h | 16 | ||||
-rw-r--r-- | net/sunrpc/auth.c | 13 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 21 |
17 files changed, 442 insertions, 407 deletions
diff --git a/fs/Kconfig b/fs/Kconfig index 6a649902c5ac..58a0650293e1 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -1674,7 +1674,7 @@ config NFSD_V3_ACL | |||
1674 | 1674 | ||
1675 | config NFSD_V4 | 1675 | config NFSD_V4 |
1676 | bool "Provide NFSv4 server support (EXPERIMENTAL)" | 1676 | bool "Provide NFSv4 server support (EXPERIMENTAL)" |
1677 | depends on NFSD_V3 && EXPERIMENTAL | 1677 | depends on NFSD && NFSD_V3 && EXPERIMENTAL |
1678 | select RPCSEC_GSS_KRB5 | 1678 | select RPCSEC_GSS_KRB5 |
1679 | help | 1679 | help |
1680 | If you would like to include the NFSv4 server as well as the NFSv2 | 1680 | If you would like to include the NFSv4 server as well as the NFSv2 |
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index 849a2029975d..058ade7efe79 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c | |||
@@ -179,7 +179,7 @@ static __be32 decode_getattr_args(struct svc_rqst *rqstp, struct xdr_stream *xdr | |||
179 | args->addr = svc_addr_in(rqstp); | 179 | args->addr = svc_addr_in(rqstp); |
180 | status = decode_bitmap(xdr, args->bitmap); | 180 | status = decode_bitmap(xdr, args->bitmap); |
181 | out: | 181 | out: |
182 | dprintk("%s: exit with status = %d\n", __FUNCTION__, status); | 182 | dprintk("%s: exit with status = %d\n", __FUNCTION__, ntohl(status)); |
183 | return status; | 183 | return status; |
184 | } | 184 | } |
185 | 185 | ||
@@ -200,7 +200,7 @@ static __be32 decode_recall_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, | |||
200 | args->truncate = ntohl(*p); | 200 | args->truncate = ntohl(*p); |
201 | status = decode_fh(xdr, &args->fh); | 201 | status = decode_fh(xdr, &args->fh); |
202 | out: | 202 | out: |
203 | dprintk("%s: exit with status = %d\n", __FUNCTION__, status); | 203 | dprintk("%s: exit with status = %d\n", __FUNCTION__, ntohl(status)); |
204 | return status; | 204 | return status; |
205 | } | 205 | } |
206 | 206 | ||
@@ -349,7 +349,7 @@ static __be32 encode_getattr_res(struct svc_rqst *rqstp, struct xdr_stream *xdr, | |||
349 | status = encode_attr_mtime(xdr, res->bitmap, &res->mtime); | 349 | status = encode_attr_mtime(xdr, res->bitmap, &res->mtime); |
350 | *savep = htonl((unsigned int)((char *)xdr->p - (char *)(savep+1))); | 350 | *savep = htonl((unsigned int)((char *)xdr->p - (char *)(savep+1))); |
351 | out: | 351 | out: |
352 | dprintk("%s: exit with status = %d\n", __FUNCTION__, status); | 352 | dprintk("%s: exit with status = %d\n", __FUNCTION__, ntohl(status)); |
353 | return status; | 353 | return status; |
354 | } | 354 | } |
355 | 355 | ||
@@ -392,7 +392,7 @@ static __be32 process_op(struct svc_rqst *rqstp, | |||
392 | status = res; | 392 | status = res; |
393 | if (op->encode_res != NULL && status == 0) | 393 | if (op->encode_res != NULL && status == 0) |
394 | status = op->encode_res(rqstp, xdr_out, resp); | 394 | status = op->encode_res(rqstp, xdr_out, resp); |
395 | dprintk("%s: done, status = %d\n", __FUNCTION__, status); | 395 | dprintk("%s: done, status = %d\n", __FUNCTION__, ntohl(status)); |
396 | return status; | 396 | return status; |
397 | } | 397 | } |
398 | 398 | ||
@@ -431,7 +431,7 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r | |||
431 | } | 431 | } |
432 | *hdr_res.status = status; | 432 | *hdr_res.status = status; |
433 | *hdr_res.nops = htonl(nops); | 433 | *hdr_res.nops = htonl(nops); |
434 | dprintk("%s: done, status = %u\n", __FUNCTION__, status); | 434 | dprintk("%s: done, status = %u\n", __FUNCTION__, ntohl(status)); |
435 | return rpc_success; | 435 | return rpc_success; |
436 | } | 436 | } |
437 | 437 | ||
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 322141f4ab48..ea97408e423e 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -654,7 +654,7 @@ static int nfs_check_verifier(struct inode *dir, struct dentry *dentry) | |||
654 | 654 | ||
655 | if (IS_ROOT(dentry)) | 655 | if (IS_ROOT(dentry)) |
656 | return 1; | 656 | return 1; |
657 | verf = (unsigned long)dentry->d_fsdata; | 657 | verf = dentry->d_time; |
658 | if (nfs_caches_unstable(dir) | 658 | if (nfs_caches_unstable(dir) |
659 | || verf != NFS_I(dir)->cache_change_attribute) | 659 | || verf != NFS_I(dir)->cache_change_attribute) |
660 | return 0; | 660 | return 0; |
@@ -663,7 +663,7 @@ static int nfs_check_verifier(struct inode *dir, struct dentry *dentry) | |||
663 | 663 | ||
664 | static inline void nfs_set_verifier(struct dentry * dentry, unsigned long verf) | 664 | static inline void nfs_set_verifier(struct dentry * dentry, unsigned long verf) |
665 | { | 665 | { |
666 | dentry->d_fsdata = (void *)verf; | 666 | dentry->d_time = verf; |
667 | } | 667 | } |
668 | 668 | ||
669 | static void nfs_refresh_verifier(struct dentry * dentry, unsigned long verf) | 669 | static void nfs_refresh_verifier(struct dentry * dentry, unsigned long verf) |
@@ -869,7 +869,7 @@ static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode) | |||
869 | if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { | 869 | if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { |
870 | lock_kernel(); | 870 | lock_kernel(); |
871 | drop_nlink(inode); | 871 | drop_nlink(inode); |
872 | nfs_complete_unlink(dentry); | 872 | nfs_complete_unlink(dentry, inode); |
873 | unlock_kernel(); | 873 | unlock_kernel(); |
874 | } | 874 | } |
875 | /* When creating a negative dentry, we want to renew d_time */ | 875 | /* When creating a negative dentry, we want to renew d_time */ |
@@ -1411,7 +1411,7 @@ static int nfs_sillyrename(struct inode *dir, struct dentry *dentry) | |||
1411 | nfs_renew_times(dentry); | 1411 | nfs_renew_times(dentry); |
1412 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); | 1412 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); |
1413 | d_move(dentry, sdentry); | 1413 | d_move(dentry, sdentry); |
1414 | error = nfs_async_unlink(dentry); | 1414 | error = nfs_async_unlink(dir, dentry); |
1415 | /* If we return 0 we don't unlink */ | 1415 | /* If we return 0 we don't unlink */ |
1416 | } | 1416 | } |
1417 | dput(sdentry); | 1417 | dput(sdentry); |
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index 7fcc78f2aa71..c5fce7567200 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #define NFS_entry_sz (NFS_filename_sz+3) | 43 | #define NFS_entry_sz (NFS_filename_sz+3) |
44 | 44 | ||
45 | #define NFS_diropargs_sz (NFS_fhandle_sz+NFS_filename_sz) | 45 | #define NFS_diropargs_sz (NFS_fhandle_sz+NFS_filename_sz) |
46 | #define NFS_removeargs_sz (NFS_fhandle_sz+NFS_filename_sz) | ||
46 | #define NFS_sattrargs_sz (NFS_fhandle_sz+NFS_sattr_sz) | 47 | #define NFS_sattrargs_sz (NFS_fhandle_sz+NFS_sattr_sz) |
47 | #define NFS_readlinkargs_sz (NFS_fhandle_sz) | 48 | #define NFS_readlinkargs_sz (NFS_fhandle_sz) |
48 | #define NFS_readargs_sz (NFS_fhandle_sz+3) | 49 | #define NFS_readargs_sz (NFS_fhandle_sz+3) |
@@ -66,7 +67,7 @@ | |||
66 | * Common NFS XDR functions as inlines | 67 | * Common NFS XDR functions as inlines |
67 | */ | 68 | */ |
68 | static inline __be32 * | 69 | static inline __be32 * |
69 | xdr_encode_fhandle(__be32 *p, struct nfs_fh *fhandle) | 70 | xdr_encode_fhandle(__be32 *p, const struct nfs_fh *fhandle) |
70 | { | 71 | { |
71 | memcpy(p, fhandle->data, NFS2_FHSIZE); | 72 | memcpy(p, fhandle->data, NFS2_FHSIZE); |
72 | return p + XDR_QUADLEN(NFS2_FHSIZE); | 73 | return p + XDR_QUADLEN(NFS2_FHSIZE); |
@@ -204,7 +205,7 @@ nfs_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs_sattrargs *args) | |||
204 | 205 | ||
205 | /* | 206 | /* |
206 | * Encode directory ops argument | 207 | * Encode directory ops argument |
207 | * LOOKUP, REMOVE, RMDIR | 208 | * LOOKUP, RMDIR |
208 | */ | 209 | */ |
209 | static int | 210 | static int |
210 | nfs_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs_diropargs *args) | 211 | nfs_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs_diropargs *args) |
@@ -216,6 +217,18 @@ nfs_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs_diropargs *args) | |||
216 | } | 217 | } |
217 | 218 | ||
218 | /* | 219 | /* |
220 | * Encode REMOVE argument | ||
221 | */ | ||
222 | static int | ||
223 | nfs_xdr_removeargs(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs *args) | ||
224 | { | ||
225 | p = xdr_encode_fhandle(p, args->fh); | ||
226 | p = xdr_encode_array(p, args->name.name, args->name.len); | ||
227 | req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); | ||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | /* | ||
219 | * Arguments to a READ call. Since we read data directly into the page | 232 | * Arguments to a READ call. Since we read data directly into the page |
220 | * cache, we also set up the reply iovec here so that iov[1] points | 233 | * cache, we also set up the reply iovec here so that iov[1] points |
221 | * exactly to the page we want to fetch. | 234 | * exactly to the page we want to fetch. |
@@ -705,7 +718,7 @@ struct rpc_procinfo nfs_procedures[] = { | |||
705 | PROC(READ, readargs, readres, 3), | 718 | PROC(READ, readargs, readres, 3), |
706 | PROC(WRITE, writeargs, writeres, 4), | 719 | PROC(WRITE, writeargs, writeres, 4), |
707 | PROC(CREATE, createargs, diropres, 0), | 720 | PROC(CREATE, createargs, diropres, 0), |
708 | PROC(REMOVE, diropargs, stat, 0), | 721 | PROC(REMOVE, removeargs, stat, 0), |
709 | PROC(RENAME, renameargs, stat, 0), | 722 | PROC(RENAME, renameargs, stat, 0), |
710 | PROC(LINK, linkargs, stat, 0), | 723 | PROC(LINK, linkargs, stat, 0), |
711 | PROC(SYMLINK, symlinkargs, stat, 0), | 724 | PROC(SYMLINK, symlinkargs, stat, 0), |
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 814d886b6aa4..c7ca5d70870b 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c | |||
@@ -349,62 +349,42 @@ out: | |||
349 | static int | 349 | static int |
350 | nfs3_proc_remove(struct inode *dir, struct qstr *name) | 350 | nfs3_proc_remove(struct inode *dir, struct qstr *name) |
351 | { | 351 | { |
352 | struct nfs_fattr dir_attr; | 352 | struct nfs_removeargs arg = { |
353 | struct nfs3_diropargs arg = { | 353 | .fh = NFS_FH(dir), |
354 | .fh = NFS_FH(dir), | 354 | .name.len = name->len, |
355 | .name = name->name, | 355 | .name.name = name->name, |
356 | .len = name->len | ||
357 | }; | 356 | }; |
358 | struct rpc_message msg = { | 357 | struct nfs_removeres res; |
359 | .rpc_proc = &nfs3_procedures[NFS3PROC_REMOVE], | 358 | struct rpc_message msg = { |
360 | .rpc_argp = &arg, | 359 | .rpc_proc = &nfs3_procedures[NFS3PROC_REMOVE], |
361 | .rpc_resp = &dir_attr, | 360 | .rpc_argp = &arg, |
361 | .rpc_resp = &res, | ||
362 | }; | 362 | }; |
363 | int status; | 363 | int status; |
364 | 364 | ||
365 | dprintk("NFS call remove %s\n", name->name); | 365 | dprintk("NFS call remove %s\n", name->name); |
366 | nfs_fattr_init(&dir_attr); | 366 | nfs_fattr_init(&res.dir_attr); |
367 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); | 367 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); |
368 | nfs_post_op_update_inode(dir, &dir_attr); | 368 | nfs_post_op_update_inode(dir, &res.dir_attr); |
369 | dprintk("NFS reply remove: %d\n", status); | 369 | dprintk("NFS reply remove: %d\n", status); |
370 | return status; | 370 | return status; |
371 | } | 371 | } |
372 | 372 | ||
373 | static int | 373 | static void |
374 | nfs3_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir, struct qstr *name) | 374 | nfs3_proc_unlink_setup(struct rpc_message *msg, struct inode *dir) |
375 | { | 375 | { |
376 | struct unlinkxdr { | ||
377 | struct nfs3_diropargs arg; | ||
378 | struct nfs_fattr res; | ||
379 | } *ptr; | ||
380 | |||
381 | ptr = kmalloc(sizeof(*ptr), GFP_KERNEL); | ||
382 | if (!ptr) | ||
383 | return -ENOMEM; | ||
384 | ptr->arg.fh = NFS_FH(dir->d_inode); | ||
385 | ptr->arg.name = name->name; | ||
386 | ptr->arg.len = name->len; | ||
387 | nfs_fattr_init(&ptr->res); | ||
388 | msg->rpc_proc = &nfs3_procedures[NFS3PROC_REMOVE]; | 376 | msg->rpc_proc = &nfs3_procedures[NFS3PROC_REMOVE]; |
389 | msg->rpc_argp = &ptr->arg; | ||
390 | msg->rpc_resp = &ptr->res; | ||
391 | return 0; | ||
392 | } | 377 | } |
393 | 378 | ||
394 | static int | 379 | static int |
395 | nfs3_proc_unlink_done(struct dentry *dir, struct rpc_task *task) | 380 | nfs3_proc_unlink_done(struct rpc_task *task, struct inode *dir) |
396 | { | 381 | { |
397 | struct rpc_message *msg = &task->tk_msg; | 382 | struct nfs_removeres *res; |
398 | struct nfs_fattr *dir_attr; | 383 | if (nfs3_async_handle_jukebox(task, dir)) |
399 | 384 | return 0; | |
400 | if (nfs3_async_handle_jukebox(task, dir->d_inode)) | 385 | res = task->tk_msg.rpc_resp; |
401 | return 1; | 386 | nfs_post_op_update_inode(dir, &res->dir_attr); |
402 | if (msg->rpc_argp) { | 387 | return 1; |
403 | dir_attr = (struct nfs_fattr*)msg->rpc_resp; | ||
404 | nfs_post_op_update_inode(dir->d_inode, dir_attr); | ||
405 | kfree(msg->rpc_argp); | ||
406 | } | ||
407 | return 0; | ||
408 | } | 388 | } |
409 | 389 | ||
410 | static int | 390 | static int |
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index b4647a22f349..d9e08f0cf2a0 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c | |||
@@ -50,6 +50,7 @@ | |||
50 | 50 | ||
51 | #define NFS3_sattrargs_sz (NFS3_fh_sz+NFS3_sattr_sz+3) | 51 | #define NFS3_sattrargs_sz (NFS3_fh_sz+NFS3_sattr_sz+3) |
52 | #define NFS3_diropargs_sz (NFS3_fh_sz+NFS3_filename_sz) | 52 | #define NFS3_diropargs_sz (NFS3_fh_sz+NFS3_filename_sz) |
53 | #define NFS3_removeargs_sz (NFS3_fh_sz+NFS3_filename_sz) | ||
53 | #define NFS3_accessargs_sz (NFS3_fh_sz+1) | 54 | #define NFS3_accessargs_sz (NFS3_fh_sz+1) |
54 | #define NFS3_readlinkargs_sz (NFS3_fh_sz) | 55 | #define NFS3_readlinkargs_sz (NFS3_fh_sz) |
55 | #define NFS3_readargs_sz (NFS3_fh_sz+3) | 56 | #define NFS3_readargs_sz (NFS3_fh_sz+3) |
@@ -65,6 +66,7 @@ | |||
65 | 66 | ||
66 | #define NFS3_attrstat_sz (1+NFS3_fattr_sz) | 67 | #define NFS3_attrstat_sz (1+NFS3_fattr_sz) |
67 | #define NFS3_wccstat_sz (1+NFS3_wcc_data_sz) | 68 | #define NFS3_wccstat_sz (1+NFS3_wcc_data_sz) |
69 | #define NFS3_removeres_sz (NFS3_wccstat_sz) | ||
68 | #define NFS3_lookupres_sz (1+NFS3_fh_sz+(2 * NFS3_post_op_attr_sz)) | 70 | #define NFS3_lookupres_sz (1+NFS3_fh_sz+(2 * NFS3_post_op_attr_sz)) |
69 | #define NFS3_accessres_sz (1+NFS3_post_op_attr_sz+1) | 71 | #define NFS3_accessres_sz (1+NFS3_post_op_attr_sz+1) |
70 | #define NFS3_readlinkres_sz (1+NFS3_post_op_attr_sz+1) | 72 | #define NFS3_readlinkres_sz (1+NFS3_post_op_attr_sz+1) |
@@ -106,7 +108,7 @@ static struct { | |||
106 | * Common NFS XDR functions as inlines | 108 | * Common NFS XDR functions as inlines |
107 | */ | 109 | */ |
108 | static inline __be32 * | 110 | static inline __be32 * |
109 | xdr_encode_fhandle(__be32 *p, struct nfs_fh *fh) | 111 | xdr_encode_fhandle(__be32 *p, const struct nfs_fh *fh) |
110 | { | 112 | { |
111 | return xdr_encode_array(p, fh->data, fh->size); | 113 | return xdr_encode_array(p, fh->data, fh->size); |
112 | } | 114 | } |
@@ -300,6 +302,18 @@ nfs3_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs3_diropargs *args) | |||
300 | } | 302 | } |
301 | 303 | ||
302 | /* | 304 | /* |
305 | * Encode REMOVE argument | ||
306 | */ | ||
307 | static int | ||
308 | nfs3_xdr_removeargs(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs *args) | ||
309 | { | ||
310 | p = xdr_encode_fhandle(p, args->fh); | ||
311 | p = xdr_encode_array(p, args->name.name, args->name.len); | ||
312 | req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); | ||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | /* | ||
303 | * Encode access() argument | 317 | * Encode access() argument |
304 | */ | 318 | */ |
305 | static int | 319 | static int |
@@ -736,6 +750,12 @@ nfs3_xdr_wccstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) | |||
736 | return status; | 750 | return status; |
737 | } | 751 | } |
738 | 752 | ||
753 | static int | ||
754 | nfs3_xdr_removeres(struct rpc_rqst *req, __be32 *p, struct nfs_removeres *res) | ||
755 | { | ||
756 | return nfs3_xdr_wccstat(req, p, &res->dir_attr); | ||
757 | } | ||
758 | |||
739 | /* | 759 | /* |
740 | * Decode LOOKUP reply | 760 | * Decode LOOKUP reply |
741 | */ | 761 | */ |
@@ -1126,7 +1146,7 @@ struct rpc_procinfo nfs3_procedures[] = { | |||
1126 | PROC(MKDIR, mkdirargs, createres, 0), | 1146 | PROC(MKDIR, mkdirargs, createres, 0), |
1127 | PROC(SYMLINK, symlinkargs, createres, 0), | 1147 | PROC(SYMLINK, symlinkargs, createres, 0), |
1128 | PROC(MKNOD, mknodargs, createres, 0), | 1148 | PROC(MKNOD, mknodargs, createres, 0), |
1129 | PROC(REMOVE, diropargs, wccstat, 0), | 1149 | PROC(REMOVE, removeargs, removeres, 0), |
1130 | PROC(RMDIR, diropargs, wccstat, 0), | 1150 | PROC(RMDIR, diropargs, wccstat, 0), |
1131 | PROC(RENAME, renameargs, renameres, 0), | 1151 | PROC(RENAME, renameargs, renameres, 0), |
1132 | PROC(LINK, linkargs, linkres, 0), | 1152 | PROC(LINK, linkargs, linkres, 0), |
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 6c028e734fe6..d2802b1ca3b9 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h | |||
@@ -182,7 +182,7 @@ extern int nfs4_do_close(struct path *path, struct nfs4_state *state); | |||
182 | extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *); | 182 | extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *); |
183 | extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *); | 183 | extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *); |
184 | extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle); | 184 | extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle); |
185 | extern int nfs4_proc_fs_locations(struct inode *dir, struct qstr *name, | 185 | extern int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, |
186 | struct nfs4_fs_locations *fs_locations, struct page *page); | 186 | struct nfs4_fs_locations *fs_locations, struct page *page); |
187 | 187 | ||
188 | extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops; | 188 | extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops; |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index fee2da856c95..6ca2795ccd9c 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -66,6 +66,8 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry | |||
66 | static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception); | 66 | static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception); |
67 | static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client *clp); | 67 | static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client *clp); |
68 | static int _nfs4_do_access(struct inode *inode, struct rpc_cred *cred, int openflags); | 68 | static int _nfs4_do_access(struct inode *inode, struct rpc_cred *cred, int openflags); |
69 | static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr); | ||
70 | static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr); | ||
69 | 71 | ||
70 | /* Prevent leaks of NFSv4 errors into userland */ | 72 | /* Prevent leaks of NFSv4 errors into userland */ |
71 | int nfs4_map_errors(int err) | 73 | int nfs4_map_errors(int err) |
@@ -552,6 +554,18 @@ static struct nfs_open_context *nfs4_state_find_open_context(struct nfs4_state * | |||
552 | return ERR_PTR(-ENOENT); | 554 | return ERR_PTR(-ENOENT); |
553 | } | 555 | } |
554 | 556 | ||
557 | static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context *ctx, struct nfs4_state *state) | ||
558 | { | ||
559 | struct nfs4_opendata *opendata; | ||
560 | |||
561 | opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, NULL); | ||
562 | if (opendata == NULL) | ||
563 | return ERR_PTR(-ENOMEM); | ||
564 | opendata->state = state; | ||
565 | atomic_inc(&state->count); | ||
566 | return opendata; | ||
567 | } | ||
568 | |||
555 | static int nfs4_open_recover_helper(struct nfs4_opendata *opendata, mode_t openflags, struct nfs4_state **res) | 569 | static int nfs4_open_recover_helper(struct nfs4_opendata *opendata, mode_t openflags, struct nfs4_state **res) |
556 | { | 570 | { |
557 | struct nfs4_state *newstate; | 571 | struct nfs4_state *newstate; |
@@ -626,12 +640,11 @@ static int _nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state | |||
626 | int delegation_type = 0; | 640 | int delegation_type = 0; |
627 | int status; | 641 | int status; |
628 | 642 | ||
629 | opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, NULL); | 643 | opendata = nfs4_open_recoverdata_alloc(ctx, state); |
630 | if (opendata == NULL) | 644 | if (IS_ERR(opendata)) |
631 | return -ENOMEM; | 645 | return PTR_ERR(opendata); |
632 | opendata->o_arg.claim = NFS4_OPEN_CLAIM_PREVIOUS; | 646 | opendata->o_arg.claim = NFS4_OPEN_CLAIM_PREVIOUS; |
633 | opendata->o_arg.fh = NFS_FH(state->inode); | 647 | opendata->o_arg.fh = NFS_FH(state->inode); |
634 | nfs_copy_fh(&opendata->o_res.fh, opendata->o_arg.fh); | ||
635 | rcu_read_lock(); | 648 | rcu_read_lock(); |
636 | delegation = rcu_dereference(NFS_I(state->inode)->delegation); | 649 | delegation = rcu_dereference(NFS_I(state->inode)->delegation); |
637 | if (delegation != NULL && (delegation->flags & NFS_DELEGATION_NEED_RECLAIM) != 0) | 650 | if (delegation != NULL && (delegation->flags & NFS_DELEGATION_NEED_RECLAIM) != 0) |
@@ -672,13 +685,12 @@ static int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *sta | |||
672 | 685 | ||
673 | static int _nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid) | 686 | static int _nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid) |
674 | { | 687 | { |
675 | struct nfs4_state_owner *sp = state->owner; | ||
676 | struct nfs4_opendata *opendata; | 688 | struct nfs4_opendata *opendata; |
677 | int ret; | 689 | int ret; |
678 | 690 | ||
679 | opendata = nfs4_opendata_alloc(&ctx->path, sp, 0, NULL); | 691 | opendata = nfs4_open_recoverdata_alloc(ctx, state); |
680 | if (opendata == NULL) | 692 | if (IS_ERR(opendata)) |
681 | return -ENOMEM; | 693 | return PTR_ERR(opendata); |
682 | opendata->o_arg.claim = NFS4_OPEN_CLAIM_DELEGATE_CUR; | 694 | opendata->o_arg.claim = NFS4_OPEN_CLAIM_DELEGATE_CUR; |
683 | memcpy(opendata->o_arg.u.delegation.data, stateid->data, | 695 | memcpy(opendata->o_arg.u.delegation.data, stateid->data, |
684 | sizeof(opendata->o_arg.u.delegation.data)); | 696 | sizeof(opendata->o_arg.u.delegation.data)); |
@@ -823,8 +835,10 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata) | |||
823 | /* Update sequence id. */ | 835 | /* Update sequence id. */ |
824 | data->o_arg.id = sp->so_owner_id.id; | 836 | data->o_arg.id = sp->so_owner_id.id; |
825 | data->o_arg.clientid = sp->so_client->cl_clientid; | 837 | data->o_arg.clientid = sp->so_client->cl_clientid; |
826 | if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) | 838 | if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) { |
827 | msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR]; | 839 | msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR]; |
840 | nfs_copy_fh(&data->o_res.fh, data->o_arg.fh); | ||
841 | } | ||
828 | data->timestamp = jiffies; | 842 | data->timestamp = jiffies; |
829 | rpc_call_setup(task, &msg, 0); | 843 | rpc_call_setup(task, &msg, 0); |
830 | return; | 844 | return; |
@@ -918,6 +932,9 @@ static int _nfs4_proc_open(struct nfs4_opendata *data) | |||
918 | if (status != 0 || !data->rpc_done) | 932 | if (status != 0 || !data->rpc_done) |
919 | return status; | 933 | return status; |
920 | 934 | ||
935 | if (o_res->fh.size == 0) | ||
936 | _nfs4_proc_lookup(dir, o_arg->name, &o_res->fh, o_res->f_attr); | ||
937 | |||
921 | if (o_arg->open_flags & O_CREAT) { | 938 | if (o_arg->open_flags & O_CREAT) { |
922 | update_changeattr(dir, &o_res->cinfo); | 939 | update_changeattr(dir, &o_res->cinfo); |
923 | nfs_post_op_update_inode(dir, o_res->dir_attr); | 940 | nfs_post_op_update_inode(dir, o_res->dir_attr); |
@@ -929,7 +946,7 @@ static int _nfs4_proc_open(struct nfs4_opendata *data) | |||
929 | return status; | 946 | return status; |
930 | } | 947 | } |
931 | if (!(o_res->f_attr->valid & NFS_ATTR_FATTR)) | 948 | if (!(o_res->f_attr->valid & NFS_ATTR_FATTR)) |
932 | return server->nfs_client->rpc_ops->getattr(server, &o_res->fh, o_res->f_attr); | 949 | _nfs4_proc_getattr(server, &o_res->fh, o_res->f_attr); |
933 | return 0; | 950 | return 0; |
934 | } | 951 | } |
935 | 952 | ||
@@ -989,9 +1006,9 @@ static int _nfs4_open_expired(struct nfs_open_context *ctx, struct nfs4_state *s | |||
989 | struct nfs4_opendata *opendata; | 1006 | struct nfs4_opendata *opendata; |
990 | int ret; | 1007 | int ret; |
991 | 1008 | ||
992 | opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, NULL); | 1009 | opendata = nfs4_open_recoverdata_alloc(ctx, state); |
993 | if (opendata == NULL) | 1010 | if (IS_ERR(opendata)) |
994 | return -ENOMEM; | 1011 | return PTR_ERR(opendata); |
995 | ret = nfs4_open_recover(opendata, state); | 1012 | ret = nfs4_open_recover(opendata, state); |
996 | if (ret == -ESTALE) { | 1013 | if (ret == -ESTALE) { |
997 | /* Invalidate the state owner so we don't ever use it again */ | 1014 | /* Invalidate the state owner so we don't ever use it again */ |
@@ -1553,7 +1570,7 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, | |||
1553 | * Note that we'll actually follow the referral later when | 1570 | * Note that we'll actually follow the referral later when |
1554 | * we detect fsid mismatch in inode revalidation | 1571 | * we detect fsid mismatch in inode revalidation |
1555 | */ | 1572 | */ |
1556 | static int nfs4_get_referral(struct inode *dir, struct qstr *name, struct nfs_fattr *fattr, struct nfs_fh *fhandle) | 1573 | static int nfs4_get_referral(struct inode *dir, const struct qstr *name, struct nfs_fattr *fattr, struct nfs_fh *fhandle) |
1557 | { | 1574 | { |
1558 | int status = -ENOMEM; | 1575 | int status = -ENOMEM; |
1559 | struct page *page = NULL; | 1576 | struct page *page = NULL; |
@@ -1668,8 +1685,8 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr, | |||
1668 | return status; | 1685 | return status; |
1669 | } | 1686 | } |
1670 | 1687 | ||
1671 | static int _nfs4_proc_lookupfh(struct nfs_server *server, struct nfs_fh *dirfh, | 1688 | static int _nfs4_proc_lookupfh(struct nfs_server *server, const struct nfs_fh *dirfh, |
1672 | struct qstr *name, struct nfs_fh *fhandle, | 1689 | const struct qstr *name, struct nfs_fh *fhandle, |
1673 | struct nfs_fattr *fattr) | 1690 | struct nfs_fattr *fattr) |
1674 | { | 1691 | { |
1675 | int status; | 1692 | int status; |
@@ -1715,7 +1732,7 @@ static int nfs4_proc_lookupfh(struct nfs_server *server, struct nfs_fh *dirfh, | |||
1715 | return err; | 1732 | return err; |
1716 | } | 1733 | } |
1717 | 1734 | ||
1718 | static int _nfs4_proc_lookup(struct inode *dir, struct qstr *name, | 1735 | static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, |
1719 | struct nfs_fh *fhandle, struct nfs_fattr *fattr) | 1736 | struct nfs_fh *fhandle, struct nfs_fattr *fattr) |
1720 | { | 1737 | { |
1721 | int status; | 1738 | int status; |
@@ -1908,28 +1925,27 @@ out: | |||
1908 | static int _nfs4_proc_remove(struct inode *dir, struct qstr *name) | 1925 | static int _nfs4_proc_remove(struct inode *dir, struct qstr *name) |
1909 | { | 1926 | { |
1910 | struct nfs_server *server = NFS_SERVER(dir); | 1927 | struct nfs_server *server = NFS_SERVER(dir); |
1911 | struct nfs4_remove_arg args = { | 1928 | struct nfs_removeargs args = { |
1912 | .fh = NFS_FH(dir), | 1929 | .fh = NFS_FH(dir), |
1913 | .name = name, | 1930 | .name.len = name->len, |
1931 | .name.name = name->name, | ||
1914 | .bitmask = server->attr_bitmask, | 1932 | .bitmask = server->attr_bitmask, |
1915 | }; | 1933 | }; |
1916 | struct nfs_fattr dir_attr; | 1934 | struct nfs_removeres res = { |
1917 | struct nfs4_remove_res res = { | ||
1918 | .server = server, | 1935 | .server = server, |
1919 | .dir_attr = &dir_attr, | ||
1920 | }; | 1936 | }; |
1921 | struct rpc_message msg = { | 1937 | struct rpc_message msg = { |
1922 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE], | 1938 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE], |
1923 | .rpc_argp = &args, | 1939 | .rpc_argp = &args, |
1924 | .rpc_resp = &res, | 1940 | .rpc_resp = &res, |
1925 | }; | 1941 | }; |
1926 | int status; | 1942 | int status; |
1927 | 1943 | ||
1928 | nfs_fattr_init(res.dir_attr); | 1944 | nfs_fattr_init(&res.dir_attr); |
1929 | status = rpc_call_sync(server->client, &msg, 0); | 1945 | status = rpc_call_sync(server->client, &msg, 0); |
1930 | if (status == 0) { | 1946 | if (status == 0) { |
1931 | update_changeattr(dir, &res.cinfo); | 1947 | update_changeattr(dir, &res.cinfo); |
1932 | nfs_post_op_update_inode(dir, res.dir_attr); | 1948 | nfs_post_op_update_inode(dir, &res.dir_attr); |
1933 | } | 1949 | } |
1934 | return status; | 1950 | return status; |
1935 | } | 1951 | } |
@@ -1946,48 +1962,26 @@ static int nfs4_proc_remove(struct inode *dir, struct qstr *name) | |||
1946 | return err; | 1962 | return err; |
1947 | } | 1963 | } |
1948 | 1964 | ||
1949 | struct unlink_desc { | 1965 | static void nfs4_proc_unlink_setup(struct rpc_message *msg, struct inode *dir) |
1950 | struct nfs4_remove_arg args; | ||
1951 | struct nfs4_remove_res res; | ||
1952 | struct nfs_fattr dir_attr; | ||
1953 | }; | ||
1954 | |||
1955 | static int nfs4_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir, | ||
1956 | struct qstr *name) | ||
1957 | { | 1966 | { |
1958 | struct nfs_server *server = NFS_SERVER(dir->d_inode); | 1967 | struct nfs_server *server = NFS_SERVER(dir); |
1959 | struct unlink_desc *up; | 1968 | struct nfs_removeargs *args = msg->rpc_argp; |
1969 | struct nfs_removeres *res = msg->rpc_resp; | ||
1960 | 1970 | ||
1961 | up = kmalloc(sizeof(*up), GFP_KERNEL); | 1971 | args->bitmask = server->attr_bitmask; |
1962 | if (!up) | 1972 | res->server = server; |
1963 | return -ENOMEM; | ||
1964 | |||
1965 | up->args.fh = NFS_FH(dir->d_inode); | ||
1966 | up->args.name = name; | ||
1967 | up->args.bitmask = server->attr_bitmask; | ||
1968 | up->res.server = server; | ||
1969 | up->res.dir_attr = &up->dir_attr; | ||
1970 | |||
1971 | msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE]; | 1973 | msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE]; |
1972 | msg->rpc_argp = &up->args; | ||
1973 | msg->rpc_resp = &up->res; | ||
1974 | return 0; | ||
1975 | } | 1974 | } |
1976 | 1975 | ||
1977 | static int nfs4_proc_unlink_done(struct dentry *dir, struct rpc_task *task) | 1976 | static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir) |
1978 | { | 1977 | { |
1979 | struct rpc_message *msg = &task->tk_msg; | 1978 | struct nfs_removeres *res = task->tk_msg.rpc_resp; |
1980 | struct unlink_desc *up; | 1979 | |
1981 | 1980 | if (nfs4_async_handle_error(task, res->server) == -EAGAIN) | |
1982 | if (msg->rpc_resp != NULL) { | 1981 | return 0; |
1983 | up = container_of(msg->rpc_resp, struct unlink_desc, res); | 1982 | update_changeattr(dir, &res->cinfo); |
1984 | update_changeattr(dir->d_inode, &up->res.cinfo); | 1983 | nfs_post_op_update_inode(dir, &res->dir_attr); |
1985 | nfs_post_op_update_inode(dir->d_inode, up->res.dir_attr); | 1984 | return 1; |
1986 | kfree(up); | ||
1987 | msg->rpc_resp = NULL; | ||
1988 | msg->rpc_argp = NULL; | ||
1989 | } | ||
1990 | return 0; | ||
1991 | } | 1985 | } |
1992 | 1986 | ||
1993 | static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name, | 1987 | static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name, |
@@ -3672,7 +3666,7 @@ ssize_t nfs4_listxattr(struct dentry *dentry, char *buf, size_t buflen) | |||
3672 | return len; | 3666 | return len; |
3673 | } | 3667 | } |
3674 | 3668 | ||
3675 | int nfs4_proc_fs_locations(struct inode *dir, struct qstr *name, | 3669 | int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, |
3676 | struct nfs4_fs_locations *fs_locations, struct page *page) | 3670 | struct nfs4_fs_locations *fs_locations, struct page *page) |
3677 | { | 3671 | { |
3678 | struct nfs_server *server = NFS_SERVER(dir); | 3672 | struct nfs_server *server = NFS_SERVER(dir); |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index c08738441f73..badd73b7ca12 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -72,10 +72,15 @@ static int nfs4_stat_to_errno(int); | |||
72 | */ | 72 | */ |
73 | #define open_owner_id_maxsz (1 + 4) | 73 | #define open_owner_id_maxsz (1 + 4) |
74 | #define lock_owner_id_maxsz (1 + 4) | 74 | #define lock_owner_id_maxsz (1 + 4) |
75 | #define decode_lockowner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ)) | ||
75 | #define compound_encode_hdr_maxsz (3 + (NFS4_MAXTAGLEN >> 2)) | 76 | #define compound_encode_hdr_maxsz (3 + (NFS4_MAXTAGLEN >> 2)) |
76 | #define compound_decode_hdr_maxsz (3 + (NFS4_MAXTAGLEN >> 2)) | 77 | #define compound_decode_hdr_maxsz (3 + (NFS4_MAXTAGLEN >> 2)) |
77 | #define op_encode_hdr_maxsz (1) | 78 | #define op_encode_hdr_maxsz (1) |
78 | #define op_decode_hdr_maxsz (2) | 79 | #define op_decode_hdr_maxsz (2) |
80 | #define encode_stateid_maxsz (XDR_QUADLEN(NFS4_STATEID_SIZE)) | ||
81 | #define decode_stateid_maxsz (XDR_QUADLEN(NFS4_STATEID_SIZE)) | ||
82 | #define encode_verifier_maxsz (XDR_QUADLEN(NFS4_VERIFIER_SIZE)) | ||
83 | #define decode_verifier_maxsz (XDR_QUADLEN(NFS4_VERIFIER_SIZE)) | ||
79 | #define encode_putfh_maxsz (op_encode_hdr_maxsz + 1 + \ | 84 | #define encode_putfh_maxsz (op_encode_hdr_maxsz + 1 + \ |
80 | (NFS4_FHSIZE >> 2)) | 85 | (NFS4_FHSIZE >> 2)) |
81 | #define decode_putfh_maxsz (op_decode_hdr_maxsz) | 86 | #define decode_putfh_maxsz (op_decode_hdr_maxsz) |
@@ -96,6 +101,11 @@ static int nfs4_stat_to_errno(int); | |||
96 | #define nfs4_fattr_maxsz (nfs4_fattr_bitmap_maxsz + \ | 101 | #define nfs4_fattr_maxsz (nfs4_fattr_bitmap_maxsz + \ |
97 | nfs4_fattr_value_maxsz) | 102 | nfs4_fattr_value_maxsz) |
98 | #define decode_getattr_maxsz (op_decode_hdr_maxsz + nfs4_fattr_maxsz) | 103 | #define decode_getattr_maxsz (op_decode_hdr_maxsz + nfs4_fattr_maxsz) |
104 | #define encode_attrs_maxsz (nfs4_fattr_bitmap_maxsz + \ | ||
105 | 1 + 2 + 1 + \ | ||
106 | nfs4_owner_maxsz + \ | ||
107 | nfs4_group_maxsz + \ | ||
108 | 4 + 4) | ||
99 | #define encode_savefh_maxsz (op_encode_hdr_maxsz) | 109 | #define encode_savefh_maxsz (op_encode_hdr_maxsz) |
100 | #define decode_savefh_maxsz (op_decode_hdr_maxsz) | 110 | #define decode_savefh_maxsz (op_decode_hdr_maxsz) |
101 | #define encode_restorefh_maxsz (op_encode_hdr_maxsz) | 111 | #define encode_restorefh_maxsz (op_encode_hdr_maxsz) |
@@ -123,7 +133,7 @@ static int nfs4_stat_to_errno(int); | |||
123 | #define decode_lookup_maxsz (op_decode_hdr_maxsz) | 133 | #define decode_lookup_maxsz (op_decode_hdr_maxsz) |
124 | #define encode_share_access_maxsz \ | 134 | #define encode_share_access_maxsz \ |
125 | (2) | 135 | (2) |
126 | #define encode_createmode_maxsz (1 + nfs4_fattr_maxsz) | 136 | #define encode_createmode_maxsz (1 + encode_attrs_maxsz) |
127 | #define encode_opentype_maxsz (1 + encode_createmode_maxsz) | 137 | #define encode_opentype_maxsz (1 + encode_createmode_maxsz) |
128 | #define encode_claim_null_maxsz (1 + nfs4_name_maxsz) | 138 | #define encode_claim_null_maxsz (1 + nfs4_name_maxsz) |
129 | #define encode_open_maxsz (op_encode_hdr_maxsz + \ | 139 | #define encode_open_maxsz (op_encode_hdr_maxsz + \ |
@@ -132,14 +142,52 @@ static int nfs4_stat_to_errno(int); | |||
132 | encode_opentype_maxsz + \ | 142 | encode_opentype_maxsz + \ |
133 | encode_claim_null_maxsz) | 143 | encode_claim_null_maxsz) |
134 | #define decode_ace_maxsz (3 + nfs4_owner_maxsz) | 144 | #define decode_ace_maxsz (3 + nfs4_owner_maxsz) |
135 | #define decode_delegation_maxsz (1 + XDR_QUADLEN(NFS4_STATEID_SIZE) + 1 + \ | 145 | #define decode_delegation_maxsz (1 + decode_stateid_maxsz + 1 + \ |
136 | decode_ace_maxsz) | 146 | decode_ace_maxsz) |
137 | #define decode_change_info_maxsz (5) | 147 | #define decode_change_info_maxsz (5) |
138 | #define decode_open_maxsz (op_decode_hdr_maxsz + \ | 148 | #define decode_open_maxsz (op_decode_hdr_maxsz + \ |
139 | XDR_QUADLEN(NFS4_STATEID_SIZE) + \ | 149 | decode_stateid_maxsz + \ |
140 | decode_change_info_maxsz + 1 + \ | 150 | decode_change_info_maxsz + 1 + \ |
141 | nfs4_fattr_bitmap_maxsz + \ | 151 | nfs4_fattr_bitmap_maxsz + \ |
142 | decode_delegation_maxsz) | 152 | decode_delegation_maxsz) |
153 | #define encode_open_confirm_maxsz \ | ||
154 | (op_encode_hdr_maxsz + \ | ||
155 | encode_stateid_maxsz + 1) | ||
156 | #define decode_open_confirm_maxsz \ | ||
157 | (op_decode_hdr_maxsz + \ | ||
158 | decode_stateid_maxsz) | ||
159 | #define encode_open_downgrade_maxsz \ | ||
160 | (op_encode_hdr_maxsz + \ | ||
161 | encode_stateid_maxsz + 1 + \ | ||
162 | encode_share_access_maxsz) | ||
163 | #define decode_open_downgrade_maxsz \ | ||
164 | (op_decode_hdr_maxsz + \ | ||
165 | decode_stateid_maxsz) | ||
166 | #define encode_close_maxsz (op_encode_hdr_maxsz + \ | ||
167 | 1 + encode_stateid_maxsz) | ||
168 | #define decode_close_maxsz (op_decode_hdr_maxsz + \ | ||
169 | decode_stateid_maxsz) | ||
170 | #define encode_setattr_maxsz (op_encode_hdr_maxsz + \ | ||
171 | encode_stateid_maxsz + \ | ||
172 | encode_attrs_maxsz) | ||
173 | #define decode_setattr_maxsz (op_decode_hdr_maxsz + \ | ||
174 | nfs4_fattr_bitmap_maxsz) | ||
175 | #define encode_read_maxsz (op_encode_hdr_maxsz + \ | ||
176 | encode_stateid_maxsz + 3) | ||
177 | #define decode_read_maxsz (op_decode_hdr_maxsz + 2) | ||
178 | #define encode_readdir_maxsz (op_encode_hdr_maxsz + \ | ||
179 | 2 + encode_verifier_maxsz + 5) | ||
180 | #define decode_readdir_maxsz (op_decode_hdr_maxsz + \ | ||
181 | decode_verifier_maxsz) | ||
182 | #define encode_readlink_maxsz (op_encode_hdr_maxsz) | ||
183 | #define decode_readlink_maxsz (op_decode_hdr_maxsz + 1) | ||
184 | #define encode_write_maxsz (op_encode_hdr_maxsz + \ | ||
185 | encode_stateid_maxsz + 4) | ||
186 | #define decode_write_maxsz (op_decode_hdr_maxsz + \ | ||
187 | 2 + decode_verifier_maxsz) | ||
188 | #define encode_commit_maxsz (op_encode_hdr_maxsz + 3) | ||
189 | #define decode_commit_maxsz (op_decode_hdr_maxsz + \ | ||
190 | decode_verifier_maxsz) | ||
143 | #define encode_remove_maxsz (op_encode_hdr_maxsz + \ | 191 | #define encode_remove_maxsz (op_encode_hdr_maxsz + \ |
144 | nfs4_name_maxsz) | 192 | nfs4_name_maxsz) |
145 | #define encode_rename_maxsz (op_encode_hdr_maxsz + \ | 193 | #define encode_rename_maxsz (op_encode_hdr_maxsz + \ |
@@ -148,19 +196,44 @@ static int nfs4_stat_to_errno(int); | |||
148 | #define encode_link_maxsz (op_encode_hdr_maxsz + \ | 196 | #define encode_link_maxsz (op_encode_hdr_maxsz + \ |
149 | nfs4_name_maxsz) | 197 | nfs4_name_maxsz) |
150 | #define decode_link_maxsz (op_decode_hdr_maxsz + 5) | 198 | #define decode_link_maxsz (op_decode_hdr_maxsz + 5) |
199 | #define encode_lock_maxsz (op_encode_hdr_maxsz + \ | ||
200 | 7 + \ | ||
201 | 1 + encode_stateid_maxsz + 8) | ||
202 | #define decode_lock_denied_maxsz \ | ||
203 | (8 + decode_lockowner_maxsz) | ||
204 | #define decode_lock_maxsz (op_decode_hdr_maxsz + \ | ||
205 | decode_lock_denied_maxsz) | ||
206 | #define encode_lockt_maxsz (op_encode_hdr_maxsz + 12) | ||
207 | #define decode_lockt_maxsz (op_decode_hdr_maxsz + \ | ||
208 | decode_lock_denied_maxsz) | ||
209 | #define encode_locku_maxsz (op_encode_hdr_maxsz + 3 + \ | ||
210 | encode_stateid_maxsz + \ | ||
211 | 4) | ||
212 | #define decode_locku_maxsz (op_decode_hdr_maxsz + \ | ||
213 | decode_stateid_maxsz) | ||
214 | #define encode_access_maxsz (op_encode_hdr_maxsz + 1) | ||
215 | #define decode_access_maxsz (op_decode_hdr_maxsz + 2) | ||
151 | #define encode_symlink_maxsz (op_encode_hdr_maxsz + \ | 216 | #define encode_symlink_maxsz (op_encode_hdr_maxsz + \ |
152 | 1 + nfs4_name_maxsz + \ | 217 | 1 + nfs4_name_maxsz + \ |
153 | 1 + \ | 218 | 1 + \ |
154 | nfs4_fattr_maxsz) | 219 | nfs4_fattr_maxsz) |
155 | #define decode_symlink_maxsz (op_decode_hdr_maxsz + 8) | 220 | #define decode_symlink_maxsz (op_decode_hdr_maxsz + 8) |
156 | #define encode_create_maxsz (op_encode_hdr_maxsz + \ | 221 | #define encode_create_maxsz (op_encode_hdr_maxsz + \ |
157 | 2 + nfs4_name_maxsz + \ | 222 | 1 + 2 + nfs4_name_maxsz + \ |
158 | nfs4_fattr_maxsz) | 223 | encode_attrs_maxsz) |
159 | #define decode_create_maxsz (op_decode_hdr_maxsz + \ | 224 | #define decode_create_maxsz (op_decode_hdr_maxsz + \ |
160 | decode_change_info_maxsz + \ | 225 | decode_change_info_maxsz + \ |
161 | nfs4_fattr_bitmap_maxsz) | 226 | nfs4_fattr_bitmap_maxsz) |
227 | #define encode_statfs_maxsz (encode_getattr_maxsz) | ||
228 | #define decode_statfs_maxsz (decode_getattr_maxsz) | ||
162 | #define encode_delegreturn_maxsz (op_encode_hdr_maxsz + 4) | 229 | #define encode_delegreturn_maxsz (op_encode_hdr_maxsz + 4) |
163 | #define decode_delegreturn_maxsz (op_decode_hdr_maxsz) | 230 | #define decode_delegreturn_maxsz (op_decode_hdr_maxsz) |
231 | #define encode_getacl_maxsz (encode_getattr_maxsz) | ||
232 | #define decode_getacl_maxsz (op_decode_hdr_maxsz + \ | ||
233 | nfs4_fattr_bitmap_maxsz + 1) | ||
234 | #define encode_setacl_maxsz (op_encode_hdr_maxsz + \ | ||
235 | encode_stateid_maxsz + 3) | ||
236 | #define decode_setacl_maxsz (decode_setattr_maxsz) | ||
164 | #define encode_fs_locations_maxsz \ | 237 | #define encode_fs_locations_maxsz \ |
165 | (encode_getattr_maxsz) | 238 | (encode_getattr_maxsz) |
166 | #define decode_fs_locations_maxsz \ | 239 | #define decode_fs_locations_maxsz \ |
@@ -169,37 +242,37 @@ static int nfs4_stat_to_errno(int); | |||
169 | #define NFS4_dec_compound_sz (1024) /* XXX: large enough? */ | 242 | #define NFS4_dec_compound_sz (1024) /* XXX: large enough? */ |
170 | #define NFS4_enc_read_sz (compound_encode_hdr_maxsz + \ | 243 | #define NFS4_enc_read_sz (compound_encode_hdr_maxsz + \ |
171 | encode_putfh_maxsz + \ | 244 | encode_putfh_maxsz + \ |
172 | op_encode_hdr_maxsz + 7) | 245 | encode_read_maxsz) |
173 | #define NFS4_dec_read_sz (compound_decode_hdr_maxsz + \ | 246 | #define NFS4_dec_read_sz (compound_decode_hdr_maxsz + \ |
174 | decode_putfh_maxsz + \ | 247 | decode_putfh_maxsz + \ |
175 | op_decode_hdr_maxsz + 2) | 248 | decode_read_maxsz) |
176 | #define NFS4_enc_readlink_sz (compound_encode_hdr_maxsz + \ | 249 | #define NFS4_enc_readlink_sz (compound_encode_hdr_maxsz + \ |
177 | encode_putfh_maxsz + \ | 250 | encode_putfh_maxsz + \ |
178 | op_encode_hdr_maxsz) | 251 | encode_readlink_maxsz) |
179 | #define NFS4_dec_readlink_sz (compound_decode_hdr_maxsz + \ | 252 | #define NFS4_dec_readlink_sz (compound_decode_hdr_maxsz + \ |
180 | decode_putfh_maxsz + \ | 253 | decode_putfh_maxsz + \ |
181 | op_decode_hdr_maxsz) | 254 | decode_readlink_maxsz) |
182 | #define NFS4_enc_readdir_sz (compound_encode_hdr_maxsz + \ | 255 | #define NFS4_enc_readdir_sz (compound_encode_hdr_maxsz + \ |
183 | encode_putfh_maxsz + \ | 256 | encode_putfh_maxsz + \ |
184 | op_encode_hdr_maxsz + 9) | 257 | encode_readdir_maxsz) |
185 | #define NFS4_dec_readdir_sz (compound_decode_hdr_maxsz + \ | 258 | #define NFS4_dec_readdir_sz (compound_decode_hdr_maxsz + \ |
186 | decode_putfh_maxsz + \ | 259 | decode_putfh_maxsz + \ |
187 | op_decode_hdr_maxsz + 2) | 260 | decode_readdir_maxsz) |
188 | #define NFS4_enc_write_sz (compound_encode_hdr_maxsz + \ | 261 | #define NFS4_enc_write_sz (compound_encode_hdr_maxsz + \ |
189 | encode_putfh_maxsz + \ | 262 | encode_putfh_maxsz + \ |
190 | op_encode_hdr_maxsz + 8 + \ | 263 | encode_write_maxsz + \ |
191 | encode_getattr_maxsz) | 264 | encode_getattr_maxsz) |
192 | #define NFS4_dec_write_sz (compound_decode_hdr_maxsz + \ | 265 | #define NFS4_dec_write_sz (compound_decode_hdr_maxsz + \ |
193 | decode_putfh_maxsz + \ | 266 | decode_putfh_maxsz + \ |
194 | op_decode_hdr_maxsz + 4 + \ | 267 | decode_write_maxsz + \ |
195 | decode_getattr_maxsz) | 268 | decode_getattr_maxsz) |
196 | #define NFS4_enc_commit_sz (compound_encode_hdr_maxsz + \ | 269 | #define NFS4_enc_commit_sz (compound_encode_hdr_maxsz + \ |
197 | encode_putfh_maxsz + \ | 270 | encode_putfh_maxsz + \ |
198 | op_encode_hdr_maxsz + 3 + \ | 271 | encode_commit_maxsz + \ |
199 | encode_getattr_maxsz) | 272 | encode_getattr_maxsz) |
200 | #define NFS4_dec_commit_sz (compound_decode_hdr_maxsz + \ | 273 | #define NFS4_dec_commit_sz (compound_decode_hdr_maxsz + \ |
201 | decode_putfh_maxsz + \ | 274 | decode_putfh_maxsz + \ |
202 | op_decode_hdr_maxsz + 2 + \ | 275 | decode_commit_maxsz + \ |
203 | decode_getattr_maxsz) | 276 | decode_getattr_maxsz) |
204 | #define NFS4_enc_open_sz (compound_encode_hdr_maxsz + \ | 277 | #define NFS4_enc_open_sz (compound_encode_hdr_maxsz + \ |
205 | encode_putfh_maxsz + \ | 278 | encode_putfh_maxsz + \ |
@@ -217,13 +290,14 @@ static int nfs4_stat_to_errno(int); | |||
217 | decode_getattr_maxsz + \ | 290 | decode_getattr_maxsz + \ |
218 | decode_restorefh_maxsz + \ | 291 | decode_restorefh_maxsz + \ |
219 | decode_getattr_maxsz) | 292 | decode_getattr_maxsz) |
220 | #define NFS4_enc_open_confirm_sz \ | 293 | #define NFS4_enc_open_confirm_sz \ |
221 | (compound_encode_hdr_maxsz + \ | 294 | (compound_encode_hdr_maxsz + \ |
222 | encode_putfh_maxsz + \ | 295 | encode_putfh_maxsz + \ |
223 | op_encode_hdr_maxsz + 5) | 296 | encode_open_confirm_maxsz) |
224 | #define NFS4_dec_open_confirm_sz (compound_decode_hdr_maxsz + \ | 297 | #define NFS4_dec_open_confirm_sz \ |
225 | decode_putfh_maxsz + \ | 298 | (compound_decode_hdr_maxsz + \ |
226 | op_decode_hdr_maxsz + 4) | 299 | decode_putfh_maxsz + \ |
300 | decode_open_confirm_maxsz) | ||
227 | #define NFS4_enc_open_noattr_sz (compound_encode_hdr_maxsz + \ | 301 | #define NFS4_enc_open_noattr_sz (compound_encode_hdr_maxsz + \ |
228 | encode_putfh_maxsz + \ | 302 | encode_putfh_maxsz + \ |
229 | encode_open_maxsz + \ | 303 | encode_open_maxsz + \ |
@@ -234,31 +308,30 @@ static int nfs4_stat_to_errno(int); | |||
234 | decode_getattr_maxsz) | 308 | decode_getattr_maxsz) |
235 | #define NFS4_enc_open_downgrade_sz \ | 309 | #define NFS4_enc_open_downgrade_sz \ |
236 | (compound_encode_hdr_maxsz + \ | 310 | (compound_encode_hdr_maxsz + \ |
237 | encode_putfh_maxsz + \ | 311 | encode_putfh_maxsz + \ |
238 | op_encode_hdr_maxsz + 7 + \ | 312 | encode_open_downgrade_maxsz + \ |
239 | encode_getattr_maxsz) | 313 | encode_getattr_maxsz) |
240 | #define NFS4_dec_open_downgrade_sz \ | 314 | #define NFS4_dec_open_downgrade_sz \ |
241 | (compound_decode_hdr_maxsz + \ | 315 | (compound_decode_hdr_maxsz + \ |
242 | decode_putfh_maxsz + \ | 316 | decode_putfh_maxsz + \ |
243 | op_decode_hdr_maxsz + 4 + \ | 317 | decode_open_downgrade_maxsz + \ |
244 | decode_getattr_maxsz) | 318 | decode_getattr_maxsz) |
245 | #define NFS4_enc_close_sz (compound_encode_hdr_maxsz + \ | 319 | #define NFS4_enc_close_sz (compound_encode_hdr_maxsz + \ |
246 | encode_putfh_maxsz + \ | 320 | encode_putfh_maxsz + \ |
247 | op_encode_hdr_maxsz + 5 + \ | 321 | encode_close_maxsz + \ |
248 | encode_getattr_maxsz) | 322 | encode_getattr_maxsz) |
249 | #define NFS4_dec_close_sz (compound_decode_hdr_maxsz + \ | 323 | #define NFS4_dec_close_sz (compound_decode_hdr_maxsz + \ |
250 | decode_putfh_maxsz + \ | 324 | decode_putfh_maxsz + \ |
251 | op_decode_hdr_maxsz + 4 + \ | 325 | decode_close_maxsz + \ |
252 | decode_getattr_maxsz) | 326 | decode_getattr_maxsz) |
253 | #define NFS4_enc_setattr_sz (compound_encode_hdr_maxsz + \ | 327 | #define NFS4_enc_setattr_sz (compound_encode_hdr_maxsz + \ |
254 | encode_putfh_maxsz + \ | 328 | encode_putfh_maxsz + \ |
255 | op_encode_hdr_maxsz + 4 + \ | 329 | encode_setattr_maxsz + \ |
256 | nfs4_fattr_maxsz + \ | 330 | encode_getattr_maxsz) |
257 | encode_getattr_maxsz) | 331 | #define NFS4_dec_setattr_sz (compound_decode_hdr_maxsz + \ |
258 | #define NFS4_dec_setattr_sz (compound_decode_hdr_maxsz + \ | 332 | decode_putfh_maxsz + \ |
259 | decode_putfh_maxsz + \ | 333 | decode_setattr_maxsz + \ |
260 | op_decode_hdr_maxsz + 3 + \ | 334 | decode_getattr_maxsz) |
261 | nfs4_fattr_maxsz) | ||
262 | #define NFS4_enc_fsinfo_sz (compound_encode_hdr_maxsz + \ | 335 | #define NFS4_enc_fsinfo_sz (compound_encode_hdr_maxsz + \ |
263 | encode_putfh_maxsz + \ | 336 | encode_putfh_maxsz + \ |
264 | encode_fsinfo_maxsz) | 337 | encode_fsinfo_maxsz) |
@@ -285,39 +358,28 @@ static int nfs4_stat_to_errno(int); | |||
285 | decode_fsinfo_maxsz) | 358 | decode_fsinfo_maxsz) |
286 | #define NFS4_enc_lock_sz (compound_encode_hdr_maxsz + \ | 359 | #define NFS4_enc_lock_sz (compound_encode_hdr_maxsz + \ |
287 | encode_putfh_maxsz + \ | 360 | encode_putfh_maxsz + \ |
288 | encode_getattr_maxsz + \ | 361 | encode_lock_maxsz) |
289 | op_encode_hdr_maxsz + \ | ||
290 | 1 + 1 + 2 + 2 + \ | ||
291 | 1 + 4 + 1 + 2 + \ | ||
292 | lock_owner_id_maxsz) | ||
293 | #define NFS4_dec_lock_sz (compound_decode_hdr_maxsz + \ | 362 | #define NFS4_dec_lock_sz (compound_decode_hdr_maxsz + \ |
294 | decode_putfh_maxsz + \ | 363 | decode_putfh_maxsz + \ |
295 | decode_getattr_maxsz + \ | 364 | decode_lock_maxsz) |
296 | op_decode_hdr_maxsz + \ | ||
297 | 2 + 2 + 1 + 2 + \ | ||
298 | lock_owner_id_maxsz) | ||
299 | #define NFS4_enc_lockt_sz (compound_encode_hdr_maxsz + \ | 365 | #define NFS4_enc_lockt_sz (compound_encode_hdr_maxsz + \ |
300 | encode_putfh_maxsz + \ | 366 | encode_putfh_maxsz + \ |
301 | encode_getattr_maxsz + \ | 367 | encode_lockt_maxsz) |
302 | op_encode_hdr_maxsz + \ | 368 | #define NFS4_dec_lockt_sz (compound_decode_hdr_maxsz + \ |
303 | 1 + 2 + 2 + 2 + \ | 369 | decode_putfh_maxsz + \ |
304 | lock_owner_id_maxsz) | 370 | decode_lockt_maxsz) |
305 | #define NFS4_dec_lockt_sz (NFS4_dec_lock_sz) | ||
306 | #define NFS4_enc_locku_sz (compound_encode_hdr_maxsz + \ | 371 | #define NFS4_enc_locku_sz (compound_encode_hdr_maxsz + \ |
307 | encode_putfh_maxsz + \ | 372 | encode_putfh_maxsz + \ |
308 | encode_getattr_maxsz + \ | 373 | encode_locku_maxsz) |
309 | op_encode_hdr_maxsz + \ | ||
310 | 1 + 1 + 4 + 2 + 2) | ||
311 | #define NFS4_dec_locku_sz (compound_decode_hdr_maxsz + \ | 374 | #define NFS4_dec_locku_sz (compound_decode_hdr_maxsz + \ |
312 | decode_putfh_maxsz + \ | 375 | decode_putfh_maxsz + \ |
313 | decode_getattr_maxsz + \ | 376 | decode_locku_maxsz) |
314 | op_decode_hdr_maxsz + 4) | ||
315 | #define NFS4_enc_access_sz (compound_encode_hdr_maxsz + \ | 377 | #define NFS4_enc_access_sz (compound_encode_hdr_maxsz + \ |
316 | encode_putfh_maxsz + \ | 378 | encode_putfh_maxsz + \ |
317 | op_encode_hdr_maxsz + 1) | 379 | encode_access_maxsz) |
318 | #define NFS4_dec_access_sz (compound_decode_hdr_maxsz + \ | 380 | #define NFS4_dec_access_sz (compound_decode_hdr_maxsz + \ |
319 | decode_putfh_maxsz + \ | 381 | decode_putfh_maxsz + \ |
320 | op_decode_hdr_maxsz + 2) | 382 | decode_access_maxsz) |
321 | #define NFS4_enc_getattr_sz (compound_encode_hdr_maxsz + \ | 383 | #define NFS4_enc_getattr_sz (compound_encode_hdr_maxsz + \ |
322 | encode_putfh_maxsz + \ | 384 | encode_putfh_maxsz + \ |
323 | encode_getattr_maxsz) | 385 | encode_getattr_maxsz) |
@@ -416,10 +478,10 @@ static int nfs4_stat_to_errno(int); | |||
416 | decode_getattr_maxsz) | 478 | decode_getattr_maxsz) |
417 | #define NFS4_enc_statfs_sz (compound_encode_hdr_maxsz + \ | 479 | #define NFS4_enc_statfs_sz (compound_encode_hdr_maxsz + \ |
418 | encode_putfh_maxsz + \ | 480 | encode_putfh_maxsz + \ |
419 | encode_getattr_maxsz) | 481 | encode_statfs_maxsz) |
420 | #define NFS4_dec_statfs_sz (compound_decode_hdr_maxsz + \ | 482 | #define NFS4_dec_statfs_sz (compound_decode_hdr_maxsz + \ |
421 | decode_putfh_maxsz + \ | 483 | decode_putfh_maxsz + \ |
422 | op_decode_hdr_maxsz + 12) | 484 | decode_statfs_maxsz) |
423 | #define NFS4_enc_server_caps_sz (compound_encode_hdr_maxsz + \ | 485 | #define NFS4_enc_server_caps_sz (compound_encode_hdr_maxsz + \ |
424 | encode_putfh_maxsz + \ | 486 | encode_putfh_maxsz + \ |
425 | encode_getattr_maxsz) | 487 | encode_getattr_maxsz) |
@@ -435,18 +497,16 @@ static int nfs4_stat_to_errno(int); | |||
435 | decode_getattr_maxsz) | 497 | decode_getattr_maxsz) |
436 | #define NFS4_enc_getacl_sz (compound_encode_hdr_maxsz + \ | 498 | #define NFS4_enc_getacl_sz (compound_encode_hdr_maxsz + \ |
437 | encode_putfh_maxsz + \ | 499 | encode_putfh_maxsz + \ |
438 | encode_getattr_maxsz) | 500 | encode_getacl_maxsz) |
439 | #define NFS4_dec_getacl_sz (compound_decode_hdr_maxsz + \ | 501 | #define NFS4_dec_getacl_sz (compound_decode_hdr_maxsz + \ |
440 | decode_putfh_maxsz + \ | 502 | decode_putfh_maxsz + \ |
441 | op_decode_hdr_maxsz + \ | 503 | decode_getacl_maxsz) |
442 | nfs4_fattr_bitmap_maxsz + 1) | ||
443 | #define NFS4_enc_setacl_sz (compound_encode_hdr_maxsz + \ | 504 | #define NFS4_enc_setacl_sz (compound_encode_hdr_maxsz + \ |
444 | encode_putfh_maxsz + \ | 505 | encode_putfh_maxsz + \ |
445 | op_encode_hdr_maxsz + 4 + \ | 506 | encode_setacl_maxsz) |
446 | nfs4_fattr_bitmap_maxsz + 1) | ||
447 | #define NFS4_dec_setacl_sz (compound_decode_hdr_maxsz + \ | 507 | #define NFS4_dec_setacl_sz (compound_decode_hdr_maxsz + \ |
448 | decode_putfh_maxsz + \ | 508 | decode_putfh_maxsz + \ |
449 | op_decode_hdr_maxsz + nfs4_fattr_bitmap_maxsz) | 509 | decode_setacl_maxsz) |
450 | #define NFS4_enc_fs_locations_sz \ | 510 | #define NFS4_enc_fs_locations_sz \ |
451 | (compound_encode_hdr_maxsz + \ | 511 | (compound_encode_hdr_maxsz + \ |
452 | encode_putfh_maxsz + \ | 512 | encode_putfh_maxsz + \ |
@@ -1108,12 +1168,10 @@ static int encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args) | |||
1108 | 1168 | ||
1109 | static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req) | 1169 | static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req) |
1110 | { | 1170 | { |
1111 | struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; | ||
1112 | uint32_t attrs[2] = { | 1171 | uint32_t attrs[2] = { |
1113 | FATTR4_WORD0_RDATTR_ERROR|FATTR4_WORD0_FILEID, | 1172 | FATTR4_WORD0_RDATTR_ERROR|FATTR4_WORD0_FILEID, |
1114 | FATTR4_WORD1_MOUNTED_ON_FILEID, | 1173 | FATTR4_WORD1_MOUNTED_ON_FILEID, |
1115 | }; | 1174 | }; |
1116 | int replen; | ||
1117 | __be32 *p; | 1175 | __be32 *p; |
1118 | 1176 | ||
1119 | RESERVE_SPACE(12+NFS4_VERIFIER_SIZE+20); | 1177 | RESERVE_SPACE(12+NFS4_VERIFIER_SIZE+20); |
@@ -1138,37 +1196,16 @@ static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg | |||
1138 | attrs[0] & readdir->bitmask[0], | 1196 | attrs[0] & readdir->bitmask[0], |
1139 | attrs[1] & readdir->bitmask[1]); | 1197 | attrs[1] & readdir->bitmask[1]); |
1140 | 1198 | ||
1141 | /* set up reply kvec | ||
1142 | * toplevel_status + taglen + rescount + OP_PUTFH + status | ||
1143 | * + OP_READDIR + status + verifer(2) = 9 | ||
1144 | */ | ||
1145 | replen = (RPC_REPHDRSIZE + auth->au_rslack + 9) << 2; | ||
1146 | xdr_inline_pages(&req->rq_rcv_buf, replen, readdir->pages, | ||
1147 | readdir->pgbase, readdir->count); | ||
1148 | dprintk("%s: inlined page args = (%u, %p, %u, %u)\n", | ||
1149 | __FUNCTION__, replen, readdir->pages, | ||
1150 | readdir->pgbase, readdir->count); | ||
1151 | |||
1152 | return 0; | 1199 | return 0; |
1153 | } | 1200 | } |
1154 | 1201 | ||
1155 | static int encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *readlink, struct rpc_rqst *req) | 1202 | static int encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *readlink, struct rpc_rqst *req) |
1156 | { | 1203 | { |
1157 | struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; | ||
1158 | unsigned int replen; | ||
1159 | __be32 *p; | 1204 | __be32 *p; |
1160 | 1205 | ||
1161 | RESERVE_SPACE(4); | 1206 | RESERVE_SPACE(4); |
1162 | WRITE32(OP_READLINK); | 1207 | WRITE32(OP_READLINK); |
1163 | 1208 | ||
1164 | /* set up reply kvec | ||
1165 | * toplevel_status + taglen + rescount + OP_PUTFH + status | ||
1166 | * + OP_READLINK + status + string length = 8 | ||
1167 | */ | ||
1168 | replen = (RPC_REPHDRSIZE + auth->au_rslack + 8) << 2; | ||
1169 | xdr_inline_pages(&req->rq_rcv_buf, replen, readlink->pages, | ||
1170 | readlink->pgbase, readlink->pglen); | ||
1171 | |||
1172 | return 0; | 1209 | return 0; |
1173 | } | 1210 | } |
1174 | 1211 | ||
@@ -1398,7 +1435,7 @@ out: | |||
1398 | /* | 1435 | /* |
1399 | * Encode REMOVE request | 1436 | * Encode REMOVE request |
1400 | */ | 1437 | */ |
1401 | static int nfs4_xdr_enc_remove(struct rpc_rqst *req, __be32 *p, const struct nfs4_remove_arg *args) | 1438 | static int nfs4_xdr_enc_remove(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs *args) |
1402 | { | 1439 | { |
1403 | struct xdr_stream xdr; | 1440 | struct xdr_stream xdr; |
1404 | struct compound_hdr hdr = { | 1441 | struct compound_hdr hdr = { |
@@ -1410,7 +1447,7 @@ static int nfs4_xdr_enc_remove(struct rpc_rqst *req, __be32 *p, const struct nfs | |||
1410 | encode_compound_hdr(&xdr, &hdr); | 1447 | encode_compound_hdr(&xdr, &hdr); |
1411 | if ((status = encode_putfh(&xdr, args->fh)) != 0) | 1448 | if ((status = encode_putfh(&xdr, args->fh)) != 0) |
1412 | goto out; | 1449 | goto out; |
1413 | if ((status = encode_remove(&xdr, args->name)) != 0) | 1450 | if ((status = encode_remove(&xdr, &args->name)) != 0) |
1414 | goto out; | 1451 | goto out; |
1415 | status = encode_getfattr(&xdr, args->bitmask); | 1452 | status = encode_getfattr(&xdr, args->bitmask); |
1416 | out: | 1453 | out: |
@@ -1734,6 +1771,8 @@ static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, __be32 *p, const struct n | |||
1734 | struct compound_hdr hdr = { | 1771 | struct compound_hdr hdr = { |
1735 | .nops = 2, | 1772 | .nops = 2, |
1736 | }; | 1773 | }; |
1774 | struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; | ||
1775 | unsigned int replen; | ||
1737 | int status; | 1776 | int status; |
1738 | 1777 | ||
1739 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 1778 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); |
@@ -1742,6 +1781,15 @@ static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, __be32 *p, const struct n | |||
1742 | if(status) | 1781 | if(status) |
1743 | goto out; | 1782 | goto out; |
1744 | status = encode_readlink(&xdr, args, req); | 1783 | status = encode_readlink(&xdr, args, req); |
1784 | |||
1785 | /* set up reply kvec | ||
1786 | * toplevel_status + taglen + rescount + OP_PUTFH + status | ||
1787 | * + OP_READLINK + status + string length = 8 | ||
1788 | */ | ||
1789 | replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_readlink_sz) << 2; | ||
1790 | xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, | ||
1791 | args->pgbase, args->pglen); | ||
1792 | |||
1745 | out: | 1793 | out: |
1746 | return status; | 1794 | return status; |
1747 | } | 1795 | } |
@@ -1755,6 +1803,8 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nf | |||
1755 | struct compound_hdr hdr = { | 1803 | struct compound_hdr hdr = { |
1756 | .nops = 2, | 1804 | .nops = 2, |
1757 | }; | 1805 | }; |
1806 | struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; | ||
1807 | int replen; | ||
1758 | int status; | 1808 | int status; |
1759 | 1809 | ||
1760 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 1810 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); |
@@ -1763,6 +1813,18 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nf | |||
1763 | if(status) | 1813 | if(status) |
1764 | goto out; | 1814 | goto out; |
1765 | status = encode_readdir(&xdr, args, req); | 1815 | status = encode_readdir(&xdr, args, req); |
1816 | |||
1817 | /* set up reply kvec | ||
1818 | * toplevel_status + taglen + rescount + OP_PUTFH + status | ||
1819 | * + OP_READDIR + status + verifer(2) = 9 | ||
1820 | */ | ||
1821 | replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_readdir_sz) << 2; | ||
1822 | xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, | ||
1823 | args->pgbase, args->count); | ||
1824 | dprintk("%s: inlined page args = (%u, %p, %u, %u)\n", | ||
1825 | __FUNCTION__, replen, args->pages, | ||
1826 | args->pgbase, args->count); | ||
1827 | |||
1766 | out: | 1828 | out: |
1767 | return status; | 1829 | return status; |
1768 | } | 1830 | } |
@@ -3161,11 +3223,12 @@ static int decode_getfh(struct xdr_stream *xdr, struct nfs_fh *fh) | |||
3161 | uint32_t len; | 3223 | uint32_t len; |
3162 | int status; | 3224 | int status; |
3163 | 3225 | ||
3226 | /* Zero handle first to allow comparisons */ | ||
3227 | memset(fh, 0, sizeof(*fh)); | ||
3228 | |||
3164 | status = decode_op_hdr(xdr, OP_GETFH); | 3229 | status = decode_op_hdr(xdr, OP_GETFH); |
3165 | if (status) | 3230 | if (status) |
3166 | return status; | 3231 | return status; |
3167 | /* Zero handle first to allow comparisons */ | ||
3168 | memset(fh, 0, sizeof(*fh)); | ||
3169 | 3232 | ||
3170 | READ_BUF(4); | 3233 | READ_BUF(4); |
3171 | READ32(len); | 3234 | READ32(len); |
@@ -3772,7 +3835,7 @@ out: | |||
3772 | /* | 3835 | /* |
3773 | * Decode REMOVE response | 3836 | * Decode REMOVE response |
3774 | */ | 3837 | */ |
3775 | static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_remove_res *res) | 3838 | static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, __be32 *p, struct nfs_removeres *res) |
3776 | { | 3839 | { |
3777 | struct xdr_stream xdr; | 3840 | struct xdr_stream xdr; |
3778 | struct compound_hdr hdr; | 3841 | struct compound_hdr hdr; |
@@ -3785,7 +3848,7 @@ static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_re | |||
3785 | goto out; | 3848 | goto out; |
3786 | if ((status = decode_remove(&xdr, &res->cinfo)) != 0) | 3849 | if ((status = decode_remove(&xdr, &res->cinfo)) != 0) |
3787 | goto out; | 3850 | goto out; |
3788 | decode_getfattr(&xdr, res->dir_attr, res->server); | 3851 | decode_getfattr(&xdr, &res->dir_attr, res->server); |
3789 | out: | 3852 | out: |
3790 | return status; | 3853 | return status; |
3791 | } | 3854 | } |
@@ -4030,12 +4093,11 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, __be32 *p, struct nfs_openr | |||
4030 | status = decode_open(&xdr, res); | 4093 | status = decode_open(&xdr, res); |
4031 | if (status) | 4094 | if (status) |
4032 | goto out; | 4095 | goto out; |
4033 | status = decode_getfh(&xdr, &res->fh); | 4096 | if (decode_getfh(&xdr, &res->fh) != 0) |
4034 | if (status) | ||
4035 | goto out; | 4097 | goto out; |
4036 | if (decode_getfattr(&xdr, res->f_attr, res->server) != 0) | 4098 | if (decode_getfattr(&xdr, res->f_attr, res->server) != 0) |
4037 | goto out; | 4099 | goto out; |
4038 | if ((status = decode_restorefh(&xdr)) != 0) | 4100 | if (decode_restorefh(&xdr) != 0) |
4039 | goto out; | 4101 | goto out; |
4040 | decode_getfattr(&xdr, res->dir_attr, res->server); | 4102 | decode_getfattr(&xdr, res->dir_attr, res->server); |
4041 | out: | 4103 | out: |
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index 7be0ee2782cb..845cdde1d8b7 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c | |||
@@ -272,14 +272,14 @@ nfs_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
272 | static int | 272 | static int |
273 | nfs_proc_remove(struct inode *dir, struct qstr *name) | 273 | nfs_proc_remove(struct inode *dir, struct qstr *name) |
274 | { | 274 | { |
275 | struct nfs_diropargs arg = { | 275 | struct nfs_removeargs arg = { |
276 | .fh = NFS_FH(dir), | 276 | .fh = NFS_FH(dir), |
277 | .name = name->name, | 277 | .name.len = name->len, |
278 | .len = name->len | 278 | .name.name = name->name, |
279 | }; | 279 | }; |
280 | struct rpc_message msg = { | 280 | struct rpc_message msg = { |
281 | .rpc_proc = &nfs_procedures[NFSPROC_REMOVE], | 281 | .rpc_proc = &nfs_procedures[NFSPROC_REMOVE], |
282 | .rpc_argp = &arg, | 282 | .rpc_argp = &arg, |
283 | }; | 283 | }; |
284 | int status; | 284 | int status; |
285 | 285 | ||
@@ -291,32 +291,16 @@ nfs_proc_remove(struct inode *dir, struct qstr *name) | |||
291 | return status; | 291 | return status; |
292 | } | 292 | } |
293 | 293 | ||
294 | static int | 294 | static void |
295 | nfs_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir, struct qstr *name) | 295 | nfs_proc_unlink_setup(struct rpc_message *msg, struct inode *dir) |
296 | { | 296 | { |
297 | struct nfs_diropargs *arg; | ||
298 | |||
299 | arg = kmalloc(sizeof(*arg), GFP_KERNEL); | ||
300 | if (!arg) | ||
301 | return -ENOMEM; | ||
302 | arg->fh = NFS_FH(dir->d_inode); | ||
303 | arg->name = name->name; | ||
304 | arg->len = name->len; | ||
305 | msg->rpc_proc = &nfs_procedures[NFSPROC_REMOVE]; | 297 | msg->rpc_proc = &nfs_procedures[NFSPROC_REMOVE]; |
306 | msg->rpc_argp = arg; | ||
307 | return 0; | ||
308 | } | 298 | } |
309 | 299 | ||
310 | static int | 300 | static int nfs_proc_unlink_done(struct rpc_task *task, struct inode *dir) |
311 | nfs_proc_unlink_done(struct dentry *dir, struct rpc_task *task) | ||
312 | { | 301 | { |
313 | struct rpc_message *msg = &task->tk_msg; | 302 | nfs_mark_for_revalidate(dir); |
314 | 303 | return 1; | |
315 | if (msg->rpc_argp) { | ||
316 | nfs_mark_for_revalidate(dir->d_inode); | ||
317 | kfree(msg->rpc_argp); | ||
318 | } | ||
319 | return 0; | ||
320 | } | 304 | } |
321 | 305 | ||
322 | static int | 306 | static int |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index adffe1615c51..b34b7a711d5b 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -1685,6 +1685,9 @@ static int nfs4_validate_mount_data(struct nfs4_mount_data **options, | |||
1685 | 1685 | ||
1686 | dprintk("MNTPATH: %s\n", *mntpath); | 1686 | dprintk("MNTPATH: %s\n", *mntpath); |
1687 | 1687 | ||
1688 | if (args.client_address == NULL) | ||
1689 | goto out_no_client_address; | ||
1690 | |||
1688 | *ip_addr = args.client_address; | 1691 | *ip_addr = args.client_address; |
1689 | 1692 | ||
1690 | break; | 1693 | break; |
@@ -1705,6 +1708,10 @@ out_inval_auth: | |||
1705 | out_no_address: | 1708 | out_no_address: |
1706 | dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n"); | 1709 | dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n"); |
1707 | return -EINVAL; | 1710 | return -EINVAL; |
1711 | |||
1712 | out_no_client_address: | ||
1713 | dfprintk(MOUNT, "NFS4: mount program didn't pass callback address\n"); | ||
1714 | return -EINVAL; | ||
1708 | } | 1715 | } |
1709 | 1716 | ||
1710 | /* | 1717 | /* |
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c index 0e28189c2151..045ab805c17f 100644 --- a/fs/nfs/unlink.c +++ b/fs/nfs/unlink.c | |||
@@ -3,7 +3,6 @@ | |||
3 | * | 3 | * |
4 | * nfs sillydelete handling | 4 | * nfs sillydelete handling |
5 | * | 5 | * |
6 | * NOTE: we rely on holding the BKL for list manipulation protection. | ||
7 | */ | 6 | */ |
8 | 7 | ||
9 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
@@ -15,46 +14,23 @@ | |||
15 | 14 | ||
16 | 15 | ||
17 | struct nfs_unlinkdata { | 16 | struct nfs_unlinkdata { |
18 | struct nfs_unlinkdata *next; | 17 | struct nfs_removeargs args; |
19 | struct dentry *dir, *dentry; | 18 | struct nfs_removeres res; |
20 | struct qstr name; | 19 | struct inode *dir; |
21 | struct rpc_task task; | ||
22 | struct rpc_cred *cred; | 20 | struct rpc_cred *cred; |
23 | unsigned int count; | ||
24 | }; | 21 | }; |
25 | 22 | ||
26 | static struct nfs_unlinkdata *nfs_deletes; | ||
27 | static RPC_WAITQ(nfs_delete_queue, "nfs_delete_queue"); | ||
28 | |||
29 | /** | ||
30 | * nfs_detach_unlinkdata - Remove asynchronous unlink from global list | ||
31 | * @data: pointer to descriptor | ||
32 | */ | ||
33 | static inline void | ||
34 | nfs_detach_unlinkdata(struct nfs_unlinkdata *data) | ||
35 | { | ||
36 | struct nfs_unlinkdata **q; | ||
37 | |||
38 | for (q = &nfs_deletes; *q != NULL; q = &((*q)->next)) { | ||
39 | if (*q == data) { | ||
40 | *q = data->next; | ||
41 | break; | ||
42 | } | ||
43 | } | ||
44 | } | ||
45 | |||
46 | /** | 23 | /** |
47 | * nfs_put_unlinkdata - release data from a sillydelete operation. | 24 | * nfs_free_unlinkdata - release data from a sillydelete operation. |
48 | * @data: pointer to unlink structure. | 25 | * @data: pointer to unlink structure. |
49 | */ | 26 | */ |
50 | static void | 27 | static void |
51 | nfs_put_unlinkdata(struct nfs_unlinkdata *data) | 28 | nfs_free_unlinkdata(struct nfs_unlinkdata *data) |
52 | { | 29 | { |
53 | if (--data->count == 0) { | 30 | iput(data->dir); |
54 | nfs_detach_unlinkdata(data); | 31 | put_rpccred(data->cred); |
55 | kfree(data->name.name); | 32 | kfree(data->args.name.name); |
56 | kfree(data); | 33 | kfree(data); |
57 | } | ||
58 | } | 34 | } |
59 | 35 | ||
60 | #define NAME_ALLOC_LEN(len) ((len+16) & ~15) | 36 | #define NAME_ALLOC_LEN(len) ((len+16) & ~15) |
@@ -63,50 +39,36 @@ nfs_put_unlinkdata(struct nfs_unlinkdata *data) | |||
63 | * @dentry: pointer to dentry | 39 | * @dentry: pointer to dentry |
64 | * @data: nfs_unlinkdata | 40 | * @data: nfs_unlinkdata |
65 | */ | 41 | */ |
66 | static inline void | 42 | static int nfs_copy_dname(struct dentry *dentry, struct nfs_unlinkdata *data) |
67 | nfs_copy_dname(struct dentry *dentry, struct nfs_unlinkdata *data) | ||
68 | { | 43 | { |
69 | char *str; | 44 | char *str; |
70 | int len = dentry->d_name.len; | 45 | int len = dentry->d_name.len; |
71 | 46 | ||
72 | str = kmalloc(NAME_ALLOC_LEN(len), GFP_KERNEL); | 47 | str = kmemdup(dentry->d_name.name, NAME_ALLOC_LEN(len), GFP_KERNEL); |
73 | if (!str) | 48 | if (!str) |
74 | return; | 49 | return -ENOMEM; |
75 | memcpy(str, dentry->d_name.name, len); | 50 | data->args.name.len = len; |
76 | if (!data->name.len) { | 51 | data->args.name.name = str; |
77 | data->name.len = len; | 52 | return 0; |
78 | data->name.name = str; | ||
79 | } else | ||
80 | kfree(str); | ||
81 | } | 53 | } |
82 | 54 | ||
83 | /** | 55 | /** |
84 | * nfs_async_unlink_init - Initialize the RPC info | 56 | * nfs_async_unlink_init - Initialize the RPC info |
85 | * @task: rpc_task of the sillydelete | 57 | * task: rpc_task of the sillydelete |
86 | * | ||
87 | * We delay initializing RPC info until after the call to dentry_iput() | ||
88 | * in order to minimize races against rename(). | ||
89 | */ | 58 | */ |
90 | static void nfs_async_unlink_init(struct rpc_task *task, void *calldata) | 59 | static void nfs_async_unlink_init(struct rpc_task *task, void *calldata) |
91 | { | 60 | { |
92 | struct nfs_unlinkdata *data = calldata; | 61 | struct nfs_unlinkdata *data = calldata; |
93 | struct dentry *dir = data->dir; | 62 | struct inode *dir = data->dir; |
94 | struct rpc_message msg = { | 63 | struct rpc_message msg = { |
95 | .rpc_cred = data->cred, | 64 | .rpc_argp = &data->args, |
65 | .rpc_resp = &data->res, | ||
66 | .rpc_cred = data->cred, | ||
96 | }; | 67 | }; |
97 | int status = -ENOENT; | ||
98 | |||
99 | if (!data->name.len) | ||
100 | goto out_err; | ||
101 | 68 | ||
102 | status = NFS_PROTO(dir->d_inode)->unlink_setup(&msg, dir, &data->name); | 69 | nfs_begin_data_update(dir); |
103 | if (status < 0) | 70 | NFS_PROTO(dir)->unlink_setup(&msg, dir); |
104 | goto out_err; | ||
105 | nfs_begin_data_update(dir->d_inode); | ||
106 | rpc_call_setup(task, &msg, 0); | 71 | rpc_call_setup(task, &msg, 0); |
107 | return; | ||
108 | out_err: | ||
109 | rpc_exit(task, status); | ||
110 | } | 72 | } |
111 | 73 | ||
112 | /** | 74 | /** |
@@ -117,19 +79,13 @@ static void nfs_async_unlink_init(struct rpc_task *task, void *calldata) | |||
117 | */ | 79 | */ |
118 | static void nfs_async_unlink_done(struct rpc_task *task, void *calldata) | 80 | static void nfs_async_unlink_done(struct rpc_task *task, void *calldata) |
119 | { | 81 | { |
120 | struct nfs_unlinkdata *data = calldata; | 82 | struct nfs_unlinkdata *data = calldata; |
121 | struct dentry *dir = data->dir; | 83 | struct inode *dir = data->dir; |
122 | struct inode *dir_i; | 84 | |
123 | 85 | if (!NFS_PROTO(dir)->unlink_done(task, dir)) | |
124 | if (!dir) | 86 | rpc_restart_call(task); |
125 | return; | 87 | else |
126 | dir_i = dir->d_inode; | 88 | nfs_end_data_update(dir); |
127 | nfs_end_data_update(dir_i); | ||
128 | if (NFS_PROTO(dir_i)->unlink_done(dir, task)) | ||
129 | return; | ||
130 | put_rpccred(data->cred); | ||
131 | data->cred = NULL; | ||
132 | dput(dir); | ||
133 | } | 89 | } |
134 | 90 | ||
135 | /** | 91 | /** |
@@ -142,7 +98,7 @@ static void nfs_async_unlink_done(struct rpc_task *task, void *calldata) | |||
142 | static void nfs_async_unlink_release(void *calldata) | 98 | static void nfs_async_unlink_release(void *calldata) |
143 | { | 99 | { |
144 | struct nfs_unlinkdata *data = calldata; | 100 | struct nfs_unlinkdata *data = calldata; |
145 | nfs_put_unlinkdata(data); | 101 | nfs_free_unlinkdata(data); |
146 | } | 102 | } |
147 | 103 | ||
148 | static const struct rpc_call_ops nfs_unlink_ops = { | 104 | static const struct rpc_call_ops nfs_unlink_ops = { |
@@ -151,73 +107,94 @@ static const struct rpc_call_ops nfs_unlink_ops = { | |||
151 | .rpc_release = nfs_async_unlink_release, | 107 | .rpc_release = nfs_async_unlink_release, |
152 | }; | 108 | }; |
153 | 109 | ||
110 | static int nfs_call_unlink(struct dentry *dentry, struct nfs_unlinkdata *data) | ||
111 | { | ||
112 | struct rpc_task *task; | ||
113 | struct dentry *parent; | ||
114 | struct inode *dir; | ||
115 | |||
116 | if (nfs_copy_dname(dentry, data) < 0) | ||
117 | goto out_free; | ||
118 | |||
119 | parent = dget_parent(dentry); | ||
120 | if (parent == NULL) | ||
121 | goto out_free; | ||
122 | dir = igrab(parent->d_inode); | ||
123 | dput(parent); | ||
124 | if (dir == NULL) | ||
125 | goto out_free; | ||
126 | |||
127 | data->dir = dir; | ||
128 | data->args.fh = NFS_FH(dir); | ||
129 | nfs_fattr_init(&data->res.dir_attr); | ||
130 | |||
131 | task = rpc_run_task(NFS_CLIENT(dir), RPC_TASK_ASYNC, &nfs_unlink_ops, data); | ||
132 | if (!IS_ERR(task)) | ||
133 | rpc_put_task(task); | ||
134 | return 1; | ||
135 | out_free: | ||
136 | return 0; | ||
137 | } | ||
138 | |||
154 | /** | 139 | /** |
155 | * nfs_async_unlink - asynchronous unlinking of a file | 140 | * nfs_async_unlink - asynchronous unlinking of a file |
141 | * @dir: parent directory of dentry | ||
156 | * @dentry: dentry to unlink | 142 | * @dentry: dentry to unlink |
157 | */ | 143 | */ |
158 | int | 144 | int |
159 | nfs_async_unlink(struct dentry *dentry) | 145 | nfs_async_unlink(struct inode *dir, struct dentry *dentry) |
160 | { | 146 | { |
161 | struct dentry *dir = dentry->d_parent; | 147 | struct nfs_unlinkdata *data; |
162 | struct nfs_unlinkdata *data; | 148 | int status = -ENOMEM; |
163 | struct rpc_clnt *clnt = NFS_CLIENT(dir->d_inode); | ||
164 | int status = -ENOMEM; | ||
165 | 149 | ||
166 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 150 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
167 | if (!data) | 151 | if (data == NULL) |
168 | goto out; | 152 | goto out; |
169 | 153 | ||
170 | data->cred = rpcauth_lookupcred(clnt->cl_auth, 0); | 154 | data->cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0); |
171 | if (IS_ERR(data->cred)) { | 155 | if (IS_ERR(data->cred)) { |
172 | status = PTR_ERR(data->cred); | 156 | status = PTR_ERR(data->cred); |
173 | goto out_free; | 157 | goto out_free; |
174 | } | 158 | } |
175 | data->dir = dget(dir); | ||
176 | data->dentry = dentry; | ||
177 | |||
178 | data->next = nfs_deletes; | ||
179 | nfs_deletes = data; | ||
180 | data->count = 1; | ||
181 | |||
182 | rpc_init_task(&data->task, clnt, RPC_TASK_ASYNC, &nfs_unlink_ops, data); | ||
183 | 159 | ||
160 | status = -EBUSY; | ||
184 | spin_lock(&dentry->d_lock); | 161 | spin_lock(&dentry->d_lock); |
162 | if (dentry->d_flags & DCACHE_NFSFS_RENAMED) | ||
163 | goto out_unlock; | ||
185 | dentry->d_flags |= DCACHE_NFSFS_RENAMED; | 164 | dentry->d_flags |= DCACHE_NFSFS_RENAMED; |
165 | dentry->d_fsdata = data; | ||
186 | spin_unlock(&dentry->d_lock); | 166 | spin_unlock(&dentry->d_lock); |
187 | 167 | return 0; | |
188 | rpc_sleep_on(&nfs_delete_queue, &data->task, NULL, NULL); | 168 | out_unlock: |
189 | status = 0; | 169 | spin_unlock(&dentry->d_lock); |
190 | out: | 170 | put_rpccred(data->cred); |
191 | return status; | ||
192 | out_free: | 171 | out_free: |
193 | kfree(data); | 172 | kfree(data); |
173 | out: | ||
194 | return status; | 174 | return status; |
195 | } | 175 | } |
196 | 176 | ||
197 | /** | 177 | /** |
198 | * nfs_complete_unlink - Initialize completion of the sillydelete | 178 | * nfs_complete_unlink - Initialize completion of the sillydelete |
199 | * @dentry: dentry to delete | 179 | * @dentry: dentry to delete |
180 | * @inode: inode | ||
200 | * | 181 | * |
201 | * Since we're most likely to be called by dentry_iput(), we | 182 | * Since we're most likely to be called by dentry_iput(), we |
202 | * only use the dentry to find the sillydelete. We then copy the name | 183 | * only use the dentry to find the sillydelete. We then copy the name |
203 | * into the qstr. | 184 | * into the qstr. |
204 | */ | 185 | */ |
205 | void | 186 | void |
206 | nfs_complete_unlink(struct dentry *dentry) | 187 | nfs_complete_unlink(struct dentry *dentry, struct inode *inode) |
207 | { | 188 | { |
208 | struct nfs_unlinkdata *data; | 189 | struct nfs_unlinkdata *data = NULL; |
209 | 190 | ||
210 | for(data = nfs_deletes; data != NULL; data = data->next) { | ||
211 | if (dentry == data->dentry) | ||
212 | break; | ||
213 | } | ||
214 | if (!data) | ||
215 | return; | ||
216 | data->count++; | ||
217 | nfs_copy_dname(dentry, data); | ||
218 | spin_lock(&dentry->d_lock); | 191 | spin_lock(&dentry->d_lock); |
219 | dentry->d_flags &= ~DCACHE_NFSFS_RENAMED; | 192 | if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { |
193 | dentry->d_flags &= ~DCACHE_NFSFS_RENAMED; | ||
194 | data = dentry->d_fsdata; | ||
195 | } | ||
220 | spin_unlock(&dentry->d_lock); | 196 | spin_unlock(&dentry->d_lock); |
221 | rpc_wake_up_task(&data->task); | 197 | |
222 | nfs_put_unlinkdata(data); | 198 | if (data != NULL && (NFS_STALE(inode) || !nfs_call_unlink(dentry, data))) |
199 | nfs_free_unlinkdata(data); | ||
223 | } | 200 | } |
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index c098ae194f79..9ba4aec37c50 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h | |||
@@ -407,8 +407,8 @@ extern void nfs_release_automount_timer(void); | |||
407 | /* | 407 | /* |
408 | * linux/fs/nfs/unlink.c | 408 | * linux/fs/nfs/unlink.c |
409 | */ | 409 | */ |
410 | extern int nfs_async_unlink(struct dentry *); | 410 | extern int nfs_async_unlink(struct inode *dir, struct dentry *dentry); |
411 | extern void nfs_complete_unlink(struct dentry *); | 411 | extern void nfs_complete_unlink(struct dentry *dentry, struct inode *); |
412 | 412 | ||
413 | /* | 413 | /* |
414 | * linux/fs/nfs/write.c | 414 | * linux/fs/nfs/write.c |
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 38d77681cf27..cf74a4db84a5 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
@@ -278,6 +278,21 @@ struct nfs_writeres { | |||
278 | }; | 278 | }; |
279 | 279 | ||
280 | /* | 280 | /* |
281 | * Common arguments to the unlink call | ||
282 | */ | ||
283 | struct nfs_removeargs { | ||
284 | const struct nfs_fh *fh; | ||
285 | struct qstr name; | ||
286 | const u32 * bitmask; | ||
287 | }; | ||
288 | |||
289 | struct nfs_removeres { | ||
290 | const struct nfs_server *server; | ||
291 | struct nfs4_change_info cinfo; | ||
292 | struct nfs_fattr dir_attr; | ||
293 | }; | ||
294 | |||
295 | /* | ||
281 | * Argument struct for decode_entry function | 296 | * Argument struct for decode_entry function |
282 | */ | 297 | */ |
283 | struct nfs_entry { | 298 | struct nfs_entry { |
@@ -631,18 +646,6 @@ struct nfs4_readlink { | |||
631 | struct page ** pages; /* zero-copy data */ | 646 | struct page ** pages; /* zero-copy data */ |
632 | }; | 647 | }; |
633 | 648 | ||
634 | struct nfs4_remove_arg { | ||
635 | const struct nfs_fh * fh; | ||
636 | const struct qstr * name; | ||
637 | const u32 * bitmask; | ||
638 | }; | ||
639 | |||
640 | struct nfs4_remove_res { | ||
641 | const struct nfs_server * server; | ||
642 | struct nfs4_change_info cinfo; | ||
643 | struct nfs_fattr * dir_attr; | ||
644 | }; | ||
645 | |||
646 | struct nfs4_rename_arg { | 649 | struct nfs4_rename_arg { |
647 | const struct nfs_fh * old_dir; | 650 | const struct nfs_fh * old_dir; |
648 | const struct nfs_fh * new_dir; | 651 | const struct nfs_fh * new_dir; |
@@ -788,9 +791,8 @@ struct nfs_rpc_ops { | |||
788 | int (*create) (struct inode *, struct dentry *, | 791 | int (*create) (struct inode *, struct dentry *, |
789 | struct iattr *, int, struct nameidata *); | 792 | struct iattr *, int, struct nameidata *); |
790 | int (*remove) (struct inode *, struct qstr *); | 793 | int (*remove) (struct inode *, struct qstr *); |
791 | int (*unlink_setup) (struct rpc_message *, | 794 | void (*unlink_setup) (struct rpc_message *, struct inode *dir); |
792 | struct dentry *, struct qstr *); | 795 | int (*unlink_done) (struct rpc_task *, struct inode *); |
793 | int (*unlink_done) (struct dentry *, struct rpc_task *); | ||
794 | int (*rename) (struct inode *, struct qstr *, | 796 | int (*rename) (struct inode *, struct qstr *, |
795 | struct inode *, struct qstr *); | 797 | struct inode *, struct qstr *); |
796 | int (*link) (struct inode *, struct inode *, struct qstr *); | 798 | int (*link) (struct inode *, struct inode *, struct qstr *); |
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index 9e340fa23c06..c6b53d181bfa 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/uio.h> | 12 | #include <linux/uio.h> |
13 | #include <asm/byteorder.h> | 13 | #include <asm/byteorder.h> |
14 | #include <linux/scatterlist.h> | 14 | #include <linux/scatterlist.h> |
15 | #include <linux/smp_lock.h> | ||
15 | 16 | ||
16 | /* | 17 | /* |
17 | * Buffer adjustment | 18 | * Buffer adjustment |
@@ -36,6 +37,21 @@ struct xdr_netobj { | |||
36 | typedef int (*kxdrproc_t)(void *rqstp, __be32 *data, void *obj); | 37 | typedef int (*kxdrproc_t)(void *rqstp, __be32 *data, void *obj); |
37 | 38 | ||
38 | /* | 39 | /* |
40 | * We're still requiring the BKL in the xdr code until it's been | ||
41 | * more carefully audited, at which point this wrapper will become | ||
42 | * unnecessary. | ||
43 | */ | ||
44 | static inline int rpc_call_xdrproc(kxdrproc_t xdrproc, void *rqstp, __be32 *data, void *obj) | ||
45 | { | ||
46 | int ret; | ||
47 | |||
48 | lock_kernel(); | ||
49 | ret = xdrproc(rqstp, data, obj); | ||
50 | unlock_kernel(); | ||
51 | return ret; | ||
52 | } | ||
53 | |||
54 | /* | ||
39 | * Basic structure for transmission/reception of a client XDR message. | 55 | * Basic structure for transmission/reception of a client XDR message. |
40 | * Features a header (for a linear buffer containing RPC headers | 56 | * Features a header (for a linear buffer containing RPC headers |
41 | * and the data payload for short messages), and then an array of | 57 | * and the data payload for short messages), and then an array of |
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 29a8ecc60928..1ea27559b1de 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
14 | #include <linux/sunrpc/clnt.h> | 14 | #include <linux/sunrpc/clnt.h> |
15 | #include <linux/spinlock.h> | 15 | #include <linux/spinlock.h> |
16 | #include <linux/smp_lock.h> | ||
17 | 16 | ||
18 | #ifdef RPC_DEBUG | 17 | #ifdef RPC_DEBUG |
19 | # define RPCDBG_FACILITY RPCDBG_AUTH | 18 | # define RPCDBG_FACILITY RPCDBG_AUTH |
@@ -476,17 +475,13 @@ rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, | |||
476 | __be32 *data, void *obj) | 475 | __be32 *data, void *obj) |
477 | { | 476 | { |
478 | struct rpc_cred *cred = task->tk_msg.rpc_cred; | 477 | struct rpc_cred *cred = task->tk_msg.rpc_cred; |
479 | int ret; | ||
480 | 478 | ||
481 | dprintk("RPC: %5u using %s cred %p to wrap rpc data\n", | 479 | dprintk("RPC: %5u using %s cred %p to wrap rpc data\n", |
482 | task->tk_pid, cred->cr_ops->cr_name, cred); | 480 | task->tk_pid, cred->cr_ops->cr_name, cred); |
483 | if (cred->cr_ops->crwrap_req) | 481 | if (cred->cr_ops->crwrap_req) |
484 | return cred->cr_ops->crwrap_req(task, encode, rqstp, data, obj); | 482 | return cred->cr_ops->crwrap_req(task, encode, rqstp, data, obj); |
485 | /* By default, we encode the arguments normally. */ | 483 | /* By default, we encode the arguments normally. */ |
486 | lock_kernel(); | 484 | return rpc_call_xdrproc(encode, rqstp, data, obj); |
487 | ret = encode(rqstp, data, obj); | ||
488 | unlock_kernel(); | ||
489 | return ret; | ||
490 | } | 485 | } |
491 | 486 | ||
492 | int | 487 | int |
@@ -494,7 +489,6 @@ rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, | |||
494 | __be32 *data, void *obj) | 489 | __be32 *data, void *obj) |
495 | { | 490 | { |
496 | struct rpc_cred *cred = task->tk_msg.rpc_cred; | 491 | struct rpc_cred *cred = task->tk_msg.rpc_cred; |
497 | int ret; | ||
498 | 492 | ||
499 | dprintk("RPC: %5u using %s cred %p to unwrap rpc data\n", | 493 | dprintk("RPC: %5u using %s cred %p to unwrap rpc data\n", |
500 | task->tk_pid, cred->cr_ops->cr_name, cred); | 494 | task->tk_pid, cred->cr_ops->cr_name, cred); |
@@ -502,10 +496,7 @@ rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, | |||
502 | return cred->cr_ops->crunwrap_resp(task, decode, rqstp, | 496 | return cred->cr_ops->crunwrap_resp(task, decode, rqstp, |
503 | data, obj); | 497 | data, obj); |
504 | /* By default, we decode the arguments normally. */ | 498 | /* By default, we decode the arguments normally. */ |
505 | lock_kernel(); | 499 | return rpc_call_xdrproc(decode, rqstp, data, obj); |
506 | ret = decode(rqstp, data, obj); | ||
507 | unlock_kernel(); | ||
508 | return ret; | ||
509 | } | 500 | } |
510 | 501 | ||
511 | int | 502 | int |
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index abfda33bac64..4bbc59cc237c 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -43,7 +43,6 @@ | |||
43 | #include <linux/types.h> | 43 | #include <linux/types.h> |
44 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
45 | #include <linux/sched.h> | 45 | #include <linux/sched.h> |
46 | #include <linux/smp_lock.h> | ||
47 | #include <linux/pagemap.h> | 46 | #include <linux/pagemap.h> |
48 | #include <linux/sunrpc/clnt.h> | 47 | #include <linux/sunrpc/clnt.h> |
49 | #include <linux/sunrpc/auth.h> | 48 | #include <linux/sunrpc/auth.h> |
@@ -1000,9 +999,7 @@ gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx, | |||
1000 | offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; | 999 | offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; |
1001 | *p++ = htonl(rqstp->rq_seqno); | 1000 | *p++ = htonl(rqstp->rq_seqno); |
1002 | 1001 | ||
1003 | lock_kernel(); | 1002 | status = rpc_call_xdrproc(encode, rqstp, p, obj); |
1004 | status = encode(rqstp, p, obj); | ||
1005 | unlock_kernel(); | ||
1006 | if (status) | 1003 | if (status) |
1007 | return status; | 1004 | return status; |
1008 | 1005 | ||
@@ -1096,9 +1093,7 @@ gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, | |||
1096 | offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; | 1093 | offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; |
1097 | *p++ = htonl(rqstp->rq_seqno); | 1094 | *p++ = htonl(rqstp->rq_seqno); |
1098 | 1095 | ||
1099 | lock_kernel(); | 1096 | status = rpc_call_xdrproc(encode, rqstp, p, obj); |
1100 | status = encode(rqstp, p, obj); | ||
1101 | unlock_kernel(); | ||
1102 | if (status) | 1097 | if (status) |
1103 | return status; | 1098 | return status; |
1104 | 1099 | ||
@@ -1157,16 +1152,12 @@ gss_wrap_req(struct rpc_task *task, | |||
1157 | /* The spec seems a little ambiguous here, but I think that not | 1152 | /* The spec seems a little ambiguous here, but I think that not |
1158 | * wrapping context destruction requests makes the most sense. | 1153 | * wrapping context destruction requests makes the most sense. |
1159 | */ | 1154 | */ |
1160 | lock_kernel(); | 1155 | status = rpc_call_xdrproc(encode, rqstp, p, obj); |
1161 | status = encode(rqstp, p, obj); | ||
1162 | unlock_kernel(); | ||
1163 | goto out; | 1156 | goto out; |
1164 | } | 1157 | } |
1165 | switch (gss_cred->gc_service) { | 1158 | switch (gss_cred->gc_service) { |
1166 | case RPC_GSS_SVC_NONE: | 1159 | case RPC_GSS_SVC_NONE: |
1167 | lock_kernel(); | 1160 | status = rpc_call_xdrproc(encode, rqstp, p, obj); |
1168 | status = encode(rqstp, p, obj); | ||
1169 | unlock_kernel(); | ||
1170 | break; | 1161 | break; |
1171 | case RPC_GSS_SVC_INTEGRITY: | 1162 | case RPC_GSS_SVC_INTEGRITY: |
1172 | status = gss_wrap_req_integ(cred, ctx, encode, | 1163 | status = gss_wrap_req_integ(cred, ctx, encode, |
@@ -1282,9 +1273,7 @@ gss_unwrap_resp(struct rpc_task *task, | |||
1282 | cred->cr_auth->au_rslack = cred->cr_auth->au_verfsize + (p - savedp) | 1273 | cred->cr_auth->au_rslack = cred->cr_auth->au_verfsize + (p - savedp) |
1283 | + (savedlen - head->iov_len); | 1274 | + (savedlen - head->iov_len); |
1284 | out_decode: | 1275 | out_decode: |
1285 | lock_kernel(); | 1276 | status = rpc_call_xdrproc(decode, rqstp, p, obj); |
1286 | status = decode(rqstp, p, obj); | ||
1287 | unlock_kernel(); | ||
1288 | out: | 1277 | out: |
1289 | gss_put_ctx(ctx); | 1278 | gss_put_ctx(ctx); |
1290 | dprintk("RPC: %5u gss_unwrap_resp returning %d\n", task->tk_pid, | 1279 | dprintk("RPC: %5u gss_unwrap_resp returning %d\n", task->tk_pid, |