| Age | Commit message (Collapse) | Author |
|
CEPH_MDS_IS_READY() is parsed so that the ternary expression can
return true for an MDS entry with state 0 when it is not laggy. This
allows the random selector to choose a down/DNE rank.
Group the ternary expression under the state check so zero-state ranks
are not treated as ready.
Cc: stable@vger.kernel.org
Fixes: b38c9eb4757d ("ceph: add possible_max_rank and make the code more readable")
Link: https://tracker.ceph.com/issues/78648
Signed-off-by: Yiming Zhu <zhuyiming@kuaishou.com>
Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
|
|
Function gfs2_glock_hold() is expected only to be called when the glock is
held, so use lockref_get_not_zero() instead of lockref_get_not_dead().
In addition, when an asynchronous callback arrives in gfs2_glock_cb(), the
glock can already be dead (from __gfs2_glock_put()), or it can be on the glock
lru list with refcount 0, so we cannot use gfs2_glock_hold() there.
With gfs2_glock_cb() now handling dead glocks, we can remove the racy check in
gdlm_bast().
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
|
|
It was an effort to enhance fscache as a kernel cache for lazy
pulling (at least according to previous Incremental FS discussion [1])
and EROFS over fscache was the in-tree user of this mode.
fscache has since evolved to be netfslib-oriented, serving network
filesystem inodes via the netfs library, but EROFS never acts as a
network filesystem and we need to cache golden filesystem images rather
than individual EROFS inodes.
Since EROFS over fscache is now removed, clean up netfs/fscache/
cachefiles upstream too.
[1] https://lore.kernel.org/r/CAOQ4uxi4dzxArY24YO=+kBCK2gGoq3Ptb8WkzCqSogPgU_R3dQ@mail.gmail.com
[dh] Fixed up comments on:
https://sashiko.dev/#/patchset/20260716103030.3065561-1-dhowells%40redhat.com
https://sashiko.dev/#/patchset/20260722130218.78958-1-dhowells%40redhat.com
Signed-off-by: Gao Xiang <xiang@kernel.org>
Signed-off-by: David Howells <dhowells@redhat.com>
Link: https://patch.msgid.link/1046393.1786544127@warthog.procyon.org.uk
cc: Paulo Alcantara <pc@manguebit.org>
cc: netfs@lists.linux.dev
cc: linux-erofs@lists.ozlabs.org
cc: bpf@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
|
|
ovl_create_real() releases the new dentry twice when the casefold
consistency check fails. The S_IFDIR branch calls end_creating() and
sets err, then falls through to the common out: label which calls
end_creating() on the same dentry again:
case S_IFDIR:
newdentry = ovl_do_mkdir(ofs, dir, newdentry, attr->mode);
err = PTR_ERR_OR_ZERO(newdentry);
if (!err && ofs->casefold != ovl_dentry_casefolded(newdentry)) {
pr_warn_ratelimited(...);
end_creating(newdentry); /* first */
err = -EINVAL;
}
break;
...
if (err)
goto out;
...
out:
if (err) {
end_creating(newdentry); /* second, same dentry */
return ERR_PTR(err);
}
end_creating() is end_dirop(), which does inode_unlock() on the parent
and dput() on the dentry, so the parent directory's i_rwsem is unlocked
twice and the dentry is put twice. The second unlock releases a lock
that is not held, which is what wedges every later creation under that
parent, and the second dput() drops a reference that was never taken.
The branch was added by commit dfc7da402ccc ("ovl: Check for casefold
consistency when creating new dentries") as a bare dput(), which already
released the reference twice; commit fe497f0759e0 ("VFS: change
vfs_mkdir() to unlock on failure.") converted both sites to
end_creating(), adding the double unlock.
This is reachable by an unprivileged user. The casefold consistency of
the layers is validated at mount time in ovl_parse_layer(), and again on
every lookup in ovl_lookup_single(), but ofs->workdir is the internal
"work" subdirectory created inside the user-supplied workdir, and that
subdirectory is not re-checked. Marking it casefolded after the mount
therefore makes every ovl_create_temp() inherit the wrong state - and
that path reaches ovl_create_real() through ovl_start_creating_temp(),
which uses start_creating() with a generated name and so never runs the
lookup-time check.
unshare -Urm
mount -t tmpfs -o casefold=utf8-12.1.0 tmpfs mnt
mkdir -p mnt/lower/d mnt/upper mnt/work mnt/merged
mount -t overlay ovl -o lowerdir=mnt/lower,\
upperdir=mnt/upper,workdir=mnt/work mnt/merged
chattr +F mnt/work/work
mkdir mnt/merged/d/sub # directory copy-up
overlayfs: wrong inherited casefold (work/#5)
and the next copy-up blocks forever on the parent's i_rwsem:
mkdir D start_creating+0x65/0xb0
ovl_start_creating_temp+0xb0/0xe0 [overlay]
ovl_create_temp+0xa3/0x1d0 [overlay]
ovl_copy_up_one+0x1f1c/0x21c0 [overlay]
ovl_copy_up_flags+0xf5/0x140 [overlay]
ovl_create_object+0xb7/0x220 [overlay]
ovl_mkdir+0x23/0x40 [overlay]
Drop the end_creating() from the branch and let out: own the cleanup,
which is what every other error path in this function already does.
Fixes: dfc7da402ccc ("ovl: Check for casefold consistency when creating new dentries")
Cc: stable@vger.kernel.org
Signed-off-by: Vivek Parikh <vivek.parikh@breachx.ai>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
|
|
pipe_poll() unconditionally sets ->poll_usage on the first call, forcing
anon_pipe_write() to wake up readers on every write even if the pipe was
not empty.
The reason is that some legacy epoll(EPOLLET) users depend on historical
per-write wakeups, see commit 3a34b13a88ca ("pipe: make pipe writes always
wake up readers").
Test-case:
#include <unistd.h>
#include <sys/epoll.h>
#include <assert.h>
int main(void)
{
int pfd[2], efd;
struct epoll_event evt = { .events = EPOLLIN | EPOLLET };
pipe(pfd);
efd = epoll_create1(0);
epoll_ctl(efd, EPOLL_CTL_ADD, pfd[0], &evt);
for (int i = 0; i < 2; ++i) {
write(pfd[1], "", 1);
assert(epoll_wait(efd, &evt, 1, 0) == 1);
}
return 0;
}
it fails if WRITE_ONCE(poll_usage, true) is removed from pipe_poll().
However, without EPOLLET in .events, it does not need the extra wakeup
and succeeds even if write() is called only once before the main loop.
Currently io_uring without (unsupported) IORING_POLL_ADD_LEVEL always
sets EPOLLET, and in IORING_POLL_ADD_MULTI mode it depends on per-write
wakeups the same way:
#include <unistd.h>
#include <sys/mman.h>
#include <sys/epoll.h>
#include <sys/syscall.h>
#include <linux/io_uring.h>
#include <assert.h>
int main(void)
{
struct io_uring_params p = {};
int fd, pfd[2];
pipe(pfd);
fd = syscall(SYS_io_uring_setup, 2, &p);
assert(fd >= 0);
void *ring = mmap(0, p.cq_off.cqes + p.cq_entries * sizeof(struct io_uring_cqe),
PROT_READ | PROT_WRITE, MAP_SHARED, fd, IORING_OFF_SQ_RING);
assert(ring != MAP_FAILED);
*(unsigned *)(ring + p.sq_off.tail) = 1;
struct io_uring_sqe *sqes = mmap(0, p.sq_entries * sizeof(*sqes),
PROT_READ | PROT_WRITE, MAP_SHARED, fd, IORING_OFF_SQES);
assert(sqes != MAP_FAILED);
sqes[0].opcode = IORING_OP_POLL_ADD;
sqes[0].fd = pfd[0];
sqes[0].len = IORING_POLL_ADD_MULTI;
sqes[0].poll32_events = EPOLLIN;
syscall(SYS_io_uring_enter, fd, 1, 0, 0, 0, 0);
unsigned *cq_head = ring + p.cq_off.head;
unsigned *cq_tail = ring + p.cq_off.tail;
for (int i = 0; i < 2; ++i) {
write(pfd[1], "", 1);
syscall(SYS_io_uring_enter, fd, 0, 0, IORING_ENTER_GETEVENTS, 0, 0);
assert(*cq_tail == ++*cq_head);
}
return 0;
}
the 2nd assert() in the main loop fails without ->poll_usage == true.
Rename ->poll_usage to ->pseudo_edgetrigger to make the purpose clearer,
update the comments, and change pipe_poll() to set ->pseudo_edgetrigger
only if wait->_key & EPOLLET is true. This check should catch both users,
and this way poll/select and epoll without EPOLLET users will not pay for
the extra wakeup.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Link: https://patch.msgid.link/anCNoW-x0bcB2ggg@redhat.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
|
|
The PIDFD_GET_*_NAMESPACE ioctls in pidfd_ioctl() perform a filesystem
credentials ptrace access check before handing out a namespace file
descriptor. The accompanying comment states that the code "mirrors nsfs
behavior", but, unlike the corresponding procfs paths, it does so without
holding the target task's exec_update_lock.
proc_ns_get_link() and proc_ns_readlink() both take exec_update_lock for
reading around the ptrace check and the namespace lookup, so that the
credentials used for the access decision match those of the task when its
namespace is read. Without it, a caller can pass the check against the
target's old credentials and then read the namespace after the target has
execve()'d a setuid binary and committed new credentials -- accessing
namespace information it should have been denied.
Hold exec_update_lock for reading around the ptrace check and the
namespace lookup so that pidfd truly mirrors nsfs behavior, as the comment
already claims. open_namespace() itself runs outside the lock: once a
namespace reference is obtained it carries its own refcount and is opened
with the caller's own credentials, so a concurrent execve() on the target
can no longer affect the outcome.
Fixes: 5b08bd408534 ("pidfs: allow retrieval of namespace file descriptors")
Cc: stable@vger.kernel.org
Signed-off-by: Chen Linxuan <me@black-desk.cn>
Link: https://patch.msgid.link/20260731-pidfd-exec-update-lock-v1-1-b388f2f3a8b0@black-desk.cn
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
|
|
backing_file_open() derives the path to be stored in the new backing
file from user_file->f_path. This is incorrect when user_file itself
is a backing file, which is the case for nested stacking filesystems,
e.g. overlayfs mounts where the lowerdir of one overlayfs is the merged
directory of another. Since commit def3ae83da02 ("fs: store real path
instead of fake path in backing file f_path") the f_path of a backing
file holds the real path of the intermediate layer, not the path that
the user opened.
Commit 924577e4f6ca ("ovl: Fix nested backing file paths") fixed this
for such configurations by passing file_user_path() from
ovl_open_realfile(). However, commit 6af36aeb147a ("lsm: add
backing_file LSM hooks") changed the first argument of
backing_file_open() from the user path back to the user file and
derived the path from user_file->f_path again, silently re-introducing
the problem.
As a result, files mapped through a nested overlayfs show the wrong
path in /proc/<pid>/maps and in perf/ftrace mmap records. For example,
with two nested overlayfs mounts:
mkdir -p /ovl/{lower,upper,work,merged} /ovl/nested
echo hello > /ovl/lower/foo
mount -t overlay overlay \
-o lowerdir=/ovl/lower,upperdir=/ovl/upper,workdir=/ovl/work \
/ovl/merged
# at least two lowerdirs are needed when upperdir is nonexistent
mount -t overlay overlay \
-o lowerdir=/ovl/merged:/ovl/lower /ovl/nested
mapping /ovl/nested/foo shows a disconnected path instead of the user
path:
# readlink /proc/self/fd/3
/ovl/nested/foo
# grep foo /proc/self/maps
7f6e2c100000-7f6e2c101000 r--s 00000000 00:24 15813027 /foo
The bogus path is derived from the f_path of the intermediate backing
file, whose mount is a private clone that d_path() cannot resolve.
Fix this by using file_user_path(), which returns the outermost
user-visible path for backing files and falls back to
&user_file->f_path for regular files. This restores the behavior of
commit 924577e4f6ca ("ovl: Fix nested backing file paths") for
overlayfs and also fixes the same problem for the other
backing_file_open() callers, fuse passthrough and erofs ishare, when
their user file is itself a backing file.
backing_tmpfile_open() has the same pattern but is not affected: it is
only called by ovl_create_tmpfile() for the upper layer, and another
overlayfs is rejected as upperdir by the DCACHE_OP_REAL check in
ovl_mount_dir_check(), so its user_file can never be a backing file.
Fixes: 6af36aeb147a ("lsm: add backing_file LSM hooks")
Cc: stable@vger.kernel.org
Signed-off-by: Baokun Li <libaokun@linux.alibaba.com>
Link: https://patch.msgid.link/20260804034204.3487077-1-libaokun@linux.alibaba.com
Tested-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
|
|
inode_insert5() no longer has an isnew argument, but its
kernel-doc still documents one. This triggers a W=1 kernel-doc
warning.
Remove the stale parameter description.
Signed-off-by: Yichong Chen <chenyichong@uniontech.com>
Link: https://patch.msgid.link/20260805024149.935769-1-chenyichong@uniontech.com
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
|
|
The case labels in the sysfs(2) syscall implementation are indented
one level deeper than the switch statement itself, which does not
match the kernel coding style (switch and case should be at the same
indentation level). Fix the indentation; no functional change.
Signed-off-by: Manush Prajwal <manushprajwal555@gmail.com>
Link: https://patch.msgid.link/20260808182816.2399-1-manushprajwal555@gmail.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
|
|
Which could leak blkg references.
Fixes: c03cea42149d ("iomap: add initial support for writes without buffer heads")
Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://patch.msgid.link/20260804124404.737145-3-hch@lst.de
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Anuj Gupta <anuj20.g@samsung.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
|
|
fs_bio_integrity_alloc might not allocate a bio integrity payload if PI
verification is disabled on the block device. Check for that case before
calling fs_bio_integrity_free in iomap_bio_read_folio_range_sync to
avoid a NULL pointer dereferences.
Make the branch cover the PI verification as well - while
fs_bio_integrity_verify works without an integrity payload, it requires
one to actually do useful work.
Fixes: 0b10a370529c ("iomap: support T10 protection information")
Cc: stable@vger.kernel.org # v7.1
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Anuj Gupta <anuj20.g@samsung.com>
Reviewed-by: Kanchan Joshi <joshi.k@samsung.com>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Link: https://patch.msgid.link/20260804124404.737145-2-hch@lst.de
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
|
|
WARN_ON_ONCE() takes a condition, not a message. The string literals
are always true, so the warnings still trigger but the messages are
never printed.
Use WARN_ONCE(1, ...) instead to print the messages and keep the
once-only behavior.
Found with a Coccinelle script. Clang's -Wstring-conversion also flags
such calls but is not enabled in kernel builds.
Fixes: f0cd988016f6 ("fs: massage locking helpers")
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Link: https://patch.msgid.link/20260808123802.73687-1-kmehltretter@gmail.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
|
|
__hfsplus_ext_write_extent() writes the cached extent record back into a
B-tree node using fd->entrylength as the length, and fd->entrylength is
derived in __hfs_brec_find() from two on-disk values:
fd->entrylength = len - keylen;
A crafted image can keep both len and keylen valid but make fd->entrylength
negative (keylen > len). __hfsplus_ext_write_extent() doesn't check
fd->entrylength before consuming it, and hfs_bnode_write() takes the length
as u32, so the negative value turns into a huge one. The copy then reads
data past the end of hip->cached_extents, which is only
sizeof(hfsplus_extent_rec) bytes long, and leaks kernel memory into the
image.
Reject an fd->entrylength that does not match sizeof(hfsplus_extent_rec) in
__hfsplus_ext_write_extent(), mirroring the check already performed in
__hfsplus_ext_read_extent().
Link: https://lore.kernel.org/lkml/cbd7003314c530d4f910eacf019ff80adad6687e.camel@dubeyko.com/
Signed-off-by: Jiaming Zhang <r772577952@gmail.com>
Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
Link: https://lore.kernel.org/r/20260810092422.1691377-1-r772577952@gmail.com
Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
|
|
A crafted HFS+ image can contain a corrupted B-tree node. The node
descriptor may contain a record count that does not fit in the node, and
record offsets may be unordered, unaligned, outside the node, or point into
the offset table itself.
Several B-tree helpers consume these on-disk fields before validating them:
hfs_bnode_dump() can walk past the offset table when num_recs is corrupted,
hfs_brec_lenoff() can produce an underflowed length or a record range that
overlaps the offset table. This can make the unlink/writeback path
repeatedly call hfs_bnode_read_u16() with invalid offsets while holding the
HFS+ B-tree lock, producing a flood of "requested invalid offset" messages.
Other writeback workers then block on tree->tree_lock and the system
reports tasks hung in hfsplus_write_inode().
Validate num_recs against the node size before walking the record offset
table. Reject record ranges that are unordered, unaligned, outside the
node, or overlapping the offset table. Reject invalid record indexes before
reading their offset entries, and avoid decrementing an already-zero
leaf_count.
Closes: https://lore.kernel.org/lkml/CANypQFb_2TqKGrztAXj5m0_v+QChxXDnQVeifzV8J25Vuju10Q@mail.gmail.com/
Assisted-by: Codex:gpt-5.5-xhigh
Signed-off-by: Jiaming Zhang <r772577952@gmail.com>
Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
Tested-by: Viacheslav Dubeyko <slava@dubeyko.com>
Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
Link: https://lore.kernel.org/r/20260806073358.1184938-1-r772577952@gmail.com
Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
|
|
ubifs_sb_verify_signature() bounds the on-disk ubifs_sig_node->len field
before handing the signature payload to verify_pkcs7_signature(), but the
check has the wrong sign:
if (le32_to_cpu(signode->len) > snod->len + sizeof(struct ubifs_sig_node))
The signature bytes start sizeof(struct ubifs_sig_node) (UBIFS_SIG_NODE_SZ,
64 bytes) into the node, so the payload is at most
snod->len - sizeof(struct ubifs_sig_node)
bytes long. Adding the header size instead of subtracting it accepts a
declared length up to 2 * UBIFS_SIG_NODE_SZ larger than the node actually
holds -- past the end of c->sbuf, which is vmalloc(c->leb_size).
verify_pkcs7_signature() -> pkcs7_parse_message() -> asn1_ber_decoder()
is then handed that inflated length and reads beyond the allocation while
walking the DER headers. The node length comes straight from the mounted
image, so a crafted signed UBIFS image reaches this via
ubifs_read_superblock() before the signature is cryptographically checked.
snod->len is guaranteed to be >= UBIFS_SIG_NODE_SZ by the node scanner
(c->ranges[UBIFS_SIG_NODE].min_len == UBIFS_SIG_NODE_SZ), so the corrected
subtraction cannot underflow. Legitimately signed images are unaffected: a
correct superblock never declares a signature longer than the node it is
embedded in.
Fixes: 817aa094842d ("ubifs: support offline signed images")
Cc: stable@vger.kernel.org
Signed-off-by: Ibrahim Hashimov <security@auditcode.ai>
Assisted-by: AuditCode-AI:2026.07
Reviewed-by: Richard Weinberger <richard@nod.at>
Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
|
|
- use the struct keyword when describing a struct in kernel-doc format.
- add or correct missing struct members @leaf, @eof, and
@superblock_need_write.
- add Returns: clauses for 4 function descriptions.
to prevent kernel-doc warnings:
Warning: fs/ubifs/ubifs.h:755 struct member 'leaf' not described in 'ubifs_zbranch'
Warning: fs/ubifs/ubifs.h:814 struct member 'eof' not described in 'bu_info'
Warning: fs/ubifs/ubifs.h:814 Excess struct member 'oef' description in 'bu_info'
Warning: fs/ubifs/ubifs.h:992 cannot understand function prototype: 'struct ubifs_stats_info'
Warning: fs/ubifs/ubifs.h:1513 struct member 'superblock_need_write' not described in 'ubifs_info'
Warning: fs/ubifs/ubifs.h:1597 No description found for return value of 'ubifs_check_hash'
Warning: fs/ubifs/ubifs.h:1612 No description found for return value of 'ubifs_check_hmac'
Warning: fs/ubifs/ubifs.h:1653 No description found for return value of 'ubifs_branch_hash'
Warning: fs/ubifs/ubifs.h:1703 No description found for return value of 'ubifs_auth_node_sz'
Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
|
|
Use @hash as the function parameter name to prevent kernel-doc warnings:
Warning: fs/ubifs/key.h:42 function parameter 'hash' not described in 'key_mask_hash'
Warning: fs/ubifs/key.h:42 Excess function parameter 'val' description in 'key_mask_hash'
Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
|
|
Use the "struct" keyword to describe structs in kernel-doc format.
This avoids kernel-doc warnings:
Warning: fs/ubifs/debug.h:75 cannot understand function prototype: 'struct ubifs_debug_info'
Warning: fs/ubifs/debug.h:130 cannot understand function prototype: 'struct ubifs_global_debug_info'
Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
Signed-off-by: Richard Weinberger <richard@nod.at>
|
|
orangefs_prepare_cdm_array() sizes each client debug keyword buffer
with strcspn(cds_head, " "), but then parses the keyword with %s. The
%s conversion skips leading whitespace, while strcspn() does not.
If a client debug entry starts with a space, the allocation can be sized
for an empty keyword while sscanf() copies the following non-empty token.
This can write past the end of the allocated keyword buffer.
Skip leading spaces before computing the keyword length so the allocation
matches the string parsed by sscanf().
Fixes: f7be4ee07fb7 ("Orangefs: kernel client part 4")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: Codex:gpt-5.4
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Signed-off-by: Ren Wei <enjou1224z@gmail.com>
Signed-off-by: Mike Marshall <hubcap@omnibond.com>
|
|
The code has been commented out since 2017 - remove it.
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Signed-off-by: Mike Marshall <hubcap@omnibond.com>
|
|
orangefs_page_mkwrite() records the faulted range with
page_offset(vmf->page) and PAGE_SIZE, although the write range it sets
is attached to the folio and the rest of the function already operates
on folios. Use folio_pos() and folio_size() instead. This gets rid of
two calls to page_offset(), removing two calls to compound_head().
No functional change. orangefs folios are always order-0, so the values
are identical. However, if orangefs ever enables large folios, this
change is necessary for correctness with the current write range
tracking scheme. Tracking only a single page of a larger folio would
leave the rest of the folio's dirty data outside the range that gets
written back, leading to data loss.
Signed-off-by: Tal Zussman <tz2294@columbia.edu>
Signed-off-by: Mike Marshall <hubcap@omnibond.com>
|
|
On a readdir downcall, orangefs_devreq_write_iter() frees
op->downcall.trailer_buf with vfree() when copy_from_iter_full() fails,
but does not clear the pointer before goto Efault. The waiter in
do_readdir() is then woken with a negative status and frees the same
pointer again on its r < 0 path, causing a deterministic double-free.
A client holding /dev/pvfs2-req triggers it by sending a readdir
downcall whose declared trailer_size exceeds the bytes it supplies.
Clear the pointer after freeing so the readdir-side vfree() becomes a
no-op.
Fixes: 382f4581e67f ("orangefs: rewrite readdir to fix several bugs")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Yifei Gao <gyf161023@gmail.com>
Signed-off-by: Mike Marshall <hubcap@omnibond.com>
|
|
The f2fs_evict_inode() can be called during the direct reclaim path, but
__add_ino_entry requires allocating some memory. Since we don't need to
do that in that context, let's migrate it in other workqueue context.
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
|
|
Currently, metadata access for file-backed mounts reuses the page cache
of backing inodes directly.
Switch to per-sb dedicated pseudo inodes ("managed cache") for metadata
access on file-backed mounts (although I still don't think it is
necessary due to the EROFS immutable model). As the result, metadata
cache won't use the page cache of backing inodes anymore.
The "managed cache" was originally used to cache physical compressed
data according to the current cache strategy and I/O patterns; since
file-backed mounts also need to access physical data for metadata
access, it's natural to reuse the managed cache for this too, providing
a unique inode for all physical data access.
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Gao Xiang <xiang@kernel.org>
|
|
Allow userspace to pass an already-opened file descriptor as the mount
source instead of a path string. This is useful for tools that already
hold an fd to the image, such as composefs reusing an existing erofs
backing file.
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Reviewed-by: Gao Xiang <xiang@kernel.org>
Reviewed-by: Christian Brauner (Amutable) <brauner@kernel.org>
Acked-by: Jan Kara <jack@suse.cz>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Gao Xiang <xiang@kernel.org>
|
|
exfat_ioctl_get_volume_label() passes uniname.name_len to
exfat_utf16_to_nls() as the output buffer length. However, name_len is
the number of UTF-16 code units, while exfat_utf16_to_nls() expects the
buffer size in bytes.
As a result, volume labels that expand during charset conversion are
truncated.The destination buffer is FSLABEL_MAX bytes long, so pass
its actual size to the conversion helper.
Signed-off-by: Yang Wen <anmuxixixi@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
|
|
1. f2fs_pre_evict_inode()
: drop all in-memory structures
2. f2fs_delete_inode()
: truncate inode blocks, if it was unlinked.
3. f2fs_post_evict_inode()
: update inode records for future access
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
|
|
This patch adds a dynamic management feature to the existing device
aliasing functionality. It allows users to dynamically reserve or
release specific devices from the filesystem's free pool at runtime
through new ioctls.
To support this, three new ioctls are introduced:
- F2FS_IOC_RESERVE_DEV_ALIAS: This reclaims the space occupied by a
device aliasing file. It first performs a capacity check, resets GC
victim information for the target range, marks the segments as in-use
to prevent new allocations, and then triggers GC to migrate existing
valid data out of the range. Finally, it reserves these blocks in the
SIT to effectively exclude the device from the usable capacity.
- F2FS_IOC_RELEASE_DEV_ALIAS: This releases the reserved space of a
previously reserved device aliasing file. It truncates the blocks
associated with the file, which makes them available for general
filesystem allocation again.
- F2FS_IOC_GET_DEV_ALIAS_STATUS: This retrieves the current aliasing
status of a device aliasing file, returning whether the file is
released (inactive alias) or reserved (active alias, with blocks
fully allocated on the device).
Signed-off-by: Daeho Jeong <daehojeong@google.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
|
|
Variables handling inode numbers - such as the 'i_ino' member of the
inode structure - have been converted to 'u64' within the kernel to
ensure consistency. However, some parts of the nilfs2 implementation
still use 'ino_t' or 'unsigned long' - both of which are
architecture-dependent types - to handle inode numbers.
Replace those remaining instances of 'ino_t' or 'unsigned long' with
'u64'.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
|
|
syzbot reported a warning on nilfs_btree_assign:
WARNING: fs/nilfs2/btree.c:2302 at nilfs_btree_assign+0x983/0xbe0 fs/nilfs2/btree.c:2302,
Analysis found that a corrupted file has the following btree layout:
Level2(key/ptr): [ 256/15 ]
Level1(key/ptr): [ 0/8, 1/9, 0/10, 3/11, 4/12, 5/13, 6/14,
139637976727559/16, 0/17 ]
The test truncated the file to 2 bytes, which partially zeroes the first
block and adds the file to the dirty list. When the segment constructor
writes it and assigns a new blocknr for the index block, it searches the
btree with key=0 and min level=2, and apparently returns -ENOENT.
Therefore, we should perform more checks on the btree nodes and return
early.
[ryusuke: split long lines in btree.c to satisfy checkpatch and
improved the error message format for clarity]
Reported-by: syzbot+158be45e4d99232e1900@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=158be45e4d99232e1900
Signed-off-by: Wang Jianjian <wangjianjian3@huawei.com>
Fixes: 17c76b0104e4 ("nilfs2: B-tree based block mapping")
Cc: stable+noautosel@kernel.org # Warning suppression primarily
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
|
|
When an NFS server grants a delegation in an OPEN reply,
nfs_inode_set_delegation() records it on the client. However, three
of its error flows return without sending DELEGRETURN.
A delegation can be relinquished only by DELEGRETURN (RFC 8881
Section 20.2.4), so dropping one silently leaves the server believing
the client still holds it. If the server happens to recall that
delegation, the client answers CB_RECALL with NFS4ERR_BADHANDLE
because it has no record of the stateid. The server revokes the
delegation and moves it onto its cl_revoked list, because the client
never sends the FREE_STATEID that would drain it. Every subsequent
SEQUENCE reply then carries SEQ4_STATUS_RECALLABLE_STATE_REVOKED,
and the client's state manager loops issuing TEST_STATEID across its
delegations without ever clearing the condition.
The window is easy to reach now that a server offers a write
delegation on any write OPEN: a delegation recalled for one opener
races a re-open that the server answers with a fresh write
delegation.
Instead of dropping it, hand the delegation back during these error
flows.
Fixes: ade04647dd56 ("NFSv4: Ensure we honour NFS_DELEGATION_RETURNING in nfs_inode_set_delegation()")
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
|
|
Add a proc4cb-ops nested attribute to the server-stats netlink dump,
reusing the existing server-proc-entry (op/count) layout. The dump
gains a callback section that emits one entry per callback opcode
(OP_CB_GETATTR..OP_CB_OFFLOAD) from the per-netns callback counters,
paged across messages like the other per-operation sections.
This lets nfsstat report NFSv4 backchannel operation counts over
netlink, including CB_GETATTR which corresponds to the procfs
wdeleg_getattr line.
Assisted-by: LLM
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260717-exportd-netlink-v7-6-b7ce17b83b60@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
The NFS server tracks per-operation call counts for the forward channel
(proc4ops) but keeps no statistics for the NFSv4 backchannel (callback)
operations it sends to clients.
Add a per-netns array of percpu counters for callback operations, indexed
by RFC 8881 callback opcode (OP_CB_GETATTR..OP_CB_OFFLOAD), and bump the
relevant counter in nfsd4_run_cb(), which is hit exactly once per callback
that is actually queued.
CB_GETATTR is sent when a GETATTR conflicts with an outstanding write
delegation, which is roughly what the dedicated wdeleg_getattr counter
tracked. The two are not identical: the old counter incremented on every
such conflict, whereas the CB_GETATTR counter only counts callbacks that
are actually queued, so concurrent conflicts that coalesce onto an
already in-flight CB_GETATTR are now counted once rather than once per
conflict. Report the procfs "wdeleg_getattr" line from the CB_GETATTR
counter and drop the now-redundant NFSD_STATS_WDELEG_GETATTR counter, its
helper, and its increment site.
Assisted-by: LLM
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260717-exportd-netlink-v7-5-b7ce17b83b60@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
Now that svc_seq_show() and the nfsd netlink stats handler both use
the per-netns svc_stat vs_count arrays, the global per-version
vs_count percpu counters are no longer read by anything. Remove the
vs_count field from struct svc_version and all the associated
DEFINE_PER_CPU_ALIGNED arrays and initializers across nfsd, lockd,
and the NFS client callback service.
Assisted-by: LLM
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260717-exportd-netlink-v7-4-b7ce17b83b60@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
Implement nfsd_nl_server_stats_get_dumpit() which exposes the
NFS server statistics currently available via /proc/net/rpc/nfsd
through the nfsd generic netlink family.
The handler uses a dump operation to stream statistics across one
or more netlink messages. The reply is divided into sections that
are emitted in order:
- scalar stats (reply cache, filehandle, IO, network, RPC),
emitted once in the first message, then
- per-version procedure counts (proc2/3/4-ops) and the NFSv4
per-operation counts (proc4ops-ops), using the per-netns
vs_count arrays.
cb->args[0] tracks the current section and cb->args[1] the entry
index within it, so a section that does not fit in the current
message is closed and resumed in the next one. This matters because
the first dump message is allocated at NLMSG_GOODSIZE (a single page
on most architectures) regardless of the client's receive buffer;
packing every counter into one message would overflow it and fail
the dump with -EMSGSIZE. Userspace merges the attributes from every
message.
This allows nfsstat to retrieve server statistics via netlink
with a procfs fallback for older kernels.
Assisted-by: LLM
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260717-exportd-netlink-v7-3-b7ce17b83b60@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
The existing per-procedure call counts live in global
svc_version->vs_count[] arrays which are not network-namespace-aware.
Add per-netns equivalents in struct svc_stat so the upcoming netlink
stats interface can return namespace-scoped statistics.
Add a vs_count pointer array to struct svc_stat, along with
svc_stat_alloc_counts() and svc_stat_free_counts() helpers to manage
per-version percpu call count arrays.
Increment the per-net counter alongside the global one in
svc_generic_init_request(). Call the alloc/free helpers from
nfsd_net_init() and nfsd_net_exit().
Assisted-by: LLM
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260717-exportd-netlink-v7-1-b7ce17b83b60@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
nfsd_stats_io_write_add() and nfsd_stats_io_read_add() accumulate
byte counts in per-net-namespace and per-export percpu_counters
using percpu_counter_add(), which applies the default batch
threshold of max(32, 2*nr_cpus).
For a 4 KB NFS WRITE, the amount (4096) always exceeds this
threshold, so percpu_counter_add_batch() acquires the counter's
global spinlock on every update. Each WRITE RPC updates two
counters (per-net and per-export), producing two global lock
acquisitions per operation. Profiling on a 10-CPU RDMA NFS
server shows 0.44% of total CPU cycles spent contending on
these locks during a small random write workload.
Switch to percpu_counter_add_local(), which batches with
INT_MAX so that updates always remain on the per-CPU fast
path regardless of the amount. All readers of these counters
already use percpu_counter_sum_positive(), which sums the
per-CPU deltas under the global lock, so read accuracy is
unaffected.
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: NeilBrown <neil@brown.name>
Link: https://patch.msgid.link/20260717001232.438792-5-cel@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
Each RPC passes through nfsd_cache_lookup(), which increments one
of nfsd_stats_rc_hits_inc(), nfsd_stats_rc_misses_inc(), or
nfsd_stats_rc_nocache_inc(). These helpers update
per-net-namespace percpu_counters with percpu_counter_inc(),
which applies the default batch threshold of max(32, 2*nr_cpus).
Once a CPU's local delta reaches that threshold, the update folds
into the shared counter under its global spinlock. On a busy
multi-CPU server this produces lock traffic on a counter cacheline
shared across all CPUs, growing with the request rate.
Switch to percpu_counter_add_local(fbc, 1), which batches with
INT_MAX so that increments always remain on the per-CPU fast path.
This matches the treatment already applied to the IO byte and DRC
memory counters. All readers of these counters use
percpu_counter_sum_positive(), which sums the per-CPU deltas under
the global lock, so read accuracy is unaffected.
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: NeilBrown <neil@brown.name>
Link: https://patch.msgid.link/20260717001232.438792-4-cel@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
The DRC memory usage counter (NFSD_STATS_DRC_MEM_USAGE) tracks
bytes, but percpu_counter_add() uses the global percpu_counter_batch
threshold of max(32, 2*nr_cpus). Each DRC entry add or removal
updates the counter by sizeof(struct nfsd_cacherep) (~144 bytes),
which always exceeds the batch threshold. percpu_counter_add()
then acquires the counter's global spinlock on every update,
serializing all nfsd threads.
On a 10-CPU NFS server handling a high rate of non-idempotent
NFSv3 operations, this lock accounts for a measurable fraction
of total spin lock overhead because nfsd_cache_lookup() both
inserts a new entry and prunes up to three old entries per RPC,
producing 4-7 global lock acquisitions per operation.
Switch to percpu_counter_add_local() and percpu_counter_sub_local(),
which batch with INT_MAX so that updates always remain on the per-CPU
fast path regardless of the amount. The only reader of this counter uses
percpu_counter_sum_positive(), which sums the per-CPU deltas under the
global lock, so read accuracy is unaffected.
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: NeilBrown <neil@brown.name>
Link: https://patch.msgid.link/20260717001232.438792-3-cel@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
nfsd_prune_bucket_locked() evicts an entry before checking
the freed count against @max. The check uses "++freed > max",
which does not break until freed exceeds max, resulting in
max + 1 evictions. Use ">=" so the limit stated in the
function comment is honored.
Fixes: a9507f6af145 ("NFSD: Replace nfsd_prune_bucket()")
Cc: stable@vger.kernel.org
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: NeilBrown <neil@brown.name>
Link: https://patch.msgid.link/20260717001232.438792-2-cel@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
These NFSv4 attribute bitmask definitions live in nfsd.h, which
nearly every nfsd source file includes, yet only nfs4proc.c and
nfs4xdr.c reference them. Move them to a dedicated header so only
those two consumers pull them in.
While moving the block, correct the stale QUOTA_* annotation: the
promised support never materialized, so these attributes are
unlikely to be supported any time soon rather than forthcoming.
Link: https://patch.msgid.link/20260712204554.125308-10-cel@kernel.org
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
Clean up: Common practice in the Linux kernel is to avoid the use of
static inline functions when there is only a single call site. The
30-line helper function is removed from a header pulled into ~25 .c
files, removing <linux/sunrpc/addr.h> from that header's transitive
include surface, dropping a now-redundant <linux/sunrpc/msg_prot.h>
include, and reducing the function's visibility to the one translation
unit that uses it.
Link: https://patch.msgid.link/20260712204554.125308-9-cel@kernel.org
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
Refactor: nfsd_user_namespace() currently lives in nfsd.h, so every
caller must pull in nfsd.h -- directly or transitively via state.h --
and with it the NFS protocol definitions from uapi/linux/nfs.h and
friends, even when the caller uses nothing else from nfsd.h.
Since nfsd_user_namespace() is an auth-related function, move it
to fs/nfsd/auth.c in preparation for removing '#include "nfsd.h"'
from a few places.
Link: https://patch.msgid.link/20260712204554.125308-8-cel@kernel.org
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
struct readdir_cd is part of the VFS readdir API, but it lives in
nfsd.h, the subsystem's catch-all header, rather than alongside that
API. That forces vfs.h to include nfsd.h solely to declare readdir_cd
for its nfsd_readdir() prototype, a layering inversion since vfs.h is
the lower-level shim.
Relocate readdir_cd to vfs.h, just below the nfsd_filldir_t callback
typedef. vfs.h then defines the struct itself and no longer includes
nfsd.h. The xdr headers that embed readdir_cd by value include vfs.h
to obtain the definition. This prepares the ground for dropping nfsd.h
from more files.
Link: https://patch.msgid.link/20260712204554.125308-7-cel@kernel.org
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
Nothing declared in fs/nfsd/nfsd.h references a type, macro, or
function that export.h defines. The include is present only so
that source files including nfsd.h pick up export.h's definitions
transitively. Of the twenty source files that include nfsd.h, only
auth.c relies on that side effect: it names struct svc_export and the
NFSEXP_* flags yet includes no header that supplies them.
Add the export.h include directly to auth.c, then drop it from nfsd.h
so the header carries only the dependencies its own declarations
require.
Link: https://patch.msgid.link/20260712204554.125308-6-cel@kernel.org
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
Clean up: cache.h does not need the full definition of struct
nfsd_net. A forward declaration suffices.
Link: https://patch.msgid.link/20260712204554.125308-5-cel@kernel.org
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
Nothing in fs/nfsd/nfsd.h needs the contents of "netns.h"; the
prototypes there that take a struct nfsd_net pointer need only a
forward declaration of that type. Relocate the existing forward
declaration ahead of the first such prototype, drop the "netns.h"
include from nfsd.h, and include it directly in the translation
units that operate on struct nfsd_net.
"netns.h" had also been the path by which <linux/filelock.h>
reached nfsxdr.c and state.h. Both now include <linux/filelock.h>
themselves.
Link: https://patch.msgid.link/20260712204554.125308-4-cel@kernel.org
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
Nothing in fs/nfsd/nfsd.h needs what is defined in "stats.h", so that
header can be moved out to the six translation units that actually
need it.
Link: https://patch.msgid.link/20260712204554.125308-3-cel@kernel.org
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
The inline helpers in fs/nfsd/stats.h dereference struct nfsd_net and
struct svc_export, yet the header includes neither "netns.h" nor
"export.h", where those types are defined. Each helper therefore
compiles only when its translation unit has already pulled in both
headers ahead of "stats.h" -- a hidden ordering requirement that has
to be honored at every include site.
Include "netns.h" and "export.h" from "stats.h" directly so the
header stands on its own, and no consumer has to order its includes
to satisfy it.
Link: https://patch.msgid.link/20260712204554.125308-2-cel@kernel.org
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <cel@kernel.org>
|
|
The generated server-side decoder and encoder for a void procedure
argument or result are named after the RPC program (for example,
nfs_svc_decode_void). xdrgen derives that prefix from the program
name alone, not the version, so two versions of one program built
into the same module emit the identical symbol. NFSv2 and NFSv3
both declare program NFS_PROGRAM; once both are converted, fs/nfsd
fails to link with multiple definitions of nfs_svc_decode_void and
nfs_svc_encode_void.
A void handler carries no program- or version-specific behavior:
each merely forwards to xdrgen_decode_void() or xdrgen_encode_void().
Define one shared pair, xdrgen_svc_decode_void() and
xdrgen_svc_encode_void(), in the xdrgen builtins, and stop the
program generator from emitting a per-program void handler.
lockd is the one in-tree consumer that already emits per-program
void handlers, so regenerate the NLMv3 and NLMv4 XDR code to drop
nlm_svc_{decode,encode}_void() and nlm4_svc_{decode,encode}_void()
and point both procedure tables at the shared handlers. The shared
handlers are identical to the generated ones they replace, so no
wire behavior changes.
Only the server (svc) handlers are affected. The client-side void
stubs remain static and per-program, so they do not collide.
Link: https://patch.msgid.link/20260712193122.116845-3-cel@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
|