ceph: use atomic_t for ceph_inode_info::i_shared_gen
[linux-2.6-block.git] / fs / ceph / dir.c
index 8a5266699b67657b0ea9053a03fe0ed255abb293..d671d58768282310fd38dd8b2dde991066f6eaf1 100644 (file)
@@ -173,7 +173,7 @@ __dcache_find_get_entry(struct dentry *parent, u64 idx,
  * the MDS if/when the directory is modified).
  */
 static int __dcache_readdir(struct file *file,  struct dir_context *ctx,
-                           u32 shared_gen)
+                           int shared_gen)
 {
        struct ceph_file_info *fi = file->private_data;
        struct dentry *parent = file->f_path.dentry;
@@ -184,7 +184,7 @@ static int __dcache_readdir(struct file *file,  struct dir_context *ctx,
        u64 idx = 0;
        int err = 0;
 
-       dout("__dcache_readdir %p v%u at %llx\n", dir, shared_gen, ctx->pos);
+       dout("__dcache_readdir %p v%u at %llx\n", dir, (unsigned)shared_gen, ctx->pos);
 
        /* search start position */
        if (ctx->pos > 2) {
@@ -333,7 +333,7 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx)
            ceph_snap(inode) != CEPH_SNAPDIR &&
            __ceph_dir_is_complete_ordered(ci) &&
            __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1)) {
-               u32 shared_gen = ci->i_shared_gen;
+               int shared_gen = atomic_read(&ci->i_shared_gen);
                spin_unlock(&ci->i_ceph_lock);
                err = __dcache_readdir(file, ctx, shared_gen);
                if (err != -EAGAIN)
@@ -381,6 +381,7 @@ more:
                if (op == CEPH_MDS_OP_READDIR) {
                        req->r_direct_hash = ceph_frag_value(frag);
                        __set_bit(CEPH_MDS_R_DIRECT_IS_HASH, &req->r_req_flags);
+                       req->r_inode_drop = CEPH_CAP_FILE_EXCL;
                }
                if (fi->last_name) {
                        req->r_path2 = kstrdup(fi->last_name, GFP_KERNEL);
@@ -750,7 +751,7 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry,
                        spin_unlock(&ci->i_ceph_lock);
                        dout(" dir %p complete, -ENOENT\n", dir);
                        d_add(dentry, NULL);
-                       di->lease_shared_gen = ci->i_shared_gen;
+                       di->lease_shared_gen = atomic_read(&ci->i_shared_gen);
                        return NULL;
                }
                spin_unlock(&ci->i_ceph_lock);
@@ -835,7 +836,7 @@ static int ceph_mknod(struct inode *dir, struct dentry *dentry,
        set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
        req->r_args.mknod.mode = cpu_to_le32(mode);
        req->r_args.mknod.rdev = cpu_to_le32(rdev);
-       req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+       req->r_dentry_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_AUTH_EXCL;
        req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
        if (acls.pagelist) {
                req->r_pagelist = acls.pagelist;
@@ -887,7 +888,7 @@ static int ceph_symlink(struct inode *dir, struct dentry *dentry,
        set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
        req->r_dentry = dget(dentry);
        req->r_num_caps = 2;
-       req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+       req->r_dentry_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_AUTH_EXCL;
        req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
        err = ceph_mdsc_do_request(mdsc, dir, req);
        if (!err && !req->r_reply_info.head->is_dentry)
@@ -936,7 +937,7 @@ static int ceph_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
        req->r_parent = dir;
        set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
        req->r_args.mkdir.mode = cpu_to_le32(mode);
-       req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+       req->r_dentry_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_AUTH_EXCL;
        req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
        if (acls.pagelist) {
                req->r_pagelist = acls.pagelist;
@@ -983,7 +984,7 @@ static int ceph_link(struct dentry *old_dentry, struct inode *dir,
        req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
        req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
        /* release LINK_SHARED on source inode (mds will lock it) */
-       req->r_old_inode_drop = CEPH_CAP_LINK_SHARED;
+       req->r_old_inode_drop = CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL;
        err = ceph_mdsc_do_request(mdsc, dir, req);
        if (err) {
                d_drop(dentry);
@@ -1096,7 +1097,7 @@ static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry,
        req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
        req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
        /* release LINK_RDCACHE on source inode (mds will lock it) */
-       req->r_old_inode_drop = CEPH_CAP_LINK_SHARED;
+       req->r_old_inode_drop = CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL;
        if (d_really_is_positive(new_dentry))
                req->r_inode_drop = drop_caps_for_unlink(d_inode(new_dentry));
        err = ceph_mdsc_do_request(mdsc, old_dir, req);
@@ -1106,16 +1107,7 @@ static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry,
                 * do_request, above).  If there is no trace, we need
                 * to do it here.
                 */
-
-               /* d_move screws up sibling dentries' offsets */
-               ceph_dir_clear_complete(old_dir);
-               ceph_dir_clear_complete(new_dir);
-
                d_move(old_dentry, new_dentry);
-
-               /* ensure target dentry is invalidated, despite
-                  rehashing bug in vfs_rename_dir */
-               ceph_invalidate_dentry_lease(new_dentry);
        }
        ceph_mdsc_put_request(req);
        return err;
@@ -1199,12 +1191,12 @@ static int dir_lease_is_valid(struct inode *dir, struct dentry *dentry)
        int valid = 0;
 
        spin_lock(&ci->i_ceph_lock);
-       if (ci->i_shared_gen == di->lease_shared_gen)
+       if (atomic_read(&ci->i_shared_gen) == di->lease_shared_gen)
                valid = __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1);
        spin_unlock(&ci->i_ceph_lock);
        dout("dir_lease_is_valid dir %p v%u dentry %p v%u = %d\n",
-            dir, (unsigned)ci->i_shared_gen, dentry,
-            (unsigned)di->lease_shared_gen, valid);
+            dir, (unsigned)atomic_read(&ci->i_shared_gen),
+            dentry, (unsigned)di->lease_shared_gen, valid);
        return valid;
 }