From: NeilBrown <neilb@cse.unsw.edu.au>

The blockdev layer has a concept of 'claiming' a device, so for example it
can be claimed when a filesystem is mounted or when it is included into a
raid array.  Only one subsystem can claim it at a time.

This patch matches this functionality available to user-space via the
O_EXCL flag to open.

This allows user-space programs to easily test if a device is currently
mounted etc, and to prevent a device from being mounted or otherwise
claimed.



 fs/block_dev.c |   16 +++++++++++++++-
 1 files changed, 15 insertions(+), 1 deletion(-)

diff -puN fs/block_dev.c~O_EXCL-claim-blockdevs fs/block_dev.c
--- 25/fs/block_dev.c~O_EXCL-claim-blockdevs	2003-08-18 22:27:17.000000000 -0700
+++ 25-akpm/fs/block_dev.c	2003-08-18 22:27:17.000000000 -0700
@@ -643,6 +643,7 @@ int blkdev_get(struct block_device *bdev
 int blkdev_open(struct inode * inode, struct file * filp)
 {
 	struct block_device *bdev;
+	int res;
 
 	/*
 	 * Preserve backwards compatibility and allow large file access
@@ -655,7 +656,18 @@ int blkdev_open(struct inode * inode, st
 	bd_acquire(inode);
 	bdev = inode->i_bdev;
 
-	return do_open(bdev, inode, filp);
+	res = do_open(bdev, inode, filp);
+	if (res)
+		return res;
+
+	if (!(filp->f_flags & O_EXCL) )
+		return 0;
+
+	if (!(res = bd_claim(bdev, filp)))
+		return 0;
+
+	blkdev_put(bdev, BDEV_FILE);
+	return res;
 }
 
 int blkdev_put(struct block_device *bdev, int kind)
@@ -704,6 +716,8 @@ int blkdev_put(struct block_device *bdev
 
 int blkdev_close(struct inode * inode, struct file * filp)
 {
+	if (inode->i_bdev->bd_holder == filp)
+		bd_release(inode->i_bdev);
 	return blkdev_put(inode->i_bdev, BDEV_FILE);
 }
 

_