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

Commit 889d94d4 authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFSv4.1/flexfiles: Mark layout for return if the mirrors are invalid



If a read-write layout has an invalid mirror, then we should
mark it as invalid, and return it.
If a read-only layout has an invalid mirror, then mark it as invalid
and check if there is still at least one valid mirror before we return
it.

Note: Also fix incorrect use of pnfs_generic_mark_devid_invalid().
We really want nfs4_mark_deviceid_unavailable().

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
parent 81d6dc8b
Loading
Loading
Loading
Loading
+30 −15
Original line number Diff line number Diff line
@@ -172,6 +172,32 @@ nfs4_ff_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev,
	return NULL;
}

static void ff_layout_mark_devid_invalid(struct pnfs_layout_segment *lseg,
		struct nfs4_deviceid_node *devid)
{
	nfs4_mark_deviceid_unavailable(devid);
	if (!ff_layout_has_available_ds(lseg))
		pnfs_error_mark_layout_for_return(lseg->pls_layout->plh_inode,
				lseg);
}

static bool ff_layout_mirror_valid(struct pnfs_layout_segment *lseg,
		struct nfs4_ff_layout_mirror *mirror)
{
	if (mirror == NULL || mirror->mirror_ds == NULL) {
		pnfs_error_mark_layout_for_return(lseg->pls_layout->plh_inode,
					lseg);
		return false;
	}
	if (mirror->mirror_ds->ds == NULL) {
		struct nfs4_deviceid_node *devid;
		devid = &mirror->mirror_ds->id_node;
		ff_layout_mark_devid_invalid(lseg, devid);
		return false;
	}
	return true;
}

static u64
end_offset(u64 start, u64 len)
{
@@ -336,16 +362,10 @@ nfs4_ff_layout_select_ds_fh(struct pnfs_layout_segment *lseg, u32 mirror_idx)
{
	struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, mirror_idx);
	struct nfs_fh *fh = NULL;
	struct nfs4_deviceid_node *devid;

	if (mirror == NULL || mirror->mirror_ds == NULL ||
	    mirror->mirror_ds->ds == NULL) {
		printk(KERN_ERR "NFS: %s: No data server for mirror offset index %d\n",
	if (!ff_layout_mirror_valid(lseg, mirror)) {
		pr_err_ratelimited("NFS: %s: No data server for mirror offset index %d\n",
			__func__, mirror_idx);
		if (mirror && mirror->mirror_ds) {
			devid = &mirror->mirror_ds->id_node;
			nfs4_mark_deviceid_unavailable(devid);
		}
		goto out;
	}

@@ -368,14 +388,9 @@ nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx,
	unsigned int max_payload;
	rpc_authflavor_t flavor;

	if (mirror == NULL || mirror->mirror_ds == NULL ||
	    mirror->mirror_ds->ds == NULL) {
		printk(KERN_ERR "NFS: %s: No data server for offset index %d\n",
	if (!ff_layout_mirror_valid(lseg, mirror)) {
		pr_err_ratelimited("NFS: %s: No data server for offset index %d\n",
			__func__, ds_idx);
		if (mirror && mirror->mirror_ds) {
			devid = &mirror->mirror_ds->id_node;
			nfs4_mark_deviceid_unavailable(devid);
		}
		goto out;
	}