Commit 344ba37b authored by Linus Torvalds's avatar Linus Torvalds

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

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
...@@ -241,7 +241,7 @@ static int nfs_callback_start_svc(int minorversion, struct rpc_xprt *xprt, ...@@ -241,7 +241,7 @@ static int nfs_callback_start_svc(int minorversion, struct rpc_xprt *xprt,
svc_exit_thread(cb_info->rqst); svc_exit_thread(cb_info->rqst);
cb_info->rqst = NULL; cb_info->rqst = NULL;
cb_info->task = NULL; cb_info->task = NULL;
return PTR_ERR(cb_info->task); return ret;
} }
dprintk("nfs_callback_up: service started\n"); dprintk("nfs_callback_up: service started\n");
return 0; return 0;
......
...@@ -122,12 +122,21 @@ static void filelayout_reset_read(struct nfs_read_data *data) ...@@ -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, static int filelayout_async_handle_error(struct rpc_task *task,
struct nfs4_state *state, struct nfs4_state *state,
struct nfs_client *clp, struct nfs_client *clp,
struct pnfs_layout_segment *lseg) 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 nfs_server *mds_server = NFS_SERVER(inode);
struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg); struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg);
struct nfs_client *mds_client = mds_server->nfs_client; struct nfs_client *mds_client = mds_server->nfs_client;
...@@ -204,10 +213,8 @@ static int filelayout_async_handle_error(struct rpc_task *task, ...@@ -204,10 +213,8 @@ static int filelayout_async_handle_error(struct rpc_task *task,
dprintk("%s DS connection error %d\n", __func__, dprintk("%s DS connection error %d\n", __func__,
task->tk_status); task->tk_status);
nfs4_mark_deviceid_unavailable(devid); nfs4_mark_deviceid_unavailable(devid);
clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(inode)->flags); set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags);
_pnfs_return_layout(inode);
rpc_wake_up(&tbl->slot_tbl_waitq); rpc_wake_up(&tbl->slot_tbl_waitq);
nfs4_ds_disconnect(clp);
/* fall through */ /* fall through */
default: default:
reset: reset:
...@@ -331,7 +338,9 @@ static void filelayout_read_count_stats(struct rpc_task *task, void *data) ...@@ -331,7 +338,9 @@ static void filelayout_read_count_stats(struct rpc_task *task, void *data)
static void filelayout_read_release(void *data) static void filelayout_read_release(void *data)
{ {
struct nfs_read_data *rdata = 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); nfs_put_client(rdata->ds_clp);
rdata->header->mds_ops->rpc_release(data); rdata->header->mds_ops->rpc_release(data);
} }
...@@ -429,7 +438,9 @@ static void filelayout_write_count_stats(struct rpc_task *task, void *data) ...@@ -429,7 +438,9 @@ static void filelayout_write_count_stats(struct rpc_task *task, void *data)
static void filelayout_write_release(void *data) static void filelayout_write_release(void *data)
{ {
struct nfs_write_data *wdata = 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); nfs_put_client(wdata->ds_clp);
wdata->header->mds_ops->rpc_release(data); wdata->header->mds_ops->rpc_release(data);
} }
...@@ -739,7 +750,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo, ...@@ -739,7 +750,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo,
goto out_err; goto out_err;
if (fl->num_fh > 0) { 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); gfp_flags);
if (!fl->fh_array) if (!fl->fh_array)
goto out_err; goto out_err;
......
...@@ -149,6 +149,5 @@ extern void nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr); ...@@ -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); extern void nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr);
struct nfs4_file_layout_dsaddr * struct nfs4_file_layout_dsaddr *
filelayout_get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags); 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 */ #endif /* FS_NFS_NFS4FILELAYOUT_H */
...@@ -148,28 +148,6 @@ _data_server_lookup_locked(const struct list_head *dsaddrs) ...@@ -148,28 +148,6 @@ _data_server_lookup_locked(const struct list_head *dsaddrs)
return NULL; 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 * Create an rpc connection to the nfs4_pnfs_ds data server
* Currently only supports IPv4 and IPv6 addresses * Currently only supports IPv4 and IPv6 addresses
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <linux/nfs_fs.h> #include <linux/nfs_fs.h>
#include "nfs4_fs.h" #include "nfs4_fs.h"
#include "internal.h"
#define NFSDBG_FACILITY NFSDBG_CLIENT #define NFSDBG_FACILITY NFSDBG_CLIENT
......
...@@ -369,7 +369,7 @@ void objio_free_result(struct objlayout_io_res *oir) ...@@ -369,7 +369,7 @@ void objio_free_result(struct objlayout_io_res *oir)
kfree(objios); kfree(objios);
} }
enum pnfs_osd_errno osd_pri_2_pnfs_err(enum osd_err_priority oep) static enum pnfs_osd_errno osd_pri_2_pnfs_err(enum osd_err_priority oep)
{ {
switch (oep) { switch (oep) {
case OSD_ERR_PRI_NO_ERROR: case OSD_ERR_PRI_NO_ERROR:
...@@ -574,7 +574,7 @@ static bool objio_pg_test(struct nfs_pageio_descriptor *pgio, ...@@ -574,7 +574,7 @@ static bool objio_pg_test(struct nfs_pageio_descriptor *pgio,
(unsigned long)pgio->pg_layout_private; (unsigned long)pgio->pg_layout_private;
} }
void objio_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) static void objio_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
{ {
pnfs_generic_pg_init_read(pgio, req); pnfs_generic_pg_init_read(pgio, req);
if (unlikely(pgio->pg_lseg == NULL)) if (unlikely(pgio->pg_lseg == NULL))
...@@ -604,7 +604,7 @@ static bool aligned_on_raid_stripe(u64 offset, struct ore_layout *layout, ...@@ -604,7 +604,7 @@ static bool aligned_on_raid_stripe(u64 offset, struct ore_layout *layout,
return false; return false;
} }
void objio_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) static void objio_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
{ {
unsigned long stripe_end = 0; unsigned long stripe_end = 0;
u64 wb_size; u64 wb_size;
......
...@@ -62,6 +62,7 @@ enum { ...@@ -62,6 +62,7 @@ enum {
NFS_LAYOUT_RW_FAILED, /* get rw layout failed stop trying */ NFS_LAYOUT_RW_FAILED, /* get rw layout failed stop trying */
NFS_LAYOUT_BULK_RECALL, /* bulk recall affecting layout */ NFS_LAYOUT_BULK_RECALL, /* bulk recall affecting layout */
NFS_LAYOUT_ROC, /* some lseg had roc bit set */ NFS_LAYOUT_ROC, /* some lseg had roc bit set */
NFS_LAYOUT_RETURN, /* Return this layout ASAP */
}; };
enum layoutdriver_policy_flags { enum layoutdriver_policy_flags {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment