summaryrefslogtreecommitdiffstats
path: root/fs/overlayfs/util.c
diff options
context:
space:
mode:
authorAmir Goldstein <amir73il@gmail.com>2017-11-07 12:55:04 +0100
committerMiklos Szeredi <mszeredi@redhat.com>2018-04-12 12:04:50 +0200
commite487d889b7e3e8ec4091eb83bc4f7e67c7f05e27 (patch)
treebab0024b22cbfacdacc7892cdad93129101fe8bc /fs/overlayfs/util.c
parentovl: allocate anon bdev per unique lower fs (diff)
downloadlinux-e487d889b7e3e8ec4091eb83bc4f7e67c7f05e27.tar.xz
linux-e487d889b7e3e8ec4091eb83bc4f7e67c7f05e27.zip
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>
Diffstat (limited to 'fs/overlayfs/util.c')
-rw-r--r--fs/overlayfs/util.c17
1 files changed, 14 insertions, 3 deletions
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)
return NULL;
}
-bool ovl_can_decode_fh(struct super_block *sb)
+/*
+ * Check if underlying fs supports file handles and try to determine encoding
+ * type, in order to deduce maximum inode number used by fs.
+ *
+ * Return 0 if file handles are not supported.
+ * Return 1 (FILEID_INO32_GEN) if fs uses the default 32bit inode encoding.
+ * Return -1 if fs uses a non default encoding with unknown inode size.
+ */
+int ovl_can_decode_fh(struct super_block *sb)
{
- return (sb->s_export_op && sb->s_export_op->fh_to_dentry &&
- !uuid_is_null(&sb->s_uuid));
+ if (!sb->s_export_op || !sb->s_export_op->fh_to_dentry ||
+ uuid_is_null(&sb->s_uuid))
+ return 0;
+
+ return sb->s_export_op->encode_fh ? -1 : FILEID_INO32_GEN;
}
struct dentry *ovl_indexdir(struct super_block *sb)