[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Cluster-devel] cluster/gfs-kernel/src/gfs diaper.c ops_fstype.c



CVSROOT:	/cvs/cluster
Module name:	cluster
Branch: 	STABLE
Changes by:	rpeterso sourceware org	2007-02-23 20:57:29

Modified files:
	gfs-kernel/src/gfs: diaper.c ops_fstype.c 

Log message:
	This fixes some issues reported on linux-cluster.  Essentially, the
	previous code was deadlocking in some cases, primarily, when you run
	the sync command.  That's because sync does a down_read on the
	s_umount semaphore.  The deadlock was caused by some code I removed
	with the port to the 2.6.20 kernel.  However, I removed it because
	s_umount was needed in the down state for unmounts.  That's because
	the diaper device isn't managed by the normal mount path in vfs.
	I also fixed a kernel panic I discovered in testing when trying to mount
	an invalid fs; for example, trying to mount a gfs2 file system as gfs.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs-kernel/src/gfs/diaper.c.diff?cvsroot=cluster&only_with_tag=STABLE&r1=1.1.2.1.4.1.2.2&r2=1.1.2.1.4.1.2.3
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs-kernel/src/gfs/ops_fstype.c.diff?cvsroot=cluster&only_with_tag=STABLE&r1=1.13.2.1.4.2.2.4&r2=1.13.2.1.4.2.2.5

--- cluster/gfs-kernel/src/gfs/Attic/diaper.c	2007/02/07 15:25:05	1.1.2.1.4.1.2.2
+++ cluster/gfs-kernel/src/gfs/Attic/diaper.c	2007/02/23 20:57:29	1.1.2.1.4.1.2.3
@@ -252,6 +252,7 @@
 	sb->s_op = &gfs_dummy_sops;
 	sb->s_fs_info = dh;
 
+	up_write(&sb->s_umount);
 	module_put(gfs_fs_type.owner);
 
 	dh->dh_dummy_sb = sb;
@@ -262,6 +263,7 @@
 	iput(inode);
 
  fail:
+	up_write(&sb->s_umount);
 	deactivate_super(sb);
 	return error;
 }
@@ -431,6 +433,7 @@
 	struct gendisk *gd = dh->dh_gendisk;
 	int minor = dh->dh_gendisk->first_minor;
 
+	down_write(&dh->dh_dummy_sb->s_umount);
 	generic_shutdown_super(dh->dh_dummy_sb);
 
 	mempool_destroy(dh->dh_mempool);
--- cluster/gfs-kernel/src/gfs/ops_fstype.c	2007/02/07 15:25:05	1.13.2.1.4.2.2.4
+++ cluster/gfs-kernel/src/gfs/ops_fstype.c	2007/02/23 20:57:29	1.13.2.1.4.2.2.5
@@ -682,7 +682,7 @@
  */
 
 static int gfs_get_sb(struct file_system_type *fs_type, int flags,
-					  const char *dev_name, void *data, struct vfsmount *mnt)
+		      const char *dev_name, void *data, struct vfsmount *mnt)
 {
 	struct block_device *real, *diaper;
 	struct super_block *sb;
@@ -702,15 +702,17 @@
 	sb = sget(fs_type, gfs_test_bdev_super, gfs_set_bdev_super, diaper);
 	up(&diaper->bd_mount_sem);
 	if (IS_ERR(sb))
-		goto out;
+		goto error_s;
 
 	if (sb->s_root) {
 		if ((flags ^ sb->s_flags) & MS_RDONLY) {
 			up_write(&sb->s_umount);
 			deactivate_super(sb);
-			sb = ERR_PTR(-EBUSY);
+			error = -EBUSY;
+			goto error_bdev;
 		}
-		goto out;
+
+		close_bdev_excl(real);
 	} else {
 		char buf[BDEVNAME_SIZE];
 
@@ -721,9 +723,10 @@
 		if (error) {
 			up_write(&sb->s_umount);
 			deactivate_super(sb);
-			sb = ERR_PTR(error);
-		} else
-			sb->s_flags |= MS_ACTIVE;
+			goto error;
+		}
+		sb->s_flags |= MS_ACTIVE;
+		/* Equivilant of bdev_uevent(bdev, KOBJ_MOUNT): */
 		if (real->bd_disk) {
 			if (real->bd_part)
 				kobject_uevent(&real->bd_part->kobj, KOBJ_MOUNT);
@@ -734,10 +737,13 @@
 
 	return simple_set_mnt(mnt, sb);
 
- out:
-	gfs_diaper_put(diaper);
+error_s:
+	error = PTR_ERR(sb);
+error_bdev:
 	close_bdev_excl(real);
-	return simple_set_mnt(mnt, sb);
+error:
+	gfs_diaper_put(diaper);
+	return error;
 }
 
 /**
@@ -755,16 +761,17 @@
 	struct block_device *real = gfs_diaper_2real(diaper);
 	unsigned long bsize = block_size(real);
 
-	generic_shutdown_super(sb);
-	set_blocksize(diaper, bsize);
-	set_blocksize(real, bsize);
-	gfs_diaper_put(diaper);
+	/* Equivalent of bdev_uevent(bdev, KOBJ_UMOUNT); */
 	if (real->bd_disk) {
 		if (real->bd_part)
 			kobject_uevent(&real->bd_part->kobj, KOBJ_UMOUNT);
 		else
 			kobject_uevent(&real->bd_disk->kobj, KOBJ_UMOUNT);
 	}
+	generic_shutdown_super(sb);
+	set_blocksize(diaper, bsize);
+	set_blocksize(real, bsize);
+	gfs_diaper_put(diaper);
 	sync_blockdev(real);
 	close_bdev_excl(real);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]