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.5-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs

Pull NFS client bugfixes from Trond Myklebust:
"Highlights include:

- Fix a couple of mount regressions due to the recent cleanups.
- Fix an Oops in the open recovery code
- Fix an rpc_pipefs upcall hang that results from some of the net
namespace work from 3.4.x (stable kernel candidate).
- Fix a couple of write and o_direct regressions that were found at
last weeks Bakeathon testing event in Ann Arbor."

* tag 'nfs-for-3.5-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
NFS: add an endian notation for sparse
NFSv4.1: integer overflow in decode_cb_sequence_args()
rpc_pipefs: allow rpc_purge_list to take a NULL waitq pointer
NFSv4 do not send an empty SETATTR compound
NFSv2: EOF incorrectly set on short read
NFS: Use the NFS_DEFAULT_VERSION for v2 and v3 mounts
NFS: fix directio refcount bug on commit
NFSv4: Fix unnecessary delegation returns in nfs4_do_open
NFSv4.1: Convert another trivial printk into a dprintk
NFS4: Fix open bug when pnfs module blacklisted
NFS: Remove incorrect BUG_ON in nfs_found_client
NFS: Map minor mismatch error to protocol not support error.
NFS: Fix a commit bug
NFS4: Set parsed mount data version to 4
NFSv4.1: Ensure we clear session state flags after a session creation
NFSv4.1: Convert a trivial printk into a dprintk
NFSv4: Fix up decode_attr_mdsthreshold
NFSv4: Fix an Oops in the open recovery code
NFSv4.1: Fix a request leak on the back channel

