Subject: [PATCH] (6/6) further block_device cleanups
From: Alexander Viro <[email-masked]>
To: Linus Torvalds <[email-masked]>
Cc: Andrea Arcangeli <[email-masked]>
Date: Sat, 22 Sep 2001 02:16:41 -0400 (EDT)

Part 6:

cleanup.

blkdev_put() does bdput() on return now.  Callers updated.
blkdev_get() does bdput() in case of failure. Ditto.

Assorted bugs (two of them mine  - partitions/ibm.c ;-/) with sloppy
refcounting fixed (some places did bdput() even if bdget() failed, some -
ignored failure from blkdev_get() and kept going, etc.; see the patch).

diff -urN S10-pre13-lazy_bdev/drivers/block/rd.c S10-pre13-current/drivers/block/rd.c
--- S10-pre13-lazy_bdev/drivers/block/rd.c	Fri Sep 21 22:34:02 2001
+++ S10-pre13-current/drivers/block/rd.c	Fri Sep 21 23:36:03 2001
@@ -422,7 +422,6 @@
 		initrd_start = 0;
 		inode->i_bdev->bd_cache_openers--;
 		blkdev_put(inode->i_bdev, BDEV_FILE);
-		bdput(inode->i_bdev);
 	}
 	return 0;
 }
@@ -492,7 +491,6 @@
 			bdev->bd_cache_openers--;
 			truncate_inode_pages(bdev->bd_inode->i_mapping, 0);
 			blkdev_put(bdev, BDEV_FILE);
-			bdput(bdev);
 		}
 		destroy_buffers(MKDEV(MAJOR_NR, i));
 	}
diff -urN S10-pre13-lazy_bdev/drivers/char/raw.c S10-pre13-current/drivers/char/raw.c
--- S10-pre13-lazy_bdev/drivers/char/raw.c	Fri Sep 21 09:45:16 2001
+++ S10-pre13-current/drivers/char/raw.c	Sat Sep 22 00:03:36 2001
@@ -103,6 +103,7 @@
 	if (!bdev)
 		goto out;
 
+	atomic_inc(&bdev->bd_count);
 	rdev = to_kdev_t(bdev->bd_dev);
 	err = blkdev_get(bdev, filp->f_mode, 0, BDEV_RAW);
 	if (err)
diff -urN S10-pre13-lazy_bdev/drivers/ide/hptraid.c S10-pre13-current/drivers/ide/hptraid.c
--- S10-pre13-lazy_bdev/drivers/ide/hptraid.c	Fri Sep 21 09:45:17 2001
+++ S10-pre13-current/drivers/ide/hptraid.c	Sat Sep 22 00:00:24 2001
@@ -279,6 +279,7 @@
 	int i;
         struct highpoint_raid_conf *prom;
 	static unsigned char block[4096];
+	struct block_device *bdev;
 	
 	if (maxsectors(major,minor)==0)
 		return;
@@ -301,12 +302,12 @@
 	if (i>8) 
 		return;
 
