diff options
Diffstat (limited to 'fs/smbfs/proc.c')
-rw-r--r-- | fs/smbfs/proc.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/fs/smbfs/proc.c b/fs/smbfs/proc.c index 71c29b6670b4..7b0c74971ad4 100644 --- a/fs/smbfs/proc.c +++ b/fs/smbfs/proc.c | |||
@@ -332,6 +332,7 @@ static int smb_build_path(struct smb_sb_info *server, unsigned char *buf, | |||
332 | * and store it in reversed order [see reverse_string()] | 332 | * and store it in reversed order [see reverse_string()] |
333 | */ | 333 | */ |
334 | dget(entry); | 334 | dget(entry); |
335 | again: | ||
335 | spin_lock(&entry->d_lock); | 336 | spin_lock(&entry->d_lock); |
336 | while (!IS_ROOT(entry)) { | 337 | while (!IS_ROOT(entry)) { |
337 | struct dentry *parent; | 338 | struct dentry *parent; |
@@ -350,6 +351,7 @@ static int smb_build_path(struct smb_sb_info *server, unsigned char *buf, | |||
350 | dput(entry); | 351 | dput(entry); |
351 | return len; | 352 | return len; |
352 | } | 353 | } |
354 | |||
353 | reverse_string(path, len); | 355 | reverse_string(path, len); |
354 | path += len; | 356 | path += len; |
355 | if (unicode) { | 357 | if (unicode) { |
@@ -361,7 +363,11 @@ static int smb_build_path(struct smb_sb_info *server, unsigned char *buf, | |||
361 | maxlen -= len+1; | 363 | maxlen -= len+1; |
362 | 364 | ||
363 | parent = entry->d_parent; | 365 | parent = entry->d_parent; |
364 | dget(parent); | 366 | if (!spin_trylock(&parent->d_lock)) { |
367 | spin_unlock(&entry->d_lock); | ||
368 | goto again; | ||
369 | } | ||
370 | dget_dlock(parent); | ||
365 | spin_unlock(&entry->d_lock); | 371 | spin_unlock(&entry->d_lock); |
366 | dput(entry); | 372 | dput(entry); |
367 | entry = parent; | 373 | entry = parent; |