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

Commit 24a52e41 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull more NFS client updates from Trond Myklebust:
 "Highlights include:

   - Fix a use-after-free in decode_cb_sequence_args()
   - Fix a compile error when #undef CONFIG_PROC_FS
   - NFSv4.1 backchannel spinlocking issue
   - Cleanups in the NFS unstable write code requested by Linus
   - NFSv4.1 fix issues when the server denies our backchannel request
   - Cleanups in create_session and bind_conn_to_session"

* tag 'nfs-for-3.20-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
  NFSv4.1: Clean up bind_conn_to_session
  NFSv4.1: Always set up a forward channel when binding the session
  NFSv4.1: Don't set up a backchannel if the server didn't agree to do so
  NFSv4.1: Clean up create_session
  pnfs: Refactor the *_layout_mark_request_commit to use pnfs_layout_mark_request_commit
  NFSv4: Kill unused nfs_inode->delegation_state field
  NFS: struct nfs_commit_info.lock must always point to inode->i_lock
  nfs: Can call nfs_clear_page_commit() instead
  nfs: Provide and use helper functions for marking a page as unstable
  SUNRPC: Always manipulate rpc_rqst::rq_bc_pa_list under xprt->bc_pa_lock
  SUNRPC: Fix a compile error when #undef CONFIG_PROC_FS
  NFSv4.1: Convert open-coded array allocation calls to kmalloc_array()
  NFSv4.1: Fix a kfree() of uninitialised pointers in decode_cb_sequence_args
parents cd50b70c 71a097c6
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -427,6 +427,8 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args,
	if (clp == NULL)
		goto out;

	if (!(clp->cl_session->flags & SESSION4_BACK_CHAN))
		goto out;
	tbl = &clp->cl_session->bc_slot_table;

	spin_lock(&tbl->slot_tbl_lock);
+5 −3
Original line number Diff line number Diff line
@@ -313,7 +313,7 @@ __be32 decode_devicenotify_args(struct svc_rqst *rqstp,
		goto out;
	}

	args->devs = kmalloc(n * sizeof(*args->devs), GFP_KERNEL);
	args->devs = kmalloc_array(n, sizeof(*args->devs), GFP_KERNEL);
	if (!args->devs) {
		status = htonl(NFS4ERR_DELAY);
		goto out;
@@ -415,7 +415,7 @@ static __be32 decode_rc_list(struct xdr_stream *xdr,
			     rc_list->rcl_nrefcalls * 2 * sizeof(uint32_t));
		if (unlikely(p == NULL))
			goto out;
		rc_list->rcl_refcalls = kmalloc(rc_list->rcl_nrefcalls *
		rc_list->rcl_refcalls = kmalloc_array(rc_list->rcl_nrefcalls,
						sizeof(*rc_list->rcl_refcalls),
						GFP_KERNEL);
		if (unlikely(rc_list->rcl_refcalls == NULL))
@@ -464,10 +464,12 @@ static __be32 decode_cb_sequence_args(struct svc_rqst *rqstp,

		for (i = 0; i < args->csa_nrclists; i++) {
			status = decode_rc_list(xdr, &args->csa_rclists[i]);
			if (status)
			if (status) {
				args->csa_nrclists = i;
				goto out_free;
			}
		}
	}
	status = 0;

	dprintk("%s: sessionid %x:%x:%x:%x sequenceid %u slotid %u "
+0 −4
Original line number Diff line number Diff line
@@ -180,7 +180,6 @@ void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred,
			delegation->cred = get_rpccred(cred);
			clear_bit(NFS_DELEGATION_NEED_RECLAIM,
				  &delegation->flags);
			NFS_I(inode)->delegation_state = delegation->type;
			spin_unlock(&delegation->lock);
			put_rpccred(oldcred);
			rcu_read_unlock();
@@ -275,7 +274,6 @@ nfs_detach_delegation_locked(struct nfs_inode *nfsi,
	set_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
	list_del_rcu(&delegation->super_list);
	delegation->inode = NULL;
	nfsi->delegation_state = 0;
	rcu_assign_pointer(nfsi->delegation, NULL);
	spin_unlock(&delegation->lock);
	return delegation;
@@ -355,7 +353,6 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
					&delegation->stateid)) {
			nfs_update_inplace_delegation(old_delegation,
					delegation);
			nfsi->delegation_state = old_delegation->type;
			goto out;
		}
		/*
@@ -379,7 +376,6 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
			goto out;
	}
	list_add_rcu(&delegation->super_list, &server->delegations);
	nfsi->delegation_state = delegation->type;
	rcu_assign_pointer(nfsi->delegation, delegation);
	delegation = NULL;

+1 −1
Original line number Diff line number Diff line
@@ -283,7 +283,7 @@ static void nfs_direct_release_pages(struct page **pages, unsigned int npages)
void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo,
			      struct nfs_direct_req *dreq)
{
	cinfo->lock = &dreq->lock;
	cinfo->lock = &dreq->inode->i_lock;
	cinfo->mds = &dreq->mds_cinfo;
	cinfo->ds = &dreq->ds_cinfo;
	cinfo->dreq = dreq;
+10 −43
Original line number Diff line number Diff line
@@ -960,15 +960,10 @@ filelayout_mark_request_commit(struct nfs_page *req,
{
	struct nfs4_filelayout_segment *fl = FILELAYOUT_LSEG(lseg);
	u32 i, j;
	struct list_head *list;
	struct pnfs_commit_bucket *buckets;

	if (fl->commit_through_mds) {
		list = &cinfo->mds->list;
		spin_lock(cinfo->lock);
		goto mds_commit;
	}

		nfs_request_add_commit_list(req, &cinfo->mds->list, cinfo);
	} else {
		/* Note that we are calling nfs4_fl_calc_j_index on each page
		 * that ends up being committed to a data server.  An attractive
		 * alternative is to add a field to nfs_write_data and nfs_page
@@ -977,35 +972,7 @@ filelayout_mark_request_commit(struct nfs_page *req,
		 */
		j = nfs4_fl_calc_j_index(lseg, req_offset(req));
		i = select_bucket_index(fl, j);
	spin_lock(cinfo->lock);
	buckets = cinfo->ds->buckets;
	list = &buckets[i].written;
	if (list_empty(list)) {
		/* Non-empty buckets hold a reference on the lseg.  That ref
		 * is normally transferred to the COMMIT call and released
		 * there.  It could also be released if the last req is pulled
		 * off due to a rewrite, in which case it will be done in
		 * pnfs_generic_clear_request_commit
		 */
		buckets[i].wlseg = pnfs_get_lseg(lseg);
	}
	set_bit(PG_COMMIT_TO_DS, &req->wb_flags);
	cinfo->ds->nwritten++;

mds_commit:
	/* nfs_request_add_commit_list(). We need to add req to list without
	 * dropping cinfo lock.
	 */
	set_bit(PG_CLEAN, &(req)->wb_flags);
	nfs_list_add_request(req, list);
	cinfo->mds->ncommit++;
	spin_unlock(cinfo->lock);
	if (!cinfo->dreq) {
		inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
		inc_bdi_stat(inode_to_bdi(page_file_mapping(req->wb_page)->host),
			     BDI_RECLAIMABLE);
		__mark_inode_dirty(req->wb_context->dentry->d_inode,
				   I_DIRTY_DATASYNC);
		pnfs_layout_mark_request_commit(req, lseg, cinfo, i);
	}
}

Loading