diff options
Diffstat (limited to 'fs/reiserfs/namei.c')
-rw-r--r-- | fs/reiserfs/namei.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 271579128634..e296ff72a6cc 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c | |||
@@ -324,6 +324,7 @@ static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry, | |||
324 | struct nameidata *nd) | 324 | struct nameidata *nd) |
325 | { | 325 | { |
326 | int retval; | 326 | int retval; |
327 | int lock_depth; | ||
327 | struct inode *inode = NULL; | 328 | struct inode *inode = NULL; |
328 | struct reiserfs_dir_entry de; | 329 | struct reiserfs_dir_entry de; |
329 | INITIALIZE_PATH(path_to_entry); | 330 | INITIALIZE_PATH(path_to_entry); |
@@ -331,7 +332,13 @@ static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry, | |||
331 | if (REISERFS_MAX_NAME(dir->i_sb->s_blocksize) < dentry->d_name.len) | 332 | if (REISERFS_MAX_NAME(dir->i_sb->s_blocksize) < dentry->d_name.len) |
332 | return ERR_PTR(-ENAMETOOLONG); | 333 | return ERR_PTR(-ENAMETOOLONG); |
333 | 334 | ||
334 | reiserfs_write_lock(dir->i_sb); | 335 | /* |
336 | * Might be called with or without the write lock, must be careful | ||
337 | * to not recursively hold it in case we want to release the lock | ||
338 | * before rescheduling. | ||
339 | */ | ||
340 | lock_depth = reiserfs_write_lock_once(dir->i_sb); | ||
341 | |||
335 | de.de_gen_number_bit_string = NULL; | 342 | de.de_gen_number_bit_string = NULL; |
336 | retval = | 343 | retval = |
337 | reiserfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, | 344 | reiserfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, |
@@ -341,7 +348,7 @@ static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry, | |||
341 | inode = reiserfs_iget(dir->i_sb, | 348 | inode = reiserfs_iget(dir->i_sb, |
342 | (struct cpu_key *)&(de.de_dir_id)); | 349 | (struct cpu_key *)&(de.de_dir_id)); |
343 | if (!inode || IS_ERR(inode)) { | 350 | if (!inode || IS_ERR(inode)) { |
344 | reiserfs_write_unlock(dir->i_sb); | 351 | reiserfs_write_unlock_once(dir->i_sb, lock_depth); |
345 | return ERR_PTR(-EACCES); | 352 | return ERR_PTR(-EACCES); |
346 | } | 353 | } |
347 | 354 | ||
@@ -350,7 +357,7 @@ static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry, | |||
350 | if (IS_PRIVATE(dir)) | 357 | if (IS_PRIVATE(dir)) |
351 | inode->i_flags |= S_PRIVATE; | 358 | inode->i_flags |= S_PRIVATE; |
352 | } | 359 | } |
353 | reiserfs_write_unlock(dir->i_sb); | 360 | reiserfs_write_unlock_once(dir->i_sb, lock_depth); |
354 | if (retval == IO_ERROR) { | 361 | if (retval == IO_ERROR) { |
355 | return ERR_PTR(-EIO); | 362 | return ERR_PTR(-EIO); |
356 | } | 363 | } |
@@ -725,6 +732,7 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
725 | struct inode *inode; | 732 | struct inode *inode; |
726 | struct reiserfs_transaction_handle th; | 733 | struct reiserfs_transaction_handle th; |
727 | struct reiserfs_security_handle security; | 734 | struct reiserfs_security_handle security; |
735 | int lock_depth; | ||
728 | /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */ | 736 | /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */ |
729 | int jbegin_count = | 737 | int jbegin_count = |
730 | JOURNAL_PER_BALANCE_CNT * 3 + | 738 | JOURNAL_PER_BALANCE_CNT * 3 + |
@@ -748,7 +756,7 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
748 | return retval; | 756 | return retval; |
749 | } | 757 | } |
750 | jbegin_count += retval; | 758 | jbegin_count += retval; |
751 | reiserfs_write_lock(dir->i_sb); | 759 | lock_depth = reiserfs_write_lock_once(dir->i_sb); |
752 | 760 | ||
753 | retval = journal_begin(&th, dir->i_sb, jbegin_count); | 761 | retval = journal_begin(&th, dir->i_sb, jbegin_count); |
754 | if (retval) { | 762 | if (retval) { |
@@ -798,8 +806,8 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
798 | d_instantiate(dentry, inode); | 806 | d_instantiate(dentry, inode); |
799 | unlock_new_inode(inode); | 807 | unlock_new_inode(inode); |
800 | retval = journal_end(&th, dir->i_sb, jbegin_count); | 808 | retval = journal_end(&th, dir->i_sb, jbegin_count); |
801 | out_failed: | 809 | out_failed: |
802 | reiserfs_write_unlock(dir->i_sb); | 810 | reiserfs_write_unlock_once(dir->i_sb, lock_depth); |
803 | return retval; | 811 | return retval; |
804 | } | 812 | } |
805 | 813 | ||