Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'xfs-for-linus-v3.14-rc1' of git://oss.sgi.com/xfs/xfs

Pull xfs update from Ben Myers:
"This is primarily bug fixes, many of which you already have. New
stuff includes a series to decouple the in-memory and on-disk log
format, helpers in the area of inode clusters, and i_version handling.

We decided to try to use more topic branches this release, so there
are some merge commits in there on account of that. I'm afraid I
didn't do a good job of putting meaningful comments in the first
couple of merges. Sorry about that. I think I have the hang of it
now.

For 3.14-rc1 there are fixes in the areas of remote attributes,
discard, growfs, memory leaks in recovery, directory v2, quotas, the
MAINTAINERS file, allocation alignment, extent list locking, and in
xfs_bmapi_allocate. There are cleanups in xfs_setsize_buftarg,
removing unused macros, quotas, setattr, and freeing of inode
clusters. The in-memory and on-disk log format have been decoupled, a
common helper to calculate the number of blocks in an inode cluster
has been added, and handling of i_version has been pulled into the
filesystems that use it.

- cleanup in xfs_setsize_buftarg
- removal of remaining unused flags for vop toss/flush/flushinval
- fix for memory corruption in xfs_attrlist_by_handle
- fix for out-of-date comment in xfs_trans_dqlockedjoin
- fix for discard if range length is less than one block
- fix for overrun of agfl buffer using growfs on v4 superblock
filesystems
- pull i_version handling out into the filesystems that use it
- don't leak recovery items on error
- fix for memory leak in xfs_dir2_node_removename
- several cleanups for quotas
- fix bad assertion in xfs_qm_vop_create_dqattach
- cleanup for xfs_setattr_mode, and add xfs_setattr_time
- fix quota assert in xfs_setattr_nonsize
- fix an infinite loop when turning off group/project quota before
user quota
- fix for temporary buffer allocation failure in xfs_dir2_block_to_sf
with large directory block sizes
- fix Dave's email address in MAINTAINERS
- cleanup calculation of freed inode cluster blocks
- fix alignment of initial file allocations to match filesystem
geometry
- decouple in-memory and on-disk log format
- introduce a common helper to calculate the number of filesystem
blocks in an inode cluster
- fixes for extent list locking
- fix for off-by-one in xfs_attr3_rmt_verify
- fix for missing destroy_work_on_stack in xfs_bmapi_allocate"

* tag 'xfs-for-linus-v3.14-rc1' of git://oss.sgi.com/xfs/xfs: (51 commits)
xfs: Calling destroy_work_on_stack() to pair with INIT_WORK_ONSTACK()
xfs: fix off-by-one error in xfs_attr3_rmt_verify
xfs: assert that we hold the ilock for extent map access
xfs: use xfs_ilock_attr_map_shared in xfs_attr_list_int
xfs: use xfs_ilock_attr_map_shared in xfs_attr_get
xfs: use xfs_ilock_data_map_shared in xfs_qm_dqiterate
xfs: use xfs_ilock_data_map_shared in xfs_qm_dqtobp
xfs: take the ilock around xfs_bmapi_read in xfs_zero_remaining_bytes
xfs: reinstate the ilock in xfs_readdir
xfs: add xfs_ilock_attr_map_shared
xfs: rename xfs_ilock_map_shared
xfs: remove xfs_iunlock_map_shared
xfs: no need to lock the inode in xfs_find_handle
xfs: use xfs_icluster_size_fsb in xfs_imap
xfs: use xfs_icluster_size_fsb in xfs_ifree_cluster
xfs: use xfs_icluster_size_fsb in xfs_ialloc_inode_init
xfs: use xfs_icluster_size_fsb in xfs_bulkstat
xfs: introduce a common helper xfs_icluster_size_fsb
xfs: get rid of XFS_IALLOC_BLOCKS macros
xfs: get rid of XFS_INODE_CLUSTER_SIZE macros
...

