]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: versioned inodes (ino,snap)
authorSage Weil <sage@newdream.net>
Fri, 8 Aug 2008 16:02:27 +0000 (09:02 -0700)
committerSage Weil <sage@newdream.net>
Fri, 8 Aug 2008 16:02:27 +0000 (09:02 -0700)
13 files changed:
src/TODO
src/kernel/addr.c
src/kernel/dir.c
src/kernel/export.c
src/kernel/file.c
src/kernel/inode.c
src/kernel/mds_client.c
src/kernel/mds_client.h
src/kernel/osd_client.c
src/kernel/osd_client.h
src/kernel/super.c
src/kernel/super.h
src/kernel/types.h [new file with mode: 0644]

index 3313d6118aeb2edc23fe14dc3bdf4c906ea26dfd..f16d433f96785700017d2ec0c9f5a593095edfc0 100644 (file)
--- a/src/TODO
+++ b/src/TODO
@@ -18,6 +18,10 @@ big items
 - libuuid?
 
 
+yehuda
+- what is the purpose of ceph_inode_info.i_hashval.. can we remove it..
+
+
 snaps on mds
 - cap release probably needs ack by mds.  or, mds needs to possibly initiate recovery on import?  no, release should pbly just be acked by mds... like it was way back when... bah!
 
index 8615850776a0aa173a28f86fad7281d93fd31e9a..298ca22393a8ffc407dbd0e858548fc91e91c590 100644 (file)
@@ -106,7 +106,7 @@ static int ceph_readpage(struct file *filp, struct page *page)
 
        dout(10, "readpage inode %p file %p page %p index %lu\n",
             inode, filp, page, page->index);
