Skip to content

Commit 7879d7a

Browse files
committed
Merge tag 'vfs-6.17-rc1.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull misc VFS updates from Christian Brauner: "This contains the usual selections of misc updates for this cycle. Features: - Add ext4 IOCB_DONTCACHE support This refactors the address_space_operations write_begin() and write_end() callbacks to take const struct kiocb * as their first argument, allowing IOCB flags such as IOCB_DONTCACHE to propagate to the filesystem's buffered I/O path. Ext4 is updated to implement handling of the IOCB_DONTCACHE flag and advertises support via the FOP_DONTCACHE file operation flag. Additionally, the i915 driver's shmem write paths are updated to bypass the legacy write_begin/write_end interface in favor of directly calling write_iter() with a constructed synchronous kiocb. Another i915 change replaces a manual write loop with kernel_write() during GEM shmem object creation. Cleanups: - don't duplicate vfs_open() in kernel_file_open() - proc_fd_getattr(): don't bother with S_ISDIR() check - fs/ecryptfs: replace snprintf with sysfs_emit in show function - vfs: Remove unnecessary list_for_each_entry_safe() from evict_inodes() - filelock: add new locks_wake_up_waiter() helper - fs: Remove three arguments from block_write_end() - VFS: change old_dir and new_dir in struct renamedata to dentrys - netfs: Remove unused declaration netfs_queue_write_request() Fixes: - eventpoll: Fix semi-unbounded recursion - eventpoll: fix sphinx documentation build warning - fs/read_write: Fix spelling typo - fs: annotate data race between poll_schedule_timeout() and pollwake() - fs/pipe: set FMODE_NOWAIT in create_pipe_files() - docs/vfs: update references to i_mutex to i_rwsem - fs/buffer: remove comment about hard sectorsize - fs/buffer: remove the min and max limit checks in __getblk_slow() - fs/libfs: don't assume blocksize <= PAGE_SIZE in generic_check_addressable - fs_context: fix parameter name in infofc() macro - fs: Prevent file descriptor table allocations exceeding INT_MAX" * tag 'vfs-6.17-rc1.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (24 commits) netfs: Remove unused declaration netfs_queue_write_request() eventpoll: fix sphinx documentation build warning ext4: support uncached buffered I/O mm/pagemap: add write_begin_get_folio() helper function fs: change write_begin/write_end interface to take struct kiocb * drm/i915: Refactor shmem_pwrite() to use kiocb and write_iter drm/i915: Use kernel_write() in shmem object create eventpoll: Fix semi-unbounded recursion vfs: Remove unnecessary list_for_each_entry_safe() from evict_inodes() fs/libfs: don't assume blocksize <= PAGE_SIZE in generic_check_addressable fs/buffer: remove the min and max limit checks in __getblk_slow() fs: Prevent file descriptor table allocations exceeding INT_MAX fs: Remove three arguments from block_write_end() fs/ecryptfs: replace snprintf with sysfs_emit in show function fs: annotate suspected data race between poll_schedule_timeout() and pollwake() docs/vfs: update references to i_mutex to i_rwsem fs/buffer: remove comment about hard sectorsize fs_context: fix parameter name in infofc() macro VFS: change old_dir and new_dir in struct renamedata to dentrys proc_fd_getattr(): don't bother with S_ISDIR() check ...
2 parents 794cbac + 4e8fc4f commit 7879d7a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+520
-457
lines changed

