Skip to content

Commit

Permalink
Merge branch 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/n…
Browse files Browse the repository at this point in the history
…fs-2.6

* 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6:
  NFSv4.1: Ensure that layoutget uses the correct gfp modes
  NFSv4.1: remove pnfs_layout_hdr from pnfs_destroy_all_layouts tmp_list
  NFSv41: Resend on NFS4ERR_RETRY_UNCACHED_REP
  • Loading branch information
Linus Torvalds committed May 13, 2011
2 parents 087fbc9 + a75b9df commit cf70cc5
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 50 deletions.
27 changes: 16 additions & 11 deletions fs/nfs/nfs4filelayout.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ static int filelayout_async_handle_error(struct rpc_task *task,
case -EKEYEXPIRED:
rpc_delay(task, FILELAYOUT_POLL_RETRY_MAX);
break;
case -NFS4ERR_RETRY_UNCACHED_REP:
break;
default:
dprintk("%s DS error. Retry through MDS %d\n", __func__,
task->tk_status);
Expand Down Expand Up @@ -416,7 +418,8 @@ static int
filelayout_check_layout(struct pnfs_layout_hdr *lo,
struct nfs4_filelayout_segment *fl,
struct nfs4_layoutget_res *lgr,
struct nfs4_deviceid *id)
struct nfs4_deviceid *id,
gfp_t gfp_flags)
{
struct nfs4_file_layout_dsaddr *dsaddr;
int status = -EINVAL;
Expand All @@ -439,7 +442,7 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo,
/* find and reference the deviceid */
dsaddr = nfs4_fl_find_get_deviceid(id);
if (dsaddr == NULL) {
dsaddr = get_device_info(lo->plh_inode, id);
dsaddr = get_device_info(lo->plh_inode, id, gfp_flags);
if (dsaddr == NULL)
goto out;
}
Expand Down Expand Up @@ -500,7 +503,8 @@ static int
filelayout_decode_layout(struct pnfs_layout_hdr *flo,
struct nfs4_filelayout_segment *fl,
struct nfs4_layoutget_res *lgr,
struct nfs4_deviceid *id)
struct nfs4_deviceid *id,
gfp_t gfp_flags)
{
struct xdr_stream stream;
struct xdr_buf buf = {
Expand All @@ -516,7 +520,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo,

dprintk("%s: set_layout_map Begin\n", __func__);

scratch = alloc_page(GFP_KERNEL);
scratch = alloc_page(gfp_flags);
if (!scratch)
return -ENOMEM;

Expand Down Expand Up @@ -554,13 +558,13 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo,
goto out_err;

fl->fh_array = kzalloc(fl->num_fh * sizeof(struct nfs_fh *),
GFP_KERNEL);
gfp_flags);
if (!fl->fh_array)
goto out_err;

for (i = 0; i < fl->num_fh; i++) {
/* Do we want to use a mempool here? */
fl->fh_array[i] = kmalloc(sizeof(struct nfs_fh), GFP_KERNEL);
fl->fh_array[i] = kmalloc(sizeof(struct nfs_fh), gfp_flags);
if (!fl->fh_array[i])
goto out_err_free;

Expand Down Expand Up @@ -605,19 +609,20 @@ filelayout_free_lseg(struct pnfs_layout_segment *lseg)

static struct pnfs_layout_segment *
filelayout_alloc_lseg(struct pnfs_layout_hdr *layoutid,
struct nfs4_layoutget_res *lgr)
struct nfs4_layoutget_res *lgr,
gfp_t gfp_flags)
{
struct nfs4_filelayout_segment *fl;
int rc;
struct nfs4_deviceid id;

dprintk("--> %s\n", __func__);
fl = kzalloc(sizeof(*fl), GFP_KERNEL);
fl = kzalloc(sizeof(*fl), gfp_flags);
if (!fl)
return NULL;

rc = filelayout_decode_layout(layoutid, fl, lgr, &id);
if (rc != 0 || filelayout_check_layout(layoutid, fl, lgr, &id)) {
rc = filelayout_decode_layout(layoutid, fl, lgr, &id, gfp_flags);
if (rc != 0 || filelayout_check_layout(layoutid, fl, lgr, &id, gfp_flags)) {
_filelayout_free_lseg(fl);
return NULL;
}
Expand All @@ -633,7 +638,7 @@ filelayout_alloc_lseg(struct pnfs_layout_hdr *layoutid,
int size = (fl->stripe_type == STRIPE_SPARSE) ?
fl->dsaddr->ds_num : fl->dsaddr->stripe_count;

fl->commit_buckets = kcalloc(size, sizeof(struct list_head), GFP_KERNEL);
fl->commit_buckets = kcalloc(size, sizeof(struct list_head), gfp_flags);
if (!fl->commit_buckets) {
filelayout_free_lseg(&fl->generic_hdr);
return NULL;
Expand Down
2 changes: 1 addition & 1 deletion fs/nfs/nfs4filelayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,6 @@ extern struct nfs4_file_layout_dsaddr *
nfs4_fl_find_get_deviceid(struct nfs4_deviceid *dev_id);
extern void nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr);
struct nfs4_file_layout_dsaddr *
get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id);
get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags);

#endif /* FS_NFS_NFS4FILELAYOUT_H */
34 changes: 17 additions & 17 deletions fs/nfs/nfs4filelayoutdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,11 +225,11 @@ nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr)
}

