Skip to content

Commit fbfd64d

Browse files
committed
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull vfs fixes from Christian Brauner: - Relax assertions on failure to encode file handles The ->encode_fh() method can fail for various reasons. None of them warrant a WARN_ON(). - Fix overlayfs file handle encoding by allowing encoding an fid from an inode without an alias - Make sure fuse_dir_open() handles FOPEN_KEEP_CACHE. If it's not specified fuse needs to invaludate the directory inode page cache - Fix qnx6 so it builds with gcc-15 - Various fixes for netfslib and ceph and nfs filesystems: - Ignore silly rename files from afs and nfs when building header archives - Fix read result collection in netfslib with multiple subrequests - Handle ENOMEM for netfslib buffered reads - Fix oops in nfs_netfs_init_request() - Parse the secctx command immediately in cachefiles - Remove a redundant smp_rmb() in netfslib - Handle recursion in read retry in netfslib - Fix clearing of folio_queue - Fix missing cancellation of copy-to_cache when the cache for a file is temporarly disabled in netfslib - Sanity check the hfs root record - Fix zero padding data issues in concurrent write scenarios - Fix is_mnt_ns_file() after converting nsfs to path_from_stashed() - Fix missing declaration of init_files - Increase I/O priority when writing revoke records in jbd2 - Flush filesystem device before updating tail sequence in jbd2 * tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (23 commits) ovl: support encoding fid from inode with no alias ovl: pass realinode to ovl_encode_real_fh() instead of realdentry fuse: respect FOPEN_KEEP_CACHE on opendir netfs: Fix is-caching check in read-retry netfs: Fix the (non-)cancellation of copy when cache is temporarily disabled netfs: Fix ceph copy to cache on write-begin netfs: Work around recursion by abandoning retry if nothing read netfs: Fix missing barriers by using clear_and_wake_up_bit() netfs: Remove redundant use of smp_rmb() cachefiles: Parse the "secctx" immediately nfs: Fix oops in nfs_netfs_init_request() when copying to cache netfs: Fix enomem handling in buffered reads netfs: Fix non-contiguous donation between completed reads kheaders: Ignore silly-rename files fs: relax assertions on failure to encode file handles fs: fix missing declaration of init_files fs: fix is_mnt_ns_file() iomap: fix zero padding data issue in concurrent append writes iomap: pass byte granular end position to iomap_add_to_ioend jbd2: flush filesystem device before updating tail sequence ...
2 parents 13563da + 368fcc5 commit fbfd64d

31 files changed

+217
-123
lines changed

fs/9p/vfs_addr.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ static void v9fs_issue_write(struct netfs_io_subrequest *subreq)
5757
int err, len;
5858

5959
len = p9_client_write(fid, subreq->start, &subreq->io_iter, &err);
60+
if (len > 0)
61+
__set_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags);
6062
netfs_write_subrequest_terminated(subreq, len ?: err, false);
6163
}
6264

@@ -80,8 +82,10 @@ static void v9fs_issue_read(struct netfs_io_subrequest *subreq)
8082
if (pos + total >= i_size_read(rreq->inode))
8183
__set_bit(NETFS_SREQ_HIT_EOF, &subreq->flags);
8284

83-
if (!err)
85+
if (!err) {
8486
subreq->transferred += total;
87+
__set_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags);
88+
}
8589

8690
netfs_read_subreq_terminated(subreq, err, false);
8791
}

fs/afs/write.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ static void afs_issue_write_worker(struct work_struct *work)
122122
if (subreq->debug_index == 3)
123123
return netfs_write_subrequest_terminated(subreq, -ENOANO, false);
124124

125-
if (!test_bit(NETFS_SREQ_RETRYING, &subreq->flags)) {
125+
if (!subreq->retry_count) {
126126
set_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags);
127127
return netfs_write_subrequest_terminated(subreq, -EAGAIN, false);
128128
}
@@ -149,6 +149,9 @@ static void afs_issue_write_worker(struct work_struct *work)
149149
afs_wait_for_operation(op);
150150
ret = afs_put_operation(op);
151151
switch (ret) {
152+
case 0:
153+
__set_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags);
154+
break;
152155
case -EACCES:
153156
case -EPERM:
154157
case -ENOKEY:

fs/cachefiles/daemon.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <linux/namei.h>
1616
#include <linux/poll.h>
1717
#include <linux/mount.h>
18+
#include <linux/security.h>
1819
#include <linux/statfs.h>
1920
#include <linux/ctype.h>
2021
#include <linux/string.h>
@@ -576,7 +577,7 @@ static int cachefiles_daemon_dir(struct cachefiles_cache *cache, char *args)
576577
*/
577578
static int cachefiles_daemon_secctx(struct cachefiles_cache *cache, char *args)
578579
{
579-
char *secctx;
580+
int err;
580581

581582
_enter(",%s", args);
582583

@@ -585,16 +586,16 @@ static int cachefiles_daemon_secctx(struct cachefiles_cache *cache, char *args)
585586
return -EINVAL;
586587
}
587588

