Skip to content

Commit def3ae8

Browse files
amir73ilbrauner
authored andcommitted
fs: store real path instead of fake path in backing file f_path
A backing file struct stores two path's, one "real" path that is referring to f_inode and one "fake" path, which should be displayed to users in /proc/<pid>/maps. There is a lot more potential code that needs to know the "real" path, then code that needs to know the "fake" path. Instead of code having to request the "real" path with file_real_path(), store the "real" path in f_path and require code that needs to know the "fake" path request it with file_user_path(). Replace the file_real_path() helper with a simple const accessor f_path(). After this change, file_dentry() is not expected to observe any files with overlayfs f_path and real f_inode, so the call to ->d_real() should not be needed. Leave the ->d_real() call for now and add an assertion in ovl_d_real() to catch if we made wrong assumptions. Suggested-by: Miklos Szeredi <[email protected]> Link: https://lore.kernel.org/r/CAJfpegtt48eXhhjDFA1ojcHPNKj3Go6joryCPtEFAKpocyBsnw@mail.gmail.com/ Signed-off-by: Amir Goldstein <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Christian Brauner <[email protected]>
1 parent 08582d6 commit def3ae8

File tree

6 files changed

+35
-43
lines changed

6 files changed

+35
-43
lines changed

fs/file_table.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,22 +44,22 @@ static struct kmem_cache *filp_cachep __read_mostly;
4444

4545
static struct percpu_counter nr_files __cacheline_aligned_in_smp;
4646

47-
/* Container for backing file with optional real path */
47+
/* Container for backing file with optional user path */
4848
struct backing_file {
4949
struct file file;
50-
struct path real_path;
50+
struct path user_path;
5151
};
5252

5353
static inline struct backing_file *backing_file(struct file *f)
5454
{
5555
return container_of(f, struct backing_file, file);
5656
}
5757

58-
struct path *backing_file_real_path(struct file *f)
58+
struct path *backing_file_user_path(struct file *f)
5959
{
60-
return &backing_file(f)->real_path;
60+
return &backing_file(f)->user_path;
6161
}
62-
EXPORT_SYMBOL_GPL(backing_file_real_path);
62+
EXPORT_SYMBOL_GPL(backing_file_user_path);
6363

