ovl: avoid possible inode number collisions with xino=on
[sfrench/cifs-2.6.git] / fs / overlayfs / readdir.c
index 40ac9ce2465a4fc1f8eec6f7e97f9882d456f62c..6325dcc4c48bb996315936b933feed174dc4dbac 100644 (file)
@@ -440,13 +440,19 @@ static struct ovl_dir_cache *ovl_cache_get(struct dentry *dentry)
 static u64 ovl_remap_lower_ino(u64 ino, int xinobits, int fsid,
                               const char *name, int namelen)
 {
-       if (ino >> (64 - xinobits)) {
+       unsigned int xinoshift = 64 - xinobits;
+
+       if (unlikely(ino >> xinoshift)) {
                pr_warn_ratelimited("d_ino too big (%.*s, ino=%llu, xinobits=%d)\n",
                                    namelen, name, ino, xinobits);
                return ino;
        }
 
-       return ino | ((u64)fsid) << (64 - xinobits);
+       /*
+        * The lowest xinobit is reserved for mapping the non-peresistent inode
+        * numbers range, but this range is only exposed via st_ino, not here.
+        */
+       return ino | ((u64)fsid) << (xinoshift + 1);
 }
 
 /*