mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-30 14:19:16 +00:00
NFS client bugfixes for Linux 3.5
Highlights include: - Fix a couple of mount regressions due to the recent cleanups. - Fix an Oops in the open recovery code - Fix an rpc_pipefs upcall hang that results from some of the net namespace work from 3.4.x (stable kernel candidate). - Fix a couple of write and o_direct regressions that were found at last weeks Bakeathon testing event in Ann Arbor. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABAgAGBQJP2gmaAAoJEGcL54qWCgDyrBMP/RY/T++He8y5k3M9aEqiIv0q D8ZVMwzID6f4Zgw4xRg96aYr02sBTw0q+0mP5x1EZmg8mK29rnBiVeKHE1iwSfXq 10/SYISlpIjhJC4I4kHXGd2KClgj7qRRCbDKFRWwoIIwYU+kJn8MRnPa9XqdL8kP q68lrtayW8THSJDR8bk1GQn+ARxGeoY++qzHxm3vpQCbZVVb19VqKMWAWSN4VKqb epWehOSAzB3iA7HrLRbf8Y8/sDdXewxCQpr9CC/wxuu++l5ifPphR0ToX+k9VZXI BKFLUojCUZHTMAgCxuxjrFYehMeyClbzL2lLkz5Pgj0gQhOX6Myj+WMXoEg/uWfo XNf51FH3yBbnfayTaOUs6Y50iuU+dQO7TUTAoWTPpW9V/iT5z/fWAKUVJhDtrPk5 DVDkR6SEgb4P1RqkehZKLq5k5GSAcTR+MZr452eDrFYXJrY8ORDE6o6kP4Rr3Nnd n8gap0gHxzIYlhBghem6+nLN+HhpZQopWeD8mNub20VuXsChRDr9/+XWuMCSJaZF 2kleVdt2+rTDzi9bJTRYlsX397oaThL0NbRvshHAwnXIDtIQrzxx6+dUyOsEWMEu go/EdSUUESXGNlsWTqewCBsOjPeE4L5ijI/QglfDkF+CzD5dDjrxl+5i57iMKVfc Ydste3pQJkS7PiZu1sWA =unbu -----END PGP SIGNATURE----- Merge tag 'nfs-for-3.5-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs Pull NFS client bugfixes from Trond Myklebust: "Highlights include: - Fix a couple of mount regressions due to the recent cleanups. - Fix an Oops in the open recovery code - Fix an rpc_pipefs upcall hang that results from some of the net namespace work from 3.4.x (stable kernel candidate). - Fix a couple of write and o_direct regressions that were found at last weeks Bakeathon testing event in Ann Arbor." * tag 'nfs-for-3.5-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: NFS: add an endian notation for sparse NFSv4.1: integer overflow in decode_cb_sequence_args() rpc_pipefs: allow rpc_purge_list to take a NULL waitq pointer NFSv4 do not send an empty SETATTR compound NFSv2: EOF incorrectly set on short read NFS: Use the NFS_DEFAULT_VERSION for v2 and v3 mounts NFS: fix directio refcount bug on commit NFSv4: Fix unnecessary delegation returns in nfs4_do_open NFSv4.1: Convert another trivial printk into a dprintk NFS4: Fix open bug when pnfs module blacklisted NFS: Remove incorrect BUG_ON in nfs_found_client NFS: Map minor mismatch error to protocol not support error. NFS: Fix a commit bug NFS4: Set parsed mount data version to 4 NFSv4.1: Ensure we clear session state flags after a session creation NFSv4.1: Convert a trivial printk into a dprintk NFSv4: Fix up decode_attr_mdsthreshold NFSv4: Fix an Oops in the open recovery code NFSv4.1: Fix a request leak on the back channel
This commit is contained in:
commit
873b779d99
14 changed files with 85 additions and 46 deletions
|
@ -455,9 +455,9 @@ static __be32 decode_cb_sequence_args(struct svc_rqst *rqstp,
|
||||||
args->csa_nrclists = ntohl(*p++);
|
args->csa_nrclists = ntohl(*p++);
|
||||||
args->csa_rclists = NULL;
|
args->csa_rclists = NULL;
|
||||||
if (args->csa_nrclists) {
|
if (args->csa_nrclists) {
|
||||||
args->csa_rclists = kmalloc(args->csa_nrclists *
|
args->csa_rclists = kmalloc_array(args->csa_nrclists,
|
||||||
sizeof(*args->csa_rclists),
|
sizeof(*args->csa_rclists),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (unlikely(args->csa_rclists == NULL))
|
if (unlikely(args->csa_rclists == NULL))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -696,7 +696,7 @@ static __be32 encode_cb_sequence_res(struct svc_rqst *rqstp,
|
||||||
const struct cb_sequenceres *res)
|
const struct cb_sequenceres *res)
|
||||||
{
|
{
|
||||||
__be32 *p;
|
__be32 *p;
|
||||||
unsigned status = res->csr_status;
|
__be32 status = res->csr_status;
|
||||||
|
|
||||||
if (unlikely(status != 0))
|
if (unlikely(status != 0))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
|
@ -544,8 +544,6 @@ nfs_found_client(const struct nfs_client_initdata *cl_init,
|
||||||
|
|
||||||
smp_rmb();
|
smp_rmb();
|
||||||
|
|
||||||
BUG_ON(clp->cl_cons_state != NFS_CS_READY);
|
|
||||||
|
|
||||||
dprintk("<-- %s found nfs_client %p for %s\n",
|
dprintk("<-- %s found nfs_client %p for %s\n",
|
||||||
__func__, clp, cl_init->hostname ?: "");
|
__func__, clp, cl_init->hostname ?: "");
|
||||||
return clp;
|
return clp;
|
||||||
|
|
|
@ -523,9 +523,9 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data)
|
||||||
nfs_list_remove_request(req);
|
nfs_list_remove_request(req);
|
||||||
if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES) {
|
if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES) {
|
||||||
/* Note the rewrite will go through mds */
|
/* Note the rewrite will go through mds */
|
||||||
kref_get(&req->wb_kref);
|
|
||||||
nfs_mark_request_commit(req, NULL, &cinfo);
|
nfs_mark_request_commit(req, NULL, &cinfo);
|
||||||
}
|
} else
|
||||||
|
nfs_release_request(req);
|
||||||
nfs_unlock_and_release_request(req);
|
nfs_unlock_and_release_request(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -716,12 +716,12 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr)
|
||||||
if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES)
|
if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES)
|
||||||
bit = NFS_IOHDR_NEED_RESCHED;
|
bit = NFS_IOHDR_NEED_RESCHED;
|
||||||
else if (dreq->flags == 0) {
|
else if (dreq->flags == 0) {
|
||||||
memcpy(&dreq->verf, &req->wb_verf,
|
memcpy(&dreq->verf, hdr->verf,
|
||||||
sizeof(dreq->verf));
|
sizeof(dreq->verf));
|
||||||
bit = NFS_IOHDR_NEED_COMMIT;
|
bit = NFS_IOHDR_NEED_COMMIT;
|
||||||
dreq->flags = NFS_ODIRECT_DO_COMMIT;
|
dreq->flags = NFS_ODIRECT_DO_COMMIT;
|
||||||
} else if (dreq->flags == NFS_ODIRECT_DO_COMMIT) {
|
} else if (dreq->flags == NFS_ODIRECT_DO_COMMIT) {
|
||||||
if (memcmp(&dreq->verf, &req->wb_verf, sizeof(dreq->verf))) {
|
if (memcmp(&dreq->verf, hdr->verf, sizeof(dreq->verf))) {
|
||||||
dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
|
dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
|
||||||
bit = NFS_IOHDR_NEED_RESCHED;
|
bit = NFS_IOHDR_NEED_RESCHED;
|
||||||
} else
|
} else
|
||||||
|
|
|
@ -295,7 +295,7 @@ is_ds_client(struct nfs_client *clp)
|
||||||
|
|
||||||
extern const struct nfs4_minor_version_ops *nfs_v4_minor_ops[];
|
extern const struct nfs4_minor_version_ops *nfs_v4_minor_ops[];
|
||||||
|
|
||||||
extern const u32 nfs4_fattr_bitmap[2];
|
extern const u32 nfs4_fattr_bitmap[3];
|
||||||
extern const u32 nfs4_statfs_bitmap[2];
|
extern const u32 nfs4_statfs_bitmap[2];
|
||||||
extern const u32 nfs4_pathconf_bitmap[2];
|
extern const u32 nfs4_pathconf_bitmap[2];
|
||||||
extern const u32 nfs4_fsinfo_bitmap[3];
|
extern const u32 nfs4_fsinfo_bitmap[3];
|
||||||
|
|
|
@ -105,6 +105,8 @@ static int nfs4_map_errors(int err)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
case -NFS4ERR_SHARE_DENIED:
|
case -NFS4ERR_SHARE_DENIED:
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
|
case -NFS4ERR_MINOR_VERS_MISMATCH:
|
||||||
|
return -EPROTONOSUPPORT;
|
||||||
default:
|
default:
|
||||||
dprintk("%s could not handle NFSv4 error %d\n",
|
dprintk("%s could not handle NFSv4 error %d\n",
|
||||||
__func__, -err);
|
__func__, -err);
|
||||||
|
@ -116,7 +118,7 @@ static int nfs4_map_errors(int err)
|
||||||
/*
|
/*
|
||||||
* This is our standard bitmap for GETATTR requests.
|
* This is our standard bitmap for GETATTR requests.
|
||||||
*/
|
*/
|
||||||
const u32 nfs4_fattr_bitmap[2] = {
|
const u32 nfs4_fattr_bitmap[3] = {
|
||||||
FATTR4_WORD0_TYPE
|
FATTR4_WORD0_TYPE
|
||||||
| FATTR4_WORD0_CHANGE
|
| FATTR4_WORD0_CHANGE
|
||||||
| FATTR4_WORD0_SIZE
|
| FATTR4_WORD0_SIZE
|
||||||
|
@ -133,6 +135,24 @@ const u32 nfs4_fattr_bitmap[2] = {
|
||||||
| FATTR4_WORD1_TIME_MODIFY
|
| FATTR4_WORD1_TIME_MODIFY
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const u32 nfs4_pnfs_open_bitmap[3] = {
|
||||||
|
FATTR4_WORD0_TYPE
|
||||||
|
| FATTR4_WORD0_CHANGE
|
||||||
|
| FATTR4_WORD0_SIZE
|
||||||
|
| FATTR4_WORD0_FSID
|
||||||
|
| FATTR4_WORD0_FILEID,
|
||||||
|
FATTR4_WORD1_MODE
|
||||||
|
| FATTR4_WORD1_NUMLINKS
|
||||||
|
| FATTR4_WORD1_OWNER
|
||||||
|
| FATTR4_WORD1_OWNER_GROUP
|
||||||
|
| FATTR4_WORD1_RAWDEV
|
||||||
|
| FATTR4_WORD1_SPACE_USED
|
||||||
|
| FATTR4_WORD1_TIME_ACCESS
|
||||||
|
| FATTR4_WORD1_TIME_METADATA
|
||||||
|
| FATTR4_WORD1_TIME_MODIFY,
|
||||||
|
FATTR4_WORD2_MDSTHRESHOLD
|
||||||
|
};
|
||||||
|
|
||||||
const u32 nfs4_statfs_bitmap[2] = {
|
const u32 nfs4_statfs_bitmap[2] = {
|
||||||
FATTR4_WORD0_FILES_AVAIL
|
FATTR4_WORD0_FILES_AVAIL
|
||||||
| FATTR4_WORD0_FILES_FREE
|
| FATTR4_WORD0_FILES_FREE
|
||||||
|
@ -844,6 +864,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
|
||||||
p->o_arg.name = &dentry->d_name;
|
p->o_arg.name = &dentry->d_name;
|
||||||
p->o_arg.server = server;
|
p->o_arg.server = server;
|
||||||
p->o_arg.bitmask = server->attr_bitmask;
|
p->o_arg.bitmask = server->attr_bitmask;
|
||||||
|
p->o_arg.open_bitmap = &nfs4_fattr_bitmap[0];
|
||||||
p->o_arg.claim = NFS4_OPEN_CLAIM_NULL;
|
p->o_arg.claim = NFS4_OPEN_CLAIM_NULL;
|
||||||
if (attrs != NULL && attrs->ia_valid != 0) {
|
if (attrs != NULL && attrs->ia_valid != 0) {
|
||||||
__be32 verf[2];
|
__be32 verf[2];
|
||||||
|
@ -1820,6 +1841,7 @@ static int _nfs4_do_open(struct inode *dir,
|
||||||
opendata->f_attr.mdsthreshold = pnfs_mdsthreshold_alloc();
|
opendata->f_attr.mdsthreshold = pnfs_mdsthreshold_alloc();
|
||||||
if (!opendata->f_attr.mdsthreshold)
|
if (!opendata->f_attr.mdsthreshold)
|
||||||
goto err_opendata_put;
|
goto err_opendata_put;
|
||||||
|
opendata->o_arg.open_bitmap = &nfs4_pnfs_open_bitmap[0];
|
||||||
}
|
}
|
||||||
if (dentry->d_inode != NULL)
|
if (dentry->d_inode != NULL)
|
||||||
opendata->state = nfs4_get_open_state(dentry->d_inode, sp);
|
opendata->state = nfs4_get_open_state(dentry->d_inode, sp);
|
||||||
|
@ -1880,6 +1902,7 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir,
|
||||||
struct nfs4_state *res;
|
struct nfs4_state *res;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
|
fmode &= FMODE_READ|FMODE_WRITE;
|
||||||
do {
|
do {
|
||||||
status = _nfs4_do_open(dir, dentry, fmode, flags, sattr, cred,
|
status = _nfs4_do_open(dir, dentry, fmode, flags, sattr, cred,
|
||||||
&res, ctx_th);
|
&res, ctx_th);
|
||||||
|
@ -2526,6 +2549,14 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
|
||||||
|
|
||||||
nfs_fattr_init(fattr);
|
nfs_fattr_init(fattr);
|
||||||
|
|
||||||
|
/* Deal with open(O_TRUNC) */
|
||||||
|
if (sattr->ia_valid & ATTR_OPEN)
|
||||||
|
sattr->ia_valid &= ~(ATTR_MTIME|ATTR_CTIME|ATTR_OPEN);
|
||||||
|
|
||||||
|
/* Optimization: if the end result is no change, don't RPC */
|
||||||
|
if ((sattr->ia_valid & ~(ATTR_FILE)) == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* Search for an existing open(O_WRITE) file */
|
/* Search for an existing open(O_WRITE) file */
|
||||||
if (sattr->ia_valid & ATTR_FILE) {
|
if (sattr->ia_valid & ATTR_FILE) {
|
||||||
struct nfs_open_context *ctx;
|
struct nfs_open_context *ctx;
|
||||||
|
@ -2537,10 +2568,6 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Deal with open(O_TRUNC) */
|
|
||||||
if (sattr->ia_valid & ATTR_OPEN)
|
|
||||||
sattr->ia_valid &= ~(ATTR_MTIME|ATTR_CTIME|ATTR_OPEN);
|
|
||||||
|
|
||||||
status = nfs4_do_setattr(inode, cred, fattr, sattr, state);
|
status = nfs4_do_setattr(inode, cred, fattr, sattr, state);
|
||||||
if (status == 0)
|
if (status == 0)
|
||||||
nfs_setattr_update_inode(inode, sattr);
|
nfs_setattr_update_inode(inode, sattr);
|
||||||
|
@ -5275,7 +5302,7 @@ static int _nfs4_proc_destroy_clientid(struct nfs_client *clp,
|
||||||
|
|
||||||
status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
|
status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
|
||||||
if (status)
|
if (status)
|
||||||
pr_warn("NFS: Got error %d from the server %s on "
|
dprintk("NFS: Got error %d from the server %s on "
|
||||||
"DESTROY_CLIENTID.", status, clp->cl_hostname);
|
"DESTROY_CLIENTID.", status, clp->cl_hostname);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -5746,8 +5773,7 @@ int nfs4_proc_destroy_session(struct nfs4_session *session,
|
||||||
status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
|
status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
|
||||||
|
|
||||||
if (status)
|
if (status)
|
||||||
printk(KERN_WARNING
|
dprintk("NFS: Got error %d from the server on DESTROY_SESSION. "
|
||||||
"NFS: Got error %d from the server on DESTROY_SESSION. "
|
|
||||||
"Session has been destroyed regardless...\n", status);
|
"Session has been destroyed regardless...\n", status);
|
||||||
|
|
||||||
dprintk("<-- nfs4_proc_destroy_session\n");
|
dprintk("<-- nfs4_proc_destroy_session\n");
|
||||||
|
|
|
@ -244,6 +244,16 @@ static int nfs4_begin_drain_session(struct nfs_client *clp)
|
||||||
return nfs4_wait_on_slot_tbl(&ses->fc_slot_table);
|
return nfs4_wait_on_slot_tbl(&ses->fc_slot_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void nfs41_finish_session_reset(struct nfs_client *clp)
|
||||||
|
{
|
||||||
|
clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
|
||||||
|
clear_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state);
|
||||||
|
/* create_session negotiated new slot table */
|
||||||
|
clear_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state);
|
||||||
|
clear_bit(NFS4CLNT_BIND_CONN_TO_SESSION, &clp->cl_state);
|
||||||
|
nfs41_setup_state_renewal(clp);
|
||||||
|
}
|
||||||
|
|
||||||
int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
|
int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
|
@ -259,8 +269,7 @@ int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
|
||||||
status = nfs4_proc_create_session(clp, cred);
|
status = nfs4_proc_create_session(clp, cred);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
goto out;
|
goto out;
|
||||||
clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
|
nfs41_finish_session_reset(clp);
|
||||||
nfs41_setup_state_renewal(clp);
|
|
||||||
nfs_mark_client_ready(clp, NFS_CS_READY);
|
nfs_mark_client_ready(clp, NFS_CS_READY);
|
||||||
out:
|
out:
|
||||||
return status;
|
return status;
|
||||||
|
@ -1772,16 +1781,9 @@ static int nfs4_reset_session(struct nfs_client *clp)
|
||||||
status = nfs4_handle_reclaim_lease_error(clp, status);
|
status = nfs4_handle_reclaim_lease_error(clp, status);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
clear_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state);
|
nfs41_finish_session_reset(clp);
|
||||||
/* create_session negotiated new slot table */
|
|
||||||
clear_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state);
|
|
||||||
clear_bit(NFS4CLNT_BIND_CONN_TO_SESSION, &clp->cl_state);
|
|
||||||
dprintk("%s: session reset was successful for server %s!\n",
|
dprintk("%s: session reset was successful for server %s!\n",
|
||||||
__func__, clp->cl_hostname);
|
__func__, clp->cl_hostname);
|
||||||
|
|
||||||
/* Let the state manager reestablish state */
|
|
||||||
if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
|
|
||||||
nfs41_setup_state_renewal(clp);
|
|
||||||
out:
|
out:
|
||||||
if (cred)
|
if (cred)
|
||||||
put_rpccred(cred);
|
put_rpccred(cred);
|
||||||
|
|
|
@ -1198,12 +1198,13 @@ static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct c
|
||||||
}
|
}
|
||||||
|
|
||||||
static void encode_getfattr_open(struct xdr_stream *xdr, const u32 *bitmask,
|
static void encode_getfattr_open(struct xdr_stream *xdr, const u32 *bitmask,
|
||||||
|
const u32 *open_bitmap,
|
||||||
struct compound_hdr *hdr)
|
struct compound_hdr *hdr)
|
||||||
{
|
{
|
||||||
encode_getattr_three(xdr,
|
encode_getattr_three(xdr,
|
||||||
bitmask[0] & nfs4_fattr_bitmap[0],
|
bitmask[0] & open_bitmap[0],
|
||||||
bitmask[1] & nfs4_fattr_bitmap[1],
|
bitmask[1] & open_bitmap[1],
|
||||||
bitmask[2] & FATTR4_WORD2_MDSTHRESHOLD,
|
bitmask[2] & open_bitmap[2],
|
||||||
hdr);
|
hdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2221,7 +2222,7 @@ static void nfs4_xdr_enc_open(struct rpc_rqst *req, struct xdr_stream *xdr,
|
||||||
encode_putfh(xdr, args->fh, &hdr);
|
encode_putfh(xdr, args->fh, &hdr);
|
||||||
encode_open(xdr, args, &hdr);
|
encode_open(xdr, args, &hdr);
|
||||||
encode_getfh(xdr, &hdr);
|
encode_getfh(xdr, &hdr);
|
||||||
encode_getfattr_open(xdr, args->bitmask, &hdr);
|
encode_getfattr_open(xdr, args->bitmask, args->open_bitmap, &hdr);
|
||||||
encode_nops(&hdr);
|
encode_nops(&hdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4359,7 +4360,10 @@ static int decode_attr_mdsthreshold(struct xdr_stream *xdr,
|
||||||
|
|
||||||
if (unlikely(bitmap[2] & (FATTR4_WORD2_MDSTHRESHOLD - 1U)))
|
if (unlikely(bitmap[2] & (FATTR4_WORD2_MDSTHRESHOLD - 1U)))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
if (likely(bitmap[2] & FATTR4_WORD2_MDSTHRESHOLD)) {
|
if (bitmap[2] & FATTR4_WORD2_MDSTHRESHOLD) {
|
||||||
|
/* Did the server return an unrequested attribute? */
|
||||||
|
if (unlikely(res == NULL))
|
||||||
|
return -EREMOTEIO;
|
||||||
p = xdr_inline_decode(xdr, 4);
|
p = xdr_inline_decode(xdr, 4);
|
||||||
if (unlikely(!p))
|
if (unlikely(!p))
|
||||||
goto out_overflow;
|
goto out_overflow;
|
||||||
|
@ -4372,6 +4376,7 @@ static int decode_attr_mdsthreshold(struct xdr_stream *xdr,
|
||||||
__func__);
|
__func__);
|
||||||
|
|
||||||
status = decode_first_threshold_item4(xdr, res);
|
status = decode_first_threshold_item4(xdr, res);
|
||||||
|
bitmap[2] &= ~FATTR4_WORD2_MDSTHRESHOLD;
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
out_overflow:
|
out_overflow:
|
||||||
|
|
|
@ -365,7 +365,7 @@ static inline bool
|
||||||
pnfs_use_threshold(struct nfs4_threshold **dst, struct nfs4_threshold *src,
|
pnfs_use_threshold(struct nfs4_threshold **dst, struct nfs4_threshold *src,
|
||||||
struct nfs_server *nfss)
|
struct nfs_server *nfss)
|
||||||
{
|
{
|
||||||
return (dst && src && src->bm != 0 &&
|
return (dst && src && src->bm != 0 && nfss->pnfs_curr_ld &&
|
||||||
nfss->pnfs_curr_ld->id == src->l_type);
|
nfss->pnfs_curr_ld->id == src->l_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -651,7 +651,7 @@ static int nfs_read_done(struct rpc_task *task, struct nfs_read_data *data)
|
||||||
/* Emulate the eof flag, which isn't normally needed in NFSv2
|
/* Emulate the eof flag, which isn't normally needed in NFSv2
|
||||||
* as it is guaranteed to always return the file attributes
|
* as it is guaranteed to always return the file attributes
|
||||||
*/
|
*/
|
||||||
if (data->args.offset + data->args.count >= data->res.fattr->size)
|
if (data->args.offset + data->res.count >= data->res.fattr->size)
|
||||||
data->res.eof = 1;
|
data->res.eof = 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1867,6 +1867,7 @@ static int nfs23_validate_mount_data(void *options,
|
||||||
if (data == NULL)
|
if (data == NULL)
|
||||||
goto out_no_data;
|
goto out_no_data;
|
||||||
|
|
||||||
|
args->version = NFS_DEFAULT_VERSION;
|
||||||
switch (data->version) {
|
switch (data->version) {
|
||||||
case 1:
|
case 1:
|
||||||
data->namlen = 0;
|
data->namlen = 0;
|
||||||
|
@ -2637,6 +2638,8 @@ static int nfs4_validate_mount_data(void *options,
|
||||||
if (data == NULL)
|
if (data == NULL)
|
||||||
goto out_no_data;
|
goto out_no_data;
|
||||||
|
|
||||||
|
args->version = 4;
|
||||||
|
|
||||||
switch (data->version) {
|
switch (data->version) {
|
||||||
case 1:
|
case 1:
|
||||||
if (data->host_addrlen > sizeof(args->nfs_server.address))
|
if (data->host_addrlen > sizeof(args->nfs_server.address))
|
||||||
|
|
|
@ -80,6 +80,7 @@ struct nfs_write_header *nfs_writehdr_alloc(void)
|
||||||
INIT_LIST_HEAD(&hdr->rpc_list);
|
INIT_LIST_HEAD(&hdr->rpc_list);
|
||||||
spin_lock_init(&hdr->lock);
|
spin_lock_init(&hdr->lock);
|
||||||
atomic_set(&hdr->refcnt, 0);
|
atomic_set(&hdr->refcnt, 0);
|
||||||
|
hdr->verf = &p->verf;
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -619,6 +620,7 @@ static void nfs_write_completion(struct nfs_pgio_header *hdr)
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
if (test_bit(NFS_IOHDR_NEED_COMMIT, &hdr->flags)) {
|
if (test_bit(NFS_IOHDR_NEED_COMMIT, &hdr->flags)) {
|
||||||
|
memcpy(&req->wb_verf, hdr->verf, sizeof(req->wb_verf));
|
||||||
nfs_mark_request_commit(req, hdr->lseg, &cinfo);
|
nfs_mark_request_commit(req, hdr->lseg, &cinfo);
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
@ -1255,15 +1257,14 @@ static void nfs_writeback_release_common(void *calldata)
|
||||||
struct nfs_write_data *data = calldata;
|
struct nfs_write_data *data = calldata;
|
||||||
struct nfs_pgio_header *hdr = data->header;
|
struct nfs_pgio_header *hdr = data->header;
|
||||||
int status = data->task.tk_status;
|
int status = data->task.tk_status;
|
||||||
struct nfs_page *req = hdr->req;
|
|
||||||
|
|
||||||
if ((status >= 0) && nfs_write_need_commit(data)) {
|
if ((status >= 0) && nfs_write_need_commit(data)) {
|
||||||
spin_lock(&hdr->lock);
|
spin_lock(&hdr->lock);
|
||||||
if (test_bit(NFS_IOHDR_NEED_RESCHED, &hdr->flags))
|
if (test_bit(NFS_IOHDR_NEED_RESCHED, &hdr->flags))
|
||||||
; /* Do nothing */
|
; /* Do nothing */
|
||||||
else if (!test_and_set_bit(NFS_IOHDR_NEED_COMMIT, &hdr->flags))
|
else if (!test_and_set_bit(NFS_IOHDR_NEED_COMMIT, &hdr->flags))
|
||||||
memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf));
|
memcpy(hdr->verf, &data->verf, sizeof(*hdr->verf));
|
||||||
else if (memcmp(&req->wb_verf, &data->verf, sizeof(req->wb_verf)))
|
else if (memcmp(hdr->verf, &data->verf, sizeof(*hdr->verf)))
|
||||||
set_bit(NFS_IOHDR_NEED_RESCHED, &hdr->flags);
|
set_bit(NFS_IOHDR_NEED_RESCHED, &hdr->flags);
|
||||||
spin_unlock(&hdr->lock);
|
spin_unlock(&hdr->lock);
|
||||||
}
|
}
|
||||||
|
|
|
@ -348,6 +348,7 @@ struct nfs_openargs {
|
||||||
const struct qstr * name;
|
const struct qstr * name;
|
||||||
const struct nfs_server *server; /* Needed for ID mapping */
|
const struct nfs_server *server; /* Needed for ID mapping */
|
||||||
const u32 * bitmask;
|
const u32 * bitmask;
|
||||||
|
const u32 * open_bitmap;
|
||||||
__u32 claim;
|
__u32 claim;
|
||||||
struct nfs4_sequence_args seq_args;
|
struct nfs4_sequence_args seq_args;
|
||||||
};
|
};
|
||||||
|
@ -1236,6 +1237,7 @@ struct nfs_pgio_header {
|
||||||
struct list_head rpc_list;
|
struct list_head rpc_list;
|
||||||
atomic_t refcnt;
|
atomic_t refcnt;
|
||||||
struct nfs_page *req;
|
struct nfs_page *req;
|
||||||
|
struct nfs_writeverf *verf;
|
||||||
struct pnfs_layout_segment *lseg;
|
struct pnfs_layout_segment *lseg;
|
||||||
loff_t io_start;
|
loff_t io_start;
|
||||||
const struct rpc_call_ops *mds_ops;
|
const struct rpc_call_ops *mds_ops;
|
||||||
|
@ -1273,6 +1275,7 @@ struct nfs_write_data {
|
||||||
struct nfs_write_header {
|
struct nfs_write_header {
|
||||||
struct nfs_pgio_header header;
|
struct nfs_pgio_header header;
|
||||||
struct nfs_write_data rpc_data;
|
struct nfs_write_data rpc_data;
|
||||||
|
struct nfs_writeverf verf;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nfs_mds_commit_info {
|
struct nfs_mds_commit_info {
|
||||||
|
|
|
@ -71,7 +71,9 @@ static void rpc_purge_list(wait_queue_head_t *waitq, struct list_head *head,
|
||||||
msg->errno = err;
|
msg->errno = err;
|
||||||
destroy_msg(msg);
|
destroy_msg(msg);
|
||||||
} while (!list_empty(head));
|
} while (!list_empty(head));
|
||||||
wake_up(waitq);
|
|
||||||
|
if (waitq)
|
||||||
|
wake_up(waitq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -91,11 +93,9 @@ rpc_timeout_upcall_queue(struct work_struct *work)
|
||||||
}
|
}
|
||||||
dentry = dget(pipe->dentry);
|
dentry = dget(pipe->dentry);
|
||||||
spin_unlock(&pipe->lock);
|
spin_unlock(&pipe->lock);
|
||||||
if (dentry) {
|
rpc_purge_list(dentry ? &RPC_I(dentry->d_inode)->waitq : NULL,
|
||||||
rpc_purge_list(&RPC_I(dentry->d_inode)->waitq,
|
&free_list, destroy_msg, -ETIMEDOUT);
|
||||||
&free_list, destroy_msg, -ETIMEDOUT);
|
dput(dentry);
|
||||||
dput(dentry);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t rpc_pipe_generic_upcall(struct file *filp, struct rpc_pipe_msg *msg,
|
ssize_t rpc_pipe_generic_upcall(struct file *filp, struct rpc_pipe_msg *msg,
|
||||||
|
|
|
@ -1374,7 +1374,8 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req,
|
||||||
sizeof(req->rq_snd_buf));
|
sizeof(req->rq_snd_buf));
|
||||||
return bc_send(req);
|
return bc_send(req);
|
||||||
} else {
|
} else {
|
||||||
/* Nothing to do to drop request */
|
/* drop request */
|
||||||
|
xprt_free_bc_request(req);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue