diff options
author | Christoph Hellwig <hch@lst.de> | 2008-11-05 14:58:42 +0100 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-12-04 04:22:57 -0500 |
commit | fd4ce1acd0f8558033b1a6968001552bd7671e6d (patch) | |
tree | 7ce54f2b2c967fe2315917ffa2eb8eb7d47e7a2b | |
parent | ebbefc011e56bd85b4745d01e5b8d7d05d95ed5d (diff) | |
download | lwn-fd4ce1acd0f8558033b1a6968001552bd7671e6d.tar.gz lwn-fd4ce1acd0f8558033b1a6968001552bd7671e6d.zip |
[PATCH 1/2] kill FMODE_NDELAY_NOW
Update FMODE_NDELAY before each ioctl call so that we can kill the
magic FMODE_NDELAY_NOW. It would be even better to do this directly
in setfl(), but for that we'd need to have FMODE_NDELAY for all files,
not just block special files.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | block/compat_ioctl.c | 8 | ||||
-rw-r--r-- | drivers/scsi/sd.c | 2 | ||||
-rw-r--r-- | drivers/scsi/sr.c | 2 | ||||
-rw-r--r-- | fs/block_dev.c | 10 | ||||
-rw-r--r-- | include/linux/fs.h | 1 |
5 files changed, 18 insertions, 5 deletions
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c index d43e6087badc..67eb93cff699 100644 --- a/block/compat_ioctl.c +++ b/block/compat_ioctl.c @@ -722,8 +722,14 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg) struct backing_dev_info *bdi; loff_t size; + /* + * O_NDELAY can be altered using fcntl(.., F_SETFL, ..), so we have + * to updated it before every ioctl. + */ if (file->f_flags & O_NDELAY) - mode |= FMODE_NDELAY_NOW; + mode |= FMODE_NDELAY; + else + mode &= ~FMODE_NDELAY; switch (cmd) { case HDIO_GETGEO: diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index c9e1242eaf25..5081b3981d3c 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -757,7 +757,7 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode, * access to the device is prohibited. */ error = scsi_nonblockable_ioctl(sdp, cmd, p, - (mode & FMODE_NDELAY_NOW) != 0); + (mode & FMODE_NDELAY) != 0); if (!scsi_block_when_processing_errors(sdp) || !error) return error; diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 62b6633e3a97..45b66b98a516 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -521,7 +521,7 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, * if it doesn't recognise the ioctl */ ret = scsi_nonblockable_ioctl(sdev, cmd, argp, - (mode & FMODE_NDELAY_NOW) != 0); + (mode & FMODE_NDELAY) != 0); if (ret != -ENODEV) return ret; return scsi_ioctl(sdev, cmd, argp); diff --git a/fs/block_dev.c b/fs/block_dev.c index 7c727523bc54..99e0ae1a4c78 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -1206,8 +1206,16 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg) { struct block_device *bdev = I_BDEV(file->f_mapping->host); fmode_t mode = file->f_mode; + + /* + * O_NDELAY can be altered using fcntl(.., F_SETFL, ..), so we have + * to updated it before every ioctl. + */ if (file->f_flags & O_NDELAY) - mode |= FMODE_NDELAY_NOW; + mode |= FMODE_NDELAY; + else + mode &= ~FMODE_NDELAY; + return blkdev_ioctl(bdev, mode, cmd, arg); } diff --git a/include/linux/fs.h b/include/linux/fs.h index 0dcdd9458f4b..b3345a90e11a 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -79,7 +79,6 @@ extern int dir_notify_enable; #define FMODE_NDELAY ((__force fmode_t)32) #define FMODE_EXCL ((__force fmode_t)64) #define FMODE_WRITE_IOCTL ((__force fmode_t)128) -#define FMODE_NDELAY_NOW ((__force fmode_t)256) #define RW_MASK 1 #define RWA_MASK 2 |