+85 -46
+4 -4
fs/nfs/callback_xdr.c
··· 455 455 args->csa_nrclists = ntohl(*p++); 456 456 args->csa_rclists = NULL; 457 457 if (args->csa_nrclists) { 458 - args->csa_rclists = kmalloc(args->csa_nrclists * 459 - sizeof(*args->csa_rclists), 460 - GFP_KERNEL); 458 + args->csa_rclists = kmalloc_array(args->csa_nrclists, 459 + sizeof(*args->csa_rclists), 460 + GFP_KERNEL); 461 461 if (unlikely(args->csa_rclists == NULL)) 462 462 goto out; 463 463 ··· 696 696 const struct cb_sequenceres *res) 697 697 { 698 698 __be32 *p; 699 - unsigned status = res->csr_status; 699 + __be32 status = res->csr_status; 700 700 701 701 if (unlikely(status != 0)) 702 702 goto out;
-2
fs/nfs/client.c
··· 544 544 545 545 smp_rmb(); 546 546 547 - BUG_ON(clp->cl_cons_state != NFS_CS_READY); 548 - 549 547 dprintk("<-- %s found nfs_client %p for %s\n", 550 548 __func__, clp, cl_init->hostname ?: ""); 551 549 return clp;
+4 -4
fs/nfs/direct.c
··· 523 523 nfs_list_remove_request(req); 524 524 if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES) { 525 525 /* Note the rewrite will go through mds */ 526 - kref_get(&req->wb_kref); 527 526 nfs_mark_request_commit(req, NULL, &cinfo); 528 - } 527 + } else 528 + nfs_release_request(req); 529 529 nfs_unlock_and_release_request(req); 530 530 } 531 531 ··· 716 716 if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES) 717 717 bit = NFS_IOHDR_NEED_RESCHED; 718 718 else if (dreq->flags == 0) { 719 - memcpy(&dreq->verf, &req->wb_verf, 719 + memcpy(&dreq->verf, hdr->verf, 720 720 sizeof(dreq->verf)); 721 721 bit = NFS_IOHDR_NEED_COMMIT; 722 722 dreq->flags = NFS_ODIRECT_DO_COMMIT; 723 723 } else if (dreq->flags == NFS_ODIRECT_DO_COMMIT) { 724 - if (memcmp(&dreq->verf, &req->wb_verf, sizeof(dreq->verf))) { 724 + if (memcmp(&dreq->verf, hdr->verf, sizeof(dreq->verf))) { 725 725 dreq->flags = NFS_ODIRECT_RESCHED_WRITES; 726 726 bit = NFS_IOHDR_NEED_RESCHED; 727 727 } else
+1 -1
fs/nfs/nfs4_fs.h
··· 295 295 296 296 extern const struct nfs4_minor_version_ops *nfs_v4_minor_ops[]; 297 297 298 - extern const u32 nfs4_fattr_bitmap[2]; 298 + extern const u32 nfs4_fattr_bitmap[3]; 299 299 extern const u32 nfs4_statfs_bitmap[2]; 300 300 extern const u32 nfs4_pathconf_bitmap[2]; 301 301 extern const u32 nfs4_fsinfo_bitmap[3];
+34 -8
fs/nfs/nfs4proc.c
··· 105 105 return -EINVAL; 106 106 case -NFS4ERR_SHARE_DENIED: 107 107 return -EACCES; 108 + case -NFS4ERR_MINOR_VERS_MISMATCH: 109 + return -EPROTONOSUPPORT; 108 110 default: 109 111 dprintk("%s could not handle NFSv4 error %d\n", 110 112 __func__, -err); ··· 118 116 /* 119 117 * This is our standard bitmap for GETATTR requests. 120 118 */ 121 - const u32 nfs4_fattr_bitmap[2] = { 119 + const u32 nfs4_fattr_bitmap[3] = { 122 120 FATTR4_WORD0_TYPE 123 121 | FATTR4_WORD0_CHANGE 124 122 | FATTR4_WORD0_SIZE ··· 133 131 | FATTR4_WORD1_TIME_ACCESS 134 132 | FATTR4_WORD1_TIME_METADATA 135 133 | FATTR4_WORD1_TIME_MODIFY 134 + }; 135 + 136 + static const u32 nfs4_pnfs_open_bitmap[3] = { 137 + FATTR4_WORD0_TYPE 138 + | FATTR4_WORD0_CHANGE 139 + | FATTR4_WORD0_SIZE 140 + | FATTR4_WORD0_FSID 141 + | FATTR4_WORD0_FILEID, 142 + FATTR4_WORD1_MODE 143 + | FATTR4_WORD1_NUMLINKS 144 + | FATTR4_WORD1_OWNER 145 + | FATTR4_WORD1_OWNER_GROUP 146 + | FATTR4_WORD1_RAWDEV 147 + | FATTR4_WORD1_SPACE_USED 148 + | FATTR4_WORD1_TIME_ACCESS 149 + | FATTR4_WORD1_TIME_METADATA 150 + | FATTR4_WORD1_TIME_MODIFY, 151 + FATTR4_WORD2_MDSTHRESHOLD 136 152 }; 137 153 138 154 const u32 nfs4_statfs_bitmap[2] = { ··· 864 844 p->o_arg.name = &dentry->d_name; 865 845 p->o_arg.server = server; 866 846 p->o_arg.bitmask = server->attr_bitmask; 847 + p->o_arg.open_bitmap = &nfs4_fattr_bitmap[0]; 867 848 p->o_arg.claim = NFS4_OPEN_CLAIM_NULL; 868 849 if (attrs != NULL && attrs->ia_valid != 0) { 869 850 __be32 verf[2]; ··· 1841 1820 opendata->f_attr.mdsthreshold = pnfs_mdsthreshold_alloc(); 1842 1821 if (!opendata->f_attr.mdsthreshold) 1843 1822 goto err_opendata_put; 1823 + opendata->o_arg.open_bitmap = &nfs4_pnfs_open_bitmap[0]; 1844 1824 } 1845 1825 if (dentry->d_inode != NULL) 1846 1826 opendata->state = nfs4_get_open_state(dentry->d_inode, sp); ··· 1902 1880 struct nfs4_state *res; 1903 1881 int status; 1904 1882 1883 + fmode &= FMODE_READ|FMODE_WRITE; 1905 1884 do { 1906 1885 status = _nfs4_do_open(dir, dentry, fmode, flags, sattr, cred, 1907 1886 &res, ctx_th); ··· 2549 2526 2550 2527 nfs_fattr_init(fattr); 2551 2528 2529 + /* Deal with open(O_TRUNC) */ 2530 + if (sattr->ia_valid & ATTR_OPEN) 2531 + sattr->ia_valid &= ~(ATTR_MTIME|ATTR_CTIME|ATTR_OPEN); 2532 + 2533 + /* Optimization: if the end result is no change, don't RPC */ 2534 + if ((sattr->ia_valid & ~(ATTR_FILE)) == 0) 2535 + return 0; 2536 + 2552 2537 /* Search for an existing open(O_WRITE) file */ 2553 2538 if (sattr->ia_valid & ATTR_FILE) { 2554 2539 struct nfs_open_context *ctx; ··· 2567 2536 state = ctx->state; 2568 2537 } 2569 2538 } 2570 - 2571 - /* Deal with open(O_TRUNC) */ 2572 - if (sattr->ia_valid & ATTR_OPEN) 2573 - sattr->ia_valid &= ~(ATTR_MTIME|ATTR_CTIME|ATTR_OPEN); 2574 2539 2575 2540 status = nfs4_do_setattr(inode, cred, fattr, sattr, state); 2576 2541 if (status == 0) ··· 5302 5275 5303 5276 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 5304 5277 if (status) 5305 - pr_warn("NFS: Got error %d from the server %s on " 5278 + dprintk("NFS: Got error %d from the server %s on " 5306 5279 "DESTROY_CLIENTID.", status, clp->cl_hostname); 5307 5280 return status; 5308 5281 } ··· 5773 5746 status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 5774 5747 5775 5748 if (status) 5776 - printk(KERN_WARNING 5777 - "NFS: Got error %d from the server on DESTROY_SESSION. " 5749 + dprintk("NFS: Got error %d from the server on DESTROY_SESSION. " 5778 5750 "Session has been destroyed regardless...\n", status); 5779 5751 5780 5752 dprintk("<-- nfs4_proc_destroy_session\n");
+12 -10
fs/nfs/nfs4state.c
··· 244 244 return nfs4_wait_on_slot_tbl(&ses->fc_slot_table); 245 245 } 246 246 247 + static void nfs41_finish_session_reset(struct nfs_client *clp) 248 + { 249 + clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); 250 + clear_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state); 251 + /* create_session negotiated new slot table */ 252 + clear_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state); 253 + clear_bit(NFS4CLNT_BIND_CONN_TO_SESSION, &clp->cl_state); 254 + nfs41_setup_state_renewal(clp); 255 + } 256 + 247 257 int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred) 248 258 { 249 259 int status; ··· 269 259 status = nfs4_proc_create_session(clp, cred); 270 260 if (status != 0) 271 261 goto out; 272 - clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); 273 - nfs41_setup_state_renewal(clp); 262 + nfs41_finish_session_reset(clp); 274 263 nfs_mark_client_ready(clp, NFS_CS_READY); 275 264 out: 276 265 return status; ··· 1781 1772 status = nfs4_handle_reclaim_lease_error(clp, status); 1782 1773 goto out; 1783 1774 } 1784 - clear_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state); 1785 - /* create_session negotiated new slot table */ 1786 - clear_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state); 1787 - clear_bit(NFS4CLNT_BIND_CONN_TO_SESSION, &clp->cl_state); 1775 + nfs41_finish_session_reset(clp); 1788 1776 dprintk("%s: session reset was successful for server %s!\n", 1789 1777 __func__, clp->cl_hostname); 1790 - 1791 - /* Let the state manager reestablish state */ 1792 - if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) 1793 - nfs41_setup_state_renewal(clp); 1794 1778 out: 1795 1779 if (cred) 1796 1780 put_rpccred(cred);
+10 -5
fs/nfs/nfs4xdr.c
··· 1198 1198 } 1199 1199 1200 1200 static void encode_getfattr_open(struct xdr_stream *xdr, const u32 *bitmask, 1201 + const u32 *open_bitmap, 1201 1202 struct compound_hdr *hdr) 1202 1203 { 1203 1204 encode_getattr_three(xdr, 1204 - bitmask[0] & nfs4_fattr_bitmap[0], 1205 - bitmask[1] & nfs4_fattr_bitmap[1], 1206 - bitmask[2] & FATTR4_WORD2_MDSTHRESHOLD, 1205 + bitmask[0] & open_bitmap[0], 1206 + bitmask[1] & open_bitmap[1], 1207 + bitmask[2] & open_bitmap[2], 1207 1208 hdr); 1208 1209 } 1209 1210 ··· 2222 2221 encode_putfh(xdr, args->fh, &hdr); 2223 2222 encode_open(xdr, args, &hdr); 2224 2223 encode_getfh(xdr, &hdr); 2225 - encode_getfattr_open(xdr, args->bitmask, &hdr); 2224 + encode_getfattr_open(xdr, args->bitmask, args->open_bitmap, &hdr); 2226 2225 encode_nops(&hdr); 2227 2226 } 2228 2227 ··· 4360 4359 4361 4360 if (unlikely(bitmap[2] & (FATTR4_WORD2_MDSTHRESHOLD - 1U))) 4362 4361 return -EIO; 4363 - if (likely(bitmap[2] & FATTR4_WORD2_MDSTHRESHOLD)) { 4362 + if (bitmap[2] & FATTR4_WORD2_MDSTHRESHOLD) { 4363 + /* Did the server return an unrequested attribute? */ 4364 + if (unlikely(res == NULL)) 4365 + return -EREMOTEIO; 4364 4366 p = xdr_inline_decode(xdr, 4); 4365 4367 if (unlikely(!p)) 4366 4368 goto out_overflow; ··· 4376 4372 __func__); 4377 4373 4378 4374 status = decode_first_threshold_item4(xdr, res); 4375 + bitmap[2] &= ~FATTR4_WORD2_MDSTHRESHOLD; 4379 4376 } 4380 4377 return status; 4381 4378 out_overflow:
+1 -1
fs/nfs/pnfs.h
··· 365 365 pnfs_use_threshold(struct nfs4_threshold **dst, struct nfs4_threshold *src, 366 366 struct nfs_server *nfss) 367 367 { 368 - return (dst && src && src->bm != 0 && 368 + return (dst && src && src->bm != 0 && nfss->pnfs_curr_ld && 369 369 nfss->pnfs_curr_ld->id == src->l_type); 370 370 } 371 371
+1 -1
fs/nfs/proc.c
··· 651 651 /* Emulate the eof flag, which isn't normally needed in NFSv2 652 652 * as it is guaranteed to always return the file attributes 653 653 */ 654 - if (data->args.offset + data->args.count >= data->res.fattr->size) 654 + if (data->args.offset + data->res.count >= data->res.fattr->size) 655 655 data->res.eof = 1; 656 656 } 657 657 return 0;
+3
fs/nfs/super.c
··· 1867 1867 if (data == NULL) 1868 1868 goto out_no_data; 1869 1869 1870 + args->version = NFS_DEFAULT_VERSION; 1870 1871 switch (data->version) { 1871 1872 case 1: 1872 1873 data->namlen = 0; ··· 2637 2636 2638 2637 if (data == NULL) 2639 2638 goto out_no_data; 2639 + 2640 + args->version = 4; 2640 2641 2641 2642 switch (data->version) { 2642 2643 case 1:
+4 -3
fs/nfs/write.c
··· 80 80 INIT_LIST_HEAD(&hdr->rpc_list); 81 81 spin_lock_init(&hdr->lock); 82 82 atomic_set(&hdr->refcnt, 0); 83 + hdr->verf = &p->verf; 83 84 } 84 85 return p; 85 86 } ··· 620 619 goto next; 621 620 } 622 621 if (test_bit(NFS_IOHDR_NEED_COMMIT, &hdr->flags)) { 622 + memcpy(&req->wb_verf, hdr->verf, sizeof(req->wb_verf)); 623 623 nfs_mark_request_commit(req, hdr->lseg, &cinfo); 624 624 goto next; 625 625 } ··· 1257 1255 struct nfs_write_data *data = calldata; 1258 1256 struct nfs_pgio_header *hdr = data->header; 1259 1257 int status = data->task.tk_status; 1260 - struct nfs_page *req = hdr->req; 1261 1258 1262 1259 if ((status >= 0) && nfs_write_need_commit(data)) { 1263 1260 spin_lock(&hdr->lock); 1264 1261 if (test_bit(NFS_IOHDR_NEED_RESCHED, &hdr->flags)) 1265 1262 ; /* Do nothing */ 1266 1263 else if (!test_and_set_bit(NFS_IOHDR_NEED_COMMIT, &hdr->flags)) 1267 - memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf)); 1268 - else if (memcmp(&req->wb_verf, &data->verf, sizeof(req->wb_verf))) 1264 + memcpy(hdr->verf, &data->verf, sizeof(*hdr->verf)); 1265 + else if (memcmp(hdr->verf, &data->verf, sizeof(*hdr->verf))) 1269 1266 set_bit(NFS_IOHDR_NEED_RESCHED, &hdr->flags); 1270 1267 spin_unlock(&hdr->lock); 1271 1268 }
+3
include/linux/nfs_xdr.h
··· 348 348 const struct qstr * name; 349 349 const struct nfs_server *server; /* Needed for ID mapping */ 350 350 const u32 * bitmask; 351 + const u32 * open_bitmap; 351 352 __u32 claim; 352 353 struct nfs4_sequence_args seq_args; 353 354 }; ··· 1237 1236 struct list_head rpc_list; 1238 1237 atomic_t refcnt; 1239 1238 struct nfs_page *req; 1239 + struct nfs_writeverf *verf; 1240 1240 struct pnfs_layout_segment *lseg; 1241 1241 loff_t io_start; 1242 1242 const struct rpc_call_ops *mds_ops; ··· 1275 1273 struct nfs_write_header { 1276 1274 struct nfs_pgio_header header; 1277 1275 struct nfs_write_data rpc_data; 1276 + struct nfs_writeverf verf; 1278 1277 }; 1279 1278 1280 1279 struct nfs_mds_commit_info {
+6 -6
net/sunrpc/rpc_pipe.c
··· 71 71 msg->errno = err; 72 72 destroy_msg(msg); 73 73 } while (!list_empty(head)); 74 - wake_up(waitq); 74 + 75 + if (waitq) 76 + wake_up(waitq); 75 77 } 76 78 77 79 static void ··· 93 91 } 94 92 dentry = dget(pipe->dentry); 95 93 spin_unlock(&pipe->lock); 96 - if (dentry) { 97 - rpc_purge_list(&RPC_I(dentry->d_inode)->waitq, 98 - &free_list, destroy_msg, -ETIMEDOUT); 99 - dput(dentry); 100 - } 94 + rpc_purge_list(dentry ? &RPC_I(dentry->d_inode)->waitq : NULL, 95 + &free_list, destroy_msg, -ETIMEDOUT); 96 + dput(dentry); 101 97 } 102 98 103 99 ssize_t rpc_pipe_generic_upcall(struct file *filp, struct rpc_pipe_msg *msg,
+2 -1
net/sunrpc/svc.c
··· 1374 1374 sizeof(req->rq_snd_buf)); 1375 1375 return bc_send(req); 1376 1376 } else { 1377 - /* Nothing to do to drop request */ 1377 + /* drop request */ 1378 + xprt_free_bc_request(req); 1378 1379 return 0; 1379 1380 } 1380 1381 }