Merge tag 'ovl-update-4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs
Pull overlayfs updates from Miklos Szeredi: "This contains two new features: - Stack file operations: this allows removal of several hacks from the VFS, proper interaction of read-only open files with copy-up, possibility to implement fs modifying ioctls properly, and others. - Metadata only copy-up: when file is on lower layer and only metadata is modified (except size) then only copy up the metadata and continue to use the data from the lower file" * tag 'ovl-update-4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs: (66 commits) ovl: Enable metadata only feature ovl: Do not do metacopy only for ioctl modifying file attr ovl: Do not do metadata only copy-up for truncate operation ovl: add helper to force data copy-up ovl: Check redirect on index as well ovl: Set redirect on upper inode when it is linked ovl: Set redirect on metacopy files upon rename ovl: Do not set dentry type ORIGIN for broken hardlinks ovl: Add an inode flag OVL_CONST_INO ovl: Treat metacopy dentries as type OVL_PATH_MERGE ovl: Check redirects for metacopy files ovl: Move some dir related ovl_lookup_single() code in else block ovl: Do not expose metacopy only dentry from d_real() ovl: Open file with data except for the case of fsync ovl: Add helper ovl_inode_realdata() ovl: Store lower data inode in ovl_inode ovl: Fix ovl_getattr() to get number of blocks from lower ovl: Add helper ovl_dentry_lowerdata() to get lower data dentry ovl: Copy up meta inode data from lowest data inode ovl: Modify ovl_lookup() and friends to lookup metacopy dentry ...
This commit is contained in:
@@ -145,8 +145,7 @@ struct dentry_operations {
|
||||
char *(*d_dname)(struct dentry *, char *, int);
|
||||
struct vfsmount *(*d_automount)(struct path *);
|
||||
int (*d_manage)(const struct path *, bool);
|
||||
struct dentry *(*d_real)(struct dentry *, const struct inode *,
|
||||
unsigned int, unsigned int);
|
||||
struct dentry *(*d_real)(struct dentry *, const struct inode *);
|
||||
} ____cacheline_aligned;
|
||||
|
||||
/*
|
||||
@@ -561,15 +560,10 @@ static inline struct dentry *d_backing_dentry(struct dentry *upper)
|
||||
return upper;
|
||||
}
|
||||
|
||||
/* d_real() flags */
|
||||
#define D_REAL_UPPER 0x2 /* return upper dentry or NULL if non-upper */
|
||||
|
||||
/**
|
||||
* d_real - Return the real dentry
|
||||
* @dentry: the dentry to query
|
||||
* @inode: inode to select the dentry from multiple layers (can be NULL)
|
||||
* @open_flags: open flags to control copy-up behavior
|
||||
* @flags: flags to control what is returned by this function
|
||||
*
|
||||
* If dentry is on a union/overlay, then return the underlying, real dentry.
|
||||
* Otherwise return the dentry itself.
|
||||
@@ -577,11 +571,10 @@ static inline struct dentry *d_backing_dentry(struct dentry *upper)
|
||||
* See also: Documentation/filesystems/vfs.txt
|
||||
*/
|
||||
static inline struct dentry *d_real(struct dentry *dentry,
|
||||
const struct inode *inode,
|
||||
unsigned int open_flags, unsigned int flags)
|
||||
const struct inode *inode)
|
||||
{
|
||||
if (unlikely(dentry->d_flags & DCACHE_OP_REAL))
|
||||
return dentry->d_op->d_real(dentry, inode, open_flags, flags);
|
||||
return dentry->d_op->d_real(dentry, inode);
|
||||
else
|
||||
return dentry;
|
||||
}
|
||||
@@ -596,7 +589,7 @@ static inline struct dentry *d_real(struct dentry *dentry,
|
||||
static inline struct inode *d_real_inode(const struct dentry *dentry)
|
||||
{
|
||||
/* This usage of d_real() results in const dentry */
|
||||
return d_backing_inode(d_real((struct dentry *) dentry, NULL, 0, 0));
|
||||
return d_backing_inode(d_real((struct dentry *) dentry, NULL));
|
||||
}
|
||||
|
||||
struct name_snapshot {
|
||||
|
@@ -157,6 +157,9 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
|
||||
/* File is capable of returning -EAGAIN if I/O will block */
|
||||
#define FMODE_NOWAIT ((__force fmode_t)0x8000000)
|
||||
|
||||
/* File does not contribute to nr_files count */
|
||||
#define FMODE_NOACCOUNT ((__force fmode_t)0x20000000)
|
||||
|
||||
/*
|
||||
* Flag for rw_copy_check_uvector and compat_rw_copy_check_uvector
|
||||
* that indicates that they should check the contents of the iovec are
|
||||
@@ -1067,17 +1070,7 @@ struct file_lock_context {
|
||||
|
||||
extern void send_sigio(struct fown_struct *fown, int fd, int band);
|
||||
|
||||
/*
|
||||
* Return the inode to use for locking
|
||||
*
|
||||
* For overlayfs this should be the overlay inode, not the real inode returned
|
||||
* by file_inode(). For any other fs file_inode(filp) and locks_inode(filp) are
|
||||
* equal.
|
||||
*/
|
||||
static inline struct inode *locks_inode(const struct file *f)
|
||||
{
|
||||
return f->f_path.dentry->d_inode;
|
||||
}
|
||||
#define locks_inode(f) file_inode(f)
|
||||
|
||||
#ifdef CONFIG_FILE_LOCKING
|
||||
extern int fcntl_getlk(struct file *, unsigned int, struct flock *);
|
||||
@@ -1262,7 +1255,7 @@ static inline struct inode *file_inode(const struct file *f)
|
||||
|
||||
static inline struct dentry *file_dentry(const struct file *file)
|
||||
{
|
||||
return d_real(file->f_path.dentry, file_inode(file), 0, 0);
|
||||
return d_real(file->f_path.dentry, file_inode(file));
|
||||
}
|
||||
|
||||
static inline int locks_lock_file_wait(struct file *filp, struct file_lock *fl)
|
||||
@@ -1318,7 +1311,6 @@ extern int send_sigurg(struct fown_struct *fown);
|
||||
|
||||
/* These sb flags are internal to the kernel */
|
||||
#define SB_SUBMOUNT (1<<26)
|
||||
#define SB_NOREMOTELOCK (1<<27)
|
||||
#define SB_NOSEC (1<<28)
|
||||
#define SB_BORN (1<<29)
|
||||
#define SB_ACTIVE (1<<30)
|
||||
@@ -1647,6 +1639,8 @@ int vfs_mkobj(struct dentry *, umode_t,
|
||||
int (*f)(struct dentry *, umode_t, void *),
|
||||
void *);
|
||||
|
||||
extern long vfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
|
||||
|
||||
/*
|
||||
* VFS file helper functions.
|
||||
*/
|
||||
@@ -1765,7 +1759,7 @@ struct file_operations {
|
||||
loff_t, size_t, unsigned int);
|
||||
int (*clone_file_range)(struct file *, loff_t, struct file *, loff_t,
|
||||
u64);
|
||||
ssize_t (*dedupe_file_range)(struct file *, u64, u64, struct file *,
|
||||
int (*dedupe_file_range)(struct file *, loff_t, struct file *, loff_t,
|
||||
u64);
|
||||
} __randomize_layout;
|
||||
|
||||
@@ -1838,6 +1832,10 @@ extern int vfs_dedupe_file_range_compare(struct inode *src, loff_t srcoff,
|
||||
loff_t len, bool *is_same);
|
||||
extern int vfs_dedupe_file_range(struct file *file,
|
||||
struct file_dedupe_range *same);
|
||||
extern int vfs_dedupe_file_range_one(struct file *src_file, loff_t src_pos,
|
||||
struct file *dst_file, loff_t dst_pos,
|
||||
u64 len);
|
||||
|
||||
|
||||
struct super_operations {
|
||||
struct inode *(*alloc_inode)(struct super_block *sb);
|
||||
@@ -2096,6 +2094,7 @@ enum file_time_flags {
|
||||
S_VERSION = 8,
|
||||
};
|
||||
|
||||
extern bool atime_needs_update(const struct path *, struct inode *);
|
||||
extern void touch_atime(const struct path *);
|
||||
static inline void file_accessed(struct file *file)
|
||||
{
|
||||
@@ -2441,6 +2440,8 @@ extern struct file *filp_open(const char *, int, umode_t);
|
||||
extern struct file *file_open_root(struct dentry *, struct vfsmount *,
|
||||
const char *, int, umode_t);
|
||||
extern struct file * dentry_open(const struct path *, int, const struct cred *);
|
||||
extern struct file * open_with_fake_path(const struct path *, int,
|
||||
struct inode*, const struct cred *);
|
||||
static inline struct file *file_clone_open(struct file *file)
|
||||
{
|
||||
return dentry_open(&file->f_path, file->f_flags, file->f_cred);
|
||||
|
@@ -30,11 +30,7 @@ static inline int fsnotify_parent(const struct path *path, struct dentry *dentry
|
||||
static inline int fsnotify_perm(struct file *file, int mask)
|
||||
{
|
||||
const struct path *path = &file->f_path;
|
||||
/*
|
||||
* Do not use file_inode() here or anywhere in this file to get the
|
||||
* inode. That would break *notity on overlayfs.
|
||||
*/
|
||||
struct inode *inode = path->dentry->d_inode;
|
||||
struct inode *inode = file_inode(file);
|
||||
__u32 fsnotify_mask = 0;
|
||||
int ret;
|
||||
|
||||
@@ -178,7 +174,7 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry)
|
||||
static inline void fsnotify_access(struct file *file)
|
||||
{
|
||||
const struct path *path = &file->f_path;
|
||||
struct inode *inode = path->dentry->d_inode;
|
||||
struct inode *inode = file_inode(file);
|
||||
__u32 mask = FS_ACCESS;
|
||||
|
||||
if (S_ISDIR(inode->i_mode))
|
||||
@@ -196,7 +192,7 @@ static inline void fsnotify_access(struct file *file)
|
||||
static inline void fsnotify_modify(struct file *file)
|
||||
{
|
||||
const struct path *path = &file->f_path;
|
||||
struct inode *inode = path->dentry->d_inode;
|
||||
struct inode *inode = file_inode(file);
|
||||
__u32 mask = FS_MODIFY;
|
||||
|
||||
if (S_ISDIR(inode->i_mode))
|
||||
@@ -214,7 +210,7 @@ static inline void fsnotify_modify(struct file *file)
|
||||
static inline void fsnotify_open(struct file *file)
|
||||
{
|
||||
const struct path *path = &file->f_path;
|
||||
struct inode *inode = path->dentry->d_inode;
|
||||
struct inode *inode = file_inode(file);
|
||||
__u32 mask = FS_OPEN;
|
||||
|
||||
if (S_ISDIR(inode->i_mode))
|
||||
@@ -230,7 +226,7 @@ static inline void fsnotify_open(struct file *file)
|
||||
static inline void fsnotify_close(struct file *file)
|
||||
{
|
||||
const struct path *path = &file->f_path;
|
||||
struct inode *inode = path->dentry->d_inode;
|
||||
struct inode *inode = file_inode(file);
|
||||
fmode_t mode = file->f_mode;
|
||||
__u32 mask = (mode & FMODE_WRITE) ? FS_CLOSE_WRITE : FS_CLOSE_NOWRITE;
|
||||
|
||||
|
Reference in New Issue
Block a user