int cl_local_size(struct inode *inode);
__u16 ll_dirent_type_get(struct lu_dirent *ent);
-ino_t cl_fid_build_ino(const struct lu_fid *fid);
+__u64 cl_fid_build_ino(const struct lu_fid *fid);
+__u32 cl_fid_build_ino32(const struct lu_fid *fid);
__u32 cl_fid_build_gen(const struct lu_fid *fid);
#ifdef INVARIANT_CHECK
#define to_kdev_t(dev) (dev)
#define kdev_t_to_nr(dev) (dev)
#define val_to_kdev(dev) (dev)
-#define ILOOKUP(sb, ino, test, data) ilookup5(sb, ino, test, (void *)(data));
#ifdef HAVE_BLKDEV_PUT_2ARGS
#define ll_blkdev_put(a, b) blkdev_put(a, b)
enum {
/*
- * This is how may FIDs may be allocated in one sequence. 16384 for
- * now.
+ * This is how may FIDs may be allocated in one sequence(128k)
*/
- LUSTRE_SEQ_MAX_WIDTH = 0x0000000000000400ULL,
+ LUSTRE_SEQ_MAX_WIDTH = 0x0000000000020000ULL,
/*
- * How many sequences may be allocate for meta-sequence (this is 128
- * sequences).
+ * How many sequences to allocate to a client at once.
*/
- /* changed to 16 to avoid overflow in test11 */
- LUSTRE_SEQ_META_WIDTH = 0x0000000000000010ULL,
+ LUSTRE_SEQ_META_WIDTH = 0x0000000000000001ULL,
/*
* seq allocation pool size.
return name;
}
+
+/**
+ * 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 32 bits
+ * of the SEQ into the range where there may not be many
+ * OID values in use, to minimize the risk of conflict.
+ *
+ * The time between re-used inode numbers is very long -
+ * 2^32 SEQ numbers, or about 2^32 client mounts. */
static inline __u64 fid_flatten(const struct lu_fid *fid)
{
- return (fid_seq(fid) - 1) * LUSTRE_SEQ_MAX_WIDTH + fid_oid(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 >> (64-8)) & 0xffffff0000ULL) + fid_oid(fid);
+
+ RETURN(ino ? 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 1024 clients and 128 k = 128M inodes without collisions.
+ */
+
+ ino = ((seq & 0x000fffffULL) << 12) + ((seq >> 8) & 0xfffff000) +
+ (seq >> (64 - (40-8)) & 0xffffff00) +
+ (fid_oid(fid) & 0xff000fff) + ((fid_oid(fid) & 0x00fff000) << 16);
+
+ RETURN(ino ? ino : fid_oid(fid));
}
#define LUSTRE_SEQ_SRV_NAME "seq_srv"
}
/**
- * build inode number from passed @fid */
-ino_t cl_fid_build_ino(const struct lu_fid *fid)
+ * for 32 bit inode numbers directly map seq+oid to 32bit number.
+ */
+__u32 cl_fid_build_ino32(const struct lu_fid *fid)
{
- ino_t ino;
- ENTRY;
-
- if (fid_is_igif(fid)) {
- ino = lu_igif_ino(fid);
- RETURN(ino);
- }
-
- /* Very stupid and having many downsides inode allocation algorithm
- * based on fid. */
- ino = fid_flatten(fid) & 0xFFFFFFFF;
+ RETURN(fid_flatten32(fid));
+}
- if (unlikely(ino == 0))
- /* the first result ino is 0xFFC001, so this is rarely used */
- ino = 0xffbcde;
- ino = ino | 0x80000000;
- RETURN(ino);
+/**
+ * build inode number from passed @fid */
+__u64 cl_fid_build_ino(const struct lu_fid *fid)
+{
+#if BITS_PER_LONG == 32
+ RETURN(fid_flatten32(fid));
+#else
+ RETURN(fid_flatten(fid));
+#endif
}
/**
char *name;
int namelen;
struct lu_fid fid;
- ino_t ino;
+ __u64 ino;
hash = le64_to_cpu(ent->lde_hash);
namelen = le16_to_cpu(ent->lde_namelen);
char *name;
int namelen;
struct lu_fid fid;
- ino_t ino;
+ __u64 ino;
/*
* XXX: implement correct swabbing here.
fid = ent->lde_fid;
name = ent->lde_name;
fid_le_to_cpu(&fid, &fid);
- ino = cl_fid_build_ino(&fid);
+ if (cfs_curproc_is_32bit())
+ ino = cl_fid_build_ino32(&fid);
+ else
+ ino = cl_fid_build_ino(&fid);
type = ll_dirent_type_get(ent);
done = filldir(cookie, name, namelen,
(loff_t)hash, ino, type);
struct lookup_intent *it, struct kstat *stat)
{
struct inode *inode = de->d_inode;
+ struct ll_inode_info *lli = ll_i2info(inode);
int res = 0;
res = ll_inode_revalidate_it(de, it);
return res;
stat->dev = inode->i_sb->s_dev;
- stat->ino = inode->i_ino;
+ if (cfs_curproc_is_32bit())
+ stat->ino = cl_fid_build_ino32(&lli->lli_fid);
+ else
+ stat->ino = inode->i_ino;
+
stat->mode = inode->i_mode;
stat->nlink = inode->i_nlink;
stat->uid = inode->i_uid;
struct ptlrpc_request *req = NULL;
struct inode *inode = NULL;
int eadatalen = 0;
- ino_t ino = cl_fid_build_ino(fid);
+ unsigned long hash = (unsigned long) cl_fid_build_ino(fid);
struct md_op_data *op_data;
int rc;
ENTRY;
- CDEBUG(D_INFO, "searching inode for:(%lu,"DFID")\n", ino, PFID(fid));
+ CDEBUG(D_INFO, "searching inode for:(%lu,"DFID")\n", hash, PFID(fid));
- inode = ILOOKUP(sb, ino, ll_nfs_test_inode, fid);
+ inode = ilookup5(sb, hash, ll_nfs_test_inode, (void *)fid);
if (inode)
RETURN(inode);
/*
* Flush current sequence to make client obtain new one
* from server in case of disconnect/reconnect.
- * If range is already empty then no need to flush it.
*/
- if (cli->cl_seq != NULL &&
- !range_is_exhausted(&cli->cl_seq->lcs_space)) {
+ if (cli->cl_seq != NULL)
seq_client_flush(cli->cl_seq);
- }
rc = obd_notify_observer(obd, obd, OBD_NOTIFY_INACTIVE, NULL);
break;