diff options
author | David Howells <dhowells@redhat.com> | 2015-06-18 09:32:31 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2015-06-19 03:19:32 -0400 |
commit | 4bacc9c9234c7c8eec44f5ed4e960d9f96fa0f01 (patch) | |
tree | 1ecac38332d4e8cf5370627f1214a1d7c5ff7529 /fs/dcache.c | |
parent | f25801ee4680ef1db21e15c112e6e5fe3ffe8da5 (diff) |
overlayfs: Make f_path always point to the overlay and f_inode to the underlay
Make file->f_path always point to the overlay dentry so that the path in
/proc/pid/fd is correct and to ensure that label-based LSMs have access to the
overlay as well as the underlay (path-based LSMs probably don't need it).
Using my union testsuite to set things up, before the patch I see:
[root@andromeda union-testsuite]# bash 5</mnt/a/foo107
[root@andromeda union-testsuite]# ls -l /proc/$$/fd/
...
lr-x------. 1 root root 64 Jun 5 14:38 5 -> /a/foo107
[root@andromeda union-testsuite]# stat /mnt/a/foo107
...
Device: 23h/35d Inode: 13381 Links: 1
...
[root@andromeda union-testsuite]# stat -L /proc/$$/fd/5
...
Device: 23h/35d Inode: 13381 Links: 1
...
After the patch:
[root@andromeda union-testsuite]# bash 5</mnt/a/foo107
[root@andromeda union-testsuite]# ls -l /proc/$$/fd/
...
lr-x------. 1 root root 64 Jun 5 14:22 5 -> /mnt/a/foo107
[root@andromeda union-testsuite]# stat /mnt/a/foo107
...
Device: 23h/35d Inode: 40346 Links: 1
...
[root@andromeda union-testsuite]# stat -L /proc/$$/fd/5
...
Device: 23h/35d Inode: 40346 Links: 1
...
Note the change in where /proc/$$/fd/5 points to in the ls command. It was
pointing to /a/foo107 (which doesn't exist) and now points to /mnt/a/foo107
(which is correct).
The inode accessed, however, is the lower layer. The union layer is on device
25h/37d and the upper layer on 24h/36d.
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 37b5afdaf698..c4ce35110704 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -1673,7 +1673,8 @@ void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op) | |||
1673 | DCACHE_OP_COMPARE | | 1673 | DCACHE_OP_COMPARE | |
1674 | DCACHE_OP_REVALIDATE | | 1674 | DCACHE_OP_REVALIDATE | |
1675 | DCACHE_OP_WEAK_REVALIDATE | | 1675 | DCACHE_OP_WEAK_REVALIDATE | |
1676 | DCACHE_OP_DELETE )); | 1676 | DCACHE_OP_DELETE | |
1677 | DCACHE_OP_SELECT_INODE)); | ||
1677 | dentry->d_op = op; | 1678 | dentry->d_op = op; |
1678 | if (!op) | 1679 | if (!op) |
1679 | return; | 1680 | return; |
@@ -1689,6 +1690,8 @@ void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op) | |||
1689 | dentry->d_flags |= DCACHE_OP_DELETE; | 1690 | dentry->d_flags |= DCACHE_OP_DELETE; |
1690 | if (op->d_prune) | 1691 | if (op->d_prune) |
1691 | dentry->d_flags |= DCACHE_OP_PRUNE; | 1692 | dentry->d_flags |= DCACHE_OP_PRUNE; |
1693 | if (op->d_select_inode) | ||
1694 | dentry->d_flags |= DCACHE_OP_SELECT_INODE; | ||
1692 | 1695 | ||
1693 | } | 1696 | } |
1694 | EXPORT_SYMBOL(d_set_d_op); | 1697 | EXPORT_SYMBOL(d_set_d_op); |