Skip to content

Commit 1f95267

Browse files
committed
Pull ntfs3 updates from Konstantin Komarov: - fix some memory leaks and panic - fixed xfstests (tested on x86_64): generic/092 generic/099 generic/228 generic/240 generic/307 generic/444 - fix some typos, dead code, etc * tag 'ntfs3_for_5.19' of https://github.com/Paragon-Software-Group/linux-ntfs3: fs/ntfs3: provide block_invalidate_folio to fix memory leak fs/ntfs3: Fix invalid free in log_replay fs/ntfs3: Update valid size if -EIOCBQUEUED fs/ntfs3: Check new size for limits fs/ntfs3: Fix fiemap + fix shrink file size (to remove preallocated space) fs/ntfs3: In function ntfs_set_acl_ex do not change inode->i_mode if called from function ntfs_init_acl fs/ntfs3: Optimize locking in ntfs_save_wsl_perm fs/ntfs3: Update i_ctime when xattr is added fs/ntfs3: Restore ntfs_xattr_get_acl and ntfs_xattr_set_acl functions fs/ntfs3: Keep preallocated only if option prealloc enabled fs/ntfs3: Fix some memory leaks in an error handling path of 'log_replay()'
2 parents 67850b7 + 724bbe4 commit 1f95267

File tree

5 files changed

+149
-30
lines changed

5 files changed

+149
-30
lines changed

fs/ntfs3/file.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ static int ntfs_truncate(struct inode *inode, loff_t new_size)
492492

493493
down_write(&ni->file.run_lock);
494494
err = attr_set_size(ni, ATTR_DATA, NULL, 0, &ni->file.run, new_size,
495-
&new_valid, true, NULL);
495+
&new_valid, ni->mi.sbi->options->prealloc, NULL);
496496
up_write(&ni->file.run_lock);
497497

498498
if (new_valid < ni->i_valid)
@@ -659,7 +659,13 @@ static long ntfs_fallocate(struct file *file, int mode, loff_t vbo, loff_t len)
659659
/*
660660
* Normal file: Allocate clusters, do not change 'valid' size.
661661
*/
662-
err = ntfs_set_size(inode, max(end, i_size));
662+
loff_t new_size = max(end, i_size);
663+
664+
err = inode_newsize_ok(inode, new_size);
665+
if (err)
666+
goto out;
667+
668+
err = ntfs_set_size(inode, new_size);
663669
if (err)
664670
goto out;
665671

@@ -759,7 +765,7 @@ int ntfs3_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
759765
}
760766
inode_dio_wait(inode);
761767

762-
if (attr->ia_size < oldsize)
768+
if (attr->ia_size <= oldsize)
763769
err = ntfs_truncate(inode, attr->ia_size);
764770
else if (attr->ia_size > oldsize)
765771
err = ntfs_extend(inode, attr->ia_size, 0, NULL);

fs/ntfs3/frecord.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1964,10 +1964,8 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo,
19641964

19651965
vcn += clen;
19661966

1967-
if (vbo + bytes >= end) {
1967+
if (vbo + bytes >= end)
19681968
bytes = end - vbo;
1969-
flags |= FIEMAP_EXTENT_LAST;
1970-
}
19711969

19721970
if (vbo + bytes <= valid) {
19731971
;
@@ -1977,6 +1975,9 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo,
19771975
/* vbo < valid && valid < vbo + bytes */
19781976
u64 dlen = valid - vbo;
19791977

1978+
if (vbo + dlen >= end)
1979+
flags |= FIEMAP_EXTENT_LAST;
1980+
19801981
err = fiemap_fill_next_extent(fieinfo, vbo, lbo, dlen,
19811982
flags);
19821983
if (err < 0)
@@ -1995,6 +1996,9 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo,
19951996
flags |= FIEMAP_EXTENT_UNWRITTEN;
19961997
}
19971998

1999+
if (vbo + bytes >= end)
2000+
flags |= FIEMAP_EXTENT_LAST;
2001+
19982002
err = fiemap_fill_next_extent(fieinfo, vbo, lbo, bytes, flags);
19992003
if (err < 0)
20002004
break;

