Skip to content

Commit

Permalink
Merge tag 'vfs-6.12.folio' of gitolite.kernel.org:pub/scm/linux/kerne…
Browse files Browse the repository at this point in the history
…l/git/vfs/vfs

Pull vfs folio updates from Christian Brauner:
 "This contains work to port write_begin and write_end to rely on folios
  for various filesystems.

  This converts ocfs2, vboxfs, orangefs, jffs2, hostfs, fuse, f2fs,
  ecryptfs, ntfs3, nilfs2, reiserfs, minixfs, qnx6, sysv, ufs, and
  squashfs.

  After this series lands a bunch of the filesystems in this list do not
  mention struct page anymore"

* tag 'vfs-6.12.folio' of gitolite.kernel.org:pub/scm/linux/kernel/git/vfs/vfs: (61 commits)
  Squashfs: Ensure all readahead pages have been used
  Squashfs: Rewrite and update squashfs_readahead_fragment() to not use page->index
  Squashfs: Update squashfs_readpage_block() to not use page->index
  Squashfs: Update squashfs_readahead() to not use page->index
  Squashfs: Update page_actor to not use page->index
  jffs2: Use a folio in jffs2_garbage_collect_dnode()
  jffs2: Convert jffs2_do_readpage_nolock to take a folio
  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
  ...
  • Loading branch information
Linus Torvalds committed Sep 16, 2024
2 parents 8f72c31 + 84e0e03 commit 2775df6
Show file tree
Hide file tree
Showing 83 changed files with 994 additions and 1,064 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 2775df6

Please sign in to comment.