Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <amir73il@gmail.com>
Link: https://lore.kernel.org/r/20231009153712.1566422-2-amir73il@gmail.com
Signed-off-by: Christian Brauner <brauner@kernel.org>

authored by

Amir Goldstein and committed by
Christian Brauner
83bc1d29 6c4d1c99

+34 -8
+9 -2
fs/internal.h
··· 96 96 struct file *alloc_empty_backing_file(int flags, const struct cred *cred); 97 97 void release_empty_file(struct file *f); 98 98 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 + 99 107 static inline void put_file_access(struct file *file) 100 108 { 101 109 if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) { 102 110 i_readcount_dec(file->f_inode); 103 111 } 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); 106 113 } 107 114 } 108 115
+25 -6
fs/open.c
··· 870 870 return ksys_fchown(fd, user, group); 871 871 } 872 872 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 + 873 897 static int do_dentry_open(struct file *f, 874 898 struct inode *inode, 875 899 int (*open)(struct inode *, struct file *)) ··· 916 892 if ((f->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) { 917 893 i_readcount_inc(inode); 918 894 } else if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) { 919 - error = get_write_access(inode); 895 + error = file_get_write_access(f); 920 896 if (unlikely(error)) 921 897 goto cleanup_file; 922 - error = mnt_get_write_access(f->f_path.mnt); 923 - if (unlikely(error)) { 924 - put_write_access(inode); 925 - goto cleanup_file; 926 - } 927 898 f->f_mode |= FMODE_WRITER; 928 899 } 929 900