aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/dcache.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 91e551b5af59..dddc67fed732 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -2869,6 +2869,16 @@ static int prepend_unreachable(char **buffer, int *buflen)
2869 return prepend(buffer, buflen, "(unreachable)", 13); 2869 return prepend(buffer, buflen, "(unreachable)", 13);
2870} 2870}
2871 2871
2872static void get_fs_root_rcu(struct fs_struct *fs, struct path *root)
2873{
2874 unsigned seq;
2875
2876 do {
2877 seq = read_seqcount_begin(&fs->seq);
2878 *root = fs->root;
2879 } while (read_seqcount_retry(&fs->seq, seq));
2880}
2881
2872/** 2882/**
2873 * d_path - return the path of a dentry 2883 * d_path - return the path of a dentry
2874 * @path: path to report 2884 * @path: path to report
@@ -2901,13 +2911,15 @@ char *d_path(const struct path *path, char *buf, int buflen)
2901 if (path->dentry->d_op && path->dentry->d_op->d_dname) 2911 if (path->dentry->d_op && path->dentry->d_op->d_dname)
2902 return path->dentry->d_op->d_dname(path->dentry, buf, buflen); 2912 return path->dentry->d_op->d_dname(path->dentry, buf, buflen);
2903 2913
2904 get_fs_root(current->fs, &root); 2914 rcu_read_lock();
2915 get_fs_root_rcu(current->fs, &root);
2905 br_read_lock(&vfsmount_lock); 2916 br_read_lock(&vfsmount_lock);
2906 error = path_with_deleted(path, &root, &res, &buflen); 2917 error = path_with_deleted(path, &root, &res, &buflen);
2907 br_read_unlock(&vfsmount_lock); 2918 br_read_unlock(&vfsmount_lock);
2919 rcu_read_unlock();
2920
2908 if (error < 0) 2921 if (error < 0)
2909 res = ERR_PTR(error); 2922 res = ERR_PTR(error);
2910 path_put(&root);
2911 return res; 2923 return res;
2912} 2924}
2913EXPORT_SYMBOL(d_path); 2925EXPORT_SYMBOL(d_path);