Skip to content

Commit 0e6acf0

Browse files
committed
Merge tag 'xfs-for-linus-4.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs
Pull xfs updates from Dave Chinner: "The major addition is the new iomap based block mapping infrastructure. We've been kicking this about locally for years, but there are other filesystems want to use it too (e.g. gfs2). Now it is fully working, reviewed and ready for merge and be used by other filesystems. There are a lot of other fixes and cleanups in the tree, but those are XFS internal things and none are of the scale or visibility of the iomap changes. See below for details. I am likely to send another pull request next week - we're just about ready to merge some new functionality (on disk block->owner reverse mapping infrastructure), but that's a huge chunk of code (74 files changed, 7283 insertions(+), 1114 deletions(-)) so I'm keeping that separate to all the "normal" pull request changes so they don't get lost in the noise. Summary of changes in this update: - generic iomap based IO path infrastructure - generic iomap based fiemap implementation - xfs iomap based Io path implementation - buffer error handling fixes - tracking of in flight buffer IO for unmount serialisation - direct IO and DAX io path separation and simplification - shortform directory format definition changes for wider platform compatibility - various buffer cache fixes - cleanups in preparation for rmap merge - error injection cleanups and fixes - log item format buffer memory allocation restructuring to prevent rare OOM reclaim deadlocks - sparse inode chunks are now fully supported" * tag 'xfs-for-linus-4.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs: (53 commits) xfs: remove EXPERIMENTAL tag from sparse inode feature xfs: bufferhead chains are invalid after end_page_writeback xfs: allocate log vector buffers outside CIL context lock libxfs: directory node splitting does not have an extra block xfs: remove dax code from object file when disabled xfs: skip dirty pages in ->releasepage() xfs: remove __arch_pack xfs: kill xfs_dir2_inou_t xfs: kill xfs_dir2_sf_off_t xfs: split direct I/O and DAX path xfs: direct calls in the direct I/O path xfs: stop using generic_file_read_iter for direct I/O xfs: split xfs_file_read_iter into buffered and direct I/O helpers xfs: remove s_maxbytes enforcement in xfs_file_read_iter xfs: kill ioflags xfs: don't pass ioflags around in the ioctl path xfs: track and serialize in-flight async buffers against unmount xfs: exclude never-released buffers from buftarg I/O accounting xfs: don't reset b_retries to 0 on every failure xfs: remove extraneous buffer flag changes ...
2 parents 0e06f5c + f2bdfda commit 0e6acf0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+2026
-1440
lines changed

fs/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ config DCACHE_WORD_ACCESS
1010

1111
if BLOCK
1212

13+
config FS_IOMAP
14+
bool
15+
1316
source "fs/ext2/Kconfig"
1417
source "fs/ext4/Kconfig"
1518
source "fs/jbd2/Kconfig"

fs/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ obj-$(CONFIG_COREDUMP) += coredump.o
4949
obj-$(CONFIG_SYSCTL) += drop_caches.o
5050

5151
obj-$(CONFIG_FHANDLE) += fhandle.o
52+
obj-$(CONFIG_FS_IOMAP) += iomap.o
5253

5354
obj-y += quota/
5455

fs/buffer.c

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <linux/kernel.h>
2222
#include <linux/syscalls.h>
2323
#include <linux/fs.h>
24+
#include <linux/iomap.h>
2425
#include <linux/mm.h>
2526
#include <linux/percpu.h>
2627
#include <linux/slab.h>
@@ -1892,8 +1893,62 @@ void page_zero_new_buffers(struct page *page, unsigned from, unsigned to)
18921893
}
18931894
EXPORT_SYMBOL(page_zero_new_buffers);
18941895

