THank you for the hints and discussion. I think u all are right....bd_claim and O_EXCL is the answer.
First, when u open a device with O_EXCL flag, u lock the buffer as the API blkdev_open() shows:
static int blkdev_open(struct inode * inode, struct file * filp)
{
struct block_device *bdev;
int res;
/*
* Preserve backwards compatibility and allow large file access
* even if userspace doesn't ask for it explicitly. Some mkfs
* binary needs it. We might want to drop this workaround
* during an unstable branch.
*/
filp->f_flags |= O_LARGEFILE;
bdev = bd_acquire(inode);
if (bdev == NULL)
return -ENOMEM;
res = do_open(bdev, filp, 0);
if (res)
return res;
if (!(filp->f_flags & O_EXCL) )
return 0;
if (!(res = bd_claim(bdev, filp)))==================> buffer is locked, at the VFS level.
return 0;
blkdev_put(bdev);
return res;
}
Since it worked at the VFS level, it is the same for all the different filesystem like ext3 or ext4 etc.
locking block device buffer
THank you for the hints and discussion. I think u all are right....bd_claim and O_EXCL is the answer.
First, when u open a device with O_EXCL flag, u lock the buffer as the API blkdev_open() shows:
static int blkdev_open(struct inode * inode, struct file * filp)
{
struct block_device *bdev;
int res;
/*
* Preserve backwards compatibility and allow large file access
* even if userspace doesn't ask for it explicitly. Some mkfs
* binary needs it. We might want to drop this workaround
* during an unstable branch.
*/
filp->f_flags |= O_LARGEFILE;
bdev = bd_acquire(inode);
if (bdev == NULL)
return -ENOMEM;
res = do_open(bdev, filp, 0);
if (res)
return res;
if (!(filp->f_flags & O_EXCL) )
return 0;
if (!(res = bd_claim(bdev, filp)))==================> buffer is locked, at the VFS level.
return 0;
blkdev_put(bdev);
return res;
}
Since it worked at the VFS level, it is the same for all the different filesystem like ext3 or ext4 etc.
There goes your userspace solution as well.