2023-09-26 14:31:11

by Konstantin Komarov

[permalink] [raw]
Subject: [PATCH 0/8] fs/ntfs3: Bugfix and refactoring

This series contains various fixes and refactoring for ntfs3.
Added more info into /proc/fs/ntfs3/<dev>/volinfo

Konstantin Komarov (8):
  fs/ntfs3: Use inode_set_ctime_to_ts instead of inode_set_ctime
  fs/ntfs3: Allow repeated call to ntfs3_put_sbi
  fs/ntfs3: Fix alternative boot searching
  fs/ntfs3: Refactoring and comments
  fs/ntfs3: Add more info into /proc/fs/ntfs3/<dev>/volinfo
  fs/ntfs3: Do not allow to change label if volume is read-only
  fs/ntfs3: Fix possible NULL-ptr-deref in ni_readpage_cmpr()
  fs/ntfs3: Fix NULL pointer dereference on error in
    attr_allocate_frame()

 fs/ntfs3/attrib.c  | 12 ++++----
 fs/ntfs3/bitmap.c  |  1 +
 fs/ntfs3/file.c    |  4 +--
 fs/ntfs3/frecord.c |  2 +-
 fs/ntfs3/inode.c   |  5 ++--
 fs/ntfs3/namei.c   |  6 ++--
 fs/ntfs3/ntfs.h    |  2 +-
 fs/ntfs3/ntfs_fs.h |  2 --
 fs/ntfs3/record.c  |  6 ++++
 fs/ntfs3/super.c   | 71 +++++++++++++++++++++++++++++++---------------
 10 files changed, 70 insertions(+), 41 deletions(-)

--
2.34.1



2023-09-26 16:07:32

by Konstantin Komarov

[permalink] [raw]
Subject: [PATCH 3/8] fs/ntfs3: Fix alternative boot searching


Signed-off-by: Konstantin Komarov <[email protected]>
---
 fs/ntfs3/super.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c
