diff options
Diffstat (limited to 'fs/nfs')
| -rw-r--r-- | fs/nfs/dir.c | 8 | ||||
| -rw-r--r-- | fs/nfs/nfs2xdr.c | 21 | ||||
| -rw-r--r-- | fs/nfs/nfs3proc.c | 14 | ||||
| -rw-r--r-- | fs/nfs/nfs3xdr.c | 7 | ||||
| -rw-r--r-- | fs/nfs/nfs4proc.c | 12 | ||||
| -rw-r--r-- | fs/nfs/nfs4xdr.c | 8 | ||||
| -rw-r--r-- | fs/nfs/proc.c | 14 |
7 files changed, 49 insertions, 35 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index b483e5d206cb..51328ae640dd 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
| @@ -1464,10 +1464,6 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym | |||
| 1464 | char *kaddr; | 1464 | char *kaddr; |
| 1465 | struct iattr attr; | 1465 | struct iattr attr; |
| 1466 | unsigned int pathlen = strlen(symname); | 1466 | unsigned int pathlen = strlen(symname); |
| 1467 | struct qstr qsymname = { | ||
| 1468 | .name = symname, | ||
| 1469 | .len = pathlen, | ||
| 1470 | }; | ||
| 1471 | int error; | 1467 | int error; |
| 1472 | 1468 | ||
| 1473 | dfprintk(VFS, "NFS: symlink(%s/%ld, %s, %s)\n", dir->i_sb->s_id, | 1469 | dfprintk(VFS, "NFS: symlink(%s/%ld, %s, %s)\n", dir->i_sb->s_id, |
| @@ -1493,10 +1489,8 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym | |||
| 1493 | memset(kaddr + pathlen, 0, PAGE_SIZE - pathlen); | 1489 | memset(kaddr + pathlen, 0, PAGE_SIZE - pathlen); |
| 1494 | kunmap_atomic(kaddr, KM_USER0); | 1490 | kunmap_atomic(kaddr, KM_USER0); |
| 1495 | 1491 | ||
| 1496 | /* XXX: eventually this will pass in {page, pathlen}, | ||
| 1497 | * instead of qsymname; need XDR changes for that */ | ||
| 1498 | nfs_begin_data_update(dir); | 1492 | nfs_begin_data_update(dir); |
| 1499 | error = NFS_PROTO(dir)->symlink(dir, dentry, &qsymname, &attr); | 1493 | error = NFS_PROTO(dir)->symlink(dir, dentry, page, pathlen, &attr); |
| 1500 | nfs_end_data_update(dir); | 1494 | nfs_end_data_update(dir); |
| 1501 | if (error != 0) { | 1495 | if (error != 0) { |
| 1502 | dfprintk(VFS, "NFS: symlink(%s/%ld, %s, %s) error %d\n", | 1496 | dfprintk(VFS, "NFS: symlink(%s/%ld, %s, %s) error %d\n", |
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index 67391eef6b93..b49501fc0a79 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c | |||
| @@ -51,7 +51,7 @@ | |||
| 51 | #define NFS_createargs_sz (NFS_diropargs_sz+NFS_sattr_sz) | 51 | #define NFS_createargs_sz (NFS_diropargs_sz+NFS_sattr_sz) |
| 52 | #define NFS_renameargs_sz (NFS_diropargs_sz+NFS_diropargs_sz) | 52 | #define NFS_renameargs_sz (NFS_diropargs_sz+NFS_diropargs_sz) |
| 53 | #define NFS_linkargs_sz (NFS_fhandle_sz+NFS_diropargs_sz) | 53 | #define NFS_linkargs_sz (NFS_fhandle_sz+NFS_diropargs_sz) |
| 54 | #define NFS_symlinkargs_sz (NFS_diropargs_sz+NFS_path_sz+NFS_sattr_sz) | 54 | #define NFS_symlinkargs_sz (NFS_diropargs_sz+1+NFS_sattr_sz) |
| 55 | #define NFS_readdirargs_sz (NFS_fhandle_sz+2) | 55 | #define NFS_readdirargs_sz (NFS_fhandle_sz+2) |
| 56 | 56 | ||
| 57 | #define NFS_attrstat_sz (1+NFS_fattr_sz) | 57 | #define NFS_attrstat_sz (1+NFS_fattr_sz) |
| @@ -351,11 +351,26 @@ nfs_xdr_linkargs(struct rpc_rqst *req, u32 *p, struct nfs_linkargs *args) | |||
| 351 | static int | 351 | static int |
| 352 | nfs_xdr_symlinkargs(struct rpc_rqst *req, u32 *p, struct nfs_symlinkargs *args) | 352 | nfs_xdr_symlinkargs(struct rpc_rqst *req, u32 *p, struct nfs_symlinkargs *args) |
| 353 | { | 353 | { |
| 354 | struct xdr_buf *sndbuf = &req->rq_snd_buf; | ||
| 355 | size_t pad; | ||
| 356 | |||
| 354 | p = xdr_encode_fhandle(p, args->fromfh); | 357 | p = xdr_encode_fhandle(p, args->fromfh); |
| 355 | p = xdr_encode_array(p, args->fromname, args->fromlen); | 358 | p = xdr_encode_array(p, args->fromname, args->fromlen); |
| 356 | p = xdr_encode_array(p, args->topath, args->tolen); | 359 | *p++ = htonl(args->pathlen); |
| 360 | sndbuf->len = xdr_adjust_iovec(sndbuf->head, p); | ||
| 361 | |||
| 362 | xdr_encode_pages(sndbuf, args->pages, 0, args->pathlen); | ||
| 363 | |||
| 364 | /* | ||
| 365 | * xdr_encode_pages may have added a few bytes to ensure the | ||
| 366 | * pathname ends on a 4-byte boundary. Start encoding the | ||
| 367 | * attributes after the pad bytes. | ||
| 368 | */ | ||
| 369 | pad = sndbuf->tail->iov_len; | ||
| 370 | if (pad > 0) | ||
| 371 | p++; | ||
| 357 | p = xdr_encode_sattr(p, args->sattr); | 372 | p = xdr_encode_sattr(p, args->sattr); |
| 358 | req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); | 373 | sndbuf->len += xdr_adjust_iovec(sndbuf->tail, p) - pad; |
| 359 | return 0; | 374 | return 0; |
| 360 | } | 375 | } |
| 361 | 376 | ||
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index d85ac427c326..f8688eaa0001 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c | |||
| @@ -544,8 +544,8 @@ nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name) | |||
| 544 | } | 544 | } |
| 545 | 545 | ||
| 546 | static int | 546 | static int |
| 547 | nfs3_proc_symlink(struct inode *dir, struct dentry *dentry, struct qstr *path, | 547 | nfs3_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page, |
| 548 | struct iattr *sattr) | 548 | unsigned int len, struct iattr *sattr) |
| 549 | { | 549 | { |
| 550 | struct nfs_fh fhandle; | 550 | struct nfs_fh fhandle; |
| 551 | struct nfs_fattr fattr, dir_attr; | 551 | struct nfs_fattr fattr, dir_attr; |
| @@ -553,8 +553,8 @@ nfs3_proc_symlink(struct inode *dir, struct dentry *dentry, struct qstr *path, | |||
| 553 | .fromfh = NFS_FH(dir), | 553 | .fromfh = NFS_FH(dir), |
| 554 | .fromname = dentry->d_name.name, | 554 | .fromname = dentry->d_name.name, |
| 555 | .fromlen = dentry->d_name.len, | 555 | .fromlen = dentry->d_name.len, |
| 556 | .topath = path->name, | 556 | .pages = &page, |
| 557 | .tolen = path->len, | 557 | .pathlen = len, |
| 558 | .sattr = sattr | 558 | .sattr = sattr |
| 559 | }; | 559 | }; |
| 560 | struct nfs3_diropres res = { | 560 | struct nfs3_diropres res = { |
| @@ -569,11 +569,11 @@ nfs3_proc_symlink(struct inode *dir, struct dentry *dentry, struct qstr *path, | |||
| 569 | }; | 569 | }; |
| 570 | int status; | 570 | int status; |
| 571 | 571 | ||
| 572 | if (path->len > NFS3_MAXPATHLEN) | 572 | if (len > NFS3_MAXPATHLEN) |
| 573 | return -ENAMETOOLONG; | 573 | return -ENAMETOOLONG; |
| 574 | 574 | ||
| 575 | dprintk("NFS call symlink %s -> %s\n", dentry->d_name.name, | 575 | dprintk("NFS call symlink %s\n", dentry->d_name.name); |
| 576 | path->name); | 576 | |
| 577 | nfs_fattr_init(&dir_attr); | 577 | nfs_fattr_init(&dir_attr); |
| 578 | nfs_fattr_init(&fattr); | 578 | nfs_fattr_init(&fattr); |
| 579 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); | 579 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); |
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index 0250269e9753..16556fa4effb 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c | |||
| @@ -56,7 +56,7 @@ | |||
| 56 | #define NFS3_writeargs_sz (NFS3_fh_sz+5) | 56 | #define NFS3_writeargs_sz (NFS3_fh_sz+5) |
| 57 | #define NFS3_createargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz) | 57 | #define NFS3_createargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz) |
| 58 | #define NFS3_mkdirargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz) | 58 | #define NFS3_mkdirargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz) |
| 59 | #define NFS3_symlinkargs_sz (NFS3_diropargs_sz+NFS3_path_sz+NFS3_sattr_sz) | 59 | #define NFS3_symlinkargs_sz (NFS3_diropargs_sz+1+NFS3_sattr_sz) |
| 60 | #define NFS3_mknodargs_sz (NFS3_diropargs_sz+2+NFS3_sattr_sz) | 60 | #define NFS3_mknodargs_sz (NFS3_diropargs_sz+2+NFS3_sattr_sz) |
| 61 | #define NFS3_renameargs_sz (NFS3_diropargs_sz+NFS3_diropargs_sz) | 61 | #define NFS3_renameargs_sz (NFS3_diropargs_sz+NFS3_diropargs_sz) |
| 62 | #define NFS3_linkargs_sz (NFS3_fh_sz+NFS3_diropargs_sz) | 62 | #define NFS3_linkargs_sz (NFS3_fh_sz+NFS3_diropargs_sz) |
| @@ -398,8 +398,11 @@ nfs3_xdr_symlinkargs(struct rpc_rqst *req, u32 *p, struct nfs3_symlinkargs *args | |||
| 398 | p = xdr_encode_fhandle(p, args->fromfh); | 398 | p = xdr_encode_fhandle(p, args->fromfh); |
| 399 | p = xdr_encode_array(p, args->fromname, args->fromlen); | 399 | p = xdr_encode_array(p, args->fromname, args->fromlen); |
| 400 | p = xdr_encode_sattr(p, args->sattr); | 400 | p = xdr_encode_sattr(p, args->sattr); |
| 401 | p = xdr_encode_array(p, args->topath, args->tolen); | 401 | *p++ = htonl(args->pathlen); |
| 402 | req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); | 402 | req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); |
| 403 | |||
| 404 | /* Copy the page */ | ||
| 405 | xdr_encode_pages(&req->rq_snd_buf, args->pages, 0, args->pathlen); | ||
| 403 | return 0; | 406 | return 0; |
| 404 | } | 407 | } |
| 405 | 408 | ||
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 2d18eac6bee5..7f60beb40df3 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
| @@ -2085,7 +2085,7 @@ static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *n | |||
| 2085 | } | 2085 | } |
| 2086 | 2086 | ||
| 2087 | static int _nfs4_proc_symlink(struct inode *dir, struct dentry *dentry, | 2087 | static int _nfs4_proc_symlink(struct inode *dir, struct dentry *dentry, |
| 2088 | struct qstr *path, struct iattr *sattr) | 2088 | struct page *page, unsigned int len, struct iattr *sattr) |
| 2089 | { | 2089 | { |
| 2090 | struct nfs_server *server = NFS_SERVER(dir); | 2090 | struct nfs_server *server = NFS_SERVER(dir); |
| 2091 | struct nfs_fh fhandle; | 2091 | struct nfs_fh fhandle; |
| @@ -2111,10 +2111,11 @@ static int _nfs4_proc_symlink(struct inode *dir, struct dentry *dentry, | |||
| 2111 | }; | 2111 | }; |
| 2112 | int status; | 2112 | int status; |
| 2113 | 2113 | ||
| 2114 | if (path->len > NFS4_MAXPATHLEN) | 2114 | if (len > NFS4_MAXPATHLEN) |
| 2115 | return -ENAMETOOLONG; | 2115 | return -ENAMETOOLONG; |
| 2116 | 2116 | ||
| 2117 | arg.u.symlink = path; | 2117 | arg.u.symlink.pages = &page; |
| 2118 | arg.u.symlink.len = len; | ||
| 2118 | nfs_fattr_init(&fattr); | 2119 | nfs_fattr_init(&fattr); |
| 2119 | nfs_fattr_init(&dir_fattr); | 2120 | nfs_fattr_init(&dir_fattr); |
| 2120 | 2121 | ||
| @@ -2128,13 +2129,14 @@ static int _nfs4_proc_symlink(struct inode *dir, struct dentry *dentry, | |||
| 2128 | } | 2129 | } |
| 2129 | 2130 | ||
| 2130 | static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry, | 2131 | static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry, |
| 2131 | struct qstr *path, struct iattr *sattr) | 2132 | struct page *page, unsigned int len, struct iattr *sattr) |
| 2132 | { | 2133 | { |
| 2133 | struct nfs4_exception exception = { }; | 2134 | struct nfs4_exception exception = { }; |
| 2134 | int err; | 2135 | int err; |
| 2135 | do { | 2136 | do { |
| 2136 | err = nfs4_handle_exception(NFS_SERVER(dir), | 2137 | err = nfs4_handle_exception(NFS_SERVER(dir), |
| 2137 | _nfs4_proc_symlink(dir, dentry, path, sattr), | 2138 | _nfs4_proc_symlink(dir, dentry, page, |
| 2139 | len, sattr), | ||
| 2138 | &exception); | 2140 | &exception); |
| 2139 | } while (exception.retry); | 2141 | } while (exception.retry); |
| 2140 | return err; | 2142 | return err; |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 99926067eca4..3dd413f52da1 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
| @@ -128,7 +128,7 @@ static int nfs4_stat_to_errno(int); | |||
| 128 | #define decode_link_maxsz (op_decode_hdr_maxsz + 5) | 128 | #define decode_link_maxsz (op_decode_hdr_maxsz + 5) |
| 129 | #define encode_symlink_maxsz (op_encode_hdr_maxsz + \ | 129 | #define encode_symlink_maxsz (op_encode_hdr_maxsz + \ |
| 130 | 1 + nfs4_name_maxsz + \ | 130 | 1 + nfs4_name_maxsz + \ |
| 131 | nfs4_path_maxsz + \ | 131 | 1 + \ |
| 132 | nfs4_fattr_maxsz) | 132 | nfs4_fattr_maxsz) |
| 133 | #define decode_symlink_maxsz (op_decode_hdr_maxsz + 8) | 133 | #define decode_symlink_maxsz (op_decode_hdr_maxsz + 8) |
| 134 | #define encode_create_maxsz (op_encode_hdr_maxsz + \ | 134 | #define encode_create_maxsz (op_encode_hdr_maxsz + \ |
| @@ -673,9 +673,9 @@ static int encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *c | |||
| 673 | 673 | ||
| 674 | switch (create->ftype) { | 674 | switch (create->ftype) { |
| 675 | case NF4LNK: | 675 | case NF4LNK: |
| 676 | RESERVE_SPACE(4 + create->u.symlink->len); | 676 | RESERVE_SPACE(4); |
| 677 | WRITE32(create->u.symlink->len); | 677 | WRITE32(create->u.symlink.len); |
| 678 | WRITEMEM(create->u.symlink->name, create->u.symlink->len); | 678 | xdr_write_pages(xdr, create->u.symlink.pages, 0, create->u.symlink.len); |
| 679 | break; | 679 | break; |
| 680 | 680 | ||
| 681 | case NF4BLK: case NF4CHR: | 681 | case NF4BLK: case NF4CHR: |
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index 0b507bf0f330..630e50647bbb 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c | |||
| @@ -425,8 +425,8 @@ nfs_proc_link(struct inode *inode, struct inode *dir, struct qstr *name) | |||
| 425 | } | 425 | } |
| 426 | 426 | ||
| 427 | static int | 427 | static int |
| 428 | nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct qstr *path, | 428 | nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page, |
| 429 | struct iattr *sattr) | 429 | unsigned int len, struct iattr *sattr) |
| 430 | { | 430 | { |
| 431 | struct nfs_fh fhandle; | 431 | struct nfs_fh fhandle; |
| 432 | struct nfs_fattr fattr; | 432 | struct nfs_fattr fattr; |
| @@ -434,8 +434,8 @@ nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct qstr *path, | |||
| 434 | .fromfh = NFS_FH(dir), | 434 | .fromfh = NFS_FH(dir), |
| 435 | .fromname = dentry->d_name.name, | 435 | .fromname = dentry->d_name.name, |
| 436 | .fromlen = dentry->d_name.len, | 436 | .fromlen = dentry->d_name.len, |
| 437 | .topath = path->name, | 437 | .pages = &page, |
| 438 | .tolen = path->len, | 438 | .pathlen = len, |
| 439 | .sattr = sattr | 439 | .sattr = sattr |
| 440 | }; | 440 | }; |
| 441 | struct rpc_message msg = { | 441 | struct rpc_message msg = { |
| @@ -444,11 +444,11 @@ nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct qstr *path, | |||
| 444 | }; | 444 | }; |
| 445 | int status; | 445 | int status; |
| 446 | 446 | ||
| 447 | if (path->len > NFS2_MAXPATHLEN) | 447 | if (len > NFS2_MAXPATHLEN) |
| 448 | return -ENAMETOOLONG; | 448 | return -ENAMETOOLONG; |
| 449 | 449 | ||
| 450 | dprintk("NFS call symlink %s -> %s\n", dentry->d_name.name, | 450 | dprintk("NFS call symlink %s\n", dentry->d_name.name); |
| 451 | path->name); | 451 | |
| 452 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); | 452 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); |
| 453 | nfs_mark_for_revalidate(dir); | 453 | nfs_mark_for_revalidate(dir); |
| 454 | 454 | ||
