Skip to content

Commit 519b078

Browse files
fs/ntfs3: Exclude call make_bad_inode for live nodes.
Use ntfs_inode field 'ni_bad' to mark inode as bad (if something went wrong) and to avoid any operations Suggested-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
1 parent d99208b commit 519b078

7 files changed

Lines changed: 103 additions & 1 deletion

File tree

fs/ntfs3/file.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ long ntfs_ioctl(struct file *filp, u32 cmd, unsigned long arg)
5757
struct inode *inode = file_inode(filp);
5858
struct ntfs_sb_info *sbi = inode->i_sb->s_fs_info;
5959

60+
/* Avoid any operation if inode is bad. */
61+
if (unlikely(is_bad_ni(ntfs_i(inode))))
62+
return -EINVAL;
63+
6064
switch (cmd) {
6165
case FITRIM:
6266
return ntfs_ioctl_fitrim(sbi, arg);
@@ -81,6 +85,10 @@ int ntfs_getattr(struct mnt_idmap *idmap, const struct path *path,
8185
struct inode *inode = d_inode(path->dentry);
8286
struct ntfs_inode *ni = ntfs_i(inode);
8387

88+
/* Avoid any operation if inode is bad. */
89+
if (unlikely(is_bad_ni(ni)))
90+
return -EINVAL;
91+
8492
stat->result_mask |= STATX_BTIME;
8593
stat->btime = ni->i_crtime;
8694
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)
271279
bool rw = vma->vm_flags & VM_WRITE;
272280
int err;
273281

282+
/* Avoid any operation if inode is bad. */
283+
if (unlikely(is_bad_ni(ni)))
284+
return -EINVAL;
285+
274286
if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
275287
return -EIO;
276288

@@ -735,6 +747,10 @@ int ntfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
735747
umode_t mode = inode->i_mode;
736748
int err;
737749

750+
/* Avoid any operation if inode is bad. */
751+
if (unlikely(is_bad_ni(ni)))
752+
return -EINVAL;
753+
738754
if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
739755
return -EIO;
740756

@@ -795,6 +811,10 @@ static int check_read_restriction(struct inode *inode)
795811
{
796812
struct ntfs_inode *ni = ntfs_i(inode);
797813

814+
/* Avoid any operation if inode is bad. */
815+
if (unlikely(is_bad_ni(ni)))
816+
return -EINVAL;
817+
798818
if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
799819
return -EIO;
800820

@@ -1130,6 +1150,10 @@ static int check_write_restriction(struct inode *inode)
11301150
{
11311151
struct ntfs_inode *ni = ntfs_i(inode);
11321152

1153+
/* Avoid any operation if inode is bad. */
1154+
if (unlikely(is_bad_ni(ni)))
1155+
return -EINVAL;
1156+
11331157
if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
11341158
return -EIO;
11351159

@@ -1212,6 +1236,10 @@ int ntfs_file_open(struct inode *inode, struct file *file)
12121236
{
12131237
struct ntfs_inode *ni = ntfs_i(inode);
12141238

1239+
/* Avoid any operation if inode is bad. */
1240+
if (unlikely(is_bad_ni(ni)))
1241+
return -EINVAL;
1242+
12151243
if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
12161244
return -EIO;
12171245

@@ -1281,6 +1309,10 @@ int ntfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
12811309
int err;
12821310
struct ntfs_inode *ni = ntfs_i(inode);
12831311

1312+
/* Avoid any operation if inode is bad. */
1313+
if (unlikely(is_bad_ni(ni)))
1314+
return -EINVAL;
1315+
12841316
err = fiemap_prep(inode, fieinfo, start, &len, ~FIEMAP_FLAG_XATTR);
12851317
if (err)
12861318
return err;

fs/ntfs3/frecord.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3208,6 +3208,10 @@ int ni_write_inode(struct inode *inode, int sync, const char *hint)
32083208
if (is_bad_inode(inode) || sb_rdonly(sb))
32093209
return 0;
32103210

3211+
/* Avoid any operation if inode is bad. */
3212+
if (unlikely(is_bad_ni(ni)))
3213+
return -EINVAL;
3214+
32113215
if (unlikely(ntfs3_forced_shutdown(sb)))
32123216
return -EIO;
32133217

fs/ntfs3/fsntfs.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -905,9 +905,13 @@ void ntfs_update_mftmirr(struct ntfs_sb_info *sbi, int wait)
905905
void ntfs_bad_inode(struct inode *inode, const char *hint)
906906
{
907907
struct ntfs_sb_info *sbi = inode->i_sb->s_fs_info;
908+
struct ntfs_inode *ni = ntfs_i(inode);
908909

909910
ntfs_inode_err(inode, "%s", hint);
910-
make_bad_inode(inode);
911+
912+
/* Do not call make_bad_inode()! */
913+
ni->ni_bad = true;
914+
911915
/* Avoid recursion if bad inode is $Volume. */
912916
if (inode->i_ino != MFT_REC_VOL &&
913917
!(sbi->flags & NTFS_FLAGS_LOG_REPLAYING)) {

fs/ntfs3/inode.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,10 @@ static int ntfs_resident_writepage(struct folio *folio,
878878
struct ntfs_inode *ni = ntfs_i(inode);
879879
int ret;
880880

881+
/* Avoid any operation if inode is bad. */
882+
if (unlikely(is_bad_ni(ni)))
883+
return -EINVAL;
884+
881885
if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
882886
return -EIO;
883887

@@ -896,6 +900,10 @@ static int ntfs_writepages(struct address_space *mapping,
896900
{
897901
struct inode *inode = mapping->host;
898902

903+
/* Avoid any operation if inode is bad. */
904+
if (unlikely(is_bad_ni(ntfs_i(inode))))
905+
return -EINVAL;
906+
899907
if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
900908
return -EIO;
901909

@@ -919,6 +927,10 @@ int ntfs_write_begin(struct file *file, struct address_space *mapping,
919927
struct inode *inode = mapping->host;
920928
struct ntfs_inode *ni = ntfs_i(inode);
921929

930+
/* Avoid any operation if inode is bad. */
931+
if (unlikely(is_bad_ni(ni)))
932+
return -EINVAL;
933+
922934
if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
923935
return -EIO;
924936

@@ -1265,6 +1277,12 @@ int ntfs_create_inode(struct mnt_idmap *idmap, struct inode *dir,
12651277
goto out1;
12661278
}
12671279

1280+
/* Avoid any operation if inode is bad. */
1281+
if (unlikely(is_bad_ni(dir_ni))) {
1282+
err = -EINVAL;
1283+
goto out2;
1284+
}
1285+
12681286
if (unlikely(ntfs3_forced_shutdown(sb))) {
12691287
err = -EIO;
12701288
goto out2;

fs/ntfs3/namei.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,10 @@ static int ntfs_unlink(struct inode *dir, struct dentry *dentry)
171171
struct ntfs_inode *ni = ntfs_i(dir);
172172
int err;
173173

174+
/* Avoid any operation if inode is bad. */
175+
if (unlikely(is_bad_ni(ni)))
176+
return -EINVAL;
177+
174178
if (unlikely(ntfs3_forced_shutdown(dir->i_sb)))
175179
return -EIO;
176180

@@ -191,6 +195,10 @@ static int ntfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
191195
{
192196
u32 size = strlen(symname);
193197

198+
/* Avoid any operation if inode is bad. */
199+
if (unlikely(is_bad_ni(ntfs_i(dir))))
200+
return -EINVAL;
201+
194202
if (unlikely(ntfs3_forced_shutdown(dir->i_sb)))
195203
return -EIO;
196204

@@ -216,6 +224,10 @@ static int ntfs_rmdir(struct inode *dir, struct dentry *dentry)
216224
struct ntfs_inode *ni = ntfs_i(dir);
217225
int err;
218226

227+
/* Avoid any operation if inode is bad. */
228+
if (unlikely(is_bad_ni(ni)))
229+
return -EINVAL;
230+
219231
if (unlikely(ntfs3_forced_shutdown(dir->i_sb)))
220232
return -EIO;
221233

@@ -256,6 +268,10 @@ static int ntfs_rename(struct mnt_idmap *idmap, struct inode *dir,
256268
1024);
257269
static_assert(PATH_MAX >= 4 * 1024);
258270

271+
/* Avoid any operation if inode is bad. */
272+
if (unlikely(is_bad_ni(ni)))
273+
return -EINVAL;
274+
259275
if (unlikely(ntfs3_forced_shutdown(sb)))
260276
return -EIO;
261277

fs/ntfs3/ntfs_fs.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,13 @@ struct ntfs_inode {
377377
*/
378378
u8 mi_loaded;
379379

380+
/*
381+
* Use this field to avoid any write(s).
382+
* If inode is bad during initialization - use make_bad_inode
383+
* If inode is bad during operations - use this field
384+
*/
385+
u8 ni_bad;
386+
380387
union {
381388
struct ntfs_index dir;
382389
struct {
@@ -1024,6 +1031,11 @@ static inline bool is_compressed(const struct ntfs_inode *ni)
10241031
(ni->ni_flags & NI_FLAG_COMPRESSED_MASK);
10251032
}
10261033

1034+
static inline bool is_bad_ni(const struct ntfs_inode *ni)
1035+
{
1036+
return ni->ni_bad;
1037+
}
1038+
10271039
static inline int ni_ext_compress_bits(const struct ntfs_inode *ni)
10281040
{
10291041
return 0xb + (ni->ni_flags & NI_FLAG_COMPRESSED_MASK);

fs/ntfs3/xattr.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,10 @@ struct posix_acl *ntfs_get_acl(struct mnt_idmap *idmap, struct dentry *dentry,
552552
int err;
553553
void *buf;
554554

555+
/* Avoid any operation if inode is bad. */
556+
if (unlikely(is_bad_ni(ni)))
557+
return ERR_PTR(-EINVAL);
558+
555559
/* Allocate PATH_MAX bytes. */
556560
buf = __getname();
557561
if (!buf)
@@ -600,6 +604,10 @@ static noinline int ntfs_set_acl_ex(struct mnt_idmap *idmap,
600604
int flags;
601605
umode_t mode;
602606

607+
/* Avoid any operation if inode is bad. */
608+
if (unlikely(is_bad_ni(ntfs_i(inode))))
609+
return -EINVAL;
610+
603611
if (S_ISLNK(inode->i_mode))
604612
return -EOPNOTSUPP;
605613

@@ -730,6 +738,10 @@ ssize_t ntfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
730738
struct ntfs_inode *ni = ntfs_i(inode);
731739
ssize_t ret;
732740

741+
/* Avoid any operation if inode is bad. */
742+
if (unlikely(is_bad_ni(ni)))
743+
return -EINVAL;
744+
733745
if (!(ni->ni_flags & NI_FLAG_EA)) {
734746
/* no xattr in file */
735747
return 0;
@@ -751,6 +763,10 @@ static int ntfs_getxattr(const struct xattr_handler *handler, struct dentry *de,
751763
int err;
752764
struct ntfs_inode *ni = ntfs_i(inode);
753765

766+
/* Avoid any operation if inode is bad. */
767+
if (unlikely(is_bad_ni(ni)))
768+
return -EINVAL;
769+
754770
if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
755771
return -EIO;
756772

0 commit comments

Comments
 (0)