diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-08 11:19:16 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-08 11:19:16 -0500 |
commit | 6035ccd8e9e40bb654fbfdef325902ab531679a5 (patch) | |
tree | c1810d8a4d4ef150cdf14af72e6087dfc3f4b6e0 /fs | |
parent | 23eb3b64b5e44680c867e165fe1cd18e57fba255 (diff) | |
parent | 878eaddd05d251cefa9632c2b8046833c5eead66 (diff) |
Merge branch 'for-2.6.33' of git://git.kernel.dk/linux-2.6-block
* 'for-2.6.33' of git://git.kernel.dk/linux-2.6-block: (113 commits)
cfq-iosched: Do not access cfqq after freeing it
block: include linux/err.h to use ERR_PTR
cfq-iosched: use call_rcu() instead of doing grace period stall on queue exit
blkio: Allow CFQ group IO scheduling even when CFQ is a module
blkio: Implement dynamic io controlling policy registration
blkio: Export some symbols from blkio as its user CFQ can be a module
block: Fix io_context leak after failure of clone with CLONE_IO
block: Fix io_context leak after clone with CLONE_IO
cfq-iosched: make nonrot check logic consistent
io controller: quick fix for blk-cgroup and modular CFQ
cfq-iosched: move IO controller declerations to a header file
cfq-iosched: fix compile problem with !CONFIG_CGROUP
blkio: Documentation
blkio: Wait on sync-noidle queue even if rq_noidle = 1
blkio: Implement group_isolation tunable
blkio: Determine async workload length based on total number of queues
blkio: Wait for cfq queue to get backlogged if group is empty
blkio: Propagate cgroup weight updation to cfq groups
blkio: Drop the reference to queue once the task changes cgroup
blkio: Provide some isolation between groups
...
Diffstat (limited to 'fs')
-rw-r--r-- | fs/aio.c | 62 | ||||
-rw-r--r-- | fs/bio.c | 12 | ||||
-rw-r--r-- | fs/block_dev.c | 12 | ||||
-rw-r--r-- | fs/direct-io.c | 10 | ||||
-rw-r--r-- | fs/fs-writeback.c | 28 | ||||
-rw-r--r-- | fs/nfs/write.c | 2 | ||||
-rw-r--r-- | fs/partitions/check.c | 12 | ||||
-rw-r--r-- | fs/partitions/efi.c | 30 | ||||
-rw-r--r-- | fs/partitions/efi.h | 8 | ||||
-rw-r--r-- | fs/read_write.c | 2 | ||||
-rw-r--r-- | fs/splice.c | 24 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_aops.c | 9 |
12 files changed, 143 insertions, 68 deletions
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/aio_abi.h> | 15 | #include <linux/aio_abi.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/syscalls.h> | 17 | #include <linux/syscalls.h> |
18 | #include <linux/backing-dev.h> | ||
18 | #include <linux/uio.h> | 19 | #include <linux/uio.h> |
19 | 20 | ||
20 | #define DEBUG 0 | 21 | #define DEBUG 0 |
@@ -32,6 +33,9 @@ | |||
32 | #include <linux/workqueue.h> | 33 | #include <linux/workqueue.h> |
33 | #include <linux/security.h> | 34 | #include <linux/security.h> |
34 | #include <linux/eventfd.h> | 35 | #include <linux/eventfd.h> |
36 | #include <linux/blkdev.h> | ||
37 | #include <linux/mempool.h> | ||
38 | #include <linux/hash.h> | ||
35 | 39 | ||
36 | #include <asm/kmap_types.h> | 40 | #include <asm/kmap_types.h> |
37 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
@@ -60,6 +64,14 @@ static DECLARE_WORK(fput_work, aio_fput_routine); | |||
60 | static DEFINE_SPINLOCK(fput_lock); | 64 | static DEFINE_SPINLOCK(fput_lock); |
61 | static LIST_HEAD(fput_head); | 65 | static LIST_HEAD(fput_head); |
62 | 66 | ||
67 | #define AIO_BATCH_HASH_BITS 3 /* allocated on-stack, so don't go crazy */ | ||
68 | #define AIO_BATCH_HASH_SIZE (1 << AIO_BATCH_HASH_BITS) | ||
69 | struct aio_batch_entry { | ||
70 | struct hlist_node list; | ||
71 | struct address_space *mapping; | ||
72 | }; | ||
73 | mempool_t *abe_pool; | ||
74 | |||
63 | static void aio_kick_handler(struct work_struct *); | 75 | static void aio_kick_handler(struct work_struct *); |
64 | static void aio_queue_work(struct kioctx *); | 76 | static void aio_queue_work(struct kioctx *); |
65 | 77 | ||
@@ -73,6 +85,8 @@ static int __init aio_setup(void) | |||
73 | kioctx_cachep = KMEM_CACHE(kioctx,SLAB_HWCACHE_ALIGN|SLAB_PANIC); | 85 | kioctx_cachep = KMEM_CACHE(kioctx,SLAB_HWCACHE_ALIGN|SLAB_PANIC); |
74 | 86 | ||
75 | aio_wq = create_workqueue("aio"); | 87 | aio_wq = create_workqueue("aio"); |
88 | abe_pool = mempool_create_kmalloc_pool(1, sizeof(struct aio_batch_entry)); | ||
89 | BUG_ON(!abe_pool); | ||
76 | 90 | ||
77 | pr_debug("aio_setup: sizeof(struct page) = %d\n", (int)sizeof(struct page)); | 91 | pr_debug("aio_setup: sizeof(struct page) = %d\n", (int)sizeof(struct page)); |
78 | 92 | ||
@@ -1531,8 +1545,44 @@ static int aio_wake_function(wait_queue_t *wait, unsigned mode, | |||
1531 | return 1; | 1545 | return 1; |
1532 | } | 1546 | } |
1533 | 1547 | ||
1548 | static void aio_batch_add(struct address_space *mapping, | ||
1549 | struct hlist_head *batch_hash) | ||
1550 | { | ||
1551 | struct aio_batch_entry *abe; | ||
1552 | struct hlist_node *pos; | ||
1553 | unsigned bucket; | ||
1554 | |||
1555 | bucket = hash_ptr(mapping, AIO_BATCH_HASH_BITS); | ||
1556 | hlist_for_each_entry(abe, pos, &batch_hash[bucket], list) { | ||
1557 | if (abe->mapping == mapping) | ||
1558 | return; | ||
1559 | } | ||
1560 | |||
1561 | abe = mempool_alloc(abe_pool, GFP_KERNEL); | ||
1562 | BUG_ON(!igrab(mapping->host)); | ||
1563 | abe->mapping = mapping; | ||
1564 | hlist_add_head(&abe->list, &batch_hash[bucket]); | ||
1565 | return; | ||
1566 | } | ||
1567 | |||
1568 | static void aio_batch_free(struct hlist_head *batch_hash) | ||
1569 | { | ||
1570 | struct aio_batch_entry *abe; | ||
1571 | struct hlist_node *pos, *n; | ||
1572 | int i; | ||
1573 | |||
1574 | for (i = 0; i < AIO_BATCH_HASH_SIZE; i++) { | ||
1575 | hlist_for_each_entry_safe(abe, pos, n, &batch_hash[i], list) { | ||
1576 | blk_run_address_space(abe->mapping); | ||
1577 | iput(abe->mapping->host); | ||
1578 | hlist_del(&abe->list); | ||
1579 | mempool_free(abe, abe_pool); | ||
1580 | } | ||
1581 | } | ||
1582 | } | ||
1583 | |||
1534 | static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, | 1584 | static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, |
1535 | struct iocb *iocb) | 1585 | struct iocb *iocb, struct hlist_head *batch_hash) |
1536 | { | 1586 | { |
1537 | struct kiocb *req; | 1587 | struct kiocb *req; |
1538 | struct file *file; | 1588 | struct file *file; |
@@ -1608,6 +1658,12 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, | |||
1608 | ; | 1658 | ; |
1609 | } | 1659 | } |
1610 | spin_unlock_irq(&ctx->ctx_lock); | 1660 | spin_unlock_irq(&ctx->ctx_lock); |
1661 | if (req->ki_opcode == IOCB_CMD_PREAD || | ||
1662 | req->ki_opcode == IOCB_CMD_PREADV || | ||
1663 | req->ki_opcode == IOCB_CMD_PWRITE || | ||
1664 | req->ki_opcode == IOCB_CMD_PWRITEV) | ||
1665 | aio_batch_add(file->f_mapping, batch_hash); | ||
1666 | |||
1611 | aio_put_req(req); /* drop extra ref to req */ | 1667 | aio_put_req(req); /* drop extra ref to req */ |
1612 | return 0; | 1668 | return 0; |
1613 | 1669 | ||
@@ -1635,6 +1691,7 @@ SYSCALL_DEFINE3(io_submit, aio_context_t, ctx_id, long, nr, | |||
1635 | struct kioctx *ctx; | 1691 | struct kioctx *ctx; |
1636 | long ret = 0; | 1692 | long ret = 0; |
1637 | int i; | 1693 | int i; |
1694 | struct hlist_head batch_hash[AIO_BATCH_HASH_SIZE] = { { 0, }, }; | ||
1638 | 1695 | ||
1639 | if (unlikely(nr < 0)) | 1696 | if (unlikely(nr < 0)) |
1640 | return -EINVAL; | 1697 | return -EINVAL; |
@@ -1666,10 +1723,11 @@ SYSCALL_DEFINE3(io_submit, aio_context_t, ctx_id, long, nr, | |||
1666 | break; | 1723 | break; |
1667 | } | 1724 | } |
1668 | 1725 | ||
1669 | ret = io_submit_one(ctx, user_iocb, &tmp); | 1726 | ret = io_submit_one(ctx, user_iocb, &tmp, batch_hash); |
1670 | if (ret) | 1727 | if (ret) |
1671 | break; | 1728 | break; |
1672 | } | 1729 | } |
1730 | aio_batch_free(batch_hash); | ||
1673 | 1731 | ||
1674 | put_ioctx(ctx); | 1732 | put_ioctx(ctx); |
1675 | return i ? i : ret; | 1733 | return i ? i : ret; |
@@ -1393,6 +1393,18 @@ void bio_check_pages_dirty(struct bio *bio) | |||
1393 | } | 1393 | } |
1394 | } | 1394 | } |
1395 | 1395 | ||
1396 | #if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE | ||
1397 | void bio_flush_dcache_pages(struct bio *bi) | ||
1398 | { | ||
1399 | int i; | ||
1400 | struct bio_vec *bvec; | ||
1401 | |||
1402 | bio_for_each_segment(bvec, bi, i) | ||
1403 | flush_dcache_page(bvec->bv_page); | ||
1404 | } | ||
1405 | EXPORT_SYMBOL(bio_flush_dcache_pages); | ||
1406 | #endif | ||
1407 | |||
1396 | /** | 1408 | /** |
1397 | * bio_endio - end I/O on a bio | 1409 | * bio_endio - end I/O on a bio |
1398 | * @bio: bio | 1410 | * @bio: bio |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 8bed0557d88c..73d6a735b8f3 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -405,7 +405,17 @@ static loff_t block_llseek(struct file *file, loff_t offset, int origin) | |||
405 | 405 | ||
406 | static int block_fsync(struct file *filp, struct dentry *dentry, int datasync) | 406 | static int block_fsync(struct file *filp, struct dentry *dentry, int datasync) |
407 | { | 407 | { |
408 | return sync_blockdev(I_BDEV(filp->f_mapping->host)); | 408 | struct block_device *bdev = I_BDEV(filp->f_mapping->host); |
409 | int error; | ||
410 | |||
411 | error = sync_blockdev(bdev); | ||
412 | if (error) | ||
413 | return error; | ||
414 | |||
415 | error = blkdev_issue_flush(bdev, NULL); | ||
416 | if (error == -EOPNOTSUPP) | ||
417 | error = 0; | ||
418 | return error; | ||
409 | } | 419 | } |
410 | 420 | ||
411 | /* | 421 | /* |
diff --git a/fs/direct-io.c b/fs/direct-io.c index 8b10b87dc01a..b912270942fa 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c | |||
@@ -1028,9 +1028,6 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode, | |||
1028 | if (dio->bio) | 1028 | if (dio->bio) |
1029 | dio_bio_submit(dio); | 1029 | dio_bio_submit(dio); |
1030 | 1030 | ||
1031 | /* All IO is now issued, send it on its way */ | ||
1032 | blk_run_address_space(inode->i_mapping); | ||
1033 | |||
1034 | /* | 1031 | /* |
1035 | * It is possible that, we return short IO due to end of file. | 1032 | * It is possible that, we return short IO due to end of file. |
1036 | * In that case, we need to release all the pages we got hold on. | 1033 | * In that case, we need to release all the pages we got hold on. |
@@ -1057,8 +1054,11 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode, | |||
1057 | ((rw & READ) || (dio->result == dio->size))) | 1054 | ((rw & READ) || (dio->result == dio->size))) |
1058 | ret = -EIOCBQUEUED; | 1055 | ret = -EIOCBQUEUED; |
1059 | 1056 | ||
1060 | if (ret != -EIOCBQUEUED) | 1057 | if (ret != -EIOCBQUEUED) { |
1058 | /* All IO is now issued, send it on its way */ | ||
1059 | blk_run_address_space(inode->i_mapping); | ||
1061 | dio_await_completion(dio); | 1060 | dio_await_completion(dio); |
1061 | } | ||
1062 | 1062 | ||
1063 | /* | 1063 | /* |
1064 | * Sync will always be dropping the final ref and completing the | 1064 | * Sync will always be dropping the final ref and completing the |
@@ -1124,7 +1124,7 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, | |||
1124 | int acquire_i_mutex = 0; | 1124 | int acquire_i_mutex = 0; |
1125 | 1125 | ||
1126 | if (rw & WRITE) | 1126 | if (rw & WRITE) |
1127 | rw = WRITE_ODIRECT; | 1127 | rw = WRITE_ODIRECT_PLUG; |
1128 | 1128 | ||
1129 | if (bdev) | 1129 | if (bdev) |
1130 | bdev_blkbits = blksize_bits(bdev_logical_block_size(bdev)); | 1130 | bdev_blkbits = blksize_bits(bdev_logical_block_size(bdev)); |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 9d5360c4c2af..49bc1b8e8f19 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -614,7 +614,6 @@ static void writeback_inodes_wb(struct bdi_writeback *wb, | |||
614 | struct writeback_control *wbc) | 614 | struct writeback_control *wbc) |
615 | { | 615 | { |
616 | struct super_block *sb = wbc->sb, *pin_sb = NULL; | 616 | struct super_block *sb = wbc->sb, *pin_sb = NULL; |
617 | const int is_blkdev_sb = sb_is_blkdev_sb(sb); | ||
618 | const unsigned long start = jiffies; /* livelock avoidance */ | 617 | const unsigned long start = jiffies; /* livelock avoidance */ |
619 | 618 | ||
620 | spin_lock(&inode_lock); | 619 | spin_lock(&inode_lock); |
@@ -635,36 +634,11 @@ static void writeback_inodes_wb(struct bdi_writeback *wb, | |||
635 | continue; | 634 | continue; |
636 | } | 635 | } |
637 | 636 | ||
638 | if (!bdi_cap_writeback_dirty(wb->bdi)) { | ||
639 | redirty_tail(inode); | ||
640 | if (is_blkdev_sb) { | ||
641 | /* | ||
642 | * Dirty memory-backed blockdev: the ramdisk | ||
643 | * driver does this. Skip just this inode | ||
644 | */ | ||
645 | continue; | ||
646 | } | ||
647 | /* | ||
648 | * Dirty memory-backed inode against a filesystem other | ||
649 | * than the kernel-internal bdev filesystem. Skip the | ||
650 | * entire superblock. | ||
651 | */ | ||
652 | break; | ||
653 | } | ||
654 | |||
655 | if (inode->i_state & (I_NEW | I_WILL_FREE)) { | 637 | if (inode->i_state & (I_NEW | I_WILL_FREE)) { |
656 | requeue_io(inode); | 638 | requeue_io(inode); |
657 | continue; | 639 | continue; |
658 | } | 640 | } |
659 | 641 | ||
660 | if (wbc->nonblocking && bdi_write_congested(wb->bdi)) { | ||
661 | wbc->encountered_congestion = 1; | ||
662 | if (!is_blkdev_sb) | ||
663 | break; /* Skip a congested fs */ | ||
664 | requeue_io(inode); | ||
665 | continue; /* Skip a congested blockdev */ | ||
666 | } | ||
667 | |||
668 | /* | 642 | /* |
669 | * Was this inode dirtied after sync_sb_inodes was called? | 643 | * Was this inode dirtied after sync_sb_inodes was called? |
670 | * This keeps sync from extra jobs and livelock. | 644 | * This keeps sync from extra jobs and livelock. |
@@ -756,6 +730,7 @@ static long wb_writeback(struct bdi_writeback *wb, | |||
756 | .sync_mode = args->sync_mode, | 730 | .sync_mode = args->sync_mode, |
757 | .older_than_this = NULL, | 731 | .older_than_this = NULL, |
758 | .for_kupdate = args->for_kupdate, | 732 | .for_kupdate = args->for_kupdate, |
733 | .for_background = args->for_background, | ||
759 | .range_cyclic = args->range_cyclic, | 734 | .range_cyclic = args->range_cyclic, |
760 | }; | 735 | }; |
761 | unsigned long oldest_jif; | 736 | unsigned long oldest_jif; |
@@ -787,7 +762,6 @@ static long wb_writeback(struct bdi_writeback *wb, | |||
787 | break; | 762 | break; |
788 | 763 | ||
789 | wbc.more_io = 0; | 764 | wbc.more_io = 0; |
790 | wbc.encountered_congestion = 0; | ||
791 | wbc.nr_to_write = MAX_WRITEBACK_PAGES; | 765 | wbc.nr_to_write = MAX_WRITEBACK_PAGES; |
792 | wbc.pages_skipped = 0; | 766 | wbc.pages_skipped = 0; |
793 | writeback_inodes_wb(wb, &wbc); | 767 | writeback_inodes_wb(wb, &wbc); |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 53eb26c16b50..c84b5cc1a943 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -178,7 +178,7 @@ static int wb_priority(struct writeback_control *wbc) | |||
178 | { | 178 | { |
179 | if (wbc->for_reclaim) | 179 | if (wbc->for_reclaim) |
180 | return FLUSH_HIGHPRI | FLUSH_STABLE; | 180 | return FLUSH_HIGHPRI | FLUSH_STABLE; |
181 | if (wbc->for_kupdate) | 181 | if (wbc->for_kupdate || wbc->for_background) |
182 | return FLUSH_LOWPRI; | 182 | return FLUSH_LOWPRI; |
183 | return 0; | 183 | return 0; |
184 | } | 184 | } |
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 7b685e10cbad..64bc8998ac9a 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -226,6 +226,13 @@ ssize_t part_alignment_offset_show(struct device *dev, | |||
226 | return sprintf(buf, "%llu\n", (unsigned long long)p->alignment_offset); | 226 | return sprintf(buf, "%llu\n", (unsigned long long)p->alignment_offset); |
227 | } | 227 | } |
228 | 228 | ||
229 | ssize_t part_discard_alignment_show(struct device *dev, | ||
230 | struct device_attribute *attr, char *buf) | ||
231 | { | ||
232 | struct hd_struct *p = dev_to_part(dev); | ||
233 | return sprintf(buf, "%u\n", p->discard_alignment); | ||
234 | } | ||
235 | |||
229 | ssize_t part_stat_show(struct device *dev, | 236 | ssize_t part_stat_show(struct device *dev, |
230 | struct device_attribute *attr, char *buf) | 237 | struct device_attribute *attr, char *buf) |
231 | { | 238 | { |
@@ -288,6 +295,8 @@ static DEVICE_ATTR(partition, S_IRUGO, part_partition_show, NULL); | |||
288 | static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL); | 295 | static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL); |
289 | static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL); | 296 | static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL); |
290 | static DEVICE_ATTR(alignment_offset, S_IRUGO, part_alignment_offset_show, NULL); | 297 | static DEVICE_ATTR(alignment_offset, S_IRUGO, part_alignment_offset_show, NULL); |
298 | static DEVICE_ATTR(discard_alignment, S_IRUGO, part_discard_alignment_show, | ||
299 | NULL); | ||
291 | static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL); | 300 | static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL); |
292 | static DEVICE_ATTR(inflight, S_IRUGO, part_inflight_show, NULL); | 301 | static DEVICE_ATTR(inflight, S_IRUGO, part_inflight_show, NULL); |
293 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 302 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
@@ -300,6 +309,7 @@ static struct attribute *part_attrs[] = { | |||
300 | &dev_attr_start.attr, | 309 | &dev_attr_start.attr, |
301 | &dev_attr_size.attr, | 310 | &dev_attr_size.attr, |
302 | &dev_attr_alignment_offset.attr, | 311 | &dev_attr_alignment_offset.attr, |
312 | &dev_attr_discard_alignment.attr, | ||
303 | &dev_attr_stat.attr, | 313 | &dev_attr_stat.attr, |
304 | &dev_attr_inflight.attr, | 314 | &dev_attr_inflight.attr, |
305 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 315 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
@@ -403,6 +413,8 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno, | |||
403 | 413 | ||
404 | p->start_sect = start; | 414 | p->start_sect = start; |
405 | p->alignment_offset = queue_sector_alignment_offset(disk->queue, start); | 415 | p->alignment_offset = queue_sector_alignment_offset(disk->queue, start); |
416 | p->discard_alignment = queue_sector_discard_alignment(disk->queue, | ||
417 | start); | ||
406 | p->nr_sects = len; | 418 | p->nr_sects = len; |
407 | p->partno = partno; | 419 | p->partno = partno; |
408 | p->policy = get_disk_ro(disk); | 420 | p->policy = get_disk_ro(disk); |
diff --git a/fs/partitions/efi.c b/fs/partitions/efi.c index 038a6022152f..49cfd5f54238 100644 --- a/fs/partitions/efi.c +++ b/fs/partitions/efi.c | |||
@@ -1,7 +1,9 @@ | |||
1 | /************************************************************ | 1 | /************************************************************ |
2 | * EFI GUID Partition Table handling | 2 | * EFI GUID Partition Table handling |
3 | * Per Intel EFI Specification v1.02 | 3 | * |
4 | * http://developer.intel.com/technology/efi/efi.htm | 4 | * http://www.uefi.org/specs/ |
5 | * http://www.intel.com/technology/efi/ | ||
6 | * | ||
5 | * efi.[ch] by Matt Domsch <Matt_Domsch@dell.com> | 7 | * efi.[ch] by Matt Domsch <Matt_Domsch@dell.com> |
6 | * Copyright 2000,2001,2002,2004 Dell Inc. | 8 | * Copyright 2000,2001,2002,2004 Dell Inc. |
7 | * | 9 | * |
@@ -92,6 +94,7 @@ | |||
92 | * | 94 | * |
93 | ************************************************************/ | 95 | ************************************************************/ |
94 | #include <linux/crc32.h> | 96 | #include <linux/crc32.h> |
97 | #include <linux/math64.h> | ||
95 | #include "check.h" | 98 | #include "check.h" |
96 | #include "efi.h" | 99 | #include "efi.h" |
97 | 100 | ||
@@ -141,7 +144,8 @@ last_lba(struct block_device *bdev) | |||
141 | { | 144 | { |
142 | if (!bdev || !bdev->bd_inode) | 145 | if (!bdev || !bdev->bd_inode) |
143 | return 0; | 146 | return 0; |
144 | return (bdev->bd_inode->i_size >> 9) - 1ULL; | 147 | return div_u64(bdev->bd_inode->i_size, |
148 | bdev_logical_block_size(bdev)) - 1ULL; | ||
145 | } | 149 | } |
146 | 150 | ||
147 | static inline int | 151 | static inline int |
@@ -188,6 +192,7 @@ static size_t | |||
188 | read_lba(struct block_device *bdev, u64 lba, u8 * buffer, size_t count) | 192 | read_lba(struct block_device *bdev, u64 lba, u8 * buffer, size_t count) |
189 | { | 193 | { |
190 | size_t totalreadcount = 0; | 194 | size_t totalreadcount = 0; |
195 | sector_t n = lba * (bdev_logical_block_size(bdev) / 512); | ||
191 | 196 | ||
192 | if (!bdev || !buffer || lba > last_lba(bdev)) | 197 | if (!bdev || !buffer || lba > last_lba(bdev)) |
193 | return 0; | 198 | return 0; |
@@ -195,7 +200,7 @@ read_lba(struct block_device *bdev, u64 lba, u8 * buffer, size_t count) | |||
195 | while (count) { | 200 | while (count) { |
196 | int copied = 512; | 201 | int copied = 512; |
197 | Sector sect; | 202 | Sector sect; |
198 | unsigned char *data = read_dev_sector(bdev, lba++, §); | 203 | unsigned char *data = read_dev_sector(bdev, n++, §); |
199 | if (!data) | 204 | if (!data) |
200 | break; | 205 | break; |
201 | if (copied > count) | 206 | if (copied > count) |
@@ -257,15 +262,16 @@ static gpt_header * | |||
257 | alloc_read_gpt_header(struct block_device *bdev, u64 lba) | 262 | alloc_read_gpt_header(struct block_device *bdev, u64 lba) |
258 | { | 263 | { |
259 | gpt_header *gpt; | 264 | gpt_header *gpt; |
265 | unsigned ssz = bdev_logical_block_size(bdev); | ||
266 | |||
260 | if (!bdev) | 267 | if (!bdev) |
261 | return NULL; | 268 | return NULL; |
262 | 269 | ||
263 | gpt = kzalloc(sizeof (gpt_header), GFP_KERNEL); | 270 | gpt = kzalloc(ssz, GFP_KERNEL); |
264 | if (!gpt) | 271 | if (!gpt) |
265 | return NULL; | 272 | return NULL; |
266 | 273 | ||
267 | if (read_lba(bdev, lba, (u8 *) gpt, | 274 | if (read_lba(bdev, lba, (u8 *) gpt, ssz) < ssz) { |
268 | sizeof (gpt_header)) < sizeof (gpt_header)) { | ||
269 | kfree(gpt); | 275 | kfree(gpt); |
270 | gpt=NULL; | 276 | gpt=NULL; |
271 | return NULL; | 277 | return NULL; |
@@ -601,6 +607,7 @@ efi_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
601 | gpt_header *gpt = NULL; | 607 | gpt_header *gpt = NULL; |
602 | gpt_entry *ptes = NULL; | 608 | gpt_entry *ptes = NULL; |
603 | u32 i; | 609 | u32 i; |
610 | unsigned ssz = bdev_logical_block_size(bdev) / 512; | ||
604 | 611 | ||
605 | if (!find_valid_gpt(bdev, &gpt, &ptes) || !gpt || !ptes) { | 612 | if (!find_valid_gpt(bdev, &gpt, &ptes) || !gpt || !ptes) { |
606 | kfree(gpt); | 613 | kfree(gpt); |
@@ -611,13 +618,14 @@ efi_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
611 | pr_debug("GUID Partition Table is valid! Yea!\n"); | 618 | pr_debug("GUID Partition Table is valid! Yea!\n"); |
612 | 619 | ||
613 | for (i = 0; i < le32_to_cpu(gpt->num_partition_entries) && i < state->limit-1; i++) { | 620 | for (i = 0; i < le32_to_cpu(gpt->num_partition_entries) && i < state->limit-1; i++) { |
621 | u64 start = le64_to_cpu(ptes[i].starting_lba); | ||
622 | u64 size = le64_to_cpu(ptes[i].ending_lba) - | ||
623 | le64_to_cpu(ptes[i].starting_lba) + 1ULL; | ||
624 | |||
614 | if (!is_pte_valid(&ptes[i], last_lba(bdev))) | 625 | if (!is_pte_valid(&ptes[i], last_lba(bdev))) |
615 | continue; | 626 | continue; |
616 | 627 | ||
617 | put_partition(state, i+1, le64_to_cpu(ptes[i].starting_lba), | 628 | put_partition(state, i+1, start * ssz, size * ssz); |
618 | (le64_to_cpu(ptes[i].ending_lba) - | ||
619 | le64_to_cpu(ptes[i].starting_lba) + | ||
620 | 1ULL)); | ||
621 | 629 | ||
622 | /* If this is a RAID volume, tell md */ | 630 | /* If this is a RAID volume, tell md */ |
623 | if (!efi_guidcmp(ptes[i].partition_type_guid, | 631 | if (!efi_guidcmp(ptes[i].partition_type_guid, |
diff --git a/fs/partitions/efi.h b/fs/partitions/efi.h index 2cc89d0475bf..6998b589abf9 100644 --- a/fs/partitions/efi.h +++ b/fs/partitions/efi.h | |||
@@ -37,7 +37,6 @@ | |||
37 | #define EFI_PMBR_OSTYPE_EFI 0xEF | 37 | #define EFI_PMBR_OSTYPE_EFI 0xEF |
38 | #define EFI_PMBR_OSTYPE_EFI_GPT 0xEE | 38 | #define EFI_PMBR_OSTYPE_EFI_GPT 0xEE |
39 | 39 | ||
40 | #define GPT_BLOCK_SIZE 512 | ||
41 | #define GPT_HEADER_SIGNATURE 0x5452415020494645ULL | 40 | #define GPT_HEADER_SIGNATURE 0x5452415020494645ULL |
42 | #define GPT_HEADER_REVISION_V1 0x00010000 | 41 | #define GPT_HEADER_REVISION_V1 0x00010000 |
43 | #define GPT_PRIMARY_PARTITION_TABLE_LBA 1 | 42 | #define GPT_PRIMARY_PARTITION_TABLE_LBA 1 |
@@ -79,7 +78,12 @@ typedef struct _gpt_header { | |||
79 | __le32 num_partition_entries; | 78 | __le32 num_partition_entries; |
80 | __le32 sizeof_partition_entry; | 79 | __le32 sizeof_partition_entry; |
81 | __le32 partition_entry_array_crc32; | 80 | __le32 partition_entry_array_crc32; |
82 | u8 reserved2[GPT_BLOCK_SIZE - 92]; | 81 | |
82 | /* The rest of the logical block is reserved by UEFI and must be zero. | ||
83 | * EFI standard handles this by: | ||
84 | * | ||
85 | * uint8_t reserved2[ BlockSize - 92 ]; | ||
86 | */ | ||
83 | } __attribute__ ((packed)) gpt_header; | 87 | } __attribute__ ((packed)) gpt_header; |
84 | 88 | ||
85 | typedef struct _gpt_entry_attributes { | 89 | typedef struct _gpt_entry_attributes { |
diff --git a/fs/read_write.c b/fs/read_write.c index 3ac28987f22a..b7f4a1f94d48 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
@@ -826,8 +826,6 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | |||
826 | if (!(out_file->f_mode & FMODE_WRITE)) | 826 | if (!(out_file->f_mode & FMODE_WRITE)) |
827 | goto fput_out; | 827 | goto fput_out; |
828 | retval = -EINVAL; | 828 | retval = -EINVAL; |
829 | if (!out_file->f_op || !out_file->f_op->sendpage) | ||
830 | goto fput_out; | ||
831 | in_inode = in_file->f_path.dentry->d_inode; | 829 | in_inode = in_file->f_path.dentry->d_inode; |
832 | out_inode = out_file->f_path.dentry->d_inode; | 830 | out_inode = out_file->f_path.dentry->d_inode; |
833 | retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count); | 831 | retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count); |
diff --git a/fs/splice.c b/fs/splice.c index 7394e9e17534..39208663aaf1 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -648,9 +648,11 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe, | |||
648 | ret = buf->ops->confirm(pipe, buf); | 648 | ret = buf->ops->confirm(pipe, buf); |
649 | if (!ret) { | 649 | if (!ret) { |
650 | more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len; | 650 | more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len; |
651 | 651 | if (file->f_op && file->f_op->sendpage) | |
652 | ret = file->f_op->sendpage(file, buf->page, buf->offset, | 652 | ret = file->f_op->sendpage(file, buf->page, buf->offset, |
653 | sd->len, &pos, more); | 653 | sd->len, &pos, more); |
654 | else | ||
655 | ret = -EINVAL; | ||
654 | } | 656 | } |
655 | 657 | ||
656 | return ret; | 658 | return ret; |
@@ -1068,8 +1070,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, | |||
1068 | if (unlikely(ret < 0)) | 1070 | if (unlikely(ret < 0)) |
1069 | return ret; | 1071 | return ret; |
1070 | 1072 | ||
1071 | splice_write = out->f_op->splice_write; | 1073 | if (out->f_op && out->f_op->splice_write) |
1072 | if (!splice_write) | 1074 | splice_write = out->f_op->splice_write; |
1075 | else | ||
1073 | splice_write = default_file_splice_write; | 1076 | splice_write = default_file_splice_write; |
1074 | 1077 | ||
1075 | return splice_write(pipe, out, ppos, len, flags); | 1078 | return splice_write(pipe, out, ppos, len, flags); |
@@ -1093,8 +1096,9 @@ static long do_splice_to(struct file *in, loff_t *ppos, | |||
1093 | if (unlikely(ret < 0)) | 1096 | if (unlikely(ret < 0)) |
1094 | return ret; | 1097 | return ret; |
1095 | 1098 | ||
1096 | splice_read = in->f_op->splice_read; | 1099 | if (in->f_op && in->f_op->splice_read) |
1097 | if (!splice_read) | 1100 | splice_read = in->f_op->splice_read; |
1101 | else | ||
1098 | splice_read = default_file_splice_read; | 1102 | splice_read = default_file_splice_read; |
1099 | 1103 | ||
1100 | return splice_read(in, ppos, pipe, len, flags); | 1104 | return splice_read(in, ppos, pipe, len, flags); |
@@ -1316,7 +1320,8 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
1316 | if (off_in) | 1320 | if (off_in) |
1317 | return -ESPIPE; | 1321 | return -ESPIPE; |
1318 | if (off_out) { | 1322 | if (off_out) { |
1319 | if (out->f_op->llseek == no_llseek) | 1323 | if (!out->f_op || !out->f_op->llseek || |
1324 | out->f_op->llseek == no_llseek) | ||
1320 | return -EINVAL; | 1325 | return -EINVAL; |
1321 | if (copy_from_user(&offset, off_out, sizeof(loff_t))) | 1326 | if (copy_from_user(&offset, off_out, sizeof(loff_t))) |
1322 | return -EFAULT; | 1327 | return -EFAULT; |
@@ -1336,7 +1341,8 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
1336 | if (off_out) | 1341 | if (off_out) |
1337 | return -ESPIPE; | 1342 | return -ESPIPE; |
1338 | if (off_in) { | 1343 | if (off_in) { |
1339 | if (in->f_op->llseek == no_llseek) | 1344 | if (!in->f_op || !in->f_op->llseek || |
1345 | in->f_op->llseek == no_llseek) | ||
1340 | return -EINVAL; | 1346 | return -EINVAL; |
1341 | if (copy_from_user(&offset, off_in, sizeof(loff_t))) | 1347 | if (copy_from_user(&offset, off_in, sizeof(loff_t))) |
1342 | return -EFAULT; | 1348 | return -EFAULT; |
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index c2e30eea74dc..70f989895d15 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
@@ -904,16 +904,9 @@ xfs_convert_page( | |||
904 | 904 | ||
905 | if (startio) { | 905 | if (startio) { |
906 | if (count) { | 906 | if (count) { |
907 | struct backing_dev_info *bdi; | ||
908 | |||
909 | bdi = inode->i_mapping->backing_dev_info; | ||
910 | wbc->nr_to_write--; | 907 | wbc->nr_to_write--; |
911 | if (bdi_write_congested(bdi)) { | 908 | if (wbc->nr_to_write <= 0) |
912 | wbc->encountered_congestion = 1; | ||
913 | done = 1; | ||
914 | } else if (wbc->nr_to_write <= 0) { | ||
915 | done = 1; | 909 | done = 1; |
916 | } | ||
917 | } | 910 | } |
918 | xfs_start_page_writeback(page, !page_dirty, count); | 911 | xfs_start_page_writeback(page, !page_dirty, count); |
919 | } | 912 | } |