]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - fs/ocfs2/export.c
Merge tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / fs / ocfs2 / export.c
index 4bf8d5854b2711ebcac47c5c1f38d49f120d0eb5..af2888d23de38fbc59270f21a7322118bbb7810e 100644 (file)
@@ -148,16 +148,24 @@ static struct dentry *ocfs2_get_parent(struct dentry *child)
        u64 blkno;
        struct dentry *parent;
        struct inode *dir = d_inode(child);
+       int set;
 
        trace_ocfs2_get_parent(child, child->d_name.len, child->d_name.name,
                               (unsigned long long)OCFS2_I(dir)->ip_blkno);
 
+       status = ocfs2_nfs_sync_lock(OCFS2_SB(dir->i_sb), 1);
+       if (status < 0) {
+               mlog(ML_ERROR, "getting nfs sync lock(EX) failed %d\n", status);
+               parent = ERR_PTR(status);
+               goto bail;
+       }
+
        status = ocfs2_inode_lock(dir, NULL, 0);
        if (status < 0) {
                if (status != -ENOENT)
                        mlog_errno(status);
                parent = ERR_PTR(status);
-               goto bail;
+               goto unlock_nfs_sync;
        }
 
        status = ocfs2_lookup_ino_from_name(dir, "..", 2, &blkno);
@@ -166,11 +174,31 @@ static struct dentry *ocfs2_get_parent(struct dentry *child)
                goto bail_unlock;
        }
 
+       status = ocfs2_test_inode_bit(OCFS2_SB(dir->i_sb), blkno, &set);
+       if (status < 0) {
+               if (status == -EINVAL) {
+                       status = -ESTALE;
+               } else
+                       mlog(ML_ERROR, "test inode bit failed %d\n", status);
+               parent = ERR_PTR(status);
+               goto bail_unlock;
+       }
+
+       trace_ocfs2_get_dentry_test_bit(status, set);
+       if (!set) {
+               status = -ESTALE;
+               parent = ERR_PTR(status);
+               goto bail_unlock;
+       }
+
        parent = d_obtain_alias(ocfs2_iget(OCFS2_SB(dir->i_sb), blkno, 0, 0));
 
 bail_unlock:
        ocfs2_inode_unlock(dir, 0);
 
+unlock_nfs_sync:
+       ocfs2_nfs_sync_unlock(OCFS2_SB(dir->i_sb), 1);
+
 bail:
        trace_ocfs2_get_parent_end(parent);