]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
fat: Track metadata bhs in fs-private inode part
authorJan Kara <jack@suse.cz>
Thu, 26 Mar 2026 09:54:31 +0000 (10:54 +0100)
committerChristian Brauner <brauner@kernel.org>
Thu, 26 Mar 2026 14:03:32 +0000 (15:03 +0100)
Track metadata bhs for an inode in fs-private part of the inode.

Signed-off-by: Jan Kara <jack@suse.cz>
Link: https://patch.msgid.link/20260326095354.16340-79-jack@suse.cz
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/fat/dir.c
fs/fat/fat.h
fs/fat/fatent.c
fs/fat/file.c
fs/fat/inode.c
fs/fat/namei_msdos.c
fs/fat/namei_vfat.c

index 4b8b25f688e4f0c4e5b54bc6dd245076729c1756..4f6f42f33613df60d3fe5caab5dd99590f494005 100644 (file)
@@ -1027,7 +1027,7 @@ static int __fat_remove_entries(struct inode *dir, loff_t pos, int nr_slots)
                        de++;
                        nr_slots--;
                }
-               mark_buffer_dirty_inode(bh, dir);
+               mmb_mark_buffer_dirty(bh, &MSDOS_I(dir)->i_metadata_bhs);
                if (IS_DIRSYNC(dir))
                        err = sync_dirty_buffer(bh);
                brelse(bh);
@@ -1062,7 +1062,7 @@ int fat_remove_entries(struct inode *dir, struct fat_slot_info *sinfo)
                de--;
                nr_slots--;
        }
-       mark_buffer_dirty_inode(bh, dir);
+       mmb_mark_buffer_dirty(bh, &MSDOS_I(dir)->i_metadata_bhs);
        if (IS_DIRSYNC(dir))
                err = sync_dirty_buffer(bh);
        brelse(bh);
@@ -1114,7 +1114,7 @@ static int fat_zeroed_cluster(struct inode *dir, sector_t blknr, int nr_used,
                memset(bhs[n]->b_data, 0, sb->s_blocksize);
                set_buffer_uptodate(bhs[n]);
                unlock_buffer(bhs[n]);
-               mark_buffer_dirty_inode(bhs[n], dir);
+               mmb_mark_buffer_dirty(bhs[n], &MSDOS_I(dir)->i_metadata_bhs);
 
                n++;
                blknr++;
@@ -1195,7 +1195,7 @@ int fat_alloc_new_dir(struct inode *dir, struct timespec64 *ts)
        memset(de + 2, 0, sb->s_blocksize - 2 * sizeof(*de));
        set_buffer_uptodate(bhs[0]);
        unlock_buffer(bhs[0]);
-       mark_buffer_dirty_inode(bhs[0], dir);
+       mmb_mark_buffer_dirty(bhs[0], &MSDOS_I(dir)->i_metadata_bhs);
 
        err = fat_zeroed_cluster(dir, blknr, 1, bhs, MAX_BUF_PER_PAGE);
        if (err)
@@ -1257,7 +1257,8 @@ static int fat_add_new_entries(struct inode *dir, void *slots, int nr_slots,
                        memcpy(bhs[n]->b_data, slots, copy);
                        set_buffer_uptodate(bhs[n]);
                        unlock_buffer(bhs[n]);
-                       mark_buffer_dirty_inode(bhs[n], dir);
+                       mmb_mark_buffer_dirty(bhs[n],
+                                             &MSDOS_I(dir)->i_metadata_bhs);
                        slots += copy;
                        size -= copy;
                        if (!size)
@@ -1358,7 +1359,8 @@ found:
                for (i = 0; i < long_bhs; i++) {
                        int copy = umin(sb->s_blocksize - offset, size);
                        memcpy(bhs[i]->b_data + offset, slots, copy);
-                       mark_buffer_dirty_inode(bhs[i], dir);
+                       mmb_mark_buffer_dirty(bhs[i],
+                                             &MSDOS_I(dir)->i_metadata_bhs);
                        offset = 0;
                        slots += copy;
                        size -= copy;
@@ -1369,7 +1371,8 @@ found:
                        /* Fill the short name slot. */
                        int copy = umin(sb->s_blocksize - offset, size);
                        memcpy(bhs[i]->b_data + offset, slots, copy);
-                       mark_buffer_dirty_inode(bhs[i], dir);
+                       mmb_mark_buffer_dirty(bhs[i],
+                                             &MSDOS_I(dir)->i_metadata_bhs);
                        if (IS_DIRSYNC(dir))
                                err = sync_dirty_buffer(bhs[i]);
                }
index 0d269dba897bba304eaf569fbd63c8e3cf7d6bc4..5a58f0bf8ce83dd510e1708bab2acac71ff6d2c6 100644 (file)
@@ -130,6 +130,7 @@ struct msdos_inode_info {
        struct hlist_node i_dir_hash;   /* hash by i_logstart */
        struct rw_semaphore truncate_lock; /* protect bmap against truncate */
        struct timespec64 i_crtime;     /* File creation (birth) time */
+       struct mapping_metadata_bhs i_metadata_bhs;
        struct inode vfs_inode;
 };
 
index a7061c2ad8e4d2fd946e274bab62228e3caf1633..f0801d99dd62aefee4f573cfda332e7201235c32 100644 (file)
@@ -170,9 +170,11 @@ static void fat12_ent_put(struct fat_entry *fatent, int new)
        }
        spin_unlock(&fat12_entry_lock);
 
-       mark_buffer_dirty_inode(fatent->bhs[0], fatent->fat_inode);
+       mmb_mark_buffer_dirty(fatent->bhs[0],
+                             &MSDOS_I(fatent->fat_inode)->i_metadata_bhs);
        if (fatent->nr_bhs == 2)
-               mark_buffer_dirty_inode(fatent->bhs[1], fatent->fat_inode);
+               mmb_mark_buffer_dirty(fatent->bhs[1],
+                               &MSDOS_I(fatent->fat_inode)->i_metadata_bhs);
 }
 
 static void fat16_ent_put(struct fat_entry *fatent, int new)
