Loading Documentation/filesystems/overlayfs.txt +28 −0 Original line number Original line Diff line number Diff line Loading @@ -159,6 +159,22 @@ overlay filesystem (though an operation on the name of the file such as rename or unlink will of course be noticed and handled). rename or unlink will of course be noticed and handled). Multiple lower layers --------------------- Multiple lower layers can now be given using the the colon (":") as a separator character between the directory names. For example: mount -t overlay overlay -olowerdir=/lower1:/lower2:/lower3 /merged As the example shows, "upperdir=" and "workdir=" may be omitted. In that case the overlay will be read-only. The specified lower directories will be stacked beginning from the rightmost one and going left. In the above example lower1 will be the top, lower2 the middle and lower3 the bottom layer. Non-standard behavior Non-standard behavior --------------------- --------------------- Loading Loading @@ -196,3 +212,15 @@ Changes to the underlying filesystems while part of a mounted overlay filesystem are not allowed. If the underlying filesystem is changed, filesystem are not allowed. If the underlying filesystem is changed, the behavior of the overlay is undefined, though it will not result in the behavior of the overlay is undefined, though it will not result in a crash or deadlock. a crash or deadlock. Testsuite --------- There's testsuite developed by David Howells at: git://git.infradead.org/users/dhowells/unionmount-testsuite.git Run as root: # cd unionmount-testsuite # ./run --ov fs/overlayfs/copy_up.c +2 −3 Original line number Original line Diff line number Diff line Loading @@ -191,7 +191,6 @@ int ovl_set_attr(struct dentry *upperdentry, struct kstat *stat) ovl_set_timestamps(upperdentry, stat); ovl_set_timestamps(upperdentry, stat); return err; return err; } } static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, Loading Loading @@ -385,7 +384,7 @@ int ovl_copy_up(struct dentry *dentry) struct kstat stat; struct kstat stat; enum ovl_path_type type = ovl_path_type(dentry); enum ovl_path_type type = ovl_path_type(dentry); if (type != OVL_PATH_LOWER) if (OVL_TYPE_UPPER(type)) break; break; next = dget(dentry); next = dget(dentry); Loading @@ -394,7 +393,7 @@ int ovl_copy_up(struct dentry *dentry) parent = dget_parent(next); parent = dget_parent(next); type = ovl_path_type(parent); type = ovl_path_type(parent); if (type != OVL_PATH_LOWER) if (OVL_TYPE_UPPER(type)) break; break; dput(next); dput(next); Loading fs/overlayfs/dir.c +14 −14 Original line number Original line Diff line number Diff line Loading @@ -118,14 +118,14 @@ int ovl_create_real(struct inode *dir, struct dentry *newdentry, static int ovl_set_opaque(struct dentry *upperdentry) static int ovl_set_opaque(struct dentry *upperdentry) { { return ovl_do_setxattr(upperdentry, ovl_opaque_xattr, "y", 1, 0); return ovl_do_setxattr(upperdentry, OVL_XATTR_OPAQUE, "y", 1, 0); } } static void ovl_remove_opaque(struct dentry *upperdentry) static void ovl_remove_opaque(struct dentry *upperdentry) { { int err; int err; err = ovl_do_removexattr(upperdentry, ovl_opaque_xattr); err = ovl_do_removexattr(upperdentry, OVL_XATTR_OPAQUE); if (err) { if (err) { pr_warn("overlayfs: failed to remove opaque from '%s' (%i)\n", pr_warn("overlayfs: failed to remove opaque from '%s' (%i)\n", upperdentry->d_name.name, err); upperdentry->d_name.name, err); Loading @@ -152,7 +152,7 @@ static int ovl_dir_getattr(struct vfsmount *mnt, struct dentry *dentry, * correct link count. nlink=1 seems to pacify 'find' and * correct link count. nlink=1 seems to pacify 'find' and * other utilities. * other utilities. */ */ if (type == OVL_PATH_MERGE) if (OVL_TYPE_MERGE(type)) stat->nlink = 1; stat->nlink = 1; return 0; return 0; Loading Loading @@ -506,7 +506,7 @@ static int ovl_remove_and_whiteout(struct dentry *dentry, bool is_dir) struct dentry *opaquedir = NULL; struct dentry *opaquedir = NULL; int err; int err; if (is_dir) { if (is_dir && OVL_TYPE_MERGE_OR_LOWER(ovl_path_type(dentry))) { opaquedir = ovl_check_empty_and_clear(dentry); opaquedir = ovl_check_empty_and_clear(dentry); err = PTR_ERR(opaquedir); err = PTR_ERR(opaquedir); if (IS_ERR(opaquedir)) if (IS_ERR(opaquedir)) Loading Loading @@ -630,7 +630,7 @@ static int ovl_do_remove(struct dentry *dentry, bool is_dir) goto out_drop_write; goto out_drop_write; type = ovl_path_type(dentry); type = ovl_path_type(dentry); if (type == OVL_PATH_PURE_UPPER) { if (OVL_TYPE_PURE_UPPER(type)) { err = ovl_remove_upper(dentry, is_dir); err = ovl_remove_upper(dentry, is_dir); } else { } else { const struct cred *old_cred; const struct cred *old_cred; Loading Loading @@ -712,7 +712,7 @@ static int ovl_rename2(struct inode *olddir, struct dentry *old, /* Don't copy up directory trees */ /* Don't copy up directory trees */ old_type = ovl_path_type(old); old_type = ovl_path_type(old); err = -EXDEV; err = -EXDEV; if ((old_type == OVL_PATH_LOWER || old_type == OVL_PATH_MERGE) && is_dir) if (OVL_TYPE_MERGE_OR_LOWER(old_type) && is_dir) goto out; goto out; if (new->d_inode) { if (new->d_inode) { Loading @@ -725,25 +725,25 @@ static int ovl_rename2(struct inode *olddir, struct dentry *old, new_type = ovl_path_type(new); new_type = ovl_path_type(new); err = -EXDEV; err = -EXDEV; if (!overwrite && (new_type == OVL_PATH_LOWER || new_type == OVL_PATH_MERGE) && new_is_dir) if (!overwrite && OVL_TYPE_MERGE_OR_LOWER(new_type) && new_is_dir) goto out; goto out; err = 0; err = 0; if (new_type == OVL_PATH_LOWER && old_type == OVL_PATH_LOWER) { if (!OVL_TYPE_UPPER(new_type) && !OVL_TYPE_UPPER(old_type)) { if (ovl_dentry_lower(old)->d_inode == if (ovl_dentry_lower(old)->d_inode == ovl_dentry_lower(new)->d_inode) ovl_dentry_lower(new)->d_inode) goto out; goto out; } } if (new_type != OVL_PATH_LOWER && old_type != OVL_PATH_LOWER) { if (OVL_TYPE_UPPER(new_type) && OVL_TYPE_UPPER(old_type)) { if (ovl_dentry_upper(old)->d_inode == if (ovl_dentry_upper(old)->d_inode == ovl_dentry_upper(new)->d_inode) ovl_dentry_upper(new)->d_inode) goto out; goto out; } } } else { } else { if (ovl_dentry_is_opaque(new)) if (ovl_dentry_is_opaque(new)) new_type = OVL_PATH_UPPER; new_type = __OVL_PATH_UPPER; else else new_type = OVL_PATH_PURE_UPPER; new_type = __OVL_PATH_UPPER | __OVL_PATH_PURE; } } err = ovl_want_write(old); err = ovl_want_write(old); Loading @@ -763,8 +763,8 @@ static int ovl_rename2(struct inode *olddir, struct dentry *old, goto out_drop_write; goto out_drop_write; } } old_opaque = old_type != OVL_PATH_PURE_UPPER; old_opaque = !OVL_TYPE_PURE_UPPER(old_type); new_opaque = new_type != OVL_PATH_PURE_UPPER; new_opaque = !OVL_TYPE_PURE_UPPER(new_type); if (old_opaque || new_opaque) { if (old_opaque || new_opaque) { err = -ENOMEM; err = -ENOMEM; Loading @@ -787,7 +787,7 @@ static int ovl_rename2(struct inode *olddir, struct dentry *old, old_cred = override_creds(override_cred); old_cred = override_creds(override_cred); } } if (overwrite && (new_type == OVL_PATH_LOWER || new_type == OVL_PATH_MERGE) && new_is_dir) { if (overwrite && OVL_TYPE_MERGE_OR_LOWER(new_type) && new_is_dir) { opaquedir = ovl_check_empty_and_clear(new); opaquedir = ovl_check_empty_and_clear(new); err = PTR_ERR(opaquedir); err = PTR_ERR(opaquedir); if (IS_ERR(opaquedir)) { if (IS_ERR(opaquedir)) { Loading fs/overlayfs/inode.c +7 −5 Original line number Original line Diff line number Diff line Loading @@ -205,7 +205,7 @@ static int ovl_readlink(struct dentry *dentry, char __user *buf, int bufsiz) static bool ovl_is_private_xattr(const char *name) static bool ovl_is_private_xattr(const char *name) { { return strncmp(name, "trusted.overlay.", 14) == 0; return strncmp(name, OVL_XATTR_PRE_NAME, OVL_XATTR_PRE_LEN) == 0; } } int ovl_setxattr(struct dentry *dentry, const char *name, int ovl_setxattr(struct dentry *dentry, const char *name, Loading Loading @@ -238,7 +238,10 @@ int ovl_setxattr(struct dentry *dentry, const char *name, static bool ovl_need_xattr_filter(struct dentry *dentry, static bool ovl_need_xattr_filter(struct dentry *dentry, enum ovl_path_type type) enum ovl_path_type type) { { return type == OVL_PATH_UPPER && S_ISDIR(dentry->d_inode->i_mode); if ((type & (__OVL_PATH_PURE | __OVL_PATH_UPPER)) == __OVL_PATH_UPPER) return S_ISDIR(dentry->d_inode->i_mode); else return false; } } ssize_t ovl_getxattr(struct dentry *dentry, const char *name, ssize_t ovl_getxattr(struct dentry *dentry, const char *name, Loading Loading @@ -299,7 +302,7 @@ int ovl_removexattr(struct dentry *dentry, const char *name) if (ovl_need_xattr_filter(dentry, type) && ovl_is_private_xattr(name)) if (ovl_need_xattr_filter(dentry, type) && ovl_is_private_xattr(name)) goto out_drop_write; goto out_drop_write; if (type == OVL_PATH_LOWER) { if (!OVL_TYPE_UPPER(type)) { err = vfs_getxattr(realpath.dentry, name, NULL, 0); err = vfs_getxattr(realpath.dentry, name, NULL, 0); if (err < 0) if (err < 0) goto out_drop_write; goto out_drop_write; Loading @@ -321,7 +324,7 @@ int ovl_removexattr(struct dentry *dentry, const char *name) static bool ovl_open_need_copy_up(int flags, enum ovl_path_type type, static bool ovl_open_need_copy_up(int flags, enum ovl_path_type type, struct dentry *realdentry) struct dentry *realdentry) { { if (type != OVL_PATH_LOWER) if (OVL_TYPE_UPPER(type)) return false; return false; if (special_file(realdentry->d_inode->i_mode)) if (special_file(realdentry->d_inode->i_mode)) Loading Loading @@ -430,5 +433,4 @@ struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, } } return inode; return inode; } } fs/overlayfs/overlayfs.h +13 −5 Original line number Original line Diff line number Diff line Loading @@ -12,13 +12,20 @@ struct ovl_entry; struct ovl_entry; enum ovl_path_type { enum ovl_path_type { OVL_PATH_PURE_UPPER, __OVL_PATH_PURE = (1 << 0), OVL_PATH_UPPER, __OVL_PATH_UPPER = (1 << 1), OVL_PATH_MERGE, __OVL_PATH_MERGE = (1 << 2), OVL_PATH_LOWER, }; }; extern const char *ovl_opaque_xattr; #define OVL_TYPE_UPPER(type) ((type) & __OVL_PATH_UPPER) #define OVL_TYPE_MERGE(type) ((type) & __OVL_PATH_MERGE) #define OVL_TYPE_PURE_UPPER(type) ((type) & __OVL_PATH_PURE) #define OVL_TYPE_MERGE_OR_LOWER(type) \ (OVL_TYPE_MERGE(type) || !OVL_TYPE_UPPER(type)) #define OVL_XATTR_PRE_NAME "trusted.overlay." #define OVL_XATTR_PRE_LEN 16 #define OVL_XATTR_OPAQUE OVL_XATTR_PRE_NAME"opaque" static inline int ovl_do_rmdir(struct inode *dir, struct dentry *dentry) static inline int ovl_do_rmdir(struct inode *dir, struct dentry *dentry) { { Loading Loading @@ -130,6 +137,7 @@ void ovl_dentry_version_inc(struct dentry *dentry); void ovl_path_upper(struct dentry *dentry, struct path *path); void ovl_path_upper(struct dentry *dentry, struct path *path); void ovl_path_lower(struct dentry *dentry, struct path *path); void ovl_path_lower(struct dentry *dentry, struct path *path); enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path); enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path); int ovl_path_next(int idx, struct dentry *dentry, struct path *path); struct dentry *ovl_dentry_upper(struct dentry *dentry); struct dentry *ovl_dentry_upper(struct dentry *dentry); struct dentry *ovl_dentry_lower(struct dentry *dentry); struct dentry *ovl_dentry_lower(struct dentry *dentry); struct dentry *ovl_dentry_real(struct dentry *dentry); struct dentry *ovl_dentry_real(struct dentry *dentry); Loading Loading
Documentation/filesystems/overlayfs.txt +28 −0 Original line number Original line Diff line number Diff line Loading @@ -159,6 +159,22 @@ overlay filesystem (though an operation on the name of the file such as rename or unlink will of course be noticed and handled). rename or unlink will of course be noticed and handled). Multiple lower layers --------------------- Multiple lower layers can now be given using the the colon (":") as a separator character between the directory names. For example: mount -t overlay overlay -olowerdir=/lower1:/lower2:/lower3 /merged As the example shows, "upperdir=" and "workdir=" may be omitted. In that case the overlay will be read-only. The specified lower directories will be stacked beginning from the rightmost one and going left. In the above example lower1 will be the top, lower2 the middle and lower3 the bottom layer. Non-standard behavior Non-standard behavior --------------------- --------------------- Loading Loading @@ -196,3 +212,15 @@ Changes to the underlying filesystems while part of a mounted overlay filesystem are not allowed. If the underlying filesystem is changed, filesystem are not allowed. If the underlying filesystem is changed, the behavior of the overlay is undefined, though it will not result in the behavior of the overlay is undefined, though it will not result in a crash or deadlock. a crash or deadlock. Testsuite --------- There's testsuite developed by David Howells at: git://git.infradead.org/users/dhowells/unionmount-testsuite.git Run as root: # cd unionmount-testsuite # ./run --ov
fs/overlayfs/copy_up.c +2 −3 Original line number Original line Diff line number Diff line Loading @@ -191,7 +191,6 @@ int ovl_set_attr(struct dentry *upperdentry, struct kstat *stat) ovl_set_timestamps(upperdentry, stat); ovl_set_timestamps(upperdentry, stat); return err; return err; } } static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, Loading Loading @@ -385,7 +384,7 @@ int ovl_copy_up(struct dentry *dentry) struct kstat stat; struct kstat stat; enum ovl_path_type type = ovl_path_type(dentry); enum ovl_path_type type = ovl_path_type(dentry); if (type != OVL_PATH_LOWER) if (OVL_TYPE_UPPER(type)) break; break; next = dget(dentry); next = dget(dentry); Loading @@ -394,7 +393,7 @@ int ovl_copy_up(struct dentry *dentry) parent = dget_parent(next); parent = dget_parent(next); type = ovl_path_type(parent); type = ovl_path_type(parent); if (type != OVL_PATH_LOWER) if (OVL_TYPE_UPPER(type)) break; break; dput(next); dput(next); Loading
fs/overlayfs/dir.c +14 −14 Original line number Original line Diff line number Diff line Loading @@ -118,14 +118,14 @@ int ovl_create_real(struct inode *dir, struct dentry *newdentry, static int ovl_set_opaque(struct dentry *upperdentry) static int ovl_set_opaque(struct dentry *upperdentry) { { return ovl_do_setxattr(upperdentry, ovl_opaque_xattr, "y", 1, 0); return ovl_do_setxattr(upperdentry, OVL_XATTR_OPAQUE, "y", 1, 0); } } static void ovl_remove_opaque(struct dentry *upperdentry) static void ovl_remove_opaque(struct dentry *upperdentry) { { int err; int err; err = ovl_do_removexattr(upperdentry, ovl_opaque_xattr); err = ovl_do_removexattr(upperdentry, OVL_XATTR_OPAQUE); if (err) { if (err) { pr_warn("overlayfs: failed to remove opaque from '%s' (%i)\n", pr_warn("overlayfs: failed to remove opaque from '%s' (%i)\n", upperdentry->d_name.name, err); upperdentry->d_name.name, err); Loading @@ -152,7 +152,7 @@ static int ovl_dir_getattr(struct vfsmount *mnt, struct dentry *dentry, * correct link count. nlink=1 seems to pacify 'find' and * correct link count. nlink=1 seems to pacify 'find' and * other utilities. * other utilities. */ */ if (type == OVL_PATH_MERGE) if (OVL_TYPE_MERGE(type)) stat->nlink = 1; stat->nlink = 1; return 0; return 0; Loading Loading @@ -506,7 +506,7 @@ static int ovl_remove_and_whiteout(struct dentry *dentry, bool is_dir) struct dentry *opaquedir = NULL; struct dentry *opaquedir = NULL; int err; int err; if (is_dir) { if (is_dir && OVL_TYPE_MERGE_OR_LOWER(ovl_path_type(dentry))) { opaquedir = ovl_check_empty_and_clear(dentry); opaquedir = ovl_check_empty_and_clear(dentry); err = PTR_ERR(opaquedir); err = PTR_ERR(opaquedir); if (IS_ERR(opaquedir)) if (IS_ERR(opaquedir)) Loading Loading @@ -630,7 +630,7 @@ static int ovl_do_remove(struct dentry *dentry, bool is_dir) goto out_drop_write; goto out_drop_write; type = ovl_path_type(dentry); type = ovl_path_type(dentry); if (type == OVL_PATH_PURE_UPPER) { if (OVL_TYPE_PURE_UPPER(type)) { err = ovl_remove_upper(dentry, is_dir); err = ovl_remove_upper(dentry, is_dir); } else { } else { const struct cred *old_cred; const struct cred *old_cred; Loading Loading @@ -712,7 +712,7 @@ static int ovl_rename2(struct inode *olddir, struct dentry *old, /* Don't copy up directory trees */ /* Don't copy up directory trees */ old_type = ovl_path_type(old); old_type = ovl_path_type(old); err = -EXDEV; err = -EXDEV; if ((old_type == OVL_PATH_LOWER || old_type == OVL_PATH_MERGE) && is_dir) if (OVL_TYPE_MERGE_OR_LOWER(old_type) && is_dir) goto out; goto out; if (new->d_inode) { if (new->d_inode) { Loading @@ -725,25 +725,25 @@ static int ovl_rename2(struct inode *olddir, struct dentry *old, new_type = ovl_path_type(new); new_type = ovl_path_type(new); err = -EXDEV; err = -EXDEV; if (!overwrite && (new_type == OVL_PATH_LOWER || new_type == OVL_PATH_MERGE) && new_is_dir) if (!overwrite && OVL_TYPE_MERGE_OR_LOWER(new_type) && new_is_dir) goto out; goto out; err = 0; err = 0; if (new_type == OVL_PATH_LOWER && old_type == OVL_PATH_LOWER) { if (!OVL_TYPE_UPPER(new_type) && !OVL_TYPE_UPPER(old_type)) { if (ovl_dentry_lower(old)->d_inode == if (ovl_dentry_lower(old)->d_inode == ovl_dentry_lower(new)->d_inode) ovl_dentry_lower(new)->d_inode) goto out; goto out; } } if (new_type != OVL_PATH_LOWER && old_type != OVL_PATH_LOWER) { if (OVL_TYPE_UPPER(new_type) && OVL_TYPE_UPPER(old_type)) { if (ovl_dentry_upper(old)->d_inode == if (ovl_dentry_upper(old)->d_inode == ovl_dentry_upper(new)->d_inode) ovl_dentry_upper(new)->d_inode) goto out; goto out; } } } else { } else { if (ovl_dentry_is_opaque(new)) if (ovl_dentry_is_opaque(new)) new_type = OVL_PATH_UPPER; new_type = __OVL_PATH_UPPER; else else new_type = OVL_PATH_PURE_UPPER; new_type = __OVL_PATH_UPPER | __OVL_PATH_PURE; } } err = ovl_want_write(old); err = ovl_want_write(old); Loading @@ -763,8 +763,8 @@ static int ovl_rename2(struct inode *olddir, struct dentry *old, goto out_drop_write; goto out_drop_write; } } old_opaque = old_type != OVL_PATH_PURE_UPPER; old_opaque = !OVL_TYPE_PURE_UPPER(old_type); new_opaque = new_type != OVL_PATH_PURE_UPPER; new_opaque = !OVL_TYPE_PURE_UPPER(new_type); if (old_opaque || new_opaque) { if (old_opaque || new_opaque) { err = -ENOMEM; err = -ENOMEM; Loading @@ -787,7 +787,7 @@ static int ovl_rename2(struct inode *olddir, struct dentry *old, old_cred = override_creds(override_cred); old_cred = override_creds(override_cred); } } if (overwrite && (new_type == OVL_PATH_LOWER || new_type == OVL_PATH_MERGE) && new_is_dir) { if (overwrite && OVL_TYPE_MERGE_OR_LOWER(new_type) && new_is_dir) { opaquedir = ovl_check_empty_and_clear(new); opaquedir = ovl_check_empty_and_clear(new); err = PTR_ERR(opaquedir); err = PTR_ERR(opaquedir); if (IS_ERR(opaquedir)) { if (IS_ERR(opaquedir)) { Loading
fs/overlayfs/inode.c +7 −5 Original line number Original line Diff line number Diff line Loading @@ -205,7 +205,7 @@ static int ovl_readlink(struct dentry *dentry, char __user *buf, int bufsiz) static bool ovl_is_private_xattr(const char *name) static bool ovl_is_private_xattr(const char *name) { { return strncmp(name, "trusted.overlay.", 14) == 0; return strncmp(name, OVL_XATTR_PRE_NAME, OVL_XATTR_PRE_LEN) == 0; } } int ovl_setxattr(struct dentry *dentry, const char *name, int ovl_setxattr(struct dentry *dentry, const char *name, Loading Loading @@ -238,7 +238,10 @@ int ovl_setxattr(struct dentry *dentry, const char *name, static bool ovl_need_xattr_filter(struct dentry *dentry, static bool ovl_need_xattr_filter(struct dentry *dentry, enum ovl_path_type type) enum ovl_path_type type) { { return type == OVL_PATH_UPPER && S_ISDIR(dentry->d_inode->i_mode); if ((type & (__OVL_PATH_PURE | __OVL_PATH_UPPER)) == __OVL_PATH_UPPER) return S_ISDIR(dentry->d_inode->i_mode); else return false; } } ssize_t ovl_getxattr(struct dentry *dentry, const char *name, ssize_t ovl_getxattr(struct dentry *dentry, const char *name, Loading Loading @@ -299,7 +302,7 @@ int ovl_removexattr(struct dentry *dentry, const char *name) if (ovl_need_xattr_filter(dentry, type) && ovl_is_private_xattr(name)) if (ovl_need_xattr_filter(dentry, type) && ovl_is_private_xattr(name)) goto out_drop_write; goto out_drop_write; if (type == OVL_PATH_LOWER) { if (!OVL_TYPE_UPPER(type)) { err = vfs_getxattr(realpath.dentry, name, NULL, 0); err = vfs_getxattr(realpath.dentry, name, NULL, 0); if (err < 0) if (err < 0) goto out_drop_write; goto out_drop_write; Loading @@ -321,7 +324,7 @@ int ovl_removexattr(struct dentry *dentry, const char *name) static bool ovl_open_need_copy_up(int flags, enum ovl_path_type type, static bool ovl_open_need_copy_up(int flags, enum ovl_path_type type, struct dentry *realdentry) struct dentry *realdentry) { { if (type != OVL_PATH_LOWER) if (OVL_TYPE_UPPER(type)) return false; return false; if (special_file(realdentry->d_inode->i_mode)) if (special_file(realdentry->d_inode->i_mode)) Loading Loading @@ -430,5 +433,4 @@ struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, } } return inode; return inode; } }
fs/overlayfs/overlayfs.h +13 −5 Original line number Original line Diff line number Diff line Loading @@ -12,13 +12,20 @@ struct ovl_entry; struct ovl_entry; enum ovl_path_type { enum ovl_path_type { OVL_PATH_PURE_UPPER, __OVL_PATH_PURE = (1 << 0), OVL_PATH_UPPER, __OVL_PATH_UPPER = (1 << 1), OVL_PATH_MERGE, __OVL_PATH_MERGE = (1 << 2), OVL_PATH_LOWER, }; }; extern const char *ovl_opaque_xattr; #define OVL_TYPE_UPPER(type) ((type) & __OVL_PATH_UPPER) #define OVL_TYPE_MERGE(type) ((type) & __OVL_PATH_MERGE) #define OVL_TYPE_PURE_UPPER(type) ((type) & __OVL_PATH_PURE) #define OVL_TYPE_MERGE_OR_LOWER(type) \ (OVL_TYPE_MERGE(type) || !OVL_TYPE_UPPER(type)) #define OVL_XATTR_PRE_NAME "trusted.overlay." #define OVL_XATTR_PRE_LEN 16 #define OVL_XATTR_OPAQUE OVL_XATTR_PRE_NAME"opaque" static inline int ovl_do_rmdir(struct inode *dir, struct dentry *dentry) static inline int ovl_do_rmdir(struct inode *dir, struct dentry *dentry) { { Loading Loading @@ -130,6 +137,7 @@ void ovl_dentry_version_inc(struct dentry *dentry); void ovl_path_upper(struct dentry *dentry, struct path *path); void ovl_path_upper(struct dentry *dentry, struct path *path); void ovl_path_lower(struct dentry *dentry, struct path *path); void ovl_path_lower(struct dentry *dentry, struct path *path); enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path); enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path); int ovl_path_next(int idx, struct dentry *dentry, struct path *path); struct dentry *ovl_dentry_upper(struct dentry *dentry); struct dentry *ovl_dentry_upper(struct dentry *dentry); struct dentry *ovl_dentry_lower(struct dentry *dentry); struct dentry *ovl_dentry_lower(struct dentry *dentry); struct dentry *ovl_dentry_real(struct dentry *dentry); struct dentry *ovl_dentry_real(struct dentry *dentry); Loading