From: Jan Kara Date: Thu, 26 Mar 2026 09:54:32 +0000 (+0100) Subject: udf: Track metadata bhs in fs-private inode part X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d0874a580a4b6409b5a78edc9472732b2c1f4cda;p=thirdparty%2Flinux.git udf: Track metadata bhs in fs-private inode part Track metadata bhs for an inode in fs-private part of the inode. Signed-off-by: Jan Kara Link: https://patch.msgid.link/20260326095354.16340-80-jack@suse.cz Signed-off-by: Christian Brauner --- diff --git a/fs/udf/dir.c b/fs/udf/dir.c index a1705aedac462..ebc9f6a379fe3 100644 --- a/fs/udf/dir.c +++ b/fs/udf/dir.c @@ -157,6 +157,6 @@ const struct file_operations udf_dir_operations = { .read = generic_read_dir, .iterate_shared = udf_readdir, .unlocked_ioctl = udf_ioctl, - .fsync = generic_buffers_fsync, + .fsync = udf_fsync, .setlease = generic_setlease, }; diff --git a/fs/udf/directory.c b/fs/udf/directory.c index 632453aa38934..83edd04ca6fa6 100644 --- a/fs/udf/directory.c +++ b/fs/udf/directory.c @@ -430,9 +430,10 @@ void udf_fiiter_write_fi(struct udf_fileident_iter *iter, uint8_t *impuse) if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { mark_inode_dirty(iter->dir); } else { - mark_buffer_dirty_inode(iter->bh[0], iter->dir); + mmb_mark_buffer_dirty(iter->bh[0], &iinfo->i_metadata_bhs); if (iter->bh[1]) - mark_buffer_dirty_inode(iter->bh[1], iter->dir); + mmb_mark_buffer_dirty(iter->bh[1], + &iinfo->i_metadata_bhs); } inode_inc_iversion(iter->dir); } diff --git a/fs/udf/file.c b/fs/udf/file.c index 627b07320d067..e8c57c6ee8b8a 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -198,6 +198,13 @@ static int udf_file_mmap(struct file *file, struct vm_area_struct *vma) return 0; } +int udf_fsync(struct file *file, loff_t start, loff_t end, int datasync) +{ + return mmb_fsync(file, + &UDF_I(file->f_mapping->host)->i_metadata_bhs, + start, end, datasync); +} + const struct file_operations udf_file_operations = { .read_iter = generic_file_read_iter, .unlocked_ioctl = udf_ioctl, @@ -205,7 +212,7 @@ const struct file_operations udf_file_operations = { .mmap = udf_file_mmap, .write_iter = udf_file_write_iter, .release = udf_release_file, - .fsync = generic_buffers_fsync, + .fsync = udf_fsync, .splice_read = filemap_splice_read, .splice_write = iter_file_splice_write, .llseek = generic_file_llseek, diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 739b190ca4e93..656eb031b4c00 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -155,8 +155,8 @@ void udf_evict_inode(struct inode *inode) } truncate_inode_pages_final(&inode->i_data); if (!want_delete) - sync_mapping_buffers(&inode->i_data); - invalidate_inode_buffers(inode); + mmb_sync(&iinfo->i_metadata_bhs); + mmb_invalidate(&iinfo->i_metadata_bhs); clear_inode(inode); kfree(iinfo->i_data); iinfo->i_data = NULL; @@ -1263,7 +1263,7 @@ struct buffer_head *udf_bread(struct inode *inode, udf_pblk_t block, memset(bh->b_data, 0x00, inode->i_sb->s_blocksize); set_buffer_uptodate(bh); unlock_buffer(bh); - mark_buffer_dirty_inode(bh, inode); + mmb_mark_buffer_dirty(bh, &UDF_I(inode)->i_metadata_bhs); return bh; } @@ -2011,7 +2011,7 @@ int udf_setup_indirect_aext(struct inode *inode, udf_pblk_t block, memset(bh->b_data, 0x00, sb->s_blocksize); set_buffer_uptodate(bh); unlock_buffer(bh); - mark_buffer_dirty_inode(bh, inode); + mmb_mark_buffer_dirty(bh, &UDF_I(inode)->i_metadata_bhs); aed = (struct allocExtDesc *)(bh->b_data); if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT)) { @@ -2106,7 +2106,7 @@ int __udf_add_aext(struct inode *inode, struct extent_position *epos, else udf_update_tag(epos->bh->b_data, sizeof(struct allocExtDesc)); - mark_buffer_dirty_inode(epos->bh, inode); + mmb_mark_buffer_dirty(epos->bh, &iinfo->i_metadata_bhs); } return 0; @@ -2190,7 +2190,7 @@ void udf_write_aext(struct inode *inode, struct extent_position *epos, le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct allocExtDesc)); } - mark_buffer_dirty_inode(epos->bh, inode); + mmb_mark_buffer_dirty(epos->bh, &iinfo->i_metadata_bhs); } else { mark_inode_dirty(inode); } @@ -2398,7 +2398,7 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos) else udf_update_tag(oepos.bh->b_data, sizeof(struct allocExtDesc)); - mark_buffer_dirty_inode(oepos.bh, inode); + mmb_mark_buffer_dirty(oepos.bh, &iinfo->i_metadata_bhs); } } else { udf_write_aext(inode, &oepos, &eloc, elen, 1); @@ -2415,7 +2415,7 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos) else udf_update_tag(oepos.bh->b_data, sizeof(struct allocExtDesc)); - mark_buffer_dirty_inode(oepos.bh, inode); + mmb_mark_buffer_dirty(oepos.bh, &iinfo->i_metadata_bhs); } } diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 5f2e9a892bffa..4ef2ff014170d 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -638,7 +638,7 @@ static int udf_symlink(struct mnt_idmap *idmap, struct inode *dir, memset(epos.bh->b_data, 0x00, bsize); set_buffer_uptodate(epos.bh); unlock_buffer(epos.bh); - mark_buffer_dirty_inode(epos.bh, inode); + mmb_mark_buffer_dirty(epos.bh, &iinfo->i_metadata_bhs); ea = epos.bh->b_data + udf_ext0_offset(inode); } else ea = iinfo->i_data + iinfo->i_lenEAttr; diff --git a/fs/udf/super.c b/fs/udf/super.c index 27f463fd1d89e..e02775007c462 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -166,6 +166,7 @@ static struct inode *udf_alloc_inode(struct super_block *sb) ei->cached_extent.lstart = -1; spin_lock_init(&ei->i_extent_cache_lock); inode_set_iversion(&ei->vfs_inode, 1); + mmb_init(&ei->i_metadata_bhs, &ei->vfs_inode.i_data); return &ei->vfs_inode; } diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c index b4071c9cf8c95..41b2bfd30449b 100644 --- a/fs/udf/truncate.c +++ b/fs/udf/truncate.c @@ -186,7 +186,7 @@ static void udf_update_alloc_ext_desc(struct inode *inode, len += lenalloc; udf_update_tag(epos->bh->b_data, len); - mark_buffer_dirty_inode(epos->bh, inode); + mmb_mark_buffer_dirty(epos->bh, &UDF_I(inode)->i_metadata_bhs); } /* diff --git a/fs/udf/udf_i.h b/fs/udf/udf_i.h index 312b7c9ef10e2..fdaa88c49c2b7 100644 --- a/fs/udf/udf_i.h +++ b/fs/udf/udf_i.h @@ -50,6 +50,7 @@ struct udf_inode_info { struct kernel_lb_addr i_locStreamdir; __u64 i_lenStreams; struct rw_semaphore i_data_sem; + struct mapping_metadata_bhs i_metadata_bhs; struct udf_ext_cache cached_extent; /* Spinlock for protecting extent cache */ spinlock_t i_extent_cache_lock; diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index d159f20d61e89..6d951e05c0046 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h @@ -137,6 +137,7 @@ static inline unsigned int udf_dir_entry_len(struct fileIdentDesc *cfi) /* file.c */ extern long udf_ioctl(struct file *, unsigned int, unsigned long); +int udf_fsync(struct file *file, loff_t start, loff_t end, int datasync); /* inode.c */ extern struct inode *__udf_iget(struct super_block *, struct kernel_lb_addr *,