Whamcloud - gitweb
LU-16831 lod: replace (__u16)-1 with LOV_ALL_STRIPES
[fs/lustre-release.git] / lustre / include / uapi / linux / lustre / lustre_fid.h
index 0cf7c17..43787e3 100644 (file)
 #define _UAPI_LUSTRE_FID_H_
 
 #include <linux/types.h>
-/*
- * This is due to us being out of kernel and the way the OpenSFS branch
- * handles CFLAGS.
- */
-#ifdef __KERNEL__
-# include <uapi/linux/lustre/lustre_idl.h>
-#else
-# include <linux/lustre/lustre_idl.h>
-#endif
+#include <linux/lustre/lustre_idl.h>
 
 /** returns fid object sequence */
 static inline __u64 fid_seq(const struct lu_fid *fid)
@@ -286,7 +278,7 @@ static inline bool fid_is_last_id(const struct lu_fid *fid)
  * \param fid an igif to get inode number from.
  * \return inode number for the igif.
  */
-static inline ino_t lu_igif_ino(const struct lu_fid *fid)
+static inline __kernel_ino_t lu_igif_ino(const struct lu_fid *fid)
 {
        return fid_seq(fid);
 }
@@ -369,4 +361,69 @@ static inline int lu_fid_cmp(const struct lu_fid *f0,
 
        return 0;
 }
+
+/**
+ * Flatten 128-bit FID values into a 64-bit value for use as an inode number.
+ * For non-IGIF FIDs this starts just over 2^32, and continues without
+ * conflict until 2^64, at which point we wrap the high 24 bits of the SEQ
+ * into the range where there may not be many OID values in use, to minimize
+ * the risk of conflict.
+ *
+ * Suppose LUSTRE_SEQ_MAX_WIDTH less than (1 << 24) which is currently true,
+ * the time between re-used inode numbers is very long - 2^40 SEQ numbers,
+ * or about 2^40 client mounts, if clients create less than 2^24 files/mount.
+ */
+static inline __u64 fid_flatten64(const struct lu_fid *fid)
+{
+       __u64 ino;
+       __u64 seq;
+
+       if (fid_is_igif(fid)) {
+               ino = lu_igif_ino(fid);
+               return ino;
+       }
+
+       seq = fid_seq(fid);
+
+       ino = (seq << 24) + ((seq >> 24) & 0xffffff0000ULL) + fid_oid(fid);
+
+       return ino ?: fid_oid(fid);
+}
+
+/**
+ * map fid to 32 bit value for ino on 32bit systems.
+ */
+static inline __u32 fid_flatten32(const struct lu_fid *fid)
+{
+       __u32 ino;
+       __u64 seq;
+
+       if (fid_is_igif(fid)) {
+               ino = lu_igif_ino(fid);
+               return ino;
+       }
+
+       seq = fid_seq(fid) - FID_SEQ_START;
+
+       /* Map the high bits of the OID into higher bits of the inode number so
+        * that inodes generated at about the same time have a reduced chance
+        * of collisions. This will give a period of 2^12 = 1024 unique clients
+        * (from SEQ) and up to min(LUSTRE_SEQ_MAX_WIDTH, 2^20) = 128k objects
+        * (from OID), or up to 128M inodes without collisions for new files.
+        */
+       ino = ((seq & 0x000fffffULL) << 12) + ((seq >> 8) & 0xfffff000) +
+             (seq >> (64 - (40-8)) & 0xffffff00) +
+             (fid_oid(fid) & 0xff000fff) + ((fid_oid(fid) & 0x00fff000) << 8);
+
+       return ino ?: fid_oid(fid);
+}
+
+#if __BITS_PER_LONG == 32
+#define fid_flatten_long fid_flatten32
+#elif __BITS_PER_LONG == 64
+#define fid_flatten_long fid_flatten64
+#else
+#error "Wordsize not 32 or 64"
+#endif
+
 #endif