linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/16] fs/ntfs3: Bugfix and refactoring
@ 2023-12-06 15:08 Konstantin Komarovc
  2023-12-06 15:08 ` [PATCH 01/16] fs/ntfs3: Improve alternative boot processing Konstantin Komarovc
                   ` (15 more replies)
  0 siblings, 16 replies; 18+ messages in thread
From: Konstantin Komarovc @ 2023-12-06 15:08 UTC (permalink / raw)
  To: ntfs3; +Cc: linux-kernel, linux-fsdevel

This series contains various fixes and refactoring for ntfs3.
Improved alternative boot processing, reduced stack usage.

Konstantin Komarov (16):
   fs/ntfs3: Improve alternative boot processing
   fs/ntfs3: Modified fix directory element type detection
   fs/ntfs3: Improve ntfs_dir_count
   fs/ntfs3: Correct hard links updating when dealing with DOS names
   fs/ntfs3: Print warning while fixing hard links count
   fs/ntfs3: Reduce stack usage
   fs/ntfs3: Fix multithreaded stress test
   fs/ntfs3: Fix detected field-spanning write (size 8) of single field
     "le->name"
   fs/ntfs3: Correct use bh_read
   fs/ntfs3: Add file_modified
   fs/ntfs3: Drop suid and sgid bits as a part of fpunch
   fs/ntfs3: Implement super_operations::shutdown
   fs/ntfs3: ntfs3_forced_shutdown use int instead of bool
   fs/ntfs3: Add and fix comments
   fs/ntfs3: Add NULL ptr dereference checking at the end of
     attr_allocate_frame()
   fs/ntfs3: Fix c/mtime typo

  fs/ntfs3/attrib.c  |  41 +++++----
  fs/ntfs3/dir.c     |  44 ++++++---
  fs/ntfs3/file.c    |  59 +++++++++---
  fs/ntfs3/frecord.c |   5 +-
  fs/ntfs3/fslog.c   | 218 ++++++++++++++++++++-------------------------
  fs/ntfs3/fsntfs.c  |   5 +-
  fs/ntfs3/inode.c   |  30 +++++--
  fs/ntfs3/namei.c   |  12 +++
  fs/ntfs3/ntfs.h    |   2 +-
  fs/ntfs3/ntfs_fs.h |  11 ++-
  fs/ntfs3/record.c  |  16 +++-
  fs/ntfs3/super.c   |  47 ++++++----
  fs/ntfs3/xattr.c   |   3 +
  13 files changed, 302 insertions(+), 191 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 01/16] fs/ntfs3: Improve alternative boot processing
  2023-12-06 15:08 [PATCH 00/16] fs/ntfs3: Bugfix and refactoring Konstantin Komarovc
@ 2023-12-06 15:08 ` Konstantin Komarovc
  2023-12-06 15:09 ` [PATCH 02/16] fs/ntfs3: Modified fix directory element type detection Konstantin Komarovc
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Konstantin Komarovc @ 2023-12-06 15:08 UTC (permalink / raw)
  To: ntfs3; +Cc: linux-kernel, linux-fsdevel


Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
---
  fs/ntfs3/super.c | 35 +++++++++++++++++------------------
  1 file changed, 17 insertions(+), 18 deletions(-)

diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c
index 9153dffde950..09d61c6c90aa 100644
--- a/fs/ntfs3/super.c
+++ b/fs/ntfs3/super.c
@@ -866,6 +866,7 @@ static int ntfs_init_from_boot(struct super_block 
*sb, u32 sector_size,
      u16 fn, ao;
      u8 cluster_bits;
      u32 boot_off = 0;
+    sector_t boot_block = 0;
      const char *hint = "Primary boot";

      /* Save original dev_size. Used with alternative boot. */
@@ -873,11 +874,11 @@ static int ntfs_init_from_boot(struct super_block 
*sb, u32 sector_size,

      sbi->volume.blocks = dev_size >> PAGE_SHIFT;

-    bh = ntfs_bread(sb, 0);
+read_boot:
+    bh = ntfs_bread(sb, boot_block);
      if (!bh)
-        return -EIO;
+        return boot_block ? -EINVAL : -EIO;

-check_boot:
      err = -EINVAL;

      /* Corrupted image; do not read OOB */
@@ -1108,26 +1109,24 @@ static int ntfs_init_from_boot(struct 
super_block *sb, u32 sector_size,
      }

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

-        /*
-          * Try alternative boot (last sector)
-         */
-        brelse(bh);
-
-        sb_set_blocksize(sb, block_size);
-        bh = ntfs_bread(sb, lbo >> blksize_bits(block_size));
-        if (!bh)
-            return -EINVAL;
-
+        boot_block = lbo >> blksize_bits(block_size);
          boot_off = lbo & (block_size - 1);
-        hint = "Alternative boot";
-        dev_size = dev_size0; /* restore original size. */
-        goto check_boot;
+        if (boot_block && block_size >= boot_off + sizeof(*boot)) {
+            /*
+             * Try alternative boot (last sector)
+             */
+            sb_set_blocksize(sb, block_size);
+            hint = "Alternative boot";
+            dev_size = dev_size0; /* restore original size. */
+            goto read_boot;
+        }
      }
-    brelse(bh);

      return err;
  }
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 02/16] fs/ntfs3: Modified fix directory element type detection
  2023-12-06 15:08 [PATCH 00/16] fs/ntfs3: Bugfix and refactoring Konstantin Komarovc
  2023-12-06 15:08 ` [PATCH 01/16] fs/ntfs3: Improve alternative boot processing Konstantin Komarovc
@ 2023-12-06 15:09 ` Konstantin Komarovc
  2023-12-06 15:10 ` [PATCH 03/16] fs/ntfs3: Improve ntfs_dir_count Konstantin Komarovc
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Konstantin Komarovc @ 2023-12-06 15:09 UTC (permalink / raw)
  To: ntfs3; +Cc: linux-kernel, linux-fsdevel

Unfortunately reparse attribute is used for many purposes (several dozens).
It is not possible here to know is this name symlink or not.
To get exactly the type of name we should to open inode (read mft).
getattr for opened file (fstat) correctly returns symlink.

Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
---
  fs/ntfs3/dir.c | 30 +++++++++++++++++++++++++-----
  1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/fs/ntfs3/dir.c b/fs/ntfs3/dir.c
index ec0566b322d5..22ede4da0450 100644
--- a/fs/ntfs3/dir.c
+++ b/fs/ntfs3/dir.c
@@ -309,11 +309,31 @@ static inline int ntfs_filldir(struct ntfs_sb_info 
*sbi, struct ntfs_inode *ni,
          return 0;
      }

-    /* NTFS: symlinks are "dir + reparse" or "file + reparse" */
-    if (fname->dup.fa & FILE_ATTRIBUTE_REPARSE_POINT)
-        dt_type = DT_LNK;
-    else
-        dt_type = (fname->dup.fa & FILE_ATTRIBUTE_DIRECTORY) ? DT_DIR : 
DT_REG;
+    /*
+     * NTFS: symlinks are "dir + reparse" or "file + reparse"
+     * Unfortunately reparse attribute is used for many purposes 
(several dozens).
+     * It is not possible here to know is this name symlink or not.
+     * To get exactly the type of name we should to open inode (read mft).
+     * getattr for opened file (fstat) correctly returns symlink.
+     */
+    dt_type = (fname->dup.fa & FILE_ATTRIBUTE_DIRECTORY) ? DT_DIR : DT_REG;
+
+    /*
+     * It is not reliable to detect the type of name using duplicated 
information
+     * stored in parent directory.
+     * The only correct way to get the type of name - read MFT record 
and find ATTR_STD.
+     * The code below is not good idea.
+     * 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) &&
+        ino != ni->mi.rno) {
+        struct inode *inode = ntfs_iget5(sbi->sb, &e->ref, NULL);
+        if (!IS_ERR_OR_NULL(inode)) {
+            dt_type = fs_umode_to_dtype(inode->i_mode);
+            iput(inode);
+        }
+    }

      return !dir_emit(ctx, (s8 *)name, name_len, ino, dt_type);
  }
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 03/16] fs/ntfs3: Improve ntfs_dir_count
  2023-12-06 15:08 [PATCH 00/16] fs/ntfs3: Bugfix and refactoring Konstantin Komarovc
  2023-12-06 15:08 ` [PATCH 01/16] fs/ntfs3: Improve alternative boot processing Konstantin Komarovc
  2023-12-06 15:09 ` [PATCH 02/16] fs/ntfs3: Modified fix directory element type detection Konstantin Komarovc
@ 2023-12-06 15:10 ` Konstantin Komarovc
  2023-12-06 15:10 ` [PATCH 04/16] fs/ntfs3: Correct hard links updating when dealing with DOS neams Konstantin Komarovc
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Konstantin Komarovc @ 2023-12-06 15:10 UTC (permalink / raw)
  To: ntfs3; +Cc: linux-kernel, linux-fsdevel


Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
---
  fs/ntfs3/dir.c | 10 +++-------
  1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/fs/ntfs3/dir.c b/fs/ntfs3/dir.c
index 22ede4da0450..726122ecd39b 100644
--- a/fs/ntfs3/dir.c
+++ b/fs/ntfs3/dir.c
@@ -515,11 +515,9 @@ static int ntfs_dir_count(struct inode *dir, bool 
*is_empty, size_t *dirs,
      struct INDEX_HDR *hdr;
      const struct ATTR_FILE_NAME *fname;
      u32 e_size, off, end;
-    u64 vbo = 0;
      size_t drs = 0, fles = 0, bit = 0;
-    loff_t i_size = ni->vfs_inode.i_size;
      struct indx_node *node = NULL;
-    u8 index_bits = ni->dir.index_bits;
+    size_t max_indx = ni->vfs_inode.i_size >> ni->dir.index_bits;

      if (is_empty)
          *is_empty = true;
@@ -563,7 +561,7 @@ static int ntfs_dir_count(struct inode *dir, bool 
*is_empty, size_t *dirs,
                  fles += 1;
          }

-        if (vbo >= i_size)
+        if (bit >= max_indx)
              goto out;

          err = indx_used_bit(&ni->dir, ni, &bit);
@@ -573,8 +571,7 @@ static int ntfs_dir_count(struct inode *dir, bool 
*is_empty, size_t *dirs,
          if (bit == MINUS_ONE_T)
              goto out;

-        vbo = (u64)bit << index_bits;
-        if (vbo >= i_size)
+        if (bit >= max_indx)
              goto out;

          err = indx_read(&ni->dir, ni, bit << ni->dir.idx2vbn_bits,
@@ -584,7 +581,6 @@ static int ntfs_dir_count(struct inode *dir, bool 
*is_empty, size_t *dirs,

          hdr = &node->index->ihdr;
          bit += 1;
-        vbo = (u64)bit << ni->dir.idx2vbn_bits;
      }

  out:
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 04/16] fs/ntfs3: Correct hard links updating when dealing with DOS neams
  2023-12-06 15:08 [PATCH 00/16] fs/ntfs3: Bugfix and refactoring Konstantin Komarovc
                   ` (2 preceding siblings ...)
  2023-12-06 15:10 ` [PATCH 03/16] fs/ntfs3: Improve ntfs_dir_count Konstantin Komarovc
@ 2023-12-06 15:10 ` Konstantin Komarovc
  2023-12-06 15:11 ` [PATCH 05/16] fs/ntfs3: Print warning while fixing hard links count Konstantin Komarovc
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Konstantin Komarovc @ 2023-12-06 15:10 UTC (permalink / raw)
  To: ntfs3; +Cc: linux-kernel, linux-fsdevel


Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
---
  fs/ntfs3/record.c | 16 ++++++++++++++--
  1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/fs/ntfs3/record.c b/fs/ntfs3/record.c
index 53629b1f65e9..7b6423584eae 100644
--- a/fs/ntfs3/record.c
+++ b/fs/ntfs3/record.c
@@ -535,8 +535,20 @@ bool mi_remove_attr(struct ntfs_inode *ni, struct 
mft_inode *mi,
          return false;

      if (ni && is_attr_indexed(attr)) {
-        le16_add_cpu(&ni->mi.mrec->hard_links, -1);
-        ni->mi.dirty = true;
+        u16 links = le16_to_cpu(ni->mi.mrec->hard_links);
+        struct ATTR_FILE_NAME *fname =
+            attr->type != ATTR_NAME ?
+                NULL :
+                resident_data_ex(attr,
+                         SIZEOF_ATTRIBUTE_FILENAME);
+        if (fname && fname->type == FILE_NAME_DOS) {
+            /* Do not decrease links count deleting DOS name. */
+        } else if (!links) {
+            /* minor error. Not critical. */
+        } else {
+            ni->mi.mrec->hard_links = cpu_to_le16(links - 1);
+            ni->mi.dirty = true;
+        }
      }

      used -= asize;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 05/16] fs/ntfs3: Print warning while fixing hard links count
  2023-12-06 15:08 [PATCH 00/16] fs/ntfs3: Bugfix and refactoring Konstantin Komarovc
                   ` (3 preceding siblings ...)
  2023-12-06 15:10 ` [PATCH 04/16] fs/ntfs3: Correct hard links updating when dealing with DOS neams Konstantin Komarovc
@ 2023-12-06 15:11 ` Konstantin Komarovc
  2023-12-06 15:11 ` [PATCH 06/16] fs/ntfs3: Reduce stack usage Konstantin Komarovc
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Konstantin Komarovc @ 2023-12-06 15:11 UTC (permalink / raw)
  To: ntfs3; +Cc: linux-kernel, linux-fsdevel


Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
---
  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 5e3d71374918..fa6c7965473c 100644
--- a/fs/ntfs3/inode.c
+++ b/fs/ntfs3/inode.c
@@ -412,7 +412,6 @@ static struct inode *ntfs_read_mft(struct inode *inode,
          goto out;

      if (!is_match && name) {
-        /* Reuse rec as buffer for ascii name. */
          err = -ENOENT;
          goto out;
      }
@@ -427,6 +426,7 @@ static struct inode *ntfs_read_mft(struct inode *inode,

      if (names != le16_to_cpu(rec->hard_links)) {
          /* Correct minor error on the fly. Do not mark inode as dirty. */
+        ntfs_inode_warn(inode, "Correct links count -> %u.", names);
          rec->hard_links = cpu_to_le16(names);
          ni->mi.dirty = true;
      }
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 06/16] fs/ntfs3: Reduce stack usage
  2023-12-06 15:08 [PATCH 00/16] fs/ntfs3: Bugfix and refactoring Konstantin Komarovc
                   ` (4 preceding siblings ...)
  2023-12-06 15:11 ` [PATCH 05/16] fs/ntfs3: Print warning while fixing hard links count Konstantin Komarovc
@ 2023-12-06 15:11 ` Konstantin Komarovc
  2023-12-06 15:12 ` [PATCH 07/16] fs/ntfs3: Fix multithreaded stress test Konstantin Komarovc
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Konstantin Komarovc @ 2023-12-06 15:11 UTC (permalink / raw)
  To: ntfs3; +Cc: linux-kernel, linux-fsdevel


Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
---
  fs/ntfs3/fslog.c | 218 +++++++++++++++++++++--------------------------
  1 file changed, 98 insertions(+), 120 deletions(-)

diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c
index 98ccb6650858..7dbb000fc691 100644
--- a/fs/ntfs3/fslog.c
+++ b/fs/ntfs3/fslog.c
@@ -974,6 +974,16 @@ static inline void *alloc_rsttbl_from_idx(struct 
RESTART_TABLE **tbl, u32 vbo)
      return e;
  }

+struct restart_info {
+    u64 last_lsn;
+    struct RESTART_HDR *r_page;
+    u32 vbo;
+    bool chkdsk_was_run;
+    bool valid_page;
+    bool initialized;
+    bool restart;
+};
+
  #define RESTART_SINGLE_PAGE_IO cpu_to_le16(0x0001)

  #define NTFSLOG_WRAPPED 0x00000001
@@ -987,6 +997,7 @@ struct ntfs_log {
      struct ntfs_inode *ni;

      u32 l_size;
+    u32 orig_file_size;
      u32 sys_page_size;
      u32 sys_page_mask;
      u32 page_size;
@@ -1040,6 +1051,8 @@ struct ntfs_log {

      struct CLIENT_ID client_id;
      u32 client_undo_commit;
+
+    struct restart_info rst_info, rst_info2;
  };

  static inline u32 lsn_to_vbo(struct ntfs_log *log, const u64 lsn)
@@ -1105,16 +1118,6 @@ static inline bool verify_client_lsn(struct 
ntfs_log *log,
             lsn <= le64_to_cpu(log->ra->current_lsn) && lsn;
  }

-struct restart_info {
-    u64 last_lsn;
-    struct RESTART_HDR *r_page;
-    u32 vbo;
-    bool chkdsk_was_run;
-    bool valid_page;
-    bool initialized;
-    bool restart;
-};
-
  static int read_log_page(struct ntfs_log *log, u32 vbo,
               struct RECORD_PAGE_HDR **buffer, bool *usa_error)
  {
@@ -1176,7 +1179,7 @@ static int read_log_page(struct ntfs_log *log, u32 
vbo,
   * restart page header. It will stop the first time we find a
   * valid page header.
   */
-static int log_read_rst(struct ntfs_log *log, u32 l_size, bool first,
+static int log_read_rst(struct ntfs_log *log, bool first,
              struct restart_info *info)
  {
      u32 skip, vbo;
@@ -1192,7 +1195,7 @@ static int log_read_rst(struct ntfs_log *log, u32 
l_size, bool first,
      }

      /* Loop continuously until we succeed. */
-    for (; vbo < l_size; vbo = 2 * vbo + skip, skip = 0) {
+    for (; vbo < log->l_size; vbo = 2 * vbo + skip, skip = 0) {
          bool usa_error;
          bool brst, bchk;
          struct RESTART_AREA *ra;
@@ -1285,22 +1288,17 @@ static int log_read_rst(struct ntfs_log *log, 
u32 l_size, bool first,
  /*
   * Ilog_init_pg_hdr - Init @log from restart page header.
   */
-static void log_init_pg_hdr(struct ntfs_log *log, u32 sys_page_size,
-                u32 page_size, u16 major_ver, u16 minor_ver)
+static void log_init_pg_hdr(struct ntfs_log *log, u16 major_ver, u16 
minor_ver)
  {
-    log->sys_page_size = sys_page_size;
-    log->sys_page_mask = sys_page_size - 1;
-    log->page_size = page_size;
-    log->page_mask = page_size - 1;
-    log->page_bits = blksize_bits(page_size);
+    log->sys_page_size = log->page_size;
+    log->sys_page_mask = log->page_mask;

      log->clst_per_page = log->page_size >> log->ni->mi.sbi->cluster_bits;
      if (!log->clst_per_page)
          log->clst_per_page = 1;

-    log->first_page = major_ver >= 2 ?
-                  0x22 * page_size :
-                  ((sys_page_size << 1) + (page_size << 1));
+    log->first_page = major_ver >= 2 ? 0x22 * log->page_size :
+                       4 * log->page_size;
      log->major_ver = major_ver;
      log->minor_ver = minor_ver;
  }
@@ -1308,12 +1306,11 @@ static void log_init_pg_hdr(struct ntfs_log 
*log, u32 sys_page_size,
  /*
   * log_create - Init @log in cases when we don't have a restart area 
to use.
   */
-static void log_create(struct ntfs_log *log, u32 l_size, const u64 
last_lsn,
+static void log_create(struct ntfs_log *log, const u64 last_lsn,
                 u32 open_log_count, bool wrapped, bool use_multi_page)
  {
-    log->l_size = l_size;
      /* All file offsets must be quadword aligned. */
-    log->file_data_bits = blksize_bits(l_size) - 3;
+    log->file_data_bits = blksize_bits(log->l_size) - 3;
      log->seq_num_mask = (8 << log->file_data_bits) - 1;
      log->seq_num_bits = sizeof(u64) * 8 - log->file_data_bits;
      log->seq_num = (last_lsn >> log->file_data_bits) + 2;
@@ -3720,10 +3717,8 @@ int log_replay(struct ntfs_inode *ni, bool 
*initialized)
      struct ntfs_sb_info *sbi = ni->mi.sbi;
      struct ntfs_log *log;

-    struct restart_info rst_info, rst_info2;
-    u64 rec_lsn, ra_lsn, checkpt_lsn = 0, rlsn = 0;
+    u64 rec_lsn, checkpt_lsn = 0, rlsn = 0;
      struct ATTR_NAME_ENTRY *attr_names = NULL;
-    struct ATTR_NAME_ENTRY *ane;
      struct RESTART_TABLE *dptbl = NULL;
      struct RESTART_TABLE *trtbl = NULL;
      const struct RESTART_TABLE *rt;
@@ -3741,9 +3736,7 @@ int log_replay(struct ntfs_inode *ni, bool 
*initialized)
      struct TRANSACTION_ENTRY *tr;
      struct DIR_PAGE_ENTRY *dp;
      u32 i, bytes_per_attr_entry;
-    u32 l_size = ni->vfs_inode.i_size;
-    u32 orig_file_size = l_size;
-    u32 page_size, vbo, tail, off, dlen;
+    u32 vbo, tail, off, dlen;
      u32 saved_len, rec_len, transact_id;
      bool use_second_page;
      struct RESTART_AREA *ra2, *ra = NULL;
@@ -3758,52 +3751,50 @@ int log_replay(struct ntfs_inode *ni, bool 
*initialized)
      u16 t16;
      u32 t32;

-    /* Get the size of page. NOTE: To replay we can use default page. */
-#if PAGE_SIZE >= DefaultLogPageSize && PAGE_SIZE <= DefaultLogPageSize * 2
-    page_size = norm_file_page(PAGE_SIZE, &l_size, true);
-#else
-    page_size = norm_file_page(PAGE_SIZE, &l_size, false);
-#endif
-    if (!page_size)
-        return -EINVAL;
-
      log = kzalloc(sizeof(struct ntfs_log), GFP_NOFS);
      if (!log)
          return -ENOMEM;

      log->ni = ni;
-    log->l_size = l_size;
-    log->one_page_buf = kmalloc(page_size, GFP_NOFS);
+    log->l_size = log->orig_file_size = ni->vfs_inode.i_size;
+
+    /* Get the size of page. NOTE: To replay we can use default page. */
+#if PAGE_SIZE >= DefaultLogPageSize && PAGE_SIZE <= DefaultLogPageSize * 2
+    log->page_size = norm_file_page(PAGE_SIZE, &log->l_size, true);
+#else
+    log->page_size = norm_file_page(PAGE_SIZE, &log->l_size, false);
+#endif
+    if (!log->page_size) {
+        err = -EINVAL;
+        goto out;
+    }

+    log->one_page_buf = kmalloc(log->page_size, GFP_NOFS);
      if (!log->one_page_buf) {
          err = -ENOMEM;
          goto out;
      }

-    log->page_size = page_size;
-    log->page_mask = page_size - 1;
-    log->page_bits = blksize_bits(page_size);
+    log->page_mask = log->page_size - 1;
+    log->page_bits = blksize_bits(log->page_size);

      /* Look for a restart area on the disk. */
-    memset(&rst_info, 0, sizeof(struct restart_info));
-    err = log_read_rst(log, l_size, true, &rst_info);
+    err = log_read_rst(log, true, &log->rst_info);
      if (err)
          goto out;

      /* remember 'initialized' */
-    *initialized = rst_info.initialized;
+    *initialized = log->rst_info.initialized;

-    if (!rst_info.restart) {
-        if (rst_info.initialized) {
+    if (!log->rst_info.restart) {
+        if (log->rst_info.initialized) {
              /* No restart area but the file is not initialized. */
              err = -EINVAL;
              goto out;
          }

-        log_init_pg_hdr(log, page_size, page_size, 1, 1);
-        log_create(log, l_size, 0, get_random_u32(), false, false);
-
-        log->ra = ra;
+        log_init_pg_hdr(log, 1, 1);
+        log_create(log, 0, get_random_u32(), false, false);

          ra = log_create_ra(log);
          if (!ra) {
@@ -3820,25 +3811,26 @@ int log_replay(struct ntfs_inode *ni, bool 
*initialized)
       * If the restart offset above wasn't zero then we won't
       * look for a second restart.
       */
-    if (rst_info.vbo)
+    if (log->rst_info.vbo)
          goto check_restart_area;

-    memset(&rst_info2, 0, sizeof(struct restart_info));
-    err = log_read_rst(log, l_size, false, &rst_info2);
+    err = log_read_rst(log, false, &log->rst_info2);
      if (err)
          goto out;

      /* Determine which restart area to use. */
-    if (!rst_info2.restart || rst_info2.last_lsn <= rst_info.last_lsn)
+    if (!log->rst_info2.restart ||
+        log->rst_info2.last_lsn <= log->rst_info.last_lsn)
          goto use_first_page;

      use_second_page = true;

-    if (rst_info.chkdsk_was_run && page_size != rst_info.vbo) {
+    if (log->rst_info.chkdsk_was_run &&
+        log->page_size != log->rst_info.vbo) {
          struct RECORD_PAGE_HDR *sp = NULL;
          bool usa_error;

-        if (!read_log_page(log, page_size, &sp, &usa_error) &&
+        if (!read_log_page(log, log->page_size, &sp, &usa_error) &&
              sp->rhdr.sign == NTFS_CHKD_SIGNATURE) {
              use_second_page = false;
          }
@@ -3846,52 +3838,43 @@ int log_replay(struct ntfs_inode *ni, bool 
*initialized)
      }

      if (use_second_page) {
-        kfree(rst_info.r_page);
-        memcpy(&rst_info, &rst_info2, sizeof(struct restart_info));
-        rst_info2.r_page = NULL;
+        kfree(log->rst_info.r_page);
+        memcpy(&log->rst_info, &log->rst_info2,
+               sizeof(struct restart_info));
+        log->rst_info2.r_page = NULL;
      }

  use_first_page:
-    kfree(rst_info2.r_page);
+    kfree(log->rst_info2.r_page);

  check_restart_area:
      /*
       * If the restart area is at offset 0, we want
       * to write the second restart area first.
       */
-    log->init_ra = !!rst_info.vbo;
+    log->init_ra = !!log->rst_info.vbo;

      /* If we have a valid page then grab a pointer to the restart area. */
-    ra2 = rst_info.valid_page ?
-              Add2Ptr(rst_info.r_page,
-                  le16_to_cpu(rst_info.r_page->ra_off)) :
+    ra2 = log->rst_info.valid_page ?
+              Add2Ptr(log->rst_info.r_page,
+                  le16_to_cpu(log->rst_info.r_page->ra_off)) :
                NULL;

-    if (rst_info.chkdsk_was_run ||
+    if (log->rst_info.chkdsk_was_run ||
          (ra2 && ra2->client_idx[1] == LFS_NO_CLIENT_LE)) {
          bool wrapped = false;
          bool use_multi_page = false;
          u32 open_log_count;

          /* Do some checks based on whether we have a valid log page. */
-        if (!rst_info.valid_page) {
-            open_log_count = get_random_u32();
-            goto init_log_instance;
-        }
-        open_log_count = le32_to_cpu(ra2->open_log_count);
-
-        /*
-         * If the restart page size isn't changing then we want to
-         * check how much work we need to do.
-         */
-        if (page_size != le32_to_cpu(rst_info.r_page->sys_page_size))
-            goto init_log_instance;
+        open_log_count = log->rst_info.valid_page ?
+                     le32_to_cpu(ra2->open_log_count) :
+                     get_random_u32();

-init_log_instance:
-        log_init_pg_hdr(log, page_size, page_size, 1, 1);
+        log_init_pg_hdr(log, 1, 1);

-        log_create(log, l_size, rst_info.last_lsn, open_log_count,
-               wrapped, use_multi_page);
+        log_create(log, log->rst_info.last_lsn, open_log_count, wrapped,
+               use_multi_page);

          ra = log_create_ra(log);
          if (!ra) {
@@ -3916,28 +3899,27 @@ int log_replay(struct ntfs_inode *ni, bool 
*initialized)
       * use the log file. We must use the system page size instead of the
       * default size if there is not a clean shutdown.
       */
-    t32 = le32_to_cpu(rst_info.r_page->sys_page_size);
-    if (page_size != t32) {
-        l_size = orig_file_size;
-        page_size =
-            norm_file_page(t32, &l_size, t32 == DefaultLogPageSize);
+    t32 = le32_to_cpu(log->rst_info.r_page->sys_page_size);
+    if (log->page_size != t32) {
+        log->l_size = log->orig_file_size;
+        log->page_size = norm_file_page(t32, &log->l_size,
+                        t32 == DefaultLogPageSize);
      }

-    if (page_size != t32 ||
-        page_size != le32_to_cpu(rst_info.r_page->page_size)) {
+    if (log->page_size != t32 ||
+        log->page_size != le32_to_cpu(log->rst_info.r_page->page_size)) {
          err = -EINVAL;
          goto out;
      }

      /* If the file size has shrunk then we won't mount it. */
-    if (l_size < le64_to_cpu(ra2->l_size)) {
+    if (log->l_size < le64_to_cpu(ra2->l_size)) {
          err = -EINVAL;
          goto out;
      }

-    log_init_pg_hdr(log, page_size, page_size,
-            le16_to_cpu(rst_info.r_page->major_ver),
-            le16_to_cpu(rst_info.r_page->minor_ver));
+    log_init_pg_hdr(log, le16_to_cpu(log->rst_info.r_page->major_ver),
+            le16_to_cpu(log->rst_info.r_page->minor_ver));

      log->l_size = le64_to_cpu(ra2->l_size);
      log->seq_num_bits = le32_to_cpu(ra2->seq_num_bits);
@@ -3945,7 +3927,7 @@ int log_replay(struct ntfs_inode *ni, bool 
*initialized)
      log->seq_num_mask = (8 << log->file_data_bits) - 1;
      log->last_lsn = le64_to_cpu(ra2->current_lsn);
      log->seq_num = log->last_lsn >> log->file_data_bits;
-    log->ra_off = le16_to_cpu(rst_info.r_page->ra_off);
+    log->ra_off = le16_to_cpu(log->rst_info.r_page->ra_off);
      log->restart_size = log->sys_page_size - log->ra_off;
      log->record_header_len = le16_to_cpu(ra2->rec_hdr_len);
      log->ra_size = le16_to_cpu(ra2->ra_len);
@@ -4045,7 +4027,7 @@ int log_replay(struct ntfs_inode *ni, bool 
*initialized)
      log->current_avail = current_log_avail(log);

      /* Remember which restart area to write first. */
-    log->init_ra = rst_info.vbo;
+    log->init_ra = log->rst_info.vbo;

  process_log:
      /* 1.0, 1.1, 2.0 log->major_ver/minor_ver - short values. */
@@ -4105,7 +4087,7 @@ int log_replay(struct ntfs_inode *ni, bool 
*initialized)
      log->client_id.seq_num = cr->seq_num;
      log->client_id.client_idx = client;

-    err = read_rst_area(log, &rst, &ra_lsn);
+    err = read_rst_area(log, &rst, &checkpt_lsn);
      if (err)
          goto out;

@@ -4114,9 +4096,8 @@ int log_replay(struct ntfs_inode *ni, bool 
*initialized)

      bytes_per_attr_entry = !rst->major_ver ? 0x2C : 0x28;

-    checkpt_lsn = le64_to_cpu(rst->check_point_start);
-    if (!checkpt_lsn)
-        checkpt_lsn = ra_lsn;
+    if (rst->check_point_start)
+        checkpt_lsn = le64_to_cpu(rst->check_point_start);

      /* Allocate and Read the Transaction Table. */
      if (!rst->transact_table_len)
@@ -4330,23 +4311,20 @@ int log_replay(struct ntfs_inode *ni, bool 
*initialized)
      lcb = NULL;

  check_attribute_names2:
-    if (!rst->attr_names_len)
-        goto trace_attribute_table;
-
-    ane = attr_names;
-    if (!oatbl)
-        goto trace_attribute_table;
-    while (ane->off) {
-        /* TODO: Clear table on exit! */
-        oe = Add2Ptr(oatbl, le16_to_cpu(ane->off));
-        t16 = le16_to_cpu(ane->name_bytes);
-        oe->name_len = t16 / sizeof(short);
-        oe->ptr = ane->name;
-        oe->is_attr_name = 2;
-        ane = Add2Ptr(ane, sizeof(struct ATTR_NAME_ENTRY) + t16);
-    }
-
-trace_attribute_table:
+    if (rst->attr_names_len && oatbl) {
+        struct ATTR_NAME_ENTRY *ane = attr_names;
+        while (ane->off) {
+            /* TODO: Clear table on exit! */
+            oe = Add2Ptr(oatbl, le16_to_cpu(ane->off));
+            t16 = le16_to_cpu(ane->name_bytes);
+            oe->name_len = t16 / sizeof(short);
+            oe->ptr = ane->name;
+            oe->is_attr_name = 2;
+            ane = Add2Ptr(ane,
+                      sizeof(struct ATTR_NAME_ENTRY) + t16);
+        }
+    }
+
      /*
       * If the checkpt_lsn is zero, then this is a freshly
       * formatted disk and we have no work to do.
@@ -5189,7 +5167,7 @@ int log_replay(struct ntfs_inode *ni, bool 
*initialized)
      kfree(oatbl);
      kfree(dptbl);
      kfree(attr_names);
-    kfree(rst_info.r_page);
+    kfree(log->rst_info.r_page);

      kfree(ra);
      kfree(log->one_page_buf);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 07/16] fs/ntfs3: Fix multithreaded stress test
  2023-12-06 15:08 [PATCH 00/16] fs/ntfs3: Bugfix and refactoring Konstantin Komarovc
                   ` (5 preceding siblings ...)
  2023-12-06 15:11 ` [PATCH 06/16] fs/ntfs3: Reduce stack usage Konstantin Komarovc
@ 2023-12-06 15:12 ` Konstantin Komarovc
  2023-12-06 15:12 ` [PATCH 08/16] fs/ntfs3: Fix detected field-spanning write (size 8) of single field "le->name" Konstantin Komarovc
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Konstantin Komarovc @ 2023-12-06 15:12 UTC (permalink / raw)
  To: ntfs3; +Cc: linux-kernel, linux-fsdevel


Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
---
  fs/ntfs3/attrib.c | 21 ++++++++++++++-------
  1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c
index 63f70259edc0..4b78b669a3bd 100644
--- a/fs/ntfs3/attrib.c
+++ b/fs/ntfs3/attrib.c
@@ -886,7 +886,7 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST 
vcn, CLST clen, CLST *lcn,
      struct runs_tree *run = &ni->file.run;
      struct ntfs_sb_info *sbi;
      u8 cluster_bits;
-    struct ATTRIB *attr = NULL, *attr_b;
+    struct ATTRIB *attr, *attr_b;
      struct ATTR_LIST_ENTRY *le, *le_b;
      struct mft_inode *mi, *mi_b;
      CLST hint, svcn, to_alloc, evcn1, next_svcn, asize, end, vcn0, alen;
@@ -904,12 +904,8 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST 
vcn, CLST clen, CLST *lcn,
          *len = 0;
      up_read(&ni->file.run_lock);

-    if (*len) {
-        if (*lcn != SPARSE_LCN || !new)
-            return 0; /* Fast normal way without allocation. */
-        else if (clen > *len)
-            clen = *len;
-    }
+    if (*len && (*lcn != SPARSE_LCN || !new))
+        return 0; /* Fast normal way without allocation. */

      /* No cluster in cache or we need to allocate cluster in hole. */
      sbi = ni->mi.sbi;
@@ -918,6 +914,17 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST 
vcn, CLST clen, CLST *lcn,
      ni_lock(ni);
      down_write(&ni->file.run_lock);

+    /* Repeat the code above (under write lock). */
+    if (!run_lookup_entry(run, vcn, lcn, len, NULL))
+        *len = 0;
+
+    if (*len) {
+        if (*lcn != SPARSE_LCN || !new)
+            goto out; /* normal way without allocation. */
+        if (clen > *len)
+            clen = *len;
+    }
+
      le_b = NULL;
      attr_b = ni_find_attr(ni, NULL, &le_b, ATTR_DATA, NULL, 0, NULL, 
&mi_b);
      if (!attr_b) {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 08/16] fs/ntfs3: Fix detected field-spanning write (size 8) of single field "le->name"
  2023-12-06 15:08 [PATCH 00/16] fs/ntfs3: Bugfix and refactoring Konstantin Komarovc
                   ` (6 preceding siblings ...)
  2023-12-06 15:12 ` [PATCH 07/16] fs/ntfs3: Fix multithreaded stress test Konstantin Komarovc
@ 2023-12-06 15:12 ` Konstantin Komarovc
  2023-12-07  9:31   ` Geert Uytterhoeven
  2023-12-06 15:12 ` [PATCH 09/16] fs/ntfs3: Correct use bh_read Konstantin Komarovc
                   ` (7 subsequent siblings)
  15 siblings, 1 reply; 18+ messages in thread
From: Konstantin Komarovc @ 2023-12-06 15:12 UTC (permalink / raw)
  To: ntfs3; +Cc: linux-kernel, linux-fsdevel


Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
---
  fs/ntfs3/ntfs.h | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/ntfs3/ntfs.h b/fs/ntfs3/ntfs.h
index 86aecbb01a92..13e96fc63dae 100644
--- a/fs/ntfs3/ntfs.h
+++ b/fs/ntfs3/ntfs.h
@@ -523,7 +523,7 @@ struct ATTR_LIST_ENTRY {
      __le64 vcn;        // 0x08: Starting VCN of this attribute.
      struct MFT_REF ref;    // 0x10: MFT record number with attribute.
      __le16 id;        // 0x18: struct ATTRIB ID.
-    __le16 name[3];        // 0x1A: Just to align. To get real name can 
use bNameOffset.
+    __le16 name[];        // 0x1A: Just to align. To get real name can 
use name_off.

  }; // sizeof(0x20)

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 09/16] fs/ntfs3: Correct use bh_read
  2023-12-06 15:08 [PATCH 00/16] fs/ntfs3: Bugfix and refactoring Konstantin Komarovc
                   ` (7 preceding siblings ...)
  2023-12-06 15:12 ` [PATCH 08/16] fs/ntfs3: Fix detected field-spanning write (size 8) of single field "le->name" Konstantin Komarovc
@ 2023-12-06 15:12 ` Konstantin Komarovc
  2023-12-06 15:12 ` [PATCH 10/16] fs/ntfs3: Add file_modified Konstantin Komarovc
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Konstantin Komarovc @ 2023-12-06 15:12 UTC (permalink / raw)
  To: ntfs3; +Cc: linux-kernel, linux-fsdevel


Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
---
  fs/ntfs3/file.c  | 19 +++++++++----------
  fs/ntfs3/inode.c |  7 +++----
  2 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
index a5a30a24ce5d..5691f04e6751 100644
--- a/fs/ntfs3/file.c
+++ b/fs/ntfs3/file.c
@@ -188,6 +188,7 @@ static int ntfs_zero_range(struct inode *inode, u64 
vbo, u64 vbo_to)
      u32 bh_next, bh_off, to;
      sector_t iblock;
      struct folio *folio;
+    bool dirty = false;

      for (; idx < idx_end; idx += 1, from = 0) {
          page_off = (loff_t)idx << PAGE_SHIFT;
@@ -223,29 +224,27 @@ static int ntfs_zero_range(struct inode *inode, 
u64 vbo, u64 vbo_to)
              /* Ok, it's mapped. Make sure it's up-to-date. */
              if (folio_test_uptodate(folio))
                  set_buffer_uptodate(bh);
-
-            if (!buffer_uptodate(bh)) {
-                err = bh_read(bh, 0);
-                if (err < 0) {
-                    folio_unlock(folio);
-                    folio_put(folio);
-                    goto out;
-                }
+            else if (bh_read(bh, 0) < 0) {
+                err = -EIO;
+                folio_unlock(folio);
+                folio_put(folio);
+                goto out;
              }

              mark_buffer_dirty(bh);
-
          } while (bh_off = bh_next, iblock += 1,
               head != (bh = bh->b_this_page));

          folio_zero_segment(folio, from, to);
+        dirty = true;

          folio_unlock(folio);
          folio_put(folio);
          cond_resched();
      }
  out:
-    mark_inode_dirty(inode);
+    if (dirty)
+        mark_inode_dirty(inode);
      return err;
  }

diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c
index fa6c7965473c..bba0208c4afd 100644
--- a/fs/ntfs3/inode.c
+++ b/fs/ntfs3/inode.c
@@ -345,9 +345,7 @@ static struct inode *ntfs_read_mft(struct inode *inode,
              inode->i_size = le16_to_cpu(rp.SymbolicLinkReparseBuffer
                                  .PrintNameLength) /
                      sizeof(u16);
-
              ni->i_valid = inode->i_size;
-
              /* Clear directory bit. */
              if (ni->ni_flags & NI_FLAG_DIR) {
                  indx_clear(&ni->dir);
@@ -653,9 +651,10 @@ static noinline int ntfs_get_block_vbo(struct inode 
*inode, u64 vbo,
              off = vbo & (PAGE_SIZE - 1);
              folio_set_bh(bh, folio, off);

-            err = bh_read(bh, 0);
-            if (err < 0)
+            if (bh_read(bh, 0) < 0) {
+                err = -EIO;
                  goto out;
+            }
              folio_zero_segment(folio, off + voff, off + block_size);
          }
      }
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 10/16] fs/ntfs3: Add file_modified
  2023-12-06 15:08 [PATCH 00/16] fs/ntfs3: Bugfix and refactoring Konstantin Komarovc
                   ` (8 preceding siblings ...)
  2023-12-06 15:12 ` [PATCH 09/16] fs/ntfs3: Correct use bh_read Konstantin Komarovc
@ 2023-12-06 15:12 ` Konstantin Komarovc
  2023-12-06 15:13 ` [PATCH 11/16] fs/ntfs3: Drop suid and sgid bits as a part of fpunch Konstantin Komarovc
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Konstantin Komarovc @ 2023-12-06 15:12 UTC (permalink / raw)
  To: ntfs3; +Cc: linux-kernel, linux-fsdevel


Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
---
  fs/ntfs3/file.c | 13 +++++++++++++
  1 file changed, 13 insertions(+)

diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
index 5691f04e6751..bb80ce2eec2f 100644
--- a/fs/ntfs3/file.c
+++ b/fs/ntfs3/file.c
@@ -632,11 +632,17 @@ static long ntfs_fallocate(struct file *file, int 
mode, loff_t vbo, loff_t len)
                          &ni->file.run, i_size, &ni->i_valid,
                          true, NULL);
              ni_unlock(ni);
+            if (err)
+                goto out;
          } else if (new_size > i_size) {
              inode->i_size = new_size;
          }
      }

+    err = file_modified(file);
+    if (err)
+        goto out;
+
  out:
      if (map_locked)
          filemap_invalidate_unlock(mapping);
@@ -1040,6 +1046,7 @@ static ssize_t ntfs_file_write_iter(struct kiocb 
*iocb, struct iov_iter *from)
      struct address_space *mapping = file->f_mapping;
      struct inode *inode = mapping->host;
      ssize_t ret;
+    int err;
      struct ntfs_inode *ni = ntfs_i(inode);

      if (is_encrypted(ni)) {
@@ -1067,6 +1074,12 @@ static ssize_t ntfs_file_write_iter(struct kiocb 
*iocb, struct iov_iter *from)
      if (ret <= 0)
          goto out;

+    err = file_modified(iocb->ki_filp);
+    if (err) {
+        ret = err;
+        goto out;
+    }
+
      if (WARN_ON(ni->ni_flags & NI_FLAG_COMPRESSED_MASK)) {
          /* Should never be here, see ntfs_file_open(). */
          ret = -EOPNOTSUPP;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 11/16] fs/ntfs3: Drop suid and sgid bits as a part of fpunch
  2023-12-06 15:08 [PATCH 00/16] fs/ntfs3: Bugfix and refactoring Konstantin Komarovc
                   ` (9 preceding siblings ...)
  2023-12-06 15:12 ` [PATCH 10/16] fs/ntfs3: Add file_modified Konstantin Komarovc
@ 2023-12-06 15:13 ` Konstantin Komarovc
  2023-12-06 15:13 ` [PATCH 12/16] fs/ntfs3: Implement super_operations::shutdown Konstantin Komarovc
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Konstantin Komarovc @ 2023-12-06 15:13 UTC (permalink / raw)
  To: ntfs3; +Cc: linux-kernel, linux-fsdevel


Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
---
  fs/ntfs3/file.c | 9 +++++++++
  1 file changed, 9 insertions(+)

diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
index bb80ce2eec2f..0ff5d3af2889 100644
--- a/fs/ntfs3/file.c
+++ b/fs/ntfs3/file.c
@@ -498,10 +498,14 @@ static long ntfs_fallocate(struct file *file, int 
mode, loff_t vbo, loff_t len)
          ni_lock(ni);
          err = attr_punch_hole(ni, vbo, len, &frame_size);
          ni_unlock(ni);
+        if (!err)
+            goto ok;
+
          if (err != E_NTFS_NOTALIGNED)
              goto out;

          /* Process not aligned punch. */
+        err = 0;
          mask = frame_size - 1;
          vbo_a = (vbo + mask) & ~mask;
          end_a = end & ~mask;
@@ -524,6 +528,8 @@ static long ntfs_fallocate(struct file *file, int 
mode, loff_t vbo, loff_t len)
              ni_lock(ni);
              err = attr_punch_hole(ni, vbo_a, end_a - vbo_a, NULL);
              ni_unlock(ni);
+            if (err)
+                goto out;
          }
      } else if (mode & FALLOC_FL_COLLAPSE_RANGE) {
          /*
@@ -563,6 +569,8 @@ static long ntfs_fallocate(struct file *file, int 
mode, loff_t vbo, loff_t len)
          ni_lock(ni);
          err = attr_insert_range(ni, vbo, len);
          ni_unlock(ni);
+        if (err)
+            goto out;
      } else {
          /* Check new size. */
          u8 cluster_bits = sbi->cluster_bits;
@@ -639,6 +647,7 @@ static long ntfs_fallocate(struct file *file, int 
mode, loff_t vbo, loff_t len)
          }
      }

+ok:
      err = file_modified(file);
      if (err)
          goto out;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 12/16] fs/ntfs3: Implement super_operations::shutdown
  2023-12-06 15:08 [PATCH 00/16] fs/ntfs3: Bugfix and refactoring Konstantin Komarovc
                   ` (10 preceding siblings ...)
  2023-12-06 15:13 ` [PATCH 11/16] fs/ntfs3: Drop suid and sgid bits as a part of fpunch Konstantin Komarovc
@ 2023-12-06 15:13 ` Konstantin Komarovc
  2023-12-06 15:13 ` [PATCH 13/16] fs/ntfs3: ntfs3_forced_shutdown use int instead of bool Konstantin Komarovc
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Konstantin Komarovc @ 2023-12-06 15:13 UTC (permalink / raw)
  To: ntfs3; +Cc: linux-kernel, linux-fsdevel


Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
---
  fs/ntfs3/file.c    | 18 ++++++++++++++++++
  fs/ntfs3/frecord.c |  3 +++
  fs/ntfs3/inode.c   | 21 +++++++++++++++++++--
  fs/ntfs3/namei.c   | 12 ++++++++++++
  fs/ntfs3/ntfs_fs.h |  9 ++++++++-
  fs/ntfs3/super.c   | 12 ++++++++++++
  fs/ntfs3/xattr.c   |  3 +++
  7 files changed, 75 insertions(+), 3 deletions(-)

diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
index 0ff5d3af2889..07ed3d946e7c 100644
--- a/fs/ntfs3/file.c
+++ b/fs/ntfs3/file.c
@@ -260,6 +260,9 @@ static int ntfs_file_mmap(struct file *file, struct 
vm_area_struct *vma)
      bool rw = vma->vm_flags & VM_WRITE;
      int err;

+    if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
+        return -EIO;
+
      if (is_encrypted(ni)) {
          ntfs_inode_warn(inode, "mmap encrypted not supported");
          return -EOPNOTSUPP;
@@ -677,6 +680,9 @@ int ntfs3_setattr(struct mnt_idmap *idmap, struct 
dentry *dentry,
      umode_t mode = inode->i_mode;
      int err;

+    if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
+        return -EIO;
+
      err = setattr_prepare(idmap, dentry, attr);
      if (err)
          goto out;
@@ -732,6 +738,9 @@ static ssize_t ntfs_file_read_iter(struct kiocb 
*iocb, struct iov_iter *iter)
      struct inode *inode = file->f_mapping->host;
      struct ntfs_inode *ni = ntfs_i(inode);

+    if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
+        return -EIO;
+
      if (is_encrypted(ni)) {
          ntfs_inode_warn(inode, "encrypted i/o not supported");
          return -EOPNOTSUPP;
@@ -766,6 +775,9 @@ static ssize_t ntfs_file_splice_read(struct file 
*in, loff_t *ppos,
      struct inode *inode = in->f_mapping->host;
      struct ntfs_inode *ni = ntfs_i(inode);

+    if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
+        return -EIO;
+
      if (is_encrypted(ni)) {
          ntfs_inode_warn(inode, "encrypted i/o not supported");
          return -EOPNOTSUPP;
@@ -1058,6 +1070,9 @@ static ssize_t ntfs_file_write_iter(struct kiocb 
*iocb, struct iov_iter *from)
      int err;
      struct ntfs_inode *ni = ntfs_i(inode);

+    if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
+        return -EIO;
+
      if (is_encrypted(ni)) {
          ntfs_inode_warn(inode, "encrypted i/o not supported");
          return -EOPNOTSUPP;
@@ -1118,6 +1133,9 @@ int ntfs_file_open(struct inode *inode, struct 
file *file)
  {
      struct ntfs_inode *ni = ntfs_i(inode);

+    if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
+        return -EIO;
+
      if (unlikely((is_compressed(ni) || is_encrypted(ni)) &&
               (file->f_flags & O_DIRECT))) {
          return -EOPNOTSUPP;
diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c
index 3df2d9e34b91..8744ba36d422 100644
--- a/fs/ntfs3/frecord.c
+++ b/fs/ntfs3/frecord.c
@@ -3259,6 +3259,9 @@ int ni_write_inode(struct inode *inode, int sync, 
const char *hint)
      if (is_bad_inode(inode) || sb_rdonly(sb))
          return 0;

+    if (unlikely(ntfs3_forced_shutdown(sb)))
+        return -EIO;
+
      if (!ni_trylock(ni)) {
          /* 'ni' is under modification, skip for now. */
          mark_inode_dirty_sync(inode);
diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c
index bba0208c4afd..85452a6b1d40 100644
--- a/fs/ntfs3/inode.c
+++ b/fs/ntfs3/inode.c
@@ -852,9 +852,13 @@ static int ntfs_resident_writepage(struct folio *folio,
                     struct writeback_control *wbc, void *data)
  {
      struct address_space *mapping = data;
-    struct ntfs_inode *ni = ntfs_i(mapping->host);
+    struct inode *inode = mapping->host;
+    struct ntfs_inode *ni = ntfs_i(inode);
      int ret;

+    if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
+        return -EIO;
+
      ni_lock(ni);
      ret = attr_data_write_resident(ni, &folio->page);
      ni_unlock(ni);
@@ -868,7 +872,12 @@ static int ntfs_resident_writepage(struct folio *folio,
  static int ntfs_writepages(struct address_space *mapping,
                 struct writeback_control *wbc)
  {
-    if (is_resident(ntfs_i(mapping->host)))
+    struct inode *inode = mapping->host;
+
+    if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
+        return -EIO;
+
+    if (is_resident(ntfs_i(inode)))
          return write_cache_pages(mapping, wbc, ntfs_resident_writepage,
                       mapping);
      return mpage_writepages(mapping, wbc, ntfs_get_block);
@@ -888,6 +897,9 @@ int ntfs_write_begin(struct file *file, struct 
address_space *mapping,
      struct inode *inode = mapping->host;
      struct ntfs_inode *ni = ntfs_i(inode);

+    if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
+        return -EIO;
+
      *pagep = NULL;
      if (is_resident(ni)) {
          struct page *page =
@@ -1305,6 +1317,11 @@ struct inode *ntfs_create_inode(struct mnt_idmap 
*idmap, struct inode *dir,
          goto out1;
      }

+    if (unlikely(ntfs3_forced_shutdown(sb))) {
+        err = -EIO;
+        goto out2;
+    }
+
      /* Mark rw ntfs as dirty. it will be cleared at umount. */
      ntfs_set_state(sbi, NTFS_DIRTY_DIRTY);

diff --git a/fs/ntfs3/namei.c b/fs/ntfs3/namei.c
index ee3093be5170..cae41db0aaa7 100644
--- a/fs/ntfs3/namei.c
+++ b/fs/ntfs3/namei.c
@@ -181,6 +181,9 @@ static int ntfs_unlink(struct inode *dir, struct 
dentry *dentry)
      struct ntfs_inode *ni = ntfs_i(dir);
      int err;

+    if (unlikely(ntfs3_forced_shutdown(dir->i_sb)))
+        return -EIO;
+
      ni_lock_dir(ni);

      err = ntfs_unlink_inode(dir, dentry);
@@ -199,6 +202,9 @@ static int ntfs_symlink(struct mnt_idmap *idmap, 
struct inode *dir,
      u32 size = strlen(symname);
      struct inode *inode;

+    if (unlikely(ntfs3_forced_shutdown(dir->i_sb)))
+        return -EIO;
+
      inode = ntfs_create_inode(idmap, dir, dentry, NULL, S_IFLNK | 0777, 0,
                    symname, size, NULL);

@@ -227,6 +233,9 @@ static int ntfs_rmdir(struct inode *dir, struct 
dentry *dentry)
      struct ntfs_inode *ni = ntfs_i(dir);
      int err;

+    if (unlikely(ntfs3_forced_shutdown(dir->i_sb)))
+        return -EIO;
+
      ni_lock_dir(ni);

      err = ntfs_unlink_inode(dir, dentry);
@@ -264,6 +273,9 @@ static int ntfs_rename(struct mnt_idmap *idmap, 
struct inode *dir,
                1024);
      static_assert(PATH_MAX >= 4 * 1024);

+    if (unlikely(ntfs3_forced_shutdown(sb)))
+        return -EIO;
+
      if (flags & ~RENAME_NOREPLACE)
          return -EINVAL;

diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h
index f6706143d14b..d40bc7669ae5 100644
--- a/fs/ntfs3/ntfs_fs.h
+++ b/fs/ntfs3/ntfs_fs.h
@@ -61,6 +61,8 @@ enum utf16_endian;

  /* sbi->flags */
  #define NTFS_FLAGS_NODISCARD        0x00000001
+/* ntfs in shutdown state. */
+#define NTFS_FLAGS_SHUTDOWN        0x00000002
  /* Set when LogFile is replaying. */
  #define NTFS_FLAGS_LOG_REPLAYING    0x00000008
  /* Set when we changed first MFT's which copy must be updated in 
$MftMirr. */
@@ -226,7 +228,7 @@ struct ntfs_sb_info {
      u64 maxbytes; // Maximum size for normal files.
      u64 maxbytes_sparse; // Maximum size for sparse file.

-    u32 flags; // See NTFS_FLAGS_XXX.
+    unsigned long flags; // See NTFS_FLAGS_

      CLST zone_max; // Maximum MFT zone length in clusters
      CLST bad_clusters; // The count of marked bad clusters.
@@ -999,6 +1001,11 @@ static inline struct ntfs_sb_info *ntfs_sb(struct 
super_block *sb)
      return sb->s_fs_info;
  }

+static inline bool ntfs3_forced_shutdown(struct super_block *sb)
+{
+    return test_bit(NTFS_FLAGS_SHUTDOWN, &ntfs_sb(sb)->flags);
+}
+
  /*
   * ntfs_up_cluster - Align up on cluster boundary.
   */
diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c
index 09d61c6c90aa..af8521a6ed95 100644
--- a/fs/ntfs3/super.c
+++ b/fs/ntfs3/super.c
@@ -714,6 +714,14 @@ static int ntfs_show_options(struct seq_file *m, 
struct dentry *root)
      return 0;
  }

+/*
+ * ntfs_shutdown - super_operations::shutdown
+ */
+static void ntfs_shutdown(struct super_block *sb)
+{
+    set_bit(NTFS_FLAGS_SHUTDOWN, &ntfs_sb(sb)->flags);
+}
+
  /*
   * ntfs_sync_fs - super_operations::sync_fs
   */
@@ -724,6 +732,9 @@ static int ntfs_sync_fs(struct super_block *sb, int 
wait)
      struct ntfs_inode *ni;
      struct inode *inode;

+    if (unlikely(ntfs3_forced_shutdown(sb)))
+        return -EIO;
+
      ni = sbi->security.ni;
      if (ni) {
          inode = &ni->vfs_inode;
@@ -763,6 +774,7 @@ static const struct super_operations ntfs_sops = {
      .put_super = ntfs_put_super,
      .statfs = ntfs_statfs,
      .show_options = ntfs_show_options,
+    .shutdown = ntfs_shutdown,
      .sync_fs = ntfs_sync_fs,
      .write_inode = ntfs3_write_inode,
  };
diff --git a/fs/ntfs3/xattr.c b/fs/ntfs3/xattr.c
index 4274b6f31cfa..071356d096d8 100644
--- a/fs/ntfs3/xattr.c
+++ b/fs/ntfs3/xattr.c
@@ -744,6 +744,9 @@ static int ntfs_getxattr(const struct xattr_handler 
*handler, struct dentry *de,
      int err;
      struct ntfs_inode *ni = ntfs_i(inode);

+    if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
+        return -EIO;
+
      /* Dispatch request. */
      if (!strcmp(name, SYSTEM_DOS_ATTRIB)) {
          /* system.dos_attrib */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 13/16] fs/ntfs3: ntfs3_forced_shutdown use int instead of bool
  2023-12-06 15:08 [PATCH 00/16] fs/ntfs3: Bugfix and refactoring Konstantin Komarovc
                   ` (11 preceding siblings ...)
  2023-12-06 15:13 ` [PATCH 12/16] fs/ntfs3: Implement super_operations::shutdown Konstantin Komarovc
@ 2023-12-06 15:13 ` Konstantin Komarovc
  2023-12-06 15:14 ` [PATCH 14/16] fs/ntfs3: Add and fix comments Konstantin Komarovc
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Konstantin Komarovc @ 2023-12-06 15:13 UTC (permalink / raw)
  To: ntfs3; +Cc: linux-kernel, linux-fsdevel


Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
---
  fs/ntfs3/fsntfs.c  | 3 ++-
  fs/ntfs3/ntfs_fs.h | 6 +++---
  fs/ntfs3/super.c   | 2 +-
  3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c
index fbfe21dbb425..350461d8cece 100644
--- a/fs/ntfs3/fsntfs.c
+++ b/fs/ntfs3/fsntfs.c
@@ -853,7 +853,8 @@ void ntfs_update_mftmirr(struct ntfs_sb_info *sbi, 
int wait)
      /*
       * sb can be NULL here. In this case sbi->flags should be 0 too.
       */
-    if (!sb || !(sbi->flags & NTFS_FLAGS_MFTMIRR))
+    if (!sb || !(sbi->flags & NTFS_FLAGS_MFTMIRR) ||
+        unlikely(ntfs3_forced_shutdown(sb)))
          return;

      blocksize = sb->s_blocksize;
diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h
index d40bc7669ae5..7510875efef6 100644
--- a/fs/ntfs3/ntfs_fs.h
+++ b/fs/ntfs3/ntfs_fs.h
@@ -62,7 +62,7 @@ enum utf16_endian;
  /* sbi->flags */
  #define NTFS_FLAGS_NODISCARD        0x00000001
  /* ntfs in shutdown state. */
-#define NTFS_FLAGS_SHUTDOWN        0x00000002
+#define NTFS_FLAGS_SHUTDOWN_BIT        0x00000002  /* == 4*/
  /* Set when LogFile is replaying. */
  #define NTFS_FLAGS_LOG_REPLAYING    0x00000008
  /* Set when we changed first MFT's which copy must be updated in 
$MftMirr. */
@@ -1001,9 +1001,9 @@ static inline struct ntfs_sb_info *ntfs_sb(struct 
super_block *sb)
      return sb->s_fs_info;
  }

-static inline bool ntfs3_forced_shutdown(struct super_block *sb)
+static inline int ntfs3_forced_shutdown(struct super_block *sb)
  {
-    return test_bit(NTFS_FLAGS_SHUTDOWN, &ntfs_sb(sb)->flags);
+    return test_bit(NTFS_FLAGS_SHUTDOWN_BIT, &ntfs_sb(sb)->flags);
  }

  /*
diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c
index af8521a6ed95..65ef4b57411f 100644
--- a/fs/ntfs3/super.c
+++ b/fs/ntfs3/super.c
@@ -719,7 +719,7 @@ static int ntfs_show_options(struct seq_file *m, 
struct dentry *root)
   */
  static void ntfs_shutdown(struct super_block *sb)
  {
-    set_bit(NTFS_FLAGS_SHUTDOWN, &ntfs_sb(sb)->flags);
+    set_bit(NTFS_FLAGS_SHUTDOWN_BIT, &ntfs_sb(sb)->flags);
  }

  /*
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 14/16] fs/ntfs3: Add and fix comments
  2023-12-06 15:08 [PATCH 00/16] fs/ntfs3: Bugfix and refactoring Konstantin Komarovc
                   ` (12 preceding siblings ...)
  2023-12-06 15:13 ` [PATCH 13/16] fs/ntfs3: ntfs3_forced_shutdown use int instead of bool Konstantin Komarovc
@ 2023-12-06 15:14 ` Konstantin Komarovc
  2023-12-06 15:14 ` [PATCH 15/16] fs/ntfs3: Add NULL ptr dereference checking at the end of attr_allocate_frame() Konstantin Komarovc
  2023-12-06 15:14 ` [PATCH 16/16] fs/ntfs3: Fix c/mtime typo Konstantin Komarovc
  15 siblings, 0 replies; 18+ messages in thread
