Commit c366082d authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] Allow O_EXCL on a block device to claim exclusive use.

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.
parent f57dea91
...@@ -643,6 +643,7 @@ int blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags, int kind) ...@@ -643,6 +643,7 @@ int blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags, int kind)
int blkdev_open(struct inode * inode, struct file * filp) int blkdev_open(struct inode * inode, struct file * filp)
{ {
struct block_device *bdev; struct block_device *bdev;
int res;
/* /*
* Preserve backwards compatibility and allow large file access * Preserve backwards compatibility and allow large file access
...@@ -655,7 +656,18 @@ int blkdev_open(struct inode * inode, struct file * filp) ...@@ -655,7 +656,18 @@ int blkdev_open(struct inode * inode, struct file * filp)
bd_acquire(inode); bd_acquire(inode);
bdev = inode->i_bdev; 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) int blkdev_put(struct block_device *bdev, int kind)
...@@ -704,6 +716,8 @@ int blkdev_put(struct block_device *bdev, int kind) ...@@ -704,6 +716,8 @@ int blkdev_put(struct block_device *bdev, int kind)
int blkdev_close(struct inode * inode, struct file * filp) 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); return blkdev_put(inode->i_bdev, BDEV_FILE);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment