[pnfs] [PATCH 02/10] pnfs: decode_device error path bug fix

andros at umihc.edu andros at umihc.edu
Fri Mar 14 12:23:38 EDT 2008


From: Andy Adamson <andros at umich.edu>

INIT_HLIST_NODE sets the next and prev pointers to NULL. hlist_del_rcu
references these pointers, and causes a crash in destroy_device when
the hlist is empty as is the case int the out_err_free path of decode_device.

Remove INIT_HLIST_NODE which is not needed due to kzalloc. Replace
hlist_del_rcu with hlist_del_init which checks for the NULL values.
Clean up comment in nfs4_pnfs_dev_item declaration.

Signed-off-by: Andy Adamson<andros at umich.edu>
---
 fs/nfs/nfs4filelayout.h    |    2 +-
 fs/nfs/nfs4filelayoutdev.c |    9 +++------
 2 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/fs/nfs/nfs4filelayout.h b/fs/nfs/nfs4filelayout.h
index d4fcf39..1b086f6 100644
--- a/fs/nfs/nfs4filelayout.h
+++ b/fs/nfs/nfs4filelayout.h
@@ -55,7 +55,7 @@ struct nfs4_pnfs_dev {
 
 /* stripe_count is length of dev_list, bounded by NFS4_PNFS_MAX_STRIPE_CNT */
 struct nfs4_pnfs_dev_item {
-	struct hlist_node	hash_node;	/* nfs4_pnfs_dev_hlist dev_list */
+	struct hlist_node	hash_node;   /* nfs4_pnfs_dev_hlist dev_list */
 	pnfs_deviceid		dev_id;
 	u32 			stripe_count;
 	struct nfs4_pnfs_dev	*stripe_devs;
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c
index 4d59311..45e53c9 100644
--- a/fs/nfs/nfs4filelayoutdev.c
+++ b/fs/nfs/nfs4filelayoutdev.c
@@ -330,7 +330,7 @@ device_destroy(struct nfs4_pnfs_dev_item *dev,
 	print_stripe_devs(dev);
 
 	write_lock(&hlist->dev_lock);
-	hlist_del_rcu(&dev->hash_node);
+	hlist_del_init(&dev->hash_node);
 
 	fdev = &dev->stripe_devs[0];
 	for (i = 0; i < dev->stripe_count; i++) {
@@ -344,6 +344,7 @@ device_destroy(struct nfs4_pnfs_dev_item *dev,
 	write_unlock(&hlist->dev_lock);
 	hlist_for_each(np, &release) {
 		ds = hlist_entry(np, struct nfs4_pnfs_ds, ds_node);
+		hlist_del(&ds->ds_node);
 		destroy_ds(ds);
 	}
 	kfree(dev->stripe_devs);
@@ -541,12 +542,8 @@ decode_device(struct filelayout_mount_type *mt, struct pnfs_device *dev)
 					GFP_KERNEL);
 	if (!file_dev->stripe_devs)
 		goto out_err_free;
-	file_dev->stripe_count = len;
-
-	/* Initialize dev */
-	INIT_HLIST_NODE(&file_dev->hash_node);
 
-	/* Device id */
+	file_dev->stripe_count = len;
 	memcpy(&file_dev->dev_id, &dev->dev_id, NFS4_PNFS_DEVICEID4_SIZE);
 
 	fdev = &file_dev->stripe_devs[0];
-- 
1.5.0.2



More information about the pNFS mailing list