From: Konstantin Komarovc @ 2023-12-06 15:14 UTC (permalink / raw)
  To: ntfs3; +Cc: linux-kernel, linux-fsdevel


Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
---
  fs/ntfs3/dir.c     | 4 +++-
  fs/ntfs3/fsntfs.c  | 2 +-
  fs/ntfs3/ntfs.h    | 2 +-
  fs/ntfs3/ntfs_fs.h | 2 +-
  4 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/fs/ntfs3/dir.c b/fs/ntfs3/dir.c
index 726122ecd39b..9f6dd445eb04 100644
--- a/fs/ntfs3/dir.c
+++ b/fs/ntfs3/dir.c
@@ -536,8 +536,10 @@ static int ntfs_dir_count(struct inode *dir, bool 
*is_empty, size_t *dirs,
              e = Add2Ptr(hdr, off);
              e_size = le16_to_cpu(e->size);
              if (e_size < sizeof(struct NTFS_DE) ||
-                off + e_size > end)
+                off + e_size > end) {
+                /* Looks like corruption. */
                  break;
+            }

              if (de_is_last(e))
                  break;
diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c
index 350461d8cece..321978019407 100644
--- a/fs/ntfs3/fsntfs.c
+++ b/fs/ntfs3/fsntfs.c
@@ -2129,8 +2129,8 @@ int ntfs_insert_security(struct ntfs_sb_info *sbi,
              if (le32_to_cpu(d_security->size) == new_sec_size &&
                  d_security->key.hash == hash_key.hash &&
                  !memcmp(d_security + 1, sd, size_sd)) {
-                *security_id = d_security->key.sec_id;
                  /* Such security already exists. */
+                *security_id = d_security->key.sec_id;
                  err = 0;
                  goto out;
              }
diff --git a/fs/ntfs3/ntfs.h b/fs/ntfs3/ntfs.h
index 13e96fc63dae..c8981429c721 100644
--- a/fs/ntfs3/ntfs.h
+++ b/fs/ntfs3/ntfs.h
@@ -523,7 +523,7 @@ struct ATTR_LIST_ENTRY {
      __le64 vcn;        // 0x08: Starting VCN of this attribute.
      struct MFT_REF ref;    // 0x10: MFT record number with attribute.
      __le16 id;        // 0x18: struct ATTRIB ID.
-    __le16 name[];        // 0x1A: Just to align. To get real name can 
use name_off.
+    __le16 name[];        // 0x1A: To get real name use name_off.

  }; // sizeof(0x20)

diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h
index 7510875efef6..abbc7182554a 100644
--- a/fs/ntfs3/ntfs_fs.h
+++ b/fs/ntfs3/ntfs_fs.h
@@ -874,7 +874,7 @@ int ntfs_init_acl(struct mnt_idmap *idmap, struct 
inode *inode,

  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[];
+extern const struct xattr_handler *const ntfs_xattr_handlers[];

  int ntfs_save_wsl_perm(struct inode *inode, __le16 *ea_size);
  void ntfs_get_wsl_perm(struct inode *inode);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 15/16] fs/ntfs3: Add NULL ptr dereference checking at the end of attr_allocate_frame()
  2023-12-06 15:08 [PATCH 00/16] fs/ntfs3: Bugfix and refactoring Konstantin Komarovc
                   ` (13 preceding siblings ...)
  2023-12-06 15:14 ` [PATCH 14/16] fs/ntfs3: Add and fix comments Konstantin Komarovc
@ 2023-12-06 15:14 ` Konstantin Komarovc
  2023-12-06 15:14 ` [PATCH 16/16] fs/ntfs3: Fix c/mtime typo Konstantin Komarovc
  15 siblings, 0 replies; 18+ messages in thread
From: Konstantin Komarovc @ 2023-12-06 15:14 UTC (permalink / raw)
  To: ntfs3; +Cc: linux-kernel, linux-fsdevel

It is preferable to exit through the out: label because
internal debugging functions are located there.

Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
---
  fs/ntfs3/attrib.c | 20 ++++++++++++--------
  1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c
index 4b78b669a3bd..646e2dad1b75 100644
--- a/fs/ntfs3/attrib.c
+++ b/fs/ntfs3/attrib.c
@@ -1743,8 +1743,10 @@ 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)
-                return -ENOENT;
+            if (!attr_b) {
+                err = -ENOENT;
+                goto out;
+            }

              attr = attr_b;
              le = le_b;
