Skip to contentSkip to conversation

2 of 2 - Allow O_EXCL on a block device to claim exclusive use.

PATCH In review NeilBrown 4 participants 5 messages Aug 11, 2003 – Aug 12, 2003 VFS

lore
Share & tools
lore

NeilBrown

author
#0 lore raw

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
diff ./fs/block_dev.c~current~ ./fs/block_dev.c
@@ -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);
 }
 
#1 lore raw
Quoted 18 lines · NeilBrown

diff ./fs/block_dev.c~current~ ./fs/block_dev.c

fs/block_dev.c renamed from fs/block_dev.c~current~ +3 -1
@@ -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)

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?

author
#2 lore raw
Quoted 10 lines · On Monday August 11, [email protected] wrote:
Quoted 9 lines · NeilBrown

diff ./fs/block_dev.c~current~ ./fs/block_dev.c

fs/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

#3 lore raw
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 by do_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.

#4 lore raw
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 by do_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?