diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-03-02 16:46:07 -0800 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-03-02 16:46:07 -0800 | 
| commit | 8d05b3771da8775799673212b57d62f57c70d68a (patch) | |
| tree | ebce0455032cec54428227022c92a480fa726da0 /fs/nfs/nfs4proc.c | |
| parent | b695188dd39162a1a6bff11fdbcc4c0b65b933ab (diff) | |
| parent | 512e4b291c0e97af24619a91f3e8963697da00d8 (diff) | |
| download | olio-linux-3.10-8d05b3771da8775799673212b57d62f57c70d68a.tar.xz olio-linux-3.10-8d05b3771da8775799673212b57d62f57c70d68a.zip  | |
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
Diffstat (limited to 'fs/nfs/nfs4proc.c')
| -rw-r--r-- | fs/nfs/nfs4proc.c | 21 | 
1 files changed, 18 insertions, 3 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index eae83bf96c6..b2671cb0f90 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -93,6 +93,8 @@ static int nfs4_map_errors(int err)  		return err;  	switch (err) {  	case -NFS4ERR_RESOURCE: +	case -NFS4ERR_LAYOUTTRYLATER: +	case -NFS4ERR_RECALLCONFLICT:  		return -EREMOTEIO;  	case -NFS4ERR_WRONGSEC:  		return -EPERM; @@ -1158,6 +1160,7 @@ _nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data)  			data->o_arg.fmode);  	iput(inode);  out: +	nfs_release_seqid(data->o_arg.seqid);  	return state;  err_put_inode:  	iput(inode); @@ -6045,6 +6048,7 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata)  	struct nfs_server *server = NFS_SERVER(inode);  	struct pnfs_layout_hdr *lo;  	struct nfs4_state *state = NULL; +	unsigned long timeo, giveup;  	dprintk("--> %s\n", __func__); @@ -6056,7 +6060,10 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata)  		goto out;  	case -NFS4ERR_LAYOUTTRYLATER:  	case -NFS4ERR_RECALLCONFLICT: -		task->tk_status = -NFS4ERR_DELAY; +		timeo = rpc_get_timeout(task->tk_client); +		giveup = lgp->args.timestamp + timeo; +		if (time_after(giveup, jiffies)) +			task->tk_status = -NFS4ERR_DELAY;  		break;  	case -NFS4ERR_EXPIRED:  	case -NFS4ERR_BAD_STATEID: @@ -6129,11 +6136,13 @@ static struct page **nfs4_alloc_pages(size_t size, gfp_t gfp_flags)  static void nfs4_layoutget_release(void *calldata)  {  	struct nfs4_layoutget *lgp = calldata; -	struct nfs_server *server = NFS_SERVER(lgp->args.inode); +	struct inode *inode = lgp->args.inode; +	struct nfs_server *server = NFS_SERVER(inode);  	size_t max_pages = max_response_pages(server);  	dprintk("--> %s\n", __func__);  	nfs4_free_pages(lgp->args.layout.pages, max_pages); +	pnfs_put_layout_hdr(NFS_I(inode)->layout);  	put_nfs_open_context(lgp->args.ctx);  	kfree(calldata);  	dprintk("<-- %s\n", __func__); @@ -6148,7 +6157,8 @@ static const struct rpc_call_ops nfs4_layoutget_call_ops = {  struct pnfs_layout_segment *  nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)  { -	struct nfs_server *server = NFS_SERVER(lgp->args.inode); +	struct inode *inode = lgp->args.inode; +	struct nfs_server *server = NFS_SERVER(inode);  	size_t max_pages = max_response_pages(server);  	struct rpc_task *task;  	struct rpc_message msg = { @@ -6174,10 +6184,15 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)  		return ERR_PTR(-ENOMEM);  	}  	lgp->args.layout.pglen = max_pages * PAGE_SIZE; +	lgp->args.timestamp = jiffies;  	lgp->res.layoutp = &lgp->args.layout;  	lgp->res.seq_res.sr_slot = NULL;  	nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0); + +	/* nfs4_layoutget_release calls pnfs_put_layout_hdr */ +	pnfs_get_layout_hdr(NFS_I(inode)->layout); +  	task = rpc_run_task(&task_setup_data);  	if (IS_ERR(task))  		return ERR_CAST(task);  |