diff options
Diffstat (limited to 'fs/gfs2/aops.c')
-rw-r--r-- | fs/gfs2/aops.c | 44 |
1 files changed, 22 insertions, 22 deletions
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 194fe16d8418..f9fbbe96c222 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c | |||
@@ -36,8 +36,8 @@ | |||
36 | #include "glops.h" | 36 | #include "glops.h" |
37 | 37 | ||
38 | 38 | ||
39 | static void gfs2_page_add_databufs(struct gfs2_inode *ip, struct page *page, | 39 | void gfs2_page_add_databufs(struct gfs2_inode *ip, struct page *page, |
40 | unsigned int from, unsigned int to) | 40 | unsigned int from, unsigned int to) |
41 | { | 41 | { |
42 | struct buffer_head *head = page_buffers(page); | 42 | struct buffer_head *head = page_buffers(page); |
43 | unsigned int bsize = head->b_size; | 43 | unsigned int bsize = head->b_size; |
@@ -615,10 +615,9 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping, | |||
615 | unsigned int data_blocks = 0, ind_blocks = 0, rblocks; | 615 | unsigned int data_blocks = 0, ind_blocks = 0, rblocks; |
616 | int alloc_required; | 616 | int alloc_required; |
617 | int error = 0; | 617 | int error = 0; |
618 | struct gfs2_alloc *al; | 618 | struct gfs2_alloc *al = NULL; |
619 | pgoff_t index = pos >> PAGE_CACHE_SHIFT; | 619 | pgoff_t index = pos >> PAGE_CACHE_SHIFT; |
620 | unsigned from = pos & (PAGE_CACHE_SIZE - 1); | 620 | unsigned from = pos & (PAGE_CACHE_SIZE - 1); |
621 | unsigned to = from + len; | ||
622 | struct page *page; | 621 | struct page *page; |
623 | 622 | ||
624 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh); | 623 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh); |
@@ -663,6 +662,8 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping, | |||
663 | rblocks += RES_STATFS + RES_QUOTA; | 662 | rblocks += RES_STATFS + RES_QUOTA; |
664 | if (&ip->i_inode == sdp->sd_rindex) | 663 | if (&ip->i_inode == sdp->sd_rindex) |
665 | rblocks += 2 * RES_STATFS; | 664 | rblocks += 2 * RES_STATFS; |
665 | if (alloc_required) | ||
666 | rblocks += gfs2_rg_blocks(al); | ||
666 | 667 | ||
667 | error = gfs2_trans_begin(sdp, rblocks, | 668 | error = gfs2_trans_begin(sdp, rblocks, |
668 | PAGE_CACHE_SIZE/sdp->sd_sb.sb_bsize); | 669 | PAGE_CACHE_SIZE/sdp->sd_sb.sb_bsize); |
@@ -689,20 +690,19 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping, | |||
689 | } | 690 | } |
690 | 691 | ||
691 | prepare_write: | 692 | prepare_write: |
692 | error = block_prepare_write(page, from, to, gfs2_block_map); | 693 | error = __block_write_begin(page, from, len, gfs2_block_map); |
693 | out: | 694 | out: |
694 | if (error == 0) | 695 | if (error == 0) |
695 | return 0; | 696 | return 0; |
696 | 697 | ||
698 | unlock_page(page); | ||
697 | page_cache_release(page); | 699 | page_cache_release(page); |
698 | 700 | ||
699 | /* | 701 | gfs2_trans_end(sdp); |
700 | * XXX(truncate): the call below should probably be replaced with | ||
701 | * a call to the gfs2-specific truncate blocks helper to actually | ||
702 | * release disk blocks.. | ||
703 | */ | ||
704 | if (pos + len > ip->i_inode.i_size) | 702 | if (pos + len > ip->i_inode.i_size) |
705 | truncate_setsize(&ip->i_inode, ip->i_inode.i_size); | 703 | gfs2_trim_blocks(&ip->i_inode); |
704 | goto out_trans_fail; | ||
705 | |||
706 | out_endtrans: | 706 | out_endtrans: |
707 | gfs2_trans_end(sdp); | 707 | gfs2_trans_end(sdp); |
708 | out_trans_fail: | 708 | out_trans_fail: |
@@ -802,10 +802,8 @@ static int gfs2_stuffed_write_end(struct inode *inode, struct buffer_head *dibh, | |||
802 | page_cache_release(page); | 802 | page_cache_release(page); |
803 | 803 | ||
804 | if (copied) { | 804 | if (copied) { |
805 | if (inode->i_size < to) { | 805 | if (inode->i_size < to) |
806 | i_size_write(inode, to); | 806 | i_size_write(inode, to); |
807 | ip->i_disksize = inode->i_size; | ||
808 | } | ||
809 | gfs2_dinode_out(ip, di); | 807 | gfs2_dinode_out(ip, di); |
810 | mark_inode_dirty(inode); | 808 | mark_inode_dirty(inode); |
811 | } | 809 | } |
@@ -876,8 +874,6 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping, | |||
876 | 874 | ||
877 | ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata); | 875 | ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata); |
878 | if (ret > 0) { | 876 | if (ret > 0) { |
879 | if (inode->i_size > ip->i_disksize) | ||
880 | ip->i_disksize = inode->i_size; | ||
881 | gfs2_dinode_out(ip, dibh->b_data); | 877 | gfs2_dinode_out(ip, dibh->b_data); |
882 | mark_inode_dirty(inode); | 878 | mark_inode_dirty(inode); |
883 | } | 879 | } |
@@ -888,8 +884,8 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping, | |||
888 | } | 884 | } |
889 | 885 | ||
890 | brelse(dibh); | 886 | brelse(dibh); |
891 | gfs2_trans_end(sdp); | ||
892 | failed: | 887 | failed: |
888 | gfs2_trans_end(sdp); | ||
893 | if (al) { | 889 | if (al) { |
894 | gfs2_inplace_release(ip); | 890 | gfs2_inplace_release(ip); |
895 | gfs2_quota_unlock(ip); | 891 | gfs2_quota_unlock(ip); |
@@ -1073,6 +1069,7 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask) | |||
1073 | return 0; | 1069 | return 0; |
1074 | 1070 | ||
1075 | gfs2_log_lock(sdp); | 1071 | gfs2_log_lock(sdp); |
1072 | spin_lock(&sdp->sd_ail_lock); | ||
1076 | head = bh = page_buffers(page); | 1073 | head = bh = page_buffers(page); |
1077 | do { | 1074 | do { |
1078 | if (atomic_read(&bh->b_count)) | 1075 | if (atomic_read(&bh->b_count)) |
@@ -1080,10 +1077,11 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask) | |||
1080 | bd = bh->b_private; | 1077 | bd = bh->b_private; |
1081 | if (bd && bd->bd_ail) | 1078 | if (bd && bd->bd_ail) |
1082 | goto cannot_release; | 1079 | goto cannot_release; |
1083 | gfs2_assert_warn(sdp, !buffer_pinned(bh)); | 1080 | if (buffer_pinned(bh) || buffer_dirty(bh)) |
1084 | gfs2_assert_warn(sdp, !buffer_dirty(bh)); | 1081 | goto not_possible; |
1085 | bh = bh->b_this_page; | 1082 | bh = bh->b_this_page; |
1086 | } while(bh != head); | 1083 | } while(bh != head); |
1084 | spin_unlock(&sdp->sd_ail_lock); | ||
1087 | gfs2_log_unlock(sdp); | 1085 | gfs2_log_unlock(sdp); |
1088 | 1086 | ||
1089 | head = bh = page_buffers(page); | 1087 | head = bh = page_buffers(page); |
@@ -1111,7 +1109,12 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask) | |||
1111 | } while (bh != head); | 1109 | } while (bh != head); |
1112 | 1110 | ||
1113 | return try_to_free_buffers(page); | 1111 | return try_to_free_buffers(page); |
1112 | |||
1113 | not_possible: /* Should never happen */ | ||
1114 | WARN_ON(buffer_dirty(bh)); | ||
1115 | WARN_ON(buffer_pinned(bh)); | ||
1114 | cannot_release: | 1116 | cannot_release: |
1117 | spin_unlock(&sdp->sd_ail_lock); | ||
1115 | gfs2_log_unlock(sdp); | 1118 | gfs2_log_unlock(sdp); |
1116 | return 0; | 1119 | return 0; |
1117 | } | 1120 | } |
@@ -1121,7 +1124,6 @@ static const struct address_space_operations gfs2_writeback_aops = { | |||
1121 | .writepages = gfs2_writeback_writepages, | 1124 | .writepages = gfs2_writeback_writepages, |
1122 | .readpage = gfs2_readpage, | 1125 | .readpage = gfs2_readpage, |
1123 | .readpages = gfs2_readpages, | 1126 | .readpages = gfs2_readpages, |
1124 | .sync_page = block_sync_page, | ||
1125 | .write_begin = gfs2_write_begin, | 1127 | .write_begin = gfs2_write_begin, |
1126 | .write_end = gfs2_write_end, | 1128 | .write_end = gfs2_write_end, |
1127 | .bmap = gfs2_bmap, | 1129 | .bmap = gfs2_bmap, |
@@ -1137,7 +1139,6 @@ static const struct address_space_operations gfs2_ordered_aops = { | |||
1137 | .writepage = gfs2_ordered_writepage, | 1139 | .writepage = gfs2_ordered_writepage, |
1138 | .readpage = gfs2_readpage, | 1140 | .readpage = gfs2_readpage, |
1139 | .readpages = gfs2_readpages, | 1141 | .readpages = gfs2_readpages, |
1140 | .sync_page = block_sync_page, | ||
1141 | .write_begin = gfs2_write_begin, | 1142 | .write_begin = gfs2_write_begin, |
1142 | .write_end = gfs2_write_end, | 1143 | .write_end = gfs2_write_end, |
1143 | .set_page_dirty = gfs2_set_page_dirty, | 1144 | .set_page_dirty = gfs2_set_page_dirty, |
@@ -1155,7 +1156,6 @@ static const struct address_space_operations gfs2_jdata_aops = { | |||
1155 | .writepages = gfs2_jdata_writepages, | 1156 | .writepages = gfs2_jdata_writepages, |
1156 | .readpage = gfs2_readpage, | 1157 | .readpage = gfs2_readpage, |
1157 | .readpages = gfs2_readpages, | 1158 | .readpages = gfs2_readpages, |
1158 | .sync_page = block_sync_page, | ||
1159 | .write_begin = gfs2_write_begin, | 1159 | .write_begin = gfs2_write_begin, |
1160 | .write_end = gfs2_write_end, | 1160 | .write_end = gfs2_write_end, |
1161 | .set_page_dirty = gfs2_set_page_dirty, | 1161 | .set_page_dirty = gfs2_set_page_dirty, |