Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8d05b377 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents b695188d 512e4b29
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -237,6 +237,8 @@ nfs_find_actor(struct inode *inode, void *opaque)

	if (NFS_FILEID(inode) != fattr->fileid)
		return 0;
	if ((S_IFMT & inode->i_mode) != (S_IFMT & fattr->mode))
		return 0;
	if (nfs_compare_fh(NFS_FH(inode), fh))
		return 0;
	if (is_bad_inode(inode) || NFS_STALE(inode))
+4 −2
Original line number Diff line number Diff line
@@ -99,7 +99,8 @@ static void filelayout_reset_write(struct nfs_write_data *data)

		task->tk_status = pnfs_write_done_resend_to_mds(hdr->inode,
							&hdr->pages,
							hdr->completion_ops);
							hdr->completion_ops,
							hdr->dreq);
	}
}

@@ -119,7 +120,8 @@ static void filelayout_reset_read(struct nfs_read_data *data)

		task->tk_status = pnfs_read_done_resend_to_mds(hdr->inode,
							&hdr->pages,
							hdr->completion_ops);
							hdr->completion_ops,
							hdr->dreq);
	}
}

+1 −1
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@
 * Default data server connection timeout and retrans vaules.
 * Set by module paramters dataserver_timeo and dataserver_retrans.
 */
#define NFS4_DEF_DS_TIMEO   60
#define NFS4_DEF_DS_TIMEO   600 /* in tenths of a second */
#define NFS4_DEF_DS_RETRANS 5

/*
+18 −3
Original line number Diff line number Diff line
@@ -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,6 +6060,9 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata)
		goto out;
	case -NFS4ERR_LAYOUTTRYLATER:
	case -NFS4ERR_RECALLCONFLICT:
		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:
@@ -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);
+13 −8
Original line number Diff line number Diff line
@@ -1181,7 +1181,7 @@ pnfs_update_layout(struct inode *ino,
	struct nfs_client *clp = server->nfs_client;
	struct pnfs_layout_hdr *lo;
	struct pnfs_layout_segment *lseg = NULL;
	bool first = false;
	bool first;

	if (!pnfs_enabled_sb(NFS_SERVER(ino)))
		goto out;
@@ -1215,10 +1215,9 @@ pnfs_update_layout(struct inode *ino,
		goto out_unlock;
	atomic_inc(&lo->plh_outstanding);

	if (list_empty(&lo->plh_segs))
		first = true;

	first = list_empty(&lo->plh_layouts) ? true : false;
	spin_unlock(&ino->i_lock);

	if (first) {
		/* The lo must be on the clp list if there is any
		 * chance of a CB_LAYOUTRECALL(FILE) coming in.
@@ -1422,13 +1421,15 @@ EXPORT_SYMBOL_GPL(pnfs_generic_pg_test);

int pnfs_write_done_resend_to_mds(struct inode *inode,
				struct list_head *head,
				const struct nfs_pgio_completion_ops *compl_ops)
				const struct nfs_pgio_completion_ops *compl_ops,
				struct nfs_direct_req *dreq)
{
	struct nfs_pageio_descriptor pgio;
	LIST_HEAD(failed);

	/* Resend all requests through the MDS */
	nfs_pageio_init_write(&pgio, inode, FLUSH_STABLE, compl_ops);
	pgio.pg_dreq = dreq;
	while (!list_empty(head)) {
		struct nfs_page *req = nfs_list_entry(head->next);

@@ -1463,7 +1464,8 @@ static void pnfs_ld_handle_write_error(struct nfs_write_data *data)
	if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags))
		data->task.tk_status = pnfs_write_done_resend_to_mds(hdr->inode,
							&hdr->pages,
							hdr->completion_ops);
							hdr->completion_ops,
							hdr->dreq);
}

/*
@@ -1578,13 +1580,15 @@ EXPORT_SYMBOL_GPL(pnfs_generic_pg_writepages);

int pnfs_read_done_resend_to_mds(struct inode *inode,
				struct list_head *head,
				const struct nfs_pgio_completion_ops *compl_ops)
				const struct nfs_pgio_completion_ops *compl_ops,
				struct nfs_direct_req *dreq)
{
	struct nfs_pageio_descriptor pgio;
	LIST_HEAD(failed);

	/* Resend all requests through the MDS */
	nfs_pageio_init_read(&pgio, inode, compl_ops);
	pgio.pg_dreq = dreq;
	while (!list_empty(head)) {
		struct nfs_page *req = nfs_list_entry(head->next);

@@ -1615,7 +1619,8 @@ static void pnfs_ld_handle_read_error(struct nfs_read_data *data)
	if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags))
		data->task.tk_status = pnfs_read_done_resend_to_mds(hdr->inode,
							&hdr->pages,
							hdr->completion_ops);
							hdr->completion_ops,
							hdr->dreq);
}

/*
Loading