On Sun 23-03-14 15:08:44, Matthew Wilcox wrote: > This new function allows us to support hole-punch for XIP files by zeroing > a partial page, as opposed to the xip_truncate_page() function which can > only truncate to the end of the page. Reimplement xip_truncate_page() as > a macro that calls xip_zero_page_range(). > > Signed-off-by: Matthew Wilcox <matthew.r.wilcox@xxxxxxxxx> > [ported to 3.13-rc2] > Signed-off-by: Ross Zwisler <ross.zwisler@xxxxxxxxxxxxxxx> Two comments below... ... > diff --git a/fs/dax.c b/fs/dax.c > index 45a0a41..2d6b4bc 100644 > --- a/fs/dax.c > +++ b/fs/dax.c ... > @@ -491,11 +494,16 @@ int dax_truncate_page(struct inode *inode, loff_t from, get_block_t get_block) > if (buffer_written(&bh)) { > void *addr; > err = dax_get_addr(inode, &bh, &addr); > - if (err) > + if (err < 0) > return err; > + /* > + * ext4 sometimes asks to zero past the end of a block. It > + * really just wants to zero to the end of the block. > + */ Then we should really fix ext4 I believe... > + length = min_t(unsigned, length, PAGE_CACHE_SIZE - offset); > memset(addr + offset, 0, length); > } > > return 0; > } > -EXPORT_SYMBOL_GPL(dax_truncate_page); > +EXPORT_SYMBOL_GPL(dax_zero_page_range); > diff --git a/include/linux/fs.h b/include/linux/fs.h > index bff394d..d0381ab 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -2521,6 +2521,7 @@ extern int nonseekable_open(struct inode * inode, struct file * filp); > > #ifdef CONFIG_FS_DAX > int dax_clear_blocks(struct inode *, sector_t block, long size); > +int dax_zero_page_range(struct inode *, loff_t from, unsigned len, get_block_t); > int dax_truncate_page(struct inode *, loff_t from, get_block_t); > ssize_t dax_do_io(int rw, struct kiocb *, struct inode *, const struct iovec *, > loff_t, unsigned segs, get_block_t, dio_iodone_t, int flags); > @@ -2532,7 +2533,8 @@ static inline int dax_clear_blocks(struct inode *i, sector_t blk, long sz) > return 0; > } > > -static inline int dax_truncate_page(struct inode *i, loff_t frm, get_block_t gb) > +static inline int dax_zero_page_range(struct inode *inode, loff_t from, > + unsigned len, get_block_t gb) > { > return 0; > } > @@ -2545,6 +2547,11 @@ static inline ssize_t dax_do_io(int rw, struct kiocb *iocb, struct inode *inode, > } > #endif > > +/* Can't be a function because PAGE_CACHE_SIZE is defined in pagemap.h */ > +#define dax_truncate_page(inode, from, get_block) \ > + dax_zero_page_range(inode, from, PAGE_CACHE_SIZE, get_block) ^^^^ This should be (PAGE_CACHE_SIZE - (from & (PAGE_CACHE_SIZE - 1))), shouldn't it? > + > + > #ifdef CONFIG_BLOCK > typedef void (dio_submit_t)(int rw, struct bio *bio, struct inode *inode, Honza -- Jan Kara <jack@xxxxxxx> SUSE Labs, CR -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>