Documentation/filesystems/locking.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,10 +253,10 @@ prototypes::
253253
int (*writepages)(struct address_space *, struct writeback_control *);
254254
bool (*dirty_folio)(struct address_space *, struct folio *folio);
255255
void (*readahead)(struct readahead_control *);
256-
int (*write_begin)(struct file *, struct address_space *mapping,
256+
int (*write_begin)(const struct kiocb *, struct address_space *mapping,
257257
loff_t pos, unsigned len,
258258
struct folio **foliop, void **fsdata);
259-
int (*write_end)(struct file *, struct address_space *mapping,
259+
int (*write_end)(const struct kiocb *, struct address_space *mapping,
260260
loff_t pos, unsigned len, unsigned copied,
261261
struct folio *folio, void *fsdata);
262262
sector_t (*bmap)(struct address_space *, sector_t);

Documentation/filesystems/vfs.rst

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -758,8 +758,9 @@ process is more complicated and uses write_begin/write_end or
758758
dirty_folio to write data into the address_space, and
759759
writepages to writeback data to storage.
760760

761-
Adding and removing pages to/from an address_space is protected by the
762-
inode's i_mutex.
761+
Removing pages from an address_space requires holding the inode's i_rwsem
762+
exclusively, while adding pages to the address_space requires holding the
763+
inode's i_mapping->invalidate_lock exclusively.
763764

764765
When data is written to a page, the PG_Dirty flag should be set. It
765766
typically remains set until writepages asks for it to be written. This
@@ -822,10 +823,10 @@ cache in your filesystem. The following members are defined:
822823
int (*writepages)(struct address_space *, struct writeback_control *);
823824
bool (*dirty_folio)(struct address_space *, struct folio *);
824825
void (*readahead)(struct readahead_control *);
825-
int (*write_begin)(struct file *, struct address_space *mapping,
826+
int (*write_begin)(const struct kiocb *, struct address_space *mapping,
826827
loff_t pos, unsigned len,
827-
struct page **pagep, void **fsdata);
828-
int (*write_end)(struct file *, struct address_space *mapping,
828+
struct page **pagep, void **fsdata);
829+
int (*write_end)(const struct kiocb *, struct address_space *mapping,
829830
loff_t pos, unsigned len, unsigned copied,
830831
struct folio *folio, void *fsdata);
831832
sector_t (*bmap)(struct address_space *, sector_t);

block/fops.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -496,18 +496,21 @@ static void blkdev_readahead(struct readahead_control *rac)
496496
mpage_readahead(rac, blkdev_get_block);
497497
}
498498

499-
static int blkdev_write_begin(struct file *file, struct address_space *mapping,
500-
loff_t pos, unsigned len, struct folio **foliop, void **fsdata)
499+
static int blkdev_write_begin(const struct kiocb *iocb,
500+
struct address_space *mapping, loff_t pos,
501+
unsigned len, struct folio **foliop,
502+
void **fsdata)
501503
{
502504
return block_write_begin(mapping, pos, len, foliop, blkdev_get_block);
503505
}
504506

505-
static int blkdev_write_end(struct file *file, struct address_space *mapping,
506-
loff_t pos, unsigned len, unsigned copied, struct folio *folio,
507-
void *fsdata)
507+
static int blkdev_write_end(const struct kiocb *iocb,
508+
struct address_space *mapping,
509+
loff_t pos, unsigned len, unsigned copied,
510+
struct folio *folio, void *fsdata)
508511
{
509512
int ret;
510-
ret = block_write_end(file, mapping, pos, len, copied, folio, fsdata);
513+
ret = block_write_end(pos, len, copied, folio);
511514

512515
folio_unlock(folio);
513516
folio_put(folio);

drivers/gpu/drm/i915/gem/i915_gem_shmem.c

Lines changed: 31 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <linux/pagevec.h>
77
#include <linux/shmem_fs.h>
88
#include <linux/swap.h>
9+
#include <linux/uio.h>
910

1011
#include <drm/drm_cache.h>
1112

@@ -400,12 +401,12 @@ static int
400401
shmem_pwrite(struct drm_i915_gem_object *obj,
401402
const struct drm_i915_gem_pwrite *arg)
402403
{
403-
struct address_space *mapping = obj->base.filp->f_mapping;
404-
const struct address_space_operations *aops = mapping->a_ops;
405404
char __user *user_data = u64_to_user_ptr(arg->data_ptr);
406-
u64 remain;
407-
loff_t pos;
408-
unsigned int pg;
405+
struct file *file = obj->base.filp;
406+
struct kiocb kiocb;
407+
struct iov_iter iter;
408+
ssize_t written;
409+
u64 size = arg->size;
409410

410411
/* Caller already validated user args */
411412
GEM_BUG_ON(!access_ok(user_data, arg->size));
@@ -428,63 +429,24 @@ shmem_pwrite(struct drm_i915_gem_object *obj,
428429
if (obj->mm.madv != I915_MADV_WILLNEED)
429430
return -EFAULT;
430431

431-
/*
432-
* Before the pages are instantiated the object is treated as being
433-
* in the CPU domain. The pages will be clflushed as required before
434-
* use, and we can freely write into the pages directly. If userspace
435-
* races pwrite with any other operation; corruption will ensue -
436-
* that is userspace's prerogative!
437-
*/
432+
if (size > MAX_RW_COUNT)
433+
return -EFBIG;
438434

439-
remain = arg->size;
440-
pos = arg->offset;
441-
pg = offset_in_page(pos);
435+
if (!file->f_op->write_iter)
436+
return -EINVAL;
442437

443-
do {
444-
unsigned int len, unwritten;
445-
struct folio *folio;
446-
void *data, *vaddr;
447-
int err;
448-
char __maybe_unused c;
449-
450-
len = PAGE_SIZE - pg;
451-
if (len > remain)
452-
len = remain;
453-
454-
/* Prefault the user page to reduce potential recursion */
455-
err = __get_user(c, user_data);
456-
if (err)
457-
return err;
458-
459-
err = __get_user(c, user_data + len - 1);
460-
if (err)
461-
return err;
462-
463-
err = aops->write_begin(obj->base.filp, mapping, pos, len,
464-
&folio, &data);
465-
if (err < 0)
466-
return err;
467-
468-
vaddr = kmap_local_folio(folio, offset_in_folio(folio, pos));
469-
pagefault_disable();
470-
unwritten = __copy_from_user_inatomic(vaddr, user_data, len);
471-
pagefault_enable();
472-
kunmap_local(vaddr);
473-
474-
err = aops->write_end(obj->base.filp, mapping, pos, len,
475-
len - unwritten, folio, data);
476-
if (err < 0)
477-
return err;
478-
479-
/* We don't handle -EFAULT, leave it to the caller to check */
480-
if (unwritten)
481-
return -ENODEV;
482-
483-
remain -= len;
484-
user_data += len;
485-
pos += len;
486-
pg = 0;
487-
} while (remain);
438+
init_sync_kiocb(&kiocb, file);
439+
kiocb.ki_pos = arg->offset;
440+
iov_iter_ubuf(&iter, ITER_SOURCE, (void __user *)user_data, size);
441+
442+
written = file->f_op->write_iter(&kiocb, &iter);
443+
BUG_ON(written == -EIOCBQUEUED);
444+
445+
if (written != size)
446+
return -EIO;
447+
448+
if (written < 0)
449+
return written;
488450

489451
return 0;
490452
}
@@ -637,9 +599,8 @@ i915_gem_object_create_shmem_from_data(struct drm_i915_private *i915,
637599
{
638600
struct drm_i915_gem_object *obj;
639601
struct file *file;
640-
const struct address_space_operations *aops;
641-
loff_t pos;
642-
int err;
602+
loff_t pos = 0;
603+
ssize_t err;
643604

644605
GEM_WARN_ON(IS_DGFX(i915));
645606
obj = i915_gem_object_create_shmem(i915, round_up(size, PAGE_SIZE));
@@ -649,29 +610,15 @@ i915_gem_object_create_shmem_from_data(struct drm_i915_private *i915,
649610
GEM_BUG_ON(obj->write_domain != I915_GEM_DOMAIN_CPU);
650611

651612
file = obj->base.filp;
652-
aops = file->f_mapping->a_ops;
653-
pos = 0;
654-
do {
655-
unsigned int len = min_t(typeof(size), size, PAGE_SIZE);
656-
struct folio *folio;
657-
void *fsdata;
658-
659-
err = aops->write_begin(file, file->f_mapping, pos, len,
660-
&folio, &fsdata);
661-
if (err < 0)
662-
goto fail;
613+
err = kernel_write(file, data, size, &pos);
663614

664-
memcpy_to_folio(folio, offset_in_folio(folio, pos), data, len);
615+
if (err < 0)
616+
goto fail;
665617

666-
err = aops->write_end(file, file->f_mapping, pos, len, len,
667-
folio, fsdata);
668-
if (err < 0)
669-
goto fail;
670-
671-
size -= len;
672-
data += len;
673-
pos += len;
674-
} while (size);
618+
if (err != size) {
619+
err = -EIO;
620+
goto fail;
621+
}
675622

676623
return obj;
677624

fs/adfs/inode.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,14 @@ static void adfs_write_failed(struct address_space *mapping, loff_t to)
5353
truncate_pagecache(inode, inode->i_size);
5454
}
5555

56-
static int adfs_write_begin(struct file *file, struct address_space *mapping,
57-
loff_t pos, unsigned len,
58-
struct folio **foliop, void **fsdata)
56+
static int adfs_write_begin(const struct kiocb *iocb,
57+
struct address_space *mapping,
58+
loff_t pos, unsigned len,
59+
struct folio **foliop, void **fsdata)
5960
{
6061
int ret;
6162

62-
ret = cont_write_begin(file, mapping, pos, len, foliop, fsdata,
63+
ret = cont_write_begin(iocb, mapping, pos, len, foliop, fsdata,
6364
adfs_get_block,
6465
&ADFS_I(mapping->host)->mmu_private);
6566
if (unlikely(ret))

fs/affs/file.c

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -415,13 +415,14 @@ affs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
415415
return ret;
416416
}
417417

418-
static int affs_write_begin(struct file *file, struct address_space *mapping,
419-
loff_t pos, unsigned len,
420-
struct folio **foliop, void **fsdata)
418+
static int affs_write_begin(const struct kiocb *iocb,
419+
struct address_space *mapping,
420+
loff_t pos, unsigned len,
421+
struct folio **foliop, void **fsdata)
421422
{
422423
int ret;
423424

424-
ret = cont_write_begin(file, mapping, pos, len, foliop, fsdata,
425+
ret = cont_write_begin(iocb, mapping, pos, len, foliop, fsdata,
425426
affs_get_block,
426427
&AFFS_I(mapping->host)->mmu_private);
427428
if (unlikely(ret))
@@ -430,14 +431,15 @@ static int affs_write_begin(struct file *file, struct address_space *mapping,
430431
return ret;
431432
}
432433

433-
static int affs_write_end(struct file *file, struct address_space *mapping,
434-
loff_t pos, unsigned int len, unsigned int copied,
434+
static int affs_write_end(const struct kiocb *iocb,
435+
struct address_space *mapping, loff_t pos,
436+
unsigned int len, unsigned int copied,
435437
struct folio *folio, void *fsdata)
436438
{
437439
struct inode *inode = mapping->host;
438440
int ret;
439441

440-
ret = generic_write_end(file, mapping, pos, len, copied, folio, fsdata);
442+
ret = generic_write_end(iocb, mapping, pos, len, copied, folio, fsdata);
441443

442444
/* Clear Archived bit on file writes, as AmigaOS would do */
443445
if (AFFS_I(inode)->i_protect & FIBF_ARCHIVED) {
@@ -645,7 +647,8 @@ static int affs_read_folio_ofs(struct file *file, struct folio *folio)
645647
return err;
646648
}
647649

648-
static int affs_write_begin_ofs(struct file *file, struct address_space *mapping,
650+
static int affs_write_begin_ofs(const struct kiocb *iocb,
651+
struct address_space *mapping,
649652
loff_t pos, unsigned len,
650653
struct folio **foliop, void **fsdata)
651654
{
@@ -684,9 +687,10 @@ static int affs_write_begin_ofs(struct file *file, struct address_space *mapping
684687
return err;
685688
}
686689

687-
static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
688-
loff_t pos, unsigned len, unsigned copied,
689-
struct folio *folio, void *fsdata)
690+
static int affs_write_end_ofs(const struct kiocb *iocb,
691+
struct address_space *mapping,
692+
loff_t pos, unsigned len, unsigned copied,
693+
struct folio *folio, void *fsdata)
690694
{
691695
struct inode *inode = mapping->host;
692696
struct super_block *sb = inode->i_sb;

fs/attr.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ EXPORT_SYMBOL(setattr_prepare);
230230
* @inode: the inode to be truncated
231231
* @offset: the new size to assign to the inode
232232
*
233-
* inode_newsize_ok must be called with i_mutex held.
233+
* inode_newsize_ok must be called with i_rwsem held exclusively.
234234
*
235235
* inode_newsize_ok will check filesystem limits and ulimits to check that the
236236
* new inode size is within limits. inode_newsize_ok will also send SIGXFSZ
@@ -318,7 +318,7 @@ static void setattr_copy_mgtime(struct inode *inode, const struct iattr *attr)
318318
* @inode: the inode to be updated
319319
* @attr: the new attributes
320320
*
321-
* setattr_copy must be called with i_mutex held.
321+
* setattr_copy must be called with i_rwsem held exclusively.
322322
*
323323
* setattr_copy updates the inode's metadata with that specified
324324
* in attr on idmapped mounts. Necessary permission checks to determine
@@ -403,13 +403,13 @@ EXPORT_SYMBOL(may_setattr);
403403
* @attr: new attributes
404404
* @delegated_inode: returns inode, if the inode is delegated
405405
*
406-
* The caller must hold the i_mutex on the affected object.
406+
* The caller must hold the i_rwsem exclusively on the affected object.
407407
*
408408
* If notify_change discovers a delegation in need of breaking,
409409
* it will return -EWOULDBLOCK and return a reference to the inode in
410410
* delegated_inode. The caller should then break the delegation and
411411
* retry. Because breaking a delegation may take a long time, the
412-
* caller should drop the i_mutex before doing so.
412+
* caller should drop the i_rwsem before doing so.
413413
*
414414
* Alternatively, a caller may pass NULL for delegated_inode. This may
415415
* be appropriate for callers that expect the underlying filesystem not
@@ -456,7 +456,7 @@ int notify_change(struct mnt_idmap *idmap, struct dentry *dentry,
456456
if (S_ISLNK(inode->i_mode))
457457
return -EOPNOTSUPP;
458458

459-
/* Flag setting protected by i_mutex */
459+
/* Flag setting protected by i_rwsem */
460460
if (is_sxid(attr->ia_mode))
461461
inode->i_flags &= ~S_NOSEC;
462462
}

fs/bcachefs/fs-io-buffered.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,7 @@ int bch2_writepages(struct address_space *mapping, struct writeback_control *wbc
674674

675675
/* buffered writes: */
676676

677-
int bch2_write_begin(struct file *file, struct address_space *mapping,
677+
int bch2_write_begin(const struct kiocb *iocb, struct address_space *mapping,
678678
loff_t pos, unsigned len,
679679
struct folio **foliop, void **fsdata)
680680
{
@@ -757,7 +757,7 @@ int bch2_write_begin(struct file *file, struct address_space *mapping,
757757
return bch2_err_class(ret);
758758
}
759759

760-
int bch2_write_end(struct file *file, struct address_space *mapping,
760+
int bch2_write_end(const struct kiocb *iocb, struct address_space *mapping,
761761
loff_t pos, unsigned len, unsigned copied,
762762
struct folio *folio, void *fsdata)
763763
{

fs/bcachefs/fs-io-buffered.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ int bch2_read_folio(struct file *, struct folio *);
1010
int bch2_writepages(struct address_space *, struct writeback_control *);
1111
void bch2_readahead(struct readahead_control *);
1212

13-
int bch2_write_begin(struct file *, struct address_space *, loff_t pos,
13+
int bch2_write_begin(const struct kiocb *, struct address_space *, loff_t pos,
1414
unsigned len, struct folio **, void **);
15-
int bch2_write_end(struct file *, struct address_space *, loff_t,
15+
int bch2_write_end(const struct kiocb *, struct address_space *, loff_t,
1616
unsigned len, unsigned copied, struct folio *, void *);
1717

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

fs/bfs/file.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,10 @@ static void bfs_write_failed(struct address_space *mapping, loff_t to)
170170
truncate_pagecache(inode, inode->i_size);
171171
}
172172

173-
static int bfs_write_begin(struct file *file, struct address_space *mapping,
174-
loff_t pos, unsigned len,
175-
struct folio **foliop, void **fsdata)
173+
static int bfs_write_begin(const struct kiocb *iocb,
174+
struct address_space *mapping,
175+
loff_t pos, unsigned len,
176+
struct folio **foliop, void **fsdata)
176177
{
177178
int ret;
178179

0 commit comments

Comments
 (0)