index 71c80c578feb..d2951b23f52a 100644
--- a/fs/ntfs3/super.c
+++ b/fs/ntfs3/super.c
@@ -846,7 +846,7 @@ static int ntfs_init_from_boot(struct super_block
*sb, u32 sector_size,
     struct ntfs_sb_info *sbi = sb->s_fs_info;
     int err;
     u32 mb, gb, boot_sector_size, sct_per_clst, record_size;
-    u64 sectors, clusters, mlcn, mlcn2;
+    u64 sectors, clusters, mlcn, mlcn2, dev_size0;
     struct NTFS_BOOT *boot;
     struct buffer_head *bh;
     struct MFT_REC *rec;
@@ -855,6 +855,9 @@ static int ntfs_init_from_boot(struct super_block
*sb, u32 sector_size,
     u32 boot_off = 0;
     const char *hint = "Primary boot";

+    /* Save original dev_size. Used with alternative boot. */
+    dev_size0 = dev_size;
+
     sbi->volume.blocks = dev_size >> PAGE_SHIFT;

     bh = ntfs_bread(sb, 0);
@@ -1087,9 +1090,9 @@ static int ntfs_init_from_boot(struct super_block
*sb, u32 sector_size,
     }

 out:
-    if (err == -EINVAL && !bh->b_blocknr && dev_size > PAGE_SHIFT) {
+    if (err == -EINVAL && !bh->b_blocknr && dev_size0 > PAGE_SHIFT) {
         u32 block_size = min_t(u32, sector_size, PAGE_SIZE);
-        u64 lbo = dev_size - sizeof(*boot);
+        u64 lbo = dev_size0 - sizeof(*boot);

         /*
           * Try alternative boot (last sector)
@@ -1103,6 +1106,7 @@ static int ntfs_init_from_boot(struct super_block
*sb, u32 sector_size,

         boot_off = lbo & (block_size - 1);
         hint = "Alternative boot";
+        dev_size = dev_size0; /* restore original size. */
         goto check_boot;
     }
     brelse(bh);
--
2.34.1

2023-09-26 18:49:49

by Konstantin Komarov

[permalink] [raw]
Subject: [PATCH 6/8] fs/ntfs3: Do not allow to change label if volume is read-only


Signed-off-by: Konstantin Komarov <[email protected]>
---
 fs/ntfs3/super.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c
index 5811da7e9d45..cf0a720523f0 100644
--- a/fs/ntfs3/super.c
+++ b/fs/ntfs3/super.c
@@ -497,7 +497,12 @@ static ssize_t ntfs3_label_write(struct file *file,
const char __user *buffer,
     int err;
     struct super_block *sb = pde_data(file_inode(file));
     ssize_t ret = count;
-    u8 *label = kmalloc(count, GFP_NOFS);
+    u8 *label;
+
+    if (sb_rdonly(sb))
+        return -EROFS;
+
+    label = kmalloc(count, GFP_NOFS);

     if (!label)
         return -ENOMEM;
--
2.34.1

2023-09-26 22:07:26

by Konstantin Komarov

[permalink] [raw]
Subject: [PATCH 1/8] fs/ntfs3: Use inode_set_ctime_to_ts instead of inode_set_ctime


Signed-off-by: Konstantin Komarov <[email protected]>

---
 fs/ntfs3/inode.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c
index eb2ed0701495..2f76dc055c1f 100644
--- a/fs/ntfs3/inode.c
+++ b/fs/ntfs3/inode.c
@@ -170,8 +170,8 @@ static struct inode *ntfs_read_mft(struct inode *inode,
         nt2kernel(std5->cr_time, &ni->i_crtime);
 #endif
         nt2kernel(std5->a_time, &inode->i_atime);
-        ctime = inode_get_ctime(inode);
         nt2kernel(std5->c_time, &ctime);
+        inode_set_ctime_to_ts(inode, ctime);
         nt2kernel(std5->m_time, &inode->i_mtime);

         ni->std_fa = std5->fa;
--
2.34.1

2023-09-26 23:51:26

by Konstantin Komarov

[permalink] [raw]
Subject: [PATCH 2/8] fs/ntfs3: Allow repeated call to ntfs3_put_sbi


Signed-off-by: Konstantin Komarov <[email protected]>
---
 fs/ntfs3/bitmap.c |  1 +
 fs/ntfs3/super.c  | 21 ++++++++++++++++-----
 2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/fs/ntfs3/bitmap.c b/fs/ntfs3/bitmap.c
index d66055e30aff..63f14a0232f6 100644
--- a/fs/ntfs3/bitmap.c
+++ b/fs/ntfs3/bitmap.c
@@ -125,6 +125,7 @@ void wnd_close(struct wnd_bitmap *wnd)
     struct rb_node *node, *next;

     kfree(wnd->free_bits);
+    wnd->free_bits = NULL;
     run_close(&wnd->run);

     node = rb_first(&wnd->start_tree);
diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c
index f78c67452b2a..71c80c578feb 100644
--- a/fs/ntfs3/super.c
+++ b/fs/ntfs3/super.c
@@ -576,20 +576,30 @@ static noinline void ntfs3_put_sbi(struct
ntfs_sb_info *sbi)
     wnd_close(&sbi->mft.bitmap);
     wnd_close(&sbi->used.bitmap);

-    if (sbi->mft.ni)
+    if (sbi->mft.ni) {
         iput(&sbi->mft.ni->vfs_inode);
+        sbi->mft.ni = NULL;
+    }

-    if (sbi->security.ni)
+    if (sbi->security.ni) {
         iput(&sbi->security.ni->vfs_inode);
+        sbi->security.ni = NULL;
+    }

-    if (sbi->reparse.ni)
+    if (sbi->reparse.ni) {
         iput(&sbi->reparse.ni->vfs_inode);
+        sbi->reparse.ni = NULL;
+    }

-    if (sbi->objid.ni)
+    if (sbi->objid.ni) {
         iput(&sbi->objid.ni->vfs_inode);
+        sbi->objid.ni = NULL;
+    }

-    if (sbi->volume.ni)
+    if (sbi->volume.ni) {
         iput(&sbi->volume.ni->vfs_inode);
+        sbi->volume.ni = NULL;
+    }

     ntfs_update_mftmirr(sbi, 0);

@@ -1577,6 +1587,7 @@ static int ntfs_fill_super(struct super_block *sb,
struct fs_context *fc)
     iput(inode);
 out:
     kfree(boot2);
+    ntfs3_put_sbi(sbi);
     return err;
 }

--
2.34.1

2023-09-27 01:50:54

by Konstantin Komarov

[permalink] [raw]
Subject: [PATCH 8/8] fs/ntfs3: Fix NULL pointer dereference on error in attr_allocate_frame()


Signed-off-by: Konstantin Komarov <[email protected]>
---
 fs/ntfs3/attrib.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c
index e16487764282..63f70259edc0 100644
--- a/fs/ntfs3/attrib.c
+++ b/fs/ntfs3/attrib.c
@@ -1736,10 +1736,8 @@ int attr_allocate_frame(struct ntfs_inode *ni,
CLST frame, size_t compr_size,
             le_b = NULL;
             attr_b = ni_find_attr(ni, NULL, &le_b, ATTR_DATA, NULL,
                           0, NULL, &mi_b);
-            if (!attr_b) {
-                err = -ENOENT;
-                goto out;
-            }
+            if (!attr_b)
+                return -ENOENT;

             attr = attr_b;
             le = le_b;
--
2.34.1

2023-09-27 02:07:47

by Konstantin Komarov

[permalink] [raw]
Subject: [PATCH 5/8] fs/ntfs3: Add more info into /proc/fs/ntfs3/<dev>/volinfo


Signed-off-by: Konstantin Komarov <[email protected]>
---
 fs/ntfs3/super.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c
index f9a214367113..5811da7e9d45 100644
--- a/fs/ntfs3/super.c
+++ b/fs/ntfs3/super.c
@@ -453,15 +453,23 @@ static struct proc_dir_entry *proc_info_root;
  * ntfs3.1
  * cluster size
  * number of clusters
+ * total number of mft records
+ * number of used mft records ~= number of files + folders
+ * real state of ntfs "dirty"/"clean"
+ * current state of ntfs "dirty"/"clean"
 */
 static int ntfs3_volinfo(struct seq_file *m, void *o)
 {
     struct super_block *sb = m->private;
     struct ntfs_sb_info *sbi = sb->s_fs_info;

-    seq_printf(m, "ntfs%d.%d\n%u\n%zu\n", sbi->volume.major_ver,
-           sbi->volume.minor_ver, sbi->cluster_size,
-           sbi->used.bitmap.nbits);
+    seq_printf(m, "ntfs%d.%d\n%u\n%zu\n\%zu\n%zu\n%s\n%s\n",
+           sbi->volume.major_ver, sbi->volume.minor_ver,
+           sbi->cluster_size, sbi->used.bitmap.nbits,
+           sbi->mft.bitmap.nbits,
+           sbi->mft.bitmap.nbits - wnd_zeroes(&sbi->mft.bitmap),
+           sbi->volume.real_dirty ? "dirty" : "clean",
+           (sbi->volume.flags & VOLUME_FLAG_DIRTY) ? "dirty" : "clean");

     return 0;
 }
--
2.34.1