aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/compat_ioctl.c31
-rw-r--r--drivers/block/pktcdvd.c4
-rw-r--r--drivers/scsi/sd.c2
-rw-r--r--drivers/scsi/sr.c2
-rw-r--r--fs/block_dev.c21
-rw-r--r--include/linux/fs.h33
-rw-r--r--kernel/power/swap.c2
7 files changed, 68 insertions, 27 deletions
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index 3d3e7a46f38c..67eb93cff699 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -677,6 +677,29 @@ static int compat_blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
677 case DVD_WRITE_STRUCT: 677 case DVD_WRITE_STRUCT:
678 case DVD_AUTH: 678 case DVD_AUTH:
679 arg = (unsigned long)compat_ptr(arg); 679 arg = (unsigned long)compat_ptr(arg);
680 /* These intepret arg as an unsigned long, not as a pointer,
681 * so we must not do compat_ptr() conversion. */
682 case HDIO_SET_MULTCOUNT:
683 case HDIO_SET_UNMASKINTR:
684 case HDIO_SET_KEEPSETTINGS:
685 case HDIO_SET_32BIT:
686 case HDIO_SET_NOWERR:
687 case HDIO_SET_DMA:
688 case HDIO_SET_PIO_MODE:
689 case HDIO_SET_NICE:
690 case HDIO_SET_WCACHE:
691 case HDIO_SET_ACOUSTIC:
692 case HDIO_SET_BUSSTATE:
693 case HDIO_SET_ADDRESS:
694 case CDROMEJECT_SW:
695 case CDROM_SET_OPTIONS:
696 case CDROM_CLEAR_OPTIONS:
697 case CDROM_SELECT_SPEED:
698 case CDROM_SELECT_DISC:
699 case CDROM_MEDIA_CHANGED:
700 case CDROM_DRIVE_STATUS:
701 case CDROM_LOCKDOOR:
702 case CDROM_DEBUG:
680 break; 703 break;
681 default: 704 default:
682 /* unknown ioctl number */ 705 /* unknown ioctl number */
@@ -699,8 +722,14 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
699 struct backing_dev_info *bdi; 722 struct backing_dev_info *bdi;
700 loff_t size; 723 loff_t size;
701 724
725 /*
726 * O_NDELAY can be altered using fcntl(.., F_SETFL, ..), so we have
727 * to updated it before every ioctl.
728 */
702 if (file->f_flags & O_NDELAY) 729 if (file->f_flags & O_NDELAY)
703 mode |= FMODE_NDELAY_NOW; 730 mode |= FMODE_NDELAY;
731 else
732 mode &= ~FMODE_NDELAY;
704 733
705 switch (cmd) { 734 switch (cmd) {
706 case HDIO_GETGEO: 735 case HDIO_GETGEO:
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index f20bf359b84f..edda7b6b077b 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -2790,7 +2790,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
2790 return 0; 2790 return 0;
2791 2791
2792out_mem: 2792out_mem:
2793 blkdev_put(bdev, FMODE_READ|FMODE_WRITE); 2793 blkdev_put(bdev, FMODE_READ | FMODE_NDELAY);
2794 /* This is safe: open() is still holding a reference. */ 2794 /* This is safe: open() is still holding a reference. */
2795 module_put(THIS_MODULE); 2795 module_put(THIS_MODULE);
2796 return ret; 2796 return ret;
@@ -2975,7 +2975,7 @@ static int pkt_remove_dev(dev_t pkt_dev)
2975 pkt_debugfs_dev_remove(pd); 2975 pkt_debugfs_dev_remove(pd);
2976 pkt_sysfs_dev_remove(pd); 2976 pkt_sysfs_dev_remove(pd);
2977 2977
2978 blkdev_put(pd->bdev, FMODE_READ|FMODE_WRITE); 2978 blkdev_put(pd->bdev, FMODE_READ | FMODE_NDELAY);
2979 2979
2980 remove_proc_entry(pd->name, pkt_proc); 2980 remove_proc_entry(pd->name, pkt_proc);
2981 DPRINTK(DRIVER_NAME": writer %s unmapped\n", pd->name); 2981 DPRINTK(DRIVER_NAME": writer %s unmapped\n", pd->name);
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,
757 * access to the device is prohibited. 757 * access to the device is prohibited.
758 */ 758 */
759 error = scsi_nonblockable_ioctl(sdp, cmd, p, 759 error = scsi_nonblockable_ioctl(sdp, cmd, p,
760 (mode & FMODE_NDELAY_NOW) != 0); 760 (mode & FMODE_NDELAY) != 0);
761 if (!scsi_block_when_processing_errors(sdp) || !error) 761 if (!scsi_block_when_processing_errors(sdp) || !error)
762 return error; 762 return error;
763 763
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,
521 * if it doesn't recognise the ioctl 521 * if it doesn't recognise the ioctl
522 */ 522 */
523 ret = scsi_nonblockable_ioctl(sdev, cmd, argp, 523 ret = scsi_nonblockable_ioctl(sdev, cmd, argp,
524 (mode & FMODE_NDELAY_NOW) != 0); 524 (mode & FMODE_NDELAY) != 0);
525 if (ret != -ENODEV) 525 if (ret != -ENODEV)
526 return ret; 526 return ret;
527 return scsi_ioctl(sdev, cmd, argp); 527 return scsi_ioctl(sdev, cmd, argp);
diff --git a/fs/block_dev.c b/fs/block_dev.c
index db831efbdbbd..99e0ae1a4c78 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1135,12 +1135,15 @@ static int blkdev_open(struct inode * inode, struct file * filp)
1135 if (res) 1135 if (res)
1136 return res; 1136 return res;
1137 1137
1138 if (!(filp->f_mode & FMODE_EXCL)) 1138 if (filp->f_mode & FMODE_EXCL) {
1139 return 0; 1139 res = bd_claim(bdev, filp);
1140 if (res)
1141 goto out_blkdev_put;
1142 }
1140 1143
1141 if (!(res = bd_claim(bdev, filp))) 1144 return 0;
1142 return 0;
1143 1145
1146 out_blkdev_put:
1144 blkdev_put(bdev, filp->f_mode); 1147 blkdev_put(bdev, filp->f_mode);
1145 return res; 1148 return res;
1146} 1149}
@@ -1203,8 +1206,16 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg)
1203{ 1206{
1204 struct block_device *bdev = I_BDEV(file->f_mapping->host); 1207 struct block_device *bdev = I_BDEV(file->f_mapping->host);
1205 fmode_t mode = file->f_mode; 1208 fmode_t mode = file->f_mode;
1209
1210 /*
1211 * O_NDELAY can be altered using fcntl(.., F_SETFL, ..), so we have
1212 * to updated it before every ioctl.
1213 */
1206 if (file->f_flags & O_NDELAY) 1214 if (file->f_flags & O_NDELAY)
1207 mode |= FMODE_NDELAY_NOW; 1215 mode |= FMODE_NDELAY;
1216 else
1217 mode &= ~FMODE_NDELAY;
1218
1208 return blkdev_ioctl(bdev, mode, cmd, arg); 1219 return blkdev_ioctl(bdev, mode, cmd, arg);
1209} 1220}
1210 1221
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 0dcdd9458f4b..4a853ef6fd35 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -63,23 +63,24 @@ extern int dir_notify_enable;
63#define MAY_ACCESS 16 63#define MAY_ACCESS 16
64#define MAY_OPEN 32 64#define MAY_OPEN 32
65 65
66#define FMODE_READ ((__force fmode_t)1) 66/* file is open for reading */
67#define FMODE_WRITE ((__force fmode_t)2) 67#define FMODE_READ ((__force fmode_t)1)
68 68/* file is open for writing */
69/* Internal kernel extensions */ 69#define FMODE_WRITE ((__force fmode_t)2)
70#define FMODE_LSEEK ((__force fmode_t)4) 70/* file is seekable */
71#define FMODE_PREAD ((__force fmode_t)8) 71#define FMODE_LSEEK ((__force fmode_t)4)
72#define FMODE_PWRITE FMODE_PREAD /* These go hand in hand */ 72/* file can be accessed using pread/pwrite */
73 73#define FMODE_PREAD ((__force fmode_t)8)
74/* File is being opened for execution. Primary users of this flag are 74#define FMODE_PWRITE FMODE_PREAD /* These go hand in hand */
75 distributed filesystems that can use it to achieve correct ETXTBUSY 75/* File is opened for execution with sys_execve / sys_uselib */
76 behavior for cross-node execution/opening_for_writing of files */ 76#define FMODE_EXEC ((__force fmode_t)16)
77#define FMODE_EXEC ((__force fmode_t)16) 77/* File is opened with O_NDELAY (only set for block devices) */
78 78#define FMODE_NDELAY ((__force fmode_t)32)
79#define FMODE_NDELAY ((__force fmode_t)32) 79/* File is opened with O_EXCL (only set for block devices) */
80#define FMODE_EXCL ((__force fmode_t)64) 80#define FMODE_EXCL ((__force fmode_t)64)
81/* File is opened using open(.., 3, ..) and is writeable only for ioctls
82 (specialy hack for floppy.c) */
81#define FMODE_WRITE_IOCTL ((__force fmode_t)128) 83#define FMODE_WRITE_IOCTL ((__force fmode_t)128)
82#define FMODE_NDELAY_NOW ((__force fmode_t)256)
83 84
84#define RW_MASK 1 85#define RW_MASK 1
85#define RWA_MASK 2 86#define RWA_MASK 2
diff --git a/kernel/power/swap.c b/kernel/power/swap.c
index b7713b53d07a..6da14358537c 100644
--- a/kernel/power/swap.c
+++ b/kernel/power/swap.c
@@ -633,7 +633,7 @@ void swsusp_close(fmode_t mode)
633 return; 633 return;
634 } 634 }
635 635
636 blkdev_put(resume_bdev, mode); /* move up */ 636 blkdev_put(resume_bdev, mode);
637} 637}
638 638
639static int swsusp_header_init(void) 639static int swsusp_header_init(void)