Merge remote branch 'intel/drm-intel-next' of /ssd/git/drm-next into drm-core-next
[sfrench/cifs-2.6.git] / fs / ceph / dir.c
index f85719310db2f7aa48d15dee2b3b278e5e8375e0..f94ed3c7f6a5a862a3276b4b222231ab4c40e97f 100644 (file)
@@ -266,6 +266,7 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir)
        spin_lock(&inode->i_lock);
        if ((filp->f_pos == 2 || fi->dentry) &&
            !ceph_test_opt(client, NOASYNCREADDIR) &&
+           ceph_snap(inode) != CEPH_SNAPDIR &&
            (ci->i_ceph_flags & CEPH_I_COMPLETE) &&
            __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1)) {
                err = __dcache_readdir(filp, dirent, filldir);
@@ -1013,18 +1014,22 @@ out_touch:
 
 /*
  * When a dentry is released, clear the dir I_COMPLETE if it was part
- * of the current dir gen.
+ * of the current dir gen or if this is in the snapshot namespace.
  */
 static void ceph_dentry_release(struct dentry *dentry)
 {
        struct ceph_dentry_info *di = ceph_dentry(dentry);
        struct inode *parent_inode = dentry->d_parent->d_inode;
+       u64 snapid = ceph_snap(parent_inode);
 
-       if (parent_inode) {
+       dout("dentry_release %p parent %p\n", dentry, parent_inode);
+
+       if (parent_inode && snapid != CEPH_SNAPDIR) {
                struct ceph_inode_info *ci = ceph_inode(parent_inode);
 
                spin_lock(&parent_inode->i_lock);
-               if (ci->i_shared_gen == di->lease_shared_gen) {
+               if (ci->i_shared_gen == di->lease_shared_gen ||
+                   snapid <= CEPH_MAXSNAP) {
                        dout(" clearing %p complete (d_release)\n",
                             parent_inode);
                        ci->i_ceph_flags &= ~CEPH_I_COMPLETE;
@@ -1241,7 +1246,9 @@ struct dentry_operations ceph_dentry_ops = {
 
 struct dentry_operations ceph_snapdir_dentry_ops = {
        .d_revalidate = ceph_snapdir_d_revalidate,
+       .d_release = ceph_dentry_release,
 };
 
 struct dentry_operations ceph_snap_dentry_ops = {
+       .d_release = ceph_dentry_release,
 };