static struct nfs4_pnfs_ds *
nfs4_pnfs_ds_add(struct inode *inode, u32 ip_addr, u32 port)
nfs4_pnfs_ds_add(struct inode *inode, u32 ip_addr, u32 port, gfp_t gfp_flags)
{
struct nfs4_pnfs_ds *tmp_ds, *ds;

ds = kzalloc(sizeof(*tmp_ds), GFP_KERNEL);
ds = kzalloc(sizeof(*tmp_ds), gfp_flags);
if (!ds)
goto out;

Expand Down Expand Up @@ -261,7 +261,7 @@ nfs4_pnfs_ds_add(struct inode *inode, u32 ip_addr, u32 port)
* Currently only support ipv4, and one multi-path address.
*/
static struct nfs4_pnfs_ds *
decode_and_add_ds(struct xdr_stream *streamp, struct inode *inode)
decode_and_add_ds(struct xdr_stream *streamp, struct inode *inode, gfp_t gfp_flags)
{
struct nfs4_pnfs_ds *ds = NULL;
char *buf;
Expand Down Expand Up @@ -303,7 +303,7 @@ decode_and_add_ds(struct xdr_stream *streamp, struct inode *inode)
rlen);
goto out_err;
}
buf = kmalloc(rlen + 1, GFP_KERNEL);
buf = kmalloc(rlen + 1, gfp_flags);
if (!buf) {
dprintk("%s: Not enough memory\n", __func__);
goto out_err;
Expand Down Expand Up @@ -333,7 +333,7 @@ decode_and_add_ds(struct xdr_stream *streamp, struct inode *inode)
sscanf(pstr, "-%d-%d", &tmp[0], &tmp[1]);
port = htons((tmp[0] << 8) | (tmp[1]));

ds = nfs4_pnfs_ds_add(inode, ip_addr, port);
ds = nfs4_pnfs_ds_add(inode, ip_addr, port, gfp_flags);
dprintk("%s: Decoded address and port %s\n", __func__, buf);
out_free:
kfree(buf);
Expand All @@ -343,7 +343,7 @@ decode_and_add_ds(struct xdr_stream *streamp, struct inode *inode)

/* Decode opaque device data and return the result */
static struct nfs4_file_layout_dsaddr*
decode_device(struct inode *ino, struct pnfs_device *pdev)
decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags)
{
int i;
u32 cnt, num;
Expand All @@ -362,7 +362,7 @@ decode_device(struct inode *ino, struct pnfs_device *pdev)
struct page *scratch;

/* set up xdr stream */
scratch = alloc_page(GFP_KERNEL);
scratch = alloc_page(gfp_flags);
if (!scratch)
goto out_err;

Expand All @@ -384,7 +384,7 @@ decode_device(struct inode *ino, struct pnfs_device *pdev)
}

/* read stripe indices */
stripe_indices = kcalloc(cnt, sizeof(u8), GFP_KERNEL);
stripe_indices = kcalloc(cnt, sizeof(u8), gfp_flags);
if (!stripe_indices)
goto out_err_free_scratch;

Expand Down Expand Up @@ -423,7 +423,7 @@ decode_device(struct inode *ino, struct pnfs_device *pdev)

dsaddr = kzalloc(sizeof(*dsaddr) +
(sizeof(struct nfs4_pnfs_ds *) * (num - 1)),
GFP_KERNEL);
gfp_flags);
if (!dsaddr)
goto out_err_free_stripe_indices;

Expand Down Expand Up @@ -452,7 +452,7 @@ decode_device(struct inode *ino, struct pnfs_device *pdev)
for (j = 0; j < mp_count; j++) {
if (j == 0) {
dsaddr->ds_list[i] = decode_and_add_ds(&stream,
ino);
ino, gfp_flags);
if (dsaddr->ds_list[i] == NULL)
goto out_err_free_deviceid;
} else {
Expand Down Expand Up @@ -503,12 +503,12 @@ decode_device(struct inode *ino, struct pnfs_device *pdev)
* available devices.
*/
static struct nfs4_file_layout_dsaddr *
decode_and_add_device(struct inode *inode, struct pnfs_device *dev)
decode_and_add_device(struct inode *inode, struct pnfs_device *dev, gfp_t gfp_flags)
{
struct nfs4_file_layout_dsaddr *d, *new;
long hash;

new = decode_device(inode, dev);
new = decode_device(inode, dev, gfp_flags);
if (!new) {
printk(KERN_WARNING "%s: Could not decode or add device\n",
__func__);
Expand Down Expand Up @@ -537,7 +537,7 @@ decode_and_add_device(struct inode *inode, struct pnfs_device *dev)
* of available devices, and return it.
*/
struct nfs4_file_layout_dsaddr *
get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id)
get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags)
{
struct pnfs_device *pdev = NULL;
u32 max_resp_sz;
Expand All @@ -556,17 +556,17 @@ get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id)
dprintk("%s inode %p max_resp_sz %u max_pages %d\n",
__func__, inode, max_resp_sz, max_pages);

pdev = kzalloc(sizeof(struct pnfs_device), GFP_KERNEL);
pdev = kzalloc(sizeof(struct pnfs_device), gfp_flags);
if (pdev == NULL)
return NULL;

pages = kzalloc(max_pages * sizeof(struct page *), GFP_KERNEL);
pages = kzalloc(max_pages * sizeof(struct page *), gfp_flags);
if (pages == NULL) {
kfree(pdev);
return NULL;
}
for (i = 0; i < max_pages; i++) {
pages[i] = alloc_page(GFP_KERNEL);
pages[i] = alloc_page(gfp_flags);
if (!pages[i])
goto out_free;
}
Expand All @@ -587,7 +587,7 @@ get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id)
* Found new device, need to decode it and then add it to the
* list of known devices for this mountpoint.
*/
dsaddr = decode_and_add_device(inode, pdev);
dsaddr = decode_and_add_device(inode, pdev, gfp_flags);
out_free:
for (i = 0; i < max_pages; i++)
__free_page(pages[i]);
Expand Down
6 changes: 6 additions & 0 deletions fs/nfs/nfs4proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc
ret = nfs4_delay(server->client, &exception->timeout);
if (ret != 0)
break;
case -NFS4ERR_RETRY_UNCACHED_REP:
case -NFS4ERR_OLD_STATEID:
exception->retry = 1;
break;
Expand Down Expand Up @@ -3695,6 +3696,7 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
rpc_delay(task, NFS4_POLL_RETRY_MAX);
task->tk_status = 0;
return -EAGAIN;
case -NFS4ERR_RETRY_UNCACHED_REP:
case -NFS4ERR_OLD_STATEID:
task->tk_status = 0;
return -EAGAIN;
Expand Down Expand Up @@ -4844,6 +4846,8 @@ static void nfs4_get_lease_time_done(struct rpc_task *task, void *calldata)
dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status);
rpc_delay(task, NFS4_POLL_RETRY_MIN);
task->tk_status = 0;
/* fall through */
case -NFS4ERR_RETRY_UNCACHED_REP:
nfs_restart_rpc(task, data->clp);
return;
}
Expand Down Expand Up @@ -5479,6 +5483,8 @@ static int nfs41_reclaim_complete_handle_errors(struct rpc_task *task, struct nf
break;
case -NFS4ERR_DELAY:
rpc_delay(task, NFS4_POLL_RETRY_MAX);
/* fall through */
case -NFS4ERR_RETRY_UNCACHED_REP:
return -EAGAIN;
default:
nfs4_schedule_lease_recovery(clp);
Expand Down
Loading

0 comments on commit cf70cc5

Please sign in to comment.