mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
Updates various miscellaneous operations including collation, debugging, logfile handling, unicode string processing, bdev io helpers, object id system file handling. Acked-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
159 lines
3.8 KiB
C
159 lines
3.8 KiB
C
// 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;
|
|
}
|