diff options
Diffstat (limited to 'fs/ocfs2/namei.c')
-rw-r--r-- | fs/ocfs2/namei.c | 304 |
1 files changed, 159 insertions, 145 deletions
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index a57b751d4f40..9637039c2633 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 | { |
@@ -598,9 +587,11 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, | |||
598 | } | 587 | } |
599 | 588 | ||
600 | ocfs2_inode_set_new(osb, inode); | 589 | ocfs2_inode_set_new(osb, inode); |
601 | status = ocfs2_create_new_inode_locks(inode); | 590 | if (!ocfs2_mount_local(osb)) { |
602 | if (status < 0) | 591 | status = ocfs2_create_new_inode_locks(inode); |
603 | mlog_errno(status); | 592 | if (status < 0) |
593 | mlog_errno(status); | ||
594 | } | ||
604 | 595 | ||
605 | status = 0; /* error in ocfs2_create_new_inode_locks is not | 596 | status = 0; /* error in ocfs2_create_new_inode_locks is not |
606 | * critical */ | 597 | * critical */ |
@@ -653,7 +644,7 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
653 | struct inode *dir, | 644 | struct inode *dir, |
654 | struct dentry *dentry) | 645 | struct dentry *dentry) |
655 | { | 646 | { |
656 | struct ocfs2_journal_handle *handle = NULL; | 647 | handle_t *handle; |
657 | struct inode *inode = old_dentry->d_inode; | 648 | struct inode *inode = old_dentry->d_inode; |
658 | int err; | 649 | int err; |
659 | struct buffer_head *fe_bh = NULL; | 650 | struct buffer_head *fe_bh = NULL; |
@@ -666,68 +657,60 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
666 | old_dentry->d_name.len, old_dentry->d_name.name, | 657 | old_dentry->d_name.len, old_dentry->d_name.name, |
667 | dentry->d_name.len, dentry->d_name.name); | 658 | dentry->d_name.len, dentry->d_name.name); |
668 | 659 | ||
669 | if (S_ISDIR(inode->i_mode)) { | 660 | if (S_ISDIR(inode->i_mode)) |
670 | err = -EPERM; | 661 | 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 | 662 | ||
680 | err = ocfs2_meta_lock(dir, handle, &parent_fe_bh, 1); | 663 | err = ocfs2_meta_lock(dir, &parent_fe_bh, 1); |
681 | if (err < 0) { | 664 | if (err < 0) { |
682 | if (err != -ENOENT) | 665 | if (err != -ENOENT) |
683 | mlog_errno(err); | 666 | mlog_errno(err); |
684 | goto bail; | 667 | return err; |
685 | } | 668 | } |
686 | 669 | ||
687 | if (!dir->i_nlink) { | 670 | if (!dir->i_nlink) { |
688 | err = -ENOENT; | 671 | err = -ENOENT; |
689 | goto bail; | 672 | goto out; |
690 | } | 673 | } |
691 | 674 | ||
692 | err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name, | 675 | err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name, |
693 | dentry->d_name.len); | 676 | dentry->d_name.len); |
694 | if (err) | 677 | if (err) |
695 | goto bail; | 678 | goto out; |
696 | 679 | ||
697 | err = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh, | 680 | err = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh, |
698 | dentry->d_name.name, | 681 | dentry->d_name.name, |
699 | dentry->d_name.len, &de_bh); | 682 | dentry->d_name.len, &de_bh); |
700 | if (err < 0) { | 683 | if (err < 0) { |
701 | mlog_errno(err); | 684 | mlog_errno(err); |
702 | goto bail; | 685 | goto out; |
703 | } | 686 | } |
704 | 687 | ||
705 | err = ocfs2_meta_lock(inode, handle, &fe_bh, 1); | 688 | err = ocfs2_meta_lock(inode, &fe_bh, 1); |
706 | if (err < 0) { | 689 | if (err < 0) { |
707 | if (err != -ENOENT) | 690 | if (err != -ENOENT) |
708 | mlog_errno(err); | 691 | mlog_errno(err); |
709 | goto bail; | 692 | goto out; |
710 | } | 693 | } |
711 | 694 | ||
712 | fe = (struct ocfs2_dinode *) fe_bh->b_data; | 695 | fe = (struct ocfs2_dinode *) fe_bh->b_data; |
713 | if (le16_to_cpu(fe->i_links_count) >= OCFS2_LINK_MAX) { | 696 | if (le16_to_cpu(fe->i_links_count) >= OCFS2_LINK_MAX) { |
714 | err = -EMLINK; | 697 | err = -EMLINK; |
715 | goto bail; | 698 | goto out_unlock_inode; |
716 | } | 699 | } |
717 | 700 | ||
718 | handle = ocfs2_start_trans(osb, handle, OCFS2_LINK_CREDITS); | 701 | handle = ocfs2_start_trans(osb, OCFS2_LINK_CREDITS); |
719 | if (IS_ERR(handle)) { | 702 | if (IS_ERR(handle)) { |
720 | err = PTR_ERR(handle); | 703 | err = PTR_ERR(handle); |
721 | handle = NULL; | 704 | handle = NULL; |
722 | mlog_errno(err); | 705 | mlog_errno(err); |
723 | goto bail; | 706 | goto out_unlock_inode; |
724 | } | 707 | } |
725 | 708 | ||
726 | err = ocfs2_journal_access(handle, inode, fe_bh, | 709 | err = ocfs2_journal_access(handle, inode, fe_bh, |
727 | OCFS2_JOURNAL_ACCESS_WRITE); | 710 | OCFS2_JOURNAL_ACCESS_WRITE); |
728 | if (err < 0) { | 711 | if (err < 0) { |
729 | mlog_errno(err); | 712 | mlog_errno(err); |
730 | goto bail; | 713 | goto out_commit; |
731 | } | 714 | } |
732 | 715 | ||
733 | inc_nlink(inode); | 716 | inc_nlink(inode); |
@@ -741,7 +724,7 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
741 | le16_add_cpu(&fe->i_links_count, -1); | 724 | le16_add_cpu(&fe->i_links_count, -1); |
742 | drop_nlink(inode); | 725 | drop_nlink(inode); |
743 | mlog_errno(err); | 726 | mlog_errno(err); |
744 | goto bail; | 727 | goto out_commit; |
745 | } | 728 | } |
746 | 729 | ||
747 | err = ocfs2_add_entry(handle, dentry, inode, | 730 | err = ocfs2_add_entry(handle, dentry, inode, |
@@ -751,21 +734,27 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
751 | le16_add_cpu(&fe->i_links_count, -1); | 734 | le16_add_cpu(&fe->i_links_count, -1); |
752 | drop_nlink(inode); | 735 | drop_nlink(inode); |
753 | mlog_errno(err); | 736 | mlog_errno(err); |
754 | goto bail; | 737 | goto out_commit; |
755 | } | 738 | } |
756 | 739 | ||
757 | err = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno); | 740 | err = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno); |
758 | if (err) { | 741 | if (err) { |
759 | mlog_errno(err); | 742 | mlog_errno(err); |
760 | goto bail; | 743 | goto out_commit; |
761 | } | 744 | } |
762 | 745 | ||
763 | atomic_inc(&inode->i_count); | 746 | atomic_inc(&inode->i_count); |
764 | dentry->d_op = &ocfs2_dentry_ops; | 747 | dentry->d_op = &ocfs2_dentry_ops; |
765 | d_instantiate(dentry, inode); | 748 | d_instantiate(dentry, inode); |
766 | bail: | 749 | |
767 | if (handle) | 750 | out_commit: |
768 | ocfs2_commit_trans(handle); | 751 | ocfs2_commit_trans(osb, handle); |
752 | out_unlock_inode: | ||
753 | ocfs2_meta_unlock(inode, 1); | ||
754 | |||
755 | out: | ||
756 | ocfs2_meta_unlock(dir, 1); | ||
757 | |||
769 | if (de_bh) | 758 | if (de_bh) |
770 | brelse(de_bh); | 759 | brelse(de_bh); |
771 | if (fe_bh) | 760 | if (fe_bh) |
@@ -812,13 +801,15 @@ static int ocfs2_unlink(struct inode *dir, | |||
812 | struct dentry *dentry) | 801 | struct dentry *dentry) |
813 | { | 802 | { |
814 | int status; | 803 | int status; |
804 | int child_locked = 0; | ||
815 | struct inode *inode = dentry->d_inode; | 805 | struct inode *inode = dentry->d_inode; |
806 | struct inode *orphan_dir = NULL; | ||
816 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); | 807 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); |
817 | u64 blkno; | 808 | u64 blkno; |
818 | struct ocfs2_dinode *fe = NULL; | 809 | struct ocfs2_dinode *fe = NULL; |
819 | struct buffer_head *fe_bh = NULL; | 810 | struct buffer_head *fe_bh = NULL; |
820 | struct buffer_head *parent_node_bh = NULL; | 811 | struct buffer_head *parent_node_bh = NULL; |
821 | struct ocfs2_journal_handle *handle = NULL; | 812 | handle_t *handle = NULL; |
822 | struct ocfs2_dir_entry *dirent = NULL; | 813 | struct ocfs2_dir_entry *dirent = NULL; |
823 | struct buffer_head *dirent_bh = NULL; | 814 | struct buffer_head *dirent_bh = NULL; |
824 | char orphan_name[OCFS2_ORPHAN_NAMELEN + 1]; | 815 | char orphan_name[OCFS2_ORPHAN_NAMELEN + 1]; |
@@ -833,22 +824,14 @@ static int ocfs2_unlink(struct inode *dir, | |||
833 | 824 | ||
834 | if (inode == osb->root_inode) { | 825 | if (inode == osb->root_inode) { |
835 | mlog(0, "Cannot delete the root directory\n"); | 826 | mlog(0, "Cannot delete the root directory\n"); |
836 | status = -EPERM; | 827 | return -EPERM; |
837 | goto leave; | ||
838 | } | ||
839 | |||
840 | handle = ocfs2_alloc_handle(osb); | ||
841 | if (handle == NULL) { | ||
842 | status = -ENOMEM; | ||
843 | mlog_errno(status); | ||
844 | goto leave; | ||
845 | } | 828 | } |
846 | 829 | ||
847 | status = ocfs2_meta_lock(dir, handle, &parent_node_bh, 1); | 830 | status = ocfs2_meta_lock(dir, &parent_node_bh, 1); |
848 | if (status < 0) { | 831 | if (status < 0) { |
849 | if (status != -ENOENT) | 832 | if (status != -ENOENT) |
850 | mlog_errno(status); | 833 | mlog_errno(status); |
851 | goto leave; | 834 | return status; |
852 | } | 835 | } |
853 | 836 | ||
854 | status = ocfs2_find_files_on_disk(dentry->d_name.name, | 837 | status = ocfs2_find_files_on_disk(dentry->d_name.name, |
@@ -869,12 +852,13 @@ static int ocfs2_unlink(struct inode *dir, | |||
869 | goto leave; | 852 | goto leave; |
870 | } | 853 | } |
871 | 854 | ||
872 | status = ocfs2_meta_lock(inode, handle, &fe_bh, 1); | 855 | status = ocfs2_meta_lock(inode, &fe_bh, 1); |
873 | if (status < 0) { | 856 | if (status < 0) { |
874 | if (status != -ENOENT) | 857 | if (status != -ENOENT) |
875 | mlog_errno(status); | 858 | mlog_errno(status); |
876 | goto leave; | 859 | goto leave; |
877 | } | 860 | } |
861 | child_locked = 1; | ||
878 | 862 | ||
879 | if (S_ISDIR(inode->i_mode)) { | 863 | if (S_ISDIR(inode->i_mode)) { |
880 | if (!ocfs2_empty_dir(inode)) { | 864 | if (!ocfs2_empty_dir(inode)) { |
@@ -895,7 +879,7 @@ static int ocfs2_unlink(struct inode *dir, | |||
895 | } | 879 | } |
896 | 880 | ||
897 | if (inode_is_unlinkable(inode)) { | 881 | if (inode_is_unlinkable(inode)) { |
898 | status = ocfs2_prepare_orphan_dir(osb, handle, inode, | 882 | status = ocfs2_prepare_orphan_dir(osb, &orphan_dir, inode, |
899 | orphan_name, | 883 | orphan_name, |
900 | &orphan_entry_bh); | 884 | &orphan_entry_bh); |
901 | if (status < 0) { | 885 | if (status < 0) { |
@@ -904,7 +888,7 @@ static int ocfs2_unlink(struct inode *dir, | |||
904 | } | 888 | } |
905 | } | 889 | } |
906 | 890 | ||
907 | handle = ocfs2_start_trans(osb, handle, OCFS2_UNLINK_CREDITS); | 891 | handle = ocfs2_start_trans(osb, OCFS2_UNLINK_CREDITS); |
908 | if (IS_ERR(handle)) { | 892 | if (IS_ERR(handle)) { |
909 | status = PTR_ERR(handle); | 893 | status = PTR_ERR(handle); |
910 | handle = NULL; | 894 | handle = NULL; |
@@ -923,7 +907,7 @@ static int ocfs2_unlink(struct inode *dir, | |||
923 | 907 | ||
924 | if (inode_is_unlinkable(inode)) { | 908 | if (inode_is_unlinkable(inode)) { |
925 | status = ocfs2_orphan_add(osb, handle, inode, fe, orphan_name, | 909 | status = ocfs2_orphan_add(osb, handle, inode, fe, orphan_name, |
926 | orphan_entry_bh); | 910 | orphan_entry_bh, orphan_dir); |
927 | if (status < 0) { | 911 | if (status < 0) { |
928 | mlog_errno(status); | 912 | mlog_errno(status); |
929 | goto leave; | 913 | goto leave; |
@@ -960,7 +944,19 @@ static int ocfs2_unlink(struct inode *dir, | |||
960 | 944 | ||
961 | leave: | 945 | leave: |
962 | if (handle) | 946 | if (handle) |
963 | ocfs2_commit_trans(handle); | 947 | ocfs2_commit_trans(osb, handle); |
948 | |||
949 | if (child_locked) | ||
950 | ocfs2_meta_unlock(inode, 1); | ||
951 | |||
952 | ocfs2_meta_unlock(dir, 1); | ||
953 | |||
954 | if (orphan_dir) { | ||
955 | /* This was locked for us in ocfs2_prepare_orphan_dir() */ | ||
956 | ocfs2_meta_unlock(orphan_dir, 1); | ||
957 | mutex_unlock(&orphan_dir->i_mutex); | ||
958 | iput(orphan_dir); | ||
959 | } | ||
964 | 960 | ||
965 | if (fe_bh) | 961 | if (fe_bh) |
966 | brelse(fe_bh); | 962 | brelse(fe_bh); |
@@ -984,7 +980,6 @@ leave: | |||
984 | * if they have the same id, then the 1st one is the only one locked. | 980 | * if they have the same id, then the 1st one is the only one locked. |
985 | */ | 981 | */ |
986 | static int ocfs2_double_lock(struct ocfs2_super *osb, | 982 | static int ocfs2_double_lock(struct ocfs2_super *osb, |
987 | struct ocfs2_journal_handle *handle, | ||
988 | struct buffer_head **bh1, | 983 | struct buffer_head **bh1, |
989 | struct inode *inode1, | 984 | struct inode *inode1, |
990 | struct buffer_head **bh2, | 985 | struct buffer_head **bh2, |
@@ -1000,8 +995,6 @@ static int ocfs2_double_lock(struct ocfs2_super *osb, | |||
1000 | (unsigned long long)oi1->ip_blkno, | 995 | (unsigned long long)oi1->ip_blkno, |
1001 | (unsigned long long)oi2->ip_blkno); | 996 | (unsigned long long)oi2->ip_blkno); |
1002 | 997 | ||
1003 | BUG_ON(!handle); | ||
1004 | |||
1005 | if (*bh1) | 998 | if (*bh1) |
1006 | *bh1 = NULL; | 999 | *bh1 = NULL; |
1007 | if (*bh2) | 1000 | if (*bh2) |
@@ -1021,25 +1014,41 @@ static int ocfs2_double_lock(struct ocfs2_super *osb, | |||
1021 | inode1 = tmpinode; | 1014 | inode1 = tmpinode; |
1022 | } | 1015 | } |
1023 | /* lock id2 */ | 1016 | /* lock id2 */ |
1024 | status = ocfs2_meta_lock(inode2, handle, bh2, 1); | 1017 | status = ocfs2_meta_lock(inode2, bh2, 1); |
1025 | if (status < 0) { | 1018 | if (status < 0) { |
1026 | if (status != -ENOENT) | 1019 | if (status != -ENOENT) |
1027 | mlog_errno(status); | 1020 | mlog_errno(status); |
1028 | goto bail; | 1021 | goto bail; |
1029 | } | 1022 | } |
1030 | } | 1023 | } |
1024 | |||
1031 | /* lock id1 */ | 1025 | /* lock id1 */ |
1032 | status = ocfs2_meta_lock(inode1, handle, bh1, 1); | 1026 | status = ocfs2_meta_lock(inode1, bh1, 1); |
1033 | if (status < 0) { | 1027 | if (status < 0) { |
1028 | /* | ||
1029 | * An error return must mean that no cluster locks | ||
1030 | * were held on function exit. | ||
1031 | */ | ||
1032 | if (oi1->ip_blkno != oi2->ip_blkno) | ||
1033 | ocfs2_meta_unlock(inode2, 1); | ||
1034 | |||
1034 | if (status != -ENOENT) | 1035 | if (status != -ENOENT) |
1035 | mlog_errno(status); | 1036 | mlog_errno(status); |
1036 | goto bail; | ||
1037 | } | 1037 | } |
1038 | |||
1038 | bail: | 1039 | bail: |
1039 | mlog_exit(status); | 1040 | mlog_exit(status); |
1040 | return status; | 1041 | return status; |
1041 | } | 1042 | } |
1042 | 1043 | ||
1044 | static void ocfs2_double_unlock(struct inode *inode1, struct inode *inode2) | ||
1045 | { | ||
1046 | ocfs2_meta_unlock(inode1, 1); | ||
1047 | |||
1048 | if (inode1 != inode2) | ||
1049 | ocfs2_meta_unlock(inode2, 1); | ||
1050 | } | ||
1051 | |||
1043 | #define PARENT_INO(buffer) \ | 1052 | #define PARENT_INO(buffer) \ |
1044 | ((struct ocfs2_dir_entry *) \ | 1053 | ((struct ocfs2_dir_entry *) \ |
1045 | ((char *)buffer + \ | 1054 | ((char *)buffer + \ |
@@ -1050,9 +1059,11 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1050 | struct inode *new_dir, | 1059 | struct inode *new_dir, |
1051 | struct dentry *new_dentry) | 1060 | struct dentry *new_dentry) |
1052 | { | 1061 | { |
1053 | int status = 0, rename_lock = 0; | 1062 | int status = 0, rename_lock = 0, parents_locked = 0; |
1063 | int old_child_locked = 0, new_child_locked = 0; | ||
1054 | struct inode *old_inode = old_dentry->d_inode; | 1064 | struct inode *old_inode = old_dentry->d_inode; |
1055 | struct inode *new_inode = new_dentry->d_inode; | 1065 | struct inode *new_inode = new_dentry->d_inode; |
1066 | struct inode *orphan_dir = NULL; | ||
1056 | struct ocfs2_dinode *newfe = NULL; | 1067 | struct ocfs2_dinode *newfe = NULL; |
1057 | char orphan_name[OCFS2_ORPHAN_NAMELEN + 1]; | 1068 | char orphan_name[OCFS2_ORPHAN_NAMELEN + 1]; |
1058 | struct buffer_head *orphan_entry_bh = NULL; | 1069 | struct buffer_head *orphan_entry_bh = NULL; |
@@ -1060,7 +1071,7 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1060 | struct buffer_head *insert_entry_bh = NULL; | 1071 | struct buffer_head *insert_entry_bh = NULL; |
1061 | struct ocfs2_super *osb = NULL; | 1072 | struct ocfs2_super *osb = NULL; |
1062 | u64 newfe_blkno; | 1073 | u64 newfe_blkno; |
1063 | struct ocfs2_journal_handle *handle = NULL; | 1074 | handle_t *handle = NULL; |
1064 | struct buffer_head *old_dir_bh = NULL; | 1075 | struct buffer_head *old_dir_bh = NULL; |
1065 | struct buffer_head *new_dir_bh = NULL; | 1076 | struct buffer_head *new_dir_bh = NULL; |
1066 | struct ocfs2_dir_entry *old_de = NULL, *new_de = NULL; // dirent for old_dentry | 1077 | struct ocfs2_dir_entry *old_de = NULL, *new_de = NULL; // dirent for old_dentry |
@@ -1105,21 +1116,14 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1105 | rename_lock = 1; | 1116 | rename_lock = 1; |
1106 | } | 1117 | } |
1107 | 1118 | ||
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. */ | 1119 | /* if old and new are the same, this'll just do one lock. */ |
1116 | status = ocfs2_double_lock(osb, handle, | 1120 | status = ocfs2_double_lock(osb, &old_dir_bh, old_dir, |
1117 | &old_dir_bh, old_dir, | 1121 | &new_dir_bh, new_dir); |
1118 | &new_dir_bh, new_dir); | ||
1119 | if (status < 0) { | 1122 | if (status < 0) { |
1120 | mlog_errno(status); | 1123 | mlog_errno(status); |
1121 | goto bail; | 1124 | goto bail; |
1122 | } | 1125 | } |
1126 | parents_locked = 1; | ||
1123 | 1127 | ||
1124 | /* make sure both dirs have bhs | 1128 | /* make sure both dirs have bhs |
1125 | * get an extra ref on old_dir_bh if old==new */ | 1129 | * get an extra ref on old_dir_bh if old==new */ |
@@ -1140,12 +1144,13 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1140 | * the vote thread on other nodes won't have to concurrently | 1144 | * the vote thread on other nodes won't have to concurrently |
1141 | * downconvert the inode and the dentry locks. | 1145 | * downconvert the inode and the dentry locks. |
1142 | */ | 1146 | */ |
1143 | status = ocfs2_meta_lock(old_inode, handle, NULL, 1); | 1147 | status = ocfs2_meta_lock(old_inode, NULL, 1); |
1144 | if (status < 0) { | 1148 | if (status < 0) { |
1145 | if (status != -ENOENT) | 1149 | if (status != -ENOENT) |
1146 | mlog_errno(status); | 1150 | mlog_errno(status); |
1147 | goto bail; | 1151 | goto bail; |
1148 | } | 1152 | } |
1153 | old_child_locked = 1; | ||
1149 | 1154 | ||
1150 | status = ocfs2_remote_dentry_delete(old_dentry); | 1155 | status = ocfs2_remote_dentry_delete(old_dentry); |
1151 | if (status < 0) { | 1156 | if (status < 0) { |
@@ -1231,12 +1236,13 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1231 | goto bail; | 1236 | goto bail; |
1232 | } | 1237 | } |
1233 | 1238 | ||
1234 | status = ocfs2_meta_lock(new_inode, handle, &newfe_bh, 1); | 1239 | status = ocfs2_meta_lock(new_inode, &newfe_bh, 1); |
1235 | if (status < 0) { | 1240 | if (status < 0) { |
1236 | if (status != -ENOENT) | 1241 | if (status != -ENOENT) |
1237 | mlog_errno(status); | 1242 | mlog_errno(status); |
1238 | goto bail; | 1243 | goto bail; |
1239 | } | 1244 | } |
1245 | new_child_locked = 1; | ||
1240 | 1246 | ||
1241 | status = ocfs2_remote_dentry_delete(new_dentry); | 1247 | status = ocfs2_remote_dentry_delete(new_dentry); |
1242 | if (status < 0) { | 1248 | if (status < 0) { |
@@ -1252,7 +1258,7 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1252 | (unsigned long long)newfe_bh->b_blocknr : 0ULL); | 1258 | (unsigned long long)newfe_bh->b_blocknr : 0ULL); |
1253 | 1259 | ||
1254 | if (S_ISDIR(new_inode->i_mode) || (new_inode->i_nlink == 1)) { | 1260 | if (S_ISDIR(new_inode->i_mode) || (new_inode->i_nlink == 1)) { |
1255 | status = ocfs2_prepare_orphan_dir(osb, handle, | 1261 | status = ocfs2_prepare_orphan_dir(osb, &orphan_dir, |
1256 | new_inode, | 1262 | new_inode, |
1257 | orphan_name, | 1263 | orphan_name, |
1258 | &orphan_entry_bh); | 1264 | &orphan_entry_bh); |
@@ -1280,7 +1286,7 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1280 | } | 1286 | } |
1281 | } | 1287 | } |
1282 | 1288 | ||
1283 | handle = ocfs2_start_trans(osb, handle, OCFS2_RENAME_CREDITS); | 1289 | handle = ocfs2_start_trans(osb, OCFS2_RENAME_CREDITS); |
1284 | if (IS_ERR(handle)) { | 1290 | if (IS_ERR(handle)) { |
1285 | status = PTR_ERR(handle); | 1291 | status = PTR_ERR(handle); |
1286 | handle = NULL; | 1292 | handle = NULL; |
@@ -1307,7 +1313,7 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1307 | (newfe->i_links_count == cpu_to_le16(1))){ | 1313 | (newfe->i_links_count == cpu_to_le16(1))){ |
1308 | status = ocfs2_orphan_add(osb, handle, new_inode, | 1314 | status = ocfs2_orphan_add(osb, handle, new_inode, |
1309 | newfe, orphan_name, | 1315 | newfe, orphan_name, |
1310 | orphan_entry_bh); | 1316 | orphan_entry_bh, orphan_dir); |
1311 | if (status < 0) { | 1317 | if (status < 0) { |
1312 | mlog_errno(status); | 1318 | mlog_errno(status); |
1313 | goto bail; | 1319 | goto bail; |
@@ -1424,7 +1430,23 @@ bail: | |||
1424 | ocfs2_rename_unlock(osb); | 1430 | ocfs2_rename_unlock(osb); |
1425 | 1431 | ||
1426 | if (handle) | 1432 | if (handle) |
1427 | ocfs2_commit_trans(handle); | 1433 | ocfs2_commit_trans(osb, handle); |
1434 | |||
1435 | if (parents_locked) | ||
1436 | ocfs2_double_unlock(old_dir, new_dir); | ||
1437 | |||
1438 | if (old_child_locked) | ||
1439 | ocfs2_meta_unlock(old_inode, 1); | ||
1440 | |||
1441 | if (new_child_locked) | ||
1442 | ocfs2_meta_unlock(new_inode, 1); | ||
1443 | |||
1444 | if (orphan_dir) { | ||
1445 | /* This was locked for us in ocfs2_prepare_orphan_dir() */ | ||
1446 | ocfs2_meta_unlock(orphan_dir, 1); | ||
1447 | mutex_unlock(&orphan_dir->i_mutex); | ||
1448 | iput(orphan_dir); | ||
1449 | } | ||
1428 | 1450 | ||
1429 | if (new_inode) | 1451 | if (new_inode) |
1430 | sync_mapping_buffers(old_inode->i_mapping); | 1452 | sync_mapping_buffers(old_inode->i_mapping); |
@@ -1458,7 +1480,7 @@ bail: | |||
1458 | * data, including the null terminator. | 1480 | * data, including the null terminator. |
1459 | */ | 1481 | */ |
1460 | static int ocfs2_create_symlink_data(struct ocfs2_super *osb, | 1482 | static int ocfs2_create_symlink_data(struct ocfs2_super *osb, |
1461 | struct ocfs2_journal_handle *handle, | 1483 | handle_t *handle, |
1462 | struct inode *inode, | 1484 | struct inode *inode, |
1463 | const char *symname) | 1485 | const char *symname) |
1464 | { | 1486 | { |
@@ -1573,7 +1595,7 @@ static int ocfs2_symlink(struct inode *dir, | |||
1573 | struct buffer_head *parent_fe_bh = NULL; | 1595 | struct buffer_head *parent_fe_bh = NULL; |
1574 | struct ocfs2_dinode *fe = NULL; | 1596 | struct ocfs2_dinode *fe = NULL; |
1575 | struct ocfs2_dinode *dirfe; | 1597 | struct ocfs2_dinode *dirfe; |
1576 | struct ocfs2_journal_handle *handle = NULL; | 1598 | handle_t *handle = NULL; |
1577 | struct ocfs2_alloc_context *inode_ac = NULL; | 1599 | struct ocfs2_alloc_context *inode_ac = NULL; |
1578 | struct ocfs2_alloc_context *data_ac = NULL; | 1600 | struct ocfs2_alloc_context *data_ac = NULL; |
1579 | 1601 | ||
@@ -1587,19 +1609,12 @@ static int ocfs2_symlink(struct inode *dir, | |||
1587 | 1609 | ||
1588 | credits = ocfs2_calc_symlink_credits(sb); | 1610 | credits = ocfs2_calc_symlink_credits(sb); |
1589 | 1611 | ||
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 */ | 1612 | /* lock the parent directory */ |
1598 | status = ocfs2_meta_lock(dir, handle, &parent_fe_bh, 1); | 1613 | status = ocfs2_meta_lock(dir, &parent_fe_bh, 1); |
1599 | if (status < 0) { | 1614 | if (status < 0) { |
1600 | if (status != -ENOENT) | 1615 | if (status != -ENOENT) |
1601 | mlog_errno(status); | 1616 | mlog_errno(status); |
1602 | goto bail; | 1617 | return status; |
1603 | } | 1618 | } |
1604 | 1619 | ||
1605 | dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data; | 1620 | dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data; |
@@ -1622,7 +1637,7 @@ static int ocfs2_symlink(struct inode *dir, | |||
1622 | goto bail; | 1637 | goto bail; |
1623 | } | 1638 | } |
1624 | 1639 | ||
1625 | status = ocfs2_reserve_new_inode(osb, handle, &inode_ac); | 1640 | status = ocfs2_reserve_new_inode(osb, &inode_ac); |
1626 | if (status < 0) { | 1641 | if (status < 0) { |
1627 | if (status != -ENOSPC) | 1642 | if (status != -ENOSPC) |
1628 | mlog_errno(status); | 1643 | mlog_errno(status); |
@@ -1631,7 +1646,7 @@ static int ocfs2_symlink(struct inode *dir, | |||
1631 | 1646 | ||
1632 | /* don't reserve bitmap space for fast symlinks. */ | 1647 | /* don't reserve bitmap space for fast symlinks. */ |
1633 | if (l > ocfs2_fast_symlink_chars(sb)) { | 1648 | if (l > ocfs2_fast_symlink_chars(sb)) { |
1634 | status = ocfs2_reserve_clusters(osb, handle, 1, &data_ac); | 1649 | status = ocfs2_reserve_clusters(osb, 1, &data_ac); |
1635 | if (status < 0) { | 1650 | if (status < 0) { |
1636 | if (status != -ENOSPC) | 1651 | if (status != -ENOSPC) |
1637 | mlog_errno(status); | 1652 | mlog_errno(status); |
@@ -1639,7 +1654,7 @@ static int ocfs2_symlink(struct inode *dir, | |||
1639 | } | 1654 | } |
1640 | } | 1655 | } |
1641 | 1656 | ||
1642 | handle = ocfs2_start_trans(osb, handle, credits); | 1657 | handle = ocfs2_start_trans(osb, credits); |
1643 | if (IS_ERR(handle)) { | 1658 | if (IS_ERR(handle)) { |
1644 | status = PTR_ERR(handle); | 1659 | status = PTR_ERR(handle); |
1645 | handle = NULL; | 1660 | handle = NULL; |
@@ -1717,7 +1732,10 @@ static int ocfs2_symlink(struct inode *dir, | |||
1717 | d_instantiate(dentry, inode); | 1732 | d_instantiate(dentry, inode); |
1718 | bail: | 1733 | bail: |
1719 | if (handle) | 1734 | if (handle) |
1720 | ocfs2_commit_trans(handle); | 1735 | ocfs2_commit_trans(osb, handle); |
1736 | |||
1737 | ocfs2_meta_unlock(dir, 1); | ||
1738 | |||
1721 | if (new_fe_bh) | 1739 | if (new_fe_bh) |
1722 | brelse(new_fe_bh); | 1740 | brelse(new_fe_bh); |
1723 | if (parent_fe_bh) | 1741 | if (parent_fe_bh) |
@@ -1768,7 +1786,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 | 1786 | * If you pass me insert_bh, I'll skip the search of the other dir |
1769 | * blocks and put the record in there. | 1787 | * blocks and put the record in there. |
1770 | */ | 1788 | */ |
1771 | static int __ocfs2_add_entry(struct ocfs2_journal_handle *handle, | 1789 | static int __ocfs2_add_entry(handle_t *handle, |
1772 | struct inode *dir, | 1790 | struct inode *dir, |
1773 | const char *name, int namelen, | 1791 | const char *name, int namelen, |
1774 | struct inode *inode, u64 blkno, | 1792 | struct inode *inode, u64 blkno, |
@@ -1854,7 +1872,7 @@ bail: | |||
1854 | * ocfs2_delete_entry deletes a directory entry by merging it with the | 1872 | * ocfs2_delete_entry deletes a directory entry by merging it with the |
1855 | * previous entry | 1873 | * previous entry |
1856 | */ | 1874 | */ |
1857 | static int ocfs2_delete_entry(struct ocfs2_journal_handle *handle, | 1875 | static int ocfs2_delete_entry(handle_t *handle, |
1858 | struct inode *dir, | 1876 | struct inode *dir, |
1859 | struct ocfs2_dir_entry *de_del, | 1877 | struct ocfs2_dir_entry *de_del, |
1860 | struct buffer_head *bh) | 1878 | struct buffer_head *bh) |
@@ -2085,19 +2103,19 @@ bail: | |||
2085 | } | 2103 | } |
2086 | 2104 | ||
2087 | static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, | 2105 | static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, |
2088 | struct ocfs2_journal_handle *handle, | 2106 | struct inode **ret_orphan_dir, |
2089 | struct inode *inode, | 2107 | struct inode *inode, |
2090 | char *name, | 2108 | char *name, |
2091 | struct buffer_head **de_bh) | 2109 | struct buffer_head **de_bh) |
2092 | { | 2110 | { |
2093 | struct inode *orphan_dir_inode = NULL; | 2111 | struct inode *orphan_dir_inode; |
2094 | struct buffer_head *orphan_dir_bh = NULL; | 2112 | struct buffer_head *orphan_dir_bh = NULL; |
2095 | int status = 0; | 2113 | int status = 0; |
2096 | 2114 | ||
2097 | status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno, name); | 2115 | status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno, name); |
2098 | if (status < 0) { | 2116 | if (status < 0) { |
2099 | mlog_errno(status); | 2117 | mlog_errno(status); |
2100 | goto leave; | 2118 | return status; |
2101 | } | 2119 | } |
2102 | 2120 | ||
2103 | orphan_dir_inode = ocfs2_get_system_file_inode(osb, | 2121 | orphan_dir_inode = ocfs2_get_system_file_inode(osb, |
@@ -2106,11 +2124,12 @@ static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, | |||
2106 | if (!orphan_dir_inode) { | 2124 | if (!orphan_dir_inode) { |
2107 | status = -ENOENT; | 2125 | status = -ENOENT; |
2108 | mlog_errno(status); | 2126 | mlog_errno(status); |
2109 | goto leave; | 2127 | return status; |
2110 | } | 2128 | } |
2111 | 2129 | ||
2112 | ocfs2_handle_add_inode(handle, orphan_dir_inode); | 2130 | mutex_lock(&orphan_dir_inode->i_mutex); |
2113 | status = ocfs2_meta_lock(orphan_dir_inode, handle, &orphan_dir_bh, 1); | 2131 | |
2132 | status = ocfs2_meta_lock(orphan_dir_inode, &orphan_dir_bh, 1); | ||
2114 | if (status < 0) { | 2133 | if (status < 0) { |
2115 | mlog_errno(status); | 2134 | mlog_errno(status); |
2116 | goto leave; | 2135 | goto leave; |
@@ -2120,13 +2139,19 @@ static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, | |||
2120 | orphan_dir_bh, name, | 2139 | orphan_dir_bh, name, |
2121 | OCFS2_ORPHAN_NAMELEN, de_bh); | 2140 | OCFS2_ORPHAN_NAMELEN, de_bh); |
2122 | if (status < 0) { | 2141 | if (status < 0) { |
2142 | ocfs2_meta_unlock(orphan_dir_inode, 1); | ||
2143 | |||
2123 | mlog_errno(status); | 2144 | mlog_errno(status); |
2124 | goto leave; | 2145 | goto leave; |
2125 | } | 2146 | } |
2126 | 2147 | ||
2148 | *ret_orphan_dir = orphan_dir_inode; | ||
2149 | |||
2127 | leave: | 2150 | leave: |
2128 | if (orphan_dir_inode) | 2151 | if (status) { |
2152 | mutex_unlock(&orphan_dir_inode->i_mutex); | ||
2129 | iput(orphan_dir_inode); | 2153 | iput(orphan_dir_inode); |
2154 | } | ||
2130 | 2155 | ||
2131 | if (orphan_dir_bh) | 2156 | if (orphan_dir_bh) |
2132 | brelse(orphan_dir_bh); | 2157 | brelse(orphan_dir_bh); |
@@ -2136,28 +2161,19 @@ leave: | |||
2136 | } | 2161 | } |
2137 | 2162 | ||
2138 | static int ocfs2_orphan_add(struct ocfs2_super *osb, | 2163 | static int ocfs2_orphan_add(struct ocfs2_super *osb, |
2139 | struct ocfs2_journal_handle *handle, | 2164 | handle_t *handle, |
2140 | struct inode *inode, | 2165 | struct inode *inode, |
2141 | struct ocfs2_dinode *fe, | 2166 | struct ocfs2_dinode *fe, |
2142 | char *name, | 2167 | char *name, |
2143 | struct buffer_head *de_bh) | 2168 | struct buffer_head *de_bh, |
2169 | struct inode *orphan_dir_inode) | ||
2144 | { | 2170 | { |
2145 | struct inode *orphan_dir_inode = NULL; | ||
2146 | struct buffer_head *orphan_dir_bh = NULL; | 2171 | struct buffer_head *orphan_dir_bh = NULL; |
2147 | int status = 0; | 2172 | int status = 0; |
2148 | struct ocfs2_dinode *orphan_fe; | 2173 | struct ocfs2_dinode *orphan_fe; |
2149 | 2174 | ||
2150 | mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino); | 2175 | mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino); |
2151 | 2176 | ||
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, | 2177 | status = ocfs2_read_block(osb, |
2162 | OCFS2_I(orphan_dir_inode)->ip_blkno, | 2178 | OCFS2_I(orphan_dir_inode)->ip_blkno, |
2163 | &orphan_dir_bh, OCFS2_BH_CACHED, | 2179 | &orphan_dir_bh, OCFS2_BH_CACHED, |
@@ -2209,9 +2225,6 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb, | |||
2209 | (unsigned long long)OCFS2_I(inode)->ip_blkno, osb->slot_num); | 2225 | (unsigned long long)OCFS2_I(inode)->ip_blkno, osb->slot_num); |
2210 | 2226 | ||
2211 | leave: | 2227 | leave: |
2212 | if (orphan_dir_inode) | ||
2213 | iput(orphan_dir_inode); | ||
2214 | |||
2215 | if (orphan_dir_bh) | 2228 | if (orphan_dir_bh) |
2216 | brelse(orphan_dir_bh); | 2229 | brelse(orphan_dir_bh); |
2217 | 2230 | ||
@@ -2221,7 +2234,7 @@ leave: | |||
2221 | 2234 | ||
2222 | /* unlike orphan_add, we expect the orphan dir to already be locked here. */ | 2235 | /* unlike orphan_add, we expect the orphan dir to already be locked here. */ |
2223 | int ocfs2_orphan_del(struct ocfs2_super *osb, | 2236 | int ocfs2_orphan_del(struct ocfs2_super *osb, |
2224 | struct ocfs2_journal_handle *handle, | 2237 | handle_t *handle, |
2225 | struct inode *orphan_dir_inode, | 2238 | struct inode *orphan_dir_inode, |
2226 | struct inode *inode, | 2239 | struct inode *inode, |
2227 | struct buffer_head *orphan_dir_bh) | 2240 | struct buffer_head *orphan_dir_bh) |
@@ -2300,4 +2313,5 @@ struct inode_operations ocfs2_dir_iops = { | |||
2300 | .rename = ocfs2_rename, | 2313 | .rename = ocfs2_rename, |
2301 | .setattr = ocfs2_setattr, | 2314 | .setattr = ocfs2_setattr, |
2302 | .getattr = ocfs2_getattr, | 2315 | .getattr = ocfs2_getattr, |
2316 | .permission = ocfs2_permission, | ||
2303 | }; | 2317 | }; |