diff options
author | Nathan Scott <nathans@sgi.com> | 2006-03-13 21:26:27 -0500 |
---|---|---|
committer | Nathan Scott <nathans@sgi.com> | 2006-03-13 21:26:27 -0500 |
commit | f51623b21fe3068d12f0c5d39e02fd2549635a99 (patch) | |
tree | 3b97d6690d0b01442543f9607cc4b7d3ec230128 | |
parent | 02d7c92334c84897d7d2840fc25e5896535766f9 (diff) |
[XFS] Move some code around to avoid prototypes and prep for future
writepages code.
SGI-PV: 950211
SGI-Modid: xfs-linux-melb:xfs-kern:25311a
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nathan Scott <nathans@sgi.com>
-rw-r--r-- | fs/xfs/linux-2.6/xfs_aops.c | 367 |
1 files changed, 183 insertions, 184 deletions
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 74d8be87f983..58fc7ade90b5 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
@@ -43,7 +43,32 @@ | |||
43 | #include <linux/pagevec.h> | 43 | #include <linux/pagevec.h> |
44 | #include <linux/writeback.h> | 44 | #include <linux/writeback.h> |
45 | 45 | ||
46 | STATIC void xfs_count_page_state(struct page *, int *, int *, int *); | 46 | |
47 | STATIC void | ||
48 | xfs_count_page_state( | ||
49 | struct page *page, | ||
50 | int *delalloc, | ||
51 | int *unmapped, | ||
52 | int *unwritten) | ||
53 | { | ||
54 | struct buffer_head *bh, *head; | ||
55 | |||
56 | *delalloc = *unmapped = *unwritten = 0; | ||
57 | |||
58 | bh = head = page_buffers(page); | ||
59 | do { | ||
60 | if (buffer_uptodate(bh) && !buffer_mapped(bh)) | ||
61 | (*unmapped) = 1; | ||
62 | else if (buffer_unwritten(bh) && !buffer_delay(bh)) | ||
63 | clear_buffer_unwritten(bh); | ||
64 | else if (buffer_unwritten(bh)) | ||
65 | (*unwritten) = 1; | ||
66 | else if (buffer_delay(bh)) | ||
67 | (*delalloc) = 1; | ||
68 | } while ((bh = bh->b_this_page) != head); | ||
69 | } | ||
70 | |||
71 | |||
47 | 72 | ||
48 | #if defined(XFS_RW_TRACE) | 73 | #if defined(XFS_RW_TRACE) |
49 | void | 74 | void |
@@ -1040,6 +1065,154 @@ error: | |||
1040 | return err; | 1065 | return err; |
1041 | } | 1066 | } |
1042 | 1067 | ||
1068 | /* | ||
1069 | * writepage: Called from one of two places: | ||
1070 | * | ||
1071 | * 1. we are flushing a delalloc buffer head. | ||
1072 | * | ||
1073 | * 2. we are writing out a dirty page. Typically the page dirty | ||
1074 | * state is cleared before we get here. In this case is it | ||
1075 | * conceivable we have no buffer heads. | ||
1076 | * | ||
1077 | * For delalloc space on the page we need to allocate space and | ||
1078 | * flush it. For unmapped buffer heads on the page we should | ||
1079 | * allocate space if the page is uptodate. For any other dirty | ||
1080 | * buffer heads on the page we should flush them. | ||
1081 | * | ||
1082 | * If we detect that a transaction would be required to flush | ||
1083 | * the page, we have to check the process flags first, if we | ||
1084 | * are already in a transaction or disk I/O during allocations | ||
1085 | * is off, we need to fail the writepage and redirty the page. | ||
1086 | */ | ||
1087 | |||
1088 | STATIC int | ||
1089 | linvfs_writepage( | ||
1090 | struct page *page, | ||
1091 | struct writeback_control *wbc) | ||
1092 | { | ||
1093 | int error; | ||
1094 | int need_trans; | ||
1095 | int delalloc, unmapped, unwritten; | ||
1096 | struct inode *inode = page->mapping->host; | ||
1097 | |||
1098 | xfs_page_trace(XFS_WRITEPAGE_ENTER, inode, page, 0); | ||
1099 | |||
1100 | /* | ||
1101 | * We need a transaction if: | ||
1102 | * 1. There are delalloc buffers on the page | ||
1103 | * 2. The page is uptodate and we have unmapped buffers | ||
1104 | * 3. The page is uptodate and we have no buffers | ||
1105 | * 4. There are unwritten buffers on the page | ||
1106 | */ | ||
1107 | |||
1108 | if (!page_has_buffers(page)) { | ||
1109 | unmapped = 1; | ||
1110 | need_trans = 1; | ||
1111 | } else { | ||
1112 | xfs_count_page_state(page, &delalloc, &unmapped, &unwritten); | ||
1113 | if (!PageUptodate(page)) | ||
1114 | unmapped = 0; | ||
1115 | need_trans = delalloc + unmapped + unwritten; | ||
1116 | } | ||
1117 | |||
1118 | /* | ||
1119 | * If we need a transaction and the process flags say | ||
1120 | * we are already in a transaction, or no IO is allowed | ||
1121 | * then mark the page dirty again and leave the page | ||
1122 | * as is. | ||
1123 | */ | ||
1124 | if (PFLAGS_TEST_FSTRANS() && need_trans) | ||
1125 | goto out_fail; | ||
1126 | |||
1127 | /* | ||
1128 | * Delay hooking up buffer heads until we have | ||
1129 | * made our go/no-go decision. | ||
1130 | */ | ||
1131 | if (!page_has_buffers(page)) | ||
1132 | create_empty_buffers(page, 1 << inode->i_blkbits, 0); | ||
1133 | |||
1134 | /* | ||
1135 | * Convert delayed allocate, unwritten or unmapped space | ||
1136 | * to real space and flush out to disk. | ||
1137 | */ | ||
1138 | error = xfs_page_state_convert(inode, page, wbc, 1, unmapped); | ||
1139 | if (error == -EAGAIN) | ||
1140 | goto out_fail; | ||
1141 | if (unlikely(error < 0)) | ||
1142 | goto out_unlock; | ||
1143 | |||
1144 | return 0; | ||
1145 | |||
1146 | out_fail: | ||
1147 | redirty_page_for_writepage(wbc, page); | ||
1148 | unlock_page(page); | ||
1149 | return 0; | ||
1150 | out_unlock: | ||
1151 | unlock_page(page); | ||
1152 | return error; | ||
1153 | } | ||
1154 | |||
1155 | /* | ||
1156 | * Called to move a page into cleanable state - and from there | ||
1157 | * to be released. Possibly the page is already clean. We always | ||
1158 | * have buffer heads in this call. | ||
1159 | * | ||
1160 | * Returns 0 if the page is ok to release, 1 otherwise. | ||
1161 | * | ||
1162 | * Possible scenarios are: | ||
1163 | * | ||
1164 | * 1. We are being called to release a page which has been written | ||
1165 | * to via regular I/O. buffer heads will be dirty and possibly | ||
1166 | * delalloc. If no delalloc buffer heads in this case then we | ||
1167 | * can just return zero. | ||
1168 | * | ||
1169 | * 2. We are called to release a page which has been written via | ||
1170 | * mmap, all we need to do is ensure there is no delalloc | ||
1171 | * state in the buffer heads, if not we can let the caller | ||
1172 | * free them and we should come back later via writepage. | ||
1173 | */ | ||
1174 | STATIC int | ||
1175 | linvfs_release_page( | ||
1176 | struct page *page, | ||
1177 | gfp_t gfp_mask) | ||
1178 | { | ||
1179 | struct inode *inode = page->mapping->host; | ||
1180 | int dirty, delalloc, unmapped, unwritten; | ||
1181 | struct writeback_control wbc = { | ||
1182 | .sync_mode = WB_SYNC_ALL, | ||
1183 | .nr_to_write = 1, | ||
1184 | }; | ||
1185 | |||
1186 | xfs_page_trace(XFS_RELEASEPAGE_ENTER, inode, page, gfp_mask); | ||
1187 | |||
1188 | xfs_count_page_state(page, &delalloc, &unmapped, &unwritten); | ||
1189 | if (!delalloc && !unwritten) | ||
1190 | goto free_buffers; | ||
1191 | |||
1192 | if (!(gfp_mask & __GFP_FS)) | ||
1193 | return 0; | ||
1194 | |||
1195 | /* If we are already inside a transaction or the thread cannot | ||
1196 | * do I/O, we cannot release this page. | ||
1197 | */ | ||
1198 | if (PFLAGS_TEST_FSTRANS()) | ||
1199 | return 0; | ||
1200 | |||
1201 | /* | ||
1202 | * Convert delalloc space to real space, do not flush the | ||
1203 | * data out to disk, that will be done by the caller. | ||
1204 | * Never need to allocate space here - we will always | ||
1205 | * come back to writepage in that case. | ||
1206 | */ | ||
1207 | dirty = xfs_page_state_convert(inode, page, &wbc, 0, 0); | ||
1208 | if (dirty == 0 && !unwritten) | ||
1209 | goto free_buffers; | ||
1210 | return 0; | ||
1211 | |||
1212 | free_buffers: | ||
1213 | return try_to_free_buffers(page); | ||
1214 | } | ||
1215 | |||
1043 | STATIC int | 1216 | STATIC int |
1044 | __linvfs_get_block( | 1217 | __linvfs_get_block( |
1045 | struct inode *inode, | 1218 | struct inode *inode, |
@@ -1223,6 +1396,15 @@ linvfs_direct_IO( | |||
1223 | return ret; | 1396 | return ret; |
1224 | } | 1397 | } |
1225 | 1398 | ||
1399 | STATIC int | ||
1400 | linvfs_prepare_write( | ||
1401 | struct file *file, | ||
1402 | struct page *page, | ||
1403 | unsigned int from, | ||
1404 | unsigned int to) | ||
1405 | { | ||
1406 | return block_prepare_write(page, from, to, linvfs_get_block); | ||
1407 | } | ||
1226 | 1408 | ||
1227 | STATIC sector_t | 1409 | STATIC sector_t |
1228 | linvfs_bmap( | 1410 | linvfs_bmap( |
@@ -1259,118 +1441,6 @@ linvfs_readpages( | |||
1259 | return mpage_readpages(mapping, pages, nr_pages, linvfs_get_block); | 1441 | return mpage_readpages(mapping, pages, nr_pages, linvfs_get_block); |
1260 | } | 1442 | } |
1261 | 1443 | ||
1262 | STATIC void | ||
1263 | xfs_count_page_state( | ||
1264 | struct page *page, | ||
1265 | int *delalloc, | ||
1266 | int *unmapped, | ||
1267 | int *unwritten) | ||
1268 | { | ||
1269 | struct buffer_head *bh, *head; | ||
1270 | |||
1271 | *delalloc = *unmapped = *unwritten = 0; | ||
1272 | |||
1273 | bh = head = page_buffers(page); | ||
1274 | do { | ||
1275 | if (buffer_uptodate(bh) && !buffer_mapped(bh)) | ||
1276 | (*unmapped) = 1; | ||
1277 | else if (buffer_unwritten(bh) && !buffer_delay(bh)) | ||
1278 | clear_buffer_unwritten(bh); | ||
1279 | else if (buffer_unwritten(bh)) | ||
1280 | (*unwritten) = 1; | ||
1281 | else if (buffer_delay(bh)) | ||
1282 | (*delalloc) = 1; | ||
1283 | } while ((bh = bh->b_this_page) != head); | ||
1284 | } | ||
1285 | |||
1286 | |||
1287 | /* | ||
1288 | * writepage: Called from one of two places: | ||
1289 | * | ||
1290 | * 1. we are flushing a delalloc buffer head. | ||
1291 | * | ||
1292 | * 2. we are writing out a dirty page. Typically the page dirty | ||
1293 | * state is cleared before we get here. In this case is it | ||
1294 | * conceivable we have no buffer heads. | ||
1295 | * | ||
1296 | * For delalloc space on the page we need to allocate space and | ||
1297 | * flush it. For unmapped buffer heads on the page we should | ||
1298 | * allocate space if the page is uptodate. For any other dirty | ||
1299 | * buffer heads on the page we should flush them. | ||
1300 | * | ||
1301 | * If we detect that a transaction would be required to flush | ||
1302 | * the page, we have to check the process flags first, if we | ||
1303 | * are already in a transaction or disk I/O during allocations | ||
1304 | * is off, we need to fail the writepage and redirty the page. | ||
1305 | */ | ||
1306 | |||
1307 | STATIC int | ||
1308 | linvfs_writepage( | ||
1309 | struct page *page, | ||
1310 | struct writeback_control *wbc) | ||
1311 | { | ||
1312 | int error; | ||
1313 | int need_trans; | ||
1314 | int delalloc, unmapped, unwritten; | ||
1315 | struct inode *inode = page->mapping->host; | ||
1316 | |||
1317 | xfs_page_trace(XFS_WRITEPAGE_ENTER, inode, page, 0); | ||
1318 | |||
1319 | /* | ||
1320 | * We need a transaction if: | ||
1321 | * 1. There are delalloc buffers on the page | ||
1322 | * 2. The page is uptodate and we have unmapped buffers | ||
1323 | * 3. The page is uptodate and we have no buffers | ||
1324 | * 4. There are unwritten buffers on the page | ||
1325 | */ | ||
1326 | |||
1327 | if (!page_has_buffers(page)) { | ||
1328 | unmapped = 1; | ||
1329 | need_trans = 1; | ||
1330 | } else { | ||
1331 | xfs_count_page_state(page, &delalloc, &unmapped, &unwritten); | ||
1332 | if (!PageUptodate(page)) | ||
1333 | unmapped = 0; | ||
1334 | need_trans = delalloc + unmapped + unwritten; | ||
1335 | } | ||
1336 | |||
1337 | /* | ||
1338 | * If we need a transaction and the process flags say | ||
1339 | * we are already in a transaction, or no IO is allowed | ||
1340 | * then mark the page dirty again and leave the page | ||
1341 | * as is. | ||
1342 | */ | ||
1343 | if (PFLAGS_TEST_FSTRANS() && need_trans) | ||
1344 | goto out_fail; | ||
1345 | |||
1346 | /* | ||
1347 | * Delay hooking up buffer heads until we have | ||
1348 | * made our go/no-go decision. | ||
1349 | */ | ||
1350 | if (!page_has_buffers(page)) | ||
1351 | create_empty_buffers(page, 1 << inode->i_blkbits, 0); | ||
1352 | |||
1353 | /* | ||
1354 | * Convert delayed allocate, unwritten or unmapped space | ||
1355 | * to real space and flush out to disk. | ||
1356 | */ | ||
1357 | error = xfs_page_state_convert(inode, page, wbc, 1, unmapped); | ||
1358 | if (error == -EAGAIN) | ||
1359 | goto out_fail; | ||
1360 | if (unlikely(error < 0)) | ||
1361 | goto out_unlock; | ||
1362 | |||
1363 | return 0; | ||
1364 | |||
1365 | out_fail: | ||
1366 | redirty_page_for_writepage(wbc, page); | ||
1367 | unlock_page(page); | ||
1368 | return 0; | ||
1369 | out_unlock: | ||
1370 | unlock_page(page); | ||
1371 | return error; | ||
1372 | } | ||
1373 | |||
1374 | STATIC int | 1444 | STATIC int |
1375 | linvfs_invalidate_page( | 1445 | linvfs_invalidate_page( |
1376 | struct page *page, | 1446 | struct page *page, |
@@ -1381,77 +1451,6 @@ linvfs_invalidate_page( | |||
1381 | return block_invalidatepage(page, offset); | 1451 | return block_invalidatepage(page, offset); |
1382 | } | 1452 | } |
1383 | 1453 | ||
1384 | /* | ||
1385 | * Called to move a page into cleanable state - and from there | ||
1386 | * to be released. Possibly the page is already clean. We always | ||
1387 | * have buffer heads in this call. | ||
1388 | * | ||
1389 | * Returns 0 if the page is ok to release, 1 otherwise. | ||
1390 | * | ||
1391 | * Possible scenarios are: | ||
1392 | * | ||
1393 | * 1. We are being called to release a page which has been written | ||
1394 | * to via regular I/O. buffer heads will be dirty and possibly | ||
1395 | * delalloc. If no delalloc buffer heads in this case then we | ||
1396 | * can just return zero. | ||
1397 | * | ||
1398 | * 2. We are called to release a page which has been written via | ||
1399 | * mmap, all we need to do is ensure there is no delalloc | ||
1400 | * state in the buffer heads, if not we can let the caller | ||
1401 | * free them and we should come back later via writepage. | ||
1402 | */ | ||
1403 | STATIC int | ||
1404 | linvfs_release_page( | ||
1405 | struct page *page, | ||
1406 | gfp_t gfp_mask) | ||
1407 | { | ||
1408 | struct inode *inode = page->mapping->host; | ||
1409 | int dirty, delalloc, unmapped, unwritten; | ||
1410 | struct writeback_control wbc = { | ||
1411 | .sync_mode = WB_SYNC_ALL, | ||
1412 | .nr_to_write = 1, | ||
1413 | }; | ||
1414 | |||
1415 | xfs_page_trace(XFS_RELEASEPAGE_ENTER, inode, page, gfp_mask); | ||
1416 | |||
1417 | xfs_count_page_state(page, &delalloc, &unmapped, &unwritten); | ||
1418 | if (!delalloc && !unwritten) | ||
1419 | goto free_buffers; | ||
1420 | |||
1421 | if (!(gfp_mask & __GFP_FS)) | ||
1422 | return 0; | ||
1423 | |||
1424 | /* If we are already inside a transaction or the thread cannot | ||
1425 | * do I/O, we cannot release this page. | ||
1426 | */ | ||
1427 | if (PFLAGS_TEST_FSTRANS()) | ||
1428 | return 0; | ||
1429 | |||
1430 | /* | ||
1431 | * Convert delalloc space to real space, do not flush the | ||
1432 | * data out to disk, that will be done by the caller. | ||
1433 | * Never need to allocate space here - we will always | ||
1434 | * come back to writepage in that case. | ||
1435 | */ | ||
1436 | dirty = xfs_page_state_convert(inode, page, &wbc, 0, 0); | ||
1437 | if (dirty == 0 && !unwritten) | ||
1438 | goto free_buffers; | ||
1439 | return 0; | ||
1440 | |||
1441 | free_buffers: | ||
1442 | return try_to_free_buffers(page); | ||
1443 | } | ||
1444 | |||
1445 | STATIC int | ||
1446 | linvfs_prepare_write( | ||
1447 | struct file *file, | ||
1448 | struct page *page, | ||
1449 | unsigned int from, | ||
1450 | unsigned int to) | ||
1451 | { | ||
1452 | return block_prepare_write(page, from, to, linvfs_get_block); | ||
1453 | } | ||
1454 | |||
1455 | struct address_space_operations linvfs_aops = { | 1454 | struct address_space_operations linvfs_aops = { |
1456 | .readpage = linvfs_readpage, | 1455 | .readpage = linvfs_readpage, |
1457 | .readpages = linvfs_readpages, | 1456 | .readpages = linvfs_readpages, |