aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2010-06-23 19:46:01 -0400
committerAlex Elder <aelder@sgi.com>2010-07-26 14:16:41 -0400
commit20cb52ebd1b5ca6fa8a5d9b6b1392292f5ca8a45 (patch)
treec4644ab4b8b12d2c6100fb47c7dfa4c5949107ca
parent89f3b363967a958e756a549c8747c1fb9c930c1a (diff)
xfs: simplify xfs_vm_writepage
The writepage implementation in XFS still tries to deal with dirty but unmapped buffers which used to caused by writes through shared mmaps. Since the introduction of ->page_mkwrite these can't happen anymore, so remove the code dealing with them. Note that the all_bh variable which causes us to start I/O on all buffers on the pages was controlled by the count of unmapped buffers, which also included those not actually dirty. It's now unconditionally initialized to 0 but set to 1 for the case of small file size extensions. It probably can be removed entirely, but that's left for another patch. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com>
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c139
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.h2
-rw-r--r--fs/xfs/linux-2.6/xfs_trace.h10
3 files changed, 49 insertions, 102 deletions
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 7744a3b630e0..1776cdd944b5 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -85,18 +85,15 @@ void
85xfs_count_page_state( 85xfs_count_page_state(
86 struct page *page, 86 struct page *page,
87 int *delalloc, 87 int *delalloc,
88 int *unmapped,
89 int *unwritten) 88 int *unwritten)
90{ 89{
91 struct buffer_head *bh, *head; 90 struct buffer_head *bh, *head;
92 91
93 *delalloc = *unmapped = *unwritten = 0; 92 *delalloc = *unwritten = 0;
94 93
95 bh = head = page_buffers(page); 94 bh = head = page_buffers(page);
96 do { 95 do {
97 if (buffer_uptodate(bh) && !buffer_mapped(bh)) 96 if (buffer_unwritten(bh))
98 (*unmapped) = 1;
99 else if (buffer_unwritten(bh))
100 (*unwritten) = 1; 97 (*unwritten) = 1;
101 else if (buffer_delay(bh)) 98 else if (buffer_delay(bh))
102 (*delalloc) = 1; 99 (*delalloc) = 1;
@@ -607,31 +604,30 @@ xfs_map_at_offset(
607STATIC unsigned int 604STATIC unsigned int
608xfs_probe_page( 605xfs_probe_page(
609 struct page *page, 606 struct page *page,
610 unsigned int pg_offset, 607 unsigned int pg_offset)
611 int mapped)
612{ 608{
609 struct buffer_head *bh, *head;
613 int ret = 0; 610 int ret = 0;
614 611
615 if (PageWriteback(page)) 612 if (PageWriteback(page))
616 return 0; 613 return 0;
614 if (!PageDirty(page))
615 return 0;
616 if (!page->mapping)
617 return 0;
618 if (!page_has_buffers(page))
619 return 0;
617 620
618 if (page->mapping && PageDirty(page)) { 621 bh = head = page_buffers(page);
619 if (page_has_buffers(page)) { 622 do {
620 struct buffer_head *bh, *head; 623 if (!buffer_uptodate(bh))
621 624 break;
622 bh = head = page_buffers(page); 625 if (!buffer_mapped(bh))
623 do { 626 break;
624 if (!buffer_uptodate(bh)) 627 ret += bh->b_size;
625 break; 628 if (ret >= pg_offset)
626 if (mapped != buffer_mapped(bh)) 629 break;
627 break; 630 } while ((bh = bh->b_this_page) != head);
628 ret += bh->b_size;
629 if (ret >= pg_offset)
630 break;
631 } while ((bh = bh->b_this_page) != head);
632 } else
633 ret = mapped ? 0 : PAGE_CACHE_SIZE;
634 }
635 631
636 return ret; 632 return ret;
637} 633}
@@ -641,8 +637,7 @@ xfs_probe_cluster(
641 struct inode *inode, 637 struct inode *inode,
642 struct page *startpage, 638 struct page *startpage,
643 struct buffer_head *bh, 639 struct buffer_head *bh,
644 struct buffer_head *head, 640 struct buffer_head *head)
645 int mapped)
646{ 641{
647 struct pagevec pvec; 642 struct pagevec pvec;
648 pgoff_t tindex, tlast, tloff; 643 pgoff_t tindex, tlast, tloff;
@@ -651,7 +646,7 @@ xfs_probe_cluster(
651 646
652 /* First sum forwards in this page */ 647 /* First sum forwards in this page */
653 do { 648 do {
654 if (!buffer_uptodate(bh) || (mapped != buffer_mapped(bh))) 649 if (!buffer_uptodate(bh) || !buffer_mapped(bh))
655 return total; 650 return total;
656 total += bh->b_size; 651 total += bh->b_size;
657 } while ((bh = bh->b_this_page) != head); 652 } while ((bh = bh->b_this_page) != head);
@@ -685,7 +680,7 @@ xfs_probe_cluster(
685 pg_offset = PAGE_CACHE_SIZE; 680 pg_offset = PAGE_CACHE_SIZE;
686 681
687 if (page->index == tindex && trylock_page(page)) { 682 if (page->index == tindex && trylock_page(page)) {
688 pg_len = xfs_probe_page(page, pg_offset, mapped); 683 pg_len = xfs_probe_page(page, pg_offset);
689 unlock_page(page); 684 unlock_page(page);
690 } 685 }
691 686
@@ -1021,18 +1016,12 @@ out_invalidate:
1021 * For delalloc space on the page we need to allocate space and flush it. 1016 * For delalloc space on the page we need to allocate space and flush it.
1022 * For unwritten space on the page we need to start the conversion to 1017 * For unwritten space on the page we need to start the conversion to
1023 * regular allocated space. 1018 * regular allocated space.
1024 * For unmapped buffer heads on the page we should allocate space if the
1025 * page is uptodate.
1026 * For any other dirty buffer heads on the page we should flush them. 1019 * For any other dirty buffer heads on the page we should flush them.
1027 * 1020 *
1028 * If we detect that a transaction would be required to flush the page, we 1021 * If we detect that a transaction would be required to flush the page, we
1029 * have to check the process flags first, if we are already in a transaction 1022 * have to check the process flags first, if we are already in a transaction
1030 * or disk I/O during allocations is off, we need to fail the writepage and 1023 * or disk I/O during allocations is off, we need to fail the writepage and
1031 * redirty the page. 1024 * redirty the page.
1032 *
1033 * The bh->b_state's cannot know if any of the blocks or which block for that
1034 * matter are dirty due to mmap writes, and therefore bh uptodate is only
1035 * valid if the page itself isn't completely uptodate.
1036 */ 1025 */
1037STATIC int 1026STATIC int
1038xfs_vm_writepage( 1027xfs_vm_writepage(
@@ -1040,8 +1029,7 @@ xfs_vm_writepage(
1040 struct writeback_control *wbc) 1029 struct writeback_control *wbc)
1041{ 1030{
1042 struct inode *inode = page->mapping->host; 1031 struct inode *inode = page->mapping->host;
1043 int need_trans; 1032 int delalloc, unwritten;
1044 int delalloc, unmapped, unwritten;
1045 struct buffer_head *bh, *head; 1033 struct buffer_head *bh, *head;
1046 struct xfs_bmbt_irec imap; 1034 struct xfs_bmbt_irec imap;
1047 xfs_ioend_t *ioend = NULL, *iohead = NULL; 1035 xfs_ioend_t *ioend = NULL, *iohead = NULL;
@@ -1052,10 +1040,12 @@ xfs_vm_writepage(
1052 ssize_t size, len; 1040 ssize_t size, len;
1053 int flags, err, imap_valid = 0, uptodate = 1; 1041 int flags, err, imap_valid = 0, uptodate = 1;
1054 int count = 0; 1042 int count = 0;
1055 int all_bh; 1043 int all_bh = 0;
1056 1044
1057 trace_xfs_writepage(inode, page, 0); 1045 trace_xfs_writepage(inode, page, 0);
1058 1046
1047 ASSERT(page_has_buffers(page));
1048
1059 /* 1049 /*
1060 * Refuse to write the page out if we are called from reclaim context. 1050 * Refuse to write the page out if we are called from reclaim context.
1061 * 1051 *
@@ -1072,29 +1062,15 @@ xfs_vm_writepage(
1072 goto out_fail; 1062 goto out_fail;
1073 1063
1074 /* 1064 /*
1075 * We need a transaction if: 1065 * We need a transaction if there are delalloc or unwritten buffers
1076 * 1. There are delalloc buffers on the page 1066 * on the page.
1077 * 2. The page is uptodate and we have unmapped buffers 1067 *
1078 * 3. The page is uptodate and we have no buffers 1068 * If we need a transaction and the process flags say we are already
1079 * 4. There are unwritten buffers on the page 1069 * in a transaction, or no IO is allowed then mark the page dirty
1080 */ 1070 * again and leave the page as is.
1081 if (!page_has_buffers(page)) {
1082 unmapped = 1;
1083 need_trans = 1;
1084 } else {
1085 xfs_count_page_state(page, &delalloc, &unmapped, &unwritten);
1086 if (!PageUptodate(page))
1087 unmapped = 0;
1088 need_trans = delalloc + unmapped + unwritten;
1089 }
1090
1091 /*
1092 * If we need a transaction and the process flags say
1093 * we are already in a transaction, or no IO is allowed
1094 * then mark the page dirty again and leave the page
1095 * as is.
1096 */ 1071 */
1097 if (current_test_flags(PF_FSTRANS) && need_trans) 1072 xfs_count_page_state(page, &delalloc, &unwritten);
1073 if ((current->flags & PF_FSTRANS) && (delalloc || unwritten))
1098 goto out_fail; 1074 goto out_fail;
1099 1075
1100 /* 1076 /*
@@ -1117,7 +1093,8 @@ xfs_vm_writepage(
1117 } 1093 }
1118 1094
1119 end_offset = min_t(unsigned long long, 1095 end_offset = min_t(unsigned long long,
1120 (xfs_off_t)(page->index + 1) << PAGE_CACHE_SHIFT, offset); 1096 (xfs_off_t)(page->index + 1) << PAGE_CACHE_SHIFT,
1097 offset);
1121 len = 1 << inode->i_blkbits; 1098 len = 1 << inode->i_blkbits;
1122 1099
1123 bh = head = page_buffers(page); 1100 bh = head = page_buffers(page);
@@ -1125,8 +1102,6 @@ xfs_vm_writepage(
1125 flags = BMAPI_READ; 1102 flags = BMAPI_READ;
1126 type = IO_NEW; 1103 type = IO_NEW;
1127 1104
1128 all_bh = unmapped;
1129
1130 do { 1105 do {
1131 if (offset >= end_offset) 1106 if (offset >= end_offset)
1132 break; 1107 break;
@@ -1146,19 +1121,7 @@ xfs_vm_writepage(
1146 if (imap_valid) 1121 if (imap_valid)
1147 imap_valid = xfs_imap_valid(inode, &imap, offset); 1122 imap_valid = xfs_imap_valid(inode, &imap, offset);
1148 1123
1149 /* 1124 if (buffer_unwritten(bh) || buffer_delay(bh)) {
1150 * First case, map an unwritten extent and prepare for
1151 * extent state conversion transaction on completion.
1152 *
1153 * Second case, allocate space for a delalloc buffer.
1154 * We can return EAGAIN here in the release page case.
1155 *
1156 * Third case, an unmapped buffer was found, and we are
1157 * in a path where we need to write the whole page out.
1158 */
1159 if (buffer_unwritten(bh) || buffer_delay(bh) ||
1160 ((buffer_uptodate(bh) || PageUptodate(page)) &&
1161 !buffer_mapped(bh))) {
1162 int new_ioend = 0; 1125 int new_ioend = 0;
1163 1126
1164 /* 1127 /*
@@ -1177,14 +1140,11 @@ xfs_vm_writepage(
1177 if (wbc->sync_mode == WB_SYNC_NONE && 1140 if (wbc->sync_mode == WB_SYNC_NONE &&
1178 wbc->nonblocking) 1141 wbc->nonblocking)
1179 flags |= BMAPI_TRYLOCK; 1142 flags |= BMAPI_TRYLOCK;
1180 } else {
1181 type = IO_NEW;
1182 flags = BMAPI_WRITE | BMAPI_MMAP;
1183 } 1143 }
1184 1144
1185 if (!imap_valid) { 1145 if (!imap_valid) {
1186 /* 1146 /*
1187 * if we didn't have a valid mapping then we 1147 * If we didn't have a valid mapping then we
1188 * need to ensure that we put the new mapping 1148 * need to ensure that we put the new mapping
1189 * in a new ioend structure. This needs to be 1149 * in a new ioend structure. This needs to be
1190 * done to ensure that the ioends correctly 1150 * done to ensure that the ioends correctly
@@ -1192,14 +1152,7 @@ xfs_vm_writepage(
1192 * for unwritten extent conversion. 1152 * for unwritten extent conversion.
1193 */ 1153 */
1194 new_ioend = 1; 1154 new_ioend = 1;
1195 if (type == IO_NEW) { 1155 err = xfs_map_blocks(inode, offset, len,
1196 size = xfs_probe_cluster(inode,
1197 page, bh, head, 0);
1198 } else {
1199 size = len;
1200 }
1201
1202 err = xfs_map_blocks(inode, offset, size,
1203 &imap, flags); 1156 &imap, flags);
1204 if (err) 1157 if (err)
1205 goto error; 1158 goto error;
@@ -1220,8 +1173,7 @@ xfs_vm_writepage(
1220 */ 1173 */
1221 if (!imap_valid || flags != BMAPI_READ) { 1174 if (!imap_valid || flags != BMAPI_READ) {
1222 flags = BMAPI_READ; 1175 flags = BMAPI_READ;
1223 size = xfs_probe_cluster(inode, page, bh, 1176 size = xfs_probe_cluster(inode, page, bh, head);
1224 head, 1);
1225 err = xfs_map_blocks(inode, offset, size, 1177 err = xfs_map_blocks(inode, offset, size,
1226 &imap, flags); 1178 &imap, flags);
1227 if (err) 1179 if (err)
@@ -1240,7 +1192,6 @@ xfs_vm_writepage(
1240 */ 1192 */
1241 type = IO_NEW; 1193 type = IO_NEW;
1242 if (trylock_buffer(bh)) { 1194 if (trylock_buffer(bh)) {
1243 ASSERT(buffer_mapped(bh));
1244 if (imap_valid) 1195 if (imap_valid)
1245 all_bh = 1; 1196 all_bh = 1;
1246 xfs_add_to_ioend(inode, bh, offset, type, 1197 xfs_add_to_ioend(inode, bh, offset, type,
@@ -1250,6 +1201,7 @@ xfs_vm_writepage(
1250 imap_valid = 0; 1201 imap_valid = 0;
1251 } 1202 }
1252 } else if (PageUptodate(page)) { 1203 } else if (PageUptodate(page)) {
1204 ASSERT(buffer_mapped(bh));
1253 imap_valid = 0; 1205 imap_valid = 0;
1254 } 1206 }
1255 1207
@@ -1291,8 +1243,7 @@ error:
1291 if (iohead) 1243 if (iohead)
1292 xfs_cancel_ioend(iohead); 1244 xfs_cancel_ioend(iohead);
1293 1245
1294 if (!unmapped) 1246 xfs_aops_discard_page(page);
1295 xfs_aops_discard_page(page);
1296 ClearPageUptodate(page); 1247 ClearPageUptodate(page);
1297 unlock_page(page); 1248 unlock_page(page);
1298 return err; 1249 return err;
@@ -1324,11 +1275,11 @@ xfs_vm_releasepage(
1324 struct page *page, 1275 struct page *page,
1325 gfp_t gfp_mask) 1276 gfp_t gfp_mask)
1326{ 1277{
1327 int delalloc, unmapped, unwritten; 1278 int delalloc, unwritten;
1328 1279
1329 trace_xfs_releasepage(page->mapping->host, page, 0); 1280 trace_xfs_releasepage(page->mapping->host, page, 0);
1330 1281
1331 xfs_count_page_state(page, &delalloc, &unmapped, &unwritten); 1282 xfs_count_page_state(page, &delalloc, &unwritten);
1332 1283
1333 if (WARN_ON(delalloc)) 1284 if (WARN_ON(delalloc))
1334 return 0; 1285 return 0;
diff --git a/fs/xfs/linux-2.6/xfs_aops.h b/fs/xfs/linux-2.6/xfs_aops.h
index 4cfc6ea87df8..319da173cc1a 100644
--- a/fs/xfs/linux-2.6/xfs_aops.h
+++ b/fs/xfs/linux-2.6/xfs_aops.h
@@ -45,6 +45,6 @@ extern int xfs_get_blocks(struct inode *, sector_t, struct buffer_head *, int);
45extern void xfs_ioend_init(void); 45extern void xfs_ioend_init(void);
46extern void xfs_ioend_wait(struct xfs_inode *); 46extern void xfs_ioend_wait(struct xfs_inode *);
47 47
48extern void xfs_count_page_state(struct page *, int *, int *, int *); 48extern void xfs_count_page_state(struct page *, int *, int *);
49 49
50#endif /* __XFS_AOPS_H__ */ 50#endif /* __XFS_AOPS_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h
index 0aea6d5f705a..3f2eec28c70d 100644
--- a/fs/xfs/linux-2.6/xfs_trace.h
+++ b/fs/xfs/linux-2.6/xfs_trace.h
@@ -832,33 +832,29 @@ DECLARE_EVENT_CLASS(xfs_page_class,
832 __field(loff_t, size) 832 __field(loff_t, size)
833 __field(unsigned long, offset) 833 __field(unsigned long, offset)
834 __field(int, delalloc) 834 __field(int, delalloc)
835 __field(int, unmapped)
836 __field(int, unwritten) 835 __field(int, unwritten)
837 ), 836 ),
838 TP_fast_assign( 837 TP_fast_assign(
839 int delalloc = -1, unmapped = -1, unwritten = -1; 838 int delalloc = -1, unwritten = -1;
840 839
841 if (page_has_buffers(page)) 840 if (page_has_buffers(page))
842 xfs_count_page_state(page, &delalloc, 841 xfs_count_page_state(page, &delalloc, &unwritten);
843 &unmapped, &unwritten);
844 __entry->dev = inode->i_sb->s_dev; 842 __entry->dev = inode->i_sb->s_dev;
845 __entry->ino = XFS_I(inode)->i_ino; 843 __entry->ino = XFS_I(inode)->i_ino;
846 __entry->pgoff = page_offset(page); 844 __entry->pgoff = page_offset(page);
847 __entry->size = i_size_read(inode); 845 __entry->size = i_size_read(inode);
848 __entry->offset = off; 846 __entry->offset = off;
849 __entry->delalloc = delalloc; 847 __entry->delalloc = delalloc;
850 __entry->unmapped = unmapped;
851 __entry->unwritten = unwritten; 848 __entry->unwritten = unwritten;
852 ), 849 ),
853 TP_printk("dev %d:%d ino 0x%llx pgoff 0x%lx size 0x%llx offset %lx " 850 TP_printk("dev %d:%d ino 0x%llx pgoff 0x%lx size 0x%llx offset %lx "
854 "delalloc %d unmapped %d unwritten %d", 851 "delalloc %d unwritten %d",
855 MAJOR(__entry->dev), MINOR(__entry->dev), 852 MAJOR(__entry->dev), MINOR(__entry->dev),
856 __entry->ino, 853 __entry->ino,
857 __entry->pgoff, 854 __entry->pgoff,
858 __entry->size, 855 __entry->size,
859 __entry->offset, 856 __entry->offset,
860 __entry->delalloc, 857 __entry->delalloc,
861 __entry->unmapped,
862 __entry->unwritten) 858 __entry->unwritten)
863) 859)
864 860