588-
if (cache->secctx) {
589+
if (cache->have_secid) {
589590
pr_err("Second security context specified\n");
590591
return -EINVAL;
591592
}
592593

593-
secctx = kstrdup(args, GFP_KERNEL);
594-
if (!secctx)
595-
return -ENOMEM;
594+
err = security_secctx_to_secid(args, strlen(args), &cache->secid);
595+
if (err)
596+
return err;
596597

597-
cache->secctx = secctx;
598+
cache->have_secid = true;
598599
return 0;
599600
}
600601

@@ -820,7 +821,6 @@ static void cachefiles_daemon_unbind(struct cachefiles_cache *cache)
820821
put_cred(cache->cache_cred);
821822

822823
kfree(cache->rootdirname);
823-
kfree(cache->secctx);
824824
kfree(cache->tag);
825825

826826
_leave("");

fs/cachefiles/internal.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,15 @@ struct cachefiles_cache {
122122
#define CACHEFILES_STATE_CHANGED 3 /* T if state changed (poll trigger) */
123123
#define CACHEFILES_ONDEMAND_MODE 4 /* T if in on-demand read mode */
124124
char *rootdirname; /* name of cache root directory */
125-
char *secctx; /* LSM security context */
126125
char *tag; /* cache binding tag */
127126
refcount_t unbind_pincount;/* refcount to do daemon unbind */
128127
struct xarray reqs; /* xarray of pending on-demand requests */
129128
unsigned long req_id_next;
130129
struct xarray ondemand_ids; /* xarray for ondemand_id allocation */
131130
u32 ondemand_id_next;
132131
u32 msg_id_next;
132+
u32 secid; /* LSM security id */
133+
bool have_secid; /* whether "secid" was set */
133134
};
134135

135136
static inline bool cachefiles_in_ondemand_mode(struct cachefiles_cache *cache)

fs/cachefiles/security.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@ int cachefiles_get_security_ID(struct cachefiles_cache *cache)
1818
struct cred *new;
1919
int ret;
2020

21-
_enter("{%s}", cache->secctx);
21+
_enter("{%u}", cache->have_secid ? cache->secid : 0);
2222

2323
new = prepare_kernel_cred(current);
2424
if (!new) {
2525
ret = -ENOMEM;
2626
goto error;
2727
}
2828

