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

Commit 344ba37b authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull NFS client bugfixes from Trond Myklebust:
 - Do not call pnfs_return_layout() from an rpciod context
 - nfs4_ds_disconnect can cause Oopses.  Kill it...
 - Fix the return value for nfs_callback_start_svc
 - Fix a number of compile warnings

* tag 'nfs-for-3.7-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
  NFSv4: Fix the return value for nfs_callback_start_svc
  NFSv4.1: Declare osd_pri_2_pnfs_err(), objio_init_read/write to be static
  NFSv4: fs/nfs/nfs4getroot.c needs to include "internal.h"
  NFSv4.1: Use kcalloc() to allocate zeroed arrays instead of kzalloc()
  NFSv4.1: Do not call pnfs_return_layout() from an rpciod context
  NFSv4.1: Kill nfs4_ds_disconnect()
parents c52f1dd5 e9b7e917
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -241,7 +241,7 @@ static int nfs_callback_start_svc(int minorversion, struct rpc_xprt *xprt,
		svc_exit_thread(cb_info->rqst);
		cb_info->rqst = NULL;
		cb_info->task = NULL;
		return PTR_ERR(cb_info->task);
		return ret;
	}
	dprintk("nfs_callback_up: service started\n");
	return 0;
+16 −5
Original line number Diff line number Diff line
@@ -122,12 +122,21 @@ static void filelayout_reset_read(struct nfs_read_data *data)
	}
}

static void filelayout_fenceme(struct inode *inode, struct pnfs_layout_hdr *lo)
{
	if (!test_and_clear_bit(NFS_LAYOUT_RETURN, &lo->plh_flags))
		return;
	clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(inode)->flags);
	pnfs_return_layout(inode);
}

static int filelayout_async_handle_error(struct rpc_task *task,
					 struct nfs4_state *state,
					 struct nfs_client *clp,
					 struct pnfs_layout_segment *lseg)
{
	struct inode *inode = lseg->pls_layout->plh_inode;
	struct pnfs_layout_hdr *lo = lseg->pls_layout;
	struct inode *inode = lo->plh_inode;
	struct nfs_server *mds_server = NFS_SERVER(inode);
	struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg);
	struct nfs_client *mds_client = mds_server->nfs_client;
@@ -204,10 +213,8 @@ static int filelayout_async_handle_error(struct rpc_task *task,
		dprintk("%s DS connection error %d\n", __func__,
			task->tk_status);
		nfs4_mark_deviceid_unavailable(devid);
		clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(inode)->flags);
		_pnfs_return_layout(inode);
		set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags);
		rpc_wake_up(&tbl->slot_tbl_waitq);
		nfs4_ds_disconnect(clp);
		/* fall through */
	default:
reset:
@@ -331,7 +338,9 @@ static void filelayout_read_count_stats(struct rpc_task *task, void *data)
static void filelayout_read_release(void *data)
{
	struct nfs_read_data *rdata = data;
	struct pnfs_layout_hdr *lo = rdata->header->lseg->pls_layout;

	filelayout_fenceme(lo->plh_inode, lo);
	nfs_put_client(rdata->ds_clp);
	rdata->header->mds_ops->rpc_release(data);
}
@@ -429,7 +438,9 @@ static void filelayout_write_count_stats(struct rpc_task *task, void *data)
static void filelayout_write_release(void *data)
{
	struct nfs_write_data *wdata = data;
	struct pnfs_layout_hdr *lo = wdata->header->lseg->pls_layout;

	filelayout_fenceme(lo->plh_inode, lo);
	nfs_put_client(wdata->ds_clp);
	wdata->header->mds_ops->rpc_release(data);
}
@@ -739,7 +750,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo,
		goto out_err;

	if (fl->num_fh > 0) {
		fl->fh_array = kzalloc(fl->num_fh * sizeof(struct nfs_fh *),
		fl->fh_array = kcalloc(fl->num_fh, sizeof(fl->fh_array[0]),
				       gfp_flags);
		if (!fl->fh_array)
			goto out_err;
+0 −1
Original line number Diff line number Diff line
@@ -149,6 +149,5 @@ extern void nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr);
extern void nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr);
struct nfs4_file_layout_dsaddr *
filelayout_get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags);
void nfs4_ds_disconnect(struct nfs_client *clp);

#endif /* FS_NFS_NFS4FILELAYOUT_H */
+0 −22
Original line number Diff line number Diff line
@@ -148,28 +148,6 @@ _data_server_lookup_locked(const struct list_head *dsaddrs)
	return NULL;
}

/*
 * Lookup DS by nfs_client pointer. Zero data server client pointer
 */
void nfs4_ds_disconnect(struct nfs_client *clp)
{
	struct nfs4_pnfs_ds *ds;
	struct nfs_client *found = NULL;

	dprintk("%s clp %p\n", __func__, clp);
	spin_lock(&nfs4_ds_cache_lock);
	list_for_each_entry(ds, &nfs4_data_server_cache, ds_node)
		if (ds->ds_clp && ds->ds_clp == clp) {
			found = ds->ds_clp;
			ds->ds_clp = NULL;
		}
	spin_unlock(&nfs4_ds_cache_lock);
	if (found) {
		set_bit(NFS_CS_STOP_RENEW, &clp->cl_res_state);
		nfs_put_client(clp);
	}
}

/*
 * Create an rpc connection to the nfs4_pnfs_ds data server
 * Currently only supports IPv4 and IPv6 addresses
+1 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@

#include <linux/nfs_fs.h>
#include "nfs4_fs.h"
#include "internal.h"

#define NFSDBG_FACILITY		NFSDBG_CLIENT

Loading