diff options
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 193 |
1 files changed, 45 insertions, 148 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 9dda7cc32848..b21022499c2e 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -299,11 +299,8 @@ xfs_iformat( | |||
299 | { | 299 | { |
300 | xfs_attr_shortform_t *atp; | 300 | xfs_attr_shortform_t *atp; |
301 | int size; | 301 | int size; |
302 | int error; | 302 | int error = 0; |
303 | xfs_fsize_t di_size; | 303 | xfs_fsize_t di_size; |
304 | ip->i_df.if_ext_max = | ||
305 | XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); | ||
306 | error = 0; | ||
307 | 304 | ||
308 | if (unlikely(be32_to_cpu(dip->di_nextents) + | 305 | if (unlikely(be32_to_cpu(dip->di_nextents) + |
309 | be16_to_cpu(dip->di_anextents) > | 306 | be16_to_cpu(dip->di_anextents) > |
@@ -350,7 +347,6 @@ xfs_iformat( | |||
350 | return XFS_ERROR(EFSCORRUPTED); | 347 | return XFS_ERROR(EFSCORRUPTED); |
351 | } | 348 | } |
352 | ip->i_d.di_size = 0; | 349 | ip->i_d.di_size = 0; |
353 | ip->i_size = 0; | ||
354 | ip->i_df.if_u2.if_rdev = xfs_dinode_get_rdev(dip); | 350 | ip->i_df.if_u2.if_rdev = xfs_dinode_get_rdev(dip); |
355 | break; | 351 | break; |
356 | 352 | ||
@@ -409,10 +405,10 @@ xfs_iformat( | |||
409 | } | 405 | } |
410 | if (!XFS_DFORK_Q(dip)) | 406 | if (!XFS_DFORK_Q(dip)) |
411 | return 0; | 407 | return 0; |
408 | |||
412 | ASSERT(ip->i_afp == NULL); | 409 | ASSERT(ip->i_afp == NULL); |
413 | ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP | KM_NOFS); | 410 | ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP | KM_NOFS); |
414 | ip->i_afp->if_ext_max = | 411 | |
415 | XFS_IFORK_ASIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); | ||
416 | switch (dip->di_aformat) { | 412 | switch (dip->di_aformat) { |
417 | case XFS_DINODE_FMT_LOCAL: | 413 | case XFS_DINODE_FMT_LOCAL: |
418 | atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip); | 414 | atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip); |
@@ -604,10 +600,11 @@ xfs_iformat_btree( | |||
604 | * or the number of extents is greater than the number of | 600 | * or the number of extents is greater than the number of |
605 | * blocks. | 601 | * blocks. |
606 | */ | 602 | */ |
607 | if (unlikely(XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max | 603 | if (unlikely(XFS_IFORK_NEXTENTS(ip, whichfork) <= |
608 | || XFS_BMDR_SPACE_CALC(nrecs) > | 604 | XFS_IFORK_MAXEXT(ip, whichfork) || |
609 | XFS_DFORK_SIZE(dip, ip->i_mount, whichfork) | 605 | XFS_BMDR_SPACE_CALC(nrecs) > |
610 | || XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks)) { | 606 | XFS_DFORK_SIZE(dip, ip->i_mount, whichfork) || |
607 | XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks)) { | ||
611 | xfs_warn(ip->i_mount, "corrupt inode %Lu (btree).", | 608 | xfs_warn(ip->i_mount, "corrupt inode %Lu (btree).", |
612 | (unsigned long long) ip->i_ino); | 609 | (unsigned long long) ip->i_ino); |
613 | XFS_CORRUPTION_ERROR("xfs_iformat_btree", XFS_ERRLEVEL_LOW, | 610 | XFS_CORRUPTION_ERROR("xfs_iformat_btree", XFS_ERRLEVEL_LOW, |
@@ -835,12 +832,6 @@ xfs_iread( | |||
835 | * with the uninitialized part of it. | 832 | * with the uninitialized part of it. |
836 | */ | 833 | */ |
837 | ip->i_d.di_mode = 0; | 834 | ip->i_d.di_mode = 0; |
838 | /* | ||
839 | * Initialize the per-fork minima and maxima for a new | ||
840 | * inode here. xfs_iformat will do it for old inodes. | ||
841 | */ | ||
842 | ip->i_df.if_ext_max = | ||
843 | XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); | ||
844 | } | 835 | } |
845 | 836 | ||
846 | /* | 837 | /* |
@@ -861,7 +852,6 @@ xfs_iread( | |||
861 | } | 852 | } |
862 | 853 | ||
863 | ip->i_delayed_blks = 0; | 854 | ip->i_delayed_blks = 0; |
864 | ip->i_size = ip->i_d.di_size; | ||
865 | 855 | ||
866 | /* | 856 | /* |
867 | * Mark the buffer containing the inode as something to keep | 857 | * Mark the buffer containing the inode as something to keep |
@@ -1051,7 +1041,6 @@ xfs_ialloc( | |||
1051 | } | 1041 | } |
1052 | 1042 | ||
1053 | ip->i_d.di_size = 0; | 1043 | ip->i_d.di_size = 0; |
1054 | ip->i_size = 0; | ||
1055 | ip->i_d.di_nextents = 0; | 1044 | ip->i_d.di_nextents = 0; |
1056 | ASSERT(ip->i_d.di_nblocks == 0); | 1045 | ASSERT(ip->i_d.di_nblocks == 0); |
1057 | 1046 | ||
@@ -1166,52 +1155,6 @@ xfs_ialloc( | |||
1166 | } | 1155 | } |
1167 | 1156 | ||
1168 | /* | 1157 | /* |
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 | 1158 | * 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 | 1159 | * 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. | 1160 | * data fork, and does not modify the inode size, which is left to the caller. |
@@ -1252,12 +1195,14 @@ xfs_itruncate_extents( | |||
1252 | int done = 0; | 1195 | int done = 0; |
1253 | 1196 | ||
1254 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL)); | 1197 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL)); |
1255 | ASSERT(new_size <= ip->i_size); | 1198 | ASSERT(new_size <= XFS_ISIZE(ip)); |
1256 | ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); | 1199 | ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); |
1257 | ASSERT(ip->i_itemp != NULL); | 1200 | ASSERT(ip->i_itemp != NULL); |
1258 | ASSERT(ip->i_itemp->ili_lock_flags == 0); | 1201 | ASSERT(ip->i_itemp->ili_lock_flags == 0); |
1259 | ASSERT(!XFS_NOT_DQATTACHED(mp, ip)); | 1202 | ASSERT(!XFS_NOT_DQATTACHED(mp, ip)); |
1260 | 1203 | ||
1204 | trace_xfs_itruncate_extents_start(ip, new_size); | ||
1205 | |||
1261 | /* | 1206 | /* |
1262 | * Since it is possible for space to become allocated beyond | 1207 | * Since it is possible for space to become allocated beyond |
1263 | * the end of the file (in a crash where the space is allocated | 1208 | * the end of the file (in a crash where the space is allocated |
@@ -1325,6 +1270,14 @@ xfs_itruncate_extents( | |||
1325 | goto out; | 1270 | goto out; |
1326 | } | 1271 | } |
1327 | 1272 | ||
1273 | /* | ||
1274 | * Always re-log the inode so that our permanent transaction can keep | ||
1275 | * on rolling it forward in the log. | ||
1276 | */ | ||
1277 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | ||
1278 | |||
1279 | trace_xfs_itruncate_extents_end(ip, new_size); | ||
1280 | |||
1328 | out: | 1281 | out: |
1329 | *tpp = tp; | 1282 | *tpp = tp; |
1330 | return error; | 1283 | return error; |
@@ -1338,74 +1291,6 @@ out_bmap_cancel: | |||
1338 | goto out; | 1291 | goto out; |
1339 | } | 1292 | } |
1340 | 1293 | ||
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 | /* | 1294 | /* |
1410 | * This is called when the inode's link count goes to 0. | 1295 | * 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 | 1296 | * We place the on-disk inode on a list in the AGI. It |
@@ -1824,8 +1709,7 @@ xfs_ifree( | |||
1824 | ASSERT(ip->i_d.di_nlink == 0); | 1709 | ASSERT(ip->i_d.di_nlink == 0); |
1825 | ASSERT(ip->i_d.di_nextents == 0); | 1710 | ASSERT(ip->i_d.di_nextents == 0); |
1826 | ASSERT(ip->i_d.di_anextents == 0); | 1711 | ASSERT(ip->i_d.di_anextents == 0); |
1827 | ASSERT((ip->i_d.di_size == 0 && ip->i_size == 0) || | 1712 | ASSERT(ip->i_d.di_size == 0 || !S_ISREG(ip->i_d.di_mode)); |
1828 | (!S_ISREG(ip->i_d.di_mode))); | ||
1829 | ASSERT(ip->i_d.di_nblocks == 0); | 1713 | ASSERT(ip->i_d.di_nblocks == 0); |
1830 | 1714 | ||
1831 | /* | 1715 | /* |
@@ -1844,8 +1728,6 @@ xfs_ifree( | |||
1844 | ip->i_d.di_flags = 0; | 1728 | ip->i_d.di_flags = 0; |
1845 | ip->i_d.di_dmevmask = 0; | 1729 | ip->i_d.di_dmevmask = 0; |
1846 | ip->i_d.di_forkoff = 0; /* mark the attr fork not in use */ | 1730 | ip->i_d.di_forkoff = 0; /* mark the attr fork not in use */ |
1847 | ip->i_df.if_ext_max = | ||
1848 | XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); | ||
1849 | ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS; | 1731 | ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS; |
1850 | ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; | 1732 | ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; |
1851 | /* | 1733 | /* |
@@ -2151,7 +2033,7 @@ xfs_idestroy_fork( | |||
2151 | * once someone is waiting for it to be unpinned. | 2033 | * once someone is waiting for it to be unpinned. |
2152 | */ | 2034 | */ |
2153 | static void | 2035 | static void |
2154 | xfs_iunpin_nowait( | 2036 | xfs_iunpin( |
2155 | struct xfs_inode *ip) | 2037 | struct xfs_inode *ip) |
2156 | { | 2038 | { |
2157 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); | 2039 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); |
@@ -2163,14 +2045,29 @@ xfs_iunpin_nowait( | |||
2163 | 2045 | ||
2164 | } | 2046 | } |
2165 | 2047 | ||
2048 | static void | ||
2049 | __xfs_iunpin_wait( | ||
2050 | struct xfs_inode *ip) | ||
2051 | { | ||
2052 | wait_queue_head_t *wq = bit_waitqueue(&ip->i_flags, __XFS_IPINNED_BIT); | ||
2053 | DEFINE_WAIT_BIT(wait, &ip->i_flags, __XFS_IPINNED_BIT); | ||
2054 | |||
2055 | xfs_iunpin(ip); | ||
2056 | |||
2057 | do { | ||
2058 | prepare_to_wait(wq, &wait.wait, TASK_UNINTERRUPTIBLE); | ||
2059 | if (xfs_ipincount(ip)) | ||
2060 | io_schedule(); | ||
2061 | } while (xfs_ipincount(ip)); | ||
2062 | finish_wait(wq, &wait.wait); | ||
2063 | } | ||
2064 | |||
2166 | void | 2065 | void |
2167 | xfs_iunpin_wait( | 2066 | xfs_iunpin_wait( |
2168 | struct xfs_inode *ip) | 2067 | struct xfs_inode *ip) |
2169 | { | 2068 | { |
2170 | if (xfs_ipincount(ip)) { | 2069 | if (xfs_ipincount(ip)) |
2171 | xfs_iunpin_nowait(ip); | 2070 | __xfs_iunpin_wait(ip); |
2172 | wait_event(ip->i_ipin_wait, (xfs_ipincount(ip) == 0)); | ||
2173 | } | ||
2174 | } | 2071 | } |
2175 | 2072 | ||
2176 | /* | 2073 | /* |
@@ -2510,9 +2407,9 @@ xfs_iflush( | |||
2510 | XFS_STATS_INC(xs_iflush_count); | 2407 | XFS_STATS_INC(xs_iflush_count); |
2511 | 2408 | ||
2512 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); | 2409 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); |
2513 | ASSERT(!completion_done(&ip->i_flush)); | 2410 | ASSERT(xfs_isiflocked(ip)); |
2514 | ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || | 2411 | ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || |
2515 | ip->i_d.di_nextents > ip->i_df.if_ext_max); | 2412 | ip->i_d.di_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); |
2516 | 2413 | ||
2517 | iip = ip->i_itemp; | 2414 | iip = ip->i_itemp; |
2518 | mp = ip->i_mount; | 2415 | mp = ip->i_mount; |
@@ -2529,7 +2426,7 @@ xfs_iflush( | |||
2529 | * out for us if they occur after the log force completes. | 2426 | * out for us if they occur after the log force completes. |
2530 | */ | 2427 | */ |
2531 | if (!(flags & SYNC_WAIT) && xfs_ipincount(ip)) { | 2428 | if (!(flags & SYNC_WAIT) && xfs_ipincount(ip)) { |
2532 | xfs_iunpin_nowait(ip); | 2429 | xfs_iunpin(ip); |
2533 | xfs_ifunlock(ip); | 2430 | xfs_ifunlock(ip); |
2534 | return EAGAIN; | 2431 | return EAGAIN; |
2535 | } | 2432 | } |
@@ -2626,9 +2523,9 @@ xfs_iflush_int( | |||
2626 | #endif | 2523 | #endif |
2627 | 2524 | ||
2628 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); | 2525 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); |
2629 | ASSERT(!completion_done(&ip->i_flush)); | 2526 | ASSERT(xfs_isiflocked(ip)); |
2630 | ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || | 2527 | ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || |
2631 | ip->i_d.di_nextents > ip->i_df.if_ext_max); | 2528 | ip->i_d.di_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); |
2632 | 2529 | ||
2633 | iip = ip->i_itemp; | 2530 | iip = ip->i_itemp; |
2634 | mp = ip->i_mount; | 2531 | mp = ip->i_mount; |