diff options
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 | }; |
