aboutsummaryrefslogtreecommitdiff
path: root/fs
AgeCommit message (Collapse)AuthorFilesLines
2024-05-29Merge tag '9p-for-6.10-rc2' of https://github.com/martinetd/linuxLinus Torvalds1-2/+7
Pull 9p fixes from Dominique Martinet: "Two fixes headed to stable trees: - a trace event was dumping uninitialized values - a missing lock that was thought to have exclusive access, and it turned out not to" * tag '9p-for-6.10-rc2' of https://github.com/martinetd/linux: 9p: add missing locking around taking dentry fid list net/9p: fix uninit-value in p9_client_rpc()
2024-05-29gfs2: Get rid of demote_ok checksAndreas Gruenbacher3-41/+1
The demote_ok glock operation is only still used to prevent the inode glocks of the "jindex" and "rindex" directories from getting recycled while they are still referenced by sdp->sd_jindex and sdp->sd_rindex. However, the LRU walking code will no longer recycle glocks which are referenced, so the demote_ok glock operation is obsolete and can be removed. Each of a glock's holders in the gl_holders list is holding a reference on the glock, so when the list of holders isn't empty in demote_ok(), the existing reference count check will already prevent the glock from getting released. This means that demote_ok() is obsolete as well. Signed-off-by: Andreas Gruenbacher <[email protected]>
2024-05-29Revert "GFS2: Don't add all glocks to the lru"Andreas Gruenbacher3-12/+4
This reverts commit e7ccaf5fe1590667b3fa2f8df5c5ec9ba0dc5b85. Before commit e7ccaf5fe159, every time a resource group glock was dequeued by gfs2_glock_dq(), it was added to the glock LRU list even though the glock was still referenced by the resource group and could never be evicted, anyway. Commit e7ccaf5fe159 added a GLOF_LRU hack to avoid that overhead for resource group glocks, and that hack was since adopted for some other types of glocks as well. We now no longer add glocks to the glock LRU list while they are still referenced. This solves the underlying problem, and obsoletes the GLOF_LRU hack. Signed-off-by: Andreas Gruenbacher <[email protected]> (cherry picked from commit 3e5257c810cba91e274d07f3db5cf013c7c830be)
2024-05-29gfs2: Revise glock reference counting modelAndreas Gruenbacher3-28/+30
In the current glock reference counting model, a bias of one is added to a glock's refcount when it is locked (gl->gl_state != LM_ST_UNLOCKED). A glock is removed from the lru_list when it is enqueued, and added back when it is dequeued. This isn't a very appropriate model because most glocks are held for long periods of time (for example, the inode "owns" references to its inode and iopen glocks as long as the inode is cached even when the glock state changes to LM_ST_UNLOCKED), and they can only be freed when they are no longer referenced, anyway. Fix this by getting rid of the refcount bias for locked glocks. That way, we can use lockref_put_or_lock() to efficiently drop all but the last glock reference, and put the glock onto the lru_list when the last reference is dropped. When find_insert_glock() returns a reference to a cached glock, it removes the glock from the lru_list. Dumping the "glocks" and "glstats" debugfs files also takes glock references, but instead of removing the glocks from the lru_list in that case as well, we leave them on the list. This ensures that dumping those files won't perturb the order of the glocks on the lru_list. In addition, when the last reference to an *unlocked* glock is dropped, we immediately free it; this preserves the preexisting behavior. If it later turns out that caching unlocked glocks is useful in some situations, we can change the caching strategy. It is currently unclear if a glock that has no active references can have the GLF_LFLUSH flag set. To make sure that such a glock won't accidentally be evicted due to memory pressure, we add a GLF_LFLUSH check to gfs2_dispose_glock_lru(). Signed-off-by: Andreas Gruenbacher <[email protected]>
2024-05-29gfs2: Switch to a per-filesystem glock workqueueAndreas Gruenbacher3-15/+18
Switch to a per-filesystem glock workqueue. Additional workqueues are cheap nowadays, and keeping separate workqueues allows to flush the work of each filesystem without affecting the others. Signed-off-by: Andreas Gruenbacher <[email protected]>
2024-05-29gfs2: Report when glocks cannot be freed for a long timeAndreas Gruenbacher1-3/+15
When glocks cannot be freed for a long time, avoid the "task blocked for more than N seconds" messages and report how many glocks are still outstanding, instead. Signed-off-by: Andreas Gruenbacher <[email protected]>
2024-05-29gfs2: gfs2_glock_get cleanupAndreas Gruenbacher1-20/+13
Clean up the messy code in gfs2_glock_get(). No change in functionality. Signed-off-by: Andreas Gruenbacher <[email protected]>
2024-05-29gfs2: Invert the GLF_INITIAL flagAndreas Gruenbacher3-10/+22
Invert the meaning of the GLF_INITIAL flag: right now, when GLF_INITIAL is set, a DLM lock exists and we have a valid identifier for it; when GLF_INITIAL is cleared, no DLM lock exists (yet). This is confusing. In addition, it makes more sense to highlight the exceptional case (i.e., no DLM lock exists yet) in glock dumps and trace points than to highlight the common case. To avoid confusion between the "old" and the "new" meaning of the flag, use 'a' instead of 'I' to represent the flag. For improved code consistency, check if the GLF_INITIAL flag is cleared to determine whether a DLM lock exists instead of checking if the lock identifier is non-zero. Document what the flag is used for. Signed-off-by: Andreas Gruenbacher <[email protected]>
2024-05-29gfs2: Remove outdated comment in glock_work_funcAndreas Gruenbacher1-5/+1
Signed-off-by: Andreas Gruenbacher <[email protected]>
2024-05-29Merge patch series "cachefiles: some bugfixes and cleanups for ondemand ↵Christian Brauner3-56/+169
requests" [email protected] <[email protected]> says: We've been testing ondemand mode for cachefiles since January, and we're almost done. We hit a lot of issues during the testing period, and this patch set fixes some of the issues related to ondemand requests. The patches have passed internal testing without regression. The following is a brief overview of the patches, see the patches for more details. Patch 1-5: Holding reference counts of reqs and objects on read requests to avoid malicious restore leading to use-after-free. Patch 6-10: Add some consistency checks to copen/cread/get_fd to avoid malicious copen/cread/close fd injections causing use-after-free or hung. Patch 11: When cache is marked as CACHEFILES_DEAD, flush all requests, otherwise the kernel may be hung. since this state is irreversible, the daemon can read open requests but cannot copen. Patch 12: Allow interrupting a read request being processed by killing the read process as a way of avoiding hung in some special cases. fs/cachefiles/daemon.c | 3 +- fs/cachefiles/internal.h | 5 + fs/cachefiles/ondemand.c | 217 ++++++++++++++++++++++-------- include/trace/events/cachefiles.h | 8 +- 4 files changed, 176 insertions(+), 57 deletions(-) * patches from https://lore.kernel.org/r/[email protected]: cachefiles: make on-demand read killable cachefiles: flush all requests after setting CACHEFILES_DEAD cachefiles: Set object to close if ondemand_id < 0 in copen cachefiles: defer exposing anon_fd until after copy_to_user() succeeds cachefiles: never get a new anonymous fd if ondemand_id is valid cachefiles: add spin_lock for cachefiles_ondemand_info cachefiles: add consistency check for copen/cread cachefiles: remove err_put_fd label in cachefiles_ondemand_daemon_read() cachefiles: fix slab-use-after-free in cachefiles_ondemand_daemon_read() cachefiles: fix slab-use-after-free in cachefiles_ondemand_get_fd() cachefiles: remove requests from xarray during flushing requests cachefiles: add output string to cachefiles_obj_[get|put]_ondemand_fd Signed-off-by: Christian Brauner <[email protected]>
2024-05-29cachefiles: make on-demand read killableBaokun Li1-12/+28
Replacing wait_for_completion() with wait_for_completion_killable() in cachefiles_ondemand_send_req() allows us to kill processes that might trigger a hunk_task if the daemon is abnormal. But now only CACHEFILES_OP_READ is killable, because OP_CLOSE and OP_OPEN is initiated from kworker context and the signal is prohibited in these kworker. Note that when the req in xas changes, i.e. xas_load(&xas) != req, it means that a process will complete the current request soon, so wait again for the request to be completed. In addition, add the cachefiles_ondemand_finish_req() helper function to simplify the code. Suggested-by: Hou Tao <[email protected]> Signed-off-by: Baokun Li <[email protected]> Link: https://lore.kernel.org/r/[email protected] Acked-by: Jeff Layton <[email protected]> Reviewed-by: Jia Zhu <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
2024-05-29cachefiles: flush all requests after setting CACHEFILES_DEADBaokun Li2-1/+4
In ondemand mode, when the daemon is processing an open request, if the kernel flags the cache as CACHEFILES_DEAD, the cachefiles_daemon_write() will always return -EIO, so the daemon can't pass the copen to the kernel. Then the kernel process that is waiting for the copen triggers a hung_task. Since the DEAD state is irreversible, it can only be exited by closing /dev/cachefiles. Therefore, after calling cachefiles_io_error() to mark the cache as CACHEFILES_DEAD, if in ondemand mode, flush all requests to avoid the above hungtask. We may still be able to read some of the cached data before closing the fd of /dev/cachefiles. Note that this relies on the patch that adds reference counting to the req, otherwise it may UAF. Fixes: c8383054506c ("cachefiles: notify the user daemon when looking up cookie") Signed-off-by: Baokun Li <[email protected]> Link: https://lore.kernel.org/r/[email protected] Acked-by: Jeff Layton <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
2024-05-29cachefiles: Set object to close if ondemand_id < 0 in copenZizhi Wo1-1/+6
If copen is maliciously called in the user mode, it may delete the request corresponding to the random id. And the request may have not been read yet. Note that when the object is set to reopen, the open request will be done with the still reopen state in above case. As a result, the request corresponding to this object is always skipped in select_req function, so the read request is never completed and blocks other process. Fix this issue by simply set object to close if its id < 0 in copen. Signed-off-by: Zizhi Wo <[email protected]> Signed-off-by: Baokun Li <[email protected]> Link: https://lore.kernel.org/r/[email protected] Acked-by: Jeff Layton <[email protected]> Reviewed-by: Jia Zhu <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
2024-05-29cachefiles: defer exposing anon_fd until after copy_to_user() succeedsBaokun Li1-20/+33
After installing the anonymous fd, we can now see it in userland and close it. However, at this point we may not have gotten the reference count of the cache, but we will put it during colse fd, so this may cause a cache UAF. So grab the cache reference count before fd_install(). In addition, by kernel convention, fd is taken over by the user land after fd_install(), and the kernel should not call close_fd() after that, i.e., it should call fd_install() after everything is ready, thus fd_install() is called after copy_to_user() succeeds. Fixes: c8383054506c ("cachefiles: notify the user daemon when looking up cookie") Suggested-by: Hou Tao <[email protected]> Signed-off-by: Baokun Li <[email protected]> Link: https://lore.kernel.org/r/[email protected] Acked-by: Jeff Layton <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
2024-05-29cachefiles: never get a new anonymous fd if ondemand_id is validBaokun Li1-6/+28
Now every time the daemon reads an open request, it gets a new anonymous fd and ondemand_id. With the introduction of "restore", it is possible to read the same open request more than once, and therefore an object can have more than one anonymous fd. If the anonymous fd is not unique, the following concurrencies will result in an fd leak: t1 | t2 | t3 ------------------------------------------------------------ cachefiles_ondemand_init_object cachefiles_ondemand_send_req REQ_A = kzalloc(sizeof(*req) + data_len) wait_for_completion(&REQ_A->done) cachefiles_daemon_read cachefiles_ondemand_daemon_read REQ_A = cachefiles_ondemand_select_req cachefiles_ondemand_get_fd load->fd = fd0 ondemand_id = object_id0 ------ restore ------ cachefiles_ondemand_restore // restore REQ_A cachefiles_daemon_read cachefiles_ondemand_daemon_read REQ_A = cachefiles_ondemand_select_req cachefiles_ondemand_get_fd load->fd = fd1 ondemand_id = object_id1 process_open_req(REQ_A) write(devfd, ("copen %u,%llu", msg->msg_id, size)) cachefiles_ondemand_copen xa_erase(&cache->reqs, id) complete(&REQ_A->done) kfree(REQ_A) process_open_req(REQ_A) // copen fails due to no req // daemon close(fd1) cachefiles_ondemand_fd_release // set object closed -- umount -- cachefiles_withdraw_cookie cachefiles_ondemand_clean_object cachefiles_ondemand_init_close_req if (!cachefiles_ondemand_object_is_open(object)) return -ENOENT; // The fd0 is not closed until the daemon exits. However, the anonymous fd holds the reference count of the object and the object holds the reference count of the cookie. So even though the cookie has been relinquished, it will not be unhashed and freed until the daemon exits. In fscache_hash_cookie(), when the same cookie is found in the hash list, if the cookie is set with the FSCACHE_COOKIE_RELINQUISHED bit, then the new cookie waits for the old cookie to be unhashed, while the old cookie is waiting for the leaked fd to be closed, if the daemon does not exit in time it will trigger a hung task. To avoid this, allocate a new anonymous fd only if no anonymous fd has been allocated (ondemand_id == 0) or if the previously allocated anonymous fd has been closed (ondemand_id == -1). Moreover, returns an error if ondemand_id is valid, letting the daemon know that the current userland restore logic is abnormal and needs to be checked. Fixes: c8383054506c ("cachefiles: notify the user daemon when looking up cookie") Signed-off-by: Baokun Li <[email protected]> Link: https://lore.kernel.org/r/[email protected] Acked-by: Jeff Layton <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
2024-05-29cachefiles: add spin_lock for cachefiles_ondemand_infoBaokun Li2-1/+35
The following concurrency may cause a read request to fail to be completed and result in a hung: t1 | t2 --------------------------------------------------------- cachefiles_ondemand_copen req = xa_erase(&cache->reqs, id) // Anon fd is maliciously closed. cachefiles_ondemand_fd_release xa_lock(&cache->reqs) cachefiles_ondemand_set_object_close(object) xa_unlock(&cache->reqs) cachefiles_ondemand_set_object_open // No one will ever close it again. cachefiles_ondemand_daemon_read cachefiles_ondemand_select_req // Get a read req but its fd is already closed. // The daemon can't issue a cread ioctl with an closed fd, then hung. So add spin_lock for cachefiles_ondemand_info to protect ondemand_id and state, thus we can avoid the above problem in cachefiles_ondemand_copen() by using ondemand_id to determine if fd has been closed. Fixes: c8383054506c ("cachefiles: notify the user daemon when looking up cookie") Signed-off-by: Baokun Li <[email protected]> Link: https://lore.kernel.org/r/[email protected] Acked-by: Jeff Layton <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
2024-05-29cachefiles: add consistency check for copen/creadBaokun Li1-7/+20
This prevents malicious processes from completing random copen/cread requests and crashing the system. Added checks are listed below: * Generic, copen can only complete open requests, and cread can only complete read requests. * For copen, ondemand_id must not be 0, because this indicates that the request has not been read by the daemon. * For cread, the object corresponding to fd and req should be the same. Signed-off-by: Baokun Li <[email protected]> Link: https://lore.kernel.org/r/[email protected] Acked-by: Jeff Layton <[email protected]> Reviewed-by: Jingbo Xu <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
2024-05-29cachefiles: remove err_put_fd label in cachefiles_ondemand_daemon_read()Baokun Li1-29/+16
The err_put_fd label is only used once, so remove it to make the code more readable. In addition, the logic for deleting error request and CLOSE request is merged to simplify the code. Signed-off-by: Baokun Li <[email protected]> Link: https://lore.kernel.org/r/[email protected] Acked-by: Jeff Layton <[email protected]> Reviewed-by: Jia Zhu <[email protected]> Reviewed-by: Gao Xiang <[email protected]> Reviewed-by: Jingbo Xu <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
2024-05-29cachefiles: fix slab-use-after-free in cachefiles_ondemand_daemon_read()Baokun Li1-0/+3
We got the following issue in a fuzz test of randomly issuing the restore command: ================================================================== BUG: KASAN: slab-use-after-free in cachefiles_ondemand_daemon_read+0xb41/0xb60 Read of size 8 at addr ffff888122e84088 by task ondemand-04-dae/963 CPU: 13 PID: 963 Comm: ondemand-04-dae Not tainted 6.8.0-dirty #564 Call Trace: kasan_report+0x93/0xc0 cachefiles_ondemand_daemon_read+0xb41/0xb60 vfs_read+0x169/0xb50 ksys_read+0xf5/0x1e0 Allocated by task 116: kmem_cache_alloc+0x140/0x3a0 cachefiles_lookup_cookie+0x140/0xcd0 fscache_cookie_state_machine+0x43c/0x1230 [...] Freed by task 792: kmem_cache_free+0xfe/0x390 cachefiles_put_object+0x241/0x480 fscache_cookie_state_machine+0x5c8/0x1230 [...] ================================================================== Following is the process that triggers the issue: mount | daemon_thread1 | daemon_thread2 ------------------------------------------------------------ cachefiles_withdraw_cookie cachefiles_ondemand_clean_object(object) cachefiles_ondemand_send_req REQ_A = kzalloc(sizeof(*req) + data_len) wait_for_completion(&REQ_A->done) cachefiles_daemon_read cachefiles_ondemand_daemon_read REQ_A = cachefiles_ondemand_select_req msg->object_id = req->object->ondemand->ondemand_id ------ restore ------ cachefiles_ondemand_restore xas_for_each(&xas, req, ULONG_MAX) xas_set_mark(&xas, CACHEFILES_REQ_NEW) cachefiles_daemon_read cachefiles_ondemand_daemon_read REQ_A = cachefiles_ondemand_select_req copy_to_user(_buffer, msg, n) xa_erase(&cache->reqs, id) complete(&REQ_A->done) ------ close(fd) ------ cachefiles_ondemand_fd_release cachefiles_put_object cachefiles_put_object kmem_cache_free(cachefiles_object_jar, object) REQ_A->object->ondemand->ondemand_id // object UAF !!! When we see the request within xa_lock, req->object must not have been freed yet, so grab the reference count of object before xa_unlock to avoid the above issue. Fixes: 0a7e54c1959c ("cachefiles: resend an open request if the read request's object is closed") Signed-off-by: Baokun Li <[email protected]> Link: https://lore.kernel.org/r/[email protected] Acked-by: Jeff Layton <[email protected]> Reviewed-by: Jia Zhu <[email protected]> Reviewed-by: Jingbo Xu <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
2024-05-29cachefiles: fix slab-use-after-free in cachefiles_ondemand_get_fd()Baokun Li2-4/+20
We got the following issue in a fuzz test of randomly issuing the restore command: ================================================================== BUG: KASAN: slab-use-after-free in cachefiles_ondemand_daemon_read+0x609/0xab0 Write of size 4 at addr ffff888109164a80 by task ondemand-04-dae/4962 CPU: 11 PID: 4962 Comm: ondemand-04-dae Not tainted 6.8.0-rc7-dirty #542 Call Trace: kasan_report+0x94/0xc0 cachefiles_ondemand_daemon_read+0x609/0xab0 vfs_read+0x169/0xb50 ksys_read+0xf5/0x1e0 Allocated by task 626: __kmalloc+0x1df/0x4b0 cachefiles_ondemand_send_req+0x24d/0x690 cachefiles_create_tmpfile+0x249/0xb30 cachefiles_create_file+0x6f/0x140 cachefiles_look_up_object+0x29c/0xa60 cachefiles_lookup_cookie+0x37d/0xca0 fscache_cookie_state_machine+0x43c/0x1230 [...] Freed by task 626: kfree+0xf1/0x2c0 cachefiles_ondemand_send_req+0x568/0x690 cachefiles_create_tmpfile+0x249/0xb30 cachefiles_create_file+0x6f/0x140 cachefiles_look_up_object+0x29c/0xa60 cachefiles_lookup_cookie+0x37d/0xca0 fscache_cookie_state_machine+0x43c/0x1230 [...] ================================================================== Following is the process that triggers the issue: mount | daemon_thread1 | daemon_thread2 ------------------------------------------------------------ cachefiles_ondemand_init_object cachefiles_ondemand_send_req REQ_A = kzalloc(sizeof(*req) + data_len) wait_for_completion(&REQ_A->done) cachefiles_daemon_read cachefiles_ondemand_daemon_read REQ_A = cachefiles_ondemand_select_req cachefiles_ondemand_get_fd copy_to_user(_buffer, msg, n) process_open_req(REQ_A) ------ restore ------ cachefiles_ondemand_restore xas_for_each(&xas, req, ULONG_MAX) xas_set_mark(&xas, CACHEFILES_REQ_NEW); cachefiles_daemon_read cachefiles_ondemand_daemon_read REQ_A = cachefiles_ondemand_select_req write(devfd, ("copen %u,%llu", msg->msg_id, size)); cachefiles_ondemand_copen xa_erase(&cache->reqs, id) complete(&REQ_A->done) kfree(REQ_A) cachefiles_ondemand_get_fd(REQ_A) fd = get_unused_fd_flags file = anon_inode_getfile fd_install(fd, file) load = (void *)REQ_A->msg.data; load->fd = fd; // load UAF !!! This issue is caused by issuing a restore command when the daemon is still alive, which results in a request being processed multiple times thus triggering a UAF. So to avoid this problem, add an additional reference count to cachefiles_req, which is held while waiting and reading, and then released when the waiting and reading is over. Note that since there is only one reference count for waiting, we need to avoid the same request being completed multiple times, so we can only complete the request if it is successfully removed from the xarray. Fixes: e73fa11a356c ("cachefiles: add restore command to recover inflight ondemand read requests") Suggested-by: Hou Tao <[email protected]> Signed-off-by: Baokun Li <[email protected]> Link: https://lore.kernel.org/r/[email protected] Acked-by: Jeff Layton <[email protected]> Reviewed-by: Jia Zhu <[email protected]> Reviewed-by: Jingbo Xu <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
2024-05-29cachefiles: remove requests from xarray during flushing requestsBaokun Li1-0/+1
Even with CACHEFILES_DEAD set, we can still read the requests, so in the following concurrency the request may be used after it has been freed: mount | daemon_thread1 | daemon_thread2 ------------------------------------------------------------ cachefiles_ondemand_init_object cachefiles_ondemand_send_req REQ_A = kzalloc(sizeof(*req) + data_len) wait_for_completion(&REQ_A->done) cachefiles_daemon_read cachefiles_ondemand_daemon_read // close dev fd cachefiles_flush_reqs complete(&REQ_A->done) kfree(REQ_A) xa_lock(&cache->reqs); cachefiles_ondemand_select_req req->msg.opcode != CACHEFILES_OP_READ // req use-after-free !!! xa_unlock(&cache->reqs); xa_destroy(&cache->reqs) Hence remove requests from cache->reqs when flushing them to avoid accessing freed requests. Fixes: c8383054506c ("cachefiles: notify the user daemon when looking up cookie") Signed-off-by: Baokun Li <[email protected]> Link: https://lore.kernel.org/r/[email protected] Acked-by: Jeff Layton <[email protected]> Reviewed-by: Jia Zhu <[email protected]> Reviewed-by: Gao Xiang <[email protected]> Reviewed-by: Jingbo Xu <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
2024-05-28bcachefs: Don't return -EROFS from mount on inconsistency errorKent Overstreet1-2/+10
We were accidentally returning -EROFS during recovery on filesystem inconsistency - since this is what the journal returns on emergency shutdown. Signed-off-by: Kent Overstreet <[email protected]>
2024-05-28bcachefs: Fix uninitialized var warningKent Overstreet2-2/+2
Can't actually be used uninitialized, but gcc was being silly. Signed-off-by: Kent Overstreet <[email protected]>
2024-05-28bcachefs: Split out sb-errors_format.hKent Overstreet3-292/+297
Signed-off-by: Kent Overstreet <[email protected]>
2024-05-28bcachefs: Split out journal_seq_blacklist_format.hKent Overstreet2-10/+16
Signed-off-by: Kent Overstreet <[email protected]>
2024-05-28bcachefs: Split out replicas_format.hKent Overstreet2-32/+36
Signed-off-by: Kent Overstreet <[email protected]>
2024-05-28bcachefs: Split out disk_groups_format.hKent Overstreet2-18/+22
Signed-off-by: Kent Overstreet <[email protected]>
2024-05-28bcachefs: split out sb-downgrade_format.hKent Overstreet2-13/+18
Signed-off-by: Kent Overstreet <[email protected]>
2024-05-28bcachefs: split out sb-members_format.hKent Overstreet2-101/+111
Signed-off-by: Kent Overstreet <[email protected]>
2024-05-28bcachefs: Better fsck error message for key versionKent Overstreet1-4/+5
Signed-off-by: Kent Overstreet <[email protected]>
2024-05-28bcachefs: btree_gc can now handle unknown btreesKent Overstreet5-73/+55
Compatibility fix - we no longer have a separate table for which order gc walks btrees in, and special case the stripes btree directly. Signed-off-by: Kent Overstreet <[email protected]>
2024-05-28bcachefs: add missing MODULE_DESCRIPTION()Jeff Johnson1-0/+1
Fix the 'make W=1' warning: WARNING: modpost: missing MODULE_DESCRIPTION() in fs/bcachefs/mean_and_variance_test.o Signed-off-by: Jeff Johnson <[email protected]> Signed-off-by: Kent Overstreet <[email protected]>
2024-05-28bcachefs: Fix setting of downgrade recovery passes/errorsKent Overstreet1-9/+3
bch2_check_version_downgrade() was setting c->sb.version, which bch2_sb_set_downgrade() expects to be at the previous version; and it shouldn't even have been set directly because c->sb.version is updated by write_super(). Signed-off-by: Kent Overstreet <[email protected]>
2024-05-28bcachefs: Run check_key_has_snapshot in snapshot_delete_keys()Kent Overstreet3-24/+29
delete_dead_snapshots now runs before the main fsck.c passes which check for keys for invalid snapshots; thus, it needs those checks as well. Signed-off-by: Kent Overstreet <[email protected]>
2024-05-28bcachefs: Refactor delete_dead_snapshots()Kent Overstreet1-40/+25
Consolidate per-key work into delete_dead_snapshots_process_key(), so we now walk all keys once, not twice. Signed-off-by: Kent Overstreet <[email protected]>
2024-05-28bcachefs: Fix locking assertKent Overstreet1-5/+5
We now track whether a transaction is locked, and verify that we don't have nodes locked when the transaction isn't locked; reorder relocks to not pop the new assert. Signed-off-by: Kent Overstreet <[email protected]>
2024-05-28bcachefs: Fix lookup_first_inode() when inode_generations are presentKent Overstreet1-14/+10
This function is used for finding the hash seed (which is the same in all versions of an inode in different snapshots): ff an inode has been deleted in a child snapshot we need to iterate until we find a live version. Signed-off-by: Kent Overstreet <[email protected]>
2024-05-28bcachefs: Plumb bkey into __btree_err()Kent Overstreet1-40/+45
It can be useful to know the exact byte offset within a btree node where an error occured. Signed-off-by: Kent Overstreet <[email protected]>
2024-05-28gfs2: Rename handle_callback to request_demoteAndreas Gruenbacher1-10/+10
Function handle_callback() is used to request a glock demote. This often happens in response to a conflicting remote locking request and subsequent bast callback from DLM, but there are other reasons for triggering a demote request as well, such as when trying to release a glock in response to memory pressure. To clarify that, rename the function to request_demote(). Signed-off-by: Andreas Gruenbacher <[email protected]>
2024-05-28gfs2: Rename GLF_FROZEN to GLF_HAVE_FROZEN_REPLYAndreas Gruenbacher3-6/+6
The GLF_FROZEN flag indicates that a reply to a DLM locking request has been received, but should not be processed at this time. To clarify that meaning, rename the flag to GLF_HAVE_FROZEN_REPLY. Signed-off-by: Andreas Gruenbacher <[email protected]>
2024-05-28gfs2: Rename GLF_REPLY_PENDING to GLF_HAVE_REPLYAndreas Gruenbacher3-9/+9
The GLF_REPLY_PENDING flag indicates to glock_work_func() that in response to a locking request, DLM has sent a reply that needs to be processed. A flag with that name could as well indicate that we are waiting on a reply from DLM, however. To disambiguate these two cases, rename the flag to GLF_HAVE_REPLY. Signed-off-by: Andreas Gruenbacher <[email protected]>
2024-05-28gfs2: Rename GLF_FREEING to GLF_UNLOCKEDAndreas Gruenbacher5-16/+16
Rename the GLF_FREEING flag to GLF_UNLOCKED, and the ->go_free glock operation to ->go_unlocked. This mechanism is used to wait for the underlying DLM lock to be unlocked; being able to free the glock is a consequence of the DLM lock being unlocked. Signed-off-by: Andreas Gruenbacher <[email protected]>
2024-05-28gfs2: Remove useless return statement in run_queueAndreas Gruenbacher1-1/+0
The return statement at the end of run_queue() is useless. Signed-off-by: Andreas Gruenbacher <[email protected]>
2024-05-28gfs2: Remove unnecessary function prototypeAndreas Gruenbacher1-1/+0
Function __gfs2_glock_dq() gets defined before it is used, so there is no need for a separate function declaration. Signed-off-by: Andreas Gruenbacher <[email protected]>
2024-05-28btrfs: ensure fast fsync waits for ordered extents after a write failureFilipe Manana3-0/+57
If a write path in COW mode fails, either before submitting a bio for the new extents or an actual IO error happens, we can end up allowing a fast fsync to log file extent items that point to unwritten extents. This is because dropping the extent maps happens when completing ordered extents, at btrfs_finish_one_ordered(), and the completion of an ordered extent is executed in a work queue. This can result in a fast fsync to start logging file extent items based on existing extent maps before the ordered extents complete, therefore resulting in a log that has file extent items that point to unwritten extents, resulting in a corrupt file if a crash happens after and the log tree is replayed the next time the fs is mounted. This can happen for both direct IO writes and buffered writes. For example consider a direct IO write, in COW mode, that fails at btrfs_dio_submit_io() because btrfs_extract_ordered_extent() returned an error: 1) We call btrfs_finish_ordered_extent() with the 'uptodate' parameter set to false, meaning an error happened; 2) That results in marking the ordered extent with the BTRFS_ORDERED_IOERR flag; 3) btrfs_finish_ordered_extent() queues the completion of the ordered extent - so that btrfs_finish_one_ordered() will be executed later in a work queue. That function will drop extent maps in the range when it's executed, since the extent maps point to unwritten locations (signaled by the BTRFS_ORDERED_IOERR flag); 4) After calling btrfs_finish_ordered_extent() we keep going down the write path and unlock the inode; 5) After that a fast fsync starts and locks the inode; 6) Before the work queue executes btrfs_finish_one_ordered(), the fsync task sees the extent maps that point to the unwritten locations and logs file extent items based on them - it does not know they are unwritten, and the fast fsync path does not wait for ordered extents to complete, which is an intentional behaviour in order to reduce latency. For the buffered write case, here's one example: 1) A fast fsync begins, and it starts by flushing delalloc and waiting for the writeback to complete by calling filemap_fdatawait_range(); 2) Flushing the dellaloc created a new extent map X; 3) During the writeback some IO error happened, and at the end io callback (end_bbio_data_write()) we call btrfs_finish_ordered_extent(), which sets the BTRFS_ORDERED_IOERR flag in the ordered extent and queues its completion; 4) After queuing the ordered extent completion, the end io callback clears the writeback flag from all pages (or folios), and from that moment the fast fsync can proceed; 5) The fast fsync proceeds sees extent map X and logs a file extent item based on extent map X, resulting in a log that points to an unwritten data extent - because the ordered extent completion hasn't run yet, it happens only after the logging. To fix this make btrfs_finish_ordered_extent() set the inode flag BTRFS_INODE_NEEDS_FULL_SYNC in case an error happened for a COW write, so that a fast fsync will wait for ordered extent completion. Note that this issues of using extent maps that point to unwritten locations can not happen for reads, because in read paths we start by locking the extent range and wait for any ordered extents in the range to complete before looking for extent maps. Reviewed-by: Qu Wenruo <[email protected]> Signed-off-by: Filipe Manana <[email protected]> Signed-off-by: David Sterba <[email protected]>
2024-05-28fhandle: relax open_by_handle_at() permission checksChristian Brauner5-42/+150
A current limitation of open_by_handle_at() is that it's currently not possible to use it from within containers at all because we require CAP_DAC_READ_SEARCH in the initial namespace. That's unfortunate because there are scenarios where using open_by_handle_at() from within containers. Two examples: (1) cgroupfs allows to encode cgroups to file handles and reopen them with open_by_handle_at(). (2) Fanotify allows placing filesystem watches they currently aren't usable in containers because the returned file handles cannot be used. Here's a proposal for relaxing the permission check for open_by_handle_at(). (1) Opening file handles when the caller has privileges over the filesystem (1.1) The caller has an unobstructed view of the filesystem. (1.2) The caller has permissions to follow a path to the file handle. This doesn't address the problem of opening a file handle when only a portion of a filesystem is exposed as is common in containers by e.g., bind-mounting a subtree. The proposal to solve this use-case is: (2) Opening file handles when the caller has privileges over a subtree (2.1) The caller is able to reach the file from the provided mount fd. (2.2) The caller has permissions to construct an unobstructed path to the file handle. (2.3) The caller has permissions to follow a path to the file handle. The relaxed permission checks are currently restricted to directory file handles which are what both cgroupfs and fanotify need. Handling disconnected non-directory file handles would lead to a potentially non-deterministic api. If a disconnected non-directory file handle is provided we may fail to decode a valid path that we could use for permission checking. That in itself isn't a problem as we would just return EACCES in that case. However, confusion may arise if a non-disconnected dentry ends up in the cache later and those opening the file handle would suddenly succeed. * It's potentially possible to use timing information (side-channel) to infer whether a given inode exists. I don't think that's particularly problematic. Thanks to Jann for bringing this to my attention. * An unrelated note (IOW, these are thoughts that apply to open_by_handle_at() generically and are unrelated to the changes here): Jann pointed out that we should verify whether deleted files could potentially be reopened through open_by_handle_at(). I don't think that's possible though. Another potential thing to check is whether open_by_handle_at() could be abused to open internal stuff like memfds or gpu stuff. I don't think so but I haven't had the time to completely verify this. This dates back to discussions Amir and I had quite some time ago and thanks to him for providing a lot of details around the export code and related patches! Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Amir Goldstein <[email protected]> Reviewed-by: Jeff Layton <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
2024-05-28debugfs: continue to ignore unknown mount optionsChristian Brauner1-1/+9
Wolfram reported that debugfs remained empty on some of his boards triggering the message "debugfs: Unknown parameter 'auto'". The root of the issue is that we ignored unknown mount options in the old mount api but we started rejecting unknown mount options in the new mount api. Continue to ignore unknown mount options to not regress userspace. Fixes: a20971c18752 ("vfs: Convert debugfs to use the new mount API") Link: https://lore.kernel.org/r/20240527100618.np2wqiw5mz7as3vk@ninjato Reported-by: Wolfram Sang <[email protected]> Tested-by: Wolfram Sang <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
2024-05-28fs: autofs: add MODULE_DESCRIPTION()Jeff Johnson1-0/+1
Fix the 'make W=1' warning: WARNING: modpost: missing MODULE_DESCRIPTION() in fs/autofs/autofs4.o Signed-off-by: Jeff Johnson <[email protected]> Link: https://lore.kernel.org/r/[email protected] Acked-by: Al Viro <[email protected]> Acked-by: Ian Kent <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
2024-05-28fs: fat: add missing MODULE_DESCRIPTION() macrosJeff Johnson2-0/+2
Fix the 'make W=1' warnings: WARNING: modpost: missing MODULE_DESCRIPTION() in fs/fat/fat.o WARNING: modpost: missing MODULE_DESCRIPTION() in fs/fat/fat_test.o Signed-off-by: Jeff Johnson <[email protected]> Link: https://lore.kernel.org/r/[email protected] Acked-by: OGAWA Hirofumi <[email protected]> Acked-by: Al Viro <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
2024-05-28fs: binfmt: add missing MODULE_DESCRIPTION() macrosJeff Johnson2-0/+2
Fix the 'make W=1' warnings: WARNING: modpost: missing MODULE_DESCRIPTION() in fs/binfmt_misc.o WARNING: modpost: missing MODULE_DESCRIPTION() in fs/binfmt_script.o Signed-off-by: Jeff Johnson <[email protected]> Link: https://lore.kernel.org/r/[email protected] Acked-by: Al Viro <[email protected]> Signed-off-by: Christian Brauner <[email protected]>