aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/libxfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/libxfs')
-rw-r--r--fs/xfs/libxfs/xfs_alloc_btree.c2
-rw-r--r--fs/xfs/libxfs/xfs_attr_sf.h16
-rw-r--r--fs/xfs/libxfs/xfs_bmap.c172
-rw-r--r--fs/xfs/libxfs/xfs_bmap_btree.c5
-rw-r--r--fs/xfs/libxfs/xfs_btree.c32
-rw-r--r--fs/xfs/libxfs/xfs_da_format.h16
-rw-r--r--fs/xfs/libxfs/xfs_dir2.c12
-rw-r--r--fs/xfs/libxfs/xfs_dir2_node.c4
-rw-r--r--fs/xfs/libxfs/xfs_ialloc.c4
-rw-r--r--fs/xfs/libxfs/xfs_ialloc_btree.c12
-rw-r--r--fs/xfs/libxfs/xfs_inode_buf.c170
-rw-r--r--fs/xfs/libxfs/xfs_inode_buf.h38
-rw-r--r--fs/xfs/libxfs/xfs_inode_fork.c3
-rw-r--r--fs/xfs/libxfs/xfs_log_format.h19
-rw-r--r--fs/xfs/libxfs/xfs_quota_defs.h3
-rw-r--r--fs/xfs/libxfs/xfs_rtbitmap.c32
-rw-r--r--fs/xfs/libxfs/xfs_sb.h1
-rw-r--r--fs/xfs/libxfs/xfs_shared.h1
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 */
31typedef 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;
43typedef struct xfs_attr_sf_hdr xfs_attr_sf_hdr_t; 27typedef struct xfs_attr_sf_hdr xfs_attr_sf_hdr_t;
44typedef struct xfs_attr_sf_entry xfs_attr_sf_entry_t; 28typedef 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
486error0: 483error0:
@@ -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 */
4732static xfs_filblks_t
4733xfs_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;
5351nodelete: 5419nodelete:
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
297static int
298xfs_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 */
647typedef 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
644typedef struct xfs_attr_leaf_map { /* RLE map of free bytes */ 660typedef 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
140STATIC int 132STATIC 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
197void 197void
198xfs_dinode_from_disk( 198xfs_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
244void 261void
245xfs_dinode_to_disk( 262xfs_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
318void
319xfs_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
21struct xfs_inode; 21struct xfs_inode;
22struct xfs_dinode; 22struct xfs_dinode;
23struct 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 */
30struct 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 *,
38int xfs_iread(struct xfs_mount *, struct xfs_trans *, 67int xfs_iread(struct xfs_mount *, struct xfs_trans *,
39 struct xfs_inode *, uint); 68 struct xfs_inode *, uint);
40void xfs_dinode_calc_crc(struct xfs_mount *, struct xfs_dinode *); 69void xfs_dinode_calc_crc(struct xfs_mount *, struct xfs_dinode *);
41void xfs_dinode_to_disk(struct xfs_dinode *to, struct xfs_icdinode *from); 70void xfs_inode_to_disk(struct xfs_inode *ip, struct xfs_dinode *to,
42void xfs_dinode_from_disk(struct xfs_icdinode *to, struct xfs_dinode *from); 71 xfs_lsn_t lsn);
72void xfs_inode_from_disk(struct xfs_inode *ip, struct xfs_dinode *from);
73void 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)
45void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *); 77void 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
35kmem_zone_t *xfs_ifork_zone; 36kmem_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 */
366typedef struct xfs_icdinode { 367struct 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
412static inline uint xfs_icdinode_size(int version) 413static 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 */
49static void
50xfs_rtbuf_verify_read(
51 struct xfs_buf *bp)
52{
53 return;
54}
55
56static void
57xfs_rtbuf_verify_write(
58 struct xfs_buf *bp)
59{
60 return;
61}
62
63const 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,
27extern void xfs_perag_put(struct xfs_perag *pag); 27extern void xfs_perag_put(struct xfs_perag *pag);
28extern int xfs_initialize_perag_data(struct xfs_mount *, xfs_agnumber_t); 28extern int xfs_initialize_perag_data(struct xfs_mount *, xfs_agnumber_t);
29 29
30extern void xfs_sb_calc_crc(struct xfs_buf *bp);
31extern void xfs_log_sb(struct xfs_trans *tp); 30extern void xfs_log_sb(struct xfs_trans *tp);
32extern int xfs_sync_sb(struct xfs_mount *mp, bool wait); 31extern int xfs_sync_sb(struct xfs_mount *mp, bool wait);
33extern void xfs_sb_mount_common(struct xfs_mount *mp, struct xfs_sb *sbp); 32extern 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;
53extern const struct xfs_buf_ops xfs_sb_buf_ops; 53extern const struct xfs_buf_ops xfs_sb_buf_ops;
54extern const struct xfs_buf_ops xfs_sb_quiet_buf_ops; 54extern const struct xfs_buf_ops xfs_sb_quiet_buf_ops;
55extern const struct xfs_buf_ops xfs_symlink_buf_ops; 55extern const struct xfs_buf_ops xfs_symlink_buf_ops;
56extern 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