Commit ad1fee96 authored by Yehuda Sadeh's avatar Yehuda Sadeh Committed by Sage Weil
Browse files

ceph: add ino32 mount option



The ino32 mount option forces the ceph fs to report 32 bit
ino values.  This is useful for 64 bit kernels with 32 bit userspace.

Signed-off-by: default avatarYehuda Sadeh <yehuda@hq.newdream.net>
parent 483fac71
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -161,7 +161,7 @@ more:
	filp->f_pos = di->offset;
	err = filldir(dirent, dentry->d_name.name,
		      dentry->d_name.len, di->offset,
		      dentry->d_inode->i_ino,
		      ceph_translate_ino(dentry->d_sb, dentry->d_inode->i_ino),
		      dentry->d_inode->i_mode >> 12);

	if (last) {
@@ -245,15 +245,17 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir)

		dout("readdir off 0 -> '.'\n");
		if (filldir(dirent, ".", 1, ceph_make_fpos(0, 0),
			    inode->i_ino, inode->i_mode >> 12) < 0)
			    ceph_translate_ino(inode->i_sb, inode->i_ino),
			    inode->i_mode >> 12) < 0)
			return 0;
		filp->f_pos = 1;
		off = 1;
	}
	if (filp->f_pos == 1) {
		ino_t ino = filp->f_dentry->d_parent->d_inode->i_ino;
		dout("readdir off 1 -> '..'\n");
		if (filldir(dirent, "..", 2, ceph_make_fpos(0, 1),
			    filp->f_dentry->d_parent->d_inode->i_ino,
			    ceph_translate_ino(inode->i_sb, ino),
			    inode->i_mode >> 12) < 0)
			return 0;
		filp->f_pos = 2;
@@ -377,7 +379,8 @@ more:
		if (filldir(dirent,
			    rinfo->dir_dname[off - fi->offset],
			    rinfo->dir_dname_len[off - fi->offset],
			    pos, ino, ftype) < 0) {
			    pos,
			    ceph_translate_ino(inode->i_sb, ino), ftype) < 0) {
			dout("filldir stopping us...\n");
			return 0;
		}
+8 −1
Original line number Diff line number Diff line
@@ -36,6 +36,13 @@ static void ceph_vmtruncate_work(struct work_struct *work);
/*
 * find or create an inode, given the ceph ino number
 */
static int ceph_set_ino_cb(struct inode *inode, void *data)
{
	ceph_inode(inode)->i_vino = *(struct ceph_vino *)data;
	inode->i_ino = ceph_vino_to_ino(*(struct ceph_vino *)data);
	return 0;
}

