Commit 0f831ec8 authored by Amir Goldstein's avatar Amir Goldstein Committed by Miklos Szeredi

ovl: simplify ovl_same_sb() helper

No code uses the sb returned from this helper, so make it retrun a boolean
and rename it to ovl_same_fs().

The xino mode is irrelevant when all layers are on same fs, so instead of
describing samefs with mode OVL_XINO_OFF, use a new xino_mode state, which
is 0 in the case of samefs, -1 in the case of xino=off and > 0 with xino
enabled.

Create a new helper ovl_same_dev(), to use instead of the common check for
(ovl_same_fs() || xinobits).
Signed-off-by: default avatarAmir Goldstein <amir73il@gmail.com>
Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent 94375f9d
...@@ -78,7 +78,7 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr) ...@@ -78,7 +78,7 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
static int ovl_map_dev_ino(struct dentry *dentry, struct kstat *stat, static int ovl_map_dev_ino(struct dentry *dentry, struct kstat *stat,
struct ovl_layer *lower_layer) struct ovl_layer *lower_layer)
{ {
bool samefs = ovl_same_sb(dentry->d_sb); bool samefs = ovl_same_fs(dentry->d_sb);
unsigned int xinobits = ovl_xino_bits(dentry->d_sb); unsigned int xinobits = ovl_xino_bits(dentry->d_sb);
if (samefs) { if (samefs) {
...@@ -146,7 +146,7 @@ int ovl_getattr(const struct path *path, struct kstat *stat, ...@@ -146,7 +146,7 @@ int ovl_getattr(const struct path *path, struct kstat *stat,
struct path realpath; struct path realpath;
const struct cred *old_cred; const struct cred *old_cred;
bool is_dir = S_ISDIR(dentry->d_inode->i_mode); bool is_dir = S_ISDIR(dentry->d_inode->i_mode);
bool samefs = ovl_same_sb(dentry->d_sb); bool samefs = ovl_same_fs(dentry->d_sb);
struct ovl_layer *lower_layer = NULL; struct ovl_layer *lower_layer = NULL;
int err; int err;
bool metacopy_blocks = false; bool metacopy_blocks = false;
...@@ -168,7 +168,7 @@ int ovl_getattr(const struct path *path, struct kstat *stat, ...@@ -168,7 +168,7 @@ int ovl_getattr(const struct path *path, struct kstat *stat,
* If lower filesystem supports NFS file handles, this also guaranties * If lower filesystem supports NFS file handles, this also guaranties
* persistent st_ino across mount cycle. * persistent st_ino across mount cycle.
*/ */
if (!is_dir || samefs || ovl_xino_bits(dentry->d_sb)) { if (!is_dir || ovl_same_dev(dentry->d_sb)) {
if (!OVL_TYPE_UPPER(type)) { if (!OVL_TYPE_UPPER(type)) {
lower_layer = ovl_layer_lower(dentry); lower_layer = ovl_layer_lower(dentry);
} else if (OVL_TYPE_ORIGIN(type)) { } else if (OVL_TYPE_ORIGIN(type)) {
...@@ -586,7 +586,7 @@ static void ovl_fill_inode(struct inode *inode, umode_t mode, dev_t rdev, ...@@ -586,7 +586,7 @@ static void ovl_fill_inode(struct inode *inode, umode_t mode, dev_t rdev,
* ovl_new_inode(), ino arg is 0, so i_ino will be updated to real * ovl_new_inode(), ino arg is 0, so i_ino will be updated to real
* upper inode i_ino on ovl_inode_init() or ovl_inode_update(). * upper inode i_ino on ovl_inode_init() or ovl_inode_update().
*/ */
if (ovl_same_sb(inode->i_sb) || xinobits) { if (ovl_same_dev(inode->i_sb)) {
inode->i_ino = ino; inode->i_ino = ino;
if (xinobits && fsid && !(ino >> (64 - xinobits))) if (xinobits && fsid && !(ino >> (64 - xinobits)))
inode->i_ino |= (unsigned long)fsid << (64 - xinobits); inode->i_ino |= (unsigned long)fsid << (64 - xinobits);
......
...@@ -224,7 +224,6 @@ int ovl_want_write(struct dentry *dentry); ...@@ -224,7 +224,6 @@ int ovl_want_write(struct dentry *dentry);
void ovl_drop_write(struct dentry *dentry); void ovl_drop_write(struct dentry *dentry);
struct dentry *ovl_workdir(struct dentry *dentry); struct dentry *ovl_workdir(struct dentry *dentry);
const struct cred *ovl_override_creds(struct super_block *sb); const struct cred *ovl_override_creds(struct super_block *sb);
struct super_block *ovl_same_sb(struct super_block *sb);
int ovl_can_decode_fh(struct super_block *sb); int ovl_can_decode_fh(struct super_block *sb);
struct dentry *ovl_indexdir(struct super_block *sb); struct dentry *ovl_indexdir(struct super_block *sb);
bool ovl_index_all(struct super_block *sb); bool ovl_index_all(struct super_block *sb);
...@@ -302,11 +301,21 @@ static inline bool ovl_is_impuredir(struct dentry *dentry) ...@@ -302,11 +301,21 @@ static inline bool ovl_is_impuredir(struct dentry *dentry)
return ovl_check_dir_xattr(dentry, OVL_XATTR_IMPURE); return ovl_check_dir_xattr(dentry, OVL_XATTR_IMPURE);
} }
static inline unsigned int ovl_xino_bits(struct super_block *sb) /* All layers on same fs? */
static inline bool ovl_same_fs(struct super_block *sb)
{ {
struct ovl_fs *ofs = sb->s_fs_info; return OVL_FS(sb)->xino_mode == 0;
}
return ofs->xino_bits; /* All overlay inodes have same st_dev? */
static inline bool ovl_same_dev(struct super_block *sb)
{
return OVL_FS(sb)->xino_mode >= 0;
}
static inline unsigned int ovl_xino_bits(struct super_block *sb)
{
return ovl_same_dev(sb) ? OVL_FS(sb)->xino_mode : 0;
} }
static inline int ovl_inode_lock(struct inode *inode) static inline int ovl_inode_lock(struct inode *inode)
......
...@@ -71,10 +71,15 @@ struct ovl_fs { ...@@ -71,10 +71,15 @@ struct ovl_fs {
struct inode *workbasedir_trap; struct inode *workbasedir_trap;
struct inode *workdir_trap; struct inode *workdir_trap;
struct inode *indexdir_trap; struct inode *indexdir_trap;
/* Inode numbers in all layers do not use the high xino_bits */ /* -1: disabled, 0: same fs, 1..32: number of unused ino bits */
unsigned int xino_bits; int xino_mode;
}; };
static inline struct ovl_fs *OVL_FS(struct super_block *sb)
{
return (struct ovl_fs *)sb->s_fs_info;
}
/* private information held for every overlayfs dentry */ /* private information held for every overlayfs dentry */
struct ovl_entry { struct ovl_entry {
union { union {
......
...@@ -469,7 +469,7 @@ static int ovl_cache_update_ino(struct path *path, struct ovl_cache_entry *p) ...@@ -469,7 +469,7 @@ static int ovl_cache_update_ino(struct path *path, struct ovl_cache_entry *p)
int xinobits = ovl_xino_bits(dir->d_sb); int xinobits = ovl_xino_bits(dir->d_sb);
int err = 0; int err = 0;
if (!ovl_same_sb(dir->d_sb) && !xinobits) if (!ovl_same_dev(dir->d_sb))
goto out; goto out;
if (p->name[0] == '.') { if (p->name[0] == '.') {
...@@ -744,7 +744,7 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx) ...@@ -744,7 +744,7 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx)
* entries. * entries.
*/ */
if (ovl_xino_bits(dentry->d_sb) || if (ovl_xino_bits(dentry->d_sb) ||
(ovl_same_sb(dentry->d_sb) && (ovl_same_fs(dentry->d_sb) &&
(ovl_is_impure_dir(file) || (ovl_is_impure_dir(file) ||
OVL_TYPE_MERGE(ovl_path_type(dentry->d_parent))))) { OVL_TYPE_MERGE(ovl_path_type(dentry->d_parent))))) {
return ovl_iterate_real(file, ctx); return ovl_iterate_real(file, ctx);
......
...@@ -358,7 +358,7 @@ static int ovl_show_options(struct seq_file *m, struct dentry *dentry) ...@@ -358,7 +358,7 @@ static int ovl_show_options(struct seq_file *m, struct dentry *dentry)
if (ofs->config.nfs_export != ovl_nfs_export_def) if (ofs->config.nfs_export != ovl_nfs_export_def)
seq_printf(m, ",nfs_export=%s", ofs->config.nfs_export ? seq_printf(m, ",nfs_export=%s", ofs->config.nfs_export ?
"on" : "off"); "on" : "off");
if (ofs->config.xino != ovl_xino_def()) if (ofs->config.xino != ovl_xino_def() && !ovl_same_fs(sb))
seq_printf(m, ",xino=%s", ovl_xino_str[ofs->config.xino]); seq_printf(m, ",xino=%s", ovl_xino_str[ofs->config.xino]);
if (ofs->config.metacopy != ovl_metacopy_def) if (ofs->config.metacopy != ovl_metacopy_def)
seq_printf(m, ",metacopy=%s", seq_printf(m, ",metacopy=%s",
...@@ -811,7 +811,7 @@ static int ovl_lower_dir(const char *name, struct path *path, ...@@ -811,7 +811,7 @@ static int ovl_lower_dir(const char *name, struct path *path,
/* Check if lower fs has 32bit inode numbers */ /* Check if lower fs has 32bit inode numbers */
if (fh_type != FILEID_INO32_GEN) if (fh_type != FILEID_INO32_GEN)
ofs->xino_bits = 0; ofs->xino_mode = -1;
return 0; return 0;
...@@ -1142,7 +1142,7 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs, ...@@ -1142,7 +1142,7 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs,
/* Check if upper fs has 32bit inode numbers */ /* Check if upper fs has 32bit inode numbers */
if (fh_type != FILEID_INO32_GEN) if (fh_type != FILEID_INO32_GEN)
ofs->xino_bits = 0; ofs->xino_mode = -1;
/* NFS export of r/w mount depends on index */ /* NFS export of r/w mount depends on index */
if (ofs->config.nfs_export && !ofs->config.index) { if (ofs->config.nfs_export && !ofs->config.index) {
...@@ -1395,21 +1395,22 @@ static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs, ...@@ -1395,21 +1395,22 @@ static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs,
* inode number. * inode number.
*/ */
if (!ofs->numlowerfs || (ofs->numlowerfs == 1 && !ofs->upper_mnt)) { if (!ofs->numlowerfs || (ofs->numlowerfs == 1 && !ofs->upper_mnt)) {
ofs->xino_bits = 0; if (ofs->config.xino == OVL_XINO_ON)
ofs->config.xino = OVL_XINO_OFF; pr_info("\"xino=on\" is useless with all layers on same fs, ignore.\n");
} else if (ofs->config.xino == OVL_XINO_ON && !ofs->xino_bits) { ofs->xino_mode = 0;
} else if (ofs->config.xino == OVL_XINO_ON && ofs->xino_mode < 0) {
/* /*
* This is a roundup of number of bits needed for numlowerfs+1 * This is a roundup of number of bits needed for numlowerfs+1
* (i.e. ilog2(numlowerfs+1 - 1) + 1). fsid 0 is reserved for * (i.e. ilog2(numlowerfs+1 - 1) + 1). fsid 0 is reserved for
* upper fs even with non upper overlay. * upper fs even with non upper overlay.
*/ */
BUILD_BUG_ON(ilog2(OVL_MAX_STACK) > 31); BUILD_BUG_ON(ilog2(OVL_MAX_STACK) > 31);
ofs->xino_bits = ilog2(ofs->numlowerfs) + 1; ofs->xino_mode = ilog2(ofs->numlowerfs) + 1;
} }
if (ofs->xino_bits) { if (ofs->xino_mode > 0) {
pr_info("\"xino\" feature enabled using %d upper inode bits.\n", pr_info("\"xino\" feature enabled using %d upper inode bits.\n",
ofs->xino_bits); ofs->xino_mode);
} }
err = 0; err = 0;
...@@ -1610,7 +1611,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) ...@@ -1610,7 +1611,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
sb->s_maxbytes = MAX_LFS_FILESIZE; sb->s_maxbytes = MAX_LFS_FILESIZE;
/* Assume underlaying fs uses 32bit inodes unless proven otherwise */ /* Assume underlaying fs uses 32bit inodes unless proven otherwise */
if (ofs->config.xino != OVL_XINO_OFF) if (ofs->config.xino != OVL_XINO_OFF)
ofs->xino_bits = BITS_PER_LONG - 32; ofs->xino_mode = BITS_PER_LONG - 32;
/* alloc/destroy_inode needed for setting up traps in inode cache */ /* alloc/destroy_inode needed for setting up traps in inode cache */
sb->s_op = &ovl_super_operations; sb->s_op = &ovl_super_operations;
......
...@@ -40,18 +40,6 @@ const struct cred *ovl_override_creds(struct super_block *sb) ...@@ -40,18 +40,6 @@ const struct cred *ovl_override_creds(struct super_block *sb)
return override_creds(ofs->creator_cred); return override_creds(ofs->creator_cred);
} }
struct super_block *ovl_same_sb(struct super_block *sb)
{
struct ovl_fs *ofs = sb->s_fs_info;
if (!ofs->numlowerfs)
return ofs->upper_mnt->mnt_sb;
else if (ofs->numlowerfs == 1 && !ofs->upper_mnt)
return ofs->lower_fs[0].sb;
else
return NULL;
}
/* /*
* Check if underlying fs supports file handles and try to determine encoding * Check if underlying fs supports file handles and try to determine encoding
* type, in order to deduce maximum inode number used by fs. * type, in order to deduce maximum inode number used by fs.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment