dax,ext2: replace xip_truncate_page with dax_truncate_page
authorMatthew Wilcox <matthew.r.wilcox@intel.com>
Mon, 16 Feb 2015 23:59:06 +0000 (15:59 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 17 Feb 2015 01:56:03 +0000 (17:56 -0800)
It takes a get_block parameter just like nobh_truncate_page() and
block_truncate_page()

Signed-off-by: Matthew Wilcox <matthew.r.wilcox@intel.com>
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andreas Dilger <andreas.dilger@intel.com>
Cc: Boaz Harrosh <boaz@plexistor.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Jan Kara <jack@suse.cz>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Ross Zwisler <ross.zwisler@linux.intel.com>
Cc: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/dax.c
fs/ext2/inode.c
include/linux/fs.h
mm/filemap_xip.c

index 553e55b93495d64e88ba49808c0ca10c0ac206f8..ebf9b2231b0f824738437ec95a04050ddbf8bff4 100644 (file)
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -462,3 +462,47 @@ int dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
        return result;
 }
 EXPORT_SYMBOL_GPL(dax_fault);
+
+/**
+ * dax_truncate_page - handle a partial page being truncated in a DAX file
+ * @inode: The file being truncated
+ * @from: The file offset that is being truncated to
+ * @get_block: The filesystem method used to translate file offsets to blocks
+ *
+ * Similar to block_truncate_page(), this function can be called by a
+ * filesystem when it is truncating an DAX file to handle the partial page.
+ *
+ * We work in terms of PAGE_CACHE_SIZE here for commonality with
+ * block_truncate_page(), but we could go down to PAGE_SIZE if the filesystem
+ * took care of disposing of the unnecessary blocks.  Even if the filesystem
+ * block size is smaller than PAGE_SIZE, we have to zero the rest of the page
+ * since the file might be mmaped.
+ */
+int dax_truncate_page(struct inode *inode, loff_t from, get_block_t get_block)
+{
+       struct buffer_head bh;
+       pgoff_t index = from >> PAGE_CACHE_SHIFT;
+       unsigned offset = from & (PAGE_CACHE_SIZE-1);
+       unsigned length = PAGE_CACHE_ALIGN(from) - from;
+       int err;
+
+       /* Block boundary? Nothing to do */
+       if (!length)
+               return 0;
+
+       memset(&bh, 0, sizeof(bh));
+       bh.b_size = PAGE_CACHE_SIZE;
+       err = get_block(inode, index, &bh, 0);
+       if (err < 0)
+               return err;
+       if (buffer_written(&bh)) {
+               void *addr;
+               err = dax_get_addr(&bh, &addr, inode->i_blkbits);
+               if (err < 0)
+                       return err;
+               memset(addr + offset, 0, length);
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(dax_truncate_page);
index 52978b853226e0b7393e18a6641b765e17241a89..5ac0a3461b3c6f74c9101aeb53ef3e9da1cbeb79 100644 (file)
@@ -1210,7 +1210,7 @@ static int ext2_setsize(struct inode *inode, loff_t newsize)
        inode_dio_wait(inode);
 
        if (IS_DAX(inode))
-               error = xip_truncate_page(inode->i_mapping, newsize);
+               error = dax_truncate_page(inode, newsize, ext2_get_block);
        else if (test_opt(inode->i_sb, NOBH))
                error = nobh_truncate_page(inode->i_mapping,
                                newsize, ext2_get_block);
index 6bad6d4c579b80f39f6407a2b68ee99815affee1..2c8f9055af3839e1e712b442b4aab2423b429be8 100644 (file)
@@ -2591,18 +2591,10 @@ extern int nonseekable_open(struct inode * inode, struct file * filp);
 ssize_t dax_do_io(int rw, struct kiocb *, struct inode *, struct iov_iter *,
                loff_t, get_block_t, dio_iodone_t, int flags);
 int dax_clear_blocks(struct inode *, sector_t block, long size);
+int dax_truncate_page(struct inode *, loff_t from, get_block_t);
 int dax_fault(struct vm_area_struct *, struct vm_fault *, get_block_t);
 #define dax_mkwrite(vma, vmf, gb)      dax_fault(vma, vmf, gb)
 
-#ifdef CONFIG_FS_XIP
-extern int xip_truncate_page(struct address_space *mapping, loff_t from);
-#else
-static inline int xip_truncate_page(struct address_space *mapping, loff_t from)
-{
-       return 0;
-}
-#endif
-
 #ifdef CONFIG_BLOCK
 typedef void (dio_submit_t)(int rw, struct bio *bio, struct inode *inode,
                            loff_t file_offset);
index 59fb387b223870bfc082809afab1cb5fb2039661..8e3f99b619599d40e01c75aad43d3c470d19a386 100644 (file)
 #include <asm/tlbflush.h>
 #include <asm/io.h>
 
-/*
- * truncate a page used for execute in place
- * functionality is analog to block_truncate_page but does use get_xip_mem
- * to get the page instead of page cache
- */
-int
-xip_truncate_page(struct address_space *mapping, loff_t from)
-{
-       pgoff_t index = from >> PAGE_CACHE_SHIFT;
-       unsigned offset = from & (PAGE_CACHE_SIZE-1);
-       unsigned blocksize;
-       unsigned length;
-       void *xip_mem;
-       unsigned long xip_pfn;
-       int err;
-
-       BUG_ON(!mapping->a_ops->get_xip_mem);
-
-       blocksize = 1 << mapping->host->i_blkbits;
-       length = offset & (blocksize - 1);
-
-       /* Block boundary? Nothing to do */
-       if (!length)
-               return 0;
-
-       length = blocksize - length;
-
-       err = mapping->a_ops->get_xip_mem(mapping, index, 0,
-                                               &xip_mem, &xip_pfn);
-       if (unlikely(err)) {
-               if (err == -ENODATA)
-                       /* Hole? No need to truncate */
-                       return 0;
-               else
-                       return err;
-       }
-       memset(xip_mem + offset, 0, length);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(xip_truncate_page);