diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-10-02 12:17:24 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-10-02 12:17:24 -0700 |
| commit | 3f1fe48a36b0b6722dc3fd421d93512bac138e9a (patch) | |
| tree | b767d7f6e26bc64334d3f14f8422d187239dc45d /fs/ntfs/object_id.c | |
| download | linux-stable-3f1fe48a36b0b6722dc3fd421d93512bac138e9a.tar.gz linux-stable-3f1fe48a36b0b6722dc3fd421d93512bac138e9a.zip | |
Merge tag 'io_uring-7.3-20261002' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linuxgrafted
Pull io_uring fixes from Jens Axboe:
- Fix a task_work add use-after-free with SQPOLL.
The sqpoll thread could pop and complete the last request while
io_req_normal_work_add() was still looking at them after the mpscq
push.
Use the same approach as DEFER_TASKRUN to protect from that, holding
an RCU read lock across the add, and have exit wait for an RCU grace
period for SQPOLL rings as well.
- CQE32 ring fixes: correct the free entry check for 32b CQEs, zero the
big_cqe for aux CQEs, and only post the dummy skip CQE on CQE_MIXED
rings
- Mark the source filter table as COW when cloning bpf filters, so
registering another filter on the source doesn't modify the shared
table in place
- Initialize the task context before running the BPF loop
- Requeue zcrx multishot receives stopped by a local resource
- End a TX_TIMESTAMP multishot cmd when the CQ is full (lollipopkit)
* tag 'io_uring-7.3-20261002' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux:
io_uring: fix task_work add use-after-free with SQPOLL
io_uring/cmd_net: end TX_TIMESTAMP multishot when the CQ is full
io_uring/zcrx: requeue multishot receives stopped by a local resource
io_uring: initialize task context before running the BPF loop
io_uring: zero big_cqe for aux CQEs on CQE32 rings
io_uring: fix free entry check for 32b CQEs on CQE32 rings
io_uring: only post the dummy skip CQE on CQE_MIXED rings
io_uring/bpf_filter: mark source as COW when cloning filters
Diffstat (limited to 'fs/ntfs/object_id.c')
| -rw-r--r-- | fs/ntfs/object_id.c | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/fs/ntfs/object_id.c b/fs/ntfs/object_id.c new file mode 100644 index 000000000..89002c375 --- /dev/null +++ b/fs/ntfs/object_id.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Pocessing of object ids + * + * Part of this file is based on code from the NTFS-3G. + * + * Copyright (c) 2009-2019 Jean-Pierre Andre + * Copyright (c) 2026 LG Electronics Co., Ltd. + */ + +#include "ntfs.h" +#include "index.h" +#include "object_id.h" + +struct object_id_index_key { + union { + u32 alignment; + struct guid guid; + } object_id; +} __packed; + +struct object_id_index_data { + __le64 file_id; + struct guid birth_volume_id; + struct guid birth_object_id; + struct guid domain_id; +} __packed; + +/* Index entry in $Extend/$ObjId */ +struct object_id_index { + struct index_entry_header header; + struct object_id_index_key key; + struct object_id_index_data data; +} __packed; + +__le16 objid_index_name[] = {cpu_to_le16('$'), cpu_to_le16('O'), 0}; + +/* + * open_object_id_index - Open the $Extend/$ObjId file and its index + * @vol: NTFS volume structure + * + * Opens the $ObjId system file and retrieves its index context. + * + * Return: The index context if opened successfully, or NULL if an error + * occurred. + */ +static struct ntfs_index_context *open_object_id_index(struct ntfs_volume *vol) +{ + struct inode *dir_vi, *vi; + struct ntfs_inode *dir_ni; + struct ntfs_index_context *xo = NULL; + struct ntfs_name *name = NULL; + u64 mref; + int uname_len; + __le16 *uname; + + uname_len = ntfs_nlstoucs(vol, "$ObjId", 6, &uname, + NTFS_MAX_NAME_LEN); + if (uname_len < 0) + return NULL; + + /* do not use path_name_to inode - could reopen root */ + dir_vi = ntfs_iget(vol->sb, FILE_Extend); + if (IS_ERR(dir_vi)) { + kmem_cache_free(ntfs_name_cache, uname); + return NULL; + } + dir_ni = NTFS_I(dir_vi); + + mutex_lock_nested(&dir_ni->mrec_lock, NTFS_EXTEND_MUTEX_PARENT); + mref = ntfs_lookup_inode_by_name(dir_ni, uname, uname_len, &name); + mutex_unlock(&dir_ni->mrec_lock); + kfree(name); + kmem_cache_free(ntfs_name_cache, uname); + if (IS_ERR_MREF(mref)) + goto put_dir_vi; + + vi = ntfs_iget(vol->sb, MREF(mref)); + if (IS_ERR(vi)) + goto put_dir_vi; + + xo = ntfs_index_ctx_get(NTFS_I(vi), objid_index_name, 2); + if (!xo) + iput(vi); +put_dir_vi: + iput(dir_vi); + return xo; +} + + +/* + * remove_object_id_index - Remove an object id index entry if attribute present + * @ni: NTFS inode structure containing the attribute + * @xo: Index context for the object id index + * + * Reads the existing object ID attribute and removes it from the index. + * + * Return: 0 on success, or a negative error code on failure. + */ +static int remove_object_id_index(struct ntfs_inode *ni, struct ntfs_index_context *xo) +{ + struct object_id_index_key key = {0}; + s64 size; + + if (ni->data_size == 0) + return -ENODATA; + + /* read the existing object id attribute */ + size = ntfs_inode_attr_pread(VFS_I(ni), 0, sizeof(struct guid), + (char *)&key); + if (size != sizeof(struct guid)) + return -ENODATA; + + if (!ntfs_index_lookup(&key, sizeof(struct object_id_index_key), xo)) + return ntfs_index_rm(xo); + + return 0; +} + +/* + * ntfs_delete_object_id_index - Delete an object_id index entry + * @ni: NTFS inode structure + * + * Opens the object ID index and removes the entry corresponding to the inode. + * + * Return: 0 on success, or a negative error code on failure. + */ +int ntfs_delete_object_id_index(struct ntfs_inode *ni) +{ + struct ntfs_index_context *xo; + struct ntfs_inode *xoni; + struct inode *attr_vi; + int ret = 0; + + attr_vi = ntfs_attr_iget(VFS_I(ni), AT_OBJECT_ID, AT_UNNAMED, 0); + if (IS_ERR(attr_vi)) + return PTR_ERR(attr_vi); + + /* + * read the existing object id and un-index it + */ + xo = open_object_id_index(ni->vol); + if (xo) { + xoni = xo->idx_ni; + mutex_lock_nested(&xoni->mrec_lock, NTFS_EXTEND_MUTEX_PARENT); + ret = remove_object_id_index(NTFS_I(attr_vi), xo); + if (!ret) { + ntfs_index_entry_mark_dirty(xo); + mark_mft_record_dirty(xoni); + } + ntfs_index_ctx_put(xo); + mutex_unlock(&xoni->mrec_lock); + iput(VFS_I(xoni)); + } + + iput(attr_vi); + return ret; +} |
