Skip to content

Commit 762321d

Browse files
Christoph Hellwigbrauner
authored andcommitted
filemap: add a per-mapping stable writes flag
folio_wait_stable waits for writeback to finish before modifying the contents of a folio again, e.g. to support check summing of the data in the block integrity code. Currently this behavior is controlled by the SB_I_STABLE_WRITES flag on the super_block, which means it is uniform for the entire file system. This is wrong for the block device pseudofs which is shared by all block devices, or file systems that can use multiple devices like XFS witht the RT subvolume or btrfs (although btrfs currently reimplements folio_wait_stable anyway). Add a per-address_space AS_STABLE_WRITES flag to control the behavior in a more fine grained way. The existing SB_I_STABLE_WRITES is kept to initialize AS_STABLE_WRITES to the existing default which covers most cases. Signed-off-by: Christoph Hellwig <[email protected]> Link: https://lore.kernel.org/r/[email protected] Tested-by: Ilya Dryomov <[email protected]> Reviewed-by: Matthew Wilcox (Oracle) <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
1 parent 66917f8 commit 762321d

File tree

3 files changed

+20
-1
lines changed

3 files changed

+20
-1
lines changed

fs/inode.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,8 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
215215
lockdep_set_class_and_name(&mapping->invalidate_lock,
216216
&sb->s_type->invalidate_lock_key,
217217
"mapping.invalidate_lock");
218+
if (sb->s_iflags & SB_I_STABLE_WRITES)
219+
mapping_set_stable_writes(mapping);
218220
inode->i_private = NULL;
219221
inode->i_mapping = mapping;
220222
INIT_HLIST_HEAD(&inode->i_dentry); /* buggered by rcu freeing */

include/linux/pagemap.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,8 @@ enum mapping_flags {
204204
AS_NO_WRITEBACK_TAGS = 5,
205205
AS_LARGE_FOLIO_SUPPORT = 6,
206206
AS_RELEASE_ALWAYS, /* Call ->release_folio(), even if no private data */
207+
AS_STABLE_WRITES, /* must wait for writeback before modifying
208+
folio contents */
207209
};
208210

209211
/**
@@ -289,6 +291,21 @@ static inline void mapping_clear_release_always(struct address_space *mapping)
289291
clear_bit(AS_RELEASE_ALWAYS, &mapping->flags);
290292
}
291293

294+
static inline bool mapping_stable_writes(const struct address_space *mapping)
295+
{
296+
return test_bit(AS_STABLE_WRITES, &mapping->flags);
297+
}
298+
299+
static inline void mapping_set_stable_writes(struct address_space *mapping)
300+
{
301+
set_bit(AS_STABLE_WRITES, &mapping->flags);
302+
}
303+
304+
static inline void mapping_clear_stable_writes(struct address_space *mapping)
305+
{
306+
clear_bit(AS_STABLE_WRITES, &mapping->flags);
307+
}
308+
292309
static inline gfp_t mapping_gfp_mask(struct address_space * mapping)
293310
{
294311
return mapping->gfp_mask;

mm/page-writeback.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3107,7 +3107,7 @@ EXPORT_SYMBOL_GPL(folio_wait_writeback_killable);
31073107
*/
31083108
void folio_wait_stable(struct folio *folio)
31093109
{
3110-
if (folio_inode(folio)->i_sb->s_iflags & SB_I_STABLE_WRITES)
3110+
if (mapping_stable_writes(folio_mapping(folio)))
31113111
folio_wait_writeback(folio);
31123112
}
31133113
EXPORT_SYMBOL_GPL(folio_wait_stable);

0 commit comments

Comments
 (0)