Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'vfs-6.13-rc1.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull vfs fixes from Christian Brauner:

- Fix a few iomap bugs

- Fix a wrong argument in backing file callback

- Fix security mount option retrieval in statmount()

- Cleanup how statmount() handles unescaped options

- Add a missing inode_owner_or_capable() check for setting write hints

- Clear the return value in read_kcore_iter() after a successful
iov_iter_zero()

- Fix a mount_setattr() selftest

- Fix function signature in mount api documentation

- Remove duplicate include header in the fscache code

* tag 'vfs-6.13-rc1.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
fs/backing_file: fix wrong argument in callback
fs_parser: update mount_api doc to match function signature
fs: require inode_owner_or_capable for F_SET_RW_HINT
fs/proc/kcore.c: Clear ret value in read_kcore_iter after successful iov_iter_zero
statmount: fix security option retrieval
statmount: clean up unescaped option handling
fscache: Remove duplicate included header
iomap: elide flush from partial eof zero range
iomap: lift zeroed mapping handling into iomap_zero_range()
iomap: reset per-iter state on non-error iter advances
iomap: warn on zero range of a post-eof folio
selftests/mount_setattr: Fix failures on 64K PAGE_SIZE kernels

+81 -79
+2 -1
Documentation/filesystems/mount_api.rst
··· 770 770 771 771 * :: 772 772 773 - bool fs_validate_description(const struct fs_parameter_description *desc); 773 + bool fs_validate_description(const char *name, 774 + const struct fs_parameter_description *desc); 774 775 775 776 This performs some validation checks on a parameter description. It 776 777 returns true if the description is good and false if it is not. It will
+2 -1
fs/backing-file.c
··· 327 327 struct backing_file_ctx *ctx) 328 328 { 329 329 const struct cred *old_cred; 330 + struct file *user_file = vma->vm_file; 330 331 int ret; 331 332 332 333 if (WARN_ON_ONCE(!(file->f_mode & FMODE_BACKING))) ··· 343 342 revert_creds_light(old_cred); 344 343 345 344 if (ctx->accessed) 346 - ctx->accessed(vma->vm_file); 345 + ctx->accessed(user_file); 347 346 348 347 return ret; 349 348 }
+3
fs/fcntl.c
··· 374 374 u64 __user *argp = (u64 __user *)arg; 375 375 u64 hint; 376 376 377 + if (!inode_owner_or_capable(file_mnt_idmap(file), inode)) 378 + return -EPERM; 379 + 377 380 if (copy_from_user(&hint, argp, sizeof(hint))) 378 381 return -EFAULT; 379 382 if (!rw_hint_valid(hint))
+47 -43
fs/iomap/buffered-io.c
··· 1350 1350 return filemap_write_and_wait_range(mapping, i->pos, end); 1351 1351 } 1352 1352 1353 - static loff_t iomap_zero_iter(struct iomap_iter *iter, bool *did_zero, 1354 - bool *range_dirty) 1353 + static loff_t iomap_zero_iter(struct iomap_iter *iter, bool *did_zero) 1355 1354 { 1356 - const struct iomap *srcmap = iomap_iter_srcmap(iter); 1357 1355 loff_t pos = iter->pos; 1358 1356 loff_t length = iomap_length(iter); 1359 1357 loff_t written = 0; 1360 - 1361 - /* 1362 - * We must zero subranges of unwritten mappings that might be dirty in 1363 - * pagecache from previous writes. We only know whether the entire range 1364 - * was clean or not, however, and dirty folios may have been written 1365 - * back or reclaimed at any point after mapping lookup. 1366 - * 1367 - * The easiest way to deal with this is to flush pagecache to trigger 1368 - * any pending unwritten conversions and then grab the updated extents 1369 - * from the fs. The flush may change the current mapping, so mark it 1370 - * stale for the iterator to remap it for the next pass to handle 1371 - * properly. 1372 - * 1373 - * Note that holes are treated the same as unwritten because zero range 1374 - * is (ab)used for partial folio zeroing in some cases. Hole backed 1375 - * post-eof ranges can be dirtied via mapped write and the flush 1376 - * triggers writeback time post-eof zeroing. 1377 - */ 1378 - if (srcmap->type == IOMAP_HOLE || srcmap->type == IOMAP_UNWRITTEN) { 1379 - if (*range_dirty) { 1380 - *range_dirty = false; 1381 - return iomap_zero_iter_flush_and_stale(iter); 1382 - } 1383 - /* range is clean and already zeroed, nothing to do */ 1384 - return length; 1385 - } 1386 1358 1387 1359 do { 1388 1360 struct folio *folio; ··· 1369 1397 if (iter->iomap.flags & IOMAP_F_STALE) 1370 1398 break; 1371 1399 1400 + /* warn about zeroing folios beyond eof that won't write back */ 1401 + WARN_ON_ONCE(folio_pos(folio) > iter->inode->i_size); 1372 1402 offset = offset_in_folio(folio, pos); 1373 1403 if (bytes > folio_size(folio) - offset) 1374 1404 bytes = folio_size(folio) - offset; ··· 1403 1429 .len = len, 1404 1430 .flags = IOMAP_ZERO, 1405 1431 }; 1432 + struct address_space *mapping = inode->i_mapping; 1433 + unsigned int blocksize = i_blocksize(inode); 1434 + unsigned int off = pos & (blocksize - 1); 1435 + loff_t plen = min_t(loff_t, len, blocksize - off); 1406 1436 int ret; 1407 1437 bool range_dirty; 1408 1438 1409 1439 /* 1410 - * Zero range wants to skip pre-zeroed (i.e. unwritten) mappings, but 1411 - * pagecache must be flushed to ensure stale data from previous 1412 - * buffered writes is not exposed. A flush is only required for certain 1413 - * types of mappings, but checking pagecache after mapping lookup is 1414 - * racy with writeback and reclaim. 1440 + * Zero range can skip mappings that are zero on disk so long as 1441 + * pagecache is clean. If pagecache was dirty prior to zero range, the 1442 + * mapping converts on writeback completion and so must be zeroed. 1415 1443 * 1416 - * Therefore, check the entire range first and pass along whether any 1417 - * part of it is dirty. If so and an underlying mapping warrants it, 1418 - * flush the cache at that point. This trades off the occasional false 1419 - * positive (and spurious flush, if the dirty data and mapping don't 1420 - * happen to overlap) for simplicity in handling a relatively uncommon 1421 - * situation. 1444 + * The simplest way to deal with this across a range is to flush 1445 + * pagecache and process the updated mappings. To avoid excessive 1446 + * flushing on partial eof zeroing, special case it to zero the 1447 + * unaligned start portion if already dirty in pagecache. 1448 + */ 1449 + if (off && 1450 + filemap_range_needs_writeback(mapping, pos, pos + plen - 1)) { 1451 + iter.len = plen; 1452 + while ((ret = iomap_iter(&iter, ops)) > 0) 1453 + iter.processed = iomap_zero_iter(&iter, did_zero); 1454 + 1455 + iter.len = len - (iter.pos - pos); 1456 + if (ret || !iter.len) 1457 + return ret; 1458 + } 1459 + 1460 + /* 1461 + * To avoid an unconditional flush, check pagecache state and only flush 1462 + * if dirty and the fs returns a mapping that might convert on 1463 + * writeback. 1422 1464 */ 1423 1465 range_dirty = filemap_range_needs_writeback(inode->i_mapping, 1424 - pos, pos + len - 1); 1466 + iter.pos, iter.pos + iter.len - 1); 1467 + while ((ret = iomap_iter(&iter, ops)) > 0) { 1468 + const struct iomap *srcmap = iomap_iter_srcmap(&iter); 1425 1469 1426 - while ((ret = iomap_iter(&iter, ops)) > 0) 1427 - iter.processed = iomap_zero_iter(&iter, did_zero, &range_dirty); 1470 + if (srcmap->type == IOMAP_HOLE || 1471 + srcmap->type == IOMAP_UNWRITTEN) { 1472 + loff_t proc = iomap_length(&iter); 1473 + 1474 + if (range_dirty) { 1475 + range_dirty = false; 1476 + proc = iomap_zero_iter_flush_and_stale(&iter); 1477 + } 1478 + iter.processed = proc; 1479 + continue; 1480 + } 1481 + 1482 + iter.processed = iomap_zero_iter(&iter, did_zero); 1483 + } 1428 1484 return ret; 1429 1485 } 1430 1486 EXPORT_SYMBOL_GPL(iomap_zero_range);
+5 -6
fs/iomap/iter.c
··· 22 22 static inline int iomap_iter_advance(struct iomap_iter *iter) 23 23 { 24 24 bool stale = iter->iomap.flags & IOMAP_F_STALE; 25 + int ret = 1; 25 26 26 27 /* handle the previous iteration (if any) */ 27 28 if (iter->iomap.length) { 28 29 if (iter->processed < 0) 29 30 return iter->processed; 30 - if (!iter->processed && !stale) 31 - return 0; 32 31 if (WARN_ON_ONCE(iter->processed > iomap_length(iter))) 33 32 return -EIO; 34 33 iter->pos += iter->processed; 35 34 iter->len -= iter->processed; 36 - if (!iter->len) 37 - return 0; 35 + if (!iter->len || (!iter->processed && !stale)) 36 + ret = 0; 38 37 } 39 38 40 - /* clear the state for the next iteration */ 39 + /* clear the per iteration state */ 41 40 iter->processed = 0; 42 41 memset(&iter->iomap, 0, sizeof(iter->iomap)); 43 42 memset(&iter->srcmap, 0, sizeof(iter->srcmap)); 44 - return 1; 43 + return ret; 45 44 } 46 45 47 46 static inline void iomap_iter_done(struct iomap_iter *iter)
+20 -26
fs/namespace.c
··· 5057 5057 return 0; 5058 5058 } 5059 5059 5060 - static inline int statmount_opt_unescape(struct seq_file *seq, char *buf_start) 5060 + static inline int statmount_opt_process(struct seq_file *seq, size_t start) 5061 5061 { 5062 - char *buf_end, *opt_start, *opt_end; 5062 + char *buf_end, *opt_end, *src, *dst; 5063 5063 int count = 0; 5064 5064 5065 + if (unlikely(seq_has_overflowed(seq))) 5066 + return -EAGAIN; 5067 + 5065 5068 buf_end = seq->buf + seq->count; 5069 + dst = seq->buf + start; 5070 + src = dst + 1; /* skip initial comma */ 5071 + 5072 + if (src >= buf_end) { 5073 + seq->count = start; 5074 + return 0; 5075 + } 5076 + 5066 5077 *buf_end = '\0'; 5067 - for (opt_start = buf_start + 1; opt_start < buf_end; opt_start = opt_end + 1) { 5068 - opt_end = strchrnul(opt_start, ','); 5078 + for (; src < buf_end; src = opt_end + 1) { 5079 + opt_end = strchrnul(src, ','); 5069 5080 *opt_end = '\0'; 5070 - buf_start += string_unescape(opt_start, buf_start, 0, UNESCAPE_OCTAL) + 1; 5081 + dst += string_unescape(src, dst, 0, UNESCAPE_OCTAL) + 1; 5071 5082 if (WARN_ON_ONCE(++count == INT_MAX)) 5072 5083 return -EOVERFLOW; 5073 5084 } 5074 - seq->count = buf_start - 1 - seq->buf; 5085 + seq->count = dst - 1 - seq->buf; 5075 5086 return count; 5076 5087 } 5077 5088 ··· 5091 5080 struct vfsmount *mnt = s->mnt; 5092 5081 struct super_block *sb = mnt->mnt_sb; 5093 5082 size_t start = seq->count; 5094 - char *buf_start; 5095 5083 int err; 5096 5084 5097 5085 if (!sb->s_op->show_options) 5098 5086 return 0; 5099 5087 5100 - buf_start = seq->buf + start; 5101 5088 err = sb->s_op->show_options(seq, mnt->mnt_root); 5102 5089 if (err) 5103 5090 return err; 5104 5091 5105 - if (unlikely(seq_has_overflowed(seq))) 5106 - return -EAGAIN; 5107 - 5108 - if (seq->count == start) 5109 - return 0; 5110 - 5111 - err = statmount_opt_unescape(seq, buf_start); 5092 + err = statmount_opt_process(seq, start); 5112 5093 if (err < 0) 5113 5094 return err; 5114 5095 ··· 5113 5110 struct vfsmount *mnt = s->mnt; 5114 5111 struct super_block *sb = mnt->mnt_sb; 5115 5112 size_t start = seq->count; 5116 - char *buf_start; 5117 5113 int err; 5118 5114 5119 - buf_start = seq->buf + start; 5120 - 5121 5115 err = security_sb_show_options(seq, sb); 5122 - if (!err) 5116 + if (err) 5123 5117 return err; 5124 5118 5125 - if (unlikely(seq_has_overflowed(seq))) 5126 - return -EAGAIN; 5127 - 5128 - if (seq->count == start) 5129 - return 0; 5130 - 5131 - err = statmount_opt_unescape(seq, buf_start); 5119 + err = statmount_opt_process(seq, start); 5132 5120 if (err < 0) 5133 5121 return err; 5134 5122
-1
fs/netfs/fscache_io.c
··· 9 9 #include <linux/uio.h> 10 10 #include <linux/bvec.h> 11 11 #include <linux/slab.h> 12 - #include <linux/uio.h> 13 12 #include "internal.h" 14 13 15 14 /**
+1
fs/proc/kcore.c
··· 600 600 ret = -EFAULT; 601 601 goto out; 602 602 } 603 + ret = 0; 603 604 /* 604 605 * We know the bounce buffer is safe to copy from, so 605 606 * use _copy_to_iter() directly.
+1 -1
tools/testing/selftests/mount_setattr/mount_setattr_test.c
··· 1026 1026 "size=100000,mode=700"), 0); 1027 1027 1028 1028 ASSERT_EQ(mount("testing", "/mnt", "tmpfs", MS_NOATIME | MS_NODEV, 1029 - "size=100000,mode=700"), 0); 1029 + "size=2m,mode=700"), 0); 1030 1030 1031 1031 ASSERT_EQ(mkdir("/mnt/A", 0777), 0); 1032 1032