diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-13 13:45:01 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-13 13:45:01 -0500 |
commit | 275220f0fcff1adf28a717076e00f575edf05fda (patch) | |
tree | d249bccc80c64443dab211639050c4fb14332648 /drivers | |
parent | fe3c560b8a22cb28e54fe8950abef38e88d75831 (diff) | |
parent | 81c5e2ae33c4b19e53966b427e33646bf6811830 (diff) |
Merge branch 'for-2.6.38/core' of git://git.kernel.dk/linux-2.6-block
* 'for-2.6.38/core' of git://git.kernel.dk/linux-2.6-block: (43 commits)
block: ensure that completion error gets properly traced
blktrace: add missing probe argument to block_bio_complete
block cfq: don't use atomic_t for cfq_group
block cfq: don't use atomic_t for cfq_queue
block: trace event block fix unassigned field
block: add internal hd part table references
block: fix accounting bug on cross partition merges
kref: add kref_test_and_get
bio-integrity: mark kintegrityd_wq highpri and CPU intensive
block: make kblockd_workqueue smarter
Revert "sd: implement sd_check_events()"
block: Clean up exit_io_context() source code.
Fix compile warnings due to missing removal of a 'ret' variable
fs/block: type signature of major_to_index(int) to major_to_index(unsigned)
block: convert !IS_ERR(p) && p to !IS_ERR_NOR_NULL(p)
cfq-iosched: don't check cfqg in choose_service_tree()
fs/splice: Pull buf->ops->confirm() from splice_from_pipe actors
cdrom: export cdrom_check_events()
sd: implement sd_check_events()
sr: implement sr_check_events()
...
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/block/drbd/drbd_int.h | 2 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 7 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_nl.c | 103 | ||||
-rw-r--r-- | drivers/block/loop.c | 6 | ||||
-rw-r--r-- | drivers/block/pktcdvd.c | 22 | ||||
-rw-r--r-- | drivers/cdrom/cdrom.c | 56 | ||||
-rw-r--r-- | drivers/char/raw.c | 14 | ||||
-rw-r--r-- | drivers/md/dm-table.c | 20 | ||||
-rw-r--r-- | drivers/md/dm.c | 6 | ||||
-rw-r--r-- | drivers/md/md.c | 16 | ||||
-rw-r--r-- | drivers/mtd/devices/block2mtd.c | 10 | ||||
-rw-r--r-- | drivers/s390/block/dasd_genhd.c | 2 | ||||
-rw-r--r-- | drivers/scsi/scsi_lib.c | 13 | ||||
-rw-r--r-- | drivers/scsi/sd.c | 10 | ||||
-rw-r--r-- | drivers/scsi/sr.c | 174 | ||||
-rw-r--r-- | drivers/scsi/sr.h | 3 | ||||
-rw-r--r-- | drivers/scsi/sr_ioctl.c | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/storage_common.c | 7 |
18 files changed, 233 insertions, 240 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 1ea1a34e78b2..3803a0348937 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
@@ -911,8 +911,6 @@ struct drbd_md { | |||
911 | struct drbd_backing_dev { | 911 | struct drbd_backing_dev { |
912 | struct block_device *backing_bdev; | 912 | struct block_device *backing_bdev; |
913 | struct block_device *md_bdev; | 913 | struct block_device *md_bdev; |
914 | struct file *lo_file; | ||
915 | struct file *md_file; | ||
916 | struct drbd_md md; | 914 | struct drbd_md md; |
917 | struct disk_conf dc; /* The user provided config... */ | 915 | struct disk_conf dc; /* The user provided config... */ |
918 | sector_t known_size; /* last known size of that backing device */ | 916 | sector_t known_size; /* last known size of that backing device */ |
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 6be5401d0e88..29cd0dc9fe4f 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -3372,11 +3372,8 @@ void drbd_free_bc(struct drbd_backing_dev *ldev) | |||
3372 | if (ldev == NULL) | 3372 | if (ldev == NULL) |
3373 | return; | 3373 | return; |
3374 | 3374 | ||
3375 | bd_release(ldev->backing_bdev); | 3375 | blkdev_put(ldev->backing_bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL); |
3376 | bd_release(ldev->md_bdev); | 3376 | blkdev_put(ldev->md_bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL); |
3377 | |||
3378 | fput(ldev->lo_file); | ||
3379 | fput(ldev->md_file); | ||
3380 | 3377 | ||
3381 | kfree(ldev); | 3378 | kfree(ldev); |
3382 | } | 3379 | } |
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 29e5c70e4e26..8cbfaa687d72 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c | |||
@@ -855,7 +855,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp | |||
855 | sector_t max_possible_sectors; | 855 | sector_t max_possible_sectors; |
856 | sector_t min_md_device_sectors; | 856 | sector_t min_md_device_sectors; |
857 | struct drbd_backing_dev *nbc = NULL; /* new_backing_conf */ | 857 | struct drbd_backing_dev *nbc = NULL; /* new_backing_conf */ |
858 | struct inode *inode, *inode2; | 858 | struct block_device *bdev; |
859 | struct lru_cache *resync_lru = NULL; | 859 | struct lru_cache *resync_lru = NULL; |
860 | union drbd_state ns, os; | 860 | union drbd_state ns, os; |
861 | unsigned int max_seg_s; | 861 | unsigned int max_seg_s; |
@@ -907,46 +907,40 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp | |||
907 | } | 907 | } |
908 | } | 908 | } |
909 | 909 | ||
910 | nbc->lo_file = filp_open(nbc->dc.backing_dev, O_RDWR, 0); | 910 | bdev = blkdev_get_by_path(nbc->dc.backing_dev, |
911 | if (IS_ERR(nbc->lo_file)) { | 911 | FMODE_READ | FMODE_WRITE | FMODE_EXCL, mdev); |
912 | if (IS_ERR(bdev)) { | ||
912 | dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.backing_dev, | 913 | dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.backing_dev, |
913 | PTR_ERR(nbc->lo_file)); | 914 | PTR_ERR(bdev)); |
914 | nbc->lo_file = NULL; | ||
915 | retcode = ERR_OPEN_DISK; | 915 | retcode = ERR_OPEN_DISK; |
916 | goto fail; | 916 | goto fail; |
917 | } | 917 | } |
918 | nbc->backing_bdev = bdev; | ||
918 | 919 | ||
919 | inode = nbc->lo_file->f_dentry->d_inode; | 920 | /* |
920 | 921 | * meta_dev_idx >= 0: external fixed size, possibly multiple | |
921 | if (!S_ISBLK(inode->i_mode)) { | 922 | * drbd sharing one meta device. TODO in that case, paranoia |
922 | retcode = ERR_DISK_NOT_BDEV; | 923 | * check that [md_bdev, meta_dev_idx] is not yet used by some |
923 | goto fail; | 924 | * other drbd minor! (if you use drbd.conf + drbdadm, that |
924 | } | 925 | * should check it for you already; but if you don't, or |
925 | 926 | * someone fooled it, we need to double check here) | |
926 | nbc->md_file = filp_open(nbc->dc.meta_dev, O_RDWR, 0); | 927 | */ |
927 | if (IS_ERR(nbc->md_file)) { | 928 | bdev = blkdev_get_by_path(nbc->dc.meta_dev, |
929 | FMODE_READ | FMODE_WRITE | FMODE_EXCL, | ||
930 | (nbc->dc.meta_dev_idx < 0) ? | ||
931 | (void *)mdev : (void *)drbd_m_holder); | ||
932 | if (IS_ERR(bdev)) { | ||
928 | dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.meta_dev, | 933 | dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.meta_dev, |
929 | PTR_ERR(nbc->md_file)); | 934 | PTR_ERR(bdev)); |
930 | nbc->md_file = NULL; | ||
931 | retcode = ERR_OPEN_MD_DISK; | 935 | retcode = ERR_OPEN_MD_DISK; |
932 | goto fail; | 936 | goto fail; |
933 | } | 937 | } |
938 | nbc->md_bdev = bdev; | ||
934 | 939 | ||
935 | inode2 = nbc->md_file->f_dentry->d_inode; | 940 | if ((nbc->backing_bdev == nbc->md_bdev) != |
936 | 941 | (nbc->dc.meta_dev_idx == DRBD_MD_INDEX_INTERNAL || | |
937 | if (!S_ISBLK(inode2->i_mode)) { | 942 | nbc->dc.meta_dev_idx == DRBD_MD_INDEX_FLEX_INT)) { |
938 | retcode = ERR_MD_NOT_BDEV; | 943 | retcode = ERR_MD_IDX_INVALID; |
939 | goto fail; | ||
940 | } | ||
941 | |||
942 | nbc->backing_bdev = inode->i_bdev; | ||
943 | if (bd_claim(nbc->backing_bdev, mdev)) { | ||
944 | printk(KERN_ERR "drbd: bd_claim(%p,%p); failed [%p;%p;%u]\n", | ||
945 | nbc->backing_bdev, mdev, | ||
946 | nbc->backing_bdev->bd_holder, | ||
947 | nbc->backing_bdev->bd_contains->bd_holder, | ||
948 | nbc->backing_bdev->bd_holders); | ||
949 | retcode = ERR_BDCLAIM_DISK; | ||
950 | goto fail; | 944 | goto fail; |
951 | } | 945 | } |
952 | 946 | ||
@@ -955,28 +949,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp | |||
955 | offsetof(struct bm_extent, lce)); | 949 | offsetof(struct bm_extent, lce)); |
956 | if (!resync_lru) { | 950 | if (!resync_lru) { |
957 | retcode = ERR_NOMEM; | 951 | retcode = ERR_NOMEM; |
958 | goto release_bdev_fail; | 952 | goto fail; |
959 | } | ||
960 | |||
961 | /* meta_dev_idx >= 0: external fixed size, | ||
962 | * possibly multiple drbd sharing one meta device. | ||
963 | * TODO in that case, paranoia check that [md_bdev, meta_dev_idx] is | ||
964 | * not yet used by some other drbd minor! | ||
965 | * (if you use drbd.conf + drbdadm, | ||
966 | * that should check it for you already; but if you don't, or someone | ||
967 | * fooled it, we need to double check here) */ | ||
968 | nbc->md_bdev = inode2->i_bdev; | ||
969 | if (bd_claim(nbc->md_bdev, (nbc->dc.meta_dev_idx < 0) ? (void *)mdev | ||
970 | : (void *) drbd_m_holder)) { | ||
971 | retcode = ERR_BDCLAIM_MD_DISK; | ||
972 | goto release_bdev_fail; | ||
973 | } | ||
974 | |||
975 | if ((nbc->backing_bdev == nbc->md_bdev) != | ||
976 | (nbc->dc.meta_dev_idx == DRBD_MD_INDEX_INTERNAL || | ||
977 | nbc->dc.meta_dev_idx == DRBD_MD_INDEX_FLEX_INT)) { | ||
978 | retcode = ERR_MD_IDX_INVALID; | ||
979 | goto release_bdev2_fail; | ||
980 | } | 953 | } |
981 | 954 | ||
982 | /* RT - for drbd_get_max_capacity() DRBD_MD_INDEX_FLEX_INT */ | 955 | /* RT - for drbd_get_max_capacity() DRBD_MD_INDEX_FLEX_INT */ |
@@ -987,7 +960,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp | |||
987 | (unsigned long long) drbd_get_max_capacity(nbc), | 960 | (unsigned long long) drbd_get_max_capacity(nbc), |
988 | (unsigned long long) nbc->dc.disk_size); | 961 | (unsigned long long) nbc->dc.disk_size); |
989 | retcode = ERR_DISK_TO_SMALL; | 962 | retcode = ERR_DISK_TO_SMALL; |
990 | goto release_bdev2_fail; | 963 | goto fail; |
991 | } | 964 | } |
992 | 965 | ||
993 | if (nbc->dc.meta_dev_idx < 0) { | 966 | if (nbc->dc.meta_dev_idx < 0) { |
@@ -1004,7 +977,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp | |||
1004 | dev_warn(DEV, "refusing attach: md-device too small, " | 977 | dev_warn(DEV, "refusing attach: md-device too small, " |
1005 | "at least %llu sectors needed for this meta-disk type\n", | 978 | "at least %llu sectors needed for this meta-disk type\n", |
1006 | (unsigned long long) min_md_device_sectors); | 979 | (unsigned long long) min_md_device_sectors); |
1007 | goto release_bdev2_fail; | 980 | goto fail; |
1008 | } | 981 | } |
1009 | 982 | ||
1010 | /* Make sure the new disk is big enough | 983 | /* Make sure the new disk is big enough |
@@ -1012,7 +985,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp | |||
1012 | if (drbd_get_max_capacity(nbc) < | 985 | if (drbd_get_max_capacity(nbc) < |
1013 | drbd_get_capacity(mdev->this_bdev)) { | 986 | drbd_get_capacity(mdev->this_bdev)) { |
1014 | retcode = ERR_DISK_TO_SMALL; | 987 | retcode = ERR_DISK_TO_SMALL; |
1015 | goto release_bdev2_fail; | 988 | goto fail; |
1016 | } | 989 | } |
1017 | 990 | ||
1018 | nbc->known_size = drbd_get_capacity(nbc->backing_bdev); | 991 | nbc->known_size = drbd_get_capacity(nbc->backing_bdev); |
@@ -1035,7 +1008,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp | |||
1035 | retcode = _drbd_request_state(mdev, NS(disk, D_ATTACHING), CS_VERBOSE); | 1008 | retcode = _drbd_request_state(mdev, NS(disk, D_ATTACHING), CS_VERBOSE); |
1036 | drbd_resume_io(mdev); | 1009 | drbd_resume_io(mdev); |
1037 | if (retcode < SS_SUCCESS) | 1010 | if (retcode < SS_SUCCESS) |
1038 | goto release_bdev2_fail; | 1011 | goto fail; |
1039 | 1012 | ||
1040 | if (!get_ldev_if_state(mdev, D_ATTACHING)) | 1013 | if (!get_ldev_if_state(mdev, D_ATTACHING)) |
1041 | goto force_diskless; | 1014 | goto force_diskless; |
@@ -1269,18 +1242,14 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp | |||
1269 | force_diskless: | 1242 | force_diskless: |
1270 | drbd_force_state(mdev, NS(disk, D_FAILED)); | 1243 | drbd_force_state(mdev, NS(disk, D_FAILED)); |
1271 | drbd_md_sync(mdev); | 1244 | drbd_md_sync(mdev); |
1272 | release_bdev2_fail: | ||
1273 | if (nbc) | ||
1274 | bd_release(nbc->md_bdev); | ||
1275 | release_bdev_fail: | ||
1276 | if (nbc) | ||
1277 | bd_release(nbc->backing_bdev); | ||
1278 | fail: | 1245 | fail: |
1279 | if (nbc) { | 1246 | if (nbc) { |
1280 | if (nbc->lo_file) | 1247 | if (nbc->backing_bdev) |
1281 | fput(nbc->lo_file); | 1248 | blkdev_put(nbc->backing_bdev, |
1282 | if (nbc->md_file) | 1249 | FMODE_READ | FMODE_WRITE | FMODE_EXCL); |
1283 | fput(nbc->md_file); | 1250 | if (nbc->md_bdev) |
1251 | blkdev_put(nbc->md_bdev, | ||
1252 | FMODE_READ | FMODE_WRITE | FMODE_EXCL); | ||
1284 | kfree(nbc); | 1253 | kfree(nbc); |
1285 | } | 1254 | } |
1286 | lc_destroy(resync_lru); | 1255 | lc_destroy(resync_lru); |
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 7ea0bea2f7e3..44e18c073c44 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -395,11 +395,7 @@ lo_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf, | |||
395 | struct loop_device *lo = p->lo; | 395 | struct loop_device *lo = p->lo; |
396 | struct page *page = buf->page; | 396 | struct page *page = buf->page; |
397 | sector_t IV; | 397 | sector_t IV; |
398 | int size, ret; | 398 | int size; |
399 | |||
400 | ret = buf->ops->confirm(pipe, buf); | ||
401 | if (unlikely(ret)) | ||
402 | return ret; | ||
403 | 399 | ||
404 | IV = ((sector_t) page->index << (PAGE_CACHE_SHIFT - 9)) + | 400 | IV = ((sector_t) page->index << (PAGE_CACHE_SHIFT - 9)) + |
405 | (buf->offset >> 9); | 401 | (buf->offset >> 9); |
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 19b3568e9326..77d70eebb6b2 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
@@ -2296,15 +2296,12 @@ static int pkt_open_dev(struct pktcdvd_device *pd, fmode_t write) | |||
2296 | * so bdget() can't fail. | 2296 | * so bdget() can't fail. |
2297 | */ | 2297 | */ |
2298 | bdget(pd->bdev->bd_dev); | 2298 | bdget(pd->bdev->bd_dev); |
2299 | if ((ret = blkdev_get(pd->bdev, FMODE_READ))) | 2299 | if ((ret = blkdev_get(pd->bdev, FMODE_READ | FMODE_EXCL, pd))) |
2300 | goto out; | 2300 | goto out; |
2301 | 2301 | ||
2302 | if ((ret = bd_claim(pd->bdev, pd))) | ||
2303 | goto out_putdev; | ||
2304 | |||
2305 | if ((ret = pkt_get_last_written(pd, &lba))) { | 2302 | if ((ret = pkt_get_last_written(pd, &lba))) { |
2306 | printk(DRIVER_NAME": pkt_get_last_written failed\n"); | 2303 | printk(DRIVER_NAME": pkt_get_last_written failed\n"); |
2307 | goto out_unclaim; | 2304 | goto out_putdev; |
2308 | } | 2305 | } |
2309 | 2306 | ||
2310 | set_capacity(pd->disk, lba << 2); | 2307 | set_capacity(pd->disk, lba << 2); |
@@ -2314,7 +2311,7 @@ static int pkt_open_dev(struct pktcdvd_device *pd, fmode_t write) | |||
2314 | q = bdev_get_queue(pd->bdev); | 2311 | q = bdev_get_queue(pd->bdev); |
2315 | if (write) { | 2312 | if (write) { |
2316 | if ((ret = pkt_open_write(pd))) | 2313 | if ((ret = pkt_open_write(pd))) |
2317 | goto out_unclaim; | 2314 | goto out_putdev; |
2318 | /* | 2315 | /* |
2319 | * Some CDRW drives can not handle writes larger than one packet, | 2316 | * Some CDRW drives can not handle writes larger than one packet, |
2320 | * even if the size is a multiple of the packet size. | 2317 | * even if the size is a multiple of the packet size. |
@@ -2329,23 +2326,21 @@ static int pkt_open_dev(struct pktcdvd_device *pd, fmode_t write) | |||
2329 | } | 2326 | } |
2330 | 2327 | ||
2331 | if ((ret = pkt_set_segment_merging(pd, q))) | 2328 | if ((ret = pkt_set_segment_merging(pd, q))) |
2332 | goto out_unclaim; | 2329 | goto out_putdev; |
2333 | 2330 | ||
2334 | if (write) { | 2331 | if (write) { |
2335 | if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) { | 2332 | if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) { |
2336 | printk(DRIVER_NAME": not enough memory for buffers\n"); | 2333 | printk(DRIVER_NAME": not enough memory for buffers\n"); |
2337 | ret = -ENOMEM; | 2334 | ret = -ENOMEM; |
2338 | goto out_unclaim; | 2335 | goto out_putdev; |
2339 | } | 2336 | } |
2340 | printk(DRIVER_NAME": %lukB available on disc\n", lba << 1); | 2337 | printk(DRIVER_NAME": %lukB available on disc\n", lba << 1); |
2341 | } | 2338 | } |
2342 | 2339 | ||
2343 | return 0; | 2340 | return 0; |
2344 | 2341 | ||
2345 | out_unclaim: | ||
2346 | bd_release(pd->bdev); | ||
2347 | out_putdev: | 2342 | out_putdev: |
2348 | blkdev_put(pd->bdev, FMODE_READ); | 2343 | blkdev_put(pd->bdev, FMODE_READ | FMODE_EXCL); |
2349 | out: | 2344 | out: |
2350 | return ret; | 2345 | return ret; |
2351 | } | 2346 | } |
@@ -2362,8 +2357,7 @@ static void pkt_release_dev(struct pktcdvd_device *pd, int flush) | |||
2362 | pkt_lock_door(pd, 0); | 2357 | pkt_lock_door(pd, 0); |
2363 | 2358 | ||
2364 | pkt_set_speed(pd, MAX_SPEED, MAX_SPEED); | 2359 | pkt_set_speed(pd, MAX_SPEED, MAX_SPEED); |
2365 | bd_release(pd->bdev); | 2360 | blkdev_put(pd->bdev, FMODE_READ | FMODE_EXCL); |
2366 | blkdev_put(pd->bdev, FMODE_READ); | ||
2367 | 2361 | ||
2368 | pkt_shrink_pktlist(pd); | 2362 | pkt_shrink_pktlist(pd); |
2369 | } | 2363 | } |
@@ -2733,7 +2727,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev) | |||
2733 | bdev = bdget(dev); | 2727 | bdev = bdget(dev); |
2734 | if (!bdev) | 2728 | if (!bdev) |
2735 | return -ENOMEM; | 2729 | return -ENOMEM; |
2736 | ret = blkdev_get(bdev, FMODE_READ | FMODE_NDELAY); | 2730 | ret = blkdev_get(bdev, FMODE_READ | FMODE_NDELAY, NULL); |
2737 | if (ret) | 2731 | if (ret) |
2738 | return ret; | 2732 | return ret; |
2739 | 2733 | ||
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index af13c62dc473..14033a36bcd0 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c | |||
@@ -1348,7 +1348,10 @@ static int cdrom_select_disc(struct cdrom_device_info *cdi, int slot) | |||
1348 | if (!CDROM_CAN(CDC_SELECT_DISC)) | 1348 | if (!CDROM_CAN(CDC_SELECT_DISC)) |
1349 | return -EDRIVE_CANT_DO_THIS; | 1349 | return -EDRIVE_CANT_DO_THIS; |
1350 | 1350 | ||
1351 | (void) cdi->ops->media_changed(cdi, slot); | 1351 | if (cdi->ops->check_events) |
1352 | cdi->ops->check_events(cdi, 0, slot); | ||
1353 | else | ||
1354 | cdi->ops->media_changed(cdi, slot); | ||
1352 | 1355 | ||
1353 | if (slot == CDSL_NONE) { | 1356 | if (slot == CDSL_NONE) { |
1354 | /* set media changed bits, on both queues */ | 1357 | /* set media changed bits, on both queues */ |
@@ -1392,6 +1395,42 @@ static int cdrom_select_disc(struct cdrom_device_info *cdi, int slot) | |||
1392 | return slot; | 1395 | return slot; |
1393 | } | 1396 | } |
1394 | 1397 | ||
1398 | /* | ||
1399 | * As cdrom implements an extra ioctl consumer for media changed | ||
1400 | * event, it needs to buffer ->check_events() output, such that event | ||
1401 | * is not lost for both the usual VFS and ioctl paths. | ||
1402 | * cdi->{vfs|ioctl}_events are used to buffer pending events for each | ||
1403 | * path. | ||
1404 | * | ||
1405 | * XXX: Locking is non-existent. cdi->ops->check_events() can be | ||
1406 | * called in parallel and buffering fields are accessed without any | ||
1407 | * exclusion. The original media_changed code had the same problem. | ||
1408 | * It might be better to simply deprecate CDROM_MEDIA_CHANGED ioctl | ||
1409 | * and remove this cruft altogether. It doesn't have much usefulness | ||
1410 | * at this point. | ||
1411 | */ | ||
1412 | static void cdrom_update_events(struct cdrom_device_info *cdi, | ||
1413 | unsigned int clearing) | ||
1414 | { | ||
1415 | unsigned int events; | ||
1416 | |||
1417 | events = cdi->ops->check_events(cdi, clearing, CDSL_CURRENT); | ||
1418 | cdi->vfs_events |= events; | ||
1419 | cdi->ioctl_events |= events; | ||
1420 | } | ||
1421 | |||
1422 | unsigned int cdrom_check_events(struct cdrom_device_info *cdi, | ||
1423 | unsigned int clearing) | ||
1424 | { | ||
1425 | unsigned int events; | ||
1426 | |||
1427 | cdrom_update_events(cdi, clearing); | ||
1428 | events = cdi->vfs_events; | ||
1429 | cdi->vfs_events = 0; | ||
1430 | return events; | ||
1431 | } | ||
1432 | EXPORT_SYMBOL(cdrom_check_events); | ||
1433 | |||
1395 | /* We want to make media_changed accessible to the user through an | 1434 | /* We want to make media_changed accessible to the user through an |
1396 | * ioctl. The main problem now is that we must double-buffer the | 1435 | * ioctl. The main problem now is that we must double-buffer the |
1397 | * low-level implementation, to assure that the VFS and the user both | 1436 | * low-level implementation, to assure that the VFS and the user both |
@@ -1403,15 +1442,26 @@ int media_changed(struct cdrom_device_info *cdi, int queue) | |||
1403 | { | 1442 | { |
1404 | unsigned int mask = (1 << (queue & 1)); | 1443 | unsigned int mask = (1 << (queue & 1)); |
1405 | int ret = !!(cdi->mc_flags & mask); | 1444 | int ret = !!(cdi->mc_flags & mask); |
1445 | bool changed; | ||
1406 | 1446 | ||
1407 | if (!CDROM_CAN(CDC_MEDIA_CHANGED)) | 1447 | if (!CDROM_CAN(CDC_MEDIA_CHANGED)) |
1408 | return ret; | 1448 | return ret; |
1449 | |||
1409 | /* changed since last call? */ | 1450 | /* changed since last call? */ |
1410 | if (cdi->ops->media_changed(cdi, CDSL_CURRENT)) { | 1451 | if (cdi->ops->check_events) { |
1452 | BUG_ON(!queue); /* shouldn't be called from VFS path */ | ||
1453 | cdrom_update_events(cdi, DISK_EVENT_MEDIA_CHANGE); | ||
1454 | changed = cdi->ioctl_events & DISK_EVENT_MEDIA_CHANGE; | ||
1455 | cdi->ioctl_events = 0; | ||
1456 | } else | ||
1457 | changed = cdi->ops->media_changed(cdi, CDSL_CURRENT); | ||
1458 | |||
1459 | if (changed) { | ||
1411 | cdi->mc_flags = 0x3; /* set bit on both queues */ | 1460 | cdi->mc_flags = 0x3; /* set bit on both queues */ |
1412 | ret |= 1; | 1461 | ret |= 1; |
1413 | cdi->media_written = 0; | 1462 | cdi->media_written = 0; |
1414 | } | 1463 | } |
1464 | |||
1415 | cdi->mc_flags &= ~mask; /* clear bit */ | 1465 | cdi->mc_flags &= ~mask; /* clear bit */ |
1416 | return ret; | 1466 | return ret; |
1417 | } | 1467 | } |
diff --git a/drivers/char/raw.c b/drivers/char/raw.c index bfe25ea9766b..b4b9d5a47885 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c | |||
@@ -65,15 +65,12 @@ static int raw_open(struct inode *inode, struct file *filp) | |||
65 | if (!bdev) | 65 | if (!bdev) |
66 | goto out; | 66 | goto out; |
67 | igrab(bdev->bd_inode); | 67 | igrab(bdev->bd_inode); |
68 | err = blkdev_get(bdev, filp->f_mode); | 68 | err = blkdev_get(bdev, filp->f_mode | FMODE_EXCL, raw_open); |
69 | if (err) | 69 | if (err) |
70 | goto out; | 70 | goto out; |
71 | err = bd_claim(bdev, raw_open); | ||
72 | if (err) | ||
73 | goto out1; | ||
74 | err = set_blocksize(bdev, bdev_logical_block_size(bdev)); | 71 | err = set_blocksize(bdev, bdev_logical_block_size(bdev)); |
75 | if (err) | 72 | if (err) |
76 | goto out2; | 73 | goto out1; |
77 | filp->f_flags |= O_DIRECT; | 74 | filp->f_flags |= O_DIRECT; |
78 | filp->f_mapping = bdev->bd_inode->i_mapping; | 75 | filp->f_mapping = bdev->bd_inode->i_mapping; |
79 | if (++raw_devices[minor].inuse == 1) | 76 | if (++raw_devices[minor].inuse == 1) |
@@ -83,10 +80,8 @@ static int raw_open(struct inode *inode, struct file *filp) | |||
83 | mutex_unlock(&raw_mutex); | 80 | mutex_unlock(&raw_mutex); |
84 | return 0; | 81 | return 0; |
85 | 82 | ||
86 | out2: | ||
87 | bd_release(bdev); | ||
88 | out1: | 83 | out1: |
89 | blkdev_put(bdev, filp->f_mode); | 84 | blkdev_put(bdev, filp->f_mode | FMODE_EXCL); |
90 | out: | 85 | out: |
91 | mutex_unlock(&raw_mutex); | 86 | mutex_unlock(&raw_mutex); |
92 | return err; | 87 | return err; |
@@ -110,8 +105,7 @@ static int raw_release(struct inode *inode, struct file *filp) | |||
110 | } | 105 | } |
111 | mutex_unlock(&raw_mutex); | 106 | mutex_unlock(&raw_mutex); |
112 | 107 | ||
113 | bd_release(bdev); | 108 | blkdev_put(bdev, filp->f_mode | FMODE_EXCL); |
114 | blkdev_put(bdev, filp->f_mode); | ||
115 | return 0; | 109 | return 0; |
116 | } | 110 | } |
117 | 111 | ||
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 4d705cea0f8c..985c20a4f30e 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
@@ -325,15 +325,18 @@ static int open_dev(struct dm_dev_internal *d, dev_t dev, | |||
325 | 325 | ||
326 | BUG_ON(d->dm_dev.bdev); | 326 | BUG_ON(d->dm_dev.bdev); |
327 | 327 | ||
328 | bdev = open_by_devnum(dev, d->dm_dev.mode); | 328 | bdev = blkdev_get_by_dev(dev, d->dm_dev.mode | FMODE_EXCL, _claim_ptr); |
329 | if (IS_ERR(bdev)) | 329 | if (IS_ERR(bdev)) |
330 | return PTR_ERR(bdev); | 330 | return PTR_ERR(bdev); |
331 | r = bd_claim_by_disk(bdev, _claim_ptr, dm_disk(md)); | 331 | |
332 | if (r) | 332 | r = bd_link_disk_holder(bdev, dm_disk(md)); |
333 | blkdev_put(bdev, d->dm_dev.mode); | 333 | if (r) { |
334 | else | 334 | blkdev_put(bdev, d->dm_dev.mode | FMODE_EXCL); |
335 | d->dm_dev.bdev = bdev; | 335 | return r; |
336 | return r; | 336 | } |
337 | |||
338 | d->dm_dev.bdev = bdev; | ||
339 | return 0; | ||
337 | } | 340 | } |
338 | 341 | ||
339 | /* | 342 | /* |
@@ -344,8 +347,7 @@ static void close_dev(struct dm_dev_internal *d, struct mapped_device *md) | |||
344 | if (!d->dm_dev.bdev) | 347 | if (!d->dm_dev.bdev) |
345 | return; | 348 | return; |
346 | 349 | ||
347 | bd_release_from_disk(d->dm_dev.bdev, dm_disk(md)); | 350 | blkdev_put(d->dm_dev.bdev, d->dm_dev.mode | FMODE_EXCL); |
348 | blkdev_put(d->dm_dev.bdev, d->dm_dev.mode); | ||
349 | d->dm_dev.bdev = NULL; | 351 | d->dm_dev.bdev = NULL; |
350 | } | 352 | } |
351 | 353 | ||
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 7cb1352f7e7a..f48a2f359ac4 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -630,7 +630,7 @@ static void dec_pending(struct dm_io *io, int error) | |||
630 | queue_io(md, bio); | 630 | queue_io(md, bio); |
631 | } else { | 631 | } else { |
632 | /* done with normal IO or empty flush */ | 632 | /* done with normal IO or empty flush */ |
633 | trace_block_bio_complete(md->queue, bio); | 633 | trace_block_bio_complete(md->queue, bio, io_error); |
634 | bio_endio(bio, io_error); | 634 | bio_endio(bio, io_error); |
635 | } | 635 | } |
636 | } | 636 | } |
@@ -990,8 +990,8 @@ static void __map_bio(struct dm_target *ti, struct bio *clone, | |||
990 | if (r == DM_MAPIO_REMAPPED) { | 990 | if (r == DM_MAPIO_REMAPPED) { |
991 | /* the bio has been remapped so dispatch it */ | 991 | /* the bio has been remapped so dispatch it */ |
992 | 992 | ||
993 | trace_block_remap(bdev_get_queue(clone->bi_bdev), clone, | 993 | trace_block_bio_remap(bdev_get_queue(clone->bi_bdev), clone, |
994 | tio->io->bio->bi_bdev->bd_dev, sector); | 994 | tio->io->bio->bi_bdev->bd_dev, sector); |
995 | 995 | ||
996 | generic_make_request(clone); | 996 | generic_make_request(clone); |
997 | } else if (r < 0 || r == DM_MAPIO_REQUEUE) { | 997 | } else if (r < 0 || r == DM_MAPIO_REQUEUE) { |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 175c424f201f..7fc090ac9e28 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -1879,7 +1879,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) | |||
1879 | rdev->sysfs_state = sysfs_get_dirent_safe(rdev->kobj.sd, "state"); | 1879 | rdev->sysfs_state = sysfs_get_dirent_safe(rdev->kobj.sd, "state"); |
1880 | 1880 | ||
1881 | list_add_rcu(&rdev->same_set, &mddev->disks); | 1881 | list_add_rcu(&rdev->same_set, &mddev->disks); |
1882 | bd_claim_by_disk(rdev->bdev, rdev->bdev->bd_holder, mddev->gendisk); | 1882 | bd_link_disk_holder(rdev->bdev, mddev->gendisk); |
1883 | 1883 | ||
1884 | /* May as well allow recovery to be retried once */ | 1884 | /* May as well allow recovery to be retried once */ |
1885 | mddev->recovery_disabled = 0; | 1885 | mddev->recovery_disabled = 0; |
@@ -1906,7 +1906,6 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev) | |||
1906 | MD_BUG(); | 1906 | MD_BUG(); |
1907 | return; | 1907 | return; |
1908 | } | 1908 | } |
1909 | bd_release_from_disk(rdev->bdev, rdev->mddev->gendisk); | ||
1910 | list_del_rcu(&rdev->same_set); | 1909 | list_del_rcu(&rdev->same_set); |
1911 | printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b)); | 1910 | printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b)); |
1912 | rdev->mddev = NULL; | 1911 | rdev->mddev = NULL; |
@@ -1934,19 +1933,13 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev, int shared) | |||
1934 | struct block_device *bdev; | 1933 | struct block_device *bdev; |
1935 | char b[BDEVNAME_SIZE]; | 1934 | char b[BDEVNAME_SIZE]; |
1936 | 1935 | ||
1937 | bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE); | 1936 | bdev = blkdev_get_by_dev(dev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, |
1937 | shared ? (mdk_rdev_t *)lock_rdev : rdev); | ||
1938 | if (IS_ERR(bdev)) { | 1938 | if (IS_ERR(bdev)) { |
1939 | printk(KERN_ERR "md: could not open %s.\n", | 1939 | printk(KERN_ERR "md: could not open %s.\n", |
1940 | __bdevname(dev, b)); | 1940 | __bdevname(dev, b)); |
1941 | return PTR_ERR(bdev); | 1941 | return PTR_ERR(bdev); |
1942 | } | 1942 | } |
1943 | err = bd_claim(bdev, shared ? (mdk_rdev_t *)lock_rdev : rdev); | ||
1944 | if (err) { | ||
1945 | printk(KERN_ERR "md: could not bd_claim %s.\n", | ||
1946 | bdevname(bdev, b)); | ||
1947 | blkdev_put(bdev, FMODE_READ|FMODE_WRITE); | ||
1948 | return err; | ||
1949 | } | ||
1950 | if (!shared) | 1943 | if (!shared) |
1951 | set_bit(AllReserved, &rdev->flags); | 1944 | set_bit(AllReserved, &rdev->flags); |
1952 | rdev->bdev = bdev; | 1945 | rdev->bdev = bdev; |
@@ -1959,8 +1952,7 @@ static void unlock_rdev(mdk_rdev_t *rdev) | |||
1959 | rdev->bdev = NULL; | 1952 | rdev->bdev = NULL; |
1960 | if (!bdev) | 1953 | if (!bdev) |
1961 | MD_BUG(); | 1954 | MD_BUG(); |
1962 | bd_release(bdev); | 1955 | blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); |
1963 | blkdev_put(bdev, FMODE_READ|FMODE_WRITE); | ||
1964 | } | 1956 | } |
1965 | 1957 | ||
1966 | void md_autodetect_dev(dev_t dev); | 1958 | void md_autodetect_dev(dev_t dev); |
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index 2cf0cc6a4189..f29a6f9df6e7 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c | |||
@@ -224,7 +224,7 @@ static void block2mtd_free_device(struct block2mtd_dev *dev) | |||
224 | if (dev->blkdev) { | 224 | if (dev->blkdev) { |
225 | invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping, | 225 | invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping, |
226 | 0, -1); | 226 | 0, -1); |
227 | close_bdev_exclusive(dev->blkdev, FMODE_READ|FMODE_WRITE); | 227 | blkdev_put(dev->blkdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); |
228 | } | 228 | } |
229 | 229 | ||
230 | kfree(dev); | 230 | kfree(dev); |
@@ -234,6 +234,7 @@ static void block2mtd_free_device(struct block2mtd_dev *dev) | |||
234 | /* FIXME: ensure that mtd->size % erase_size == 0 */ | 234 | /* FIXME: ensure that mtd->size % erase_size == 0 */ |
235 | static struct block2mtd_dev *add_device(char *devname, int erase_size) | 235 | static struct block2mtd_dev *add_device(char *devname, int erase_size) |
236 | { | 236 | { |
237 | const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL; | ||
237 | struct block_device *bdev; | 238 | struct block_device *bdev; |
238 | struct block2mtd_dev *dev; | 239 | struct block2mtd_dev *dev; |
239 | char *name; | 240 | char *name; |
@@ -246,7 +247,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) | |||
246 | return NULL; | 247 | return NULL; |
247 | 248 | ||
248 | /* Get a handle on the device */ | 249 | /* Get a handle on the device */ |
249 | bdev = open_bdev_exclusive(devname, FMODE_READ|FMODE_WRITE, NULL); | 250 | bdev = blkdev_get_by_path(devname, mode, dev); |
250 | #ifndef MODULE | 251 | #ifndef MODULE |
251 | if (IS_ERR(bdev)) { | 252 | if (IS_ERR(bdev)) { |
252 | 253 | ||
@@ -254,9 +255,8 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) | |||
254 | to resolve the device name by other means. */ | 255 | to resolve the device name by other means. */ |
255 | 256 | ||
256 | dev_t devt = name_to_dev_t(devname); | 257 | dev_t devt = name_to_dev_t(devname); |
257 | if (devt) { | 258 | if (devt) |
258 | bdev = open_by_devnum(devt, FMODE_WRITE | FMODE_READ); | 259 | bdev = blkdev_get_by_dev(devt, mode, dev); |
259 | } | ||
260 | } | 260 | } |
261 | #endif | 261 | #endif |
262 | 262 | ||
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c index 30a1ca3d08b7..5505bc07e1e7 100644 --- a/drivers/s390/block/dasd_genhd.c +++ b/drivers/s390/block/dasd_genhd.c | |||
@@ -103,7 +103,7 @@ int dasd_scan_partitions(struct dasd_block *block) | |||
103 | struct block_device *bdev; | 103 | struct block_device *bdev; |
104 | 104 | ||
105 | bdev = bdget_disk(block->gdp, 0); | 105 | bdev = bdget_disk(block->gdp, 0); |
106 | if (!bdev || blkdev_get(bdev, FMODE_READ) < 0) | 106 | if (!bdev || blkdev_get(bdev, FMODE_READ, NULL) < 0) |
107 | return -ENODEV; | 107 | return -ENODEV; |
108 | /* | 108 | /* |
109 | * See fs/partition/check.c:register_disk,rescan_partitions | 109 | * See fs/partition/check.c:register_disk,rescan_partitions |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 501f67bef719..9045c52abd25 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -1977,8 +1977,7 @@ EXPORT_SYMBOL(scsi_mode_sense); | |||
1977 | * in. | 1977 | * in. |
1978 | * | 1978 | * |
1979 | * Returns zero if unsuccessful or an error if TUR failed. For | 1979 | * Returns zero if unsuccessful or an error if TUR failed. For |
1980 | * removable media, a return of NOT_READY or UNIT_ATTENTION is | 1980 | * removable media, UNIT_ATTENTION sets ->changed flag. |
1981 | * translated to success, with the ->changed flag updated. | ||
1982 | **/ | 1981 | **/ |
1983 | int | 1982 | int |
1984 | scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries, | 1983 | scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries, |
@@ -2005,16 +2004,6 @@ scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries, | |||
2005 | } while (scsi_sense_valid(sshdr) && | 2004 | } while (scsi_sense_valid(sshdr) && |
2006 | sshdr->sense_key == UNIT_ATTENTION && --retries); | 2005 | sshdr->sense_key == UNIT_ATTENTION && --retries); |
2007 | 2006 | ||
2008 | if (!sshdr) | ||
2009 | /* could not allocate sense buffer, so can't process it */ | ||
2010 | return result; | ||
2011 | |||
2012 | if (sdev->removable && scsi_sense_valid(sshdr) && | ||
2013 | (sshdr->sense_key == UNIT_ATTENTION || | ||
2014 | sshdr->sense_key == NOT_READY)) { | ||
2015 | sdev->changed = 1; | ||
2016 | result = 0; | ||
2017 | } | ||
2018 | if (!sshdr_external) | 2007 | if (!sshdr_external) |
2019 | kfree(sshdr); | 2008 | kfree(sshdr); |
2020 | return result; | 2009 | return result; |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 365024b0c407..b65e65aa07eb 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -1043,15 +1043,7 @@ static int sd_media_changed(struct gendisk *disk) | |||
1043 | sshdr); | 1043 | sshdr); |
1044 | } | 1044 | } |
1045 | 1045 | ||
1046 | /* | 1046 | if (retval) { |
1047 | * Unable to test, unit probably not ready. This usually | ||
1048 | * means there is no disc in the drive. Mark as changed, | ||
1049 | * and we will figure it out later once the drive is | ||
1050 | * available again. | ||
1051 | */ | ||
1052 | if (retval || (scsi_sense_valid(sshdr) && | ||
1053 | /* 0x3a is medium not present */ | ||
1054 | sshdr->asc == 0x3a)) { | ||
1055 | set_media_not_present(sdkp); | 1047 | set_media_not_present(sdkp); |
1056 | goto out; | 1048 | goto out; |
1057 | } | 1049 | } |
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index d7b383c96d5d..be6baf8ad704 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c | |||
@@ -104,14 +104,15 @@ static void sr_release(struct cdrom_device_info *); | |||
104 | static void get_sectorsize(struct scsi_cd *); | 104 | static void get_sectorsize(struct scsi_cd *); |
105 | static void get_capabilities(struct scsi_cd *); | 105 | static void get_capabilities(struct scsi_cd *); |
106 | 106 | ||
107 | static int sr_media_change(struct cdrom_device_info *, int); | 107 | static unsigned int sr_check_events(struct cdrom_device_info *cdi, |
108 | unsigned int clearing, int slot); | ||
108 | static int sr_packet(struct cdrom_device_info *, struct packet_command *); | 109 | static int sr_packet(struct cdrom_device_info *, struct packet_command *); |
109 | 110 | ||
110 | static struct cdrom_device_ops sr_dops = { | 111 | static struct cdrom_device_ops sr_dops = { |
111 | .open = sr_open, | 112 | .open = sr_open, |
112 | .release = sr_release, | 113 | .release = sr_release, |
113 | .drive_status = sr_drive_status, | 114 | .drive_status = sr_drive_status, |
114 | .media_changed = sr_media_change, | 115 | .check_events = sr_check_events, |
115 | .tray_move = sr_tray_move, | 116 | .tray_move = sr_tray_move, |
116 | .lock_door = sr_lock_door, | 117 | .lock_door = sr_lock_door, |
117 | .select_speed = sr_select_speed, | 118 | .select_speed = sr_select_speed, |
@@ -165,90 +166,96 @@ static void scsi_cd_put(struct scsi_cd *cd) | |||
165 | mutex_unlock(&sr_ref_mutex); | 166 | mutex_unlock(&sr_ref_mutex); |
166 | } | 167 | } |
167 | 168 | ||
168 | /* identical to scsi_test_unit_ready except that it doesn't | 169 | static unsigned int sr_get_events(struct scsi_device *sdev) |
169 | * eat the NOT_READY returns for removable media */ | ||
170 | int sr_test_unit_ready(struct scsi_device *sdev, struct scsi_sense_hdr *sshdr) | ||
171 | { | 170 | { |
172 | int retries = MAX_RETRIES; | 171 | u8 buf[8]; |
173 | int the_result; | 172 | u8 cmd[] = { GET_EVENT_STATUS_NOTIFICATION, |
174 | u8 cmd[] = {TEST_UNIT_READY, 0, 0, 0, 0, 0 }; | 173 | 1, /* polled */ |
174 | 0, 0, /* reserved */ | ||
175 | 1 << 4, /* notification class: media */ | ||
176 | 0, 0, /* reserved */ | ||
177 | 0, sizeof(buf), /* allocation length */ | ||
178 | 0, /* control */ | ||
179 | }; | ||
180 | struct event_header *eh = (void *)buf; | ||
181 | struct media_event_desc *med = (void *)(buf + 4); | ||
182 | struct scsi_sense_hdr sshdr; | ||
183 | int result; | ||
175 | 184 | ||
176 | /* issue TEST_UNIT_READY until the initial startup UNIT_ATTENTION | 185 | result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, sizeof(buf), |
177 | * conditions are gone, or a timeout happens | 186 | &sshdr, SR_TIMEOUT, MAX_RETRIES, NULL); |
178 | */ | 187 | if (scsi_sense_valid(&sshdr) && sshdr.sense_key == UNIT_ATTENTION) |
179 | do { | 188 | return DISK_EVENT_MEDIA_CHANGE; |
180 | the_result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, | 189 | |
181 | 0, sshdr, SR_TIMEOUT, | 190 | if (result || be16_to_cpu(eh->data_len) < sizeof(*med)) |
182 | retries--, NULL); | 191 | return 0; |
183 | if (scsi_sense_valid(sshdr) && | 192 | |
184 | sshdr->sense_key == UNIT_ATTENTION) | 193 | if (eh->nea || eh->notification_class != 0x4) |
185 | sdev->changed = 1; | 194 | return 0; |
186 | 195 | ||
187 | } while (retries > 0 && | 196 | if (med->media_event_code == 1) |
188 | (!scsi_status_is_good(the_result) || | 197 | return DISK_EVENT_EJECT_REQUEST; |
189 | (scsi_sense_valid(sshdr) && | 198 | else if (med->media_event_code == 2) |
190 | sshdr->sense_key == UNIT_ATTENTION))); | 199 | return DISK_EVENT_MEDIA_CHANGE; |
191 | return the_result; | 200 | return 0; |
192 | } | 201 | } |
193 | 202 | ||
194 | /* | 203 | /* |
195 | * This function checks to see if the media has been changed in the | 204 | * This function checks to see if the media has been changed or eject |
196 | * CDROM drive. It is possible that we have already sensed a change, | 205 | * button has been pressed. It is possible that we have already |
197 | * or the drive may have sensed one and not yet reported it. We must | 206 | * sensed a change, or the drive may have sensed one and not yet |
198 | * be ready for either case. This function always reports the current | 207 | * reported it. The past events are accumulated in sdev->changed and |
199 | * value of the changed bit. If flag is 0, then the changed bit is reset. | 208 | * returned together with the current state. |
200 | * This function could be done as an ioctl, but we would need to have | ||
201 | * an inode for that to work, and we do not always have one. | ||
202 | */ | 209 | */ |
203 | 210 | static unsigned int sr_check_events(struct cdrom_device_info *cdi, | |
204 | static int sr_media_change(struct cdrom_device_info *cdi, int slot) | 211 | unsigned int clearing, int slot) |
205 | { | 212 | { |
206 | struct scsi_cd *cd = cdi->handle; | 213 | struct scsi_cd *cd = cdi->handle; |
207 | int retval; | 214 | bool last_present; |
208 | struct scsi_sense_hdr *sshdr; | 215 | struct scsi_sense_hdr sshdr; |
216 | unsigned int events; | ||
217 | int ret; | ||
209 | 218 | ||
210 | if (CDSL_CURRENT != slot) { | 219 | /* no changer support */ |
211 | /* no changer support */ | 220 | if (CDSL_CURRENT != slot) |
212 | return -EINVAL; | 221 | return 0; |
213 | } | ||
214 | 222 | ||
215 | sshdr = kzalloc(sizeof(*sshdr), GFP_KERNEL); | 223 | events = sr_get_events(cd->device); |
216 | retval = sr_test_unit_ready(cd->device, sshdr); | 224 | /* |
217 | if (retval || (scsi_sense_valid(sshdr) && | 225 | * GET_EVENT_STATUS_NOTIFICATION is enough unless MEDIA_CHANGE |
218 | /* 0x3a is medium not present */ | 226 | * is being cleared. Note that there are devices which hang |
219 | sshdr->asc == 0x3a)) { | 227 | * if asked to execute TUR repeatedly. |
220 | /* Media not present or unable to test, unit probably not | 228 | */ |
221 | * ready. This usually means there is no disc in the drive. | 229 | if (!(clearing & DISK_EVENT_MEDIA_CHANGE)) |
222 | * Mark as changed, and we will figure it out later once | 230 | goto skip_tur; |
223 | * the drive is available again. | 231 | |
224 | */ | 232 | /* let's see whether the media is there with TUR */ |
225 | cd->device->changed = 1; | 233 | last_present = cd->media_present; |
226 | /* This will force a flush, if called from check_disk_change */ | 234 | ret = scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr); |
227 | retval = 1; | 235 | |
228 | goto out; | 236 | /* |
229 | }; | 237 | * Media is considered to be present if TUR succeeds or fails with |
238 | * sense data indicating something other than media-not-present | ||
239 | * (ASC 0x3a). | ||
240 | */ | ||
241 | cd->media_present = scsi_status_is_good(ret) || | ||
242 | (scsi_sense_valid(&sshdr) && sshdr.asc != 0x3a); | ||
230 | 243 | ||
231 | retval = cd->device->changed; | 244 | if (last_present != cd->media_present) |
232 | cd->device->changed = 0; | 245 | events |= DISK_EVENT_MEDIA_CHANGE; |
233 | /* If the disk changed, the capacity will now be different, | 246 | skip_tur: |
234 | * so we force a re-read of this information */ | 247 | if (cd->device->changed) { |
235 | if (retval) { | 248 | events |= DISK_EVENT_MEDIA_CHANGE; |
236 | /* check multisession offset etc */ | 249 | cd->device->changed = 0; |
237 | sr_cd_check(cdi); | ||
238 | get_sectorsize(cd); | ||
239 | } | 250 | } |
240 | 251 | ||
241 | out: | 252 | /* for backward compatibility */ |
242 | /* Notify userspace, that media has changed. */ | 253 | if (events & DISK_EVENT_MEDIA_CHANGE) |
243 | if (retval != cd->previous_state) | ||
244 | sdev_evt_send_simple(cd->device, SDEV_EVT_MEDIA_CHANGE, | 254 | sdev_evt_send_simple(cd->device, SDEV_EVT_MEDIA_CHANGE, |
245 | GFP_KERNEL); | 255 | GFP_KERNEL); |
246 | cd->previous_state = retval; | 256 | return events; |
247 | kfree(sshdr); | ||
248 | |||
249 | return retval; | ||
250 | } | 257 | } |
251 | 258 | ||
252 | /* | 259 | /* |
253 | * sr_done is the interrupt routine for the device driver. | 260 | * sr_done is the interrupt routine for the device driver. |
254 | * | 261 | * |
@@ -533,10 +540,25 @@ out: | |||
533 | return ret; | 540 | return ret; |
534 | } | 541 | } |
535 | 542 | ||
536 | static int sr_block_media_changed(struct gendisk *disk) | 543 | static unsigned int sr_block_check_events(struct gendisk *disk, |
544 | unsigned int clearing) | ||
537 | { | 545 | { |
538 | struct scsi_cd *cd = scsi_cd(disk); | 546 | struct scsi_cd *cd = scsi_cd(disk); |
539 | return cdrom_media_changed(&cd->cdi); | 547 | return cdrom_check_events(&cd->cdi, clearing); |
548 | } | ||
549 | |||
550 | static int sr_block_revalidate_disk(struct gendisk *disk) | ||
551 | { | ||
552 | struct scsi_cd *cd = scsi_cd(disk); | ||
553 | struct scsi_sense_hdr sshdr; | ||
554 | |||
555 | /* if the unit is not ready, nothing more to do */ | ||
556 | if (scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr)) | ||
557 | return 0; | ||
558 | |||
559 | sr_cd_check(&cd->cdi); | ||
560 | get_sectorsize(cd); | ||
561 | return 0; | ||
540 | } | 562 | } |
541 | 563 | ||
542 | static const struct block_device_operations sr_bdops = | 564 | static const struct block_device_operations sr_bdops = |
@@ -545,7 +567,8 @@ static const struct block_device_operations sr_bdops = | |||
545 | .open = sr_block_open, | 567 | .open = sr_block_open, |
546 | .release = sr_block_release, | 568 | .release = sr_block_release, |
547 | .ioctl = sr_block_ioctl, | 569 | .ioctl = sr_block_ioctl, |
548 | .media_changed = sr_block_media_changed, | 570 | .check_events = sr_block_check_events, |
571 | .revalidate_disk = sr_block_revalidate_disk, | ||
549 | /* | 572 | /* |
550 | * No compat_ioctl for now because sr_block_ioctl never | 573 | * No compat_ioctl for now because sr_block_ioctl never |
551 | * seems to pass arbitary ioctls down to host drivers. | 574 | * seems to pass arbitary ioctls down to host drivers. |
@@ -618,6 +641,7 @@ static int sr_probe(struct device *dev) | |||
618 | sprintf(disk->disk_name, "sr%d", minor); | 641 | sprintf(disk->disk_name, "sr%d", minor); |
619 | disk->fops = &sr_bdops; | 642 | disk->fops = &sr_bdops; |
620 | disk->flags = GENHD_FL_CD; | 643 | disk->flags = GENHD_FL_CD; |
644 | disk->events = DISK_EVENT_MEDIA_CHANGE | DISK_EVENT_EJECT_REQUEST; | ||
621 | 645 | ||
622 | blk_queue_rq_timeout(sdev->request_queue, SR_TIMEOUT); | 646 | blk_queue_rq_timeout(sdev->request_queue, SR_TIMEOUT); |
623 | 647 | ||
@@ -627,7 +651,7 @@ static int sr_probe(struct device *dev) | |||
627 | cd->disk = disk; | 651 | cd->disk = disk; |
628 | cd->capacity = 0x1fffff; | 652 | cd->capacity = 0x1fffff; |
629 | cd->device->changed = 1; /* force recheck CD type */ | 653 | cd->device->changed = 1; /* force recheck CD type */ |
630 | cd->previous_state = 1; | 654 | cd->media_present = 1; |
631 | cd->use = 1; | 655 | cd->use = 1; |
632 | cd->readcd_known = 0; | 656 | cd->readcd_known = 0; |
633 | cd->readcd_cdda = 0; | 657 | cd->readcd_cdda = 0; |
@@ -780,7 +804,7 @@ static void get_capabilities(struct scsi_cd *cd) | |||
780 | } | 804 | } |
781 | 805 | ||
782 | /* eat unit attentions */ | 806 | /* eat unit attentions */ |
783 | sr_test_unit_ready(cd->device, &sshdr); | 807 | scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr); |
784 | 808 | ||
785 | /* ask for mode page 0x2a */ | 809 | /* ask for mode page 0x2a */ |
786 | rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128, | 810 | rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128, |
diff --git a/drivers/scsi/sr.h b/drivers/scsi/sr.h index 1e144dfdbd4b..e036f1dc83c8 100644 --- a/drivers/scsi/sr.h +++ b/drivers/scsi/sr.h | |||
@@ -40,7 +40,7 @@ typedef struct scsi_cd { | |||
40 | unsigned xa_flag:1; /* CD has XA sectors ? */ | 40 | unsigned xa_flag:1; /* CD has XA sectors ? */ |
41 | unsigned readcd_known:1; /* drive supports READ_CD (0xbe) */ | 41 | unsigned readcd_known:1; /* drive supports READ_CD (0xbe) */ |
42 | unsigned readcd_cdda:1; /* reading audio data using READ_CD */ | 42 | unsigned readcd_cdda:1; /* reading audio data using READ_CD */ |
43 | unsigned previous_state:1; /* media has changed */ | 43 | unsigned media_present:1; /* media is present */ |
44 | struct cdrom_device_info cdi; | 44 | struct cdrom_device_info cdi; |
45 | /* We hold gendisk and scsi_device references on probe and use | 45 | /* We hold gendisk and scsi_device references on probe and use |
46 | * the refs on this kref to decide when to release them */ | 46 | * the refs on this kref to decide when to release them */ |
@@ -61,7 +61,6 @@ int sr_select_speed(struct cdrom_device_info *cdi, int speed); | |||
61 | int sr_audio_ioctl(struct cdrom_device_info *, unsigned int, void *); | 61 | int sr_audio_ioctl(struct cdrom_device_info *, unsigned int, void *); |
62 | 62 | ||
63 | int sr_is_xa(Scsi_CD *); | 63 | int sr_is_xa(Scsi_CD *); |
64 | int sr_test_unit_ready(struct scsi_device *sdev, struct scsi_sense_hdr *sshdr); | ||
65 | 64 | ||
66 | /* sr_vendor.c */ | 65 | /* sr_vendor.c */ |
67 | void sr_vendor_init(Scsi_CD *); | 66 | void sr_vendor_init(Scsi_CD *); |
diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c index 3cd8ffbad577..8be30554119b 100644 --- a/drivers/scsi/sr_ioctl.c +++ b/drivers/scsi/sr_ioctl.c | |||
@@ -307,7 +307,7 @@ int sr_drive_status(struct cdrom_device_info *cdi, int slot) | |||
307 | /* we have no changer support */ | 307 | /* we have no changer support */ |
308 | return -EINVAL; | 308 | return -EINVAL; |
309 | } | 309 | } |
310 | if (0 == sr_test_unit_ready(cd->device, &sshdr)) | 310 | if (!scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr)) |
311 | return CDS_DISC_OK; | 311 | return CDS_DISC_OK; |
312 | 312 | ||
313 | /* SK/ASC/ASCQ of 2/4/1 means "unit is becoming ready" */ | 313 | /* SK/ASC/ASCQ of 2/4/1 means "unit is becoming ready" */ |
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 3b513bafaf2a..b015561fd602 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c | |||
@@ -543,7 +543,7 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) | |||
543 | ro = curlun->initially_ro; | 543 | ro = curlun->initially_ro; |
544 | if (!ro) { | 544 | if (!ro) { |
545 | filp = filp_open(filename, O_RDWR | O_LARGEFILE, 0); | 545 | filp = filp_open(filename, O_RDWR | O_LARGEFILE, 0); |
546 | if (-EROFS == PTR_ERR(filp)) | 546 | if (PTR_ERR(filp) == -EROFS || PTR_ERR(filp) == -EACCES) |
547 | ro = 1; | 547 | ro = 1; |
548 | } | 548 | } |
549 | if (ro) | 549 | if (ro) |
@@ -558,10 +558,7 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) | |||
558 | 558 | ||
559 | if (filp->f_path.dentry) | 559 | if (filp->f_path.dentry) |
560 | inode = filp->f_path.dentry->d_inode; | 560 | inode = filp->f_path.dentry->d_inode; |
561 | if (inode && S_ISBLK(inode->i_mode)) { | 561 | if (!inode || (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))) { |
562 | if (bdev_read_only(inode->i_bdev)) | ||
563 | ro = 1; | ||
564 | } else if (!inode || !S_ISREG(inode->i_mode)) { | ||
565 | LINFO(curlun, "invalid file type: %s\n", filename); | 562 | LINFO(curlun, "invalid file type: %s\n", filename); |
566 | goto out; | 563 | goto out; |
567 | } | 564 | } |