diff options
Diffstat (limited to 'fs/ocfs2')
| -rw-r--r-- | fs/ocfs2/alloc.c | 40 | ||||
| -rw-r--r-- | fs/ocfs2/file.c | 60 | ||||
| -rw-r--r-- | fs/ocfs2/localalloc.c | 42 | ||||
| -rw-r--r-- | fs/ocfs2/localalloc.h | 6 | ||||
| -rw-r--r-- | fs/ocfs2/namei.c | 17 | ||||
| -rw-r--r-- | fs/ocfs2/quota_global.c | 27 | ||||
| -rw-r--r-- | fs/ocfs2/quota_local.c | 4 |
7 files changed, 159 insertions, 37 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 8750ae1b8636..e2edff38be52 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
| @@ -4742,6 +4742,7 @@ int ocfs2_add_clusters_in_btree(handle_t *handle, | |||
| 4742 | enum ocfs2_alloc_restarted *reason_ret) | 4742 | enum ocfs2_alloc_restarted *reason_ret) |
| 4743 | { | 4743 | { |
| 4744 | int status = 0, err = 0; | 4744 | int status = 0, err = 0; |
| 4745 | int need_free = 0; | ||
| 4745 | int free_extents; | 4746 | int free_extents; |
| 4746 | enum ocfs2_alloc_restarted reason = RESTART_NONE; | 4747 | enum ocfs2_alloc_restarted reason = RESTART_NONE; |
| 4747 | u32 bit_off, num_bits; | 4748 | u32 bit_off, num_bits; |
| @@ -4796,7 +4797,8 @@ int ocfs2_add_clusters_in_btree(handle_t *handle, | |||
| 4796 | OCFS2_JOURNAL_ACCESS_WRITE); | 4797 | OCFS2_JOURNAL_ACCESS_WRITE); |
| 4797 | if (status < 0) { | 4798 | if (status < 0) { |
| 4798 | mlog_errno(status); | 4799 | mlog_errno(status); |
| 4799 | goto leave; | 4800 | need_free = 1; |
| 4801 | goto bail; | ||
| 4800 | } | 4802 | } |
| 4801 | 4803 | ||
| 4802 | block = ocfs2_clusters_to_blocks(osb->sb, bit_off); | 4804 | block = ocfs2_clusters_to_blocks(osb->sb, bit_off); |
| @@ -4807,7 +4809,8 @@ int ocfs2_add_clusters_in_btree(handle_t *handle, | |||
| 4807 | num_bits, flags, meta_ac); | 4809 | num_bits, flags, meta_ac); |
| 4808 | if (status < 0) { | 4810 | if (status < 0) { |
| 4809 | mlog_errno(status); | 4811 | mlog_errno(status); |
| 4810 | goto leave; | 4812 | need_free = 1; |
| 4813 | goto bail; | ||
| 4811 | } | 4814 | } |
| 4812 | 4815 | ||
| 4813 | ocfs2_journal_dirty(handle, et->et_root_bh); | 4816 | ocfs2_journal_dirty(handle, et->et_root_bh); |
| @@ -4821,6 +4824,19 @@ int ocfs2_add_clusters_in_btree(handle_t *handle, | |||
| 4821 | reason = RESTART_TRANS; | 4824 | reason = RESTART_TRANS; |
| 4822 | } | 4825 | } |
| 4823 | 4826 | ||
| 4827 | bail: | ||
| 4828 | if (need_free) { | ||
| 4829 | if (data_ac->ac_which == OCFS2_AC_USE_LOCAL) | ||
| 4830 | ocfs2_free_local_alloc_bits(osb, handle, data_ac, | ||
| 4831 | bit_off, num_bits); | ||
| 4832 | else | ||
| 4833 | ocfs2_free_clusters(handle, | ||
| 4834 | data_ac->ac_inode, | ||
| 4835 | data_ac->ac_bh, | ||
| 4836 | ocfs2_clusters_to_blocks(osb->sb, bit_off), | ||
| 4837 | num_bits); | ||
| 4838 | } | ||
| 4839 | |||
| 4824 | leave: | 4840 | leave: |
| 4825 | if (reason_ret) | 4841 | if (reason_ret) |
| 4826 | *reason_ret = reason; | 4842 | *reason_ret = reason; |
| @@ -6805,6 +6821,8 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
| 6805 | struct buffer_head *di_bh) | 6821 | struct buffer_head *di_bh) |
| 6806 | { | 6822 | { |
| 6807 | int ret, i, has_data, num_pages = 0; | 6823 | int ret, i, has_data, num_pages = 0; |
| 6824 | int need_free = 0; | ||
| 6825 | u32 bit_off, num; | ||
| 6808 | handle_t *handle; | 6826 | handle_t *handle; |
| 6809 | u64 uninitialized_var(block); | 6827 | u64 uninitialized_var(block); |
| 6810 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | 6828 | struct ocfs2_inode_info *oi = OCFS2_I(inode); |
| @@ -6850,7 +6868,6 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
| 6850 | } | 6868 | } |
| 6851 | 6869 | ||
| 6852 | if (has_data) { | 6870 | if (has_data) { |
| 6853 | u32 bit_off, num; | ||
| 6854 | unsigned int page_end; | 6871 | unsigned int page_end; |
| 6855 | u64 phys; | 6872 | u64 phys; |
| 6856 | 6873 | ||
| @@ -6886,6 +6903,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
| 6886 | ret = ocfs2_grab_eof_pages(inode, 0, end, pages, &num_pages); | 6903 | ret = ocfs2_grab_eof_pages(inode, 0, end, pages, &num_pages); |
| 6887 | if (ret) { | 6904 | if (ret) { |
| 6888 | mlog_errno(ret); | 6905 | mlog_errno(ret); |
| 6906 | need_free = 1; | ||
| 6889 | goto out_commit; | 6907 | goto out_commit; |
| 6890 | } | 6908 | } |
| 6891 | 6909 | ||
| @@ -6896,6 +6914,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
| 6896 | ret = ocfs2_read_inline_data(inode, pages[0], di_bh); | 6914 | ret = ocfs2_read_inline_data(inode, pages[0], di_bh); |
| 6897 | if (ret) { | 6915 | if (ret) { |
| 6898 | mlog_errno(ret); | 6916 | mlog_errno(ret); |
| 6917 | need_free = 1; | ||
| 6899 | goto out_commit; | 6918 | goto out_commit; |
| 6900 | } | 6919 | } |
| 6901 | 6920 | ||
| @@ -6927,6 +6946,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
| 6927 | ret = ocfs2_insert_extent(handle, &et, 0, block, 1, 0, NULL); | 6946 | ret = ocfs2_insert_extent(handle, &et, 0, block, 1, 0, NULL); |
| 6928 | if (ret) { | 6947 | if (ret) { |
| 6929 | mlog_errno(ret); | 6948 | mlog_errno(ret); |
| 6949 | need_free = 1; | ||
| 6930 | goto out_commit; | 6950 | goto out_commit; |
| 6931 | } | 6951 | } |
| 6932 | 6952 | ||
| @@ -6938,6 +6958,18 @@ out_commit: | |||
| 6938 | dquot_free_space_nodirty(inode, | 6958 | dquot_free_space_nodirty(inode, |
| 6939 | ocfs2_clusters_to_bytes(osb->sb, 1)); | 6959 | ocfs2_clusters_to_bytes(osb->sb, 1)); |
| 6940 | 6960 | ||
| 6961 | if (need_free) { | ||
| 6962 | if (data_ac->ac_which == OCFS2_AC_USE_LOCAL) | ||
| 6963 | ocfs2_free_local_alloc_bits(osb, handle, data_ac, | ||
| 6964 | bit_off, num); | ||
| 6965 | else | ||
| 6966 | ocfs2_free_clusters(handle, | ||
| 6967 | data_ac->ac_inode, | ||
| 6968 | data_ac->ac_bh, | ||
| 6969 | ocfs2_clusters_to_blocks(osb->sb, bit_off), | ||
| 6970 | num); | ||
| 6971 | } | ||
| 6972 | |||
| 6941 | ocfs2_commit_trans(osb, handle); | 6973 | ocfs2_commit_trans(osb, handle); |
| 6942 | 6974 | ||
| 6943 | out_unlock: | 6975 | out_unlock: |
| @@ -7126,7 +7158,7 @@ int ocfs2_truncate_inline(struct inode *inode, struct buffer_head *di_bh, | |||
| 7126 | if (end > i_size_read(inode)) | 7158 | if (end > i_size_read(inode)) |
| 7127 | end = i_size_read(inode); | 7159 | end = i_size_read(inode); |
| 7128 | 7160 | ||
| 7129 | BUG_ON(start >= end); | 7161 | BUG_ON(start > end); |
| 7130 | 7162 | ||
| 7131 | if (!(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) || | 7163 | if (!(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) || |
| 7132 | !(le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_DATA_FL) || | 7164 | !(le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_DATA_FL) || |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index d77d71ead8d1..51632c40e896 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
| @@ -185,6 +185,9 @@ static int ocfs2_sync_file(struct file *file, loff_t start, loff_t end, | |||
| 185 | file->f_path.dentry->d_name.name, | 185 | file->f_path.dentry->d_name.name, |
| 186 | (unsigned long long)datasync); | 186 | (unsigned long long)datasync); |
| 187 | 187 | ||
| 188 | if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) | ||
| 189 | return -EROFS; | ||
| 190 | |||
| 188 | err = filemap_write_and_wait_range(inode->i_mapping, start, end); | 191 | err = filemap_write_and_wait_range(inode->i_mapping, start, end); |
| 189 | if (err) | 192 | if (err) |
| 190 | return err; | 193 | return err; |
| @@ -474,11 +477,6 @@ static int ocfs2_truncate_file(struct inode *inode, | |||
| 474 | goto bail; | 477 | goto bail; |
| 475 | } | 478 | } |
| 476 | 479 | ||
| 477 | /* lets handle the simple truncate cases before doing any more | ||
| 478 | * cluster locking. */ | ||
| 479 | if (new_i_size == le64_to_cpu(fe->i_size)) | ||
| 480 | goto bail; | ||
| 481 | |||
| 482 | down_write(&OCFS2_I(inode)->ip_alloc_sem); | 480 | down_write(&OCFS2_I(inode)->ip_alloc_sem); |
| 483 | 481 | ||
| 484 | ocfs2_resv_discard(&osb->osb_la_resmap, | 482 | ocfs2_resv_discard(&osb->osb_la_resmap, |
| @@ -718,7 +716,8 @@ leave: | |||
| 718 | * While a write will already be ordering the data, a truncate will not. | 716 | * While a write will already be ordering the data, a truncate will not. |
| 719 | * Thus, we need to explicitly order the zeroed pages. | 717 | * Thus, we need to explicitly order the zeroed pages. |
| 720 | */ | 718 | */ |
| 721 | static handle_t *ocfs2_zero_start_ordered_transaction(struct inode *inode) | 719 | static handle_t *ocfs2_zero_start_ordered_transaction(struct inode *inode, |
| 720 | struct buffer_head *di_bh) | ||
| 722 | { | 721 | { |
| 723 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 722 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
| 724 | handle_t *handle = NULL; | 723 | handle_t *handle = NULL; |
| @@ -735,7 +734,14 @@ static handle_t *ocfs2_zero_start_ordered_transaction(struct inode *inode) | |||
| 735 | } | 734 | } |
| 736 | 735 | ||
| 737 | ret = ocfs2_jbd2_file_inode(handle, inode); | 736 | ret = ocfs2_jbd2_file_inode(handle, inode); |
| 738 | if (ret < 0) | 737 | if (ret < 0) { |
| 738 | mlog_errno(ret); | ||
| 739 | goto out; | ||
| 740 | } | ||
| 741 | |||
| 742 | ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), di_bh, | ||
| 743 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
| 744 | if (ret) | ||
| 739 | mlog_errno(ret); | 745 | mlog_errno(ret); |
| 740 | 746 | ||
| 741 | out: | 747 | out: |
| @@ -751,7 +757,7 @@ out: | |||
| 751 | * to be too fragile to do exactly what we need without us having to | 757 | * to be too fragile to do exactly what we need without us having to |
| 752 | * worry about recursive locking in ->write_begin() and ->write_end(). */ | 758 | * worry about recursive locking in ->write_begin() and ->write_end(). */ |
| 753 | static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from, | 759 | static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from, |
| 754 | u64 abs_to) | 760 | u64 abs_to, struct buffer_head *di_bh) |
| 755 | { | 761 | { |
| 756 | struct address_space *mapping = inode->i_mapping; | 762 | struct address_space *mapping = inode->i_mapping; |
| 757 | struct page *page; | 763 | struct page *page; |
| @@ -759,6 +765,7 @@ static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from, | |||
| 759 | handle_t *handle = NULL; | 765 | handle_t *handle = NULL; |
| 760 | int ret = 0; | 766 | int ret = 0; |
| 761 | unsigned zero_from, zero_to, block_start, block_end; | 767 | unsigned zero_from, zero_to, block_start, block_end; |
| 768 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; | ||
| 762 | 769 | ||
| 763 | BUG_ON(abs_from >= abs_to); | 770 | BUG_ON(abs_from >= abs_to); |
| 764 | BUG_ON(abs_to > (((u64)index + 1) << PAGE_CACHE_SHIFT)); | 771 | BUG_ON(abs_to > (((u64)index + 1) << PAGE_CACHE_SHIFT)); |
| @@ -801,7 +808,8 @@ static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from, | |||
| 801 | } | 808 | } |
| 802 | 809 | ||
| 803 | if (!handle) { | 810 | if (!handle) { |
| 804 | handle = ocfs2_zero_start_ordered_transaction(inode); | 811 | handle = ocfs2_zero_start_ordered_transaction(inode, |
| 812 | di_bh); | ||
| 805 | if (IS_ERR(handle)) { | 813 | if (IS_ERR(handle)) { |
| 806 | ret = PTR_ERR(handle); | 814 | ret = PTR_ERR(handle); |
| 807 | handle = NULL; | 815 | handle = NULL; |
| @@ -818,8 +826,22 @@ static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from, | |||
| 818 | ret = 0; | 826 | ret = 0; |
| 819 | } | 827 | } |
| 820 | 828 | ||
| 821 | if (handle) | 829 | if (handle) { |
| 830 | /* | ||
| 831 | * fs-writeback will release the dirty pages without page lock | ||
| 832 | * whose offset are over inode size, the release happens at | ||
| 833 | * block_write_full_page_endio(). | ||
| 834 | */ | ||
| 835 | i_size_write(inode, abs_to); | ||
| 836 | inode->i_blocks = ocfs2_inode_sector_count(inode); | ||
| 837 | di->i_size = cpu_to_le64((u64)i_size_read(inode)); | ||
| 838 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
| 839 | di->i_mtime = di->i_ctime = cpu_to_le64(inode->i_mtime.tv_sec); | ||
| 840 | di->i_ctime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec); | ||
| 841 | di->i_mtime_nsec = di->i_ctime_nsec; | ||
| 842 | ocfs2_journal_dirty(handle, di_bh); | ||
| 822 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); | 843 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); |
| 844 | } | ||
| 823 | 845 | ||
| 824 | out_unlock: | 846 | out_unlock: |
| 825 | unlock_page(page); | 847 | unlock_page(page); |
| @@ -915,7 +937,7 @@ out: | |||
| 915 | * has made sure that the entire range needs zeroing. | 937 | * has made sure that the entire range needs zeroing. |
| 916 | */ | 938 | */ |
| 917 | static int ocfs2_zero_extend_range(struct inode *inode, u64 range_start, | 939 | static int ocfs2_zero_extend_range(struct inode *inode, u64 range_start, |
| 918 | u64 range_end) | 940 | u64 range_end, struct buffer_head *di_bh) |
| 919 | { | 941 | { |
| 920 | int rc = 0; | 942 | int rc = 0; |
| 921 | u64 next_pos; | 943 | u64 next_pos; |
| @@ -931,7 +953,7 @@ static int ocfs2_zero_extend_range(struct inode *inode, u64 range_start, | |||
| 931 | next_pos = (zero_pos & PAGE_CACHE_MASK) + PAGE_CACHE_SIZE; | 953 | next_pos = (zero_pos & PAGE_CACHE_MASK) + PAGE_CACHE_SIZE; |
| 932 | if (next_pos > range_end) | 954 | if (next_pos > range_end) |
| 933 | next_pos = range_end; | 955 | next_pos = range_end; |
| 934 | rc = ocfs2_write_zero_page(inode, zero_pos, next_pos); | 956 | rc = ocfs2_write_zero_page(inode, zero_pos, next_pos, di_bh); |
| 935 | if (rc < 0) { | 957 | if (rc < 0) { |
| 936 | mlog_errno(rc); | 958 | mlog_errno(rc); |
| 937 | break; | 959 | break; |
| @@ -977,7 +999,7 @@ int ocfs2_zero_extend(struct inode *inode, struct buffer_head *di_bh, | |||
| 977 | range_end = zero_to_size; | 999 | range_end = zero_to_size; |
| 978 | 1000 | ||
| 979 | ret = ocfs2_zero_extend_range(inode, range_start, | 1001 | ret = ocfs2_zero_extend_range(inode, range_start, |
| 980 | range_end); | 1002 | range_end, di_bh); |
| 981 | if (ret) { | 1003 | if (ret) { |
| 982 | mlog_errno(ret); | 1004 | mlog_errno(ret); |
| 983 | break; | 1005 | break; |
| @@ -1145,14 +1167,14 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
| 1145 | goto bail_unlock_rw; | 1167 | goto bail_unlock_rw; |
| 1146 | } | 1168 | } |
| 1147 | 1169 | ||
| 1148 | if (size_change && attr->ia_size != i_size_read(inode)) { | 1170 | if (size_change) { |
| 1149 | status = inode_newsize_ok(inode, attr->ia_size); | 1171 | status = inode_newsize_ok(inode, attr->ia_size); |
| 1150 | if (status) | 1172 | if (status) |
| 1151 | goto bail_unlock; | 1173 | goto bail_unlock; |
| 1152 | 1174 | ||
| 1153 | inode_dio_wait(inode); | 1175 | inode_dio_wait(inode); |
| 1154 | 1176 | ||
| 1155 | if (i_size_read(inode) > attr->ia_size) { | 1177 | if (i_size_read(inode) >= attr->ia_size) { |
| 1156 | if (ocfs2_should_order_data(inode)) { | 1178 | if (ocfs2_should_order_data(inode)) { |
| 1157 | status = ocfs2_begin_ordered_truncate(inode, | 1179 | status = ocfs2_begin_ordered_truncate(inode, |
| 1158 | attr->ia_size); | 1180 | attr->ia_size); |
| @@ -2371,8 +2393,8 @@ out_dio: | |||
| 2371 | 2393 | ||
| 2372 | if (((file->f_flags & O_DSYNC) && !direct_io) || IS_SYNC(inode) || | 2394 | if (((file->f_flags & O_DSYNC) && !direct_io) || IS_SYNC(inode) || |
| 2373 | ((file->f_flags & O_DIRECT) && !direct_io)) { | 2395 | ((file->f_flags & O_DIRECT) && !direct_io)) { |
| 2374 | ret = filemap_fdatawrite_range(file->f_mapping, pos, | 2396 | ret = filemap_fdatawrite_range(file->f_mapping, *ppos, |
| 2375 | pos + count - 1); | 2397 | *ppos + count - 1); |
| 2376 | if (ret < 0) | 2398 | if (ret < 0) |
| 2377 | written = ret; | 2399 | written = ret; |
| 2378 | 2400 | ||
| @@ -2385,8 +2407,8 @@ out_dio: | |||
| 2385 | } | 2407 | } |
| 2386 | 2408 | ||
| 2387 | if (!ret) | 2409 | if (!ret) |
| 2388 | ret = filemap_fdatawait_range(file->f_mapping, pos, | 2410 | ret = filemap_fdatawait_range(file->f_mapping, *ppos, |
| 2389 | pos + count - 1); | 2411 | *ppos + count - 1); |
| 2390 | } | 2412 | } |
| 2391 | 2413 | ||
| 2392 | /* | 2414 | /* |
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c index cd5496b7a0a3..044013455621 100644 --- a/fs/ocfs2/localalloc.c +++ b/fs/ocfs2/localalloc.c | |||
| @@ -781,6 +781,48 @@ bail: | |||
| 781 | return status; | 781 | return status; |
| 782 | } | 782 | } |
| 783 | 783 | ||
| 784 | int ocfs2_free_local_alloc_bits(struct ocfs2_super *osb, | ||
| 785 | handle_t *handle, | ||
| 786 | struct ocfs2_alloc_context *ac, | ||
| 787 | u32 bit_off, | ||
| 788 | u32 num_bits) | ||
| 789 | { | ||
| 790 | int status, start; | ||
| 791 | u32 clear_bits; | ||
| 792 | struct inode *local_alloc_inode; | ||
| 793 | void *bitmap; | ||
| 794 | struct ocfs2_dinode *alloc; | ||
| 795 | struct ocfs2_local_alloc *la; | ||
| 796 | |||
| 797 | BUG_ON(ac->ac_which != OCFS2_AC_USE_LOCAL); | ||
| 798 | |||
| 799 | local_alloc_inode = ac->ac_inode; | ||
| 800 | alloc = (struct ocfs2_dinode *) osb->local_alloc_bh->b_data; | ||
| 801 | la = OCFS2_LOCAL_ALLOC(alloc); | ||
| 802 | |||
| 803 | bitmap = la->la_bitmap; | ||
| 804 | start = bit_off - le32_to_cpu(la->la_bm_off); | ||
| 805 | clear_bits = num_bits; | ||
| 806 | |||
| 807 | status = ocfs2_journal_access_di(handle, | ||
| 808 | INODE_CACHE(local_alloc_inode), | ||
| 809 | osb->local_alloc_bh, | ||
| 810 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
| 811 | if (status < 0) { | ||
| 812 | mlog_errno(status); | ||
| 813 | goto bail; | ||
| 814 | } | ||
| 815 | |||
| 816 | while (clear_bits--) | ||
| 817 | ocfs2_clear_bit(start++, bitmap); | ||
| 818 | |||
| 819 | le32_add_cpu(&alloc->id1.bitmap1.i_used, -num_bits); | ||
| 820 | ocfs2_journal_dirty(handle, osb->local_alloc_bh); | ||
| 821 | |||
| 822 | bail: | ||
| 823 | return status; | ||
| 824 | } | ||
| 825 | |||
| 784 | static u32 ocfs2_local_alloc_count_bits(struct ocfs2_dinode *alloc) | 826 | static u32 ocfs2_local_alloc_count_bits(struct ocfs2_dinode *alloc) |
| 785 | { | 827 | { |
| 786 | u32 count; | 828 | u32 count; |
diff --git a/fs/ocfs2/localalloc.h b/fs/ocfs2/localalloc.h index 1be9b5864460..44a7d1fb2dec 100644 --- a/fs/ocfs2/localalloc.h +++ b/fs/ocfs2/localalloc.h | |||
| @@ -55,6 +55,12 @@ int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb, | |||
| 55 | u32 *bit_off, | 55 | u32 *bit_off, |
| 56 | u32 *num_bits); | 56 | u32 *num_bits); |
| 57 | 57 | ||
| 58 | int ocfs2_free_local_alloc_bits(struct ocfs2_super *osb, | ||
| 59 | handle_t *handle, | ||
| 60 | struct ocfs2_alloc_context *ac, | ||
| 61 | u32 bit_off, | ||
| 62 | u32 num_bits); | ||
| 63 | |||
| 58 | void ocfs2_local_alloc_seen_free_bits(struct ocfs2_super *osb, | 64 | void ocfs2_local_alloc_seen_free_bits(struct ocfs2_super *osb, |
| 59 | unsigned int num_clusters); | 65 | unsigned int num_clusters); |
| 60 | void ocfs2_la_enable_worker(struct work_struct *work); | 66 | void ocfs2_la_enable_worker(struct work_struct *work); |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index f4d609be9400..3683643f3f0e 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
| @@ -664,6 +664,7 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
| 664 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); | 664 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); |
| 665 | struct ocfs2_dir_lookup_result lookup = { NULL, }; | 665 | struct ocfs2_dir_lookup_result lookup = { NULL, }; |
| 666 | sigset_t oldset; | 666 | sigset_t oldset; |
| 667 | u64 old_de_ino; | ||
| 667 | 668 | ||
| 668 | trace_ocfs2_link((unsigned long long)OCFS2_I(inode)->ip_blkno, | 669 | trace_ocfs2_link((unsigned long long)OCFS2_I(inode)->ip_blkno, |
| 669 | old_dentry->d_name.len, old_dentry->d_name.name, | 670 | old_dentry->d_name.len, old_dentry->d_name.name, |
| @@ -686,6 +687,22 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
| 686 | goto out; | 687 | goto out; |
| 687 | } | 688 | } |
| 688 | 689 | ||
| 690 | err = ocfs2_lookup_ino_from_name(dir, old_dentry->d_name.name, | ||
| 691 | old_dentry->d_name.len, &old_de_ino); | ||
| 692 | if (err) { | ||
| 693 | err = -ENOENT; | ||
| 694 | goto out; | ||
| 695 | } | ||
| 696 | |||
| 697 | /* | ||
| 698 | * Check whether another node removed the source inode while we | ||
| 699 | * were in the vfs. | ||
| 700 | */ | ||
| 701 | if (old_de_ino != OCFS2_I(inode)->ip_blkno) { | ||
| 702 | err = -ENOENT; | ||
| 703 | goto out; | ||
| 704 | } | ||
| 705 | |||
| 689 | err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name, | 706 | err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name, |
| 690 | dentry->d_name.len); | 707 | dentry->d_name.len); |
| 691 | if (err) | 708 | if (err) |
diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c index aaa50611ec66..d7b5108789e2 100644 --- a/fs/ocfs2/quota_global.c +++ b/fs/ocfs2/quota_global.c | |||
| @@ -717,6 +717,12 @@ static int ocfs2_release_dquot(struct dquot *dquot) | |||
| 717 | */ | 717 | */ |
| 718 | if (status < 0) | 718 | if (status < 0) |
| 719 | mlog_errno(status); | 719 | mlog_errno(status); |
| 720 | /* | ||
| 721 | * Clear dq_off so that we search for the structure in quota file next | ||
| 722 | * time we acquire it. The structure might be deleted and reallocated | ||
| 723 | * elsewhere by another node while our dquot structure is on freelist. | ||
| 724 | */ | ||
| 725 | dquot->dq_off = 0; | ||
| 720 | clear_bit(DQ_ACTIVE_B, &dquot->dq_flags); | 726 | clear_bit(DQ_ACTIVE_B, &dquot->dq_flags); |
| 721 | out_trans: | 727 | out_trans: |
| 722 | ocfs2_commit_trans(osb, handle); | 728 | ocfs2_commit_trans(osb, handle); |
| @@ -756,16 +762,17 @@ static int ocfs2_acquire_dquot(struct dquot *dquot) | |||
| 756 | status = ocfs2_lock_global_qf(info, 1); | 762 | status = ocfs2_lock_global_qf(info, 1); |
| 757 | if (status < 0) | 763 | if (status < 0) |
| 758 | goto out; | 764 | goto out; |
| 759 | if (!test_bit(DQ_READ_B, &dquot->dq_flags)) { | 765 | status = ocfs2_qinfo_lock(info, 0); |
| 760 | status = ocfs2_qinfo_lock(info, 0); | 766 | if (status < 0) |
| 761 | if (status < 0) | 767 | goto out_dq; |
| 762 | goto out_dq; | 768 | /* |
| 763 | status = qtree_read_dquot(&info->dqi_gi, dquot); | 769 | * We always want to read dquot structure from disk because we don't |
| 764 | ocfs2_qinfo_unlock(info, 0); | 770 | * know what happened with it while it was on freelist. |
| 765 | if (status < 0) | 771 | */ |
| 766 | goto out_dq; | 772 | status = qtree_read_dquot(&info->dqi_gi, dquot); |
| 767 | } | 773 | ocfs2_qinfo_unlock(info, 0); |
| 768 | set_bit(DQ_READ_B, &dquot->dq_flags); | 774 | if (status < 0) |
| 775 | goto out_dq; | ||
| 769 | 776 | ||
| 770 | OCFS2_DQUOT(dquot)->dq_use_count++; | 777 | OCFS2_DQUOT(dquot)->dq_use_count++; |
| 771 | OCFS2_DQUOT(dquot)->dq_origspace = dquot->dq_dqb.dqb_curspace; | 778 | OCFS2_DQUOT(dquot)->dq_origspace = dquot->dq_dqb.dqb_curspace; |
diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c index 2e4344be3b96..2001862bf2b1 100644 --- a/fs/ocfs2/quota_local.c +++ b/fs/ocfs2/quota_local.c | |||
| @@ -1303,10 +1303,6 @@ int ocfs2_local_release_dquot(handle_t *handle, struct dquot *dquot) | |||
| 1303 | ocfs2_journal_dirty(handle, od->dq_chunk->qc_headerbh); | 1303 | ocfs2_journal_dirty(handle, od->dq_chunk->qc_headerbh); |
| 1304 | 1304 | ||
| 1305 | out: | 1305 | out: |
| 1306 | /* Clear the read bit so that next time someone uses this | ||
| 1307 | * dquot he reads fresh info from disk and allocates local | ||
| 1308 | * dquot structure */ | ||
| 1309 | clear_bit(DQ_READ_B, &dquot->dq_flags); | ||
| 1310 | return status; | 1306 | return status; |
| 1311 | } | 1307 | } |
| 1312 | 1308 | ||