@@ -181,7 +183,8 @@ static void fat16_ent_put(struct fat_entry *fatent, int new)
                new = EOF_FAT16;
 
        *fatent->u.ent16_p = cpu_to_le16(new);
-       mark_buffer_dirty_inode(fatent->bhs[0], fatent->fat_inode);
+       mmb_mark_buffer_dirty(fatent->bhs[0],
+                             &MSDOS_I(fatent->fat_inode)->i_metadata_bhs);
 }
 
 static void fat32_ent_put(struct fat_entry *fatent, int new)
@@ -189,7 +192,8 @@ static void fat32_ent_put(struct fat_entry *fatent, int new)
        WARN_ON(new & 0xf0000000);
        new |= le32_to_cpu(*fatent->u.ent32_p) & ~0x0fffffff;
        *fatent->u.ent32_p = cpu_to_le32(new);
-       mark_buffer_dirty_inode(fatent->bhs[0], fatent->fat_inode);
+       mmb_mark_buffer_dirty(fatent->bhs[0],
+                             &MSDOS_I(fatent->fat_inode)->i_metadata_bhs);
 }
 
 static int fat12_ent_next(struct fat_entry *fatent)
@@ -395,7 +399,8 @@ static int fat_mirror_bhs(struct super_block *sb, struct buffer_head **bhs,
                        memcpy(c_bh->b_data, bhs[n]->b_data, sb->s_blocksize);
                        set_buffer_uptodate(c_bh);
                        unlock_buffer(c_bh);
-                       mark_buffer_dirty_inode(c_bh, sbi->fat_inode);
+                       mmb_mark_buffer_dirty(c_bh,
+                               &MSDOS_I(sbi->fat_inode)->i_metadata_bhs);
                        if (sb->s_flags & SB_SYNCHRONOUS)
                                err = sync_dirty_buffer(c_bh);
                        brelse(c_bh);
index 1551065a7964e97b8d4be5d0351c9f39d8238265..becccdd2e501a8adcd21121d122db96b186f4b94 100644 (file)
@@ -186,13 +186,15 @@ static int fat_file_release(struct inode *inode, struct file *filp)
 int fat_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
 {
        struct inode *inode = filp->f_mapping->host;
+       struct inode *fat_inode = MSDOS_SB(inode->i_sb)->fat_inode;
        int err;
 
-       err = generic_buffers_fsync_noflush(filp, start, end, datasync);
+       err = mmb_fsync_noflush(filp, &MSDOS_I(inode)->i_metadata_bhs,
+                               start, end, datasync);
        if (err)
                return err;
 
-       err = sync_mapping_buffers(MSDOS_SB(inode->i_sb)->fat_inode->i_mapping);
+       err = mmb_sync(&MSDOS_I(fat_inode)->i_metadata_bhs);
        if (err)
                return err;
 
@@ -236,7 +238,7 @@ static int fat_cont_expand(struct inode *inode, loff_t size)
                 */
                err = filemap_fdatawrite_range(mapping, start,
                                               start + count - 1);
-               err2 = sync_mapping_buffers(mapping);
+               err2 = mmb_sync(&MSDOS_I(inode)->i_metadata_bhs);
                if (!err)
                        err = err2;
                err2 = write_inode_now(inode, 1);
index ce88602b0d575f5695a27e560e10e46937c1aef2..28f78df086efcc082570dd2d92d1ff0c30825047 100644 (file)
@@ -658,11 +658,11 @@ static void fat_evict_inode(struct inode *inode)
                inode->i_size = 0;
                fat_truncate_blocks(inode, 0);
        } else {
-               sync_mapping_buffers(inode->i_mapping);
+               mmb_sync(&MSDOS_I(inode)->i_metadata_bhs);
                fat_free_eofblocks(inode);
        }
 
-       invalidate_inode_buffers(inode);
+       mmb_invalidate(&MSDOS_I(inode)->i_metadata_bhs);
        clear_inode(inode);
        fat_cache_inval_inode(inode);
        fat_detach(inode);
@@ -763,6 +763,7 @@ static struct inode *fat_alloc_inode(struct super_block *sb)
        ei->i_pos = 0;
        ei->i_crtime.tv_sec = 0;
        ei->i_crtime.tv_nsec = 0;
+       mmb_init(&ei->i_metadata_bhs, &ei->vfs_inode.i_data);
 
        return &ei->vfs_inode;
 }
