Changes for 6.17-rc1

Added:
     sanity check for file name;
     mark live inode as bad and avoid any operations.
 
 Fixed:
     handling of symlinks created in windows;
     creation of symlinks for relative path.
 
 Changed:
     cancel setting inode as bad after removing name fails;
     revert "replace inode_trylock with inode_lock".
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEh0DEKNP0I9IjwfWEqbAzH4MkB7YFAmiDiMwACgkQqbAzH4Mk
 B7aJFg//Q/L5xNxtXf3bUDCGhEYfex2qvvSnMg8MZEcLXJI9DW/Z701Xs7ay8BBL
 Gp982rSX87hnnA/+1YutzAEiyTCnwRWPKNocrfPEqzXDFl4t/4Rua1Wf+Bw2/p5C
 YjGd8zFbFel3NDkZa94KSCV6ATsPMnF3UN3Zj0+izyoaxQPnpoAaaOsxS2PlK+97
 ePZ9PWeAe6vjW3myKQzSKz8vjeb2bNK3R67Z27igCi78jjsuI6BomBhKjGN3iOk5
 eZjCrWL+DesTN43EyV8yL72Mha+BvT5XQx83gzBKghhKCBXa2BMZo3l+KDI4pGr6
 Mmynw1i+o1Z+P+xvCAPEiil6x6DNauUCUtgKJEEoRatGjGOPRM4U/NWZiXITZuFD
 zkSmToA3ZtJA0XBHRnoPSDg0wEQ965sy6lsGs/O1sUfURJ51lc9EwmnWmGmq4Fs+
 HZ3aNbaizi1TEx89R+BEaE7bZqSK0cv4nHHtcepTgVimgSzz02uvCpz9SLLs3JsB
 g9a3b6M68Rtex2+unos5Cw9Afq1Y34wcPFn9rAK8+LashAgKKhRuUqwTaZ1k7nMU
 hZIFsXCxvgnQgmbF5Dod8uA/2eO+U7BXixZWvGqhAliPuLSrubhb7dZrSANRkFlt
 lv9qLmrcD/cpa/JvnrqOf6NyEc9vFoowvio3JQxkIhf7wQviv44=
 =OGQG
 -----END PGP SIGNATURE-----

Merge tag 'ntfs3_for_6.17' of https://github.com/Paragon-Software-Group/linux-ntfs3

Pull ntfs3 updates from Konstantin Komarov:
 "Added:
   - sanity check for file name
   - mark live inode as bad and avoid any operations

  Fixed:
   - handling of symlinks created in windows
   - creation of symlinks for relative path

  Changed:
   - cancel setting inode as bad after removing name fails
   - revert 'replace inode_trylock with inode_lock'"

* tag 'ntfs3_for_6.17' of https://github.com/Paragon-Software-Group/linux-ntfs3:
  Revert "fs/ntfs3: Replace inode_trylock with inode_lock"
  fs/ntfs3: Exclude call make_bad_inode for live nodes.
  fs/ntfs3: cancle set bad inode after removing name fails
  fs/ntfs3: Add sanity check for file name
  fs/ntfs3: correctly create symlink for relative path
  fs/ntfs3: fix symlinks cannot be handled correctly
This commit is contained in:
Linus Torvalds 2025-07-28 08:46:55 -07:00
commit a11b4fa602
9 changed files with 178 additions and 61 deletions

View File