struct inode *ceph_get_inode(struct super_block *sb, struct ceph_vino vino)
{
	struct inode *inode;
@@ -1809,7 +1816,7 @@ int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry,
	err = ceph_do_getattr(inode, CEPH_STAT_CAP_INODE_ALL);
	if (!err) {
		generic_fillattr(inode, stat);
		stat->ino = inode->i_ino;
		stat->ino = ceph_translate_ino(inode->i_sb, inode->i_ino);
		if (ceph_snap(inode) != CEPH_NOSNAP)
			stat->dev = ceph_snap(inode);
		else
+5 −0
Original line number Diff line number Diff line
@@ -131,6 +131,7 @@ enum {
	Opt_rbytes,
	Opt_norbytes,
	Opt_noasyncreaddir,
	Opt_ino32,
};

static match_table_t fsopt_tokens = {
@@ -150,6 +151,7 @@ static match_table_t fsopt_tokens = {
	{Opt_rbytes, "rbytes"},
	{Opt_norbytes, "norbytes"},
	{Opt_noasyncreaddir, "noasyncreaddir"},
	{Opt_ino32, "ino32"},
	{-1, NULL}
};

@@ -225,6 +227,9 @@ static int parse_fsopt_token(char *c, void *private)
	case Opt_noasyncreaddir:
		fsopt->flags |= CEPH_MOUNT_OPT_NOASYNCREADDIR;
		break;
	case Opt_ino32:
		fsopt->flags |= CEPH_MOUNT_OPT_INO32;
		break;
	default:
		BUG_ON(token);
	}
+45 −20
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#define CEPH_MOUNT_OPT_DIRSTAT         (1<<4) /* `cat dirname` for stats */
#define CEPH_MOUNT_OPT_RBYTES          (1<<5) /* dir st_bytes = rbytes */
#define CEPH_MOUNT_OPT_NOASYNCREADDIR  (1<<7) /* no dcache readdir */
#define CEPH_MOUNT_OPT_INO32           (1<<8) /* 32 bit inos */

#define CEPH_MOUNT_OPT_DEFAULT    (CEPH_MOUNT_OPT_RBYTES)

@@ -319,6 +320,16 @@ static inline struct ceph_inode_info *ceph_inode(struct inode *inode)
	return container_of(inode, struct ceph_inode_info, vfs_inode);
}

static inline struct ceph_fs_client *ceph_inode_to_client(struct inode *inode)
{
	return (struct ceph_fs_client *)inode->i_sb->s_fs_info;
}

static inline struct ceph_fs_client *ceph_sb_to_client(struct super_block *sb)
{
	return (struct ceph_fs_client *)sb->s_fs_info;
}

static inline struct ceph_vino ceph_vino(struct inode *inode)
{
	return ceph_inode(inode)->i_vino;
@@ -327,19 +338,49 @@ static inline struct ceph_vino ceph_vino(struct inode *inode)
/*
 * ino_t is <64 bits on many architectures, blech.
 *
 * don't include snap in ino hash, at least for now.
 *               i_ino (kernel inode)   st_ino (userspace)
 * i386          32                     32
 * x86_64+ino32  64                     32
 * x86_64        64                     64
 */
static inline u32 ceph_ino_to_ino32(ino_t ino)
{
	ino ^= ino >> (sizeof(ino) * 8 - 32);
	if (!ino)
		ino = 1;
	return ino;
}

/*
 * kernel i_ino value
 */
static inline ino_t ceph_vino_to_ino(struct ceph_vino vino)
{
	ino_t ino = (ino_t)vino.ino;  /* ^ (vino.snap << 20); */
#if BITS_PER_LONG == 32
	ino ^= vino.ino >> (sizeof(u64)-sizeof(ino_t)) * 8;
	if (!ino)
		ino = 1;
	ino = ceph_ino_to_ino32(ino);
#endif
	return ino;
}

/*
 * user-visible ino (stat, filldir)
 */
#if BITS_PER_LONG == 32
static inline ino_t ceph_translate_ino(struct super_block *sb, ino_t ino)
{
	return ino;
}
#else
static inline ino_t ceph_translate_ino(struct super_block *sb, ino_t ino)
{
	if (ceph_test_mount_opt(ceph_sb_to_client(sb), INO32))
		ino = ceph_ino_to_ino32(ino);
	return ino;
}
#endif


/* for printf-style formatting */
#define ceph_vinop(i) ceph_inode(i)->i_vino.ino, ceph_inode(i)->i_vino.snap

@@ -428,13 +469,6 @@ static inline loff_t ceph_make_fpos(unsigned frag, unsigned off)
	return ((loff_t)frag << 32) | (loff_t)off;
}

static inline int ceph_set_ino_cb(struct inode *inode, void *data)
{
	ceph_inode(inode)->i_vino = *(struct ceph_vino *)data;
	inode->i_ino = ceph_vino_to_ino(*(struct ceph_vino *)data);
	return 0;
}

/*
 * caps helpers
 */
@@ -503,15 +537,6 @@ extern void ceph_reservation_status(struct ceph_fs_client *client,
				    int *total, int *avail, int *used,
				    int *reserved, int *min);

static inline struct ceph_fs_client *ceph_inode_to_client(struct inode *inode)
{
	return (struct ceph_fs_client *)inode->i_sb->s_fs_info;
}

static inline struct ceph_fs_client *ceph_sb_to_client(struct super_block *sb)
{
	return (struct ceph_fs_client *)sb->s_fs_info;
}


/*