-       err = ceph_osdc_readpage(osdc, ceph_ino(inode), &ci->i_layout,
+       err = ceph_osdc_readpage(osdc, ceph_vino(inode), &ci->i_layout,
                                 page->index << PAGE_SHIFT, PAGE_SIZE, page);
        if (unlikely(err < 0))
                goto out;
@@ -143,7 +143,7 @@ static int ceph_readpages(struct file *file, struct address_space *mapping,
        BUG_ON(list_empty(page_list));
        page = list_entry(page_list->prev, struct page, lru);
        offset = page->index << PAGE_CACHE_SHIFT;
-       rc = ceph_osdc_readpages(osdc, mapping, ceph_ino(inode), &ci->i_layout,
+       rc = ceph_osdc_readpages(osdc, mapping, ceph_vino(inode), &ci->i_layout,
                                 offset, nr_pages << PAGE_CACHE_SHIFT,
                                 page_list, nr_pages);
        if (rc < 0)
@@ -211,7 +211,7 @@ static int ceph_writepage(struct page *page, struct writeback_control *wbc)
        page_cache_get(page);
        was_dirty = PageDirty(page);
        set_page_writeback(page);
-       err = ceph_osdc_writepages(osdc, ceph_ino(inode), &ci->i_layout,
+       err = ceph_osdc_writepages(osdc, ceph_vino(inode), &ci->i_layout,
                                   page_off, len, &page, 1);
        if (err >= 0) {
                if (was_dirty) {
@@ -429,7 +429,7 @@ get_more_pages:
                        dout(10, "writepages got %d pages at %llu~%llu\n",
                             locked_pages, offset, len);
                        rc = ceph_osdc_writepages(&client->osdc,
-                                                 ceph_ino(inode),
+                                                 ceph_vino(inode),
                                                  &ci->i_layout,
                                                  offset, len,
                                                  pagep,
@@ -542,7 +542,7 @@ static int ceph_write_begin(struct file *file, struct address_space *mapping,
        /* or, do sub-page granularity dirty accounting? */
        /* try to read the full page */
        ci = ceph_inode(inode);
-       r = ceph_osdc_readpage(osdc, ceph_ino(inode), &ci->i_layout,
+       r = ceph_osdc_readpage(osdc, ceph_vino(inode), &ci->i_layout,
                               page_off, PAGE_SIZE, page);
        if (r < 0)
                return r;
index 90779edbe147ba8ee6d274398110d94307d6d4c0..0e66b65b28be9bf94af0adc73d6fc7011f040c86 100644 (file)
@@ -92,7 +92,7 @@ retry:
                goto retry;
        }
 
-       *base = ceph_ino(temp->d_inode);
+       *base = ceph_vino(temp->d_inode).ino;
        *plen = len;
        dout(10, "build_path_dentry on %p %d built %llx '%.*s'\n",
             dentry, atomic_read(&dentry->d_count), *base, len, path);
@@ -133,15 +133,21 @@ nextfrag:
        if (fi->frag != frag || fi->last_readdir == NULL) {
                struct ceph_mds_request *req;
                struct ceph_mds_request_head *rhead;
+               char *path;
+               int pathlen;
+               u64 pathbase;
 
                frag = ceph_choose_frag(ceph_inode(inode), frag, 0);
 
                /* query mds */
-               dout(10, "dir_readdir querying mds for ino %llx frag %x\n",
-                    ceph_ino(inode), frag);
+               dout(10, "dir_readdir querying mds for ino %llx.%llx frag %x\n",
+                    ceph_vinop(inode), frag);
+               path = ceph_build_dentry_path(filp->f_dentry, &pathlen,
+                                             &pathbase, 1);
                req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_READDIR,
-                                              ceph_ino(inode), "", 0, 0,
+                                              pathbase, path, 0, 0,
                                               filp->f_dentry, USE_AUTH_MDS);
+               kfree(path);
                if (IS_ERR(req))
                        return PTR_ERR(req);
                req->r_direct_hash = frag_value(frag);
@@ -302,8 +308,9 @@ struct dentry *ceph_do_lookup(struct super_block *sb, struct dentry *dentry,
        dout(10, "do_lookup %p mask %d\n", dentry, mask);
        if (on_inode) {
                /* stat ino directly */
+               WARN_ON(ceph_vino(dentry->d_inode).snap != CEPH_NOSNAP);
                req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LSTAT,
-                                              ceph_ino(dentry->d_inode), 0,
+                                              ceph_vino(dentry->d_inode).ino,0,
                                               0, 0,
                                               dentry, USE_CAP_MDS);
        } else {
@@ -658,7 +665,7 @@ static int ceph_dentry_revalidate(struct dentry *dentry, struct nameidata *nd)
        dout(10, "d_revalidate %p '%.*s' inode %p\n", dentry,
             dentry->d_name.len, dentry->d_name.name, dentry->d_inode);
 
-       if (ceph_ino(dir) != 1 &&  /* ICONTENT useless on root inode */
+       if (ceph_vino(dir).ino != 1 &&  /* ICONTENT useless on root inode */
            ceph_inode(dir)->i_version == dentry->d_time &&
            ceph_inode_lease_valid(dir, CEPH_LOCK_ICONTENT)) {
                dout(20, "dentry_revalidate %p %lu ICONTENT on dir %p %llu\n",
index d14afc18c6c9b30b1d8a45b834bd5911515d0d5f..2ebc7cdcf1d77ca7ca5d13cb35206953131c9ac5 100644 (file)
@@ -33,14 +33,14 @@ int ceph_encode_fh(struct dentry *dentry, __u32 *rawfh, int *max_len,
         * pretty sure this is racy
         */
        /* note: caller holds dentry->d_lock */
-       fh[0].ino = cpu_to_le64(ceph_ino(dentry->d_inode));
+       fh[0].ino = cpu_to_le64(ceph_vino(dentry->d_inode).ino);
        fh[0].dname_hash = cpu_to_le32(dentry->d_name.hash);
        len = 1;
        while (len < max) {
                dentry = dentry->d_parent;
                if (!dentry)
                        break;
-               fh[len].ino = cpu_to_le64(ceph_ino(dentry->d_inode));
+               fh[len].ino = cpu_to_le64(ceph_vino(dentry->d_inode).ino);
                fh[len].dname_hash = cpu_to_le32(dentry->d_name.hash);
                len++;
                type = 2;
@@ -59,13 +59,16 @@ struct dentry *__fh_to_dentry(struct super_block *sb,
        struct inode *inode;
        struct dentry *dentry;
        int err;
-       u64 ino = le64_to_cpu(fh[0].ino);
+       struct ceph_vino vino = {
+               .ino = le64_to_cpu(fh[0].ino),
+               .snap = CEPH_NOSNAP,   /* FIXME */
+       };
        u32 hash = le32_to_cpu(fh[0].dname_hash);
 
-       inode = ceph_find_inode(sb, ino);
+       inode = ceph_find_inode(sb, vino);
        if (!inode) {
                struct ceph_mds_request *req;
-               derr(10, "__fh_to_dentry %llx.%x -- no inode\n", ino, hash);
+               derr(10, "__fh_to_dentry %llx.%x -- no inode\n", vino.ino,hash);
                
                req = ceph_mdsc_create_request(mdsc,
                                               CEPH_MDS_OP_FINDINODE,
@@ -76,20 +79,21 @@ struct dentry *__fh_to_dentry(struct super_block *sb,
                err = ceph_mdsc_do_request(mdsc, req);
                ceph_mdsc_put_request(req);
                
-               inode = ceph_find_inode(sb, ino);
+               inode = ceph_find_inode(sb, vino);
                if (!inode)
                        return ERR_PTR(err ? err : -ESTALE);
        }
 
        dentry = d_alloc_anon(inode);
        if (!dentry) {
-               derr(10, "__fh_to_dentry %llx.%x -- inode %p but ENOMEM\n", ino,
+               derr(10, "__fh_to_dentry %llx.%x -- inode %p but ENOMEM\n",
+                    vino.ino,
                     hash, inode);
                iput(inode);
                return ERR_PTR(-ENOMEM);
        }
-       dout(10, "__fh_to_dentry %llx.%x -- inode %p dentry %p\n", ino, hash,
-            inode, dentry);
+       dout(10, "__fh_to_dentry %llx.%x -- inode %p dentry %p\n", vino.ino,
+            hash, inode, dentry);
        return dentry;  
 
 }
index 8d8246cd4864291096c389b8c6cbd5214795dad5..16077650499be34d7c3b28a026268a16fc92dff7 100644 (file)
@@ -84,8 +84,8 @@ int ceph_open(struct inode *inode, struct file *file)
        if (S_ISDIR(inode->i_mode))
                flags = O_DIRECTORY;
 
-       dout(5, "open inode %p ino %llx file %p flags %d (%d)\n", inode,
-            ceph_ino(inode), file, flags, file->f_flags);
+       dout(5, "open inode %p ino %llx.%llx file %p flags %d (%d)\n", inode,
+            ceph_vinop(inode), file, flags, file->f_flags);
        fmode = ceph_flags_to_mode(flags);
        wantcaps = ceph_caps_for_mode(fmode);
 
@@ -119,7 +119,7 @@ int ceph_open(struct inode *inode, struct file *file)
        if (err == 0)
                err = ceph_init_file(inode, file, req->r_fmode);
        ceph_mdsc_put_request(req);
-       dout(5, "open result=%d on %llx\n", err, ceph_ino(inode));
+       dout(5, "open result=%d on %llx.%llx\n", err, ceph_vinop(inode));
 out:
        dput(dentry);
        return err;
@@ -212,7 +212,7 @@ static ssize_t ceph_sync_read(struct file *file, char __user *data,
        dout(10, "sync_read on file %p %lld~%u\n", file, *offset,
             (unsigned)count);
 
-       ret = ceph_osdc_sync_read(&client->osdc, ceph_ino(inode),
+       ret = ceph_osdc_sync_read(&client->osdc, ceph_vino(inode),
                                  &ci->i_layout,
                                  pos, count, data);
        if (ret > 0)
@@ -235,7 +235,7 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data,
        if (file->f_flags & O_APPEND)
                pos = i_size_read(inode);
 
-       ret = ceph_osdc_sync_write(&client->osdc, ceph_ino(inode),
+       ret = ceph_osdc_sync_write(&client->osdc, ceph_vino(inode),
                                   &ci->i_layout,
                                   pos, count, data);
        if (ret > 0) {
@@ -265,16 +265,16 @@ ssize_t ceph_aio_read(struct kiocb *iocb, const struct iovec *iov,
 
        __ceph_do_pending_vmtruncate(inode);
 
-       dout(10, "aio_read %llx %llu~%u trying to get caps on %p\n",
-            ceph_ino(inode), pos, (unsigned)len, inode);
+       dout(10, "aio_read %llx.%llx %llu~%u trying to get caps on %p\n",
+            ceph_vinop(inode), pos, (unsigned)len, inode);
        ret = wait_event_interruptible(ci->i_cap_wq,
                                       ceph_get_cap_refs(ci, CEPH_CAP_RD,
                                                         CEPH_CAP_RDCACHE,
                                                         &got, -1));
        if (ret < 0)
                goto out;
-       dout(10, "aio_read %llx %llu~%u got cap refs %d\n",
-            ceph_ino(inode), pos, (unsigned)len, got);
+       dout(10, "aio_read %llx.%llx %llu~%u got cap refs %d\n",
+            ceph_vinop(inode), pos, (unsigned)len, got);
 
        if ((got & CEPH_CAP_RDCACHE) == 0 ||
            (inode->i_sb->s_flags & MS_SYNCHRONOUS))
@@ -284,8 +284,8 @@ ssize_t ceph_aio_read(struct kiocb *iocb, const struct iovec *iov,
                ret = generic_file_aio_read(iocb, iov, nr_segs, pos);
 
 out:
-       dout(10, "aio_read %llx dropping cap refs on %d\n", ceph_ino(inode),
-            got);
+       dout(10, "aio_read %llx.%llx dropping cap refs on %d\n",
+            ceph_vinop(inode), got);
        ceph_put_cap_refs(ci, got);
        return ret;
 }
index 7e49d949016b6b385e0fbeb3e2540c0c122d96d1..19a3a1fc855838528b96c5f2639f4c0eb928ba8b 100644 (file)
@@ -21,31 +21,27 @@ const struct inode_operations ceph_symlink_iops;
 /*
  * find or create an inode, given the ceph ino number
  */
-struct inode *ceph_get_inode(struct super_block *sb, __u64 ino)
+struct inode *ceph_get_inode(struct super_block *sb, struct ceph_vino vino)
 {
        struct inode *inode;
        struct ceph_inode_info *ci;
-       ino_t inot;
+       ino_t t = ceph_vino_to_ino(vino);
 
-       inot = ceph_ino_to_ino(ino);
-#if BITS_PER_LONG == 64
-       inode = iget_locked(sb, ino);
-#else
-       inode = iget5_locked(sb, inot, ceph_ino_compare, ceph_set_ino_cb, &ino);
-#endif
+       inode = iget5_locked(sb, t, ceph_ino_compare, ceph_set_ino_cb, &vino);
        if (inode == NULL)
                return ERR_PTR(-ENOMEM);
        if (inode->i_state & I_NEW) {
-               dout(40, "get_inode created new inode %p %llx\n", inode,
-                    ceph_ino(inode));
+               dout(40, "get_inode created new inode %p %llx.%llx\n", inode,
+                    ceph_vinop(inode));
                unlock_new_inode(inode);
        }
 
        ci = ceph_inode(inode);
-       ceph_set_ino(inode, ino);
+       ceph_set_ino(inode, vino);
        ci->i_hashval = inode->i_ino;
 
-       dout(30, "get_inode on %lu=%llx got %p\n", inode->i_ino, ino, inode);
+       dout(30, "get_inode on %lu=%llx.%llx got %p\n", inode->i_ino, vino.ino,
+            vino.snap, inode);
        return inode;
 }
 
@@ -112,7 +108,8 @@ retry:
        rb_link_node(&frag->node, parent, p);
        rb_insert_color(&frag->node, &ci->i_fragtree);
 
-       dout(20, "get_frag added %llx frag %x\n", ceph_ino(&ci->vfs_inode), f);
+       dout(20, "get_frag added %llx.%llx frag %x\n",
+            ceph_vinop(&ci->vfs_inode), f);
 
 out:
        kfree(newfrag);
@@ -183,14 +180,14 @@ static int ceph_fill_dirfrag(struct inode *inode,
                        goto out;
                if (frag->split_by == 0) {
                        /* tree leaf, remove */
-                       dout(20, "fill_dirfrag removed %llx frag %x (no ref)\n",
-                            ceph_ino(inode), id);
+                       dout(20, "fill_dirfrag removed %llx.%llx frag %x"
+                            " (no ref)\n", ceph_vinop(inode), id);
                        rb_erase(&frag->node, &ci->i_fragtree);
                        kfree(frag);
                } else {
                        /* tree branch, keep */
-                       dout(20, "fill_dirfrag cleared %llx frag %x referral\n",
-                            ceph_ino(inode), id);
+                       dout(20, "fill_dirfrag cleared %llx.%llx frag %x"
+                            " referral\n", ceph_vinop(inode), id);
                        frag->mds = -1;
                        frag->ndist = 0;
                }
@@ -201,8 +198,8 @@ static int ceph_fill_dirfrag(struct inode *inode,
        /* find/add this frag to store mds delegation info */
        frag = __ceph_get_frag(ci, id);
        if (IS_ERR(frag)) {
-               derr(0, "fill_dirfrag ENOMEM on mds ref ino %llx frag %x\n",
-                    ceph_ino(inode), le32_to_cpu(dirinfo->frag));
+               derr(0, "fill_dirfrag ENOMEM on mds ref %llx.%llx frag %x\n",
+                    ceph_vinop(inode), le32_to_cpu(dirinfo->frag));
                err = -ENOMEM;
                goto out;
        }
@@ -211,8 +208,8 @@ static int ceph_fill_dirfrag(struct inode *inode,
        frag->ndist = min_t(u32, ndist, MAX_DIRFRAG_REP);
        for (i = 0; i < frag->ndist; i++)
                frag->dist[i] = le32_to_cpu(dirinfo->dist[i]);
-       dout(20, "fill_dirfrag %llx frag %x referral mds %d ndist=%d\n",
-            ceph_ino(inode), frag->frag, frag->mds, frag->ndist);
+       dout(20, "fill_dirfrag %llx.%llx frag %x referral mds %d ndist=%d\n",
+            ceph_vinop(inode), frag->frag, frag->mds, frag->ndist);
 
 out:
        spin_unlock(&inode->i_lock);
@@ -362,8 +359,8 @@ no_change:
                u32 id = le32_to_cpu(info->fragtree.splits[i].frag);
                struct ceph_inode_frag *frag = __ceph_get_frag(ci, id);
                if (IS_ERR(frag)) {
-                       derr(0,"ENOMEM on ino %llx frag %x\n",
-                            ceph_ino(inode), id);
+                       derr(0,"ENOMEM on ino %llx.%llx frag %x\n",
+                            ceph_vinop(inode), id);
                        continue;
                }
                frag->split_by =
@@ -635,27 +632,27 @@ static struct dentry *splice_dentry(struct dentry *dn, struct inode *in,
        realdn = d_materialise_unique(dn, in);
        if (IS_ERR(realdn)) {
                derr(0, "error splicing %p (%d) with %p (%d) "
-                    "inode %p ino %llx\n",
+                    "inode %p ino %llx.%llx\n",
                     dn, atomic_read(&dn->d_count),
                     realdn, atomic_read(&realdn->d_count),
                     realdn->d_inode,
-                    ceph_ino(realdn->d_inode));
+                    ceph_vinop(realdn->d_inode));
                if (prehash)
                        *prehash = false; /* don't rehash on error */
                goto out;
        } else if (realdn) {
                dout(10, "dn %p (%d) spliced with %p (%d) "
-                    "inode %p ino %llx\n",
+                    "inode %p ino %llx.%llx\n",
                     dn, atomic_read(&dn->d_count),
                     realdn, atomic_read(&realdn->d_count),
                     realdn->d_inode,
-                    ceph_ino(realdn->d_inode));
+                    ceph_vinop(realdn->d_inode));
                dput(dn);
                dn = realdn;
                ceph_init_dentry(dn);
        } else
-               dout(10, "dn %p attached to %p ino %llx\n",
-                    dn, dn->d_inode, ceph_ino(dn->d_inode));
+               dout(10, "dn %p attached to %p ino %llx.%llx\n",
+                    dn, dn->d_inode, ceph_vinop(dn->d_inode));
        if ((!prehash || *prehash) && d_unhashed(dn))
                d_rehash(dn);
 out:
@@ -684,7 +681,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
        struct inode *in;
        struct ceph_mds_reply_inode *ininfo;
        int d = 0;
-       u64 ino;
+       struct ceph_vino vino;
        int have_icontent = 0;
        bool have_lease = 0;
 
@@ -709,15 +706,16 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
        }
 #endif
 
-       ino = le64_to_cpu(rinfo->trace_in[0].in->ino);
+       vino.ino = le64_to_cpu(rinfo->trace_in[0].in->ino);
+       vino.snap = le64_to_cpu(rinfo->trace_in[0].in->snapid);
        if (likely(dn)) {
                in = dn->d_inode;
                /* trace should start at root, or have only 1 dentry
                 * (if it is in mds stray dir) */
-               WARN_ON(ino != 1 && rinfo->trace_numd != 1);
+               WARN_ON(vino.ino != 1 && rinfo->trace_numd != 1);
        } else {
                /* first reply (i.e. mount) */
-               in = ceph_get_inode(sb, ino);
+               in = ceph_get_inode(sb, vino);
                if (IS_ERR(in))
                        return PTR_ERR(in);
                dn = d_alloc_root(in);
@@ -727,7 +725,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
                }
        }
 
-       if (ino == 1) {
+       if (vino.ino == 1) {
                err = ceph_fill_inode(in, &rinfo->trace_in[0],
                                      rinfo->trace_numd ?
                                      rinfo->trace_dir[0]:0);
@@ -849,19 +847,22 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
 
                /* attach proper inode */
                ininfo = rinfo->trace_in[d+1].in;
+               vino.ino = le64_to_cpu(ininfo->ino);
+               vino.snap = le64_to_cpu(ininfo->snapid);
                if (dn->d_inode) {
-                       if (ceph_ino(dn->d_inode) != le64_to_cpu(ininfo->ino)) {
-                               dout(10, "dn %p wrong inode %p ino %llx\n",
-                                    dn, dn->d_inode, ceph_ino(dn->d_inode));
+                       if (ceph_vino(dn->d_inode).ino != vino.ino ||
+                           ceph_vino(dn->d_inode).snap != vino.snap) {
+                               dout(10, "dn %p wrong inode %p ino %llx.%llx\n",
+                                    dn, dn->d_inode, ceph_vinop(dn->d_inode));
                                d_delete(dn);
                                dput(dn);
                                goto retry_lookup;
                        }
-                       dout(10, "dn %p correct %p ino %llx\n",
-                            dn, dn->d_inode, ceph_ino(dn->d_inode));
+                       dout(10, "dn %p correct %p ino %llx.%llx\n",
+                            dn, dn->d_inode, ceph_vinop(dn->d_inode));
                        in = dn->d_inode;
                } else {
-                       in = ceph_get_inode(dn->d_sb, le64_to_cpu(ininfo->ino));
+                       in = ceph_get_inode(dn->d_sb, vino);
                        if (IS_ERR(in)) {
                                derr(30, "get_inode badness\n");
                                err = PTR_ERR(in);
@@ -931,7 +932,9 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
 
                /* find existing inode */
                ininfo = rinfo->trace_in[d+1].in;
-               in = ceph_get_inode(parent->d_sb, le64_to_cpu(ininfo->ino));
+               vino.ino = le64_to_cpu(ininfo->ino);
+               vino.snap = le64_to_cpu(ininfo->snapid);
+               in = ceph_get_inode(parent->d_sb, vino);
                if (IS_ERR(in)) {
                        derr(30, "ceph_get_inode badness\n");
                        err = PTR_ERR(in);
@@ -996,11 +999,15 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req)
                ceph_fill_dirfrag(parent->d_inode, rinfo->dir_dir);
 
        for (i = 0; i < rinfo->dir_nr; i++) {
+               struct ceph_vino vino;
                /* dentry */
                dname.name = rinfo->dir_dname[i];
-               dname.len = rinfo->dir_dname_len[i];
+               dname.len = le32_to_cpu(rinfo->dir_dname_len[i]);
                dname.hash = full_name_hash(dname.name, dname.len);
 
+               vino.ino = le64_to_cpu(rinfo->dir_in[i].in->ino);
+               vino.snap = le64_to_cpu(rinfo->dir_in[i].in->snapid);
+
 retry_lookup:
                dn = d_lookup(parent, &dname);
                dout(30, "calling d_lookup on parent=%p name=%.*s"
@@ -1016,8 +1023,8 @@ retry_lookup:
                        }
                        ceph_init_dentry(dn);
                } else if (dn->d_inode &&
-                          ceph_ino(dn->d_inode) !=
-                          le64_to_cpu(rinfo->dir_in[i].in->ino)) {
+                          (ceph_vino(dn->d_inode).ino != vino.ino ||
+                           ceph_vino(dn->d_inode).snap != vino.snap)) {
                        dout(10, " dn %p points to wrong inode %p\n",
                             dn, dn->d_inode);
                        d_delete(dn);
@@ -1029,8 +1036,7 @@ retry_lookup:
                if (dn->d_inode)
                        in = dn->d_inode;
                else {
-                       in = ceph_get_inode(parent->d_sb,
-                                           rinfo->dir_in[i].in->ino);
+                       in = ceph_get_inode(parent->d_sb, vino);
                        if (in == NULL) {
                                dout(30, "new_inode badness\n");
                                d_delete(dn);
@@ -1149,8 +1155,8 @@ int ceph_add_cap(struct inode *inode,
                }
        }
 
-       dout(10, "add_cap inode %p (%llx) got cap %xh now %xh seq %d from %d\n",
-            inode, ceph_ino(inode), issued, issued|cap->issued, seq, mds);
+       dout(10, "add_cap inode %p (%llx.%llx) cap %xh now %xh seq %d mds%d\n",
+            inode, ceph_vinop(inode), issued, issued|cap->issued, seq, mds);
        cap->issued |= issued;
        cap->implemented |= issued;
        cap->seq = seq;
@@ -1419,8 +1425,8 @@ int ceph_handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
                 * or we'll be mixing up different instances of caps on the
                 * same inode, and confuse the mds.
                 */
-               dout(10, "no cap on %p ino %llx from mds%d, ignoring\n",
-                    inode, ci->i_ceph_ino, mds);
+               dout(10, "no cap on %p ino %llx.%llx from mds%d, ignoring\n",
+                    inode, ci->i_vino.ino, ci->i_vino.snap, mds);
                goto out;
        }
        dout(10, " cap %p\n", cap);
@@ -1819,11 +1825,11 @@ static struct ceph_mds_request *prepare_setattr(struct ceph_mds_client *mdsc,
        u64 pathbase;
 
        if (ia_valid & ATTR_FILE) {
-               dout(5, "prepare_setattr dentry %p (inode %llx)\n", dentry,
-                    ceph_ino(dentry->d_inode));
+               dout(5, "prepare_setattr dentry %p (inode %llx.%llx)\n", dentry,
+                    ceph_vinop(dentry->d_inode));
                req = ceph_mdsc_create_request(mdsc, op,
-                                              ceph_ino(dentry->d_inode), "",
-                                              0, 0,
+                                              ceph_vino(dentry->d_inode).ino,
+                                              "", 0, 0,
                                               dentry, USE_CAP_MDS);
        } else {
                dout(5, "prepare_setattr dentry %p (full path)\n", dentry);
@@ -2174,8 +2180,8 @@ out:
        return err;
 
 bad:
-       derr(10, "corrupt xattr info on %p %llx\n", dentry->d_inode,
-            ceph_ino(dentry->d_inode));
+       derr(10, "corrupt xattr info on %p %llx.%llx\n", dentry->d_inode,
+            ceph_vinop(dentry->d_inode));
        err = -EIO;
        goto out;
 }
@@ -2240,8 +2246,8 @@ out:
        return err;
 
 bad:
-       derr(10, "corrupt xattr info on %p %llx\n", dentry->d_inode,
-            ceph_ino(dentry->d_inode));
+       derr(10, "corrupt xattr info on %p %llx.%llx\n", dentry->d_inode,
+            ceph_vinop(dentry->d_inode));
        err = -EIO;
        goto out;
 }
index 2dd05f3e9ffea5497fc98908d5e54a1691387369..82b207988a83887aa1fec80b059e431063c4236e 100644 (file)
@@ -468,12 +468,12 @@ static int choose_mds(struct ceph_mds_client *mdsc,
        if (mode == USE_CAP_MDS) {
                mds = ceph_get_cap_mds(dentry->d_inode);
                if (mds >= 0) {
-                       dout(20, "choose_mds %p %llx mds%d (cap)\n",
-                            dentry->d_inode, ceph_ino(dentry->d_inode), mds);
+                       dout(20, "choose_mds %p %llx.%llx mds%d (cap)\n",
+                            dentry->d_inode, ceph_vinop(dentry->d_inode), mds);
                        return mds;
                }
-               derr(0, "choose_mds %p %llx has NO CAPS, using auth\n",
-                    dentry->d_inode, ceph_ino(dentry->d_inode));
+               derr(0, "choose_mds %p %llx.%llx has NO CAPS, using auth\n",
+                    dentry->d_inode, ceph_vinop(dentry->d_inode));
                WARN_ON(1);
                mode = USE_AUTH_MDS;
        }
@@ -498,9 +498,10 @@ static int choose_mds(struct ceph_mds_client *mdsc,
                                        get_random_bytes(&r, 1);
                                        r %= frag->ndist;
                                        mds = frag->dist[r];
-                                       dout(20, "choose_mds %p %llx frag %u "
-                                            "mds%d (%d/%d)\n", dentry->d_inode,
-                                            ceph_ino(&ci->vfs_inode),
+                                       dout(20, "choose_mds %p %llx.%llx "
+                                            "frag %u mds%d (%d/%d)\n",
+                                            dentry->d_inode,
+                                            ceph_vinop(&ci->vfs_inode),
                                             frag->frag, frag->mds,
                                             (int)r, frag->ndist);
                                        return mds;
@@ -508,9 +509,10 @@ static int choose_mds(struct ceph_mds_client *mdsc,
                                mode = USE_AUTH_MDS;
                                if (frag->mds >= 0) {
                                        mds = frag->mds;
-                                       dout(20, "choose_mds %p %llx frag %u "
-                                            "mds%d (auth)\n", dentry->d_inode,
-                                            ceph_ino(&ci->vfs_inode),
+                                       dout(20, "choose_mds %p %llx.%llx "
+                                            "frag %u mds%d (auth)\n",
+                                            dentry->d_inode,
+                                            ceph_vinop(&ci->vfs_inode),
                                             frag->frag, mds);
                                        return mds;
                                }
@@ -1082,8 +1084,11 @@ retry:
        send_msg_mds(mdsc, req->r_request, mds);
        wait_for_completion(&req->r_completion);
        spin_lock(&mdsc->lock);
-       if (req->r_reply == NULL)
+       if (req->r_reply == NULL) {
+               put_session(session);
+               req->r_session = 0;
                goto retry;
+       }
 
        /* clean up request, parse reply */
        __unregister_request(mdsc, req);
@@ -1331,9 +1336,9 @@ retry:
                ceph_decode_need(&p, end, sizeof(u64) +
                                 sizeof(struct ceph_mds_cap_reconnect),
                                 needmore);
-               dout(10, " adding cap %p on ino %llx inode %p\n", cap,
-                    ceph_ino(&ci->vfs_inode), &ci->vfs_inode);
-               ceph_encode_64(&p, ceph_ino(&ci->vfs_inode));
+               dout(10, " adding cap %p on ino %llx.%llx inode %p\n", cap,
+                    ceph_vinop(&ci->vfs_inode), &ci->vfs_inode);
+               ceph_encode_64(&p, ceph_vino(&ci->vfs_inode).ino);
                rec = p;
                p += sizeof(*rec);
                BUG_ON(p > end);
@@ -1501,8 +1506,8 @@ void ceph_mdsc_handle_caps(struct ceph_mds_client *mdsc,
        int mds = le32_to_cpu(msg->hdr.src.name.num);
        int op;
        u32 seq;
-       u64 ino, size, max_size;
-       ino_t inot;
+       struct ceph_vino vino;
+       u64 size, max_size;
 
        dout(10, "handle_caps from mds%d\n", mds);
 
@@ -1511,7 +1516,8 @@ void ceph_mdsc_handle_caps(struct ceph_mds_client *mdsc,
                goto bad;
        h = msg->front.iov_base;
        op = le32_to_cpu(h->op);
-       ino = le64_to_cpu(h->ino);
+       vino.ino = le64_to_cpu(h->ino);
+       vino.snap = CEPH_NOSNAP;
        seq = le32_to_cpu(h->seq);
        size = le64_to_cpu(h->size);
        max_size = le64_to_cpu(h->max_size);
@@ -1529,18 +1535,12 @@ void ceph_mdsc_handle_caps(struct ceph_mds_client *mdsc,
        session->s_seq++;
 
        /* lookup ino */
-       inot = ceph_ino_to_ino(ino);
-#if BITS_PER_LONG == 64
-       inode = ilookup(sb, ino);
-#else
-       inode = ilookup5(sb, inot, ceph_ino_compare, &ino);
-#endif
-       dout(20, "op %d ino %llx inode %p\n", op, ino, inode);
+       inode = ceph_find_inode(sb, vino);
+       dout(20, "op %d ino %llx inode %p\n", op, vino.ino, inode);
 
        if (!inode) {
-               dout(10, "wtf, i don't have ino %lu=%llx?  closing out cap\n",
-                    inot, ino);
-               send_cap_ack(mdsc, ino, 0, 0, seq, size, 0, 0, 0, 0, mds);
+               dout(10, "i don't have ino %llx, sending release\n", vino.ino);
+               send_cap_ack(mdsc, vino.ino, 0, 0, seq, size, 0, 0, 0, 0, mds);
                goto no_inode;
        }
 
@@ -1646,7 +1646,7 @@ int __ceph_mdsc_send_cap(struct ceph_mds_client *mdsc,
                dout(20, "done invalidating pages on %p\n", inode);
        }
 
-       send_cap_ack(mdsc, ceph_ino(inode),
+       send_cap_ack(mdsc, ceph_vino(inode).ino,
                     keep, wanted, seq,
                     size, max_size, &mtime, &atime, time_warp_seq,
                     session->s_mds);
@@ -1756,17 +1756,17 @@ void ceph_mdsc_handle_lease(struct ceph_mds_client *mdsc, struct ceph_msg *msg)
        struct dentry *parent, *dentry;
        int mds = le32_to_cpu(msg->hdr.src.name.num);
        struct ceph_mds_lease *h = msg->front.iov_base;
-       u64 ino;
+       struct ceph_vino vino;
        int mask;
        struct qstr dname;
-       ino_t inot;
 
        dout(10, "handle_lease from mds%d\n", mds);
 
        /* decode */
        if (msg->front.iov_len < sizeof(*h) + sizeof(u32))
                goto bad;
-       ino = le64_to_cpu(h->ino);
+       vino.ino = le64_to_cpu(h->ino);
+       vino.snap = CEPH_NOSNAP;
        mask = le16_to_cpu(h->mask);
        dname.name = (void *)h + sizeof(*h) + sizeof(u32);
        dname.len = msg->front.iov_len - sizeof(*h) - sizeof(u32);
@@ -1786,22 +1786,16 @@ void ceph_mdsc_handle_lease(struct ceph_mds_client *mdsc, struct ceph_msg *msg)
        mutex_lock(&session->s_mutex);
 
        /* lookup inode */
-       inot = ceph_ino_to_ino(ino);
-#if BITS_PER_LONG == 64
-       inode = ilookup(sb, ino);
-#else
-       inode = ilookup5(sb, inot, ceph_ino_compare, &ino);
-#endif
+       inode = ceph_find_inode(sb, vino);
        dout(20, "action is %d, mask %d, ino %llx %p\n", h->action,
-            mask, ino, inode);
-
-       BUG_ON(h->action != CEPH_MDS_LEASE_REVOKE);  /* for now */
-
+            mask, vino.ino, inode);
        if (inode == NULL) {
-               dout(10, "i don't have inode %llx\n", ino);
+               dout(10, "i don't have inode %llx\n", vino.ino);
                goto release;
        }
 
+       BUG_ON(h->action != CEPH_MDS_LEASE_REVOKE);  /* for now */
+
        /* inode */
        ci = ceph_inode(inode);
        revoke_inode_lease(ci, mask);
@@ -1904,7 +1898,7 @@ void ceph_mdsc_lease_release(struct ceph_mds_client *mdsc, struct inode *inode,
        lease = msg->front.iov_base;
        lease->action = CEPH_MDS_LEASE_RELEASE;
        lease->mask = mask;
-       lease->ino = cpu_to_le64(ceph_ino(inode));
+       lease->ino = cpu_to_le64(ceph_vino(inode).ino);
        *(__le32 *)((void *)lease + sizeof(*lease)) = cpu_to_le32(dnamelen);
        if (dentry)
                memcpy((void *)lease + sizeof(*lease) + 4, dentry->d_name.name,
index 82cbdceac9d782ea3c72ae43e3a8410afcb5d4a4..7f4fd0d4d5cfbf468883de90f93206d6af647438 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/completion.h>
 #include <linux/spinlock.h>
 
+#include "types.h"
 #include "messenger.h"
 #include "mdsmap.h"
 
@@ -156,8 +157,8 @@ extern void ceph_mdsc_lease_release(struct ceph_mds_client *mdsc,
 
 extern struct ceph_mds_request *
 ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op,
-                        ceph_ino_t ino1, const char *path1,
-                        ceph_ino_t ino2, const char *path2,
+                        u64 ino1, const char *path1,
+                        u64 ino2, const char *path2,
                         struct dentry *ref, int want_auth);
 extern int ceph_mdsc_do_request(struct ceph_mds_client *mdsc,
                                struct ceph_mds_request *req);
index 776a01f89e8fc301be90e43adb7efde0a66b7dcb..fb29e1d5da9738957ac2afbc0f189c4077a47716 100644 (file)
@@ -550,15 +550,15 @@ void ceph_osdc_stop(struct ceph_osd_client *osdc)
  * object boundary.
  */
 static __u64 calc_layout(struct ceph_osd_client *osdc,
-                        ceph_ino_t ino, struct ceph_file_layout *layout,
+                        struct ceph_vino vino, struct ceph_file_layout *layout,
                         __u64 off, __u64 len,
                         struct ceph_osd_request *req)
 {
        struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base;
        __u64 toff = off, tlen = len;
 
-       reqhead->oid.ino = ino;
-       reqhead->oid.snap = 0;
+       reqhead->oid.ino = vino.ino;
+       reqhead->oid.snap = vino.snap;
 
        calc_file_object_mapping(layout, &toff, &tlen, &reqhead->oid,
                                 &off, &len);
@@ -581,7 +581,7 @@ static __u64 calc_layout(struct ceph_osd_client *osdc,
 /*
  * synchronous read direct to user buffer
  */
-int ceph_osdc_sync_read(struct ceph_osd_client *osdc, ceph_ino_t ino,
+int ceph_osdc_sync_read(struct ceph_osd_client *osdc, struct ceph_vino vino,
                        struct ceph_file_layout *layout,
                        __u64 off, __u64 len,
                        char __user *data)
@@ -591,7 +591,8 @@ int ceph_osdc_sync_read(struct ceph_osd_client *osdc, ceph_ino_t ino,
        int nr_pages, i, po, left, l;
        __s32 rc;
 
-       dout(10, "sync_read on ino %llx at %llu~%llu\n", ino, off, len);
+       dout(10, "sync_read on vino %llx.%llx at %llu~%llu\n", vino.ino,
+            vino.snap, off, len);
 
        /* request msg */
        reqm = new_request_msg(osdc, CEPH_OSD_OP_READ);
@@ -603,7 +604,7 @@ int ceph_osdc_sync_read(struct ceph_osd_client *osdc, ceph_ino_t ino,
        if (IS_ERR(req))
                return PTR_ERR(req);
 
-       len = calc_layout(osdc, ino, layout, off, len, req);
+       len = calc_layout(osdc, vino, layout, off, len, req);
        nr_pages = calc_pages_for(off, len);  /* recalc */
        dout(10, "sync_read %llu~%llu -> %d pages\n", off, len, nr_pages);
 
@@ -658,7 +659,7 @@ out:
 /*
  * read a single page.
  */
-int ceph_osdc_readpage(struct ceph_osd_client *osdc, ceph_ino_t ino,
+int ceph_osdc_readpage(struct ceph_osd_client *osdc, struct ceph_vino vino,
                       struct ceph_file_layout *layout,
                       loff_t off, loff_t len,
                       struct page *page)
@@ -668,7 +669,8 @@ int ceph_osdc_readpage(struct ceph_osd_client *osdc, ceph_ino_t ino,
        struct ceph_osd_request *req;
        __s32 rc;
 
-       dout(10, "readpage on ino %llx at %lld~%lld\n", ino, off, len);
+       dout(10, "readpage on ino %llx.%llx at %lld~%lld\n", vino.ino,
+            vino.snap, off, len);
 
        /* request msg */
        reqm = new_request_msg(osdc, CEPH_OSD_OP_READ);
@@ -683,7 +685,7 @@ int ceph_osdc_readpage(struct ceph_osd_client *osdc, ceph_ino_t ino,
        }
        req->r_pages[0] = page;
 
-       len = calc_layout(osdc, ino, layout, off, len, req);
+       len = calc_layout(osdc, vino, layout, off, len, req);
        BUG_ON(len != PAGE_CACHE_SIZE);
 
        rc = do_request(osdc, req);
@@ -700,7 +702,7 @@ int ceph_osdc_readpage(struct ceph_osd_client *osdc, ceph_ino_t ino,
  */
 int ceph_osdc_readpages(struct ceph_osd_client *osdc,
                        struct address_space *mapping,
-                       ceph_ino_t ino, struct ceph_file_layout *layout,
+                       struct ceph_vino vino, struct ceph_file_layout *layout,
                        __u64 off, __u64 len,
                        struct list_head *page_list, int nr_pages)
 {
@@ -717,7 +719,8 @@ int ceph_osdc_readpages(struct ceph_osd_client *osdc,
         * we can that falls within the range specified by
         * nr_pages.
         */
-       dout(10, "readpages on ino %llx on %llu~%llu\n", ino, off, len);
+       dout(10, "readpages on ino %llx.%llx on %llu~%llu\n", vino.ino,
+            vino.snap, off, len);
 
        /* alloc request, w/ optimistically-sized page vector */
        reqm = new_request_msg(osdc, CEPH_OSD_OP_READ);
@@ -748,7 +751,7 @@ int ceph_osdc_readpages(struct ceph_osd_client *osdc,
        dout(10, "readpages contig page extent is %llu~%llu\n", off, len);
 
        /* request msg */
-       len = calc_layout(osdc, ino, layout, off, len, req);
+       len = calc_layout(osdc, vino, layout, off, len, req);
        req->r_nr_pages = calc_pages_for(off, len);
        dout(10, "readpages final extent is %llu~%llu -> %d pages\n",
             off, len, req->r_nr_pages);
@@ -766,7 +769,7 @@ out:
 /*
  * synchronous write.  from userspace.
  */
-int ceph_osdc_sync_write(struct ceph_osd_client *osdc, ceph_ino_t ino,
+int ceph_osdc_sync_write(struct ceph_osd_client *osdc, struct ceph_vino vino,
                         struct ceph_file_layout *layout,
                         __u64 off, __u64 len, const char __user *data)
 {
@@ -776,7 +779,8 @@ int ceph_osdc_sync_write(struct ceph_osd_client *osdc, ceph_ino_t ino,
        int nr_pages, i, po, l, left;
        __s32 rc;
 
-       dout(10, "sync_write on ino %llx at %llu~%llu\n", ino, off, len);
+       dout(10, "sync_write on ino %llx.%llx at %llu~%llu\n", vino.ino,
+            vino.snap, off, len);
 
        /* request msg */
        reqm = new_request_msg(osdc, CEPH_OSD_OP_WRITE);
@@ -793,7 +797,7 @@ int ceph_osdc_sync_write(struct ceph_osd_client *osdc, ceph_ino_t ino,
                return PTR_ERR(req);
        }
 
-       len = calc_layout(osdc, ino, layout, off, len, req);
+       len = calc_layout(osdc, vino, layout, off, len, req);
        nr_pages = calc_pages_for(off, len);  /* recalc */
        dout(10, "sync_write %llu~%llu -> %d pages\n", off, len, nr_pages);
 
@@ -839,7 +843,7 @@ out:
 /*
  * do a write job for N pages
  */
-int ceph_osdc_writepages(struct ceph_osd_client *osdc, ceph_ino_t ino,
+int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino,
                         struct ceph_file_layout *layout,
                         loff_t off, loff_t len,
                         struct page **pages, int nr_pages)
@@ -849,6 +853,8 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, ceph_ino_t ino,
        struct ceph_osd_request *req;
        int rc = 0;
 
+       BUG_ON(vino.snap != CEPH_NOSNAP);
+
        /* request + msg */
        reqm = new_request_msg(osdc, CEPH_OSD_OP_WRITE);
        if (IS_ERR(reqm))
@@ -865,7 +871,7 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, ceph_ino_t ino,
        else
                reqhead->flags = CEPH_OSD_OP_SAFE;
 
-       len = calc_layout(osdc, ino, layout, off, len, req);
+       len = calc_layout(osdc, vino, layout, off, len, req);
        nr_pages = calc_pages_for(off, len);
        dout(10, "writepages %llu~%llu -> %d pages\n", off, len, nr_pages);
 
index 9c0949069b26a6fb0f56eb928a0d0eeb0409875c..72e942e02721020f800fd1f0482a9f84761e70a5 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/completion.h>
 
 #include "ceph_fs.h"
+#include "types.h"
 #include "osdmap.h"
 
 struct ceph_msg;
@@ -60,46 +61,56 @@ extern void ceph_osdc_handle_map(struct ceph_osd_client *osdc,
                                 struct ceph_msg *msg);
 extern int ceph_osdc_prepare_pages(void *p, struct ceph_msg *m, int want);
 
-extern int ceph_osdc_readpage(struct ceph_osd_client *osdc, ceph_ino_t ino,
+extern int ceph_osdc_readpage(struct ceph_osd_client *osdc,
+                             struct ceph_vino vino,
                              struct ceph_file_layout *layout,
                              loff_t off, loff_t len,
                              struct page *page);
 extern int ceph_osdc_readpages(struct ceph_osd_client *osdc,
                               struct address_space *mapping,
-                              ceph_ino_t ino, struct ceph_file_layout *layout,
+                              struct ceph_vino vino,
+                              struct ceph_file_layout *layout,
                               __u64 off, __u64 len,
                               struct list_head *page_list, int nr_pages);
-extern int ceph_osdc_prepare_write(struct ceph_osd_client *osdc, ceph_ino_t ino,
-                             struct ceph_file_layout *layout,
-                             loff_t off, loff_t len,
-                             struct page *page);
-extern int ceph_osdc_commit_write(struct ceph_osd_client *osdc, ceph_ino_t ino,
-                             struct ceph_file_layout *layout,
-                             loff_t off, loff_t len,
-                             struct page *page);
-extern int ceph_osdc_writepages(struct ceph_osd_client *osdc, ceph_ino_t ino,
+extern int ceph_osdc_prepare_write(struct ceph_osd_client *osdc,
+                                  struct ceph_vino vino,
+                                  struct ceph_file_layout *layout,
+                                  loff_t off, loff_t len,
+                                  struct page *page);
+extern int ceph_osdc_commit_write(struct ceph_osd_client *osdc,
+                                 struct ceph_vino vino,
+                                 struct ceph_file_layout *layout,
+                                 loff_t off, loff_t len,
+                                 struct page *page);
+extern int ceph_osdc_writepages(struct ceph_osd_client *osdc,
+                               struct ceph_vino vino,
                                struct ceph_file_layout *layout,
                                loff_t off, loff_t len,
                                struct page **pagevec, int nr_pages);
 
-extern int ceph_osdc_sync_read(struct ceph_osd_client *osdc, ceph_ino_t ino,
+extern int ceph_osdc_sync_read(struct ceph_osd_client *osdc,
+                              struct ceph_vino vino,
                               struct ceph_file_layout *layout,
                               __u64 off, __u64 len,
                               char __user *data);
-extern int ceph_osdc_sync_write(struct ceph_osd_client *osdc, ceph_ino_t ino,
+extern int ceph_osdc_sync_write(struct ceph_osd_client *osdc,
+                               struct ceph_vino vino,
                                struct ceph_file_layout *layout,
                                __u64 off, __u64 len,
                                const char __user *data);
 
-extern int ceph_osdc_prepare_write(struct ceph_osd_client *osdc, ceph_ino_t ino,
+extern int ceph_osdc_prepare_write(struct ceph_osd_client *osdc,
+                                  struct ceph_vino vino,
                                   struct ceph_file_layout *layout,
                                   loff_t off, loff_t len,
                                   struct page *page);
-extern int ceph_osdc_commit_write(struct ceph_osd_client *osdc, ceph_ino_t ino,
+extern int ceph_osdc_commit_write(struct ceph_osd_client *osdc,
+                                 struct ceph_vino vino,
                                  struct ceph_file_layout *layout,
                                  loff_t off, loff_t len,
                                  struct page *page);
-extern int ceph_osdc_writepage(struct ceph_osd_client *osdc, ceph_ino_t ino,
+extern int ceph_osdc_writepage(struct ceph_osd_client *osdc,
+                              struct ceph_vino vino,
                               struct ceph_file_layout *layout,
                               loff_t off, loff_t len,
                               struct page *page);
index 4280c31901a64710b7c3baac24c3939793b50c82..2cccd990775c59423d99988a552e2337f56e557e 100644 (file)
@@ -46,8 +46,8 @@ 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 %llx .. atime updated\n",
-                    ceph_ino(inode));
+               dout(30, "ceph_write_inode %llx.%llx .. atime updated\n",
+                    ceph_vinop(inode));
                /* eventually push this async to mds ... */
        }
        return 0;
@@ -198,7 +198,7 @@ static void ceph_destroy_inode(struct inode *inode)
        struct ceph_inode_frag *frag;
        struct rb_node *n;
        
-       dout(30, "destroy_inode %p ino %llx\n", inode, ceph_ino(inode));
+       dout(30, "destroy_inode %p ino %llx.%llx\n", inode, ceph_vinop(inode));
        kfree(ci->i_symlink);
        while ((n = rb_first(&ci->i_fragtree)) != 0) {
                frag = rb_entry(n, struct ceph_inode_frag, node);
@@ -927,7 +927,7 @@ static int ceph_get_sb(struct file_system_type *fs_type,
        err = ceph_mount(client, mnt, path);
        if (err < 0)
                goto out_splat;
-       dout(22, "root ino %llx\n", ceph_ino(mnt->mnt_root->d_inode));
+       dout(22, "root ino %llx.%llx\n", ceph_vinop(mnt->mnt_root->d_inode));
        return 0;
 
 out_splat:
index 30b62c5e6260be37bf2621e19e7579443f447c6f..5a9382ad85af713c06572ca97ed33a429e0fe569 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/sysfs.h>
 
 #include "ceph_fs.h"
+#include "types.h"
 #include "messenger.h"
 #include "mon_client.h"
 #include "mds_client.h"
@@ -203,7 +204,8 @@ struct ceph_dir_info {
 };
 
 struct ceph_inode_info {
-       u64 i_ceph_ino;   /* make this ifdef away on 64 bit */
+       struct ceph_vino i_vino;   /* ceph ino + snap */
+       unsigned long i_hashval;
 
        u64 i_version;
        u64 i_time_warp_seq;
@@ -247,7 +249,6 @@ struct ceph_inode_info {
        int i_rd_ref, i_rdcache_ref, i_wr_ref;
        atomic_t i_wrbuffer_ref;
 
-       unsigned long i_hashval;
 
        struct work_struct i_wb_work;  /* writeback work */
 
@@ -304,47 +305,51 @@ static inline void ceph_queue_writeback(struct ceph_client *cl,
 
 
 /*
- * ino_t is <64 bits on many architectures... blech
+ * ino_t is <64 bits on many architectures, blech.
+ * let snapped inos chain up on the same linux ino_t.
  */
-static inline ino_t ceph_ino_to_ino(u64 cephino)
+static inline ino_t ceph_vino_to_ino(struct ceph_vino vino)
 {
-       ino_t ino = (ino_t)cephino;
+       ino_t ino = (ino_t)vino.ino;
 #if BITS_PER_LONG == 32
-       ino ^= cephino >> (sizeof(u64)-sizeof(ino_t)) * 8;
+       ino ^= vino.ino >> (sizeof(u64)-sizeof(ino_t)) * 8;
 #endif
        return ino;
 }
 
-static inline void ceph_set_ino(struct inode *inode, __u64 ino)
+static inline void ceph_set_ino(struct inode *inode, struct ceph_vino vino)
 {
        struct ceph_inode_info *ci = ceph_inode(inode);
-       ci->i_ceph_ino = ino;
-       inode->i_ino = ceph_ino_to_ino(ino);
+       ci->i_vino = vino;
+       inode->i_ino = ceph_vino_to_ino(vino);
 }
 
 static inline int ceph_set_ino_cb(struct inode *inode, void *data)
 {
-       ceph_set_ino(inode, *(__u64 *)data);
+       ceph_set_ino(inode, *(struct ceph_vino *)data);
        return 0;
 }
 
-static inline u64 ceph_ino(struct inode *inode)
+static inline struct ceph_vino ceph_vino(struct inode *inode)
 {
        struct ceph_inode_info *ci = ceph_inode(inode);
-       return ci->i_ceph_ino;
+       return ci->i_vino;
 }
+#define ceph_vinop(i) ceph_inode(i)->i_vino.ino, ceph_inode(i)->i_vino.snap
 
 static inline int ceph_ino_compare(struct inode *inode, void *data)
 {
-       __u64 ino = *(__u64 *)data;
+       struct ceph_vino *pvino = (struct ceph_vino *)data;
        struct ceph_inode_info *ci = ceph_inode(inode);
-       return (ci->i_ceph_ino == ino);
+       return (ci->i_vino.ino == pvino->ino &&
+               ci->i_vino.snap == pvino->snap);
 }
 
-static inline struct inode *ceph_find_inode(struct super_block *sb, __u64 ino)
+static inline struct inode *ceph_find_inode(struct super_block *sb,
+                                           struct ceph_vino vino)
 {
-       ino_t inot = ceph_ino_to_ino(ino);
-       return ilookup5(sb, inot, ceph_ino_compare, &ino);
+       ino_t t = ceph_vino_to_ino(vino);
+       return ilookup5(sb, t, ceph_ino_compare, &vino);
 }
 
 
@@ -438,7 +443,8 @@ extern const char *ceph_msg_type_name(int type);
 /* inode.c */
 extern const struct inode_operations ceph_file_iops;
 extern const struct inode_operations ceph_special_iops;
-extern struct inode *ceph_get_inode(struct super_block *sb, u64 ino);
+extern struct inode *ceph_get_inode(struct super_block *sb,
+                                   struct ceph_vino vino);
 extern int ceph_fill_inode(struct inode *inode,
                           struct ceph_mds_reply_info_in *iinfo,
                           struct ceph_mds_reply_dirfrag *dirinfo);
diff --git a/src/kernel/types.h b/src/kernel/types.h
new file mode 100644 (file)
index 0000000..5cd9292
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef _FS_CEPH_TYPES_H
+#define _FS_CEPH_TYPES_H
+
+struct ceph_vino {
+       u64 ino;
+       u64 snap;
+};
+
+#endif