@@ -1825,13 +1827,15 @@ int attr_allocate_frame(struct ntfs_inode *ni, 
CLST frame, size_t compr_size,
  ok:
      run_truncate_around(run, vcn);
  out:
-    if (new_valid > data_size)
-        new_valid = data_size;
+    if (attr_b) {
+        if (new_valid > data_size)
+            new_valid = data_size;

-    valid_size = le64_to_cpu(attr_b->nres.valid_size);
-    if (new_valid != valid_size) {
-        attr_b->nres.valid_size = cpu_to_le64(valid_size);
-        mi_b->dirty = true;
+        valid_size = le64_to_cpu(attr_b->nres.valid_size);
+        if (new_valid != valid_size) {
+            attr_b->nres.valid_size = cpu_to_le64(valid_size);
+            mi_b->dirty = true;
+        }
      }

      return err;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 16/16] fs/ntfs3: Fix c/mtime typo
  2023-12-06 15:08 [PATCH 00/16] fs/ntfs3: Bugfix and refactoring Konstantin Komarovc
                   ` (14 preceding siblings ...)
  2023-12-06 15:14 ` [PATCH 15/16] fs/ntfs3: Add NULL ptr dereference checking at the end of attr_allocate_frame() Konstantin Komarovc
@ 2023-12-06 15:14 ` Konstantin Komarovc
  15 siblings, 0 replies; 18+ messages in thread
From: Konstantin Komarovc @ 2023-12-06 15:14 UTC (permalink / raw)
  To: ntfs3; +Cc: linux-kernel, linux-fsdevel


Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
---
  fs/ntfs3/frecord.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c
index 8744ba36d422..6ff4f70ba077 100644
--- a/fs/ntfs3/frecord.c
+++ b/fs/ntfs3/frecord.c
@@ -3291,7 +3291,7 @@ int ni_write_inode(struct inode *inode, int sync, 
const char *hint)
              modified = true;
          }

-        ts = inode_get_mtime(inode);
+        ts = inode_get_ctime(inode);
          dup.c_time = kernel2nt(&ts);
          if (std->c_time != dup.c_time) {
              std->c_time = dup.c_time;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH 08/16] fs/ntfs3: Fix detected field-spanning write (size 8) of single field "le->name"
  2023-12-06 15:12 ` [PATCH 08/16] fs/ntfs3: Fix detected field-spanning write (size 8) of single field "le->name" Konstantin Komarovc
@ 2023-12-07  9:31   ` Geert Uytterhoeven
  0 siblings, 0 replies; 18+ messages in thread
From: Geert Uytterhoeven @ 2023-12-07  9:31 UTC (permalink / raw)
  To: Konstantin Komarovc; +Cc: ntfs3, linux-kernel, linux-fsdevel

Hi Konstantin,

On Wed, Dec 6, 2023 at 4:12 PM Konstantin Komarovc
<almaz.alexandrovich@paragon-software.com> wrote:
> Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>

Thanks for your patch, which is now commit d155617006ebc172 ("fs/ntfs3:
Fix detected field-spanning write (size 8) of single field "le->name"")
in next-20231207.

> --- a/fs/ntfs3/ntfs.h
> +++ b/fs/ntfs3/ntfs.h
> @@ -523,7 +523,7 @@ struct ATTR_LIST_ENTRY {
>       __le64 vcn;        // 0x08: Starting VCN of this attribute.
>       struct MFT_REF ref;    // 0x10: MFT record number with attribute.
>       __le16 id;        // 0x18: struct ATTRIB ID.
> -    __le16 name[3];        // 0x1A: Just to align. To get real name can
> use bNameOffset.
> +    __le16 name[];        // 0x1A: Just to align. To get real name can
> use name_off.

noreply@ellerman.id.au reports for all m68k configs[1]:

include/linux/build_bug.h:78:41: error: static assertion failed:
"sizeof(struct ATTR_LIST_ENTRY) == 0x20"

>
>   }; // sizeof(0x20)

Indeed, we now have a hole of 4 bytes at the end of the structure,
which shrinks the size of the structure on all architectures where
alignof(u64) < sizeof(u64).

So either the patch should be reverted, or explicit padding should
be added.  Your patch description is not very descriptive, so I
don't know which is the correct solution.

[1] http://kisskb.ellerman.id.au/kisskb/head/8e00ce02066e8f6f1ad5eab49a2ede7bf7a5ef64

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2023-12-07  9:32 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-12-06 15:08 [PATCH 00/16] fs/ntfs3: Bugfix and refactoring Konstantin Komarovc
2023-12-06 15:08 ` [PATCH 01/16] fs/ntfs3: Improve alternative boot processing Konstantin Komarovc
2023-12-06 15:09 ` [PATCH 02/16] fs/ntfs3: Modified fix directory element type detection Konstantin Komarovc
2023-12-06 15:10 ` [PATCH 03/16] fs/ntfs3: Improve ntfs_dir_count Konstantin Komarovc
2023-12-06 15:10 ` [PATCH 04/16] fs/ntfs3: Correct hard links updating when dealing with DOS neams Konstantin Komarovc
2023-12-06 15:11 ` [PATCH 05/16] fs/ntfs3: Print warning while fixing hard links count Konstantin Komarovc
2023-12-06 15:11 ` [PATCH 06/16] fs/ntfs3: Reduce stack usage Konstantin Komarovc
2023-12-06 15:12 ` [PATCH 07/16] fs/ntfs3: Fix multithreaded stress test Konstantin Komarovc
2023-12-06 15:12 ` [PATCH 08/16] fs/ntfs3: Fix detected field-spanning write (size 8) of single field "le->name" Konstantin Komarovc
2023-12-07  9:31   ` Geert Uytterhoeven
2023-12-06 15:12 ` [PATCH 09/16] fs/ntfs3: Correct use bh_read Konstantin Komarovc
2023-12-06 15:12 ` [PATCH 10/16] fs/ntfs3: Add file_modified Konstantin Komarovc
2023-12-06 15:13 ` [PATCH 11/16] fs/ntfs3: Drop suid and sgid bits as a part of fpunch Konstantin Komarovc
2023-12-06 15:13 ` [PATCH 12/16] fs/ntfs3: Implement super_operations::shutdown Konstantin Komarovc
2023-12-06 15:13 ` [PATCH 13/16] fs/ntfs3: ntfs3_forced_shutdown use int instead of bool Konstantin Komarovc
2023-12-06 15:14 ` [PATCH 14/16] fs/ntfs3: Add and fix comments Konstantin Komarovc
2023-12-06 15:14 ` [PATCH 15/16] fs/ntfs3: Add NULL ptr dereference checking at the end of attr_allocate_frame() Konstantin Komarovc
2023-12-06 15:14 ` [PATCH 16/16] fs/ntfs3: Fix c/mtime typo Konstantin Komarovc

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).