Loading fs/ceph/dir.c +7 −4 Original line number Diff line number Diff line Loading @@ -161,7 +161,7 @@ static int __dcache_readdir(struct file *filp, 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) { Loading Loading @@ -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; Loading Loading @@ -377,7 +379,8 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir) 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; } Loading fs/ceph/inode.c +8 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading fs/ceph/super.c +5 −0 Original line number Diff line number Diff line Loading @@ -131,6 +131,7 @@ enum { Opt_rbytes, Opt_norbytes, Opt_noasyncreaddir, Opt_ino32, }; static match_table_t fsopt_tokens = { Loading @@ -150,6 +151,7 @@ static match_table_t fsopt_tokens = { {Opt_rbytes, "rbytes"}, {Opt_norbytes, "norbytes"}, {Opt_noasyncreaddir, "noasyncreaddir"}, {Opt_ino32, "ino32"}, {-1, NULL} }; Loading Loading @@ -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); } Loading fs/ceph/super.h +45 −20 Original line number Diff line number Diff line Loading @@ -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) Loading Loading @@ -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; Loading @@ -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 Loading Loading @@ -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 */ Loading Loading @@ -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; } /* Loading Loading
fs/ceph/dir.c +7 −4 Original line number Diff line number Diff line Loading @@ -161,7 +161,7 @@ static int __dcache_readdir(struct file *filp, 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) { Loading Loading @@ -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; Loading Loading @@ -377,7 +379,8 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir) 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; } Loading
fs/ceph/inode.c +8 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading
fs/ceph/super.c +5 −0 Original line number Diff line number Diff line Loading @@ -131,6 +131,7 @@ enum { Opt_rbytes, Opt_norbytes, Opt_noasyncreaddir, Opt_ino32, }; static match_table_t fsopt_tokens = { Loading @@ -150,6 +151,7 @@ static match_table_t fsopt_tokens = { {Opt_rbytes, "rbytes"}, {Opt_norbytes, "norbytes"}, {Opt_noasyncreaddir, "noasyncreaddir"}, {Opt_ino32, "ino32"}, {-1, NULL} }; Loading Loading @@ -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); } Loading
fs/ceph/super.h +45 −20 Original line number Diff line number Diff line Loading @@ -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) Loading Loading @@ -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; Loading @@ -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 Loading Loading @@ -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 */ Loading Loading @@ -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; } /* Loading