fs/ntfs3: extend ni_insert_nonresident to return inserted ATTR_LIST_ENTRY
authorKonstantin Komarov <almaz.alexandrovich@paragon-software.com>
Fri, 13 May 2022 15:25:04 +0000 (18:25 +0300)
committerKonstantin Komarov <almaz.alexandrovich@paragon-software.com>
Wed, 3 Aug 2022 15:25:04 +0000 (18:25 +0300)
Fixes xfstest generic/300
Fixes: 4534a70b7056 ("fs/ntfs3: Add headers and misc files")

Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
fs/ntfs3/attrib.c
fs/ntfs3/frecord.c
fs/ntfs3/index.c
fs/ntfs3/ntfs_fs.h

index c9b7181..ad713f6 100644 (file)
@@ -320,7 +320,7 @@ int attr_make_nonresident(struct ntfs_inode *ni, struct ATTRIB *attr,
 
        err = ni_insert_nonresident(ni, attr_s->type, attr_name(attr_s),
                                    attr_s->name_len, run, 0, alen,
-                                   attr_s->flags, &attr, NULL);
+                                   attr_s->flags, &attr, NULL, NULL);
        if (err)
                goto out3;
 
@@ -637,7 +637,7 @@ pack_runs:
                /* Insert new attribute segment. */
                err = ni_insert_nonresident(ni, type, name, name_len, run,
                                            next_svcn, vcn - next_svcn,
-                                           attr_b->flags, &attr, &mi);
+                                           attr_b->flags, &attr, &mi, NULL);
                if (err)
                        goto out;
 
@@ -855,7 +855,7 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn,
                goto out;
        }
 
-       asize = le64_to_cpu(attr_b->nres.alloc_size) >> sbi->cluster_bits;
+       asize = le64_to_cpu(attr_b->nres.alloc_size) >> cluster_bits;
        if (vcn >= asize) {
                err = -EINVAL;
                goto out;
@@ -1047,7 +1047,7 @@ ins_ext:
        if (evcn1 > next_svcn) {
                err = ni_insert_nonresident(ni, ATTR_DATA, NULL, 0, run,
                                            next_svcn, evcn1 - next_svcn,
-                                           attr_b->flags, &attr, &mi);
+                                           attr_b->flags, &attr, &mi, NULL);
                if (err)
                        goto out;
        }
@@ -1647,7 +1647,7 @@ ins_ext:
        if (evcn1 > next_svcn) {
                err = ni_insert_nonresident(ni, ATTR_DATA, NULL, 0, run,
                                            next_svcn, evcn1 - next_svcn,
-                                           attr_b->flags, &attr, &mi);
+                                           attr_b->flags, &attr, &mi, NULL);
                if (err)
                        goto out;
        }
@@ -1812,18 +1812,12 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)
                                err = ni_insert_nonresident(
                                        ni, ATTR_DATA, NULL, 0, run, next_svcn,
                                        evcn1 - eat - next_svcn, a_flags, &attr,
-                                       &mi);
+                                       &mi, &le);
                                if (err)
                                        goto out;
 
                                /* Layout of records maybe changed. */
                                attr_b = NULL;
-                               le = al_find_ex(ni, NULL, ATTR_DATA, NULL, 0,
-                                               &next_svcn);
-                               if (!le) {
-                                       err = -EINVAL;
-                                       goto out;
-                               }
                        }
 
                        /* Free all allocated memory. */
@@ -1936,9 +1930,10 @@ int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size)
        struct ATTRIB *attr = NULL, *attr_b;
        struct ATTR_LIST_ENTRY *le, *le_b;
        struct mft_inode *mi, *mi_b;
-       CLST svcn, evcn1, vcn, len, end, alen, dealloc;
+       CLST svcn, evcn1, vcn, len, end, alen, dealloc, next_svcn;
        u64 total_size, alloc_size;
        u32 mask;
+       __le16 a_flags;
 
        if (!bytes)
                return 0;
@@ -2001,6 +1996,7 @@ int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size)
 
        svcn = le64_to_cpu(attr_b->nres.svcn);
        evcn1 = le64_to_cpu(attr_b->nres.evcn) + 1;
+       a_flags = attr_b->flags;
 
        if (svcn <= vcn && vcn < evcn1) {
                attr = attr_b;
@@ -2048,6 +2044,17 @@ int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size)
                        err = mi_pack_runs(mi, attr, run, evcn1 - svcn);
                        if (err)
                                goto out;
+                       next_svcn = le64_to_cpu(attr->nres.evcn) + 1;
+                       if (next_svcn < evcn1) {
+                               err = ni_insert_nonresident(ni, ATTR_DATA, NULL,
+                                                           0, run, next_svcn,
+                                                           evcn1 - next_svcn,
+                                                           a_flags, &attr, &mi,
+                                                           &le);
+                               if (err)
+                                       goto out;
+                               /* Layout of records maybe changed. */
+                       }
                }
                /* Free all allocated memory. */
                run_truncate(run, 0);
@@ -2250,7 +2257,7 @@ int attr_insert_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)
        if (next_svcn < evcn1 + len) {
                err = ni_insert_nonresident(ni, ATTR_DATA, NULL, 0, run,
                                            next_svcn, evcn1 + len - next_svcn,
-                                           a_flags, NULL, NULL);
+                                           a_flags, NULL, NULL, NULL);
                if (err)
                        goto out;
        }
index 3576268..6404115 100644 (file)
@@ -1406,7 +1406,7 @@ int ni_insert_nonresident(struct ntfs_inode *ni, enum ATTR_TYPE type,
                          const __le16 *name, u8 name_len,
                          const struct runs_tree *run, CLST svcn, CLST len,
                          __le16 flags, struct ATTRIB **new_attr,
-                         struct mft_inode **mi)
+                         struct mft_inode **mi, struct ATTR_LIST_ENTRY **le)
 {
        int err;
        CLST plen;
@@ -1439,7 +1439,7 @@ int ni_insert_nonresident(struct ntfs_inode *ni, enum ATTR_TYPE type,
        }
 
        err = ni_insert_attr(ni, type, name, name_len, asize, name_off, svcn,
-                            &attr, mi, NULL);
+                            &attr, mi, le);
 
        if (err)
                goto out;
index ba2a07d..4403281 100644 (file)
@@ -1347,7 +1347,7 @@ static int indx_create_allocate(struct ntfs_index *indx, struct ntfs_inode *ni,
                goto out;
 
        err = ni_insert_nonresident(ni, ATTR_ALLOC, in->name, in->name_len,
-                                   &run, 0, len, 0, &alloc, NULL);
+                                   &run, 0, len, 0, &alloc, NULL, NULL);
        if (err)
                goto out1;
 
index 8f05b91..27b610c 100644 (file)
@@ -529,7 +529,7 @@ int ni_insert_nonresident(struct ntfs_inode *ni, enum ATTR_TYPE type,
                          const __le16 *name, u8 name_len,
                          const struct runs_tree *run, CLST svcn, CLST len,
                          __le16 flags, struct ATTRIB **new_attr,
-                         struct mft_inode **mi);
+                         struct mft_inode **mi, struct ATTR_LIST_ENTRY **le);
 int ni_insert_resident(struct ntfs_inode *ni, u32 data_size,
                       enum ATTR_TYPE type, const __le16 *name, u8 name_len,
                       struct ATTRIB **new_attr, struct mft_inode **mi,