diff options
Diffstat (limited to 'fs/xfs/libxfs')
-rw-r--r-- | fs/xfs/libxfs/xfs_alloc_btree.c | 2 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_attr_sf.h | 16 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_bmap.c | 172 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_bmap_btree.c | 5 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_btree.c | 32 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_da_format.h | 16 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_dir2.c | 12 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_dir2_node.c | 4 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_ialloc.c | 4 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_ialloc_btree.c | 12 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_inode_buf.c | 170 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_inode_buf.h | 38 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_inode_fork.c | 3 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_log_format.h | 19 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_quota_defs.h | 3 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_rtbitmap.c | 32 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_sb.h | 1 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_shared.h | 1 |
18 files changed, 366 insertions, 176 deletions
diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c index 444626ddbd1b..d9b42425291e 100644 --- a/fs/xfs/libxfs/xfs_alloc_btree.c +++ b/fs/xfs/libxfs/xfs_alloc_btree.c | |||
@@ -118,8 +118,6 @@ xfs_allocbt_free_block( | |||
118 | xfs_extent_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1, | 118 | xfs_extent_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1, |
119 | XFS_EXTENT_BUSY_SKIP_DISCARD); | 119 | XFS_EXTENT_BUSY_SKIP_DISCARD); |
120 | xfs_trans_agbtree_delta(cur->bc_tp, -1); | 120 | xfs_trans_agbtree_delta(cur->bc_tp, -1); |
121 | |||
122 | xfs_trans_binval(cur->bc_tp, bp); | ||
123 | return 0; | 121 | return 0; |
124 | } | 122 | } |
125 | 123 | ||
diff --git a/fs/xfs/libxfs/xfs_attr_sf.h b/fs/xfs/libxfs/xfs_attr_sf.h index 919756e3ba53..90928bbe693c 100644 --- a/fs/xfs/libxfs/xfs_attr_sf.h +++ b/fs/xfs/libxfs/xfs_attr_sf.h | |||
@@ -24,22 +24,6 @@ | |||
24 | * Small attribute lists are packed as tightly as possible so as | 24 | * Small attribute lists are packed as tightly as possible so as |
25 | * to fit into the literal area of the inode. | 25 | * to fit into the literal area of the inode. |
26 | */ | 26 | */ |
27 | |||
28 | /* | ||
29 | * Entries are packed toward the top as tight as possible. | ||
30 | */ | ||
31 | typedef struct xfs_attr_shortform { | ||
32 | struct xfs_attr_sf_hdr { /* constant-structure header block */ | ||
33 | __be16 totsize; /* total bytes in shortform list */ | ||
34 | __u8 count; /* count of active entries */ | ||
35 | } hdr; | ||
36 | struct xfs_attr_sf_entry { | ||
37 | __uint8_t namelen; /* actual length of name (no NULL) */ | ||
38 | __uint8_t valuelen; /* actual length of value (no NULL) */ | ||
39 | __uint8_t flags; /* flags bits (see xfs_attr_leaf.h) */ | ||
40 | __uint8_t nameval[1]; /* name & value bytes concatenated */ | ||
41 | } list[1]; /* variable sized array */ | ||
42 | } xfs_attr_shortform_t; | ||
43 | typedef struct xfs_attr_sf_hdr xfs_attr_sf_hdr_t; | 27 | typedef struct xfs_attr_sf_hdr xfs_attr_sf_hdr_t; |
44 | typedef struct xfs_attr_sf_entry xfs_attr_sf_entry_t; | 28 | typedef struct xfs_attr_sf_entry xfs_attr_sf_entry_t; |
45 | 29 | ||
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index ef00156f4f96..041b6948aecc 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c | |||
@@ -477,10 +477,7 @@ xfs_bmap_check_leaf_extents( | |||
477 | } | 477 | } |
478 | block = XFS_BUF_TO_BLOCK(bp); | 478 | block = XFS_BUF_TO_BLOCK(bp); |
479 | } | 479 | } |
480 | if (bp_release) { | 480 | |
481 | bp_release = 0; | ||
482 | xfs_trans_brelse(NULL, bp); | ||
483 | } | ||
484 | return; | 481 | return; |
485 | 482 | ||
486 | error0: | 483 | error0: |
@@ -912,7 +909,7 @@ xfs_bmap_local_to_extents( | |||
912 | * We don't want to deal with the case of keeping inode data inline yet. | 909 | * We don't want to deal with the case of keeping inode data inline yet. |
913 | * So sending the data fork of a regular inode is invalid. | 910 | * So sending the data fork of a regular inode is invalid. |
914 | */ | 911 | */ |
915 | ASSERT(!(S_ISREG(ip->i_d.di_mode) && whichfork == XFS_DATA_FORK)); | 912 | ASSERT(!(S_ISREG(VFS_I(ip)->i_mode) && whichfork == XFS_DATA_FORK)); |
916 | ifp = XFS_IFORK_PTR(ip, whichfork); | 913 | ifp = XFS_IFORK_PTR(ip, whichfork); |
917 | ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); | 914 | ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); |
918 | 915 | ||
@@ -1079,7 +1076,7 @@ xfs_bmap_add_attrfork_local( | |||
1079 | if (ip->i_df.if_bytes <= XFS_IFORK_DSIZE(ip)) | 1076 | if (ip->i_df.if_bytes <= XFS_IFORK_DSIZE(ip)) |
1080 | return 0; | 1077 | return 0; |
1081 | 1078 | ||
1082 | if (S_ISDIR(ip->i_d.di_mode)) { | 1079 | if (S_ISDIR(VFS_I(ip)->i_mode)) { |
1083 | memset(&dargs, 0, sizeof(dargs)); | 1080 | memset(&dargs, 0, sizeof(dargs)); |
1084 | dargs.geo = ip->i_mount->m_dir_geo; | 1081 | dargs.geo = ip->i_mount->m_dir_geo; |
1085 | dargs.dp = ip; | 1082 | dargs.dp = ip; |
@@ -1091,7 +1088,7 @@ xfs_bmap_add_attrfork_local( | |||
1091 | return xfs_dir2_sf_to_block(&dargs); | 1088 | return xfs_dir2_sf_to_block(&dargs); |
1092 | } | 1089 | } |
1093 | 1090 | ||
1094 | if (S_ISLNK(ip->i_d.di_mode)) | 1091 | if (S_ISLNK(VFS_I(ip)->i_mode)) |
1095 | return xfs_bmap_local_to_extents(tp, ip, firstblock, 1, | 1092 | return xfs_bmap_local_to_extents(tp, ip, firstblock, 1, |
1096 | flags, XFS_DATA_FORK, | 1093 | flags, XFS_DATA_FORK, |
1097 | xfs_symlink_local_to_remote); | 1094 | xfs_symlink_local_to_remote); |
@@ -4721,6 +4718,66 @@ error0: | |||
4721 | } | 4718 | } |
4722 | 4719 | ||
4723 | /* | 4720 | /* |
4721 | * When a delalloc extent is split (e.g., due to a hole punch), the original | ||
4722 | * indlen reservation must be shared across the two new extents that are left | ||
4723 | * behind. | ||
4724 | * | ||
4725 | * Given the original reservation and the worst case indlen for the two new | ||
4726 | * extents (as calculated by xfs_bmap_worst_indlen()), split the original | ||
4727 | * reservation fairly across the two new extents. If necessary, steal available | ||
4728 | * blocks from a deleted extent to make up a reservation deficiency (e.g., if | ||
4729 | * ores == 1). The number of stolen blocks is returned. The availability and | ||
4730 | * subsequent accounting of stolen blocks is the responsibility of the caller. | ||
4731 | */ | ||
4732 | static xfs_filblks_t | ||
4733 | xfs_bmap_split_indlen( | ||
4734 | xfs_filblks_t ores, /* original res. */ | ||
4735 | xfs_filblks_t *indlen1, /* ext1 worst indlen */ | ||
4736 | xfs_filblks_t *indlen2, /* ext2 worst indlen */ | ||
4737 | xfs_filblks_t avail) /* stealable blocks */ | ||
4738 | { | ||
4739 | xfs_filblks_t len1 = *indlen1; | ||
4740 | xfs_filblks_t len2 = *indlen2; | ||
4741 | xfs_filblks_t nres = len1 + len2; /* new total res. */ | ||
4742 | xfs_filblks_t stolen = 0; | ||
4743 | |||
4744 | /* | ||
4745 | * Steal as many blocks as we can to try and satisfy the worst case | ||
4746 | * indlen for both new extents. | ||
4747 | */ | ||
4748 | while (nres > ores && avail) { | ||
4749 | nres--; | ||
4750 | avail--; | ||
4751 | stolen++; | ||
4752 | } | ||
4753 | |||
4754 | /* | ||
4755 | * The only blocks available are those reserved for the original | ||
4756 | * extent and what we can steal from the extent being removed. | ||
4757 | * If this still isn't enough to satisfy the combined | ||
4758 | * requirements for the two new extents, skim blocks off of each | ||
4759 | * of the new reservations until they match what is available. | ||
4760 | */ | ||
4761 | while (nres > ores) { | ||
4762 | if (len1) { | ||
4763 | len1--; | ||
4764 | nres--; | ||
4765 | } | ||
4766 | if (nres == ores) | ||
4767 | break; | ||
4768 | if (len2) { | ||
4769 | len2--; | ||
4770 | nres--; | ||
4771 | } | ||
4772 | } | ||
4773 | |||
4774 | *indlen1 = len1; | ||
4775 | *indlen2 = len2; | ||
4776 | |||
4777 | return stolen; | ||
4778 | } | ||
4779 | |||
4780 | /* | ||
4724 | * Called by xfs_bmapi to update file extent records and the btree | 4781 | * Called by xfs_bmapi to update file extent records and the btree |
4725 | * after removing space (or undoing a delayed allocation). | 4782 | * after removing space (or undoing a delayed allocation). |
4726 | */ | 4783 | */ |
@@ -4984,28 +5041,29 @@ xfs_bmap_del_extent( | |||
4984 | XFS_IFORK_NEXT_SET(ip, whichfork, | 5041 | XFS_IFORK_NEXT_SET(ip, whichfork, |
4985 | XFS_IFORK_NEXTENTS(ip, whichfork) + 1); | 5042 | XFS_IFORK_NEXTENTS(ip, whichfork) + 1); |
4986 | } else { | 5043 | } else { |
5044 | xfs_filblks_t stolen; | ||
4987 | ASSERT(whichfork == XFS_DATA_FORK); | 5045 | ASSERT(whichfork == XFS_DATA_FORK); |
4988 | temp = xfs_bmap_worst_indlen(ip, temp); | 5046 | |
5047 | /* | ||
5048 | * Distribute the original indlen reservation across the | ||
5049 | * two new extents. Steal blocks from the deleted extent | ||
5050 | * if necessary. Stealing blocks simply fudges the | ||
5051 | * fdblocks accounting in xfs_bunmapi(). | ||
5052 | */ | ||
5053 | temp = xfs_bmap_worst_indlen(ip, got.br_blockcount); | ||
5054 | temp2 = xfs_bmap_worst_indlen(ip, new.br_blockcount); | ||
5055 | stolen = xfs_bmap_split_indlen(da_old, &temp, &temp2, | ||
5056 | del->br_blockcount); | ||
5057 | da_new = temp + temp2 - stolen; | ||
5058 | del->br_blockcount -= stolen; | ||
5059 | |||
5060 | /* | ||
5061 | * Set the reservation for each extent. Warn if either | ||
5062 | * is zero as this can lead to delalloc problems. | ||
5063 | */ | ||
5064 | WARN_ON_ONCE(!temp || !temp2); | ||
4989 | xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); | 5065 | xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); |
4990 | temp2 = xfs_bmap_worst_indlen(ip, temp2); | ||
4991 | new.br_startblock = nullstartblock((int)temp2); | 5066 | new.br_startblock = nullstartblock((int)temp2); |
4992 | da_new = temp + temp2; | ||
4993 | while (da_new > da_old) { | ||
4994 | if (temp) { | ||
4995 | temp--; | ||
4996 | da_new--; | ||
4997 | xfs_bmbt_set_startblock(ep, | ||
4998 | nullstartblock((int)temp)); | ||
4999 | } | ||
5000 | if (da_new == da_old) | ||
5001 | break; | ||
5002 | if (temp2) { | ||
5003 | temp2--; | ||
5004 | da_new--; | ||
5005 | new.br_startblock = | ||
5006 | nullstartblock((int)temp2); | ||
5007 | } | ||
5008 | } | ||
5009 | } | 5067 | } |
5010 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); | 5068 | trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); |
5011 | xfs_iext_insert(ip, *idx + 1, 1, &new, state); | 5069 | xfs_iext_insert(ip, *idx + 1, 1, &new, state); |
@@ -5210,7 +5268,7 @@ xfs_bunmapi( | |||
5210 | * This is better than zeroing it. | 5268 | * This is better than zeroing it. |
5211 | */ | 5269 | */ |
5212 | ASSERT(del.br_state == XFS_EXT_NORM); | 5270 | ASSERT(del.br_state == XFS_EXT_NORM); |
5213 | ASSERT(xfs_trans_get_block_res(tp) > 0); | 5271 | ASSERT(tp->t_blk_res > 0); |
5214 | /* | 5272 | /* |
5215 | * If this spans a realtime extent boundary, | 5273 | * If this spans a realtime extent boundary, |
5216 | * chop it back to the start of the one we end at. | 5274 | * chop it back to the start of the one we end at. |
@@ -5241,7 +5299,7 @@ xfs_bunmapi( | |||
5241 | del.br_startblock += mod; | 5299 | del.br_startblock += mod; |
5242 | } else if ((del.br_startoff == start && | 5300 | } else if ((del.br_startoff == start && |
5243 | (del.br_state == XFS_EXT_UNWRITTEN || | 5301 | (del.br_state == XFS_EXT_UNWRITTEN || |
5244 | xfs_trans_get_block_res(tp) == 0)) || | 5302 | tp->t_blk_res == 0)) || |
5245 | !xfs_sb_version_hasextflgbit(&mp->m_sb)) { | 5303 | !xfs_sb_version_hasextflgbit(&mp->m_sb)) { |
5246 | /* | 5304 | /* |
5247 | * Can't make it unwritten. There isn't | 5305 | * Can't make it unwritten. There isn't |
@@ -5296,9 +5354,37 @@ xfs_bunmapi( | |||
5296 | goto nodelete; | 5354 | goto nodelete; |
5297 | } | 5355 | } |
5298 | } | 5356 | } |
5357 | |||
5358 | /* | ||
5359 | * If it's the case where the directory code is running | ||
5360 | * with no block reservation, and the deleted block is in | ||
5361 | * the middle of its extent, and the resulting insert | ||
5362 | * of an extent would cause transformation to btree format, | ||
5363 | * then reject it. The calling code will then swap | ||
5364 | * blocks around instead. | ||
5365 | * We have to do this now, rather than waiting for the | ||
5366 | * conversion to btree format, since the transaction | ||
5367 | * will be dirty. | ||
5368 | */ | ||
5369 | if (!wasdel && tp->t_blk_res == 0 && | ||
5370 | XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && | ||
5371 | XFS_IFORK_NEXTENTS(ip, whichfork) >= /* Note the >= */ | ||
5372 | XFS_IFORK_MAXEXT(ip, whichfork) && | ||
5373 | del.br_startoff > got.br_startoff && | ||
5374 | del.br_startoff + del.br_blockcount < | ||
5375 | got.br_startoff + got.br_blockcount) { | ||
5376 | error = -ENOSPC; | ||
5377 | goto error0; | ||
5378 | } | ||
5379 | |||
5380 | /* | ||
5381 | * Unreserve quota and update realtime free space, if | ||
5382 | * appropriate. If delayed allocation, update the inode delalloc | ||
5383 | * counter now and wait to update the sb counters as | ||
5384 | * xfs_bmap_del_extent() might need to borrow some blocks. | ||
5385 | */ | ||
5299 | if (wasdel) { | 5386 | if (wasdel) { |
5300 | ASSERT(startblockval(del.br_startblock) > 0); | 5387 | ASSERT(startblockval(del.br_startblock) > 0); |
5301 | /* Update realtime/data freespace, unreserve quota */ | ||
5302 | if (isrt) { | 5388 | if (isrt) { |
5303 | xfs_filblks_t rtexts; | 5389 | xfs_filblks_t rtexts; |
5304 | 5390 | ||
@@ -5309,8 +5395,6 @@ xfs_bunmapi( | |||
5309 | ip, -((long)del.br_blockcount), 0, | 5395 | ip, -((long)del.br_blockcount), 0, |
5310 | XFS_QMOPT_RES_RTBLKS); | 5396 | XFS_QMOPT_RES_RTBLKS); |
5311 | } else { | 5397 | } else { |
5312 | xfs_mod_fdblocks(mp, (int64_t)del.br_blockcount, | ||
5313 | false); | ||
5314 | (void)xfs_trans_reserve_quota_nblks(NULL, | 5398 | (void)xfs_trans_reserve_quota_nblks(NULL, |
5315 | ip, -((long)del.br_blockcount), 0, | 5399 | ip, -((long)del.br_blockcount), 0, |
5316 | XFS_QMOPT_RES_REGBLKS); | 5400 | XFS_QMOPT_RES_REGBLKS); |
@@ -5321,32 +5405,16 @@ xfs_bunmapi( | |||
5321 | XFS_BTCUR_BPRV_WASDEL; | 5405 | XFS_BTCUR_BPRV_WASDEL; |
5322 | } else if (cur) | 5406 | } else if (cur) |
5323 | cur->bc_private.b.flags &= ~XFS_BTCUR_BPRV_WASDEL; | 5407 | cur->bc_private.b.flags &= ~XFS_BTCUR_BPRV_WASDEL; |
5324 | /* | 5408 | |
5325 | * If it's the case where the directory code is running | ||
5326 | * with no block reservation, and the deleted block is in | ||
5327 | * the middle of its extent, and the resulting insert | ||
5328 | * of an extent would cause transformation to btree format, | ||
5329 | * then reject it. The calling code will then swap | ||
5330 | * blocks around instead. | ||
5331 | * We have to do this now, rather than waiting for the | ||
5332 | * conversion to btree format, since the transaction | ||
5333 | * will be dirty. | ||
5334 | */ | ||
5335 | if (!wasdel && xfs_trans_get_block_res(tp) == 0 && | ||
5336 | XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && | ||
5337 | XFS_IFORK_NEXTENTS(ip, whichfork) >= /* Note the >= */ | ||
5338 | XFS_IFORK_MAXEXT(ip, whichfork) && | ||
5339 | del.br_startoff > got.br_startoff && | ||
5340 | del.br_startoff + del.br_blockcount < | ||
5341 | got.br_startoff + got.br_blockcount) { | ||
5342 | error = -ENOSPC; | ||
5343 | goto error0; | ||
5344 | } | ||
5345 | error = xfs_bmap_del_extent(ip, tp, &lastx, flist, cur, &del, | 5409 | error = xfs_bmap_del_extent(ip, tp, &lastx, flist, cur, &del, |
5346 | &tmp_logflags, whichfork); | 5410 | &tmp_logflags, whichfork); |
5347 | logflags |= tmp_logflags; | 5411 | logflags |= tmp_logflags; |
5348 | if (error) | 5412 | if (error) |
5349 | goto error0; | 5413 | goto error0; |
5414 | |||
5415 | if (!isrt && wasdel) | ||
5416 | xfs_mod_fdblocks(mp, (int64_t)del.br_blockcount, false); | ||
5417 | |||
5350 | bno = del.br_startoff - 1; | 5418 | bno = del.br_startoff - 1; |
5351 | nodelete: | 5419 | nodelete: |
5352 | /* | 5420 | /* |
diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index 1637c37bfbaa..6282f6e708af 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c | |||
@@ -461,7 +461,7 @@ xfs_bmbt_alloc_block( | |||
461 | * reservation amount is insufficient then we may fail a | 461 | * reservation amount is insufficient then we may fail a |
462 | * block allocation here and corrupt the filesystem. | 462 | * block allocation here and corrupt the filesystem. |
463 | */ | 463 | */ |
464 | args.minleft = xfs_trans_get_block_res(args.tp); | 464 | args.minleft = args.tp->t_blk_res; |
465 | } else if (cur->bc_private.b.flist->xbf_low) { | 465 | } else if (cur->bc_private.b.flist->xbf_low) { |
466 | args.type = XFS_ALLOCTYPE_START_BNO; | 466 | args.type = XFS_ALLOCTYPE_START_BNO; |
467 | } else { | 467 | } else { |
@@ -470,7 +470,7 @@ xfs_bmbt_alloc_block( | |||
470 | 470 | ||
471 | args.minlen = args.maxlen = args.prod = 1; | 471 | args.minlen = args.maxlen = args.prod = 1; |
472 | args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL; | 472 | args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL; |
473 | if (!args.wasdel && xfs_trans_get_block_res(args.tp) == 0) { | 473 | if (!args.wasdel && args.tp->t_blk_res == 0) { |
474 | error = -ENOSPC; | 474 | error = -ENOSPC; |
475 | goto error0; | 475 | goto error0; |
476 | } | 476 | } |
@@ -531,7 +531,6 @@ xfs_bmbt_free_block( | |||
531 | 531 | ||
532 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 532 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
533 | xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); | 533 | xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); |
534 | xfs_trans_binval(tp, bp); | ||
535 | return 0; | 534 | return 0; |
536 | } | 535 | } |
537 | 536 | ||
diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index a0eb18ce3ad3..1f88e1ce770f 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c | |||
@@ -294,6 +294,21 @@ xfs_btree_sblock_verify_crc( | |||
294 | return true; | 294 | return true; |
295 | } | 295 | } |
296 | 296 | ||
297 | static int | ||
298 | xfs_btree_free_block( | ||
299 | struct xfs_btree_cur *cur, | ||
300 | struct xfs_buf *bp) | ||
301 | { | ||
302 | int error; | ||
303 | |||
304 | error = cur->bc_ops->free_block(cur, bp); | ||
305 | if (!error) { | ||
306 | xfs_trans_binval(cur->bc_tp, bp); | ||
307 | XFS_BTREE_STATS_INC(cur, free); | ||
308 | } | ||
309 | return error; | ||
310 | } | ||
311 | |||
297 | /* | 312 | /* |
298 | * Delete the btree cursor. | 313 | * Delete the btree cursor. |
299 | */ | 314 | */ |
@@ -3209,6 +3224,7 @@ xfs_btree_kill_iroot( | |||
3209 | int level; | 3224 | int level; |
3210 | int index; | 3225 | int index; |
3211 | int numrecs; | 3226 | int numrecs; |
3227 | int error; | ||
3212 | #ifdef DEBUG | 3228 | #ifdef DEBUG |
3213 | union xfs_btree_ptr ptr; | 3229 | union xfs_btree_ptr ptr; |
3214 | int i; | 3230 | int i; |
@@ -3272,8 +3288,6 @@ xfs_btree_kill_iroot( | |||
3272 | cpp = xfs_btree_ptr_addr(cur, 1, cblock); | 3288 | cpp = xfs_btree_ptr_addr(cur, 1, cblock); |
3273 | #ifdef DEBUG | 3289 | #ifdef DEBUG |
3274 | for (i = 0; i < numrecs; i++) { | 3290 | for (i = 0; i < numrecs; i++) { |
3275 | int error; | ||
3276 | |||
3277 | error = xfs_btree_check_ptr(cur, cpp, i, level - 1); | 3291 | error = xfs_btree_check_ptr(cur, cpp, i, level - 1); |
3278 | if (error) { | 3292 | if (error) { |
3279 | XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); | 3293 | XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); |
@@ -3283,8 +3297,11 @@ xfs_btree_kill_iroot( | |||
3283 | #endif | 3297 | #endif |
3284 | xfs_btree_copy_ptrs(cur, pp, cpp, numrecs); | 3298 | xfs_btree_copy_ptrs(cur, pp, cpp, numrecs); |
3285 | 3299 | ||
3286 | cur->bc_ops->free_block(cur, cbp); | 3300 | error = xfs_btree_free_block(cur, cbp); |
3287 | XFS_BTREE_STATS_INC(cur, free); | 3301 | if (error) { |
3302 | XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); | ||
3303 | return error; | ||
3304 | } | ||
3288 | 3305 | ||
3289 | cur->bc_bufs[level - 1] = NULL; | 3306 | cur->bc_bufs[level - 1] = NULL; |
3290 | be16_add_cpu(&block->bb_level, -1); | 3307 | be16_add_cpu(&block->bb_level, -1); |
@@ -3317,14 +3334,12 @@ xfs_btree_kill_root( | |||
3317 | */ | 3334 | */ |
3318 | cur->bc_ops->set_root(cur, newroot, -1); | 3335 | cur->bc_ops->set_root(cur, newroot, -1); |
3319 | 3336 | ||
3320 | error = cur->bc_ops->free_block(cur, bp); | 3337 | error = xfs_btree_free_block(cur, bp); |
3321 | if (error) { | 3338 | if (error) { |
3322 | XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); | 3339 | XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); |
3323 | return error; | 3340 | return error; |
3324 | } | 3341 | } |
3325 | 3342 | ||
3326 | XFS_BTREE_STATS_INC(cur, free); | ||
3327 | |||
3328 | cur->bc_bufs[level] = NULL; | 3343 | cur->bc_bufs[level] = NULL; |
3329 | cur->bc_ra[level] = 0; | 3344 | cur->bc_ra[level] = 0; |
3330 | cur->bc_nlevels--; | 3345 | cur->bc_nlevels--; |
@@ -3830,10 +3845,9 @@ xfs_btree_delrec( | |||
3830 | } | 3845 | } |
3831 | 3846 | ||
3832 | /* Free the deleted block. */ | 3847 | /* Free the deleted block. */ |
3833 | error = cur->bc_ops->free_block(cur, rbp); | 3848 | error = xfs_btree_free_block(cur, rbp); |
3834 | if (error) | 3849 | if (error) |
3835 | goto error0; | 3850 | goto error0; |
3836 | XFS_BTREE_STATS_INC(cur, free); | ||
3837 | 3851 | ||
3838 | /* | 3852 | /* |
3839 | * If we joined with the left neighbor, set the buffer in the | 3853 | * If we joined with the left neighbor, set the buffer in the |
diff --git a/fs/xfs/libxfs/xfs_da_format.h b/fs/xfs/libxfs/xfs_da_format.h index b14bbd6bb05f..8d4d8bce41bf 100644 --- a/fs/xfs/libxfs/xfs_da_format.h +++ b/fs/xfs/libxfs/xfs_da_format.h | |||
@@ -641,6 +641,22 @@ xfs_dir2_block_leaf_p(struct xfs_dir2_block_tail *btp) | |||
641 | */ | 641 | */ |
642 | #define XFS_ATTR_LEAF_MAPSIZE 3 /* how many freespace slots */ | 642 | #define XFS_ATTR_LEAF_MAPSIZE 3 /* how many freespace slots */ |
643 | 643 | ||
644 | /* | ||
645 | * Entries are packed toward the top as tight as possible. | ||
646 | */ | ||
647 | typedef struct xfs_attr_shortform { | ||
648 | struct xfs_attr_sf_hdr { /* constant-structure header block */ | ||
649 | __be16 totsize; /* total bytes in shortform list */ | ||
650 | __u8 count; /* count of active entries */ | ||
651 | } hdr; | ||
652 | struct xfs_attr_sf_entry { | ||
653 | __uint8_t namelen; /* actual length of name (no NULL) */ | ||
654 | __uint8_t valuelen; /* actual length of value (no NULL) */ | ||
655 | __uint8_t flags; /* flags bits (see xfs_attr_leaf.h) */ | ||
656 | __uint8_t nameval[1]; /* name & value bytes concatenated */ | ||
657 | } list[1]; /* variable sized array */ | ||
658 | } xfs_attr_shortform_t; | ||
659 | |||
644 | typedef struct xfs_attr_leaf_map { /* RLE map of free bytes */ | 660 | typedef struct xfs_attr_leaf_map { /* RLE map of free bytes */ |
645 | __be16 base; /* base of free region */ | 661 | __be16 base; /* base of free region */ |
646 | __be16 size; /* length of free region */ | 662 | __be16 size; /* length of free region */ |
diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 2fb53a5c0a74..af0f9d171f8a 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c | |||
@@ -176,7 +176,7 @@ xfs_dir_isempty( | |||
176 | { | 176 | { |
177 | xfs_dir2_sf_hdr_t *sfp; | 177 | xfs_dir2_sf_hdr_t *sfp; |
178 | 178 | ||
179 | ASSERT(S_ISDIR(dp->i_d.di_mode)); | 179 | ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); |
180 | if (dp->i_d.di_size == 0) /* might happen during shutdown. */ | 180 | if (dp->i_d.di_size == 0) /* might happen during shutdown. */ |
181 | return 1; | 181 | return 1; |
182 | if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp)) | 182 | if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp)) |
@@ -231,7 +231,7 @@ xfs_dir_init( | |||
231 | struct xfs_da_args *args; | 231 | struct xfs_da_args *args; |
232 | int error; | 232 | int error; |
233 | 233 | ||
234 | ASSERT(S_ISDIR(dp->i_d.di_mode)); | 234 | ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); |
235 | error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino); | 235 | error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino); |
236 | if (error) | 236 | if (error) |
237 | return error; | 237 | return error; |
@@ -266,7 +266,7 @@ xfs_dir_createname( | |||
266 | int rval; | 266 | int rval; |
267 | int v; /* type-checking value */ | 267 | int v; /* type-checking value */ |
268 | 268 | ||
269 | ASSERT(S_ISDIR(dp->i_d.di_mode)); | 269 | ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); |
270 | if (inum) { | 270 | if (inum) { |
271 | rval = xfs_dir_ino_validate(tp->t_mountp, inum); | 271 | rval = xfs_dir_ino_validate(tp->t_mountp, inum); |
272 | if (rval) | 272 | if (rval) |
@@ -364,7 +364,7 @@ xfs_dir_lookup( | |||
364 | int v; /* type-checking value */ | 364 | int v; /* type-checking value */ |
365 | int lock_mode; | 365 | int lock_mode; |
366 | 366 | ||
367 | ASSERT(S_ISDIR(dp->i_d.di_mode)); | 367 | ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); |
368 | XFS_STATS_INC(dp->i_mount, xs_dir_lookup); | 368 | XFS_STATS_INC(dp->i_mount, xs_dir_lookup); |
369 | 369 | ||
370 | /* | 370 | /* |
@@ -443,7 +443,7 @@ xfs_dir_removename( | |||
443 | int rval; | 443 | int rval; |
444 | int v; /* type-checking value */ | 444 | int v; /* type-checking value */ |
445 | 445 | ||
446 | ASSERT(S_ISDIR(dp->i_d.di_mode)); | 446 | ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); |
447 | XFS_STATS_INC(dp->i_mount, xs_dir_remove); | 447 | XFS_STATS_INC(dp->i_mount, xs_dir_remove); |
448 | 448 | ||
449 | args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS); | 449 | args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS); |
@@ -505,7 +505,7 @@ xfs_dir_replace( | |||
505 | int rval; | 505 | int rval; |
506 | int v; /* type-checking value */ | 506 | int v; /* type-checking value */ |
507 | 507 | ||
508 | ASSERT(S_ISDIR(dp->i_d.di_mode)); | 508 | ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); |
509 | 509 | ||
510 | rval = xfs_dir_ino_validate(tp->t_mountp, inum); | 510 | rval = xfs_dir_ino_validate(tp->t_mountp, inum); |
511 | if (rval) | 511 | if (rval) |
diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 63ee03db796c..75a557432d0f 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c | |||
@@ -2235,6 +2235,9 @@ xfs_dir2_node_trim_free( | |||
2235 | 2235 | ||
2236 | dp = args->dp; | 2236 | dp = args->dp; |
2237 | tp = args->trans; | 2237 | tp = args->trans; |
2238 | |||
2239 | *rvalp = 0; | ||
2240 | |||
2238 | /* | 2241 | /* |
2239 | * Read the freespace block. | 2242 | * Read the freespace block. |
2240 | */ | 2243 | */ |
@@ -2255,7 +2258,6 @@ xfs_dir2_node_trim_free( | |||
2255 | */ | 2258 | */ |
2256 | if (freehdr.nused > 0) { | 2259 | if (freehdr.nused > 0) { |
2257 | xfs_trans_brelse(tp, bp); | 2260 | xfs_trans_brelse(tp, bp); |
2258 | *rvalp = 0; | ||
2259 | return 0; | 2261 | return 0; |
2260 | } | 2262 | } |
2261 | /* | 2263 | /* |
diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 66d702e6b9ff..22297f9b0fd5 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c | |||
@@ -2403,8 +2403,8 @@ xfs_ialloc_compute_maxlevels( | |||
2403 | 2403 | ||
2404 | maxleafents = (1LL << XFS_INO_AGINO_BITS(mp)) >> | 2404 | maxleafents = (1LL << XFS_INO_AGINO_BITS(mp)) >> |
2405 | XFS_INODES_PER_CHUNK_LOG; | 2405 | XFS_INODES_PER_CHUNK_LOG; |
2406 | minleafrecs = mp->m_alloc_mnr[0]; | 2406 | minleafrecs = mp->m_inobt_mnr[0]; |
2407 | minnoderecs = mp->m_alloc_mnr[1]; | 2407 | minnoderecs = mp->m_inobt_mnr[1]; |
2408 | maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs; | 2408 | maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs; |
2409 | for (level = 1; maxblocks > 1; level++) | 2409 | for (level = 1; maxblocks > 1; level++) |
2410 | maxblocks = (maxblocks + minnoderecs - 1) / minnoderecs; | 2410 | maxblocks = (maxblocks + minnoderecs - 1) / minnoderecs; |
diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index c679f3c05b63..89c21d771e35 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c | |||
@@ -125,16 +125,8 @@ xfs_inobt_free_block( | |||
125 | struct xfs_btree_cur *cur, | 125 | struct xfs_btree_cur *cur, |
126 | struct xfs_buf *bp) | 126 | struct xfs_buf *bp) |
127 | { | 127 | { |
128 | xfs_fsblock_t fsbno; | 128 | return xfs_free_extent(cur->bc_tp, |
129 | int error; | 129 | XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(bp)), 1); |
130 | |||
131 | fsbno = XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(bp)); | ||
132 | error = xfs_free_extent(cur->bc_tp, fsbno, 1); | ||
133 | if (error) | ||
134 | return error; | ||
135 | |||
136 | xfs_trans_binval(cur->bc_tp, bp); | ||
137 | return error; | ||
138 | } | 130 | } |
139 | 131 | ||
140 | STATIC int | 132 | STATIC int |
diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index 1aabfda669b0..9d9559eb2835 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c | |||
@@ -195,28 +195,50 @@ xfs_imap_to_bp( | |||
195 | } | 195 | } |
196 | 196 | ||
197 | void | 197 | void |
198 | xfs_dinode_from_disk( | 198 | xfs_inode_from_disk( |
199 | xfs_icdinode_t *to, | 199 | struct xfs_inode *ip, |
200 | xfs_dinode_t *from) | 200 | struct xfs_dinode *from) |
201 | { | 201 | { |
202 | to->di_magic = be16_to_cpu(from->di_magic); | 202 | struct xfs_icdinode *to = &ip->i_d; |
203 | to->di_mode = be16_to_cpu(from->di_mode); | 203 | struct inode *inode = VFS_I(ip); |
204 | to->di_version = from ->di_version; | 204 | |
205 | |||
206 | /* | ||
207 | * Convert v1 inodes immediately to v2 inode format as this is the | ||
208 | * minimum inode version format we support in the rest of the code. | ||
209 | */ | ||
210 | to->di_version = from->di_version; | ||
211 | if (to->di_version == 1) { | ||
212 | set_nlink(inode, be16_to_cpu(from->di_onlink)); | ||
213 | to->di_projid_lo = 0; | ||
214 | to->di_projid_hi = 0; | ||
215 | to->di_version = 2; | ||
216 | } else { | ||
217 | set_nlink(inode, be32_to_cpu(from->di_nlink)); | ||
218 | to->di_projid_lo = be16_to_cpu(from->di_projid_lo); | ||
219 | to->di_projid_hi = be16_to_cpu(from->di_projid_hi); | ||
220 | } | ||
221 | |||
205 | to->di_format = from->di_format; | 222 | to->di_format = from->di_format; |
206 | to->di_onlink = be16_to_cpu(from->di_onlink); | ||
207 | to->di_uid = be32_to_cpu(from->di_uid); | 223 | to->di_uid = be32_to_cpu(from->di_uid); |
208 | to->di_gid = be32_to_cpu(from->di_gid); | 224 | to->di_gid = be32_to_cpu(from->di_gid); |
209 | to->di_nlink = be32_to_cpu(from->di_nlink); | ||
210 | to->di_projid_lo = be16_to_cpu(from->di_projid_lo); | ||
211 | to->di_projid_hi = be16_to_cpu(from->di_projid_hi); | ||
212 | memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); | ||
213 | to->di_flushiter = be16_to_cpu(from->di_flushiter); | 225 | to->di_flushiter = be16_to_cpu(from->di_flushiter); |
214 | to->di_atime.t_sec = be32_to_cpu(from->di_atime.t_sec); | 226 | |
215 | to->di_atime.t_nsec = be32_to_cpu(from->di_atime.t_nsec); | 227 | /* |
216 | to->di_mtime.t_sec = be32_to_cpu(from->di_mtime.t_sec); | 228 | * Time is signed, so need to convert to signed 32 bit before |
217 | to->di_mtime.t_nsec = be32_to_cpu(from->di_mtime.t_nsec); | 229 | * storing in inode timestamp which may be 64 bit. Otherwise |
218 | to->di_ctime.t_sec = be32_to_cpu(from->di_ctime.t_sec); | 230 | * a time before epoch is converted to a time long after epoch |
219 | to->di_ctime.t_nsec = be32_to_cpu(from->di_ctime.t_nsec); | 231 | * on 64 bit systems. |
232 | */ | ||
233 | inode->i_atime.tv_sec = (int)be32_to_cpu(from->di_atime.t_sec); | ||
234 | inode->i_atime.tv_nsec = (int)be32_to_cpu(from->di_atime.t_nsec); | ||
235 | inode->i_mtime.tv_sec = (int)be32_to_cpu(from->di_mtime.t_sec); | ||
236 | inode->i_mtime.tv_nsec = (int)be32_to_cpu(from->di_mtime.t_nsec); | ||
237 | inode->i_ctime.tv_sec = (int)be32_to_cpu(from->di_ctime.t_sec); | ||
238 | inode->i_ctime.tv_nsec = (int)be32_to_cpu(from->di_ctime.t_nsec); | ||
239 | inode->i_generation = be32_to_cpu(from->di_gen); | ||
240 | inode->i_mode = be16_to_cpu(from->di_mode); | ||
241 | |||
220 | to->di_size = be64_to_cpu(from->di_size); | 242 | to->di_size = be64_to_cpu(from->di_size); |
221 | to->di_nblocks = be64_to_cpu(from->di_nblocks); | 243 | to->di_nblocks = be64_to_cpu(from->di_nblocks); |
222 | to->di_extsize = be32_to_cpu(from->di_extsize); | 244 | to->di_extsize = be32_to_cpu(from->di_extsize); |
@@ -227,42 +249,96 @@ xfs_dinode_from_disk( | |||
227 | to->di_dmevmask = be32_to_cpu(from->di_dmevmask); | 249 | to->di_dmevmask = be32_to_cpu(from->di_dmevmask); |
228 | to->di_dmstate = be16_to_cpu(from->di_dmstate); | 250 | to->di_dmstate = be16_to_cpu(from->di_dmstate); |
229 | to->di_flags = be16_to_cpu(from->di_flags); | 251 | to->di_flags = be16_to_cpu(from->di_flags); |
230 | to->di_gen = be32_to_cpu(from->di_gen); | ||
231 | 252 | ||
232 | if (to->di_version == 3) { | 253 | if (to->di_version == 3) { |
233 | to->di_changecount = be64_to_cpu(from->di_changecount); | 254 | inode->i_version = be64_to_cpu(from->di_changecount); |
234 | to->di_crtime.t_sec = be32_to_cpu(from->di_crtime.t_sec); | 255 | to->di_crtime.t_sec = be32_to_cpu(from->di_crtime.t_sec); |
235 | to->di_crtime.t_nsec = be32_to_cpu(from->di_crtime.t_nsec); | 256 | to->di_crtime.t_nsec = be32_to_cpu(from->di_crtime.t_nsec); |
236 | to->di_flags2 = be64_to_cpu(from->di_flags2); | 257 | to->di_flags2 = be64_to_cpu(from->di_flags2); |
237 | to->di_ino = be64_to_cpu(from->di_ino); | ||
238 | to->di_lsn = be64_to_cpu(from->di_lsn); | ||
239 | memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2)); | ||
240 | uuid_copy(&to->di_uuid, &from->di_uuid); | ||
241 | } | 258 | } |
242 | } | 259 | } |
243 | 260 | ||
244 | void | 261 | void |
245 | xfs_dinode_to_disk( | 262 | xfs_inode_to_disk( |
246 | xfs_dinode_t *to, | 263 | struct xfs_inode *ip, |
247 | xfs_icdinode_t *from) | 264 | struct xfs_dinode *to, |
265 | xfs_lsn_t lsn) | ||
266 | { | ||
267 | struct xfs_icdinode *from = &ip->i_d; | ||
268 | struct inode *inode = VFS_I(ip); | ||
269 | |||
270 | to->di_magic = cpu_to_be16(XFS_DINODE_MAGIC); | ||
271 | to->di_onlink = 0; | ||
272 | |||
273 | to->di_version = from->di_version; | ||
274 | to->di_format = from->di_format; | ||
275 | to->di_uid = cpu_to_be32(from->di_uid); | ||
276 | to->di_gid = cpu_to_be32(from->di_gid); | ||
277 | to->di_projid_lo = cpu_to_be16(from->di_projid_lo); | ||
278 | to->di_projid_hi = cpu_to_be16(from->di_projid_hi); | ||
279 | |||
280 | memset(to->di_pad, 0, sizeof(to->di_pad)); | ||
281 | to->di_atime.t_sec = cpu_to_be32(inode->i_atime.tv_sec); | ||
282 | to->di_atime.t_nsec = cpu_to_be32(inode->i_atime.tv_nsec); | ||
283 | to->di_mtime.t_sec = cpu_to_be32(inode->i_mtime.tv_sec); | ||
284 | to->di_mtime.t_nsec = cpu_to_be32(inode->i_mtime.tv_nsec); | ||
285 | to->di_ctime.t_sec = cpu_to_be32(inode->i_ctime.tv_sec); | ||
286 | to->di_ctime.t_nsec = cpu_to_be32(inode->i_ctime.tv_nsec); | ||
287 | to->di_nlink = cpu_to_be32(inode->i_nlink); | ||
288 | to->di_gen = cpu_to_be32(inode->i_generation); | ||
289 | to->di_mode = cpu_to_be16(inode->i_mode); | ||
290 | |||
291 | to->di_size = cpu_to_be64(from->di_size); | ||
292 | to->di_nblocks = cpu_to_be64(from->di_nblocks); | ||
293 | to->di_extsize = cpu_to_be32(from->di_extsize); | ||
294 | to->di_nextents = cpu_to_be32(from->di_nextents); | ||
295 | to->di_anextents = cpu_to_be16(from->di_anextents); | ||
296 | to->di_forkoff = from->di_forkoff; | ||
297 | to->di_aformat = from->di_aformat; | ||
298 | to->di_dmevmask = cpu_to_be32(from->di_dmevmask); | ||
299 | to->di_dmstate = cpu_to_be16(from->di_dmstate); | ||
300 | to->di_flags = cpu_to_be16(from->di_flags); | ||
301 | |||
302 | if (from->di_version == 3) { | ||
303 | to->di_changecount = cpu_to_be64(inode->i_version); | ||
304 | to->di_crtime.t_sec = cpu_to_be32(from->di_crtime.t_sec); | ||
305 | to->di_crtime.t_nsec = cpu_to_be32(from->di_crtime.t_nsec); | ||
306 | to->di_flags2 = cpu_to_be64(from->di_flags2); | ||
307 | |||
308 | to->di_ino = cpu_to_be64(ip->i_ino); | ||
309 | to->di_lsn = cpu_to_be64(lsn); | ||
310 | memset(to->di_pad2, 0, sizeof(to->di_pad2)); | ||
311 | uuid_copy(&to->di_uuid, &ip->i_mount->m_sb.sb_meta_uuid); | ||
312 | to->di_flushiter = 0; | ||
313 | } else { | ||
314 | to->di_flushiter = cpu_to_be16(from->di_flushiter); | ||
315 | } | ||
316 | } | ||
317 | |||
318 | void | ||
319 | xfs_log_dinode_to_disk( | ||
320 | struct xfs_log_dinode *from, | ||
321 | struct xfs_dinode *to) | ||
248 | { | 322 | { |
249 | to->di_magic = cpu_to_be16(from->di_magic); | 323 | to->di_magic = cpu_to_be16(from->di_magic); |
250 | to->di_mode = cpu_to_be16(from->di_mode); | 324 | to->di_mode = cpu_to_be16(from->di_mode); |
251 | to->di_version = from ->di_version; | 325 | to->di_version = from->di_version; |
252 | to->di_format = from->di_format; | 326 | to->di_format = from->di_format; |
253 | to->di_onlink = cpu_to_be16(from->di_onlink); | 327 | to->di_onlink = 0; |
254 | to->di_uid = cpu_to_be32(from->di_uid); | 328 | to->di_uid = cpu_to_be32(from->di_uid); |
255 | to->di_gid = cpu_to_be32(from->di_gid); | 329 | to->di_gid = cpu_to_be32(from->di_gid); |
256 | to->di_nlink = cpu_to_be32(from->di_nlink); | 330 | to->di_nlink = cpu_to_be32(from->di_nlink); |
257 | to->di_projid_lo = cpu_to_be16(from->di_projid_lo); | 331 | to->di_projid_lo = cpu_to_be16(from->di_projid_lo); |
258 | to->di_projid_hi = cpu_to_be16(from->di_projid_hi); | 332 | to->di_projid_hi = cpu_to_be16(from->di_projid_hi); |
259 | memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); | 333 | memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); |
334 | |||
260 | to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec); | 335 | to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec); |
261 | to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec); | 336 | to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec); |
262 | to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec); | 337 | to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec); |
263 | to->di_mtime.t_nsec = cpu_to_be32(from->di_mtime.t_nsec); | 338 | to->di_mtime.t_nsec = cpu_to_be32(from->di_mtime.t_nsec); |
264 | to->di_ctime.t_sec = cpu_to_be32(from->di_ctime.t_sec); | 339 | to->di_ctime.t_sec = cpu_to_be32(from->di_ctime.t_sec); |
265 | to->di_ctime.t_nsec = cpu_to_be32(from->di_ctime.t_nsec); | 340 | to->di_ctime.t_nsec = cpu_to_be32(from->di_ctime.t_nsec); |
341 | |||
266 | to->di_size = cpu_to_be64(from->di_size); | 342 | to->di_size = cpu_to_be64(from->di_size); |
267 | to->di_nblocks = cpu_to_be64(from->di_nblocks); | 343 | to->di_nblocks = cpu_to_be64(from->di_nblocks); |
268 | to->di_extsize = cpu_to_be32(from->di_extsize); | 344 | to->di_extsize = cpu_to_be32(from->di_extsize); |
@@ -367,13 +443,10 @@ xfs_iread( | |||
367 | !(mp->m_flags & XFS_MOUNT_IKEEP)) { | 443 | !(mp->m_flags & XFS_MOUNT_IKEEP)) { |
368 | /* initialise the on-disk inode core */ | 444 | /* initialise the on-disk inode core */ |
369 | memset(&ip->i_d, 0, sizeof(ip->i_d)); | 445 | memset(&ip->i_d, 0, sizeof(ip->i_d)); |
370 | ip->i_d.di_magic = XFS_DINODE_MAGIC; | 446 | VFS_I(ip)->i_generation = prandom_u32(); |
371 | ip->i_d.di_gen = prandom_u32(); | 447 | if (xfs_sb_version_hascrc(&mp->m_sb)) |
372 | if (xfs_sb_version_hascrc(&mp->m_sb)) { | ||
373 | ip->i_d.di_version = 3; | 448 | ip->i_d.di_version = 3; |
374 | ip->i_d.di_ino = ip->i_ino; | 449 | else |
375 | uuid_copy(&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid); | ||
376 | } else | ||
377 | ip->i_d.di_version = 2; | 450 | ip->i_d.di_version = 2; |
378 | return 0; | 451 | return 0; |
379 | } | 452 | } |
@@ -403,7 +476,7 @@ xfs_iread( | |||
403 | * Otherwise, just get the truly permanent information. | 476 | * Otherwise, just get the truly permanent information. |
404 | */ | 477 | */ |
405 | if (dip->di_mode) { | 478 | if (dip->di_mode) { |
406 | xfs_dinode_from_disk(&ip->i_d, dip); | 479 | xfs_inode_from_disk(ip, dip); |
407 | error = xfs_iformat_fork(ip, dip); | 480 | error = xfs_iformat_fork(ip, dip); |
408 | if (error) { | 481 | if (error) { |
409 | #ifdef DEBUG | 482 | #ifdef DEBUG |
@@ -417,16 +490,10 @@ xfs_iread( | |||
417 | * Partial initialisation of the in-core inode. Just the bits | 490 | * Partial initialisation of the in-core inode. Just the bits |
418 | * that xfs_ialloc won't overwrite or relies on being correct. | 491 | * that xfs_ialloc won't overwrite or relies on being correct. |
419 | */ | 492 | */ |
420 | ip->i_d.di_magic = be16_to_cpu(dip->di_magic); | ||
421 | ip->i_d.di_version = dip->di_version; | 493 | ip->i_d.di_version = dip->di_version; |
422 | ip->i_d.di_gen = be32_to_cpu(dip->di_gen); | 494 | VFS_I(ip)->i_generation = be32_to_cpu(dip->di_gen); |
423 | ip->i_d.di_flushiter = be16_to_cpu(dip->di_flushiter); | 495 | ip->i_d.di_flushiter = be16_to_cpu(dip->di_flushiter); |
424 | 496 | ||
425 | if (dip->di_version == 3) { | ||
426 | ip->i_d.di_ino = be64_to_cpu(dip->di_ino); | ||
427 | uuid_copy(&ip->i_d.di_uuid, &dip->di_uuid); | ||
428 | } | ||
429 | |||
430 | /* | 497 | /* |
431 | * Make sure to pull in the mode here as well in | 498 | * Make sure to pull in the mode here as well in |
432 | * case the inode is released without being used. | 499 | * case the inode is released without being used. |
@@ -434,25 +501,10 @@ xfs_iread( | |||
434 | * the inode is already free and not try to mess | 501 | * the inode is already free and not try to mess |
435 | * with the uninitialized part of it. | 502 | * with the uninitialized part of it. |
436 | */ | 503 | */ |
437 | ip->i_d.di_mode = 0; | 504 | VFS_I(ip)->i_mode = 0; |
438 | } | ||
439 | |||
440 | /* | ||
441 | * Automatically convert version 1 inode formats in memory to version 2 | ||
442 | * inode format. If the inode is modified, it will get logged and | ||
443 | * rewritten as a version 2 inode. We can do this because we set the | ||
444 | * superblock feature bit for v2 inodes unconditionally during mount | ||
445 | * and it means the reast of the code can assume the inode version is 2 | ||
446 | * or higher. | ||
447 | */ | ||
448 | if (ip->i_d.di_version == 1) { | ||
449 | ip->i_d.di_version = 2; | ||
450 | memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); | ||
451 | ip->i_d.di_nlink = ip->i_d.di_onlink; | ||
452 | ip->i_d.di_onlink = 0; | ||
453 | xfs_set_projid(ip, 0); | ||
454 | } | 505 | } |
455 | 506 | ||
507 | ASSERT(ip->i_d.di_version >= 2); | ||
456 | ip->i_delayed_blks = 0; | 508 | ip->i_delayed_blks = 0; |
457 | 509 | ||
458 | /* | 510 | /* |
diff --git a/fs/xfs/libxfs/xfs_inode_buf.h b/fs/xfs/libxfs/xfs_inode_buf.h index 9308c47f2a52..7c4dd321b215 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.h +++ b/fs/xfs/libxfs/xfs_inode_buf.h | |||
@@ -20,7 +20,36 @@ | |||
20 | 20 | ||
21 | struct xfs_inode; | 21 | struct xfs_inode; |
22 | struct xfs_dinode; | 22 | struct xfs_dinode; |
23 | struct xfs_icdinode; | 23 | |
24 | /* | ||
25 | * In memory representation of the XFS inode. This is held in the in-core struct | ||
26 | * xfs_inode and represents the current on disk values but the structure is not | ||
27 | * in on-disk format. That is, this structure is always translated to on-disk | ||
28 | * format specific structures at the appropriate time. | ||
29 | */ | ||
30 | struct xfs_icdinode { | ||
31 | __int8_t di_version; /* inode version */ | ||
32 | __int8_t di_format; /* format of di_c data */ | ||
33 | __uint16_t di_flushiter; /* incremented on flush */ | ||
34 | __uint32_t di_uid; /* owner's user id */ | ||
35 | __uint32_t di_gid; /* owner's group id */ | ||
36 | __uint16_t di_projid_lo; /* lower part of owner's project id */ | ||
37 | __uint16_t di_projid_hi; /* higher part of owner's project id */ | ||
38 | xfs_fsize_t di_size; /* number of bytes in file */ | ||
39 | xfs_rfsblock_t di_nblocks; /* # of direct & btree blocks used */ | ||
40 | xfs_extlen_t di_extsize; /* basic/minimum extent size for file */ | ||
41 | xfs_extnum_t di_nextents; /* number of extents in data fork */ | ||
42 | xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/ | ||
43 | __uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */ | ||
44 | __int8_t di_aformat; /* format of attr fork's data */ | ||
45 | __uint32_t di_dmevmask; /* DMIG event mask */ | ||
46 | __uint16_t di_dmstate; /* DMIG state info */ | ||
47 | __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */ | ||
48 | |||
49 | __uint64_t di_flags2; /* more random flags */ | ||
50 | |||
51 | xfs_ictimestamp_t di_crtime; /* time created */ | ||
52 | }; | ||
24 | 53 | ||
25 | /* | 54 | /* |
26 | * Inode location information. Stored in the inode and passed to | 55 | * Inode location information. Stored in the inode and passed to |
@@ -38,8 +67,11 @@ int xfs_imap_to_bp(struct xfs_mount *, struct xfs_trans *, | |||
38 | int xfs_iread(struct xfs_mount *, struct xfs_trans *, | 67 | int xfs_iread(struct xfs_mount *, struct xfs_trans *, |
39 | struct xfs_inode *, uint); | 68 | struct xfs_inode *, uint); |
40 | void xfs_dinode_calc_crc(struct xfs_mount *, struct xfs_dinode *); | 69 | void xfs_dinode_calc_crc(struct xfs_mount *, struct xfs_dinode *); |
41 | void xfs_dinode_to_disk(struct xfs_dinode *to, struct xfs_icdinode *from); | 70 | void xfs_inode_to_disk(struct xfs_inode *ip, struct xfs_dinode *to, |
42 | void xfs_dinode_from_disk(struct xfs_icdinode *to, struct xfs_dinode *from); | 71 | xfs_lsn_t lsn); |
72 | void xfs_inode_from_disk(struct xfs_inode *ip, struct xfs_dinode *from); | ||
73 | void xfs_log_dinode_to_disk(struct xfs_log_dinode *from, | ||
74 | struct xfs_dinode *to); | ||
43 | 75 | ||
44 | #if defined(DEBUG) | 76 | #if defined(DEBUG) |
45 | void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *); | 77 | void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *); |
diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index 0defbd02f62d..11faf7df14c8 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "xfs_error.h" | 31 | #include "xfs_error.h" |
32 | #include "xfs_trace.h" | 32 | #include "xfs_trace.h" |
33 | #include "xfs_attr_sf.h" | 33 | #include "xfs_attr_sf.h" |
34 | #include "xfs_da_format.h" | ||
34 | 35 | ||
35 | kmem_zone_t *xfs_ifork_zone; | 36 | kmem_zone_t *xfs_ifork_zone; |
36 | 37 | ||
@@ -120,7 +121,7 @@ xfs_iformat_fork( | |||
120 | return -EFSCORRUPTED; | 121 | return -EFSCORRUPTED; |
121 | } | 122 | } |
122 | 123 | ||
123 | switch (ip->i_d.di_mode & S_IFMT) { | 124 | switch (VFS_I(ip)->i_mode & S_IFMT) { |
124 | case S_IFIFO: | 125 | case S_IFIFO: |
125 | case S_IFCHR: | 126 | case S_IFCHR: |
126 | case S_IFBLK: | 127 | case S_IFBLK: |
diff --git a/fs/xfs/libxfs/xfs_log_format.h b/fs/xfs/libxfs/xfs_log_format.h index 265314690415..d54a8018b079 100644 --- a/fs/xfs/libxfs/xfs_log_format.h +++ b/fs/xfs/libxfs/xfs_log_format.h | |||
@@ -290,6 +290,7 @@ typedef struct xfs_inode_log_format_64 { | |||
290 | __int32_t ilf_boffset; /* off of inode in buffer */ | 290 | __int32_t ilf_boffset; /* off of inode in buffer */ |
291 | } xfs_inode_log_format_64_t; | 291 | } xfs_inode_log_format_64_t; |
292 | 292 | ||
293 | |||
293 | /* | 294 | /* |
294 | * Flags for xfs_trans_log_inode flags field. | 295 | * Flags for xfs_trans_log_inode flags field. |
295 | */ | 296 | */ |
@@ -360,15 +361,15 @@ typedef struct xfs_ictimestamp { | |||
360 | } xfs_ictimestamp_t; | 361 | } xfs_ictimestamp_t; |
361 | 362 | ||
362 | /* | 363 | /* |
363 | * NOTE: This structure must be kept identical to struct xfs_dinode | 364 | * Define the format of the inode core that is logged. This structure must be |
364 | * except for the endianness annotations. | 365 | * kept identical to struct xfs_dinode except for the endianness annotations. |
365 | */ | 366 | */ |
366 | typedef struct xfs_icdinode { | 367 | struct xfs_log_dinode { |
367 | __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */ | 368 | __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */ |
368 | __uint16_t di_mode; /* mode and type of file */ | 369 | __uint16_t di_mode; /* mode and type of file */ |
369 | __int8_t di_version; /* inode version */ | 370 | __int8_t di_version; /* inode version */ |
370 | __int8_t di_format; /* format of di_c data */ | 371 | __int8_t di_format; /* format of di_c data */ |
371 | __uint16_t di_onlink; /* old number of links to file */ | 372 | __uint8_t di_pad3[2]; /* unused in v2/3 inodes */ |
372 | __uint32_t di_uid; /* owner's user id */ | 373 | __uint32_t di_uid; /* owner's user id */ |
373 | __uint32_t di_gid; /* owner's group id */ | 374 | __uint32_t di_gid; /* owner's group id */ |
374 | __uint32_t di_nlink; /* number of links to file */ | 375 | __uint32_t di_nlink; /* number of links to file */ |
@@ -407,13 +408,13 @@ typedef struct xfs_icdinode { | |||
407 | uuid_t di_uuid; /* UUID of the filesystem */ | 408 | uuid_t di_uuid; /* UUID of the filesystem */ |
408 | 409 | ||
409 | /* structure must be padded to 64 bit alignment */ | 410 | /* structure must be padded to 64 bit alignment */ |
410 | } xfs_icdinode_t; | 411 | }; |
411 | 412 | ||
412 | static inline uint xfs_icdinode_size(int version) | 413 | static inline uint xfs_log_dinode_size(int version) |
413 | { | 414 | { |
414 | if (version == 3) | 415 | if (version == 3) |
415 | return sizeof(struct xfs_icdinode); | 416 | return sizeof(struct xfs_log_dinode); |
416 | return offsetof(struct xfs_icdinode, di_next_unlinked); | 417 | return offsetof(struct xfs_log_dinode, di_next_unlinked); |
417 | } | 418 | } |
418 | 419 | ||
419 | /* | 420 | /* |
@@ -495,6 +496,8 @@ enum xfs_blft { | |||
495 | XFS_BLFT_ATTR_LEAF_BUF, | 496 | XFS_BLFT_ATTR_LEAF_BUF, |
496 | XFS_BLFT_ATTR_RMT_BUF, | 497 | XFS_BLFT_ATTR_RMT_BUF, |
497 | XFS_BLFT_SB_BUF, | 498 | XFS_BLFT_SB_BUF, |
499 | XFS_BLFT_RTBITMAP_BUF, | ||
500 | XFS_BLFT_RTSUMMARY_BUF, | ||
498 | XFS_BLFT_MAX_BUF = (1 << XFS_BLFT_BITS), | 501 | XFS_BLFT_MAX_BUF = (1 << XFS_BLFT_BITS), |
499 | }; | 502 | }; |
500 | 503 | ||
diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h index f51078f1e92a..8eed51275bb3 100644 --- a/fs/xfs/libxfs/xfs_quota_defs.h +++ b/fs/xfs/libxfs/xfs_quota_defs.h | |||
@@ -37,7 +37,7 @@ typedef __uint16_t xfs_qwarncnt_t; | |||
37 | #define XFS_DQ_PROJ 0x0002 /* project quota */ | 37 | #define XFS_DQ_PROJ 0x0002 /* project quota */ |
38 | #define XFS_DQ_GROUP 0x0004 /* a group quota */ | 38 | #define XFS_DQ_GROUP 0x0004 /* a group quota */ |
39 | #define XFS_DQ_DIRTY 0x0008 /* dquot is dirty */ | 39 | #define XFS_DQ_DIRTY 0x0008 /* dquot is dirty */ |
40 | #define XFS_DQ_FREEING 0x0010 /* dquot is beeing torn down */ | 40 | #define XFS_DQ_FREEING 0x0010 /* dquot is being torn down */ |
41 | 41 | ||
42 | #define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP) | 42 | #define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP) |
43 | 43 | ||
@@ -116,6 +116,7 @@ typedef __uint16_t xfs_qwarncnt_t; | |||
116 | #define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot if damaged */ | 116 | #define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot if damaged */ |
117 | #define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */ | 117 | #define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */ |
118 | #define XFS_QMOPT_ENOSPC 0x0004000 /* enospc instead of edquot (prj) */ | 118 | #define XFS_QMOPT_ENOSPC 0x0004000 /* enospc instead of edquot (prj) */ |
119 | #define XFS_QMOPT_DQNEXT 0x0008000 /* return next dquot >= this ID */ | ||
119 | 120 | ||
120 | /* | 121 | /* |
121 | * flags to xfs_trans_mod_dquot to indicate which field needs to be | 122 | * flags to xfs_trans_mod_dquot to indicate which field needs to be |
diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index 9b59ffa1fc19..951c044e24e4 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c | |||
@@ -42,6 +42,31 @@ | |||
42 | */ | 42 | */ |
43 | 43 | ||
44 | /* | 44 | /* |
45 | * Real time buffers need verifiers to avoid runtime warnings during IO. | ||
46 | * We don't have anything to verify, however, so these are just dummy | ||
47 | * operations. | ||
48 | */ | ||
49 | static void | ||
50 | xfs_rtbuf_verify_read( | ||
51 | struct xfs_buf *bp) | ||
52 | { | ||
53 | return; | ||
54 | } | ||
55 | |||
56 | static void | ||
57 | xfs_rtbuf_verify_write( | ||
58 | struct xfs_buf *bp) | ||
59 | { | ||
60 | return; | ||
61 | } | ||
62 | |||
63 | const struct xfs_buf_ops xfs_rtbuf_ops = { | ||
64 | .name = "rtbuf", | ||
65 | .verify_read = xfs_rtbuf_verify_read, | ||
66 | .verify_write = xfs_rtbuf_verify_write, | ||
67 | }; | ||
68 | |||
69 | /* | ||
45 | * Get a buffer for the bitmap or summary file block specified. | 70 | * Get a buffer for the bitmap or summary file block specified. |
46 | * The buffer is returned read and locked. | 71 | * The buffer is returned read and locked. |
47 | */ | 72 | */ |
@@ -68,9 +93,12 @@ xfs_rtbuf_get( | |||
68 | ASSERT(map.br_startblock != NULLFSBLOCK); | 93 | ASSERT(map.br_startblock != NULLFSBLOCK); |
69 | error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, | 94 | error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, |
70 | XFS_FSB_TO_DADDR(mp, map.br_startblock), | 95 | XFS_FSB_TO_DADDR(mp, map.br_startblock), |
71 | mp->m_bsize, 0, &bp, NULL); | 96 | mp->m_bsize, 0, &bp, &xfs_rtbuf_ops); |
72 | if (error) | 97 | if (error) |
73 | return error; | 98 | return error; |
99 | |||
100 | xfs_trans_buf_set_type(tp, bp, issum ? XFS_BLFT_RTSUMMARY_BUF | ||
101 | : XFS_BLFT_RTBITMAP_BUF); | ||
74 | *bpp = bp; | 102 | *bpp = bp; |
75 | return 0; | 103 | return 0; |
76 | } | 104 | } |
@@ -983,7 +1011,7 @@ xfs_rtfree_extent( | |||
983 | mp->m_sb.sb_rextents) { | 1011 | mp->m_sb.sb_rextents) { |
984 | if (!(mp->m_rbmip->i_d.di_flags & XFS_DIFLAG_NEWRTBM)) | 1012 | if (!(mp->m_rbmip->i_d.di_flags & XFS_DIFLAG_NEWRTBM)) |
985 | mp->m_rbmip->i_d.di_flags |= XFS_DIFLAG_NEWRTBM; | 1013 | mp->m_rbmip->i_d.di_flags |= XFS_DIFLAG_NEWRTBM; |
986 | *(__uint64_t *)&mp->m_rbmip->i_d.di_atime = 0; | 1014 | *(__uint64_t *)&VFS_I(mp->m_rbmip)->i_atime = 0; |
987 | xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE); | 1015 | xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE); |
988 | } | 1016 | } |
989 | return 0; | 1017 | return 0; |
diff --git a/fs/xfs/libxfs/xfs_sb.h b/fs/xfs/libxfs/xfs_sb.h index b25bb9a343f3..961e6475a309 100644 --- a/fs/xfs/libxfs/xfs_sb.h +++ b/fs/xfs/libxfs/xfs_sb.h | |||
@@ -27,7 +27,6 @@ extern struct xfs_perag *xfs_perag_get_tag(struct xfs_mount *, xfs_agnumber_t, | |||
27 | extern void xfs_perag_put(struct xfs_perag *pag); | 27 | extern void xfs_perag_put(struct xfs_perag *pag); |
28 | extern int xfs_initialize_perag_data(struct xfs_mount *, xfs_agnumber_t); | 28 | extern int xfs_initialize_perag_data(struct xfs_mount *, xfs_agnumber_t); |
29 | 29 | ||
30 | extern void xfs_sb_calc_crc(struct xfs_buf *bp); | ||
31 | extern void xfs_log_sb(struct xfs_trans *tp); | 30 | extern void xfs_log_sb(struct xfs_trans *tp); |
32 | extern int xfs_sync_sb(struct xfs_mount *mp, bool wait); | 31 | extern int xfs_sync_sb(struct xfs_mount *mp, bool wait); |
33 | extern void xfs_sb_mount_common(struct xfs_mount *mp, struct xfs_sb *sbp); | 32 | extern void xfs_sb_mount_common(struct xfs_mount *mp, struct xfs_sb *sbp); |
diff --git a/fs/xfs/libxfs/xfs_shared.h b/fs/xfs/libxfs/xfs_shared.h index 15c3ceb845b9..81ac870834da 100644 --- a/fs/xfs/libxfs/xfs_shared.h +++ b/fs/xfs/libxfs/xfs_shared.h | |||
@@ -53,6 +53,7 @@ extern const struct xfs_buf_ops xfs_dquot_buf_ra_ops; | |||
53 | extern const struct xfs_buf_ops xfs_sb_buf_ops; | 53 | extern const struct xfs_buf_ops xfs_sb_buf_ops; |
54 | extern const struct xfs_buf_ops xfs_sb_quiet_buf_ops; | 54 | extern const struct xfs_buf_ops xfs_sb_quiet_buf_ops; |
55 | extern const struct xfs_buf_ops xfs_symlink_buf_ops; | 55 | extern const struct xfs_buf_ops xfs_symlink_buf_ops; |
56 | extern const struct xfs_buf_ops xfs_rtbuf_ops; | ||
56 | 57 | ||
57 | /* | 58 | /* |
58 | * Transaction types. Used to distinguish types of buffers. These never reach | 59 | * Transaction types. Used to distinguish types of buffers. These never reach |