[pnfs] [PATCH 08/10] pnfs: filelayout check layout device parameters

andros at netapp.com andros at netapp.com
Wed May 7 16:53:43 EDT 2008


From: Andy Adamson <andros at netapp.com>

Sanity check the layout parameters WRT the device prior to adding to
the layout cache.

Fixes a bug when the device is NULL.

Note: There are more checks to be added.

Signed-off-by: Andy Adamson<andros at netapp.com>
---
 fs/nfs/nfs4filelayout.c |   54 +++++++++++++++++++++++++++++++++++++++++++++++
 fs/nfs/nfs4filelayout.h |    5 ++++
 2 files changed, 59 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index a55d54e..e2a3c65 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -569,6 +569,56 @@ filelayout_free_layout(struct pnfs_layout_type *layoutid)
 	kfree(layoutid);
 }
 
+/*
+ * filelayout_check_layout()
+ *
+ * Make sure layout segment parameters are sane WRT the device.
+ *
+ * Notes:
+ * 1) current code insists that # stripe index = # multipath devices which
+ *    is wrong.
+ * 2) pattern_offset is ignored and must == 0 which is wrong;
+ * 3) the pattern_offset needs to be a mutliple of the stripe unit.
+*/
+
+static int
+filelayout_check_layout(struct pnfs_layout_type *lo,
+			struct pnfs_layout_segment *lseg)
+{
+	struct nfs4_filelayout_segment *fl = LSEG_LD_DATA(lseg);
+	struct nfs4_pnfs_dev_item *dev;
+	int status = -EINVAL;
+
+	dprintk("--> %s\n", __func__);
+	dev = nfs4_pnfs_device_item_get(FILE_MT(lo->inode), NFS_FH(lo->inode),
+					&fl->dev_id);
+	if (dev == NULL) {
+		dprintk("%s NO device for dev_id %s\n",
+				__func__, deviceid_fmt(&fl->dev_id));
+		goto out;
+	}
+	/* FIX-ME: need a # stripe index field */
+	if (fl->first_stripe_index < 0 ||
+	    fl->first_stripe_index > dev->stripe_count) {
+		dprintk("%s Bad first_stripe_index %d\n",
+				__func__, fl->first_stripe_index);
+		goto out;
+	}
+
+	/* FIX-ME: need a # stripe index field */
+	if (fl->pattern_offset != 0) {
+		dprintk("%s Unsupported no-zero pattern_offset %Ld\n",
+				__func__, fl->pattern_offset);
+		goto out;
+	}
+	status = 0;
+out:
+	dprintk("--> %s returns %d\n", __func__, status);
+	return status;
+}
+
+static void filelayout_free_lseg(struct pnfs_layout_segment *lseg);
+
 /* Decode layout and store in layoutid.  Overwrite any existing layout
  * information for this file.
  */
@@ -631,6 +681,10 @@ filelayout_alloc_lseg(struct pnfs_layout_type *layoutid,
 		return NULL;
 
 	filelayout_set_layout(flo, LSEG_LD_DATA(lseg), lgr);
+	if (filelayout_check_layout(layoutid, lseg)) {
+		filelayout_free_lseg(lseg);
+		lseg = NULL;
+	}
 	return lseg;
 }
 
diff --git a/fs/nfs/nfs4filelayout.h b/fs/nfs/nfs4filelayout.h
index d0aeb78..6866e7e 100644
--- a/fs/nfs/nfs4filelayout.h
+++ b/fs/nfs/nfs4filelayout.h
@@ -125,4 +125,9 @@ int process_deviceid_list(struct filelayout_mount_type *mt,
 	p += XDR_QUADLEN(nbytes);		\
 } while (0)
 
+struct nfs4_pnfs_dev_item *
+nfs4_pnfs_device_item_get(struct filelayout_mount_type *,
+			  struct nfs_fh *,
+			  struct pnfs_deviceid *);
+
 #endif /* FS_NFS_NFS4FILELAYOUT_H */
-- 
1.5.4.1



More information about the pNFS mailing list