fs/ntfs3/fslog.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,8 +1185,6 @@ static int log_read_rst(struct ntfs_log *log, u32 l_size, bool first,
11851185
if (!r_page)
11861186
return -ENOMEM;
11871187

1188-
memset(info, 0, sizeof(struct restart_info));
1189-
11901188
/* Determine which restart area we are looking for. */
11911189
if (first) {
11921190
vbo = 0;
@@ -3791,10 +3789,11 @@ int log_replay(struct ntfs_inode *ni, bool *initialized)
37913789
if (!log)
37923790
return -ENOMEM;
37933791

3792+
memset(&rst_info, 0, sizeof(struct restart_info));
3793+
37943794
log->ni = ni;
37953795
log->l_size = l_size;
37963796
log->one_page_buf = kmalloc(page_size, GFP_NOFS);
3797-
37983797
if (!log->one_page_buf) {
37993798
err = -ENOMEM;
38003799
goto out;
@@ -3842,6 +3841,7 @@ int log_replay(struct ntfs_inode *ni, bool *initialized)
38423841
if (rst_info.vbo)
38433842
goto check_restart_area;
38443843

3844+
memset(&rst_info2, 0, sizeof(struct restart_info));
38453845
err = log_read_rst(log, l_size, false, &rst_info2);
38463846

38473847
/* Determine which restart area to use. */
@@ -4085,8 +4085,10 @@ int log_replay(struct ntfs_inode *ni, bool *initialized)
40854085
if (client == LFS_NO_CLIENT_LE) {
40864086
/* Insert "NTFS" client LogFile. */
40874087
client = ra->client_idx[0];
4088-
if (client == LFS_NO_CLIENT_LE)
4089-
return -EINVAL;
4088+
if (client == LFS_NO_CLIENT_LE) {
4089+
err = -EINVAL;
4090+
goto out;
4091+
}
40904092

40914093
t16 = le16_to_cpu(client);
40924094
cr = ca + t16;

fs/ntfs3/inode.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,7 @@ static ssize_t ntfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
758758
loff_t vbo = iocb->ki_pos;
759759
loff_t end;
760760
int wr = iov_iter_rw(iter) & WRITE;
761+
size_t iter_count = iov_iter_count(iter);
761762
loff_t valid;
762763
ssize_t ret;
763764

@@ -771,10 +772,13 @@ static ssize_t ntfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
771772
wr ? ntfs_get_block_direct_IO_W
772773
: ntfs_get_block_direct_IO_R);
773774

774-
if (ret <= 0)
775+
if (ret > 0)
776+
end = vbo + ret;
777+
else if (wr && ret == -EIOCBQUEUED)
778+
end = vbo + iter_count;
779+
else
775780
goto out;
776781

777-
end = vbo + ret;
778782
valid = ni->i_valid;
779783
if (wr) {
780784
if (end > valid && !S_ISBLK(inode->i_mode)) {
@@ -1950,6 +1954,7 @@ const struct address_space_operations ntfs_aops = {
19501954
.direct_IO = ntfs_direct_IO,
19511955
.bmap = ntfs_bmap,
19521956
.dirty_folio = block_dirty_folio,
1957+
.invalidate_folio = block_invalidate_folio,
19531958
};
19541959

19551960
const struct address_space_operations ntfs_aops_cmpr = {

fs/ntfs3/xattr.c

Lines changed: 119 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ static int ntfs_read_ea(struct ntfs_inode *ni, struct EA_FULL **ea,
112112
return -ENOMEM;
113113

114114
if (!size) {
115-
;
115+
/* EA info persists, but xattr is empty. Looks like EA problem. */
116116
} else if (attr_ea->non_res) {
117117
struct runs_tree run;
118118

@@ -259,7 +259,7 @@ static int ntfs_get_ea(struct inode *inode, const char *name, size_t name_len,
259259

260260
static noinline int ntfs_set_ea(struct inode *inode, const char *name,
261261
size_t name_len, const void *value,
262-
size_t val_size, int flags)
262+
size_t val_size, int flags, bool locked)
263263
{
264264
struct ntfs_inode *ni = ntfs_i(inode);
265265
struct ntfs_sb_info *sbi = ni->mi.sbi;
@@ -278,7 +278,8 @@ static noinline int ntfs_set_ea(struct inode *inode, const char *name,
278278
u64 new_sz;
279279
void *p;
280280

281-
ni_lock(ni);
281+
if (!locked)
282+
ni_lock(ni);
282283

283284
run_init(&ea_run);
284285

@@ -467,7 +468,8 @@ static noinline int ntfs_set_ea(struct inode *inode, const char *name,
467468
mark_inode_dirty(&ni->vfs_inode);
468469

469470
out:
470-
ni_unlock(ni);
471+
if (!locked)
472+
ni_unlock(ni);
471473

472474
run_close(&ea_run);
473475
kfree(ea_all);
@@ -541,7 +543,7 @@ struct posix_acl *ntfs_get_acl(struct inode *inode, int type, bool rcu)
541543

542544
static noinline int ntfs_set_acl_ex(struct user_namespace *mnt_userns,
543545
struct inode *inode, struct posix_acl *acl,
544-
int type)
546+
int type, bool init_acl)
545547
{
546548
const char *name;
547549
size_t size, name_len;
@@ -554,8 +556,9 @@ static noinline int ntfs_set_acl_ex(struct user_namespace *mnt_userns,
554556

555557
switch (type) {
556558
case ACL_TYPE_ACCESS:
557-
if (acl) {
558-
umode_t mode = inode->i_mode;
559+
/* Do not change i_mode if we are in init_acl */
560+
if (acl && !init_acl) {
561+
umode_t mode;
559562

560563
err = posix_acl_update_mode(mnt_userns, inode, &mode,
561564
&acl);
@@ -598,7 +601,7 @@ static noinline int ntfs_set_acl_ex(struct user_namespace *mnt_userns,
598601
flags = 0;
599602
}
600603

601-
err = ntfs_set_ea(inode, name, name_len, value, size, flags);
604+
err = ntfs_set_ea(inode, name, name_len, value, size, flags, 0);
602605
if (err == -ENODATA && !size)
603606
err = 0; /* Removing non existed xattr. */
604607
if (!err)
@@ -616,7 +619,68 @@ static noinline int ntfs_set_acl_ex(struct user_namespace *mnt_userns,
616619
int ntfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
617620
struct posix_acl *acl, int type)
618621
{
619-
return ntfs_set_acl_ex(mnt_userns, inode, acl, type);
622+
return ntfs_set_acl_ex(mnt_userns, inode, acl, type, false);
623+
}
624+
625+
static int ntfs_xattr_get_acl(struct user_namespace *mnt_userns,
626+
struct inode *inode, int type, void *buffer,
627+
size_t size)
628+
{
629+
struct posix_acl *acl;
630+
int err;
631+
632+
if (!(inode->i_sb->s_flags & SB_POSIXACL)) {
633+
ntfs_inode_warn(inode, "add mount option \"acl\" to use acl");
634+
return -EOPNOTSUPP;
635+
}
636+
637+
acl = ntfs_get_acl(inode, type, false);
638+
if (IS_ERR(acl))
639+
return PTR_ERR(acl);
640+
641+
if (!acl)
642+
return -ENODATA;
643+
644+
err = posix_acl_to_xattr(mnt_userns, acl, buffer, size);
645+
posix_acl_release(acl);
646+
647+
return err;
648+
}
649+
650+
static int ntfs_xattr_set_acl(struct user_namespace *mnt_userns,
651+
struct inode *inode, int type, const void *value,
652+
size_t size)
653+
{
654+
struct posix_acl *acl;
655+
int err;
656+
657+
if (!(inode->i_sb->s_flags & SB_POSIXACL)) {
658+
ntfs_inode_warn(inode, "add mount option \"acl\" to use acl");
659+
return -EOPNOTSUPP;
660+
}
661+
662+
if (!inode_owner_or_capable(mnt_userns, inode))
663+
return -EPERM;
664+
665+
if (!value) {
666+
acl = NULL;
667+
} else {
668+
acl = posix_acl_from_xattr(mnt_userns, value, size);
669+
if (IS_ERR(acl))
670+
return PTR_ERR(acl);
671+
672+
if (acl) {
673+
err = posix_acl_valid(mnt_userns, acl);
674+
if (err)
675+
goto release_and_out;
676+
}
677+
}
678+
679+
err = ntfs_set_acl(mnt_userns, inode, acl, type);
680+
681+
release_and_out:
682+
posix_acl_release(acl);
683+
return err;
620684
}
621685

622686
/*
@@ -636,7 +700,7 @@ int ntfs_init_acl(struct user_namespace *mnt_userns, struct inode *inode,
636700

637701
if (default_acl) {
638702
err = ntfs_set_acl_ex(mnt_userns, inode, default_acl,
639-
ACL_TYPE_DEFAULT);
703+
ACL_TYPE_DEFAULT, true);
640704
posix_acl_release(default_acl);
641705
} else {
642706
inode->i_default_acl = NULL;
@@ -647,7 +711,7 @@ int ntfs_init_acl(struct user_namespace *mnt_userns, struct inode *inode,
647711
else {
648712
if (!err)
649713
err = ntfs_set_acl_ex(mnt_userns, inode, acl,
650-
ACL_TYPE_ACCESS);
714+
ACL_TYPE_ACCESS, true);
651715
posix_acl_release(acl);
652716
}
653717

@@ -785,6 +849,23 @@ static int ntfs_getxattr(const struct xattr_handler *handler, struct dentry *de,
785849
goto out;
786850
}
787851

852+
#ifdef CONFIG_NTFS3_FS_POSIX_ACL
853+
if ((name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1 &&
854+
!memcmp(name, XATTR_NAME_POSIX_ACL_ACCESS,
855+
sizeof(XATTR_NAME_POSIX_ACL_ACCESS))) ||
856+
(name_len == sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1 &&
857+
!memcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT,
858+
sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)))) {
859+
/* TODO: init_user_ns? */
860+
err = ntfs_xattr_get_acl(
861+
&init_user_ns, inode,
862+
name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1
863+
? ACL_TYPE_ACCESS
864+
: ACL_TYPE_DEFAULT,
865+
buffer, size);
866+
goto out;
867+
}
868+
#endif
788869
/* Deal with NTFS extended attribute. */
789870
err = ntfs_get_ea(inode, name, name_len, buffer, size, NULL);
790871

@@ -897,10 +978,29 @@ static noinline int ntfs_setxattr(const struct xattr_handler *handler,
897978
goto out;
898979
}
899980

981+
#ifdef CONFIG_NTFS3_FS_POSIX_ACL
982+
if ((name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1 &&
983+
!memcmp(name, XATTR_NAME_POSIX_ACL_ACCESS,
984+
sizeof(XATTR_NAME_POSIX_ACL_ACCESS))) ||
985+
(name_len == sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1 &&
986+
!memcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT,
987+
sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)))) {
988+
err = ntfs_xattr_set_acl(
989+
mnt_userns, inode,
990+
name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1
991+
? ACL_TYPE_ACCESS
992+
: ACL_TYPE_DEFAULT,
993+
value, size);
994+
goto out;
995+
}
996+
#endif
900997
/* Deal with NTFS extended attribute. */
901-
err = ntfs_set_ea(inode, name, name_len, value, size, flags);
998+
err = ntfs_set_ea(inode, name, name_len, value, size, flags, 0);
902999

9031000
out:
1001+
inode->i_ctime = current_time(inode);
1002+
mark_inode_dirty(inode);
1003+
9041004
return err;
9051005
}
9061006

@@ -913,35 +1013,37 @@ int ntfs_save_wsl_perm(struct inode *inode)
9131013
{
9141014
int err;
9151015
__le32 value;
1016+
struct ntfs_inode *ni = ntfs_i(inode);
9161017

917-
/* TODO: refactor this, so we don't lock 4 times in ntfs_set_ea */
1018+
ni_lock(ni);
9181019
value = cpu_to_le32(i_uid_read(inode));
9191020
err = ntfs_set_ea(inode, "$LXUID", sizeof("$LXUID") - 1, &value,
920-
sizeof(value), 0);
1021+
sizeof(value), 0, true); /* true == already locked. */
9211022
if (err)
9221023
goto out;
9231024

9241025
value = cpu_to_le32(i_gid_read(inode));
9251026
err = ntfs_set_ea(inode, "$LXGID", sizeof("$LXGID") - 1, &value,
926-
sizeof(value), 0);
1027+
sizeof(value), 0, true);
9271028
if (err)
9281029
goto out;
9291030

9301031
value = cpu_to_le32(inode->i_mode);
9311032
err = ntfs_set_ea(inode, "$LXMOD", sizeof("$LXMOD") - 1, &value,
932-
sizeof(value), 0);
1033+
sizeof(value), 0, true);
9331034
if (err)
9341035
goto out;
9351036

9361037
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
9371038
value = cpu_to_le32(inode->i_rdev);
9381039
err = ntfs_set_ea(inode, "$LXDEV", sizeof("$LXDEV") - 1, &value,
939-
sizeof(value), 0);
1040+
sizeof(value), 0, true);
9401041
if (err)
9411042
goto out;
9421043
}
9431044

9441045
out:
1046+
ni_unlock(ni);
9451047
/* In case of error should we delete all WSL xattr? */
9461048
return err;
9471049
}

0 commit comments

Comments
 (0)