29-
if (cache->secctx) {
30-
ret = set_security_override_from_ctx(new, cache->secctx);
29+
if (cache->have_secid) {
30+
ret = set_security_override(new, cache->secid);
3131
if (ret < 0) {
3232
put_cred(new);
3333
pr_err("Security denies permission to nominate security context: error %d\n",

fs/file.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/close_range.h>
2323
#include <linux/file_ref.h>
2424
#include <net/sock.h>
25+
#include <linux/init_task.h>
2526

2627
#include "internal.h"
2728

fs/fuse/dir.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1681,6 +1681,8 @@ static int fuse_dir_open(struct inode *inode, struct file *file)
16811681
*/
16821682
if (ff->open_flags & (FOPEN_STREAM | FOPEN_NONSEEKABLE))
16831683
nonseekable_open(inode, file);
1684+
if (!(ff->open_flags & FOPEN_KEEP_CACHE))
1685+
invalidate_inode_pages2(inode->i_mapping);
16841686
}
16851687

16861688
return err;

fs/hfs/super.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,11 +349,13 @@ static int hfs_fill_super(struct super_block *sb, struct fs_context *fc)
349349
goto bail_no_root;
350350
res = hfs_cat_find_brec(sb, HFS_ROOT_CNID, &fd);
351351
if (!res) {
352-
if (fd.entrylength > sizeof(rec) || fd.entrylength < 0) {
352+
if (fd.entrylength != sizeof(rec.dir)) {
353353
res = -EIO;
354354
goto bail_hfs_find;
355355
}
356356
hfs_bnode_read(fd.bnode, &rec, fd.entryoffset, fd.entrylength);
357+
if (rec.type != HFS_CDR_DIR)
358+
res = -EIO;
357359
}
358360
if (res)
359361
goto bail_hfs_find;

fs/iomap/buffered-io.c

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1774,7 +1774,8 @@ static bool iomap_can_add_to_ioend(struct iomap_writepage_ctx *wpc, loff_t pos)
17741774
*/
17751775
static int iomap_add_to_ioend(struct iomap_writepage_ctx *wpc,
17761776
struct writeback_control *wbc, struct folio *folio,
1777-
struct inode *inode, loff_t pos, unsigned len)
1777+
struct inode *inode, loff_t pos, loff_t end_pos,
1778+
unsigned len)
17781779
{
17791780
struct iomap_folio_state *ifs = folio->private;
17801781
size_t poff = offset_in_folio(folio, pos);
@@ -1793,15 +1794,60 @@ static int iomap_add_to_ioend(struct iomap_writepage_ctx *wpc,
17931794

17941795
if (ifs)
17951796
atomic_add(len, &ifs->write_bytes_pending);
1797+
1798+
/*
1799+
* Clamp io_offset and io_size to the incore EOF so that ondisk
1800+
* file size updates in the ioend completion are byte-accurate.
1801+
* This avoids recovering files with zeroed tail regions when
1802+
* writeback races with appending writes:
1803+
*
1804+
* Thread 1: Thread 2:
1805+
* ------------ -----------
1806+
* write [A, A+B]
1807+
* update inode size to A+B
1808+
* submit I/O [A, A+BS]
1809+
* write [A+B, A+B+C]
1810+
* update inode size to A+B+C
1811+
* <I/O completes, updates disk size to min(A+B+C, A+BS)>
1812+
* <power failure>
1813+
*
1814+
* After reboot:
1815+
* 1) with A+B+C < A+BS, the file has zero padding in range
1816+
* [A+B, A+B+C]
1817+
*
1818+
* |< Block Size (BS) >|
1819+
* |DDDDDDDDDDDD0000000000000|
1820+
* ^ ^ ^
1821+
* A A+B A+B+C
1822+
* (EOF)
1823+
*
1824+
* 2) with A+B+C > A+BS, the file has zero padding in range
1825+
* [A+B, A+BS]
1826+
*
1827+
* |< Block Size (BS) >|< Block Size (BS) >|
1828+
* |DDDDDDDDDDDD0000000000000|00000000000000000000000000|
1829+
* ^ ^ ^ ^
1830+
* A A+B A+BS A+B+C
1831+
* (EOF)
1832+
*
1833+
* D = Valid Data
1834+
* 0 = Zero Padding
1835+
*
1836+
* Note that this defeats the ability to chain the ioends of
1837+
* appending writes.
1838+
*/
17961839
wpc->ioend->io_size += len;
1840+
if (wpc->ioend->io_offset + wpc->ioend->io_size > end_pos)
1841+
wpc->ioend->io_size = end_pos - wpc->ioend->io_offset;
1842+
17971843
wbc_account_cgroup_owner(wbc, folio, len);
17981844
return 0;
17991845
}
18001846

18011847
static int iomap_writepage_map_blocks(struct iomap_writepage_ctx *wpc,
18021848
struct writeback_control *wbc, struct folio *folio,
1803-
struct inode *inode, u64 pos, unsigned dirty_len,
1804-
unsigned *count)
1849+
struct inode *inode, u64 pos, u64 end_pos,
1850+
unsigned dirty_len, unsigned *count)
18051851
{
18061852
int error;
18071853

@@ -1826,7 +1872,7 @@ static int iomap_writepage_map_blocks(struct iomap_writepage_ctx *wpc,
18261872
break;
18271873
default:
18281874
error = iomap_add_to_ioend(wpc, wbc, folio, inode, pos,
1829-
map_len);
1875+
end_pos, map_len);
18301876
if (!error)
18311877
(*count)++;
18321878
break;
@@ -1897,11 +1943,11 @@ static bool iomap_writepage_handle_eof(struct folio *folio, struct inode *inode,
18971943
* remaining memory is zeroed when mapped, and writes to that
18981944
* region are not written out to the file.
18991945
*
1900-
* Also adjust the writeback range to skip all blocks entirely
1901-
* beyond i_size.
1946+
* Also adjust the end_pos to the end of file and skip writeback
1947+
* for all blocks entirely beyond i_size.
19021948
*/
19031949
folio_zero_segment(folio, poff, folio_size(folio));
1904-
*end_pos = round_up(isize, i_blocksize(inode));
1950+
*end_pos = isize;
19051951
}
19061952

19071953
return true;
@@ -1914,6 +1960,7 @@ static int iomap_writepage_map(struct iomap_writepage_ctx *wpc,
19141960
struct inode *inode = folio->mapping->host;
19151961
u64 pos = folio_pos(folio);
19161962
u64 end_pos = pos + folio_size(folio);
1963+
u64 end_aligned = 0;
19171964
unsigned count = 0;
19181965
int error = 0;
19191966
u32 rlen;
@@ -1955,9 +2002,10 @@ static int iomap_writepage_map(struct iomap_writepage_ctx *wpc,
19552002
/*
19562003
* Walk through the folio to find dirty areas to write back.
19572004
*/
1958-
while ((rlen = iomap_find_dirty_range(folio, &pos, end_pos))) {
2005+
end_aligned = round_up(end_pos, i_blocksize(inode));
2006+
while ((rlen = iomap_find_dirty_range(folio, &pos, end_aligned))) {
19592007
error = iomap_writepage_map_blocks(wpc, wbc, folio, inode,
1960-
pos, rlen, &count);
2008+
pos, end_pos, rlen, &count);
19612009
if (error)
19622010
break;
19632011
pos += rlen;

fs/jbd2/commit.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -772,9 +772,9 @@ void jbd2_journal_commit_transaction(journal_t *journal)
772772
/*
773773
* If the journal is not located on the file system device,
774774
* then we must flush the file system device before we issue
775-
* the commit record
775+
* the commit record and update the journal tail sequence.
776776
*/
777-
if (commit_transaction->t_need_data_flush &&
777+
if ((commit_transaction->t_need_data_flush || update_tail) &&
778778
(journal->j_fs_dev != journal->j_dev) &&
779779
(journal->j_flags & JBD2_BARRIER))
780780
blkdev_issue_flush(journal->j_fs_dev);

0 commit comments

Comments
 (0)