diff options
author | David Howells <dhowells@redhat.com> | 2006-12-05 12:01:28 -0500 |
---|---|---|
committer | David Howells <dhowells@warthog.cambridge.redhat.com> | 2006-12-05 12:01:28 -0500 |
commit | 9db73724453a9350e1c22dbe732d427e2939a5c9 (patch) | |
tree | 15e3ead6413ae97398a54292acc199bee0864d42 /fs/ocfs2/namei.c | |
parent | 4c1ac1b49122b805adfa4efc620592f68dccf5db (diff) | |
parent | e62438630ca37539c8cc1553710bbfaa3cf960a7 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
drivers/ata/libata-scsi.c
include/linux/libata.h
Futher merge of Linus's head and compilation fixups.
Signed-Off-By: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/ocfs2/namei.c')
-rw-r--r-- | fs/ocfs2/namei.c | 296 |
1 files changed, 154 insertions, 142 deletions
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index a57b751d4f40..21db45ddf144 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
@@ -75,12 +75,12 @@ static int inline ocfs2_search_dirblock(struct buffer_head *bh, | |||
75 | unsigned long offset, | 75 | unsigned long offset, |
76 | struct ocfs2_dir_entry **res_dir); | 76 | struct ocfs2_dir_entry **res_dir); |
77 | 77 | ||
78 | static int ocfs2_delete_entry(struct ocfs2_journal_handle *handle, | 78 | static int ocfs2_delete_entry(handle_t *handle, |
79 | struct inode *dir, | 79 | struct inode *dir, |
80 | struct ocfs2_dir_entry *de_del, | 80 | struct ocfs2_dir_entry *de_del, |
81 | struct buffer_head *bh); | 81 | struct buffer_head *bh); |
82 | 82 | ||
83 | static int __ocfs2_add_entry(struct ocfs2_journal_handle *handle, | 83 | static int __ocfs2_add_entry(handle_t *handle, |
84 | struct inode *dir, | 84 | struct inode *dir, |
85 | const char *name, int namelen, | 85 | const char *name, int namelen, |
86 | struct inode *inode, u64 blkno, | 86 | struct inode *inode, u64 blkno, |
@@ -93,43 +93,37 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, | |||
93 | dev_t dev, | 93 | dev_t dev, |
94 | struct buffer_head **new_fe_bh, | 94 | struct buffer_head **new_fe_bh, |
95 | struct buffer_head *parent_fe_bh, | 95 | struct buffer_head *parent_fe_bh, |
96 | struct ocfs2_journal_handle *handle, | 96 | handle_t *handle, |
97 | struct inode **ret_inode, | 97 | struct inode **ret_inode, |
98 | struct ocfs2_alloc_context *inode_ac); | 98 | struct ocfs2_alloc_context *inode_ac); |
99 | 99 | ||
100 | static int ocfs2_fill_new_dir(struct ocfs2_super *osb, | 100 | static int ocfs2_fill_new_dir(struct ocfs2_super *osb, |
101 | struct ocfs2_journal_handle *handle, | 101 | handle_t *handle, |
102 | struct inode *parent, | 102 | struct inode *parent, |
103 | struct inode *inode, | 103 | struct inode *inode, |
104 | struct buffer_head *fe_bh, | 104 | struct buffer_head *fe_bh, |
105 | struct ocfs2_alloc_context *data_ac); | 105 | struct ocfs2_alloc_context *data_ac); |
106 | 106 | ||
107 | static int ocfs2_double_lock(struct ocfs2_super *osb, | ||
108 | struct ocfs2_journal_handle *handle, | ||
109 | struct buffer_head **bh1, | ||
110 | struct inode *inode1, | ||
111 | struct buffer_head **bh2, | ||
112 | struct inode *inode2); | ||
113 | |||
114 | static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, | 107 | static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, |
115 | struct ocfs2_journal_handle *handle, | 108 | struct inode **ret_orphan_dir, |
116 | struct inode *inode, | 109 | struct inode *inode, |
117 | char *name, | 110 | char *name, |
118 | struct buffer_head **de_bh); | 111 | struct buffer_head **de_bh); |
119 | 112 | ||
120 | static int ocfs2_orphan_add(struct ocfs2_super *osb, | 113 | static int ocfs2_orphan_add(struct ocfs2_super *osb, |
121 | struct ocfs2_journal_handle *handle, | 114 | handle_t *handle, |
122 | struct inode *inode, | 115 | struct inode *inode, |
123 | struct ocfs2_dinode *fe, | 116 | struct ocfs2_dinode *fe, |
124 | char *name, | 117 | char *name, |
125 | struct buffer_head *de_bh); | 118 | struct buffer_head *de_bh, |
119 | struct inode *orphan_dir_inode); | ||
126 | 120 | ||
127 | static int ocfs2_create_symlink_data(struct ocfs2_super *osb, | 121 | static int ocfs2_create_symlink_data(struct ocfs2_super *osb, |
128 | struct ocfs2_journal_handle *handle, | 122 | handle_t *handle, |
129 | struct inode *inode, | 123 | struct inode *inode, |
130 | const char *symname); | 124 | const char *symname); |
131 | 125 | ||
132 | static inline int ocfs2_add_entry(struct ocfs2_journal_handle *handle, | 126 | static inline int ocfs2_add_entry(handle_t *handle, |
133 | struct dentry *dentry, | 127 | struct dentry *dentry, |
134 | struct inode *inode, u64 blkno, | 128 | struct inode *inode, u64 blkno, |
135 | struct buffer_head *parent_fe_bh, | 129 | struct buffer_head *parent_fe_bh, |
@@ -165,7 +159,7 @@ static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry, | |||
165 | mlog(0, "find name %.*s in directory %llu\n", dentry->d_name.len, | 159 | mlog(0, "find name %.*s in directory %llu\n", dentry->d_name.len, |
166 | dentry->d_name.name, (unsigned long long)OCFS2_I(dir)->ip_blkno); | 160 | dentry->d_name.name, (unsigned long long)OCFS2_I(dir)->ip_blkno); |
167 | 161 | ||
168 | status = ocfs2_meta_lock(dir, NULL, NULL, 0); | 162 | status = ocfs2_meta_lock(dir, NULL, 0); |
169 | if (status < 0) { | 163 | if (status < 0) { |
170 | if (status != -ENOENT) | 164 | if (status != -ENOENT) |
171 | mlog_errno(status); | 165 | mlog_errno(status); |
@@ -242,7 +236,7 @@ bail: | |||
242 | } | 236 | } |
243 | 237 | ||
244 | static int ocfs2_fill_new_dir(struct ocfs2_super *osb, | 238 | static int ocfs2_fill_new_dir(struct ocfs2_super *osb, |
245 | struct ocfs2_journal_handle *handle, | 239 | handle_t *handle, |
246 | struct inode *parent, | 240 | struct inode *parent, |
247 | struct inode *inode, | 241 | struct inode *inode, |
248 | struct buffer_head *fe_bh, | 242 | struct buffer_head *fe_bh, |
@@ -317,7 +311,7 @@ static int ocfs2_mknod(struct inode *dir, | |||
317 | { | 311 | { |
318 | int status = 0; | 312 | int status = 0; |
319 | struct buffer_head *parent_fe_bh = NULL; | 313 | struct buffer_head *parent_fe_bh = NULL; |
320 | struct ocfs2_journal_handle *handle = NULL; | 314 | handle_t *handle = NULL; |
321 | struct ocfs2_super *osb; | 315 | struct ocfs2_super *osb; |
322 | struct ocfs2_dinode *dirfe; | 316 | struct ocfs2_dinode *dirfe; |
323 | struct buffer_head *new_fe_bh = NULL; | 317 | struct buffer_head *new_fe_bh = NULL; |
@@ -333,18 +327,11 @@ static int ocfs2_mknod(struct inode *dir, | |||
333 | /* get our super block */ | 327 | /* get our super block */ |
334 | osb = OCFS2_SB(dir->i_sb); | 328 | osb = OCFS2_SB(dir->i_sb); |
335 | 329 | ||
336 | handle = ocfs2_alloc_handle(osb); | 330 | status = ocfs2_meta_lock(dir, &parent_fe_bh, 1); |
337 | if (handle == NULL) { | ||
338 | status = -ENOMEM; | ||
339 | mlog_errno(status); | ||
340 | goto leave; | ||
341 | } | ||
342 | |||
343 | status = ocfs2_meta_lock(dir, handle, &parent_fe_bh, 1); | ||
344 | if (status < 0) { | 331 | if (status < 0) { |
345 | if (status != -ENOENT) | 332 | if (status != -ENOENT) |
346 | mlog_errno(status); | 333 | mlog_errno(status); |
347 | goto leave; | 334 | return status; |
348 | } | 335 | } |
349 | 336 | ||
350 | if (S_ISDIR(mode) && (dir->i_nlink >= OCFS2_LINK_MAX)) { | 337 | if (S_ISDIR(mode) && (dir->i_nlink >= OCFS2_LINK_MAX)) { |
@@ -374,7 +361,7 @@ static int ocfs2_mknod(struct inode *dir, | |||
374 | } | 361 | } |
375 | 362 | ||
376 | /* reserve an inode spot */ | 363 | /* reserve an inode spot */ |
377 | status = ocfs2_reserve_new_inode(osb, handle, &inode_ac); | 364 | status = ocfs2_reserve_new_inode(osb, &inode_ac); |
378 | if (status < 0) { | 365 | if (status < 0) { |
379 | if (status != -ENOSPC) | 366 | if (status != -ENOSPC) |
380 | mlog_errno(status); | 367 | mlog_errno(status); |
@@ -384,7 +371,7 @@ static int ocfs2_mknod(struct inode *dir, | |||
384 | /* are we making a directory? If so, reserve a cluster for his | 371 | /* are we making a directory? If so, reserve a cluster for his |
385 | * 1st extent. */ | 372 | * 1st extent. */ |
386 | if (S_ISDIR(mode)) { | 373 | if (S_ISDIR(mode)) { |
387 | status = ocfs2_reserve_clusters(osb, handle, 1, &data_ac); | 374 | status = ocfs2_reserve_clusters(osb, 1, &data_ac); |
388 | if (status < 0) { | 375 | if (status < 0) { |
389 | if (status != -ENOSPC) | 376 | if (status != -ENOSPC) |
390 | mlog_errno(status); | 377 | mlog_errno(status); |
@@ -392,7 +379,7 @@ static int ocfs2_mknod(struct inode *dir, | |||
392 | } | 379 | } |
393 | } | 380 | } |
394 | 381 | ||
395 | handle = ocfs2_start_trans(osb, handle, OCFS2_MKNOD_CREDITS); | 382 | handle = ocfs2_start_trans(osb, OCFS2_MKNOD_CREDITS); |
396 | if (IS_ERR(handle)) { | 383 | if (IS_ERR(handle)) { |
397 | status = PTR_ERR(handle); | 384 | status = PTR_ERR(handle); |
398 | handle = NULL; | 385 | handle = NULL; |
@@ -453,7 +440,9 @@ static int ocfs2_mknod(struct inode *dir, | |||
453 | status = 0; | 440 | status = 0; |
454 | leave: | 441 | leave: |
455 | if (handle) | 442 | if (handle) |
456 | ocfs2_commit_trans(handle); | 443 | ocfs2_commit_trans(osb, handle); |
444 | |||
445 | ocfs2_meta_unlock(dir, 1); | ||
457 | 446 | ||
458 | if (status == -ENOSPC) | 447 | if (status == -ENOSPC) |
459 | mlog(0, "Disk is full\n"); | 448 | mlog(0, "Disk is full\n"); |
@@ -487,7 +476,7 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, | |||
487 | dev_t dev, | 476 | dev_t dev, |
488 | struct buffer_head **new_fe_bh, | 477 | struct buffer_head **new_fe_bh, |
489 | struct buffer_head *parent_fe_bh, | 478 | struct buffer_head *parent_fe_bh, |
490 | struct ocfs2_journal_handle *handle, | 479 | handle_t *handle, |
491 | struct inode **ret_inode, | 480 | struct inode **ret_inode, |
492 | struct ocfs2_alloc_context *inode_ac) | 481 | struct ocfs2_alloc_context *inode_ac) |
493 | { | 482 | { |
@@ -653,7 +642,7 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
653 | struct inode *dir, | 642 | struct inode *dir, |
654 | struct dentry *dentry) | 643 | struct dentry *dentry) |
655 | { | 644 | { |
656 | struct ocfs2_journal_handle *handle = NULL; | 645 | handle_t *handle; |
657 | struct inode *inode = old_dentry->d_inode; | 646 | struct inode *inode = old_dentry->d_inode; |
658 | int err; | 647 | int err; |
659 | struct buffer_head *fe_bh = NULL; | 648 | struct buffer_head *fe_bh = NULL; |
@@ -666,68 +655,60 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
666 | old_dentry->d_name.len, old_dentry->d_name.name, | 655 | old_dentry->d_name.len, old_dentry->d_name.name, |
667 | dentry->d_name.len, dentry->d_name.name); | 656 | dentry->d_name.len, dentry->d_name.name); |
668 | 657 | ||
669 | if (S_ISDIR(inode->i_mode)) { | 658 | if (S_ISDIR(inode->i_mode)) |
670 | err = -EPERM; | 659 | return -EPERM; |
671 | goto bail; | ||
672 | } | ||
673 | |||
674 | handle = ocfs2_alloc_handle(osb); | ||
675 | if (handle == NULL) { | ||
676 | err = -ENOMEM; | ||
677 | goto bail; | ||
678 | } | ||
679 | 660 | ||
680 | err = ocfs2_meta_lock(dir, handle, &parent_fe_bh, 1); | 661 | err = ocfs2_meta_lock(dir, &parent_fe_bh, 1); |
681 | if (err < 0) { | 662 | if (err < 0) { |
682 | if (err != -ENOENT) | 663 | if (err != -ENOENT) |
683 | mlog_errno(err); | 664 | mlog_errno(err); |
684 | goto bail; | 665 | return err; |
685 | } | 666 | } |
686 | 667 | ||
687 | if (!dir->i_nlink) { | 668 | if (!dir->i_nlink) { |
688 | err = -ENOENT; | 669 | err = -ENOENT; |
689 | goto bail; | 670 | goto out; |
690 | } | 671 | } |
691 | 672 | ||
692 | err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name, | 673 | err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name, |
693 | dentry->d_name.len); | 674 | dentry->d_name.len); |
694 | if (err) | 675 | if (err) |
695 | goto bail; | 676 | goto out; |
696 | 677 | ||
697 | err = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh, | 678 | err = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh, |
698 | dentry->d_name.name, | 679 | dentry->d_name.name, |
699 | dentry->d_name.len, &de_bh); | 680 | dentry->d_name.len, &de_bh); |
700 | if (err < 0) { | 681 | if (err < 0) { |
701 | mlog_errno(err); | 682 | mlog_errno(err); |
702 | goto bail; | 683 | goto out; |
703 | } | 684 | } |
704 | 685 | ||
705 | err = ocfs2_meta_lock(inode, handle, &fe_bh, 1); | 686 | err = ocfs2_meta_lock(inode, &fe_bh, 1); |
706 | if (err < 0) { | 687 | if (err < 0) { |
707 | if (err != -ENOENT) | 688 | if (err != -ENOENT) |
708 | mlog_errno(err); | 689 | mlog_errno(err); |
709 | goto bail; | 690 | goto out; |
710 | } | 691 | } |
711 | 692 | ||
712 | fe = (struct ocfs2_dinode *) fe_bh->b_data; | 693 | fe = (struct ocfs2_dinode *) fe_bh->b_data; |
713 | if (le16_to_cpu(fe->i_links_count) >= OCFS2_LINK_MAX) { | 694 | if (le16_to_cpu(fe->i_links_count) >= OCFS2_LINK_MAX) { |
714 | err = -EMLINK; | 695 | err = -EMLINK; |
715 | goto bail; | 696 | goto out_unlock_inode; |
716 | } | 697 | } |
717 | 698 | ||
718 | handle = ocfs2_start_trans(osb, handle, OCFS2_LINK_CREDITS); | 699 | handle = ocfs2_start_trans(osb, OCFS2_LINK_CREDITS); |
719 | if (IS_ERR(handle)) { | 700 | if (IS_ERR(handle)) { |
720 | err = PTR_ERR(handle); | 701 | err = PTR_ERR(handle); |
721 | handle = NULL; | 702 | handle = NULL; |
722 | mlog_errno(err); | 703 | mlog_errno(err); |
723 | goto bail; | 704 | goto out_unlock_inode; |
724 | } | 705 | } |
725 | 706 | ||
726 | err = ocfs2_journal_access(handle, inode, fe_bh, | 707 | err = ocfs2_journal_access(handle, inode, fe_bh, |
727 | OCFS2_JOURNAL_ACCESS_WRITE); | 708 | OCFS2_JOURNAL_ACCESS_WRITE); |
728 | if (err < 0) { | 709 | if (err < 0) { |
729 | mlog_errno(err); | 710 | mlog_errno(err); |
730 | goto bail; | 711 | goto out_commit; |
731 | } | 712 | } |
732 | 713 | ||
733 | inc_nlink(inode); | 714 | inc_nlink(inode); |
@@ -741,7 +722,7 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
741 | le16_add_cpu(&fe->i_links_count, -1); | 722 | le16_add_cpu(&fe->i_links_count, -1); |
742 | drop_nlink(inode); | 723 | drop_nlink(inode); |
743 | mlog_errno(err); | 724 | mlog_errno(err); |
744 | goto bail; | 725 | goto out_commit; |
745 | } | 726 | } |
746 | 727 | ||
747 | err = ocfs2_add_entry(handle, dentry, inode, | 728 | err = ocfs2_add_entry(handle, dentry, inode, |
@@ -751,21 +732,27 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
751 | le16_add_cpu(&fe->i_links_count, -1); | 732 | le16_add_cpu(&fe->i_links_count, -1); |
752 | drop_nlink(inode); | 733 | drop_nlink(inode); |
753 | mlog_errno(err); | 734 | mlog_errno(err); |
754 | goto bail; | 735 | goto out_commit; |
755 | } | 736 | } |
756 | 737 | ||
757 | err = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno); | 738 | err = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno); |
758 | if (err) { | 739 | if (err) { |
759 | mlog_errno(err); | 740 | mlog_errno(err); |
760 | goto bail; | 741 | goto out_commit; |
761 | } | 742 | } |
762 | 743 | ||
763 | atomic_inc(&inode->i_count); | 744 | atomic_inc(&inode->i_count); |
764 | dentry->d_op = &ocfs2_dentry_ops; | 745 | dentry->d_op = &ocfs2_dentry_ops; |
765 | d_instantiate(dentry, inode); | 746 | d_instantiate(dentry, inode); |
766 | bail: | 747 | |
767 | if (handle) | 748 | out_commit: |
768 | ocfs2_commit_trans(handle); | 749 | ocfs2_commit_trans(osb, handle); |
750 | out_unlock_inode: | ||
751 | ocfs2_meta_unlock(inode, 1); | ||
752 | |||
753 | out: | ||
754 | ocfs2_meta_unlock(dir, 1); | ||
755 | |||
769 | if (de_bh) | 756 | if (de_bh) |
770 | brelse(de_bh); | 757 | brelse(de_bh); |
771 | if (fe_bh) | 758 | if (fe_bh) |
@@ -812,13 +799,15 @@ static int ocfs2_unlink(struct inode *dir, | |||
812 | struct dentry *dentry) | 799 | struct dentry *dentry) |
813 | { | 800 | { |
814 | int status; | 801 | int status; |
802 | int child_locked = 0; | ||
815 | struct inode *inode = dentry->d_inode; | 803 | struct inode *inode = dentry->d_inode; |
804 | struct inode *orphan_dir = NULL; | ||
816 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); | 805 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); |
817 | u64 blkno; | 806 | u64 blkno; |
818 | struct ocfs2_dinode *fe = NULL; | 807 | struct ocfs2_dinode *fe = NULL; |
819 | struct buffer_head *fe_bh = NULL; | 808 | struct buffer_head *fe_bh = NULL; |
820 | struct buffer_head *parent_node_bh = NULL; | 809 | struct buffer_head *parent_node_bh = NULL; |
821 | struct ocfs2_journal_handle *handle = NULL; | 810 | handle_t *handle = NULL; |
822 | struct ocfs2_dir_entry *dirent = NULL; | 811 | struct ocfs2_dir_entry *dirent = NULL; |
823 | struct buffer_head *dirent_bh = NULL; | 812 | struct buffer_head *dirent_bh = NULL; |
824 | char orphan_name[OCFS2_ORPHAN_NAMELEN + 1]; | 813 | char orphan_name[OCFS2_ORPHAN_NAMELEN + 1]; |
@@ -833,22 +822,14 @@ static int ocfs2_unlink(struct inode *dir, | |||
833 | 822 | ||
834 | if (inode == osb->root_inode) { | 823 | if (inode == osb->root_inode) { |
835 | mlog(0, "Cannot delete the root directory\n"); | 824 | mlog(0, "Cannot delete the root directory\n"); |
836 | status = -EPERM; | 825 | return -EPERM; |
837 | goto leave; | ||
838 | } | 826 | } |
839 | 827 | ||
840 | handle = ocfs2_alloc_handle(osb); | 828 | status = ocfs2_meta_lock(dir, &parent_node_bh, 1); |
841 | if (handle == NULL) { | ||
842 | status = -ENOMEM; | ||
843 | mlog_errno(status); | ||
844 | goto leave; | ||
845 | } | ||
846 | |||
847 | status = ocfs2_meta_lock(dir, handle, &parent_node_bh, 1); | ||
848 | if (status < 0) { | 829 | if (status < 0) { |
849 | if (status != -ENOENT) | 830 | if (status != -ENOENT) |
850 | mlog_errno(status); | 831 | mlog_errno(status); |
851 | goto leave; | 832 | return status; |
852 | } | 833 | } |
853 | 834 | ||
854 | status = ocfs2_find_files_on_disk(dentry->d_name.name, | 835 | status = ocfs2_find_files_on_disk(dentry->d_name.name, |
@@ -869,12 +850,13 @@ static int ocfs2_unlink(struct inode *dir, | |||
869 | goto leave; | 850 | goto leave; |
870 | } | 851 | } |
871 | 852 | ||
872 | status = ocfs2_meta_lock(inode, handle, &fe_bh, 1); | 853 | status = ocfs2_meta_lock(inode, &fe_bh, 1); |
873 | if (status < 0) { | 854 | if (status < 0) { |
874 | if (status != -ENOENT) | 855 | if (status != -ENOENT) |
875 | mlog_errno(status); | 856 | mlog_errno(status); |
876 | goto leave; | 857 | goto leave; |
877 | } | 858 | } |
859 | child_locked = 1; | ||
878 | 860 | ||
879 | if (S_ISDIR(inode->i_mode)) { | 861 | if (S_ISDIR(inode->i_mode)) { |
880 | if (!ocfs2_empty_dir(inode)) { | 862 | if (!ocfs2_empty_dir(inode)) { |
@@ -895,7 +877,7 @@ static int ocfs2_unlink(struct inode *dir, | |||
895 | } | 877 | } |
896 | 878 | ||
897 | if (inode_is_unlinkable(inode)) { | 879 | if (inode_is_unlinkable(inode)) { |
898 | status = ocfs2_prepare_orphan_dir(osb, handle, inode, | 880 | status = ocfs2_prepare_orphan_dir(osb, &orphan_dir, inode, |
899 | orphan_name, | 881 | orphan_name, |
900 | &orphan_entry_bh); | 882 | &orphan_entry_bh); |
901 | if (status < 0) { | 883 | if (status < 0) { |
@@ -904,7 +886,7 @@ static int ocfs2_unlink(struct inode *dir, | |||
904 | } | 886 | } |
905 | } | 887 | } |
906 | 888 | ||
907 | handle = ocfs2_start_trans(osb, handle, OCFS2_UNLINK_CREDITS); | 889 | handle = ocfs2_start_trans(osb, OCFS2_UNLINK_CREDITS); |
908 | if (IS_ERR(handle)) { | 890 | if (IS_ERR(handle)) { |
909 | status = PTR_ERR(handle); | 891 | status = PTR_ERR(handle); |
910 | handle = NULL; | 892 | handle = NULL; |
@@ -923,7 +905,7 @@ static int ocfs2_unlink(struct inode *dir, | |||
923 | 905 | ||
924 | if (inode_is_unlinkable(inode)) { | 906 | if (inode_is_unlinkable(inode)) { |
925 | status = ocfs2_orphan_add(osb, handle, inode, fe, orphan_name, | 907 | status = ocfs2_orphan_add(osb, handle, inode, fe, orphan_name, |
926 | orphan_entry_bh); | 908 | orphan_entry_bh, orphan_dir); |
927 | if (status < 0) { | 909 | if (status < 0) { |
928 | mlog_errno(status); | 910 | mlog_errno(status); |
929 | goto leave; | 911 | goto leave; |
@@ -960,7 +942,19 @@ static int ocfs2_unlink(struct inode *dir, | |||
960 | 942 | ||
961 | leave: | 943 | leave: |
962 | if (handle) | 944 | if (handle) |
963 | ocfs2_commit_trans(handle); | 945 | ocfs2_commit_trans(osb, handle); |
946 | |||
947 | if (child_locked) | ||
948 | ocfs2_meta_unlock(inode, 1); | ||
949 | |||
950 | ocfs2_meta_unlock(dir, 1); | ||
951 | |||
952 | if (orphan_dir) { | ||
953 | /* This was locked for us in ocfs2_prepare_orphan_dir() */ | ||
954 | ocfs2_meta_unlock(orphan_dir, 1); | ||
955 | mutex_unlock(&orphan_dir->i_mutex); | ||
956 | iput(orphan_dir); | ||
957 | } | ||
964 | 958 | ||
965 | if (fe_bh) | 959 | if (fe_bh) |
966 | brelse(fe_bh); | 960 | brelse(fe_bh); |
@@ -984,7 +978,6 @@ leave: | |||
984 | * if they have the same id, then the 1st one is the only one locked. | 978 | * if they have the same id, then the 1st one is the only one locked. |
985 | */ | 979 | */ |
986 | static int ocfs2_double_lock(struct ocfs2_super *osb, | 980 | static int ocfs2_double_lock(struct ocfs2_super *osb, |
987 | struct ocfs2_journal_handle *handle, | ||
988 | struct buffer_head **bh1, | 981 | struct buffer_head **bh1, |
989 | struct inode *inode1, | 982 | struct inode *inode1, |
990 | struct buffer_head **bh2, | 983 | struct buffer_head **bh2, |
@@ -1000,8 +993,6 @@ static int ocfs2_double_lock(struct ocfs2_super *osb, | |||
1000 | (unsigned long long)oi1->ip_blkno, | 993 | (unsigned long long)oi1->ip_blkno, |
1001 | (unsigned long long)oi2->ip_blkno); | 994 | (unsigned long long)oi2->ip_blkno); |
1002 | 995 | ||
1003 | BUG_ON(!handle); | ||
1004 | |||
1005 | if (*bh1) | 996 | if (*bh1) |
1006 | *bh1 = NULL; | 997 | *bh1 = NULL; |
1007 | if (*bh2) | 998 | if (*bh2) |
@@ -1021,25 +1012,41 @@ static int ocfs2_double_lock(struct ocfs2_super *osb, | |||
1021 | inode1 = tmpinode; | 1012 | inode1 = tmpinode; |
1022 | } | 1013 | } |
1023 | /* lock id2 */ | 1014 | /* lock id2 */ |
1024 | status = ocfs2_meta_lock(inode2, handle, bh2, 1); | 1015 | status = ocfs2_meta_lock(inode2, bh2, 1); |
1025 | if (status < 0) { | 1016 | if (status < 0) { |
1026 | if (status != -ENOENT) | 1017 | if (status != -ENOENT) |
1027 | mlog_errno(status); | 1018 | mlog_errno(status); |
1028 | goto bail; | 1019 | goto bail; |
1029 | } | 1020 | } |
1030 | } | 1021 | } |
1022 | |||
1031 | /* lock id1 */ | 1023 | /* lock id1 */ |
1032 | status = ocfs2_meta_lock(inode1, handle, bh1, 1); | 1024 | status = ocfs2_meta_lock(inode1, bh1, 1); |
1033 | if (status < 0) { | 1025 | if (status < 0) { |
1026 | /* | ||
1027 | * An error return must mean that no cluster locks | ||
1028 | * were held on function exit. | ||
1029 | */ | ||
1030 | if (oi1->ip_blkno != oi2->ip_blkno) | ||
1031 | ocfs2_meta_unlock(inode2, 1); | ||
1032 | |||
1034 | if (status != -ENOENT) | 1033 | if (status != -ENOENT) |
1035 | mlog_errno(status); | 1034 | mlog_errno(status); |
1036 | goto bail; | ||
1037 | } | 1035 | } |
1036 | |||
1038 | bail: | 1037 | bail: |
1039 | mlog_exit(status); | 1038 | mlog_exit(status); |
1040 | return status; | 1039 | return status; |
1041 | } | 1040 | } |
1042 | 1041 | ||
1042 | static void ocfs2_double_unlock(struct inode *inode1, struct inode *inode2) | ||
1043 | { | ||
1044 | ocfs2_meta_unlock(inode1, 1); | ||
1045 | |||
1046 | if (inode1 != inode2) | ||
1047 | ocfs2_meta_unlock(inode2, 1); | ||
1048 | } | ||
1049 | |||
1043 | #define PARENT_INO(buffer) \ | 1050 | #define PARENT_INO(buffer) \ |
1044 | ((struct ocfs2_dir_entry *) \ | 1051 | ((struct ocfs2_dir_entry *) \ |
1045 | ((char *)buffer + \ | 1052 | ((char *)buffer + \ |
@@ -1050,9 +1057,11 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1050 | struct inode *new_dir, | 1057 | struct inode *new_dir, |
1051 | struct dentry *new_dentry) | 1058 | struct dentry *new_dentry) |
1052 | { | 1059 | { |
1053 | int status = 0, rename_lock = 0; | 1060 | int status = 0, rename_lock = 0, parents_locked = 0; |
1061 | int old_child_locked = 0, new_child_locked = 0; | ||
1054 | struct inode *old_inode = old_dentry->d_inode; | 1062 | struct inode *old_inode = old_dentry->d_inode; |
1055 | struct inode *new_inode = new_dentry->d_inode; | 1063 | struct inode *new_inode = new_dentry->d_inode; |
1064 | struct inode *orphan_dir = NULL; | ||
1056 | struct ocfs2_dinode *newfe = NULL; | 1065 | struct ocfs2_dinode *newfe = NULL; |
1057 | char orphan_name[OCFS2_ORPHAN_NAMELEN + 1]; | 1066 | char orphan_name[OCFS2_ORPHAN_NAMELEN + 1]; |
1058 | struct buffer_head *orphan_entry_bh = NULL; | 1067 | struct buffer_head *orphan_entry_bh = NULL; |
@@ -1060,7 +1069,7 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1060 | struct buffer_head *insert_entry_bh = NULL; | 1069 | struct buffer_head *insert_entry_bh = NULL; |
1061 | struct ocfs2_super *osb = NULL; | 1070 | struct ocfs2_super *osb = NULL; |
1062 | u64 newfe_blkno; | 1071 | u64 newfe_blkno; |
1063 | struct ocfs2_journal_handle *handle = NULL; | 1072 | handle_t *handle = NULL; |
1064 | struct buffer_head *old_dir_bh = NULL; | 1073 | struct buffer_head *old_dir_bh = NULL; |
1065 | struct buffer_head *new_dir_bh = NULL; | 1074 | struct buffer_head *new_dir_bh = NULL; |
1066 | struct ocfs2_dir_entry *old_de = NULL, *new_de = NULL; // dirent for old_dentry | 1075 | struct ocfs2_dir_entry *old_de = NULL, *new_de = NULL; // dirent for old_dentry |
@@ -1105,21 +1114,14 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1105 | rename_lock = 1; | 1114 | rename_lock = 1; |
1106 | } | 1115 | } |
1107 | 1116 | ||
1108 | handle = ocfs2_alloc_handle(osb); | ||
1109 | if (handle == NULL) { | ||
1110 | status = -ENOMEM; | ||
1111 | mlog_errno(status); | ||
1112 | goto bail; | ||
1113 | } | ||
1114 | |||
1115 | /* if old and new are the same, this'll just do one lock. */ | 1117 | /* if old and new are the same, this'll just do one lock. */ |
1116 | status = ocfs2_double_lock(osb, handle, | 1118 | status = ocfs2_double_lock(osb, &old_dir_bh, old_dir, |
1117 | &old_dir_bh, old_dir, | 1119 | &new_dir_bh, new_dir); |
1118 | &new_dir_bh, new_dir); | ||
1119 | if (status < 0) { | 1120 | if (status < 0) { |
1120 | mlog_errno(status); | 1121 | mlog_errno(status); |
1121 | goto bail; | 1122 | goto bail; |
1122 | } | 1123 | } |
1124 | parents_locked = 1; | ||
1123 | 1125 | ||
1124 | /* make sure both dirs have bhs | 1126 | /* make sure both dirs have bhs |
1125 | * get an extra ref on old_dir_bh if old==new */ | 1127 | * get an extra ref on old_dir_bh if old==new */ |
@@ -1140,12 +1142,13 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1140 | * the vote thread on other nodes won't have to concurrently | 1142 | * the vote thread on other nodes won't have to concurrently |
1141 | * downconvert the inode and the dentry locks. | 1143 | * downconvert the inode and the dentry locks. |
1142 | */ | 1144 | */ |
1143 | status = ocfs2_meta_lock(old_inode, handle, NULL, 1); | 1145 | status = ocfs2_meta_lock(old_inode, NULL, 1); |
1144 | if (status < 0) { | 1146 | if (status < 0) { |
1145 | if (status != -ENOENT) | 1147 | if (status != -ENOENT) |
1146 | mlog_errno(status); | 1148 | mlog_errno(status); |
1147 | goto bail; | 1149 | goto bail; |
1148 | } | 1150 | } |
1151 | old_child_locked = 1; | ||
1149 | 1152 | ||
1150 | status = ocfs2_remote_dentry_delete(old_dentry); | 1153 | status = ocfs2_remote_dentry_delete(old_dentry); |
1151 | if (status < 0) { | 1154 | if (status < 0) { |
@@ -1231,12 +1234,13 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1231 | goto bail; | 1234 | goto bail; |
1232 | } | 1235 | } |
1233 | 1236 | ||
1234 | status = ocfs2_meta_lock(new_inode, handle, &newfe_bh, 1); | 1237 | status = ocfs2_meta_lock(new_inode, &newfe_bh, 1); |
1235 | if (status < 0) { | 1238 | if (status < 0) { |
1236 | if (status != -ENOENT) | 1239 | if (status != -ENOENT) |
1237 | mlog_errno(status); | 1240 | mlog_errno(status); |
1238 | goto bail; | 1241 | goto bail; |
1239 | } | 1242 | } |
1243 | new_child_locked = 1; | ||
1240 | 1244 | ||
1241 | status = ocfs2_remote_dentry_delete(new_dentry); | 1245 | status = ocfs2_remote_dentry_delete(new_dentry); |
1242 | if (status < 0) { | 1246 | if (status < 0) { |
@@ -1252,7 +1256,7 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1252 | (unsigned long long)newfe_bh->b_blocknr : 0ULL); | 1256 | (unsigned long long)newfe_bh->b_blocknr : 0ULL); |
1253 | 1257 | ||
1254 | if (S_ISDIR(new_inode->i_mode) || (new_inode->i_nlink == 1)) { | 1258 | if (S_ISDIR(new_inode->i_mode) || (new_inode->i_nlink == 1)) { |
1255 | status = ocfs2_prepare_orphan_dir(osb, handle, | 1259 | status = ocfs2_prepare_orphan_dir(osb, &orphan_dir, |
1256 | new_inode, | 1260 | new_inode, |
1257 | orphan_name, | 1261 | orphan_name, |
1258 | &orphan_entry_bh); | 1262 | &orphan_entry_bh); |
@@ -1280,7 +1284,7 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1280 | } | 1284 | } |
1281 | } | 1285 | } |
1282 | 1286 | ||
1283 | handle = ocfs2_start_trans(osb, handle, OCFS2_RENAME_CREDITS); | 1287 | handle = ocfs2_start_trans(osb, OCFS2_RENAME_CREDITS); |
1284 | if (IS_ERR(handle)) { | 1288 | if (IS_ERR(handle)) { |
1285 | status = PTR_ERR(handle); | 1289 | status = PTR_ERR(handle); |
1286 | handle = NULL; | 1290 | handle = NULL; |
@@ -1307,7 +1311,7 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1307 | (newfe->i_links_count == cpu_to_le16(1))){ | 1311 | (newfe->i_links_count == cpu_to_le16(1))){ |
1308 | status = ocfs2_orphan_add(osb, handle, new_inode, | 1312 | status = ocfs2_orphan_add(osb, handle, new_inode, |
1309 | newfe, orphan_name, | 1313 | newfe, orphan_name, |
1310 | orphan_entry_bh); | 1314 | orphan_entry_bh, orphan_dir); |
1311 | if (status < 0) { | 1315 | if (status < 0) { |
1312 | mlog_errno(status); | 1316 | mlog_errno(status); |
1313 | goto bail; | 1317 | goto bail; |
@@ -1424,7 +1428,23 @@ bail: | |||
1424 | ocfs2_rename_unlock(osb); | 1428 | ocfs2_rename_unlock(osb); |
1425 | 1429 | ||
1426 | if (handle) | 1430 | if (handle) |
1427 | ocfs2_commit_trans(handle); | 1431 | ocfs2_commit_trans(osb, handle); |
1432 | |||
1433 | if (parents_locked) | ||
1434 | ocfs2_double_unlock(old_dir, new_dir); | ||
1435 | |||
1436 | if (old_child_locked) | ||
1437 | ocfs2_meta_unlock(old_inode, 1); | ||
1438 | |||
1439 | if (new_child_locked) | ||
1440 | ocfs2_meta_unlock(new_inode, 1); | ||
1441 | |||
1442 | if (orphan_dir) { | ||
1443 | /* This was locked for us in ocfs2_prepare_orphan_dir() */ | ||
1444 | ocfs2_meta_unlock(orphan_dir, 1); | ||
1445 | mutex_unlock(&orphan_dir->i_mutex); | ||
1446 | iput(orphan_dir); | ||
1447 | } | ||
1428 | 1448 | ||
1429 | if (new_inode) | 1449 | if (new_inode) |
1430 | sync_mapping_buffers(old_inode->i_mapping); | 1450 | sync_mapping_buffers(old_inode->i_mapping); |
@@ -1458,7 +1478,7 @@ bail: | |||
1458 | * data, including the null terminator. | 1478 | * data, including the null terminator. |
1459 | */ | 1479 | */ |
1460 | static int ocfs2_create_symlink_data(struct ocfs2_super *osb, | 1480 | static int ocfs2_create_symlink_data(struct ocfs2_super *osb, |
1461 | struct ocfs2_journal_handle *handle, | 1481 | handle_t *handle, |
1462 | struct inode *inode, | 1482 | struct inode *inode, |
1463 | const char *symname) | 1483 | const char *symname) |
1464 | { | 1484 | { |
@@ -1573,7 +1593,7 @@ static int ocfs2_symlink(struct inode *dir, | |||
1573 | struct buffer_head *parent_fe_bh = NULL; | 1593 | struct buffer_head *parent_fe_bh = NULL; |
1574 | struct ocfs2_dinode *fe = NULL; | 1594 | struct ocfs2_dinode *fe = NULL; |
1575 | struct ocfs2_dinode *dirfe; | 1595 | struct ocfs2_dinode *dirfe; |
1576 | struct ocfs2_journal_handle *handle = NULL; | 1596 | handle_t *handle = NULL; |
1577 | struct ocfs2_alloc_context *inode_ac = NULL; | 1597 | struct ocfs2_alloc_context *inode_ac = NULL; |
1578 | struct ocfs2_alloc_context *data_ac = NULL; | 1598 | struct ocfs2_alloc_context *data_ac = NULL; |
1579 | 1599 | ||
@@ -1587,19 +1607,12 @@ static int ocfs2_symlink(struct inode *dir, | |||
1587 | 1607 | ||
1588 | credits = ocfs2_calc_symlink_credits(sb); | 1608 | credits = ocfs2_calc_symlink_credits(sb); |
1589 | 1609 | ||
1590 | handle = ocfs2_alloc_handle(osb); | ||
1591 | if (handle == NULL) { | ||
1592 | status = -ENOMEM; | ||
1593 | mlog_errno(status); | ||
1594 | goto bail; | ||
1595 | } | ||
1596 | |||
1597 | /* lock the parent directory */ | 1610 | /* lock the parent directory */ |
1598 | status = ocfs2_meta_lock(dir, handle, &parent_fe_bh, 1); | 1611 | status = ocfs2_meta_lock(dir, &parent_fe_bh, 1); |
1599 | if (status < 0) { | 1612 | if (status < 0) { |
1600 | if (status != -ENOENT) | 1613 | if (status != -ENOENT) |
1601 | mlog_errno(status); | 1614 | mlog_errno(status); |
1602 | goto bail; | 1615 | return status; |
1603 | } | 1616 | } |
1604 | 1617 | ||
1605 | dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data; | 1618 | dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data; |
@@ -1622,7 +1635,7 @@ static int ocfs2_symlink(struct inode *dir, | |||
1622 | goto bail; | 1635 | goto bail; |
1623 | } | 1636 | } |
1624 | 1637 | ||
1625 | status = ocfs2_reserve_new_inode(osb, handle, &inode_ac); | 1638 | status = ocfs2_reserve_new_inode(osb, &inode_ac); |
1626 | if (status < 0) { | 1639 | if (status < 0) { |
1627 | if (status != -ENOSPC) | 1640 | if (status != -ENOSPC) |
1628 | mlog_errno(status); | 1641 | mlog_errno(status); |
@@ -1631,7 +1644,7 @@ static int ocfs2_symlink(struct inode *dir, | |||
1631 | 1644 | ||
1632 | /* don't reserve bitmap space for fast symlinks. */ | 1645 | /* don't reserve bitmap space for fast symlinks. */ |
1633 | if (l > ocfs2_fast_symlink_chars(sb)) { | 1646 | if (l > ocfs2_fast_symlink_chars(sb)) { |
1634 | status = ocfs2_reserve_clusters(osb, handle, 1, &data_ac); | 1647 | status = ocfs2_reserve_clusters(osb, 1, &data_ac); |
1635 | if (status < 0) { | 1648 | if (status < 0) { |
1636 | if (status != -ENOSPC) | 1649 | if (status != -ENOSPC) |
1637 | mlog_errno(status); | 1650 | mlog_errno(status); |
@@ -1639,7 +1652,7 @@ static int ocfs2_symlink(struct inode *dir, | |||
1639 | } | 1652 | } |
1640 | } | 1653 | } |
1641 | 1654 | ||
1642 | handle = ocfs2_start_trans(osb, handle, credits); | 1655 | handle = ocfs2_start_trans(osb, credits); |
1643 | if (IS_ERR(handle)) { | 1656 | if (IS_ERR(handle)) { |
1644 | status = PTR_ERR(handle); | 1657 | status = PTR_ERR(handle); |
1645 | handle = NULL; | 1658 | handle = NULL; |
@@ -1717,7 +1730,10 @@ static int ocfs2_symlink(struct inode *dir, | |||
1717 | d_instantiate(dentry, inode); | 1730 | d_instantiate(dentry, inode); |
1718 | bail: | 1731 | bail: |
1719 | if (handle) | 1732 | if (handle) |
1720 | ocfs2_commit_trans(handle); | 1733 | ocfs2_commit_trans(osb, handle); |
1734 | |||
1735 | ocfs2_meta_unlock(dir, 1); | ||
1736 | |||
1721 | if (new_fe_bh) | 1737 | if (new_fe_bh) |
1722 | brelse(new_fe_bh); | 1738 | brelse(new_fe_bh); |
1723 | if (parent_fe_bh) | 1739 | if (parent_fe_bh) |
@@ -1768,7 +1784,7 @@ int ocfs2_check_dir_entry(struct inode * dir, | |||
1768 | * If you pass me insert_bh, I'll skip the search of the other dir | 1784 | * If you pass me insert_bh, I'll skip the search of the other dir |
1769 | * blocks and put the record in there. | 1785 | * blocks and put the record in there. |
1770 | */ | 1786 | */ |
1771 | static int __ocfs2_add_entry(struct ocfs2_journal_handle *handle, | 1787 | static int __ocfs2_add_entry(handle_t *handle, |
1772 | struct inode *dir, | 1788 | struct inode *dir, |
1773 | const char *name, int namelen, | 1789 | const char *name, int namelen, |
1774 | struct inode *inode, u64 blkno, | 1790 | struct inode *inode, u64 blkno, |
@@ -1854,7 +1870,7 @@ bail: | |||
1854 | * ocfs2_delete_entry deletes a directory entry by merging it with the | 1870 | * ocfs2_delete_entry deletes a directory entry by merging it with the |
1855 | * previous entry | 1871 | * previous entry |
1856 | */ | 1872 | */ |
1857 | static int ocfs2_delete_entry(struct ocfs2_journal_handle *handle, | 1873 | static int ocfs2_delete_entry(handle_t *handle, |
1858 | struct inode *dir, | 1874 | struct inode *dir, |
1859 | struct ocfs2_dir_entry *de_del, | 1875 | struct ocfs2_dir_entry *de_del, |
1860 | struct buffer_head *bh) | 1876 | struct buffer_head *bh) |
@@ -2085,19 +2101,19 @@ bail: | |||
2085 | } | 2101 | } |
2086 | 2102 | ||
2087 | static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, | 2103 | static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, |
2088 | struct ocfs2_journal_handle *handle, | 2104 | struct inode **ret_orphan_dir, |
2089 | struct inode *inode, | 2105 | struct inode *inode, |
2090 | char *name, | 2106 | char *name, |
2091 | struct buffer_head **de_bh) | 2107 | struct buffer_head **de_bh) |
2092 | { | 2108 | { |
2093 | struct inode *orphan_dir_inode = NULL; | 2109 | struct inode *orphan_dir_inode; |
2094 | struct buffer_head *orphan_dir_bh = NULL; | 2110 | struct buffer_head *orphan_dir_bh = NULL; |
2095 | int status = 0; | 2111 | int status = 0; |
2096 | 2112 | ||
2097 | status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno, name); | 2113 | status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno, name); |
2098 | if (status < 0) { | 2114 | if (status < 0) { |
2099 | mlog_errno(status); | 2115 | mlog_errno(status); |
2100 | goto leave; | 2116 | return status; |
2101 | } | 2117 | } |
2102 | 2118 | ||
2103 | orphan_dir_inode = ocfs2_get_system_file_inode(osb, | 2119 | orphan_dir_inode = ocfs2_get_system_file_inode(osb, |
@@ -2106,11 +2122,12 @@ static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, | |||
2106 | if (!orphan_dir_inode) { | 2122 | if (!orphan_dir_inode) { |
2107 | status = -ENOENT; | 2123 | status = -ENOENT; |
2108 | mlog_errno(status); | 2124 | mlog_errno(status); |
2109 | goto leave; | 2125 | return status; |
2110 | } | 2126 | } |
2111 | 2127 | ||
2112 | ocfs2_handle_add_inode(handle, orphan_dir_inode); | 2128 | mutex_lock(&orphan_dir_inode->i_mutex); |
2113 | status = ocfs2_meta_lock(orphan_dir_inode, handle, &orphan_dir_bh, 1); | 2129 | |
2130 | status = ocfs2_meta_lock(orphan_dir_inode, &orphan_dir_bh, 1); | ||
2114 | if (status < 0) { | 2131 | if (status < 0) { |
2115 | mlog_errno(status); | 2132 | mlog_errno(status); |
2116 | goto leave; | 2133 | goto leave; |
@@ -2120,13 +2137,19 @@ static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, | |||
2120 | orphan_dir_bh, name, | 2137 | orphan_dir_bh, name, |
2121 | OCFS2_ORPHAN_NAMELEN, de_bh); | 2138 | OCFS2_ORPHAN_NAMELEN, de_bh); |
2122 | if (status < 0) { | 2139 | if (status < 0) { |
2140 | ocfs2_meta_unlock(orphan_dir_inode, 1); | ||
2141 | |||
2123 | mlog_errno(status); | 2142 | mlog_errno(status); |
2124 | goto leave; | 2143 | goto leave; |
2125 | } | 2144 | } |
2126 | 2145 | ||
2146 | *ret_orphan_dir = orphan_dir_inode; | ||
2147 | |||
2127 | leave: | 2148 | leave: |
2128 | if (orphan_dir_inode) | 2149 | if (status) { |
2150 | mutex_unlock(&orphan_dir_inode->i_mutex); | ||
2129 | iput(orphan_dir_inode); | 2151 | iput(orphan_dir_inode); |
2152 | } | ||
2130 | 2153 | ||
2131 | if (orphan_dir_bh) | 2154 | if (orphan_dir_bh) |
2132 | brelse(orphan_dir_bh); | 2155 | brelse(orphan_dir_bh); |
@@ -2136,28 +2159,19 @@ leave: | |||
2136 | } | 2159 | } |
2137 | 2160 | ||
2138 | static int ocfs2_orphan_add(struct ocfs2_super *osb, | 2161 | static int ocfs2_orphan_add(struct ocfs2_super *osb, |
2139 | struct ocfs2_journal_handle *handle, | 2162 | handle_t *handle, |
2140 | struct inode *inode, | 2163 | struct inode *inode, |
2141 | struct ocfs2_dinode *fe, | 2164 | struct ocfs2_dinode *fe, |
2142 | char *name, | 2165 | char *name, |
2143 | struct buffer_head *de_bh) | 2166 | struct buffer_head *de_bh, |
2167 | struct inode *orphan_dir_inode) | ||
2144 | { | 2168 | { |
2145 | struct inode *orphan_dir_inode = NULL; | ||
2146 | struct buffer_head *orphan_dir_bh = NULL; | 2169 | struct buffer_head *orphan_dir_bh = NULL; |
2147 | int status = 0; | 2170 | int status = 0; |
2148 | struct ocfs2_dinode *orphan_fe; | 2171 | struct ocfs2_dinode *orphan_fe; |
2149 | 2172 | ||
2150 | mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino); | 2173 | mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino); |
2151 | 2174 | ||
2152 | orphan_dir_inode = ocfs2_get_system_file_inode(osb, | ||
2153 | ORPHAN_DIR_SYSTEM_INODE, | ||
2154 | osb->slot_num); | ||
2155 | if (!orphan_dir_inode) { | ||
2156 | status = -ENOENT; | ||
2157 | mlog_errno(status); | ||
2158 | goto leave; | ||
2159 | } | ||
2160 | |||
2161 | status = ocfs2_read_block(osb, | 2175 | status = ocfs2_read_block(osb, |
2162 | OCFS2_I(orphan_dir_inode)->ip_blkno, | 2176 | OCFS2_I(orphan_dir_inode)->ip_blkno, |
2163 | &orphan_dir_bh, OCFS2_BH_CACHED, | 2177 | &orphan_dir_bh, OCFS2_BH_CACHED, |
@@ -2209,9 +2223,6 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb, | |||
2209 | (unsigned long long)OCFS2_I(inode)->ip_blkno, osb->slot_num); | 2223 | (unsigned long long)OCFS2_I(inode)->ip_blkno, osb->slot_num); |
2210 | 2224 | ||
2211 | leave: | 2225 | leave: |
2212 | if (orphan_dir_inode) | ||
2213 | iput(orphan_dir_inode); | ||
2214 | |||
2215 | if (orphan_dir_bh) | 2226 | if (orphan_dir_bh) |
2216 | brelse(orphan_dir_bh); | 2227 | brelse(orphan_dir_bh); |
2217 | 2228 | ||
@@ -2221,7 +2232,7 @@ leave: | |||
2221 | 2232 | ||
2222 | /* unlike orphan_add, we expect the orphan dir to already be locked here. */ | 2233 | /* unlike orphan_add, we expect the orphan dir to already be locked here. */ |
2223 | int ocfs2_orphan_del(struct ocfs2_super *osb, | 2234 | int ocfs2_orphan_del(struct ocfs2_super *osb, |
2224 | struct ocfs2_journal_handle *handle, | 2235 | handle_t *handle, |
2225 | struct inode *orphan_dir_inode, | 2236 | struct inode *orphan_dir_inode, |
2226 | struct inode *inode, | 2237 | struct inode *inode, |
2227 | struct buffer_head *orphan_dir_bh) | 2238 | struct buffer_head *orphan_dir_bh) |
@@ -2300,4 +2311,5 @@ struct inode_operations ocfs2_dir_iops = { | |||
2300 | .rename = ocfs2_rename, | 2311 | .rename = ocfs2_rename, |
2301 | .setattr = ocfs2_setattr, | 2312 | .setattr = ocfs2_setattr, |
2302 | .getattr = ocfs2_getattr, | 2313 | .getattr = ocfs2_getattr, |
2314 | .permission = ocfs2_permission, | ||
2303 | }; | 2315 | }; |