aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-10 20:04:23 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-10 20:04:23 -0400
commitce40be7a820bb393ac4ac69865f018d2f4038cf0 (patch)
treeb1fe5a93346eb06f22b1c303d63ec5456d7212ab /include/linux
parentba0a5a36f60e4c1152af3a2ae2813251974405bf (diff)
parent02f3939e1a9357b7c370a4a69717cf9c02452737 (diff)
Merge branch 'for-3.7/core' of git://git.kernel.dk/linux-block
Pull block IO update from Jens Axboe: "Core block IO bits for 3.7. Not a huge round this time, it contains: - First series from Kent cleaning up and generalizing bio allocation and freeing. - WRITE_SAME support from Martin. - Mikulas patches to prevent O_DIRECT crashes when someone changes the block size of a device. - Make bio_split() work on data-less bio's (like trim/discards). - A few other minor fixups." Fixed up silent semantic mis-merge as per Mikulas Patocka and Andrew Morton. It is due to the VM no longer using a prio-tree (see commit 6b2dbba8b6ac: "mm: replace vma prio_tree with an interval tree"). So make set_blocksize() use mapping_mapped() instead of open-coding the internal VM knowledge that has changed. * 'for-3.7/core' of git://git.kernel.dk/linux-block: (26 commits) block: makes bio_split support bio without data scatterlist: refactor the sg_nents scatterlist: add sg_nents fs: fix include/percpu-rwsem.h export error percpu-rw-semaphore: fix documentation typos fs/block_dev.c:1644:5: sparse: symbol 'blkdev_mmap' was not declared blockdev: turn a rw semaphore into a percpu rw semaphore Fix a crash when block device is read and block size is changed at the same time block: fix request_queue->flags initialization block: lift the initial queue bypass mode on blk_register_queue() instead of blk_init_allocated_queue() block: ioctl to zero block ranges block: Make blkdev_issue_zeroout use WRITE SAME block: Implement support for WRITE SAME block: Consolidate command flag and queue limit checks for merges block: Clean up special command handling logic block/blk-tag.c: Remove useless kfree block: remove the duplicated setting for congestion_threshold block: reject invalid queue attribute values block: Add bio_clone_bioset(), bio_clone_kmalloc() block: Consolidate bio_alloc_bioset(), bio_kmalloc() ...
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/bio.h70
-rw-r--r--include/linux/blk_types.h36
-rw-r--r--include/linux/blkdev.h82
-rw-r--r--include/linux/fs.h6
-rw-r--r--include/linux/percpu-rwsem.h89
-rw-r--r--include/linux/scatterlist.h1
6 files changed, 249 insertions, 35 deletions
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 26435890dc87..820e7aaad4fd 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -212,20 +212,41 @@ extern void bio_pair_release(struct bio_pair *dbio);
212extern struct bio_set *bioset_create(unsigned int, unsigned int); 212extern struct bio_set *bioset_create(unsigned int, unsigned int);
213extern void bioset_free(struct bio_set *); 213extern void bioset_free(struct bio_set *);
214 214
215extern struct bio *bio_alloc(gfp_t, unsigned int);
216extern struct bio *bio_kmalloc(gfp_t, unsigned int);
217extern struct bio *bio_alloc_bioset(gfp_t, int, struct bio_set *); 215extern struct bio *bio_alloc_bioset(gfp_t, int, struct bio_set *);
218extern void bio_put(struct bio *); 216extern void bio_put(struct bio *);
219extern void bio_free(struct bio *, struct bio_set *); 217
218extern void __bio_clone(struct bio *, struct bio *);
219extern struct bio *bio_clone_bioset(struct bio *, gfp_t, struct bio_set *bs);
220
221extern struct bio_set *fs_bio_set;
222
223static inline struct bio *bio_alloc(gfp_t gfp_mask, unsigned int nr_iovecs)
224{
225 return bio_alloc_bioset(gfp_mask, nr_iovecs, fs_bio_set);
226}
227
228static inline struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask)
229{
230 return bio_clone_bioset(bio, gfp_mask, fs_bio_set);
231}
232
233static inline struct bio *bio_kmalloc(gfp_t gfp_mask, unsigned int nr_iovecs)
234{
235 return bio_alloc_bioset(gfp_mask, nr_iovecs, NULL);
236}
237
238static inline struct bio *bio_clone_kmalloc(struct bio *bio, gfp_t gfp_mask)
239{
240 return bio_clone_bioset(bio, gfp_mask, NULL);
241
242}
220 243
221extern void bio_endio(struct bio *, int); 244extern void bio_endio(struct bio *, int);
222struct request_queue; 245struct request_queue;
223extern int bio_phys_segments(struct request_queue *, struct bio *); 246extern int bio_phys_segments(struct request_queue *, struct bio *);
224 247
225extern void __bio_clone(struct bio *, struct bio *);
226extern struct bio *bio_clone(struct bio *, gfp_t);
227
228extern void bio_init(struct bio *); 248extern void bio_init(struct bio *);
249extern void bio_reset(struct bio *);
229 250
230extern int bio_add_page(struct bio *, struct page *, unsigned int,unsigned int); 251extern int bio_add_page(struct bio *, struct page *, unsigned int,unsigned int);
231extern int bio_add_pc_page(struct request_queue *, struct bio *, struct page *, 252extern int bio_add_pc_page(struct request_queue *, struct bio *, struct page *,
@@ -304,8 +325,6 @@ struct biovec_slab {
304 struct kmem_cache *slab; 325 struct kmem_cache *slab;
305}; 326};
306 327
307extern struct bio_set *fs_bio_set;
308
309/* 328/*
310 * a small number of entries is fine, not going to be performance critical. 329 * a small number of entries is fine, not going to be performance critical.
311 * basically we just need to survive 330 * basically we just need to survive
@@ -367,9 +386,31 @@ static inline char *__bio_kmap_irq(struct bio *bio, unsigned short idx,
367/* 386/*
368 * Check whether this bio carries any data or not. A NULL bio is allowed. 387 * Check whether this bio carries any data or not. A NULL bio is allowed.
369 */ 388 */
370static inline int bio_has_data(struct bio *bio) 389static inline bool bio_has_data(struct bio *bio)
371{ 390{
372 return bio && bio->bi_io_vec != NULL; 391 if (bio && bio->bi_vcnt)
392 return true;
393
394 return false;
395}
396
397static inline bool bio_is_rw(struct bio *bio)
398{
399 if (!bio_has_data(bio))
400 return false;
401
402 if (bio->bi_rw & REQ_WRITE_SAME)
403 return false;
404
405 return true;
406}
407
408static inline bool bio_mergeable(struct bio *bio)
409{
410 if (bio->bi_rw & REQ_NOMERGE_FLAGS)
411 return false;
412
413 return true;
373} 414}
374 415
375/* 416/*
@@ -505,9 +546,8 @@ static inline struct bio *bio_list_get(struct bio_list *bl)
505 546
506#define bio_integrity(bio) (bio->bi_integrity != NULL) 547#define bio_integrity(bio) (bio->bi_integrity != NULL)
507 548
508extern struct bio_integrity_payload *bio_integrity_alloc_bioset(struct bio *, gfp_t, unsigned int, struct bio_set *);
509extern struct bio_integrity_payload *bio_integrity_alloc(struct bio *, gfp_t, unsigned int); 549extern struct bio_integrity_payload *bio_integrity_alloc(struct bio *, gfp_t, unsigned int);
510extern void bio_integrity_free(struct bio *, struct bio_set *); 550extern void bio_integrity_free(struct bio *);
511extern int bio_integrity_add_page(struct bio *, struct page *, unsigned int, unsigned int); 551extern int bio_integrity_add_page(struct bio *, struct page *, unsigned int, unsigned int);
512extern int bio_integrity_enabled(struct bio *bio); 552extern int bio_integrity_enabled(struct bio *bio);
513extern int bio_integrity_set_tag(struct bio *, void *, unsigned int); 553extern int bio_integrity_set_tag(struct bio *, void *, unsigned int);
@@ -517,7 +557,7 @@ extern void bio_integrity_endio(struct bio *, int);
517extern void bio_integrity_advance(struct bio *, unsigned int); 557extern void bio_integrity_advance(struct bio *, unsigned int);
518extern void bio_integrity_trim(struct bio *, unsigned int, unsigned int); 558extern void bio_integrity_trim(struct bio *, unsigned int, unsigned int);
519extern void bio_integrity_split(struct bio *, struct bio_pair *, int); 559extern void bio_integrity_split(struct bio *, struct bio_pair *, int);
520extern int bio_integrity_clone(struct bio *, struct bio *, gfp_t, struct bio_set *); 560extern int bio_integrity_clone(struct bio *, struct bio *, gfp_t);
521extern int bioset_integrity_create(struct bio_set *, int); 561extern int bioset_integrity_create(struct bio_set *, int);
522extern void bioset_integrity_free(struct bio_set *); 562extern void bioset_integrity_free(struct bio_set *);
523extern void bio_integrity_init(void); 563extern void bio_integrity_init(void);
@@ -549,13 +589,13 @@ static inline int bio_integrity_prep(struct bio *bio)
549 return 0; 589 return 0;
550} 590}
551 591
552static inline void bio_integrity_free(struct bio *bio, struct bio_set *bs) 592static inline void bio_integrity_free(struct bio *bio)
553{ 593{
554 return; 594 return;
555} 595}
556 596
557static inline int bio_integrity_clone(struct bio *bio, struct bio *bio_src, 597static inline int bio_integrity_clone(struct bio *bio, struct bio *bio_src,
558 gfp_t gfp_mask, struct bio_set *bs) 598 gfp_t gfp_mask)
559{ 599{
560 return 0; 600 return 0;
561} 601}
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 7b7ac9ccec7a..cdf11191e645 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -59,12 +59,6 @@ struct bio {
59 unsigned int bi_seg_front_size; 59 unsigned int bi_seg_front_size;
60 unsigned int bi_seg_back_size; 60 unsigned int bi_seg_back_size;
61 61
62 unsigned int bi_max_vecs; /* max bvl_vecs we can hold */
63
64 atomic_t bi_cnt; /* pin count */
65
66 struct bio_vec *bi_io_vec; /* the actual vec list */
67
68 bio_end_io_t *bi_end_io; 62 bio_end_io_t *bi_end_io;
69 63
70 void *bi_private; 64 void *bi_private;
@@ -80,7 +74,17 @@ struct bio {
80 struct bio_integrity_payload *bi_integrity; /* data integrity */ 74 struct bio_integrity_payload *bi_integrity; /* data integrity */
81#endif 75#endif
82 76
83 bio_destructor_t *bi_destructor; /* destructor */ 77 /*
78 * Everything starting with bi_max_vecs will be preserved by bio_reset()
79 */
80
81 unsigned int bi_max_vecs; /* max bvl_vecs we can hold */
82
83 atomic_t bi_cnt; /* pin count */
84
85 struct bio_vec *bi_io_vec; /* the actual vec list */
86
87 struct bio_set *bi_pool;
84 88
85 /* 89 /*
86 * We can inline a number of vecs at the end of the bio, to avoid 90 * We can inline a number of vecs at the end of the bio, to avoid
@@ -90,6 +94,8 @@ struct bio {
90 struct bio_vec bi_inline_vecs[0]; 94 struct bio_vec bi_inline_vecs[0];
91}; 95};
92 96
97#define BIO_RESET_BYTES offsetof(struct bio, bi_max_vecs)
98
93/* 99/*
94 * bio flags 100 * bio flags
95 */ 101 */
@@ -105,6 +111,13 @@ struct bio {
105#define BIO_FS_INTEGRITY 9 /* fs owns integrity data, not block layer */ 111#define BIO_FS_INTEGRITY 9 /* fs owns integrity data, not block layer */
106#define BIO_QUIET 10 /* Make BIO Quiet */ 112#define BIO_QUIET 10 /* Make BIO Quiet */
107#define BIO_MAPPED_INTEGRITY 11/* integrity metadata has been remapped */ 113#define BIO_MAPPED_INTEGRITY 11/* integrity metadata has been remapped */
114
115/*
116 * Flags starting here get preserved by bio_reset() - this includes
117 * BIO_POOL_IDX()
118 */
119#define BIO_RESET_BITS 12
120
108#define bio_flagged(bio, flag) ((bio)->bi_flags & (1 << (flag))) 121#define bio_flagged(bio, flag) ((bio)->bi_flags & (1 << (flag)))
109 122
110/* 123/*
@@ -134,6 +147,7 @@ enum rq_flag_bits {
134 __REQ_PRIO, /* boost priority in cfq */ 147 __REQ_PRIO, /* boost priority in cfq */
135 __REQ_DISCARD, /* request to discard sectors */ 148 __REQ_DISCARD, /* request to discard sectors */
136 __REQ_SECURE, /* secure discard (used with __REQ_DISCARD) */ 149 __REQ_SECURE, /* secure discard (used with __REQ_DISCARD) */
150 __REQ_WRITE_SAME, /* write same block many times */
137 151
138 __REQ_NOIDLE, /* don't anticipate more IO after this one */ 152 __REQ_NOIDLE, /* don't anticipate more IO after this one */
139 __REQ_FUA, /* forced unit access */ 153 __REQ_FUA, /* forced unit access */
@@ -172,15 +186,21 @@ enum rq_flag_bits {
172#define REQ_META (1 << __REQ_META) 186#define REQ_META (1 << __REQ_META)
173#define REQ_PRIO (1 << __REQ_PRIO) 187#define REQ_PRIO (1 << __REQ_PRIO)
174#define REQ_DISCARD (1 << __REQ_DISCARD) 188#define REQ_DISCARD (1 << __REQ_DISCARD)
189#define REQ_WRITE_SAME (1 << __REQ_WRITE_SAME)
175#define REQ_NOIDLE (1 << __REQ_NOIDLE) 190#define REQ_NOIDLE (1 << __REQ_NOIDLE)
176 191
177#define REQ_FAILFAST_MASK \ 192#define REQ_FAILFAST_MASK \
178 (REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER) 193 (REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER)
179#define REQ_COMMON_MASK \ 194#define REQ_COMMON_MASK \
180 (REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | \ 195 (REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | \
181 REQ_DISCARD | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | REQ_SECURE) 196 REQ_DISCARD | REQ_WRITE_SAME | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | \
197 REQ_SECURE)
182#define REQ_CLONE_MASK REQ_COMMON_MASK 198#define REQ_CLONE_MASK REQ_COMMON_MASK
183 199
200/* This mask is used for both bio and request merge checking */
201#define REQ_NOMERGE_FLAGS \
202 (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA)
203
184#define REQ_RAHEAD (1 << __REQ_RAHEAD) 204#define REQ_RAHEAD (1 << __REQ_RAHEAD)
185#define REQ_THROTTLED (1 << __REQ_THROTTLED) 205#define REQ_THROTTLED (1 << __REQ_THROTTLED)
186 206
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 4a2ab7c85393..1756001210d2 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -270,6 +270,7 @@ struct queue_limits {
270 unsigned int io_min; 270 unsigned int io_min;
271 unsigned int io_opt; 271 unsigned int io_opt;
272 unsigned int max_discard_sectors; 272 unsigned int max_discard_sectors;
273 unsigned int max_write_same_sectors;
273 unsigned int discard_granularity; 274 unsigned int discard_granularity;
274 unsigned int discard_alignment; 275 unsigned int discard_alignment;
275 276
@@ -540,8 +541,7 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q)
540 541
541#define blk_account_rq(rq) \ 542#define blk_account_rq(rq) \
542 (((rq)->cmd_flags & REQ_STARTED) && \ 543 (((rq)->cmd_flags & REQ_STARTED) && \
543 ((rq)->cmd_type == REQ_TYPE_FS || \ 544 ((rq)->cmd_type == REQ_TYPE_FS))
544 ((rq)->cmd_flags & REQ_DISCARD)))
545 545
546#define blk_pm_request(rq) \ 546#define blk_pm_request(rq) \
547 ((rq)->cmd_type == REQ_TYPE_PM_SUSPEND || \ 547 ((rq)->cmd_type == REQ_TYPE_PM_SUSPEND || \
@@ -595,17 +595,39 @@ static inline void blk_clear_rl_full(struct request_list *rl, bool sync)
595 rl->flags &= ~flag; 595 rl->flags &= ~flag;
596} 596}
597 597
598static inline bool rq_mergeable(struct request *rq)
599{
600 if (rq->cmd_type != REQ_TYPE_FS)
601 return false;
598 602
599/* 603 if (rq->cmd_flags & REQ_NOMERGE_FLAGS)
600 * mergeable request must not have _NOMERGE or _BARRIER bit set, nor may 604 return false;
601 * it already be started by driver. 605
602 */ 606 return true;
603#define RQ_NOMERGE_FLAGS \ 607}
604 (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA | REQ_DISCARD) 608
605#define rq_mergeable(rq) \ 609static inline bool blk_check_merge_flags(unsigned int flags1,
606 (!((rq)->cmd_flags & RQ_NOMERGE_FLAGS) && \ 610 unsigned int flags2)
607 (((rq)->cmd_flags & REQ_DISCARD) || \ 611{
608 (rq)->cmd_type == REQ_TYPE_FS)) 612 if ((flags1 & REQ_DISCARD) != (flags2 & REQ_DISCARD))
613 return false;
614
615 if ((flags1 & REQ_SECURE) != (flags2 & REQ_SECURE))
616 return false;
617
618 if ((flags1 & REQ_WRITE_SAME) != (flags2 & REQ_WRITE_SAME))
619 return false;
620
621 return true;
622}
623
624static inline bool blk_write_same_mergeable(struct bio *a, struct bio *b)
625{
626 if (bio_data(a) == bio_data(b))
627 return true;
628
629 return false;
630}
609 631
610/* 632/*
611 * q->prep_rq_fn return values 633 * q->prep_rq_fn return values
@@ -802,6 +824,28 @@ static inline unsigned int blk_rq_cur_sectors(const struct request *rq)
802 return blk_rq_cur_bytes(rq) >> 9; 824 return blk_rq_cur_bytes(rq) >> 9;
803} 825}
804 826
827static inline unsigned int blk_queue_get_max_sectors(struct request_queue *q,
828 unsigned int cmd_flags)
829{
830 if (unlikely(cmd_flags & REQ_DISCARD))
831 return q->limits.max_discard_sectors;
832
833 if (unlikely(cmd_flags & REQ_WRITE_SAME))
834 return q->limits.max_write_same_sectors;
835
836 return q->limits.max_sectors;
837}
838
839static inline unsigned int blk_rq_get_max_sectors(struct request *rq)
840{
841 struct request_queue *q = rq->q;
842
843 if (unlikely(rq->cmd_type == REQ_TYPE_BLOCK_PC))
844 return q->limits.max_hw_sectors;
845
846 return blk_queue_get_max_sectors(q, rq->cmd_flags);
847}
848
805/* 849/*
806 * Request issue related functions. 850 * Request issue related functions.
807 */ 851 */
@@ -857,6 +901,8 @@ extern void blk_queue_max_segments(struct request_queue *, unsigned short);
857extern void blk_queue_max_segment_size(struct request_queue *, unsigned int); 901extern void blk_queue_max_segment_size(struct request_queue *, unsigned int);
858extern void blk_queue_max_discard_sectors(struct request_queue *q, 902extern void blk_queue_max_discard_sectors(struct request_queue *q,
859 unsigned int max_discard_sectors); 903 unsigned int max_discard_sectors);
904extern void blk_queue_max_write_same_sectors(struct request_queue *q,
905 unsigned int max_write_same_sectors);
860extern void blk_queue_logical_block_size(struct request_queue *, unsigned short); 906extern void blk_queue_logical_block_size(struct request_queue *, unsigned short);
861extern void blk_queue_physical_block_size(struct request_queue *, unsigned int); 907extern void blk_queue_physical_block_size(struct request_queue *, unsigned int);
862extern void blk_queue_alignment_offset(struct request_queue *q, 908extern void blk_queue_alignment_offset(struct request_queue *q,
@@ -987,6 +1033,8 @@ static inline struct request *blk_map_queue_find_tag(struct blk_queue_tag *bqt,
987extern int blkdev_issue_flush(struct block_device *, gfp_t, sector_t *); 1033extern int blkdev_issue_flush(struct block_device *, gfp_t, sector_t *);
988extern int blkdev_issue_discard(struct block_device *bdev, sector_t sector, 1034extern int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
989 sector_t nr_sects, gfp_t gfp_mask, unsigned long flags); 1035 sector_t nr_sects, gfp_t gfp_mask, unsigned long flags);
1036extern int blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
1037 sector_t nr_sects, gfp_t gfp_mask, struct page *page);
990extern int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector, 1038extern int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
991 sector_t nr_sects, gfp_t gfp_mask); 1039 sector_t nr_sects, gfp_t gfp_mask);
992static inline int sb_issue_discard(struct super_block *sb, sector_t block, 1040static inline int sb_issue_discard(struct super_block *sb, sector_t block,
@@ -1164,6 +1212,16 @@ static inline unsigned int bdev_discard_zeroes_data(struct block_device *bdev)
1164 return queue_discard_zeroes_data(bdev_get_queue(bdev)); 1212 return queue_discard_zeroes_data(bdev_get_queue(bdev));
1165} 1213}
1166 1214
1215static inline unsigned int bdev_write_same(struct block_device *bdev)
1216{
1217 struct request_queue *q = bdev_get_queue(bdev);
1218
1219 if (q)
1220 return q->limits.max_write_same_sectors;
1221
1222 return 0;
1223}
1224
1167static inline int queue_dma_alignment(struct request_queue *q) 1225static inline int queue_dma_alignment(struct request_queue *q)
1168{ 1226{
1169 return q ? q->dma_alignment : 511; 1227 return q ? q->dma_alignment : 511;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index c617ed024df8..39f3e12ca752 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -335,6 +335,7 @@ struct inodes_stat_t {
335#define BLKDISCARDZEROES _IO(0x12,124) 335#define BLKDISCARDZEROES _IO(0x12,124)
336#define BLKSECDISCARD _IO(0x12,125) 336#define BLKSECDISCARD _IO(0x12,125)
337#define BLKROTATIONAL _IO(0x12,126) 337#define BLKROTATIONAL _IO(0x12,126)
338#define BLKZEROOUT _IO(0x12,127)
338 339
339#define BMAP_IOCTL 1 /* obsolete - kept for compatibility */ 340#define BMAP_IOCTL 1 /* obsolete - kept for compatibility */
340#define FIBMAP _IO(0x00,1) /* bmap access */ 341#define FIBMAP _IO(0x00,1) /* bmap access */
@@ -415,6 +416,7 @@ struct inodes_stat_t {
415#include <linux/migrate_mode.h> 416#include <linux/migrate_mode.h>
416#include <linux/uidgid.h> 417#include <linux/uidgid.h>
417#include <linux/lockdep.h> 418#include <linux/lockdep.h>
419#include <linux/percpu-rwsem.h>
418 420
419#include <asm/byteorder.h> 421#include <asm/byteorder.h>
420 422
@@ -724,6 +726,8 @@ struct block_device {
724 int bd_fsfreeze_count; 726 int bd_fsfreeze_count;
725 /* Mutex for freeze */ 727 /* Mutex for freeze */
726 struct mutex bd_fsfreeze_mutex; 728 struct mutex bd_fsfreeze_mutex;
729 /* A semaphore that prevents I/O while block size is being changed */
730 struct percpu_rw_semaphore bd_block_size_semaphore;
727}; 731};
728 732
729/* 733/*
@@ -2570,6 +2574,8 @@ extern int generic_segment_checks(const struct iovec *iov,
2570 unsigned long *nr_segs, size_t *count, int access_flags); 2574 unsigned long *nr_segs, size_t *count, int access_flags);
2571 2575
2572/* fs/block_dev.c */ 2576/* fs/block_dev.c */
2577extern ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov,
2578 unsigned long nr_segs, loff_t pos);
2573extern ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov, 2579extern ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
2574 unsigned long nr_segs, loff_t pos); 2580 unsigned long nr_segs, loff_t pos);
2575extern int blkdev_fsync(struct file *filp, loff_t start, loff_t end, 2581extern int blkdev_fsync(struct file *filp, loff_t start, loff_t end,
diff --git a/include/linux/percpu-rwsem.h b/include/linux/percpu-rwsem.h
new file mode 100644
index 000000000000..cf80f7e5277f
--- /dev/null
+++ b/include/linux/percpu-rwsem.h
@@ -0,0 +1,89 @@
1#ifndef _LINUX_PERCPU_RWSEM_H
2#define _LINUX_PERCPU_RWSEM_H
3
4#include <linux/mutex.h>
5#include <linux/percpu.h>
6#include <linux/rcupdate.h>
7#include <linux/delay.h>
8
9struct percpu_rw_semaphore {
10 unsigned __percpu *counters;
11 bool locked;
12 struct mutex mtx;
13};
14
15static inline void percpu_down_read(struct percpu_rw_semaphore *p)
16{
17 rcu_read_lock();
18 if (unlikely(p->locked)) {
19 rcu_read_unlock();
20 mutex_lock(&p->mtx);
21 this_cpu_inc(*p->counters);
22 mutex_unlock(&p->mtx);
23 return;
24 }
25 this_cpu_inc(*p->counters);
26 rcu_read_unlock();
27}
28
29static inline void percpu_up_read(struct percpu_rw_semaphore *p)
30{
31 /*
32 * On X86, write operation in this_cpu_dec serves as a memory unlock
33 * barrier (i.e. memory accesses may be moved before the write, but
34 * no memory accesses are moved past the write).
35 * On other architectures this may not be the case, so we need smp_mb()
36 * there.
37 */
38#if defined(CONFIG_X86) && (!defined(CONFIG_X86_PPRO_FENCE) && !defined(CONFIG_X86_OOSTORE))
39 barrier();
40#else
41 smp_mb();
42#endif
43 this_cpu_dec(*p->counters);
44}
45
46static inline unsigned __percpu_count(unsigned __percpu *counters)
47{
48 unsigned total = 0;
49 int cpu;
50
51 for_each_possible_cpu(cpu)
52 total += ACCESS_ONCE(*per_cpu_ptr(counters, cpu));
53
54 return total;
55}
56
57static inline void percpu_down_write(struct percpu_rw_semaphore *p)
58{
59 mutex_lock(&p->mtx);
60 p->locked = true;
61 synchronize_rcu();
62 while (__percpu_count(p->counters))
63 msleep(1);
64 smp_rmb(); /* paired with smp_mb() in percpu_sem_up_read() */
65}
66
67static inline void percpu_up_write(struct percpu_rw_semaphore *p)
68{
69 p->locked = false;
70 mutex_unlock(&p->mtx);
71}
72
73static inline int percpu_init_rwsem(struct percpu_rw_semaphore *p)
74{
75 p->counters = alloc_percpu(unsigned);
76 if (unlikely(!p->counters))
77 return -ENOMEM;
78 p->locked = false;
79 mutex_init(&p->mtx);
80 return 0;
81}
82
83static inline void percpu_free_rwsem(struct percpu_rw_semaphore *p)
84{
85 free_percpu(p->counters);
86 p->counters = NULL; /* catch use after free bugs */
87}
88
89#endif
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index 7b600da9a635..4bd6c06eb28e 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -201,6 +201,7 @@ static inline void *sg_virt(struct scatterlist *sg)
201 return page_address(sg_page(sg)) + sg->offset; 201 return page_address(sg_page(sg)) + sg->offset;
202} 202}
203 203
204int sg_nents(struct scatterlist *sg);
204struct scatterlist *sg_next(struct scatterlist *); 205struct scatterlist *sg_next(struct scatterlist *);
205struct scatterlist *sg_last(struct scatterlist *s, unsigned int); 206struct scatterlist *sg_last(struct scatterlist *s, unsigned int);
206void sg_init_table(struct scatterlist *, unsigned int); 207void sg_init_table(struct scatterlist *, unsigned int);