1895-
int __block_write_begin(struct page *page, loff_t pos, unsigned len,
1896-
get_block_t *get_block)
1896+
static void
1897+
iomap_to_bh(struct inode *inode, sector_t block, struct buffer_head *bh,
1898+
struct iomap *iomap)
1899+
{
1900+
loff_t offset = block << inode->i_blkbits;
1901+
1902+
bh->b_bdev = iomap->bdev;
1903+
1904+
/*
1905+
* Block points to offset in file we need to map, iomap contains
1906+
* the offset at which the map starts. If the map ends before the
1907+
* current block, then do not map the buffer and let the caller
1908+
* handle it.
1909+
*/
1910+
BUG_ON(offset >= iomap->offset + iomap->length);
1911+
1912+
switch (iomap->type) {
1913+
case IOMAP_HOLE:
1914+
/*
1915+
* If the buffer is not up to date or beyond the current EOF,
1916+
* we need to mark it as new to ensure sub-block zeroing is
1917+
* executed if necessary.
1918+
*/
1919+
if (!buffer_uptodate(bh) ||
1920+
(offset >= i_size_read(inode)))
1921+
set_buffer_new(bh);
1922+
break;
1923+
case IOMAP_DELALLOC:
1924+
if (!buffer_uptodate(bh) ||
1925+
(offset >= i_size_read(inode)))
1926+
set_buffer_new(bh);
1927+
set_buffer_uptodate(bh);
1928+
set_buffer_mapped(bh);
1929+
set_buffer_delay(bh);
1930+
break;
1931+
case IOMAP_UNWRITTEN:
1932+
/*
1933+
* For unwritten regions, we always need to ensure that
1934+
* sub-block writes cause the regions in the block we are not
1935+
* writing to are zeroed. Set the buffer as new to ensure this.
1936+
*/
1937+
set_buffer_new(bh);
1938+
set_buffer_unwritten(bh);
1939+
/* FALLTHRU */
1940+
case IOMAP_MAPPED:
1941+
if (offset >= i_size_read(inode))
1942+
set_buffer_new(bh);
1943+
bh->b_blocknr = (iomap->blkno >> (inode->i_blkbits - 9)) +
1944+
((offset - iomap->offset) >> inode->i_blkbits);
1945+
set_buffer_mapped(bh);
1946+
break;
1947+
}
1948+
}
1949+
1950+
int __block_write_begin_int(struct page *page, loff_t pos, unsigned len,
1951+
get_block_t *get_block, struct iomap *iomap)
18971952
{
18981953
unsigned from = pos & (PAGE_SIZE - 1);
18991954
unsigned to = from + len;
@@ -1929,9 +1984,14 @@ int __block_write_begin(struct page *page, loff_t pos, unsigned len,
19291984
clear_buffer_new(bh);
19301985
if (!buffer_mapped(bh)) {
19311986
WARN_ON(bh->b_size != blocksize);
1932-
err = get_block(inode, block, bh, 1);
1933-
if (err)
1934-
break;
1987+
if (get_block) {
1988+
err = get_block(inode, block, bh, 1);
1989+
if (err)
1990+
break;
1991+
} else {
1992+
iomap_to_bh(inode, block, bh, iomap);
1993+
}
1994+
19351995
if (buffer_new(bh)) {
19361996
unmap_underlying_metadata(bh->b_bdev,
19371997
bh->b_blocknr);
@@ -1972,6 +2032,12 @@ int __block_write_begin(struct page *page, loff_t pos, unsigned len,
19722032
page_zero_new_buffers(page, from, to);
19732033
return err;
19742034
}
2035+
2036+
int __block_write_begin(struct page *page, loff_t pos, unsigned len,
2037+
get_block_t *get_block)
2038+
{
2039+
return __block_write_begin_int(page, pos, len, get_block, NULL);
2040+
}
19752041
EXPORT_SYMBOL(__block_write_begin);
19762042

19772043
static int __block_commit_write(struct inode *inode, struct page *page,

fs/internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
struct super_block;
1313
struct file_system_type;
14+
struct iomap;
1415
struct linux_binprm;
1516
struct path;
1617
struct mount;
@@ -39,6 +40,8 @@ static inline int __sync_blockdev(struct block_device *bdev, int wait)
3940
* buffer.c
4041
*/
4142
extern void guard_bio_eod(int rw, struct bio *bio);
43+
extern int __block_write_begin_int(struct page *page, loff_t pos, unsigned len,
44+
get_block_t *get_block, struct iomap *iomap);
4245

4346
/*
4447
* char_dev.c

0 commit comments

Comments
 (0)