diff options
author | Christoph Hellwig <hch@infradead.org> | 2011-12-18 15:00:04 -0500 |
---|---|---|
committer | Ben Myers <bpm@sgi.com> | 2012-01-13 13:11:45 -0500 |
commit | 673e8e597c06eb81954bf21a10f5cce74a1de8f1 (patch) | |
tree | a6d47b0c44dfe24119de8d4c944f7c5c6e2c30dc /fs/xfs/xfs_inode.c | |
parent | 099469502f62fbe0d7e4f0b83a2f22538367f734 (diff) |
xfs: remove xfs_itruncate_data
This wrapper isn't overly useful, not to say rather confusing.
Around the call to xfs_itruncate_extents it does:
- add tracing
- add a few asserts in debug builds
- conditionally update the inode size in two places
- log the inode
Both the tracing and the inode logging can be moved to xfs_itruncate_extents
as they are useful for the attribute fork as well - in fact the attr code
already does an equivalent xfs_trans_log_inode call just after calling
xfs_itruncate_extents. The conditional size updates are a mess, and there
was no reason to do them in two places anyway, as the first one was
conditional on the inode having extents - but without extents we
xfs_itruncate_extents would be a no-op and the placement wouldn't matter
anyway. Instead move the size assignments and the asserts that make sense
to the callers that want it.
As a side effect of this clean up xfs_setattr_size by introducing variables
for the old and new inode size, and moving the size updates into a common
place.
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 124 |
1 files changed, 10 insertions, 114 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 9dda7cc32848..ccd619a993f6 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -1166,52 +1166,6 @@ xfs_ialloc( | |||
1166 | } | 1166 | } |
1167 | 1167 | ||
1168 | /* | 1168 | /* |
1169 | * Check to make sure that there are no blocks allocated to the | ||
1170 | * file beyond the size of the file. We don't check this for | ||
1171 | * files with fixed size extents or real time extents, but we | ||
1172 | * at least do it for regular files. | ||
1173 | */ | ||
1174 | #ifdef DEBUG | ||
1175 | STATIC void | ||
1176 | xfs_isize_check( | ||
1177 | struct xfs_inode *ip, | ||
1178 | xfs_fsize_t isize) | ||
1179 | { | ||
1180 | struct xfs_mount *mp = ip->i_mount; | ||
1181 | xfs_fileoff_t map_first; | ||
1182 | int nimaps; | ||
1183 | xfs_bmbt_irec_t imaps[2]; | ||
1184 | int error; | ||
1185 | |||
1186 | if (!S_ISREG(ip->i_d.di_mode)) | ||
1187 | return; | ||
1188 | |||
1189 | if (XFS_IS_REALTIME_INODE(ip)) | ||
1190 | return; | ||
1191 | |||
1192 | if (ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE) | ||
1193 | return; | ||
1194 | |||
1195 | nimaps = 2; | ||
1196 | map_first = XFS_B_TO_FSB(mp, (xfs_ufsize_t)isize); | ||
1197 | /* | ||
1198 | * The filesystem could be shutting down, so bmapi may return | ||
1199 | * an error. | ||
1200 | */ | ||
1201 | error = xfs_bmapi_read(ip, map_first, | ||
1202 | (XFS_B_TO_FSB(mp, | ||
1203 | (xfs_ufsize_t)XFS_MAXIOFFSET(mp)) - map_first), | ||
1204 | imaps, &nimaps, XFS_BMAPI_ENTIRE); | ||
1205 | if (error) | ||
1206 | return; | ||
1207 | ASSERT(nimaps == 1); | ||
1208 | ASSERT(imaps[0].br_startblock == HOLESTARTBLOCK); | ||
1209 | } | ||
1210 | #else /* DEBUG */ | ||
1211 | #define xfs_isize_check(ip, isize) | ||
1212 | #endif /* DEBUG */ | ||
1213 | |||
1214 | /* | ||
1215 | * Free up the underlying blocks past new_size. The new size must be smaller | 1169 | * Free up the underlying blocks past new_size. The new size must be smaller |
1216 | * than the current size. This routine can be used both for the attribute and | 1170 | * than the current size. This routine can be used both for the attribute and |
1217 | * data fork, and does not modify the inode size, which is left to the caller. | 1171 | * data fork, and does not modify the inode size, which is left to the caller. |
@@ -1258,6 +1212,8 @@ xfs_itruncate_extents( | |||
1258 | ASSERT(ip->i_itemp->ili_lock_flags == 0); | 1212 | ASSERT(ip->i_itemp->ili_lock_flags == 0); |
1259 | ASSERT(!XFS_NOT_DQATTACHED(mp, ip)); | 1213 | ASSERT(!XFS_NOT_DQATTACHED(mp, ip)); |
1260 | 1214 | ||
1215 | trace_xfs_itruncate_extents_start(ip, new_size); | ||
1216 | |||
1261 | /* | 1217 | /* |
1262 | * Since it is possible for space to become allocated beyond | 1218 | * Since it is possible for space to become allocated beyond |
1263 | * the end of the file (in a crash where the space is allocated | 1219 | * the end of the file (in a crash where the space is allocated |
@@ -1325,6 +1281,14 @@ xfs_itruncate_extents( | |||
1325 | goto out; | 1281 | goto out; |
1326 | } | 1282 | } |
1327 | 1283 | ||
1284 | /* | ||
1285 | * Always re-log the inode so that our permanent transaction can keep | ||
1286 | * on rolling it forward in the log. | ||
1287 | */ | ||
1288 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | ||
1289 | |||
1290 | trace_xfs_itruncate_extents_end(ip, new_size); | ||
1291 | |||
1328 | out: | 1292 | out: |
1329 | *tpp = tp; | 1293 | *tpp = tp; |
1330 | return error; | 1294 | return error; |
@@ -1338,74 +1302,6 @@ out_bmap_cancel: | |||
1338 | goto out; | 1302 | goto out; |
1339 | } | 1303 | } |
1340 | 1304 | ||
1341 | int | ||
1342 | xfs_itruncate_data( | ||
1343 | struct xfs_trans **tpp, | ||
1344 | struct xfs_inode *ip, | ||
1345 | xfs_fsize_t new_size) | ||
1346 | { | ||
1347 | int error; | ||
1348 | |||
1349 | trace_xfs_itruncate_data_start(ip, new_size); | ||
1350 | |||
1351 | /* | ||
1352 | * The first thing we do is set the size to new_size permanently on | ||
1353 | * disk. This way we don't have to worry about anyone ever being able | ||
1354 | * to look at the data being freed even in the face of a crash. | ||
1355 | * What we're getting around here is the case where we free a block, it | ||
1356 | * is allocated to another file, it is written to, and then we crash. | ||
1357 | * If the new data gets written to the file but the log buffers | ||
1358 | * containing the free and reallocation don't, then we'd end up with | ||
1359 | * garbage in the blocks being freed. As long as we make the new_size | ||
1360 | * permanent before actually freeing any blocks it doesn't matter if | ||
1361 | * they get written to. | ||
1362 | */ | ||
1363 | if (ip->i_d.di_nextents > 0) { | ||
1364 | /* | ||
1365 | * If we are not changing the file size then do not update | ||
1366 | * the on-disk file size - we may be called from | ||
1367 | * xfs_inactive_free_eofblocks(). If we update the on-disk | ||
1368 | * file size and then the system crashes before the contents | ||
1369 | * of the file are flushed to disk then the files may be | ||
1370 | * full of holes (ie NULL files bug). | ||
1371 | */ | ||
1372 | if (ip->i_size != new_size) { | ||
1373 | ip->i_d.di_size = new_size; | ||
1374 | ip->i_size = new_size; | ||
1375 | xfs_trans_log_inode(*tpp, ip, XFS_ILOG_CORE); | ||
1376 | } | ||
1377 | } | ||
1378 | |||
1379 | error = xfs_itruncate_extents(tpp, ip, XFS_DATA_FORK, new_size); | ||
1380 | if (error) | ||
1381 | return error; | ||
1382 | |||
1383 | /* | ||
1384 | * If we are not changing the file size then do not update the on-disk | ||
1385 | * file size - we may be called from xfs_inactive_free_eofblocks(). | ||
1386 | * If we update the on-disk file size and then the system crashes | ||
1387 | * before the contents of the file are flushed to disk then the files | ||
1388 | * may be full of holes (ie NULL files bug). | ||
1389 | */ | ||
1390 | xfs_isize_check(ip, new_size); | ||
1391 | if (ip->i_size != new_size) { | ||
1392 | ip->i_d.di_size = new_size; | ||
1393 | ip->i_size = new_size; | ||
1394 | } | ||
1395 | |||
1396 | ASSERT(new_size != 0 || ip->i_delayed_blks == 0); | ||
1397 | ASSERT(new_size != 0 || ip->i_d.di_nextents == 0); | ||
1398 | |||
1399 | /* | ||
1400 | * Always re-log the inode so that our permanent transaction can keep | ||
1401 | * on rolling it forward in the log. | ||
1402 | */ | ||
1403 | xfs_trans_log_inode(*tpp, ip, XFS_ILOG_CORE); | ||
1404 | |||
1405 | trace_xfs_itruncate_data_end(ip, new_size); | ||
1406 | return 0; | ||
1407 | } | ||
1408 | |||
1409 | /* | 1305 | /* |
1410 | * This is called when the inode's link count goes to 0. | 1306 | * This is called when the inode's link count goes to 0. |
1411 | * We place the on-disk inode on a list in the AGI. It | 1307 | * We place the on-disk inode on a list in the AGI. It |