diff options
author | Christian Brauner <christian@brauner.io> | 2019-01-21 11:48:08 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-01-22 12:25:54 +0100 |
commit | 01684db950ea2b840531ab9298a8785776b6f6e8 (patch) | |
tree | b23af74bf5adfdc0b083af40872f85fb80f63778 | |
parent | 29ef1c8e16aed079ac09989d752e38d412b6e1a8 (diff) |
binderfs: switch from d_add() to d_instantiate()
In a previous commit we switched from a d_alloc_name() + d_lookup()
combination to setup a new dentry and find potential duplicates to the more
idiomatic lookup_one_len(). As far as I understand, this also means we need
to switch from d_add() to d_instantiate() since lookup_one_len() will
create a new dentry when it doesn't find an existing one and add the new
dentry to the hash queues. So we only need to call d_instantiate() to
connect the dentry to the inode and turn it into a positive dentry.
If we were to use d_add() we sure see stack traces like the following
indicating that adding the same dentry twice over the same inode:
[ 744.441889] CPU: 4 PID: 2849 Comm: landscape-sysin Not tainted 5.0.0-rc1-brauner-binderfs #243
[ 744.441889] Hardware name: Dell DCS XS24-SC2 /XS24-SC2 , BIOS S59_3C20 04/07/2011
[ 744.441889] RIP: 0010:__d_lookup_rcu+0x76/0x190
[ 744.441889] Code: 89 75 c0 49 c1 e9 20 49 89 fd 45 89 ce 41 83 e6 07 42 8d 04 f5 00 00 00 00 89 45 c8 eb 0c 48 8b 1b 48 85 db 0f 84 81 00 00 00 <44> 8b 63 fc 4c 3b 6b 10 75 ea 48 83 7b 08 00 74 e3 41 83 e4 fe 41
[ 744.441889] RSP: 0018:ffffb8c984e27ad0 EFLAGS: 00000282 ORIG_RAX: ffffffffffffff13
[ 744.441889] RAX: 0000000000000038 RBX: ffff9407ef770c08 RCX: ffffb8c980011000
[ 744.441889] RDX: ffffb8c984e27b54 RSI: ffffb8c984e27ce0 RDI: ffff9407e6689600
[ 744.441889] RBP: ffffb8c984e27b28 R08: ffffb8c984e27ba4 R09: 0000000000000007
[ 744.441889] R10: ffff9407e5c4f05c R11: 973f3eb9d84a94e5 R12: 0000000000000002
[ 744.441889] R13: ffff9407e6689600 R14: 0000000000000007 R15: 00000007bfef7a13
[ 744.441889] FS: 00007f0db13bb740(0000) GS:ffff9407f3b00000(0000) knlGS:0000000000000000
[ 744.441889] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 744.441889] CR2: 00007f0dacc51024 CR3: 000000032961a000 CR4: 00000000000006e0
[ 744.441889] Call Trace:
[ 744.441889] lookup_fast+0x53/0x300
[ 744.441889] walk_component+0x49/0x350
[ 744.441889] ? inode_permission+0x63/0x1a0
[ 744.441889] link_path_walk.part.33+0x1bc/0x5a0
[ 744.441889] ? path_init+0x190/0x310
[ 744.441889] path_lookupat+0x95/0x210
[ 744.441889] filename_lookup+0xb6/0x190
[ 744.441889] ? __check_object_size+0xb8/0x1b0
[ 744.441889] ? strncpy_from_user+0x50/0x1a0
[ 744.441889] user_path_at_empty+0x36/0x40
[ 744.441889] ? user_path_at_empty+0x36/0x40
[ 744.441889] vfs_statx+0x76/0xe0
[ 744.441889] __do_sys_newstat+0x3d/0x70
[ 744.441889] __x64_sys_newstat+0x16/0x20
[ 744.441889] do_syscall_64+0x5a/0x120
[ 744.441889] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 744.441889] RIP: 0033:0x7f0db0ec2775
[ 744.441889] Code: 00 00 00 75 05 48 83 c4 18 c3 e8 26 55 02 00 66 0f 1f 44 00 00 83 ff 01 48 89 f0 77 30 48 89 c7 48 89 d6 b8 04 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 03 f3 c3 90 48 8b 15 e1 b6 2d 00 f7 d8 64 89
[ 744.441889] RSP: 002b:00007ffc36bc9388 EFLAGS: 00000246 ORIG_RAX: 0000000000000004
[ 744.441889] RAX: ffffffffffffffda RBX: 00007ffc36bc9300 RCX: 00007f0db0ec2775
[ 744.441889] RDX: 00007ffc36bc9400 RSI: 00007ffc36bc9400 RDI: 00007f0dad26f050
[ 744.441889] RBP: 0000000000c0bc60 R08: 0000000000000000 R09: 0000000000000001
[ 744.441889] R10: 0000000000000000 R11: 0000000000000246 R12: 00007ffc36bc9400
[ 744.441889] R13: 0000000000000001 R14: 00000000ffffff9c R15: 0000000000c0bc60
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Christian Brauner <christian@brauner.io>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/android/binderfs.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/android/binderfs.c b/drivers/android/binderfs.c index d537dcdb5d65..6a2185eb66c5 100644 --- a/drivers/android/binderfs.c +++ b/drivers/android/binderfs.c @@ -212,7 +212,7 @@ static int binderfs_binder_device_create(struct inode *ref_inode, } inode->i_private = device; - d_add(dentry, inode); + d_instantiate(dentry, inode); fsnotify_create(root->d_inode, dentry); inode_unlock(d_inode(root)); |