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

Commit 873b779d authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents 56b880e2 e216c8c7
Loading
Loading
Loading
Loading
+4 −4
Original line number Original line Diff line number Diff line
@@ -455,7 +455,7 @@ 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))
@@ -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;
+0 −2
Original line number Original line Diff line number Diff line
@@ -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;
+4 −4
Original line number Original line Diff line number Diff line
@@ -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
+1 −1
Original line number Original line Diff line number Diff line
@@ -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];
+34 −8
Original line number Original line Diff line number Diff line
@@ -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");
Loading