From: Joseph Qi <joseph.qi@linux.alibaba.com> To: Gao Xiang <hsiangkao@linux.alibaba.com>, linux-erofs@lists.ozlabs.org, linux-fsdevel@vger.kernel.org Cc: LKML <linux-kernel@vger.kernel.org>, Christoph Hellwig <hch@lst.de>, "Darrick J . Wong" <djwong@kernel.org>, Matthew Wilcox <willy@infradead.org>, Andreas Gruenbacher <andreas.gruenbacher@gmail.com>, Huang Jianan <huangjianan@oppo.com> Subject: Re: [PATCH v7] iomap: make inline data support more flexible Date: Mon, 26 Jul 2021 16:08:21 +0800 [thread overview] Message-ID: <5a377153-85c0-4514-11f2-e8b0707e5acf@linux.alibaba.com> (raw) In-Reply-To: <20210723174131.180813-1-hsiangkao@linux.alibaba.com> On 7/24/21 1:41 AM, Gao Xiang wrote: > Add support for reading inline data content into the page cache from > nonzero page-aligned file offsets. This enables the EROFS tailpacking > mode where the last few bytes of the file are stored right after the > inode. > > The buffered write path remains untouched since EROFS cannot be used > for testing. It'd be better to be implemented if upcoming real users > care and provide a real pattern rather than leave untested dead code > around. > > Cc: Christoph Hellwig <hch@lst.de> > Cc: Darrick J. Wong <djwong@kernel.org> > Cc: Matthew Wilcox <willy@infradead.org> > Cc: Andreas Gruenbacher <andreas.gruenbacher@gmail.com> > Tested-by: Huang Jianan <huangjianan@oppo.com> # erofs > Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com> Looks good to me. Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com> > --- > v6: https://lore.kernel.org/r/20210722031729.51628-1-hsiangkao@linux.alibaba.com > changes since v6: > - based on Christoph's reply; > - update commit message suggested by Darrick; > - disable buffered write path until some real fs users. > > fs/iomap/buffered-io.c | 42 ++++++++++++++++++++++++++---------------- > fs/iomap/direct-io.c | 10 ++++++---- > include/linux/iomap.h | 14 ++++++++++++++ > 3 files changed, 46 insertions(+), 20 deletions(-) > > diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c > index 87ccb3438bec..f351e1f9e3f6 100644 > --- a/fs/iomap/buffered-io.c > +++ b/fs/iomap/buffered-io.c > @@ -205,25 +205,29 @@ struct iomap_readpage_ctx { > struct readahead_control *rac; > }; > > -static void > -iomap_read_inline_data(struct inode *inode, struct page *page, > - struct iomap *iomap) > +static int iomap_read_inline_data(struct inode *inode, struct page *page, > + struct iomap *iomap, loff_t pos) > { > - size_t size = i_size_read(inode); > + size_t size = iomap->length + iomap->offset - pos; > void *addr; > > if (PageUptodate(page)) > - return; > + return PAGE_SIZE; > > - BUG_ON(page_has_private(page)); > - BUG_ON(page->index); > - BUG_ON(size > PAGE_SIZE - offset_in_page(iomap->inline_data)); > + /* inline data must start page aligned in the file */ > + if (WARN_ON_ONCE(offset_in_page(pos))) > + return -EIO; > + if (WARN_ON_ONCE(!iomap_inline_data_size_valid(iomap))) > + return -EIO; > + if (WARN_ON_ONCE(page_has_private(page))) > + return -EIO; > > addr = kmap_atomic(page); > - memcpy(addr, iomap->inline_data, size); > + memcpy(addr, iomap_inline_buf(iomap, pos), size); > memset(addr + size, 0, PAGE_SIZE - size); > kunmap_atomic(addr); > SetPageUptodate(page); > + return PAGE_SIZE; > } > > static inline bool iomap_block_needs_zeroing(struct inode *inode, > @@ -246,11 +250,8 @@ iomap_readpage_actor(struct inode *inode, loff_t pos, loff_t length, void *data, > unsigned poff, plen; > sector_t sector; > > - if (iomap->type == IOMAP_INLINE) { > - WARN_ON_ONCE(pos); > - iomap_read_inline_data(inode, page, iomap); > - return PAGE_SIZE; > - } > + if (iomap->type == IOMAP_INLINE) > + return iomap_read_inline_data(inode, page, iomap, pos); > > /* zero post-eof blocks as the page may be mapped */ > iop = iomap_page_create(inode, page); > @@ -589,6 +590,15 @@ __iomap_write_begin(struct inode *inode, loff_t pos, unsigned len, int flags, > return 0; > } > > +static int iomap_write_begin_inline(struct inode *inode, > + struct page *page, struct iomap *srcmap) > +{ > + /* needs more work for the tailpacking case, disable for now */ > + if (WARN_ON_ONCE(srcmap->offset != 0)) > + return -EIO; > + return iomap_read_inline_data(inode, page, srcmap, 0); > +} > + > static int > iomap_write_begin(struct inode *inode, loff_t pos, unsigned len, unsigned flags, > struct page **pagep, struct iomap *iomap, struct iomap *srcmap) > @@ -618,14 +628,14 @@ iomap_write_begin(struct inode *inode, loff_t pos, unsigned len, unsigned flags, > } > > if (srcmap->type == IOMAP_INLINE) > - iomap_read_inline_data(inode, page, srcmap); > + status = iomap_write_begin_inline(inode, page, srcmap); > else if (iomap->flags & IOMAP_F_BUFFER_HEAD) > status = __block_write_begin_int(page, pos, len, NULL, srcmap); > else > status = __iomap_write_begin(inode, pos, len, flags, page, > srcmap); > > - if (unlikely(status)) > + if (unlikely(status < 0)) > goto out_unlock; > > *pagep = page; > diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c > index 9398b8c31323..a6aaea2764a5 100644 > --- a/fs/iomap/direct-io.c > +++ b/fs/iomap/direct-io.c > @@ -378,23 +378,25 @@ iomap_dio_inline_actor(struct inode *inode, loff_t pos, loff_t length, > struct iomap_dio *dio, struct iomap *iomap) > { > struct iov_iter *iter = dio->submit.iter; > + void *dst = iomap_inline_buf(iomap, pos); > size_t copied; > > - BUG_ON(pos + length > PAGE_SIZE - offset_in_page(iomap->inline_data)); > + if (WARN_ON_ONCE(!iomap_inline_data_size_valid(iomap))) > + return -EIO; > > if (dio->flags & IOMAP_DIO_WRITE) { > loff_t size = inode->i_size; > > if (pos > size) > - memset(iomap->inline_data + size, 0, pos - size); > - copied = copy_from_iter(iomap->inline_data + pos, length, iter); > + memset(iomap_inline_buf(iomap, size), 0, pos - size); > + copied = copy_from_iter(dst, length, iter); > if (copied) { > if (pos + copied > size) > i_size_write(inode, pos + copied); > mark_inode_dirty(inode); > } > } else { > - copied = copy_to_iter(iomap->inline_data + pos, length, iter); > + copied = copy_to_iter(dst, length, iter); > } > dio->size += copied; > return copied; > diff --git a/include/linux/iomap.h b/include/linux/iomap.h > index 479c1da3e221..56b118c6d05c 100644 > --- a/include/linux/iomap.h > +++ b/include/linux/iomap.h > @@ -97,6 +97,20 @@ iomap_sector(struct iomap *iomap, loff_t pos) > return (iomap->addr + pos - iomap->offset) >> SECTOR_SHIFT; > } > > +static inline void *iomap_inline_buf(const struct iomap *iomap, loff_t pos) > +{ > + return iomap->inline_data - iomap->offset + pos; > +} > + > +/* > + * iomap->inline_data is a potentially kmapped page, ensure it never crosses a > + * page boundary. > + */ > +static inline bool iomap_inline_data_size_valid(const struct iomap *iomap) > +{ > + return iomap->length <= PAGE_SIZE - offset_in_page(iomap->inline_data); > +} > + > /* > * When a filesystem sets page_ops in an iomap mapping it returns, page_prepare > * and page_done will be called for each page written to. This only applies to >
WARNING: multiple messages have this Message-ID (diff)
From: Joseph Qi <joseph.qi@linux.alibaba.com> To: Gao Xiang <hsiangkao@linux.alibaba.com>, linux-erofs@lists.ozlabs.org, linux-fsdevel@vger.kernel.org Cc: "Darrick J . Wong" <djwong@kernel.org>, Andreas Gruenbacher <andreas.gruenbacher@gmail.com>, LKML <linux-kernel@vger.kernel.org>, Matthew Wilcox <willy@infradead.org>, Christoph Hellwig <hch@lst.de> Subject: Re: [PATCH v7] iomap: make inline data support more flexible Date: Mon, 26 Jul 2021 16:08:21 +0800 [thread overview] Message-ID: <5a377153-85c0-4514-11f2-e8b0707e5acf@linux.alibaba.com> (raw) In-Reply-To: <20210723174131.180813-1-hsiangkao@linux.alibaba.com> On 7/24/21 1:41 AM, Gao Xiang wrote: > Add support for reading inline data content into the page cache from > nonzero page-aligned file offsets. This enables the EROFS tailpacking > mode where the last few bytes of the file are stored right after the > inode. > > The buffered write path remains untouched since EROFS cannot be used > for testing. It'd be better to be implemented if upcoming real users > care and provide a real pattern rather than leave untested dead code > around. > > Cc: Christoph Hellwig <hch@lst.de> > Cc: Darrick J. Wong <djwong@kernel.org> > Cc: Matthew Wilcox <willy@infradead.org> > Cc: Andreas Gruenbacher <andreas.gruenbacher@gmail.com> > Tested-by: Huang Jianan <huangjianan@oppo.com> # erofs > Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com> Looks good to me. Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com> > --- > v6: https://lore.kernel.org/r/20210722031729.51628-1-hsiangkao@linux.alibaba.com > changes since v6: > - based on Christoph's reply; > - update commit message suggested by Darrick; > - disable buffered write path until some real fs users. > > fs/iomap/buffered-io.c | 42 ++++++++++++++++++++++++++---------------- > fs/iomap/direct-io.c | 10 ++++++---- > include/linux/iomap.h | 14 ++++++++++++++ > 3 files changed, 46 insertions(+), 20 deletions(-) > > diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c > index 87ccb3438bec..f351e1f9e3f6 100644 > --- a/fs/iomap/buffered-io.c > +++ b/fs/iomap/buffered-io.c > @@ -205,25 +205,29 @@ struct iomap_readpage_ctx { > struct readahead_control *rac; > }; > > -static void > -iomap_read_inline_data(struct inode *inode, struct page *page, > - struct iomap *iomap) > +static int iomap_read_inline_data(struct inode *inode, struct page *page, > + struct iomap *iomap, loff_t pos) > { > - size_t size = i_size_read(inode); > + size_t size = iomap->length + iomap->offset - pos; > void *addr; > > if (PageUptodate(page)) > - return; > + return PAGE_SIZE; > > - BUG_ON(page_has_private(page)); > - BUG_ON(page->index); > - BUG_ON(size > PAGE_SIZE - offset_in_page(iomap->inline_data)); > + /* inline data must start page aligned in the file */ > + if (WARN_ON_ONCE(offset_in_page(pos))) > + return -EIO; > + if (WARN_ON_ONCE(!iomap_inline_data_size_valid(iomap))) > + return -EIO; > + if (WARN_ON_ONCE(page_has_private(page))) > + return -EIO; > > addr = kmap_atomic(page); > - memcpy(addr, iomap->inline_data, size); > + memcpy(addr, iomap_inline_buf(iomap, pos), size); > memset(addr + size, 0, PAGE_SIZE - size); > kunmap_atomic(addr); > SetPageUptodate(page); > + return PAGE_SIZE; > } > > static inline bool iomap_block_needs_zeroing(struct inode *inode, > @@ -246,11 +250,8 @@ iomap_readpage_actor(struct inode *inode, loff_t pos, loff_t length, void *data, > unsigned poff, plen; > sector_t sector; > > - if (iomap->type == IOMAP_INLINE) { > - WARN_ON_ONCE(pos); > - iomap_read_inline_data(inode, page, iomap); > - return PAGE_SIZE; > - } > + if (iomap->type == IOMAP_INLINE) > + return iomap_read_inline_data(inode, page, iomap, pos); > > /* zero post-eof blocks as the page may be mapped */ > iop = iomap_page_create(inode, page); > @@ -589,6 +590,15 @@ __iomap_write_begin(struct inode *inode, loff_t pos, unsigned len, int flags, > return 0; > } > > +static int iomap_write_begin_inline(struct inode *inode, > + struct page *page, struct iomap *srcmap) > +{ > + /* needs more work for the tailpacking case, disable for now */ > + if (WARN_ON_ONCE(srcmap->offset != 0)) > + return -EIO; > + return iomap_read_inline_data(inode, page, srcmap, 0); > +} > + > static int > iomap_write_begin(struct inode *inode, loff_t pos, unsigned len, unsigned flags, > struct page **pagep, struct iomap *iomap, struct iomap *srcmap) > @@ -618,14 +628,14 @@ iomap_write_begin(struct inode *inode, loff_t pos, unsigned len, unsigned flags, > } > > if (srcmap->type == IOMAP_INLINE) > - iomap_read_inline_data(inode, page, srcmap); > + status = iomap_write_begin_inline(inode, page, srcmap); > else if (iomap->flags & IOMAP_F_BUFFER_HEAD) > status = __block_write_begin_int(page, pos, len, NULL, srcmap); > else > status = __iomap_write_begin(inode, pos, len, flags, page, > srcmap); > > - if (unlikely(status)) > + if (unlikely(status < 0)) > goto out_unlock; > > *pagep = page; > diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c > index 9398b8c31323..a6aaea2764a5 100644 > --- a/fs/iomap/direct-io.c > +++ b/fs/iomap/direct-io.c > @@ -378,23 +378,25 @@ iomap_dio_inline_actor(struct inode *inode, loff_t pos, loff_t length, > struct iomap_dio *dio, struct iomap *iomap) > { > struct iov_iter *iter = dio->submit.iter; > + void *dst = iomap_inline_buf(iomap, pos); > size_t copied; > > - BUG_ON(pos + length > PAGE_SIZE - offset_in_page(iomap->inline_data)); > + if (WARN_ON_ONCE(!iomap_inline_data_size_valid(iomap))) > + return -EIO; > > if (dio->flags & IOMAP_DIO_WRITE) { > loff_t size = inode->i_size; > > if (pos > size) > - memset(iomap->inline_data + size, 0, pos - size); > - copied = copy_from_iter(iomap->inline_data + pos, length, iter); > + memset(iomap_inline_buf(iomap, size), 0, pos - size); > + copied = copy_from_iter(dst, length, iter); > if (copied) { > if (pos + copied > size) > i_size_write(inode, pos + copied); > mark_inode_dirty(inode); > } > } else { > - copied = copy_to_iter(iomap->inline_data + pos, length, iter); > + copied = copy_to_iter(dst, length, iter); > } > dio->size += copied; > return copied; > diff --git a/include/linux/iomap.h b/include/linux/iomap.h > index 479c1da3e221..56b118c6d05c 100644 > --- a/include/linux/iomap.h > +++ b/include/linux/iomap.h > @@ -97,6 +97,20 @@ iomap_sector(struct iomap *iomap, loff_t pos) > return (iomap->addr + pos - iomap->offset) >> SECTOR_SHIFT; > } > > +static inline void *iomap_inline_buf(const struct iomap *iomap, loff_t pos) > +{ > + return iomap->inline_data - iomap->offset + pos; > +} > + > +/* > + * iomap->inline_data is a potentially kmapped page, ensure it never crosses a > + * page boundary. > + */ > +static inline bool iomap_inline_data_size_valid(const struct iomap *iomap) > +{ > + return iomap->length <= PAGE_SIZE - offset_in_page(iomap->inline_data); > +} > + > /* > * When a filesystem sets page_ops in an iomap mapping it returns, page_prepare > * and page_done will be called for each page written to. This only applies to >
next prev parent reply other threads:[~2021-07-26 8:09 UTC|newest] Thread overview: 59+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-07-23 17:41 [PATCH v7] iomap: make inline data support more flexible Gao Xiang 2021-07-23 17:41 ` Gao Xiang 2021-07-23 19:40 ` Matthew Wilcox 2021-07-23 19:40 ` Matthew Wilcox 2021-07-24 0:54 ` Gao Xiang 2021-07-24 0:54 ` Gao Xiang 2021-07-25 21:39 ` Andreas Grünbacher 2021-07-25 21:39 ` Andreas Grünbacher 2021-07-25 22:16 ` Andreas Gruenbacher 2021-07-25 22:16 ` Andreas Gruenbacher 2021-07-26 2:36 ` Gao Xiang 2021-07-26 2:36 ` Gao Xiang 2021-07-26 7:22 ` Andreas Gruenbacher 2021-07-26 7:22 ` Andreas Gruenbacher 2021-07-26 7:38 ` Gao Xiang 2021-07-26 7:38 ` Gao Xiang 2021-07-26 21:36 ` Darrick J. Wong 2021-07-26 21:36 ` Darrick J. Wong 2021-07-26 22:20 ` Andreas Grünbacher 2021-07-26 22:20 ` Andreas Grünbacher 2021-07-26 3:06 ` Matthew Wilcox 2021-07-26 3:06 ` Matthew Wilcox 2021-07-26 6:56 ` Andreas Gruenbacher 2021-07-26 6:56 ` Andreas Gruenbacher 2021-07-26 4:00 ` Gao Xiang 2021-07-26 4:00 ` Gao Xiang 2021-07-26 8:08 ` Andreas Grünbacher 2021-07-26 8:08 ` Andreas Grünbacher 2021-07-26 8:17 ` Gao Xiang 2021-07-26 8:17 ` Gao Xiang 2021-07-26 11:06 ` Andreas Gruenbacher 2021-07-26 11:06 ` Andreas Gruenbacher 2021-07-26 12:17 ` Christoph Hellwig 2021-07-26 12:17 ` Christoph Hellwig 2021-07-26 12:27 ` Andreas Grünbacher 2021-07-26 12:27 ` Andreas Grünbacher 2021-07-26 12:50 ` Gao Xiang 2021-07-26 12:50 ` Gao Xiang 2021-07-26 13:10 ` Andreas Gruenbacher 2021-07-26 13:27 ` Christoph Hellwig 2021-07-26 13:27 ` Christoph Hellwig 2021-07-27 8:20 ` David Sterba 2021-07-27 8:20 ` David Sterba 2021-07-27 13:35 ` Matthew Wilcox 2021-07-27 15:04 ` Gao Xiang 2021-07-27 15:04 ` Gao Xiang 2021-07-27 16:53 ` David Sterba 2021-07-27 16:53 ` David Sterba 2021-07-26 12:32 ` Matthew Wilcox 2021-07-26 12:32 ` Matthew Wilcox 2021-07-26 13:03 ` Andreas Gruenbacher 2021-07-26 13:03 ` Andreas Gruenbacher 2021-07-26 13:12 ` Gao Xiang 2021-07-26 13:12 ` Gao Xiang 2021-07-26 13:30 ` Christoph Hellwig 2021-07-26 8:08 ` Joseph Qi [this message] 2021-07-26 8:08 ` Joseph Qi 2021-08-01 10:29 Andreas Gruenbacher 2021-08-01 10:29 ` Andreas Gruenbacher
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=5a377153-85c0-4514-11f2-e8b0707e5acf@linux.alibaba.com \ --to=joseph.qi@linux.alibaba.com \ --cc=andreas.gruenbacher@gmail.com \ --cc=djwong@kernel.org \ --cc=hch@lst.de \ --cc=hsiangkao@linux.alibaba.com \ --cc=huangjianan@oppo.com \ --cc=linux-erofs@lists.ozlabs.org \ --cc=linux-fsdevel@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=willy@infradead.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.