6464
static inline void file_free(struct file *f)
6565
{
@@ -68,7 +68,7 @@ static inline void file_free(struct file *f)
6868
percpu_counter_dec(&nr_files);
6969
put_cred(f->f_cred);
7070
if (unlikely(f->f_mode & FMODE_BACKING)) {
71-
path_put(backing_file_real_path(f));
71+
path_put(backing_file_user_path(f));
7272
kfree(backing_file(f));
7373
} else {
7474
kmem_cache_free(filp_cachep, f);

fs/internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ static inline void file_put_write_access(struct file *file)
101101
put_write_access(file->f_inode);
102102
mnt_put_write_access(file->f_path.mnt);
103103
if (unlikely(file->f_mode & FMODE_BACKING))
104-
mnt_put_write_access(backing_file_real_path(file)->mnt);
104+
mnt_put_write_access(backing_file_user_path(file)->mnt);
105105
}
106106

107107
static inline void put_file_access(struct file *file)

fs/open.c

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -881,7 +881,7 @@ static inline int file_get_write_access(struct file *f)
881881
if (unlikely(error))
882882
goto cleanup_inode;
883883
if (unlikely(f->f_mode & FMODE_BACKING)) {
884-
error = mnt_get_write_access(backing_file_real_path(f)->mnt);
884+
error = mnt_get_write_access(backing_file_user_path(f)->mnt);
885885
if (unlikely(error))
886886
goto cleanup_mnt;
887887
}
@@ -1182,20 +1182,19 @@ EXPORT_SYMBOL_GPL(kernel_file_open);
11821182

11831183
/**
11841184
* backing_file_open - open a backing file for kernel internal use
1185-
* @path: path of the file to open
1185+
* @user_path: path that the user reuqested to open
11861186
* @flags: open flags
11871187
* @real_path: path of the backing file
11881188
* @cred: credentials for open
11891189
*
11901190
* Open a backing file for a stackable filesystem (e.g., overlayfs).
1191-
* @path may be on the stackable filesystem and backing inode on the
1192-
* underlying filesystem. In this case, we want to be able to return
1193-
* the @real_path of the backing inode. This is done by embedding the
1194-
* returned file into a container structure that also stores the path of
1195-
* the backing inode on the underlying filesystem, which can be
1196-
* retrieved using backing_file_real_path().
1191+
* @user_path may be on the stackable filesystem and @real_path on the
1192+
* underlying filesystem. In this case, we want to be able to return the
1193+
* @user_path of the stackable filesystem. This is done by embedding the
1194+
* returned file into a container structure that also stores the stacked
1195+
* file's path, which can be retrieved using backing_file_user_path().
11971196
*/
1198-
struct file *backing_file_open(const struct path *path, int flags,
1197+
struct file *backing_file_open(const struct path *user_path, int flags,
11991198
const struct path *real_path,
12001199
const struct cred *cred)
12011200
{
@@ -1206,9 +1205,9 @@ struct file *backing_file_open(const struct path *path, int flags,
12061205
if (IS_ERR(f))
12071206
return f;
12081207

1209-
f->f_path = *path;
1210-
path_get(real_path);
1211-
*backing_file_real_path(f) = *real_path;
1208+
path_get(user_path);
1209+
*backing_file_user_path(f) = *user_path;
1210+
f->f_path = *real_path;
12121211
error = do_dentry_open(f, d_inode(real_path->dentry), NULL);
12131212
if (error) {
12141213
fput(f);

fs/overlayfs/super.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,22 @@ static struct dentry *ovl_d_real(struct dentry *dentry,
3434
struct dentry *real = NULL, *lower;
3535
int err;
3636

37-
/* It's an overlay file */
37+
/*
38+
* vfs is only expected to call d_real() with NULL from d_real_inode()
39+
* and with overlay inode from file_dentry() on an overlay file.
40+
*
41+
* TODO: remove @inode argument from d_real() API, remove code in this
42+
* function that deals with non-NULL @inode and remove d_real() call
43+
* from file_dentry().
44+
*/
3845
if (inode && d_inode(dentry) == inode)
3946
return dentry;
47+
else if (inode)
48+
goto bug;
4049

4150
if (!d_is_reg(dentry)) {
42-
if (!inode || inode == d_inode(dentry))
43-
return dentry;
44-
goto bug;
51+
/* d_real_inode() is only relevant for regular files */
52+
return dentry;
4553
}
4654

4755
real = ovl_dentry_upper(dentry);

include/linux/fs.h

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2492,26 +2492,10 @@ struct file *dentry_open(const struct path *path, int flags,
24922492
const struct cred *creds);
24932493
struct file *dentry_create(const struct path *path, int flags, umode_t mode,
24942494
const struct cred *cred);
2495-
struct file *backing_file_open(const struct path *path, int flags,
2495+
struct file *backing_file_open(const struct path *user_path, int flags,
24962496
const struct path *real_path,
24972497
const struct cred *cred);
2498-
struct path *backing_file_real_path(struct file *f);
2499-
2500-
/*
2501-
* file_real_path - get the path corresponding to f_inode
2502-
*
2503-
* When opening a backing file for a stackable filesystem (e.g.,
2504-
* overlayfs) f_path may be on the stackable filesystem and f_inode on
2505-
* the underlying filesystem. When the path associated with f_inode is
2506-
* needed, this helper should be used instead of accessing f_path
2507-
* directly.
2508-
*/
2509-
static inline const struct path *file_real_path(struct file *f)
2510-
{
2511-
if (unlikely(f->f_mode & FMODE_BACKING))
2512-
return backing_file_real_path(f);
2513-
return &f->f_path;
2514-
}
2498+
struct path *backing_file_user_path(struct file *f);
25152499

25162500
/*
25172501
* file_user_path - get the path to display for memory mapped file
@@ -2524,6 +2508,8 @@ static inline const struct path *file_real_path(struct file *f)
25242508
*/
25252509
static inline const struct path *file_user_path(struct file *f)
25262510
{
2511+
if (unlikely(f->f_mode & FMODE_BACKING))
2512+
return backing_file_user_path(f);
25272513
return &f->f_path;
25282514
}
25292515

include/linux/fsnotify.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,7 @@ static inline int fsnotify_file(struct file *file, __u32 mask)
9696
if (file->f_mode & FMODE_NONOTIFY)
9797
return 0;
9898

99-
/* Overlayfs internal files have fake f_path */
100-
path = file_real_path(file);
99+
path = &file->f_path;
101100
return fsnotify_parent(path->dentry, mask, path, FSNOTIFY_EVENT_PATH);
102101
}
103102

0 commit comments

Comments
 (0)