index 048c103b506a89de6ac58d6cc34513be592736c0..4cc65f330fb7ee89f69aa245d6d451c3bfc82dad 100644 (file)
@@ -527,7 +527,8 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
 
        if (update_dotdot) {
                fat_set_start(dotdot_de, MSDOS_I(new_dir)->i_logstart);
-               mark_buffer_dirty_inode(dotdot_bh, old_inode);
+               mmb_mark_buffer_dirty(dotdot_bh,
+                                     &MSDOS_I(old_inode)->i_metadata_bhs);
                if (IS_DIRSYNC(new_dir)) {
                        err = sync_dirty_buffer(dotdot_bh);
                        if (err)
@@ -566,7 +567,8 @@ error_dotdot:
 
        if (update_dotdot) {
                fat_set_start(dotdot_de, MSDOS_I(old_dir)->i_logstart);
-               mark_buffer_dirty_inode(dotdot_bh, old_inode);
+               mmb_mark_buffer_dirty(dotdot_bh,
+                                     &MSDOS_I(old_inode)->i_metadata_bhs);
                corrupt |= sync_dirty_buffer(dotdot_bh);
        }
 error_inode:
index 87dcdd86272b50a28718ca4462731cbc5915111c..918b3756674c3052c9f20be5ea4a8b7e2d9d943e 100644 (file)
@@ -915,7 +915,7 @@ static int vfat_update_dotdot_de(struct inode *dir, struct inode *inode,
                                 struct msdos_dir_entry *dotdot_de)
 {
        fat_set_start(dotdot_de, MSDOS_I(dir)->i_logstart);
-       mark_buffer_dirty_inode(dotdot_bh, inode);
+       mmb_mark_buffer_dirty(dotdot_bh, &MSDOS_I(inode)->i_metadata_bhs);
        if (IS_DIRSYNC(dir))
                return sync_dirty_buffer(dotdot_bh);
        return 0;