Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dax,ext2: replace xip_truncate_page with dax_truncate_page

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>

authored by

Matthew Wilcox and committed by
Linus Torvalds
4c0ccfef f7ca90b1

+46 -50
+44
fs/dax.c
··· 462 462 return result; 463 463 } 464 464 EXPORT_SYMBOL_GPL(dax_fault); 465 + 466 + /** 467 + * dax_truncate_page - handle a partial page being truncated in a DAX file 468 + * @inode: The file being truncated 469 + * @from: The file offset that is being truncated to 470 + * @get_block: The filesystem method used to translate file offsets to blocks 471 + * 472 + * Similar to block_truncate_page(), this function can be called by a 473 + * filesystem when it is truncating an DAX file to handle the partial page. 474 + * 475 + * We work in terms of PAGE_CACHE_SIZE here for commonality with 476 + * block_truncate_page(), but we could go down to PAGE_SIZE if the filesystem 477 + * took care of disposing of the unnecessary blocks. Even if the filesystem 478 + * block size is smaller than PAGE_SIZE, we have to zero the rest of the page 479 + * since the file might be mmaped. 480 + */ 481 + int dax_truncate_page(struct inode *inode, loff_t from, get_block_t get_block) 482 + { 483 + struct buffer_head bh; 484 + pgoff_t index = from >> PAGE_CACHE_SHIFT; 485 + unsigned offset = from & (PAGE_CACHE_SIZE-1); 486 + unsigned length = PAGE_CACHE_ALIGN(from) - from; 487 + int err; 488 + 489 + /* Block boundary? Nothing to do */ 490 + if (!length) 491 + return 0; 492 + 493 + memset(&bh, 0, sizeof(bh)); 494 + bh.b_size = PAGE_CACHE_SIZE; 495 + err = get_block(inode, index, &bh, 0); 496 + if (err < 0) 497 + return err; 498 + if (buffer_written(&bh)) { 499 + void *addr; 500 + err = dax_get_addr(&bh, &addr, inode->i_blkbits); 501 + if (err < 0) 502 + return err; 503 + memset(addr + offset, 0, length); 504 + } 505 + 506 + return 0; 507 + } 508 + EXPORT_SYMBOL_GPL(dax_truncate_page);
+1 -1
fs/ext2/inode.c
··· 1210 1210 inode_dio_wait(inode); 1211 1211 1212 1212 if (IS_DAX(inode)) 1213 - error = xip_truncate_page(inode->i_mapping, newsize); 1213 + error = dax_truncate_page(inode, newsize, ext2_get_block); 1214 1214 else if (test_opt(inode->i_sb, NOBH)) 1215 1215 error = nobh_truncate_page(inode->i_mapping, 1216 1216 newsize, ext2_get_block);
+1 -9
include/linux/fs.h
··· 2591 2591 ssize_t dax_do_io(int rw, struct kiocb *, struct inode *, struct iov_iter *, 2592 2592 loff_t, get_block_t, dio_iodone_t, int flags); 2593 2593 int dax_clear_blocks(struct inode *, sector_t block, long size); 2594 + int dax_truncate_page(struct inode *, loff_t from, get_block_t); 2594 2595 int dax_fault(struct vm_area_struct *, struct vm_fault *, get_block_t); 2595 2596 #define dax_mkwrite(vma, vmf, gb) dax_fault(vma, vmf, gb) 2596 - 2597 - #ifdef CONFIG_FS_XIP 2598 - extern int xip_truncate_page(struct address_space *mapping, loff_t from); 2599 - #else 2600 - static inline int xip_truncate_page(struct address_space *mapping, loff_t from) 2601 - { 2602 - return 0; 2603 - } 2604 - #endif 2605 2597 2606 2598 #ifdef CONFIG_BLOCK 2607 2599 typedef void (dio_submit_t)(int rw, struct bio *bio, struct inode *inode,
-40
mm/filemap_xip.c
··· 22 22 #include <asm/tlbflush.h> 23 23 #include <asm/io.h> 24 24 25 - /* 26 - * truncate a page used for execute in place 27 - * functionality is analog to block_truncate_page but does use get_xip_mem 28 - * to get the page instead of page cache 29 - */ 30 - int 31 - xip_truncate_page(struct address_space *mapping, loff_t from) 32 - { 33 - pgoff_t index = from >> PAGE_CACHE_SHIFT; 34 - unsigned offset = from & (PAGE_CACHE_SIZE-1); 35 - unsigned blocksize; 36 - unsigned length; 37 - void *xip_mem; 38 - unsigned long xip_pfn; 39 - int err; 40 - 41 - BUG_ON(!mapping->a_ops->get_xip_mem); 42 - 43 - blocksize = 1 << mapping->host->i_blkbits; 44 - length = offset & (blocksize - 1); 45 - 46 - /* Block boundary? Nothing to do */ 47 - if (!length) 48 - return 0; 49 - 50 - length = blocksize - length; 51 - 52 - err = mapping->a_ops->get_xip_mem(mapping, index, 0, 53 - &xip_mem, &xip_pfn); 54 - if (unlikely(err)) { 55 - if (err == -ENODATA) 56 - /* Hole? No need to truncate */ 57 - return 0; 58 - else 59 - return err; 60 - } 61 - memset(xip_mem + offset, 0, length); 62 - return 0; 63 - } 64 - EXPORT_SYMBOL_GPL(xip_truncate_page);