2 of 2 - Allow O_EXCL on a block device to claim exclusive use.
PATCH 1/1 2 of 2 - Allow O_EXCL on a block device to claim exclusive use.
### Comments for ChangeSet
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.
----------- Diffstat output ------------
./fs/block_dev.c | 16 +++++++++++++++- 1 files changed, 15 insertions(+), 1 deletion(-)
fs/block_dev.c renamed from fs/block_dev.c~current~ +15 -1
@@ -643,6 +643,7 @@ int blkdev_get(struct block_device *bdevint 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, stbd_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 *bdevint 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 ); }
Quoted 18 lines · NeilBrown
diff
./fs/block_dev.c~current~./fs/block_dev.cfs/block_dev.c renamed from fs/block_dev.c~current~ +3
-1@@ -643,6 +643,7 @@ int blkdev_get(struct block_device *bdevint 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, stbd_acquire (inode); bdev = inode->i_bdev; -return do_open (bdev, inode, filp); + res =do_open (bdev, inode, filp); +if (res)
fs/block_dev.c int blkdev_open(struct inode * inode, st · line 670
Quoted 10 lines
fs/block_dev.c renamed from fs/block_dev.c~current~ +10
-0+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;
Shouldn't you claim it before opening. Also what is the desired behaviour when opening partitions vs whole device with O_EXCL?
Quoted 10 lines · On Monday August 11, [email protected] wrote:
Quoted 9 lines · NeilBrown
diff
./fs/block_dev.c~current~./fs/block_dev.cfs/block_dev.c renamed from fs/block_dev.c~current~ +7
-1-return do_open (bdev, inode, filp); + res =do_open (bdev, inode, filp); +if (res) +return res; + +if (!(filp->f_flags &O_EXCL ) ) +return 0 ; +
Quoted 8 lines
fs/block_dev.c int blkdev_open(struct inode * inode, st · line 670
Quoted 5 lines
fs/block_dev.c renamed from fs/block_dev.c~current~ +5
-0+if (!(res =bd_claim (bdev, filp))) +return 0 ; + +blkdev_put (bdev,BDEV_FILE ); +return res;Shouldn't you claim it before opening. Also what is the desired behaviour when opening partitions vs whole device with
O_EXCL?
Good question.
My first attempt at this did claim before openning. However that didn't work.
Some aspects of the bdev that are needed for claiming are not initialised before it is first opened. In particular, bd_contains, gets set up by do_open.
Also, other code uses this order.
e.g. open_bdev_excl called blkdev_get (which calls do_open) before bd_claim.
NeilBrown
Quoted 5 lines · Neil Brown
My first attempt at this did claim before openning. However that didn't work.
Some aspects of the bdev that are needed for claiming are not initialised before it is first opened. In particular,bd_contains, gets set up bydo_open.
Size and structure of partitions are entirely independent of whether someone has opened them. Thus, the corresponding bookkeeping must not be in struct block_device, which exists only when the device is open, but in struct gendisk or so (and only there).
It is a design mistake to have such stuff in struct block device.
Quoted 8 lines · Andries Brouwer
Quoted 5 lines · Neil Brown
My first attempt at this did claim before openning. However that didn't work.
Some aspects of the bdev that are needed for claiming are not initialised before it is first opened. In particular,bd_contains, gets set up bydo_open.
Quoted 6 lines
Size and structure of partitions are entirely independent of whether someone has opened them. Thus, the corresponding bookkeeping must not be in struct
block_device, which exists only when the device is open, but in struct gendisk or so (and only there).It is a design mistake to have such stuff in struct block device.
WTF does it have to do with ->bd_contains? We *do* have the information you (and nobody else in this thread) are talking about - in gendisk. Exclusion upon open, OTOH, has something with opening these beast, won't you agree?