Loading fs/overlayfs/dir.c +1 −60 Original line number Diff line number Diff line Loading @@ -138,65 +138,6 @@ static int ovl_set_opaque(struct dentry *dentry, struct dentry *upperdentry) return err; } static int ovl_dir_getattr(const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags) { struct dentry *dentry = path->dentry; int err; enum ovl_path_type type; struct path realpath; const struct cred *old_cred; type = ovl_path_real(dentry, &realpath); old_cred = ovl_override_creds(dentry->d_sb); err = vfs_getattr(&realpath, stat, request_mask, flags); if (err) goto out; /* * When all layers are on the same fs, use the copy-up-origin st_ino, * which is persistent, unique and constant across copy up. * * Otherwise the pair {real st_ino; overlay st_dev} is not unique, so * use the non persistent overlay st_ino. */ if (ovl_same_sb(dentry->d_sb)) { if (OVL_TYPE_ORIGIN(type)) { struct kstat lowerstat; ovl_path_lower(dentry, &realpath); err = vfs_getattr(&realpath, &lowerstat, STATX_INO, flags); if (err) goto out; WARN_ON_ONCE(stat->dev != lowerstat.dev); stat->ino = lowerstat.ino; } } else { stat->ino = dentry->d_inode->i_ino; } /* * Always use the overlay st_dev for directories, so 'find -xdev' will * scan the entire overlay mount and won't cross the overlay mount * boundaries. */ stat->dev = dentry->d_sb->s_dev; /* * It's probably not worth it to count subdirs to get the * correct link count. nlink=1 seems to pacify 'find' and * other utilities. */ if (OVL_TYPE_MERGE(type)) stat->nlink = 1; out: revert_creds(old_cred); return err; } /* Common operations required to be done after creation of file on upper */ static void ovl_instantiate(struct dentry *dentry, struct inode *inode, struct dentry *newdentry, bool hardlink) Loading Loading @@ -1099,7 +1040,7 @@ const struct inode_operations ovl_dir_inode_operations = { .create = ovl_create, .mknod = ovl_mknod, .permission = ovl_permission, .getattr = ovl_dir_getattr, .getattr = ovl_getattr, .listxattr = ovl_listxattr, .get_acl = ovl_get_acl, .update_time = ovl_update_time, Loading fs/overlayfs/inode.c +27 −4 Original line number Diff line number Diff line Loading @@ -57,13 +57,14 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr) return err; } static int ovl_getattr(const struct path *path, struct kstat *stat, int ovl_getattr(const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags) { struct dentry *dentry = path->dentry; enum ovl_path_type type; struct path realpath; const struct cred *old_cred; bool is_dir = S_ISDIR(dentry->d_inode->i_mode); int err; type = ovl_path_real(dentry, &realpath); Loading @@ -85,10 +86,11 @@ static int ovl_getattr(const struct path *path, struct kstat *stat, if (ovl_same_sb(dentry->d_sb)) { if (OVL_TYPE_ORIGIN(type)) { struct kstat lowerstat; u32 lowermask = STATX_INO | (!is_dir ? STATX_NLINK : 0); ovl_path_lower(dentry, &realpath); err = vfs_getattr(&realpath, &lowerstat, STATX_INO | STATX_NLINK, flags); lowermask, flags); if (err) goto out; Loading @@ -98,11 +100,32 @@ static int ovl_getattr(const struct path *path, struct kstat *stat, * upper files, so we cannot use the lower origin st_ino * for those different files, even for the same fs case. */ if (lowerstat.nlink == 1) if (is_dir || lowerstat.nlink == 1) stat->ino = lowerstat.ino; } stat->dev = dentry->d_sb->s_dev; } else if (is_dir) { /* * If not all layers are on the same fs the pair {real st_ino; * overlay st_dev} is not unique, so use the non persistent * overlay st_ino. * * Always use the overlay st_dev for directories, so 'find * -xdev' will scan the entire overlay mount and won't cross the * overlay mount boundaries. */ stat->dev = dentry->d_sb->s_dev; stat->ino = dentry->d_inode->i_ino; } /* * It's probably not worth it to count subdirs to get the * correct link count. nlink=1 seems to pacify 'find' and * other utilities. */ if (is_dir && OVL_TYPE_MERGE(type)) stat->nlink = 1; out: revert_creds(old_cred); Loading fs/overlayfs/overlayfs.h +2 −0 Original line number Diff line number Diff line Loading @@ -236,6 +236,8 @@ void ovl_workdir_cleanup(struct inode *dir, struct vfsmount *mnt, /* inode.c */ int ovl_setattr(struct dentry *dentry, struct iattr *attr); int ovl_getattr(const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags); int ovl_permission(struct inode *inode, int mask); int ovl_xattr_set(struct dentry *dentry, const char *name, const void *value, size_t size, int flags); Loading Loading
fs/overlayfs/dir.c +1 −60 Original line number Diff line number Diff line Loading @@ -138,65 +138,6 @@ static int ovl_set_opaque(struct dentry *dentry, struct dentry *upperdentry) return err; } static int ovl_dir_getattr(const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags) { struct dentry *dentry = path->dentry; int err; enum ovl_path_type type; struct path realpath; const struct cred *old_cred; type = ovl_path_real(dentry, &realpath); old_cred = ovl_override_creds(dentry->d_sb); err = vfs_getattr(&realpath, stat, request_mask, flags); if (err) goto out; /* * When all layers are on the same fs, use the copy-up-origin st_ino, * which is persistent, unique and constant across copy up. * * Otherwise the pair {real st_ino; overlay st_dev} is not unique, so * use the non persistent overlay st_ino. */ if (ovl_same_sb(dentry->d_sb)) { if (OVL_TYPE_ORIGIN(type)) { struct kstat lowerstat; ovl_path_lower(dentry, &realpath); err = vfs_getattr(&realpath, &lowerstat, STATX_INO, flags); if (err) goto out; WARN_ON_ONCE(stat->dev != lowerstat.dev); stat->ino = lowerstat.ino; } } else { stat->ino = dentry->d_inode->i_ino; } /* * Always use the overlay st_dev for directories, so 'find -xdev' will * scan the entire overlay mount and won't cross the overlay mount * boundaries. */ stat->dev = dentry->d_sb->s_dev; /* * It's probably not worth it to count subdirs to get the * correct link count. nlink=1 seems to pacify 'find' and * other utilities. */ if (OVL_TYPE_MERGE(type)) stat->nlink = 1; out: revert_creds(old_cred); return err; } /* Common operations required to be done after creation of file on upper */ static void ovl_instantiate(struct dentry *dentry, struct inode *inode, struct dentry *newdentry, bool hardlink) Loading Loading @@ -1099,7 +1040,7 @@ const struct inode_operations ovl_dir_inode_operations = { .create = ovl_create, .mknod = ovl_mknod, .permission = ovl_permission, .getattr = ovl_dir_getattr, .getattr = ovl_getattr, .listxattr = ovl_listxattr, .get_acl = ovl_get_acl, .update_time = ovl_update_time, Loading
fs/overlayfs/inode.c +27 −4 Original line number Diff line number Diff line Loading @@ -57,13 +57,14 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr) return err; } static int ovl_getattr(const struct path *path, struct kstat *stat, int ovl_getattr(const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags) { struct dentry *dentry = path->dentry; enum ovl_path_type type; struct path realpath; const struct cred *old_cred; bool is_dir = S_ISDIR(dentry->d_inode->i_mode); int err; type = ovl_path_real(dentry, &realpath); Loading @@ -85,10 +86,11 @@ static int ovl_getattr(const struct path *path, struct kstat *stat, if (ovl_same_sb(dentry->d_sb)) { if (OVL_TYPE_ORIGIN(type)) { struct kstat lowerstat; u32 lowermask = STATX_INO | (!is_dir ? STATX_NLINK : 0); ovl_path_lower(dentry, &realpath); err = vfs_getattr(&realpath, &lowerstat, STATX_INO | STATX_NLINK, flags); lowermask, flags); if (err) goto out; Loading @@ -98,11 +100,32 @@ static int ovl_getattr(const struct path *path, struct kstat *stat, * upper files, so we cannot use the lower origin st_ino * for those different files, even for the same fs case. */ if (lowerstat.nlink == 1) if (is_dir || lowerstat.nlink == 1) stat->ino = lowerstat.ino; } stat->dev = dentry->d_sb->s_dev; } else if (is_dir) { /* * If not all layers are on the same fs the pair {real st_ino; * overlay st_dev} is not unique, so use the non persistent * overlay st_ino. * * Always use the overlay st_dev for directories, so 'find * -xdev' will scan the entire overlay mount and won't cross the * overlay mount boundaries. */ stat->dev = dentry->d_sb->s_dev; stat->ino = dentry->d_inode->i_ino; } /* * It's probably not worth it to count subdirs to get the * correct link count. nlink=1 seems to pacify 'find' and * other utilities. */ if (is_dir && OVL_TYPE_MERGE(type)) stat->nlink = 1; out: revert_creds(old_cred); Loading
fs/overlayfs/overlayfs.h +2 −0 Original line number Diff line number Diff line Loading @@ -236,6 +236,8 @@ void ovl_workdir_cleanup(struct inode *dir, struct vfsmount *mnt, /* inode.c */ int ovl_setattr(struct dentry *dentry, struct iattr *attr); int ovl_getattr(const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags); int ovl_permission(struct inode *inode, int mask); int ovl_xattr_set(struct dentry *dentry, const char *name, const void *value, size_t size, int flags); Loading