From 83700ff186c826c9f8e71a0cf996761c78ae8989 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 24 Jan 2008 21:25:15 -0800 Subject: [PATCH] map u64 ceph inos into ino_t on <64bit platforms --- src/TODO | 1 - src/kernel/addr.c | 4 ++-- src/kernel/dir.c | 27 ++++++++++++++------------- src/kernel/file.c | 11 ++++++----- src/kernel/inode.c | 27 ++++++++++++++------------- src/kernel/mds_client.c | 26 +++++++++++++++++--------- src/kernel/super.c | 12 ++++++------ src/kernel/super.h | 37 +++++++++++++++++++++++++++++++------ 8 files changed, 90 insertions(+), 55 deletions(-) diff --git a/src/TODO b/src/TODO index dd1e3eb3af5f8..87e418aefe1cc 100644 --- a/src/TODO +++ b/src/TODO @@ -248,7 +248,6 @@ ebofs - verify proper behavior of conflicting/overlapping reads of clones - combine inodes and/or cnodes into same blocks -- nonblocking write on missing onodes? - fix bug in node rotation on insert (and reenable) - fix NEAR_LAST_FWD (?) diff --git a/src/kernel/addr.c b/src/kernel/addr.c index 3392bdcc113a0..f446d641f68c7 100644 --- a/src/kernel/addr.c +++ b/src/kernel/addr.c @@ -19,7 +19,7 @@ static int ceph_readpage(struct file *filp, struct page *page) dout(10, "ceph_readpage inode %p file %p page %p index %lu\n", inode, filp, page, page->index); - err = ceph_osdc_readpage(osdc, inode->i_ino, &ci->i_layout, + err = ceph_osdc_readpage(osdc, ceph_ino(inode), &ci->i_layout, page->index << PAGE_SHIFT, PAGE_SIZE, page); if (err) goto out_unlock; @@ -41,7 +41,7 @@ static int ceph_readpages(struct file *file, struct address_space *mapping, dout(10, "ceph_readpages inode %p file %p nr_pages %d\n", inode, file, nr_pages); - err = ceph_osdc_readpages(osdc, inode->i_ino, &ci->i_layout, + err = ceph_osdc_readpages(osdc, ceph_ino(inode), &ci->i_layout, pages, nr_pages); if (err < 0) goto out_unlock; diff --git a/src/kernel/dir.c b/src/kernel/dir.c index 66c5d5c113385..917799947668a 100644 --- a/src/kernel/dir.c +++ b/src/kernel/dir.c @@ -110,9 +110,10 @@ nextfrag: if (fi->rinfo.reply) ceph_mdsc_destroy_reply_info(&fi->rinfo); - dout(10, "dir_readdir querying mds for ino %lu frag %u\n", inode->i_ino, frag); + dout(10, "dir_readdir querying mds for ino %llx frag %u\n", + ceph_ino(inode), frag); req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_READDIR, - inode->i_ino, "", 0, 0); + ceph_ino(inode), "", 0, 0); if (IS_ERR(req)) return PTR_ERR(req); rhead = req->front.iov_base; @@ -152,7 +153,7 @@ nextfrag: in=dn->d_inode; } - if (in->i_ino != le64_to_cpu(fi->rinfo.dir_in[i].in->ino)) { + if (ceph_ino(in) != le64_to_cpu(fi->rinfo.dir_in[i].in->ino)) { if (ceph_fill_inode(in, fi->rinfo.dir_in[i].in) < 0) { dout(30, "ceph_fill_inode badness\n"); iput(in); @@ -160,8 +161,8 @@ nextfrag: break; } d_add(dn, in); - dout(10, "dir_readdir added dentry %p inode %lu %d/%d\n", - dn, in->i_ino, i, fi->rinfo.dir_nr); + dout(10, "dir_readdir added dentry %p inode %llx %d/%d\n", + dn, ceph_ino(in), i, fi->rinfo.dir_nr); } else { if (ceph_fill_inode(in, fi->rinfo.dir_in[i].in) < 0) { dout(30, "ceph_fill_inode badness\n"); @@ -262,7 +263,7 @@ static struct dentry *ceph_dir_lookup(struct inode *dir, struct dentry *dentry, if (IS_ERR(path)) return ERR_PTR(PTR_ERR(path)); req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LSTAT, - dir->i_sb->s_root->d_inode->i_ino, path, 0, 0); + ceph_ino(dir->i_sb->s_root->d_inode), path, 0, 0); kfree(path); if (IS_ERR(req)) return ERR_PTR(PTR_ERR(req)); @@ -325,7 +326,7 @@ static int ceph_dir_mknod(struct inode *dir, struct dentry *dentry, int mode, de if (IS_ERR(path)) return PTR_ERR(path); req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_MKNOD, - dir->i_sb->s_root->d_inode->i_ino, path, 0, 0); + ceph_ino(dir->i_sb->s_root->d_inode), path, 0, 0); kfree(path); if (IS_ERR(req)) { d_drop(dentry); @@ -374,7 +375,7 @@ static int ceph_dir_symlink(struct inode *dir, struct dentry *dentry, const char if (IS_ERR(path)) return PTR_ERR(path); req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SYMLINK, - dir->i_sb->s_root->d_inode->i_ino, path, 0, dest); + ceph_ino(dir->i_sb->s_root->d_inode), path, 0, dest); kfree(path); if (IS_ERR(req)) { d_drop(dentry); @@ -421,7 +422,7 @@ static int ceph_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode) if (IS_ERR(path)) return PTR_ERR(path); req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_MKDIR, - dir->i_sb->s_root->d_inode->i_ino, path, 0, 0); + ceph_ino(dir->i_sb->s_root->d_inode), path, 0, 0); kfree(path); if (IS_ERR(req)) { d_drop(dentry); @@ -472,7 +473,7 @@ static int ceph_dir_unlink(struct inode *dir, struct dentry *dentry) if (IS_ERR(path)) return PTR_ERR(path); req = ceph_mdsc_create_request(mdsc, op, - dir->i_sb->s_root->d_inode->i_ino, path, 0, 0); + ceph_ino(dir->i_sb->s_root->d_inode), path, 0, 0); kfree(path); if (IS_ERR(req)) return PTR_ERR(req); @@ -510,8 +511,8 @@ static int ceph_dir_rename(struct inode *old_dir, struct dentry *old_dentry, return PTR_ERR(newpath); } req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_RENAME, - root->d_inode->i_ino, oldpath, - root->d_inode->i_ino, newpath); + ceph_ino(root->d_inode), oldpath, + ceph_ino(root->d_inode), newpath); kfree(oldpath); kfree(newpath); if (IS_ERR(req)) @@ -542,7 +543,7 @@ ceph_dir_create(struct inode *dir, struct dentry *dentry, int mode, struct inode *inode; dout(5, "create in dir %p dentry %p name '%s' flags %d\n", dir, dentry, dentry->d_name.name, mode); - pathbase = dir->i_sb->s_root->d_inode->i_ino; + pathbase = ceph_ino(dir->i_sb->s_root->d_inode); path = ceph_build_dentry_path(dentry, &pathlen); if (IS_ERR(path)) return PTR_ERR(path); diff --git a/src/kernel/file.c b/src/kernel/file.c index eab68a8d7db86..fd14397f2d313 100644 --- a/src/kernel/file.c +++ b/src/kernel/file.c @@ -14,7 +14,7 @@ int do_open_request(struct super_block *sb, struct dentry *dentry, int flags, in { struct ceph_client *client = ceph_sb_to_client(sb); struct ceph_mds_client *mdsc = &client->mdsc; - ceph_ino_t pathbase; + u64 pathbase; char *path; int pathlen; struct ceph_msg *req; @@ -22,7 +22,7 @@ int do_open_request(struct super_block *sb, struct dentry *dentry, int flags, in int err; dout(5, "open dentry %p name '%s' flags %d\n", dentry, dentry->d_name.name, flags); - pathbase = sb->s_root->d_inode->i_ino; + pathbase = ceph_ino(sb->s_root->d_inode); path = ceph_build_dentry_path(dentry, &pathlen); if (IS_ERR(path)) return PTR_ERR(path); @@ -91,7 +91,8 @@ int ceph_open(struct inode *inode, struct file *file) struct ceph_file_info *cf = file->private_data; int err; - dout(5, "ceph_open inode %p (%lu) file %p\n", inode, inode->i_ino, file); + dout(5, "ceph_open inode %p ino %llx file %p\n", inode, + ceph_ino(inode), file); if (cf) { /* the file is already opened */ @@ -119,7 +120,7 @@ int ceph_open(struct inode *inode, struct file *file) return err; } - dout(5, "ceph_open success, %lx\n", inode->i_ino); + dout(5, "ceph_open success, %llx\n", ceph_ino(inode)); return 0; } @@ -232,7 +233,7 @@ ssize_t ceph_silly_write(struct file *file, const char __user * data, /* this is an ugly hack */ while (count > 0) { - ret = ceph_osdc_silly_write(osdc, inode->i_ino, &ci->i_layout, count, *offset, data); + ret = ceph_osdc_silly_write(osdc, ceph_ino(inode), &ci->i_layout, count, *offset, data); dout(10, "ret is %d\n", ret); if (ret > 0) { did += ret; diff --git a/src/kernel/inode.c b/src/kernel/inode.c index 0a45fa336edc6..63fe4ac568e16 100644 --- a/src/kernel/inode.c +++ b/src/kernel/inode.c @@ -14,7 +14,7 @@ int ceph_inode_debug = 50; const struct inode_operations ceph_symlink_iops; -int ceph_get_inode(struct super_block *sb, unsigned long ino, struct inode **pinode) +int ceph_get_inode(struct super_block *sb, ino_t ino, struct inode **pinode) { struct ceph_inode_info *ci; @@ -27,6 +27,7 @@ int ceph_get_inode(struct super_block *sb, unsigned long ino, struct inode **pin unlock_new_inode(*pinode); ci = ceph_inode(*pinode); + ceph_set_ino(*pinode, ino); ci->i_hashval = ino; @@ -43,7 +44,7 @@ int ceph_fill_inode(struct inode *inode, struct ceph_mds_reply_inode *info) int i; int symlen; - inode->i_ino = le64_to_cpu(info->ino); + ceph_set_ino(inode, le64_to_cpu(info->ino)); inode->i_mode = le32_to_cpu(info->mode); inode->i_uid = le32_to_cpu(info->uid); inode->i_gid = le32_to_cpu(info->gid); @@ -57,9 +58,9 @@ int ceph_fill_inode(struct inode *inode, struct ceph_mds_reply_inode *info) ci->i_hashval = inode->i_ino; } - dout(30, "fill_inode %p ino=%lx by %d.%d sz=%llu mode %o nlink %d\n", inode, - inode->i_ino, inode->i_uid, inode->i_gid, inode->i_size, inode->i_mode, - inode->i_nlink); + dout(30, "fill_inode %p ino %lu/%llx by %d.%d sz=%llu mode %o nlink %d\n", + inode, inode->i_ino, ceph_ino(inode), inode->i_uid, inode->i_gid, + inode->i_size, inode->i_mode, inode->i_nlink); ceph_decode_timespec(&inode->i_atime, &info->atime); ceph_decode_timespec(&inode->i_mtime, &info->mtime); @@ -151,7 +152,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_reply_info *prinfo, in = dn->d_inode; for (i=0; itrace_nr; i++) - if (in->i_ino == prinfo->trace_in[i].in->ino) + if (ceph_ino(in) == prinfo->trace_in[i].in->ino) break; if (i == prinfo->trace_nr) { @@ -190,7 +191,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_reply_info *prinfo, } if ((!dn->d_inode) || - (dn->d_inode->i_ino != prinfo->trace_in[i].in->ino)) { + (ceph_ino(dn->d_inode) != prinfo->trace_in[i].in->ino)) { in = new_inode(parent->d_sb); if (in == NULL) { dout(30, "new_inode badness\n"); @@ -206,8 +207,8 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_reply_info *prinfo, break; } d_add(dn, in); - dout(10, "ceph_fill_trace added dentry %p inode %lu %d/%d\n", - dn, in->i_ino, i, prinfo->trace_nr); + dout(10, "ceph_fill_trace added dentry %p inode %llx %d/%d\n", + dn, ceph_ino(in), i, prinfo->trace_nr); } else { in = dn->d_inode; if (ceph_fill_inode(in, prinfo->trace_in[i].in) < 0) { @@ -307,8 +308,8 @@ struct ceph_inode_cap *ceph_add_cap(struct inode *inode, struct ceph_mds_session } } - dout(10, "add_cap inode %p (%lu) got cap %d %xh now %xh seq %d from %d\n", - inode, inode->i_ino, i, cap, cap|ci->i_caps[i].caps, seq, mds); + dout(10, "add_cap inode %p (%llx) got cap %d %xh now %xh seq %d from %d\n", + inode, ceph_ino(inode), i, cap, cap|ci->i_caps[i].caps, seq, mds); ci->i_caps[i].caps |= cap; ci->i_caps[i].seq = seq; return &ci->i_caps[i]; @@ -470,7 +471,7 @@ struct ceph_msg * prepare_setattr(struct ceph_mds_client *mdsc, struct dentry *d path = ceph_build_dentry_path(dentry, &pathlen); if (IS_ERR(path)) return ERR_PTR(PTR_ERR(path)); - req = ceph_mdsc_create_request(mdsc, op, dentry->d_inode->i_sb->s_root->d_inode->i_ino, path, 0, 0); + req = ceph_mdsc_create_request(mdsc, op, ceph_ino(dentry->d_inode->i_sb->s_root->d_inode), path, 0, 0); kfree(path); return req; } @@ -570,7 +571,7 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) if (ia_valid & ATTR_SIZE) { if (ia_valid & ATTR_FILE) req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_TRUNCATE, - dentry->d_inode->i_ino, "", 0, 0); + ceph_ino(dentry->d_inode), "", 0, 0); else req = prepare_setattr(mdsc, dentry, CEPH_MDS_OP_TRUNCATE); if (IS_ERR(req)) diff --git a/src/kernel/mds_client.c b/src/kernel/mds_client.c index e7d90c51c881e..e3acffc244fa8 100644 --- a/src/kernel/mds_client.c +++ b/src/kernel/mds_client.c @@ -875,8 +875,8 @@ void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds) cap = list_entry(cp, struct ceph_inode_cap, session_caps); ci = cap->ci; dout(10, "cap is %p, ci is %p, inode is %p\n", cap, ci, &ci->vfs_inode); - dout(10, " adding cap %p on ino %lx\n", cap, ci->vfs_inode.i_ino); - ceph_encode_64(&p, end, ci->vfs_inode.i_ino); + dout(10, " adding cap %p on ino %llx\n", cap, ceph_ino(&ci->vfs_inode)); + ceph_encode_64(&p, end, ceph_ino(&ci->vfs_inode)); rec = p; p += sizeof(*rec); BUG_ON(p > end); @@ -1077,8 +1077,9 @@ void ceph_mdsc_handle_filecaps(struct ceph_mds_client *mdsc, struct ceph_msg *ms struct ceph_mds_file_caps *h; int mds = msg->hdr.src.name.num; int op; - __u32 seq; - __u64 ino, size; + u32 seq; + u64 ino, size; + ino_t inot; dout(10, "handle_filecaps from mds%d\n", mds); @@ -1100,10 +1101,18 @@ void ceph_mdsc_handle_filecaps(struct ceph_mds_client *mdsc, struct ceph_msg *ms session->s_cap_seq++; /* lookup ino */ - inode = ilookup(sb, ino); - dout(20, "op is %d, inode is %llx %p\n", op, ino, inode); + inot = ceph_ino_to_ino(ino); + inode = ilookup(sb, inot); + dout(20, "op is %d, ino %llx %p\n", op, ino, inode); + + if (inode && ceph_ino(inode) != inot) { + BUG_ON(sizeof(ino_t) >= sizeof(u64)); + dout(10, "UH OH, did our lame ceph ino %llx -> %lu ino_t hash collide?" + " inode is %llx\n", ino, inot, ceph_ino(inode)); + inode = 0; + } if (!inode) { - dout(10, "hrm, wtf, i don't have inode %llx? closing out cap\n", ino); + dout(10, "hrm, wtf, i don't have ino %lu=%llx? closing out cap\n", inot, ino); send_cap_ack(mdsc, ino, 0, 0, seq, size, mds); return; } @@ -1124,7 +1133,6 @@ void ceph_mdsc_handle_filecaps(struct ceph_mds_client *mdsc, struct ceph_msg *ms } iput(inode); - return; bad: dout(10, "corrupt filecaps message\n"); @@ -1148,7 +1156,7 @@ int ceph_mdsc_update_cap_wanted(struct ceph_inode_info *ci, int wanted) BUG_ON(!session); cap->caps &= wanted; /* drop caps we don't want */ - send_cap_ack(mdsc, ci->vfs_inode.i_ino, cap->caps, wanted, + send_cap_ack(mdsc, ceph_ino(&ci->vfs_inode), cap->caps, wanted, cap->seq, ci->vfs_inode.i_size, cap->mds); } diff --git a/src/kernel/super.c b/src/kernel/super.c index 86f9d2d346a15..deb9f91f42d61 100644 --- a/src/kernel/super.c +++ b/src/kernel/super.c @@ -26,7 +26,7 @@ static int ceph_write_inode(struct inode * inode, int unused) struct ceph_inode_info *ci = ceph_inode(inode); if (memcmp(&ci->i_old_atime, &inode->i_atime, sizeof(struct timeval))) { - dout(30, "ceph_write_inode %lx .. atime updated\n", inode->i_ino); + dout(30, "ceph_write_inode %llx .. atime updated\n", ceph_ino(inode)); /* eventually push this async to mds ... */ } return 0; @@ -114,7 +114,7 @@ static struct inode *ceph_alloc_inode(struct super_block *sb) ci->i_caps = ci->i_caps_static; atomic_set(&ci->i_cap_count, 0); - dout(30, "ceph_alloc_inode sb=%p inode=%lu\n", sb, (&ci->vfs_inode)->i_ino); + dout(30, "ceph_alloc_inode sb=%p\n", sb); for (i=0; i<4; i++) ci->i_nr_by_mode[i] = 0; ci->i_cap_wanted = 0; @@ -132,9 +132,9 @@ static void ceph_destroy_inode(struct inode *inode) { struct ceph_inode_info *ci = ceph_inode(inode); - dout(30, "ceph_destroy_inode sb=%p inode=%lu\n", inode->i_sb, inode->i_ino); - - dout(10, "destroy_inode %p vfsi %p\n", ci, inode); + dout(30, "ceph_destroy_inode %p ino %lu=%llx\n", inode, + inode->i_ino, ceph_ino(inode)); + if (ci->i_caps != ci->i_caps_static) kfree(ci->i_caps); if (ci->i_symlink) @@ -440,7 +440,7 @@ static int ceph_get_sb(struct file_system_type *fs_type, mnt->mnt_sb = sb; mnt->mnt_root = droot; - dout(22, "droot inode = %ld\n", droot->d_inode->i_ino); + dout(22, "droot ino %llx\n", ceph_ino(droot->d_inode)); return 0; diff --git a/src/kernel/super.h b/src/kernel/super.h index 3859ec0b16954..291f488859934 100644 --- a/src/kernel/super.h +++ b/src/kernel/super.h @@ -113,6 +113,8 @@ enum { FILE_MODE_WRONLY }; struct ceph_inode_info { + u64 i_ceph_ino; + struct ceph_file_layout i_layout; char *i_symlink; @@ -137,6 +139,34 @@ struct ceph_inode_info { struct inode vfs_inode; /* at end */ }; +static inline struct ceph_inode_info *ceph_inode(struct inode *inode) +{ + return list_entry(inode, struct ceph_inode_info, vfs_inode); +} + +/* + * ino_t is <64 bits on many architectures... blech + */ +static inline ino_t ceph_ino_to_ino(u64 cephino) +{ + ino_t ino = (ino_t)cephino; + if (sizeof(ino_t) < sizeof(u64)) + ino ^= cephino >> (sizeof(u64)-sizeof(ino_t)) * 8; + return ino; +} +static inline void ceph_set_ino(struct inode *inode, __u64 ino) { + struct ceph_inode_info *ci = ceph_inode(inode); + ci->i_ceph_ino = ino; + inode->i_ino = ceph_ino_to_ino(ino); +} +static inline u64 ceph_ino(struct inode *inode) { + struct ceph_inode_info *ci = ceph_inode(inode); + return ci->i_ceph_ino; +} + +/* + * caps helpers + */ static inline int ceph_caps_issued(struct ceph_inode_info *ci) { int i, issued = 0; for (i=0; ii_nr_caps; i++) @@ -170,11 +200,6 @@ static inline int ceph_file_mode(int flags) BUG_ON(1); } -static inline struct ceph_inode_info *ceph_inode(struct inode *inode) -{ - return list_entry(inode, struct ceph_inode_info, vfs_inode); -} - static inline struct ceph_client *ceph_inode_to_client(struct inode *inode) { return (struct ceph_client*)inode->i_sb->s_fs_info; @@ -223,7 +248,7 @@ extern int ceph_mount(struct ceph_client *client, struct ceph_mount_args *args, /* inode.c */ -extern int ceph_get_inode(struct super_block *sb, unsigned long ino, struct inode **pinode); +extern int ceph_get_inode(struct super_block *sb, ino_t ino, struct inode **pinode); extern int ceph_fill_inode(struct inode *inode, struct ceph_mds_reply_inode *info); extern struct ceph_inode_cap *ceph_find_cap(struct inode *inode, int want); extern struct ceph_inode_cap *ceph_add_cap(struct inode *inode, struct ceph_mds_session *session, u32 cap, u32 seq); -- 2.39.5