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

Merge tag 'nfs-for-3.9-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs

Pull NFS client bugfixes from Trond Myklebust:
"We've just concluded another Connectathon interoperability testing
week, and so here are the fixes for the bugs that were discovered:

- Don't allow NFS silly-renamed files to be deleted
- Don't start the retransmission timer when out of socket space
- Fix a couple of pnfs-related Oopses.
- Fix one more NFSv4 state recovery deadlock
- Don't loop forever when LAYOUTGET returns NFS4ERR_LAYOUTTRYLATER"

* tag 'nfs-for-3.9-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
SUNRPC: One line comment fix
NFSv4.1: LAYOUTGET EDELAY loops timeout to the MDS
SUNRPC: add call to get configured timeout
PNFS: set the default DS timeout to 60 seconds
NFSv4: Fix another open/open_recovery deadlock
nfs: don't allow nfs_find_actor to match inodes of the wrong type
NFSv4.1: Hold reference to layout hdr in layoutget
pnfs: fix resend_to_mds for directio
SUNRPC: Don't start the retransmission timer when out of socket space
NFS: Don't allow NFS silly-renamed files to be deleted, no signal

+77 -24
+2
fs/nfs/inode.c
··· 237 237 238 238 if (NFS_FILEID(inode) != fattr->fileid) 239 239 return 0; 240 + if ((S_IFMT & inode->i_mode) != (S_IFMT & fattr->mode)) 241 + return 0; 240 242 if (nfs_compare_fh(NFS_FH(inode), fh)) 241 243 return 0; 242 244 if (is_bad_inode(inode) || NFS_STALE(inode))
+4 -2
fs/nfs/nfs4filelayout.c
··· 99 99 100 100 task->tk_status = pnfs_write_done_resend_to_mds(hdr->inode, 101 101 &hdr->pages, 102 - hdr->completion_ops); 102 + hdr->completion_ops, 103 + hdr->dreq); 103 104 } 104 105 } 105 106 ··· 120 119 121 120 task->tk_status = pnfs_read_done_resend_to_mds(hdr->inode, 122 121 &hdr->pages, 123 - hdr->completion_ops); 122 + hdr->completion_ops, 123 + hdr->dreq); 124 124 } 125 125 } 126 126
+1 -1
fs/nfs/nfs4filelayout.h
··· 36 36 * Default data server connection timeout and retrans vaules. 37 37 * Set by module paramters dataserver_timeo and dataserver_retrans. 38 38 */ 39 - #define NFS4_DEF_DS_TIMEO 60 39 + #define NFS4_DEF_DS_TIMEO 600 /* in tenths of a second */ 40 40 #define NFS4_DEF_DS_RETRANS 5 41 41 42 42 /*
+18 -3
fs/nfs/nfs4proc.c
··· 93 93 return err; 94 94 switch (err) { 95 95 case -NFS4ERR_RESOURCE: 96 + case -NFS4ERR_LAYOUTTRYLATER: 97 + case -NFS4ERR_RECALLCONFLICT: 96 98 return -EREMOTEIO; 97 99 case -NFS4ERR_WRONGSEC: 98 100 return -EPERM; ··· 1160 1158 data->o_arg.fmode); 1161 1159 iput(inode); 1162 1160 out: 1161 + nfs_release_seqid(data->o_arg.seqid); 1163 1162 return state; 1164 1163 err_put_inode: 1165 1164 iput(inode); ··· 6048 6045 struct nfs_server *server = NFS_SERVER(inode); 6049 6046 struct pnfs_layout_hdr *lo; 6050 6047 struct nfs4_state *state = NULL; 6048 + unsigned long timeo, giveup; 6051 6049 6052 6050 dprintk("--> %s\n", __func__); 6053 6051 ··· 6060 6056 goto out; 6061 6057 case -NFS4ERR_LAYOUTTRYLATER: 6062 6058 case -NFS4ERR_RECALLCONFLICT: 6063 - task->tk_status = -NFS4ERR_DELAY; 6059 + timeo = rpc_get_timeout(task->tk_client); 6060 + giveup = lgp->args.timestamp + timeo; 6061 + if (time_after(giveup, jiffies)) 6062 + task->tk_status = -NFS4ERR_DELAY; 6064 6063 break; 6065 6064 case -NFS4ERR_EXPIRED: 6066 6065 case -NFS4ERR_BAD_STATEID: ··· 6136 6129 static void nfs4_layoutget_release(void *calldata) 6137 6130 { 6138 6131 struct nfs4_layoutget *lgp = calldata; 6139 - struct nfs_server *server = NFS_SERVER(lgp->args.inode); 6132 + struct inode *inode = lgp->args.inode; 6133 + struct nfs_server *server = NFS_SERVER(inode); 6140 6134 size_t max_pages = max_response_pages(server); 6141 6135 6142 6136 dprintk("--> %s\n", __func__); 6143 6137 nfs4_free_pages(lgp->args.layout.pages, max_pages); 6138 + pnfs_put_layout_hdr(NFS_I(inode)->layout); 6144 6139 put_nfs_open_context(lgp->args.ctx); 6145 6140 kfree(calldata); 6146 6141 dprintk("<-- %s\n", __func__); ··· 6157 6148 struct pnfs_layout_segment * 6158 6149 nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags) 6159 6150 { 6160 - struct nfs_server *server = NFS_SERVER(lgp->args.inode); 6151 + struct inode *inode = lgp->args.inode; 6152 + struct nfs_server *server = NFS_SERVER(inode); 6161 6153 size_t max_pages = max_response_pages(server); 6162 6154 struct rpc_task *task; 6163 6155 struct rpc_message msg = { ··· 6184 6174 return ERR_PTR(-ENOMEM); 6185 6175 } 6186 6176 lgp->args.layout.pglen = max_pages * PAGE_SIZE; 6177 + lgp->args.timestamp = jiffies; 6187 6178 6188 6179 lgp->res.layoutp = &lgp->args.layout; 6189 6180 lgp->res.seq_res.sr_slot = NULL; 6190 6181 nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0); 6182 + 6183 + /* nfs4_layoutget_release calls pnfs_put_layout_hdr */ 6184 + pnfs_get_layout_hdr(NFS_I(inode)->layout); 6185 + 6191 6186 task = rpc_run_task(&task_setup_data); 6192 6187 if (IS_ERR(task)) 6193 6188 return ERR_CAST(task);
+13 -8
fs/nfs/pnfs.c
··· 1181 1181 struct nfs_client *clp = server->nfs_client; 1182 1182 struct pnfs_layout_hdr *lo; 1183 1183 struct pnfs_layout_segment *lseg = NULL; 1184 - bool first = false; 1184 + bool first; 1185 1185 1186 1186 if (!pnfs_enabled_sb(NFS_SERVER(ino))) 1187 1187 goto out; ··· 1215 1215 goto out_unlock; 1216 1216 atomic_inc(&lo->plh_outstanding); 1217 1217 1218 - if (list_empty(&lo->plh_segs)) 1219 - first = true; 1220 - 1218 + first = list_empty(&lo->plh_layouts) ? true : false; 1221 1219 spin_unlock(&ino->i_lock); 1220 + 1222 1221 if (first) { 1223 1222 /* The lo must be on the clp list if there is any 1224 1223 * chance of a CB_LAYOUTRECALL(FILE) coming in. ··· 1421 1422 1422 1423 int pnfs_write_done_resend_to_mds(struct inode *inode, 1423 1424 struct list_head *head, 1424 - const struct nfs_pgio_completion_ops *compl_ops) 1425 + const struct nfs_pgio_completion_ops *compl_ops, 1426 + struct nfs_direct_req *dreq) 1425 1427 { 1426 1428 struct nfs_pageio_descriptor pgio; 1427 1429 LIST_HEAD(failed); 1428 1430 1429 1431 /* Resend all requests through the MDS */ 1430 1432 nfs_pageio_init_write(&pgio, inode, FLUSH_STABLE, compl_ops); 1433 + pgio.pg_dreq = dreq; 1431 1434 while (!list_empty(head)) { 1432 1435 struct nfs_page *req = nfs_list_entry(head->next); 1433 1436 ··· 1464 1463 if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) 1465 1464 data->task.tk_status = pnfs_write_done_resend_to_mds(hdr->inode, 1466 1465 &hdr->pages, 1467 - hdr->completion_ops); 1466 + hdr->completion_ops, 1467 + hdr->dreq); 1468 1468 } 1469 1469 1470 1470 /* ··· 1580 1578 1581 1579 int pnfs_read_done_resend_to_mds(struct inode *inode, 1582 1580 struct list_head *head, 1583 - const struct nfs_pgio_completion_ops *compl_ops) 1581 + const struct nfs_pgio_completion_ops *compl_ops, 1582 + struct nfs_direct_req *dreq) 1584 1583 { 1585 1584 struct nfs_pageio_descriptor pgio; 1586 1585 LIST_HEAD(failed); 1587 1586 1588 1587 /* Resend all requests through the MDS */ 1589 1588 nfs_pageio_init_read(&pgio, inode, compl_ops); 1589 + pgio.pg_dreq = dreq; 1590 1590 while (!list_empty(head)) { 1591 1591 struct nfs_page *req = nfs_list_entry(head->next); 1592 1592 ··· 1619 1615 if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) 1620 1616 data->task.tk_status = pnfs_read_done_resend_to_mds(hdr->inode, 1621 1617 &hdr->pages, 1622 - hdr->completion_ops); 1618 + hdr->completion_ops, 1619 + hdr->dreq); 1623 1620 } 1624 1621 1625 1622 /*
+4 -2
fs/nfs/pnfs.h
··· 230 230 231 231 void nfs4_deviceid_mark_client_invalid(struct nfs_client *clp); 232 232 int pnfs_read_done_resend_to_mds(struct inode *inode, struct list_head *head, 233 - const struct nfs_pgio_completion_ops *compl_ops); 233 + const struct nfs_pgio_completion_ops *compl_ops, 234 + struct nfs_direct_req *dreq); 234 235 int pnfs_write_done_resend_to_mds(struct inode *inode, struct list_head *head, 235 - const struct nfs_pgio_completion_ops *compl_ops); 236 + const struct nfs_pgio_completion_ops *compl_ops, 237 + struct nfs_direct_req *dreq); 236 238 struct nfs4_threshold *pnfs_mdsthreshold_alloc(void); 237 239 238 240 /* nfs4_deviceid_flags */
+13 -7
fs/nfs/unlink.c
··· 335 335 struct inode *old_dir = data->old_dir; 336 336 struct inode *new_dir = data->new_dir; 337 337 struct dentry *old_dentry = data->old_dentry; 338 - struct dentry *new_dentry = data->new_dentry; 339 338 340 339 if (!NFS_PROTO(old_dir)->rename_done(task, old_dir, new_dir)) { 341 340 rpc_restart_call_prepare(task); 342 341 return; 343 342 } 344 343 345 - if (task->tk_status != 0) { 344 + if (task->tk_status != 0) 346 345 nfs_cancel_async_unlink(old_dentry); 347 - return; 348 - } 349 - 350 - d_drop(old_dentry); 351 - d_drop(new_dentry); 352 346 } 353 347 354 348 /** ··· 543 549 error = rpc_wait_for_completion_task(task); 544 550 if (error == 0) 545 551 error = task->tk_status; 552 + switch (error) { 553 + case 0: 554 + /* The rename succeeded */ 555 + nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 556 + d_move(dentry, sdentry); 557 + break; 558 + case -ERESTARTSYS: 559 + /* The result of the rename is unknown. Play it safe by 560 + * forcing a new lookup */ 561 + d_drop(dentry); 562 + d_drop(sdentry); 563 + } 546 564 rpc_put_task(task); 547 565 out_dput: 548 566 dput(sdentry);
+1
include/linux/nfs_xdr.h
··· 233 233 struct inode *inode; 234 234 struct nfs_open_context *ctx; 235 235 nfs4_stateid stateid; 236 + unsigned long timestamp; 236 237 struct nfs4_layoutdriver_data layout; 237 238 }; 238 239
+1
include/linux/sunrpc/clnt.h
··· 160 160 int rpc_protocol(struct rpc_clnt *); 161 161 struct net * rpc_net_ns(struct rpc_clnt *); 162 162 size_t rpc_max_payload(struct rpc_clnt *); 163 + unsigned long rpc_get_timeout(struct rpc_clnt *clnt); 163 164 void rpc_force_rebind(struct rpc_clnt *); 164 165 size_t rpc_peeraddr(struct rpc_clnt *, struct sockaddr *, size_t); 165 166 const char *rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t);
+15
net/sunrpc/clnt.c
··· 1197 1197 EXPORT_SYMBOL_GPL(rpc_max_payload); 1198 1198 1199 1199 /** 1200 + * rpc_get_timeout - Get timeout for transport in units of HZ 1201 + * @clnt: RPC client to query 1202 + */ 1203 + unsigned long rpc_get_timeout(struct rpc_clnt *clnt) 1204 + { 1205 + unsigned long ret; 1206 + 1207 + rcu_read_lock(); 1208 + ret = rcu_dereference(clnt->cl_xprt)->timeout->to_initval; 1209 + rcu_read_unlock(); 1210 + return ret; 1211 + } 1212 + EXPORT_SYMBOL_GPL(rpc_get_timeout); 1213 + 1214 + /** 1200 1215 * rpc_force_rebind - force transport to check that remote port is unchanged 1201 1216 * @clnt: client to rebind 1202 1217 *
+5 -1
net/sunrpc/xprt.c
··· 487 487 * xprt_wait_for_buffer_space - wait for transport output buffer to clear 488 488 * @task: task to be put to sleep 489 489 * @action: function pointer to be executed after wait 490 + * 491 + * Note that we only set the timer for the case of RPC_IS_SOFT(), since 492 + * we don't in general want to force a socket disconnection due to 493 + * an incomplete RPC call transmission. 490 494 */ 491 495 void xprt_wait_for_buffer_space(struct rpc_task *task, rpc_action action) 492 496 { 493 497 struct rpc_rqst *req = task->tk_rqstp; 494 498 struct rpc_xprt *xprt = req->rq_xprt; 495 499 496 - task->tk_timeout = req->rq_timeout; 500 + task->tk_timeout = RPC_IS_SOFT(task) ? req->rq_timeout : 0; 497 501 rpc_sleep_on(&xprt->pending, task, action); 498 502 } 499 503 EXPORT_SYMBOL_GPL(xprt_wait_for_buffer_space);