-	raid[device].disk[i].bdev = bdget(MKDEV(major,minor));
-        if (raid[device].disk[i].bdev != NULL) {
+	bdev = bdget(MKDEV(major,minor));
+	if (bdev && blkdev_get(bdev,FMODE_READ|FMODE_WRITE,0,BDEV_RAW) == 0) {
         	int j=0;
         	struct gendisk *gd;
-        	/* This is supposed to prevent others from stealing our underlying disks */
-		blkdev_get(raid[device].disk[i].bdev, FMODE_READ|FMODE_WRITE, 0, BDEV_RAW);
+
+		raid[device].disk[i].bdev = bdev;
 		/* now blank the /proc/partitions table for the wrong partition table,
 		   so that scripts don't accidentally mount it and crash the kernel */
 		 /* XXX: the 0 is an utter hack  --hch */
@@ -408,12 +409,12 @@
 {
 	int i,device;
 	for (device = 0; device<16; device++) {
-		for (i=0;i<8;i++) 
-			if (raid[device].disk[i].bdev) {
-				blkdev_put(raid[device].disk[i].bdev, BDEV_RAW);
-				bdput(raid[device].disk[i].bdev);
-				raid[device].disk[i].bdev = NULL;
-			}       
+		for (i=0;i<8;i++) {
+			struct block_device *bdev = raid[device].disk[i].bdev;
+			raid[device].disk[i].bdev = NULL;
+			if (bdev)
+				blkdev_put(bdev, BDEV_RAW);
+		}
 		if (raid[device].sectors)
 			ataraid_release_device(device);
 	}
diff -urN S10-pre13-lazy_bdev/drivers/ide/pdcraid.c S10-pre13-current/drivers/ide/pdcraid.c
--- S10-pre13-lazy_bdev/drivers/ide/pdcraid.c	Fri Sep 21 09:45:17 2001
+++ S10-pre13-current/drivers/ide/pdcraid.c	Sat Sep 22 00:02:50 2001
@@ -311,12 +311,12 @@
         for (i=0;(i<prom->raid.total_disks)&&(i<8);i++) {
         	if ( (prom->raid.disk[i].channel== prom->raid.channel) &&
         	     (prom->raid.disk[i].device == prom->raid.device) ) {
-        	        raid[device].disk[i].bdev = bdget(MKDEV(major,minor));
-        	        if (raid[device].disk[i].bdev != NULL) {
+			struct block_device *bdev = bdget(MKDEV(major,minor));
+			if (bdev && blkdev_get(bdev,FMODE_READ|FMODE_WRITE,0,BDEV_RAW) == 0) {
         	        	struct gendisk *gd;
         	        	int j;
         	        	/* This is supposed to prevent others from stealing our underlying disks */
-        	        	blkdev_get(raid[device].disk[i].bdev, FMODE_READ|FMODE_WRITE, 0, BDEV_RAW);
+				raid[device].disk[i].bdev = bdev;
 				gd=get_gendisk(major);
 				if (gd!=NULL) {
 					for (j=1+(minor<<gd->minor_shift);j<((minor+1)<<gd->minor_shift);j++) 
@@ -418,13 +418,12 @@
 {
 	int i,device;
 	for (device = 0; device<16; device++) {
-		for (i=0;i<8;i++) 
-			if (raid[device].disk[i].bdev) {
-				blkdev_put(raid[device].disk[i].bdev, BDEV_RAW);
-				bdput(raid[device].disk[i].bdev);
-				raid[device].disk[i].bdev = NULL;
-
-			}	
+		for (i=0;i<8;i++)  {
+			struct block_device *bdev = raid[device].disk[i].bdev;
+			raid[device].disk[i].bdev = NULL;
+			if (bdev)
+				blkdev_put(bdev, BDEV_RAW);
+		}	
 		if (raid[device].sectors)
 			ataraid_release_device(device);
 	}
diff -urN S10-pre13-lazy_bdev/drivers/md/md.c S10-pre13-current/drivers/md/md.c
--- S10-pre13-lazy_bdev/drivers/md/md.c	Fri Sep 21 09:45:19 2001
+++ S10-pre13-current/drivers/md/md.c	Fri Sep 21 23:38:42 2001
@@ -649,11 +649,11 @@
 
 static void unlock_rdev (mdk_rdev_t *rdev)
 {
-	if (!rdev->bdev)
-		MD_BUG();
-	blkdev_put(rdev->bdev, BDEV_RAW);
-	bdput(rdev->bdev);
+	struct block_device *bdev = rdev->bdev;
 	rdev->bdev = NULL;
+	if (!bdev)
+		MD_BUG();
+	blkdev_put(bdev, BDEV_RAW);
 }
 
 void md_autodetect_dev (kdev_t dev);
diff -urN S10-pre13-lazy_bdev/fs/block_dev.c S10-pre13-current/fs/block_dev.c
--- S10-pre13-lazy_bdev/fs/block_dev.c	Fri Sep 21 23:29:24 2001
+++ S10-pre13-current/fs/block_dev.c	Sat Sep 22 00:10:24 2001
@@ -747,6 +747,8 @@
 	}
 	unlock_kernel();
 	up(&bdev->bd_sem);
+	if (ret)
+		bdput(bdev);
 	return ret;
 }
 
@@ -823,6 +825,7 @@
 	}
 	unlock_kernel();
 	up(&bdev->bd_sem);
+	bdput(bdev);
 	return ret;
 }
 
diff -urN S10-pre13-lazy_bdev/fs/partitions/ibm.c S10-pre13-current/fs/partitions/ibm.c
--- S10-pre13-lazy_bdev/fs/partitions/ibm.c	Fri Sep 21 09:45:28 2001
+++ S10-pre13-current/fs/partitions/ibm.c	Fri Sep 21 23:49:47 2001
@@ -47,9 +47,10 @@
 {
 	struct block_device *bdev = bdget(kdev_t_to_nr(kdev));
 	int rc = blkdev_get(bdev, 0, 1, BDEV_FILE);
-        if ( rc == 0 )
+        if ( rc == 0 ) {
 		rc = ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo);
-	blkdev_put(bdev,BDEV_FILE);
+		blkdev_put(bdev, BDEV_FILE);
+	}
 	return rc;
 }
 
@@ -58,9 +59,10 @@
 {
 	struct block_device *bdev = bdget(kdev_t_to_nr(kdev));
 	int rc = blkdev_get(bdev, 0, 1, BDEV_FILE);
-        if ( rc == 0 )
+        if ( rc == 0 ) {
 		rc = ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)(info));
-	blkdev_put(bdev,BDEV_FILE);
+		blkdev_put(bdev, BDEV_FILE);
+	}
 	return rc;
 }
 
diff -urN S10-pre13-lazy_bdev/fs/super.c S10-pre13-current/fs/super.c
--- S10-pre13-lazy_bdev/fs/super.c	Fri Sep 21 19:12:04 2001
+++ S10-pre13-current/fs/super.c	Sat Sep 22 00:06:48 2001
@@ -934,10 +934,8 @@
 	if (!(flags & MS_RDONLY))
 		mode |= FMODE_WRITE;
 	error = blkdev_get(bdev, mode, 0, BDEV_FS);
-	if (error) {
-		bdput(bdev);
+	if (error)
 		goto out;
-	}
 	check_disk_change(dev);
 	error = -EACCES;
 	if (!(flags & MS_RDONLY) && is_read_only(dev))
@@ -967,7 +965,6 @@
 			goto restart;
 		put_super(s);
 		blkdev_put(bdev, BDEV_FS);
-		bdput(bdev);
 		path_release(&nd);
 		return old;
 	}
@@ -1003,7 +1000,6 @@
 	put_super(s);
 out1:
 	blkdev_put(bdev, BDEV_FS);
-	bdput(bdev);
 out:
 	path_release(&nd);
 	return ERR_PTR(error);
@@ -1131,10 +1127,9 @@
 	sb->s_type = NULL;
 	unlock_super(sb);
 	unlock_kernel();
-	if (bdev) {
+	if (bdev)
 		blkdev_put(bdev, BDEV_FS);
-		bdput(bdev);
-	} else
+	else
 		put_unnamed_dev(dev);
 	spin_lock(&sb_lock);
 	list_del(&sb->s_list);
@@ -1721,6 +1716,7 @@
 	if (!ROOT_DEV)
 		panic("I have no root and I want to scream");
 
+retry:
 	bdev = bdget(kdev_t_to_nr(ROOT_DEV));
 	if (!bdev)
 		panic(__FUNCTION__ ": unable to allocate root device");
@@ -1732,7 +1728,7 @@
 	retval = blkdev_get(bdev, mode, 0, BDEV_FS);
 	if (retval == -EROFS) {
 		root_mountflags |= MS_RDONLY;
-		retval = blkdev_get(bdev, FMODE_READ, 0, BDEV_FS);
+		goto retry;
 	}
 	if (retval) {
 	        /*
@@ -1980,6 +1976,7 @@
 		int blivet;
 		struct block_device *ramdisk = old_rootmnt->mnt_sb->s_bdev;
 
+		atomic_inc(&ramdisk->bd_count);
 		blivet = blkdev_get(ramdisk, FMODE_READ, 0, BDEV_FS);
 		printk(KERN_NOTICE "Trying to unmount old root ... ");
 		if (!blivet) {
diff -urN S10-pre13-lazy_bdev/mm/swapfile.c S10-pre13-current/mm/swapfile.c
--- S10-pre13-lazy_bdev/mm/swapfile.c	Fri Sep 21 21:42:52 2001
+++ S10-pre13-current/mm/swapfile.c	Fri Sep 21 23:50:05 2001
@@ -609,10 +609,8 @@
 		swap_list_unlock();
 		goto out_dput;
 	}
-	if (p->swap_device) {
+	if (p->swap_device)
 		blkdev_put(p->swap_file->d_inode->i_bdev, BDEV_SWAP);
-		bdput(p->swap_file->d_inode->i_bdev);
-	}
 	path_release(&nd);
 
 	swap_list_lock();
@@ -763,10 +761,8 @@
 		if (bdops) bdev->bd_op = bdops;
 
 		error = blkdev_get(bdev, FMODE_READ|FMODE_WRITE, 0, BDEV_SWAP);
-		if (error) {
-			bdput(bdev);
+		if (error)
 			goto bad_swap_2;
-		}
 		set_blocksize(dev, PAGE_SIZE);
 		error = -ENODEV;
 		if (!dev || (blk_size[MAJOR(dev)] &&
@@ -921,10 +917,8 @@
 	error = 0;
 	goto out;
 bad_swap:
-	if (bdev) {
+	if (bdev)
 		blkdev_put(bdev, BDEV_SWAP);
-		bdput(bdev);
-	}
 bad_swap_2:
 	swap_list_lock();
 	swap_map = p->swap_map;