From mboxrd@z Thu Jan 1 00:00:00 1970 From: rpeterso@sourceware.org Date: 23 Feb 2007 20:57:29 -0000 Subject: [Cluster-devel] cluster/gfs-kernel/src/gfs diaper.c ops_fstype.c Message-ID: <20070223205729.18043.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit CVSROOT: /cvs/cluster Module name: cluster Branch: STABLE Changes by: rpeterso at 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); }