diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-06-22 19:07:56 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-06-22 19:07:56 +0300 |
commit | 563a50672d8a86ec4b114a4a2f44d6e7ff855f5b (patch) | |
tree | 7d1766739863479592c9124753257400bde968cc /fs | |
parent | c3de9b572fc2063fb62e53df50cc55156d6bfb45 (diff) | |
parent | 348a1983cf4cf5099fc398438a968443af4c9f65 (diff) | |
download | linux-563a50672d8a86ec4b114a4a2f44d6e7ff855f5b.tar.xz |
Merge tag 'xfs-6.10-fixes-4' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull xfs fix from Chandan Babu:
- Fix assertion failure due to a race between unlink and cluster buffer
instantiation.
* tag 'xfs-6.10-fixes-4' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
xfs: fix unlink vs cluster buffer instantiation race
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/xfs_inode.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 58fb7a5062e1..f36091e1e7f5 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -2548,11 +2548,26 @@ xfs_ifree_cluster( * This buffer may not have been correctly initialised as we * didn't read it from disk. That's not important because we are * only using to mark the buffer as stale in the log, and to - * attach stale cached inodes on it. That means it will never be - * dispatched for IO. If it is, we want to know about it, and we - * want it to fail. We can acheive this by adding a write - * verifier to the buffer. + * attach stale cached inodes on it. + * + * For the inode that triggered the cluster freeing, this + * attachment may occur in xfs_inode_item_precommit() after we + * have marked this buffer stale. If this buffer was not in + * memory before xfs_ifree_cluster() started, it will not be + * marked XBF_DONE and this will cause problems later in + * xfs_inode_item_precommit() when we trip over a (stale, !done) + * buffer to attached to the transaction. + * + * Hence we have to mark the buffer as XFS_DONE here. This is + * safe because we are also marking the buffer as XBF_STALE and + * XFS_BLI_STALE. That means it will never be dispatched for + * IO and it won't be unlocked until the cluster freeing has + * been committed to the journal and the buffer unpinned. If it + * is written, we want to know about it, and we want it to + * fail. We can acheive this by adding a write verifier to the + * buffer. */ + bp->b_flags |= XBF_DONE; bp->b_ops = &xfs_inode_buf_ops; /* |