Skip to content

Commit 83bc1d2

Browse files
amir73ilbrauner
authored andcommitted
fs: get mnt_writers count for an open backing file's real path
A writeable mapped backing file can perform writes to the real inode. Therefore, the real path mount must be kept writable so long as the writable map exists. This may not be strictly needed for ovelrayfs private upper mount, but it is correct to take the mnt_writers count in the vfs helper. Signed-off-by: Amir Goldstein <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Christian Brauner <[email protected]>
1 parent 6c4d1c9 commit 83bc1d2

File tree

2 files changed

+34
-8
lines changed

2 files changed

+34
-8
lines changed

fs/internal.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,20 @@ struct file *alloc_empty_file_noaccount(int flags, const struct cred *cred);
9696
struct file *alloc_empty_backing_file(int flags, const struct cred *cred);
9797
void release_empty_file(struct file *f);
9898

99+
static inline void file_put_write_access(struct file *file)
100+
{
101+
put_write_access(file->f_inode);
102+
mnt_put_write_access(file->f_path.mnt);
103+
if (unlikely(file->f_mode & FMODE_BACKING))
104+
mnt_put_write_access(backing_file_real_path(file)->mnt);
105+
}
106+
99107
static inline void put_file_access(struct file *file)
100108
{
101109
if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
102110
i_readcount_dec(file->f_inode);
103111
} else if (file->f_mode & FMODE_WRITER) {
104-
put_write_access(file->f_inode);
105-
mnt_put_write_access(file->f_path.mnt);
112+
file_put_write_access(file);
106113
}
107114
}
108115

fs/open.c

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,30 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group)
870870
return ksys_fchown(fd, user, group);
871871
}
872872

873+
static inline int file_get_write_access(struct file *f)
874+
{
875+
int error;
876+
877+
error = get_write_access(f->f_inode);
878+
if (unlikely(error))
879+
return error;
880+
error = mnt_get_write_access(f->f_path.mnt);
881+
if (unlikely(error))
882+
goto cleanup_inode;
883+
if (unlikely(f->f_mode & FMODE_BACKING)) {
884+
error = mnt_get_write_access(backing_file_real_path(f)->mnt);
885+
if (unlikely(error))
886+
goto cleanup_mnt;
887+
}
888+
return 0;
889+
890+
cleanup_mnt:
891+
mnt_put_write_access(f->f_path.mnt);
892+
cleanup_inode:
893+
put_write_access(f->f_inode);
894+
return error;
895+
}
896+
873897
static int do_dentry_open(struct file *f,
874898
struct inode *inode,
875899
int (*open)(struct inode *, struct file *))
@@ -892,14 +916,9 @@ static int do_dentry_open(struct file *f,
892916
if ((f->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
893917
i_readcount_inc(inode);
894918
} else if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) {
895-
error = get_write_access(inode);
919+
error = file_get_write_access(f);
896920
if (unlikely(error))
897921
goto cleanup_file;
898-
error = mnt_get_write_access(f->f_path.mnt);
899-
if (unlikely(error)) {
900-
put_write_access(inode);
901-
goto cleanup_file;
902-
}
903922
f->f_mode |= FMODE_WRITER;
904923
}
905924

0 commit comments

Comments
 (0)