@ -304,6 +304,9 @@ static inline bool ntfs_dir_emit(struct ntfs_sb_info *sbi,
if (sbi->options->nohidden && (fname->dup.fa & FILE_ATTRIBUTE_HIDDEN))
return true;
if (fname->name_len + sizeof(struct NTFS_DE) > le16_to_cpu(e->size))
return true;
name_len = ntfs_utf16_to_nls(sbi, fname->name, fname->name_len, name,
PATH_MAX);
if (name_len <= 0) {
@ -329,8 +332,7 @@ static inline bool ntfs_dir_emit(struct ntfs_sb_info *sbi,
* It does additional locks/reads just to get the type of name.
* Should we use additional mount option to enable branch below?
*/
if (((fname->dup.fa & FILE_ATTRIBUTE_REPARSE_POINT) ||
fname->dup.ea_size) &&
if (fname->dup.extend_data &&
ino != ni->mi.rno) {
struct inode *inode = ntfs_iget5(sbi->sb, &e->ref, NULL);
if (!IS_ERR_OR_NULL(inode)) {

View File

@ -57,6 +57,10 @@ long ntfs_ioctl(struct file *filp, u32 cmd, unsigned long arg)
struct inode *inode = file_inode(filp);
struct ntfs_sb_info *sbi = inode->i_sb->s_fs_info;
/* Avoid any operation if inode is bad. */
if (unlikely(is_bad_ni(ntfs_i(inode))))
return -EINVAL;
switch (cmd) {
case FITRIM:
return ntfs_ioctl_fitrim(sbi, arg);
@ -81,6 +85,10 @@ int ntfs_getattr(struct mnt_idmap *idmap, const struct path *path,
struct inode *inode = d_inode(path->dentry);
struct ntfs_inode *ni = ntfs_i(inode);
/* Avoid any operation if inode is bad. */
if (unlikely(is_bad_ni(ni)))
return -EINVAL;
stat->result_mask |= STATX_BTIME;
stat->btime = ni->i_crtime;
stat->blksize = ni->mi.sbi->cluster_size; /* 512, 1K, ..., 2M */
@ -271,6 +279,10 @@ static int ntfs_file_mmap(struct file *file, struct vm_area_struct *vma)
bool rw = vma->vm_flags & VM_WRITE;
int err;
/* Avoid any operation if inode is bad. */
if (unlikely(is_bad_ni(ni)))
return -EINVAL;
if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
return -EIO;
@ -310,7 +322,10 @@ static int ntfs_file_mmap(struct file *file, struct vm_area_struct *vma)
}
if (ni->i_valid < to) {
inode_lock(inode);
if (!inode_trylock(inode)) {
err = -EAGAIN;
goto out;
}
err = ntfs_extend_initialized_size(file, ni,
ni->i_valid, to);
inode_unlock(inode);
@ -735,6 +750,10 @@ int ntfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
umode_t mode = inode->i_mode;
int err;
/* Avoid any operation if inode is bad. */
if (unlikely(is_bad_ni(ni)))
return -EINVAL;
if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
return -EIO;
@ -795,6 +814,10 @@ static int check_read_restriction(struct inode *inode)
{
struct ntfs_inode *ni = ntfs_i(inode);
/* Avoid any operation if inode is bad. */
if (unlikely(is_bad_ni(ni)))
return -EINVAL;
if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
return -EIO;
@ -1130,6 +1153,10 @@ static int check_write_restriction(struct inode *inode)
{
struct ntfs_inode *ni = ntfs_i(inode);
/* Avoid any operation if inode is bad. */
if (unlikely(is_bad_ni(ni)))
return -EINVAL;
if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
return -EIO;
@ -1212,6 +1239,10 @@ int ntfs_file_open(struct inode *inode, struct file *file)
{
struct ntfs_inode *ni = ntfs_i(inode);
/* Avoid any operation if inode is bad. */
if (unlikely(is_bad_ni(ni)))
return -EINVAL;
if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
return -EIO;
@ -1281,6 +1312,10 @@ int ntfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
int err;
struct ntfs_inode *ni = ntfs_i(inode);
/* Avoid any operation if inode is bad. */
if (unlikely(is_bad_ni(ni)))
return -EINVAL;
err = fiemap_prep(inode, fieinfo, start, &len, ~FIEMAP_FLAG_XATTR);
if (err)
return err;

View File

@ -3003,8 +3003,7 @@ int ni_add_name(struct ntfs_inode *dir_ni, struct ntfs_inode *ni,
* ni_rename - Remove one name and insert new name.
*/
int ni_rename(struct ntfs_inode *dir_ni, struct ntfs_inode *new_dir_ni,
struct ntfs_inode *ni, struct NTFS_DE *de, struct NTFS_DE *new_de,
bool *is_bad)
struct ntfs_inode *ni, struct NTFS_DE *de, struct NTFS_DE *new_de)
{
int err;
struct NTFS_DE *de2 = NULL;
@ -3027,8 +3026,8 @@ int ni_rename(struct ntfs_inode *dir_ni, struct ntfs_inode *new_dir_ni,
err = ni_add_name(new_dir_ni, ni, new_de);
if (!err) {
err = ni_remove_name(dir_ni, ni, de, &de2, &undo);
if (err && ni_remove_name(new_dir_ni, ni, new_de, &de2, &undo))
*is_bad = true;
WARN_ON(err && ni_remove_name(new_dir_ni, ni, new_de, &de2,
&undo));
}
/*
@ -3119,11 +3118,21 @@ static bool ni_update_parent(struct ntfs_inode *ni, struct NTFS_DUP_INFO *dup,
}
}
/* TODO: Fill reparse info. */
dup->reparse = 0;
dup->ea_size = 0;
dup->extend_data = 0;
if (ni->ni_flags & NI_FLAG_EA) {
if (dup->fa & FILE_ATTRIBUTE_REPARSE_POINT) {
attr = ni_find_attr(ni, NULL, NULL, ATTR_REPARSE, NULL, 0, NULL,
NULL);
if (attr) {
const struct REPARSE_POINT *rp;
rp = resident_data_ex(attr, sizeof(struct REPARSE_POINT));
/* If ATTR_REPARSE exists 'rp' can't be NULL. */
if (rp)
dup->extend_data = rp->ReparseTag;
}
} else if (ni->ni_flags & NI_FLAG_EA) {
attr = ni_find_attr(ni, attr, &le, ATTR_EA_INFO, NULL, 0, NULL,
NULL);
if (attr) {
@ -3132,7 +3141,7 @@ static bool ni_update_parent(struct ntfs_inode *ni, struct NTFS_DUP_INFO *dup,
info = resident_data_ex(attr, sizeof(struct EA_INFO));
/* If ATTR_EA_INFO exists 'info' can't be NULL. */
if (info)
dup->ea_size = info->size_pack;
dup->extend_data = info->size;
}
}
@ -3199,6 +3208,10 @@ int ni_write_inode(struct inode *inode, int sync, const char *hint)
if (is_bad_inode(inode) || sb_rdonly(sb))
return 0;
/* Avoid any operation if inode is bad. */
if (unlikely(is_bad_ni(ni)))
return -EINVAL;
if (unlikely(ntfs3_forced_shutdown(sb)))
return -EIO;

View File

@ -905,9 +905,13 @@ void ntfs_update_mftmirr(struct ntfs_sb_info *sbi, int wait)
void ntfs_bad_inode(struct inode *inode, const char *hint)
{
struct ntfs_sb_info *sbi = inode->i_sb->s_fs_info;
struct ntfs_inode *ni = ntfs_i(inode);
ntfs_inode_err(inode, "%s", hint);
make_bad_inode(inode);
/* Do not call make_bad_inode()! */
ni->ni_bad = true;
/* Avoid recursion if bad inode is $Volume. */
if (inode->i_ino != MFT_REC_VOL &&
!(sbi->flags & NTFS_FLAGS_LOG_REPLAYING)) {

View File

@ -878,6 +878,10 @@ static int ntfs_resident_writepage(struct folio *folio,
struct ntfs_inode *ni = ntfs_i(inode);
int ret;
/* Avoid any operation if inode is bad. */
if (unlikely(is_bad_ni(ni)))
return -EINVAL;
if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
return -EIO;
@ -896,6 +900,10 @@ static int ntfs_writepages(struct address_space *mapping,
{
struct inode *inode = mapping->host;
/* Avoid any operation if inode is bad. */
if (unlikely(is_bad_ni(ntfs_i(inode))))
return -EINVAL;
if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
return -EIO;
@ -919,6 +927,10 @@ int ntfs_write_begin(struct file *file, struct address_space *mapping,
struct inode *inode = mapping->host;
struct ntfs_inode *ni = ntfs_i(inode);
/* Avoid any operation if inode is bad. */
if (unlikely(is_bad_ni(ni)))
return -EINVAL;
if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
return -EIO;
@ -1062,10 +1074,10 @@ int inode_read_data(struct inode *inode, void *data, size_t bytes)
* Number of bytes for REPARSE_DATA_BUFFER(IO_REPARSE_TAG_SYMLINK)
* for unicode string of @uni_len length.
*/
static inline u32 ntfs_reparse_bytes(u32 uni_len)
static inline u32 ntfs_reparse_bytes(u32 uni_len, bool is_absolute)
{
/* Header + unicode string + decorated unicode string. */
return sizeof(short) * (2 * uni_len + 4) +
return sizeof(short) * (2 * uni_len + (is_absolute ? 4 : 0)) +
offsetof(struct REPARSE_DATA_BUFFER,
SymbolicLinkReparseBuffer.PathBuffer);
}
@ -1078,8 +1090,11 @@ ntfs_create_reparse_buffer(struct ntfs_sb_info *sbi, const char *symname,
struct REPARSE_DATA_BUFFER *rp;
__le16 *rp_name;
typeof(rp->SymbolicLinkReparseBuffer) *rs;
bool is_absolute;
rp = kzalloc(ntfs_reparse_bytes(2 * size + 2), GFP_NOFS);
is_absolute = (strlen(symname) > 1 && symname[1] == ':');
rp = kzalloc(ntfs_reparse_bytes(2 * size + 2, is_absolute), GFP_NOFS);
if (!rp)
return ERR_PTR(-ENOMEM);
@ -1094,7 +1109,7 @@ ntfs_create_reparse_buffer(struct ntfs_sb_info *sbi, const char *symname,
goto out;
/* err = the length of unicode name of symlink. */
*nsize = ntfs_reparse_bytes(err);
*nsize = ntfs_reparse_bytes(err, is_absolute);
if (*nsize > sbi->reparse.max_size) {
err = -EFBIG;
@ -1114,7 +1129,7 @@ ntfs_create_reparse_buffer(struct ntfs_sb_info *sbi, const char *symname,
/* PrintName + SubstituteName. */
rs->SubstituteNameOffset = cpu_to_le16(sizeof(short) * err);
rs->SubstituteNameLength = cpu_to_le16(sizeof(short) * err + 8);
rs->SubstituteNameLength = cpu_to_le16(sizeof(short) * err + (is_absolute ? 8 : 0));
rs->PrintNameLength = rs->SubstituteNameOffset;
/*
@ -1122,16 +1137,18 @@ ntfs_create_reparse_buffer(struct ntfs_sb_info *sbi, const char *symname,
* parse this path.
* 0-absolute path 1- relative path (SYMLINK_FLAG_RELATIVE).
*/
rs->Flags = 0;
rs->Flags = cpu_to_le32(is_absolute ? 0 : SYMLINK_FLAG_RELATIVE);
memmove(rp_name + err + 4, rp_name, sizeof(short) * err);
memmove(rp_name + err + (is_absolute ? 4 : 0), rp_name, sizeof(short) * err);
/* Decorate SubstituteName. */
rp_name += err;
rp_name[0] = cpu_to_le16('\\');
rp_name[1] = cpu_to_le16('?');
rp_name[2] = cpu_to_le16('?');
rp_name[3] = cpu_to_le16('\\');
if (is_absolute) {
/* Decorate SubstituteName. */
rp_name += err;
rp_name[0] = cpu_to_le16('\\');
rp_name[1] = cpu_to_le16('?');
rp_name[2] = cpu_to_le16('?');
rp_name[3] = cpu_to_le16('\\');
}
return rp;
out:
@ -1260,6 +1277,12 @@ int ntfs_create_inode(struct mnt_idmap *idmap, struct inode *dir,
goto out1;
}
/* Avoid any operation if inode is bad. */
if (unlikely(is_bad_ni(dir_ni))) {
err = -EINVAL;
goto out2;
}
if (unlikely(ntfs3_forced_shutdown(sb))) {
err = -EIO;
goto out2;
@ -1350,7 +1373,7 @@ int ntfs_create_inode(struct mnt_idmap *idmap, struct inode *dir,
fname->dup.a_time = std5->cr_time;
fname->dup.alloc_size = fname->dup.data_size = 0;
fname->dup.fa = std5->fa;
fname->dup.ea_size = fname->dup.reparse = 0;
fname->dup.extend_data = S_ISLNK(mode) ? IO_REPARSE_TAG_SYMLINK : 0;
dsize = le16_to_cpu(new_de->key_size);
asize = ALIGN(SIZEOF_RESIDENT + dsize, 8);
@ -1590,27 +1613,29 @@ int ntfs_create_inode(struct mnt_idmap *idmap, struct inode *dir,
inode->i_flags |= S_NOSEC;
}
/*
* ntfs_init_acl and ntfs_save_wsl_perm update extended attribute.
* The packed size of extended attribute is stored in direntry too.
* 'fname' here points to inside new_de.
*/
err = ntfs_save_wsl_perm(inode, &fname->dup.ea_size);
if (err)
goto out6;
if (!S_ISLNK(mode)) {
/*
* ntfs_init_acl and ntfs_save_wsl_perm update extended attribute.
* The packed size of extended attribute is stored in direntry too.
* 'fname' here points to inside new_de.
*/
err = ntfs_save_wsl_perm(inode, &fname->dup.extend_data);
if (err)
goto out6;
/*
* update ea_size in file_name attribute too.
* Use ni_find_attr cause layout of MFT record may be changed
* in ntfs_init_acl and ntfs_save_wsl_perm.
*/
attr = ni_find_attr(ni, NULL, NULL, ATTR_NAME, NULL, 0, NULL, NULL);
if (attr) {
struct ATTR_FILE_NAME *fn;
/*
* update ea_size in file_name attribute too.
* Use ni_find_attr cause layout of MFT record may be changed
* in ntfs_init_acl and ntfs_save_wsl_perm.
*/
attr = ni_find_attr(ni, NULL, NULL, ATTR_NAME, NULL, 0, NULL, NULL);
if (attr) {
struct ATTR_FILE_NAME *fn;
fn = resident_data_ex(attr, SIZEOF_ATTRIBUTE_FILENAME);
if (fn)
fn->dup.ea_size = fname->dup.ea_size;
fn = resident_data_ex(attr, SIZEOF_ATTRIBUTE_FILENAME);
if (fn)
fn->dup.extend_data = fname->dup.extend_data;
}
}
/* We do not need to update parent directory later */

View File

@ -171,6 +171,10 @@ static int ntfs_unlink(struct inode *dir, struct dentry *dentry)
struct ntfs_inode *ni = ntfs_i(dir);
int err;
/* Avoid any operation if inode is bad. */
if (unlikely(is_bad_ni(ni)))
return -EINVAL;
if (unlikely(ntfs3_forced_shutdown(dir->i_sb)))
return -EIO;
@ -191,6 +195,10 @@ static int ntfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
{
u32 size = strlen(symname);
/* Avoid any operation if inode is bad. */
if (unlikely(is_bad_ni(ntfs_i(dir))))
return -EINVAL;
if (unlikely(ntfs3_forced_shutdown(dir->i_sb)))
return -EIO;
@ -216,6 +224,10 @@ static int ntfs_rmdir(struct inode *dir, struct dentry *dentry)
struct ntfs_inode *ni = ntfs_i(dir);
int err;
/* Avoid any operation if inode is bad. */
if (unlikely(is_bad_ni(ni)))
return -EINVAL;
if (unlikely(ntfs3_forced_shutdown(dir->i_sb)))
return -EIO;
@ -244,7 +256,7 @@ static int ntfs_rename(struct mnt_idmap *idmap, struct inode *dir,
struct ntfs_inode *ni = ntfs_i(inode);
struct inode *new_inode = d_inode(new_dentry);
struct NTFS_DE *de, *new_de;
bool is_same, is_bad;
bool is_same;
/*
* de - memory of PATH_MAX bytes:
* [0-1024) - original name (dentry->d_name)
@ -256,6 +268,10 @@ static int ntfs_rename(struct mnt_idmap *idmap, struct inode *dir,
1024);
static_assert(PATH_MAX >= 4 * 1024);
/* Avoid any operation if inode is bad. */
if (unlikely(is_bad_ni(ni)))
return -EINVAL;
if (unlikely(ntfs3_forced_shutdown(sb)))
return -EIO;
@ -313,12 +329,8 @@ static int ntfs_rename(struct mnt_idmap *idmap, struct inode *dir,
if (dir_ni != new_dir_ni)
ni_lock_dir2(new_dir_ni);
is_bad = false;
err = ni_rename(dir_ni, new_dir_ni, ni, de, new_de, &is_bad);
if (is_bad) {
/* Restore after failed rename failed too. */
_ntfs_bad_inode(inode);
} else if (!err) {
err = ni_rename(dir_ni, new_dir_ni, ni, de, new_de);
if (!err) {
simple_rename_timestamp(dir, dentry, new_dir, new_dentry);
mark_inode_dirty(inode);
mark_inode_dirty(dir);

View File

@ -561,8 +561,7 @@ struct NTFS_DUP_INFO {
__le64 alloc_size; // 0x20: Data attribute allocated size, multiple of cluster size.
__le64 data_size; // 0x28: Data attribute size <= Dataalloc_size.
enum FILE_ATTRIBUTE fa; // 0x30: Standard DOS attributes & more.
__le16 ea_size; // 0x34: Packed EAs.
__le16 reparse; // 0x36: Used by Reparse.
__le32 extend_data; // 0x34: Extended data.
}; // 0x38

View File

@ -377,6 +377,13 @@ struct ntfs_inode {
*/
u8 mi_loaded;
/*
* Use this field to avoid any write(s).
* If inode is bad during initialization - use make_bad_inode
* If inode is bad during operations - use this field
*/
u8 ni_bad;
union {
struct ntfs_index dir;
struct {
@ -577,8 +584,7 @@ int ni_add_name(struct ntfs_inode *dir_ni, struct ntfs_inode *ni,
struct NTFS_DE *de);
int ni_rename(struct ntfs_inode *dir_ni, struct ntfs_inode *new_dir_ni,
struct ntfs_inode *ni, struct NTFS_DE *de, struct NTFS_DE *new_de,
bool *is_bad);
struct ntfs_inode *ni, struct NTFS_DE *de, struct NTFS_DE *new_de);
bool ni_is_dirty(struct inode *inode);
@ -874,7 +880,7 @@ int ntfs_acl_chmod(struct mnt_idmap *idmap, struct dentry *dentry);
ssize_t ntfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
extern const struct xattr_handler *const ntfs_xattr_handlers[];
int ntfs_save_wsl_perm(struct inode *inode, __le16 *ea_size);
int ntfs_save_wsl_perm(struct inode *inode, __le32 *ea_size);
void ntfs_get_wsl_perm(struct inode *inode);
/* globals from lznt.c */
@ -1025,6 +1031,11 @@ static inline bool is_compressed(const struct ntfs_inode *ni)
(ni->ni_flags & NI_FLAG_COMPRESSED_MASK);
}
static inline bool is_bad_ni(const struct ntfs_inode *ni)
{
return ni->ni_bad;
}
static inline int ni_ext_compress_bits(const struct ntfs_inode *ni)
{
return 0xb + (ni->ni_flags & NI_FLAG_COMPRESSED_MASK);

View File

@ -313,7 +313,7 @@ static int ntfs_get_ea(struct inode *inode, const char *name, size_t name_len,
static noinline int ntfs_set_ea(struct inode *inode, const char *name,
size_t name_len, const void *value,
size_t val_size, int flags, bool locked,
__le16 *ea_size)
__le32 *ea_size)
{
struct ntfs_inode *ni = ntfs_i(inode);
struct ntfs_sb_info *sbi = ni->mi.sbi;
@ -522,7 +522,7 @@ static noinline int ntfs_set_ea(struct inode *inode, const char *name,
if (ea_info.size_pack != size_pack)
ni->ni_flags |= NI_FLAG_UPDATE_PARENT;
if (ea_size)
*ea_size = ea_info.size_pack;
*ea_size = ea_info.size;
mark_inode_dirty(&ni->vfs_inode);
out:
@ -552,6 +552,10 @@ struct posix_acl *ntfs_get_acl(struct mnt_idmap *idmap, struct dentry *dentry,
int err;
void *buf;
/* Avoid any operation if inode is bad. */
if (unlikely(is_bad_ni(ni)))
return ERR_PTR(-EINVAL);
/* Allocate PATH_MAX bytes. */
buf = __getname();
if (!buf)
@ -600,6 +604,10 @@ static noinline int ntfs_set_acl_ex(struct mnt_idmap *idmap,
int flags;
umode_t mode;
/* Avoid any operation if inode is bad. */
if (unlikely(is_bad_ni(ntfs_i(inode))))
return -EINVAL;
if (S_ISLNK(inode->i_mode))
return -EOPNOTSUPP;
@ -730,6 +738,10 @@ ssize_t ntfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
struct ntfs_inode *ni = ntfs_i(inode);
ssize_t ret;
/* Avoid any operation if inode is bad. */
if (unlikely(is_bad_ni(ni)))
return -EINVAL;
if (!(ni->ni_flags & NI_FLAG_EA)) {
/* no xattr in file */
return 0;
@ -751,6 +763,10 @@ static int ntfs_getxattr(const struct xattr_handler *handler, struct dentry *de,
int err;
struct ntfs_inode *ni = ntfs_i(inode);
/* Avoid any operation if inode is bad. */
if (unlikely(is_bad_ni(ni)))
return -EINVAL;
if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
return -EIO;
@ -950,7 +966,7 @@ static noinline int ntfs_setxattr(const struct xattr_handler *handler,
*
* save uid/gid/mode in xattr
*/
int ntfs_save_wsl_perm(struct inode *inode, __le16 *ea_size)
int ntfs_save_wsl_perm(struct inode *inode, __le32 *ea_size)
{
int err;
__le32 value;