Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'nfs-for-3.6-4' of git://git.linux-nfs.org/projects/trondmy/linux-nfs

Pull NFS client bugfixes from Trond Myklebust:

- Final (hopefully) fix for the range checking code in NFSv4 getacl.
This should fix the Oopses being seen when the acl size is close to
PAGE_SIZE.
- Fix a regression with the legacy binary mount code
- Fix a regression in the readdir cookieverf initialisation
- Fix an RPC over UDP regression
- Ensure that we report all errors in the NFSv4 open code
- Ensure that fsync() reports all relevant synchronisation errors.

* tag 'nfs-for-3.6-4' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
NFS: fsync() must exit with an error if page writeback failed
SUNRPC: Fix a UDP transport regression
NFS: return error from decode_getfh in decode open
NFSv4: Fix buffer overflow checking in __nfs4_get_acl_uncached
NFSv4: Fix range checking in __nfs4_get_acl_uncached and __nfs4_proc_set_acl
NFS: Fix a problem with the legacy binary mount code
NFS: Fix the initialisation of the readdir 'cookieverf' array

+70 -64
+3 -1
fs/nfs/file.c
··· 287 287 struct inode *inode = file->f_path.dentry->d_inode; 288 288 289 289 ret = filemap_write_and_wait_range(inode->i_mapping, start, end); 290 + if (ret != 0) 291 + goto out; 290 292 mutex_lock(&inode->i_mutex); 291 293 ret = nfs_file_fsync_commit(file, start, end, datasync); 292 294 mutex_unlock(&inode->i_mutex); 293 - 295 + out: 294 296 return ret; 295 297 } 296 298
+1 -1
fs/nfs/inode.c
··· 154 154 nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); 155 155 nfsi->attrtimeo_timestamp = jiffies; 156 156 157 - memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); 157 + memset(NFS_I(inode)->cookieverf, 0, sizeof(NFS_I(inode)->cookieverf)); 158 158 if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) 159 159 nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; 160 160 else
+1 -1
fs/nfs/nfs3proc.c
··· 643 643 u64 cookie, struct page **pages, unsigned int count, int plus) 644 644 { 645 645 struct inode *dir = dentry->d_inode; 646 - __be32 *verf = NFS_COOKIEVERF(dir); 646 + __be32 *verf = NFS_I(dir)->cookieverf; 647 647 struct nfs3_readdirargs arg = { 648 648 .fh = NFS_FH(dir), 649 649 .cookie = cookie,
+3 -1
fs/nfs/nfs4file.c
··· 96 96 struct inode *inode = file->f_path.dentry->d_inode; 97 97 98 98 ret = filemap_write_and_wait_range(inode->i_mapping, start, end); 99 + if (ret != 0) 100 + goto out; 99 101 mutex_lock(&inode->i_mutex); 100 102 ret = nfs_file_fsync_commit(file, start, end, datasync); 101 103 if (!ret && !datasync) 102 104 /* application has asked for meta-data sync */ 103 105 ret = pnfs_layoutcommit_inode(inode, true); 104 106 mutex_unlock(&inode->i_mutex); 105 - 107 + out: 106 108 return ret; 107 109 } 108 110
+25 -30
fs/nfs/nfs4proc.c
··· 3215 3215 dentry->d_parent->d_name.name, 3216 3216 dentry->d_name.name, 3217 3217 (unsigned long long)cookie); 3218 - nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args); 3218 + nfs4_setup_readdir(cookie, NFS_I(dir)->cookieverf, dentry, &args); 3219 3219 res.pgbase = args.pgbase; 3220 3220 status = nfs4_call_sync(NFS_SERVER(dir)->client, NFS_SERVER(dir), &msg, &args.seq_args, &res.seq_res, 0); 3221 3221 if (status >= 0) { 3222 - memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE); 3222 + memcpy(NFS_I(dir)->cookieverf, res.verifier.data, NFS4_VERIFIER_SIZE); 3223 3223 status += args.pgbase; 3224 3224 } 3225 3225 ··· 3653 3653 && (server->acl_bitmask & ACL4_SUPPORT_DENY_ACL); 3654 3654 } 3655 3655 3656 - /* Assuming that XATTR_SIZE_MAX is a multiple of PAGE_CACHE_SIZE, and that 3657 - * it's OK to put sizeof(void) * (XATTR_SIZE_MAX/PAGE_CACHE_SIZE) bytes on 3656 + /* Assuming that XATTR_SIZE_MAX is a multiple of PAGE_SIZE, and that 3657 + * it's OK to put sizeof(void) * (XATTR_SIZE_MAX/PAGE_SIZE) bytes on 3658 3658 * the stack. 3659 3659 */ 3660 - #define NFS4ACL_MAXPAGES (XATTR_SIZE_MAX >> PAGE_CACHE_SHIFT) 3660 + #define NFS4ACL_MAXPAGES DIV_ROUND_UP(XATTR_SIZE_MAX, PAGE_SIZE) 3661 3661 3662 3662 static int buf_to_pages_noslab(const void *buf, size_t buflen, 3663 3663 struct page **pages, unsigned int *pgbase) ··· 3668 3668 spages = pages; 3669 3669 3670 3670 do { 3671 - len = min_t(size_t, PAGE_CACHE_SIZE, buflen); 3671 + len = min_t(size_t, PAGE_SIZE, buflen); 3672 3672 newpage = alloc_page(GFP_KERNEL); 3673 3673 3674 3674 if (newpage == NULL) ··· 3739 3739 struct nfs4_cached_acl *acl; 3740 3740 size_t buflen = sizeof(*acl) + acl_len; 3741 3741 3742 - if (pages && buflen <= PAGE_SIZE) { 3742 + if (buflen <= PAGE_SIZE) { 3743 3743 acl = kmalloc(buflen, GFP_KERNEL); 3744 3744 if (acl == NULL) 3745 3745 goto out; ··· 3782 3782 .rpc_argp = &args, 3783 3783 .rpc_resp = &res, 3784 3784 }; 3785 - int ret = -ENOMEM, npages, i; 3786 - size_t acl_len = 0; 3785 + unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE); 3786 + int ret = -ENOMEM, i; 3787 3787 3788 - npages = (buflen + PAGE_SIZE - 1) >> PAGE_SHIFT; 3789 3788 /* As long as we're doing a round trip to the server anyway, 3790 3789 * let's be prepared for a page of acl data. */ 3791 3790 if (npages == 0) 3792 3791 npages = 1; 3793 - 3794 - /* Add an extra page to handle the bitmap returned */ 3795 - npages++; 3792 + if (npages > ARRAY_SIZE(pages)) 3793 + return -ERANGE; 3796 3794 3797 3795 for (i = 0; i < npages; i++) { 3798 3796 pages[i] = alloc_page(GFP_KERNEL); ··· 3806 3808 args.acl_len = npages * PAGE_SIZE; 3807 3809 args.acl_pgbase = 0; 3808 3810 3809 - /* Let decode_getfacl know not to fail if the ACL data is larger than 3810 - * the page we send as a guess */ 3811 - if (buf == NULL) 3812 - res.acl_flags |= NFS4_ACL_LEN_REQUEST; 3813 - 3814 3811 dprintk("%s buf %p buflen %zu npages %d args.acl_len %zu\n", 3815 3812 __func__, buf, buflen, npages, args.acl_len); 3816 3813 ret = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode), ··· 3813 3820 if (ret) 3814 3821 goto out_free; 3815 3822 3816 - acl_len = res.acl_len; 3817 - if (acl_len > args.acl_len) 3818 - nfs4_write_cached_acl(inode, NULL, 0, acl_len); 3819 - else 3820 - nfs4_write_cached_acl(inode, pages, res.acl_data_offset, 3821 - acl_len); 3822 - if (buf) { 3823 + /* Handle the case where the passed-in buffer is too short */ 3824 + if (res.acl_flags & NFS4_ACL_TRUNC) { 3825 + /* Did the user only issue a request for the acl length? */ 3826 + if (buf == NULL) 3827 + goto out_ok; 3823 3828 ret = -ERANGE; 3824 - if (acl_len > buflen) 3825 - goto out_free; 3826 - _copy_from_pages(buf, pages, res.acl_data_offset, 3827 - acl_len); 3829 + goto out_free; 3828 3830 } 3829 - ret = acl_len; 3831 + nfs4_write_cached_acl(inode, pages, res.acl_data_offset, res.acl_len); 3832 + if (buf) 3833 + _copy_from_pages(buf, pages, res.acl_data_offset, res.acl_len); 3834 + out_ok: 3835 + ret = res.acl_len; 3830 3836 out_free: 3831 3837 for (i = 0; i < npages; i++) 3832 3838 if (pages[i]) ··· 3883 3891 .rpc_argp = &arg, 3884 3892 .rpc_resp = &res, 3885 3893 }; 3894 + unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE); 3886 3895 int ret, i; 3887 3896 3888 3897 if (!nfs4_server_supports_acls(server)) 3889 3898 return -EOPNOTSUPP; 3899 + if (npages > ARRAY_SIZE(pages)) 3900 + return -ERANGE; 3890 3901 i = buf_to_pages_noslab(buf, buflen, arg.acl_pages, &arg.acl_pgbase); 3891 3902 if (i < 0) 3892 3903 return i;
+7 -10
fs/nfs/nfs4xdr.c
··· 5072 5072 * are stored with the acl data to handle the problem of 5073 5073 * variable length bitmaps.*/ 5074 5074 res->acl_data_offset = xdr_stream_pos(xdr) - pg_offset; 5075 - 5076 - /* We ignore &savep and don't do consistency checks on 5077 - * the attr length. Let userspace figure it out.... */ 5078 5075 res->acl_len = attrlen; 5079 - if (attrlen > (xdr->nwords << 2)) { 5080 - if (res->acl_flags & NFS4_ACL_LEN_REQUEST) { 5081 - /* getxattr interface called with a NULL buf */ 5082 - goto out; 5083 - } 5076 + 5077 + /* Check for receive buffer overflow */ 5078 + if (res->acl_len > (xdr->nwords << 2) || 5079 + res->acl_len + res->acl_data_offset > xdr->buf->page_len) { 5080 + res->acl_flags |= NFS4_ACL_TRUNC; 5084 5081 dprintk("NFS: acl reply: attrlen %u > page_len %u\n", 5085 5082 attrlen, xdr->nwords << 2); 5086 - return -EINVAL; 5087 5083 } 5088 5084 } else 5089 5085 status = -EOPNOTSUPP; ··· 6225 6229 status = decode_open(xdr, res); 6226 6230 if (status) 6227 6231 goto out; 6228 - if (decode_getfh(xdr, &res->fh) != 0) 6232 + status = decode_getfh(xdr, &res->fh); 6233 + if (status) 6229 6234 goto out; 6230 6235 decode_getfattr(xdr, res->f_attr, res->server); 6231 6236 out:
+2
fs/nfs/super.c
··· 1867 1867 1868 1868 memcpy(sap, &data->addr, sizeof(data->addr)); 1869 1869 args->nfs_server.addrlen = sizeof(data->addr); 1870 + args->nfs_server.port = ntohs(data->addr.sin_port); 1870 1871 if (!nfs_verify_server_address(sap)) 1871 1872 goto out_no_address; 1872 1873 ··· 2565 2564 return -EFAULT; 2566 2565 if (!nfs_verify_server_address(sap)) 2567 2566 goto out_no_address; 2567 + args->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port); 2568 2568 2569 2569 if (data->auth_flavourlen) { 2570 2570 if (data->auth_flavourlen > 1)
-5
include/linux/nfs_fs.h
··· 265 265 return NFS_SERVER(inode)->nfs_client->rpc_ops; 266 266 } 267 267 268 - static inline __be32 *NFS_COOKIEVERF(const struct inode *inode) 269 - { 270 - return NFS_I(inode)->cookieverf; 271 - } 272 - 273 268 static inline unsigned NFS_MINATTRTIMEO(const struct inode *inode) 274 269 { 275 270 struct nfs_server *nfss = NFS_SERVER(inode);
+1 -1
include/linux/nfs_xdr.h
··· 652 652 }; 653 653 654 654 /* getxattr ACL interface flags */ 655 - #define NFS4_ACL_LEN_REQUEST 0x0001 /* zero length getxattr buffer */ 655 + #define NFS4_ACL_TRUNC 0x0001 /* ACL was truncated */ 656 656 struct nfs_getaclres { 657 657 size_t acl_len; 658 658 size_t acl_data_offset;
+3
include/linux/sunrpc/xprt.h
··· 114 114 void (*set_buffer_size)(struct rpc_xprt *xprt, size_t sndsize, size_t rcvsize); 115 115 int (*reserve_xprt)(struct rpc_xprt *xprt, struct rpc_task *task); 116 116 void (*release_xprt)(struct rpc_xprt *xprt, struct rpc_task *task); 117 + void (*alloc_slot)(struct rpc_xprt *xprt, struct rpc_task *task); 117 118 void (*rpcbind)(struct rpc_task *task); 118 119 void (*set_port)(struct rpc_xprt *xprt, unsigned short port); 119 120 void (*connect)(struct rpc_task *task); ··· 282 281 void xprt_reserve(struct rpc_task *task); 283 282 int xprt_reserve_xprt(struct rpc_xprt *xprt, struct rpc_task *task); 284 283 int xprt_reserve_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task); 284 + void xprt_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task); 285 + void xprt_lock_and_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task); 285 286 int xprt_prepare_transmit(struct rpc_task *task); 286 287 void xprt_transmit(struct rpc_task *task); 287 288 void xprt_end_transmit(struct rpc_task *task);
+20 -14
net/sunrpc/xprt.c
··· 969 969 return false; 970 970 } 971 971 972 - static void xprt_alloc_slot(struct rpc_task *task) 972 + void xprt_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task) 973 973 { 974 - struct rpc_xprt *xprt = task->tk_xprt; 975 974 struct rpc_rqst *req; 976 975 976 + spin_lock(&xprt->reserve_lock); 977 977 if (!list_empty(&xprt->free)) { 978 978 req = list_entry(xprt->free.next, struct rpc_rqst, rq_list); 979 979 list_del(&req->rq_list); ··· 994 994 default: 995 995 task->tk_status = -EAGAIN; 996 996 } 997 + spin_unlock(&xprt->reserve_lock); 997 998 return; 998 999 out_init_req: 999 1000 task->tk_status = 0; 1000 1001 task->tk_rqstp = req; 1001 1002 xprt_request_init(task, xprt); 1003 + spin_unlock(&xprt->reserve_lock); 1002 1004 } 1005 + EXPORT_SYMBOL_GPL(xprt_alloc_slot); 1006 + 1007 + void xprt_lock_and_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task) 1008 + { 1009 + /* Note: grabbing the xprt_lock_write() ensures that we throttle 1010 + * new slot allocation if the transport is congested (i.e. when 1011 + * reconnecting a stream transport or when out of socket write 1012 + * buffer space). 1013 + */ 1014 + if (xprt_lock_write(xprt, task)) { 1015 + xprt_alloc_slot(xprt, task); 1016 + xprt_release_write(xprt, task); 1017 + } 1018 + } 1019 + EXPORT_SYMBOL_GPL(xprt_lock_and_alloc_slot); 1003 1020 1004 1021 static void xprt_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req) 1005 1022 { ··· 1100 1083 if (task->tk_rqstp != NULL) 1101 1084 return; 1102 1085 1103 - /* Note: grabbing the xprt_lock_write() here is not strictly needed, 1104 - * but ensures that we throttle new slot allocation if the transport 1105 - * is congested (e.g. if reconnecting or if we're out of socket 1106 - * write buffer space). 1107 - */ 1108 1086 task->tk_timeout = 0; 1109 1087 task->tk_status = -EAGAIN; 1110 - if (!xprt_lock_write(xprt, task)) 1111 - return; 1112 - 1113 - spin_lock(&xprt->reserve_lock); 1114 - xprt_alloc_slot(task); 1115 - spin_unlock(&xprt->reserve_lock); 1116 - xprt_release_write(xprt, task); 1088 + xprt->ops->alloc_slot(xprt, task); 1117 1089 } 1118 1090 1119 1091 static inline __be32 xprt_alloc_xid(struct rpc_xprt *xprt)
+1
net/sunrpc/xprtrdma/transport.c
··· 713 713 static struct rpc_xprt_ops xprt_rdma_procs = { 714 714 .reserve_xprt = xprt_rdma_reserve_xprt, 715 715 .release_xprt = xprt_release_xprt_cong, /* sunrpc/xprt.c */ 716 + .alloc_slot = xprt_alloc_slot, 716 717 .release_request = xprt_release_rqst_cong, /* ditto */ 717 718 .set_retrans_timeout = xprt_set_retrans_timeout_def, /* ditto */ 718 719 .rpcbind = rpcb_getport_async, /* sunrpc/rpcb_clnt.c */
+3
net/sunrpc/xprtsock.c
··· 2473 2473 static struct rpc_xprt_ops xs_local_ops = { 2474 2474 .reserve_xprt = xprt_reserve_xprt, 2475 2475 .release_xprt = xs_tcp_release_xprt, 2476 + .alloc_slot = xprt_alloc_slot, 2476 2477 .rpcbind = xs_local_rpcbind, 2477 2478 .set_port = xs_local_set_port, 2478 2479 .connect = xs_connect, ··· 2490 2489 .set_buffer_size = xs_udp_set_buffer_size, 2491 2490 .reserve_xprt = xprt_reserve_xprt_cong, 2492 2491 .release_xprt = xprt_release_xprt_cong, 2492 + .alloc_slot = xprt_alloc_slot, 2493 2493 .rpcbind = rpcb_getport_async, 2494 2494 .set_port = xs_set_port, 2495 2495 .connect = xs_connect, ··· 2508 2506 static struct rpc_xprt_ops xs_tcp_ops = { 2509 2507 .reserve_xprt = xprt_reserve_xprt, 2510 2508 .release_xprt = xs_tcp_release_xprt, 2509 + .alloc_slot = xprt_lock_and_alloc_slot, 2511 2510 .rpcbind = rpcb_getport_async, 2512 2511 .set_port = xs_set_port, 2513 2512 .connect = xs_connect,