[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <lsq.1539530741.84278653@decadent.org.uk>
Date: Sun, 14 Oct 2018 16:25:41 +0100
From: Ben Hutchings <ben@...adent.org.uk>
To: linux-kernel@...r.kernel.org, stable@...r.kernel.org
CC: akpm@...ux-foundation.org, "Chris Mason" <clm@...com>,
"Filipe Manana" <fdmanana@...e.com>
Subject: [PATCH 3.16 281/366] Btrfs: ensure tmpfile inode is always
persisted with link count of 0
3.16.60-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <fdmanana@...e.com>
commit 5762b5c958abbecb7fb9f4596a6476d1ce91ecf6 upstream.
If we open a file with O_TMPFILE, don't do any further operation on
it (so that the inode item isn't updated) and then force a transaction
commit, we get a persisted inode item with a link count of 1, and not 0
as it should be.
Steps to reproduce it (requires a modern xfs_io with -T support):
$ mkfs.btrfs -f /dev/sdd
$ mount -o /dev/sdd /mnt
$ xfs_io -T /mnt &
$ sync
Then btrfs-debug-tree shows the inode item with a link count of 1:
$ btrfs-debug-tree /dev/sdd
(...)
fs tree key (FS_TREE ROOT_ITEM 0)
leaf 29556736 items 4 free space 15851 generation 6 owner 5
fs uuid f164d01b-1b92-481d-a4e4-435fb0f843d0
chunk uuid 0e3d0e56-bcca-4a1c-aa5f-cec2c6f4f7a6
item 0 key (256 INODE_ITEM 0) itemoff 16123 itemsize 160
inode generation 3 transid 6 size 0 block group 0 mode 40755 links 1
item 1 key (256 INODE_REF 256) itemoff 16111 itemsize 12
inode ref index 0 namelen 2 name: ..
item 2 key (257 INODE_ITEM 0) itemoff 15951 itemsize 160
inode generation 6 transid 6 size 0 block group 0 mode 100600 links 1
item 3 key (ORPHAN ORPHAN_ITEM 257) itemoff 15951 itemsize 0
orphan item
checksum tree key (CSUM_TREE ROOT_ITEM 0)
(...)
Signed-off-by: Filipe Manana <fdmanana@...e.com>
Signed-off-by: Chris Mason <clm@...com>
Signed-off-by: Ben Hutchings <ben@...adent.org.uk>
---
fs/btrfs/inode.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -5731,6 +5731,13 @@ static struct inode *btrfs_new_inode(str
}
/*
+ * O_TMPFILE, set link count to 0, so that after this point,
+ * we fill in an inode item with the correct link count.
+ */
+ if (!name)
+ set_nlink(inode, 0);
+
+ /*
* we have to initialize this early, so we can reclaim the inode
* number if we fail afterwards in this function.
*/
@@ -9096,6 +9103,14 @@ static int btrfs_tmpfile(struct inode *d
if (ret)
goto out;
+ /*
+ * We set number of links to 0 in btrfs_new_inode(), and here we set
+ * it to 1 because d_tmpfile() will issue a warning if the count is 0,
+ * through:
+ *
+ * d_tmpfile() -> inode_dec_link_count() -> drop_nlink()
+ */
+ set_nlink(inode, 1);
d_tmpfile(dentry, inode);
mark_inode_dirty(inode);
Powered by blists - more mailing lists