diff options
author | Dan Williams <dan.j.williams@intel.com> | 2016-01-28 20:25:31 -0800 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2016-01-30 13:35:32 -0800 |
commit | d1a5f2b4d8a125943dcb6b032fc7eaefc2c78296 (patch) | |
tree | afdd4251d10cbcf34b00bd4f33adb27996881cc6 /fs/dax.c | |
parent | 9f4736fe7ca804aa79b5916221bb13dfc6221a0f (diff) | |
download | lwn-d1a5f2b4d8a125943dcb6b032fc7eaefc2c78296.tar.gz lwn-d1a5f2b4d8a125943dcb6b032fc7eaefc2c78296.zip |
block: use DAX for partition table reads
Avoid populating pagecache when the block device is in DAX mode.
Otherwise these page cache entries collide with the fsync/msync
implementation and break data durability guarantees.
Cc: Jan Kara <jack@suse.com>
Cc: Jeff Moyer <jmoyer@redhat.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Reported-by: Ross Zwisler <ross.zwisler@linux.intel.com>
Tested-by: Ross Zwisler <ross.zwisler@linux.intel.com>
Reviewed-by: Matthew Wilcox <willy@linux.intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'fs/dax.c')
-rw-r--r-- | fs/dax.c | 20 |
1 files changed, 20 insertions, 0 deletions
@@ -58,6 +58,26 @@ static void dax_unmap_atomic(struct block_device *bdev, blk_queue_exit(bdev->bd_queue); } +struct page *read_dax_sector(struct block_device *bdev, sector_t n) +{ + struct page *page = alloc_pages(GFP_KERNEL, 0); + struct blk_dax_ctl dax = { + .size = PAGE_SIZE, + .sector = n & ~((((int) PAGE_SIZE) / 512) - 1), + }; + long rc; + + if (!page) + return ERR_PTR(-ENOMEM); + + rc = dax_map_atomic(bdev, &dax); + if (rc < 0) + return ERR_PTR(rc); + memcpy_from_pmem(page_address(page), dax.addr, PAGE_SIZE); + dax_unmap_atomic(bdev, &dax); + return page; +} + /* * dax_clear_blocks() is called from within transaction context from XFS, * and hence this means the stack from this point must follow GFP_NOFS |