+663 -766
-5
fs/attr.c
··· 202 202 return -EPERM; 203 203 } 204 204 205 - if ((ia_valid & ATTR_SIZE) && IS_I_VERSION(inode)) { 206 - if (attr->ia_size != inode->i_size) 207 - inode_inc_iversion(inode); 208 - } 209 - 210 205 if ((ia_valid & ATTR_MODE)) { 211 206 umode_t amode = attr->ia_mode; 212 207 /* Flag setting protected by i_mutex */
+6 -2
fs/btrfs/inode.c
··· 4354 4354 * these flags set. For all other operations the VFS set these flags 4355 4355 * explicitly if it wants a timestamp update. 4356 4356 */ 4357 - if (newsize != oldsize && (!(mask & (ATTR_CTIME | ATTR_MTIME)))) 4358 - inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb); 4357 + if (newsize != oldsize) { 4358 + inode_inc_iversion(inode); 4359 + if (!(mask & (ATTR_CTIME | ATTR_MTIME))) 4360 + inode->i_ctime = inode->i_mtime = 4361 + current_fs_time(inode->i_sb); 4362 + } 4359 4363 4360 4364 if (newsize > oldsize) { 4361 4365 truncate_pagecache(inode, newsize);
+4
fs/ext4/inode.c
··· 4586 4586 if (attr->ia_size > sbi->s_bitmap_maxbytes) 4587 4587 return -EFBIG; 4588 4588 } 4589 + 4590 + if (IS_I_VERSION(inode) && attr->ia_size != inode->i_size) 4591 + inode_inc_iversion(inode); 4592 + 4589 4593 if (S_ISREG(inode->i_mode) && 4590 4594 (attr->ia_size < inode->i_size)) { 4591 4595 if (ext4_should_order_data(inode)) {
+1 -1
fs/xfs/xfs_aops.c
··· 1217 1217 lockmode = XFS_ILOCK_EXCL; 1218 1218 xfs_ilock(ip, lockmode); 1219 1219 } else { 1220 - lockmode = xfs_ilock_map_shared(ip); 1220 + lockmode = xfs_ilock_data_map_shared(ip); 1221 1221 } 1222 1222 1223 1223 ASSERT(offset <= mp->m_super->s_maxbytes);
+3 -2
fs/xfs/xfs_attr.c
··· 164 164 { 165 165 int error; 166 166 struct xfs_name xname; 167 + uint lock_mode; 167 168 168 169 XFS_STATS_INC(xs_attr_get); 169 170 ··· 175 174 if (error) 176 175 return error; 177 176 178 - xfs_ilock(ip, XFS_ILOCK_SHARED); 177 + lock_mode = xfs_ilock_attr_map_shared(ip); 179 178 error = xfs_attr_get_int(ip, &xname, value, valuelenp, flags); 180 - xfs_iunlock(ip, XFS_ILOCK_SHARED); 179 + xfs_iunlock(ip, lock_mode); 181 180 return(error); 182 181 } 183 182
+3 -5
fs/xfs/xfs_attr_list.c
··· 507 507 { 508 508 int error; 509 509 xfs_inode_t *dp = context->dp; 510 + uint lock_mode; 510 511 511 512 XFS_STATS_INC(xs_attr_list); 512 513 513 514 if (XFS_FORCED_SHUTDOWN(dp->i_mount)) 514 515 return EIO; 515 516 516 - xfs_ilock(dp, XFS_ILOCK_SHARED); 517 - 518 517 /* 519 518 * Decide on what work routines to call based on the inode size. 520 519 */ 520 + lock_mode = xfs_ilock_attr_map_shared(dp); 521 521 if (!xfs_inode_hasattr(dp)) { 522 522 error = 0; 523 523 } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { ··· 527 527 } else { 528 528 error = xfs_attr_node_list(context); 529 529 } 530 - 531 - xfs_iunlock(dp, XFS_ILOCK_SHARED); 532 - 530 + xfs_iunlock(dp, lock_mode); 533 531 return error; 534 532 } 535 533
+4
fs/xfs/xfs_bmap.c
··· 4013 4013 ASSERT(*nmap >= 1); 4014 4014 ASSERT(!(flags & ~(XFS_BMAPI_ATTRFORK|XFS_BMAPI_ENTIRE| 4015 4015 XFS_BMAPI_IGSTATE))); 4016 + ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED|XFS_ILOCK_EXCL)); 4016 4017 4017 4018 if (unlikely(XFS_TEST_ERROR( 4018 4019 (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && ··· 4208 4207 ASSERT(*nmap >= 1); 4209 4208 ASSERT(*nmap <= XFS_BMAP_MAX_NMAP); 4210 4209 ASSERT(!(flags & ~XFS_BMAPI_ENTIRE)); 4210 + ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 4211 4211 4212 4212 if (unlikely(XFS_TEST_ERROR( 4213 4213 (XFS_IFORK_FORMAT(ip, XFS_DATA_FORK) != XFS_DINODE_FMT_EXTENTS && ··· 4502 4500 ASSERT(tp != NULL); 4503 4501 ASSERT(len > 0); 4504 4502 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL); 4503 + ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 4505 4504 4506 4505 if (unlikely(XFS_TEST_ERROR( 4507 4506 (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && ··· 5054 5051 if (XFS_FORCED_SHUTDOWN(mp)) 5055 5052 return XFS_ERROR(EIO); 5056 5053 5054 + ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 5057 5055 ASSERT(len > 0); 5058 5056 ASSERT(nexts >= 0); 5059 5057
+24 -13
fs/xfs/xfs_bmap_util.c
··· 618 618 return XFS_ERROR(ENOMEM); 619 619 620 620 xfs_ilock(ip, XFS_IOLOCK_SHARED); 621 - if (whichfork == XFS_DATA_FORK && !(iflags & BMV_IF_DELALLOC)) { 622 - if (ip->i_delayed_blks || XFS_ISIZE(ip) > ip->i_d.di_size) { 621 + if (whichfork == XFS_DATA_FORK) { 622 + if (!(iflags & BMV_IF_DELALLOC) && 623 + (ip->i_delayed_blks || XFS_ISIZE(ip) > ip->i_d.di_size)) { 623 624 error = -filemap_write_and_wait(VFS_I(ip)->i_mapping); 624 625 if (error) 625 626 goto out_unlock_iolock; 626 - } 627 - /* 628 - * even after flushing the inode, there can still be delalloc 629 - * blocks on the inode beyond EOF due to speculative 630 - * preallocation. These are not removed until the release 631 - * function is called or the inode is inactivated. Hence we 632 - * cannot assert here that ip->i_delayed_blks == 0. 633 - */ 634 - } 635 627 636 - lock = xfs_ilock_map_shared(ip); 628 + /* 629 + * Even after flushing the inode, there can still be 630 + * delalloc blocks on the inode beyond EOF due to 631 + * speculative preallocation. These are not removed 632 + * until the release function is called or the inode 633 + * is inactivated. Hence we cannot assert here that 634 + * ip->i_delayed_blks == 0. 635 + */ 636 + } 637 + 638 + lock = xfs_ilock_data_map_shared(ip); 639 + } else { 640 + lock = xfs_ilock_attr_map_shared(ip); 641 + } 637 642 638 643 /* 639 644 * Don't let nex be bigger than the number of extents ··· 743 738 out_free_map: 744 739 kmem_free(map); 745 740 out_unlock_ilock: 746 - xfs_iunlock_map_shared(ip, lock); 741 + xfs_iunlock(ip, lock); 747 742 out_unlock_iolock: 748 743 xfs_iunlock(ip, XFS_IOLOCK_SHARED); 749 744 ··· 1174 1169 xfs_buf_unlock(bp); 1175 1170 1176 1171 for (offset = startoff; offset <= endoff; offset = lastoffset + 1) { 1172 + uint lock_mode; 1173 + 1177 1174 offset_fsb = XFS_B_TO_FSBT(mp, offset); 1178 1175 nimap = 1; 1176 + 1177 + lock_mode = xfs_ilock_data_map_shared(ip); 1179 1178 error = xfs_bmapi_read(ip, offset_fsb, 1, &imap, &nimap, 0); 1179 + xfs_iunlock(ip, lock_mode); 1180 + 1180 1181 if (error || nimap < 1) 1181 1182 break; 1182 1183 ASSERT(imap.br_blockcount >= 1);
+8 -18
fs/xfs/xfs_buf.c
··· 1593 1593 kmem_free(btp); 1594 1594 } 1595 1595 1596 - STATIC int 1597 - xfs_setsize_buftarg_flags( 1596 + int 1597 + xfs_setsize_buftarg( 1598 1598 xfs_buftarg_t *btp, 1599 1599 unsigned int blocksize, 1600 - unsigned int sectorsize, 1601 - int verbose) 1600 + unsigned int sectorsize) 1602 1601 { 1603 1602 btp->bt_bsize = blocksize; 1604 1603 btp->bt_sshift = ffs(sectorsize) - 1; ··· 1618 1619 } 1619 1620 1620 1621 /* 1621 - * When allocating the initial buffer target we have not yet 1622 - * read in the superblock, so don't know what sized sectors 1623 - * are being used at this early stage. Play safe. 1622 + * When allocating the initial buffer target we have not yet 1623 + * read in the superblock, so don't know what sized sectors 1624 + * are being used at this early stage. Play safe. 1624 1625 */ 1625 1626 STATIC int 1626 1627 xfs_setsize_buftarg_early( 1627 1628 xfs_buftarg_t *btp, 1628 1629 struct block_device *bdev) 1629 1630 { 1630 - return xfs_setsize_buftarg_flags(btp, 1631 - PAGE_SIZE, bdev_logical_block_size(bdev), 0); 1632 - } 1633 - 1634 - int 1635 - xfs_setsize_buftarg( 1636 - xfs_buftarg_t *btp, 1637 - unsigned int blocksize, 1638 - unsigned int sectorsize) 1639 - { 1640 - return xfs_setsize_buftarg_flags(btp, blocksize, sectorsize, 1); 1631 + return xfs_setsize_buftarg(btp, PAGE_SIZE, 1632 + bdev_logical_block_size(bdev)); 1641 1633 } 1642 1634 1643 1635 xfs_buftarg_t *
+51 -52
fs/xfs/xfs_buf_item.c
··· 182 182 trace_xfs_buf_item_size(bip); 183 183 } 184 184 185 - static struct xfs_log_iovec * 185 + static inline void 186 + xfs_buf_item_copy_iovec( 187 + struct xfs_log_vec *lv, 188 + struct xfs_log_iovec **vecp, 189 + struct xfs_buf *bp, 190 + uint offset, 191 + int first_bit, 192 + uint nbits) 193 + { 194 + offset += first_bit * XFS_BLF_CHUNK; 195 + xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_BCHUNK, 196 + xfs_buf_offset(bp, offset), 197 + nbits * XFS_BLF_CHUNK); 198 + } 199 + 200 + static inline bool 201 + xfs_buf_item_straddle( 202 + struct xfs_buf *bp, 203 + uint offset, 204 + int next_bit, 205 + int last_bit) 206 + { 207 + return xfs_buf_offset(bp, offset + (next_bit << XFS_BLF_SHIFT)) != 208 + (xfs_buf_offset(bp, offset + (last_bit << XFS_BLF_SHIFT)) + 209 + XFS_BLF_CHUNK); 210 + } 211 + 212 + static void 186 213 xfs_buf_item_format_segment( 187 214 struct xfs_buf_log_item *bip, 188 - struct xfs_log_iovec *vecp, 215 + struct xfs_log_vec *lv, 216 + struct xfs_log_iovec **vecp, 189 217 uint offset, 190 218 struct xfs_buf_log_format *blfp) 191 219 { 192 220 struct xfs_buf *bp = bip->bli_buf; 193 221 uint base_size; 194 - uint nvecs; 195 222 int first_bit; 196 223 int last_bit; 197 224 int next_bit; 198 225 uint nbits; 199 - uint buffer_offset; 200 226 201 227 /* copy the flags across from the base format item */ 202 228 blfp->blf_flags = bip->__bli_format.blf_flags; ··· 234 208 */ 235 209 base_size = xfs_buf_log_format_size(blfp); 236 210 237 - nvecs = 0; 238 211 first_bit = xfs_next_bit(blfp->blf_data_map, blfp->blf_map_size, 0); 239 212 if (!(bip->bli_flags & XFS_BLI_STALE) && first_bit == -1) { 240 213 /* 241 214 * If the map is not be dirty in the transaction, mark 242 215 * the size as zero and do not advance the vector pointer. 243 216 */ 244 - goto out; 217 + return; 245 218 } 246 219 247 - vecp->i_addr = blfp; 248 - vecp->i_len = base_size; 249 - vecp->i_type = XLOG_REG_TYPE_BFORMAT; 250 - vecp++; 251 - nvecs = 1; 220 + blfp = xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_BFORMAT, blfp, base_size); 221 + blfp->blf_size = 1; 252 222 253 223 if (bip->bli_flags & XFS_BLI_STALE) { 254 224 /* ··· 254 232 */ 255 233 trace_xfs_buf_item_format_stale(bip); 256 234 ASSERT(blfp->blf_flags & XFS_BLF_CANCEL); 257 - goto out; 235 + return; 258 236 } 259 237 260 238 261 239 /* 262 240 * Fill in an iovec for each set of contiguous chunks. 263 241 */ 264 - 265 242 last_bit = first_bit; 266 243 nbits = 1; 267 244 for (;;) { ··· 273 252 next_bit = xfs_next_bit(blfp->blf_data_map, blfp->blf_map_size, 274 253 (uint)last_bit + 1); 275 254 /* 276 - * If we run out of bits fill in the last iovec and get 277 - * out of the loop. 278 - * Else if we start a new set of bits then fill in the 279 - * iovec for the series we were looking at and start 280 - * counting the bits in the new one. 281 - * Else we're still in the same set of bits so just 282 - * keep counting and scanning. 255 + * If we run out of bits fill in the last iovec and get out of 256 + * the loop. Else if we start a new set of bits then fill in 257 + * the iovec for the series we were looking at and start 258 + * counting the bits in the new one. Else we're still in the 259 + * same set of bits so just keep counting and scanning. 283 260 */ 284 261 if (next_bit == -1) { 285 - buffer_offset = offset + first_bit * XFS_BLF_CHUNK; 286 - vecp->i_addr = xfs_buf_offset(bp, buffer_offset); 287 - vecp->i_len = nbits * XFS_BLF_CHUNK; 288 - vecp->i_type = XLOG_REG_TYPE_BCHUNK; 289 - nvecs++; 262 + xfs_buf_item_copy_iovec(lv, vecp, bp, offset, 263 + first_bit, nbits); 264 + blfp->blf_size++; 290 265 break; 291 - } else if (next_bit != last_bit + 1) { 292 - buffer_offset = offset + first_bit * XFS_BLF_CHUNK; 293 - vecp->i_addr = xfs_buf_offset(bp, buffer_offset); 294 - vecp->i_len = nbits * XFS_BLF_CHUNK; 295 - vecp->i_type = XLOG_REG_TYPE_BCHUNK; 296 - nvecs++; 297 - vecp++; 298 - first_bit = next_bit; 299 - last_bit = next_bit; 300 - nbits = 1; 301 - } else if (xfs_buf_offset(bp, offset + 302 - (next_bit << XFS_BLF_SHIFT)) != 303 - (xfs_buf_offset(bp, offset + 304 - (last_bit << XFS_BLF_SHIFT)) + 305 - XFS_BLF_CHUNK)) { 306 - buffer_offset = offset + first_bit * XFS_BLF_CHUNK; 307 - vecp->i_addr = xfs_buf_offset(bp, buffer_offset); 308 - vecp->i_len = nbits * XFS_BLF_CHUNK; 309 - vecp->i_type = XLOG_REG_TYPE_BCHUNK; 310 - nvecs++; 311 - vecp++; 266 + } else if (next_bit != last_bit + 1 || 267 + xfs_buf_item_straddle(bp, offset, next_bit, last_bit)) { 268 + xfs_buf_item_copy_iovec(lv, vecp, bp, offset, 269 + first_bit, nbits); 270 + blfp->blf_size++; 312 271 first_bit = next_bit; 313 272 last_bit = next_bit; 314 273 nbits = 1; ··· 297 296 nbits++; 298 297 } 299 298 } 300 - out: 301 - blfp->blf_size = nvecs; 302 - return vecp; 303 299 } 304 300 305 301 /* ··· 308 310 STATIC void 309 311 xfs_buf_item_format( 310 312 struct xfs_log_item *lip, 311 - struct xfs_log_iovec *vecp) 313 + struct xfs_log_vec *lv) 312 314 { 313 315 struct xfs_buf_log_item *bip = BUF_ITEM(lip); 314 316 struct xfs_buf *bp = bip->bli_buf; 317 + struct xfs_log_iovec *vecp = NULL; 315 318 uint offset = 0; 316 319 int i; 317 320 ··· 353 354 } 354 355 355 356 for (i = 0; i < bip->bli_format_count; i++) { 356 - vecp = xfs_buf_item_format_segment(bip, vecp, offset, 357 - &bip->bli_formats[i]); 357 + xfs_buf_item_format_segment(bip, lv, &vecp, offset, 358 + &bip->bli_formats[i]); 358 359 offset += bp->b_maps[i].bm_len; 359 360 } 360 361
+4
fs/xfs/xfs_dir2_readdir.c
··· 674 674 { 675 675 int rval; /* return value */ 676 676 int v; /* type-checking value */ 677 + uint lock_mode; 677 678 678 679 trace_xfs_readdir(dp); 679 680 ··· 684 683 ASSERT(S_ISDIR(dp->i_d.di_mode)); 685 684 XFS_STATS_INC(xs_dir_getdents); 686 685 686 + lock_mode = xfs_ilock_data_map_shared(dp); 687 687 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 688 688 rval = xfs_dir2_sf_getdents(dp, ctx); 689 689 else if ((rval = xfs_dir2_isblock(NULL, dp, &v))) ··· 693 691 rval = xfs_dir2_block_getdents(dp, ctx); 694 692 else 695 693 rval = xfs_dir2_leaf_getdents(dp, ctx, bufsize); 694 + xfs_iunlock(dp, lock_mode); 695 + 696 696 return rval; 697 697 }
+34 -24
fs/xfs/xfs_dir2_sf.c
··· 170 170 char *ptr; /* current data pointer */ 171 171 xfs_dir2_sf_entry_t *sfep; /* shortform entry */ 172 172 xfs_dir2_sf_hdr_t *sfp; /* shortform directory header */ 173 + xfs_dir2_sf_hdr_t *dst; /* temporary data buffer */ 173 174 174 175 trace_xfs_dir2_block_to_sf(args); 175 176 ··· 178 177 mp = dp->i_mount; 179 178 180 179 /* 181 - * Make a copy of the block data, so we can shrink the inode 182 - * and add local data. 180 + * allocate a temporary destination buffer the size of the inode 181 + * to format the data into. Once we have formatted the data, we 182 + * can free the block and copy the formatted data into the inode literal 183 + * area. 183 184 */ 184 - hdr = kmem_alloc(mp->m_dirblksize, KM_SLEEP); 185 - memcpy(hdr, bp->b_addr, mp->m_dirblksize); 186 - logflags = XFS_ILOG_CORE; 187 - if ((error = xfs_dir2_shrink_inode(args, mp->m_dirdatablk, bp))) { 188 - ASSERT(error != ENOSPC); 189 - goto out; 190 - } 185 + dst = kmem_alloc(mp->m_sb.sb_inodesize, KM_SLEEP); 186 + hdr = bp->b_addr; 191 187 192 - /* 193 - * The buffer is now unconditionally gone, whether 194 - * xfs_dir2_shrink_inode worked or not. 195 - * 196 - * Convert the inode to local format. 197 - */ 198 - dp->i_df.if_flags &= ~XFS_IFEXTENTS; 199 - dp->i_df.if_flags |= XFS_IFINLINE; 200 - dp->i_d.di_format = XFS_DINODE_FMT_LOCAL; 201 - ASSERT(dp->i_df.if_bytes == 0); 202 - xfs_idata_realloc(dp, size, XFS_DATA_FORK); 203 - logflags |= XFS_ILOG_DDATA; 204 188 /* 205 189 * Copy the header into the newly allocate local space. 206 190 */ 207 - sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; 191 + sfp = (xfs_dir2_sf_hdr_t *)dst; 208 192 memcpy(sfp, sfhp, xfs_dir2_sf_hdr_size(sfhp->i8count)); 209 - dp->i_d.di_size = size; 193 + 210 194 /* 211 195 * Set up to loop over the block's entries. 212 196 */ ··· 244 258 ptr += dp->d_ops->data_entsize(dep->namelen); 245 259 } 246 260 ASSERT((char *)sfep - (char *)sfp == size); 261 + 262 + /* now we are done with the block, we can shrink the inode */ 263 + logflags = XFS_ILOG_CORE; 264 + error = xfs_dir2_shrink_inode(args, mp->m_dirdatablk, bp); 265 + if (error) { 266 + ASSERT(error != ENOSPC); 267 + goto out; 268 + } 269 + 270 + /* 271 + * The buffer is now unconditionally gone, whether 272 + * xfs_dir2_shrink_inode worked or not. 273 + * 274 + * Convert the inode to local format and copy the data in. 275 + */ 276 + dp->i_df.if_flags &= ~XFS_IFEXTENTS; 277 + dp->i_df.if_flags |= XFS_IFINLINE; 278 + dp->i_d.di_format = XFS_DINODE_FMT_LOCAL; 279 + ASSERT(dp->i_df.if_bytes == 0); 280 + xfs_idata_realloc(dp, size, XFS_DATA_FORK); 281 + 282 + logflags |= XFS_ILOG_DDATA; 283 + memcpy(dp->i_df.if_u1.if_data, dst, size); 284 + dp->i_d.di_size = size; 247 285 xfs_dir2_sf_check(args); 248 286 out: 249 287 xfs_trans_log_inode(args->trans, dp, logflags); 250 - kmem_free(hdr); 288 + kmem_free(dst); 251 289 return error; 252 290 } 253 291
+4 -3
fs/xfs/xfs_dquot.c
··· 469 469 struct xfs_mount *mp = dqp->q_mount; 470 470 xfs_dqid_t id = be32_to_cpu(dqp->q_core.d_id); 471 471 struct xfs_trans *tp = (tpp ? *tpp : NULL); 472 + uint lock_mode; 472 473 473 474 dqp->q_fileoffset = (xfs_fileoff_t)id / mp->m_quotainfo->qi_dqperchunk; 474 475 475 - xfs_ilock(quotip, XFS_ILOCK_SHARED); 476 + lock_mode = xfs_ilock_data_map_shared(quotip); 476 477 if (!xfs_this_quota_on(dqp->q_mount, dqp->dq_flags)) { 477 478 /* 478 479 * Return if this type of quotas is turned off while we 479 480 * didn't have the quota inode lock. 480 481 */ 481 - xfs_iunlock(quotip, XFS_ILOCK_SHARED); 482 + xfs_iunlock(quotip, lock_mode); 482 483 return ESRCH; 483 484 } 484 485 ··· 489 488 error = xfs_bmapi_read(quotip, dqp->q_fileoffset, 490 489 XFS_DQUOT_CLUSTER_SIZE_FSB, &map, &nmaps, 0); 491 490 492 - xfs_iunlock(quotip, XFS_ILOCK_SHARED); 491 + xfs_iunlock(quotip, lock_mode); 493 492 if (error) 494 493 return error; 495 494
+23 -38
fs/xfs/xfs_dquot_item.c
··· 57 57 STATIC void 58 58 xfs_qm_dquot_logitem_format( 59 59 struct xfs_log_item *lip, 60 - struct xfs_log_iovec *logvec) 60 + struct xfs_log_vec *lv) 61 61 { 62 62 struct xfs_dq_logitem *qlip = DQUOT_ITEM(lip); 63 + struct xfs_log_iovec *vecp = NULL; 64 + struct xfs_dq_logformat *qlf; 63 65 64 - logvec->i_addr = &qlip->qli_format; 65 - logvec->i_len = sizeof(xfs_dq_logformat_t); 66 - logvec->i_type = XLOG_REG_TYPE_QFORMAT; 67 - logvec++; 68 - logvec->i_addr = &qlip->qli_dquot->q_core; 69 - logvec->i_len = sizeof(xfs_disk_dquot_t); 70 - logvec->i_type = XLOG_REG_TYPE_DQUOT; 66 + qlf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_QFORMAT); 67 + qlf->qlf_type = XFS_LI_DQUOT; 68 + qlf->qlf_size = 2; 69 + qlf->qlf_id = be32_to_cpu(qlip->qli_dquot->q_core.d_id); 70 + qlf->qlf_blkno = qlip->qli_dquot->q_blkno; 71 + qlf->qlf_len = 1; 72 + qlf->qlf_boffset = qlip->qli_dquot->q_bufoffset; 73 + xlog_finish_iovec(lv, vecp, sizeof(struct xfs_dq_logformat)); 71 74 72 - qlip->qli_format.qlf_size = 2; 73 - 75 + xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_DQUOT, 76 + &qlip->qli_dquot->q_core, 77 + sizeof(struct xfs_disk_dquot)); 74 78 } 75 79 76 80 /* ··· 261 257 xfs_log_item_init(dqp->q_mount, &lp->qli_item, XFS_LI_DQUOT, 262 258 &xfs_dquot_item_ops); 263 259 lp->qli_dquot = dqp; 264 - lp->qli_format.qlf_type = XFS_LI_DQUOT; 265 - lp->qli_format.qlf_id = be32_to_cpu(dqp->q_core.d_id); 266 - lp->qli_format.qlf_blkno = dqp->q_blkno; 267 - lp->qli_format.qlf_len = 1; 268 - /* 269 - * This is just the offset of this dquot within its buffer 270 - * (which is currently 1 FSB and probably won't change). 271 - * Hence 32 bits for this offset should be just fine. 272 - * Alternatively, we can store (bufoffset / sizeof(xfs_dqblk_t)) 273 - * here, and recompute it at recovery time. 274 - */ 275 - lp->qli_format.qlf_boffset = (__uint32_t)dqp->q_bufoffset; 276 260 } 277 261 278 262 /*------------------ QUOTAOFF LOG ITEMS -------------------*/ ··· 286 294 *nbytes += sizeof(struct xfs_qoff_logitem); 287 295 } 288 296 289 - /* 290 - * This is called to fill in the vector of log iovecs for the 291 - * given quotaoff log item. We use only 1 iovec, and we point that 292 - * at the quotaoff_log_format structure embedded in the quotaoff item. 293 - * It is at this point that we assert that all of the extent 294 - * slots in the quotaoff item have been filled. 295 - */ 296 297 STATIC void 297 298 xfs_qm_qoff_logitem_format( 298 299 struct xfs_log_item *lip, 299 - struct xfs_log_iovec *log_vector) 300 + struct xfs_log_vec *lv) 300 301 { 301 302 struct xfs_qoff_logitem *qflip = QOFF_ITEM(lip); 303 + struct xfs_log_iovec *vecp = NULL; 304 + struct xfs_qoff_logformat *qlf; 302 305 303 - ASSERT(qflip->qql_format.qf_type == XFS_LI_QUOTAOFF); 304 - 305 - log_vector->i_addr = &qflip->qql_format; 306 - log_vector->i_len = sizeof(xfs_qoff_logitem_t); 307 - log_vector->i_type = XLOG_REG_TYPE_QUOTAOFF; 308 - qflip->qql_format.qf_size = 1; 306 + qlf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_QUOTAOFF); 307 + qlf->qf_type = XFS_LI_QUOTAOFF; 308 + qlf->qf_size = 1; 309 + qlf->qf_flags = qflip->qql_flags; 310 + xlog_finish_iovec(lv, vecp, sizeof(struct xfs_qoff_logitem)); 309 311 } 310 312 311 313 /* ··· 439 453 xfs_log_item_init(mp, &qf->qql_item, XFS_LI_QUOTAOFF, start ? 440 454 &xfs_qm_qoffend_logitem_ops : &xfs_qm_qoff_logitem_ops); 441 455 qf->qql_item.li_mountp = mp; 442 - qf->qql_format.qf_type = XFS_LI_QUOTAOFF; 443 - qf->qql_format.qf_flags = flags; 444 456 qf->qql_start_lip = start; 457 + qf->qql_flags = flags; 445 458 return qf; 446 459 }
+1 -2
fs/xfs/xfs_dquot_item.h
··· 27 27 xfs_log_item_t qli_item; /* common portion */ 28 28 struct xfs_dquot *qli_dquot; /* dquot ptr */ 29 29 xfs_lsn_t qli_flush_lsn; /* lsn at last flush */ 30 - xfs_dq_logformat_t qli_format; /* logged structure */ 31 30 } xfs_dq_logitem_t; 32 31 33 32 typedef struct xfs_qoff_logitem { 34 33 xfs_log_item_t qql_item; /* common portion */ 35 34 struct xfs_qoff_logitem *qql_start_lip; /* qoff-start logitem, if any */ 36 - xfs_qoff_logformat_t qql_format; /* logged structure */ 35 + unsigned int qql_flags; 37 36 } xfs_qoff_logitem_t; 38 37 39 38
+11 -10
fs/xfs/xfs_extfree_item.c
··· 26 26 #include "xfs_trans_priv.h" 27 27 #include "xfs_buf_item.h" 28 28 #include "xfs_extfree_item.h" 29 + #include "xfs_log.h" 29 30 30 31 31 32 kmem_zone_t *xfs_efi_zone; ··· 102 101 STATIC void 103 102 xfs_efi_item_format( 104 103 struct xfs_log_item *lip, 105 - struct xfs_log_iovec *log_vector) 104 + struct xfs_log_vec *lv) 106 105 { 107 106 struct xfs_efi_log_item *efip = EFI_ITEM(lip); 107 + struct xfs_log_iovec *vecp = NULL; 108 108 109 109 ASSERT(atomic_read(&efip->efi_next_extent) == 110 110 efip->efi_format.efi_nextents); ··· 113 111 efip->efi_format.efi_type = XFS_LI_EFI; 114 112 efip->efi_format.efi_size = 1; 115 113 116 - log_vector->i_addr = &efip->efi_format; 117 - log_vector->i_len = xfs_efi_item_sizeof(efip); 118 - log_vector->i_type = XLOG_REG_TYPE_EFI_FORMAT; 119 - ASSERT(log_vector->i_len >= sizeof(xfs_efi_log_format_t)); 114 + xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_EFI_FORMAT, 115 + &efip->efi_format, 116 + xfs_efi_item_sizeof(efip)); 120 117 } 121 118 122 119 ··· 369 368 STATIC void 370 369 xfs_efd_item_format( 371 370 struct xfs_log_item *lip, 372 - struct xfs_log_iovec *log_vector) 371 + struct xfs_log_vec *lv) 373 372 { 374 373 struct xfs_efd_log_item *efdp = EFD_ITEM(lip); 374 + struct xfs_log_iovec *vecp = NULL; 375 375 376 376 ASSERT(efdp->efd_next_extent == efdp->efd_format.efd_nextents); 377 377 378 378 efdp->efd_format.efd_type = XFS_LI_EFD; 379 379 efdp->efd_format.efd_size = 1; 380 380 381 - log_vector->i_addr = &efdp->efd_format; 382 - log_vector->i_len = xfs_efd_item_sizeof(efdp); 383 - log_vector->i_type = XLOG_REG_TYPE_EFD_FORMAT; 384 - ASSERT(log_vector->i_len >= sizeof(xfs_efd_log_format_t)); 381 + xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_EFD_FORMAT, 382 + &efdp->efd_format, 383 + xfs_efd_item_sizeof(efdp)); 385 384 } 386 385 387 386 /*
+5 -5
fs/xfs/xfs_file.c
··· 912 912 * If there are any blocks, read-ahead block 0 as we're almost 913 913 * certain to have the next operation be a read there. 914 914 */ 915 - mode = xfs_ilock_map_shared(ip); 915 + mode = xfs_ilock_data_map_shared(ip); 916 916 if (ip->i_d.di_nextents > 0) 917 917 xfs_dir3_data_readahead(NULL, ip, 0, -1); 918 918 xfs_iunlock(ip, mode); ··· 1215 1215 uint lock; 1216 1216 int error; 1217 1217 1218 - lock = xfs_ilock_map_shared(ip); 1218 + lock = xfs_ilock_data_map_shared(ip); 1219 1219 1220 1220 isize = i_size_read(inode); 1221 1221 if (start >= isize) { ··· 1294 1294 offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes); 1295 1295 1296 1296 out_unlock: 1297 - xfs_iunlock_map_shared(ip, lock); 1297 + xfs_iunlock(ip, lock); 1298 1298 1299 1299 if (error) 1300 1300 return -error; ··· 1319 1319 if (XFS_FORCED_SHUTDOWN(mp)) 1320 1320 return -XFS_ERROR(EIO); 1321 1321 1322 - lock = xfs_ilock_map_shared(ip); 1322 + lock = xfs_ilock_data_map_shared(ip); 1323 1323 1324 1324 isize = i_size_read(inode); 1325 1325 if (start >= isize) { ··· 1402 1402 offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes); 1403 1403 1404 1404 out_unlock: 1405 - xfs_iunlock_map_shared(ip, lock); 1405 + xfs_iunlock(ip, lock); 1406 1406 1407 1407 if (error) 1408 1408 return -error;
+23 -30
fs/xfs/xfs_ialloc.c
··· 52 52 { 53 53 if (xfs_sb_version_hasalign(&args->mp->m_sb) && 54 54 args->mp->m_sb.sb_inoalignmt >= 55 - XFS_B_TO_FSBT(args->mp, XFS_INODE_CLUSTER_SIZE(args->mp))) 55 + XFS_B_TO_FSBT(args->mp, args->mp->m_inode_cluster_size)) 56 56 return args->mp->m_sb.sb_inoalignmt; 57 57 return 1; 58 58 } ··· 170 170 { 171 171 struct xfs_buf *fbuf; 172 172 struct xfs_dinode *free; 173 - int blks_per_cluster, nbufs, ninodes; 173 + int nbufs, blks_per_cluster, inodes_per_cluster; 174 174 int version; 175 175 int i, j; 176 176 xfs_daddr_t d; 177 177 xfs_ino_t ino = 0; 178 178 179 179 /* 180 - * Loop over the new block(s), filling in the inodes. 181 - * For small block sizes, manipulate the inodes in buffers 182 - * which are multiples of the blocks size. 180 + * Loop over the new block(s), filling in the inodes. For small block 181 + * sizes, manipulate the inodes in buffers which are multiples of the 182 + * blocks size. 183 183 */ 184 - if (mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp)) { 185 - blks_per_cluster = 1; 186 - nbufs = length; 187 - ninodes = mp->m_sb.sb_inopblock; 188 - } else { 189 - blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) / 190 - mp->m_sb.sb_blocksize; 191 - nbufs = length / blks_per_cluster; 192 - ninodes = blks_per_cluster * mp->m_sb.sb_inopblock; 193 - } 184 + blks_per_cluster = xfs_icluster_size_fsb(mp); 185 + inodes_per_cluster = blks_per_cluster << mp->m_sb.sb_inopblog; 186 + nbufs = length / blks_per_cluster; 194 187 195 188 /* 196 189 * Figure out what version number to use in the inodes we create. If ··· 218 225 * they track in the AIL as if they were physically logged. 219 226 */ 220 227 if (tp) 221 - xfs_icreate_log(tp, agno, agbno, XFS_IALLOC_INODES(mp), 228 + xfs_icreate_log(tp, agno, agbno, mp->m_ialloc_inos, 222 229 mp->m_sb.sb_inodesize, length, gen); 223 230 } else if (xfs_sb_version_hasnlink(&mp->m_sb)) 224 231 version = 2; ··· 239 246 /* Initialize the inode buffers and log them appropriately. */ 240 247 fbuf->b_ops = &xfs_inode_buf_ops; 241 248 xfs_buf_zero(fbuf, 0, BBTOB(fbuf->b_length)); 242 - for (i = 0; i < ninodes; i++) { 249 + for (i = 0; i < inodes_per_cluster; i++) { 243 250 int ioffset = i << mp->m_sb.sb_inodelog; 244 251 uint isize = xfs_dinode_size(version); 245 252 ··· 322 329 * Locking will ensure that we don't have two callers in here 323 330 * at one time. 324 331 */ 325 - newlen = XFS_IALLOC_INODES(args.mp); 332 + newlen = args.mp->m_ialloc_inos; 326 333 if (args.mp->m_maxicount && 327 334 args.mp->m_sb.sb_icount + newlen > args.mp->m_maxicount) 328 335 return XFS_ERROR(ENOSPC); 329 - args.minlen = args.maxlen = XFS_IALLOC_BLOCKS(args.mp); 336 + args.minlen = args.maxlen = args.mp->m_ialloc_blks; 330 337 /* 331 338 * First try to allocate inodes contiguous with the last-allocated 332 339 * chunk of inodes. If the filesystem is striped, this will fill ··· 336 343 newino = be32_to_cpu(agi->agi_newino); 337 344 agno = be32_to_cpu(agi->agi_seqno); 338 345 args.agbno = XFS_AGINO_TO_AGBNO(args.mp, newino) + 339 - XFS_IALLOC_BLOCKS(args.mp); 346 + args.mp->m_ialloc_blks; 340 347 if (likely(newino != NULLAGINO && 341 348 (args.agbno < be32_to_cpu(agi->agi_length)))) { 342 349 args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno); ··· 578 585 * Is there enough free space for the file plus a block of 579 586 * inodes? (if we need to allocate some)? 580 587 */ 581 - ineed = XFS_IALLOC_BLOCKS(mp); 588 + ineed = mp->m_ialloc_blks; 582 589 longest = pag->pagf_longest; 583 590 if (!longest) 584 591 longest = pag->pagf_flcount > 0; ··· 992 999 * inode. 993 1000 */ 994 1001 if (mp->m_maxicount && 995 - mp->m_sb.sb_icount + XFS_IALLOC_INODES(mp) > mp->m_maxicount) { 1002 + mp->m_sb.sb_icount + mp->m_ialloc_inos > mp->m_maxicount) { 996 1003 noroom = 1; 997 1004 okalloc = 0; 998 1005 } ··· 1195 1202 * When an inode cluster is free, it becomes eligible for removal 1196 1203 */ 1197 1204 if (!(mp->m_flags & XFS_MOUNT_IKEEP) && 1198 - (rec.ir_freecount == XFS_IALLOC_INODES(mp))) { 1205 + (rec.ir_freecount == mp->m_ialloc_inos)) { 1199 1206 1200 1207 *delete = 1; 1201 1208 *first_ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino); ··· 1205 1212 * AGI and Superblock inode counts, and mark the disk space 1206 1213 * to be freed when the transaction is committed. 1207 1214 */ 1208 - ilen = XFS_IALLOC_INODES(mp); 1215 + ilen = mp->m_ialloc_inos; 1209 1216 be32_add_cpu(&agi->agi_count, -ilen); 1210 1217 be32_add_cpu(&agi->agi_freecount, -(ilen - 1)); 1211 1218 xfs_ialloc_log_agi(tp, agbp, XFS_AGI_COUNT | XFS_AGI_FREECOUNT); ··· 1221 1228 goto error0; 1222 1229 } 1223 1230 1224 - xfs_bmap_add_free(XFS_AGB_TO_FSB(mp, 1225 - agno, XFS_INO_TO_AGBNO(mp,rec.ir_startino)), 1226 - XFS_IALLOC_BLOCKS(mp), flist, mp); 1231 + xfs_bmap_add_free(XFS_AGB_TO_FSB(mp, agno, 1232 + XFS_AGINO_TO_AGBNO(mp, rec.ir_startino)), 1233 + mp->m_ialloc_blks, flist, mp); 1227 1234 } else { 1228 1235 *delete = 0; 1229 1236 ··· 1304 1311 1305 1312 /* check that the returned record contains the required inode */ 1306 1313 if (rec.ir_startino > agino || 1307 - rec.ir_startino + XFS_IALLOC_INODES(mp) <= agino) 1314 + rec.ir_startino + mp->m_ialloc_inos <= agino) 1308 1315 return EINVAL; 1309 1316 1310 1317 /* for untrusted inodes check it is allocated first */ ··· 1377 1384 return XFS_ERROR(EINVAL); 1378 1385 } 1379 1386 1380 - blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_blocklog; 1387 + blks_per_cluster = xfs_icluster_size_fsb(mp); 1381 1388 1382 1389 /* 1383 1390 * For bulkstat and handle lookups, we have an untrusted inode number ··· 1398 1405 * If the inode cluster size is the same as the blocksize or 1399 1406 * smaller we get to the buffer by simple arithmetics. 1400 1407 */ 1401 - if (XFS_INODE_CLUSTER_SIZE(mp) <= mp->m_sb.sb_blocksize) { 1408 + if (blks_per_cluster == 1) { 1402 1409 offset = XFS_INO_TO_OFFSET(mp, ino); 1403 1410 ASSERT(offset < mp->m_sb.sb_inopblock); 1404 1411
+11 -10
fs/xfs/xfs_ialloc.h
··· 25 25 struct xfs_trans; 26 26 struct xfs_btree_cur; 27 27 28 - /* 29 - * Allocation parameters for inode allocation. 30 - */ 31 - #define XFS_IALLOC_INODES(mp) (mp)->m_ialloc_inos 32 - #define XFS_IALLOC_BLOCKS(mp) (mp)->m_ialloc_blks 33 - 34 - /* 35 - * Move inodes in clusters of this size. 36 - */ 28 + /* Move inodes in clusters of this size */ 37 29 #define XFS_INODE_BIG_CLUSTER_SIZE 8192 38 - #define XFS_INODE_CLUSTER_SIZE(mp) (mp)->m_inode_cluster_size 30 + 31 + /* Calculate and return the number of filesystem blocks per inode cluster */ 32 + static inline int 33 + xfs_icluster_size_fsb( 34 + struct xfs_mount *mp) 35 + { 36 + if (mp->m_sb.sb_blocksize >= mp->m_inode_cluster_size) 37 + return 1; 38 + return mp->m_inode_cluster_size >> mp->m_sb.sb_blocklog; 39 + } 39 40 40 41 /* 41 42 * Make an inode pointer out of the buffer/offset.
+6 -4
fs/xfs/xfs_icreate_item.c
··· 28 28 #include "xfs_trans_priv.h" 29 29 #include "xfs_error.h" 30 30 #include "xfs_icreate_item.h" 31 + #include "xfs_log.h" 31 32 32 33 kmem_zone_t *xfs_icreate_zone; /* inode create item zone */ 33 34 ··· 59 58 STATIC void 60 59 xfs_icreate_item_format( 61 60 struct xfs_log_item *lip, 62 - struct xfs_log_iovec *log_vector) 61 + struct xfs_log_vec *lv) 63 62 { 64 63 struct xfs_icreate_item *icp = ICR_ITEM(lip); 64 + struct xfs_log_iovec *vecp = NULL; 65 65 66 - log_vector->i_addr = (xfs_caddr_t)&icp->ic_format; 67 - log_vector->i_len = sizeof(struct xfs_icreate_log); 68 - log_vector->i_type = XLOG_REG_TYPE_ICREATE; 66 + xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ICREATE, 67 + &icp->ic_format, 68 + sizeof(struct xfs_icreate_log)); 69 69 } 70 70 71 71
+37 -48
fs/xfs/xfs_inode.c
··· 77 77 } 78 78 79 79 /* 80 - * This is a wrapper routine around the xfs_ilock() routine used to centralize 81 - * some grungy code. It is used in places that wish to lock the inode solely 82 - * for reading the extents. The reason these places can't just call 83 - * xfs_ilock(SHARED) is that the inode lock also guards to bringing in of the 84 - * extents from disk for a file in b-tree format. If the inode is in b-tree 85 - * format, then we need to lock the inode exclusively until the extents are read 86 - * in. Locking it exclusively all the time would limit our parallelism 87 - * unnecessarily, though. What we do instead is check to see if the extents 88 - * have been read in yet, and only lock the inode exclusively if they have not. 80 + * These two are wrapper routines around the xfs_ilock() routine used to 81 + * centralize some grungy code. They are used in places that wish to lock the 82 + * inode solely for reading the extents. The reason these places can't just 83 + * call xfs_ilock(ip, XFS_ILOCK_SHARED) is that the inode lock also guards to 84 + * bringing in of the extents from disk for a file in b-tree format. If the 85 + * inode is in b-tree format, then we need to lock the inode exclusively until 86 + * the extents are read in. Locking it exclusively all the time would limit 87 + * our parallelism unnecessarily, though. What we do instead is check to see 88 + * if the extents have been read in yet, and only lock the inode exclusively 89 + * if they have not. 89 90 * 90 - * The function returns a value which should be given to the corresponding 91 - * xfs_iunlock_map_shared(). This value is the mode in which the lock was 92 - * actually taken. 91 + * The functions return a value which should be given to the corresponding 92 + * xfs_iunlock() call. 93 93 */ 94 94 uint 95 - xfs_ilock_map_shared( 96 - xfs_inode_t *ip) 95 + xfs_ilock_data_map_shared( 96 + struct xfs_inode *ip) 97 97 { 98 - uint lock_mode; 98 + uint lock_mode = XFS_ILOCK_SHARED; 99 99 100 - if ((ip->i_d.di_format == XFS_DINODE_FMT_BTREE) && 101 - ((ip->i_df.if_flags & XFS_IFEXTENTS) == 0)) { 100 + if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE && 101 + (ip->i_df.if_flags & XFS_IFEXTENTS) == 0) 102 102 lock_mode = XFS_ILOCK_EXCL; 103 - } else { 104 - lock_mode = XFS_ILOCK_SHARED; 105 - } 106 - 107 103 xfs_ilock(ip, lock_mode); 108 - 109 104 return lock_mode; 110 105 } 111 106 112 - /* 113 - * This is simply the unlock routine to go with xfs_ilock_map_shared(). 114 - * All it does is call xfs_iunlock() with the given lock_mode. 115 - */ 116 - void 117 - xfs_iunlock_map_shared( 118 - xfs_inode_t *ip, 119 - unsigned int lock_mode) 107 + uint 108 + xfs_ilock_attr_map_shared( 109 + struct xfs_inode *ip) 120 110 { 121 - xfs_iunlock(ip, lock_mode); 111 + uint lock_mode = XFS_ILOCK_SHARED; 112 + 113 + if (ip->i_d.di_aformat == XFS_DINODE_FMT_BTREE && 114 + (ip->i_afp->if_flags & XFS_IFEXTENTS) == 0) 115 + lock_mode = XFS_ILOCK_EXCL; 116 + xfs_ilock(ip, lock_mode); 117 + return lock_mode; 122 118 } 123 119 124 120 /* ··· 584 588 if (XFS_FORCED_SHUTDOWN(dp->i_mount)) 585 589 return XFS_ERROR(EIO); 586 590 587 - lock_mode = xfs_ilock_map_shared(dp); 591 + lock_mode = xfs_ilock_data_map_shared(dp); 588 592 error = xfs_dir_lookup(NULL, dp, name, &inum, ci_name); 589 - xfs_iunlock_map_shared(dp, lock_mode); 593 + xfs_iunlock(dp, lock_mode); 590 594 591 595 if (error) 592 596 goto out; ··· 2137 2141 { 2138 2142 xfs_mount_t *mp = free_ip->i_mount; 2139 2143 int blks_per_cluster; 2144 + int inodes_per_cluster; 2140 2145 int nbufs; 2141 - int ninodes; 2142 2146 int i, j; 2143 2147 xfs_daddr_t blkno; 2144 2148 xfs_buf_t *bp; ··· 2148 2152 struct xfs_perag *pag; 2149 2153 2150 2154 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, inum)); 2151 - if (mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp)) { 2152 - blks_per_cluster = 1; 2153 - ninodes = mp->m_sb.sb_inopblock; 2154 - nbufs = XFS_IALLOC_BLOCKS(mp); 2155 - } else { 2156 - blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) / 2157 - mp->m_sb.sb_blocksize; 2158 - ninodes = blks_per_cluster * mp->m_sb.sb_inopblock; 2159 - nbufs = XFS_IALLOC_BLOCKS(mp) / blks_per_cluster; 2160 - } 2155 + blks_per_cluster = xfs_icluster_size_fsb(mp); 2156 + inodes_per_cluster = blks_per_cluster << mp->m_sb.sb_inopblog; 2157 + nbufs = mp->m_ialloc_blks / blks_per_cluster; 2161 2158 2162 - for (j = 0; j < nbufs; j++, inum += ninodes) { 2159 + for (j = 0; j < nbufs; j++, inum += inodes_per_cluster) { 2163 2160 blkno = XFS_AGB_TO_DADDR(mp, XFS_INO_TO_AGNO(mp, inum), 2164 2161 XFS_INO_TO_AGBNO(mp, inum)); 2165 2162 ··· 2214 2225 * transaction stale above, which means there is no point in 2215 2226 * even trying to lock them. 2216 2227 */ 2217 - for (i = 0; i < ninodes; i++) { 2228 + for (i = 0; i < inodes_per_cluster; i++) { 2218 2229 retry: 2219 2230 rcu_read_lock(); 2220 2231 ip = radix_tree_lookup(&pag->pag_ici_root, ··· 2895 2906 2896 2907 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); 2897 2908 2898 - inodes_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog; 2909 + inodes_per_cluster = mp->m_inode_cluster_size >> mp->m_sb.sb_inodelog; 2899 2910 ilist_size = inodes_per_cluster * sizeof(xfs_inode_t *); 2900 2911 ilist = kmem_alloc(ilist_size, KM_MAYFAIL|KM_NOFS); 2901 2912 if (!ilist) 2902 2913 goto out_put; 2903 2914 2904 - mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1); 2915 + mask = ~(((mp->m_inode_cluster_size >> mp->m_sb.sb_inodelog)) - 1); 2905 2916 first_index = XFS_INO_TO_AGINO(mp, ip->i_ino) & mask; 2906 2917 rcu_read_lock(); 2907 2918 /* really need a gang lookup range call here */
+2 -2
fs/xfs/xfs_inode.h
··· 337 337 void xfs_iunlock(xfs_inode_t *, uint); 338 338 void xfs_ilock_demote(xfs_inode_t *, uint); 339 339 int xfs_isilocked(xfs_inode_t *, uint); 340 - uint xfs_ilock_map_shared(xfs_inode_t *); 341 - void xfs_iunlock_map_shared(xfs_inode_t *, uint); 340 + uint xfs_ilock_data_map_shared(struct xfs_inode *); 341 + uint xfs_ilock_attr_map_shared(struct xfs_inode *); 342 342 int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, umode_t, 343 343 xfs_nlink_t, xfs_dev_t, prid_t, int, 344 344 struct xfs_buf **, xfs_inode_t **);
+10 -7
fs/xfs/xfs_inode_fork.c
··· 431 431 xfs_ifork_t *ifp; 432 432 xfs_extnum_t nextents; 433 433 434 + ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 435 + 434 436 if (unlikely(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) { 435 437 XFS_ERROR_REPORT("xfs_iread_extents", XFS_ERRLEVEL_LOW, 436 438 ip->i_mount); ··· 723 721 } 724 722 725 723 /* 726 - * xfs_iextents_copy() 724 + * Convert in-core extents to on-disk form 727 725 * 728 - * This is called to copy the REAL extents (as opposed to the delayed 729 - * allocation extents) from the inode into the given buffer. It 730 - * returns the number of bytes copied into the buffer. 726 + * For either the data or attr fork in extent format, we need to endian convert 727 + * the in-core extent as we place them into the on-disk inode. 731 728 * 732 - * If there are no delayed allocation extents, then we can just 733 - * memcpy() the extents into the buffer. Otherwise, we need to 734 - * examine each extent in turn and skip those which are delayed. 729 + * In the case of the data fork, the in-core and on-disk fork sizes can be 730 + * different due to delayed allocation extents. We only copy on-disk extents 731 + * here, so callers must always use the physical fork size to determine the 732 + * size of the buffer passed to this routine. We will return the size actually 733 + * used. 735 734 */ 736 735 int 737 736 xfs_iextents_copy(
+213 -289
fs/xfs/xfs_inode_item.c
··· 30 30 #include "xfs_trace.h" 31 31 #include "xfs_trans_priv.h" 32 32 #include "xfs_dinode.h" 33 + #include "xfs_log.h" 33 34 34 35 35 36 kmem_zone_t *xfs_ili_zone; /* inode log item zone */ ··· 40 39 return container_of(lip, struct xfs_inode_log_item, ili_item); 41 40 } 42 41 42 + STATIC void 43 + xfs_inode_item_data_fork_size( 44 + struct xfs_inode_log_item *iip, 45 + int *nvecs, 46 + int *nbytes) 47 + { 48 + struct xfs_inode *ip = iip->ili_inode; 49 + 50 + switch (ip->i_d.di_format) { 51 + case XFS_DINODE_FMT_EXTENTS: 52 + if ((iip->ili_fields & XFS_ILOG_DEXT) && 53 + ip->i_d.di_nextents > 0 && 54 + ip->i_df.if_bytes > 0) { 55 + /* worst case, doesn't subtract delalloc extents */ 56 + *nbytes += XFS_IFORK_DSIZE(ip); 57 + *nvecs += 1; 58 + } 59 + break; 60 + case XFS_DINODE_FMT_BTREE: 61 + if ((iip->ili_fields & XFS_ILOG_DBROOT) && 62 + ip->i_df.if_broot_bytes > 0) { 63 + *nbytes += ip->i_df.if_broot_bytes; 64 + *nvecs += 1; 65 + } 66 + break; 67 + case XFS_DINODE_FMT_LOCAL: 68 + if ((iip->ili_fields & XFS_ILOG_DDATA) && 69 + ip->i_df.if_bytes > 0) { 70 + *nbytes += roundup(ip->i_df.if_bytes, 4); 71 + *nvecs += 1; 72 + } 73 + break; 74 + 75 + case XFS_DINODE_FMT_DEV: 76 + case XFS_DINODE_FMT_UUID: 77 + break; 78 + default: 79 + ASSERT(0); 80 + break; 81 + } 82 + } 83 + 84 + STATIC void 85 + xfs_inode_item_attr_fork_size( 86 + struct xfs_inode_log_item *iip, 87 + int *nvecs, 88 + int *nbytes) 89 + { 90 + struct xfs_inode *ip = iip->ili_inode; 91 + 92 + switch (ip->i_d.di_aformat) { 93 + case XFS_DINODE_FMT_EXTENTS: 94 + if ((iip->ili_fields & XFS_ILOG_AEXT) && 95 + ip->i_d.di_anextents > 0 && 96 + ip->i_afp->if_bytes > 0) { 97 + /* worst case, doesn't subtract unused space */ 98 + *nbytes += XFS_IFORK_ASIZE(ip); 99 + *nvecs += 1; 100 + } 101 + break; 102 + case XFS_DINODE_FMT_BTREE: 103 + if ((iip->ili_fields & XFS_ILOG_ABROOT) && 104 + ip->i_afp->if_broot_bytes > 0) { 105 + *nbytes += ip->i_afp->if_broot_bytes; 106 + *nvecs += 1; 107 + } 108 + break; 109 + case XFS_DINODE_FMT_LOCAL: 110 + if ((iip->ili_fields & XFS_ILOG_ADATA) && 111 + ip->i_afp->if_bytes > 0) { 112 + *nbytes += roundup(ip->i_afp->if_bytes, 4); 113 + *nvecs += 1; 114 + } 115 + break; 116 + default: 117 + ASSERT(0); 118 + break; 119 + } 120 + } 43 121 44 122 /* 45 123 * This returns the number of iovecs needed to log the given inode item. ··· 140 60 *nbytes += sizeof(struct xfs_inode_log_format) + 141 61 xfs_icdinode_size(ip->i_d.di_version); 142 62 143 - switch (ip->i_d.di_format) { 144 - case XFS_DINODE_FMT_EXTENTS: 145 - if ((iip->ili_fields & XFS_ILOG_DEXT) && 146 - ip->i_d.di_nextents > 0 && 147 - ip->i_df.if_bytes > 0) { 148 - /* worst case, doesn't subtract delalloc extents */ 149 - *nbytes += XFS_IFORK_DSIZE(ip); 150 - *nvecs += 1; 151 - } 152 - break; 153 - 154 - case XFS_DINODE_FMT_BTREE: 155 - if ((iip->ili_fields & XFS_ILOG_DBROOT) && 156 - ip->i_df.if_broot_bytes > 0) { 157 - *nbytes += ip->i_df.if_broot_bytes; 158 - *nvecs += 1; 159 - } 160 - break; 161 - 162 - case XFS_DINODE_FMT_LOCAL: 163 - if ((iip->ili_fields & XFS_ILOG_DDATA) && 164 - ip->i_df.if_bytes > 0) { 165 - *nbytes += roundup(ip->i_df.if_bytes, 4); 166 - *nvecs += 1; 167 - } 168 - break; 169 - 170 - case XFS_DINODE_FMT_DEV: 171 - case XFS_DINODE_FMT_UUID: 172 - break; 173 - 174 - default: 175 - ASSERT(0); 176 - break; 177 - } 178 - 179 - if (!XFS_IFORK_Q(ip)) 180 - return; 181 - 182 - 183 - /* 184 - * Log any necessary attribute data. 185 - */ 186 - switch (ip->i_d.di_aformat) { 187 - case XFS_DINODE_FMT_EXTENTS: 188 - if ((iip->ili_fields & XFS_ILOG_AEXT) && 189 - ip->i_d.di_anextents > 0 && 190 - ip->i_afp->if_bytes > 0) { 191 - /* worst case, doesn't subtract unused space */ 192 - *nbytes += XFS_IFORK_ASIZE(ip); 193 - *nvecs += 1; 194 - } 195 - break; 196 - 197 - case XFS_DINODE_FMT_BTREE: 198 - if ((iip->ili_fields & XFS_ILOG_ABROOT) && 199 - ip->i_afp->if_broot_bytes > 0) { 200 - *nbytes += ip->i_afp->if_broot_bytes; 201 - *nvecs += 1; 202 - } 203 - break; 204 - 205 - case XFS_DINODE_FMT_LOCAL: 206 - if ((iip->ili_fields & XFS_ILOG_ADATA) && 207 - ip->i_afp->if_bytes > 0) { 208 - *nbytes += roundup(ip->i_afp->if_bytes, 4); 209 - *nvecs += 1; 210 - } 211 - break; 212 - 213 - default: 214 - ASSERT(0); 215 - break; 216 - } 63 + xfs_inode_item_data_fork_size(iip, nvecs, nbytes); 64 + if (XFS_IFORK_Q(ip)) 65 + xfs_inode_item_attr_fork_size(iip, nvecs, nbytes); 217 66 } 218 67 219 68 /* 220 - * xfs_inode_item_format_extents - convert in-core extents to on-disk form 221 - * 222 - * For either the data or attr fork in extent format, we need to endian convert 223 - * the in-core extent as we place them into the on-disk inode. In this case, we 224 - * need to do this conversion before we write the extents into the log. Because 225 - * we don't have the disk inode to write into here, we allocate a buffer and 226 - * format the extents into it via xfs_iextents_copy(). We free the buffer in 227 - * the unlock routine after the copy for the log has been made. 228 - * 229 - * In the case of the data fork, the in-core and on-disk fork sizes can be 230 - * different due to delayed allocation extents. We only log on-disk extents 231 - * here, so always use the physical fork size to determine the size of the 232 - * buffer we need to allocate. 69 + * If this is a v1 format inode, then we need to log it as such. This means 70 + * that we have to copy the link count from the new field to the old. We 71 + * don't have to worry about the new fields, because nothing trusts them as 72 + * long as the old inode version number is there. 233 73 */ 234 74 STATIC void 235 - xfs_inode_item_format_extents( 236 - struct xfs_inode *ip, 237 - struct xfs_log_iovec *vecp, 238 - int whichfork, 239 - int type) 75 + xfs_inode_item_format_v1_inode( 76 + struct xfs_inode *ip) 240 77 { 241 - xfs_bmbt_rec_t *ext_buffer; 242 - 243 - ext_buffer = kmem_alloc(XFS_IFORK_SIZE(ip, whichfork), KM_SLEEP); 244 - if (whichfork == XFS_DATA_FORK) 245 - ip->i_itemp->ili_extents_buf = ext_buffer; 246 - else 247 - ip->i_itemp->ili_aextents_buf = ext_buffer; 248 - 249 - vecp->i_addr = ext_buffer; 250 - vecp->i_len = xfs_iextents_copy(ip, ext_buffer, whichfork); 251 - vecp->i_type = type; 78 + if (!xfs_sb_version_hasnlink(&ip->i_mount->m_sb)) { 79 + /* 80 + * Convert it back. 81 + */ 82 + ASSERT(ip->i_d.di_nlink <= XFS_MAXLINK_1); 83 + ip->i_d.di_onlink = ip->i_d.di_nlink; 84 + } else { 85 + /* 86 + * The superblock version has already been bumped, 87 + * so just make the conversion to the new inode 88 + * format permanent. 89 + */ 90 + ip->i_d.di_version = 2; 91 + ip->i_d.di_onlink = 0; 92 + memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); 93 + } 252 94 } 253 95 254 - /* 255 - * This is called to fill in the vector of log iovecs for the 256 - * given inode log item. It fills the first item with an inode 257 - * log format structure, the second with the on-disk inode structure, 258 - * and a possible third and/or fourth with the inode data/extents/b-tree 259 - * root and inode attributes data/extents/b-tree root. 260 - */ 261 96 STATIC void 262 - xfs_inode_item_format( 263 - struct xfs_log_item *lip, 264 - struct xfs_log_iovec *vecp) 97 + xfs_inode_item_format_data_fork( 98 + struct xfs_inode_log_item *iip, 99 + struct xfs_inode_log_format *ilf, 100 + struct xfs_log_vec *lv, 101 + struct xfs_log_iovec **vecp) 265 102 { 266 - struct xfs_inode_log_item *iip = INODE_ITEM(lip); 267 103 struct xfs_inode *ip = iip->ili_inode; 268 - uint nvecs; 269 104 size_t data_bytes; 270 - xfs_mount_t *mp; 271 - 272 - vecp->i_addr = &iip->ili_format; 273 - vecp->i_len = sizeof(xfs_inode_log_format_t); 274 - vecp->i_type = XLOG_REG_TYPE_IFORMAT; 275 - vecp++; 276 - nvecs = 1; 277 - 278 - vecp->i_addr = &ip->i_d; 279 - vecp->i_len = xfs_icdinode_size(ip->i_d.di_version); 280 - vecp->i_type = XLOG_REG_TYPE_ICORE; 281 - vecp++; 282 - nvecs++; 283 - 284 - /* 285 - * If this is really an old format inode, then we need to 286 - * log it as such. This means that we have to copy the link 287 - * count from the new field to the old. We don't have to worry 288 - * about the new fields, because nothing trusts them as long as 289 - * the old inode version number is there. If the superblock already 290 - * has a new version number, then we don't bother converting back. 291 - */ 292 - mp = ip->i_mount; 293 - ASSERT(ip->i_d.di_version == 1 || xfs_sb_version_hasnlink(&mp->m_sb)); 294 - if (ip->i_d.di_version == 1) { 295 - if (!xfs_sb_version_hasnlink(&mp->m_sb)) { 296 - /* 297 - * Convert it back. 298 - */ 299 - ASSERT(ip->i_d.di_nlink <= XFS_MAXLINK_1); 300 - ip->i_d.di_onlink = ip->i_d.di_nlink; 301 - } else { 302 - /* 303 - * The superblock version has already been bumped, 304 - * so just make the conversion to the new inode 305 - * format permanent. 306 - */ 307 - ip->i_d.di_version = 2; 308 - ip->i_d.di_onlink = 0; 309 - memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); 310 - } 311 - } 312 105 313 106 switch (ip->i_d.di_format) { 314 107 case XFS_DINODE_FMT_EXTENTS: ··· 192 239 if ((iip->ili_fields & XFS_ILOG_DEXT) && 193 240 ip->i_d.di_nextents > 0 && 194 241 ip->i_df.if_bytes > 0) { 242 + struct xfs_bmbt_rec *p; 243 + 195 244 ASSERT(ip->i_df.if_u1.if_extents != NULL); 196 245 ASSERT(ip->i_df.if_bytes / sizeof(xfs_bmbt_rec_t) > 0); 197 - ASSERT(iip->ili_extents_buf == NULL); 198 246 199 - #ifdef XFS_NATIVE_HOST 200 - if (ip->i_d.di_nextents == ip->i_df.if_bytes / 201 - (uint)sizeof(xfs_bmbt_rec_t)) { 202 - /* 203 - * There are no delayed allocation 204 - * extents, so just point to the 205 - * real extents array. 206 - */ 207 - vecp->i_addr = ip->i_df.if_u1.if_extents; 208 - vecp->i_len = ip->i_df.if_bytes; 209 - vecp->i_type = XLOG_REG_TYPE_IEXT; 210 - } else 211 - #endif 212 - { 213 - xfs_inode_item_format_extents(ip, vecp, 214 - XFS_DATA_FORK, XLOG_REG_TYPE_IEXT); 215 - } 216 - ASSERT(vecp->i_len <= ip->i_df.if_bytes); 217 - iip->ili_format.ilf_dsize = vecp->i_len; 218 - vecp++; 219 - nvecs++; 247 + p = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_IEXT); 248 + data_bytes = xfs_iextents_copy(ip, p, XFS_DATA_FORK); 249 + xlog_finish_iovec(lv, *vecp, data_bytes); 250 + 251 + ASSERT(data_bytes <= ip->i_df.if_bytes); 252 + 253 + ilf->ilf_dsize = data_bytes; 254 + ilf->ilf_size++; 220 255 } else { 221 256 iip->ili_fields &= ~XFS_ILOG_DEXT; 222 257 } 223 258 break; 224 - 225 259 case XFS_DINODE_FMT_BTREE: 226 260 iip->ili_fields &= 227 261 ~(XFS_ILOG_DDATA | XFS_ILOG_DEXT | ··· 217 277 if ((iip->ili_fields & XFS_ILOG_DBROOT) && 218 278 ip->i_df.if_broot_bytes > 0) { 219 279 ASSERT(ip->i_df.if_broot != NULL); 220 - vecp->i_addr = ip->i_df.if_broot; 221 - vecp->i_len = ip->i_df.if_broot_bytes; 222 - vecp->i_type = XLOG_REG_TYPE_IBROOT; 223 - vecp++; 224 - nvecs++; 225 - iip->ili_format.ilf_dsize = ip->i_df.if_broot_bytes; 280 + xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IBROOT, 281 + ip->i_df.if_broot, 282 + ip->i_df.if_broot_bytes); 283 + ilf->ilf_dsize = ip->i_df.if_broot_bytes; 284 + ilf->ilf_size++; 226 285 } else { 227 286 ASSERT(!(iip->ili_fields & 228 287 XFS_ILOG_DBROOT)); 229 288 iip->ili_fields &= ~XFS_ILOG_DBROOT; 230 289 } 231 290 break; 232 - 233 291 case XFS_DINODE_FMT_LOCAL: 234 292 iip->ili_fields &= 235 293 ~(XFS_ILOG_DEXT | XFS_ILOG_DBROOT | 236 294 XFS_ILOG_DEV | XFS_ILOG_UUID); 237 295 if ((iip->ili_fields & XFS_ILOG_DDATA) && 238 296 ip->i_df.if_bytes > 0) { 239 - ASSERT(ip->i_df.if_u1.if_data != NULL); 240 - ASSERT(ip->i_d.di_size > 0); 241 - 242 - vecp->i_addr = ip->i_df.if_u1.if_data; 243 297 /* 244 298 * Round i_bytes up to a word boundary. 245 299 * The underlying memory is guaranteed to 246 300 * to be there by xfs_idata_realloc(). 247 301 */ 248 302 data_bytes = roundup(ip->i_df.if_bytes, 4); 249 - ASSERT((ip->i_df.if_real_bytes == 0) || 250 - (ip->i_df.if_real_bytes == data_bytes)); 251 - vecp->i_len = (int)data_bytes; 252 - vecp->i_type = XLOG_REG_TYPE_ILOCAL; 253 - vecp++; 254 - nvecs++; 255 - iip->ili_format.ilf_dsize = (unsigned)data_bytes; 303 + ASSERT(ip->i_df.if_real_bytes == 0 || 304 + ip->i_df.if_real_bytes == data_bytes); 305 + ASSERT(ip->i_df.if_u1.if_data != NULL); 306 + ASSERT(ip->i_d.di_size > 0); 307 + xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_ILOCAL, 308 + ip->i_df.if_u1.if_data, data_bytes); 309 + ilf->ilf_dsize = (unsigned)data_bytes; 310 + ilf->ilf_size++; 256 311 } else { 257 312 iip->ili_fields &= ~XFS_ILOG_DDATA; 258 313 } 259 314 break; 260 - 261 315 case XFS_DINODE_FMT_DEV: 262 316 iip->ili_fields &= 263 317 ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | 264 318 XFS_ILOG_DEXT | XFS_ILOG_UUID); 265 - if (iip->ili_fields & XFS_ILOG_DEV) { 266 - iip->ili_format.ilf_u.ilfu_rdev = 267 - ip->i_df.if_u2.if_rdev; 268 - } 319 + if (iip->ili_fields & XFS_ILOG_DEV) 320 + ilf->ilf_u.ilfu_rdev = ip->i_df.if_u2.if_rdev; 269 321 break; 270 - 271 322 case XFS_DINODE_FMT_UUID: 272 323 iip->ili_fields &= 273 324 ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | 274 325 XFS_ILOG_DEXT | XFS_ILOG_DEV); 275 - if (iip->ili_fields & XFS_ILOG_UUID) { 276 - iip->ili_format.ilf_u.ilfu_uuid = 277 - ip->i_df.if_u2.if_uuid; 278 - } 326 + if (iip->ili_fields & XFS_ILOG_UUID) 327 + ilf->ilf_u.ilfu_uuid = ip->i_df.if_u2.if_uuid; 279 328 break; 280 - 281 329 default: 282 330 ASSERT(0); 283 331 break; 284 332 } 333 + } 285 334 286 - /* 287 - * If there are no attributes associated with the file, then we're done. 288 - */ 289 - if (!XFS_IFORK_Q(ip)) { 290 - iip->ili_fields &= 291 - ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT); 292 - goto out; 293 - } 335 + STATIC void 336 + xfs_inode_item_format_attr_fork( 337 + struct xfs_inode_log_item *iip, 338 + struct xfs_inode_log_format *ilf, 339 + struct xfs_log_vec *lv, 340 + struct xfs_log_iovec **vecp) 341 + { 342 + struct xfs_inode *ip = iip->ili_inode; 343 + size_t data_bytes; 294 344 295 345 switch (ip->i_d.di_aformat) { 296 346 case XFS_DINODE_FMT_EXTENTS: ··· 290 360 if ((iip->ili_fields & XFS_ILOG_AEXT) && 291 361 ip->i_d.di_anextents > 0 && 292 362 ip->i_afp->if_bytes > 0) { 363 + struct xfs_bmbt_rec *p; 364 + 293 365 ASSERT(ip->i_afp->if_bytes / sizeof(xfs_bmbt_rec_t) == 294 366 ip->i_d.di_anextents); 295 367 ASSERT(ip->i_afp->if_u1.if_extents != NULL); 296 - #ifdef XFS_NATIVE_HOST 297 - /* 298 - * There are not delayed allocation extents 299 - * for attributes, so just point at the array. 300 - */ 301 - vecp->i_addr = ip->i_afp->if_u1.if_extents; 302 - vecp->i_len = ip->i_afp->if_bytes; 303 - vecp->i_type = XLOG_REG_TYPE_IATTR_EXT; 304 - #else 305 - ASSERT(iip->ili_aextents_buf == NULL); 306 - xfs_inode_item_format_extents(ip, vecp, 307 - XFS_ATTR_FORK, XLOG_REG_TYPE_IATTR_EXT); 308 - #endif 309 - iip->ili_format.ilf_asize = vecp->i_len; 310 - vecp++; 311 - nvecs++; 368 + 369 + p = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_EXT); 370 + data_bytes = xfs_iextents_copy(ip, p, XFS_ATTR_FORK); 371 + xlog_finish_iovec(lv, *vecp, data_bytes); 372 + 373 + ilf->ilf_asize = data_bytes; 374 + ilf->ilf_size++; 312 375 } else { 313 376 iip->ili_fields &= ~XFS_ILOG_AEXT; 314 377 } 315 378 break; 316 - 317 379 case XFS_DINODE_FMT_BTREE: 318 380 iip->ili_fields &= 319 381 ~(XFS_ILOG_ADATA | XFS_ILOG_AEXT); ··· 314 392 ip->i_afp->if_broot_bytes > 0) { 315 393 ASSERT(ip->i_afp->if_broot != NULL); 316 394 317 - vecp->i_addr = ip->i_afp->if_broot; 318 - vecp->i_len = ip->i_afp->if_broot_bytes; 319 - vecp->i_type = XLOG_REG_TYPE_IATTR_BROOT; 320 - vecp++; 321 - nvecs++; 322 - iip->ili_format.ilf_asize = ip->i_afp->if_broot_bytes; 395 + xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_BROOT, 396 + ip->i_afp->if_broot, 397 + ip->i_afp->if_broot_bytes); 398 + ilf->ilf_asize = ip->i_afp->if_broot_bytes; 399 + ilf->ilf_size++; 323 400 } else { 324 401 iip->ili_fields &= ~XFS_ILOG_ABROOT; 325 402 } 326 403 break; 327 - 328 404 case XFS_DINODE_FMT_LOCAL: 329 405 iip->ili_fields &= 330 406 ~(XFS_ILOG_AEXT | XFS_ILOG_ABROOT); 331 407 332 408 if ((iip->ili_fields & XFS_ILOG_ADATA) && 333 409 ip->i_afp->if_bytes > 0) { 334 - ASSERT(ip->i_afp->if_u1.if_data != NULL); 335 - 336 - vecp->i_addr = ip->i_afp->if_u1.if_data; 337 410 /* 338 411 * Round i_bytes up to a word boundary. 339 412 * The underlying memory is guaranteed to 340 413 * to be there by xfs_idata_realloc(). 341 414 */ 342 415 data_bytes = roundup(ip->i_afp->if_bytes, 4); 343 - ASSERT((ip->i_afp->if_real_bytes == 0) || 344 - (ip->i_afp->if_real_bytes == data_bytes)); 345 - vecp->i_len = (int)data_bytes; 346 - vecp->i_type = XLOG_REG_TYPE_IATTR_LOCAL; 347 - vecp++; 348 - nvecs++; 349 - iip->ili_format.ilf_asize = (unsigned)data_bytes; 416 + ASSERT(ip->i_afp->if_real_bytes == 0 || 417 + ip->i_afp->if_real_bytes == data_bytes); 418 + ASSERT(ip->i_afp->if_u1.if_data != NULL); 419 + xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_LOCAL, 420 + ip->i_afp->if_u1.if_data, 421 + data_bytes); 422 + ilf->ilf_asize = (unsigned)data_bytes; 423 + ilf->ilf_size++; 350 424 } else { 351 425 iip->ili_fields &= ~XFS_ILOG_ADATA; 352 426 } 353 427 break; 354 - 355 428 default: 356 429 ASSERT(0); 357 430 break; 358 431 } 359 - 360 - out: 361 - /* 362 - * Now update the log format that goes out to disk from the in-core 363 - * values. We always write the inode core to make the arithmetic 364 - * games in recovery easier, which isn't a big deal as just about any 365 - * transaction would dirty it anyway. 366 - */ 367 - iip->ili_format.ilf_fields = XFS_ILOG_CORE | 368 - (iip->ili_fields & ~XFS_ILOG_TIMESTAMP); 369 - iip->ili_format.ilf_size = nvecs; 370 432 } 371 433 434 + /* 435 + * This is called to fill in the vector of log iovecs for the given inode 436 + * log item. It fills the first item with an inode log format structure, 437 + * the second with the on-disk inode structure, and a possible third and/or 438 + * fourth with the inode data/extents/b-tree root and inode attributes 439 + * data/extents/b-tree root. 440 + */ 441 + STATIC void 442 + xfs_inode_item_format( 443 + struct xfs_log_item *lip, 444 + struct xfs_log_vec *lv) 445 + { 446 + struct xfs_inode_log_item *iip = INODE_ITEM(lip); 447 + struct xfs_inode *ip = iip->ili_inode; 448 + struct xfs_inode_log_format *ilf; 449 + struct xfs_log_iovec *vecp = NULL; 450 + 451 + ilf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_IFORMAT); 452 + ilf->ilf_type = XFS_LI_INODE; 453 + ilf->ilf_ino = ip->i_ino; 454 + ilf->ilf_blkno = ip->i_imap.im_blkno; 455 + ilf->ilf_len = ip->i_imap.im_len; 456 + ilf->ilf_boffset = ip->i_imap.im_boffset; 457 + ilf->ilf_fields = XFS_ILOG_CORE; 458 + ilf->ilf_size = 2; /* format + core */ 459 + xlog_finish_iovec(lv, vecp, sizeof(struct xfs_inode_log_format)); 460 + 461 + if (ip->i_d.di_version == 1) 462 + xfs_inode_item_format_v1_inode(ip); 463 + xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ICORE, 464 + &ip->i_d, 465 + xfs_icdinode_size(ip->i_d.di_version)); 466 + 467 + xfs_inode_item_format_data_fork(iip, ilf, lv, &vecp); 468 + if (XFS_IFORK_Q(ip)) { 469 + xfs_inode_item_format_attr_fork(iip, ilf, lv, &vecp); 470 + } else { 471 + iip->ili_fields &= 472 + ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT); 473 + } 474 + 475 + /* update the format with the exact fields we actually logged */ 476 + ilf->ilf_fields |= (iip->ili_fields & ~XFS_ILOG_TIMESTAMP); 477 + } 372 478 373 479 /* 374 480 * This is called to pin the inode associated with the inode log ··· 513 563 ASSERT(ip->i_itemp != NULL); 514 564 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 515 565 516 - /* 517 - * If the inode needed a separate buffer with which to log 518 - * its extents, then free it now. 519 - */ 520 - if (iip->ili_extents_buf != NULL) { 521 - ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS); 522 - ASSERT(ip->i_d.di_nextents > 0); 523 - ASSERT(iip->ili_fields & XFS_ILOG_DEXT); 524 - ASSERT(ip->i_df.if_bytes > 0); 525 - kmem_free(iip->ili_extents_buf); 526 - iip->ili_extents_buf = NULL; 527 - } 528 - if (iip->ili_aextents_buf != NULL) { 529 - ASSERT(ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS); 530 - ASSERT(ip->i_d.di_anextents > 0); 531 - ASSERT(iip->ili_fields & XFS_ILOG_AEXT); 532 - ASSERT(ip->i_afp->if_bytes > 0); 533 - kmem_free(iip->ili_aextents_buf); 534 - iip->ili_aextents_buf = NULL; 535 - } 536 - 537 566 lock_flags = iip->ili_lock_flags; 538 567 iip->ili_lock_flags = 0; 539 568 if (lock_flags) ··· 599 670 iip->ili_inode = ip; 600 671 xfs_log_item_init(mp, &iip->ili_item, XFS_LI_INODE, 601 672 &xfs_inode_item_ops); 602 - iip->ili_format.ilf_type = XFS_LI_INODE; 603 - iip->ili_format.ilf_ino = ip->i_ino; 604 - iip->ili_format.ilf_blkno = ip->i_imap.im_blkno; 605 - iip->ili_format.ilf_len = ip->i_imap.im_len; 606 - iip->ili_format.ilf_boffset = ip->i_imap.im_boffset; 607 673 } 608 674 609 675 /*
-5
fs/xfs/xfs_inode_item.h
··· 34 34 unsigned short ili_logged; /* flushed logged data */ 35 35 unsigned int ili_last_fields; /* fields when flushed */ 36 36 unsigned int ili_fields; /* fields to be logged */ 37 - struct xfs_bmbt_rec *ili_extents_buf; /* array of logged 38 - data exts */ 39 - struct xfs_bmbt_rec *ili_aextents_buf; /* array of logged 40 - attr exts */ 41 - xfs_inode_log_format_t ili_format; /* logged structure */ 42 37 } xfs_inode_log_item_t; 43 38 44 39 static inline int xfs_inode_clean(xfs_inode_t *ip)
-4
fs/xfs/xfs_ioctl.c
··· 112 112 memset(&handle.ha_fid, 0, sizeof(handle.ha_fid)); 113 113 hsize = sizeof(xfs_fsid_t); 114 114 } else { 115 - int lock_mode; 116 - 117 - lock_mode = xfs_ilock_map_shared(ip); 118 115 handle.ha_fid.fid_len = sizeof(xfs_fid_t) - 119 116 sizeof(handle.ha_fid.fid_len); 120 117 handle.ha_fid.fid_pad = 0; 121 118 handle.ha_fid.fid_gen = ip->i_d.di_gen; 122 119 handle.ha_fid.fid_ino = ip->i_ino; 123 - xfs_iunlock_map_shared(ip, lock_mode); 124 120 125 121 hsize = XFS_HSIZE(handle); 126 122 }
+34 -42
fs/xfs/xfs_iops.c
··· 459 459 460 460 static void 461 461 xfs_setattr_mode( 462 - struct xfs_trans *tp, 463 462 struct xfs_inode *ip, 464 463 struct iattr *iattr) 465 464 { 466 - struct inode *inode = VFS_I(ip); 467 - umode_t mode = iattr->ia_mode; 465 + struct inode *inode = VFS_I(ip); 466 + umode_t mode = iattr->ia_mode; 468 467 469 - ASSERT(tp); 470 468 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 471 469 472 470 ip->i_d.di_mode &= S_IFMT; ··· 472 474 473 475 inode->i_mode &= S_IFMT; 474 476 inode->i_mode |= mode & ~S_IFMT; 477 + } 478 + 479 + static void 480 + xfs_setattr_time( 481 + struct xfs_inode *ip, 482 + struct iattr *iattr) 483 + { 484 + struct inode *inode = VFS_I(ip); 485 + 486 + ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 487 + 488 + if (iattr->ia_valid & ATTR_ATIME) { 489 + inode->i_atime = iattr->ia_atime; 490 + ip->i_d.di_atime.t_sec = iattr->ia_atime.tv_sec; 491 + ip->i_d.di_atime.t_nsec = iattr->ia_atime.tv_nsec; 492 + } 493 + if (iattr->ia_valid & ATTR_CTIME) { 494 + inode->i_ctime = iattr->ia_ctime; 495 + ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec; 496 + ip->i_d.di_ctime.t_nsec = iattr->ia_ctime.tv_nsec; 497 + } 498 + if (iattr->ia_valid & ATTR_MTIME) { 499 + inode->i_mtime = iattr->ia_mtime; 500 + ip->i_d.di_mtime.t_sec = iattr->ia_mtime.tv_sec; 501 + ip->i_d.di_mtime.t_nsec = iattr->ia_mtime.tv_nsec; 502 + } 475 503 } 476 504 477 505 int ··· 654 630 } 655 631 } 656 632 657 - /* 658 - * Change file access modes. 659 - */ 660 633 if (mask & ATTR_MODE) 661 - xfs_setattr_mode(tp, ip, iattr); 662 - 663 - /* 664 - * Change file access or modified times. 665 - */ 666 - if (mask & ATTR_ATIME) { 667 - inode->i_atime = iattr->ia_atime; 668 - ip->i_d.di_atime.t_sec = iattr->ia_atime.tv_sec; 669 - ip->i_d.di_atime.t_nsec = iattr->ia_atime.tv_nsec; 670 - } 671 - if (mask & ATTR_CTIME) { 672 - inode->i_ctime = iattr->ia_ctime; 673 - ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec; 674 - ip->i_d.di_ctime.t_nsec = iattr->ia_ctime.tv_nsec; 675 - } 676 - if (mask & ATTR_MTIME) { 677 - inode->i_mtime = iattr->ia_mtime; 678 - ip->i_d.di_mtime.t_sec = iattr->ia_mtime.tv_sec; 679 - ip->i_d.di_mtime.t_nsec = iattr->ia_mtime.tv_nsec; 680 - } 634 + xfs_setattr_mode(ip, iattr); 635 + if (mask & (ATTR_ATIME|ATTR_CTIME|ATTR_MTIME)) 636 + xfs_setattr_time(ip, iattr); 681 637 682 638 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 683 639 ··· 872 868 xfs_inode_clear_eofblocks_tag(ip); 873 869 } 874 870 875 - /* 876 - * Change file access modes. 877 - */ 878 871 if (mask & ATTR_MODE) 879 - xfs_setattr_mode(tp, ip, iattr); 880 - 881 - if (mask & ATTR_CTIME) { 882 - inode->i_ctime = iattr->ia_ctime; 883 - ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec; 884 - ip->i_d.di_ctime.t_nsec = iattr->ia_ctime.tv_nsec; 885 - } 886 - if (mask & ATTR_MTIME) { 887 - inode->i_mtime = iattr->ia_mtime; 888 - ip->i_d.di_mtime.t_sec = iattr->ia_mtime.tv_sec; 889 - ip->i_d.di_mtime.t_nsec = iattr->ia_mtime.tv_nsec; 890 - } 872 + xfs_setattr_mode(ip, iattr); 873 + if (mask & (ATTR_ATIME|ATTR_CTIME|ATTR_MTIME)) 874 + xfs_setattr_time(ip, iattr); 891 875 892 876 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 893 877
+9 -13
fs/xfs/xfs_itable.c
··· 209 209 xfs_inobt_rec_incore_t *irbuf; /* start of irec buffer */ 210 210 xfs_inobt_rec_incore_t *irbufend; /* end of good irec buffer entries */ 211 211 xfs_ino_t lastino; /* last inode number returned */ 212 - int nbcluster; /* # of blocks in a cluster */ 213 - int nicluster; /* # of inodes in a cluster */ 214 - int nimask; /* mask for inode clusters */ 212 + int blks_per_cluster; /* # of blocks per cluster */ 213 + int inodes_per_cluster;/* # of inodes per cluster */ 215 214 int nirbuf; /* size of irbuf */ 216 215 int rval; /* return value error code */ 217 216 int tmp; /* result value from btree calls */ ··· 242 243 *done = 0; 243 244 fmterror = 0; 244 245 ubufp = ubuffer; 245 - nicluster = mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp) ? 246 - mp->m_sb.sb_inopblock : 247 - (XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog); 248 - nimask = ~(nicluster - 1); 249 - nbcluster = nicluster >> mp->m_sb.sb_inopblog; 246 + blks_per_cluster = xfs_icluster_size_fsb(mp); 247 + inodes_per_cluster = blks_per_cluster << mp->m_sb.sb_inopblog; 250 248 irbuf = kmem_zalloc_greedy(&irbsize, PAGE_SIZE, PAGE_SIZE * 4); 251 249 if (!irbuf) 252 250 return ENOMEM; ··· 386 390 agbno = XFS_AGINO_TO_AGBNO(mp, r.ir_startino); 387 391 for (chunkidx = 0; 388 392 chunkidx < XFS_INODES_PER_CHUNK; 389 - chunkidx += nicluster, 390 - agbno += nbcluster) { 391 - if (xfs_inobt_maskn(chunkidx, nicluster) 392 - & ~r.ir_free) 393 + chunkidx += inodes_per_cluster, 394 + agbno += blks_per_cluster) { 395 + if (xfs_inobt_maskn(chunkidx, 396 + inodes_per_cluster) & ~r.ir_free) 393 397 xfs_btree_reada_bufs(mp, agno, 394 - agbno, nbcluster, 398 + agbno, blks_per_cluster, 395 399 &xfs_inode_buf_ops); 396 400 } 397 401 blk_finish_plug(&plug);
+46
fs/xfs/xfs_log.h
··· 30 30 31 31 #define XFS_LOG_VEC_ORDERED (-1) 32 32 33 + static inline void * 34 + xlog_prepare_iovec(struct xfs_log_vec *lv, struct xfs_log_iovec **vecp, 35 + uint type) 36 + { 37 + struct xfs_log_iovec *vec = *vecp; 38 + 39 + if (vec) { 40 + ASSERT(vec - lv->lv_iovecp < lv->lv_niovecs); 41 + vec++; 42 + } else { 43 + vec = &lv->lv_iovecp[0]; 44 + } 45 + 46 + vec->i_type = type; 47 + vec->i_addr = lv->lv_buf + lv->lv_buf_len; 48 + 49 + ASSERT(IS_ALIGNED((unsigned long)vec->i_addr, sizeof(uint64_t))); 50 + 51 + *vecp = vec; 52 + return vec->i_addr; 53 + } 54 + 55 + static inline void 56 + xlog_finish_iovec(struct xfs_log_vec *lv, struct xfs_log_iovec *vec, int len) 57 + { 58 + /* 59 + * We need to make sure the next buffer is naturally aligned for the 60 + * biggest basic data type we put into it. We already accounted for 61 + * this when sizing the buffer. 62 + */ 63 + lv->lv_buf_len += round_up(len, sizeof(uint64_t)); 64 + vec->i_len = len; 65 + } 66 + 67 + static inline void * 68 + xlog_copy_iovec(struct xfs_log_vec *lv, struct xfs_log_iovec **vecp, 69 + uint type, void *data, int len) 70 + { 71 + void *buf; 72 + 73 + buf = xlog_prepare_iovec(lv, vecp, type); 74 + memcpy(buf, data, len); 75 + xlog_finish_iovec(lv, *vecp, len); 76 + return buf; 77 + } 78 + 33 79 /* 34 80 * Structure used to pass callback function and the function's argument 35 81 * to the log manager.
+22 -52
fs/xfs/xfs_log_cil.c
··· 82 82 log->l_curr_block); 83 83 } 84 84 85 - STATIC int 86 - xlog_cil_lv_item_format( 87 - struct xfs_log_item *lip, 88 - struct xfs_log_vec *lv) 89 - { 90 - int index; 91 - char *ptr; 92 - 93 - /* format new vectors into array */ 94 - lip->li_ops->iop_format(lip, lv->lv_iovecp); 95 - 96 - /* copy data into existing array */ 97 - ptr = lv->lv_buf; 98 - for (index = 0; index < lv->lv_niovecs; index++) { 99 - struct xfs_log_iovec *vec = &lv->lv_iovecp[index]; 100 - 101 - memcpy(ptr, vec->i_addr, vec->i_len); 102 - vec->i_addr = ptr; 103 - ptr += vec->i_len; 104 - } 105 - 106 - /* 107 - * some size calculations for log vectors over-estimate, so the caller 108 - * doesn't know the amount of space actually used by the item. Return 109 - * the byte count to the caller so they can check and store it 110 - * appropriately. 111 - */ 112 - return ptr - lv->lv_buf; 113 - } 114 - 115 85 /* 116 86 * Prepare the log item for insertion into the CIL. Calculate the difference in 117 87 * log space and vectors it will consume, and if it is a new item pin it as ··· 202 232 nbytes = 0; 203 233 } 204 234 235 + /* 236 + * We 64-bit align the length of each iovec so that the start 237 + * of the next one is naturally aligned. We'll need to 238 + * account for that slack space here. 239 + */ 240 + nbytes += niovecs * sizeof(uint64_t); 241 + 205 242 /* grab the old item if it exists for reservation accounting */ 206 243 old_lv = lip->li_lv; 207 244 ··· 231 254 */ 232 255 *diff_iovecs -= lv->lv_niovecs; 233 256 *diff_len -= lv->lv_buf_len; 234 - 235 - /* Ensure the lv is set up according to ->iop_size */ 236 - lv->lv_niovecs = niovecs; 237 - lv->lv_buf = (char *)lv + buf_size - nbytes; 238 - 239 - lv->lv_buf_len = xlog_cil_lv_item_format(lip, lv); 240 - goto insert; 257 + } else { 258 + /* allocate new data chunk */ 259 + lv = kmem_zalloc(buf_size, KM_SLEEP|KM_NOFS); 260 + lv->lv_item = lip; 261 + lv->lv_size = buf_size; 262 + if (ordered) { 263 + /* track as an ordered logvec */ 264 + ASSERT(lip->li_lv == NULL); 265 + lv->lv_buf_len = XFS_LOG_VEC_ORDERED; 266 + goto insert; 267 + } 268 + lv->lv_iovecp = (struct xfs_log_iovec *)&lv[1]; 241 269 } 242 270 243 - /* allocate new data chunk */ 244 - lv = kmem_zalloc(buf_size, KM_SLEEP|KM_NOFS); 245 - lv->lv_item = lip; 246 - lv->lv_size = buf_size; 271 + /* Ensure the lv is set up according to ->iop_size */ 247 272 lv->lv_niovecs = niovecs; 248 - if (ordered) { 249 - /* track as an ordered logvec */ 250 - ASSERT(lip->li_lv == NULL); 251 - lv->lv_buf_len = XFS_LOG_VEC_ORDERED; 252 - goto insert; 253 - } 254 - 255 - /* The allocated iovec region lies beyond the log vector. */ 256 - lv->lv_iovecp = (struct xfs_log_iovec *)&lv[1]; 257 273 258 274 /* The allocated data region lies beyond the iovec region */ 275 + lv->lv_buf_len = 0; 259 276 lv->lv_buf = (char *)lv + buf_size - nbytes; 260 - 261 - lv->lv_buf_len = xlog_cil_lv_item_format(lip, lv); 277 + lip->li_ops->iop_format(lip, lv); 262 278 insert: 263 279 ASSERT(lv->lv_buf_len <= nbytes); 264 280 xfs_cil_prepare_item(log, lv, old_lv, diff_len, diff_iovecs);
+22 -11
fs/xfs/xfs_log_recover.c
··· 1654 1654 int pass) 1655 1655 { 1656 1656 xlog_recover_item_t *item, *n; 1657 + int error = 0; 1657 1658 LIST_HEAD(sort_list); 1658 1659 LIST_HEAD(cancel_list); 1659 1660 LIST_HEAD(buffer_list); ··· 1696 1695 "%s: unrecognized type of log operation", 1697 1696 __func__); 1698 1697 ASSERT(0); 1699 - return XFS_ERROR(EIO); 1698 + /* 1699 + * return the remaining items back to the transaction 1700 + * item list so they can be freed in caller. 1701 + */ 1702 + if (!list_empty(&sort_list)) 1703 + list_splice_init(&sort_list, &trans->r_itemq); 1704 + error = XFS_ERROR(EIO); 1705 + goto out; 1700 1706 } 1701 1707 } 1708 + out: 1702 1709 ASSERT(list_empty(&sort_list)); 1703 1710 if (!list_empty(&buffer_list)) 1704 1711 list_splice(&buffer_list, &trans->r_itemq); ··· 1716 1707 list_splice_tail(&inode_buffer_list, &trans->r_itemq); 1717 1708 if (!list_empty(&cancel_list)) 1718 1709 list_splice_tail(&cancel_list, &trans->r_itemq); 1719 - return 0; 1710 + return error; 1720 1711 } 1721 1712 1722 1713 /* ··· 2526 2517 * 2527 2518 * Also make sure that only inode buffers with good sizes stay in 2528 2519 * the buffer cache. The kernel moves inodes in buffers of 1 block 2529 - * or XFS_INODE_CLUSTER_SIZE bytes, whichever is bigger. The inode 2520 + * or mp->m_inode_cluster_size bytes, whichever is bigger. The inode 2530 2521 * buffers in the log can be a different size if the log was generated 2531 2522 * by an older kernel using unclustered inode buffers or a newer kernel 2532 2523 * running with a different inode cluster size. Regardless, if the 2533 - * the inode buffer size isn't MAX(blocksize, XFS_INODE_CLUSTER_SIZE) 2534 - * for *our* value of XFS_INODE_CLUSTER_SIZE, then we need to keep 2524 + * the inode buffer size isn't MAX(blocksize, mp->m_inode_cluster_size) 2525 + * for *our* value of mp->m_inode_cluster_size, then we need to keep 2535 2526 * the buffer out of the buffer cache so that the buffer won't 2536 2527 * overlap with future reads of those inodes. 2537 2528 */ 2538 2529 if (XFS_DINODE_MAGIC == 2539 2530 be16_to_cpu(*((__be16 *)xfs_buf_offset(bp, 0))) && 2540 2531 (BBTOB(bp->b_io_length) != MAX(log->l_mp->m_sb.sb_blocksize, 2541 - (__uint32_t)XFS_INODE_CLUSTER_SIZE(log->l_mp)))) { 2532 + (__uint32_t)log->l_mp->m_inode_cluster_size))) { 2542 2533 xfs_buf_stale(bp); 2543 2534 error = xfs_bwrite(bp); 2544 2535 } else { ··· 3211 3202 } 3212 3203 3213 3204 /* existing allocation is fixed value */ 3214 - ASSERT(count == XFS_IALLOC_INODES(mp)); 3215 - ASSERT(length == XFS_IALLOC_BLOCKS(mp)); 3216 - if (count != XFS_IALLOC_INODES(mp) || 3217 - length != XFS_IALLOC_BLOCKS(mp)) { 3205 + ASSERT(count == mp->m_ialloc_inos); 3206 + ASSERT(length == mp->m_ialloc_blks); 3207 + if (count != mp->m_ialloc_inos || 3208 + length != mp->m_ialloc_blks) { 3218 3209 xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad count 2"); 3219 3210 return EINVAL; 3220 3211 } ··· 3620 3611 error = XFS_ERROR(EIO); 3621 3612 break; 3622 3613 } 3623 - if (error) 3614 + if (error) { 3615 + xlog_recover_free_trans(trans); 3624 3616 return error; 3617 + } 3625 3618 } 3626 3619 dp += be32_to_cpu(ohead->oh_len); 3627 3620 num_logops--;
+4 -2
fs/xfs/xfs_qm.c
··· 1222 1222 lblkno = 0; 1223 1223 maxlblkcnt = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes); 1224 1224 do { 1225 + uint lock_mode; 1226 + 1225 1227 nmaps = XFS_DQITER_MAP_SIZE; 1226 1228 /* 1227 1229 * We aren't changing the inode itself. Just changing 1228 1230 * some of its data. No new blocks are added here, and 1229 1231 * the inode is never added to the transaction. 1230 1232 */ 1231 - xfs_ilock(qip, XFS_ILOCK_SHARED); 1233 + lock_mode = xfs_ilock_data_map_shared(qip); 1232 1234 error = xfs_bmapi_read(qip, lblkno, maxlblkcnt - lblkno, 1233 1235 map, &nmaps, 0); 1234 - xfs_iunlock(qip, XFS_ILOCK_SHARED); 1236 + xfs_iunlock(qip, lock_mode); 1235 1237 if (error) 1236 1238 break; 1237 1239
+17 -1
fs/xfs/xfs_qm.h
··· 20 20 21 21 #include "xfs_dquot_item.h" 22 22 #include "xfs_dquot.h" 23 - #include "xfs_quota_priv.h" 24 23 25 24 struct xfs_inode; 26 25 27 26 extern struct kmem_zone *xfs_qm_dqtrxzone; 27 + 28 + /* 29 + * Number of bmaps that we ask from bmapi when doing a quotacheck. 30 + * We make this restriction to keep the memory usage to a minimum. 31 + */ 32 + #define XFS_DQITER_MAP_SIZE 10 33 + 34 + #define XFS_IS_DQUOT_UNINITIALIZED(dqp) ( \ 35 + !dqp->q_core.d_blk_hardlimit && \ 36 + !dqp->q_core.d_blk_softlimit && \ 37 + !dqp->q_core.d_rtb_hardlimit && \ 38 + !dqp->q_core.d_rtb_softlimit && \ 39 + !dqp->q_core.d_ino_hardlimit && \ 40 + !dqp->q_core.d_ino_softlimit && \ 41 + !dqp->q_core.d_bcount && \ 42 + !dqp->q_core.d_rtbcount && \ 43 + !dqp->q_core.d_icount) 28 44 29 45 /* 30 46 * This defines the unit of allocation of dquots.
+12 -6
fs/xfs/xfs_qm_syscalls.c
··· 278 278 xfs_mount_t *mp, 279 279 uint flags) 280 280 { 281 - int error = 0, error2 = 0; 281 + int error; 282 282 283 283 if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0) { 284 284 xfs_debug(mp, "%s: flags=%x m_qflags=%x", ··· 286 286 return XFS_ERROR(EINVAL); 287 287 } 288 288 289 - if (flags & XFS_DQ_USER) 289 + if (flags & XFS_DQ_USER) { 290 290 error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_uquotino); 291 - if (flags & XFS_DQ_GROUP) 292 - error2 = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_gquotino); 291 + if (error) 292 + return error; 293 + } 294 + if (flags & XFS_DQ_GROUP) { 295 + error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_gquotino); 296 + if (error) 297 + return error; 298 + } 293 299 if (flags & XFS_DQ_PROJ) 294 - error2 = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_pquotino); 300 + error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_pquotino); 295 301 296 - return error ? error : error2; 302 + return error; 297 303 } 298 304 299 305 /*
-42
fs/xfs/xfs_quota_priv.h
··· 1 - /* 2 - * Copyright (c) 2000-2003 Silicon Graphics, Inc. 3 - * All Rights Reserved. 4 - * 5 - * This program is free software; you can redistribute it and/or 6 - * modify it under the terms of the GNU General Public License as 7 - * published by the Free Software Foundation. 8 - * 9 - * This program is distributed in the hope that it would be useful, 10 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - * GNU General Public License for more details. 13 - * 14 - * You should have received a copy of the GNU General Public License 15 - * along with this program; if not, write the Free Software Foundation, 16 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 - */ 18 - #ifndef __XFS_QUOTA_PRIV_H__ 19 - #define __XFS_QUOTA_PRIV_H__ 20 - 21 - /* 22 - * Number of bmaps that we ask from bmapi when doing a quotacheck. 23 - * We make this restriction to keep the memory usage to a minimum. 24 - */ 25 - #define XFS_DQITER_MAP_SIZE 10 26 - 27 - #define XFS_IS_DQUOT_UNINITIALIZED(dqp) ( \ 28 - !dqp->q_core.d_blk_hardlimit && \ 29 - !dqp->q_core.d_blk_softlimit && \ 30 - !dqp->q_core.d_rtb_hardlimit && \ 31 - !dqp->q_core.d_rtb_softlimit && \ 32 - !dqp->q_core.d_ino_hardlimit && \ 33 - !dqp->q_core.d_ino_softlimit && \ 34 - !dqp->q_core.d_bcount && \ 35 - !dqp->q_core.d_rtbcount && \ 36 - !dqp->q_core.d_icount) 37 - 38 - #define DQFLAGTO_TYPESTR(d) (((d)->dq_flags & XFS_DQ_USER) ? "USR" : \ 39 - (((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : \ 40 - (((d)->dq_flags & XFS_DQ_PROJ) ? "PRJ":"???"))) 41 - 42 - #endif /* __XFS_QUOTA_PRIV_H__ */
+1 -1
fs/xfs/xfs_trans.h
··· 64 64 65 65 struct xfs_item_ops { 66 66 void (*iop_size)(xfs_log_item_t *, int *, int *); 67 - void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *); 67 + void (*iop_format)(xfs_log_item_t *, struct xfs_log_vec *); 68 68 void (*iop_pin)(xfs_log_item_t *); 69 69 void (*iop_unpin)(xfs_log_item_t *, int remove); 70 70 uint (*iop_push)(struct xfs_log_item *, struct list_head *);
+2 -2
fs/xfs/xfs_trans_dquot.c
··· 295 295 /* 296 296 * Given an array of dqtrx structures, lock all the dquots associated and join 297 297 * them to the transaction, provided they have been modified. We know that the 298 - * highest number of dquots of one type - usr, grp OR prj - involved in a 299 - * transaction is 2 so we don't need to make this very generic. 298 + * highest number of dquots of one type - usr, grp and prj - involved in a 299 + * transaction is 3 so we don't need to make this very generic. 300 300 */ 301 301 STATIC void 302 302 xfs_trans_dqlockedjoin(
+5 -5
fs/xfs/xfs_trans_resv.c
··· 174 174 xfs_calc_buf_res(5, 0) + 175 175 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), 176 176 XFS_FSB_TO_B(mp, 1)) + 177 - xfs_calc_buf_res(2 + XFS_IALLOC_BLOCKS(mp) + 177 + xfs_calc_buf_res(2 + mp->m_ialloc_blks + 178 178 mp->m_in_maxlevels, 0))); 179 179 } 180 180 ··· 282 282 * For create we can allocate some inodes giving: 283 283 * the agi and agf of the ag getting the new inodes: 2 * sectorsize 284 284 * the superblock for the nlink flag: sector size 285 - * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize 285 + * the inode blocks allocated: mp->m_ialloc_blks * blocksize 286 286 * the inode btree: max depth * blocksize 287 287 * the allocation btrees: 2 trees * (max depth - 1) * block size 288 288 */ ··· 292 292 { 293 293 return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) + 294 294 mp->m_sb.sb_sectsize + 295 - xfs_calc_buf_res(XFS_IALLOC_BLOCKS(mp), XFS_FSB_TO_B(mp, 1)) + 295 + xfs_calc_buf_res(mp->m_ialloc_blks, XFS_FSB_TO_B(mp, 1)) + 296 296 xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) + 297 297 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), 298 298 XFS_FSB_TO_B(mp, 1)); ··· 385 385 xfs_calc_inode_res(mp, 1) + 386 386 xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) + 387 387 xfs_calc_buf_res(1, XFS_FSB_TO_B(mp, 1)) + 388 - max_t(uint, XFS_FSB_TO_B(mp, 1), XFS_INODE_CLUSTER_SIZE(mp)) + 388 + max_t(uint, XFS_FSB_TO_B(mp, 1), mp->m_inode_cluster_size) + 389 389 xfs_calc_buf_res(1, 0) + 390 - xfs_calc_buf_res(2 + XFS_IALLOC_BLOCKS(mp) + 390 + xfs_calc_buf_res(2 + mp->m_ialloc_blks + 391 391 mp->m_in_maxlevels, 0) + 392 392 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), 393 393 XFS_FSB_TO_B(mp, 1));
+1 -1
fs/xfs/xfs_trans_space.h
··· 47 47 #define XFS_DIRREMOVE_SPACE_RES(mp) \ 48 48 XFS_DAREMOVE_SPACE_RES(mp, XFS_DATA_FORK) 49 49 #define XFS_IALLOC_SPACE_RES(mp) \ 50 - (XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels - 1) 50 + ((mp)->m_ialloc_blks + (mp)->m_in_maxlevels - 1) 51 51 52 52 /* 53 53 * Space reservation values for various transactions.
-9
fs/xfs/xfs_vnode.h
··· 35 35 { IO_INVIS, "INVIS"} 36 36 37 37 /* 38 - * Flush/Invalidate options for vop_toss/flush/flushinval_pages. 39 - */ 40 - #define FI_NONE 0 /* none */ 41 - #define FI_REMAPF 1 /* Do a remapf prior to the operation */ 42 - #define FI_REMAPF_LOCKED 2 /* Do a remapf prior to the operation. 43 - Prevent VM access to the pages until 44 - the operation completes. */ 45 - 46 - /* 47 38 * Some useful predicates. 48 39 */ 49 40 #define VN_MAPPED(vp) mapping_mapped(vp->i_mapping)