Skip to content

Commit

Permalink
Merge branch 'work.write.end'
Browse files Browse the repository at this point in the history
Matthew Wilcox (Oracle) <willy@infradead.org> says:

On top of the ufs, minix, sysv and qnx6 directory handling patches, this
patch series converts us to using folios for write_begin and write_end.
That's the last mention of 'struct page' in several filesystems.

* work.write.end: (54 commits)
  buffer: Convert __block_write_begin() to take a folio
  ocfs2: Convert ocfs2_write_zero_page to use a folio
  fs: Convert aops->write_begin to take a folio
  fs: Convert aops->write_end to take a folio
  vboxsf: Use a folio in vboxsf_write_end()
  orangefs: Convert orangefs_write_begin() to use a folio
  orangefs: Convert orangefs_write_end() to use a folio
  jffs2: Convert jffs2_write_begin() to use a folio
  jffs2: Convert jffs2_write_end() to use a folio
  hostfs: Convert hostfs_write_end() to use a folio
  fuse: Convert fuse_write_begin() to use a folio
  fuse: Convert fuse_write_end() to use a folio
  f2fs: Convert f2fs_write_begin() to use a folio
  f2fs: Convert f2fs_write_end() to use a folio
  ecryptfs: Use a folio in ecryptfs_write_begin()
  ecryptfs: Convert ecryptfs_write_end() to use a folio
  buffer: Convert block_write_end() to take a folio
  ntfs3: Remove reset_log_file()
  nilfs2: Use a folio in nilfs_recover_dsync_blocks()
  buffer: Use a folio in generic_write_end()
  ...

Link: https://lore.kernel.org/r/20240717154716.237943-1-willy@infradead.org
Signed-off-by: Christian Brauner <brauner@kernel.org>
  • Loading branch information
Christian Brauner committed Aug 7, 2024
2 parents 8400291 + 9f04609 commit 3e673d6
Show file tree
Hide file tree
Showing 78 changed files with 892 additions and 997 deletions.
6 changes: 3 additions & 3 deletions Documentation/filesystems/locking.rst
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,10 @@ prototypes::
void (*readahead)(struct readahead_control *);
int (*write_begin)(struct file *, struct address_space *mapping,
loff_t pos, unsigned len,
struct page **pagep, void **fsdata);
struct folio **foliop, void **fsdata);
int (*write_end)(struct file *, struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied,
struct page *page, void *fsdata);
struct folio *folio, void *fsdata);
sector_t (*bmap)(struct address_space *, sector_t);
void (*invalidate_folio) (struct folio *, size_t start, size_t len);
bool (*release_folio)(struct folio *, gfp_t);
Expand All @@ -280,7 +280,7 @@ read_folio: yes, unlocks shared
writepages:
dirty_folio: maybe
readahead: yes, unlocks shared
write_begin: locks the page exclusive
write_begin: locks the folio exclusive
write_end: yes, unlocks exclusive
bmap:
invalidate_folio: yes exclusive
Expand Down
12 changes: 6 additions & 6 deletions Documentation/filesystems/vfs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,7 @@ cache in your filesystem. The following members are defined:
struct page **pagep, void **fsdata);
int (*write_end)(struct file *, struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied,
struct page *page, void *fsdata);
struct folio *folio, void *fsdata);
sector_t (*bmap)(struct address_space *, sector_t);
void (*invalidate_folio) (struct folio *, size_t start, size_t len);
bool (*release_folio)(struct folio *, gfp_t);
Expand Down Expand Up @@ -926,12 +926,12 @@ cache in your filesystem. The following members are defined:
(if they haven't been read already) so that the updated blocks
can be written out properly.

The filesystem must return the locked pagecache page for the
specified offset, in ``*pagep``, for the caller to write into.
The filesystem must return the locked pagecache folio for the
specified offset, in ``*foliop``, for the caller to write into.

It must be able to cope with short writes (where the length
passed to write_begin is greater than the number of bytes copied
into the page).
into the folio).

A void * may be returned in fsdata, which then gets passed into
write_end.
Expand All @@ -944,8 +944,8 @@ cache in your filesystem. The following members are defined:
called. len is the original len passed to write_begin, and
copied is the amount that was able to be copied.

The filesystem must take care of unlocking the page and
releasing it refcount, and updating i_size.
The filesystem must take care of unlocking the folio,
decrementing its refcount, and updating i_size.

Returns < 0 on failure, otherwise the number of bytes (<=
'copied') that were able to be copied into pagecache.
Expand Down
12 changes: 6 additions & 6 deletions block/fops.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,20 +451,20 @@ static void blkdev_readahead(struct readahead_control *rac)
}

static int blkdev_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, struct page **pagep, void **fsdata)
loff_t pos, unsigned len, struct folio **foliop, void **fsdata)
{
return block_write_begin(mapping, pos, len, pagep, blkdev_get_block);
return block_write_begin(mapping, pos, len, foliop, blkdev_get_block);
}

