diff options
Diffstat (limited to 'fs/nfs')
| -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 |
11 files changed, 399 insertions, 362 deletions
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 | } |
