]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/staging/pohmelfs/path_entry.c
Merge tag 'v2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / drivers / staging / pohmelfs / path_entry.c
index 8ec83d2dffb75ec23c67d35cce2c5ee272943c1a..400a9fc386ad5a399770dd7bc92ce757de18c288 100644 (file)
@@ -83,10 +83,11 @@ out:
 int pohmelfs_path_length(struct pohmelfs_inode *pi)
 {
        struct dentry *d, *root, *first;
-       int len = 1; /* Root slash */
+       int len;
+       unsigned seq;
 
-       first = d = d_find_alias(&pi->vfs_inode);
-       if (!d) {
+       first = d_find_alias(&pi->vfs_inode);
+       if (!first) {
                dprintk("%s: ino: %llu, mode: %o.\n", __func__, pi->ino, pi->vfs_inode.i_mode);
                return -ENOENT;
        }
@@ -95,7 +96,11 @@ int pohmelfs_path_length(struct pohmelfs_inode *pi)
        root = dget(current->fs->root.dentry);
        spin_unlock(&current->fs->lock);
 
-       spin_lock(&dcache_lock);
+rename_retry:
+       len = 1; /* Root slash */
+       d = first;
+       seq = read_seqbegin(&rename_lock);
+       rcu_read_lock();
 
        if (!IS_ROOT(d) && d_unhashed(d))
                len += UNHASHED_OBSCURE_STRING_SIZE; /* Obscure " (deleted)" string */
@@ -104,7 +109,9 @@ int pohmelfs_path_length(struct pohmelfs_inode *pi)
                len += d->d_name.len + 1; /* Plus slash */
                d = d->d_parent;
        }
-       spin_unlock(&dcache_lock);
+       rcu_read_unlock();
+       if (read_seqretry(&rename_lock, seq))
+               goto rename_retry;
 
        dput(root);
        dput(first);