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

Commit fa7d9a1d authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull NFS client bugfixes and cleanups from Trond Myklebust:
 "Bugfixes:
   - pNFS/flexfiles: Fix an XDR encoding bug in layoutreturn
   - pNFS/flexfiles: Improve merging of errors in LAYOUTRETURN

  Cleanups:
   - NFS: Simplify nfs_request_add_commit_list() arguments"

* tag 'nfs-for-4.5-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
  pNFS/flexfiles: Fix an XDR encoding bug in layoutreturn
  NFS: Simplify nfs_request_add_commit_list() arguments
  pNFS/flexfiles: Improve merging of errors in LAYOUTRETURN
parents 20c759ca 6d45c042
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -971,7 +971,7 @@ filelayout_mark_request_commit(struct nfs_page *req,
	u32 i, j;
	u32 i, j;


	if (fl->commit_through_mds) {
	if (fl->commit_through_mds) {
		nfs_request_add_commit_list(req, &cinfo->mds->list, cinfo);
		nfs_request_add_commit_list(req, cinfo);
	} else {
	} else {
		/* Note that we are calling nfs4_fl_calc_j_index on each page
		/* Note that we are calling nfs4_fl_calc_j_index on each page
		 * that ends up being committed to a data server.  An attractive
		 * that ends up being committed to a data server.  An attractive
+2 −4
Original line number Original line Diff line number Diff line
@@ -1948,11 +1948,9 @@ ff_layout_encode_layoutreturn(struct pnfs_layout_hdr *lo,
	start = xdr_reserve_space(xdr, 4);
	start = xdr_reserve_space(xdr, 4);
	BUG_ON(!start);
	BUG_ON(!start);


	if (ff_layout_encode_ioerr(flo, xdr, args))
	ff_layout_encode_ioerr(flo, xdr, args);
		goto out;

	ff_layout_encode_iostats(flo, xdr, args);
	ff_layout_encode_iostats(flo, xdr, args);
out:

	*start = cpu_to_be32((xdr->p - start - 1) * 4);
	*start = cpu_to_be32((xdr->p - start - 1) * 4);
	dprintk("%s: Return\n", __func__);
	dprintk("%s: Return\n", __func__);
}
}
+40 −59
Original line number Original line Diff line number Diff line
@@ -218,63 +218,55 @@ static void extend_ds_error(struct nfs4_ff_layout_ds_err *err,
	err->length = end - err->offset;
	err->length = end - err->offset;
}
}


static bool ds_error_can_merge(struct nfs4_ff_layout_ds_err *err,  u64 offset,
static int
			       u64 length, int status, enum nfs_opnum4 opnum,
ff_ds_error_match(const struct nfs4_ff_layout_ds_err *e1,
			       nfs4_stateid *stateid,
		const struct nfs4_ff_layout_ds_err *e2)
			       struct nfs4_deviceid *deviceid)
{
	return err->status == status && err->opnum == opnum &&
	       nfs4_stateid_match(&err->stateid, stateid) &&
	       !memcmp(&err->deviceid, deviceid, sizeof(*deviceid)) &&
	       end_offset(err->offset, err->length) >= offset &&
	       err->offset <= end_offset(offset, length);
}

static bool merge_ds_error(struct nfs4_ff_layout_ds_err *old,
			   struct nfs4_ff_layout_ds_err *new)
{
{
	if (!ds_error_can_merge(old, new->offset, new->length, new->status,
	int ret;
				new->opnum, &new->stateid, &new->deviceid))

		return false;
	if (e1->opnum != e2->opnum)

		return e1->opnum < e2->opnum ? -1 : 1;
	extend_ds_error(old, new->offset, new->length);
	if (e1->status != e2->status)
	return true;
		return e1->status < e2->status ? -1 : 1;
	ret = memcmp(&e1->stateid, &e2->stateid, sizeof(e1->stateid));
	if (ret != 0)
		return ret;
	ret = memcmp(&e1->deviceid, &e2->deviceid, sizeof(e1->deviceid));
	if (ret != 0)
		return ret;
	if (end_offset(e1->offset, e1->length) < e2->offset)
		return -1;
	if (e1->offset > end_offset(e2->offset, e2->length))
		return 1;
	/* If ranges overlap or are contiguous, they are the same */
	return 0;
}
}


static bool
static void
ff_layout_add_ds_error_locked(struct nfs4_flexfile_layout *flo,
ff_layout_add_ds_error_locked(struct nfs4_flexfile_layout *flo,
			      struct nfs4_ff_layout_ds_err *dserr)
			      struct nfs4_ff_layout_ds_err *dserr)
{
{
	struct nfs4_ff_layout_ds_err *err;
	struct nfs4_ff_layout_ds_err *err, *tmp;

	struct list_head *head = &flo->error_list;
	list_for_each_entry(err, &flo->error_list, list) {
	int match;
		if (merge_ds_error(err, dserr)) {

			return true;
	/* Do insertion sort w/ merges */
		}
	list_for_each_entry_safe(err, tmp, &flo->error_list, list) {
	}
		match = ff_ds_error_match(err, dserr);

		if (match < 0)
	list_add(&dserr->list, &flo->error_list);
			continue;
	return false;
		if (match > 0) {
}
			/* Add entry "dserr" _before_ entry "err" */

			head = &err->list;
static bool
ff_layout_update_ds_error(struct nfs4_flexfile_layout *flo, u64 offset,
			  u64 length, int status, enum nfs_opnum4 opnum,
			  nfs4_stateid *stateid, struct nfs4_deviceid *deviceid)
{
	bool found = false;
	struct nfs4_ff_layout_ds_err *err;

	list_for_each_entry(err, &flo->error_list, list) {
		if (ds_error_can_merge(err, offset, length, status, opnum,
				       stateid, deviceid)) {
			found = true;
			extend_ds_error(err, offset, length);
			break;
			break;
		}
		}
		/* Entries match, so merge "err" into "dserr" */
		extend_ds_error(dserr, err->offset, err->length);
		list_del(&err->list);
		kfree(err);
	}
	}


	return found;
	list_add_tail(&dserr->list, head);
}
}


int ff_layout_track_ds_error(struct nfs4_flexfile_layout *flo,
int ff_layout_track_ds_error(struct nfs4_flexfile_layout *flo,
@@ -283,7 +275,6 @@ int ff_layout_track_ds_error(struct nfs4_flexfile_layout *flo,
			     gfp_t gfp_flags)
			     gfp_t gfp_flags)
{
{
	struct nfs4_ff_layout_ds_err *dserr;
	struct nfs4_ff_layout_ds_err *dserr;
	bool needfree;


	if (status == 0)
	if (status == 0)
		return 0;
		return 0;
@@ -291,14 +282,6 @@ int ff_layout_track_ds_error(struct nfs4_flexfile_layout *flo,
	if (mirror->mirror_ds == NULL)
	if (mirror->mirror_ds == NULL)
		return -EINVAL;
		return -EINVAL;


	spin_lock(&flo->generic_hdr.plh_inode->i_lock);
	if (ff_layout_update_ds_error(flo, offset, length, status, opnum,
				      &mirror->stateid,
				      &mirror->mirror_ds->id_node.deviceid)) {
		spin_unlock(&flo->generic_hdr.plh_inode->i_lock);
		return 0;
	}
	spin_unlock(&flo->generic_hdr.plh_inode->i_lock);
	dserr = kmalloc(sizeof(*dserr), gfp_flags);
	dserr = kmalloc(sizeof(*dserr), gfp_flags);
	if (!dserr)
	if (!dserr)
		return -ENOMEM;
		return -ENOMEM;
@@ -313,10 +296,8 @@ int ff_layout_track_ds_error(struct nfs4_flexfile_layout *flo,
	       NFS4_DEVICEID4_SIZE);
	       NFS4_DEVICEID4_SIZE);


	spin_lock(&flo->generic_hdr.plh_inode->i_lock);
	spin_lock(&flo->generic_hdr.plh_inode->i_lock);
	needfree = ff_layout_add_ds_error_locked(flo, dserr);
	ff_layout_add_ds_error_locked(flo, dserr);
	spin_unlock(&flo->generic_hdr.plh_inode->i_lock);
	spin_unlock(&flo->generic_hdr.plh_inode->i_lock);
	if (needfree)
		kfree(dserr);


	return 0;
	return 0;
}
}
+1 −1
Original line number Original line Diff line number Diff line
@@ -484,7 +484,7 @@ void nfs_retry_commit(struct list_head *page_list,
		      struct nfs_commit_info *cinfo,
		      struct nfs_commit_info *cinfo,
		      u32 ds_commit_idx);
		      u32 ds_commit_idx);
void nfs_commitdata_release(struct nfs_commit_data *data);
void nfs_commitdata_release(struct nfs_commit_data *data);
void nfs_request_add_commit_list(struct nfs_page *req, struct list_head *dst,
void nfs_request_add_commit_list(struct nfs_page *req,
				 struct nfs_commit_info *cinfo);
				 struct nfs_commit_info *cinfo);
void nfs_request_add_commit_list_locked(struct nfs_page *req,
void nfs_request_add_commit_list_locked(struct nfs_page *req,
		struct list_head *dst,
		struct list_head *dst,
+3 −4
Original line number Original line Diff line number Diff line
@@ -830,11 +830,10 @@ EXPORT_SYMBOL_GPL(nfs_request_add_commit_list_locked);
 * holding the nfs_page lock.
 * holding the nfs_page lock.
 */
 */
void
void
nfs_request_add_commit_list(struct nfs_page *req, struct list_head *dst,
nfs_request_add_commit_list(struct nfs_page *req, struct nfs_commit_info *cinfo)
			    struct nfs_commit_info *cinfo)
{
{
	spin_lock(cinfo->lock);
	spin_lock(cinfo->lock);
	nfs_request_add_commit_list_locked(req, dst, cinfo);
	nfs_request_add_commit_list_locked(req, &cinfo->mds->list, cinfo);
	spin_unlock(cinfo->lock);
	spin_unlock(cinfo->lock);
	nfs_mark_page_unstable(req->wb_page, cinfo);
	nfs_mark_page_unstable(req->wb_page, cinfo);
}
}
@@ -892,7 +891,7 @@ nfs_mark_request_commit(struct nfs_page *req, struct pnfs_layout_segment *lseg,
{
{
	if (pnfs_mark_request_commit(req, lseg, cinfo, ds_commit_idx))
	if (pnfs_mark_request_commit(req, lseg, cinfo, ds_commit_idx))
		return;
		return;
	nfs_request_add_commit_list(req, &cinfo->mds->list, cinfo);
	nfs_request_add_commit_list(req, cinfo);
}
}


static void
static void