static int blkdev_write_end(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied, struct page *page,
loff_t pos, unsigned len, unsigned copied, struct folio *folio,
void *fsdata)
{
int ret;
ret = block_write_end(file, mapping, pos, len, copied, page, fsdata);
ret = block_write_end(file, mapping, pos, len, copied, folio, fsdata);

unlock_page(page);
put_page(page);
folio_unlock(folio);
folio_put(folio);

return ret;
}
Expand Down
47 changes: 22 additions & 25 deletions drivers/gpu/drm/i915/gem/i915_gem_shmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,8 @@ shmem_pwrite(struct drm_i915_gem_object *obj,
struct address_space *mapping = obj->base.filp->f_mapping;
const struct address_space_operations *aops = mapping->a_ops;
char __user *user_data = u64_to_user_ptr(arg->data_ptr);
u64 remain, offset;
u64 remain;
loff_t pos;
unsigned int pg;

/* Caller already validated user args */
Expand Down Expand Up @@ -457,12 +458,12 @@ shmem_pwrite(struct drm_i915_gem_object *obj,
*/

remain = arg->size;
offset = arg->offset;
pg = offset_in_page(offset);
pos = arg->offset;
pg = offset_in_page(pos);

do {
unsigned int len, unwritten;
struct page *page;
struct folio *folio;
void *data, *vaddr;
int err;
char __maybe_unused c;
Expand All @@ -480,21 +481,19 @@ shmem_pwrite(struct drm_i915_gem_object *obj,
if (err)
return err;

err = aops->write_begin(obj->base.filp, mapping, offset, len,
&page, &data);
err = aops->write_begin(obj->base.filp, mapping, pos, len,
&folio, &data);
if (err < 0)
return err;

vaddr = kmap_local_page(page);
vaddr = kmap_local_folio(folio, offset_in_folio(folio, pos));
pagefault_disable();
unwritten = __copy_from_user_inatomic(vaddr + pg,
user_data,
len);
unwritten = __copy_from_user_inatomic(vaddr, user_data, len);
pagefault_enable();
kunmap_local(vaddr);

err = aops->write_end(obj->base.filp, mapping, offset, len,
len - unwritten, page, data);
err = aops->write_end(obj->base.filp, mapping, pos, len,
len - unwritten, folio, data);
if (err < 0)
return err;

Expand All @@ -504,7 +503,7 @@ shmem_pwrite(struct drm_i915_gem_object *obj,

remain -= len;
user_data += len;
offset += len;
pos += len;
pg = 0;
} while (remain);

Expand Down Expand Up @@ -660,7 +659,7 @@ i915_gem_object_create_shmem_from_data(struct drm_i915_private *i915,
struct drm_i915_gem_object *obj;
struct file *file;
const struct address_space_operations *aops;
resource_size_t offset;
loff_t pos;
int err;

GEM_WARN_ON(IS_DGFX(i915));
Expand All @@ -672,29 +671,27 @@ i915_gem_object_create_shmem_from_data(struct drm_i915_private *i915,

file = obj->base.filp;
aops = file->f_mapping->a_ops;
offset = 0;
pos = 0;
do {
unsigned int len = min_t(typeof(size), size, PAGE_SIZE);
struct page *page;
void *pgdata, *vaddr;
struct folio *folio;
void *fsdata;

err = aops->write_begin(file, file->f_mapping, offset, len,
&page, &pgdata);
err = aops->write_begin(file, file->f_mapping, pos, len,
&folio, &fsdata);
if (err < 0)
goto fail;

vaddr = kmap(page);
memcpy(vaddr, data, len);
kunmap(page);
memcpy_to_folio(folio, offset_in_folio(folio, pos), data, len);

err = aops->write_end(file, file->f_mapping, offset, len, len,
page, pgdata);
err = aops->write_end(file, file->f_mapping, pos, len, len,
folio, fsdata);
if (err < 0)
goto fail;

size -= len;
data += len;
offset += len;
pos += len;
} while (size);

return obj;
Expand Down
5 changes: 2 additions & 3 deletions fs/adfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,11 @@ static void adfs_write_failed(struct address_space *mapping, loff_t to)

static int adfs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len,
struct page **pagep, void **fsdata)
struct folio **foliop, void **fsdata)
{
int ret;

*pagep = NULL;
ret = cont_write_begin(file, mapping, pos, len, pagep, fsdata,
ret = cont_write_begin(file, mapping, pos, len, foliop, fsdata,
adfs_get_block,
&ADFS_I(mapping->host)->mmu_private);
if (unlikely(ret))
Expand Down
22 changes: 10 additions & 12 deletions fs/affs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -417,12 +417,11 @@ affs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)

static int affs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len,
struct page **pagep, void **fsdata)
struct folio **foliop, void **fsdata)
{
int ret;

*pagep = NULL;
ret = cont_write_begin(file, mapping, pos, len, pagep, fsdata,
ret = cont_write_begin(file, mapping, pos, len, foliop, fsdata,
affs_get_block,
&AFFS_I(mapping->host)->mmu_private);
if (unlikely(ret))
Expand All @@ -433,12 +432,12 @@ static int affs_write_begin(struct file *file, struct address_space *mapping,

static int affs_write_end(struct file *file, struct address_space *mapping,
loff_t pos, unsigned int len, unsigned int copied,
struct page *page, void *fsdata)
struct folio *folio, void *fsdata)
{
struct inode *inode = mapping->host;
int ret;

ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata);
ret = generic_write_end(file, mapping, pos, len, copied, folio, fsdata);

/* Clear Archived bit on file writes, as AmigaOS would do */
if (AFFS_I(inode)->i_protect & FIBF_ARCHIVED) {
Expand Down Expand Up @@ -648,7 +647,7 @@ static int affs_read_folio_ofs(struct file *file, struct folio *folio)

static int affs_write_begin_ofs(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len,
struct page **pagep, void **fsdata)
struct folio **foliop, void **fsdata)
{
struct inode *inode = mapping->host;
struct folio *folio;
Expand All @@ -671,7 +670,7 @@ static int affs_write_begin_ofs(struct file *file, struct address_space *mapping
mapping_gfp_mask(mapping));
if (IS_ERR(folio))
return PTR_ERR(folio);
*pagep = &folio->page;
*foliop = folio;

if (folio_test_uptodate(folio))
return 0;
Expand All @@ -687,9 +686,8 @@ static int affs_write_begin_ofs(struct file *file, struct address_space *mapping

static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied,
struct page *page, void *fsdata)
struct folio *folio, void *fsdata)
{
struct folio *folio = page_folio(page);
struct inode *inode = mapping->host;
struct super_block *sb = inode->i_sb;
struct buffer_head *bh, *prev_bh;
Expand Down Expand Up @@ -882,14 +880,14 @@ affs_truncate(struct inode *inode)

if (inode->i_size > AFFS_I(inode)->mmu_private) {
struct address_space *mapping = inode->i_mapping;
struct page *page;
struct folio *folio;
void *fsdata = NULL;
loff_t isize = inode->i_size;
int res;

res = mapping->a_ops->write_begin(NULL, mapping, isize, 0, &page, &fsdata);
res = mapping->a_ops->write_begin(NULL, mapping, isize, 0, &folio, &fsdata);
if (!res)
res = mapping->a_ops->write_end(NULL, mapping, isize, 0, 0, page, fsdata);
res = mapping->a_ops->write_end(NULL, mapping, isize, 0, 0, folio, fsdata);
else
inode->i_size = AFFS_I(inode)->mmu_private;
mark_inode_dirty(inode);
Expand Down
8 changes: 3 additions & 5 deletions fs/bcachefs/fs-io-buffered.c
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,7 @@ int bch2_writepages(struct address_space *mapping, struct writeback_control *wbc

int bch2_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len,
struct page **pagep, void **fsdata)
struct folio **foliop, void **fsdata)
{
struct bch_inode_info *inode = to_bch_ei(mapping->host);
struct bch_fs *c = inode->v.i_sb->s_fs_info;
Expand Down Expand Up @@ -728,12 +728,11 @@ int bch2_write_begin(struct file *file, struct address_space *mapping,
goto err;
}

*pagep = &folio->page;
*foliop = folio;
return 0;
err:
folio_unlock(folio);
folio_put(folio);
*pagep = NULL;
err_unlock:
bch2_pagecache_add_put(inode);
kfree(res);
Expand All @@ -743,12 +742,11 @@ int bch2_write_begin(struct file *file, struct address_space *mapping,

int bch2_write_end(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied,
struct page *page, void *fsdata)
struct folio *folio, void *fsdata)
{
struct bch_inode_info *inode = to_bch_ei(mapping->host);
struct bch_fs *c = inode->v.i_sb->s_fs_info;
struct bch2_folio_reservation *res = fsdata;
struct folio *folio = page_folio(page);
unsigned offset = pos - folio_pos(folio);

lockdep_assert_held(&inode->v.i_rwsem);
Expand Down
6 changes: 3 additions & 3 deletions fs/bcachefs/fs-io-buffered.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ int bch2_read_folio(struct file *, struct folio *);
int bch2_writepages(struct address_space *, struct writeback_control *);
void bch2_readahead(struct readahead_control *);

int bch2_write_begin(struct file *, struct address_space *, loff_t,
unsigned, struct page **, void **);
int bch2_write_begin(struct file *, struct address_space *, loff_t pos,
unsigned len, struct folio **, void **);
int bch2_write_end(struct file *, struct address_space *, loff_t,
unsigned, unsigned, struct page *, void *);
unsigned len, unsigned copied, struct folio *, void *);

ssize_t bch2_write_iter(struct kiocb *, struct iov_iter *);

Expand Down
4 changes: 2 additions & 2 deletions fs/bfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,11 @@ static void bfs_write_failed(struct address_space *mapping, loff_t to)

static int bfs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len,
struct page **pagep, void **fsdata)
struct folio **foliop, void **fsdata)
{
int ret;

ret = block_write_begin(mapping, pos, len, pagep, bfs_get_block);
ret = block_write_begin(mapping, pos, len, foliop, bfs_get_block);
if (unlikely(ret))
bfs_write_failed(mapping, pos + len);

Expand Down
Loading

0 comments on commit 3e673d6

Please sign in to comment.