aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmir Goldstein <amir73il@gmail.com>2017-11-07 06:55:04 -0500
committerMiklos Szeredi <mszeredi@redhat.com>2018-04-12 06:04:50 -0400
commite487d889b7e3e8ec4091eb83bc4f7e67c7f05e27 (patch)
treebab0024b22cbfacdacc7892cdad93129101fe8bc
parent5148626b806a74dd219f2bce5f204abf909f6930 (diff)
ovl: constant st_ino for non-samefs with xino
On 64bit systems, when overlay layers are not all on the same fs, but all inode numbers of underlying fs are not using the high bits, use the high bits to partition the overlay st_ino address space. The high bits hold the fsid (upper fsid is 0). This way overlay inode numbers are unique and all inodes use overlay st_dev. Inode numbers are also persistent for a given layer configuration. Currently, our only indication for available high ino bits is from a filesystem that supports file handles and uses the default encode_fh() operation, which encodes a 32bit inode number. Signed-off-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
-rw-r--r--fs/overlayfs/inode.c31
-rw-r--r--fs/overlayfs/overlayfs.h9
-rw-r--r--fs/overlayfs/ovl_entry.h2
-rw-r--r--fs/overlayfs/super.c26
-rw-r--r--fs/overlayfs/util.c17
5 files changed, 75 insertions, 10 deletions
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index cfccd91c51e3..51d780898d89 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -63,6 +63,7 @@ static int ovl_map_dev_ino(struct dentry *dentry, struct kstat *stat,
63 struct ovl_layer *lower_layer) 63 struct ovl_layer *lower_layer)
64{ 64{
65 bool samefs = ovl_same_sb(dentry->d_sb); 65 bool samefs = ovl_same_sb(dentry->d_sb);
66 unsigned int xinobits = ovl_xino_bits(dentry->d_sb);
66 67
67 if (samefs) { 68 if (samefs) {
68 /* 69 /*
@@ -71,7 +72,31 @@ static int ovl_map_dev_ino(struct dentry *dentry, struct kstat *stat,
71 * which is friendly to du -x. 72 * which is friendly to du -x.
72 */ 73 */
73 stat->dev = dentry->d_sb->s_dev; 74 stat->dev = dentry->d_sb->s_dev;
74 } else if (S_ISDIR(dentry->d_inode->i_mode)) { 75 return 0;
76 } else if (xinobits) {
77 unsigned int shift = 64 - xinobits;
78 /*
79 * All inode numbers of underlying fs should not be using the
80 * high xinobits, so we use high xinobits to partition the
81 * overlay st_ino address space. The high bits holds the fsid
82 * (upper fsid is 0). This way overlay inode numbers are unique
83 * and all inodes use overlay st_dev. Inode numbers are also
84 * persistent for a given layer configuration.
85 */
86 if (stat->ino >> shift) {
87 pr_warn_ratelimited("overlayfs: inode number too big (%pd2, ino=%llu, xinobits=%d)\n",
88 dentry, stat->ino, xinobits);
89 } else {
90 if (lower_layer)
91 stat->ino |= ((u64)lower_layer->fsid) << shift;
92
93 stat->dev = dentry->d_sb->s_dev;
94 return 0;
95 }
96 }
97
98 /* The inode could not be mapped to a unified st_ino address space */
99 if (S_ISDIR(dentry->d_inode->i_mode)) {
75 /* 100 /*
76 * Always use the overlay st_dev for directories, so 'find 101 * Always use the overlay st_dev for directories, so 'find
77 * -xdev' will scan the entire overlay mount and won't cross the 102 * -xdev' will scan the entire overlay mount and won't cross the
@@ -118,11 +143,13 @@ int ovl_getattr(const struct path *path, struct kstat *stat,
118 /* 143 /*
119 * For non-dir or same fs, we use st_ino of the copy up origin. 144 * For non-dir or same fs, we use st_ino of the copy up origin.
120 * This guaranties constant st_dev/st_ino across copy up. 145 * This guaranties constant st_dev/st_ino across copy up.
146 * With xino feature and non-samefs, we use st_ino of the copy up
147 * origin masked with high bits that represent the layer id.
121 * 148 *
122 * If lower filesystem supports NFS file handles, this also guaranties 149 * If lower filesystem supports NFS file handles, this also guaranties
123 * persistent st_ino across mount cycle. 150 * persistent st_ino across mount cycle.
124 */ 151 */
125 if (!is_dir || samefs) { 152 if (!is_dir || samefs || ovl_xino_bits(dentry->d_sb)) {
126 if (!OVL_TYPE_UPPER(type)) { 153 if (!OVL_TYPE_UPPER(type)) {
127 lower_layer = ovl_layer_lower(dentry); 154 lower_layer = ovl_layer_lower(dentry);
128 } else if (OVL_TYPE_ORIGIN(type)) { 155 } else if (OVL_TYPE_ORIGIN(type)) {
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index 09779f9111a8..8eefc309aeb6 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -202,7 +202,7 @@ void ovl_drop_write(struct dentry *dentry);
202struct dentry *ovl_workdir(struct dentry *dentry); 202struct dentry *ovl_workdir(struct dentry *dentry);
203const struct cred *ovl_override_creds(struct super_block *sb); 203const struct cred *ovl_override_creds(struct super_block *sb);
204struct super_block *ovl_same_sb(struct super_block *sb); 204struct super_block *ovl_same_sb(struct super_block *sb);
205bool ovl_can_decode_fh(struct super_block *sb); 205int ovl_can_decode_fh(struct super_block *sb);
206struct dentry *ovl_indexdir(struct super_block *sb); 206struct dentry *ovl_indexdir(struct super_block *sb);
207bool ovl_index_all(struct super_block *sb); 207bool ovl_index_all(struct super_block *sb);
208bool ovl_verify_lower(struct super_block *sb); 208bool ovl_verify_lower(struct super_block *sb);
@@ -264,6 +264,13 @@ static inline bool ovl_is_impuredir(struct dentry *dentry)
264 return ovl_check_dir_xattr(dentry, OVL_XATTR_IMPURE); 264 return ovl_check_dir_xattr(dentry, OVL_XATTR_IMPURE);
265} 265}
266 266
267static inline unsigned int ovl_xino_bits(struct super_block *sb)
268{
269 struct ovl_fs *ofs = sb->s_fs_info;
270
271 return ofs->xino_bits;
272}
273
267 274
268/* namei.c */ 275/* namei.c */
269int ovl_check_fh_len(struct ovl_fh *fh, int fh_len); 276int ovl_check_fh_len(struct ovl_fh *fh, int fh_len);
diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h
index e1c838c27a74..620bd20f9a22 100644
--- a/fs/overlayfs/ovl_entry.h
+++ b/fs/overlayfs/ovl_entry.h
@@ -63,6 +63,8 @@ struct ovl_fs {
63 /* Did we take the inuse lock? */ 63 /* Did we take the inuse lock? */
64 bool upperdir_locked; 64 bool upperdir_locked;
65 bool workdir_locked; 65 bool workdir_locked;
66 /* Inode numbers in all layers do not use the high xino_bits */
67 unsigned int xino_bits;
66}; 68};
67 69
68/* private information held for every overlayfs dentry */ 70/* private information held for every overlayfs dentry */
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 7d97d30cad39..d7284444f404 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -17,6 +17,7 @@
17#include <linux/statfs.h> 17#include <linux/statfs.h>
18#include <linux/seq_file.h> 18#include <linux/seq_file.h>
19#include <linux/posix_acl_xattr.h> 19#include <linux/posix_acl_xattr.h>
20#include <linux/exportfs.h>
20#include "overlayfs.h" 21#include "overlayfs.h"
21 22
22MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>"); 23MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>");
@@ -701,6 +702,7 @@ static int ovl_check_namelen(struct path *path, struct ovl_fs *ofs,
701static int ovl_lower_dir(const char *name, struct path *path, 702static int ovl_lower_dir(const char *name, struct path *path,
702 struct ovl_fs *ofs, int *stack_depth, bool *remote) 703 struct ovl_fs *ofs, int *stack_depth, bool *remote)
703{ 704{
705 int fh_type;
704 int err; 706 int err;
705 707
706 err = ovl_mount_dir_noesc(name, path); 708 err = ovl_mount_dir_noesc(name, path);
@@ -720,15 +722,19 @@ static int ovl_lower_dir(const char *name, struct path *path,
720 * The inodes index feature and NFS export need to encode and decode 722 * The inodes index feature and NFS export need to encode and decode
721 * file handles, so they require that all layers support them. 723 * file handles, so they require that all layers support them.
722 */ 724 */
725 fh_type = ovl_can_decode_fh(path->dentry->d_sb);
723 if ((ofs->config.nfs_export || 726 if ((ofs->config.nfs_export ||
724 (ofs->config.index && ofs->config.upperdir)) && 727 (ofs->config.index && ofs->config.upperdir)) && !fh_type) {
725 !ovl_can_decode_fh(path->dentry->d_sb)) {
726 ofs->config.index = false; 728 ofs->config.index = false;
727 ofs->config.nfs_export = false; 729 ofs->config.nfs_export = false;
728 pr_warn("overlayfs: fs on '%s' does not support file handles, falling back to index=off,nfs_export=off.\n", 730 pr_warn("overlayfs: fs on '%s' does not support file handles, falling back to index=off,nfs_export=off.\n",
729 name); 731 name);
730 } 732 }
731 733
734 /* Check if lower fs has 32bit inode numbers */
735 if (fh_type != FILEID_INO32_GEN)
736 ofs->xino_bits = 0;
737
732 return 0; 738 return 0;
733 739
734out_put: 740out_put:
@@ -952,6 +958,7 @@ static int ovl_make_workdir(struct ovl_fs *ofs, struct path *workpath)
952{ 958{
953 struct vfsmount *mnt = ofs->upper_mnt; 959 struct vfsmount *mnt = ofs->upper_mnt;
954 struct dentry *temp; 960 struct dentry *temp;
961 int fh_type;
955 int err; 962 int err;
956 963
957 err = mnt_want_write(mnt); 964 err = mnt_want_write(mnt);
@@ -1001,12 +1008,16 @@ static int ovl_make_workdir(struct ovl_fs *ofs, struct path *workpath)
1001 } 1008 }
1002 1009
1003 /* Check if upper/work fs supports file handles */ 1010 /* Check if upper/work fs supports file handles */
1004 if (ofs->config.index && 1011 fh_type = ovl_can_decode_fh(ofs->workdir->d_sb);
1005 !ovl_can_decode_fh(ofs->workdir->d_sb)) { 1012 if (ofs->config.index && !fh_type) {
1006 ofs->config.index = false; 1013 ofs->config.index = false;
1007 pr_warn("overlayfs: upper fs does not support file handles, falling back to index=off.\n"); 1014 pr_warn("overlayfs: upper fs does not support file handles, falling back to index=off.\n");
1008 } 1015 }
1009 1016
1017 /* Check if upper fs has 32bit inode numbers */
1018 if (fh_type != FILEID_INO32_GEN)
1019 ofs->xino_bits = 0;
1020
1010 /* NFS export of r/w mount depends on index */ 1021 /* NFS export of r/w mount depends on index */
1011 if (ofs->config.nfs_export && !ofs->config.index) { 1022 if (ofs->config.nfs_export && !ofs->config.index) {
1012 pr_warn("overlayfs: NFS export requires \"index=on\", falling back to nfs_export=off.\n"); 1023 pr_warn("overlayfs: NFS export requires \"index=on\", falling back to nfs_export=off.\n");
@@ -1185,6 +1196,11 @@ static int ovl_get_lower_layers(struct ovl_fs *ofs, struct path *stack,
1185 } 1196 }
1186 ofs->numlower++; 1197 ofs->numlower++;
1187 } 1198 }
1199
1200 /* When all layers on same fs, overlay can use real inode numbers */
1201 if (!ofs->numlowerfs || (ofs->numlowerfs == 1 && !ofs->upper_mnt))
1202 ofs->xino_bits = 0;
1203
1188 err = 0; 1204 err = 0;
1189out: 1205out:
1190 return err; 1206 return err;
@@ -1308,6 +1324,8 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
1308 1324
1309 sb->s_stack_depth = 0; 1325 sb->s_stack_depth = 0;
1310 sb->s_maxbytes = MAX_LFS_FILESIZE; 1326 sb->s_maxbytes = MAX_LFS_FILESIZE;
1327 /* Assume underlaying fs uses 32bit inodes unless proven otherwise */
1328 ofs->xino_bits = BITS_PER_LONG - 32;
1311 if (ofs->config.upperdir) { 1329 if (ofs->config.upperdir) {
1312 if (!ofs->config.workdir) { 1330 if (!ofs->config.workdir) {
1313 pr_err("overlayfs: missing 'workdir'\n"); 1331 pr_err("overlayfs: missing 'workdir'\n");
diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
index 9dfec74ec77d..6f1078028c66 100644
--- a/fs/overlayfs/util.c
+++ b/fs/overlayfs/util.c
@@ -55,10 +55,21 @@ struct super_block *ovl_same_sb(struct super_block *sb)
55 return NULL; 55 return NULL;
56} 56}
57 57
58bool ovl_can_decode_fh(struct super_block *sb) 58/*
59 * Check if underlying fs supports file handles and try to determine encoding
60 * type, in order to deduce maximum inode number used by fs.
61 *
62 * Return 0 if file handles are not supported.
63 * Return 1 (FILEID_INO32_GEN) if fs uses the default 32bit inode encoding.
64 * Return -1 if fs uses a non default encoding with unknown inode size.
65 */
66int ovl_can_decode_fh(struct super_block *sb)
59{ 67{
60 return (sb->s_export_op && sb->s_export_op->fh_to_dentry && 68 if (!sb->s_export_op || !sb->s_export_op->fh_to_dentry ||
61 !uuid_is_null(&sb->s_uuid)); 69 uuid_is_null(&sb->s_uuid))
70 return 0;
71
72 return sb->s_export_op->encode_fh ? -1 : FILEID_INO32_GEN;
62} 73}
63 74
64struct dentry *ovl_indexdir(struct super_block *sb) 75struct dentry *ovl_indexdir(struct super_block *sb)