mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-11-07 04:09:21 +00:00
Merge branch 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6
* 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6: NFS: Fix decode_secinfo_maxsz NFSv4.1: Fix an off-by-one error in pnfs_generic_pg_test NFSv4.1: Fix some issues with pnfs_generic_pg_test NFSv4.1: file layout must consider pg_bsize for coalescing pnfs-obj: No longer needed to take an extra ref at add_device SUNRPC: Ensure the RPC client only quits on fatal signals NFSv4: Fix a readdir regression nfs4.1: mark layout as bad on error path in _pnfs_return_layout nfs4.1: prevent race that allowed use of freed layout in _pnfs_return_layout NFSv4.1: need to put_layout_hdr on _pnfs_return_layout error path NFS: (d)printks should use %zd for ssize_t arguments NFSv4.1: fix break condition in pnfs_find_lseg nfs4.1: fix several problems with _pnfs_return_layout NFSv4.1: allow zero fh array in filelayout decode layout NFSv4.1: allow nfs_fhget to succeed with mounted on fileid NFSv4.1: Fix a refcounting issue in the pNFS device id cache NFSv4.1: deprecate headerpadsz in CREATE_SESSION NFS41: do not update isize if inode needs layoutcommit NLM: Don't hang forever on NLM unlock requests NFS: fix umount of pnfs filesystems
This commit is contained in:
commit
2992c4bd57
18 changed files with 139 additions and 66 deletions
|
@ -708,7 +708,13 @@ static void nlmclnt_unlock_callback(struct rpc_task *task, void *data)
|
|||
|
||||
if (task->tk_status < 0) {
|
||||
dprintk("lockd: unlock failed (err = %d)\n", -task->tk_status);
|
||||
goto retry_rebind;
|
||||
switch (task->tk_status) {
|
||||
case -EACCES:
|
||||
case -EIO:
|
||||
goto die;
|
||||
default:
|
||||
goto retry_rebind;
|
||||
}
|
||||
}
|
||||
if (status == NLM_LCK_DENIED_GRACE_PERIOD) {
|
||||
rpc_delay(task, NLMCLNT_GRACE_WAIT);
|
||||
|
|
|
@ -256,7 +256,8 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
|
|||
|
||||
nfs_attr_check_mountpoint(sb, fattr);
|
||||
|
||||
if ((fattr->valid & NFS_ATTR_FATTR_FILEID) == 0 && (fattr->valid & NFS_ATTR_FATTR_MOUNTPOINT) == 0)
|
||||
if (((fattr->valid & NFS_ATTR_FATTR_FILEID) == 0) &&
|
||||
!nfs_attr_use_mounted_on_fileid(fattr))
|
||||
goto out_no_inode;
|
||||
if ((fattr->valid & NFS_ATTR_FATTR_TYPE) == 0)
|
||||
goto out_no_inode;
|
||||
|
@ -1294,7 +1295,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
|
|||
if (new_isize != cur_isize) {
|
||||
/* Do we perhaps have any outstanding writes, or has
|
||||
* the file grown beyond our last write? */
|
||||
if (nfsi->npages == 0 || new_isize > cur_isize) {
|
||||
if ((nfsi->npages == 0 && !test_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) ||
|
||||
new_isize > cur_isize) {
|
||||
i_size_write(inode, new_isize);
|
||||
invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,17 @@ static inline void nfs_attr_check_mountpoint(struct super_block *parent, struct
|
|||
fattr->valid |= NFS_ATTR_FATTR_MOUNTPOINT;
|
||||
}
|
||||
|
||||
static inline int nfs_attr_use_mounted_on_fileid(struct nfs_fattr *fattr)
|
||||
{
|
||||
if (((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) == 0) ||
|
||||
(((fattr->valid & NFS_ATTR_FATTR_MOUNTPOINT) == 0) &&
|
||||
((fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) == 0)))
|
||||
return 0;
|
||||
|
||||
fattr->fileid = fattr->mounted_on_fileid;
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct nfs_clone_mount {
|
||||
const struct super_block *sb;
|
||||
const struct dentry *dentry;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/nfs_fs.h>
|
||||
#include <linux/nfs_page.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "nfs4filelayout.h"
|
||||
|
@ -552,13 +553,18 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo,
|
|||
__func__, nfl_util, fl->num_fh, fl->first_stripe_index,
|
||||
fl->pattern_offset);
|
||||
|
||||
if (!fl->num_fh)
|
||||
/* Note that a zero value for num_fh is legal for STRIPE_SPARSE.
|
||||
* Futher checking is done in filelayout_check_layout */
|
||||
if (fl->num_fh < 0 || fl->num_fh >
|
||||
max(NFS4_PNFS_MAX_STRIPE_CNT, NFS4_PNFS_MAX_MULTI_CNT))
|
||||
goto out_err;
|
||||
|
||||
fl->fh_array = kzalloc(fl->num_fh * sizeof(struct nfs_fh *),
|
||||
gfp_flags);
|
||||
if (!fl->fh_array)
|
||||
goto out_err;
|
||||
if (fl->num_fh > 0) {
|
||||
fl->fh_array = kzalloc(fl->num_fh * sizeof(struct nfs_fh *),
|
||||
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? */
|
||||
|
@ -661,8 +667,9 @@ filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
|
|||
u64 p_stripe, r_stripe;
|
||||
u32 stripe_unit;
|
||||
|
||||
if (!pnfs_generic_pg_test(pgio, prev, req))
|
||||
return 0;
|
||||
if (!pnfs_generic_pg_test(pgio, prev, req) ||
|
||||
!nfs_generic_pg_test(pgio, prev, req))
|
||||
return false;
|
||||
|
||||
if (!pgio->pg_lseg)
|
||||
return 1;
|
||||
|
|
|
@ -2265,12 +2265,14 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
|
|||
return nfs4_map_errors(status);
|
||||
}
|
||||
|
||||
static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr);
|
||||
/*
|
||||
* Get locations and (maybe) other attributes of a referral.
|
||||
* Note that we'll actually follow the referral later when
|
||||
* we detect fsid mismatch in inode revalidation
|
||||
*/
|
||||
static int nfs4_get_referral(struct inode *dir, const struct qstr *name, struct nfs_fattr *fattr, struct nfs_fh *fhandle)
|
||||
static int nfs4_get_referral(struct inode *dir, const struct qstr *name,
|
||||
struct nfs_fattr *fattr, struct nfs_fh *fhandle)
|
||||
{
|
||||
int status = -ENOMEM;
|
||||
struct page *page = NULL;
|
||||
|
@ -2288,15 +2290,16 @@ static int nfs4_get_referral(struct inode *dir, const struct qstr *name, struct
|
|||
goto out;
|
||||
/* Make sure server returned a different fsid for the referral */
|
||||
if (nfs_fsid_equal(&NFS_SERVER(dir)->fsid, &locations->fattr.fsid)) {
|
||||
dprintk("%s: server did not return a different fsid for a referral at %s\n", __func__, name->name);
|
||||
dprintk("%s: server did not return a different fsid for"
|
||||
" a referral at %s\n", __func__, name->name);
|
||||
status = -EIO;
|
||||
goto out;
|
||||
}
|
||||
/* Fixup attributes for the nfs_lookup() call to nfs_fhget() */
|
||||
nfs_fixup_referral_attributes(&locations->fattr);
|
||||
|
||||
/* replace the lookup nfs_fattr with the locations nfs_fattr */
|
||||
memcpy(fattr, &locations->fattr, sizeof(struct nfs_fattr));
|
||||
fattr->valid |= NFS_ATTR_FATTR_V4_REFERRAL;
|
||||
if (!fattr->mode)
|
||||
fattr->mode = S_IFDIR;
|
||||
memset(fhandle, 0, sizeof(struct nfs_fh));
|
||||
out:
|
||||
if (page)
|
||||
|
@ -4667,11 +4670,15 @@ static size_t nfs4_xattr_list_nfs4_acl(struct dentry *dentry, char *list,
|
|||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* nfs_fhget will use either the mounted_on_fileid or the fileid
|
||||
*/
|
||||
static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr)
|
||||
{
|
||||
if (!((fattr->valid & NFS_ATTR_FATTR_FILEID) &&
|
||||
(fattr->valid & NFS_ATTR_FATTR_FSID) &&
|
||||
(fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL)))
|
||||
if (!(((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) ||
|
||||
(fattr->valid & NFS_ATTR_FATTR_FILEID)) &&
|
||||
(fattr->valid & NFS_ATTR_FATTR_FSID) &&
|
||||
(fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL)))
|
||||
return;
|
||||
|
||||
fattr->valid |= NFS_ATTR_FATTR_TYPE | NFS_ATTR_FATTR_MODE |
|
||||
|
@ -4686,7 +4693,6 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
|
|||
struct nfs_server *server = NFS_SERVER(dir);
|
||||
u32 bitmask[2] = {
|
||||
[0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS,
|
||||
[1] = FATTR4_WORD1_MOUNTED_ON_FILEID,
|
||||
};
|
||||
struct nfs4_fs_locations_arg args = {
|
||||
.dir_fh = NFS_FH(dir),
|
||||
|
@ -4705,11 +4711,18 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
|
|||
int status;
|
||||
|
||||
dprintk("%s: start\n", __func__);
|
||||
|
||||
/* Ask for the fileid of the absent filesystem if mounted_on_fileid
|
||||
* is not supported */
|
||||
if (NFS_SERVER(dir)->attr_bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)
|
||||
bitmask[1] |= FATTR4_WORD1_MOUNTED_ON_FILEID;
|
||||
else
|
||||
bitmask[0] |= FATTR4_WORD0_FILEID;
|
||||
|
||||
nfs_fattr_init(&fs_locations->fattr);
|
||||
fs_locations->server = server;
|
||||
fs_locations->nlocations = 0;
|
||||
status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
|
||||
nfs_fixup_referral_attributes(&fs_locations->fattr);
|
||||
dprintk("%s: returned status = %d\n", __func__, status);
|
||||
return status;
|
||||
}
|
||||
|
@ -5098,7 +5111,6 @@ static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args)
|
|||
if (mxresp_sz == 0)
|
||||
mxresp_sz = NFS_MAX_FILE_IO_SIZE;
|
||||
/* Fore channel attributes */
|
||||
args->fc_attrs.headerpadsz = 0;
|
||||
args->fc_attrs.max_rqst_sz = mxrqst_sz;
|
||||
args->fc_attrs.max_resp_sz = mxresp_sz;
|
||||
args->fc_attrs.max_ops = NFS4_MAX_OPS;
|
||||
|
@ -5111,7 +5123,6 @@ static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args)
|
|||
args->fc_attrs.max_ops, args->fc_attrs.max_reqs);
|
||||
|
||||
/* Back channel attributes */
|
||||
args->bc_attrs.headerpadsz = 0;
|
||||
args->bc_attrs.max_rqst_sz = PAGE_SIZE;
|
||||
args->bc_attrs.max_resp_sz = PAGE_SIZE;
|
||||
args->bc_attrs.max_resp_sz_cached = 0;
|
||||
|
@ -5131,8 +5142,6 @@ static int nfs4_verify_fore_channel_attrs(struct nfs41_create_session_args *args
|
|||
struct nfs4_channel_attrs *sent = &args->fc_attrs;
|
||||
struct nfs4_channel_attrs *rcvd = &session->fc_attrs;
|
||||
|
||||
if (rcvd->headerpadsz > sent->headerpadsz)
|
||||
return -EINVAL;
|
||||
if (rcvd->max_resp_sz > sent->max_resp_sz)
|
||||
return -EINVAL;
|
||||
/*
|
||||
|
@ -5697,6 +5706,7 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
|
|||
{
|
||||
struct nfs4_layoutreturn *lrp = calldata;
|
||||
struct nfs_server *server;
|
||||
struct pnfs_layout_hdr *lo = NFS_I(lrp->args.inode)->layout;
|
||||
|
||||
dprintk("--> %s\n", __func__);
|
||||
|
||||
|
@ -5708,16 +5718,15 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
|
|||
nfs_restart_rpc(task, lrp->clp);
|
||||
return;
|
||||
}
|
||||
spin_lock(&lo->plh_inode->i_lock);
|
||||
if (task->tk_status == 0) {
|
||||
struct pnfs_layout_hdr *lo = NFS_I(lrp->args.inode)->layout;
|
||||
|
||||
if (lrp->res.lrs_present) {
|
||||
spin_lock(&lo->plh_inode->i_lock);
|
||||
pnfs_set_layout_stateid(lo, &lrp->res.stateid, true);
|
||||
spin_unlock(&lo->plh_inode->i_lock);
|
||||
} else
|
||||
BUG_ON(!list_empty(&lo->plh_segs));
|
||||
}
|
||||
lo->plh_block_lgets--;
|
||||
spin_unlock(&lo->plh_inode->i_lock);
|
||||
dprintk("<-- %s\n", __func__);
|
||||
}
|
||||
|
||||
|
|
|
@ -255,7 +255,7 @@ static int nfs4_stat_to_errno(int);
|
|||
#define decode_fs_locations_maxsz \
|
||||
(0)
|
||||
#define encode_secinfo_maxsz (op_encode_hdr_maxsz + nfs4_name_maxsz)
|
||||
#define decode_secinfo_maxsz (op_decode_hdr_maxsz + 4 + (NFS_MAX_SECFLAVORS * (16 + GSS_OID_MAX_LEN)))
|
||||
#define decode_secinfo_maxsz (op_decode_hdr_maxsz + 1 + ((NFS_MAX_SECFLAVORS * (16 + GSS_OID_MAX_LEN)) / 4))
|
||||
|
||||
#if defined(CONFIG_NFS_V4_1)
|
||||
#define NFS4_MAX_MACHINE_NAME_LEN (64)
|
||||
|
@ -1725,7 +1725,7 @@ static void encode_create_session(struct xdr_stream *xdr,
|
|||
*p++ = cpu_to_be32(args->flags); /*flags */
|
||||
|
||||
/* Fore Channel */
|
||||
*p++ = cpu_to_be32(args->fc_attrs.headerpadsz); /* header padding size */
|
||||
*p++ = cpu_to_be32(0); /* header padding size */
|
||||
*p++ = cpu_to_be32(args->fc_attrs.max_rqst_sz); /* max req size */
|
||||
*p++ = cpu_to_be32(args->fc_attrs.max_resp_sz); /* max resp size */
|
||||
*p++ = cpu_to_be32(max_resp_sz_cached); /* Max resp sz cached */
|
||||
|
@ -1734,7 +1734,7 @@ static void encode_create_session(struct xdr_stream *xdr,
|
|||
*p++ = cpu_to_be32(0); /* rdmachannel_attrs */
|
||||
|
||||
/* Back Channel */
|
||||
*p++ = cpu_to_be32(args->fc_attrs.headerpadsz); /* header padding size */
|
||||
*p++ = cpu_to_be32(0); /* header padding size */
|
||||
*p++ = cpu_to_be32(args->bc_attrs.max_rqst_sz); /* max req size */
|
||||
*p++ = cpu_to_be32(args->bc_attrs.max_resp_sz); /* max resp size */
|
||||
*p++ = cpu_to_be32(args->bc_attrs.max_resp_sz_cached); /* Max resp sz cached */
|
||||
|
@ -3098,7 +3098,7 @@ out_overflow:
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap)
|
||||
static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap, int32_t *res)
|
||||
{
|
||||
__be32 *p;
|
||||
|
||||
|
@ -3109,7 +3109,7 @@ static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap)
|
|||
if (unlikely(!p))
|
||||
goto out_overflow;
|
||||
bitmap[0] &= ~FATTR4_WORD0_RDATTR_ERROR;
|
||||
return -be32_to_cpup(p);
|
||||
*res = -be32_to_cpup(p);
|
||||
}
|
||||
return 0;
|
||||
out_overflow:
|
||||
|
@ -4070,6 +4070,7 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
|
|||
int status;
|
||||
umode_t fmode = 0;
|
||||
uint32_t type;
|
||||
int32_t err;
|
||||
|
||||
status = decode_attr_type(xdr, bitmap, &type);
|
||||
if (status < 0)
|
||||
|
@ -4095,13 +4096,12 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
|
|||
goto xdr_error;
|
||||
fattr->valid |= status;
|
||||
|
||||
status = decode_attr_error(xdr, bitmap);
|
||||
if (status == -NFS4ERR_WRONGSEC) {
|
||||
nfs_fixup_secinfo_attributes(fattr, fh);
|
||||
status = 0;
|
||||
}
|
||||
err = 0;
|
||||
status = decode_attr_error(xdr, bitmap, &err);
|
||||
if (status < 0)
|
||||
goto xdr_error;
|
||||
if (err == -NFS4ERR_WRONGSEC)
|
||||
nfs_fixup_secinfo_attributes(fattr, fh);
|
||||
|
||||
status = decode_attr_filehandle(xdr, bitmap, fh);
|
||||
if (status < 0)
|
||||
|
@ -4997,12 +4997,14 @@ static int decode_chan_attrs(struct xdr_stream *xdr,
|
|||
struct nfs4_channel_attrs *attrs)
|
||||
{
|
||||
__be32 *p;
|
||||
u32 nr_attrs;
|
||||
u32 nr_attrs, val;
|
||||
|
||||
p = xdr_inline_decode(xdr, 28);
|
||||
if (unlikely(!p))
|
||||
goto out_overflow;
|
||||
attrs->headerpadsz = be32_to_cpup(p++);
|
||||
val = be32_to_cpup(p++); /* headerpadsz */
|
||||
if (val)
|
||||
return -EINVAL; /* no support for header padding yet */
|
||||
attrs->max_rqst_sz = be32_to_cpup(p++);
|
||||
attrs->max_resp_sz = be32_to_cpup(p++);
|
||||
attrs->max_resp_sz_cached = be32_to_cpup(p++);
|
||||
|
|
|
@ -108,7 +108,6 @@ _dev_list_add(const struct nfs_server *nfss,
|
|||
de = n;
|
||||
}
|
||||
|
||||
atomic_inc(&de->id_node.ref);
|
||||
return de;
|
||||
}
|
||||
|
||||
|
@ -1001,6 +1000,9 @@ static bool objio_pg_test(struct nfs_pageio_descriptor *pgio,
|
|||
if (!pnfs_generic_pg_test(pgio, prev, req))
|
||||
return false;
|
||||
|
||||
if (pgio->pg_lseg == NULL)
|
||||
return true;
|
||||
|
||||
return pgio->pg_count + req->wb_bytes <=
|
||||
OBJIO_LSEG(pgio->pg_lseg)->max_io_size;
|
||||
}
|
||||
|
|
|
@ -291,7 +291,7 @@ objlayout_read_done(struct objlayout_io_state *state, ssize_t status, bool sync)
|
|||
struct nfs_read_data *rdata;
|
||||
|
||||
state->status = status;
|
||||
dprintk("%s: Begin status=%ld eof=%d\n", __func__, status, eof);
|
||||
dprintk("%s: Begin status=%zd eof=%d\n", __func__, status, eof);
|
||||
rdata = state->rpcdata;
|
||||
rdata->task.tk_status = status;
|
||||
if (status >= 0) {
|
||||
|
|
|
@ -204,7 +204,7 @@ nfs_wait_on_request(struct nfs_page *req)
|
|||
TASK_UNINTERRUPTIBLE);
|
||||
}
|
||||
|
||||
static bool nfs_generic_pg_test(struct nfs_pageio_descriptor *desc, struct nfs_page *prev, struct nfs_page *req)
|
||||
bool nfs_generic_pg_test(struct nfs_pageio_descriptor *desc, struct nfs_page *prev, struct nfs_page *req)
|
||||
{
|
||||
/*
|
||||
* FIXME: ideally we should be able to coalesce all requests
|
||||
|
@ -218,6 +218,7 @@ static bool nfs_generic_pg_test(struct nfs_pageio_descriptor *desc, struct nfs_p
|
|||
|
||||
return desc->pg_count + req->wb_bytes <= desc->pg_bsize;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_generic_pg_test);
|
||||
|
||||
/**
|
||||
* nfs_pageio_init - initialise a page io descriptor
|
||||
|
|
|
@ -634,14 +634,16 @@ _pnfs_return_layout(struct inode *ino)
|
|||
|
||||
spin_lock(&ino->i_lock);
|
||||
lo = nfsi->layout;
|
||||
if (!lo || !mark_matching_lsegs_invalid(lo, &tmp_list, NULL)) {
|
||||
if (!lo) {
|
||||
spin_unlock(&ino->i_lock);
|
||||
dprintk("%s: no layout segments to return\n", __func__);
|
||||
goto out;
|
||||
dprintk("%s: no layout to return\n", __func__);
|
||||
return status;
|
||||
}
|
||||
stateid = nfsi->layout->plh_stateid;
|
||||
/* Reference matched in nfs4_layoutreturn_release */
|
||||
get_layout_hdr(lo);
|
||||
mark_matching_lsegs_invalid(lo, &tmp_list, NULL);
|
||||
lo->plh_block_lgets++;
|
||||
spin_unlock(&ino->i_lock);
|
||||
pnfs_free_lseg_list(&tmp_list);
|
||||
|
||||
|
@ -650,6 +652,9 @@ _pnfs_return_layout(struct inode *ino)
|
|||
lrp = kzalloc(sizeof(*lrp), GFP_KERNEL);
|
||||
if (unlikely(lrp == NULL)) {
|
||||
status = -ENOMEM;
|
||||
set_bit(NFS_LAYOUT_RW_FAILED, &lo->plh_flags);
|
||||
set_bit(NFS_LAYOUT_RO_FAILED, &lo->plh_flags);
|
||||
put_layout_hdr(lo);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -887,7 +892,7 @@ pnfs_find_lseg(struct pnfs_layout_hdr *lo,
|
|||
ret = get_lseg(lseg);
|
||||
break;
|
||||
}
|
||||
if (cmp_layout(range, &lseg->pls_range) > 0)
|
||||
if (lseg->pls_range.offset > range->offset)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1059,23 +1064,36 @@ pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
|
|||
gfp_flags = GFP_NOFS;
|
||||
}
|
||||
|
||||
if (pgio->pg_count == prev->wb_bytes) {
|
||||
if (pgio->pg_lseg == NULL) {
|
||||
if (pgio->pg_count != prev->wb_bytes)
|
||||
return true;
|
||||
/* This is first coelesce call for a series of nfs_pages */
|
||||
pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
|
||||
prev->wb_context,
|
||||
req_offset(req),
|
||||
req_offset(prev),
|
||||
pgio->pg_count,
|
||||
access_type,
|
||||
gfp_flags);
|
||||
return true;
|
||||
if (pgio->pg_lseg == NULL)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pgio->pg_lseg &&
|
||||
req_offset(req) > end_offset(pgio->pg_lseg->pls_range.offset,
|
||||
pgio->pg_lseg->pls_range.length))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
/*
|
||||
* Test if a nfs_page is fully contained in the pnfs_layout_range.
|
||||
* Note that this test makes several assumptions:
|
||||
* - that the previous nfs_page in the struct nfs_pageio_descriptor
|
||||
* is known to lie within the range.
|
||||
* - that the nfs_page being tested is known to be contiguous with the
|
||||
* previous nfs_page.
|
||||
* - Layout ranges are page aligned, so we only have to test the
|
||||
* start offset of the request.
|
||||
*
|
||||
* Please also note that 'end_offset' is actually the offset of the
|
||||
* first byte that lies outside the pnfs_layout_range. FIXME?
|
||||
*
|
||||
*/
|
||||
return req_offset(req) < end_offset(pgio->pg_lseg->pls_range.offset,
|
||||
pgio->pg_lseg->pls_range.length);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pnfs_generic_pg_test);
|
||||
|
||||
|
|
|
@ -186,6 +186,7 @@ int pnfs_ld_read_done(struct nfs_read_data *);
|
|||
/* pnfs_dev.c */
|
||||
struct nfs4_deviceid_node {
|
||||
struct hlist_node node;
|
||||
struct hlist_node tmpnode;
|
||||
const struct pnfs_layoutdriver_type *ld;
|
||||
const struct nfs_client *nfs_client;
|
||||
struct nfs4_deviceid deviceid;
|
||||
|
|
|
@ -174,6 +174,7 @@ nfs4_init_deviceid_node(struct nfs4_deviceid_node *d,
|
|||
const struct nfs4_deviceid *id)
|
||||
{
|
||||
INIT_HLIST_NODE(&d->node);
|
||||
INIT_HLIST_NODE(&d->tmpnode);
|
||||
d->ld = ld;
|
||||
d->nfs_client = nfs_client;
|
||||
d->deviceid = *id;
|
||||
|
@ -208,6 +209,7 @@ nfs4_insert_deviceid_node(struct nfs4_deviceid_node *new)
|
|||
|
||||
hlist_add_head_rcu(&new->node, &nfs4_deviceid_cache[hash]);
|
||||
spin_unlock(&nfs4_deviceid_lock);
|
||||
atomic_inc(&new->ref);
|
||||
|
||||
return new;
|
||||
}
|
||||
|
@ -238,24 +240,29 @@ static void
|
|||
_deviceid_purge_client(const struct nfs_client *clp, long hash)
|
||||
{
|
||||
struct nfs4_deviceid_node *d;
|
||||
struct hlist_node *n, *next;
|
||||
struct hlist_node *n;
|
||||
HLIST_HEAD(tmp);
|
||||
|
||||
spin_lock(&nfs4_deviceid_lock);
|
||||
rcu_read_lock();
|
||||
hlist_for_each_entry_rcu(d, n, &nfs4_deviceid_cache[hash], node)
|
||||
if (d->nfs_client == clp && atomic_read(&d->ref)) {
|
||||
hlist_del_init_rcu(&d->node);
|
||||
hlist_add_head(&d->node, &tmp);
|
||||
hlist_add_head(&d->tmpnode, &tmp);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
spin_unlock(&nfs4_deviceid_lock);
|
||||
|
||||
if (hlist_empty(&tmp))
|
||||
return;
|
||||
|
||||
synchronize_rcu();
|
||||
hlist_for_each_entry_safe(d, n, next, &tmp, node)
|
||||
while (!hlist_empty(&tmp)) {
|
||||
d = hlist_entry(tmp.first, struct nfs4_deviceid_node, tmpnode);
|
||||
hlist_del(&d->tmpnode);
|
||||
if (atomic_dec_and_test(&d->ref))
|
||||
d->ld->free_deviceid_node(d);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -263,8 +270,8 @@ nfs4_deviceid_purge_client(const struct nfs_client *clp)
|
|||
{
|
||||
long h;
|
||||
|
||||
spin_lock(&nfs4_deviceid_lock);
|
||||
if (!(clp->cl_exchange_flags & EXCHGID4_FLAG_USE_PNFS_MDS))
|
||||
return;
|
||||
for (h = 0; h < NFS4_DEVICE_ID_HASH_SIZE; h++)
|
||||
_deviceid_purge_client(clp, h);
|
||||
spin_unlock(&nfs4_deviceid_lock);
|
||||
}
|
||||
|
|
|
@ -92,6 +92,9 @@ extern int nfs_pageio_add_request(struct nfs_pageio_descriptor *,
|
|||
struct nfs_page *);
|
||||
extern void nfs_pageio_complete(struct nfs_pageio_descriptor *desc);
|
||||
extern void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *, pgoff_t);
|
||||
extern bool nfs_generic_pg_test(struct nfs_pageio_descriptor *desc,
|
||||
struct nfs_page *prev,
|
||||
struct nfs_page *req);
|
||||
extern int nfs_wait_on_request(struct nfs_page *);
|
||||
extern void nfs_unlock_request(struct nfs_page *req);
|
||||
extern int nfs_set_page_tag_locked(struct nfs_page *req);
|
||||
|
|
|
@ -158,7 +158,6 @@ struct nfs_seqid;
|
|||
|
||||
/* nfs41 sessions channel attributes */
|
||||
struct nfs4_channel_attrs {
|
||||
u32 headerpadsz;
|
||||
u32 max_rqst_sz;
|
||||
u32 max_resp_sz;
|
||||
u32 max_resp_sz_cached;
|
||||
|
|
|
@ -84,7 +84,8 @@ struct rpc_task {
|
|||
#endif
|
||||
unsigned char tk_priority : 2,/* Task priority */
|
||||
tk_garb_retry : 2,
|
||||
tk_cred_retry : 2;
|
||||
tk_cred_retry : 2,
|
||||
tk_rebind_retry : 2;
|
||||
};
|
||||
#define tk_xprt tk_client->cl_xprt
|
||||
|
||||
|
|
|
@ -577,13 +577,13 @@ retry:
|
|||
}
|
||||
inode = &gss_msg->inode->vfs_inode;
|
||||
for (;;) {
|
||||
prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_INTERRUPTIBLE);
|
||||
prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_KILLABLE);
|
||||
spin_lock(&inode->i_lock);
|
||||
if (gss_msg->ctx != NULL || gss_msg->msg.errno < 0) {
|
||||
break;
|
||||
}
|
||||
spin_unlock(&inode->i_lock);
|
||||
if (signalled()) {
|
||||
if (fatal_signal_pending(current)) {
|
||||
err = -ERESTARTSYS;
|
||||
goto out_intr;
|
||||
}
|
||||
|
|
|
@ -1061,7 +1061,7 @@ call_allocate(struct rpc_task *task)
|
|||
|
||||
dprintk("RPC: %5u rpc_buffer allocation failed\n", task->tk_pid);
|
||||
|
||||
if (RPC_IS_ASYNC(task) || !signalled()) {
|
||||
if (RPC_IS_ASYNC(task) || !fatal_signal_pending(current)) {
|
||||
task->tk_action = call_allocate;
|
||||
rpc_delay(task, HZ>>4);
|
||||
return;
|
||||
|
@ -1175,6 +1175,9 @@ call_bind_status(struct rpc_task *task)
|
|||
status = -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
if (task->tk_rebind_retry == 0)
|
||||
break;
|
||||
task->tk_rebind_retry--;
|
||||
rpc_delay(task, 3*HZ);
|
||||
goto retry_timeout;
|
||||
case -ETIMEDOUT:
|
||||
|
|
|
@ -792,6 +792,7 @@ static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *ta
|
|||
/* Initialize retry counters */
|
||||
task->tk_garb_retry = 2;
|
||||
task->tk_cred_retry = 2;
|
||||
task->tk_rebind_retry = 2;
|
||||
|
||||
task->tk_priority = task_setup_data->priority - RPC_PRIORITY_LOW;
|
||||
task->tk_owner = current->tgid;
|
||||
|
|
Loading…
Reference in a new issue