diff options
Diffstat (limited to 'fs/nfs/namespace.c')
-rw-r--r-- | fs/nfs/namespace.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index db6aa3673cf3..74aaf3963c10 100644 --- a/fs/nfs/namespace.c +++ b/fs/nfs/namespace.c | |||
@@ -49,12 +49,17 @@ char *nfs_path(const char *base, | |||
49 | const struct dentry *dentry, | 49 | const struct dentry *dentry, |
50 | char *buffer, ssize_t buflen) | 50 | char *buffer, ssize_t buflen) |
51 | { | 51 | { |
52 | char *end = buffer+buflen; | 52 | char *end; |
53 | int namelen; | 53 | int namelen; |
54 | unsigned seq; | ||
54 | 55 | ||
56 | rename_retry: | ||
57 | end = buffer+buflen; | ||
55 | *--end = '\0'; | 58 | *--end = '\0'; |
56 | buflen--; | 59 | buflen--; |
57 | spin_lock(&dcache_lock); | 60 | |
61 | seq = read_seqbegin(&rename_lock); | ||
62 | rcu_read_lock(); | ||
58 | while (!IS_ROOT(dentry) && dentry != droot) { | 63 | while (!IS_ROOT(dentry) && dentry != droot) { |
59 | namelen = dentry->d_name.len; | 64 | namelen = dentry->d_name.len; |
60 | buflen -= namelen + 1; | 65 | buflen -= namelen + 1; |
@@ -65,7 +70,9 @@ char *nfs_path(const char *base, | |||
65 | *--end = '/'; | 70 | *--end = '/'; |
66 | dentry = dentry->d_parent; | 71 | dentry = dentry->d_parent; |
67 | } | 72 | } |
68 | spin_unlock(&dcache_lock); | 73 | rcu_read_unlock(); |
74 | if (read_seqretry(&rename_lock, seq)) | ||
75 | goto rename_retry; | ||
69 | if (*end != '/') { | 76 | if (*end != '/') { |
70 | if (--buflen < 0) | 77 | if (--buflen < 0) |
71 | goto Elong; | 78 | goto Elong; |
@@ -82,7 +89,9 @@ char *nfs_path(const char *base, | |||
82 | memcpy(end, base, namelen); | 89 | memcpy(end, base, namelen); |
83 | return end; | 90 | return end; |
84 | Elong_unlock: | 91 | Elong_unlock: |
85 | spin_unlock(&dcache_lock); | 92 | rcu_read_unlock(); |
93 | if (read_seqretry(&rename_lock, seq)) | ||
94 | goto rename_retry; | ||
86 | Elong: | 95 | Elong: |
87 | return ERR_PTR(-ENAMETOOLONG); | 96 | return ERR_PTR(-ENAMETOOLONG); |
88 | } | 97 | } |