2003-08-11 02:36:11

by NeilBrown

[permalink] [raw]
Subject: [PATCH] 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(-)

diff ./fs/block_dev.c~current~ ./fs/block_dev.c
--- ./fs/block_dev.c~current~ 2003-08-11 09:01:38.000000000 +1000
+++ ./fs/block_dev.c 2003-08-11 09:01:41.000000000 +1000
@@ -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);
}


2003-08-11 07:22:36

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH] 2 of 2 - Allow O_EXCL on a block device to claim exclusive use.

On Mon, Aug 11, 2003 at 12:35:57PM +1000, NeilBrown wrote:
> diff ./fs/block_dev.c~current~ ./fs/block_dev.c
> --- ./fs/block_dev.c~current~ 2003-08-11 09:01:38.000000000 +1000
> +++ ./fs/block_dev.c 2003-08-11 09:01:41.000000000 +1000
> @@ -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;

Shouldn't you claim it before opening. Also what is the desired
behaviour when opening partitions vs whole device with O_EXCL?

2003-08-12 01:49:17

by NeilBrown

[permalink] [raw]
Subject: Re: [PATCH] 2 of 2 - Allow O_EXCL on a block device to claim exclusive use.

On Monday August 11, [email protected] wrote:
> On Mon, Aug 11, 2003 at 12:35:57PM +1000, NeilBrown wrote:
> > diff ./fs/block_dev.c~current~ ./fs/block_dev.c
> > - 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;
>
> 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

2003-08-12 02:56:14

by Andries Brouwer

[permalink] [raw]
Subject: Re: [PATCH] 2 of 2 - Allow O_EXCL on a block device to claim exclusive use.

On Tue, Aug 12, 2003 at 11:48:28AM +1000, Neil Brown wrote:

> 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.

2003-08-12 03:06:32

by Al Viro

[permalink] [raw]
Subject: Re: [PATCH] 2 of 2 - Allow O_EXCL on a block device to claim exclusive use.

On Tue, Aug 12, 2003 at 04:56:10AM +0200, Andries Brouwer wrote:
> On Tue, Aug 12, 2003 at 11:48:28AM +1000, Neil Brown wrote:
>
> > 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.

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?