Commit dcb399de authored by Amir Goldstein's avatar Amir Goldstein

ovl: pass ovl_fs to xino helpers

Internal ovl methods should use ovl_fs and not sb as much as
possible.

Use a constant_table to translate from enum xino mode to string
in preperation for new mount api option parsing.
Signed-off-by: default avatarAmir Goldstein <amir73il@gmail.com>
parent 367d002d
...@@ -97,8 +97,9 @@ int ovl_setattr(struct mnt_idmap *idmap, struct dentry *dentry, ...@@ -97,8 +97,9 @@ int ovl_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
static void ovl_map_dev_ino(struct dentry *dentry, struct kstat *stat, int fsid) static void ovl_map_dev_ino(struct dentry *dentry, struct kstat *stat, int fsid)
{ {
bool samefs = ovl_same_fs(dentry->d_sb); struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
unsigned int xinobits = ovl_xino_bits(dentry->d_sb); bool samefs = ovl_same_fs(ofs);
unsigned int xinobits = ovl_xino_bits(ofs);
unsigned int xinoshift = 64 - xinobits; unsigned int xinoshift = 64 - xinobits;
if (samefs) { if (samefs) {
...@@ -123,7 +124,7 @@ static void ovl_map_dev_ino(struct dentry *dentry, struct kstat *stat, int fsid) ...@@ -123,7 +124,7 @@ static void ovl_map_dev_ino(struct dentry *dentry, struct kstat *stat, int fsid)
stat->ino |= ((u64)fsid) << (xinoshift + 1); stat->ino |= ((u64)fsid) << (xinoshift + 1);
stat->dev = dentry->d_sb->s_dev; stat->dev = dentry->d_sb->s_dev;
return; return;
} else if (ovl_xino_warn(dentry->d_sb)) { } else if (ovl_xino_warn(ofs)) {
pr_warn_ratelimited("inode number too big (%pd2, ino=%llu, xinobits=%d)\n", pr_warn_ratelimited("inode number too big (%pd2, ino=%llu, xinobits=%d)\n",
dentry, stat->ino, xinobits); dentry, stat->ino, xinobits);
} }
...@@ -149,7 +150,7 @@ static void ovl_map_dev_ino(struct dentry *dentry, struct kstat *stat, int fsid) ...@@ -149,7 +150,7 @@ static void ovl_map_dev_ino(struct dentry *dentry, struct kstat *stat, int fsid)
* is unique per underlying fs, so we use the unique anonymous * is unique per underlying fs, so we use the unique anonymous
* bdev assigned to the underlying fs. * bdev assigned to the underlying fs.
*/ */
stat->dev = OVL_FS(dentry->d_sb)->fs[fsid].pseudo_dev; stat->dev = ofs->fs[fsid].pseudo_dev;
} }
} }
...@@ -186,7 +187,7 @@ int ovl_getattr(struct mnt_idmap *idmap, const struct path *path, ...@@ -186,7 +187,7 @@ int ovl_getattr(struct mnt_idmap *idmap, const struct path *path,
* 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 || ovl_same_dev(dentry->d_sb)) { if (!is_dir || ovl_same_dev(OVL_FS(dentry->d_sb))) {
if (!OVL_TYPE_UPPER(type)) { if (!OVL_TYPE_UPPER(type)) {
fsid = ovl_layer_lower(dentry)->fsid; fsid = ovl_layer_lower(dentry)->fsid;
} else if (OVL_TYPE_ORIGIN(type)) { } else if (OVL_TYPE_ORIGIN(type)) {
...@@ -961,7 +962,7 @@ static inline void ovl_lockdep_annotate_inode_mutex_key(struct inode *inode) ...@@ -961,7 +962,7 @@ static inline void ovl_lockdep_annotate_inode_mutex_key(struct inode *inode)
static void ovl_next_ino(struct inode *inode) static void ovl_next_ino(struct inode *inode)
{ {
struct ovl_fs *ofs = inode->i_sb->s_fs_info; struct ovl_fs *ofs = OVL_FS(inode->i_sb);
inode->i_ino = atomic_long_inc_return(&ofs->last_ino); inode->i_ino = atomic_long_inc_return(&ofs->last_ino);
if (unlikely(!inode->i_ino)) if (unlikely(!inode->i_ino))
...@@ -970,7 +971,8 @@ static void ovl_next_ino(struct inode *inode) ...@@ -970,7 +971,8 @@ static void ovl_next_ino(struct inode *inode)
static void ovl_map_ino(struct inode *inode, unsigned long ino, int fsid) static void ovl_map_ino(struct inode *inode, unsigned long ino, int fsid)
{ {
int xinobits = ovl_xino_bits(inode->i_sb); struct ovl_fs *ofs = OVL_FS(inode->i_sb);
int xinobits = ovl_xino_bits(ofs);
unsigned int xinoshift = 64 - xinobits; unsigned int xinoshift = 64 - xinobits;
/* /*
...@@ -981,7 +983,7 @@ static void ovl_map_ino(struct inode *inode, unsigned long ino, int fsid) ...@@ -981,7 +983,7 @@ static void ovl_map_ino(struct inode *inode, unsigned long ino, int fsid)
* with d_ino also causes nfsd readdirplus to fail. * with d_ino also causes nfsd readdirplus to fail.
*/ */
inode->i_ino = ino; inode->i_ino = ino;
if (ovl_same_fs(inode->i_sb)) { if (ovl_same_fs(ofs)) {
return; return;
} else if (xinobits && likely(!(ino >> xinoshift))) { } else if (xinobits && likely(!(ino >> xinoshift))) {
inode->i_ino |= (unsigned long)fsid << (xinoshift + 1); inode->i_ino |= (unsigned long)fsid << (xinoshift + 1);
......
...@@ -494,26 +494,26 @@ static inline bool ovl_is_impuredir(struct super_block *sb, ...@@ -494,26 +494,26 @@ static inline bool ovl_is_impuredir(struct super_block *sb,
* d_ino consistent with st_ino. * d_ino consistent with st_ino.
* With xino=on, we do the same effort but we warn if we failed. * With xino=on, we do the same effort but we warn if we failed.
*/ */
static inline bool ovl_xino_warn(struct super_block *sb) static inline bool ovl_xino_warn(struct ovl_fs *ofs)
{ {
return OVL_FS(sb)->config.xino == OVL_XINO_ON; return ofs->config.xino == OVL_XINO_ON;
} }
/* All layers on same fs? */ /* All layers on same fs? */
static inline bool ovl_same_fs(struct super_block *sb) static inline bool ovl_same_fs(struct ovl_fs *ofs)
{ {
return OVL_FS(sb)->xino_mode == 0; return ofs->xino_mode == 0;
} }
/* All overlay inodes have same st_dev? */ /* All overlay inodes have same st_dev? */
static inline bool ovl_same_dev(struct super_block *sb) static inline bool ovl_same_dev(struct ovl_fs *ofs)
{ {
return OVL_FS(sb)->xino_mode >= 0; return ofs->xino_mode >= 0;
} }
static inline unsigned int ovl_xino_bits(struct super_block *sb) static inline unsigned int ovl_xino_bits(struct ovl_fs *ofs)
{ {
return ovl_same_dev(sb) ? OVL_FS(sb)->xino_mode : 0; return ovl_same_dev(ofs) ? ofs->xino_mode : 0;
} }
static inline void ovl_inode_lock(struct inode *inode) static inline void ovl_inode_lock(struct inode *inode)
......
...@@ -118,7 +118,7 @@ static bool ovl_calc_d_ino(struct ovl_readdir_data *rdd, ...@@ -118,7 +118,7 @@ static bool ovl_calc_d_ino(struct ovl_readdir_data *rdd,
return false; return false;
/* Always recalc d_ino when remapping lower inode numbers */ /* Always recalc d_ino when remapping lower inode numbers */
if (ovl_xino_bits(rdd->dentry->d_sb)) if (ovl_xino_bits(OVL_FS(rdd->dentry->d_sb)))
return true; return true;
/* Always recalc d_ino for parent */ /* Always recalc d_ino for parent */
...@@ -460,13 +460,14 @@ static int ovl_cache_update_ino(const struct path *path, struct ovl_cache_entry ...@@ -460,13 +460,14 @@ static int ovl_cache_update_ino(const struct path *path, struct ovl_cache_entry
{ {
struct dentry *dir = path->dentry; struct dentry *dir = path->dentry;
struct ovl_fs *ofs = OVL_FS(dir->d_sb);
struct dentry *this = NULL; struct dentry *this = NULL;
enum ovl_path_type type; enum ovl_path_type type;
u64 ino = p->real_ino; u64 ino = p->real_ino;
int xinobits = ovl_xino_bits(dir->d_sb); int xinobits = ovl_xino_bits(ofs);
int err = 0; int err = 0;
if (!ovl_same_dev(dir->d_sb)) if (!ovl_same_dev(ofs))
goto out; goto out;
if (p->name[0] == '.') { if (p->name[0] == '.') {
...@@ -515,7 +516,7 @@ static int ovl_cache_update_ino(const struct path *path, struct ovl_cache_entry ...@@ -515,7 +516,7 @@ static int ovl_cache_update_ino(const struct path *path, struct ovl_cache_entry
ino = ovl_remap_lower_ino(ino, xinobits, ino = ovl_remap_lower_ino(ino, xinobits,
ovl_layer_lower(this)->fsid, ovl_layer_lower(this)->fsid,
p->name, p->len, p->name, p->len,
ovl_xino_warn(dir->d_sb)); ovl_xino_warn(ofs));
} }
out: out:
...@@ -694,12 +695,13 @@ static int ovl_iterate_real(struct file *file, struct dir_context *ctx) ...@@ -694,12 +695,13 @@ static int ovl_iterate_real(struct file *file, struct dir_context *ctx)
int err; int err;
struct ovl_dir_file *od = file->private_data; struct ovl_dir_file *od = file->private_data;
struct dentry *dir = file->f_path.dentry; struct dentry *dir = file->f_path.dentry;
struct ovl_fs *ofs = OVL_FS(dir->d_sb);
const struct ovl_layer *lower_layer = ovl_layer_lower(dir); const struct ovl_layer *lower_layer = ovl_layer_lower(dir);
struct ovl_readdir_translate rdt = { struct ovl_readdir_translate rdt = {
.ctx.actor = ovl_fill_real, .ctx.actor = ovl_fill_real,
.orig_ctx = ctx, .orig_ctx = ctx,
.xinobits = ovl_xino_bits(dir->d_sb), .xinobits = ovl_xino_bits(ofs),
.xinowarn = ovl_xino_warn(dir->d_sb), .xinowarn = ovl_xino_warn(ofs),
}; };
if (rdt.xinobits && lower_layer) if (rdt.xinobits && lower_layer)
...@@ -735,6 +737,7 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx) ...@@ -735,6 +737,7 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx)
{ {
struct ovl_dir_file *od = file->private_data; struct ovl_dir_file *od = file->private_data;
struct dentry *dentry = file->f_path.dentry; struct dentry *dentry = file->f_path.dentry;
struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
struct ovl_cache_entry *p; struct ovl_cache_entry *p;
const struct cred *old_cred; const struct cred *old_cred;
int err; int err;
...@@ -749,8 +752,8 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx) ...@@ -749,8 +752,8 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx)
* dir is impure then need to adjust d_ino for copied up * dir is impure then need to adjust d_ino for copied up
* entries. * entries.
*/ */
if (ovl_xino_bits(dentry->d_sb) || if (ovl_xino_bits(ofs) ||
(ovl_same_fs(dentry->d_sb) && (ovl_same_fs(ofs) &&
(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))))) {
err = ovl_iterate_real(file, ctx); err = ovl_iterate_real(file, ctx);
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/posix_acl_xattr.h> #include <linux/posix_acl_xattr.h>
#include <linux/exportfs.h> #include <linux/exportfs.h>
#include <linux/file.h> #include <linux/file.h>
#include <linux/fs_parser.h>
#include "overlayfs.h" #include "overlayfs.h"
MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>"); MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>");
...@@ -334,12 +335,18 @@ static const char *ovl_redirect_mode_def(void) ...@@ -334,12 +335,18 @@ static const char *ovl_redirect_mode_def(void)
return ovl_redirect_dir_def ? "on" : "off"; return ovl_redirect_dir_def ? "on" : "off";
} }
static const char * const ovl_xino_str[] = { static const struct constant_table ovl_parameter_xino[] = {
"off", { "off", OVL_XINO_OFF },
"auto", { "auto", OVL_XINO_AUTO },
"on", { "on", OVL_XINO_ON },
{}
}; };
static const char *ovl_xino_mode(struct ovl_config *config)
{
return ovl_parameter_xino[config->xino].name;
}
static inline int ovl_xino_def(void) static inline int ovl_xino_def(void)
{ {
return ovl_xino_auto_def ? OVL_XINO_AUTO : OVL_XINO_OFF; return ovl_xino_auto_def ? OVL_XINO_AUTO : OVL_XINO_OFF;
...@@ -374,8 +381,8 @@ static int ovl_show_options(struct seq_file *m, struct dentry *dentry) ...@@ -374,8 +381,8 @@ 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() && !ovl_same_fs(sb)) if (ofs->config.xino != ovl_xino_def() && !ovl_same_fs(ofs))
seq_printf(m, ",xino=%s", ovl_xino_str[ofs->config.xino]); seq_printf(m, ",xino=%s", ovl_xino_mode(&ofs->config));
if (ofs->config.metacopy != ovl_metacopy_def) if (ofs->config.metacopy != ovl_metacopy_def)
seq_printf(m, ",metacopy=%s", seq_printf(m, ",metacopy=%s",
ofs->config.metacopy ? "on" : "off"); ofs->config.metacopy ? "on" : "off");
...@@ -1566,7 +1573,7 @@ static int ovl_get_fsid(struct ovl_fs *ofs, const struct path *path) ...@@ -1566,7 +1573,7 @@ static int ovl_get_fsid(struct ovl_fs *ofs, const struct path *path)
pr_warn("%s uuid detected in lower fs '%pd2', falling back to xino=%s,index=off,nfs_export=off.\n", pr_warn("%s uuid detected in lower fs '%pd2', falling back to xino=%s,index=off,nfs_export=off.\n",
uuid_is_null(&sb->s_uuid) ? "null" : uuid_is_null(&sb->s_uuid) ? "null" :
"conflicting", "conflicting",
path->dentry, ovl_xino_str[ofs->config.xino]); path->dentry, ovl_xino_mode(&ofs->config));
} }
} }
......
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