diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-30 16:37:53 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-30 16:37:53 -0400 |
commit | 37cd9600a9e20359b0283983c9e3a55d84347168 (patch) | |
tree | fea12ce0ecbaf417b0d835b3cbee14e973103fad | |
parent | 95b18e69950ca7fd9acfa55964e929f58bec9379 (diff) | |
parent | 9a57fa8ee7c29e11c2a29ce058573ba99157eda7 (diff) |
Merge tag 'for-linus-v3.6-rc1' of git://oss.sgi.com/xfs/xfs
Pull xfs update from Ben Myers:
"Numerous cleanups and several bug fixes. Here are some highlights:
- Discontiguous directory buffer support
- Inode allocator refactoring
- Removal of the IO lock in inode reclaim
- Implementation of .update_time
- Fix for handling of EOF in xfs_vm_writepage
- Fix for races in xfsaild, and idle mode is re-enabled
- Fix for a crash in xfs_buf completion handlers on unmount."
Fix up trivial conflicts in fs/xfs/{xfs_buf.c,xfs_log.c,xfs_log_priv.h}
due to duplicate patches that had already been merged for 3.5.
* tag 'for-linus-v3.6-rc1' of git://oss.sgi.com/xfs/xfs: (44 commits)
xfs: wait for the write the superblock on unmount
xfs: re-enable xfsaild idle mode and fix associated races
xfs: remove iolock lock classes
xfs: avoid the iolock in xfs_free_eofblocks for evicted inodes
xfs: do not take the iolock in xfs_inactive
xfs: remove xfs_inactive_attrs
xfs: clean up xfs_inactive
xfs: do not read the AGI buffer in xfs_dialloc until nessecary
xfs: refactor xfs_ialloc_ag_select
xfs: add a short cut to xfs_dialloc for the non-NULL agbp case
xfs: remove the alloc_done argument to xfs_dialloc
xfs: split xfs_dialloc
xfs: remove xfs_ialloc_find_free
Prefix IO_XX flags with XFS_IO_XX to avoid namespace colision.
xfs: remove xfs_inotobp
xfs: merge xfs_itobp into xfs_imap_to_bp
xfs: handle EOF correctly in xfs_vm_writepage
xfs: implement ->update_time
xfs: fix comment typo of struct xfs_da_blkinfo.
xfs: do not call xfs_bdstrat_cb in xfs_buf_iodone_callbacks
...
46 files changed, 2457 insertions, 2415 deletions
diff --git a/fs/xfs/xfs_alloc_btree.h b/fs/xfs/xfs_alloc_btree.h index a6caa0022c9b..359fb86ed876 100644 --- a/fs/xfs/xfs_alloc_btree.h +++ b/fs/xfs/xfs_alloc_btree.h | |||
@@ -51,20 +51,6 @@ typedef struct xfs_alloc_rec_incore { | |||
51 | typedef __be32 xfs_alloc_ptr_t; | 51 | typedef __be32 xfs_alloc_ptr_t; |
52 | 52 | ||
53 | /* | 53 | /* |
54 | * Minimum and maximum blocksize and sectorsize. | ||
55 | * The blocksize upper limit is pretty much arbitrary. | ||
56 | * The sectorsize upper limit is due to sizeof(sb_sectsize). | ||
57 | */ | ||
58 | #define XFS_MIN_BLOCKSIZE_LOG 9 /* i.e. 512 bytes */ | ||
59 | #define XFS_MAX_BLOCKSIZE_LOG 16 /* i.e. 65536 bytes */ | ||
60 | #define XFS_MIN_BLOCKSIZE (1 << XFS_MIN_BLOCKSIZE_LOG) | ||
61 | #define XFS_MAX_BLOCKSIZE (1 << XFS_MAX_BLOCKSIZE_LOG) | ||
62 | #define XFS_MIN_SECTORSIZE_LOG 9 /* i.e. 512 bytes */ | ||
63 | #define XFS_MAX_SECTORSIZE_LOG 15 /* i.e. 32768 bytes */ | ||
64 | #define XFS_MIN_SECTORSIZE (1 << XFS_MIN_SECTORSIZE_LOG) | ||
65 | #define XFS_MAX_SECTORSIZE (1 << XFS_MAX_SECTORSIZE_LOG) | ||
66 | |||
67 | /* | ||
68 | * Block numbers in the AG: | 54 | * Block numbers in the AG: |
69 | * SB is sector 0, AGF is sector 1, AGI is sector 2, AGFL is sector 3. | 55 | * SB is sector 0, AGF is sector 1, AGI is sector 2, AGFL is sector 3. |
70 | */ | 56 | */ |
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 8dad722c0041..15052ff916ec 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c | |||
@@ -179,7 +179,7 @@ xfs_finish_ioend( | |||
179 | if (atomic_dec_and_test(&ioend->io_remaining)) { | 179 | if (atomic_dec_and_test(&ioend->io_remaining)) { |
180 | struct xfs_mount *mp = XFS_I(ioend->io_inode)->i_mount; | 180 | struct xfs_mount *mp = XFS_I(ioend->io_inode)->i_mount; |
181 | 181 | ||
182 | if (ioend->io_type == IO_UNWRITTEN) | 182 | if (ioend->io_type == XFS_IO_UNWRITTEN) |
183 | queue_work(mp->m_unwritten_workqueue, &ioend->io_work); | 183 | queue_work(mp->m_unwritten_workqueue, &ioend->io_work); |
184 | else if (ioend->io_append_trans) | 184 | else if (ioend->io_append_trans) |
185 | queue_work(mp->m_data_workqueue, &ioend->io_work); | 185 | queue_work(mp->m_data_workqueue, &ioend->io_work); |
@@ -210,7 +210,7 @@ xfs_end_io( | |||
210 | * For unwritten extents we need to issue transactions to convert a | 210 | * For unwritten extents we need to issue transactions to convert a |
211 | * range to normal written extens after the data I/O has finished. | 211 | * range to normal written extens after the data I/O has finished. |
212 | */ | 212 | */ |
213 | if (ioend->io_type == IO_UNWRITTEN) { | 213 | if (ioend->io_type == XFS_IO_UNWRITTEN) { |
214 | /* | 214 | /* |
215 | * For buffered I/O we never preallocate a transaction when | 215 | * For buffered I/O we never preallocate a transaction when |
216 | * doing the unwritten extent conversion, but for direct I/O | 216 | * doing the unwritten extent conversion, but for direct I/O |
@@ -312,7 +312,7 @@ xfs_map_blocks( | |||
312 | if (XFS_FORCED_SHUTDOWN(mp)) | 312 | if (XFS_FORCED_SHUTDOWN(mp)) |
313 | return -XFS_ERROR(EIO); | 313 | return -XFS_ERROR(EIO); |
314 | 314 | ||
315 | if (type == IO_UNWRITTEN) | 315 | if (type == XFS_IO_UNWRITTEN) |
316 | bmapi_flags |= XFS_BMAPI_IGSTATE; | 316 | bmapi_flags |= XFS_BMAPI_IGSTATE; |
317 | 317 | ||
318 | if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) { | 318 | if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) { |
@@ -323,10 +323,10 @@ xfs_map_blocks( | |||
323 | 323 | ||
324 | ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || | 324 | ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || |
325 | (ip->i_df.if_flags & XFS_IFEXTENTS)); | 325 | (ip->i_df.if_flags & XFS_IFEXTENTS)); |
326 | ASSERT(offset <= mp->m_maxioffset); | 326 | ASSERT(offset <= mp->m_super->s_maxbytes); |
327 | 327 | ||
328 | if (offset + count > mp->m_maxioffset) | 328 | if (offset + count > mp->m_super->s_maxbytes) |
329 | count = mp->m_maxioffset - offset; | 329 | count = mp->m_super->s_maxbytes - offset; |
330 | end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); | 330 | end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); |
331 | offset_fsb = XFS_B_TO_FSBT(mp, offset); | 331 | offset_fsb = XFS_B_TO_FSBT(mp, offset); |
332 | error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, | 332 | error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, |
@@ -336,7 +336,7 @@ xfs_map_blocks( | |||
336 | if (error) | 336 | if (error) |
337 | return -XFS_ERROR(error); | 337 | return -XFS_ERROR(error); |
338 | 338 | ||
339 | if (type == IO_DELALLOC && | 339 | if (type == XFS_IO_DELALLOC && |
340 | (!nimaps || isnullstartblock(imap->br_startblock))) { | 340 | (!nimaps || isnullstartblock(imap->br_startblock))) { |
341 | error = xfs_iomap_write_allocate(ip, offset, count, imap); | 341 | error = xfs_iomap_write_allocate(ip, offset, count, imap); |
342 | if (!error) | 342 | if (!error) |
@@ -345,7 +345,7 @@ xfs_map_blocks( | |||
345 | } | 345 | } |
346 | 346 | ||
347 | #ifdef DEBUG | 347 | #ifdef DEBUG |
348 | if (type == IO_UNWRITTEN) { | 348 | if (type == XFS_IO_UNWRITTEN) { |
349 | ASSERT(nimaps); | 349 | ASSERT(nimaps); |
350 | ASSERT(imap->br_startblock != HOLESTARTBLOCK); | 350 | ASSERT(imap->br_startblock != HOLESTARTBLOCK); |
351 | ASSERT(imap->br_startblock != DELAYSTARTBLOCK); | 351 | ASSERT(imap->br_startblock != DELAYSTARTBLOCK); |
@@ -634,11 +634,11 @@ xfs_check_page_type( | |||
634 | bh = head = page_buffers(page); | 634 | bh = head = page_buffers(page); |
635 | do { | 635 | do { |
636 | if (buffer_unwritten(bh)) | 636 | if (buffer_unwritten(bh)) |
637 | acceptable += (type == IO_UNWRITTEN); | 637 | acceptable += (type == XFS_IO_UNWRITTEN); |
638 | else if (buffer_delay(bh)) | 638 | else if (buffer_delay(bh)) |
639 | acceptable += (type == IO_DELALLOC); | 639 | acceptable += (type == XFS_IO_DELALLOC); |
640 | else if (buffer_dirty(bh) && buffer_mapped(bh)) | 640 | else if (buffer_dirty(bh) && buffer_mapped(bh)) |
641 | acceptable += (type == IO_OVERWRITE); | 641 | acceptable += (type == XFS_IO_OVERWRITE); |
642 | else | 642 | else |
643 | break; | 643 | break; |
644 | } while ((bh = bh->b_this_page) != head); | 644 | } while ((bh = bh->b_this_page) != head); |
@@ -721,11 +721,11 @@ xfs_convert_page( | |||
721 | if (buffer_unwritten(bh) || buffer_delay(bh) || | 721 | if (buffer_unwritten(bh) || buffer_delay(bh) || |
722 | buffer_mapped(bh)) { | 722 | buffer_mapped(bh)) { |
723 | if (buffer_unwritten(bh)) | 723 | if (buffer_unwritten(bh)) |
724 | type = IO_UNWRITTEN; | 724 | type = XFS_IO_UNWRITTEN; |
725 | else if (buffer_delay(bh)) | 725 | else if (buffer_delay(bh)) |
726 | type = IO_DELALLOC; | 726 | type = XFS_IO_DELALLOC; |
727 | else | 727 | else |
728 | type = IO_OVERWRITE; | 728 | type = XFS_IO_OVERWRITE; |
729 | 729 | ||
730 | if (!xfs_imap_valid(inode, imap, offset)) { | 730 | if (!xfs_imap_valid(inode, imap, offset)) { |
731 | done = 1; | 731 | done = 1; |
@@ -733,7 +733,7 @@ xfs_convert_page( | |||
733 | } | 733 | } |
734 | 734 | ||
735 | lock_buffer(bh); | 735 | lock_buffer(bh); |
736 | if (type != IO_OVERWRITE) | 736 | if (type != XFS_IO_OVERWRITE) |
737 | xfs_map_at_offset(inode, bh, imap, offset); | 737 | xfs_map_at_offset(inode, bh, imap, offset); |
738 | xfs_add_to_ioend(inode, bh, offset, type, | 738 | xfs_add_to_ioend(inode, bh, offset, type, |
739 | ioendp, done); | 739 | ioendp, done); |
@@ -831,7 +831,7 @@ xfs_aops_discard_page( | |||
831 | struct buffer_head *bh, *head; | 831 | struct buffer_head *bh, *head; |
832 | loff_t offset = page_offset(page); | 832 | loff_t offset = page_offset(page); |
833 | 833 | ||
834 | if (!xfs_check_page_type(page, IO_DELALLOC)) | 834 | if (!xfs_check_page_type(page, XFS_IO_DELALLOC)) |
835 | goto out_invalidate; | 835 | goto out_invalidate; |
836 | 836 | ||
837 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) | 837 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) |
@@ -927,11 +927,26 @@ xfs_vm_writepage( | |||
927 | end_index = offset >> PAGE_CACHE_SHIFT; | 927 | end_index = offset >> PAGE_CACHE_SHIFT; |
928 | last_index = (offset - 1) >> PAGE_CACHE_SHIFT; | 928 | last_index = (offset - 1) >> PAGE_CACHE_SHIFT; |
929 | if (page->index >= end_index) { | 929 | if (page->index >= end_index) { |
930 | if ((page->index >= end_index + 1) || | 930 | unsigned offset_into_page = offset & (PAGE_CACHE_SIZE - 1); |
931 | !(i_size_read(inode) & (PAGE_CACHE_SIZE - 1))) { | 931 | |
932 | /* | ||
933 | * Just skip the page if it is fully outside i_size, e.g. due | ||
934 | * to a truncate operation that is in progress. | ||
935 | */ | ||
936 | if (page->index >= end_index + 1 || offset_into_page == 0) { | ||
932 | unlock_page(page); | 937 | unlock_page(page); |
933 | return 0; | 938 | return 0; |
934 | } | 939 | } |
940 | |||
941 | /* | ||
942 | * The page straddles i_size. It must be zeroed out on each | ||
943 | * and every writepage invocation because it may be mmapped. | ||
944 | * "A file is mapped in multiples of the page size. For a file | ||
945 | * that is not a multiple of the page size, the remaining | ||
946 | * memory is zeroed when mapped, and writes to that region are | ||
947 | * not written out to the file." | ||
948 | */ | ||
949 | zero_user_segment(page, offset_into_page, PAGE_CACHE_SIZE); | ||
935 | } | 950 | } |
936 | 951 | ||
937 | end_offset = min_t(unsigned long long, | 952 | end_offset = min_t(unsigned long long, |
@@ -941,7 +956,7 @@ xfs_vm_writepage( | |||
941 | 956 | ||
942 | bh = head = page_buffers(page); | 957 | bh = head = page_buffers(page); |
943 | offset = page_offset(page); | 958 | offset = page_offset(page); |
944 | type = IO_OVERWRITE; | 959 | type = XFS_IO_OVERWRITE; |
945 | 960 | ||
946 | if (wbc->sync_mode == WB_SYNC_NONE) | 961 | if (wbc->sync_mode == WB_SYNC_NONE) |
947 | nonblocking = 1; | 962 | nonblocking = 1; |
@@ -966,18 +981,18 @@ xfs_vm_writepage( | |||
966 | } | 981 | } |
967 | 982 | ||
968 | if (buffer_unwritten(bh)) { | 983 | if (buffer_unwritten(bh)) { |
969 | if (type != IO_UNWRITTEN) { | 984 | if (type != XFS_IO_UNWRITTEN) { |
970 | type = IO_UNWRITTEN; | 985 | type = XFS_IO_UNWRITTEN; |
971 | imap_valid = 0; | 986 | imap_valid = 0; |
972 | } | 987 | } |
973 | } else if (buffer_delay(bh)) { | 988 | } else if (buffer_delay(bh)) { |
974 | if (type != IO_DELALLOC) { | 989 | if (type != XFS_IO_DELALLOC) { |
975 | type = IO_DELALLOC; | 990 | type = XFS_IO_DELALLOC; |
976 | imap_valid = 0; | 991 | imap_valid = 0; |
977 | } | 992 | } |
978 | } else if (buffer_uptodate(bh)) { | 993 | } else if (buffer_uptodate(bh)) { |
979 | if (type != IO_OVERWRITE) { | 994 | if (type != XFS_IO_OVERWRITE) { |
980 | type = IO_OVERWRITE; | 995 | type = XFS_IO_OVERWRITE; |
981 | imap_valid = 0; | 996 | imap_valid = 0; |
982 | } | 997 | } |
983 | } else { | 998 | } else { |
@@ -1013,7 +1028,7 @@ xfs_vm_writepage( | |||
1013 | } | 1028 | } |
1014 | if (imap_valid) { | 1029 | if (imap_valid) { |
1015 | lock_buffer(bh); | 1030 | lock_buffer(bh); |
1016 | if (type != IO_OVERWRITE) | 1031 | if (type != XFS_IO_OVERWRITE) |
1017 | xfs_map_at_offset(inode, bh, &imap, offset); | 1032 | xfs_map_at_offset(inode, bh, &imap, offset); |
1018 | xfs_add_to_ioend(inode, bh, offset, type, &ioend, | 1033 | xfs_add_to_ioend(inode, bh, offset, type, &ioend, |
1019 | new_ioend); | 1034 | new_ioend); |
@@ -1054,7 +1069,7 @@ xfs_vm_writepage( | |||
1054 | * Reserve log space if we might write beyond the on-disk | 1069 | * Reserve log space if we might write beyond the on-disk |
1055 | * inode size. | 1070 | * inode size. |
1056 | */ | 1071 | */ |
1057 | if (ioend->io_type != IO_UNWRITTEN && | 1072 | if (ioend->io_type != XFS_IO_UNWRITTEN && |
1058 | xfs_ioend_is_append(ioend)) { | 1073 | xfs_ioend_is_append(ioend)) { |
1059 | err = xfs_setfilesize_trans_alloc(ioend); | 1074 | err = xfs_setfilesize_trans_alloc(ioend); |
1060 | if (err) | 1075 | if (err) |
@@ -1162,9 +1177,9 @@ __xfs_get_blocks( | |||
1162 | lockmode = xfs_ilock_map_shared(ip); | 1177 | lockmode = xfs_ilock_map_shared(ip); |
1163 | } | 1178 | } |
1164 | 1179 | ||
1165 | ASSERT(offset <= mp->m_maxioffset); | 1180 | ASSERT(offset <= mp->m_super->s_maxbytes); |
1166 | if (offset + size > mp->m_maxioffset) | 1181 | if (offset + size > mp->m_super->s_maxbytes) |
1167 | size = mp->m_maxioffset - offset; | 1182 | size = mp->m_super->s_maxbytes - offset; |
1168 | end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + size); | 1183 | end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + size); |
1169 | offset_fsb = XFS_B_TO_FSBT(mp, offset); | 1184 | offset_fsb = XFS_B_TO_FSBT(mp, offset); |
1170 | 1185 | ||
@@ -1351,7 +1366,7 @@ xfs_end_io_direct_write( | |||
1351 | ioend->io_iocb = iocb; | 1366 | ioend->io_iocb = iocb; |
1352 | ioend->io_result = ret; | 1367 | ioend->io_result = ret; |
1353 | if (private && size > 0) | 1368 | if (private && size > 0) |
1354 | ioend->io_type = IO_UNWRITTEN; | 1369 | ioend->io_type = XFS_IO_UNWRITTEN; |
1355 | 1370 | ||
1356 | if (is_async) { | 1371 | if (is_async) { |
1357 | ioend->io_isasync = 1; | 1372 | ioend->io_isasync = 1; |
@@ -1383,7 +1398,7 @@ xfs_vm_direct_IO( | |||
1383 | * and converts at least on unwritten extent we will cancel | 1398 | * and converts at least on unwritten extent we will cancel |
1384 | * the still clean transaction after the I/O has finished. | 1399 | * the still clean transaction after the I/O has finished. |
1385 | */ | 1400 | */ |
1386 | iocb->private = ioend = xfs_alloc_ioend(inode, IO_DIRECT); | 1401 | iocb->private = ioend = xfs_alloc_ioend(inode, XFS_IO_DIRECT); |
1387 | if (offset + size > XFS_I(inode)->i_d.di_size) { | 1402 | if (offset + size > XFS_I(inode)->i_d.di_size) { |
1388 | ret = xfs_setfilesize_trans_alloc(ioend); | 1403 | ret = xfs_setfilesize_trans_alloc(ioend); |
1389 | if (ret) | 1404 | if (ret) |
diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h index 84eafbcb0d9d..c325abb8d61a 100644 --- a/fs/xfs/xfs_aops.h +++ b/fs/xfs/xfs_aops.h | |||
@@ -24,17 +24,17 @@ extern mempool_t *xfs_ioend_pool; | |||
24 | * Types of I/O for bmap clustering and I/O completion tracking. | 24 | * Types of I/O for bmap clustering and I/O completion tracking. |
25 | */ | 25 | */ |
26 | enum { | 26 | enum { |
27 | IO_DIRECT = 0, /* special case for direct I/O ioends */ | 27 | XFS_IO_DIRECT = 0, /* special case for direct I/O ioends */ |
28 | IO_DELALLOC, /* mapping covers delalloc region */ | 28 | XFS_IO_DELALLOC, /* covers delalloc region */ |
29 | IO_UNWRITTEN, /* mapping covers allocated but uninitialized data */ | 29 | XFS_IO_UNWRITTEN, /* covers allocated but uninitialized data */ |
30 | IO_OVERWRITE, /* mapping covers already allocated extent */ | 30 | XFS_IO_OVERWRITE, /* covers already allocated extent */ |
31 | }; | 31 | }; |
32 | 32 | ||
33 | #define XFS_IO_TYPES \ | 33 | #define XFS_IO_TYPES \ |
34 | { 0, "" }, \ | 34 | { 0, "" }, \ |
35 | { IO_DELALLOC, "delalloc" }, \ | 35 | { XFS_IO_DELALLOC, "delalloc" }, \ |
36 | { IO_UNWRITTEN, "unwritten" }, \ | 36 | { XFS_IO_UNWRITTEN, "unwritten" }, \ |
37 | { IO_OVERWRITE, "overwrite" } | 37 | { XFS_IO_OVERWRITE, "overwrite" } |
38 | 38 | ||
39 | /* | 39 | /* |
40 | * xfs_ioend struct manages large extent writes for XFS. | 40 | * xfs_ioend struct manages large extent writes for XFS. |
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index a17ff01b5adf..0ca1f0be62d2 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c | |||
@@ -893,7 +893,7 @@ STATIC int | |||
893 | xfs_attr_leaf_addname(xfs_da_args_t *args) | 893 | xfs_attr_leaf_addname(xfs_da_args_t *args) |
894 | { | 894 | { |
895 | xfs_inode_t *dp; | 895 | xfs_inode_t *dp; |
896 | xfs_dabuf_t *bp; | 896 | struct xfs_buf *bp; |
897 | int retval, error, committed, forkoff; | 897 | int retval, error, committed, forkoff; |
898 | 898 | ||
899 | trace_xfs_attr_leaf_addname(args); | 899 | trace_xfs_attr_leaf_addname(args); |
@@ -915,11 +915,11 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) | |||
915 | */ | 915 | */ |
916 | retval = xfs_attr_leaf_lookup_int(bp, args); | 916 | retval = xfs_attr_leaf_lookup_int(bp, args); |
917 | if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) { | 917 | if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) { |
918 | xfs_da_brelse(args->trans, bp); | 918 | xfs_trans_brelse(args->trans, bp); |
919 | return(retval); | 919 | return(retval); |
920 | } else if (retval == EEXIST) { | 920 | } else if (retval == EEXIST) { |
921 | if (args->flags & ATTR_CREATE) { /* pure create op */ | 921 | if (args->flags & ATTR_CREATE) { /* pure create op */ |
922 | xfs_da_brelse(args->trans, bp); | 922 | xfs_trans_brelse(args->trans, bp); |
923 | return(retval); | 923 | return(retval); |
924 | } | 924 | } |
925 | 925 | ||
@@ -937,7 +937,6 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) | |||
937 | * if required. | 937 | * if required. |
938 | */ | 938 | */ |
939 | retval = xfs_attr_leaf_add(bp, args); | 939 | retval = xfs_attr_leaf_add(bp, args); |
940 | xfs_da_buf_done(bp); | ||
941 | if (retval == ENOSPC) { | 940 | if (retval == ENOSPC) { |
942 | /* | 941 | /* |
943 | * Promote the attribute list to the Btree format, then | 942 | * Promote the attribute list to the Btree format, then |
@@ -1065,8 +1064,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) | |||
1065 | */ | 1064 | */ |
1066 | if (committed) | 1065 | if (committed) |
1067 | xfs_trans_ijoin(args->trans, dp, 0); | 1066 | xfs_trans_ijoin(args->trans, dp, 0); |
1068 | } else | 1067 | } |
1069 | xfs_da_buf_done(bp); | ||
1070 | 1068 | ||
1071 | /* | 1069 | /* |
1072 | * Commit the remove and start the next trans in series. | 1070 | * Commit the remove and start the next trans in series. |
@@ -1092,7 +1090,7 @@ STATIC int | |||
1092 | xfs_attr_leaf_removename(xfs_da_args_t *args) | 1090 | xfs_attr_leaf_removename(xfs_da_args_t *args) |
1093 | { | 1091 | { |
1094 | xfs_inode_t *dp; | 1092 | xfs_inode_t *dp; |
1095 | xfs_dabuf_t *bp; | 1093 | struct xfs_buf *bp; |
1096 | int error, committed, forkoff; | 1094 | int error, committed, forkoff; |
1097 | 1095 | ||
1098 | trace_xfs_attr_leaf_removename(args); | 1096 | trace_xfs_attr_leaf_removename(args); |
@@ -1111,7 +1109,7 @@ xfs_attr_leaf_removename(xfs_da_args_t *args) | |||
1111 | ASSERT(bp != NULL); | 1109 | ASSERT(bp != NULL); |
1112 | error = xfs_attr_leaf_lookup_int(bp, args); | 1110 | error = xfs_attr_leaf_lookup_int(bp, args); |
1113 | if (error == ENOATTR) { | 1111 | if (error == ENOATTR) { |
1114 | xfs_da_brelse(args->trans, bp); | 1112 | xfs_trans_brelse(args->trans, bp); |
1115 | return(error); | 1113 | return(error); |
1116 | } | 1114 | } |
1117 | 1115 | ||
@@ -1141,8 +1139,7 @@ xfs_attr_leaf_removename(xfs_da_args_t *args) | |||
1141 | */ | 1139 | */ |
1142 | if (committed) | 1140 | if (committed) |
1143 | xfs_trans_ijoin(args->trans, dp, 0); | 1141 | xfs_trans_ijoin(args->trans, dp, 0); |
1144 | } else | 1142 | } |
1145 | xfs_da_buf_done(bp); | ||
1146 | return(0); | 1143 | return(0); |
1147 | } | 1144 | } |
1148 | 1145 | ||
@@ -1155,7 +1152,7 @@ xfs_attr_leaf_removename(xfs_da_args_t *args) | |||
1155 | STATIC int | 1152 | STATIC int |
1156 | xfs_attr_leaf_get(xfs_da_args_t *args) | 1153 | xfs_attr_leaf_get(xfs_da_args_t *args) |
1157 | { | 1154 | { |
1158 | xfs_dabuf_t *bp; | 1155 | struct xfs_buf *bp; |
1159 | int error; | 1156 | int error; |
1160 | 1157 | ||
1161 | args->blkno = 0; | 1158 | args->blkno = 0; |
@@ -1167,11 +1164,11 @@ xfs_attr_leaf_get(xfs_da_args_t *args) | |||
1167 | 1164 | ||
1168 | error = xfs_attr_leaf_lookup_int(bp, args); | 1165 | error = xfs_attr_leaf_lookup_int(bp, args); |
1169 | if (error != EEXIST) { | 1166 | if (error != EEXIST) { |
1170 | xfs_da_brelse(args->trans, bp); | 1167 | xfs_trans_brelse(args->trans, bp); |
1171 | return(error); | 1168 | return(error); |
1172 | } | 1169 | } |
1173 | error = xfs_attr_leaf_getvalue(bp, args); | 1170 | error = xfs_attr_leaf_getvalue(bp, args); |
1174 | xfs_da_brelse(args->trans, bp); | 1171 | xfs_trans_brelse(args->trans, bp); |
1175 | if (!error && (args->rmtblkno > 0) && !(args->flags & ATTR_KERNOVAL)) { | 1172 | if (!error && (args->rmtblkno > 0) && !(args->flags & ATTR_KERNOVAL)) { |
1176 | error = xfs_attr_rmtval_get(args); | 1173 | error = xfs_attr_rmtval_get(args); |
1177 | } | 1174 | } |
@@ -1186,23 +1183,23 @@ xfs_attr_leaf_list(xfs_attr_list_context_t *context) | |||
1186 | { | 1183 | { |
1187 | xfs_attr_leafblock_t *leaf; | 1184 | xfs_attr_leafblock_t *leaf; |
1188 | int error; | 1185 | int error; |
1189 | xfs_dabuf_t *bp; | 1186 | struct xfs_buf *bp; |
1190 | 1187 | ||
1191 | context->cursor->blkno = 0; | 1188 | context->cursor->blkno = 0; |
1192 | error = xfs_da_read_buf(NULL, context->dp, 0, -1, &bp, XFS_ATTR_FORK); | 1189 | error = xfs_da_read_buf(NULL, context->dp, 0, -1, &bp, XFS_ATTR_FORK); |
1193 | if (error) | 1190 | if (error) |
1194 | return XFS_ERROR(error); | 1191 | return XFS_ERROR(error); |
1195 | ASSERT(bp != NULL); | 1192 | ASSERT(bp != NULL); |
1196 | leaf = bp->data; | 1193 | leaf = bp->b_addr; |
1197 | if (unlikely(leaf->hdr.info.magic != cpu_to_be16(XFS_ATTR_LEAF_MAGIC))) { | 1194 | if (unlikely(leaf->hdr.info.magic != cpu_to_be16(XFS_ATTR_LEAF_MAGIC))) { |
1198 | XFS_CORRUPTION_ERROR("xfs_attr_leaf_list", XFS_ERRLEVEL_LOW, | 1195 | XFS_CORRUPTION_ERROR("xfs_attr_leaf_list", XFS_ERRLEVEL_LOW, |
1199 | context->dp->i_mount, leaf); | 1196 | context->dp->i_mount, leaf); |
1200 | xfs_da_brelse(NULL, bp); | 1197 | xfs_trans_brelse(NULL, bp); |
1201 | return XFS_ERROR(EFSCORRUPTED); | 1198 | return XFS_ERROR(EFSCORRUPTED); |
1202 | } | 1199 | } |
1203 | 1200 | ||
1204 | error = xfs_attr_leaf_list_int(bp, context); | 1201 | error = xfs_attr_leaf_list_int(bp, context); |
1205 | xfs_da_brelse(NULL, bp); | 1202 | xfs_trans_brelse(NULL, bp); |
1206 | return XFS_ERROR(error); | 1203 | return XFS_ERROR(error); |
1207 | } | 1204 | } |
1208 | 1205 | ||
@@ -1489,7 +1486,7 @@ xfs_attr_node_removename(xfs_da_args_t *args) | |||
1489 | xfs_da_state_t *state; | 1486 | xfs_da_state_t *state; |
1490 | xfs_da_state_blk_t *blk; | 1487 | xfs_da_state_blk_t *blk; |
1491 | xfs_inode_t *dp; | 1488 | xfs_inode_t *dp; |
1492 | xfs_dabuf_t *bp; | 1489 | struct xfs_buf *bp; |
1493 | int retval, error, committed, forkoff; | 1490 | int retval, error, committed, forkoff; |
1494 | 1491 | ||
1495 | trace_xfs_attr_node_removename(args); | 1492 | trace_xfs_attr_node_removename(args); |
@@ -1601,14 +1598,13 @@ xfs_attr_node_removename(xfs_da_args_t *args) | |||
1601 | */ | 1598 | */ |
1602 | ASSERT(state->path.active == 1); | 1599 | ASSERT(state->path.active == 1); |
1603 | ASSERT(state->path.blk[0].bp); | 1600 | ASSERT(state->path.blk[0].bp); |
1604 | xfs_da_buf_done(state->path.blk[0].bp); | ||
1605 | state->path.blk[0].bp = NULL; | 1601 | state->path.blk[0].bp = NULL; |
1606 | 1602 | ||
1607 | error = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp, | 1603 | error = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp, |
1608 | XFS_ATTR_FORK); | 1604 | XFS_ATTR_FORK); |
1609 | if (error) | 1605 | if (error) |
1610 | goto out; | 1606 | goto out; |
1611 | ASSERT((((xfs_attr_leafblock_t *)bp->data)->hdr.info.magic) == | 1607 | ASSERT((((xfs_attr_leafblock_t *)bp->b_addr)->hdr.info.magic) == |
1612 | cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); | 1608 | cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); |
1613 | 1609 | ||
1614 | if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { | 1610 | if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { |
@@ -1635,7 +1631,7 @@ xfs_attr_node_removename(xfs_da_args_t *args) | |||
1635 | if (committed) | 1631 | if (committed) |
1636 | xfs_trans_ijoin(args->trans, dp, 0); | 1632 | xfs_trans_ijoin(args->trans, dp, 0); |
1637 | } else | 1633 | } else |
1638 | xfs_da_brelse(args->trans, bp); | 1634 | xfs_trans_brelse(args->trans, bp); |
1639 | } | 1635 | } |
1640 | error = 0; | 1636 | error = 0; |
1641 | 1637 | ||
@@ -1665,8 +1661,7 @@ xfs_attr_fillstate(xfs_da_state_t *state) | |||
1665 | ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH)); | 1661 | ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH)); |
1666 | for (blk = path->blk, level = 0; level < path->active; blk++, level++) { | 1662 | for (blk = path->blk, level = 0; level < path->active; blk++, level++) { |
1667 | if (blk->bp) { | 1663 | if (blk->bp) { |
1668 | blk->disk_blkno = xfs_da_blkno(blk->bp); | 1664 | blk->disk_blkno = XFS_BUF_ADDR(blk->bp); |
1669 | xfs_da_buf_done(blk->bp); | ||
1670 | blk->bp = NULL; | 1665 | blk->bp = NULL; |
1671 | } else { | 1666 | } else { |
1672 | blk->disk_blkno = 0; | 1667 | blk->disk_blkno = 0; |
@@ -1681,8 +1676,7 @@ xfs_attr_fillstate(xfs_da_state_t *state) | |||
1681 | ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH)); | 1676 | ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH)); |
1682 | for (blk = path->blk, level = 0; level < path->active; blk++, level++) { | 1677 | for (blk = path->blk, level = 0; level < path->active; blk++, level++) { |
1683 | if (blk->bp) { | 1678 | if (blk->bp) { |
1684 | blk->disk_blkno = xfs_da_blkno(blk->bp); | 1679 | blk->disk_blkno = XFS_BUF_ADDR(blk->bp); |
1685 | xfs_da_buf_done(blk->bp); | ||
1686 | blk->bp = NULL; | 1680 | blk->bp = NULL; |
1687 | } else { | 1681 | } else { |
1688 | blk->disk_blkno = 0; | 1682 | blk->disk_blkno = 0; |
@@ -1792,7 +1786,7 @@ xfs_attr_node_get(xfs_da_args_t *args) | |||
1792 | * If not in a transaction, we have to release all the buffers. | 1786 | * If not in a transaction, we have to release all the buffers. |
1793 | */ | 1787 | */ |
1794 | for (i = 0; i < state->path.active; i++) { | 1788 | for (i = 0; i < state->path.active; i++) { |
1795 | xfs_da_brelse(args->trans, state->path.blk[i].bp); | 1789 | xfs_trans_brelse(args->trans, state->path.blk[i].bp); |
1796 | state->path.blk[i].bp = NULL; | 1790 | state->path.blk[i].bp = NULL; |
1797 | } | 1791 | } |
1798 | 1792 | ||
@@ -1808,7 +1802,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) | |||
1808 | xfs_da_intnode_t *node; | 1802 | xfs_da_intnode_t *node; |
1809 | xfs_da_node_entry_t *btree; | 1803 | xfs_da_node_entry_t *btree; |
1810 | int error, i; | 1804 | int error, i; |
1811 | xfs_dabuf_t *bp; | 1805 | struct xfs_buf *bp; |
1812 | 1806 | ||
1813 | cursor = context->cursor; | 1807 | cursor = context->cursor; |
1814 | cursor->initted = 1; | 1808 | cursor->initted = 1; |
@@ -1825,30 +1819,30 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) | |||
1825 | if ((error != 0) && (error != EFSCORRUPTED)) | 1819 | if ((error != 0) && (error != EFSCORRUPTED)) |
1826 | return(error); | 1820 | return(error); |
1827 | if (bp) { | 1821 | if (bp) { |
1828 | node = bp->data; | 1822 | node = bp->b_addr; |
1829 | switch (be16_to_cpu(node->hdr.info.magic)) { | 1823 | switch (be16_to_cpu(node->hdr.info.magic)) { |
1830 | case XFS_DA_NODE_MAGIC: | 1824 | case XFS_DA_NODE_MAGIC: |
1831 | trace_xfs_attr_list_wrong_blk(context); | 1825 | trace_xfs_attr_list_wrong_blk(context); |
1832 | xfs_da_brelse(NULL, bp); | 1826 | xfs_trans_brelse(NULL, bp); |
1833 | bp = NULL; | 1827 | bp = NULL; |
1834 | break; | 1828 | break; |
1835 | case XFS_ATTR_LEAF_MAGIC: | 1829 | case XFS_ATTR_LEAF_MAGIC: |
1836 | leaf = bp->data; | 1830 | leaf = bp->b_addr; |
1837 | if (cursor->hashval > be32_to_cpu(leaf->entries[ | 1831 | if (cursor->hashval > be32_to_cpu(leaf->entries[ |
1838 | be16_to_cpu(leaf->hdr.count)-1].hashval)) { | 1832 | be16_to_cpu(leaf->hdr.count)-1].hashval)) { |
1839 | trace_xfs_attr_list_wrong_blk(context); | 1833 | trace_xfs_attr_list_wrong_blk(context); |
1840 | xfs_da_brelse(NULL, bp); | 1834 | xfs_trans_brelse(NULL, bp); |
1841 | bp = NULL; | 1835 | bp = NULL; |
1842 | } else if (cursor->hashval <= | 1836 | } else if (cursor->hashval <= |
1843 | be32_to_cpu(leaf->entries[0].hashval)) { | 1837 | be32_to_cpu(leaf->entries[0].hashval)) { |
1844 | trace_xfs_attr_list_wrong_blk(context); | 1838 | trace_xfs_attr_list_wrong_blk(context); |
1845 | xfs_da_brelse(NULL, bp); | 1839 | xfs_trans_brelse(NULL, bp); |
1846 | bp = NULL; | 1840 | bp = NULL; |
1847 | } | 1841 | } |
1848 | break; | 1842 | break; |
1849 | default: | 1843 | default: |
1850 | trace_xfs_attr_list_wrong_blk(context); | 1844 | trace_xfs_attr_list_wrong_blk(context); |
1851 | xfs_da_brelse(NULL, bp); | 1845 | xfs_trans_brelse(NULL, bp); |
1852 | bp = NULL; | 1846 | bp = NULL; |
1853 | } | 1847 | } |
1854 | } | 1848 | } |
@@ -1873,7 +1867,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) | |||
1873 | context->dp->i_mount); | 1867 | context->dp->i_mount); |
1874 | return(XFS_ERROR(EFSCORRUPTED)); | 1868 | return(XFS_ERROR(EFSCORRUPTED)); |
1875 | } | 1869 | } |
1876 | node = bp->data; | 1870 | node = bp->b_addr; |
1877 | if (node->hdr.info.magic == | 1871 | if (node->hdr.info.magic == |
1878 | cpu_to_be16(XFS_ATTR_LEAF_MAGIC)) | 1872 | cpu_to_be16(XFS_ATTR_LEAF_MAGIC)) |
1879 | break; | 1873 | break; |
@@ -1883,7 +1877,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) | |||
1883 | XFS_ERRLEVEL_LOW, | 1877 | XFS_ERRLEVEL_LOW, |
1884 | context->dp->i_mount, | 1878 | context->dp->i_mount, |
1885 | node); | 1879 | node); |
1886 | xfs_da_brelse(NULL, bp); | 1880 | xfs_trans_brelse(NULL, bp); |
1887 | return(XFS_ERROR(EFSCORRUPTED)); | 1881 | return(XFS_ERROR(EFSCORRUPTED)); |
1888 | } | 1882 | } |
1889 | btree = node->btree; | 1883 | btree = node->btree; |
@@ -1898,10 +1892,10 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) | |||
1898 | } | 1892 | } |
1899 | } | 1893 | } |
1900 | if (i == be16_to_cpu(node->hdr.count)) { | 1894 | if (i == be16_to_cpu(node->hdr.count)) { |
1901 | xfs_da_brelse(NULL, bp); | 1895 | xfs_trans_brelse(NULL, bp); |
1902 | return(0); | 1896 | return(0); |
1903 | } | 1897 | } |
1904 | xfs_da_brelse(NULL, bp); | 1898 | xfs_trans_brelse(NULL, bp); |
1905 | } | 1899 | } |
1906 | } | 1900 | } |
1907 | ASSERT(bp != NULL); | 1901 | ASSERT(bp != NULL); |
@@ -1912,24 +1906,24 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) | |||
1912 | * adding the information. | 1906 | * adding the information. |
1913 | */ | 1907 | */ |
1914 | for (;;) { | 1908 | for (;;) { |
1915 | leaf = bp->data; | 1909 | leaf = bp->b_addr; |
1916 | if (unlikely(leaf->hdr.info.magic != | 1910 | if (unlikely(leaf->hdr.info.magic != |
1917 | cpu_to_be16(XFS_ATTR_LEAF_MAGIC))) { | 1911 | cpu_to_be16(XFS_ATTR_LEAF_MAGIC))) { |
1918 | XFS_CORRUPTION_ERROR("xfs_attr_node_list(4)", | 1912 | XFS_CORRUPTION_ERROR("xfs_attr_node_list(4)", |
1919 | XFS_ERRLEVEL_LOW, | 1913 | XFS_ERRLEVEL_LOW, |
1920 | context->dp->i_mount, leaf); | 1914 | context->dp->i_mount, leaf); |
1921 | xfs_da_brelse(NULL, bp); | 1915 | xfs_trans_brelse(NULL, bp); |
1922 | return(XFS_ERROR(EFSCORRUPTED)); | 1916 | return(XFS_ERROR(EFSCORRUPTED)); |
1923 | } | 1917 | } |
1924 | error = xfs_attr_leaf_list_int(bp, context); | 1918 | error = xfs_attr_leaf_list_int(bp, context); |
1925 | if (error) { | 1919 | if (error) { |
1926 | xfs_da_brelse(NULL, bp); | 1920 | xfs_trans_brelse(NULL, bp); |
1927 | return error; | 1921 | return error; |
1928 | } | 1922 | } |
1929 | if (context->seen_enough || leaf->hdr.info.forw == 0) | 1923 | if (context->seen_enough || leaf->hdr.info.forw == 0) |
1930 | break; | 1924 | break; |
1931 | cursor->blkno = be32_to_cpu(leaf->hdr.info.forw); | 1925 | cursor->blkno = be32_to_cpu(leaf->hdr.info.forw); |
1932 | xfs_da_brelse(NULL, bp); | 1926 | xfs_trans_brelse(NULL, bp); |
1933 | error = xfs_da_read_buf(NULL, context->dp, cursor->blkno, -1, | 1927 | error = xfs_da_read_buf(NULL, context->dp, cursor->blkno, -1, |
1934 | &bp, XFS_ATTR_FORK); | 1928 | &bp, XFS_ATTR_FORK); |
1935 | if (error) | 1929 | if (error) |
@@ -1941,7 +1935,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) | |||
1941 | return(XFS_ERROR(EFSCORRUPTED)); | 1935 | return(XFS_ERROR(EFSCORRUPTED)); |
1942 | } | 1936 | } |
1943 | } | 1937 | } |
1944 | xfs_da_brelse(NULL, bp); | 1938 | xfs_trans_brelse(NULL, bp); |
1945 | return(0); | 1939 | return(0); |
1946 | } | 1940 | } |
1947 | 1941 | ||
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index 7d89d800f517..d330111ca738 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c | |||
@@ -54,10 +54,10 @@ | |||
54 | * Routines used for growing the Btree. | 54 | * Routines used for growing the Btree. |
55 | */ | 55 | */ |
56 | STATIC int xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t which_block, | 56 | STATIC int xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t which_block, |
57 | xfs_dabuf_t **bpp); | 57 | struct xfs_buf **bpp); |
58 | STATIC int xfs_attr_leaf_add_work(xfs_dabuf_t *leaf_buffer, xfs_da_args_t *args, | 58 | STATIC int xfs_attr_leaf_add_work(struct xfs_buf *leaf_buffer, |
59 | int freemap_index); | 59 | xfs_da_args_t *args, int freemap_index); |
60 | STATIC void xfs_attr_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *leaf_buffer); | 60 | STATIC void xfs_attr_leaf_compact(xfs_trans_t *tp, struct xfs_buf *leaf_buffer); |
61 | STATIC void xfs_attr_leaf_rebalance(xfs_da_state_t *state, | 61 | STATIC void xfs_attr_leaf_rebalance(xfs_da_state_t *state, |
62 | xfs_da_state_blk_t *blk1, | 62 | xfs_da_state_blk_t *blk1, |
63 | xfs_da_state_blk_t *blk2); | 63 | xfs_da_state_blk_t *blk2); |
@@ -71,9 +71,9 @@ STATIC int xfs_attr_leaf_figure_balance(xfs_da_state_t *state, | |||
71 | * Routines used for shrinking the Btree. | 71 | * Routines used for shrinking the Btree. |
72 | */ | 72 | */ |
73 | STATIC int xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, | 73 | STATIC int xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, |
74 | xfs_dabuf_t *bp, int level); | 74 | struct xfs_buf *bp, int level); |
75 | STATIC int xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, | 75 | STATIC int xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, |
76 | xfs_dabuf_t *bp); | 76 | struct xfs_buf *bp); |
77 | STATIC int xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp, | 77 | STATIC int xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp, |
78 | xfs_dablk_t blkno, int blkcnt); | 78 | xfs_dablk_t blkno, int blkcnt); |
79 | 79 | ||
@@ -480,7 +480,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args) | |||
480 | char *tmpbuffer; | 480 | char *tmpbuffer; |
481 | int error, i, size; | 481 | int error, i, size; |
482 | xfs_dablk_t blkno; | 482 | xfs_dablk_t blkno; |
483 | xfs_dabuf_t *bp; | 483 | struct xfs_buf *bp; |
484 | xfs_ifork_t *ifp; | 484 | xfs_ifork_t *ifp; |
485 | 485 | ||
486 | trace_xfs_attr_sf_to_leaf(args); | 486 | trace_xfs_attr_sf_to_leaf(args); |
@@ -550,8 +550,6 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args) | |||
550 | error = 0; | 550 | error = 0; |
551 | 551 | ||
552 | out: | 552 | out: |
553 | if(bp) | ||
554 | xfs_da_buf_done(bp); | ||
555 | kmem_free(tmpbuffer); | 553 | kmem_free(tmpbuffer); |
556 | return(error); | 554 | return(error); |
557 | } | 555 | } |
@@ -737,14 +735,16 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) | |||
737 | * a shortform attribute list. | 735 | * a shortform attribute list. |
738 | */ | 736 | */ |
739 | int | 737 | int |
740 | xfs_attr_shortform_allfit(xfs_dabuf_t *bp, xfs_inode_t *dp) | 738 | xfs_attr_shortform_allfit( |
739 | struct xfs_buf *bp, | ||
740 | struct xfs_inode *dp) | ||
741 | { | 741 | { |
742 | xfs_attr_leafblock_t *leaf; | 742 | xfs_attr_leafblock_t *leaf; |
743 | xfs_attr_leaf_entry_t *entry; | 743 | xfs_attr_leaf_entry_t *entry; |
744 | xfs_attr_leaf_name_local_t *name_loc; | 744 | xfs_attr_leaf_name_local_t *name_loc; |
745 | int bytes, i; | 745 | int bytes, i; |
746 | 746 | ||
747 | leaf = bp->data; | 747 | leaf = bp->b_addr; |
748 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); | 748 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); |
749 | 749 | ||
750 | entry = &leaf->entries[0]; | 750 | entry = &leaf->entries[0]; |
@@ -774,7 +774,10 @@ xfs_attr_shortform_allfit(xfs_dabuf_t *bp, xfs_inode_t *dp) | |||
774 | * Convert a leaf attribute list to shortform attribute list | 774 | * Convert a leaf attribute list to shortform attribute list |
775 | */ | 775 | */ |
776 | int | 776 | int |
777 | xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff) | 777 | xfs_attr_leaf_to_shortform( |
778 | struct xfs_buf *bp, | ||
779 | xfs_da_args_t *args, | ||
780 | int forkoff) | ||
778 | { | 781 | { |
779 | xfs_attr_leafblock_t *leaf; | 782 | xfs_attr_leafblock_t *leaf; |
780 | xfs_attr_leaf_entry_t *entry; | 783 | xfs_attr_leaf_entry_t *entry; |
@@ -791,10 +794,10 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff) | |||
791 | ASSERT(tmpbuffer != NULL); | 794 | ASSERT(tmpbuffer != NULL); |
792 | 795 | ||
793 | ASSERT(bp != NULL); | 796 | ASSERT(bp != NULL); |
794 | memcpy(tmpbuffer, bp->data, XFS_LBSIZE(dp->i_mount)); | 797 | memcpy(tmpbuffer, bp->b_addr, XFS_LBSIZE(dp->i_mount)); |
795 | leaf = (xfs_attr_leafblock_t *)tmpbuffer; | 798 | leaf = (xfs_attr_leafblock_t *)tmpbuffer; |
796 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); | 799 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); |
797 | memset(bp->data, 0, XFS_LBSIZE(dp->i_mount)); | 800 | memset(bp->b_addr, 0, XFS_LBSIZE(dp->i_mount)); |
798 | 801 | ||
799 | /* | 802 | /* |
800 | * Clean out the prior contents of the attribute list. | 803 | * Clean out the prior contents of the attribute list. |
@@ -855,7 +858,7 @@ xfs_attr_leaf_to_node(xfs_da_args_t *args) | |||
855 | xfs_attr_leafblock_t *leaf; | 858 | xfs_attr_leafblock_t *leaf; |
856 | xfs_da_intnode_t *node; | 859 | xfs_da_intnode_t *node; |
857 | xfs_inode_t *dp; | 860 | xfs_inode_t *dp; |
858 | xfs_dabuf_t *bp1, *bp2; | 861 | struct xfs_buf *bp1, *bp2; |
859 | xfs_dablk_t blkno; | 862 | xfs_dablk_t blkno; |
860 | int error; | 863 | int error; |
861 | 864 | ||
@@ -877,10 +880,9 @@ xfs_attr_leaf_to_node(xfs_da_args_t *args) | |||
877 | if (error) | 880 | if (error) |
878 | goto out; | 881 | goto out; |
879 | ASSERT(bp2 != NULL); | 882 | ASSERT(bp2 != NULL); |
880 | memcpy(bp2->data, bp1->data, XFS_LBSIZE(dp->i_mount)); | 883 | memcpy(bp2->b_addr, bp1->b_addr, XFS_LBSIZE(dp->i_mount)); |
881 | xfs_da_buf_done(bp1); | ||
882 | bp1 = NULL; | 884 | bp1 = NULL; |
883 | xfs_da_log_buf(args->trans, bp2, 0, XFS_LBSIZE(dp->i_mount) - 1); | 885 | xfs_trans_log_buf(args->trans, bp2, 0, XFS_LBSIZE(dp->i_mount) - 1); |
884 | 886 | ||
885 | /* | 887 | /* |
886 | * Set up the new root node. | 888 | * Set up the new root node. |
@@ -888,21 +890,17 @@ xfs_attr_leaf_to_node(xfs_da_args_t *args) | |||
888 | error = xfs_da_node_create(args, 0, 1, &bp1, XFS_ATTR_FORK); | 890 | error = xfs_da_node_create(args, 0, 1, &bp1, XFS_ATTR_FORK); |
889 | if (error) | 891 | if (error) |
890 | goto out; | 892 | goto out; |
891 | node = bp1->data; | 893 | node = bp1->b_addr; |
892 | leaf = bp2->data; | 894 | leaf = bp2->b_addr; |
893 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); | 895 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); |
894 | /* both on-disk, don't endian-flip twice */ | 896 | /* both on-disk, don't endian-flip twice */ |
895 | node->btree[0].hashval = | 897 | node->btree[0].hashval = |
896 | leaf->entries[be16_to_cpu(leaf->hdr.count)-1 ].hashval; | 898 | leaf->entries[be16_to_cpu(leaf->hdr.count)-1 ].hashval; |
897 | node->btree[0].before = cpu_to_be32(blkno); | 899 | node->btree[0].before = cpu_to_be32(blkno); |
898 | node->hdr.count = cpu_to_be16(1); | 900 | node->hdr.count = cpu_to_be16(1); |
899 | xfs_da_log_buf(args->trans, bp1, 0, XFS_LBSIZE(dp->i_mount) - 1); | 901 | xfs_trans_log_buf(args->trans, bp1, 0, XFS_LBSIZE(dp->i_mount) - 1); |
900 | error = 0; | 902 | error = 0; |
901 | out: | 903 | out: |
902 | if (bp1) | ||
903 | xfs_da_buf_done(bp1); | ||
904 | if (bp2) | ||
905 | xfs_da_buf_done(bp2); | ||
906 | return(error); | 904 | return(error); |
907 | } | 905 | } |
908 | 906 | ||
@@ -916,12 +914,15 @@ out: | |||
916 | * or a leaf in a node attribute list. | 914 | * or a leaf in a node attribute list. |
917 | */ | 915 | */ |
918 | STATIC int | 916 | STATIC int |
919 | xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp) | 917 | xfs_attr_leaf_create( |
918 | xfs_da_args_t *args, | ||
919 | xfs_dablk_t blkno, | ||
920 | struct xfs_buf **bpp) | ||
920 | { | 921 | { |
921 | xfs_attr_leafblock_t *leaf; | 922 | xfs_attr_leafblock_t *leaf; |
922 | xfs_attr_leaf_hdr_t *hdr; | 923 | xfs_attr_leaf_hdr_t *hdr; |
923 | xfs_inode_t *dp; | 924 | xfs_inode_t *dp; |
924 | xfs_dabuf_t *bp; | 925 | struct xfs_buf *bp; |
925 | int error; | 926 | int error; |
926 | 927 | ||
927 | trace_xfs_attr_leaf_create(args); | 928 | trace_xfs_attr_leaf_create(args); |
@@ -933,7 +934,7 @@ xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp) | |||
933 | if (error) | 934 | if (error) |
934 | return(error); | 935 | return(error); |
935 | ASSERT(bp != NULL); | 936 | ASSERT(bp != NULL); |
936 | leaf = bp->data; | 937 | leaf = bp->b_addr; |
937 | memset((char *)leaf, 0, XFS_LBSIZE(dp->i_mount)); | 938 | memset((char *)leaf, 0, XFS_LBSIZE(dp->i_mount)); |
938 | hdr = &leaf->hdr; | 939 | hdr = &leaf->hdr; |
939 | hdr->info.magic = cpu_to_be16(XFS_ATTR_LEAF_MAGIC); | 940 | hdr->info.magic = cpu_to_be16(XFS_ATTR_LEAF_MAGIC); |
@@ -947,7 +948,7 @@ xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp) | |||
947 | hdr->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr->firstused) - | 948 | hdr->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr->firstused) - |
948 | sizeof(xfs_attr_leaf_hdr_t)); | 949 | sizeof(xfs_attr_leaf_hdr_t)); |
949 | 950 | ||
950 | xfs_da_log_buf(args->trans, bp, 0, XFS_LBSIZE(dp->i_mount) - 1); | 951 | xfs_trans_log_buf(args->trans, bp, 0, XFS_LBSIZE(dp->i_mount) - 1); |
951 | 952 | ||
952 | *bpp = bp; | 953 | *bpp = bp; |
953 | return(0); | 954 | return(0); |
@@ -1014,7 +1015,9 @@ xfs_attr_leaf_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, | |||
1014 | * Add a name to the leaf attribute list structure. | 1015 | * Add a name to the leaf attribute list structure. |
1015 | */ | 1016 | */ |
1016 | int | 1017 | int |
1017 | xfs_attr_leaf_add(xfs_dabuf_t *bp, xfs_da_args_t *args) | 1018 | xfs_attr_leaf_add( |
1019 | struct xfs_buf *bp, | ||
1020 | struct xfs_da_args *args) | ||
1018 | { | 1021 | { |
1019 | xfs_attr_leafblock_t *leaf; | 1022 | xfs_attr_leafblock_t *leaf; |
1020 | xfs_attr_leaf_hdr_t *hdr; | 1023 | xfs_attr_leaf_hdr_t *hdr; |
@@ -1023,7 +1026,7 @@ xfs_attr_leaf_add(xfs_dabuf_t *bp, xfs_da_args_t *args) | |||
1023 | 1026 | ||
1024 | trace_xfs_attr_leaf_add(args); | 1027 | trace_xfs_attr_leaf_add(args); |
1025 | 1028 | ||
1026 | leaf = bp->data; | 1029 | leaf = bp->b_addr; |
1027 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); | 1030 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); |
1028 | ASSERT((args->index >= 0) | 1031 | ASSERT((args->index >= 0) |
1029 | && (args->index <= be16_to_cpu(leaf->hdr.count))); | 1032 | && (args->index <= be16_to_cpu(leaf->hdr.count))); |
@@ -1085,7 +1088,10 @@ xfs_attr_leaf_add(xfs_dabuf_t *bp, xfs_da_args_t *args) | |||
1085 | * Add a name to a leaf attribute list structure. | 1088 | * Add a name to a leaf attribute list structure. |
1086 | */ | 1089 | */ |
1087 | STATIC int | 1090 | STATIC int |
1088 | xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex) | 1091 | xfs_attr_leaf_add_work( |
1092 | struct xfs_buf *bp, | ||
1093 | xfs_da_args_t *args, | ||
1094 | int mapindex) | ||
1089 | { | 1095 | { |
1090 | xfs_attr_leafblock_t *leaf; | 1096 | xfs_attr_leafblock_t *leaf; |
1091 | xfs_attr_leaf_hdr_t *hdr; | 1097 | xfs_attr_leaf_hdr_t *hdr; |
@@ -1096,7 +1102,7 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex) | |||
1096 | xfs_mount_t *mp; | 1102 | xfs_mount_t *mp; |
1097 | int tmp, i; | 1103 | int tmp, i; |
1098 | 1104 | ||
1099 | leaf = bp->data; | 1105 | leaf = bp->b_addr; |
1100 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); | 1106 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); |
1101 | hdr = &leaf->hdr; | 1107 | hdr = &leaf->hdr; |
1102 | ASSERT((mapindex >= 0) && (mapindex < XFS_ATTR_LEAF_MAPSIZE)); | 1108 | ASSERT((mapindex >= 0) && (mapindex < XFS_ATTR_LEAF_MAPSIZE)); |
@@ -1110,7 +1116,7 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex) | |||
1110 | tmp = be16_to_cpu(hdr->count) - args->index; | 1116 | tmp = be16_to_cpu(hdr->count) - args->index; |
1111 | tmp *= sizeof(xfs_attr_leaf_entry_t); | 1117 | tmp *= sizeof(xfs_attr_leaf_entry_t); |
1112 | memmove((char *)(entry+1), (char *)entry, tmp); | 1118 | memmove((char *)(entry+1), (char *)entry, tmp); |
1113 | xfs_da_log_buf(args->trans, bp, | 1119 | xfs_trans_log_buf(args->trans, bp, |
1114 | XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry))); | 1120 | XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry))); |
1115 | } | 1121 | } |
1116 | be16_add_cpu(&hdr->count, 1); | 1122 | be16_add_cpu(&hdr->count, 1); |
@@ -1142,7 +1148,7 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex) | |||
1142 | args->index2++; | 1148 | args->index2++; |
1143 | } | 1149 | } |
1144 | } | 1150 | } |
1145 | xfs_da_log_buf(args->trans, bp, | 1151 | xfs_trans_log_buf(args->trans, bp, |
1146 | XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry))); | 1152 | XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry))); |
1147 | ASSERT((args->index == 0) || | 1153 | ASSERT((args->index == 0) || |
1148 | (be32_to_cpu(entry->hashval) >= be32_to_cpu((entry-1)->hashval))); | 1154 | (be32_to_cpu(entry->hashval) >= be32_to_cpu((entry-1)->hashval))); |
@@ -1174,7 +1180,7 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex) | |||
1174 | args->rmtblkno = 1; | 1180 | args->rmtblkno = 1; |
1175 | args->rmtblkcnt = XFS_B_TO_FSB(mp, args->valuelen); | 1181 | args->rmtblkcnt = XFS_B_TO_FSB(mp, args->valuelen); |
1176 | } | 1182 | } |
1177 | xfs_da_log_buf(args->trans, bp, | 1183 | xfs_trans_log_buf(args->trans, bp, |
1178 | XFS_DA_LOGRANGE(leaf, xfs_attr_leaf_name(leaf, args->index), | 1184 | XFS_DA_LOGRANGE(leaf, xfs_attr_leaf_name(leaf, args->index), |
1179 | xfs_attr_leaf_entsize(leaf, args->index))); | 1185 | xfs_attr_leaf_entsize(leaf, args->index))); |
1180 | 1186 | ||
@@ -1198,7 +1204,7 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex) | |||
1198 | } | 1204 | } |
1199 | } | 1205 | } |
1200 | be16_add_cpu(&hdr->usedbytes, xfs_attr_leaf_entsize(leaf, args->index)); | 1206 | be16_add_cpu(&hdr->usedbytes, xfs_attr_leaf_entsize(leaf, args->index)); |
1201 | xfs_da_log_buf(args->trans, bp, | 1207 | xfs_trans_log_buf(args->trans, bp, |
1202 | XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr))); | 1208 | XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr))); |
1203 | return(0); | 1209 | return(0); |
1204 | } | 1210 | } |
@@ -1207,7 +1213,9 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex) | |||
1207 | * Garbage collect a leaf attribute list block by copying it to a new buffer. | 1213 | * Garbage collect a leaf attribute list block by copying it to a new buffer. |
1208 | */ | 1214 | */ |
1209 | STATIC void | 1215 | STATIC void |
1210 | xfs_attr_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *bp) | 1216 | xfs_attr_leaf_compact( |
1217 | struct xfs_trans *trans, | ||
1218 | struct xfs_buf *bp) | ||
1211 | { | 1219 | { |
1212 | xfs_attr_leafblock_t *leaf_s, *leaf_d; | 1220 | xfs_attr_leafblock_t *leaf_s, *leaf_d; |
1213 | xfs_attr_leaf_hdr_t *hdr_s, *hdr_d; | 1221 | xfs_attr_leaf_hdr_t *hdr_s, *hdr_d; |
@@ -1217,14 +1225,14 @@ xfs_attr_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *bp) | |||
1217 | mp = trans->t_mountp; | 1225 | mp = trans->t_mountp; |
1218 | tmpbuffer = kmem_alloc(XFS_LBSIZE(mp), KM_SLEEP); | 1226 | tmpbuffer = kmem_alloc(XFS_LBSIZE(mp), KM_SLEEP); |
1219 | ASSERT(tmpbuffer != NULL); | 1227 | ASSERT(tmpbuffer != NULL); |
1220 | memcpy(tmpbuffer, bp->data, XFS_LBSIZE(mp)); | 1228 | memcpy(tmpbuffer, bp->b_addr, XFS_LBSIZE(mp)); |
1221 | memset(bp->data, 0, XFS_LBSIZE(mp)); | 1229 | memset(bp->b_addr, 0, XFS_LBSIZE(mp)); |
1222 | 1230 | ||
1223 | /* | 1231 | /* |
1224 | * Copy basic information | 1232 | * Copy basic information |
1225 | */ | 1233 | */ |
1226 | leaf_s = (xfs_attr_leafblock_t *)tmpbuffer; | 1234 | leaf_s = (xfs_attr_leafblock_t *)tmpbuffer; |
1227 | leaf_d = bp->data; | 1235 | leaf_d = bp->b_addr; |
1228 | hdr_s = &leaf_s->hdr; | 1236 | hdr_s = &leaf_s->hdr; |
1229 | hdr_d = &leaf_d->hdr; | 1237 | hdr_d = &leaf_d->hdr; |
1230 | hdr_d->info = hdr_s->info; /* struct copy */ | 1238 | hdr_d->info = hdr_s->info; /* struct copy */ |
@@ -1247,7 +1255,7 @@ xfs_attr_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *bp) | |||
1247 | */ | 1255 | */ |
1248 | xfs_attr_leaf_moveents(leaf_s, 0, leaf_d, 0, | 1256 | xfs_attr_leaf_moveents(leaf_s, 0, leaf_d, 0, |
1249 | be16_to_cpu(hdr_s->count), mp); | 1257 | be16_to_cpu(hdr_s->count), mp); |
1250 | xfs_da_log_buf(trans, bp, 0, XFS_LBSIZE(mp) - 1); | 1258 | xfs_trans_log_buf(trans, bp, 0, XFS_LBSIZE(mp) - 1); |
1251 | 1259 | ||
1252 | kmem_free(tmpbuffer); | 1260 | kmem_free(tmpbuffer); |
1253 | } | 1261 | } |
@@ -1279,8 +1287,8 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, | |||
1279 | */ | 1287 | */ |
1280 | ASSERT(blk1->magic == XFS_ATTR_LEAF_MAGIC); | 1288 | ASSERT(blk1->magic == XFS_ATTR_LEAF_MAGIC); |
1281 | ASSERT(blk2->magic == XFS_ATTR_LEAF_MAGIC); | 1289 | ASSERT(blk2->magic == XFS_ATTR_LEAF_MAGIC); |
1282 | leaf1 = blk1->bp->data; | 1290 | leaf1 = blk1->bp->b_addr; |
1283 | leaf2 = blk2->bp->data; | 1291 | leaf2 = blk2->bp->b_addr; |
1284 | ASSERT(leaf1->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); | 1292 | ASSERT(leaf1->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); |
1285 | ASSERT(leaf2->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); | 1293 | ASSERT(leaf2->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); |
1286 | args = state->args; | 1294 | args = state->args; |
@@ -1298,8 +1306,8 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, | |||
1298 | tmp_blk = blk1; | 1306 | tmp_blk = blk1; |
1299 | blk1 = blk2; | 1307 | blk1 = blk2; |
1300 | blk2 = tmp_blk; | 1308 | blk2 = tmp_blk; |
1301 | leaf1 = blk1->bp->data; | 1309 | leaf1 = blk1->bp->b_addr; |
1302 | leaf2 = blk2->bp->data; | 1310 | leaf2 = blk2->bp->b_addr; |
1303 | swap = 1; | 1311 | swap = 1; |
1304 | } | 1312 | } |
1305 | hdr1 = &leaf1->hdr; | 1313 | hdr1 = &leaf1->hdr; |
@@ -1346,8 +1354,8 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, | |||
1346 | xfs_attr_leaf_moveents(leaf1, be16_to_cpu(hdr1->count) - count, | 1354 | xfs_attr_leaf_moveents(leaf1, be16_to_cpu(hdr1->count) - count, |
1347 | leaf2, 0, count, state->mp); | 1355 | leaf2, 0, count, state->mp); |
1348 | 1356 | ||
1349 | xfs_da_log_buf(args->trans, blk1->bp, 0, state->blocksize-1); | 1357 | xfs_trans_log_buf(args->trans, blk1->bp, 0, state->blocksize-1); |
1350 | xfs_da_log_buf(args->trans, blk2->bp, 0, state->blocksize-1); | 1358 | xfs_trans_log_buf(args->trans, blk2->bp, 0, state->blocksize-1); |
1351 | } else if (count > be16_to_cpu(hdr1->count)) { | 1359 | } else if (count > be16_to_cpu(hdr1->count)) { |
1352 | /* | 1360 | /* |
1353 | * I assert that since all callers pass in an empty | 1361 | * I assert that since all callers pass in an empty |
@@ -1378,8 +1386,8 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, | |||
1378 | xfs_attr_leaf_moveents(leaf2, 0, leaf1, | 1386 | xfs_attr_leaf_moveents(leaf2, 0, leaf1, |
1379 | be16_to_cpu(hdr1->count), count, state->mp); | 1387 | be16_to_cpu(hdr1->count), count, state->mp); |
1380 | 1388 | ||
1381 | xfs_da_log_buf(args->trans, blk1->bp, 0, state->blocksize-1); | 1389 | xfs_trans_log_buf(args->trans, blk1->bp, 0, state->blocksize-1); |
1382 | xfs_da_log_buf(args->trans, blk2->bp, 0, state->blocksize-1); | 1390 | xfs_trans_log_buf(args->trans, blk2->bp, 0, state->blocksize-1); |
1383 | } | 1391 | } |
1384 | 1392 | ||
1385 | /* | 1393 | /* |
@@ -1448,8 +1456,8 @@ xfs_attr_leaf_figure_balance(xfs_da_state_t *state, | |||
1448 | /* | 1456 | /* |
1449 | * Set up environment. | 1457 | * Set up environment. |
1450 | */ | 1458 | */ |
1451 | leaf1 = blk1->bp->data; | 1459 | leaf1 = blk1->bp->b_addr; |
1452 | leaf2 = blk2->bp->data; | 1460 | leaf2 = blk2->bp->b_addr; |
1453 | hdr1 = &leaf1->hdr; | 1461 | hdr1 = &leaf1->hdr; |
1454 | hdr2 = &leaf2->hdr; | 1462 | hdr2 = &leaf2->hdr; |
1455 | foundit = 0; | 1463 | foundit = 0; |
@@ -1551,7 +1559,7 @@ xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action) | |||
1551 | xfs_da_blkinfo_t *info; | 1559 | xfs_da_blkinfo_t *info; |
1552 | int count, bytes, forward, error, retval, i; | 1560 | int count, bytes, forward, error, retval, i; |
1553 | xfs_dablk_t blkno; | 1561 | xfs_dablk_t blkno; |
1554 | xfs_dabuf_t *bp; | 1562 | struct xfs_buf *bp; |
1555 | 1563 | ||
1556 | /* | 1564 | /* |
1557 | * Check for the degenerate case of the block being over 50% full. | 1565 | * Check for the degenerate case of the block being over 50% full. |
@@ -1559,7 +1567,7 @@ xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action) | |||
1559 | * to coalesce with a sibling. | 1567 | * to coalesce with a sibling. |
1560 | */ | 1568 | */ |
1561 | blk = &state->path.blk[ state->path.active-1 ]; | 1569 | blk = &state->path.blk[ state->path.active-1 ]; |
1562 | info = blk->bp->data; | 1570 | info = blk->bp->b_addr; |
1563 | ASSERT(info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); | 1571 | ASSERT(info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); |
1564 | leaf = (xfs_attr_leafblock_t *)info; | 1572 | leaf = (xfs_attr_leafblock_t *)info; |
1565 | count = be16_to_cpu(leaf->hdr.count); | 1573 | count = be16_to_cpu(leaf->hdr.count); |
@@ -1622,13 +1630,13 @@ xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action) | |||
1622 | count = be16_to_cpu(leaf->hdr.count); | 1630 | count = be16_to_cpu(leaf->hdr.count); |
1623 | bytes = state->blocksize - (state->blocksize>>2); | 1631 | bytes = state->blocksize - (state->blocksize>>2); |
1624 | bytes -= be16_to_cpu(leaf->hdr.usedbytes); | 1632 | bytes -= be16_to_cpu(leaf->hdr.usedbytes); |
1625 | leaf = bp->data; | 1633 | leaf = bp->b_addr; |
1626 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); | 1634 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); |
1627 | count += be16_to_cpu(leaf->hdr.count); | 1635 | count += be16_to_cpu(leaf->hdr.count); |
1628 | bytes -= be16_to_cpu(leaf->hdr.usedbytes); | 1636 | bytes -= be16_to_cpu(leaf->hdr.usedbytes); |
1629 | bytes -= count * sizeof(xfs_attr_leaf_entry_t); | 1637 | bytes -= count * sizeof(xfs_attr_leaf_entry_t); |
1630 | bytes -= sizeof(xfs_attr_leaf_hdr_t); | 1638 | bytes -= sizeof(xfs_attr_leaf_hdr_t); |
1631 | xfs_da_brelse(state->args->trans, bp); | 1639 | xfs_trans_brelse(state->args->trans, bp); |
1632 | if (bytes >= 0) | 1640 | if (bytes >= 0) |
1633 | break; /* fits with at least 25% to spare */ | 1641 | break; /* fits with at least 25% to spare */ |
1634 | } | 1642 | } |
@@ -1666,7 +1674,9 @@ xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action) | |||
1666 | * If two leaves are 37% full, when combined they will leave 25% free. | 1674 | * If two leaves are 37% full, when combined they will leave 25% free. |
1667 | */ | 1675 | */ |
1668 | int | 1676 | int |
1669 | xfs_attr_leaf_remove(xfs_dabuf_t *bp, xfs_da_args_t *args) | 1677 | xfs_attr_leaf_remove( |
1678 | struct xfs_buf *bp, | ||
1679 | xfs_da_args_t *args) | ||
1670 | { | 1680 | { |
1671 | xfs_attr_leafblock_t *leaf; | 1681 | xfs_attr_leafblock_t *leaf; |
1672 | xfs_attr_leaf_hdr_t *hdr; | 1682 | xfs_attr_leaf_hdr_t *hdr; |
@@ -1676,7 +1686,7 @@ xfs_attr_leaf_remove(xfs_dabuf_t *bp, xfs_da_args_t *args) | |||
1676 | int tablesize, tmp, i; | 1686 | int tablesize, tmp, i; |
1677 | xfs_mount_t *mp; | 1687 | xfs_mount_t *mp; |
1678 | 1688 | ||
1679 | leaf = bp->data; | 1689 | leaf = bp->b_addr; |
1680 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); | 1690 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); |
1681 | hdr = &leaf->hdr; | 1691 | hdr = &leaf->hdr; |
1682 | mp = args->trans->t_mountp; | 1692 | mp = args->trans->t_mountp; |
@@ -1769,7 +1779,7 @@ xfs_attr_leaf_remove(xfs_dabuf_t *bp, xfs_da_args_t *args) | |||
1769 | */ | 1779 | */ |
1770 | memset(xfs_attr_leaf_name(leaf, args->index), 0, entsize); | 1780 | memset(xfs_attr_leaf_name(leaf, args->index), 0, entsize); |
1771 | be16_add_cpu(&hdr->usedbytes, -entsize); | 1781 | be16_add_cpu(&hdr->usedbytes, -entsize); |
1772 | xfs_da_log_buf(args->trans, bp, | 1782 | xfs_trans_log_buf(args->trans, bp, |
1773 | XFS_DA_LOGRANGE(leaf, xfs_attr_leaf_name(leaf, args->index), | 1783 | XFS_DA_LOGRANGE(leaf, xfs_attr_leaf_name(leaf, args->index), |
1774 | entsize)); | 1784 | entsize)); |
1775 | 1785 | ||
@@ -1777,7 +1787,7 @@ xfs_attr_leaf_remove(xfs_dabuf_t *bp, xfs_da_args_t *args) | |||
1777 | * sizeof(xfs_attr_leaf_entry_t); | 1787 | * sizeof(xfs_attr_leaf_entry_t); |
1778 | memmove((char *)entry, (char *)(entry+1), tmp); | 1788 | memmove((char *)entry, (char *)(entry+1), tmp); |
1779 | be16_add_cpu(&hdr->count, -1); | 1789 | be16_add_cpu(&hdr->count, -1); |
1780 | xfs_da_log_buf(args->trans, bp, | 1790 | xfs_trans_log_buf(args->trans, bp, |
1781 | XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry))); | 1791 | XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry))); |
1782 | entry = &leaf->entries[be16_to_cpu(hdr->count)]; | 1792 | entry = &leaf->entries[be16_to_cpu(hdr->count)]; |
1783 | memset((char *)entry, 0, sizeof(xfs_attr_leaf_entry_t)); | 1793 | memset((char *)entry, 0, sizeof(xfs_attr_leaf_entry_t)); |
@@ -1807,7 +1817,7 @@ xfs_attr_leaf_remove(xfs_dabuf_t *bp, xfs_da_args_t *args) | |||
1807 | } else { | 1817 | } else { |
1808 | hdr->holes = 1; /* mark as needing compaction */ | 1818 | hdr->holes = 1; /* mark as needing compaction */ |
1809 | } | 1819 | } |
1810 | xfs_da_log_buf(args->trans, bp, | 1820 | xfs_trans_log_buf(args->trans, bp, |
1811 | XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr))); | 1821 | XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr))); |
1812 | 1822 | ||
1813 | /* | 1823 | /* |
@@ -1840,8 +1850,8 @@ xfs_attr_leaf_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, | |||
1840 | mp = state->mp; | 1850 | mp = state->mp; |
1841 | ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC); | 1851 | ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC); |
1842 | ASSERT(save_blk->magic == XFS_ATTR_LEAF_MAGIC); | 1852 | ASSERT(save_blk->magic == XFS_ATTR_LEAF_MAGIC); |
1843 | drop_leaf = drop_blk->bp->data; | 1853 | drop_leaf = drop_blk->bp->b_addr; |
1844 | save_leaf = save_blk->bp->data; | 1854 | save_leaf = save_blk->bp->b_addr; |
1845 | ASSERT(drop_leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); | 1855 | ASSERT(drop_leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); |
1846 | ASSERT(save_leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); | 1856 | ASSERT(save_leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); |
1847 | drop_hdr = &drop_leaf->hdr; | 1857 | drop_hdr = &drop_leaf->hdr; |
@@ -1906,7 +1916,7 @@ xfs_attr_leaf_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, | |||
1906 | kmem_free(tmpbuffer); | 1916 | kmem_free(tmpbuffer); |
1907 | } | 1917 | } |
1908 | 1918 | ||
1909 | xfs_da_log_buf(state->args->trans, save_blk->bp, 0, | 1919 | xfs_trans_log_buf(state->args->trans, save_blk->bp, 0, |
1910 | state->blocksize - 1); | 1920 | state->blocksize - 1); |
1911 | 1921 | ||
1912 | /* | 1922 | /* |
@@ -1934,7 +1944,9 @@ xfs_attr_leaf_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, | |||
1934 | * Don't change the args->value unless we find the attribute. | 1944 | * Don't change the args->value unless we find the attribute. |
1935 | */ | 1945 | */ |
1936 | int | 1946 | int |
1937 | xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args) | 1947 | xfs_attr_leaf_lookup_int( |
1948 | struct xfs_buf *bp, | ||
1949 | xfs_da_args_t *args) | ||
1938 | { | 1950 | { |
1939 | xfs_attr_leafblock_t *leaf; | 1951 | xfs_attr_leafblock_t *leaf; |
1940 | xfs_attr_leaf_entry_t *entry; | 1952 | xfs_attr_leaf_entry_t *entry; |
@@ -1945,7 +1957,7 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args) | |||
1945 | 1957 | ||
1946 | trace_xfs_attr_leaf_lookup(args); | 1958 | trace_xfs_attr_leaf_lookup(args); |
1947 | 1959 | ||
1948 | leaf = bp->data; | 1960 | leaf = bp->b_addr; |
1949 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); | 1961 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); |
1950 | ASSERT(be16_to_cpu(leaf->hdr.count) | 1962 | ASSERT(be16_to_cpu(leaf->hdr.count) |
1951 | < (XFS_LBSIZE(args->dp->i_mount)/8)); | 1963 | < (XFS_LBSIZE(args->dp->i_mount)/8)); |
@@ -2041,7 +2053,9 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args) | |||
2041 | * list structure. | 2053 | * list structure. |
2042 | */ | 2054 | */ |
2043 | int | 2055 | int |
2044 | xfs_attr_leaf_getvalue(xfs_dabuf_t *bp, xfs_da_args_t *args) | 2056 | xfs_attr_leaf_getvalue( |
2057 | struct xfs_buf *bp, | ||
2058 | xfs_da_args_t *args) | ||
2045 | { | 2059 | { |
2046 | int valuelen; | 2060 | int valuelen; |
2047 | xfs_attr_leafblock_t *leaf; | 2061 | xfs_attr_leafblock_t *leaf; |
@@ -2049,7 +2063,7 @@ xfs_attr_leaf_getvalue(xfs_dabuf_t *bp, xfs_da_args_t *args) | |||
2049 | xfs_attr_leaf_name_local_t *name_loc; | 2063 | xfs_attr_leaf_name_local_t *name_loc; |
2050 | xfs_attr_leaf_name_remote_t *name_rmt; | 2064 | xfs_attr_leaf_name_remote_t *name_rmt; |
2051 | 2065 | ||
2052 | leaf = bp->data; | 2066 | leaf = bp->b_addr; |
2053 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); | 2067 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); |
2054 | ASSERT(be16_to_cpu(leaf->hdr.count) | 2068 | ASSERT(be16_to_cpu(leaf->hdr.count) |
2055 | < (XFS_LBSIZE(args->dp->i_mount)/8)); | 2069 | < (XFS_LBSIZE(args->dp->i_mount)/8)); |
@@ -2247,12 +2261,14 @@ xfs_attr_leaf_moveents(xfs_attr_leafblock_t *leaf_s, int start_s, | |||
2247 | * Return 0 unless leaf2 should go before leaf1. | 2261 | * Return 0 unless leaf2 should go before leaf1. |
2248 | */ | 2262 | */ |
2249 | int | 2263 | int |
2250 | xfs_attr_leaf_order(xfs_dabuf_t *leaf1_bp, xfs_dabuf_t *leaf2_bp) | 2264 | xfs_attr_leaf_order( |
2265 | struct xfs_buf *leaf1_bp, | ||
2266 | struct xfs_buf *leaf2_bp) | ||
2251 | { | 2267 | { |
2252 | xfs_attr_leafblock_t *leaf1, *leaf2; | 2268 | xfs_attr_leafblock_t *leaf1, *leaf2; |
2253 | 2269 | ||
2254 | leaf1 = leaf1_bp->data; | 2270 | leaf1 = leaf1_bp->b_addr; |
2255 | leaf2 = leaf2_bp->data; | 2271 | leaf2 = leaf2_bp->b_addr; |
2256 | ASSERT((leaf1->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)) && | 2272 | ASSERT((leaf1->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)) && |
2257 | (leaf2->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC))); | 2273 | (leaf2->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC))); |
2258 | if ((be16_to_cpu(leaf1->hdr.count) > 0) && | 2274 | if ((be16_to_cpu(leaf1->hdr.count) > 0) && |
@@ -2272,11 +2288,13 @@ xfs_attr_leaf_order(xfs_dabuf_t *leaf1_bp, xfs_dabuf_t *leaf2_bp) | |||
2272 | * Pick up the last hashvalue from a leaf block. | 2288 | * Pick up the last hashvalue from a leaf block. |
2273 | */ | 2289 | */ |
2274 | xfs_dahash_t | 2290 | xfs_dahash_t |
2275 | xfs_attr_leaf_lasthash(xfs_dabuf_t *bp, int *count) | 2291 | xfs_attr_leaf_lasthash( |
2292 | struct xfs_buf *bp, | ||
2293 | int *count) | ||
2276 | { | 2294 | { |
2277 | xfs_attr_leafblock_t *leaf; | 2295 | xfs_attr_leafblock_t *leaf; |
2278 | 2296 | ||
2279 | leaf = bp->data; | 2297 | leaf = bp->b_addr; |
2280 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); | 2298 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); |
2281 | if (count) | 2299 | if (count) |
2282 | *count = be16_to_cpu(leaf->hdr.count); | 2300 | *count = be16_to_cpu(leaf->hdr.count); |
@@ -2337,7 +2355,9 @@ xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, int *local) | |||
2337 | * Copy out attribute list entries for attr_list(), for leaf attribute lists. | 2355 | * Copy out attribute list entries for attr_list(), for leaf attribute lists. |
2338 | */ | 2356 | */ |
2339 | int | 2357 | int |
2340 | xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context) | 2358 | xfs_attr_leaf_list_int( |
2359 | struct xfs_buf *bp, | ||
2360 | xfs_attr_list_context_t *context) | ||
2341 | { | 2361 | { |
2342 | attrlist_cursor_kern_t *cursor; | 2362 | attrlist_cursor_kern_t *cursor; |
2343 | xfs_attr_leafblock_t *leaf; | 2363 | xfs_attr_leafblock_t *leaf; |
@@ -2345,7 +2365,7 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context) | |||
2345 | int retval, i; | 2365 | int retval, i; |
2346 | 2366 | ||
2347 | ASSERT(bp != NULL); | 2367 | ASSERT(bp != NULL); |
2348 | leaf = bp->data; | 2368 | leaf = bp->b_addr; |
2349 | cursor = context->cursor; | 2369 | cursor = context->cursor; |
2350 | cursor->initted = 1; | 2370 | cursor->initted = 1; |
2351 | 2371 | ||
@@ -2463,7 +2483,7 @@ xfs_attr_leaf_clearflag(xfs_da_args_t *args) | |||
2463 | xfs_attr_leafblock_t *leaf; | 2483 | xfs_attr_leafblock_t *leaf; |
2464 | xfs_attr_leaf_entry_t *entry; | 2484 | xfs_attr_leaf_entry_t *entry; |
2465 | xfs_attr_leaf_name_remote_t *name_rmt; | 2485 | xfs_attr_leaf_name_remote_t *name_rmt; |
2466 | xfs_dabuf_t *bp; | 2486 | struct xfs_buf *bp; |
2467 | int error; | 2487 | int error; |
2468 | #ifdef DEBUG | 2488 | #ifdef DEBUG |
2469 | xfs_attr_leaf_name_local_t *name_loc; | 2489 | xfs_attr_leaf_name_local_t *name_loc; |
@@ -2482,7 +2502,7 @@ xfs_attr_leaf_clearflag(xfs_da_args_t *args) | |||
2482 | } | 2502 | } |
2483 | ASSERT(bp != NULL); | 2503 | ASSERT(bp != NULL); |
2484 | 2504 | ||
2485 | leaf = bp->data; | 2505 | leaf = bp->b_addr; |
2486 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); | 2506 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); |
2487 | ASSERT(args->index < be16_to_cpu(leaf->hdr.count)); | 2507 | ASSERT(args->index < be16_to_cpu(leaf->hdr.count)); |
2488 | ASSERT(args->index >= 0); | 2508 | ASSERT(args->index >= 0); |
@@ -2505,7 +2525,7 @@ xfs_attr_leaf_clearflag(xfs_da_args_t *args) | |||
2505 | #endif /* DEBUG */ | 2525 | #endif /* DEBUG */ |
2506 | 2526 | ||
2507 | entry->flags &= ~XFS_ATTR_INCOMPLETE; | 2527 | entry->flags &= ~XFS_ATTR_INCOMPLETE; |
2508 | xfs_da_log_buf(args->trans, bp, | 2528 | xfs_trans_log_buf(args->trans, bp, |
2509 | XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry))); | 2529 | XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry))); |
2510 | 2530 | ||
2511 | if (args->rmtblkno) { | 2531 | if (args->rmtblkno) { |
@@ -2513,10 +2533,9 @@ xfs_attr_leaf_clearflag(xfs_da_args_t *args) | |||
2513 | name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); | 2533 | name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); |
2514 | name_rmt->valueblk = cpu_to_be32(args->rmtblkno); | 2534 | name_rmt->valueblk = cpu_to_be32(args->rmtblkno); |
2515 | name_rmt->valuelen = cpu_to_be32(args->valuelen); | 2535 | name_rmt->valuelen = cpu_to_be32(args->valuelen); |
2516 | xfs_da_log_buf(args->trans, bp, | 2536 | xfs_trans_log_buf(args->trans, bp, |
2517 | XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt))); | 2537 | XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt))); |
2518 | } | 2538 | } |
2519 | xfs_da_buf_done(bp); | ||
2520 | 2539 | ||
2521 | /* | 2540 | /* |
2522 | * Commit the flag value change and start the next trans in series. | 2541 | * Commit the flag value change and start the next trans in series. |
@@ -2533,7 +2552,7 @@ xfs_attr_leaf_setflag(xfs_da_args_t *args) | |||
2533 | xfs_attr_leafblock_t *leaf; | 2552 | xfs_attr_leafblock_t *leaf; |
2534 | xfs_attr_leaf_entry_t *entry; | 2553 | xfs_attr_leaf_entry_t *entry; |
2535 | xfs_attr_leaf_name_remote_t *name_rmt; | 2554 | xfs_attr_leaf_name_remote_t *name_rmt; |
2536 | xfs_dabuf_t *bp; | 2555 | struct xfs_buf *bp; |
2537 | int error; | 2556 | int error; |
2538 | 2557 | ||
2539 | trace_xfs_attr_leaf_setflag(args); | 2558 | trace_xfs_attr_leaf_setflag(args); |
@@ -2548,7 +2567,7 @@ xfs_attr_leaf_setflag(xfs_da_args_t *args) | |||
2548 | } | 2567 | } |
2549 | ASSERT(bp != NULL); | 2568 | ASSERT(bp != NULL); |
2550 | 2569 | ||
2551 | leaf = bp->data; | 2570 | leaf = bp->b_addr; |
2552 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); | 2571 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); |
2553 | ASSERT(args->index < be16_to_cpu(leaf->hdr.count)); | 2572 | ASSERT(args->index < be16_to_cpu(leaf->hdr.count)); |
2554 | ASSERT(args->index >= 0); | 2573 | ASSERT(args->index >= 0); |
@@ -2556,16 +2575,15 @@ xfs_attr_leaf_setflag(xfs_da_args_t *args) | |||
2556 | 2575 | ||
2557 | ASSERT((entry->flags & XFS_ATTR_INCOMPLETE) == 0); | 2576 | ASSERT((entry->flags & XFS_ATTR_INCOMPLETE) == 0); |
2558 | entry->flags |= XFS_ATTR_INCOMPLETE; | 2577 | entry->flags |= XFS_ATTR_INCOMPLETE; |
2559 | xfs_da_log_buf(args->trans, bp, | 2578 | xfs_trans_log_buf(args->trans, bp, |
2560 | XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry))); | 2579 | XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry))); |
2561 | if ((entry->flags & XFS_ATTR_LOCAL) == 0) { | 2580 | if ((entry->flags & XFS_ATTR_LOCAL) == 0) { |
2562 | name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); | 2581 | name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); |
2563 | name_rmt->valueblk = 0; | 2582 | name_rmt->valueblk = 0; |
2564 | name_rmt->valuelen = 0; | 2583 | name_rmt->valuelen = 0; |
2565 | xfs_da_log_buf(args->trans, bp, | 2584 | xfs_trans_log_buf(args->trans, bp, |
2566 | XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt))); | 2585 | XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt))); |
2567 | } | 2586 | } |
2568 | xfs_da_buf_done(bp); | ||
2569 | 2587 | ||
2570 | /* | 2588 | /* |
2571 | * Commit the flag value change and start the next trans in series. | 2589 | * Commit the flag value change and start the next trans in series. |
@@ -2586,7 +2604,7 @@ xfs_attr_leaf_flipflags(xfs_da_args_t *args) | |||
2586 | xfs_attr_leafblock_t *leaf1, *leaf2; | 2604 | xfs_attr_leafblock_t *leaf1, *leaf2; |
2587 | xfs_attr_leaf_entry_t *entry1, *entry2; | 2605 | xfs_attr_leaf_entry_t *entry1, *entry2; |
2588 | xfs_attr_leaf_name_remote_t *name_rmt; | 2606 | xfs_attr_leaf_name_remote_t *name_rmt; |
2589 | xfs_dabuf_t *bp1, *bp2; | 2607 | struct xfs_buf *bp1, *bp2; |
2590 | int error; | 2608 | int error; |
2591 | #ifdef DEBUG | 2609 | #ifdef DEBUG |
2592 | xfs_attr_leaf_name_local_t *name_loc; | 2610 | xfs_attr_leaf_name_local_t *name_loc; |
@@ -2620,13 +2638,13 @@ xfs_attr_leaf_flipflags(xfs_da_args_t *args) | |||
2620 | bp2 = bp1; | 2638 | bp2 = bp1; |
2621 | } | 2639 | } |
2622 | 2640 | ||
2623 | leaf1 = bp1->data; | 2641 | leaf1 = bp1->b_addr; |
2624 | ASSERT(leaf1->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); | 2642 | ASSERT(leaf1->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); |
2625 | ASSERT(args->index < be16_to_cpu(leaf1->hdr.count)); | 2643 | ASSERT(args->index < be16_to_cpu(leaf1->hdr.count)); |
2626 | ASSERT(args->index >= 0); | 2644 | ASSERT(args->index >= 0); |
2627 | entry1 = &leaf1->entries[ args->index ]; | 2645 | entry1 = &leaf1->entries[ args->index ]; |
2628 | 2646 | ||
2629 | leaf2 = bp2->data; | 2647 | leaf2 = bp2->b_addr; |
2630 | ASSERT(leaf2->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); | 2648 | ASSERT(leaf2->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); |
2631 | ASSERT(args->index2 < be16_to_cpu(leaf2->hdr.count)); | 2649 | ASSERT(args->index2 < be16_to_cpu(leaf2->hdr.count)); |
2632 | ASSERT(args->index2 >= 0); | 2650 | ASSERT(args->index2 >= 0); |
@@ -2660,30 +2678,27 @@ xfs_attr_leaf_flipflags(xfs_da_args_t *args) | |||
2660 | ASSERT((entry2->flags & XFS_ATTR_INCOMPLETE) == 0); | 2678 | ASSERT((entry2->flags & XFS_ATTR_INCOMPLETE) == 0); |
2661 | 2679 | ||
2662 | entry1->flags &= ~XFS_ATTR_INCOMPLETE; | 2680 | entry1->flags &= ~XFS_ATTR_INCOMPLETE; |
2663 | xfs_da_log_buf(args->trans, bp1, | 2681 | xfs_trans_log_buf(args->trans, bp1, |
2664 | XFS_DA_LOGRANGE(leaf1, entry1, sizeof(*entry1))); | 2682 | XFS_DA_LOGRANGE(leaf1, entry1, sizeof(*entry1))); |
2665 | if (args->rmtblkno) { | 2683 | if (args->rmtblkno) { |
2666 | ASSERT((entry1->flags & XFS_ATTR_LOCAL) == 0); | 2684 | ASSERT((entry1->flags & XFS_ATTR_LOCAL) == 0); |
2667 | name_rmt = xfs_attr_leaf_name_remote(leaf1, args->index); | 2685 | name_rmt = xfs_attr_leaf_name_remote(leaf1, args->index); |
2668 | name_rmt->valueblk = cpu_to_be32(args->rmtblkno); | 2686 | name_rmt->valueblk = cpu_to_be32(args->rmtblkno); |
2669 | name_rmt->valuelen = cpu_to_be32(args->valuelen); | 2687 | name_rmt->valuelen = cpu_to_be32(args->valuelen); |
2670 | xfs_da_log_buf(args->trans, bp1, | 2688 | xfs_trans_log_buf(args->trans, bp1, |
2671 | XFS_DA_LOGRANGE(leaf1, name_rmt, sizeof(*name_rmt))); | 2689 | XFS_DA_LOGRANGE(leaf1, name_rmt, sizeof(*name_rmt))); |
2672 | } | 2690 | } |
2673 | 2691 | ||
2674 | entry2->flags |= XFS_ATTR_INCOMPLETE; | 2692 | entry2->flags |= XFS_ATTR_INCOMPLETE; |
2675 | xfs_da_log_buf(args->trans, bp2, | 2693 | xfs_trans_log_buf(args->trans, bp2, |
2676 | XFS_DA_LOGRANGE(leaf2, entry2, sizeof(*entry2))); | 2694 | XFS_DA_LOGRANGE(leaf2, entry2, sizeof(*entry2))); |
2677 | if ((entry2->flags & XFS_ATTR_LOCAL) == 0) { | 2695 | if ((entry2->flags & XFS_ATTR_LOCAL) == 0) { |
2678 | name_rmt = xfs_attr_leaf_name_remote(leaf2, args->index2); | 2696 | name_rmt = xfs_attr_leaf_name_remote(leaf2, args->index2); |
2679 | name_rmt->valueblk = 0; | 2697 | name_rmt->valueblk = 0; |
2680 | name_rmt->valuelen = 0; | 2698 | name_rmt->valuelen = 0; |
2681 | xfs_da_log_buf(args->trans, bp2, | 2699 | xfs_trans_log_buf(args->trans, bp2, |
2682 | XFS_DA_LOGRANGE(leaf2, name_rmt, sizeof(*name_rmt))); | 2700 | XFS_DA_LOGRANGE(leaf2, name_rmt, sizeof(*name_rmt))); |
2683 | } | 2701 | } |
2684 | xfs_da_buf_done(bp1); | ||
2685 | if (bp1 != bp2) | ||
2686 | xfs_da_buf_done(bp2); | ||
2687 | 2702 | ||
2688 | /* | 2703 | /* |
2689 | * Commit the flag value change and start the next trans in series. | 2704 | * Commit the flag value change and start the next trans in series. |
@@ -2706,7 +2721,7 @@ xfs_attr_root_inactive(xfs_trans_t **trans, xfs_inode_t *dp) | |||
2706 | { | 2721 | { |
2707 | xfs_da_blkinfo_t *info; | 2722 | xfs_da_blkinfo_t *info; |
2708 | xfs_daddr_t blkno; | 2723 | xfs_daddr_t blkno; |
2709 | xfs_dabuf_t *bp; | 2724 | struct xfs_buf *bp; |
2710 | int error; | 2725 | int error; |
2711 | 2726 | ||
2712 | /* | 2727 | /* |
@@ -2718,20 +2733,20 @@ xfs_attr_root_inactive(xfs_trans_t **trans, xfs_inode_t *dp) | |||
2718 | error = xfs_da_read_buf(*trans, dp, 0, -1, &bp, XFS_ATTR_FORK); | 2733 | error = xfs_da_read_buf(*trans, dp, 0, -1, &bp, XFS_ATTR_FORK); |
2719 | if (error) | 2734 | if (error) |
2720 | return(error); | 2735 | return(error); |
2721 | blkno = xfs_da_blkno(bp); | 2736 | blkno = XFS_BUF_ADDR(bp); |
2722 | 2737 | ||
2723 | /* | 2738 | /* |
2724 | * Invalidate the tree, even if the "tree" is only a single leaf block. | 2739 | * Invalidate the tree, even if the "tree" is only a single leaf block. |
2725 | * This is a depth-first traversal! | 2740 | * This is a depth-first traversal! |
2726 | */ | 2741 | */ |
2727 | info = bp->data; | 2742 | info = bp->b_addr; |
2728 | if (info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC)) { | 2743 | if (info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC)) { |
2729 | error = xfs_attr_node_inactive(trans, dp, bp, 1); | 2744 | error = xfs_attr_node_inactive(trans, dp, bp, 1); |
2730 | } else if (info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)) { | 2745 | } else if (info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)) { |
2731 | error = xfs_attr_leaf_inactive(trans, dp, bp); | 2746 | error = xfs_attr_leaf_inactive(trans, dp, bp); |
2732 | } else { | 2747 | } else { |
2733 | error = XFS_ERROR(EIO); | 2748 | error = XFS_ERROR(EIO); |
2734 | xfs_da_brelse(*trans, bp); | 2749 | xfs_trans_brelse(*trans, bp); |
2735 | } | 2750 | } |
2736 | if (error) | 2751 | if (error) |
2737 | return(error); | 2752 | return(error); |
@@ -2742,7 +2757,7 @@ xfs_attr_root_inactive(xfs_trans_t **trans, xfs_inode_t *dp) | |||
2742 | error = xfs_da_get_buf(*trans, dp, 0, blkno, &bp, XFS_ATTR_FORK); | 2757 | error = xfs_da_get_buf(*trans, dp, 0, blkno, &bp, XFS_ATTR_FORK); |
2743 | if (error) | 2758 | if (error) |
2744 | return(error); | 2759 | return(error); |
2745 | xfs_da_binval(*trans, bp); /* remove from cache */ | 2760 | xfs_trans_binval(*trans, bp); /* remove from cache */ |
2746 | /* | 2761 | /* |
2747 | * Commit the invalidate and start the next transaction. | 2762 | * Commit the invalidate and start the next transaction. |
2748 | */ | 2763 | */ |
@@ -2756,34 +2771,37 @@ xfs_attr_root_inactive(xfs_trans_t **trans, xfs_inode_t *dp) | |||
2756 | * We're doing a depth-first traversal in order to invalidate everything. | 2771 | * We're doing a depth-first traversal in order to invalidate everything. |
2757 | */ | 2772 | */ |
2758 | STATIC int | 2773 | STATIC int |
2759 | xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp, | 2774 | xfs_attr_node_inactive( |
2760 | int level) | 2775 | struct xfs_trans **trans, |
2776 | struct xfs_inode *dp, | ||
2777 | struct xfs_buf *bp, | ||
2778 | int level) | ||
2761 | { | 2779 | { |
2762 | xfs_da_blkinfo_t *info; | 2780 | xfs_da_blkinfo_t *info; |
2763 | xfs_da_intnode_t *node; | 2781 | xfs_da_intnode_t *node; |
2764 | xfs_dablk_t child_fsb; | 2782 | xfs_dablk_t child_fsb; |
2765 | xfs_daddr_t parent_blkno, child_blkno; | 2783 | xfs_daddr_t parent_blkno, child_blkno; |
2766 | int error, count, i; | 2784 | int error, count, i; |
2767 | xfs_dabuf_t *child_bp; | 2785 | struct xfs_buf *child_bp; |
2768 | 2786 | ||
2769 | /* | 2787 | /* |
2770 | * Since this code is recursive (gasp!) we must protect ourselves. | 2788 | * Since this code is recursive (gasp!) we must protect ourselves. |
2771 | */ | 2789 | */ |
2772 | if (level > XFS_DA_NODE_MAXDEPTH) { | 2790 | if (level > XFS_DA_NODE_MAXDEPTH) { |
2773 | xfs_da_brelse(*trans, bp); /* no locks for later trans */ | 2791 | xfs_trans_brelse(*trans, bp); /* no locks for later trans */ |
2774 | return(XFS_ERROR(EIO)); | 2792 | return(XFS_ERROR(EIO)); |
2775 | } | 2793 | } |
2776 | 2794 | ||
2777 | node = bp->data; | 2795 | node = bp->b_addr; |
2778 | ASSERT(node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); | 2796 | ASSERT(node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); |
2779 | parent_blkno = xfs_da_blkno(bp); /* save for re-read later */ | 2797 | parent_blkno = XFS_BUF_ADDR(bp); /* save for re-read later */ |
2780 | count = be16_to_cpu(node->hdr.count); | 2798 | count = be16_to_cpu(node->hdr.count); |
2781 | if (!count) { | 2799 | if (!count) { |
2782 | xfs_da_brelse(*trans, bp); | 2800 | xfs_trans_brelse(*trans, bp); |
2783 | return(0); | 2801 | return(0); |
2784 | } | 2802 | } |
2785 | child_fsb = be32_to_cpu(node->btree[0].before); | 2803 | child_fsb = be32_to_cpu(node->btree[0].before); |
2786 | xfs_da_brelse(*trans, bp); /* no locks for later trans */ | 2804 | xfs_trans_brelse(*trans, bp); /* no locks for later trans */ |
2787 | 2805 | ||
2788 | /* | 2806 | /* |
2789 | * If this is the node level just above the leaves, simply loop | 2807 | * If this is the node level just above the leaves, simply loop |
@@ -2803,12 +2821,12 @@ xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp, | |||
2803 | return(error); | 2821 | return(error); |
2804 | if (child_bp) { | 2822 | if (child_bp) { |
2805 | /* save for re-read later */ | 2823 | /* save for re-read later */ |
2806 | child_blkno = xfs_da_blkno(child_bp); | 2824 | child_blkno = XFS_BUF_ADDR(child_bp); |
2807 | 2825 | ||
2808 | /* | 2826 | /* |
2809 | * Invalidate the subtree, however we have to. | 2827 | * Invalidate the subtree, however we have to. |
2810 | */ | 2828 | */ |
2811 | info = child_bp->data; | 2829 | info = child_bp->b_addr; |
2812 | if (info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC)) { | 2830 | if (info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC)) { |
2813 | error = xfs_attr_node_inactive(trans, dp, | 2831 | error = xfs_attr_node_inactive(trans, dp, |
2814 | child_bp, level+1); | 2832 | child_bp, level+1); |
@@ -2817,7 +2835,7 @@ xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp, | |||
2817 | child_bp); | 2835 | child_bp); |
2818 | } else { | 2836 | } else { |
2819 | error = XFS_ERROR(EIO); | 2837 | error = XFS_ERROR(EIO); |
2820 | xfs_da_brelse(*trans, child_bp); | 2838 | xfs_trans_brelse(*trans, child_bp); |
2821 | } | 2839 | } |
2822 | if (error) | 2840 | if (error) |
2823 | return(error); | 2841 | return(error); |
@@ -2830,7 +2848,7 @@ xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp, | |||
2830 | &child_bp, XFS_ATTR_FORK); | 2848 | &child_bp, XFS_ATTR_FORK); |
2831 | if (error) | 2849 | if (error) |
2832 | return(error); | 2850 | return(error); |
2833 | xfs_da_binval(*trans, child_bp); | 2851 | xfs_trans_binval(*trans, child_bp); |
2834 | } | 2852 | } |
2835 | 2853 | ||
2836 | /* | 2854 | /* |
@@ -2843,7 +2861,7 @@ xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp, | |||
2843 | if (error) | 2861 | if (error) |
2844 | return(error); | 2862 | return(error); |
2845 | child_fsb = be32_to_cpu(node->btree[i+1].before); | 2863 | child_fsb = be32_to_cpu(node->btree[i+1].before); |
2846 | xfs_da_brelse(*trans, bp); | 2864 | xfs_trans_brelse(*trans, bp); |
2847 | } | 2865 | } |
2848 | /* | 2866 | /* |
2849 | * Atomically commit the whole invalidate stuff. | 2867 | * Atomically commit the whole invalidate stuff. |
@@ -2863,7 +2881,10 @@ xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp, | |||
2863 | * caught holding something that the logging code wants to flush to disk. | 2881 | * caught holding something that the logging code wants to flush to disk. |
2864 | */ | 2882 | */ |
2865 | STATIC int | 2883 | STATIC int |
2866 | xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp) | 2884 | xfs_attr_leaf_inactive( |
2885 | struct xfs_trans **trans, | ||
2886 | struct xfs_inode *dp, | ||
2887 | struct xfs_buf *bp) | ||
2867 | { | 2888 | { |
2868 | xfs_attr_leafblock_t *leaf; | 2889 | xfs_attr_leafblock_t *leaf; |
2869 | xfs_attr_leaf_entry_t *entry; | 2890 | xfs_attr_leaf_entry_t *entry; |
@@ -2871,7 +2892,7 @@ xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp) | |||
2871 | xfs_attr_inactive_list_t *list, *lp; | 2892 | xfs_attr_inactive_list_t *list, *lp; |
2872 | int error, count, size, tmp, i; | 2893 | int error, count, size, tmp, i; |
2873 | 2894 | ||
2874 | leaf = bp->data; | 2895 | leaf = bp->b_addr; |
2875 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); | 2896 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); |
2876 | 2897 | ||
2877 | /* | 2898 | /* |
@@ -2892,7 +2913,7 @@ xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp) | |||
2892 | * If there are no "remote" values, we're done. | 2913 | * If there are no "remote" values, we're done. |
2893 | */ | 2914 | */ |
2894 | if (count == 0) { | 2915 | if (count == 0) { |
2895 | xfs_da_brelse(*trans, bp); | 2916 | xfs_trans_brelse(*trans, bp); |
2896 | return(0); | 2917 | return(0); |
2897 | } | 2918 | } |
2898 | 2919 | ||
@@ -2919,7 +2940,7 @@ xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp) | |||
2919 | } | 2940 | } |
2920 | } | 2941 | } |
2921 | } | 2942 | } |
2922 | xfs_da_brelse(*trans, bp); /* unlock for trans. in freextent() */ | 2943 | xfs_trans_brelse(*trans, bp); /* unlock for trans. in freextent() */ |
2923 | 2944 | ||
2924 | /* | 2945 | /* |
2925 | * Invalidate each of the "remote" value extents. | 2946 | * Invalidate each of the "remote" value extents. |
diff --git a/fs/xfs/xfs_attr_leaf.h b/fs/xfs/xfs_attr_leaf.h index 9c7d22fdcf4d..dea17722945e 100644 --- a/fs/xfs/xfs_attr_leaf.h +++ b/fs/xfs/xfs_attr_leaf.h | |||
@@ -31,7 +31,6 @@ | |||
31 | struct attrlist; | 31 | struct attrlist; |
32 | struct attrlist_cursor_kern; | 32 | struct attrlist_cursor_kern; |
33 | struct xfs_attr_list_context; | 33 | struct xfs_attr_list_context; |
34 | struct xfs_dabuf; | ||
35 | struct xfs_da_args; | 34 | struct xfs_da_args; |
36 | struct xfs_da_state; | 35 | struct xfs_da_state; |
37 | struct xfs_da_state_blk; | 36 | struct xfs_da_state_blk; |
@@ -215,7 +214,7 @@ int xfs_attr_shortform_getvalue(struct xfs_da_args *args); | |||
215 | int xfs_attr_shortform_to_leaf(struct xfs_da_args *args); | 214 | int xfs_attr_shortform_to_leaf(struct xfs_da_args *args); |
216 | int xfs_attr_shortform_remove(struct xfs_da_args *args); | 215 | int xfs_attr_shortform_remove(struct xfs_da_args *args); |
217 | int xfs_attr_shortform_list(struct xfs_attr_list_context *context); | 216 | int xfs_attr_shortform_list(struct xfs_attr_list_context *context); |
218 | int xfs_attr_shortform_allfit(struct xfs_dabuf *bp, struct xfs_inode *dp); | 217 | int xfs_attr_shortform_allfit(struct xfs_buf *bp, struct xfs_inode *dp); |
219 | int xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes); | 218 | int xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes); |
220 | 219 | ||
221 | 220 | ||
@@ -223,7 +222,7 @@ int xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes); | |||
223 | * Internal routines when attribute fork size == XFS_LBSIZE(mp). | 222 | * Internal routines when attribute fork size == XFS_LBSIZE(mp). |
224 | */ | 223 | */ |
225 | int xfs_attr_leaf_to_node(struct xfs_da_args *args); | 224 | int xfs_attr_leaf_to_node(struct xfs_da_args *args); |
226 | int xfs_attr_leaf_to_shortform(struct xfs_dabuf *bp, | 225 | int xfs_attr_leaf_to_shortform(struct xfs_buf *bp, |
227 | struct xfs_da_args *args, int forkoff); | 226 | struct xfs_da_args *args, int forkoff); |
228 | int xfs_attr_leaf_clearflag(struct xfs_da_args *args); | 227 | int xfs_attr_leaf_clearflag(struct xfs_da_args *args); |
229 | int xfs_attr_leaf_setflag(struct xfs_da_args *args); | 228 | int xfs_attr_leaf_setflag(struct xfs_da_args *args); |
@@ -235,14 +234,14 @@ int xfs_attr_leaf_flipflags(xfs_da_args_t *args); | |||
235 | int xfs_attr_leaf_split(struct xfs_da_state *state, | 234 | int xfs_attr_leaf_split(struct xfs_da_state *state, |
236 | struct xfs_da_state_blk *oldblk, | 235 | struct xfs_da_state_blk *oldblk, |
237 | struct xfs_da_state_blk *newblk); | 236 | struct xfs_da_state_blk *newblk); |
238 | int xfs_attr_leaf_lookup_int(struct xfs_dabuf *leaf, | 237 | int xfs_attr_leaf_lookup_int(struct xfs_buf *leaf, |
239 | struct xfs_da_args *args); | 238 | struct xfs_da_args *args); |
240 | int xfs_attr_leaf_getvalue(struct xfs_dabuf *bp, struct xfs_da_args *args); | 239 | int xfs_attr_leaf_getvalue(struct xfs_buf *bp, struct xfs_da_args *args); |
241 | int xfs_attr_leaf_add(struct xfs_dabuf *leaf_buffer, | 240 | int xfs_attr_leaf_add(struct xfs_buf *leaf_buffer, |
242 | struct xfs_da_args *args); | 241 | struct xfs_da_args *args); |
243 | int xfs_attr_leaf_remove(struct xfs_dabuf *leaf_buffer, | 242 | int xfs_attr_leaf_remove(struct xfs_buf *leaf_buffer, |
244 | struct xfs_da_args *args); | 243 | struct xfs_da_args *args); |
245 | int xfs_attr_leaf_list_int(struct xfs_dabuf *bp, | 244 | int xfs_attr_leaf_list_int(struct xfs_buf *bp, |
246 | struct xfs_attr_list_context *context); | 245 | struct xfs_attr_list_context *context); |
247 | 246 | ||
248 | /* | 247 | /* |
@@ -257,9 +256,9 @@ int xfs_attr_root_inactive(struct xfs_trans **trans, struct xfs_inode *dp); | |||
257 | /* | 256 | /* |
258 | * Utility routines. | 257 | * Utility routines. |
259 | */ | 258 | */ |
260 | xfs_dahash_t xfs_attr_leaf_lasthash(struct xfs_dabuf *bp, int *count); | 259 | xfs_dahash_t xfs_attr_leaf_lasthash(struct xfs_buf *bp, int *count); |
261 | int xfs_attr_leaf_order(struct xfs_dabuf *leaf1_bp, | 260 | int xfs_attr_leaf_order(struct xfs_buf *leaf1_bp, |
262 | struct xfs_dabuf *leaf2_bp); | 261 | struct xfs_buf *leaf2_bp); |
263 | int xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, | 262 | int xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, |
264 | int *local); | 263 | int *local); |
265 | #endif /* __XFS_ATTR_LEAF_H__ */ | 264 | #endif /* __XFS_ATTR_LEAF_H__ */ |
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 58b815ec8c91..848ffa77707b 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -5517,7 +5517,7 @@ xfs_getbmap( | |||
5517 | if (xfs_get_extsz_hint(ip) || | 5517 | if (xfs_get_extsz_hint(ip) || |
5518 | ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC|XFS_DIFLAG_APPEND)){ | 5518 | ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC|XFS_DIFLAG_APPEND)){ |
5519 | prealloced = 1; | 5519 | prealloced = 1; |
5520 | fixlen = XFS_MAXIOFFSET(mp); | 5520 | fixlen = mp->m_super->s_maxbytes; |
5521 | } else { | 5521 | } else { |
5522 | prealloced = 0; | 5522 | prealloced = 0; |
5523 | fixlen = XFS_ISIZE(ip); | 5523 | fixlen = XFS_ISIZE(ip); |
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 269b35c084da..d7a9dd735e1e 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c | |||
@@ -164,14 +164,49 @@ xfs_buf_stale( | |||
164 | ASSERT(atomic_read(&bp->b_hold) >= 1); | 164 | ASSERT(atomic_read(&bp->b_hold) >= 1); |
165 | } | 165 | } |
166 | 166 | ||
167 | static int | ||
168 | xfs_buf_get_maps( | ||
169 | struct xfs_buf *bp, | ||
170 | int map_count) | ||
171 | { | ||
172 | ASSERT(bp->b_maps == NULL); | ||
173 | bp->b_map_count = map_count; | ||
174 | |||
175 | if (map_count == 1) { | ||
176 | bp->b_maps = &bp->b_map; | ||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | bp->b_maps = kmem_zalloc(map_count * sizeof(struct xfs_buf_map), | ||
181 | KM_NOFS); | ||
182 | if (!bp->b_maps) | ||
183 | return ENOMEM; | ||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | /* | ||
188 | * Frees b_pages if it was allocated. | ||
189 | */ | ||
190 | static void | ||
191 | xfs_buf_free_maps( | ||
192 | struct xfs_buf *bp) | ||
193 | { | ||
194 | if (bp->b_maps != &bp->b_map) { | ||
195 | kmem_free(bp->b_maps); | ||
196 | bp->b_maps = NULL; | ||
197 | } | ||
198 | } | ||
199 | |||
167 | struct xfs_buf * | 200 | struct xfs_buf * |
168 | xfs_buf_alloc( | 201 | _xfs_buf_alloc( |
169 | struct xfs_buftarg *target, | 202 | struct xfs_buftarg *target, |
170 | xfs_daddr_t blkno, | 203 | struct xfs_buf_map *map, |
171 | size_t numblks, | 204 | int nmaps, |
172 | xfs_buf_flags_t flags) | 205 | xfs_buf_flags_t flags) |
173 | { | 206 | { |
174 | struct xfs_buf *bp; | 207 | struct xfs_buf *bp; |
208 | int error; | ||
209 | int i; | ||
175 | 210 | ||
176 | bp = kmem_zone_zalloc(xfs_buf_zone, KM_NOFS); | 211 | bp = kmem_zone_zalloc(xfs_buf_zone, KM_NOFS); |
177 | if (unlikely(!bp)) | 212 | if (unlikely(!bp)) |
@@ -192,16 +227,28 @@ xfs_buf_alloc( | |||
192 | sema_init(&bp->b_sema, 0); /* held, no waiters */ | 227 | sema_init(&bp->b_sema, 0); /* held, no waiters */ |
193 | XB_SET_OWNER(bp); | 228 | XB_SET_OWNER(bp); |
194 | bp->b_target = target; | 229 | bp->b_target = target; |
230 | bp->b_flags = flags; | ||
195 | 231 | ||
196 | /* | 232 | /* |
197 | * Set length and io_length to the same value initially. | 233 | * Set length and io_length to the same value initially. |
198 | * I/O routines should use io_length, which will be the same in | 234 | * I/O routines should use io_length, which will be the same in |
199 | * most cases but may be reset (e.g. XFS recovery). | 235 | * most cases but may be reset (e.g. XFS recovery). |
200 | */ | 236 | */ |
201 | bp->b_length = numblks; | 237 | error = xfs_buf_get_maps(bp, nmaps); |
202 | bp->b_io_length = numblks; | 238 | if (error) { |
203 | bp->b_flags = flags; | 239 | kmem_zone_free(xfs_buf_zone, bp); |
204 | bp->b_bn = blkno; | 240 | return NULL; |
241 | } | ||
242 | |||
243 | bp->b_bn = map[0].bm_bn; | ||
244 | bp->b_length = 0; | ||
245 | for (i = 0; i < nmaps; i++) { | ||
246 | bp->b_maps[i].bm_bn = map[i].bm_bn; | ||
247 | bp->b_maps[i].bm_len = map[i].bm_len; | ||
248 | bp->b_length += map[i].bm_len; | ||
249 | } | ||
250 | bp->b_io_length = bp->b_length; | ||
251 | |||
205 | atomic_set(&bp->b_pin_count, 0); | 252 | atomic_set(&bp->b_pin_count, 0); |
206 | init_waitqueue_head(&bp->b_waiters); | 253 | init_waitqueue_head(&bp->b_waiters); |
207 | 254 | ||
@@ -280,6 +327,7 @@ xfs_buf_free( | |||
280 | } else if (bp->b_flags & _XBF_KMEM) | 327 | } else if (bp->b_flags & _XBF_KMEM) |
281 | kmem_free(bp->b_addr); | 328 | kmem_free(bp->b_addr); |
282 | _xfs_buf_free_pages(bp); | 329 | _xfs_buf_free_pages(bp); |
330 | xfs_buf_free_maps(bp); | ||
283 | kmem_zone_free(xfs_buf_zone, bp); | 331 | kmem_zone_free(xfs_buf_zone, bp); |
284 | } | 332 | } |
285 | 333 | ||
@@ -327,8 +375,9 @@ xfs_buf_allocate_memory( | |||
327 | } | 375 | } |
328 | 376 | ||
329 | use_alloc_page: | 377 | use_alloc_page: |
330 | start = BBTOB(bp->b_bn) >> PAGE_SHIFT; | 378 | start = BBTOB(bp->b_map.bm_bn) >> PAGE_SHIFT; |
331 | end = (BBTOB(bp->b_bn + bp->b_length) + PAGE_SIZE - 1) >> PAGE_SHIFT; | 379 | end = (BBTOB(bp->b_map.bm_bn + bp->b_length) + PAGE_SIZE - 1) |
380 | >> PAGE_SHIFT; | ||
332 | page_count = end - start; | 381 | page_count = end - start; |
333 | error = _xfs_buf_get_pages(bp, page_count, flags); | 382 | error = _xfs_buf_get_pages(bp, page_count, flags); |
334 | if (unlikely(error)) | 383 | if (unlikely(error)) |
@@ -425,8 +474,8 @@ _xfs_buf_map_pages( | |||
425 | xfs_buf_t * | 474 | xfs_buf_t * |
426 | _xfs_buf_find( | 475 | _xfs_buf_find( |
427 | struct xfs_buftarg *btp, | 476 | struct xfs_buftarg *btp, |
428 | xfs_daddr_t blkno, | 477 | struct xfs_buf_map *map, |
429 | size_t numblks, | 478 | int nmaps, |
430 | xfs_buf_flags_t flags, | 479 | xfs_buf_flags_t flags, |
431 | xfs_buf_t *new_bp) | 480 | xfs_buf_t *new_bp) |
432 | { | 481 | { |
@@ -435,7 +484,12 @@ _xfs_buf_find( | |||
435 | struct rb_node **rbp; | 484 | struct rb_node **rbp; |
436 | struct rb_node *parent; | 485 | struct rb_node *parent; |
437 | xfs_buf_t *bp; | 486 | xfs_buf_t *bp; |
487 | xfs_daddr_t blkno = map[0].bm_bn; | ||
488 | int numblks = 0; | ||
489 | int i; | ||
438 | 490 | ||
491 | for (i = 0; i < nmaps; i++) | ||
492 | numblks += map[i].bm_len; | ||
439 | numbytes = BBTOB(numblks); | 493 | numbytes = BBTOB(numblks); |
440 | 494 | ||
441 | /* Check for IOs smaller than the sector size / not sector aligned */ | 495 | /* Check for IOs smaller than the sector size / not sector aligned */ |
@@ -527,31 +581,31 @@ found: | |||
527 | * more hits than misses. | 581 | * more hits than misses. |
528 | */ | 582 | */ |
529 | struct xfs_buf * | 583 | struct xfs_buf * |
530 | xfs_buf_get( | 584 | xfs_buf_get_map( |
531 | xfs_buftarg_t *target, | 585 | struct xfs_buftarg *target, |
532 | xfs_daddr_t blkno, | 586 | struct xfs_buf_map *map, |
533 | size_t numblks, | 587 | int nmaps, |
534 | xfs_buf_flags_t flags) | 588 | xfs_buf_flags_t flags) |
535 | { | 589 | { |
536 | struct xfs_buf *bp; | 590 | struct xfs_buf *bp; |
537 | struct xfs_buf *new_bp; | 591 | struct xfs_buf *new_bp; |
538 | int error = 0; | 592 | int error = 0; |
539 | 593 | ||
540 | bp = _xfs_buf_find(target, blkno, numblks, flags, NULL); | 594 | bp = _xfs_buf_find(target, map, nmaps, flags, NULL); |
541 | if (likely(bp)) | 595 | if (likely(bp)) |
542 | goto found; | 596 | goto found; |
543 | 597 | ||
544 | new_bp = xfs_buf_alloc(target, blkno, numblks, flags); | 598 | new_bp = _xfs_buf_alloc(target, map, nmaps, flags); |
545 | if (unlikely(!new_bp)) | 599 | if (unlikely(!new_bp)) |
546 | return NULL; | 600 | return NULL; |
547 | 601 | ||
548 | error = xfs_buf_allocate_memory(new_bp, flags); | 602 | error = xfs_buf_allocate_memory(new_bp, flags); |
549 | if (error) { | 603 | if (error) { |
550 | kmem_zone_free(xfs_buf_zone, new_bp); | 604 | xfs_buf_free(new_bp); |
551 | return NULL; | 605 | return NULL; |
552 | } | 606 | } |
553 | 607 | ||
554 | bp = _xfs_buf_find(target, blkno, numblks, flags, new_bp); | 608 | bp = _xfs_buf_find(target, map, nmaps, flags, new_bp); |
555 | if (!bp) { | 609 | if (!bp) { |
556 | xfs_buf_free(new_bp); | 610 | xfs_buf_free(new_bp); |
557 | return NULL; | 611 | return NULL; |
@@ -560,8 +614,6 @@ xfs_buf_get( | |||
560 | if (bp != new_bp) | 614 | if (bp != new_bp) |
561 | xfs_buf_free(new_bp); | 615 | xfs_buf_free(new_bp); |
562 | 616 | ||
563 | bp->b_io_length = bp->b_length; | ||
564 | |||
565 | found: | 617 | found: |
566 | if (!bp->b_addr) { | 618 | if (!bp->b_addr) { |
567 | error = _xfs_buf_map_pages(bp, flags); | 619 | error = _xfs_buf_map_pages(bp, flags); |
@@ -584,7 +636,7 @@ _xfs_buf_read( | |||
584 | xfs_buf_flags_t flags) | 636 | xfs_buf_flags_t flags) |
585 | { | 637 | { |
586 | ASSERT(!(flags & XBF_WRITE)); | 638 | ASSERT(!(flags & XBF_WRITE)); |
587 | ASSERT(bp->b_bn != XFS_BUF_DADDR_NULL); | 639 | ASSERT(bp->b_map.bm_bn != XFS_BUF_DADDR_NULL); |
588 | 640 | ||
589 | bp->b_flags &= ~(XBF_WRITE | XBF_ASYNC | XBF_READ_AHEAD); | 641 | bp->b_flags &= ~(XBF_WRITE | XBF_ASYNC | XBF_READ_AHEAD); |
590 | bp->b_flags |= flags & (XBF_READ | XBF_ASYNC | XBF_READ_AHEAD); | 642 | bp->b_flags |= flags & (XBF_READ | XBF_ASYNC | XBF_READ_AHEAD); |
@@ -596,17 +648,17 @@ _xfs_buf_read( | |||
596 | } | 648 | } |
597 | 649 | ||
598 | xfs_buf_t * | 650 | xfs_buf_t * |
599 | xfs_buf_read( | 651 | xfs_buf_read_map( |
600 | xfs_buftarg_t *target, | 652 | struct xfs_buftarg *target, |
601 | xfs_daddr_t blkno, | 653 | struct xfs_buf_map *map, |
602 | size_t numblks, | 654 | int nmaps, |
603 | xfs_buf_flags_t flags) | 655 | xfs_buf_flags_t flags) |
604 | { | 656 | { |
605 | xfs_buf_t *bp; | 657 | struct xfs_buf *bp; |
606 | 658 | ||
607 | flags |= XBF_READ; | 659 | flags |= XBF_READ; |
608 | 660 | ||
609 | bp = xfs_buf_get(target, blkno, numblks, flags); | 661 | bp = xfs_buf_get_map(target, map, nmaps, flags); |
610 | if (bp) { | 662 | if (bp) { |
611 | trace_xfs_buf_read(bp, flags, _RET_IP_); | 663 | trace_xfs_buf_read(bp, flags, _RET_IP_); |
612 | 664 | ||
@@ -634,15 +686,15 @@ xfs_buf_read( | |||
634 | * safe manner. | 686 | * safe manner. |
635 | */ | 687 | */ |
636 | void | 688 | void |
637 | xfs_buf_readahead( | 689 | xfs_buf_readahead_map( |
638 | xfs_buftarg_t *target, | 690 | struct xfs_buftarg *target, |
639 | xfs_daddr_t blkno, | 691 | struct xfs_buf_map *map, |
640 | size_t numblks) | 692 | int nmaps) |
641 | { | 693 | { |
642 | if (bdi_read_congested(target->bt_bdi)) | 694 | if (bdi_read_congested(target->bt_bdi)) |
643 | return; | 695 | return; |
644 | 696 | ||
645 | xfs_buf_read(target, blkno, numblks, | 697 | xfs_buf_read_map(target, map, nmaps, |
646 | XBF_TRYLOCK|XBF_ASYNC|XBF_READ_AHEAD); | 698 | XBF_TRYLOCK|XBF_ASYNC|XBF_READ_AHEAD); |
647 | } | 699 | } |
648 | 700 | ||
@@ -665,8 +717,10 @@ xfs_buf_read_uncached( | |||
665 | return NULL; | 717 | return NULL; |
666 | 718 | ||
667 | /* set up the buffer for a read IO */ | 719 | /* set up the buffer for a read IO */ |
668 | XFS_BUF_SET_ADDR(bp, daddr); | 720 | ASSERT(bp->b_map_count == 1); |
669 | XFS_BUF_READ(bp); | 721 | bp->b_bn = daddr; |
722 | bp->b_maps[0].bm_bn = daddr; | ||
723 | bp->b_flags |= XBF_READ; | ||
670 | 724 | ||
671 | xfsbdstrat(target->bt_mount, bp); | 725 | xfsbdstrat(target->bt_mount, bp); |
672 | error = xfs_buf_iowait(bp); | 726 | error = xfs_buf_iowait(bp); |
@@ -694,7 +748,11 @@ xfs_buf_set_empty( | |||
694 | bp->b_addr = NULL; | 748 | bp->b_addr = NULL; |
695 | bp->b_length = numblks; | 749 | bp->b_length = numblks; |
696 | bp->b_io_length = numblks; | 750 | bp->b_io_length = numblks; |
751 | |||
752 | ASSERT(bp->b_map_count == 1); | ||
697 | bp->b_bn = XFS_BUF_DADDR_NULL; | 753 | bp->b_bn = XFS_BUF_DADDR_NULL; |
754 | bp->b_maps[0].bm_bn = XFS_BUF_DADDR_NULL; | ||
755 | bp->b_maps[0].bm_len = bp->b_length; | ||
698 | } | 756 | } |
699 | 757 | ||
700 | static inline struct page * | 758 | static inline struct page * |
@@ -758,9 +816,10 @@ xfs_buf_get_uncached( | |||
758 | { | 816 | { |
759 | unsigned long page_count; | 817 | unsigned long page_count; |
760 | int error, i; | 818 | int error, i; |
761 | xfs_buf_t *bp; | 819 | struct xfs_buf *bp; |
820 | DEFINE_SINGLE_BUF_MAP(map, XFS_BUF_DADDR_NULL, numblks); | ||
762 | 821 | ||
763 | bp = xfs_buf_alloc(target, XFS_BUF_DADDR_NULL, numblks, 0); | 822 | bp = _xfs_buf_alloc(target, &map, 1, 0); |
764 | if (unlikely(bp == NULL)) | 823 | if (unlikely(bp == NULL)) |
765 | goto fail; | 824 | goto fail; |
766 | 825 | ||
@@ -791,6 +850,7 @@ xfs_buf_get_uncached( | |||
791 | __free_page(bp->b_pages[i]); | 850 | __free_page(bp->b_pages[i]); |
792 | _xfs_buf_free_pages(bp); | 851 | _xfs_buf_free_pages(bp); |
793 | fail_free_buf: | 852 | fail_free_buf: |
853 | xfs_buf_free_maps(bp); | ||
794 | kmem_zone_free(xfs_buf_zone, bp); | 854 | kmem_zone_free(xfs_buf_zone, bp); |
795 | fail: | 855 | fail: |
796 | return NULL; | 856 | return NULL; |
@@ -1144,36 +1204,39 @@ xfs_buf_bio_end_io( | |||
1144 | bio_put(bio); | 1204 | bio_put(bio); |
1145 | } | 1205 | } |
1146 | 1206 | ||
1147 | STATIC void | 1207 | static void |
1148 | _xfs_buf_ioapply( | 1208 | xfs_buf_ioapply_map( |
1149 | xfs_buf_t *bp) | 1209 | struct xfs_buf *bp, |
1210 | int map, | ||
1211 | int *buf_offset, | ||
1212 | int *count, | ||
1213 | int rw) | ||
1150 | { | 1214 | { |
1151 | int rw, map_i, total_nr_pages, nr_pages; | 1215 | int page_index; |
1152 | struct bio *bio; | 1216 | int total_nr_pages = bp->b_page_count; |
1153 | int offset = bp->b_offset; | 1217 | int nr_pages; |
1154 | int size = BBTOB(bp->b_io_length); | 1218 | struct bio *bio; |
1155 | sector_t sector = bp->b_bn; | 1219 | sector_t sector = bp->b_maps[map].bm_bn; |
1220 | int size; | ||
1221 | int offset; | ||
1156 | 1222 | ||
1157 | total_nr_pages = bp->b_page_count; | 1223 | total_nr_pages = bp->b_page_count; |
1158 | map_i = 0; | ||
1159 | 1224 | ||
1160 | if (bp->b_flags & XBF_WRITE) { | 1225 | /* skip the pages in the buffer before the start offset */ |
1161 | if (bp->b_flags & XBF_SYNCIO) | 1226 | page_index = 0; |
1162 | rw = WRITE_SYNC; | 1227 | offset = *buf_offset; |
1163 | else | 1228 | while (offset >= PAGE_SIZE) { |
1164 | rw = WRITE; | 1229 | page_index++; |
1165 | if (bp->b_flags & XBF_FUA) | 1230 | offset -= PAGE_SIZE; |
1166 | rw |= REQ_FUA; | ||
1167 | if (bp->b_flags & XBF_FLUSH) | ||
1168 | rw |= REQ_FLUSH; | ||
1169 | } else if (bp->b_flags & XBF_READ_AHEAD) { | ||
1170 | rw = READA; | ||
1171 | } else { | ||
1172 | rw = READ; | ||
1173 | } | 1231 | } |
1174 | 1232 | ||
1175 | /* we only use the buffer cache for meta-data */ | 1233 | /* |
1176 | rw |= REQ_META; | 1234 | * Limit the IO size to the length of the current vector, and update the |
1235 | * remaining IO count for the next time around. | ||
1236 | */ | ||
1237 | size = min_t(int, BBTOB(bp->b_maps[map].bm_len), *count); | ||
1238 | *count -= size; | ||
1239 | *buf_offset += size; | ||
1177 | 1240 | ||
1178 | next_chunk: | 1241 | next_chunk: |
1179 | atomic_inc(&bp->b_io_remaining); | 1242 | atomic_inc(&bp->b_io_remaining); |
@@ -1188,13 +1251,14 @@ next_chunk: | |||
1188 | bio->bi_private = bp; | 1251 | bio->bi_private = bp; |
1189 | 1252 | ||
1190 | 1253 | ||
1191 | for (; size && nr_pages; nr_pages--, map_i++) { | 1254 | for (; size && nr_pages; nr_pages--, page_index++) { |
1192 | int rbytes, nbytes = PAGE_SIZE - offset; | 1255 | int rbytes, nbytes = PAGE_SIZE - offset; |
1193 | 1256 | ||
1194 | if (nbytes > size) | 1257 | if (nbytes > size) |
1195 | nbytes = size; | 1258 | nbytes = size; |
1196 | 1259 | ||
1197 | rbytes = bio_add_page(bio, bp->b_pages[map_i], nbytes, offset); | 1260 | rbytes = bio_add_page(bio, bp->b_pages[page_index], nbytes, |
1261 | offset); | ||
1198 | if (rbytes < nbytes) | 1262 | if (rbytes < nbytes) |
1199 | break; | 1263 | break; |
1200 | 1264 | ||
@@ -1216,6 +1280,54 @@ next_chunk: | |||
1216 | xfs_buf_ioerror(bp, EIO); | 1280 | xfs_buf_ioerror(bp, EIO); |
1217 | bio_put(bio); | 1281 | bio_put(bio); |
1218 | } | 1282 | } |
1283 | |||
1284 | } | ||
1285 | |||
1286 | STATIC void | ||
1287 | _xfs_buf_ioapply( | ||
1288 | struct xfs_buf *bp) | ||
1289 | { | ||
1290 | struct blk_plug plug; | ||
1291 | int rw; | ||
1292 | int offset; | ||
1293 | int size; | ||
1294 | int i; | ||
1295 | |||
1296 | if (bp->b_flags & XBF_WRITE) { | ||
1297 | if (bp->b_flags & XBF_SYNCIO) | ||
1298 | rw = WRITE_SYNC; | ||
1299 | else | ||
1300 | rw = WRITE; | ||
1301 | if (bp->b_flags & XBF_FUA) | ||
1302 | rw |= REQ_FUA; | ||
1303 | if (bp->b_flags & XBF_FLUSH) | ||
1304 | rw |= REQ_FLUSH; | ||
1305 | } else if (bp->b_flags & XBF_READ_AHEAD) { | ||
1306 | rw = READA; | ||
1307 | } else { | ||
1308 | rw = READ; | ||
1309 | } | ||
1310 | |||
1311 | /* we only use the buffer cache for meta-data */ | ||
1312 | rw |= REQ_META; | ||
1313 | |||
1314 | /* | ||
1315 | * Walk all the vectors issuing IO on them. Set up the initial offset | ||
1316 | * into the buffer and the desired IO size before we start - | ||
1317 | * _xfs_buf_ioapply_vec() will modify them appropriately for each | ||
1318 | * subsequent call. | ||
1319 | */ | ||
1320 | offset = bp->b_offset; | ||
1321 | size = BBTOB(bp->b_io_length); | ||
1322 | blk_start_plug(&plug); | ||
1323 | for (i = 0; i < bp->b_map_count; i++) { | ||
1324 | xfs_buf_ioapply_map(bp, i, &offset, &size, rw); | ||
1325 | if (bp->b_error) | ||
1326 | break; | ||
1327 | if (size <= 0) | ||
1328 | break; /* all done */ | ||
1329 | } | ||
1330 | blk_finish_plug(&plug); | ||
1219 | } | 1331 | } |
1220 | 1332 | ||
1221 | void | 1333 | void |
@@ -1557,7 +1669,7 @@ xfs_buf_cmp( | |||
1557 | struct xfs_buf *bp = container_of(b, struct xfs_buf, b_list); | 1669 | struct xfs_buf *bp = container_of(b, struct xfs_buf, b_list); |
1558 | xfs_daddr_t diff; | 1670 | xfs_daddr_t diff; |
1559 | 1671 | ||
1560 | diff = ap->b_bn - bp->b_bn; | 1672 | diff = ap->b_map.bm_bn - bp->b_map.bm_bn; |
1561 | if (diff < 0) | 1673 | if (diff < 0) |
1562 | return -1; | 1674 | return -1; |
1563 | if (diff > 0) | 1675 | if (diff > 0) |
diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index 79344c48008e..d03b73b9604e 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h | |||
@@ -58,6 +58,7 @@ typedef enum { | |||
58 | #define _XBF_PAGES (1 << 20)/* backed by refcounted pages */ | 58 | #define _XBF_PAGES (1 << 20)/* backed by refcounted pages */ |
59 | #define _XBF_KMEM (1 << 21)/* backed by heap memory */ | 59 | #define _XBF_KMEM (1 << 21)/* backed by heap memory */ |
60 | #define _XBF_DELWRI_Q (1 << 22)/* buffer on a delwri queue */ | 60 | #define _XBF_DELWRI_Q (1 << 22)/* buffer on a delwri queue */ |
61 | #define _XBF_COMPOUND (1 << 23)/* compound buffer */ | ||
61 | 62 | ||
62 | typedef unsigned int xfs_buf_flags_t; | 63 | typedef unsigned int xfs_buf_flags_t; |
63 | 64 | ||
@@ -75,7 +76,8 @@ typedef unsigned int xfs_buf_flags_t; | |||
75 | { XBF_UNMAPPED, "UNMAPPED" }, /* ditto */\ | 76 | { XBF_UNMAPPED, "UNMAPPED" }, /* ditto */\ |
76 | { _XBF_PAGES, "PAGES" }, \ | 77 | { _XBF_PAGES, "PAGES" }, \ |
77 | { _XBF_KMEM, "KMEM" }, \ | 78 | { _XBF_KMEM, "KMEM" }, \ |
78 | { _XBF_DELWRI_Q, "DELWRI_Q" } | 79 | { _XBF_DELWRI_Q, "DELWRI_Q" }, \ |
80 | { _XBF_COMPOUND, "COMPOUND" } | ||
79 | 81 | ||
80 | typedef struct xfs_buftarg { | 82 | typedef struct xfs_buftarg { |
81 | dev_t bt_dev; | 83 | dev_t bt_dev; |
@@ -98,6 +100,14 @@ typedef void (*xfs_buf_iodone_t)(struct xfs_buf *); | |||
98 | 100 | ||
99 | #define XB_PAGES 2 | 101 | #define XB_PAGES 2 |
100 | 102 | ||
103 | struct xfs_buf_map { | ||
104 | xfs_daddr_t bm_bn; /* block number for I/O */ | ||
105 | int bm_len; /* size of I/O */ | ||
106 | }; | ||
107 | |||
108 | #define DEFINE_SINGLE_BUF_MAP(map, blkno, numblk) \ | ||
109 | struct xfs_buf_map (map) = { .bm_bn = (blkno), .bm_len = (numblk) }; | ||
110 | |||
101 | typedef struct xfs_buf { | 111 | typedef struct xfs_buf { |
102 | /* | 112 | /* |
103 | * first cacheline holds all the fields needed for an uncontended cache | 113 | * first cacheline holds all the fields needed for an uncontended cache |
@@ -107,7 +117,7 @@ typedef struct xfs_buf { | |||
107 | * fast-path on locking. | 117 | * fast-path on locking. |
108 | */ | 118 | */ |
109 | struct rb_node b_rbnode; /* rbtree node */ | 119 | struct rb_node b_rbnode; /* rbtree node */ |
110 | xfs_daddr_t b_bn; /* block number for I/O */ | 120 | xfs_daddr_t b_bn; /* block number of buffer */ |
111 | int b_length; /* size of buffer in BBs */ | 121 | int b_length; /* size of buffer in BBs */ |
112 | atomic_t b_hold; /* reference count */ | 122 | atomic_t b_hold; /* reference count */ |
113 | atomic_t b_lru_ref; /* lru reclaim ref count */ | 123 | atomic_t b_lru_ref; /* lru reclaim ref count */ |
@@ -127,12 +137,16 @@ typedef struct xfs_buf { | |||
127 | struct xfs_trans *b_transp; | 137 | struct xfs_trans *b_transp; |
128 | struct page **b_pages; /* array of page pointers */ | 138 | struct page **b_pages; /* array of page pointers */ |
129 | struct page *b_page_array[XB_PAGES]; /* inline pages */ | 139 | struct page *b_page_array[XB_PAGES]; /* inline pages */ |
140 | struct xfs_buf_map *b_maps; /* compound buffer map */ | ||
141 | struct xfs_buf_map b_map; /* inline compound buffer map */ | ||
142 | int b_map_count; | ||
130 | int b_io_length; /* IO size in BBs */ | 143 | int b_io_length; /* IO size in BBs */ |
131 | atomic_t b_pin_count; /* pin count */ | 144 | atomic_t b_pin_count; /* pin count */ |
132 | atomic_t b_io_remaining; /* #outstanding I/O requests */ | 145 | atomic_t b_io_remaining; /* #outstanding I/O requests */ |
133 | unsigned int b_page_count; /* size of page array */ | 146 | unsigned int b_page_count; /* size of page array */ |
134 | unsigned int b_offset; /* page offset in first page */ | 147 | unsigned int b_offset; /* page offset in first page */ |
135 | unsigned short b_error; /* error code on I/O */ | 148 | unsigned short b_error; /* error code on I/O */ |
149 | |||
136 | #ifdef XFS_BUF_LOCK_TRACKING | 150 | #ifdef XFS_BUF_LOCK_TRACKING |
137 | int b_last_holder; | 151 | int b_last_holder; |
138 | #endif | 152 | #endif |
@@ -140,22 +154,78 @@ typedef struct xfs_buf { | |||
140 | 154 | ||
141 | 155 | ||
142 | /* Finding and Reading Buffers */ | 156 | /* Finding and Reading Buffers */ |
143 | struct xfs_buf *_xfs_buf_find(struct xfs_buftarg *target, xfs_daddr_t blkno, | 157 | struct xfs_buf *_xfs_buf_find(struct xfs_buftarg *target, |
144 | size_t numblks, xfs_buf_flags_t flags, | 158 | struct xfs_buf_map *map, int nmaps, |
145 | struct xfs_buf *new_bp); | 159 | xfs_buf_flags_t flags, struct xfs_buf *new_bp); |
146 | #define xfs_incore(buftarg,blkno,len,lockit) \ | 160 | |
147 | _xfs_buf_find(buftarg, blkno ,len, lockit, NULL) | 161 | static inline struct xfs_buf * |
148 | 162 | xfs_incore( | |
149 | struct xfs_buf *xfs_buf_get(struct xfs_buftarg *target, xfs_daddr_t blkno, | 163 | struct xfs_buftarg *target, |
150 | size_t numblks, xfs_buf_flags_t flags); | 164 | xfs_daddr_t blkno, |
151 | struct xfs_buf *xfs_buf_read(struct xfs_buftarg *target, xfs_daddr_t blkno, | 165 | size_t numblks, |
152 | size_t numblks, xfs_buf_flags_t flags); | 166 | xfs_buf_flags_t flags) |
153 | void xfs_buf_readahead(struct xfs_buftarg *target, xfs_daddr_t blkno, | 167 | { |
154 | size_t numblks); | 168 | DEFINE_SINGLE_BUF_MAP(map, blkno, numblks); |
169 | return _xfs_buf_find(target, &map, 1, flags, NULL); | ||
170 | } | ||
171 | |||
172 | struct xfs_buf *_xfs_buf_alloc(struct xfs_buftarg *target, | ||
173 | struct xfs_buf_map *map, int nmaps, | ||
174 | xfs_buf_flags_t flags); | ||
175 | |||
176 | static inline struct xfs_buf * | ||
177 | xfs_buf_alloc( | ||
178 | struct xfs_buftarg *target, | ||
179 | xfs_daddr_t blkno, | ||
180 | size_t numblks, | ||
181 | xfs_buf_flags_t flags) | ||
182 | { | ||
183 | DEFINE_SINGLE_BUF_MAP(map, blkno, numblks); | ||
184 | return _xfs_buf_alloc(target, &map, 1, flags); | ||
185 | } | ||
186 | |||
187 | struct xfs_buf *xfs_buf_get_map(struct xfs_buftarg *target, | ||
188 | struct xfs_buf_map *map, int nmaps, | ||
189 | xfs_buf_flags_t flags); | ||
190 | struct xfs_buf *xfs_buf_read_map(struct xfs_buftarg *target, | ||
191 | struct xfs_buf_map *map, int nmaps, | ||
192 | xfs_buf_flags_t flags); | ||
193 | void xfs_buf_readahead_map(struct xfs_buftarg *target, | ||
194 | struct xfs_buf_map *map, int nmaps); | ||
195 | |||
196 | static inline struct xfs_buf * | ||
197 | xfs_buf_get( | ||
198 | struct xfs_buftarg *target, | ||
199 | xfs_daddr_t blkno, | ||
200 | size_t numblks, | ||
201 | xfs_buf_flags_t flags) | ||
202 | { | ||
203 | DEFINE_SINGLE_BUF_MAP(map, blkno, numblks); | ||
204 | return xfs_buf_get_map(target, &map, 1, flags); | ||
205 | } | ||
206 | |||
207 | static inline struct xfs_buf * | ||
208 | xfs_buf_read( | ||
209 | struct xfs_buftarg *target, | ||
210 | xfs_daddr_t blkno, | ||
211 | size_t numblks, | ||
212 | xfs_buf_flags_t flags) | ||
213 | { | ||
214 | DEFINE_SINGLE_BUF_MAP(map, blkno, numblks); | ||
215 | return xfs_buf_read_map(target, &map, 1, flags); | ||
216 | } | ||
217 | |||
218 | static inline void | ||
219 | xfs_buf_readahead( | ||
220 | struct xfs_buftarg *target, | ||
221 | xfs_daddr_t blkno, | ||
222 | size_t numblks) | ||
223 | { | ||
224 | DEFINE_SINGLE_BUF_MAP(map, blkno, numblks); | ||
225 | return xfs_buf_readahead_map(target, &map, 1); | ||
226 | } | ||
155 | 227 | ||
156 | struct xfs_buf *xfs_buf_get_empty(struct xfs_buftarg *target, size_t numblks); | 228 | struct xfs_buf *xfs_buf_get_empty(struct xfs_buftarg *target, size_t numblks); |
157 | struct xfs_buf *xfs_buf_alloc(struct xfs_buftarg *target, xfs_daddr_t blkno, | ||
158 | size_t numblks, xfs_buf_flags_t flags); | ||
159 | void xfs_buf_set_empty(struct xfs_buf *bp, size_t numblks); | 229 | void xfs_buf_set_empty(struct xfs_buf *bp, size_t numblks); |
160 | int xfs_buf_associate_memory(struct xfs_buf *bp, void *mem, size_t length); | 230 | int xfs_buf_associate_memory(struct xfs_buf *bp, void *mem, size_t length); |
161 | 231 | ||
@@ -232,8 +302,18 @@ void xfs_buf_stale(struct xfs_buf *bp); | |||
232 | #define XFS_BUF_UNWRITE(bp) ((bp)->b_flags &= ~XBF_WRITE) | 302 | #define XFS_BUF_UNWRITE(bp) ((bp)->b_flags &= ~XBF_WRITE) |
233 | #define XFS_BUF_ISWRITE(bp) ((bp)->b_flags & XBF_WRITE) | 303 | #define XFS_BUF_ISWRITE(bp) ((bp)->b_flags & XBF_WRITE) |
234 | 304 | ||
235 | #define XFS_BUF_ADDR(bp) ((bp)->b_bn) | 305 | /* |
236 | #define XFS_BUF_SET_ADDR(bp, bno) ((bp)->b_bn = (xfs_daddr_t)(bno)) | 306 | * These macros use the IO block map rather than b_bn. b_bn is now really |
307 | * just for the buffer cache index for cached buffers. As IO does not use b_bn | ||
308 | * anymore, uncached buffers do not use b_bn at all and hence must modify the IO | ||
309 | * map directly. Uncached buffers are not allowed to be discontiguous, so this | ||
310 | * is safe to do. | ||
311 | * | ||
312 | * In future, uncached buffers will pass the block number directly to the io | ||
313 | * request function and hence these macros will go away at that point. | ||
314 | */ | ||
315 | #define XFS_BUF_ADDR(bp) ((bp)->b_map.bm_bn) | ||
316 | #define XFS_BUF_SET_ADDR(bp, bno) ((bp)->b_map.bm_bn = (xfs_daddr_t)(bno)) | ||
237 | 317 | ||
238 | static inline void xfs_buf_set_ref(struct xfs_buf *bp, int lru_ref) | 318 | static inline void xfs_buf_set_ref(struct xfs_buf *bp, int lru_ref) |
239 | { | 319 | { |
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index d9e451115f98..a8d0ed911196 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c | |||
@@ -153,33 +153,25 @@ STATIC void xfs_buf_do_callbacks(struct xfs_buf *bp); | |||
153 | * If the XFS_BLI_STALE flag has been set, then log nothing. | 153 | * If the XFS_BLI_STALE flag has been set, then log nothing. |
154 | */ | 154 | */ |
155 | STATIC uint | 155 | STATIC uint |
156 | xfs_buf_item_size( | 156 | xfs_buf_item_size_segment( |
157 | struct xfs_log_item *lip) | 157 | struct xfs_buf_log_item *bip, |
158 | struct xfs_buf_log_format *blfp) | ||
158 | { | 159 | { |
159 | struct xfs_buf_log_item *bip = BUF_ITEM(lip); | ||
160 | struct xfs_buf *bp = bip->bli_buf; | 160 | struct xfs_buf *bp = bip->bli_buf; |
161 | uint nvecs; | 161 | uint nvecs; |
162 | int next_bit; | 162 | int next_bit; |
163 | int last_bit; | 163 | int last_bit; |
164 | 164 | ||
165 | ASSERT(atomic_read(&bip->bli_refcount) > 0); | 165 | last_bit = xfs_next_bit(blfp->blf_data_map, blfp->blf_map_size, 0); |
166 | if (bip->bli_flags & XFS_BLI_STALE) { | 166 | if (last_bit == -1) |
167 | /* | 167 | return 0; |
168 | * The buffer is stale, so all we need to log | 168 | |
169 | * is the buf log format structure with the | 169 | /* |
170 | * cancel flag in it. | 170 | * initial count for a dirty buffer is 2 vectors - the format structure |
171 | */ | 171 | * and the first dirty region. |
172 | trace_xfs_buf_item_size_stale(bip); | 172 | */ |
173 | ASSERT(bip->bli_format.blf_flags & XFS_BLF_CANCEL); | 173 | nvecs = 2; |
174 | return 1; | ||
175 | } | ||
176 | 174 | ||
177 | ASSERT(bip->bli_flags & XFS_BLI_LOGGED); | ||
178 | nvecs = 1; | ||
179 | last_bit = xfs_next_bit(bip->bli_format.blf_data_map, | ||
180 | bip->bli_format.blf_map_size, 0); | ||
181 | ASSERT(last_bit != -1); | ||
182 | nvecs++; | ||
183 | while (last_bit != -1) { | 175 | while (last_bit != -1) { |
184 | /* | 176 | /* |
185 | * This takes the bit number to start looking from and | 177 | * This takes the bit number to start looking from and |
@@ -187,16 +179,15 @@ xfs_buf_item_size( | |||
187 | * if there are no more bits set or the start bit is | 179 | * if there are no more bits set or the start bit is |
188 | * beyond the end of the bitmap. | 180 | * beyond the end of the bitmap. |
189 | */ | 181 | */ |
190 | next_bit = xfs_next_bit(bip->bli_format.blf_data_map, | 182 | next_bit = xfs_next_bit(blfp->blf_data_map, blfp->blf_map_size, |
191 | bip->bli_format.blf_map_size, | 183 | last_bit + 1); |
192 | last_bit + 1); | ||
193 | /* | 184 | /* |
194 | * If we run out of bits, leave the loop, | 185 | * If we run out of bits, leave the loop, |
195 | * else if we find a new set of bits bump the number of vecs, | 186 | * else if we find a new set of bits bump the number of vecs, |
196 | * else keep scanning the current set of bits. | 187 | * else keep scanning the current set of bits. |
197 | */ | 188 | */ |
198 | if (next_bit == -1) { | 189 | if (next_bit == -1) { |
199 | last_bit = -1; | 190 | break; |
200 | } else if (next_bit != last_bit + 1) { | 191 | } else if (next_bit != last_bit + 1) { |
201 | last_bit = next_bit; | 192 | last_bit = next_bit; |
202 | nvecs++; | 193 | nvecs++; |
@@ -210,22 +201,73 @@ xfs_buf_item_size( | |||
210 | } | 201 | } |
211 | } | 202 | } |
212 | 203 | ||
213 | trace_xfs_buf_item_size(bip); | ||
214 | return nvecs; | 204 | return nvecs; |
215 | } | 205 | } |
216 | 206 | ||
217 | /* | 207 | /* |
218 | * This is called to fill in the vector of log iovecs for the | 208 | * This returns the number of log iovecs needed to log the given buf log item. |
219 | * given log buf item. It fills the first entry with a buf log | 209 | * |
220 | * format structure, and the rest point to contiguous chunks | 210 | * It calculates this as 1 iovec for the buf log format structure and 1 for each |
221 | * within the buffer. | 211 | * stretch of non-contiguous chunks to be logged. Contiguous chunks are logged |
212 | * in a single iovec. | ||
213 | * | ||
214 | * Discontiguous buffers need a format structure per region that that is being | ||
215 | * logged. This makes the changes in the buffer appear to log recovery as though | ||
216 | * they came from separate buffers, just like would occur if multiple buffers | ||
217 | * were used instead of a single discontiguous buffer. This enables | ||
218 | * discontiguous buffers to be in-memory constructs, completely transparent to | ||
219 | * what ends up on disk. | ||
220 | * | ||
221 | * If the XFS_BLI_STALE flag has been set, then log nothing but the buf log | ||
222 | * format structures. | ||
222 | */ | 223 | */ |
223 | STATIC void | 224 | STATIC uint |
224 | xfs_buf_item_format( | 225 | xfs_buf_item_size( |
225 | struct xfs_log_item *lip, | 226 | struct xfs_log_item *lip) |
226 | struct xfs_log_iovec *vecp) | ||
227 | { | 227 | { |
228 | struct xfs_buf_log_item *bip = BUF_ITEM(lip); | 228 | struct xfs_buf_log_item *bip = BUF_ITEM(lip); |
229 | uint nvecs; | ||
230 | int i; | ||
231 | |||
232 | ASSERT(atomic_read(&bip->bli_refcount) > 0); | ||
233 | if (bip->bli_flags & XFS_BLI_STALE) { | ||
234 | /* | ||
235 | * The buffer is stale, so all we need to log | ||
236 | * is the buf log format structure with the | ||
237 | * cancel flag in it. | ||
238 | */ | ||
239 | trace_xfs_buf_item_size_stale(bip); | ||
240 | ASSERT(bip->bli_format.blf_flags & XFS_BLF_CANCEL); | ||
241 | return bip->bli_format_count; | ||
242 | } | ||
243 | |||
244 | ASSERT(bip->bli_flags & XFS_BLI_LOGGED); | ||
245 | |||
246 | /* | ||
247 | * the vector count is based on the number of buffer vectors we have | ||
248 | * dirty bits in. This will only be greater than one when we have a | ||
249 | * compound buffer with more than one segment dirty. Hence for compound | ||
250 | * buffers we need to track which segment the dirty bits correspond to, | ||
251 | * and when we move from one segment to the next increment the vector | ||
252 | * count for the extra buf log format structure that will need to be | ||
253 | * written. | ||
254 | */ | ||
255 | nvecs = 0; | ||
256 | for (i = 0; i < bip->bli_format_count; i++) { | ||
257 | nvecs += xfs_buf_item_size_segment(bip, &bip->bli_formats[i]); | ||
258 | } | ||
259 | |||
260 | trace_xfs_buf_item_size(bip); | ||
261 | return nvecs; | ||
262 | } | ||
263 | |||
264 | static struct xfs_log_iovec * | ||
265 | xfs_buf_item_format_segment( | ||
266 | struct xfs_buf_log_item *bip, | ||
267 | struct xfs_log_iovec *vecp, | ||
268 | uint offset, | ||
269 | struct xfs_buf_log_format *blfp) | ||
270 | { | ||
229 | struct xfs_buf *bp = bip->bli_buf; | 271 | struct xfs_buf *bp = bip->bli_buf; |
230 | uint base_size; | 272 | uint base_size; |
231 | uint nvecs; | 273 | uint nvecs; |
@@ -235,40 +277,22 @@ xfs_buf_item_format( | |||
235 | uint nbits; | 277 | uint nbits; |
236 | uint buffer_offset; | 278 | uint buffer_offset; |
237 | 279 | ||
238 | ASSERT(atomic_read(&bip->bli_refcount) > 0); | 280 | /* copy the flags across from the base format item */ |
239 | ASSERT((bip->bli_flags & XFS_BLI_LOGGED) || | 281 | blfp->blf_flags = bip->bli_format.blf_flags; |
240 | (bip->bli_flags & XFS_BLI_STALE)); | ||
241 | 282 | ||
242 | /* | 283 | /* |
243 | * The size of the base structure is the size of the | 284 | * Base size is the actual size of the ondisk structure - it reflects |
244 | * declared structure plus the space for the extra words | 285 | * the actual size of the dirty bitmap rather than the size of the in |
245 | * of the bitmap. We subtract one from the map size, because | 286 | * memory structure. |
246 | * the first element of the bitmap is accounted for in the | ||
247 | * size of the base structure. | ||
248 | */ | 287 | */ |
249 | base_size = | 288 | base_size = offsetof(struct xfs_buf_log_format, blf_data_map) + |
250 | (uint)(sizeof(xfs_buf_log_format_t) + | 289 | (blfp->blf_map_size * sizeof(blfp->blf_data_map[0])); |
251 | ((bip->bli_format.blf_map_size - 1) * sizeof(uint))); | 290 | vecp->i_addr = blfp; |
252 | vecp->i_addr = &bip->bli_format; | ||
253 | vecp->i_len = base_size; | 291 | vecp->i_len = base_size; |
254 | vecp->i_type = XLOG_REG_TYPE_BFORMAT; | 292 | vecp->i_type = XLOG_REG_TYPE_BFORMAT; |
255 | vecp++; | 293 | vecp++; |
256 | nvecs = 1; | 294 | nvecs = 1; |
257 | 295 | ||
258 | /* | ||
259 | * If it is an inode buffer, transfer the in-memory state to the | ||
260 | * format flags and clear the in-memory state. We do not transfer | ||
261 | * this state if the inode buffer allocation has not yet been committed | ||
262 | * to the log as setting the XFS_BLI_INODE_BUF flag will prevent | ||
263 | * correct replay of the inode allocation. | ||
264 | */ | ||
265 | if (bip->bli_flags & XFS_BLI_INODE_BUF) { | ||
266 | if (!((bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF) && | ||
267 | xfs_log_item_in_current_chkpt(lip))) | ||
268 | bip->bli_format.blf_flags |= XFS_BLF_INODE_BUF; | ||
269 | bip->bli_flags &= ~XFS_BLI_INODE_BUF; | ||
270 | } | ||
271 | |||
272 | if (bip->bli_flags & XFS_BLI_STALE) { | 296 | if (bip->bli_flags & XFS_BLI_STALE) { |
273 | /* | 297 | /* |
274 | * The buffer is stale, so all we need to log | 298 | * The buffer is stale, so all we need to log |
@@ -276,16 +300,15 @@ xfs_buf_item_format( | |||
276 | * cancel flag in it. | 300 | * cancel flag in it. |
277 | */ | 301 | */ |
278 | trace_xfs_buf_item_format_stale(bip); | 302 | trace_xfs_buf_item_format_stale(bip); |
279 | ASSERT(bip->bli_format.blf_flags & XFS_BLF_CANCEL); | 303 | ASSERT(blfp->blf_flags & XFS_BLF_CANCEL); |
280 | bip->bli_format.blf_size = nvecs; | 304 | blfp->blf_size = nvecs; |
281 | return; | 305 | return vecp; |
282 | } | 306 | } |
283 | 307 | ||
284 | /* | 308 | /* |
285 | * Fill in an iovec for each set of contiguous chunks. | 309 | * Fill in an iovec for each set of contiguous chunks. |
286 | */ | 310 | */ |
287 | first_bit = xfs_next_bit(bip->bli_format.blf_data_map, | 311 | first_bit = xfs_next_bit(blfp->blf_data_map, blfp->blf_map_size, 0); |
288 | bip->bli_format.blf_map_size, 0); | ||
289 | ASSERT(first_bit != -1); | 312 | ASSERT(first_bit != -1); |
290 | last_bit = first_bit; | 313 | last_bit = first_bit; |
291 | nbits = 1; | 314 | nbits = 1; |
@@ -296,9 +319,8 @@ xfs_buf_item_format( | |||
296 | * if there are no more bits set or the start bit is | 319 | * if there are no more bits set or the start bit is |
297 | * beyond the end of the bitmap. | 320 | * beyond the end of the bitmap. |
298 | */ | 321 | */ |
299 | next_bit = xfs_next_bit(bip->bli_format.blf_data_map, | 322 | next_bit = xfs_next_bit(blfp->blf_data_map, blfp->blf_map_size, |
300 | bip->bli_format.blf_map_size, | 323 | (uint)last_bit + 1); |
301 | (uint)last_bit + 1); | ||
302 | /* | 324 | /* |
303 | * If we run out of bits fill in the last iovec and get | 325 | * If we run out of bits fill in the last iovec and get |
304 | * out of the loop. | 326 | * out of the loop. |
@@ -309,14 +331,14 @@ xfs_buf_item_format( | |||
309 | * keep counting and scanning. | 331 | * keep counting and scanning. |
310 | */ | 332 | */ |
311 | if (next_bit == -1) { | 333 | if (next_bit == -1) { |
312 | buffer_offset = first_bit * XFS_BLF_CHUNK; | 334 | buffer_offset = offset + first_bit * XFS_BLF_CHUNK; |
313 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); | 335 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); |
314 | vecp->i_len = nbits * XFS_BLF_CHUNK; | 336 | vecp->i_len = nbits * XFS_BLF_CHUNK; |
315 | vecp->i_type = XLOG_REG_TYPE_BCHUNK; | 337 | vecp->i_type = XLOG_REG_TYPE_BCHUNK; |
316 | nvecs++; | 338 | nvecs++; |
317 | break; | 339 | break; |
318 | } else if (next_bit != last_bit + 1) { | 340 | } else if (next_bit != last_bit + 1) { |
319 | buffer_offset = first_bit * XFS_BLF_CHUNK; | 341 | buffer_offset = offset + first_bit * XFS_BLF_CHUNK; |
320 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); | 342 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); |
321 | vecp->i_len = nbits * XFS_BLF_CHUNK; | 343 | vecp->i_len = nbits * XFS_BLF_CHUNK; |
322 | vecp->i_type = XLOG_REG_TYPE_BCHUNK; | 344 | vecp->i_type = XLOG_REG_TYPE_BCHUNK; |
@@ -325,14 +347,17 @@ xfs_buf_item_format( | |||
325 | first_bit = next_bit; | 347 | first_bit = next_bit; |
326 | last_bit = next_bit; | 348 | last_bit = next_bit; |
327 | nbits = 1; | 349 | nbits = 1; |
328 | } else if (xfs_buf_offset(bp, next_bit << XFS_BLF_SHIFT) != | 350 | } else if (xfs_buf_offset(bp, offset + |
329 | (xfs_buf_offset(bp, last_bit << XFS_BLF_SHIFT) + | 351 | (next_bit << XFS_BLF_SHIFT)) != |
352 | (xfs_buf_offset(bp, offset + | ||
353 | (last_bit << XFS_BLF_SHIFT)) + | ||
330 | XFS_BLF_CHUNK)) { | 354 | XFS_BLF_CHUNK)) { |
331 | buffer_offset = first_bit * XFS_BLF_CHUNK; | 355 | buffer_offset = offset + first_bit * XFS_BLF_CHUNK; |
332 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); | 356 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); |
333 | vecp->i_len = nbits * XFS_BLF_CHUNK; | 357 | vecp->i_len = nbits * XFS_BLF_CHUNK; |
334 | vecp->i_type = XLOG_REG_TYPE_BCHUNK; | 358 | vecp->i_type = XLOG_REG_TYPE_BCHUNK; |
335 | /* You would think we need to bump the nvecs here too, but we do not | 359 | /* |
360 | * You would think we need to bump the nvecs here too, but we do not | ||
336 | * this number is used by recovery, and it gets confused by the boundary | 361 | * this number is used by recovery, and it gets confused by the boundary |
337 | * split here | 362 | * split here |
338 | * nvecs++; | 363 | * nvecs++; |
@@ -347,6 +372,48 @@ xfs_buf_item_format( | |||
347 | } | 372 | } |
348 | } | 373 | } |
349 | bip->bli_format.blf_size = nvecs; | 374 | bip->bli_format.blf_size = nvecs; |
375 | return vecp; | ||
376 | } | ||
377 | |||
378 | /* | ||
379 | * This is called to fill in the vector of log iovecs for the | ||
380 | * given log buf item. It fills the first entry with a buf log | ||
381 | * format structure, and the rest point to contiguous chunks | ||
382 | * within the buffer. | ||
383 | */ | ||
384 | STATIC void | ||
385 | xfs_buf_item_format( | ||
386 | struct xfs_log_item *lip, | ||
387 | struct xfs_log_iovec *vecp) | ||
388 | { | ||
389 | struct xfs_buf_log_item *bip = BUF_ITEM(lip); | ||
390 | struct xfs_buf *bp = bip->bli_buf; | ||
391 | uint offset = 0; | ||
392 | int i; | ||
393 | |||
394 | ASSERT(atomic_read(&bip->bli_refcount) > 0); | ||
395 | ASSERT((bip->bli_flags & XFS_BLI_LOGGED) || | ||
396 | (bip->bli_flags & XFS_BLI_STALE)); | ||
397 | |||
398 | /* | ||
399 | * If it is an inode buffer, transfer the in-memory state to the | ||
400 | * format flags and clear the in-memory state. We do not transfer | ||
401 | * this state if the inode buffer allocation has not yet been committed | ||
402 | * to the log as setting the XFS_BLI_INODE_BUF flag will prevent | ||
403 | * correct replay of the inode allocation. | ||
404 | */ | ||
405 | if (bip->bli_flags & XFS_BLI_INODE_BUF) { | ||
406 | if (!((bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF) && | ||
407 | xfs_log_item_in_current_chkpt(lip))) | ||
408 | bip->bli_format.blf_flags |= XFS_BLF_INODE_BUF; | ||
409 | bip->bli_flags &= ~XFS_BLI_INODE_BUF; | ||
410 | } | ||
411 | |||
412 | for (i = 0; i < bip->bli_format_count; i++) { | ||
413 | vecp = xfs_buf_item_format_segment(bip, vecp, offset, | ||
414 | &bip->bli_formats[i]); | ||
415 | offset += bp->b_maps[i].bm_len; | ||
416 | } | ||
350 | 417 | ||
351 | /* | 418 | /* |
352 | * Check to make sure everything is consistent. | 419 | * Check to make sure everything is consistent. |
@@ -622,6 +689,35 @@ static const struct xfs_item_ops xfs_buf_item_ops = { | |||
622 | .iop_committing = xfs_buf_item_committing | 689 | .iop_committing = xfs_buf_item_committing |
623 | }; | 690 | }; |
624 | 691 | ||
692 | STATIC int | ||
693 | xfs_buf_item_get_format( | ||
694 | struct xfs_buf_log_item *bip, | ||
695 | int count) | ||
696 | { | ||
697 | ASSERT(bip->bli_formats == NULL); | ||
698 | bip->bli_format_count = count; | ||
699 | |||
700 | if (count == 1) { | ||
701 | bip->bli_formats = &bip->bli_format; | ||
702 | return 0; | ||
703 | } | ||
704 | |||
705 | bip->bli_formats = kmem_zalloc(count * sizeof(struct xfs_buf_log_format), | ||
706 | KM_SLEEP); | ||
707 | if (!bip->bli_formats) | ||
708 | return ENOMEM; | ||
709 | return 0; | ||
710 | } | ||
711 | |||
712 | STATIC void | ||
713 | xfs_buf_item_free_format( | ||
714 | struct xfs_buf_log_item *bip) | ||
715 | { | ||
716 | if (bip->bli_formats != &bip->bli_format) { | ||
717 | kmem_free(bip->bli_formats); | ||
718 | bip->bli_formats = NULL; | ||
719 | } | ||
720 | } | ||
625 | 721 | ||
626 | /* | 722 | /* |
627 | * Allocate a new buf log item to go with the given buffer. | 723 | * Allocate a new buf log item to go with the given buffer. |
@@ -639,6 +735,8 @@ xfs_buf_item_init( | |||
639 | xfs_buf_log_item_t *bip; | 735 | xfs_buf_log_item_t *bip; |
640 | int chunks; | 736 | int chunks; |
641 | int map_size; | 737 | int map_size; |
738 | int error; | ||
739 | int i; | ||
642 | 740 | ||
643 | /* | 741 | /* |
644 | * Check to see if there is already a buf log item for | 742 | * Check to see if there is already a buf log item for |
@@ -650,25 +748,33 @@ xfs_buf_item_init( | |||
650 | if (lip != NULL && lip->li_type == XFS_LI_BUF) | 748 | if (lip != NULL && lip->li_type == XFS_LI_BUF) |
651 | return; | 749 | return; |
652 | 750 | ||
653 | /* | 751 | bip = kmem_zone_zalloc(xfs_buf_item_zone, KM_SLEEP); |
654 | * chunks is the number of XFS_BLF_CHUNK size pieces | ||
655 | * the buffer can be divided into. Make sure not to | ||
656 | * truncate any pieces. map_size is the size of the | ||
657 | * bitmap needed to describe the chunks of the buffer. | ||
658 | */ | ||
659 | chunks = (int)((BBTOB(bp->b_length) + (XFS_BLF_CHUNK - 1)) >> | ||
660 | XFS_BLF_SHIFT); | ||
661 | map_size = (int)((chunks + NBWORD) >> BIT_TO_WORD_SHIFT); | ||
662 | |||
663 | bip = (xfs_buf_log_item_t*)kmem_zone_zalloc(xfs_buf_item_zone, | ||
664 | KM_SLEEP); | ||
665 | xfs_log_item_init(mp, &bip->bli_item, XFS_LI_BUF, &xfs_buf_item_ops); | 752 | xfs_log_item_init(mp, &bip->bli_item, XFS_LI_BUF, &xfs_buf_item_ops); |
666 | bip->bli_buf = bp; | 753 | bip->bli_buf = bp; |
667 | xfs_buf_hold(bp); | 754 | xfs_buf_hold(bp); |
668 | bip->bli_format.blf_type = XFS_LI_BUF; | 755 | |
669 | bip->bli_format.blf_blkno = (__int64_t)XFS_BUF_ADDR(bp); | 756 | /* |
670 | bip->bli_format.blf_len = (ushort)bp->b_length; | 757 | * chunks is the number of XFS_BLF_CHUNK size pieces the buffer |
671 | bip->bli_format.blf_map_size = map_size; | 758 | * can be divided into. Make sure not to truncate any pieces. |
759 | * map_size is the size of the bitmap needed to describe the | ||
760 | * chunks of the buffer. | ||
761 | * | ||
762 | * Discontiguous buffer support follows the layout of the underlying | ||
763 | * buffer. This makes the implementation as simple as possible. | ||
764 | */ | ||
765 | error = xfs_buf_item_get_format(bip, bp->b_map_count); | ||
766 | ASSERT(error == 0); | ||
767 | |||
768 | for (i = 0; i < bip->bli_format_count; i++) { | ||
769 | chunks = DIV_ROUND_UP(BBTOB(bp->b_maps[i].bm_len), | ||
770 | XFS_BLF_CHUNK); | ||
771 | map_size = DIV_ROUND_UP(chunks, NBWORD); | ||
772 | |||
773 | bip->bli_formats[i].blf_type = XFS_LI_BUF; | ||
774 | bip->bli_formats[i].blf_blkno = bp->b_maps[i].bm_bn; | ||
775 | bip->bli_formats[i].blf_len = bp->b_maps[i].bm_len; | ||
776 | bip->bli_formats[i].blf_map_size = map_size; | ||
777 | } | ||
672 | 778 | ||
673 | #ifdef XFS_TRANS_DEBUG | 779 | #ifdef XFS_TRANS_DEBUG |
674 | /* | 780 | /* |
@@ -699,10 +805,11 @@ xfs_buf_item_init( | |||
699 | * item's bitmap. | 805 | * item's bitmap. |
700 | */ | 806 | */ |
701 | void | 807 | void |
702 | xfs_buf_item_log( | 808 | xfs_buf_item_log_segment( |
703 | xfs_buf_log_item_t *bip, | 809 | struct xfs_buf_log_item *bip, |
704 | uint first, | 810 | uint first, |
705 | uint last) | 811 | uint last, |
812 | uint *map) | ||
706 | { | 813 | { |
707 | uint first_bit; | 814 | uint first_bit; |
708 | uint last_bit; | 815 | uint last_bit; |
@@ -715,12 +822,6 @@ xfs_buf_item_log( | |||
715 | uint mask; | 822 | uint mask; |
716 | 823 | ||
717 | /* | 824 | /* |
718 | * Mark the item as having some dirty data for | ||
719 | * quick reference in xfs_buf_item_dirty. | ||
720 | */ | ||
721 | bip->bli_flags |= XFS_BLI_DIRTY; | ||
722 | |||
723 | /* | ||
724 | * Convert byte offsets to bit numbers. | 825 | * Convert byte offsets to bit numbers. |
725 | */ | 826 | */ |
726 | first_bit = first >> XFS_BLF_SHIFT; | 827 | first_bit = first >> XFS_BLF_SHIFT; |
@@ -736,7 +837,7 @@ xfs_buf_item_log( | |||
736 | * to set a bit in. | 837 | * to set a bit in. |
737 | */ | 838 | */ |
738 | word_num = first_bit >> BIT_TO_WORD_SHIFT; | 839 | word_num = first_bit >> BIT_TO_WORD_SHIFT; |
739 | wordp = &(bip->bli_format.blf_data_map[word_num]); | 840 | wordp = &map[word_num]; |
740 | 841 | ||
741 | /* | 842 | /* |
742 | * Calculate the starting bit in the first word. | 843 | * Calculate the starting bit in the first word. |
@@ -783,6 +884,51 @@ xfs_buf_item_log( | |||
783 | xfs_buf_item_log_debug(bip, first, last); | 884 | xfs_buf_item_log_debug(bip, first, last); |
784 | } | 885 | } |
785 | 886 | ||
887 | /* | ||
888 | * Mark bytes first through last inclusive as dirty in the buf | ||
889 | * item's bitmap. | ||
890 | */ | ||
891 | void | ||
892 | xfs_buf_item_log( | ||
893 | xfs_buf_log_item_t *bip, | ||
894 | uint first, | ||
895 | uint last) | ||
896 | { | ||
897 | int i; | ||
898 | uint start; | ||
899 | uint end; | ||
900 | struct xfs_buf *bp = bip->bli_buf; | ||
901 | |||
902 | /* | ||
903 | * Mark the item as having some dirty data for | ||
904 | * quick reference in xfs_buf_item_dirty. | ||
905 | */ | ||
906 | bip->bli_flags |= XFS_BLI_DIRTY; | ||
907 | |||
908 | /* | ||
909 | * walk each buffer segment and mark them dirty appropriately. | ||
910 | */ | ||
911 | start = 0; | ||
912 | for (i = 0; i < bip->bli_format_count; i++) { | ||
913 | if (start > last) | ||
914 | break; | ||
915 | end = start + BBTOB(bp->b_maps[i].bm_len); | ||
916 | if (first > end) { | ||
917 | start += BBTOB(bp->b_maps[i].bm_len); | ||
918 | continue; | ||
919 | } | ||
920 | if (first < start) | ||
921 | first = start; | ||
922 | if (end > last) | ||
923 | end = last; | ||
924 | |||
925 | xfs_buf_item_log_segment(bip, first, end, | ||
926 | &bip->bli_formats[i].blf_data_map[0]); | ||
927 | |||
928 | start += bp->b_maps[i].bm_len; | ||
929 | } | ||
930 | } | ||
931 | |||
786 | 932 | ||
787 | /* | 933 | /* |
788 | * Return 1 if the buffer has some data that has been logged (at any | 934 | * Return 1 if the buffer has some data that has been logged (at any |
@@ -804,6 +950,7 @@ xfs_buf_item_free( | |||
804 | kmem_free(bip->bli_logged); | 950 | kmem_free(bip->bli_logged); |
805 | #endif /* XFS_TRANS_DEBUG */ | 951 | #endif /* XFS_TRANS_DEBUG */ |
806 | 952 | ||
953 | xfs_buf_item_free_format(bip); | ||
807 | kmem_zone_free(xfs_buf_item_zone, bip); | 954 | kmem_zone_free(xfs_buf_item_zone, bip); |
808 | } | 955 | } |
809 | 956 | ||
diff --git a/fs/xfs/xfs_buf_item.h b/fs/xfs/xfs_buf_item.h index b6ecd2061e7c..6850f49f4af3 100644 --- a/fs/xfs/xfs_buf_item.h +++ b/fs/xfs/xfs_buf_item.h | |||
@@ -21,23 +21,6 @@ | |||
21 | extern kmem_zone_t *xfs_buf_item_zone; | 21 | extern kmem_zone_t *xfs_buf_item_zone; |
22 | 22 | ||
23 | /* | 23 | /* |
24 | * This is the structure used to lay out a buf log item in the | ||
25 | * log. The data map describes which 128 byte chunks of the buffer | ||
26 | * have been logged. | ||
27 | * For 6.2 and beyond, this is XFS_LI_BUF. We use this to log everything. | ||
28 | */ | ||
29 | typedef struct xfs_buf_log_format { | ||
30 | unsigned short blf_type; /* buf log item type indicator */ | ||
31 | unsigned short blf_size; /* size of this item */ | ||
32 | ushort blf_flags; /* misc state */ | ||
33 | ushort blf_len; /* number of blocks in this buf */ | ||
34 | __int64_t blf_blkno; /* starting blkno of this buf */ | ||
35 | unsigned int blf_map_size; /* size of data bitmap in words */ | ||
36 | unsigned int blf_data_map[1];/* variable size bitmap of */ | ||
37 | /* regions of buffer in this item */ | ||
38 | } xfs_buf_log_format_t; | ||
39 | |||
40 | /* | ||
41 | * This flag indicates that the buffer contains on disk inodes | 24 | * This flag indicates that the buffer contains on disk inodes |
42 | * and requires special recovery handling. | 25 | * and requires special recovery handling. |
43 | */ | 26 | */ |
@@ -61,6 +44,23 @@ typedef struct xfs_buf_log_format { | |||
61 | #define NBWORD (NBBY * sizeof(unsigned int)) | 44 | #define NBWORD (NBBY * sizeof(unsigned int)) |
62 | 45 | ||
63 | /* | 46 | /* |
47 | * This is the structure used to lay out a buf log item in the | ||
48 | * log. The data map describes which 128 byte chunks of the buffer | ||
49 | * have been logged. | ||
50 | */ | ||
51 | #define XFS_BLF_DATAMAP_SIZE ((XFS_MAX_BLOCKSIZE / XFS_BLF_CHUNK) / NBWORD) | ||
52 | |||
53 | typedef struct xfs_buf_log_format { | ||
54 | unsigned short blf_type; /* buf log item type indicator */ | ||
55 | unsigned short blf_size; /* size of this item */ | ||
56 | ushort blf_flags; /* misc state */ | ||
57 | ushort blf_len; /* number of blocks in this buf */ | ||
58 | __int64_t blf_blkno; /* starting blkno of this buf */ | ||
59 | unsigned int blf_map_size; /* used size of data bitmap in words */ | ||
60 | unsigned int blf_data_map[XFS_BLF_DATAMAP_SIZE]; /* dirty bitmap */ | ||
61 | } xfs_buf_log_format_t; | ||
62 | |||
63 | /* | ||
64 | * buf log item flags | 64 | * buf log item flags |
65 | */ | 65 | */ |
66 | #define XFS_BLI_HOLD 0x01 | 66 | #define XFS_BLI_HOLD 0x01 |
@@ -102,7 +102,9 @@ typedef struct xfs_buf_log_item { | |||
102 | char *bli_orig; /* original buffer copy */ | 102 | char *bli_orig; /* original buffer copy */ |
103 | char *bli_logged; /* bytes logged (bitmap) */ | 103 | char *bli_logged; /* bytes logged (bitmap) */ |
104 | #endif | 104 | #endif |
105 | xfs_buf_log_format_t bli_format; /* in-log header */ | 105 | int bli_format_count; /* count of headers */ |
106 | struct xfs_buf_log_format *bli_formats; /* array of in-log header ptrs */ | ||
107 | struct xfs_buf_log_format bli_format; /* embedded in-log header */ | ||
106 | } xfs_buf_log_item_t; | 108 | } xfs_buf_log_item_t; |
107 | 109 | ||
108 | void xfs_buf_item_init(struct xfs_buf *, struct xfs_mount *); | 110 | void xfs_buf_item_init(struct xfs_buf *, struct xfs_mount *); |
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c index 015b946c5808..7bfb7dd334fc 100644 --- a/fs/xfs/xfs_da_btree.c +++ b/fs/xfs/xfs_da_btree.c | |||
@@ -83,9 +83,9 @@ STATIC void xfs_da_node_unbalance(xfs_da_state_t *state, | |||
83 | /* | 83 | /* |
84 | * Utility routines. | 84 | * Utility routines. |
85 | */ | 85 | */ |
86 | STATIC uint xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count); | 86 | STATIC uint xfs_da_node_lasthash(struct xfs_buf *bp, int *count); |
87 | STATIC int xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp); | 87 | STATIC int xfs_da_node_order(struct xfs_buf *node1_bp, |
88 | STATIC xfs_dabuf_t *xfs_da_buf_make(int nbuf, xfs_buf_t **bps); | 88 | struct xfs_buf *node2_bp); |
89 | STATIC int xfs_da_blk_unlink(xfs_da_state_t *state, | 89 | STATIC int xfs_da_blk_unlink(xfs_da_state_t *state, |
90 | xfs_da_state_blk_t *drop_blk, | 90 | xfs_da_state_blk_t *drop_blk, |
91 | xfs_da_state_blk_t *save_blk); | 91 | xfs_da_state_blk_t *save_blk); |
@@ -100,10 +100,10 @@ STATIC void xfs_da_state_kill_altpath(xfs_da_state_t *state); | |||
100 | */ | 100 | */ |
101 | int | 101 | int |
102 | xfs_da_node_create(xfs_da_args_t *args, xfs_dablk_t blkno, int level, | 102 | xfs_da_node_create(xfs_da_args_t *args, xfs_dablk_t blkno, int level, |
103 | xfs_dabuf_t **bpp, int whichfork) | 103 | struct xfs_buf **bpp, int whichfork) |
104 | { | 104 | { |
105 | xfs_da_intnode_t *node; | 105 | xfs_da_intnode_t *node; |
106 | xfs_dabuf_t *bp; | 106 | struct xfs_buf *bp; |
107 | int error; | 107 | int error; |
108 | xfs_trans_t *tp; | 108 | xfs_trans_t *tp; |
109 | 109 | ||
@@ -114,7 +114,7 @@ xfs_da_node_create(xfs_da_args_t *args, xfs_dablk_t blkno, int level, | |||
114 | if (error) | 114 | if (error) |
115 | return(error); | 115 | return(error); |
116 | ASSERT(bp != NULL); | 116 | ASSERT(bp != NULL); |
117 | node = bp->data; | 117 | node = bp->b_addr; |
118 | node->hdr.info.forw = 0; | 118 | node->hdr.info.forw = 0; |
119 | node->hdr.info.back = 0; | 119 | node->hdr.info.back = 0; |
120 | node->hdr.info.magic = cpu_to_be16(XFS_DA_NODE_MAGIC); | 120 | node->hdr.info.magic = cpu_to_be16(XFS_DA_NODE_MAGIC); |
@@ -122,7 +122,7 @@ xfs_da_node_create(xfs_da_args_t *args, xfs_dablk_t blkno, int level, | |||
122 | node->hdr.count = 0; | 122 | node->hdr.count = 0; |
123 | node->hdr.level = cpu_to_be16(level); | 123 | node->hdr.level = cpu_to_be16(level); |
124 | 124 | ||
125 | xfs_da_log_buf(tp, bp, | 125 | xfs_trans_log_buf(tp, bp, |
126 | XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr))); | 126 | XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr))); |
127 | 127 | ||
128 | *bpp = bp; | 128 | *bpp = bp; |
@@ -138,7 +138,7 @@ xfs_da_split(xfs_da_state_t *state) | |||
138 | { | 138 | { |
139 | xfs_da_state_blk_t *oldblk, *newblk, *addblk; | 139 | xfs_da_state_blk_t *oldblk, *newblk, *addblk; |
140 | xfs_da_intnode_t *node; | 140 | xfs_da_intnode_t *node; |
141 | xfs_dabuf_t *bp; | 141 | struct xfs_buf *bp; |
142 | int max, action, error, i; | 142 | int max, action, error, i; |
143 | 143 | ||
144 | trace_xfs_da_split(state->args); | 144 | trace_xfs_da_split(state->args); |
@@ -203,7 +203,6 @@ xfs_da_split(xfs_da_state_t *state) | |||
203 | case XFS_DA_NODE_MAGIC: | 203 | case XFS_DA_NODE_MAGIC: |
204 | error = xfs_da_node_split(state, oldblk, newblk, addblk, | 204 | error = xfs_da_node_split(state, oldblk, newblk, addblk, |
205 | max - i, &action); | 205 | max - i, &action); |
206 | xfs_da_buf_done(addblk->bp); | ||
207 | addblk->bp = NULL; | 206 | addblk->bp = NULL; |
208 | if (error) | 207 | if (error) |
209 | return(error); /* GROT: dir is inconsistent */ | 208 | return(error); /* GROT: dir is inconsistent */ |
@@ -221,13 +220,6 @@ xfs_da_split(xfs_da_state_t *state) | |||
221 | * Update the btree to show the new hashval for this child. | 220 | * Update the btree to show the new hashval for this child. |
222 | */ | 221 | */ |
223 | xfs_da_fixhashpath(state, &state->path); | 222 | xfs_da_fixhashpath(state, &state->path); |
224 | /* | ||
225 | * If we won't need this block again, it's getting dropped | ||
226 | * from the active path by the loop control, so we need | ||
227 | * to mark it done now. | ||
228 | */ | ||
229 | if (i > 0 || !addblk) | ||
230 | xfs_da_buf_done(oldblk->bp); | ||
231 | } | 223 | } |
232 | if (!addblk) | 224 | if (!addblk) |
233 | return(0); | 225 | return(0); |
@@ -239,8 +231,6 @@ xfs_da_split(xfs_da_state_t *state) | |||
239 | oldblk = &state->path.blk[0]; | 231 | oldblk = &state->path.blk[0]; |
240 | error = xfs_da_root_split(state, oldblk, addblk); | 232 | error = xfs_da_root_split(state, oldblk, addblk); |
241 | if (error) { | 233 | if (error) { |
242 | xfs_da_buf_done(oldblk->bp); | ||
243 | xfs_da_buf_done(addblk->bp); | ||
244 | addblk->bp = NULL; | 234 | addblk->bp = NULL; |
245 | return(error); /* GROT: dir is inconsistent */ | 235 | return(error); /* GROT: dir is inconsistent */ |
246 | } | 236 | } |
@@ -252,7 +242,7 @@ xfs_da_split(xfs_da_state_t *state) | |||
252 | * and the original block 0 could be at any position in the list. | 242 | * and the original block 0 could be at any position in the list. |
253 | */ | 243 | */ |
254 | 244 | ||
255 | node = oldblk->bp->data; | 245 | node = oldblk->bp->b_addr; |
256 | if (node->hdr.info.forw) { | 246 | if (node->hdr.info.forw) { |
257 | if (be32_to_cpu(node->hdr.info.forw) == addblk->blkno) { | 247 | if (be32_to_cpu(node->hdr.info.forw) == addblk->blkno) { |
258 | bp = addblk->bp; | 248 | bp = addblk->bp; |
@@ -260,13 +250,13 @@ xfs_da_split(xfs_da_state_t *state) | |||
260 | ASSERT(state->extravalid); | 250 | ASSERT(state->extravalid); |
261 | bp = state->extrablk.bp; | 251 | bp = state->extrablk.bp; |
262 | } | 252 | } |
263 | node = bp->data; | 253 | node = bp->b_addr; |
264 | node->hdr.info.back = cpu_to_be32(oldblk->blkno); | 254 | node->hdr.info.back = cpu_to_be32(oldblk->blkno); |
265 | xfs_da_log_buf(state->args->trans, bp, | 255 | xfs_trans_log_buf(state->args->trans, bp, |
266 | XFS_DA_LOGRANGE(node, &node->hdr.info, | 256 | XFS_DA_LOGRANGE(node, &node->hdr.info, |
267 | sizeof(node->hdr.info))); | 257 | sizeof(node->hdr.info))); |
268 | } | 258 | } |
269 | node = oldblk->bp->data; | 259 | node = oldblk->bp->b_addr; |
270 | if (node->hdr.info.back) { | 260 | if (node->hdr.info.back) { |
271 | if (be32_to_cpu(node->hdr.info.back) == addblk->blkno) { | 261 | if (be32_to_cpu(node->hdr.info.back) == addblk->blkno) { |
272 | bp = addblk->bp; | 262 | bp = addblk->bp; |
@@ -274,14 +264,12 @@ xfs_da_split(xfs_da_state_t *state) | |||
274 | ASSERT(state->extravalid); | 264 | ASSERT(state->extravalid); |
275 | bp = state->extrablk.bp; | 265 | bp = state->extrablk.bp; |
276 | } | 266 | } |
277 | node = bp->data; | 267 | node = bp->b_addr; |
278 | node->hdr.info.forw = cpu_to_be32(oldblk->blkno); | 268 | node->hdr.info.forw = cpu_to_be32(oldblk->blkno); |
279 | xfs_da_log_buf(state->args->trans, bp, | 269 | xfs_trans_log_buf(state->args->trans, bp, |
280 | XFS_DA_LOGRANGE(node, &node->hdr.info, | 270 | XFS_DA_LOGRANGE(node, &node->hdr.info, |
281 | sizeof(node->hdr.info))); | 271 | sizeof(node->hdr.info))); |
282 | } | 272 | } |
283 | xfs_da_buf_done(oldblk->bp); | ||
284 | xfs_da_buf_done(addblk->bp); | ||
285 | addblk->bp = NULL; | 273 | addblk->bp = NULL; |
286 | return(0); | 274 | return(0); |
287 | } | 275 | } |
@@ -298,7 +286,7 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, | |||
298 | xfs_da_intnode_t *node, *oldroot; | 286 | xfs_da_intnode_t *node, *oldroot; |
299 | xfs_da_args_t *args; | 287 | xfs_da_args_t *args; |
300 | xfs_dablk_t blkno; | 288 | xfs_dablk_t blkno; |
301 | xfs_dabuf_t *bp; | 289 | struct xfs_buf *bp; |
302 | int error, size; | 290 | int error, size; |
303 | xfs_inode_t *dp; | 291 | xfs_inode_t *dp; |
304 | xfs_trans_t *tp; | 292 | xfs_trans_t *tp; |
@@ -323,8 +311,8 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, | |||
323 | if (error) | 311 | if (error) |
324 | return(error); | 312 | return(error); |
325 | ASSERT(bp != NULL); | 313 | ASSERT(bp != NULL); |
326 | node = bp->data; | 314 | node = bp->b_addr; |
327 | oldroot = blk1->bp->data; | 315 | oldroot = blk1->bp->b_addr; |
328 | if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)) { | 316 | if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)) { |
329 | size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] - | 317 | size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] - |
330 | (char *)oldroot); | 318 | (char *)oldroot); |
@@ -335,8 +323,7 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, | |||
335 | (char *)leaf); | 323 | (char *)leaf); |
336 | } | 324 | } |
337 | memcpy(node, oldroot, size); | 325 | memcpy(node, oldroot, size); |
338 | xfs_da_log_buf(tp, bp, 0, size - 1); | 326 | xfs_trans_log_buf(tp, bp, 0, size - 1); |
339 | xfs_da_buf_done(blk1->bp); | ||
340 | blk1->bp = bp; | 327 | blk1->bp = bp; |
341 | blk1->blkno = blkno; | 328 | blk1->blkno = blkno; |
342 | 329 | ||
@@ -348,7 +335,7 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, | |||
348 | be16_to_cpu(node->hdr.level) + 1, &bp, args->whichfork); | 335 | be16_to_cpu(node->hdr.level) + 1, &bp, args->whichfork); |
349 | if (error) | 336 | if (error) |
350 | return(error); | 337 | return(error); |
351 | node = bp->data; | 338 | node = bp->b_addr; |
352 | node->btree[0].hashval = cpu_to_be32(blk1->hashval); | 339 | node->btree[0].hashval = cpu_to_be32(blk1->hashval); |
353 | node->btree[0].before = cpu_to_be32(blk1->blkno); | 340 | node->btree[0].before = cpu_to_be32(blk1->blkno); |
354 | node->btree[1].hashval = cpu_to_be32(blk2->hashval); | 341 | node->btree[1].hashval = cpu_to_be32(blk2->hashval); |
@@ -365,10 +352,9 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, | |||
365 | #endif | 352 | #endif |
366 | 353 | ||
367 | /* Header is already logged by xfs_da_node_create */ | 354 | /* Header is already logged by xfs_da_node_create */ |
368 | xfs_da_log_buf(tp, bp, | 355 | xfs_trans_log_buf(tp, bp, |
369 | XFS_DA_LOGRANGE(node, node->btree, | 356 | XFS_DA_LOGRANGE(node, node->btree, |
370 | sizeof(xfs_da_node_entry_t) * 2)); | 357 | sizeof(xfs_da_node_entry_t) * 2)); |
371 | xfs_da_buf_done(bp); | ||
372 | 358 | ||
373 | return(0); | 359 | return(0); |
374 | } | 360 | } |
@@ -389,7 +375,7 @@ xfs_da_node_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, | |||
389 | 375 | ||
390 | trace_xfs_da_node_split(state->args); | 376 | trace_xfs_da_node_split(state->args); |
391 | 377 | ||
392 | node = oldblk->bp->data; | 378 | node = oldblk->bp->b_addr; |
393 | ASSERT(node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); | 379 | ASSERT(node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); |
394 | 380 | ||
395 | /* | 381 | /* |
@@ -436,7 +422,7 @@ xfs_da_node_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, | |||
436 | * | 422 | * |
437 | * If we had double-split op below us, then add the extra block too. | 423 | * If we had double-split op below us, then add the extra block too. |
438 | */ | 424 | */ |
439 | node = oldblk->bp->data; | 425 | node = oldblk->bp->b_addr; |
440 | if (oldblk->index <= be16_to_cpu(node->hdr.count)) { | 426 | if (oldblk->index <= be16_to_cpu(node->hdr.count)) { |
441 | oldblk->index++; | 427 | oldblk->index++; |
442 | xfs_da_node_add(state, oldblk, addblk); | 428 | xfs_da_node_add(state, oldblk, addblk); |
@@ -477,8 +463,8 @@ xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, | |||
477 | 463 | ||
478 | trace_xfs_da_node_rebalance(state->args); | 464 | trace_xfs_da_node_rebalance(state->args); |
479 | 465 | ||
480 | node1 = blk1->bp->data; | 466 | node1 = blk1->bp->b_addr; |
481 | node2 = blk2->bp->data; | 467 | node2 = blk2->bp->b_addr; |
482 | /* | 468 | /* |
483 | * Figure out how many entries need to move, and in which direction. | 469 | * Figure out how many entries need to move, and in which direction. |
484 | * Swap the nodes around if that makes it simpler. | 470 | * Swap the nodes around if that makes it simpler. |
@@ -532,7 +518,7 @@ xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, | |||
532 | btree_d = &node1->btree[be16_to_cpu(node1->hdr.count)]; | 518 | btree_d = &node1->btree[be16_to_cpu(node1->hdr.count)]; |
533 | memcpy(btree_d, btree_s, tmp); | 519 | memcpy(btree_d, btree_s, tmp); |
534 | be16_add_cpu(&node1->hdr.count, count); | 520 | be16_add_cpu(&node1->hdr.count, count); |
535 | xfs_da_log_buf(tp, blk1->bp, | 521 | xfs_trans_log_buf(tp, blk1->bp, |
536 | XFS_DA_LOGRANGE(node1, btree_d, tmp)); | 522 | XFS_DA_LOGRANGE(node1, btree_d, tmp)); |
537 | 523 | ||
538 | /* | 524 | /* |
@@ -549,9 +535,9 @@ xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, | |||
549 | /* | 535 | /* |
550 | * Log header of node 1 and all current bits of node 2. | 536 | * Log header of node 1 and all current bits of node 2. |
551 | */ | 537 | */ |
552 | xfs_da_log_buf(tp, blk1->bp, | 538 | xfs_trans_log_buf(tp, blk1->bp, |
553 | XFS_DA_LOGRANGE(node1, &node1->hdr, sizeof(node1->hdr))); | 539 | XFS_DA_LOGRANGE(node1, &node1->hdr, sizeof(node1->hdr))); |
554 | xfs_da_log_buf(tp, blk2->bp, | 540 | xfs_trans_log_buf(tp, blk2->bp, |
555 | XFS_DA_LOGRANGE(node2, &node2->hdr, | 541 | XFS_DA_LOGRANGE(node2, &node2->hdr, |
556 | sizeof(node2->hdr) + | 542 | sizeof(node2->hdr) + |
557 | sizeof(node2->btree[0]) * be16_to_cpu(node2->hdr.count))); | 543 | sizeof(node2->btree[0]) * be16_to_cpu(node2->hdr.count))); |
@@ -560,8 +546,8 @@ xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, | |||
560 | * Record the last hashval from each block for upward propagation. | 546 | * Record the last hashval from each block for upward propagation. |
561 | * (note: don't use the swapped node pointers) | 547 | * (note: don't use the swapped node pointers) |
562 | */ | 548 | */ |
563 | node1 = blk1->bp->data; | 549 | node1 = blk1->bp->b_addr; |
564 | node2 = blk2->bp->data; | 550 | node2 = blk2->bp->b_addr; |
565 | blk1->hashval = be32_to_cpu(node1->btree[be16_to_cpu(node1->hdr.count)-1].hashval); | 551 | blk1->hashval = be32_to_cpu(node1->btree[be16_to_cpu(node1->hdr.count)-1].hashval); |
566 | blk2->hashval = be32_to_cpu(node2->btree[be16_to_cpu(node2->hdr.count)-1].hashval); | 552 | blk2->hashval = be32_to_cpu(node2->btree[be16_to_cpu(node2->hdr.count)-1].hashval); |
567 | 553 | ||
@@ -587,7 +573,7 @@ xfs_da_node_add(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, | |||
587 | 573 | ||
588 | trace_xfs_da_node_add(state->args); | 574 | trace_xfs_da_node_add(state->args); |
589 | 575 | ||
590 | node = oldblk->bp->data; | 576 | node = oldblk->bp->b_addr; |
591 | ASSERT(node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); | 577 | ASSERT(node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); |
592 | ASSERT((oldblk->index >= 0) && (oldblk->index <= be16_to_cpu(node->hdr.count))); | 578 | ASSERT((oldblk->index >= 0) && (oldblk->index <= be16_to_cpu(node->hdr.count))); |
593 | ASSERT(newblk->blkno != 0); | 579 | ASSERT(newblk->blkno != 0); |
@@ -606,10 +592,10 @@ xfs_da_node_add(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, | |||
606 | } | 592 | } |
607 | btree->hashval = cpu_to_be32(newblk->hashval); | 593 | btree->hashval = cpu_to_be32(newblk->hashval); |
608 | btree->before = cpu_to_be32(newblk->blkno); | 594 | btree->before = cpu_to_be32(newblk->blkno); |
609 | xfs_da_log_buf(state->args->trans, oldblk->bp, | 595 | xfs_trans_log_buf(state->args->trans, oldblk->bp, |
610 | XFS_DA_LOGRANGE(node, btree, tmp + sizeof(*btree))); | 596 | XFS_DA_LOGRANGE(node, btree, tmp + sizeof(*btree))); |
611 | be16_add_cpu(&node->hdr.count, 1); | 597 | be16_add_cpu(&node->hdr.count, 1); |
612 | xfs_da_log_buf(state->args->trans, oldblk->bp, | 598 | xfs_trans_log_buf(state->args->trans, oldblk->bp, |
613 | XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr))); | 599 | XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr))); |
614 | 600 | ||
615 | /* | 601 | /* |
@@ -735,7 +721,7 @@ xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk) | |||
735 | xfs_da_intnode_t *oldroot; | 721 | xfs_da_intnode_t *oldroot; |
736 | xfs_da_args_t *args; | 722 | xfs_da_args_t *args; |
737 | xfs_dablk_t child; | 723 | xfs_dablk_t child; |
738 | xfs_dabuf_t *bp; | 724 | struct xfs_buf *bp; |
739 | int error; | 725 | int error; |
740 | 726 | ||
741 | trace_xfs_da_root_join(state->args); | 727 | trace_xfs_da_root_join(state->args); |
@@ -743,7 +729,7 @@ xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk) | |||
743 | args = state->args; | 729 | args = state->args; |
744 | ASSERT(args != NULL); | 730 | ASSERT(args != NULL); |
745 | ASSERT(root_blk->magic == XFS_DA_NODE_MAGIC); | 731 | ASSERT(root_blk->magic == XFS_DA_NODE_MAGIC); |
746 | oldroot = root_blk->bp->data; | 732 | oldroot = root_blk->bp->b_addr; |
747 | ASSERT(oldroot->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); | 733 | ASSERT(oldroot->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); |
748 | ASSERT(!oldroot->hdr.info.forw); | 734 | ASSERT(!oldroot->hdr.info.forw); |
749 | ASSERT(!oldroot->hdr.info.back); | 735 | ASSERT(!oldroot->hdr.info.back); |
@@ -765,11 +751,11 @@ xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk) | |||
765 | if (error) | 751 | if (error) |
766 | return(error); | 752 | return(error); |
767 | ASSERT(bp != NULL); | 753 | ASSERT(bp != NULL); |
768 | xfs_da_blkinfo_onlychild_validate(bp->data, | 754 | xfs_da_blkinfo_onlychild_validate(bp->b_addr, |
769 | be16_to_cpu(oldroot->hdr.level)); | 755 | be16_to_cpu(oldroot->hdr.level)); |
770 | 756 | ||
771 | memcpy(root_blk->bp->data, bp->data, state->blocksize); | 757 | memcpy(root_blk->bp->b_addr, bp->b_addr, state->blocksize); |
772 | xfs_da_log_buf(args->trans, root_blk->bp, 0, state->blocksize - 1); | 758 | xfs_trans_log_buf(args->trans, root_blk->bp, 0, state->blocksize - 1); |
773 | error = xfs_da_shrink_inode(args, child, bp); | 759 | error = xfs_da_shrink_inode(args, child, bp); |
774 | return(error); | 760 | return(error); |
775 | } | 761 | } |
@@ -791,7 +777,7 @@ xfs_da_node_toosmall(xfs_da_state_t *state, int *action) | |||
791 | xfs_da_blkinfo_t *info; | 777 | xfs_da_blkinfo_t *info; |
792 | int count, forward, error, retval, i; | 778 | int count, forward, error, retval, i; |
793 | xfs_dablk_t blkno; | 779 | xfs_dablk_t blkno; |
794 | xfs_dabuf_t *bp; | 780 | struct xfs_buf *bp; |
795 | 781 | ||
796 | /* | 782 | /* |
797 | * Check for the degenerate case of the block being over 50% full. | 783 | * Check for the degenerate case of the block being over 50% full. |
@@ -799,7 +785,7 @@ xfs_da_node_toosmall(xfs_da_state_t *state, int *action) | |||
799 | * to coalesce with a sibling. | 785 | * to coalesce with a sibling. |
800 | */ | 786 | */ |
801 | blk = &state->path.blk[ state->path.active-1 ]; | 787 | blk = &state->path.blk[ state->path.active-1 ]; |
802 | info = blk->bp->data; | 788 | info = blk->bp->b_addr; |
803 | ASSERT(info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); | 789 | ASSERT(info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); |
804 | node = (xfs_da_intnode_t *)info; | 790 | node = (xfs_da_intnode_t *)info; |
805 | count = be16_to_cpu(node->hdr.count); | 791 | count = be16_to_cpu(node->hdr.count); |
@@ -859,10 +845,10 @@ xfs_da_node_toosmall(xfs_da_state_t *state, int *action) | |||
859 | count = state->node_ents; | 845 | count = state->node_ents; |
860 | count -= state->node_ents >> 2; | 846 | count -= state->node_ents >> 2; |
861 | count -= be16_to_cpu(node->hdr.count); | 847 | count -= be16_to_cpu(node->hdr.count); |
862 | node = bp->data; | 848 | node = bp->b_addr; |
863 | ASSERT(node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); | 849 | ASSERT(node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); |
864 | count -= be16_to_cpu(node->hdr.count); | 850 | count -= be16_to_cpu(node->hdr.count); |
865 | xfs_da_brelse(state->args->trans, bp); | 851 | xfs_trans_brelse(state->args->trans, bp); |
866 | if (count >= 0) | 852 | if (count >= 0) |
867 | break; /* fits with at least 25% to spare */ | 853 | break; /* fits with at least 25% to spare */ |
868 | } | 854 | } |
@@ -934,14 +920,14 @@ xfs_da_fixhashpath(xfs_da_state_t *state, xfs_da_state_path_t *path) | |||
934 | break; | 920 | break; |
935 | } | 921 | } |
936 | for (blk--, level--; level >= 0; blk--, level--) { | 922 | for (blk--, level--; level >= 0; blk--, level--) { |
937 | node = blk->bp->data; | 923 | node = blk->bp->b_addr; |
938 | ASSERT(node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); | 924 | ASSERT(node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); |
939 | btree = &node->btree[ blk->index ]; | 925 | btree = &node->btree[ blk->index ]; |
940 | if (be32_to_cpu(btree->hashval) == lasthash) | 926 | if (be32_to_cpu(btree->hashval) == lasthash) |
941 | break; | 927 | break; |
942 | blk->hashval = lasthash; | 928 | blk->hashval = lasthash; |
943 | btree->hashval = cpu_to_be32(lasthash); | 929 | btree->hashval = cpu_to_be32(lasthash); |
944 | xfs_da_log_buf(state->args->trans, blk->bp, | 930 | xfs_trans_log_buf(state->args->trans, blk->bp, |
945 | XFS_DA_LOGRANGE(node, btree, sizeof(*btree))); | 931 | XFS_DA_LOGRANGE(node, btree, sizeof(*btree))); |
946 | 932 | ||
947 | lasthash = be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1].hashval); | 933 | lasthash = be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1].hashval); |
@@ -960,7 +946,7 @@ xfs_da_node_remove(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk) | |||
960 | 946 | ||
961 | trace_xfs_da_node_remove(state->args); | 947 | trace_xfs_da_node_remove(state->args); |
962 | 948 | ||
963 | node = drop_blk->bp->data; | 949 | node = drop_blk->bp->b_addr; |
964 | ASSERT(drop_blk->index < be16_to_cpu(node->hdr.count)); | 950 | ASSERT(drop_blk->index < be16_to_cpu(node->hdr.count)); |
965 | ASSERT(drop_blk->index >= 0); | 951 | ASSERT(drop_blk->index >= 0); |
966 | 952 | ||
@@ -972,15 +958,15 @@ xfs_da_node_remove(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk) | |||
972 | tmp = be16_to_cpu(node->hdr.count) - drop_blk->index - 1; | 958 | tmp = be16_to_cpu(node->hdr.count) - drop_blk->index - 1; |
973 | tmp *= (uint)sizeof(xfs_da_node_entry_t); | 959 | tmp *= (uint)sizeof(xfs_da_node_entry_t); |
974 | memmove(btree, btree + 1, tmp); | 960 | memmove(btree, btree + 1, tmp); |
975 | xfs_da_log_buf(state->args->trans, drop_blk->bp, | 961 | xfs_trans_log_buf(state->args->trans, drop_blk->bp, |
976 | XFS_DA_LOGRANGE(node, btree, tmp)); | 962 | XFS_DA_LOGRANGE(node, btree, tmp)); |
977 | btree = &node->btree[be16_to_cpu(node->hdr.count)-1]; | 963 | btree = &node->btree[be16_to_cpu(node->hdr.count)-1]; |
978 | } | 964 | } |
979 | memset((char *)btree, 0, sizeof(xfs_da_node_entry_t)); | 965 | memset((char *)btree, 0, sizeof(xfs_da_node_entry_t)); |
980 | xfs_da_log_buf(state->args->trans, drop_blk->bp, | 966 | xfs_trans_log_buf(state->args->trans, drop_blk->bp, |
981 | XFS_DA_LOGRANGE(node, btree, sizeof(*btree))); | 967 | XFS_DA_LOGRANGE(node, btree, sizeof(*btree))); |
982 | be16_add_cpu(&node->hdr.count, -1); | 968 | be16_add_cpu(&node->hdr.count, -1); |
983 | xfs_da_log_buf(state->args->trans, drop_blk->bp, | 969 | xfs_trans_log_buf(state->args->trans, drop_blk->bp, |
984 | XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr))); | 970 | XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr))); |
985 | 971 | ||
986 | /* | 972 | /* |
@@ -1005,8 +991,8 @@ xfs_da_node_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, | |||
1005 | 991 | ||
1006 | trace_xfs_da_node_unbalance(state->args); | 992 | trace_xfs_da_node_unbalance(state->args); |
1007 | 993 | ||
1008 | drop_node = drop_blk->bp->data; | 994 | drop_node = drop_blk->bp->b_addr; |
1009 | save_node = save_blk->bp->data; | 995 | save_node = save_blk->bp->b_addr; |
1010 | ASSERT(drop_node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); | 996 | ASSERT(drop_node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); |
1011 | ASSERT(save_node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); | 997 | ASSERT(save_node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); |
1012 | tp = state->args->trans; | 998 | tp = state->args->trans; |
@@ -1023,13 +1009,13 @@ xfs_da_node_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, | |||
1023 | tmp = be16_to_cpu(save_node->hdr.count) * (uint)sizeof(xfs_da_node_entry_t); | 1009 | tmp = be16_to_cpu(save_node->hdr.count) * (uint)sizeof(xfs_da_node_entry_t); |
1024 | memmove(btree, &save_node->btree[0], tmp); | 1010 | memmove(btree, &save_node->btree[0], tmp); |
1025 | btree = &save_node->btree[0]; | 1011 | btree = &save_node->btree[0]; |
1026 | xfs_da_log_buf(tp, save_blk->bp, | 1012 | xfs_trans_log_buf(tp, save_blk->bp, |
1027 | XFS_DA_LOGRANGE(save_node, btree, | 1013 | XFS_DA_LOGRANGE(save_node, btree, |
1028 | (be16_to_cpu(save_node->hdr.count) + be16_to_cpu(drop_node->hdr.count)) * | 1014 | (be16_to_cpu(save_node->hdr.count) + be16_to_cpu(drop_node->hdr.count)) * |
1029 | sizeof(xfs_da_node_entry_t))); | 1015 | sizeof(xfs_da_node_entry_t))); |
1030 | } else { | 1016 | } else { |
1031 | btree = &save_node->btree[be16_to_cpu(save_node->hdr.count)]; | 1017 | btree = &save_node->btree[be16_to_cpu(save_node->hdr.count)]; |
1032 | xfs_da_log_buf(tp, save_blk->bp, | 1018 | xfs_trans_log_buf(tp, save_blk->bp, |
1033 | XFS_DA_LOGRANGE(save_node, btree, | 1019 | XFS_DA_LOGRANGE(save_node, btree, |
1034 | be16_to_cpu(drop_node->hdr.count) * | 1020 | be16_to_cpu(drop_node->hdr.count) * |
1035 | sizeof(xfs_da_node_entry_t))); | 1021 | sizeof(xfs_da_node_entry_t))); |
@@ -1042,7 +1028,7 @@ xfs_da_node_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, | |||
1042 | memcpy(btree, &drop_node->btree[0], tmp); | 1028 | memcpy(btree, &drop_node->btree[0], tmp); |
1043 | be16_add_cpu(&save_node->hdr.count, be16_to_cpu(drop_node->hdr.count)); | 1029 | be16_add_cpu(&save_node->hdr.count, be16_to_cpu(drop_node->hdr.count)); |
1044 | 1030 | ||
1045 | xfs_da_log_buf(tp, save_blk->bp, | 1031 | xfs_trans_log_buf(tp, save_blk->bp, |
1046 | XFS_DA_LOGRANGE(save_node, &save_node->hdr, | 1032 | XFS_DA_LOGRANGE(save_node, &save_node->hdr, |
1047 | sizeof(save_node->hdr))); | 1033 | sizeof(save_node->hdr))); |
1048 | 1034 | ||
@@ -1100,7 +1086,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) | |||
1100 | state->path.active--; | 1086 | state->path.active--; |
1101 | return(error); | 1087 | return(error); |
1102 | } | 1088 | } |
1103 | curr = blk->bp->data; | 1089 | curr = blk->bp->b_addr; |
1104 | blk->magic = be16_to_cpu(curr->magic); | 1090 | blk->magic = be16_to_cpu(curr->magic); |
1105 | ASSERT(blk->magic == XFS_DA_NODE_MAGIC || | 1091 | ASSERT(blk->magic == XFS_DA_NODE_MAGIC || |
1106 | blk->magic == XFS_DIR2_LEAFN_MAGIC || | 1092 | blk->magic == XFS_DIR2_LEAFN_MAGIC || |
@@ -1110,7 +1096,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) | |||
1110 | * Search an intermediate node for a match. | 1096 | * Search an intermediate node for a match. |
1111 | */ | 1097 | */ |
1112 | if (blk->magic == XFS_DA_NODE_MAGIC) { | 1098 | if (blk->magic == XFS_DA_NODE_MAGIC) { |
1113 | node = blk->bp->data; | 1099 | node = blk->bp->b_addr; |
1114 | max = be16_to_cpu(node->hdr.count); | 1100 | max = be16_to_cpu(node->hdr.count); |
1115 | blk->hashval = be32_to_cpu(node->btree[max-1].hashval); | 1101 | blk->hashval = be32_to_cpu(node->btree[max-1].hashval); |
1116 | 1102 | ||
@@ -1216,15 +1202,15 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk, | |||
1216 | xfs_da_blkinfo_t *old_info, *new_info, *tmp_info; | 1202 | xfs_da_blkinfo_t *old_info, *new_info, *tmp_info; |
1217 | xfs_da_args_t *args; | 1203 | xfs_da_args_t *args; |
1218 | int before=0, error; | 1204 | int before=0, error; |
1219 | xfs_dabuf_t *bp; | 1205 | struct xfs_buf *bp; |
1220 | 1206 | ||
1221 | /* | 1207 | /* |
1222 | * Set up environment. | 1208 | * Set up environment. |
1223 | */ | 1209 | */ |
1224 | args = state->args; | 1210 | args = state->args; |
1225 | ASSERT(args != NULL); | 1211 | ASSERT(args != NULL); |
1226 | old_info = old_blk->bp->data; | 1212 | old_info = old_blk->bp->b_addr; |
1227 | new_info = new_blk->bp->data; | 1213 | new_info = new_blk->bp->b_addr; |
1228 | ASSERT(old_blk->magic == XFS_DA_NODE_MAGIC || | 1214 | ASSERT(old_blk->magic == XFS_DA_NODE_MAGIC || |
1229 | old_blk->magic == XFS_DIR2_LEAFN_MAGIC || | 1215 | old_blk->magic == XFS_DIR2_LEAFN_MAGIC || |
1230 | old_blk->magic == XFS_ATTR_LEAF_MAGIC); | 1216 | old_blk->magic == XFS_ATTR_LEAF_MAGIC); |
@@ -1261,12 +1247,11 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk, | |||
1261 | if (error) | 1247 | if (error) |
1262 | return(error); | 1248 | return(error); |
1263 | ASSERT(bp != NULL); | 1249 | ASSERT(bp != NULL); |
1264 | tmp_info = bp->data; | 1250 | tmp_info = bp->b_addr; |
1265 | ASSERT(be16_to_cpu(tmp_info->magic) == be16_to_cpu(old_info->magic)); | 1251 | ASSERT(be16_to_cpu(tmp_info->magic) == be16_to_cpu(old_info->magic)); |
1266 | ASSERT(be32_to_cpu(tmp_info->forw) == old_blk->blkno); | 1252 | ASSERT(be32_to_cpu(tmp_info->forw) == old_blk->blkno); |
1267 | tmp_info->forw = cpu_to_be32(new_blk->blkno); | 1253 | tmp_info->forw = cpu_to_be32(new_blk->blkno); |
1268 | xfs_da_log_buf(args->trans, bp, 0, sizeof(*tmp_info)-1); | 1254 | xfs_trans_log_buf(args->trans, bp, 0, sizeof(*tmp_info)-1); |
1269 | xfs_da_buf_done(bp); | ||
1270 | } | 1255 | } |
1271 | old_info->back = cpu_to_be32(new_blk->blkno); | 1256 | old_info->back = cpu_to_be32(new_blk->blkno); |
1272 | } else { | 1257 | } else { |
@@ -1283,18 +1268,17 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk, | |||
1283 | if (error) | 1268 | if (error) |
1284 | return(error); | 1269 | return(error); |
1285 | ASSERT(bp != NULL); | 1270 | ASSERT(bp != NULL); |
1286 | tmp_info = bp->data; | 1271 | tmp_info = bp->b_addr; |
1287 | ASSERT(tmp_info->magic == old_info->magic); | 1272 | ASSERT(tmp_info->magic == old_info->magic); |
1288 | ASSERT(be32_to_cpu(tmp_info->back) == old_blk->blkno); | 1273 | ASSERT(be32_to_cpu(tmp_info->back) == old_blk->blkno); |
1289 | tmp_info->back = cpu_to_be32(new_blk->blkno); | 1274 | tmp_info->back = cpu_to_be32(new_blk->blkno); |
1290 | xfs_da_log_buf(args->trans, bp, 0, sizeof(*tmp_info)-1); | 1275 | xfs_trans_log_buf(args->trans, bp, 0, sizeof(*tmp_info)-1); |
1291 | xfs_da_buf_done(bp); | ||
1292 | } | 1276 | } |
1293 | old_info->forw = cpu_to_be32(new_blk->blkno); | 1277 | old_info->forw = cpu_to_be32(new_blk->blkno); |
1294 | } | 1278 | } |
1295 | 1279 | ||
1296 | xfs_da_log_buf(args->trans, old_blk->bp, 0, sizeof(*tmp_info) - 1); | 1280 | xfs_trans_log_buf(args->trans, old_blk->bp, 0, sizeof(*tmp_info) - 1); |
1297 | xfs_da_log_buf(args->trans, new_blk->bp, 0, sizeof(*tmp_info) - 1); | 1281 | xfs_trans_log_buf(args->trans, new_blk->bp, 0, sizeof(*tmp_info) - 1); |
1298 | return(0); | 1282 | return(0); |
1299 | } | 1283 | } |
1300 | 1284 | ||
@@ -1302,12 +1286,14 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk, | |||
1302 | * Compare two intermediate nodes for "order". | 1286 | * Compare two intermediate nodes for "order". |
1303 | */ | 1287 | */ |
1304 | STATIC int | 1288 | STATIC int |
1305 | xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp) | 1289 | xfs_da_node_order( |
1290 | struct xfs_buf *node1_bp, | ||
1291 | struct xfs_buf *node2_bp) | ||
1306 | { | 1292 | { |
1307 | xfs_da_intnode_t *node1, *node2; | 1293 | xfs_da_intnode_t *node1, *node2; |
1308 | 1294 | ||
1309 | node1 = node1_bp->data; | 1295 | node1 = node1_bp->b_addr; |
1310 | node2 = node2_bp->data; | 1296 | node2 = node2_bp->b_addr; |
1311 | ASSERT(node1->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC) && | 1297 | ASSERT(node1->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC) && |
1312 | node2->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); | 1298 | node2->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); |
1313 | if ((be16_to_cpu(node1->hdr.count) > 0) && (be16_to_cpu(node2->hdr.count) > 0) && | 1299 | if ((be16_to_cpu(node1->hdr.count) > 0) && (be16_to_cpu(node2->hdr.count) > 0) && |
@@ -1324,11 +1310,13 @@ xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp) | |||
1324 | * Pick up the last hashvalue from an intermediate node. | 1310 | * Pick up the last hashvalue from an intermediate node. |
1325 | */ | 1311 | */ |
1326 | STATIC uint | 1312 | STATIC uint |
1327 | xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count) | 1313 | xfs_da_node_lasthash( |
1314 | struct xfs_buf *bp, | ||
1315 | int *count) | ||
1328 | { | 1316 | { |
1329 | xfs_da_intnode_t *node; | 1317 | xfs_da_intnode_t *node; |
1330 | 1318 | ||
1331 | node = bp->data; | 1319 | node = bp->b_addr; |
1332 | ASSERT(node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); | 1320 | ASSERT(node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); |
1333 | if (count) | 1321 | if (count) |
1334 | *count = be16_to_cpu(node->hdr.count); | 1322 | *count = be16_to_cpu(node->hdr.count); |
@@ -1346,7 +1334,7 @@ xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, | |||
1346 | { | 1334 | { |
1347 | xfs_da_blkinfo_t *drop_info, *save_info, *tmp_info; | 1335 | xfs_da_blkinfo_t *drop_info, *save_info, *tmp_info; |
1348 | xfs_da_args_t *args; | 1336 | xfs_da_args_t *args; |
1349 | xfs_dabuf_t *bp; | 1337 | struct xfs_buf *bp; |
1350 | int error; | 1338 | int error; |
1351 | 1339 | ||
1352 | /* | 1340 | /* |
@@ -1354,8 +1342,8 @@ xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, | |||
1354 | */ | 1342 | */ |
1355 | args = state->args; | 1343 | args = state->args; |
1356 | ASSERT(args != NULL); | 1344 | ASSERT(args != NULL); |
1357 | save_info = save_blk->bp->data; | 1345 | save_info = save_blk->bp->b_addr; |
1358 | drop_info = drop_blk->bp->data; | 1346 | drop_info = drop_blk->bp->b_addr; |
1359 | ASSERT(save_blk->magic == XFS_DA_NODE_MAGIC || | 1347 | ASSERT(save_blk->magic == XFS_DA_NODE_MAGIC || |
1360 | save_blk->magic == XFS_DIR2_LEAFN_MAGIC || | 1348 | save_blk->magic == XFS_DIR2_LEAFN_MAGIC || |
1361 | save_blk->magic == XFS_ATTR_LEAF_MAGIC); | 1349 | save_blk->magic == XFS_ATTR_LEAF_MAGIC); |
@@ -1380,13 +1368,12 @@ xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, | |||
1380 | if (error) | 1368 | if (error) |
1381 | return(error); | 1369 | return(error); |
1382 | ASSERT(bp != NULL); | 1370 | ASSERT(bp != NULL); |
1383 | tmp_info = bp->data; | 1371 | tmp_info = bp->b_addr; |
1384 | ASSERT(tmp_info->magic == save_info->magic); | 1372 | ASSERT(tmp_info->magic == save_info->magic); |
1385 | ASSERT(be32_to_cpu(tmp_info->forw) == drop_blk->blkno); | 1373 | ASSERT(be32_to_cpu(tmp_info->forw) == drop_blk->blkno); |
1386 | tmp_info->forw = cpu_to_be32(save_blk->blkno); | 1374 | tmp_info->forw = cpu_to_be32(save_blk->blkno); |
1387 | xfs_da_log_buf(args->trans, bp, 0, | 1375 | xfs_trans_log_buf(args->trans, bp, 0, |
1388 | sizeof(*tmp_info) - 1); | 1376 | sizeof(*tmp_info) - 1); |
1389 | xfs_da_buf_done(bp); | ||
1390 | } | 1377 | } |
1391 | } else { | 1378 | } else { |
1392 | trace_xfs_da_unlink_forward(args); | 1379 | trace_xfs_da_unlink_forward(args); |
@@ -1398,17 +1385,16 @@ xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, | |||
1398 | if (error) | 1385 | if (error) |
1399 | return(error); | 1386 | return(error); |
1400 | ASSERT(bp != NULL); | 1387 | ASSERT(bp != NULL); |
1401 | tmp_info = bp->data; | 1388 | tmp_info = bp->b_addr; |
1402 | ASSERT(tmp_info->magic == save_info->magic); | 1389 | ASSERT(tmp_info->magic == save_info->magic); |
1403 | ASSERT(be32_to_cpu(tmp_info->back) == drop_blk->blkno); | 1390 | ASSERT(be32_to_cpu(tmp_info->back) == drop_blk->blkno); |
1404 | tmp_info->back = cpu_to_be32(save_blk->blkno); | 1391 | tmp_info->back = cpu_to_be32(save_blk->blkno); |
1405 | xfs_da_log_buf(args->trans, bp, 0, | 1392 | xfs_trans_log_buf(args->trans, bp, 0, |
1406 | sizeof(*tmp_info) - 1); | 1393 | sizeof(*tmp_info) - 1); |
1407 | xfs_da_buf_done(bp); | ||
1408 | } | 1394 | } |
1409 | } | 1395 | } |
1410 | 1396 | ||
1411 | xfs_da_log_buf(args->trans, save_blk->bp, 0, sizeof(*save_info) - 1); | 1397 | xfs_trans_log_buf(args->trans, save_blk->bp, 0, sizeof(*save_info) - 1); |
1412 | return(0); | 1398 | return(0); |
1413 | } | 1399 | } |
1414 | 1400 | ||
@@ -1443,7 +1429,7 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path, | |||
1443 | level = (path->active-1) - 1; /* skip bottom layer in path */ | 1429 | level = (path->active-1) - 1; /* skip bottom layer in path */ |
1444 | for (blk = &path->blk[level]; level >= 0; blk--, level--) { | 1430 | for (blk = &path->blk[level]; level >= 0; blk--, level--) { |
1445 | ASSERT(blk->bp != NULL); | 1431 | ASSERT(blk->bp != NULL); |
1446 | node = blk->bp->data; | 1432 | node = blk->bp->b_addr; |
1447 | ASSERT(node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); | 1433 | ASSERT(node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); |
1448 | if (forward && (blk->index < be16_to_cpu(node->hdr.count)-1)) { | 1434 | if (forward && (blk->index < be16_to_cpu(node->hdr.count)-1)) { |
1449 | blk->index++; | 1435 | blk->index++; |
@@ -1471,7 +1457,7 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path, | |||
1471 | * (if it's dirty, trans won't actually let go) | 1457 | * (if it's dirty, trans won't actually let go) |
1472 | */ | 1458 | */ |
1473 | if (release) | 1459 | if (release) |
1474 | xfs_da_brelse(args->trans, blk->bp); | 1460 | xfs_trans_brelse(args->trans, blk->bp); |
1475 | 1461 | ||
1476 | /* | 1462 | /* |
1477 | * Read the next child block. | 1463 | * Read the next child block. |
@@ -1482,7 +1468,7 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path, | |||
1482 | if (error) | 1468 | if (error) |
1483 | return(error); | 1469 | return(error); |
1484 | ASSERT(blk->bp != NULL); | 1470 | ASSERT(blk->bp != NULL); |
1485 | info = blk->bp->data; | 1471 | info = blk->bp->b_addr; |
1486 | ASSERT(info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC) || | 1472 | ASSERT(info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC) || |
1487 | info->magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || | 1473 | info->magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || |
1488 | info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); | 1474 | info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); |
@@ -1702,11 +1688,13 @@ xfs_da_grow_inode( | |||
1702 | * a bmap btree split to do that. | 1688 | * a bmap btree split to do that. |
1703 | */ | 1689 | */ |
1704 | STATIC int | 1690 | STATIC int |
1705 | xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, | 1691 | xfs_da_swap_lastblock( |
1706 | xfs_dabuf_t **dead_bufp) | 1692 | xfs_da_args_t *args, |
1693 | xfs_dablk_t *dead_blknop, | ||
1694 | struct xfs_buf **dead_bufp) | ||
1707 | { | 1695 | { |
1708 | xfs_dablk_t dead_blkno, last_blkno, sib_blkno, par_blkno; | 1696 | xfs_dablk_t dead_blkno, last_blkno, sib_blkno, par_blkno; |
1709 | xfs_dabuf_t *dead_buf, *last_buf, *sib_buf, *par_buf; | 1697 | struct xfs_buf *dead_buf, *last_buf, *sib_buf, *par_buf; |
1710 | xfs_fileoff_t lastoff; | 1698 | xfs_fileoff_t lastoff; |
1711 | xfs_inode_t *ip; | 1699 | xfs_inode_t *ip; |
1712 | xfs_trans_t *tp; | 1700 | xfs_trans_t *tp; |
@@ -1744,9 +1732,9 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, | |||
1744 | /* | 1732 | /* |
1745 | * Copy the last block into the dead buffer and log it. | 1733 | * Copy the last block into the dead buffer and log it. |
1746 | */ | 1734 | */ |
1747 | memcpy(dead_buf->data, last_buf->data, mp->m_dirblksize); | 1735 | memcpy(dead_buf->b_addr, last_buf->b_addr, mp->m_dirblksize); |
1748 | xfs_da_log_buf(tp, dead_buf, 0, mp->m_dirblksize - 1); | 1736 | xfs_trans_log_buf(tp, dead_buf, 0, mp->m_dirblksize - 1); |
1749 | dead_info = dead_buf->data; | 1737 | dead_info = dead_buf->b_addr; |
1750 | /* | 1738 | /* |
1751 | * Get values from the moved block. | 1739 | * Get values from the moved block. |
1752 | */ | 1740 | */ |
@@ -1767,7 +1755,7 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, | |||
1767 | if ((sib_blkno = be32_to_cpu(dead_info->back))) { | 1755 | if ((sib_blkno = be32_to_cpu(dead_info->back))) { |
1768 | if ((error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w))) | 1756 | if ((error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w))) |
1769 | goto done; | 1757 | goto done; |
1770 | sib_info = sib_buf->data; | 1758 | sib_info = sib_buf->b_addr; |
1771 | if (unlikely( | 1759 | if (unlikely( |
1772 | be32_to_cpu(sib_info->forw) != last_blkno || | 1760 | be32_to_cpu(sib_info->forw) != last_blkno || |
1773 | sib_info->magic != dead_info->magic)) { | 1761 | sib_info->magic != dead_info->magic)) { |
@@ -1777,10 +1765,9 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, | |||
1777 | goto done; | 1765 | goto done; |
1778 | } | 1766 | } |
1779 | sib_info->forw = cpu_to_be32(dead_blkno); | 1767 | sib_info->forw = cpu_to_be32(dead_blkno); |
1780 | xfs_da_log_buf(tp, sib_buf, | 1768 | xfs_trans_log_buf(tp, sib_buf, |
1781 | XFS_DA_LOGRANGE(sib_info, &sib_info->forw, | 1769 | XFS_DA_LOGRANGE(sib_info, &sib_info->forw, |
1782 | sizeof(sib_info->forw))); | 1770 | sizeof(sib_info->forw))); |
1783 | xfs_da_buf_done(sib_buf); | ||
1784 | sib_buf = NULL; | 1771 | sib_buf = NULL; |
1785 | } | 1772 | } |
1786 | /* | 1773 | /* |
@@ -1789,7 +1776,7 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, | |||
1789 | if ((sib_blkno = be32_to_cpu(dead_info->forw))) { | 1776 | if ((sib_blkno = be32_to_cpu(dead_info->forw))) { |
1790 | if ((error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w))) | 1777 | if ((error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w))) |
1791 | goto done; | 1778 | goto done; |
1792 | sib_info = sib_buf->data; | 1779 | sib_info = sib_buf->b_addr; |
1793 | if (unlikely( | 1780 | if (unlikely( |
1794 | be32_to_cpu(sib_info->back) != last_blkno || | 1781 | be32_to_cpu(sib_info->back) != last_blkno || |
1795 | sib_info->magic != dead_info->magic)) { | 1782 | sib_info->magic != dead_info->magic)) { |
@@ -1799,10 +1786,9 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, | |||
1799 | goto done; | 1786 | goto done; |
1800 | } | 1787 | } |
1801 | sib_info->back = cpu_to_be32(dead_blkno); | 1788 | sib_info->back = cpu_to_be32(dead_blkno); |
1802 | xfs_da_log_buf(tp, sib_buf, | 1789 | xfs_trans_log_buf(tp, sib_buf, |
1803 | XFS_DA_LOGRANGE(sib_info, &sib_info->back, | 1790 | XFS_DA_LOGRANGE(sib_info, &sib_info->back, |
1804 | sizeof(sib_info->back))); | 1791 | sizeof(sib_info->back))); |
1805 | xfs_da_buf_done(sib_buf); | ||
1806 | sib_buf = NULL; | 1792 | sib_buf = NULL; |
1807 | } | 1793 | } |
1808 | par_blkno = mp->m_dirleafblk; | 1794 | par_blkno = mp->m_dirleafblk; |
@@ -1813,7 +1799,7 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, | |||
1813 | for (;;) { | 1799 | for (;;) { |
1814 | if ((error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w))) | 1800 | if ((error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w))) |
1815 | goto done; | 1801 | goto done; |
1816 | par_node = par_buf->data; | 1802 | par_node = par_buf->b_addr; |
1817 | if (unlikely(par_node->hdr.info.magic != | 1803 | if (unlikely(par_node->hdr.info.magic != |
1818 | cpu_to_be16(XFS_DA_NODE_MAGIC) || | 1804 | cpu_to_be16(XFS_DA_NODE_MAGIC) || |
1819 | (level >= 0 && level != be16_to_cpu(par_node->hdr.level) + 1))) { | 1805 | (level >= 0 && level != be16_to_cpu(par_node->hdr.level) + 1))) { |
@@ -1837,7 +1823,7 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, | |||
1837 | par_blkno = be32_to_cpu(par_node->btree[entno].before); | 1823 | par_blkno = be32_to_cpu(par_node->btree[entno].before); |
1838 | if (level == dead_level + 1) | 1824 | if (level == dead_level + 1) |
1839 | break; | 1825 | break; |
1840 | xfs_da_brelse(tp, par_buf); | 1826 | xfs_trans_brelse(tp, par_buf); |
1841 | par_buf = NULL; | 1827 | par_buf = NULL; |
1842 | } | 1828 | } |
1843 | /* | 1829 | /* |
@@ -1853,7 +1839,7 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, | |||
1853 | if (entno < be16_to_cpu(par_node->hdr.count)) | 1839 | if (entno < be16_to_cpu(par_node->hdr.count)) |
1854 | break; | 1840 | break; |
1855 | par_blkno = be32_to_cpu(par_node->hdr.info.forw); | 1841 | par_blkno = be32_to_cpu(par_node->hdr.info.forw); |
1856 | xfs_da_brelse(tp, par_buf); | 1842 | xfs_trans_brelse(tp, par_buf); |
1857 | par_buf = NULL; | 1843 | par_buf = NULL; |
1858 | if (unlikely(par_blkno == 0)) { | 1844 | if (unlikely(par_blkno == 0)) { |
1859 | XFS_ERROR_REPORT("xfs_da_swap_lastblock(6)", | 1845 | XFS_ERROR_REPORT("xfs_da_swap_lastblock(6)", |
@@ -1863,7 +1849,7 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, | |||
1863 | } | 1849 | } |
1864 | if ((error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w))) | 1850 | if ((error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w))) |
1865 | goto done; | 1851 | goto done; |
1866 | par_node = par_buf->data; | 1852 | par_node = par_buf->b_addr; |
1867 | if (unlikely( | 1853 | if (unlikely( |
1868 | be16_to_cpu(par_node->hdr.level) != level || | 1854 | be16_to_cpu(par_node->hdr.level) != level || |
1869 | par_node->hdr.info.magic != cpu_to_be16(XFS_DA_NODE_MAGIC))) { | 1855 | par_node->hdr.info.magic != cpu_to_be16(XFS_DA_NODE_MAGIC))) { |
@@ -1878,20 +1864,18 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, | |||
1878 | * Update the parent entry pointing to the moved block. | 1864 | * Update the parent entry pointing to the moved block. |
1879 | */ | 1865 | */ |
1880 | par_node->btree[entno].before = cpu_to_be32(dead_blkno); | 1866 | par_node->btree[entno].before = cpu_to_be32(dead_blkno); |
1881 | xfs_da_log_buf(tp, par_buf, | 1867 | xfs_trans_log_buf(tp, par_buf, |
1882 | XFS_DA_LOGRANGE(par_node, &par_node->btree[entno].before, | 1868 | XFS_DA_LOGRANGE(par_node, &par_node->btree[entno].before, |
1883 | sizeof(par_node->btree[entno].before))); | 1869 | sizeof(par_node->btree[entno].before))); |
1884 | xfs_da_buf_done(par_buf); | ||
1885 | xfs_da_buf_done(dead_buf); | ||
1886 | *dead_blknop = last_blkno; | 1870 | *dead_blknop = last_blkno; |
1887 | *dead_bufp = last_buf; | 1871 | *dead_bufp = last_buf; |
1888 | return 0; | 1872 | return 0; |
1889 | done: | 1873 | done: |
1890 | if (par_buf) | 1874 | if (par_buf) |
1891 | xfs_da_brelse(tp, par_buf); | 1875 | xfs_trans_brelse(tp, par_buf); |
1892 | if (sib_buf) | 1876 | if (sib_buf) |
1893 | xfs_da_brelse(tp, sib_buf); | 1877 | xfs_trans_brelse(tp, sib_buf); |
1894 | xfs_da_brelse(tp, last_buf); | 1878 | xfs_trans_brelse(tp, last_buf); |
1895 | return error; | 1879 | return error; |
1896 | } | 1880 | } |
1897 | 1881 | ||
@@ -1899,8 +1883,10 @@ done: | |||
1899 | * Remove a btree block from a directory or attribute. | 1883 | * Remove a btree block from a directory or attribute. |
1900 | */ | 1884 | */ |
1901 | int | 1885 | int |
1902 | xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, | 1886 | xfs_da_shrink_inode( |
1903 | xfs_dabuf_t *dead_buf) | 1887 | xfs_da_args_t *args, |
1888 | xfs_dablk_t dead_blkno, | ||
1889 | struct xfs_buf *dead_buf) | ||
1904 | { | 1890 | { |
1905 | xfs_inode_t *dp; | 1891 | xfs_inode_t *dp; |
1906 | int done, error, w, count; | 1892 | int done, error, w, count; |
@@ -1935,7 +1921,7 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, | |||
1935 | break; | 1921 | break; |
1936 | } | 1922 | } |
1937 | } | 1923 | } |
1938 | xfs_da_binval(tp, dead_buf); | 1924 | xfs_trans_binval(tp, dead_buf); |
1939 | return error; | 1925 | return error; |
1940 | } | 1926 | } |
1941 | 1927 | ||
@@ -1967,35 +1953,75 @@ xfs_da_map_covers_blocks( | |||
1967 | } | 1953 | } |
1968 | 1954 | ||
1969 | /* | 1955 | /* |
1970 | * Make a dabuf. | 1956 | * Convert a struct xfs_bmbt_irec to a struct xfs_buf_map. |
1971 | * Used for get_buf, read_buf, read_bufr, and reada_buf. | 1957 | * |
1958 | * For the single map case, it is assumed that the caller has provided a pointer | ||
1959 | * to a valid xfs_buf_map. For the multiple map case, this function will | ||
1960 | * allocate the xfs_buf_map to hold all the maps and replace the caller's single | ||
1961 | * map pointer with the allocated map. | ||
1972 | */ | 1962 | */ |
1973 | STATIC int | 1963 | static int |
1974 | xfs_da_do_buf( | 1964 | xfs_buf_map_from_irec( |
1975 | xfs_trans_t *trans, | 1965 | struct xfs_mount *mp, |
1976 | xfs_inode_t *dp, | 1966 | struct xfs_buf_map **mapp, |
1977 | xfs_dablk_t bno, | 1967 | unsigned int *nmaps, |
1978 | xfs_daddr_t *mappedbnop, | 1968 | struct xfs_bmbt_irec *irecs, |
1979 | xfs_dabuf_t **bpp, | 1969 | unsigned int nirecs) |
1980 | int whichfork, | ||
1981 | int caller) | ||
1982 | { | 1970 | { |
1983 | xfs_buf_t *bp = NULL; | 1971 | struct xfs_buf_map *map; |
1984 | xfs_buf_t **bplist; | 1972 | int i; |
1985 | int error=0; | 1973 | |
1986 | int i; | 1974 | ASSERT(*nmaps == 1); |
1987 | xfs_bmbt_irec_t map; | 1975 | ASSERT(nirecs >= 1); |
1988 | xfs_bmbt_irec_t *mapp; | 1976 | |
1989 | xfs_daddr_t mappedbno; | 1977 | if (nirecs > 1) { |
1990 | xfs_mount_t *mp; | 1978 | map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map), KM_SLEEP); |
1991 | int nbplist=0; | 1979 | if (!map) |
1992 | int nfsb; | 1980 | return ENOMEM; |
1993 | int nmap; | 1981 | *mapp = map; |
1994 | xfs_dabuf_t *rbp; | 1982 | } |
1983 | |||
1984 | *nmaps = nirecs; | ||
1985 | map = *mapp; | ||
1986 | for (i = 0; i < *nmaps; i++) { | ||
1987 | ASSERT(irecs[i].br_startblock != DELAYSTARTBLOCK && | ||
1988 | irecs[i].br_startblock != HOLESTARTBLOCK); | ||
1989 | map[i].bm_bn = XFS_FSB_TO_DADDR(mp, irecs[i].br_startblock); | ||
1990 | map[i].bm_len = XFS_FSB_TO_BB(mp, irecs[i].br_blockcount); | ||
1991 | } | ||
1992 | return 0; | ||
1993 | } | ||
1994 | |||
1995 | /* | ||
1996 | * Map the block we are given ready for reading. There are three possible return | ||
1997 | * values: | ||
1998 | * -1 - will be returned if we land in a hole and mappedbno == -2 so the | ||
1999 | * caller knows not to execute a subsequent read. | ||
2000 | * 0 - if we mapped the block successfully | ||
2001 | * >0 - positive error number if there was an error. | ||
2002 | */ | ||
2003 | static int | ||
2004 | xfs_dabuf_map( | ||
2005 | struct xfs_trans *trans, | ||
2006 | struct xfs_inode *dp, | ||
2007 | xfs_dablk_t bno, | ||
2008 | xfs_daddr_t mappedbno, | ||
2009 | int whichfork, | ||
2010 | struct xfs_buf_map **map, | ||
2011 | int *nmaps) | ||
2012 | { | ||
2013 | struct xfs_mount *mp = dp->i_mount; | ||
2014 | int nfsb; | ||
2015 | int error = 0; | ||
2016 | struct xfs_bmbt_irec irec; | ||
2017 | struct xfs_bmbt_irec *irecs = &irec; | ||
2018 | int nirecs; | ||
2019 | |||
2020 | ASSERT(map && *map); | ||
2021 | ASSERT(*nmaps == 1); | ||
1995 | 2022 | ||
1996 | mp = dp->i_mount; | ||
1997 | nfsb = (whichfork == XFS_DATA_FORK) ? mp->m_dirblkfsbs : 1; | 2023 | nfsb = (whichfork == XFS_DATA_FORK) ? mp->m_dirblkfsbs : 1; |
1998 | mappedbno = *mappedbnop; | 2024 | |
1999 | /* | 2025 | /* |
2000 | * Caller doesn't have a mapping. -2 means don't complain | 2026 | * Caller doesn't have a mapping. -2 means don't complain |
2001 | * if we land in a hole. | 2027 | * if we land in a hole. |
@@ -2004,112 +2030,150 @@ xfs_da_do_buf( | |||
2004 | /* | 2030 | /* |
2005 | * Optimize the one-block case. | 2031 | * Optimize the one-block case. |
2006 | */ | 2032 | */ |
2007 | if (nfsb == 1) | 2033 | if (nfsb != 1) |
2008 | mapp = ↦ | 2034 | irecs = kmem_zalloc(sizeof(irec) * nfsb, KM_SLEEP); |
2009 | else | ||
2010 | mapp = kmem_alloc(sizeof(*mapp) * nfsb, KM_SLEEP); | ||
2011 | 2035 | ||
2012 | nmap = nfsb; | 2036 | nirecs = nfsb; |
2013 | error = xfs_bmapi_read(dp, (xfs_fileoff_t)bno, nfsb, mapp, | 2037 | error = xfs_bmapi_read(dp, (xfs_fileoff_t)bno, nfsb, irecs, |
2014 | &nmap, xfs_bmapi_aflag(whichfork)); | 2038 | &nirecs, xfs_bmapi_aflag(whichfork)); |
2015 | if (error) | 2039 | if (error) |
2016 | goto exit0; | 2040 | goto out; |
2017 | } else { | 2041 | } else { |
2018 | map.br_startblock = XFS_DADDR_TO_FSB(mp, mappedbno); | 2042 | irecs->br_startblock = XFS_DADDR_TO_FSB(mp, mappedbno); |
2019 | map.br_startoff = (xfs_fileoff_t)bno; | 2043 | irecs->br_startoff = (xfs_fileoff_t)bno; |
2020 | map.br_blockcount = nfsb; | 2044 | irecs->br_blockcount = nfsb; |
2021 | mapp = ↦ | 2045 | irecs->br_state = 0; |
2022 | nmap = 1; | 2046 | nirecs = 1; |
2023 | } | 2047 | } |
2024 | if (!xfs_da_map_covers_blocks(nmap, mapp, bno, nfsb)) { | 2048 | |
2025 | error = mappedbno == -2 ? 0 : XFS_ERROR(EFSCORRUPTED); | 2049 | if (!xfs_da_map_covers_blocks(nirecs, irecs, bno, nfsb)) { |
2050 | error = mappedbno == -2 ? -1 : XFS_ERROR(EFSCORRUPTED); | ||
2026 | if (unlikely(error == EFSCORRUPTED)) { | 2051 | if (unlikely(error == EFSCORRUPTED)) { |
2027 | if (xfs_error_level >= XFS_ERRLEVEL_LOW) { | 2052 | if (xfs_error_level >= XFS_ERRLEVEL_LOW) { |
2053 | int i; | ||
2028 | xfs_alert(mp, "%s: bno %lld dir: inode %lld", | 2054 | xfs_alert(mp, "%s: bno %lld dir: inode %lld", |
2029 | __func__, (long long)bno, | 2055 | __func__, (long long)bno, |
2030 | (long long)dp->i_ino); | 2056 | (long long)dp->i_ino); |
2031 | for (i = 0; i < nmap; i++) { | 2057 | for (i = 0; i < *nmaps; i++) { |
2032 | xfs_alert(mp, | 2058 | xfs_alert(mp, |
2033 | "[%02d] br_startoff %lld br_startblock %lld br_blockcount %lld br_state %d", | 2059 | "[%02d] br_startoff %lld br_startblock %lld br_blockcount %lld br_state %d", |
2034 | i, | 2060 | i, |
2035 | (long long)mapp[i].br_startoff, | 2061 | (long long)irecs[i].br_startoff, |
2036 | (long long)mapp[i].br_startblock, | 2062 | (long long)irecs[i].br_startblock, |
2037 | (long long)mapp[i].br_blockcount, | 2063 | (long long)irecs[i].br_blockcount, |
2038 | mapp[i].br_state); | 2064 | irecs[i].br_state); |
2039 | } | 2065 | } |
2040 | } | 2066 | } |
2041 | XFS_ERROR_REPORT("xfs_da_do_buf(1)", | 2067 | XFS_ERROR_REPORT("xfs_da_do_buf(1)", |
2042 | XFS_ERRLEVEL_LOW, mp); | 2068 | XFS_ERRLEVEL_LOW, mp); |
2043 | } | 2069 | } |
2044 | goto exit0; | 2070 | goto out; |
2045 | } | 2071 | } |
2046 | if (caller != 3 && nmap > 1) { | 2072 | error = xfs_buf_map_from_irec(mp, map, nmaps, irecs, nirecs); |
2047 | bplist = kmem_alloc(sizeof(*bplist) * nmap, KM_SLEEP); | 2073 | out: |
2048 | nbplist = 0; | 2074 | if (irecs != &irec) |
2049 | } else | 2075 | kmem_free(irecs); |
2050 | bplist = NULL; | 2076 | return error; |
2051 | /* | 2077 | } |
2052 | * Turn the mapping(s) into buffer(s). | 2078 | |
2053 | */ | 2079 | /* |
2054 | for (i = 0; i < nmap; i++) { | 2080 | * Get a buffer for the dir/attr block. |
2055 | int nmapped; | 2081 | */ |
2056 | 2082 | int | |
2057 | mappedbno = XFS_FSB_TO_DADDR(mp, mapp[i].br_startblock); | 2083 | xfs_da_get_buf( |
2058 | if (i == 0) | 2084 | struct xfs_trans *trans, |
2059 | *mappedbnop = mappedbno; | 2085 | struct xfs_inode *dp, |
2060 | nmapped = (int)XFS_FSB_TO_BB(mp, mapp[i].br_blockcount); | 2086 | xfs_dablk_t bno, |
2061 | switch (caller) { | 2087 | xfs_daddr_t mappedbno, |
2062 | case 0: | 2088 | struct xfs_buf **bpp, |
2063 | bp = xfs_trans_get_buf(trans, mp->m_ddev_targp, | 2089 | int whichfork) |
2064 | mappedbno, nmapped, 0); | 2090 | { |
2065 | error = bp ? bp->b_error : XFS_ERROR(EIO); | 2091 | struct xfs_buf *bp; |
2066 | break; | 2092 | struct xfs_buf_map map; |
2067 | case 1: | 2093 | struct xfs_buf_map *mapp; |
2068 | case 2: | 2094 | int nmap; |
2069 | bp = NULL; | 2095 | int error; |
2070 | error = xfs_trans_read_buf(mp, trans, mp->m_ddev_targp, | 2096 | |
2071 | mappedbno, nmapped, 0, &bp); | 2097 | *bpp = NULL; |
2072 | break; | 2098 | mapp = ↦ |
2073 | case 3: | 2099 | nmap = 1; |
2074 | xfs_buf_readahead(mp->m_ddev_targp, mappedbno, nmapped); | 2100 | error = xfs_dabuf_map(trans, dp, bno, mappedbno, whichfork, |
2101 | &mapp, &nmap); | ||
2102 | if (error) { | ||
2103 | /* mapping a hole is not an error, but we don't continue */ | ||
2104 | if (error == -1) | ||
2075 | error = 0; | 2105 | error = 0; |
2076 | bp = NULL; | 2106 | goto out_free; |
2077 | break; | ||
2078 | } | ||
2079 | if (error) { | ||
2080 | if (bp) | ||
2081 | xfs_trans_brelse(trans, bp); | ||
2082 | goto exit1; | ||
2083 | } | ||
2084 | if (!bp) | ||
2085 | continue; | ||
2086 | if (caller == 1) { | ||
2087 | if (whichfork == XFS_ATTR_FORK) | ||
2088 | xfs_buf_set_ref(bp, XFS_ATTR_BTREE_REF); | ||
2089 | else | ||
2090 | xfs_buf_set_ref(bp, XFS_DIR_BTREE_REF); | ||
2091 | } | ||
2092 | if (bplist) { | ||
2093 | bplist[nbplist++] = bp; | ||
2094 | } | ||
2095 | } | 2107 | } |
2096 | /* | 2108 | |
2097 | * Build a dabuf structure. | 2109 | bp = xfs_trans_get_buf_map(trans, dp->i_mount->m_ddev_targp, |
2098 | */ | 2110 | mapp, nmap, 0); |
2099 | if (bplist) { | 2111 | error = bp ? bp->b_error : XFS_ERROR(EIO); |
2100 | rbp = xfs_da_buf_make(nbplist, bplist); | 2112 | if (error) { |
2101 | } else if (bp) | 2113 | xfs_trans_brelse(trans, bp); |
2102 | rbp = xfs_da_buf_make(1, &bp); | 2114 | goto out_free; |
2115 | } | ||
2116 | |||
2117 | *bpp = bp; | ||
2118 | |||
2119 | out_free: | ||
2120 | if (mapp != &map) | ||
2121 | kmem_free(mapp); | ||
2122 | |||
2123 | return error; | ||
2124 | } | ||
2125 | |||
2126 | /* | ||
2127 | * Get a buffer for the dir/attr block, fill in the contents. | ||
2128 | */ | ||
2129 | int | ||
2130 | xfs_da_read_buf( | ||
2131 | struct xfs_trans *trans, | ||
2132 | struct xfs_inode *dp, | ||
2133 | xfs_dablk_t bno, | ||
2134 | xfs_daddr_t mappedbno, | ||
2135 | struct xfs_buf **bpp, | ||
2136 | int whichfork) | ||
2137 | { | ||
2138 | struct xfs_buf *bp; | ||
2139 | struct xfs_buf_map map; | ||
2140 | struct xfs_buf_map *mapp; | ||
2141 | int nmap; | ||
2142 | int error; | ||
2143 | |||
2144 | *bpp = NULL; | ||
2145 | mapp = ↦ | ||
2146 | nmap = 1; | ||
2147 | error = xfs_dabuf_map(trans, dp, bno, mappedbno, whichfork, | ||
2148 | &mapp, &nmap); | ||
2149 | if (error) { | ||
2150 | /* mapping a hole is not an error, but we don't continue */ | ||
2151 | if (error == -1) | ||
2152 | error = 0; | ||
2153 | goto out_free; | ||
2154 | } | ||
2155 | |||
2156 | error = xfs_trans_read_buf_map(dp->i_mount, trans, | ||
2157 | dp->i_mount->m_ddev_targp, | ||
2158 | mapp, nmap, 0, &bp); | ||
2159 | if (error) | ||
2160 | goto out_free; | ||
2161 | |||
2162 | if (whichfork == XFS_ATTR_FORK) | ||
2163 | xfs_buf_set_ref(bp, XFS_ATTR_BTREE_REF); | ||
2103 | else | 2164 | else |
2104 | rbp = NULL; | 2165 | xfs_buf_set_ref(bp, XFS_DIR_BTREE_REF); |
2166 | |||
2105 | /* | 2167 | /* |
2106 | * For read_buf, check the magic number. | 2168 | * This verification code will be moved to a CRC verification callback |
2169 | * function so just leave it here unchanged until then. | ||
2107 | */ | 2170 | */ |
2108 | if (caller == 1) { | 2171 | { |
2109 | xfs_dir2_data_hdr_t *hdr = rbp->data; | 2172 | xfs_dir2_data_hdr_t *hdr = bp->b_addr; |
2110 | xfs_dir2_free_t *free = rbp->data; | 2173 | xfs_dir2_free_t *free = bp->b_addr; |
2111 | xfs_da_blkinfo_t *info = rbp->data; | 2174 | xfs_da_blkinfo_t *info = bp->b_addr; |
2112 | uint magic, magic1; | 2175 | uint magic, magic1; |
2176 | struct xfs_mount *mp = dp->i_mount; | ||
2113 | 2177 | ||
2114 | magic = be16_to_cpu(info->magic); | 2178 | magic = be16_to_cpu(info->magic); |
2115 | magic1 = be32_to_cpu(hdr->magic); | 2179 | magic1 = be32_to_cpu(hdr->magic); |
@@ -2123,66 +2187,20 @@ xfs_da_do_buf( | |||
2123 | (free->hdr.magic != cpu_to_be32(XFS_DIR2_FREE_MAGIC)), | 2187 | (free->hdr.magic != cpu_to_be32(XFS_DIR2_FREE_MAGIC)), |
2124 | mp, XFS_ERRTAG_DA_READ_BUF, | 2188 | mp, XFS_ERRTAG_DA_READ_BUF, |
2125 | XFS_RANDOM_DA_READ_BUF))) { | 2189 | XFS_RANDOM_DA_READ_BUF))) { |
2126 | trace_xfs_da_btree_corrupt(rbp->bps[0], _RET_IP_); | 2190 | trace_xfs_da_btree_corrupt(bp, _RET_IP_); |
2127 | XFS_CORRUPTION_ERROR("xfs_da_do_buf(2)", | 2191 | XFS_CORRUPTION_ERROR("xfs_da_do_buf(2)", |
2128 | XFS_ERRLEVEL_LOW, mp, info); | 2192 | XFS_ERRLEVEL_LOW, mp, info); |
2129 | error = XFS_ERROR(EFSCORRUPTED); | 2193 | error = XFS_ERROR(EFSCORRUPTED); |
2130 | xfs_da_brelse(trans, rbp); | 2194 | xfs_trans_brelse(trans, bp); |
2131 | nbplist = 0; | 2195 | goto out_free; |
2132 | goto exit1; | ||
2133 | } | 2196 | } |
2134 | } | 2197 | } |
2135 | if (bplist) { | 2198 | *bpp = bp; |
2136 | kmem_free(bplist); | 2199 | out_free: |
2137 | } | ||
2138 | if (mapp != &map) { | ||
2139 | kmem_free(mapp); | ||
2140 | } | ||
2141 | if (bpp) | ||
2142 | *bpp = rbp; | ||
2143 | return 0; | ||
2144 | exit1: | ||
2145 | if (bplist) { | ||
2146 | for (i = 0; i < nbplist; i++) | ||
2147 | xfs_trans_brelse(trans, bplist[i]); | ||
2148 | kmem_free(bplist); | ||
2149 | } | ||
2150 | exit0: | ||
2151 | if (mapp != &map) | 2200 | if (mapp != &map) |
2152 | kmem_free(mapp); | 2201 | kmem_free(mapp); |
2153 | if (bpp) | ||
2154 | *bpp = NULL; | ||
2155 | return error; | ||
2156 | } | ||
2157 | |||
2158 | /* | ||
2159 | * Get a buffer for the dir/attr block. | ||
2160 | */ | ||
2161 | int | ||
2162 | xfs_da_get_buf( | ||
2163 | xfs_trans_t *trans, | ||
2164 | xfs_inode_t *dp, | ||
2165 | xfs_dablk_t bno, | ||
2166 | xfs_daddr_t mappedbno, | ||
2167 | xfs_dabuf_t **bpp, | ||
2168 | int whichfork) | ||
2169 | { | ||
2170 | return xfs_da_do_buf(trans, dp, bno, &mappedbno, bpp, whichfork, 0); | ||
2171 | } | ||
2172 | 2202 | ||
2173 | /* | 2203 | return error; |
2174 | * Get a buffer for the dir/attr block, fill in the contents. | ||
2175 | */ | ||
2176 | int | ||
2177 | xfs_da_read_buf( | ||
2178 | xfs_trans_t *trans, | ||
2179 | xfs_inode_t *dp, | ||
2180 | xfs_dablk_t bno, | ||
2181 | xfs_daddr_t mappedbno, | ||
2182 | xfs_dabuf_t **bpp, | ||
2183 | int whichfork) | ||
2184 | { | ||
2185 | return xfs_da_do_buf(trans, dp, bno, &mappedbno, bpp, whichfork, 1); | ||
2186 | } | 2204 | } |
2187 | 2205 | ||
2188 | /* | 2206 | /* |
@@ -2190,22 +2208,41 @@ xfs_da_read_buf( | |||
2190 | */ | 2208 | */ |
2191 | xfs_daddr_t | 2209 | xfs_daddr_t |
2192 | xfs_da_reada_buf( | 2210 | xfs_da_reada_buf( |
2193 | xfs_trans_t *trans, | 2211 | struct xfs_trans *trans, |
2194 | xfs_inode_t *dp, | 2212 | struct xfs_inode *dp, |
2195 | xfs_dablk_t bno, | 2213 | xfs_dablk_t bno, |
2196 | int whichfork) | 2214 | int whichfork) |
2197 | { | 2215 | { |
2198 | xfs_daddr_t rval; | 2216 | xfs_daddr_t mappedbno = -1; |
2217 | struct xfs_buf_map map; | ||
2218 | struct xfs_buf_map *mapp; | ||
2219 | int nmap; | ||
2220 | int error; | ||
2221 | |||
2222 | mapp = ↦ | ||
2223 | nmap = 1; | ||
2224 | error = xfs_dabuf_map(trans, dp, bno, -1, whichfork, | ||
2225 | &mapp, &nmap); | ||
2226 | if (error) { | ||
2227 | /* mapping a hole is not an error, but we don't continue */ | ||
2228 | if (error == -1) | ||
2229 | error = 0; | ||
2230 | goto out_free; | ||
2231 | } | ||
2199 | 2232 | ||
2200 | rval = -1; | 2233 | mappedbno = mapp[0].bm_bn; |
2201 | if (xfs_da_do_buf(trans, dp, bno, &rval, NULL, whichfork, 3)) | 2234 | xfs_buf_readahead_map(dp->i_mount->m_ddev_targp, mapp, nmap); |
2235 | |||
2236 | out_free: | ||
2237 | if (mapp != &map) | ||
2238 | kmem_free(mapp); | ||
2239 | |||
2240 | if (error) | ||
2202 | return -1; | 2241 | return -1; |
2203 | else | 2242 | return mappedbno; |
2204 | return rval; | ||
2205 | } | 2243 | } |
2206 | 2244 | ||
2207 | kmem_zone_t *xfs_da_state_zone; /* anchor for state struct zone */ | 2245 | kmem_zone_t *xfs_da_state_zone; /* anchor for state struct zone */ |
2208 | kmem_zone_t *xfs_dabuf_zone; /* dabuf zone */ | ||
2209 | 2246 | ||
2210 | /* | 2247 | /* |
2211 | * Allocate a dir-state structure. | 2248 | * Allocate a dir-state structure. |
@@ -2225,13 +2262,8 @@ xfs_da_state_kill_altpath(xfs_da_state_t *state) | |||
2225 | { | 2262 | { |
2226 | int i; | 2263 | int i; |
2227 | 2264 | ||
2228 | for (i = 0; i < state->altpath.active; i++) { | 2265 | for (i = 0; i < state->altpath.active; i++) |
2229 | if (state->altpath.blk[i].bp) { | 2266 | state->altpath.blk[i].bp = NULL; |
2230 | if (state->altpath.blk[i].bp != state->path.blk[i].bp) | ||
2231 | xfs_da_buf_done(state->altpath.blk[i].bp); | ||
2232 | state->altpath.blk[i].bp = NULL; | ||
2233 | } | ||
2234 | } | ||
2235 | state->altpath.active = 0; | 2267 | state->altpath.active = 0; |
2236 | } | 2268 | } |
2237 | 2269 | ||
@@ -2241,204 +2273,9 @@ xfs_da_state_kill_altpath(xfs_da_state_t *state) | |||
2241 | void | 2273 | void |
2242 | xfs_da_state_free(xfs_da_state_t *state) | 2274 | xfs_da_state_free(xfs_da_state_t *state) |
2243 | { | 2275 | { |
2244 | int i; | ||
2245 | |||
2246 | xfs_da_state_kill_altpath(state); | 2276 | xfs_da_state_kill_altpath(state); |
2247 | for (i = 0; i < state->path.active; i++) { | ||
2248 | if (state->path.blk[i].bp) | ||
2249 | xfs_da_buf_done(state->path.blk[i].bp); | ||
2250 | } | ||
2251 | if (state->extravalid && state->extrablk.bp) | ||
2252 | xfs_da_buf_done(state->extrablk.bp); | ||
2253 | #ifdef DEBUG | 2277 | #ifdef DEBUG |
2254 | memset((char *)state, 0, sizeof(*state)); | 2278 | memset((char *)state, 0, sizeof(*state)); |
2255 | #endif /* DEBUG */ | 2279 | #endif /* DEBUG */ |
2256 | kmem_zone_free(xfs_da_state_zone, state); | 2280 | kmem_zone_free(xfs_da_state_zone, state); |
2257 | } | 2281 | } |
2258 | |||
2259 | /* | ||
2260 | * Create a dabuf. | ||
2261 | */ | ||
2262 | /* ARGSUSED */ | ||
2263 | STATIC xfs_dabuf_t * | ||
2264 | xfs_da_buf_make(int nbuf, xfs_buf_t **bps) | ||
2265 | { | ||
2266 | xfs_buf_t *bp; | ||
2267 | xfs_dabuf_t *dabuf; | ||
2268 | int i; | ||
2269 | int off; | ||
2270 | |||
2271 | if (nbuf == 1) | ||
2272 | dabuf = kmem_zone_alloc(xfs_dabuf_zone, KM_NOFS); | ||
2273 | else | ||
2274 | dabuf = kmem_alloc(XFS_DA_BUF_SIZE(nbuf), KM_NOFS); | ||
2275 | dabuf->dirty = 0; | ||
2276 | if (nbuf == 1) { | ||
2277 | dabuf->nbuf = 1; | ||
2278 | bp = bps[0]; | ||
2279 | dabuf->bbcount = bp->b_length; | ||
2280 | dabuf->data = bp->b_addr; | ||
2281 | dabuf->bps[0] = bp; | ||
2282 | } else { | ||
2283 | dabuf->nbuf = nbuf; | ||
2284 | for (i = 0, dabuf->bbcount = 0; i < nbuf; i++) { | ||
2285 | dabuf->bps[i] = bp = bps[i]; | ||
2286 | dabuf->bbcount += bp->b_length; | ||
2287 | } | ||
2288 | dabuf->data = kmem_alloc(BBTOB(dabuf->bbcount), KM_SLEEP); | ||
2289 | for (i = off = 0; i < nbuf; i++, off += BBTOB(bp->b_length)) { | ||
2290 | bp = bps[i]; | ||
2291 | memcpy((char *)dabuf->data + off, bp->b_addr, | ||
2292 | BBTOB(bp->b_length)); | ||
2293 | } | ||
2294 | } | ||
2295 | return dabuf; | ||
2296 | } | ||
2297 | |||
2298 | /* | ||
2299 | * Un-dirty a dabuf. | ||
2300 | */ | ||
2301 | STATIC void | ||
2302 | xfs_da_buf_clean(xfs_dabuf_t *dabuf) | ||
2303 | { | ||
2304 | xfs_buf_t *bp; | ||
2305 | int i; | ||
2306 | int off; | ||
2307 | |||
2308 | if (dabuf->dirty) { | ||
2309 | ASSERT(dabuf->nbuf > 1); | ||
2310 | dabuf->dirty = 0; | ||
2311 | for (i = off = 0; i < dabuf->nbuf; | ||
2312 | i++, off += BBTOB(bp->b_length)) { | ||
2313 | bp = dabuf->bps[i]; | ||
2314 | memcpy(bp->b_addr, dabuf->data + off, | ||
2315 | BBTOB(bp->b_length)); | ||
2316 | } | ||
2317 | } | ||
2318 | } | ||
2319 | |||
2320 | /* | ||
2321 | * Release a dabuf. | ||
2322 | */ | ||
2323 | void | ||
2324 | xfs_da_buf_done(xfs_dabuf_t *dabuf) | ||
2325 | { | ||
2326 | ASSERT(dabuf); | ||
2327 | ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]); | ||
2328 | if (dabuf->dirty) | ||
2329 | xfs_da_buf_clean(dabuf); | ||
2330 | if (dabuf->nbuf > 1) { | ||
2331 | kmem_free(dabuf->data); | ||
2332 | kmem_free(dabuf); | ||
2333 | } else { | ||
2334 | kmem_zone_free(xfs_dabuf_zone, dabuf); | ||
2335 | } | ||
2336 | } | ||
2337 | |||
2338 | /* | ||
2339 | * Log transaction from a dabuf. | ||
2340 | */ | ||
2341 | void | ||
2342 | xfs_da_log_buf(xfs_trans_t *tp, xfs_dabuf_t *dabuf, uint first, uint last) | ||
2343 | { | ||
2344 | xfs_buf_t *bp; | ||
2345 | uint f; | ||
2346 | int i; | ||
2347 | uint l; | ||
2348 | int off; | ||
2349 | |||
2350 | ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]); | ||
2351 | if (dabuf->nbuf == 1) { | ||
2352 | ASSERT(dabuf->data == dabuf->bps[0]->b_addr); | ||
2353 | xfs_trans_log_buf(tp, dabuf->bps[0], first, last); | ||
2354 | return; | ||
2355 | } | ||
2356 | dabuf->dirty = 1; | ||
2357 | ASSERT(first <= last); | ||
2358 | for (i = off = 0; i < dabuf->nbuf; i++, off += BBTOB(bp->b_length)) { | ||
2359 | bp = dabuf->bps[i]; | ||
2360 | f = off; | ||
2361 | l = f + BBTOB(bp->b_length) - 1; | ||
2362 | if (f < first) | ||
2363 | f = first; | ||
2364 | if (l > last) | ||
2365 | l = last; | ||
2366 | if (f <= l) | ||
2367 | xfs_trans_log_buf(tp, bp, f - off, l - off); | ||
2368 | /* | ||
2369 | * B_DONE is set by xfs_trans_log buf. | ||
2370 | * If we don't set it on a new buffer (get not read) | ||
2371 | * then if we don't put anything in the buffer it won't | ||
2372 | * be set, and at commit it it released into the cache, | ||
2373 | * and then a read will fail. | ||
2374 | */ | ||
2375 | else if (!(XFS_BUF_ISDONE(bp))) | ||
2376 | XFS_BUF_DONE(bp); | ||
2377 | } | ||
2378 | ASSERT(last < off); | ||
2379 | } | ||
2380 | |||
2381 | /* | ||
2382 | * Release dabuf from a transaction. | ||
2383 | * Have to free up the dabuf before the buffers are released, | ||
2384 | * since the synchronization on the dabuf is really the lock on the buffer. | ||
2385 | */ | ||
2386 | void | ||
2387 | xfs_da_brelse(xfs_trans_t *tp, xfs_dabuf_t *dabuf) | ||
2388 | { | ||
2389 | xfs_buf_t *bp; | ||
2390 | xfs_buf_t **bplist; | ||
2391 | int i; | ||
2392 | int nbuf; | ||
2393 | |||
2394 | ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]); | ||
2395 | if ((nbuf = dabuf->nbuf) == 1) { | ||
2396 | bplist = &bp; | ||
2397 | bp = dabuf->bps[0]; | ||
2398 | } else { | ||
2399 | bplist = kmem_alloc(nbuf * sizeof(*bplist), KM_SLEEP); | ||
2400 | memcpy(bplist, dabuf->bps, nbuf * sizeof(*bplist)); | ||
2401 | } | ||
2402 | xfs_da_buf_done(dabuf); | ||
2403 | for (i = 0; i < nbuf; i++) | ||
2404 | xfs_trans_brelse(tp, bplist[i]); | ||
2405 | if (bplist != &bp) | ||
2406 | kmem_free(bplist); | ||
2407 | } | ||
2408 | |||
2409 | /* | ||
2410 | * Invalidate dabuf from a transaction. | ||
2411 | */ | ||
2412 | void | ||
2413 | xfs_da_binval(xfs_trans_t *tp, xfs_dabuf_t *dabuf) | ||
2414 | { | ||
2415 | xfs_buf_t *bp; | ||
2416 | xfs_buf_t **bplist; | ||
2417 | int i; | ||
2418 | int nbuf; | ||
2419 | |||
2420 | ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]); | ||
2421 | if ((nbuf = dabuf->nbuf) == 1) { | ||
2422 | bplist = &bp; | ||
2423 | bp = dabuf->bps[0]; | ||
2424 | } else { | ||
2425 | bplist = kmem_alloc(nbuf * sizeof(*bplist), KM_SLEEP); | ||
2426 | memcpy(bplist, dabuf->bps, nbuf * sizeof(*bplist)); | ||
2427 | } | ||
2428 | xfs_da_buf_done(dabuf); | ||
2429 | for (i = 0; i < nbuf; i++) | ||
2430 | xfs_trans_binval(tp, bplist[i]); | ||
2431 | if (bplist != &bp) | ||
2432 | kmem_free(bplist); | ||
2433 | } | ||
2434 | |||
2435 | /* | ||
2436 | * Get the first daddr from a dabuf. | ||
2437 | */ | ||
2438 | xfs_daddr_t | ||
2439 | xfs_da_blkno(xfs_dabuf_t *dabuf) | ||
2440 | { | ||
2441 | ASSERT(dabuf->nbuf); | ||
2442 | ASSERT(dabuf->data); | ||
2443 | return XFS_BUF_ADDR(dabuf->bps[0]); | ||
2444 | } | ||
diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h index dbf7c074ae73..132adafb041e 100644 --- a/fs/xfs/xfs_da_btree.h +++ b/fs/xfs/xfs_da_btree.h | |||
@@ -32,7 +32,7 @@ struct zone; | |||
32 | /* | 32 | /* |
33 | * This structure is common to both leaf nodes and non-leaf nodes in the Btree. | 33 | * This structure is common to both leaf nodes and non-leaf nodes in the Btree. |
34 | * | 34 | * |
35 | * Is is used to manage a doubly linked list of all blocks at the same | 35 | * It is used to manage a doubly linked list of all blocks at the same |
36 | * level in the Btree, and to identify which type of block this is. | 36 | * level in the Btree, and to identify which type of block this is. |
37 | */ | 37 | */ |
38 | #define XFS_DA_NODE_MAGIC 0xfebe /* magic number: non-leaf blocks */ | 38 | #define XFS_DA_NODE_MAGIC 0xfebe /* magic number: non-leaf blocks */ |
@@ -133,24 +133,6 @@ typedef struct xfs_da_args { | |||
133 | { XFS_DA_OP_CILOOKUP, "CILOOKUP" } | 133 | { XFS_DA_OP_CILOOKUP, "CILOOKUP" } |
134 | 134 | ||
135 | /* | 135 | /* |
136 | * Structure to describe buffer(s) for a block. | ||
137 | * This is needed in the directory version 2 format case, when | ||
138 | * multiple non-contiguous fsblocks might be needed to cover one | ||
139 | * logical directory block. | ||
140 | * If the buffer count is 1 then the data pointer points to the | ||
141 | * same place as the b_addr field for the buffer, else to kmem_alloced memory. | ||
142 | */ | ||
143 | typedef struct xfs_dabuf { | ||
144 | int nbuf; /* number of buffer pointers present */ | ||
145 | short dirty; /* data needs to be copied back */ | ||
146 | short bbcount; /* how large is data in bbs */ | ||
147 | void *data; /* pointer for buffers' data */ | ||
148 | struct xfs_buf *bps[1]; /* actually nbuf of these */ | ||
149 | } xfs_dabuf_t; | ||
150 | #define XFS_DA_BUF_SIZE(n) \ | ||
151 | (sizeof(xfs_dabuf_t) + sizeof(struct xfs_buf *) * ((n) - 1)) | ||
152 | |||
153 | /* | ||
154 | * Storage for holding state during Btree searches and split/join ops. | 136 | * Storage for holding state during Btree searches and split/join ops. |
155 | * | 137 | * |
156 | * Only need space for 5 intermediate nodes. With a minimum of 62-way | 138 | * Only need space for 5 intermediate nodes. With a minimum of 62-way |
@@ -158,7 +140,7 @@ typedef struct xfs_dabuf { | |||
158 | * which is slightly more than enough. | 140 | * which is slightly more than enough. |
159 | */ | 141 | */ |
160 | typedef struct xfs_da_state_blk { | 142 | typedef struct xfs_da_state_blk { |
161 | xfs_dabuf_t *bp; /* buffer containing block */ | 143 | struct xfs_buf *bp; /* buffer containing block */ |
162 | xfs_dablk_t blkno; /* filesystem blkno of buffer */ | 144 | xfs_dablk_t blkno; /* filesystem blkno of buffer */ |
163 | xfs_daddr_t disk_blkno; /* on-disk blkno (in BBs) of buffer */ | 145 | xfs_daddr_t disk_blkno; /* on-disk blkno (in BBs) of buffer */ |
164 | int index; /* relevant index into block */ | 146 | int index; /* relevant index into block */ |
@@ -211,7 +193,7 @@ struct xfs_nameops { | |||
211 | * Routines used for growing the Btree. | 193 | * Routines used for growing the Btree. |
212 | */ | 194 | */ |
213 | int xfs_da_node_create(xfs_da_args_t *args, xfs_dablk_t blkno, int level, | 195 | int xfs_da_node_create(xfs_da_args_t *args, xfs_dablk_t blkno, int level, |
214 | xfs_dabuf_t **bpp, int whichfork); | 196 | struct xfs_buf **bpp, int whichfork); |
215 | int xfs_da_split(xfs_da_state_t *state); | 197 | int xfs_da_split(xfs_da_state_t *state); |
216 | 198 | ||
217 | /* | 199 | /* |
@@ -241,14 +223,14 @@ int xfs_da_grow_inode_int(struct xfs_da_args *args, xfs_fileoff_t *bno, | |||
241 | int count); | 223 | int count); |
242 | int xfs_da_get_buf(struct xfs_trans *trans, struct xfs_inode *dp, | 224 | int xfs_da_get_buf(struct xfs_trans *trans, struct xfs_inode *dp, |
243 | xfs_dablk_t bno, xfs_daddr_t mappedbno, | 225 | xfs_dablk_t bno, xfs_daddr_t mappedbno, |
244 | xfs_dabuf_t **bp, int whichfork); | 226 | struct xfs_buf **bp, int whichfork); |
245 | int xfs_da_read_buf(struct xfs_trans *trans, struct xfs_inode *dp, | 227 | int xfs_da_read_buf(struct xfs_trans *trans, struct xfs_inode *dp, |
246 | xfs_dablk_t bno, xfs_daddr_t mappedbno, | 228 | xfs_dablk_t bno, xfs_daddr_t mappedbno, |
247 | xfs_dabuf_t **bpp, int whichfork); | 229 | struct xfs_buf **bpp, int whichfork); |
248 | xfs_daddr_t xfs_da_reada_buf(struct xfs_trans *trans, struct xfs_inode *dp, | 230 | xfs_daddr_t xfs_da_reada_buf(struct xfs_trans *trans, struct xfs_inode *dp, |
249 | xfs_dablk_t bno, int whichfork); | 231 | xfs_dablk_t bno, int whichfork); |
250 | int xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, | 232 | int xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, |
251 | xfs_dabuf_t *dead_buf); | 233 | struct xfs_buf *dead_buf); |
252 | 234 | ||
253 | uint xfs_da_hashname(const __uint8_t *name_string, int name_length); | 235 | uint xfs_da_hashname(const __uint8_t *name_string, int name_length); |
254 | enum xfs_dacmp xfs_da_compname(struct xfs_da_args *args, | 236 | enum xfs_dacmp xfs_da_compname(struct xfs_da_args *args, |
@@ -258,15 +240,7 @@ enum xfs_dacmp xfs_da_compname(struct xfs_da_args *args, | |||
258 | xfs_da_state_t *xfs_da_state_alloc(void); | 240 | xfs_da_state_t *xfs_da_state_alloc(void); |
259 | void xfs_da_state_free(xfs_da_state_t *state); | 241 | void xfs_da_state_free(xfs_da_state_t *state); |
260 | 242 | ||
261 | void xfs_da_buf_done(xfs_dabuf_t *dabuf); | ||
262 | void xfs_da_log_buf(struct xfs_trans *tp, xfs_dabuf_t *dabuf, uint first, | ||
263 | uint last); | ||
264 | void xfs_da_brelse(struct xfs_trans *tp, xfs_dabuf_t *dabuf); | ||
265 | void xfs_da_binval(struct xfs_trans *tp, xfs_dabuf_t *dabuf); | ||
266 | xfs_daddr_t xfs_da_blkno(xfs_dabuf_t *dabuf); | ||
267 | |||
268 | extern struct kmem_zone *xfs_da_state_zone; | 243 | extern struct kmem_zone *xfs_da_state_zone; |
269 | extern struct kmem_zone *xfs_dabuf_zone; | ||
270 | extern const struct xfs_nameops xfs_default_nameops; | 244 | extern const struct xfs_nameops xfs_default_nameops; |
271 | 245 | ||
272 | #endif /* __XFS_DA_BTREE_H__ */ | 246 | #endif /* __XFS_DA_BTREE_H__ */ |
diff --git a/fs/xfs/xfs_dinode.h b/fs/xfs/xfs_dinode.h index a3721633abc8..1d9643b3dce6 100644 --- a/fs/xfs/xfs_dinode.h +++ b/fs/xfs/xfs_dinode.h | |||
@@ -33,7 +33,7 @@ typedef struct xfs_timestamp { | |||
33 | * variable size the leftover area split into a data and an attribute fork. | 33 | * variable size the leftover area split into a data and an attribute fork. |
34 | * The format of the data and attribute fork depends on the format of the | 34 | * The format of the data and attribute fork depends on the format of the |
35 | * inode as indicated by di_format and di_aformat. To access the data and | 35 | * inode as indicated by di_format and di_aformat. To access the data and |
36 | * attribute use the XFS_DFORK_PTR, XFS_DFORK_DPTR, and XFS_DFORK_PTR macros | 36 | * attribute use the XFS_DFORK_DPTR, XFS_DFORK_APTR, and XFS_DFORK_PTR macros |
37 | * below. | 37 | * below. |
38 | * | 38 | * |
39 | * There is a very similar struct icdinode in xfs_inode which matches the | 39 | * There is a very similar struct icdinode in xfs_inode which matches the |
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c index 67a250c36d41..b26a50f9921d 100644 --- a/fs/xfs/xfs_dir2.c +++ b/fs/xfs/xfs_dir2.c | |||
@@ -592,7 +592,7 @@ int | |||
592 | xfs_dir2_shrink_inode( | 592 | xfs_dir2_shrink_inode( |
593 | xfs_da_args_t *args, | 593 | xfs_da_args_t *args, |
594 | xfs_dir2_db_t db, | 594 | xfs_dir2_db_t db, |
595 | xfs_dabuf_t *bp) | 595 | struct xfs_buf *bp) |
596 | { | 596 | { |
597 | xfs_fileoff_t bno; /* directory file offset */ | 597 | xfs_fileoff_t bno; /* directory file offset */ |
598 | xfs_dablk_t da; /* directory file offset */ | 598 | xfs_dablk_t da; /* directory file offset */ |
@@ -634,7 +634,7 @@ xfs_dir2_shrink_inode( | |||
634 | /* | 634 | /* |
635 | * Invalidate the buffer from the transaction. | 635 | * Invalidate the buffer from the transaction. |
636 | */ | 636 | */ |
637 | xfs_da_binval(tp, bp); | 637 | xfs_trans_binval(tp, bp); |
638 | /* | 638 | /* |
639 | * If it's not a data block, we're done. | 639 | * If it's not a data block, we're done. |
640 | */ | 640 | */ |
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c index 586732f2d80d..e93ca8f054f4 100644 --- a/fs/xfs/xfs_dir2_block.c +++ b/fs/xfs/xfs_dir2_block.c | |||
@@ -37,10 +37,10 @@ | |||
37 | /* | 37 | /* |
38 | * Local function prototypes. | 38 | * Local function prototypes. |
39 | */ | 39 | */ |
40 | static void xfs_dir2_block_log_leaf(xfs_trans_t *tp, xfs_dabuf_t *bp, int first, | 40 | static void xfs_dir2_block_log_leaf(xfs_trans_t *tp, struct xfs_buf *bp, |
41 | int last); | 41 | int first, int last); |
42 | static void xfs_dir2_block_log_tail(xfs_trans_t *tp, xfs_dabuf_t *bp); | 42 | static void xfs_dir2_block_log_tail(xfs_trans_t *tp, struct xfs_buf *bp); |
43 | static int xfs_dir2_block_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **bpp, | 43 | static int xfs_dir2_block_lookup_int(xfs_da_args_t *args, struct xfs_buf **bpp, |
44 | int *entno); | 44 | int *entno); |
45 | static int xfs_dir2_block_sort(const void *a, const void *b); | 45 | static int xfs_dir2_block_sort(const void *a, const void *b); |
46 | 46 | ||
@@ -66,7 +66,7 @@ xfs_dir2_block_addname( | |||
66 | xfs_dir2_data_free_t *bf; /* bestfree table in block */ | 66 | xfs_dir2_data_free_t *bf; /* bestfree table in block */ |
67 | xfs_dir2_data_hdr_t *hdr; /* block header */ | 67 | xfs_dir2_data_hdr_t *hdr; /* block header */ |
68 | xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ | 68 | xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ |
69 | xfs_dabuf_t *bp; /* buffer for block */ | 69 | struct xfs_buf *bp; /* buffer for block */ |
70 | xfs_dir2_block_tail_t *btp; /* block tail */ | 70 | xfs_dir2_block_tail_t *btp; /* block tail */ |
71 | int compact; /* need to compact leaf ents */ | 71 | int compact; /* need to compact leaf ents */ |
72 | xfs_dir2_data_entry_t *dep; /* block data entry */ | 72 | xfs_dir2_data_entry_t *dep; /* block data entry */ |
@@ -102,14 +102,14 @@ xfs_dir2_block_addname( | |||
102 | return error; | 102 | return error; |
103 | } | 103 | } |
104 | ASSERT(bp != NULL); | 104 | ASSERT(bp != NULL); |
105 | hdr = bp->data; | 105 | hdr = bp->b_addr; |
106 | /* | 106 | /* |
107 | * Check the magic number, corrupted if wrong. | 107 | * Check the magic number, corrupted if wrong. |
108 | */ | 108 | */ |
109 | if (unlikely(hdr->magic != cpu_to_be32(XFS_DIR2_BLOCK_MAGIC))) { | 109 | if (unlikely(hdr->magic != cpu_to_be32(XFS_DIR2_BLOCK_MAGIC))) { |
110 | XFS_CORRUPTION_ERROR("xfs_dir2_block_addname", | 110 | XFS_CORRUPTION_ERROR("xfs_dir2_block_addname", |
111 | XFS_ERRLEVEL_LOW, mp, hdr); | 111 | XFS_ERRLEVEL_LOW, mp, hdr); |
112 | xfs_da_brelse(tp, bp); | 112 | xfs_trans_brelse(tp, bp); |
113 | return XFS_ERROR(EFSCORRUPTED); | 113 | return XFS_ERROR(EFSCORRUPTED); |
114 | } | 114 | } |
115 | len = xfs_dir2_data_entsize(args->namelen); | 115 | len = xfs_dir2_data_entsize(args->namelen); |
@@ -212,7 +212,7 @@ xfs_dir2_block_addname( | |||
212 | * If this isn't a real add, we're done with the buffer. | 212 | * If this isn't a real add, we're done with the buffer. |
213 | */ | 213 | */ |
214 | if (args->op_flags & XFS_DA_OP_JUSTCHECK) | 214 | if (args->op_flags & XFS_DA_OP_JUSTCHECK) |
215 | xfs_da_brelse(tp, bp); | 215 | xfs_trans_brelse(tp, bp); |
216 | /* | 216 | /* |
217 | * If we don't have space for the new entry & leaf ... | 217 | * If we don't have space for the new entry & leaf ... |
218 | */ | 218 | */ |
@@ -228,7 +228,6 @@ xfs_dir2_block_addname( | |||
228 | * Then add the new entry in that format. | 228 | * Then add the new entry in that format. |
229 | */ | 229 | */ |
230 | error = xfs_dir2_block_to_leaf(args, bp); | 230 | error = xfs_dir2_block_to_leaf(args, bp); |
231 | xfs_da_buf_done(bp); | ||
232 | if (error) | 231 | if (error) |
233 | return error; | 232 | return error; |
234 | return xfs_dir2_leaf_addname(args); | 233 | return xfs_dir2_leaf_addname(args); |
@@ -422,7 +421,6 @@ xfs_dir2_block_addname( | |||
422 | xfs_dir2_block_log_tail(tp, bp); | 421 | xfs_dir2_block_log_tail(tp, bp); |
423 | xfs_dir2_data_log_entry(tp, bp, dep); | 422 | xfs_dir2_data_log_entry(tp, bp, dep); |
424 | xfs_dir2_data_check(dp, bp); | 423 | xfs_dir2_data_check(dp, bp); |
425 | xfs_da_buf_done(bp); | ||
426 | return 0; | 424 | return 0; |
427 | } | 425 | } |
428 | 426 | ||
@@ -437,7 +435,7 @@ xfs_dir2_block_getdents( | |||
437 | filldir_t filldir) | 435 | filldir_t filldir) |
438 | { | 436 | { |
439 | xfs_dir2_data_hdr_t *hdr; /* block header */ | 437 | xfs_dir2_data_hdr_t *hdr; /* block header */ |
440 | xfs_dabuf_t *bp; /* buffer for block */ | 438 | struct xfs_buf *bp; /* buffer for block */ |
441 | xfs_dir2_block_tail_t *btp; /* block tail */ | 439 | xfs_dir2_block_tail_t *btp; /* block tail */ |
442 | xfs_dir2_data_entry_t *dep; /* block data entry */ | 440 | xfs_dir2_data_entry_t *dep; /* block data entry */ |
443 | xfs_dir2_data_unused_t *dup; /* block unused entry */ | 441 | xfs_dir2_data_unused_t *dup; /* block unused entry */ |
@@ -469,7 +467,7 @@ xfs_dir2_block_getdents( | |||
469 | * We'll skip entries before this. | 467 | * We'll skip entries before this. |
470 | */ | 468 | */ |
471 | wantoff = xfs_dir2_dataptr_to_off(mp, *offset); | 469 | wantoff = xfs_dir2_dataptr_to_off(mp, *offset); |
472 | hdr = bp->data; | 470 | hdr = bp->b_addr; |
473 | xfs_dir2_data_check(dp, bp); | 471 | xfs_dir2_data_check(dp, bp); |
474 | /* | 472 | /* |
475 | * Set up values for the loop. | 473 | * Set up values for the loop. |
@@ -514,7 +512,7 @@ xfs_dir2_block_getdents( | |||
514 | cook & 0x7fffffff, be64_to_cpu(dep->inumber), | 512 | cook & 0x7fffffff, be64_to_cpu(dep->inumber), |
515 | DT_UNKNOWN)) { | 513 | DT_UNKNOWN)) { |
516 | *offset = cook & 0x7fffffff; | 514 | *offset = cook & 0x7fffffff; |
517 | xfs_da_brelse(NULL, bp); | 515 | xfs_trans_brelse(NULL, bp); |
518 | return 0; | 516 | return 0; |
519 | } | 517 | } |
520 | } | 518 | } |
@@ -525,7 +523,7 @@ xfs_dir2_block_getdents( | |||
525 | */ | 523 | */ |
526 | *offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) & | 524 | *offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) & |
527 | 0x7fffffff; | 525 | 0x7fffffff; |
528 | xfs_da_brelse(NULL, bp); | 526 | xfs_trans_brelse(NULL, bp); |
529 | return 0; | 527 | return 0; |
530 | } | 528 | } |
531 | 529 | ||
@@ -535,17 +533,17 @@ xfs_dir2_block_getdents( | |||
535 | static void | 533 | static void |
536 | xfs_dir2_block_log_leaf( | 534 | xfs_dir2_block_log_leaf( |
537 | xfs_trans_t *tp, /* transaction structure */ | 535 | xfs_trans_t *tp, /* transaction structure */ |
538 | xfs_dabuf_t *bp, /* block buffer */ | 536 | struct xfs_buf *bp, /* block buffer */ |
539 | int first, /* index of first logged leaf */ | 537 | int first, /* index of first logged leaf */ |
540 | int last) /* index of last logged leaf */ | 538 | int last) /* index of last logged leaf */ |
541 | { | 539 | { |
542 | xfs_dir2_data_hdr_t *hdr = bp->data; | 540 | xfs_dir2_data_hdr_t *hdr = bp->b_addr; |
543 | xfs_dir2_leaf_entry_t *blp; | 541 | xfs_dir2_leaf_entry_t *blp; |
544 | xfs_dir2_block_tail_t *btp; | 542 | xfs_dir2_block_tail_t *btp; |
545 | 543 | ||
546 | btp = xfs_dir2_block_tail_p(tp->t_mountp, hdr); | 544 | btp = xfs_dir2_block_tail_p(tp->t_mountp, hdr); |
547 | blp = xfs_dir2_block_leaf_p(btp); | 545 | blp = xfs_dir2_block_leaf_p(btp); |
548 | xfs_da_log_buf(tp, bp, (uint)((char *)&blp[first] - (char *)hdr), | 546 | xfs_trans_log_buf(tp, bp, (uint)((char *)&blp[first] - (char *)hdr), |
549 | (uint)((char *)&blp[last + 1] - (char *)hdr - 1)); | 547 | (uint)((char *)&blp[last + 1] - (char *)hdr - 1)); |
550 | } | 548 | } |
551 | 549 | ||
@@ -555,13 +553,13 @@ xfs_dir2_block_log_leaf( | |||
555 | static void | 553 | static void |
556 | xfs_dir2_block_log_tail( | 554 | xfs_dir2_block_log_tail( |
557 | xfs_trans_t *tp, /* transaction structure */ | 555 | xfs_trans_t *tp, /* transaction structure */ |
558 | xfs_dabuf_t *bp) /* block buffer */ | 556 | struct xfs_buf *bp) /* block buffer */ |
559 | { | 557 | { |
560 | xfs_dir2_data_hdr_t *hdr = bp->data; | 558 | xfs_dir2_data_hdr_t *hdr = bp->b_addr; |
561 | xfs_dir2_block_tail_t *btp; | 559 | xfs_dir2_block_tail_t *btp; |
562 | 560 | ||
563 | btp = xfs_dir2_block_tail_p(tp->t_mountp, hdr); | 561 | btp = xfs_dir2_block_tail_p(tp->t_mountp, hdr); |
564 | xfs_da_log_buf(tp, bp, (uint)((char *)btp - (char *)hdr), | 562 | xfs_trans_log_buf(tp, bp, (uint)((char *)btp - (char *)hdr), |
565 | (uint)((char *)(btp + 1) - (char *)hdr - 1)); | 563 | (uint)((char *)(btp + 1) - (char *)hdr - 1)); |
566 | } | 564 | } |
567 | 565 | ||
@@ -575,7 +573,7 @@ xfs_dir2_block_lookup( | |||
575 | { | 573 | { |
576 | xfs_dir2_data_hdr_t *hdr; /* block header */ | 574 | xfs_dir2_data_hdr_t *hdr; /* block header */ |
577 | xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ | 575 | xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ |
578 | xfs_dabuf_t *bp; /* block buffer */ | 576 | struct xfs_buf *bp; /* block buffer */ |
579 | xfs_dir2_block_tail_t *btp; /* block tail */ | 577 | xfs_dir2_block_tail_t *btp; /* block tail */ |
580 | xfs_dir2_data_entry_t *dep; /* block data entry */ | 578 | xfs_dir2_data_entry_t *dep; /* block data entry */ |
581 | xfs_inode_t *dp; /* incore inode */ | 579 | xfs_inode_t *dp; /* incore inode */ |
@@ -593,7 +591,7 @@ xfs_dir2_block_lookup( | |||
593 | return error; | 591 | return error; |
594 | dp = args->dp; | 592 | dp = args->dp; |
595 | mp = dp->i_mount; | 593 | mp = dp->i_mount; |
596 | hdr = bp->data; | 594 | hdr = bp->b_addr; |
597 | xfs_dir2_data_check(dp, bp); | 595 | xfs_dir2_data_check(dp, bp); |
598 | btp = xfs_dir2_block_tail_p(mp, hdr); | 596 | btp = xfs_dir2_block_tail_p(mp, hdr); |
599 | blp = xfs_dir2_block_leaf_p(btp); | 597 | blp = xfs_dir2_block_leaf_p(btp); |
@@ -607,7 +605,7 @@ xfs_dir2_block_lookup( | |||
607 | */ | 605 | */ |
608 | args->inumber = be64_to_cpu(dep->inumber); | 606 | args->inumber = be64_to_cpu(dep->inumber); |
609 | error = xfs_dir_cilookup_result(args, dep->name, dep->namelen); | 607 | error = xfs_dir_cilookup_result(args, dep->name, dep->namelen); |
610 | xfs_da_brelse(args->trans, bp); | 608 | xfs_trans_brelse(args->trans, bp); |
611 | return XFS_ERROR(error); | 609 | return XFS_ERROR(error); |
612 | } | 610 | } |
613 | 611 | ||
@@ -617,13 +615,13 @@ xfs_dir2_block_lookup( | |||
617 | static int /* error */ | 615 | static int /* error */ |
618 | xfs_dir2_block_lookup_int( | 616 | xfs_dir2_block_lookup_int( |
619 | xfs_da_args_t *args, /* dir lookup arguments */ | 617 | xfs_da_args_t *args, /* dir lookup arguments */ |
620 | xfs_dabuf_t **bpp, /* returned block buffer */ | 618 | struct xfs_buf **bpp, /* returned block buffer */ |
621 | int *entno) /* returned entry number */ | 619 | int *entno) /* returned entry number */ |
622 | { | 620 | { |
623 | xfs_dir2_dataptr_t addr; /* data entry address */ | 621 | xfs_dir2_dataptr_t addr; /* data entry address */ |
624 | xfs_dir2_data_hdr_t *hdr; /* block header */ | 622 | xfs_dir2_data_hdr_t *hdr; /* block header */ |
625 | xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ | 623 | xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ |
626 | xfs_dabuf_t *bp; /* block buffer */ | 624 | struct xfs_buf *bp; /* block buffer */ |
627 | xfs_dir2_block_tail_t *btp; /* block tail */ | 625 | xfs_dir2_block_tail_t *btp; /* block tail */ |
628 | xfs_dir2_data_entry_t *dep; /* block data entry */ | 626 | xfs_dir2_data_entry_t *dep; /* block data entry */ |
629 | xfs_inode_t *dp; /* incore inode */ | 627 | xfs_inode_t *dp; /* incore inode */ |
@@ -647,7 +645,7 @@ xfs_dir2_block_lookup_int( | |||
647 | return error; | 645 | return error; |
648 | } | 646 | } |
649 | ASSERT(bp != NULL); | 647 | ASSERT(bp != NULL); |
650 | hdr = bp->data; | 648 | hdr = bp->b_addr; |
651 | xfs_dir2_data_check(dp, bp); | 649 | xfs_dir2_data_check(dp, bp); |
652 | btp = xfs_dir2_block_tail_p(mp, hdr); | 650 | btp = xfs_dir2_block_tail_p(mp, hdr); |
653 | blp = xfs_dir2_block_leaf_p(btp); | 651 | blp = xfs_dir2_block_leaf_p(btp); |
@@ -666,7 +664,7 @@ xfs_dir2_block_lookup_int( | |||
666 | high = mid - 1; | 664 | high = mid - 1; |
667 | if (low > high) { | 665 | if (low > high) { |
668 | ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); | 666 | ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); |
669 | xfs_da_brelse(tp, bp); | 667 | xfs_trans_brelse(tp, bp); |
670 | return XFS_ERROR(ENOENT); | 668 | return XFS_ERROR(ENOENT); |
671 | } | 669 | } |
672 | } | 670 | } |
@@ -714,7 +712,7 @@ xfs_dir2_block_lookup_int( | |||
714 | /* | 712 | /* |
715 | * No match, release the buffer and return ENOENT. | 713 | * No match, release the buffer and return ENOENT. |
716 | */ | 714 | */ |
717 | xfs_da_brelse(tp, bp); | 715 | xfs_trans_brelse(tp, bp); |
718 | return XFS_ERROR(ENOENT); | 716 | return XFS_ERROR(ENOENT); |
719 | } | 717 | } |
720 | 718 | ||
@@ -728,7 +726,7 @@ xfs_dir2_block_removename( | |||
728 | { | 726 | { |
729 | xfs_dir2_data_hdr_t *hdr; /* block header */ | 727 | xfs_dir2_data_hdr_t *hdr; /* block header */ |
730 | xfs_dir2_leaf_entry_t *blp; /* block leaf pointer */ | 728 | xfs_dir2_leaf_entry_t *blp; /* block leaf pointer */ |
731 | xfs_dabuf_t *bp; /* block buffer */ | 729 | struct xfs_buf *bp; /* block buffer */ |
732 | xfs_dir2_block_tail_t *btp; /* block tail */ | 730 | xfs_dir2_block_tail_t *btp; /* block tail */ |
733 | xfs_dir2_data_entry_t *dep; /* block data entry */ | 731 | xfs_dir2_data_entry_t *dep; /* block data entry */ |
734 | xfs_inode_t *dp; /* incore inode */ | 732 | xfs_inode_t *dp; /* incore inode */ |
@@ -753,7 +751,7 @@ xfs_dir2_block_removename( | |||
753 | dp = args->dp; | 751 | dp = args->dp; |
754 | tp = args->trans; | 752 | tp = args->trans; |
755 | mp = dp->i_mount; | 753 | mp = dp->i_mount; |
756 | hdr = bp->data; | 754 | hdr = bp->b_addr; |
757 | btp = xfs_dir2_block_tail_p(mp, hdr); | 755 | btp = xfs_dir2_block_tail_p(mp, hdr); |
758 | blp = xfs_dir2_block_leaf_p(btp); | 756 | blp = xfs_dir2_block_leaf_p(btp); |
759 | /* | 757 | /* |
@@ -790,10 +788,9 @@ xfs_dir2_block_removename( | |||
790 | * See if the size as a shortform is good enough. | 788 | * See if the size as a shortform is good enough. |
791 | */ | 789 | */ |
792 | size = xfs_dir2_block_sfsize(dp, hdr, &sfh); | 790 | size = xfs_dir2_block_sfsize(dp, hdr, &sfh); |
793 | if (size > XFS_IFORK_DSIZE(dp)) { | 791 | if (size > XFS_IFORK_DSIZE(dp)) |
794 | xfs_da_buf_done(bp); | ||
795 | return 0; | 792 | return 0; |
796 | } | 793 | |
797 | /* | 794 | /* |
798 | * If it works, do the conversion. | 795 | * If it works, do the conversion. |
799 | */ | 796 | */ |
@@ -810,7 +807,7 @@ xfs_dir2_block_replace( | |||
810 | { | 807 | { |
811 | xfs_dir2_data_hdr_t *hdr; /* block header */ | 808 | xfs_dir2_data_hdr_t *hdr; /* block header */ |
812 | xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ | 809 | xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ |
813 | xfs_dabuf_t *bp; /* block buffer */ | 810 | struct xfs_buf *bp; /* block buffer */ |
814 | xfs_dir2_block_tail_t *btp; /* block tail */ | 811 | xfs_dir2_block_tail_t *btp; /* block tail */ |
815 | xfs_dir2_data_entry_t *dep; /* block data entry */ | 812 | xfs_dir2_data_entry_t *dep; /* block data entry */ |
816 | xfs_inode_t *dp; /* incore inode */ | 813 | xfs_inode_t *dp; /* incore inode */ |
@@ -829,7 +826,7 @@ xfs_dir2_block_replace( | |||
829 | } | 826 | } |
830 | dp = args->dp; | 827 | dp = args->dp; |
831 | mp = dp->i_mount; | 828 | mp = dp->i_mount; |
832 | hdr = bp->data; | 829 | hdr = bp->b_addr; |
833 | btp = xfs_dir2_block_tail_p(mp, hdr); | 830 | btp = xfs_dir2_block_tail_p(mp, hdr); |
834 | blp = xfs_dir2_block_leaf_p(btp); | 831 | blp = xfs_dir2_block_leaf_p(btp); |
835 | /* | 832 | /* |
@@ -844,7 +841,6 @@ xfs_dir2_block_replace( | |||
844 | dep->inumber = cpu_to_be64(args->inumber); | 841 | dep->inumber = cpu_to_be64(args->inumber); |
845 | xfs_dir2_data_log_entry(args->trans, bp, dep); | 842 | xfs_dir2_data_log_entry(args->trans, bp, dep); |
846 | xfs_dir2_data_check(dp, bp); | 843 | xfs_dir2_data_check(dp, bp); |
847 | xfs_da_buf_done(bp); | ||
848 | return 0; | 844 | return 0; |
849 | } | 845 | } |
850 | 846 | ||
@@ -871,8 +867,8 @@ xfs_dir2_block_sort( | |||
871 | int /* error */ | 867 | int /* error */ |
872 | xfs_dir2_leaf_to_block( | 868 | xfs_dir2_leaf_to_block( |
873 | xfs_da_args_t *args, /* operation arguments */ | 869 | xfs_da_args_t *args, /* operation arguments */ |
874 | xfs_dabuf_t *lbp, /* leaf buffer */ | 870 | struct xfs_buf *lbp, /* leaf buffer */ |
875 | xfs_dabuf_t *dbp) /* data buffer */ | 871 | struct xfs_buf *dbp) /* data buffer */ |
876 | { | 872 | { |
877 | __be16 *bestsp; /* leaf bests table */ | 873 | __be16 *bestsp; /* leaf bests table */ |
878 | xfs_dir2_data_hdr_t *hdr; /* block header */ | 874 | xfs_dir2_data_hdr_t *hdr; /* block header */ |
@@ -898,7 +894,7 @@ xfs_dir2_leaf_to_block( | |||
898 | dp = args->dp; | 894 | dp = args->dp; |
899 | tp = args->trans; | 895 | tp = args->trans; |
900 | mp = dp->i_mount; | 896 | mp = dp->i_mount; |
901 | leaf = lbp->data; | 897 | leaf = lbp->b_addr; |
902 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC)); | 898 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC)); |
903 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); | 899 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); |
904 | /* | 900 | /* |
@@ -914,11 +910,9 @@ xfs_dir2_leaf_to_block( | |||
914 | if ((error = | 910 | if ((error = |
915 | xfs_dir2_leaf_trim_data(args, lbp, | 911 | xfs_dir2_leaf_trim_data(args, lbp, |
916 | (xfs_dir2_db_t)(be32_to_cpu(ltp->bestcount) - 1)))) | 912 | (xfs_dir2_db_t)(be32_to_cpu(ltp->bestcount) - 1)))) |
917 | goto out; | 913 | return error; |
918 | } else { | 914 | } else |
919 | error = 0; | 915 | return 0; |
920 | goto out; | ||
921 | } | ||
922 | } | 916 | } |
923 | /* | 917 | /* |
924 | * Read the data block if we don't already have it, give up if it fails. | 918 | * Read the data block if we don't already have it, give up if it fails. |
@@ -926,9 +920,9 @@ xfs_dir2_leaf_to_block( | |||
926 | if (dbp == NULL && | 920 | if (dbp == NULL && |
927 | (error = xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &dbp, | 921 | (error = xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &dbp, |
928 | XFS_DATA_FORK))) { | 922 | XFS_DATA_FORK))) { |
929 | goto out; | 923 | return error; |
930 | } | 924 | } |
931 | hdr = dbp->data; | 925 | hdr = dbp->b_addr; |
932 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC)); | 926 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC)); |
933 | /* | 927 | /* |
934 | * Size of the "leaf" area in the block. | 928 | * Size of the "leaf" area in the block. |
@@ -944,10 +938,9 @@ xfs_dir2_leaf_to_block( | |||
944 | * If it's not free or is too short we can't do it. | 938 | * If it's not free or is too short we can't do it. |
945 | */ | 939 | */ |
946 | if (be16_to_cpu(dup->freetag) != XFS_DIR2_DATA_FREE_TAG || | 940 | if (be16_to_cpu(dup->freetag) != XFS_DIR2_DATA_FREE_TAG || |
947 | be16_to_cpu(dup->length) < size) { | 941 | be16_to_cpu(dup->length) < size) |
948 | error = 0; | 942 | return 0; |
949 | goto out; | 943 | |
950 | } | ||
951 | /* | 944 | /* |
952 | * Start converting it to block form. | 945 | * Start converting it to block form. |
953 | */ | 946 | */ |
@@ -989,25 +982,17 @@ xfs_dir2_leaf_to_block( | |||
989 | * Pitch the old leaf block. | 982 | * Pitch the old leaf block. |
990 | */ | 983 | */ |
991 | error = xfs_da_shrink_inode(args, mp->m_dirleafblk, lbp); | 984 | error = xfs_da_shrink_inode(args, mp->m_dirleafblk, lbp); |
992 | lbp = NULL; | 985 | if (error) |
993 | if (error) { | 986 | return error; |
994 | goto out; | 987 | |
995 | } | ||
996 | /* | 988 | /* |
997 | * Now see if the resulting block can be shrunken to shortform. | 989 | * Now see if the resulting block can be shrunken to shortform. |
998 | */ | 990 | */ |
999 | size = xfs_dir2_block_sfsize(dp, hdr, &sfh); | 991 | size = xfs_dir2_block_sfsize(dp, hdr, &sfh); |
1000 | if (size > XFS_IFORK_DSIZE(dp)) { | 992 | if (size > XFS_IFORK_DSIZE(dp)) |
1001 | error = 0; | 993 | return 0; |
1002 | goto out; | 994 | |
1003 | } | ||
1004 | return xfs_dir2_block_to_sf(args, dbp, size, &sfh); | 995 | return xfs_dir2_block_to_sf(args, dbp, size, &sfh); |
1005 | out: | ||
1006 | if (lbp) | ||
1007 | xfs_da_buf_done(lbp); | ||
1008 | if (dbp) | ||
1009 | xfs_da_buf_done(dbp); | ||
1010 | return error; | ||
1011 | } | 996 | } |
1012 | 997 | ||
1013 | /* | 998 | /* |
@@ -1020,7 +1005,7 @@ xfs_dir2_sf_to_block( | |||
1020 | xfs_dir2_db_t blkno; /* dir-relative block # (0) */ | 1005 | xfs_dir2_db_t blkno; /* dir-relative block # (0) */ |
1021 | xfs_dir2_data_hdr_t *hdr; /* block header */ | 1006 | xfs_dir2_data_hdr_t *hdr; /* block header */ |
1022 | xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ | 1007 | xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ |
1023 | xfs_dabuf_t *bp; /* block buffer */ | 1008 | struct xfs_buf *bp; /* block buffer */ |
1024 | xfs_dir2_block_tail_t *btp; /* block tail pointer */ | 1009 | xfs_dir2_block_tail_t *btp; /* block tail pointer */ |
1025 | xfs_dir2_data_entry_t *dep; /* data entry pointer */ | 1010 | xfs_dir2_data_entry_t *dep; /* data entry pointer */ |
1026 | xfs_inode_t *dp; /* incore directory inode */ | 1011 | xfs_inode_t *dp; /* incore directory inode */ |
@@ -1088,7 +1073,7 @@ xfs_dir2_sf_to_block( | |||
1088 | kmem_free(sfp); | 1073 | kmem_free(sfp); |
1089 | return error; | 1074 | return error; |
1090 | } | 1075 | } |
1091 | hdr = bp->data; | 1076 | hdr = bp->b_addr; |
1092 | hdr->magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC); | 1077 | hdr->magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC); |
1093 | /* | 1078 | /* |
1094 | * Compute size of block "tail" area. | 1079 | * Compute size of block "tail" area. |
@@ -1217,6 +1202,5 @@ xfs_dir2_sf_to_block( | |||
1217 | xfs_dir2_block_log_leaf(tp, bp, 0, be32_to_cpu(btp->count) - 1); | 1202 | xfs_dir2_block_log_leaf(tp, bp, 0, be32_to_cpu(btp->count) - 1); |
1218 | xfs_dir2_block_log_tail(tp, bp); | 1203 | xfs_dir2_block_log_tail(tp, bp); |
1219 | xfs_dir2_data_check(dp, bp); | 1204 | xfs_dir2_data_check(dp, bp); |
1220 | xfs_da_buf_done(bp); | ||
1221 | return 0; | 1205 | return 0; |
1222 | } | 1206 | } |
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c index 2046988e9eb2..44ffd4d6bc91 100644 --- a/fs/xfs/xfs_dir2_data.c +++ b/fs/xfs/xfs_dir2_data.c | |||
@@ -42,8 +42,8 @@ xfs_dir2_data_freefind(xfs_dir2_data_hdr_t *hdr, xfs_dir2_data_unused_t *dup); | |||
42 | */ | 42 | */ |
43 | void | 43 | void |
44 | xfs_dir2_data_check( | 44 | xfs_dir2_data_check( |
45 | xfs_inode_t *dp, /* incore inode pointer */ | 45 | struct xfs_inode *dp, /* incore inode pointer */ |
46 | xfs_dabuf_t *bp) /* data block's buffer */ | 46 | struct xfs_buf *bp) /* data block's buffer */ |
47 | { | 47 | { |
48 | xfs_dir2_dataptr_t addr; /* addr for leaf lookup */ | 48 | xfs_dir2_dataptr_t addr; /* addr for leaf lookup */ |
49 | xfs_dir2_data_free_t *bf; /* bestfree table */ | 49 | xfs_dir2_data_free_t *bf; /* bestfree table */ |
@@ -65,7 +65,7 @@ xfs_dir2_data_check( | |||
65 | struct xfs_name name; | 65 | struct xfs_name name; |
66 | 66 | ||
67 | mp = dp->i_mount; | 67 | mp = dp->i_mount; |
68 | hdr = bp->data; | 68 | hdr = bp->b_addr; |
69 | bf = hdr->bestfree; | 69 | bf = hdr->bestfree; |
70 | p = (char *)(hdr + 1); | 70 | p = (char *)(hdr + 1); |
71 | 71 | ||
@@ -389,9 +389,9 @@ int /* error */ | |||
389 | xfs_dir2_data_init( | 389 | xfs_dir2_data_init( |
390 | xfs_da_args_t *args, /* directory operation args */ | 390 | xfs_da_args_t *args, /* directory operation args */ |
391 | xfs_dir2_db_t blkno, /* logical dir block number */ | 391 | xfs_dir2_db_t blkno, /* logical dir block number */ |
392 | xfs_dabuf_t **bpp) /* output block buffer */ | 392 | struct xfs_buf **bpp) /* output block buffer */ |
393 | { | 393 | { |
394 | xfs_dabuf_t *bp; /* block buffer */ | 394 | struct xfs_buf *bp; /* block buffer */ |
395 | xfs_dir2_data_hdr_t *hdr; /* data block header */ | 395 | xfs_dir2_data_hdr_t *hdr; /* data block header */ |
396 | xfs_inode_t *dp; /* incore directory inode */ | 396 | xfs_inode_t *dp; /* incore directory inode */ |
397 | xfs_dir2_data_unused_t *dup; /* unused entry pointer */ | 397 | xfs_dir2_data_unused_t *dup; /* unused entry pointer */ |
@@ -417,7 +417,7 @@ xfs_dir2_data_init( | |||
417 | /* | 417 | /* |
418 | * Initialize the header. | 418 | * Initialize the header. |
419 | */ | 419 | */ |
420 | hdr = bp->data; | 420 | hdr = bp->b_addr; |
421 | hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); | 421 | hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); |
422 | hdr->bestfree[0].offset = cpu_to_be16(sizeof(*hdr)); | 422 | hdr->bestfree[0].offset = cpu_to_be16(sizeof(*hdr)); |
423 | for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) { | 423 | for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) { |
@@ -449,16 +449,16 @@ xfs_dir2_data_init( | |||
449 | */ | 449 | */ |
450 | void | 450 | void |
451 | xfs_dir2_data_log_entry( | 451 | xfs_dir2_data_log_entry( |
452 | xfs_trans_t *tp, /* transaction pointer */ | 452 | struct xfs_trans *tp, |
453 | xfs_dabuf_t *bp, /* block buffer */ | 453 | struct xfs_buf *bp, |
454 | xfs_dir2_data_entry_t *dep) /* data entry pointer */ | 454 | xfs_dir2_data_entry_t *dep) /* data entry pointer */ |
455 | { | 455 | { |
456 | xfs_dir2_data_hdr_t *hdr = bp->data; | 456 | xfs_dir2_data_hdr_t *hdr = bp->b_addr; |
457 | 457 | ||
458 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || | 458 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || |
459 | hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)); | 459 | hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)); |
460 | 460 | ||
461 | xfs_da_log_buf(tp, bp, (uint)((char *)dep - (char *)hdr), | 461 | xfs_trans_log_buf(tp, bp, (uint)((char *)dep - (char *)hdr), |
462 | (uint)((char *)(xfs_dir2_data_entry_tag_p(dep) + 1) - | 462 | (uint)((char *)(xfs_dir2_data_entry_tag_p(dep) + 1) - |
463 | (char *)hdr - 1)); | 463 | (char *)hdr - 1)); |
464 | } | 464 | } |
@@ -468,15 +468,15 @@ xfs_dir2_data_log_entry( | |||
468 | */ | 468 | */ |
469 | void | 469 | void |
470 | xfs_dir2_data_log_header( | 470 | xfs_dir2_data_log_header( |
471 | xfs_trans_t *tp, /* transaction pointer */ | 471 | struct xfs_trans *tp, |
472 | xfs_dabuf_t *bp) /* block buffer */ | 472 | struct xfs_buf *bp) |
473 | { | 473 | { |
474 | xfs_dir2_data_hdr_t *hdr = bp->data; | 474 | xfs_dir2_data_hdr_t *hdr = bp->b_addr; |
475 | 475 | ||
476 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || | 476 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || |
477 | hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)); | 477 | hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)); |
478 | 478 | ||
479 | xfs_da_log_buf(tp, bp, 0, sizeof(*hdr) - 1); | 479 | xfs_trans_log_buf(tp, bp, 0, sizeof(*hdr) - 1); |
480 | } | 480 | } |
481 | 481 | ||
482 | /* | 482 | /* |
@@ -484,11 +484,11 @@ xfs_dir2_data_log_header( | |||
484 | */ | 484 | */ |
485 | void | 485 | void |
486 | xfs_dir2_data_log_unused( | 486 | xfs_dir2_data_log_unused( |
487 | xfs_trans_t *tp, /* transaction pointer */ | 487 | struct xfs_trans *tp, |
488 | xfs_dabuf_t *bp, /* block buffer */ | 488 | struct xfs_buf *bp, |
489 | xfs_dir2_data_unused_t *dup) /* data unused pointer */ | 489 | xfs_dir2_data_unused_t *dup) /* data unused pointer */ |
490 | { | 490 | { |
491 | xfs_dir2_data_hdr_t *hdr = bp->data; | 491 | xfs_dir2_data_hdr_t *hdr = bp->b_addr; |
492 | 492 | ||
493 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || | 493 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || |
494 | hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)); | 494 | hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)); |
@@ -496,13 +496,13 @@ xfs_dir2_data_log_unused( | |||
496 | /* | 496 | /* |
497 | * Log the first part of the unused entry. | 497 | * Log the first part of the unused entry. |
498 | */ | 498 | */ |
499 | xfs_da_log_buf(tp, bp, (uint)((char *)dup - (char *)hdr), | 499 | xfs_trans_log_buf(tp, bp, (uint)((char *)dup - (char *)hdr), |
500 | (uint)((char *)&dup->length + sizeof(dup->length) - | 500 | (uint)((char *)&dup->length + sizeof(dup->length) - |
501 | 1 - (char *)hdr)); | 501 | 1 - (char *)hdr)); |
502 | /* | 502 | /* |
503 | * Log the end (tag) of the unused entry. | 503 | * Log the end (tag) of the unused entry. |
504 | */ | 504 | */ |
505 | xfs_da_log_buf(tp, bp, | 505 | xfs_trans_log_buf(tp, bp, |
506 | (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr), | 506 | (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr), |
507 | (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr + | 507 | (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr + |
508 | sizeof(xfs_dir2_data_off_t) - 1)); | 508 | sizeof(xfs_dir2_data_off_t) - 1)); |
@@ -514,8 +514,8 @@ xfs_dir2_data_log_unused( | |||
514 | */ | 514 | */ |
515 | void | 515 | void |
516 | xfs_dir2_data_make_free( | 516 | xfs_dir2_data_make_free( |
517 | xfs_trans_t *tp, /* transaction pointer */ | 517 | struct xfs_trans *tp, |
518 | xfs_dabuf_t *bp, /* block buffer */ | 518 | struct xfs_buf *bp, |
519 | xfs_dir2_data_aoff_t offset, /* starting byte offset */ | 519 | xfs_dir2_data_aoff_t offset, /* starting byte offset */ |
520 | xfs_dir2_data_aoff_t len, /* length in bytes */ | 520 | xfs_dir2_data_aoff_t len, /* length in bytes */ |
521 | int *needlogp, /* out: log header */ | 521 | int *needlogp, /* out: log header */ |
@@ -531,7 +531,7 @@ xfs_dir2_data_make_free( | |||
531 | xfs_dir2_data_unused_t *prevdup; /* unused entry before us */ | 531 | xfs_dir2_data_unused_t *prevdup; /* unused entry before us */ |
532 | 532 | ||
533 | mp = tp->t_mountp; | 533 | mp = tp->t_mountp; |
534 | hdr = bp->data; | 534 | hdr = bp->b_addr; |
535 | 535 | ||
536 | /* | 536 | /* |
537 | * Figure out where the end of the data area is. | 537 | * Figure out where the end of the data area is. |
@@ -696,8 +696,8 @@ xfs_dir2_data_make_free( | |||
696 | */ | 696 | */ |
697 | void | 697 | void |
698 | xfs_dir2_data_use_free( | 698 | xfs_dir2_data_use_free( |
699 | xfs_trans_t *tp, /* transaction pointer */ | 699 | struct xfs_trans *tp, |
700 | xfs_dabuf_t *bp, /* data block buffer */ | 700 | struct xfs_buf *bp, |
701 | xfs_dir2_data_unused_t *dup, /* unused entry */ | 701 | xfs_dir2_data_unused_t *dup, /* unused entry */ |
702 | xfs_dir2_data_aoff_t offset, /* starting offset to use */ | 702 | xfs_dir2_data_aoff_t offset, /* starting offset to use */ |
703 | xfs_dir2_data_aoff_t len, /* length to use */ | 703 | xfs_dir2_data_aoff_t len, /* length to use */ |
@@ -713,7 +713,7 @@ xfs_dir2_data_use_free( | |||
713 | xfs_dir2_data_unused_t *newdup2; /* another new unused entry */ | 713 | xfs_dir2_data_unused_t *newdup2; /* another new unused entry */ |
714 | int oldlen; /* old unused entry's length */ | 714 | int oldlen; /* old unused entry's length */ |
715 | 715 | ||
716 | hdr = bp->data; | 716 | hdr = bp->b_addr; |
717 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || | 717 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || |
718 | hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)); | 718 | hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)); |
719 | ASSERT(be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG); | 719 | ASSERT(be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG); |
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c index 397ffbcbab1d..0b296253bd01 100644 --- a/fs/xfs/xfs_dir2_leaf.c +++ b/fs/xfs/xfs_dir2_leaf.c | |||
@@ -38,15 +38,15 @@ | |||
38 | * Local function declarations. | 38 | * Local function declarations. |
39 | */ | 39 | */ |
40 | #ifdef DEBUG | 40 | #ifdef DEBUG |
41 | static void xfs_dir2_leaf_check(xfs_inode_t *dp, xfs_dabuf_t *bp); | 41 | static void xfs_dir2_leaf_check(struct xfs_inode *dp, struct xfs_buf *bp); |
42 | #else | 42 | #else |
43 | #define xfs_dir2_leaf_check(dp, bp) | 43 | #define xfs_dir2_leaf_check(dp, bp) |
44 | #endif | 44 | #endif |
45 | static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **lbpp, | 45 | static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, struct xfs_buf **lbpp, |
46 | int *indexp, xfs_dabuf_t **dbpp); | 46 | int *indexp, struct xfs_buf **dbpp); |
47 | static void xfs_dir2_leaf_log_bests(struct xfs_trans *tp, struct xfs_dabuf *bp, | 47 | static void xfs_dir2_leaf_log_bests(struct xfs_trans *tp, struct xfs_buf *bp, |
48 | int first, int last); | 48 | int first, int last); |
49 | static void xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_dabuf *bp); | 49 | static void xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_buf *bp); |
50 | 50 | ||
51 | 51 | ||
52 | /* | 52 | /* |
@@ -55,7 +55,7 @@ static void xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_dabuf *bp); | |||
55 | int /* error */ | 55 | int /* error */ |
56 | xfs_dir2_block_to_leaf( | 56 | xfs_dir2_block_to_leaf( |
57 | xfs_da_args_t *args, /* operation arguments */ | 57 | xfs_da_args_t *args, /* operation arguments */ |
58 | xfs_dabuf_t *dbp) /* input block's buffer */ | 58 | struct xfs_buf *dbp) /* input block's buffer */ |
59 | { | 59 | { |
60 | __be16 *bestsp; /* leaf's bestsp entries */ | 60 | __be16 *bestsp; /* leaf's bestsp entries */ |
61 | xfs_dablk_t blkno; /* leaf block's bno */ | 61 | xfs_dablk_t blkno; /* leaf block's bno */ |
@@ -64,7 +64,7 @@ xfs_dir2_block_to_leaf( | |||
64 | xfs_dir2_block_tail_t *btp; /* block's tail */ | 64 | xfs_dir2_block_tail_t *btp; /* block's tail */ |
65 | xfs_inode_t *dp; /* incore directory inode */ | 65 | xfs_inode_t *dp; /* incore directory inode */ |
66 | int error; /* error return code */ | 66 | int error; /* error return code */ |
67 | xfs_dabuf_t *lbp; /* leaf block's buffer */ | 67 | struct xfs_buf *lbp; /* leaf block's buffer */ |
68 | xfs_dir2_db_t ldb; /* leaf block's bno */ | 68 | xfs_dir2_db_t ldb; /* leaf block's bno */ |
69 | xfs_dir2_leaf_t *leaf; /* leaf structure */ | 69 | xfs_dir2_leaf_t *leaf; /* leaf structure */ |
70 | xfs_dir2_leaf_tail_t *ltp; /* leaf's tail */ | 70 | xfs_dir2_leaf_tail_t *ltp; /* leaf's tail */ |
@@ -95,8 +95,8 @@ xfs_dir2_block_to_leaf( | |||
95 | return error; | 95 | return error; |
96 | } | 96 | } |
97 | ASSERT(lbp != NULL); | 97 | ASSERT(lbp != NULL); |
98 | leaf = lbp->data; | 98 | leaf = lbp->b_addr; |
99 | hdr = dbp->data; | 99 | hdr = dbp->b_addr; |
100 | xfs_dir2_data_check(dp, dbp); | 100 | xfs_dir2_data_check(dp, dbp); |
101 | btp = xfs_dir2_block_tail_p(mp, hdr); | 101 | btp = xfs_dir2_block_tail_p(mp, hdr); |
102 | blp = xfs_dir2_block_leaf_p(btp); | 102 | blp = xfs_dir2_block_leaf_p(btp); |
@@ -143,7 +143,6 @@ xfs_dir2_block_to_leaf( | |||
143 | xfs_dir2_leaf_check(dp, lbp); | 143 | xfs_dir2_leaf_check(dp, lbp); |
144 | xfs_dir2_data_check(dp, dbp); | 144 | xfs_dir2_data_check(dp, dbp); |
145 | xfs_dir2_leaf_log_bests(tp, lbp, 0, 0); | 145 | xfs_dir2_leaf_log_bests(tp, lbp, 0, 0); |
146 | xfs_da_buf_done(lbp); | ||
147 | return 0; | 146 | return 0; |
148 | } | 147 | } |
149 | 148 | ||
@@ -282,7 +281,7 @@ xfs_dir2_leaf_addname( | |||
282 | __be16 *bestsp; /* freespace table in leaf */ | 281 | __be16 *bestsp; /* freespace table in leaf */ |
283 | int compact; /* need to compact leaves */ | 282 | int compact; /* need to compact leaves */ |
284 | xfs_dir2_data_hdr_t *hdr; /* data block header */ | 283 | xfs_dir2_data_hdr_t *hdr; /* data block header */ |
285 | xfs_dabuf_t *dbp; /* data block buffer */ | 284 | struct xfs_buf *dbp; /* data block buffer */ |
286 | xfs_dir2_data_entry_t *dep; /* data block entry */ | 285 | xfs_dir2_data_entry_t *dep; /* data block entry */ |
287 | xfs_inode_t *dp; /* incore directory inode */ | 286 | xfs_inode_t *dp; /* incore directory inode */ |
288 | xfs_dir2_data_unused_t *dup; /* data unused entry */ | 287 | xfs_dir2_data_unused_t *dup; /* data unused entry */ |
@@ -291,7 +290,7 @@ xfs_dir2_leaf_addname( | |||
291 | int highstale; /* index of next stale leaf */ | 290 | int highstale; /* index of next stale leaf */ |
292 | int i; /* temporary, index */ | 291 | int i; /* temporary, index */ |
293 | int index; /* leaf table position */ | 292 | int index; /* leaf table position */ |
294 | xfs_dabuf_t *lbp; /* leaf's buffer */ | 293 | struct xfs_buf *lbp; /* leaf's buffer */ |
295 | xfs_dir2_leaf_t *leaf; /* leaf structure */ | 294 | xfs_dir2_leaf_t *leaf; /* leaf structure */ |
296 | int length; /* length of new entry */ | 295 | int length; /* length of new entry */ |
297 | xfs_dir2_leaf_entry_t *lep; /* leaf entry table pointer */ | 296 | xfs_dir2_leaf_entry_t *lep; /* leaf entry table pointer */ |
@@ -328,7 +327,7 @@ xfs_dir2_leaf_addname( | |||
328 | * But if there are dup hash values the index is of the first of those. | 327 | * But if there are dup hash values the index is of the first of those. |
329 | */ | 328 | */ |
330 | index = xfs_dir2_leaf_search_hash(args, lbp); | 329 | index = xfs_dir2_leaf_search_hash(args, lbp); |
331 | leaf = lbp->data; | 330 | leaf = lbp->b_addr; |
332 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); | 331 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); |
333 | bestsp = xfs_dir2_leaf_bests_p(ltp); | 332 | bestsp = xfs_dir2_leaf_bests_p(ltp); |
334 | length = xfs_dir2_data_entsize(args->namelen); | 333 | length = xfs_dir2_data_entsize(args->namelen); |
@@ -402,14 +401,13 @@ xfs_dir2_leaf_addname( | |||
402 | */ | 401 | */ |
403 | if ((args->op_flags & XFS_DA_OP_JUSTCHECK) || | 402 | if ((args->op_flags & XFS_DA_OP_JUSTCHECK) || |
404 | args->total == 0) { | 403 | args->total == 0) { |
405 | xfs_da_brelse(tp, lbp); | 404 | xfs_trans_brelse(tp, lbp); |
406 | return XFS_ERROR(ENOSPC); | 405 | return XFS_ERROR(ENOSPC); |
407 | } | 406 | } |
408 | /* | 407 | /* |
409 | * Convert to node form. | 408 | * Convert to node form. |
410 | */ | 409 | */ |
411 | error = xfs_dir2_leaf_to_node(args, lbp); | 410 | error = xfs_dir2_leaf_to_node(args, lbp); |
412 | xfs_da_buf_done(lbp); | ||
413 | if (error) | 411 | if (error) |
414 | return error; | 412 | return error; |
415 | /* | 413 | /* |
@@ -427,7 +425,7 @@ xfs_dir2_leaf_addname( | |||
427 | * a new data block. | 425 | * a new data block. |
428 | */ | 426 | */ |
429 | if (args->op_flags & XFS_DA_OP_JUSTCHECK) { | 427 | if (args->op_flags & XFS_DA_OP_JUSTCHECK) { |
430 | xfs_da_brelse(tp, lbp); | 428 | xfs_trans_brelse(tp, lbp); |
431 | return use_block == -1 ? XFS_ERROR(ENOSPC) : 0; | 429 | return use_block == -1 ? XFS_ERROR(ENOSPC) : 0; |
432 | } | 430 | } |
433 | /* | 431 | /* |
@@ -435,7 +433,7 @@ xfs_dir2_leaf_addname( | |||
435 | * changed anything. | 433 | * changed anything. |
436 | */ | 434 | */ |
437 | if (args->total == 0 && use_block == -1) { | 435 | if (args->total == 0 && use_block == -1) { |
438 | xfs_da_brelse(tp, lbp); | 436 | xfs_trans_brelse(tp, lbp); |
439 | return XFS_ERROR(ENOSPC); | 437 | return XFS_ERROR(ENOSPC); |
440 | } | 438 | } |
441 | /* | 439 | /* |
@@ -466,14 +464,14 @@ xfs_dir2_leaf_addname( | |||
466 | */ | 464 | */ |
467 | if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE, | 465 | if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE, |
468 | &use_block))) { | 466 | &use_block))) { |
469 | xfs_da_brelse(tp, lbp); | 467 | xfs_trans_brelse(tp, lbp); |
470 | return error; | 468 | return error; |
471 | } | 469 | } |
472 | /* | 470 | /* |
473 | * Initialize the block. | 471 | * Initialize the block. |
474 | */ | 472 | */ |
475 | if ((error = xfs_dir2_data_init(args, use_block, &dbp))) { | 473 | if ((error = xfs_dir2_data_init(args, use_block, &dbp))) { |
476 | xfs_da_brelse(tp, lbp); | 474 | xfs_trans_brelse(tp, lbp); |
477 | return error; | 475 | return error; |
478 | } | 476 | } |
479 | /* | 477 | /* |
@@ -493,7 +491,7 @@ xfs_dir2_leaf_addname( | |||
493 | */ | 491 | */ |
494 | else | 492 | else |
495 | xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); | 493 | xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); |
496 | hdr = dbp->data; | 494 | hdr = dbp->b_addr; |
497 | bestsp[use_block] = hdr->bestfree[0].length; | 495 | bestsp[use_block] = hdr->bestfree[0].length; |
498 | grown = 1; | 496 | grown = 1; |
499 | } | 497 | } |
@@ -505,10 +503,10 @@ xfs_dir2_leaf_addname( | |||
505 | if ((error = | 503 | if ((error = |
506 | xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, use_block), | 504 | xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, use_block), |
507 | -1, &dbp, XFS_DATA_FORK))) { | 505 | -1, &dbp, XFS_DATA_FORK))) { |
508 | xfs_da_brelse(tp, lbp); | 506 | xfs_trans_brelse(tp, lbp); |
509 | return error; | 507 | return error; |
510 | } | 508 | } |
511 | hdr = dbp->data; | 509 | hdr = dbp->b_addr; |
512 | grown = 0; | 510 | grown = 0; |
513 | } | 511 | } |
514 | xfs_dir2_data_check(dp, dbp); | 512 | xfs_dir2_data_check(dp, dbp); |
@@ -570,9 +568,7 @@ xfs_dir2_leaf_addname( | |||
570 | xfs_dir2_leaf_log_header(tp, lbp); | 568 | xfs_dir2_leaf_log_header(tp, lbp); |
571 | xfs_dir2_leaf_log_ents(tp, lbp, lfloglow, lfloghigh); | 569 | xfs_dir2_leaf_log_ents(tp, lbp, lfloglow, lfloghigh); |
572 | xfs_dir2_leaf_check(dp, lbp); | 570 | xfs_dir2_leaf_check(dp, lbp); |
573 | xfs_da_buf_done(lbp); | ||
574 | xfs_dir2_data_check(dp, dbp); | 571 | xfs_dir2_data_check(dp, dbp); |
575 | xfs_da_buf_done(dbp); | ||
576 | return 0; | 572 | return 0; |
577 | } | 573 | } |
578 | 574 | ||
@@ -583,8 +579,8 @@ xfs_dir2_leaf_addname( | |||
583 | */ | 579 | */ |
584 | STATIC void | 580 | STATIC void |
585 | xfs_dir2_leaf_check( | 581 | xfs_dir2_leaf_check( |
586 | xfs_inode_t *dp, /* incore directory inode */ | 582 | struct xfs_inode *dp, /* incore directory inode */ |
587 | xfs_dabuf_t *bp) /* leaf's buffer */ | 583 | struct xfs_buf *bp) /* leaf's buffer */ |
588 | { | 584 | { |
589 | int i; /* leaf index */ | 585 | int i; /* leaf index */ |
590 | xfs_dir2_leaf_t *leaf; /* leaf structure */ | 586 | xfs_dir2_leaf_t *leaf; /* leaf structure */ |
@@ -592,7 +588,7 @@ xfs_dir2_leaf_check( | |||
592 | xfs_mount_t *mp; /* filesystem mount point */ | 588 | xfs_mount_t *mp; /* filesystem mount point */ |
593 | int stale; /* count of stale leaves */ | 589 | int stale; /* count of stale leaves */ |
594 | 590 | ||
595 | leaf = bp->data; | 591 | leaf = bp->b_addr; |
596 | mp = dp->i_mount; | 592 | mp = dp->i_mount; |
597 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC)); | 593 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC)); |
598 | /* | 594 | /* |
@@ -628,14 +624,14 @@ xfs_dir2_leaf_check( | |||
628 | void | 624 | void |
629 | xfs_dir2_leaf_compact( | 625 | xfs_dir2_leaf_compact( |
630 | xfs_da_args_t *args, /* operation arguments */ | 626 | xfs_da_args_t *args, /* operation arguments */ |
631 | xfs_dabuf_t *bp) /* leaf buffer */ | 627 | struct xfs_buf *bp) /* leaf buffer */ |
632 | { | 628 | { |
633 | int from; /* source leaf index */ | 629 | int from; /* source leaf index */ |
634 | xfs_dir2_leaf_t *leaf; /* leaf structure */ | 630 | xfs_dir2_leaf_t *leaf; /* leaf structure */ |
635 | int loglow; /* first leaf entry to log */ | 631 | int loglow; /* first leaf entry to log */ |
636 | int to; /* target leaf index */ | 632 | int to; /* target leaf index */ |
637 | 633 | ||
638 | leaf = bp->data; | 634 | leaf = bp->b_addr; |
639 | if (!leaf->hdr.stale) { | 635 | if (!leaf->hdr.stale) { |
640 | return; | 636 | return; |
641 | } | 637 | } |
@@ -677,7 +673,7 @@ xfs_dir2_leaf_compact( | |||
677 | */ | 673 | */ |
678 | void | 674 | void |
679 | xfs_dir2_leaf_compact_x1( | 675 | xfs_dir2_leaf_compact_x1( |
680 | xfs_dabuf_t *bp, /* leaf buffer */ | 676 | struct xfs_buf *bp, /* leaf buffer */ |
681 | int *indexp, /* insertion index */ | 677 | int *indexp, /* insertion index */ |
682 | int *lowstalep, /* out: stale entry before us */ | 678 | int *lowstalep, /* out: stale entry before us */ |
683 | int *highstalep, /* out: stale entry after us */ | 679 | int *highstalep, /* out: stale entry after us */ |
@@ -693,7 +689,7 @@ xfs_dir2_leaf_compact_x1( | |||
693 | int newindex=0; /* new insertion index */ | 689 | int newindex=0; /* new insertion index */ |
694 | int to; /* destination copy index */ | 690 | int to; /* destination copy index */ |
695 | 691 | ||
696 | leaf = bp->data; | 692 | leaf = bp->b_addr; |
697 | ASSERT(be16_to_cpu(leaf->hdr.stale) > 1); | 693 | ASSERT(be16_to_cpu(leaf->hdr.stale) > 1); |
698 | index = *indexp; | 694 | index = *indexp; |
699 | 695 | ||
@@ -763,6 +759,218 @@ xfs_dir2_leaf_compact_x1( | |||
763 | *highstalep = highstale; | 759 | *highstalep = highstale; |
764 | } | 760 | } |
765 | 761 | ||
762 | struct xfs_dir2_leaf_map_info { | ||
763 | xfs_extlen_t map_blocks; /* number of fsbs in map */ | ||
764 | xfs_dablk_t map_off; /* last mapped file offset */ | ||
765 | int map_size; /* total entries in *map */ | ||
766 | int map_valid; /* valid entries in *map */ | ||
767 | int nmap; /* mappings to ask xfs_bmapi */ | ||
768 | xfs_dir2_db_t curdb; /* db for current block */ | ||
769 | int ra_current; /* number of read-ahead blks */ | ||
770 | int ra_index; /* *map index for read-ahead */ | ||
771 | int ra_offset; /* map entry offset for ra */ | ||
772 | int ra_want; /* readahead count wanted */ | ||
773 | struct xfs_bmbt_irec map[]; /* map vector for blocks */ | ||
774 | }; | ||
775 | |||
776 | STATIC int | ||
777 | xfs_dir2_leaf_readbuf( | ||
778 | struct xfs_inode *dp, | ||
779 | size_t bufsize, | ||
780 | struct xfs_dir2_leaf_map_info *mip, | ||
781 | xfs_dir2_off_t *curoff, | ||
782 | struct xfs_buf **bpp) | ||
783 | { | ||
784 | struct xfs_mount *mp = dp->i_mount; | ||
785 | struct xfs_buf *bp = *bpp; | ||
786 | struct xfs_bmbt_irec *map = mip->map; | ||
787 | int error = 0; | ||
788 | int length; | ||
789 | int i; | ||
790 | int j; | ||
791 | |||
792 | /* | ||
793 | * If we have a buffer, we need to release it and | ||
794 | * take it out of the mapping. | ||
795 | */ | ||
796 | |||
797 | if (bp) { | ||
798 | xfs_trans_brelse(NULL, bp); | ||
799 | bp = NULL; | ||
800 | mip->map_blocks -= mp->m_dirblkfsbs; | ||
801 | /* | ||
802 | * Loop to get rid of the extents for the | ||
803 | * directory block. | ||
804 | */ | ||
805 | for (i = mp->m_dirblkfsbs; i > 0; ) { | ||
806 | j = min_t(int, map->br_blockcount, i); | ||
807 | map->br_blockcount -= j; | ||
808 | map->br_startblock += j; | ||
809 | map->br_startoff += j; | ||
810 | /* | ||
811 | * If mapping is done, pitch it from | ||
812 | * the table. | ||
813 | */ | ||
814 | if (!map->br_blockcount && --mip->map_valid) | ||
815 | memmove(&map[0], &map[1], | ||
816 | sizeof(map[0]) * mip->map_valid); | ||
817 | i -= j; | ||
818 | } | ||
819 | } | ||
820 | |||
821 | /* | ||
822 | * Recalculate the readahead blocks wanted. | ||
823 | */ | ||
824 | mip->ra_want = howmany(bufsize + mp->m_dirblksize, | ||
825 | mp->m_sb.sb_blocksize) - 1; | ||
826 | ASSERT(mip->ra_want >= 0); | ||
827 | |||
828 | /* | ||
829 | * If we don't have as many as we want, and we haven't | ||
830 | * run out of data blocks, get some more mappings. | ||
831 | */ | ||
832 | if (1 + mip->ra_want > mip->map_blocks && | ||
833 | mip->map_off < xfs_dir2_byte_to_da(mp, XFS_DIR2_LEAF_OFFSET)) { | ||
834 | /* | ||
835 | * Get more bmaps, fill in after the ones | ||
836 | * we already have in the table. | ||
837 | */ | ||
838 | mip->nmap = mip->map_size - mip->map_valid; | ||
839 | error = xfs_bmapi_read(dp, mip->map_off, | ||
840 | xfs_dir2_byte_to_da(mp, XFS_DIR2_LEAF_OFFSET) - | ||
841 | mip->map_off, | ||
842 | &map[mip->map_valid], &mip->nmap, 0); | ||
843 | |||
844 | /* | ||
845 | * Don't know if we should ignore this or try to return an | ||
846 | * error. The trouble with returning errors is that readdir | ||
847 | * will just stop without actually passing the error through. | ||
848 | */ | ||
849 | if (error) | ||
850 | goto out; /* XXX */ | ||
851 | |||
852 | /* | ||
853 | * If we got all the mappings we asked for, set the final map | ||
854 | * offset based on the last bmap value received. Otherwise, | ||
855 | * we've reached the end. | ||
856 | */ | ||
857 | if (mip->nmap == mip->map_size - mip->map_valid) { | ||
858 | i = mip->map_valid + mip->nmap - 1; | ||
859 | mip->map_off = map[i].br_startoff + map[i].br_blockcount; | ||
860 | } else | ||
861 | mip->map_off = xfs_dir2_byte_to_da(mp, | ||
862 | XFS_DIR2_LEAF_OFFSET); | ||
863 | |||
864 | /* | ||
865 | * Look for holes in the mapping, and eliminate them. Count up | ||
866 | * the valid blocks. | ||
867 | */ | ||
868 | for (i = mip->map_valid; i < mip->map_valid + mip->nmap; ) { | ||
869 | if (map[i].br_startblock == HOLESTARTBLOCK) { | ||
870 | mip->nmap--; | ||
871 | length = mip->map_valid + mip->nmap - i; | ||
872 | if (length) | ||
873 | memmove(&map[i], &map[i + 1], | ||
874 | sizeof(map[i]) * length); | ||
875 | } else { | ||
876 | mip->map_blocks += map[i].br_blockcount; | ||
877 | i++; | ||
878 | } | ||
879 | } | ||
880 | mip->map_valid += mip->nmap; | ||
881 | } | ||
882 | |||
883 | /* | ||
884 | * No valid mappings, so no more data blocks. | ||
885 | */ | ||
886 | if (!mip->map_valid) { | ||
887 | *curoff = xfs_dir2_da_to_byte(mp, mip->map_off); | ||
888 | goto out; | ||
889 | } | ||
890 | |||
891 | /* | ||
892 | * Read the directory block starting at the first mapping. | ||
893 | */ | ||
894 | mip->curdb = xfs_dir2_da_to_db(mp, map->br_startoff); | ||
895 | error = xfs_da_read_buf(NULL, dp, map->br_startoff, | ||
896 | map->br_blockcount >= mp->m_dirblkfsbs ? | ||
897 | XFS_FSB_TO_DADDR(mp, map->br_startblock) : -1, | ||
898 | &bp, XFS_DATA_FORK); | ||
899 | |||
900 | /* | ||
901 | * Should just skip over the data block instead of giving up. | ||
902 | */ | ||
903 | if (error) | ||
904 | goto out; /* XXX */ | ||
905 | |||
906 | /* | ||
907 | * Adjust the current amount of read-ahead: we just read a block that | ||
908 | * was previously ra. | ||
909 | */ | ||
910 | if (mip->ra_current) | ||
911 | mip->ra_current -= mp->m_dirblkfsbs; | ||
912 | |||
913 | /* | ||
914 | * Do we need more readahead? | ||
915 | */ | ||
916 | for (mip->ra_index = mip->ra_offset = i = 0; | ||
917 | mip->ra_want > mip->ra_current && i < mip->map_blocks; | ||
918 | i += mp->m_dirblkfsbs) { | ||
919 | ASSERT(mip->ra_index < mip->map_valid); | ||
920 | /* | ||
921 | * Read-ahead a contiguous directory block. | ||
922 | */ | ||
923 | if (i > mip->ra_current && | ||
924 | map[mip->ra_index].br_blockcount >= mp->m_dirblkfsbs) { | ||
925 | xfs_buf_readahead(mp->m_ddev_targp, | ||
926 | XFS_FSB_TO_DADDR(mp, | ||
927 | map[mip->ra_index].br_startblock + | ||
928 | mip->ra_offset), | ||
929 | (int)BTOBB(mp->m_dirblksize)); | ||
930 | mip->ra_current = i; | ||
931 | } | ||
932 | |||
933 | /* | ||
934 | * Read-ahead a non-contiguous directory block. This doesn't | ||
935 | * use our mapping, but this is a very rare case. | ||
936 | */ | ||
937 | else if (i > mip->ra_current) { | ||
938 | xfs_da_reada_buf(NULL, dp, | ||
939 | map[mip->ra_index].br_startoff + | ||
940 | mip->ra_offset, | ||
941 | XFS_DATA_FORK); | ||
942 | mip->ra_current = i; | ||
943 | } | ||
944 | |||
945 | /* | ||
946 | * Advance offset through the mapping table. | ||
947 | */ | ||
948 | for (j = 0; j < mp->m_dirblkfsbs; j++) { | ||
949 | /* | ||
950 | * The rest of this extent but not more than a dir | ||
951 | * block. | ||
952 | */ | ||
953 | length = min_t(int, mp->m_dirblkfsbs, | ||
954 | map[mip->ra_index].br_blockcount - | ||
955 | mip->ra_offset); | ||
956 | j += length; | ||
957 | mip->ra_offset += length; | ||
958 | |||
959 | /* | ||
960 | * Advance to the next mapping if this one is used up. | ||
961 | */ | ||
962 | if (mip->ra_offset == map[mip->ra_index].br_blockcount) { | ||
963 | mip->ra_offset = 0; | ||
964 | mip->ra_index++; | ||
965 | } | ||
966 | } | ||
967 | } | ||
968 | |||
969 | out: | ||
970 | *bpp = bp; | ||
971 | return error; | ||
972 | } | ||
973 | |||
766 | /* | 974 | /* |
767 | * Getdents (readdir) for leaf and node directories. | 975 | * Getdents (readdir) for leaf and node directories. |
768 | * This reads the data blocks only, so is the same for both forms. | 976 | * This reads the data blocks only, so is the same for both forms. |
@@ -775,30 +983,18 @@ xfs_dir2_leaf_getdents( | |||
775 | xfs_off_t *offset, | 983 | xfs_off_t *offset, |
776 | filldir_t filldir) | 984 | filldir_t filldir) |
777 | { | 985 | { |
778 | xfs_dabuf_t *bp; /* data block buffer */ | 986 | struct xfs_buf *bp = NULL; /* data block buffer */ |
779 | int byteoff; /* offset in current block */ | ||
780 | xfs_dir2_db_t curdb; /* db for current block */ | ||
781 | xfs_dir2_off_t curoff; /* current overall offset */ | ||
782 | xfs_dir2_data_hdr_t *hdr; /* data block header */ | 987 | xfs_dir2_data_hdr_t *hdr; /* data block header */ |
783 | xfs_dir2_data_entry_t *dep; /* data entry */ | 988 | xfs_dir2_data_entry_t *dep; /* data entry */ |
784 | xfs_dir2_data_unused_t *dup; /* unused entry */ | 989 | xfs_dir2_data_unused_t *dup; /* unused entry */ |
785 | int error = 0; /* error return value */ | 990 | int error = 0; /* error return value */ |
786 | int i; /* temporary loop index */ | ||
787 | int j; /* temporary loop index */ | ||
788 | int length; /* temporary length value */ | 991 | int length; /* temporary length value */ |
789 | xfs_bmbt_irec_t *map; /* map vector for blocks */ | ||
790 | xfs_extlen_t map_blocks; /* number of fsbs in map */ | ||
791 | xfs_dablk_t map_off; /* last mapped file offset */ | ||
792 | int map_size; /* total entries in *map */ | ||
793 | int map_valid; /* valid entries in *map */ | ||
794 | xfs_mount_t *mp; /* filesystem mount point */ | 992 | xfs_mount_t *mp; /* filesystem mount point */ |
993 | int byteoff; /* offset in current block */ | ||
994 | xfs_dir2_off_t curoff; /* current overall offset */ | ||
795 | xfs_dir2_off_t newoff; /* new curoff after new blk */ | 995 | xfs_dir2_off_t newoff; /* new curoff after new blk */ |
796 | int nmap; /* mappings to ask xfs_bmapi */ | ||
797 | char *ptr = NULL; /* pointer to current data */ | 996 | char *ptr = NULL; /* pointer to current data */ |
798 | int ra_current; /* number of read-ahead blks */ | 997 | struct xfs_dir2_leaf_map_info *map_info; |
799 | int ra_index; /* *map index for read-ahead */ | ||
800 | int ra_offset; /* map entry offset for ra */ | ||
801 | int ra_want; /* readahead count wanted */ | ||
802 | 998 | ||
803 | /* | 999 | /* |
804 | * If the offset is at or past the largest allowed value, | 1000 | * If the offset is at or past the largest allowed value, |
@@ -814,10 +1010,12 @@ xfs_dir2_leaf_getdents( | |||
814 | * buffer size, the directory block size, and the filesystem | 1010 | * buffer size, the directory block size, and the filesystem |
815 | * block size. | 1011 | * block size. |
816 | */ | 1012 | */ |
817 | map_size = howmany(bufsize + mp->m_dirblksize, mp->m_sb.sb_blocksize); | 1013 | length = howmany(bufsize + mp->m_dirblksize, |
818 | map = kmem_alloc(map_size * sizeof(*map), KM_SLEEP); | 1014 | mp->m_sb.sb_blocksize); |
819 | map_valid = ra_index = ra_offset = ra_current = map_blocks = 0; | 1015 | map_info = kmem_zalloc(offsetof(struct xfs_dir2_leaf_map_info, map) + |
820 | bp = NULL; | 1016 | (length * sizeof(struct xfs_bmbt_irec)), |
1017 | KM_SLEEP); | ||
1018 | map_info->map_size = length; | ||
821 | 1019 | ||
822 | /* | 1020 | /* |
823 | * Inside the loop we keep the main offset value as a byte offset | 1021 | * Inside the loop we keep the main offset value as a byte offset |
@@ -829,7 +1027,9 @@ xfs_dir2_leaf_getdents( | |||
829 | * Force this conversion through db so we truncate the offset | 1027 | * Force this conversion through db so we truncate the offset |
830 | * down to get the start of the data block. | 1028 | * down to get the start of the data block. |
831 | */ | 1029 | */ |
832 | map_off = xfs_dir2_db_to_da(mp, xfs_dir2_byte_to_db(mp, curoff)); | 1030 | map_info->map_off = xfs_dir2_db_to_da(mp, |
1031 | xfs_dir2_byte_to_db(mp, curoff)); | ||
1032 | |||
833 | /* | 1033 | /* |
834 | * Loop over directory entries until we reach the end offset. | 1034 | * Loop over directory entries until we reach the end offset. |
835 | * Get more blocks and readahead as necessary. | 1035 | * Get more blocks and readahead as necessary. |
@@ -839,191 +1039,17 @@ xfs_dir2_leaf_getdents( | |||
839 | * If we have no buffer, or we're off the end of the | 1039 | * If we have no buffer, or we're off the end of the |
840 | * current buffer, need to get another one. | 1040 | * current buffer, need to get another one. |
841 | */ | 1041 | */ |
842 | if (!bp || ptr >= (char *)bp->data + mp->m_dirblksize) { | 1042 | if (!bp || ptr >= (char *)bp->b_addr + mp->m_dirblksize) { |
843 | /* | ||
844 | * If we have a buffer, we need to release it and | ||
845 | * take it out of the mapping. | ||
846 | */ | ||
847 | if (bp) { | ||
848 | xfs_da_brelse(NULL, bp); | ||
849 | bp = NULL; | ||
850 | map_blocks -= mp->m_dirblkfsbs; | ||
851 | /* | ||
852 | * Loop to get rid of the extents for the | ||
853 | * directory block. | ||
854 | */ | ||
855 | for (i = mp->m_dirblkfsbs; i > 0; ) { | ||
856 | j = MIN((int)map->br_blockcount, i); | ||
857 | map->br_blockcount -= j; | ||
858 | map->br_startblock += j; | ||
859 | map->br_startoff += j; | ||
860 | /* | ||
861 | * If mapping is done, pitch it from | ||
862 | * the table. | ||
863 | */ | ||
864 | if (!map->br_blockcount && --map_valid) | ||
865 | memmove(&map[0], &map[1], | ||
866 | sizeof(map[0]) * | ||
867 | map_valid); | ||
868 | i -= j; | ||
869 | } | ||
870 | } | ||
871 | /* | ||
872 | * Recalculate the readahead blocks wanted. | ||
873 | */ | ||
874 | ra_want = howmany(bufsize + mp->m_dirblksize, | ||
875 | mp->m_sb.sb_blocksize) - 1; | ||
876 | ASSERT(ra_want >= 0); | ||
877 | 1043 | ||
878 | /* | 1044 | error = xfs_dir2_leaf_readbuf(dp, bufsize, map_info, |
879 | * If we don't have as many as we want, and we haven't | 1045 | &curoff, &bp); |
880 | * run out of data blocks, get some more mappings. | 1046 | if (error || !map_info->map_valid) |
881 | */ | ||
882 | if (1 + ra_want > map_blocks && | ||
883 | map_off < | ||
884 | xfs_dir2_byte_to_da(mp, XFS_DIR2_LEAF_OFFSET)) { | ||
885 | /* | ||
886 | * Get more bmaps, fill in after the ones | ||
887 | * we already have in the table. | ||
888 | */ | ||
889 | nmap = map_size - map_valid; | ||
890 | error = xfs_bmapi_read(dp, map_off, | ||
891 | xfs_dir2_byte_to_da(mp, | ||
892 | XFS_DIR2_LEAF_OFFSET) - map_off, | ||
893 | &map[map_valid], &nmap, 0); | ||
894 | /* | ||
895 | * Don't know if we should ignore this or | ||
896 | * try to return an error. | ||
897 | * The trouble with returning errors | ||
898 | * is that readdir will just stop without | ||
899 | * actually passing the error through. | ||
900 | */ | ||
901 | if (error) | ||
902 | break; /* XXX */ | ||
903 | /* | ||
904 | * If we got all the mappings we asked for, | ||
905 | * set the final map offset based on the | ||
906 | * last bmap value received. | ||
907 | * Otherwise, we've reached the end. | ||
908 | */ | ||
909 | if (nmap == map_size - map_valid) | ||
910 | map_off = | ||
911 | map[map_valid + nmap - 1].br_startoff + | ||
912 | map[map_valid + nmap - 1].br_blockcount; | ||
913 | else | ||
914 | map_off = | ||
915 | xfs_dir2_byte_to_da(mp, | ||
916 | XFS_DIR2_LEAF_OFFSET); | ||
917 | /* | ||
918 | * Look for holes in the mapping, and | ||
919 | * eliminate them. Count up the valid blocks. | ||
920 | */ | ||
921 | for (i = map_valid; i < map_valid + nmap; ) { | ||
922 | if (map[i].br_startblock == | ||
923 | HOLESTARTBLOCK) { | ||
924 | nmap--; | ||
925 | length = map_valid + nmap - i; | ||
926 | if (length) | ||
927 | memmove(&map[i], | ||
928 | &map[i + 1], | ||
929 | sizeof(map[i]) * | ||
930 | length); | ||
931 | } else { | ||
932 | map_blocks += | ||
933 | map[i].br_blockcount; | ||
934 | i++; | ||
935 | } | ||
936 | } | ||
937 | map_valid += nmap; | ||
938 | } | ||
939 | /* | ||
940 | * No valid mappings, so no more data blocks. | ||
941 | */ | ||
942 | if (!map_valid) { | ||
943 | curoff = xfs_dir2_da_to_byte(mp, map_off); | ||
944 | break; | 1047 | break; |
945 | } | 1048 | |
946 | /* | ||
947 | * Read the directory block starting at the first | ||
948 | * mapping. | ||
949 | */ | ||
950 | curdb = xfs_dir2_da_to_db(mp, map->br_startoff); | ||
951 | error = xfs_da_read_buf(NULL, dp, map->br_startoff, | ||
952 | map->br_blockcount >= mp->m_dirblkfsbs ? | ||
953 | XFS_FSB_TO_DADDR(mp, map->br_startblock) : | ||
954 | -1, | ||
955 | &bp, XFS_DATA_FORK); | ||
956 | /* | ||
957 | * Should just skip over the data block instead | ||
958 | * of giving up. | ||
959 | */ | ||
960 | if (error) | ||
961 | break; /* XXX */ | ||
962 | /* | ||
963 | * Adjust the current amount of read-ahead: we just | ||
964 | * read a block that was previously ra. | ||
965 | */ | ||
966 | if (ra_current) | ||
967 | ra_current -= mp->m_dirblkfsbs; | ||
968 | /* | ||
969 | * Do we need more readahead? | ||
970 | */ | ||
971 | for (ra_index = ra_offset = i = 0; | ||
972 | ra_want > ra_current && i < map_blocks; | ||
973 | i += mp->m_dirblkfsbs) { | ||
974 | ASSERT(ra_index < map_valid); | ||
975 | /* | ||
976 | * Read-ahead a contiguous directory block. | ||
977 | */ | ||
978 | if (i > ra_current && | ||
979 | map[ra_index].br_blockcount >= | ||
980 | mp->m_dirblkfsbs) { | ||
981 | xfs_buf_readahead(mp->m_ddev_targp, | ||
982 | XFS_FSB_TO_DADDR(mp, | ||
983 | map[ra_index].br_startblock + | ||
984 | ra_offset), | ||
985 | (int)BTOBB(mp->m_dirblksize)); | ||
986 | ra_current = i; | ||
987 | } | ||
988 | /* | ||
989 | * Read-ahead a non-contiguous directory block. | ||
990 | * This doesn't use our mapping, but this | ||
991 | * is a very rare case. | ||
992 | */ | ||
993 | else if (i > ra_current) { | ||
994 | (void)xfs_da_reada_buf(NULL, dp, | ||
995 | map[ra_index].br_startoff + | ||
996 | ra_offset, XFS_DATA_FORK); | ||
997 | ra_current = i; | ||
998 | } | ||
999 | /* | ||
1000 | * Advance offset through the mapping table. | ||
1001 | */ | ||
1002 | for (j = 0; j < mp->m_dirblkfsbs; j++) { | ||
1003 | /* | ||
1004 | * The rest of this extent but not | ||
1005 | * more than a dir block. | ||
1006 | */ | ||
1007 | length = MIN(mp->m_dirblkfsbs, | ||
1008 | (int)(map[ra_index].br_blockcount - | ||
1009 | ra_offset)); | ||
1010 | j += length; | ||
1011 | ra_offset += length; | ||
1012 | /* | ||
1013 | * Advance to the next mapping if | ||
1014 | * this one is used up. | ||
1015 | */ | ||
1016 | if (ra_offset == | ||
1017 | map[ra_index].br_blockcount) { | ||
1018 | ra_offset = 0; | ||
1019 | ra_index++; | ||
1020 | } | ||
1021 | } | ||
1022 | } | ||
1023 | /* | 1049 | /* |
1024 | * Having done a read, we need to set a new offset. | 1050 | * Having done a read, we need to set a new offset. |
1025 | */ | 1051 | */ |
1026 | newoff = xfs_dir2_db_off_to_byte(mp, curdb, 0); | 1052 | newoff = xfs_dir2_db_off_to_byte(mp, map_info->curdb, 0); |
1027 | /* | 1053 | /* |
1028 | * Start of the current block. | 1054 | * Start of the current block. |
1029 | */ | 1055 | */ |
@@ -1034,8 +1060,8 @@ xfs_dir2_leaf_getdents( | |||
1034 | */ | 1060 | */ |
1035 | else if (curoff > newoff) | 1061 | else if (curoff > newoff) |
1036 | ASSERT(xfs_dir2_byte_to_db(mp, curoff) == | 1062 | ASSERT(xfs_dir2_byte_to_db(mp, curoff) == |
1037 | curdb); | 1063 | map_info->curdb); |
1038 | hdr = bp->data; | 1064 | hdr = bp->b_addr; |
1039 | xfs_dir2_data_check(dp, bp); | 1065 | xfs_dir2_data_check(dp, bp); |
1040 | /* | 1066 | /* |
1041 | * Find our position in the block. | 1067 | * Find our position in the block. |
@@ -1117,9 +1143,9 @@ xfs_dir2_leaf_getdents( | |||
1117 | *offset = XFS_DIR2_MAX_DATAPTR & 0x7fffffff; | 1143 | *offset = XFS_DIR2_MAX_DATAPTR & 0x7fffffff; |
1118 | else | 1144 | else |
1119 | *offset = xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff; | 1145 | *offset = xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff; |
1120 | kmem_free(map); | 1146 | kmem_free(map_info); |
1121 | if (bp) | 1147 | if (bp) |
1122 | xfs_da_brelse(NULL, bp); | 1148 | xfs_trans_brelse(NULL, bp); |
1123 | return error; | 1149 | return error; |
1124 | } | 1150 | } |
1125 | 1151 | ||
@@ -1130,10 +1156,10 @@ int | |||
1130 | xfs_dir2_leaf_init( | 1156 | xfs_dir2_leaf_init( |
1131 | xfs_da_args_t *args, /* operation arguments */ | 1157 | xfs_da_args_t *args, /* operation arguments */ |
1132 | xfs_dir2_db_t bno, /* directory block number */ | 1158 | xfs_dir2_db_t bno, /* directory block number */ |
1133 | xfs_dabuf_t **bpp, /* out: leaf buffer */ | 1159 | struct xfs_buf **bpp, /* out: leaf buffer */ |
1134 | int magic) /* magic number for block */ | 1160 | int magic) /* magic number for block */ |
1135 | { | 1161 | { |
1136 | xfs_dabuf_t *bp; /* leaf buffer */ | 1162 | struct xfs_buf *bp; /* leaf buffer */ |
1137 | xfs_inode_t *dp; /* incore directory inode */ | 1163 | xfs_inode_t *dp; /* incore directory inode */ |
1138 | int error; /* error return code */ | 1164 | int error; /* error return code */ |
1139 | xfs_dir2_leaf_t *leaf; /* leaf structure */ | 1165 | xfs_dir2_leaf_t *leaf; /* leaf structure */ |
@@ -1156,7 +1182,7 @@ xfs_dir2_leaf_init( | |||
1156 | return error; | 1182 | return error; |
1157 | } | 1183 | } |
1158 | ASSERT(bp != NULL); | 1184 | ASSERT(bp != NULL); |
1159 | leaf = bp->data; | 1185 | leaf = bp->b_addr; |
1160 | /* | 1186 | /* |
1161 | * Initialize the header. | 1187 | * Initialize the header. |
1162 | */ | 1188 | */ |
@@ -1186,7 +1212,7 @@ xfs_dir2_leaf_init( | |||
1186 | static void | 1212 | static void |
1187 | xfs_dir2_leaf_log_bests( | 1213 | xfs_dir2_leaf_log_bests( |
1188 | xfs_trans_t *tp, /* transaction pointer */ | 1214 | xfs_trans_t *tp, /* transaction pointer */ |
1189 | xfs_dabuf_t *bp, /* leaf buffer */ | 1215 | struct xfs_buf *bp, /* leaf buffer */ |
1190 | int first, /* first entry to log */ | 1216 | int first, /* first entry to log */ |
1191 | int last) /* last entry to log */ | 1217 | int last) /* last entry to log */ |
1192 | { | 1218 | { |
@@ -1195,12 +1221,12 @@ xfs_dir2_leaf_log_bests( | |||
1195 | xfs_dir2_leaf_t *leaf; /* leaf structure */ | 1221 | xfs_dir2_leaf_t *leaf; /* leaf structure */ |
1196 | xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ | 1222 | xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ |
1197 | 1223 | ||
1198 | leaf = bp->data; | 1224 | leaf = bp->b_addr; |
1199 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC)); | 1225 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC)); |
1200 | ltp = xfs_dir2_leaf_tail_p(tp->t_mountp, leaf); | 1226 | ltp = xfs_dir2_leaf_tail_p(tp->t_mountp, leaf); |
1201 | firstb = xfs_dir2_leaf_bests_p(ltp) + first; | 1227 | firstb = xfs_dir2_leaf_bests_p(ltp) + first; |
1202 | lastb = xfs_dir2_leaf_bests_p(ltp) + last; | 1228 | lastb = xfs_dir2_leaf_bests_p(ltp) + last; |
1203 | xfs_da_log_buf(tp, bp, (uint)((char *)firstb - (char *)leaf), | 1229 | xfs_trans_log_buf(tp, bp, (uint)((char *)firstb - (char *)leaf), |
1204 | (uint)((char *)lastb - (char *)leaf + sizeof(*lastb) - 1)); | 1230 | (uint)((char *)lastb - (char *)leaf + sizeof(*lastb) - 1)); |
1205 | } | 1231 | } |
1206 | 1232 | ||
@@ -1210,7 +1236,7 @@ xfs_dir2_leaf_log_bests( | |||
1210 | void | 1236 | void |
1211 | xfs_dir2_leaf_log_ents( | 1237 | xfs_dir2_leaf_log_ents( |
1212 | xfs_trans_t *tp, /* transaction pointer */ | 1238 | xfs_trans_t *tp, /* transaction pointer */ |
1213 | xfs_dabuf_t *bp, /* leaf buffer */ | 1239 | struct xfs_buf *bp, /* leaf buffer */ |
1214 | int first, /* first entry to log */ | 1240 | int first, /* first entry to log */ |
1215 | int last) /* last entry to log */ | 1241 | int last) /* last entry to log */ |
1216 | { | 1242 | { |
@@ -1218,12 +1244,12 @@ xfs_dir2_leaf_log_ents( | |||
1218 | xfs_dir2_leaf_entry_t *lastlep; /* pointer to last entry */ | 1244 | xfs_dir2_leaf_entry_t *lastlep; /* pointer to last entry */ |
1219 | xfs_dir2_leaf_t *leaf; /* leaf structure */ | 1245 | xfs_dir2_leaf_t *leaf; /* leaf structure */ |
1220 | 1246 | ||
1221 | leaf = bp->data; | 1247 | leaf = bp->b_addr; |
1222 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) || | 1248 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) || |
1223 | leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); | 1249 | leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); |
1224 | firstlep = &leaf->ents[first]; | 1250 | firstlep = &leaf->ents[first]; |
1225 | lastlep = &leaf->ents[last]; | 1251 | lastlep = &leaf->ents[last]; |
1226 | xfs_da_log_buf(tp, bp, (uint)((char *)firstlep - (char *)leaf), | 1252 | xfs_trans_log_buf(tp, bp, (uint)((char *)firstlep - (char *)leaf), |
1227 | (uint)((char *)lastlep - (char *)leaf + sizeof(*lastlep) - 1)); | 1253 | (uint)((char *)lastlep - (char *)leaf + sizeof(*lastlep) - 1)); |
1228 | } | 1254 | } |
1229 | 1255 | ||
@@ -1232,15 +1258,15 @@ xfs_dir2_leaf_log_ents( | |||
1232 | */ | 1258 | */ |
1233 | void | 1259 | void |
1234 | xfs_dir2_leaf_log_header( | 1260 | xfs_dir2_leaf_log_header( |
1235 | xfs_trans_t *tp, /* transaction pointer */ | 1261 | struct xfs_trans *tp, |
1236 | xfs_dabuf_t *bp) /* leaf buffer */ | 1262 | struct xfs_buf *bp) |
1237 | { | 1263 | { |
1238 | xfs_dir2_leaf_t *leaf; /* leaf structure */ | 1264 | xfs_dir2_leaf_t *leaf; /* leaf structure */ |
1239 | 1265 | ||
1240 | leaf = bp->data; | 1266 | leaf = bp->b_addr; |
1241 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) || | 1267 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) || |
1242 | leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); | 1268 | leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); |
1243 | xfs_da_log_buf(tp, bp, (uint)((char *)&leaf->hdr - (char *)leaf), | 1269 | xfs_trans_log_buf(tp, bp, (uint)((char *)&leaf->hdr - (char *)leaf), |
1244 | (uint)(sizeof(leaf->hdr) - 1)); | 1270 | (uint)(sizeof(leaf->hdr) - 1)); |
1245 | } | 1271 | } |
1246 | 1272 | ||
@@ -1249,18 +1275,18 @@ xfs_dir2_leaf_log_header( | |||
1249 | */ | 1275 | */ |
1250 | STATIC void | 1276 | STATIC void |
1251 | xfs_dir2_leaf_log_tail( | 1277 | xfs_dir2_leaf_log_tail( |
1252 | xfs_trans_t *tp, /* transaction pointer */ | 1278 | struct xfs_trans *tp, |
1253 | xfs_dabuf_t *bp) /* leaf buffer */ | 1279 | struct xfs_buf *bp) |
1254 | { | 1280 | { |
1255 | xfs_dir2_leaf_t *leaf; /* leaf structure */ | 1281 | xfs_dir2_leaf_t *leaf; /* leaf structure */ |
1256 | xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ | 1282 | xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ |
1257 | xfs_mount_t *mp; /* filesystem mount point */ | 1283 | xfs_mount_t *mp; /* filesystem mount point */ |
1258 | 1284 | ||
1259 | mp = tp->t_mountp; | 1285 | mp = tp->t_mountp; |
1260 | leaf = bp->data; | 1286 | leaf = bp->b_addr; |
1261 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC)); | 1287 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC)); |
1262 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); | 1288 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); |
1263 | xfs_da_log_buf(tp, bp, (uint)((char *)ltp - (char *)leaf), | 1289 | xfs_trans_log_buf(tp, bp, (uint)((char *)ltp - (char *)leaf), |
1264 | (uint)(mp->m_dirblksize - 1)); | 1290 | (uint)(mp->m_dirblksize - 1)); |
1265 | } | 1291 | } |
1266 | 1292 | ||
@@ -1273,12 +1299,12 @@ int | |||
1273 | xfs_dir2_leaf_lookup( | 1299 | xfs_dir2_leaf_lookup( |
1274 | xfs_da_args_t *args) /* operation arguments */ | 1300 | xfs_da_args_t *args) /* operation arguments */ |
1275 | { | 1301 | { |
1276 | xfs_dabuf_t *dbp; /* data block buffer */ | 1302 | struct xfs_buf *dbp; /* data block buffer */ |
1277 | xfs_dir2_data_entry_t *dep; /* data block entry */ | 1303 | xfs_dir2_data_entry_t *dep; /* data block entry */ |
1278 | xfs_inode_t *dp; /* incore directory inode */ | 1304 | xfs_inode_t *dp; /* incore directory inode */ |
1279 | int error; /* error return code */ | 1305 | int error; /* error return code */ |
1280 | int index; /* found entry index */ | 1306 | int index; /* found entry index */ |
1281 | xfs_dabuf_t *lbp; /* leaf buffer */ | 1307 | struct xfs_buf *lbp; /* leaf buffer */ |
1282 | xfs_dir2_leaf_t *leaf; /* leaf structure */ | 1308 | xfs_dir2_leaf_t *leaf; /* leaf structure */ |
1283 | xfs_dir2_leaf_entry_t *lep; /* leaf entry */ | 1309 | xfs_dir2_leaf_entry_t *lep; /* leaf entry */ |
1284 | xfs_trans_t *tp; /* transaction pointer */ | 1310 | xfs_trans_t *tp; /* transaction pointer */ |
@@ -1294,7 +1320,7 @@ xfs_dir2_leaf_lookup( | |||
1294 | tp = args->trans; | 1320 | tp = args->trans; |
1295 | dp = args->dp; | 1321 | dp = args->dp; |
1296 | xfs_dir2_leaf_check(dp, lbp); | 1322 | xfs_dir2_leaf_check(dp, lbp); |
1297 | leaf = lbp->data; | 1323 | leaf = lbp->b_addr; |
1298 | /* | 1324 | /* |
1299 | * Get to the leaf entry and contained data entry address. | 1325 | * Get to the leaf entry and contained data entry address. |
1300 | */ | 1326 | */ |
@@ -1303,15 +1329,15 @@ xfs_dir2_leaf_lookup( | |||
1303 | * Point to the data entry. | 1329 | * Point to the data entry. |
1304 | */ | 1330 | */ |
1305 | dep = (xfs_dir2_data_entry_t *) | 1331 | dep = (xfs_dir2_data_entry_t *) |
1306 | ((char *)dbp->data + | 1332 | ((char *)dbp->b_addr + |
1307 | xfs_dir2_dataptr_to_off(dp->i_mount, be32_to_cpu(lep->address))); | 1333 | xfs_dir2_dataptr_to_off(dp->i_mount, be32_to_cpu(lep->address))); |
1308 | /* | 1334 | /* |
1309 | * Return the found inode number & CI name if appropriate | 1335 | * Return the found inode number & CI name if appropriate |
1310 | */ | 1336 | */ |
1311 | args->inumber = be64_to_cpu(dep->inumber); | 1337 | args->inumber = be64_to_cpu(dep->inumber); |
1312 | error = xfs_dir_cilookup_result(args, dep->name, dep->namelen); | 1338 | error = xfs_dir_cilookup_result(args, dep->name, dep->namelen); |
1313 | xfs_da_brelse(tp, dbp); | 1339 | xfs_trans_brelse(tp, dbp); |
1314 | xfs_da_brelse(tp, lbp); | 1340 | xfs_trans_brelse(tp, lbp); |
1315 | return XFS_ERROR(error); | 1341 | return XFS_ERROR(error); |
1316 | } | 1342 | } |
1317 | 1343 | ||
@@ -1324,17 +1350,17 @@ xfs_dir2_leaf_lookup( | |||
1324 | static int /* error */ | 1350 | static int /* error */ |
1325 | xfs_dir2_leaf_lookup_int( | 1351 | xfs_dir2_leaf_lookup_int( |
1326 | xfs_da_args_t *args, /* operation arguments */ | 1352 | xfs_da_args_t *args, /* operation arguments */ |
1327 | xfs_dabuf_t **lbpp, /* out: leaf buffer */ | 1353 | struct xfs_buf **lbpp, /* out: leaf buffer */ |
1328 | int *indexp, /* out: index in leaf block */ | 1354 | int *indexp, /* out: index in leaf block */ |
1329 | xfs_dabuf_t **dbpp) /* out: data buffer */ | 1355 | struct xfs_buf **dbpp) /* out: data buffer */ |
1330 | { | 1356 | { |
1331 | xfs_dir2_db_t curdb = -1; /* current data block number */ | 1357 | xfs_dir2_db_t curdb = -1; /* current data block number */ |
1332 | xfs_dabuf_t *dbp = NULL; /* data buffer */ | 1358 | struct xfs_buf *dbp = NULL; /* data buffer */ |
1333 | xfs_dir2_data_entry_t *dep; /* data entry */ | 1359 | xfs_dir2_data_entry_t *dep; /* data entry */ |
1334 | xfs_inode_t *dp; /* incore directory inode */ | 1360 | xfs_inode_t *dp; /* incore directory inode */ |
1335 | int error; /* error return code */ | 1361 | int error; /* error return code */ |
1336 | int index; /* index in leaf block */ | 1362 | int index; /* index in leaf block */ |
1337 | xfs_dabuf_t *lbp; /* leaf buffer */ | 1363 | struct xfs_buf *lbp; /* leaf buffer */ |
1338 | xfs_dir2_leaf_entry_t *lep; /* leaf entry */ | 1364 | xfs_dir2_leaf_entry_t *lep; /* leaf entry */ |
1339 | xfs_dir2_leaf_t *leaf; /* leaf structure */ | 1365 | xfs_dir2_leaf_t *leaf; /* leaf structure */ |
1340 | xfs_mount_t *mp; /* filesystem mount point */ | 1366 | xfs_mount_t *mp; /* filesystem mount point */ |
@@ -1354,7 +1380,7 @@ xfs_dir2_leaf_lookup_int( | |||
1354 | if (error) | 1380 | if (error) |
1355 | return error; | 1381 | return error; |
1356 | *lbpp = lbp; | 1382 | *lbpp = lbp; |
1357 | leaf = lbp->data; | 1383 | leaf = lbp->b_addr; |
1358 | xfs_dir2_leaf_check(dp, lbp); | 1384 | xfs_dir2_leaf_check(dp, lbp); |
1359 | /* | 1385 | /* |
1360 | * Look for the first leaf entry with our hash value. | 1386 | * Look for the first leaf entry with our hash value. |
@@ -1382,12 +1408,12 @@ xfs_dir2_leaf_lookup_int( | |||
1382 | */ | 1408 | */ |
1383 | if (newdb != curdb) { | 1409 | if (newdb != curdb) { |
1384 | if (dbp) | 1410 | if (dbp) |
1385 | xfs_da_brelse(tp, dbp); | 1411 | xfs_trans_brelse(tp, dbp); |
1386 | error = xfs_da_read_buf(tp, dp, | 1412 | error = xfs_da_read_buf(tp, dp, |
1387 | xfs_dir2_db_to_da(mp, newdb), | 1413 | xfs_dir2_db_to_da(mp, newdb), |
1388 | -1, &dbp, XFS_DATA_FORK); | 1414 | -1, &dbp, XFS_DATA_FORK); |
1389 | if (error) { | 1415 | if (error) { |
1390 | xfs_da_brelse(tp, lbp); | 1416 | xfs_trans_brelse(tp, lbp); |
1391 | return error; | 1417 | return error; |
1392 | } | 1418 | } |
1393 | xfs_dir2_data_check(dp, dbp); | 1419 | xfs_dir2_data_check(dp, dbp); |
@@ -1396,7 +1422,7 @@ xfs_dir2_leaf_lookup_int( | |||
1396 | /* | 1422 | /* |
1397 | * Point to the data entry. | 1423 | * Point to the data entry. |
1398 | */ | 1424 | */ |
1399 | dep = (xfs_dir2_data_entry_t *)((char *)dbp->data + | 1425 | dep = (xfs_dir2_data_entry_t *)((char *)dbp->b_addr + |
1400 | xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); | 1426 | xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); |
1401 | /* | 1427 | /* |
1402 | * Compare name and if it's an exact match, return the index | 1428 | * Compare name and if it's an exact match, return the index |
@@ -1424,12 +1450,12 @@ xfs_dir2_leaf_lookup_int( | |||
1424 | if (args->cmpresult == XFS_CMP_CASE) { | 1450 | if (args->cmpresult == XFS_CMP_CASE) { |
1425 | ASSERT(cidb != -1); | 1451 | ASSERT(cidb != -1); |
1426 | if (cidb != curdb) { | 1452 | if (cidb != curdb) { |
1427 | xfs_da_brelse(tp, dbp); | 1453 | xfs_trans_brelse(tp, dbp); |
1428 | error = xfs_da_read_buf(tp, dp, | 1454 | error = xfs_da_read_buf(tp, dp, |
1429 | xfs_dir2_db_to_da(mp, cidb), | 1455 | xfs_dir2_db_to_da(mp, cidb), |
1430 | -1, &dbp, XFS_DATA_FORK); | 1456 | -1, &dbp, XFS_DATA_FORK); |
1431 | if (error) { | 1457 | if (error) { |
1432 | xfs_da_brelse(tp, lbp); | 1458 | xfs_trans_brelse(tp, lbp); |
1433 | return error; | 1459 | return error; |
1434 | } | 1460 | } |
1435 | } | 1461 | } |
@@ -1441,8 +1467,8 @@ xfs_dir2_leaf_lookup_int( | |||
1441 | */ | 1467 | */ |
1442 | ASSERT(cidb == -1); | 1468 | ASSERT(cidb == -1); |
1443 | if (dbp) | 1469 | if (dbp) |
1444 | xfs_da_brelse(tp, dbp); | 1470 | xfs_trans_brelse(tp, dbp); |
1445 | xfs_da_brelse(tp, lbp); | 1471 | xfs_trans_brelse(tp, lbp); |
1446 | return XFS_ERROR(ENOENT); | 1472 | return XFS_ERROR(ENOENT); |
1447 | } | 1473 | } |
1448 | 1474 | ||
@@ -1456,13 +1482,13 @@ xfs_dir2_leaf_removename( | |||
1456 | __be16 *bestsp; /* leaf block best freespace */ | 1482 | __be16 *bestsp; /* leaf block best freespace */ |
1457 | xfs_dir2_data_hdr_t *hdr; /* data block header */ | 1483 | xfs_dir2_data_hdr_t *hdr; /* data block header */ |
1458 | xfs_dir2_db_t db; /* data block number */ | 1484 | xfs_dir2_db_t db; /* data block number */ |
1459 | xfs_dabuf_t *dbp; /* data block buffer */ | 1485 | struct xfs_buf *dbp; /* data block buffer */ |
1460 | xfs_dir2_data_entry_t *dep; /* data entry structure */ | 1486 | xfs_dir2_data_entry_t *dep; /* data entry structure */ |
1461 | xfs_inode_t *dp; /* incore directory inode */ | 1487 | xfs_inode_t *dp; /* incore directory inode */ |
1462 | int error; /* error return code */ | 1488 | int error; /* error return code */ |
1463 | xfs_dir2_db_t i; /* temporary data block # */ | 1489 | xfs_dir2_db_t i; /* temporary data block # */ |
1464 | int index; /* index into leaf entries */ | 1490 | int index; /* index into leaf entries */ |
1465 | xfs_dabuf_t *lbp; /* leaf buffer */ | 1491 | struct xfs_buf *lbp; /* leaf buffer */ |
1466 | xfs_dir2_leaf_t *leaf; /* leaf structure */ | 1492 | xfs_dir2_leaf_t *leaf; /* leaf structure */ |
1467 | xfs_dir2_leaf_entry_t *lep; /* leaf entry */ | 1493 | xfs_dir2_leaf_entry_t *lep; /* leaf entry */ |
1468 | xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ | 1494 | xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ |
@@ -1483,8 +1509,8 @@ xfs_dir2_leaf_removename( | |||
1483 | dp = args->dp; | 1509 | dp = args->dp; |
1484 | tp = args->trans; | 1510 | tp = args->trans; |
1485 | mp = dp->i_mount; | 1511 | mp = dp->i_mount; |
1486 | leaf = lbp->data; | 1512 | leaf = lbp->b_addr; |
1487 | hdr = dbp->data; | 1513 | hdr = dbp->b_addr; |
1488 | xfs_dir2_data_check(dp, dbp); | 1514 | xfs_dir2_data_check(dp, dbp); |
1489 | /* | 1515 | /* |
1490 | * Point to the leaf entry, use that to point to the data entry. | 1516 | * Point to the leaf entry, use that to point to the data entry. |
@@ -1541,12 +1567,9 @@ xfs_dir2_leaf_removename( | |||
1541 | * Just go on, returning success, leaving the | 1567 | * Just go on, returning success, leaving the |
1542 | * empty block in place. | 1568 | * empty block in place. |
1543 | */ | 1569 | */ |
1544 | if (error == ENOSPC && args->total == 0) { | 1570 | if (error == ENOSPC && args->total == 0) |
1545 | xfs_da_buf_done(dbp); | ||
1546 | error = 0; | 1571 | error = 0; |
1547 | } | ||
1548 | xfs_dir2_leaf_check(dp, lbp); | 1572 | xfs_dir2_leaf_check(dp, lbp); |
1549 | xfs_da_buf_done(lbp); | ||
1550 | return error; | 1573 | return error; |
1551 | } | 1574 | } |
1552 | dbp = NULL; | 1575 | dbp = NULL; |
@@ -1577,10 +1600,9 @@ xfs_dir2_leaf_removename( | |||
1577 | /* | 1600 | /* |
1578 | * If the data block was not the first one, drop it. | 1601 | * If the data block was not the first one, drop it. |
1579 | */ | 1602 | */ |
1580 | else if (db != mp->m_dirdatablk && dbp != NULL) { | 1603 | else if (db != mp->m_dirdatablk) |
1581 | xfs_da_buf_done(dbp); | ||
1582 | dbp = NULL; | 1604 | dbp = NULL; |
1583 | } | 1605 | |
1584 | xfs_dir2_leaf_check(dp, lbp); | 1606 | xfs_dir2_leaf_check(dp, lbp); |
1585 | /* | 1607 | /* |
1586 | * See if we can convert to block form. | 1608 | * See if we can convert to block form. |
@@ -1595,12 +1617,12 @@ int /* error */ | |||
1595 | xfs_dir2_leaf_replace( | 1617 | xfs_dir2_leaf_replace( |
1596 | xfs_da_args_t *args) /* operation arguments */ | 1618 | xfs_da_args_t *args) /* operation arguments */ |
1597 | { | 1619 | { |
1598 | xfs_dabuf_t *dbp; /* data block buffer */ | 1620 | struct xfs_buf *dbp; /* data block buffer */ |
1599 | xfs_dir2_data_entry_t *dep; /* data block entry */ | 1621 | xfs_dir2_data_entry_t *dep; /* data block entry */ |
1600 | xfs_inode_t *dp; /* incore directory inode */ | 1622 | xfs_inode_t *dp; /* incore directory inode */ |
1601 | int error; /* error return code */ | 1623 | int error; /* error return code */ |
1602 | int index; /* index of leaf entry */ | 1624 | int index; /* index of leaf entry */ |
1603 | xfs_dabuf_t *lbp; /* leaf buffer */ | 1625 | struct xfs_buf *lbp; /* leaf buffer */ |
1604 | xfs_dir2_leaf_t *leaf; /* leaf structure */ | 1626 | xfs_dir2_leaf_t *leaf; /* leaf structure */ |
1605 | xfs_dir2_leaf_entry_t *lep; /* leaf entry */ | 1627 | xfs_dir2_leaf_entry_t *lep; /* leaf entry */ |
1606 | xfs_trans_t *tp; /* transaction pointer */ | 1628 | xfs_trans_t *tp; /* transaction pointer */ |
@@ -1614,7 +1636,7 @@ xfs_dir2_leaf_replace( | |||
1614 | return error; | 1636 | return error; |
1615 | } | 1637 | } |
1616 | dp = args->dp; | 1638 | dp = args->dp; |
1617 | leaf = lbp->data; | 1639 | leaf = lbp->b_addr; |
1618 | /* | 1640 | /* |
1619 | * Point to the leaf entry, get data address from it. | 1641 | * Point to the leaf entry, get data address from it. |
1620 | */ | 1642 | */ |
@@ -1623,7 +1645,7 @@ xfs_dir2_leaf_replace( | |||
1623 | * Point to the data entry. | 1645 | * Point to the data entry. |
1624 | */ | 1646 | */ |
1625 | dep = (xfs_dir2_data_entry_t *) | 1647 | dep = (xfs_dir2_data_entry_t *) |
1626 | ((char *)dbp->data + | 1648 | ((char *)dbp->b_addr + |
1627 | xfs_dir2_dataptr_to_off(dp->i_mount, be32_to_cpu(lep->address))); | 1649 | xfs_dir2_dataptr_to_off(dp->i_mount, be32_to_cpu(lep->address))); |
1628 | ASSERT(args->inumber != be64_to_cpu(dep->inumber)); | 1650 | ASSERT(args->inumber != be64_to_cpu(dep->inumber)); |
1629 | /* | 1651 | /* |
@@ -1632,9 +1654,8 @@ xfs_dir2_leaf_replace( | |||
1632 | dep->inumber = cpu_to_be64(args->inumber); | 1654 | dep->inumber = cpu_to_be64(args->inumber); |
1633 | tp = args->trans; | 1655 | tp = args->trans; |
1634 | xfs_dir2_data_log_entry(tp, dbp, dep); | 1656 | xfs_dir2_data_log_entry(tp, dbp, dep); |
1635 | xfs_da_buf_done(dbp); | ||
1636 | xfs_dir2_leaf_check(dp, lbp); | 1657 | xfs_dir2_leaf_check(dp, lbp); |
1637 | xfs_da_brelse(tp, lbp); | 1658 | xfs_trans_brelse(tp, lbp); |
1638 | return 0; | 1659 | return 0; |
1639 | } | 1660 | } |
1640 | 1661 | ||
@@ -1646,7 +1667,7 @@ xfs_dir2_leaf_replace( | |||
1646 | int /* index value */ | 1667 | int /* index value */ |
1647 | xfs_dir2_leaf_search_hash( | 1668 | xfs_dir2_leaf_search_hash( |
1648 | xfs_da_args_t *args, /* operation arguments */ | 1669 | xfs_da_args_t *args, /* operation arguments */ |
1649 | xfs_dabuf_t *lbp) /* leaf buffer */ | 1670 | struct xfs_buf *lbp) /* leaf buffer */ |
1650 | { | 1671 | { |
1651 | xfs_dahash_t hash=0; /* hash from this entry */ | 1672 | xfs_dahash_t hash=0; /* hash from this entry */ |
1652 | xfs_dahash_t hashwant; /* hash value looking for */ | 1673 | xfs_dahash_t hashwant; /* hash value looking for */ |
@@ -1656,7 +1677,7 @@ xfs_dir2_leaf_search_hash( | |||
1656 | xfs_dir2_leaf_entry_t *lep; /* leaf entry */ | 1677 | xfs_dir2_leaf_entry_t *lep; /* leaf entry */ |
1657 | int mid=0; /* current leaf index */ | 1678 | int mid=0; /* current leaf index */ |
1658 | 1679 | ||
1659 | leaf = lbp->data; | 1680 | leaf = lbp->b_addr; |
1660 | #ifndef __KERNEL__ | 1681 | #ifndef __KERNEL__ |
1661 | if (!leaf->hdr.count) | 1682 | if (!leaf->hdr.count) |
1662 | return 0; | 1683 | return 0; |
@@ -1699,11 +1720,11 @@ xfs_dir2_leaf_search_hash( | |||
1699 | int /* error */ | 1720 | int /* error */ |
1700 | xfs_dir2_leaf_trim_data( | 1721 | xfs_dir2_leaf_trim_data( |
1701 | xfs_da_args_t *args, /* operation arguments */ | 1722 | xfs_da_args_t *args, /* operation arguments */ |
1702 | xfs_dabuf_t *lbp, /* leaf buffer */ | 1723 | struct xfs_buf *lbp, /* leaf buffer */ |
1703 | xfs_dir2_db_t db) /* data block number */ | 1724 | xfs_dir2_db_t db) /* data block number */ |
1704 | { | 1725 | { |
1705 | __be16 *bestsp; /* leaf bests table */ | 1726 | __be16 *bestsp; /* leaf bests table */ |
1706 | xfs_dabuf_t *dbp; /* data block buffer */ | 1727 | struct xfs_buf *dbp; /* data block buffer */ |
1707 | xfs_inode_t *dp; /* incore directory inode */ | 1728 | xfs_inode_t *dp; /* incore directory inode */ |
1708 | int error; /* error return value */ | 1729 | int error; /* error return value */ |
1709 | xfs_dir2_leaf_t *leaf; /* leaf structure */ | 1730 | xfs_dir2_leaf_t *leaf; /* leaf structure */ |
@@ -1722,12 +1743,12 @@ xfs_dir2_leaf_trim_data( | |||
1722 | return error; | 1743 | return error; |
1723 | } | 1744 | } |
1724 | 1745 | ||
1725 | leaf = lbp->data; | 1746 | leaf = lbp->b_addr; |
1726 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); | 1747 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); |
1727 | 1748 | ||
1728 | #ifdef DEBUG | 1749 | #ifdef DEBUG |
1729 | { | 1750 | { |
1730 | struct xfs_dir2_data_hdr *hdr = dbp->data; | 1751 | struct xfs_dir2_data_hdr *hdr = dbp->b_addr; |
1731 | 1752 | ||
1732 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC)); | 1753 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC)); |
1733 | ASSERT(be16_to_cpu(hdr->bestfree[0].length) == | 1754 | ASSERT(be16_to_cpu(hdr->bestfree[0].length) == |
@@ -1741,7 +1762,7 @@ xfs_dir2_leaf_trim_data( | |||
1741 | */ | 1762 | */ |
1742 | if ((error = xfs_dir2_shrink_inode(args, db, dbp))) { | 1763 | if ((error = xfs_dir2_shrink_inode(args, db, dbp))) { |
1743 | ASSERT(error != ENOSPC); | 1764 | ASSERT(error != ENOSPC); |
1744 | xfs_da_brelse(tp, dbp); | 1765 | xfs_trans_brelse(tp, dbp); |
1745 | return error; | 1766 | return error; |
1746 | } | 1767 | } |
1747 | /* | 1768 | /* |
@@ -1781,10 +1802,10 @@ xfs_dir2_node_to_leaf( | |||
1781 | xfs_da_args_t *args; /* operation arguments */ | 1802 | xfs_da_args_t *args; /* operation arguments */ |
1782 | xfs_inode_t *dp; /* incore directory inode */ | 1803 | xfs_inode_t *dp; /* incore directory inode */ |
1783 | int error; /* error return code */ | 1804 | int error; /* error return code */ |
1784 | xfs_dabuf_t *fbp; /* buffer for freespace block */ | 1805 | struct xfs_buf *fbp; /* buffer for freespace block */ |
1785 | xfs_fileoff_t fo; /* freespace file offset */ | 1806 | xfs_fileoff_t fo; /* freespace file offset */ |
1786 | xfs_dir2_free_t *free; /* freespace structure */ | 1807 | xfs_dir2_free_t *free; /* freespace structure */ |
1787 | xfs_dabuf_t *lbp; /* buffer for leaf block */ | 1808 | struct xfs_buf *lbp; /* buffer for leaf block */ |
1788 | xfs_dir2_leaf_tail_t *ltp; /* tail of leaf structure */ | 1809 | xfs_dir2_leaf_tail_t *ltp; /* tail of leaf structure */ |
1789 | xfs_dir2_leaf_t *leaf; /* leaf structure */ | 1810 | xfs_dir2_leaf_t *leaf; /* leaf structure */ |
1790 | xfs_mount_t *mp; /* filesystem mount point */ | 1811 | xfs_mount_t *mp; /* filesystem mount point */ |
@@ -1838,7 +1859,7 @@ xfs_dir2_node_to_leaf( | |||
1838 | if (XFS_FSB_TO_B(mp, fo) > XFS_DIR2_LEAF_OFFSET + mp->m_dirblksize) | 1859 | if (XFS_FSB_TO_B(mp, fo) > XFS_DIR2_LEAF_OFFSET + mp->m_dirblksize) |
1839 | return 0; | 1860 | return 0; |
1840 | lbp = state->path.blk[0].bp; | 1861 | lbp = state->path.blk[0].bp; |
1841 | leaf = lbp->data; | 1862 | leaf = lbp->b_addr; |
1842 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); | 1863 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); |
1843 | /* | 1864 | /* |
1844 | * Read the freespace block. | 1865 | * Read the freespace block. |
@@ -1847,7 +1868,7 @@ xfs_dir2_node_to_leaf( | |||
1847 | XFS_DATA_FORK))) { | 1868 | XFS_DATA_FORK))) { |
1848 | return error; | 1869 | return error; |
1849 | } | 1870 | } |
1850 | free = fbp->data; | 1871 | free = fbp->b_addr; |
1851 | ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC)); | 1872 | ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC)); |
1852 | ASSERT(!free->hdr.firstdb); | 1873 | ASSERT(!free->hdr.firstdb); |
1853 | 1874 | ||
@@ -1857,7 +1878,7 @@ xfs_dir2_node_to_leaf( | |||
1857 | */ | 1878 | */ |
1858 | if (xfs_dir2_leaf_size(&leaf->hdr, be32_to_cpu(free->hdr.nvalid)) > | 1879 | if (xfs_dir2_leaf_size(&leaf->hdr, be32_to_cpu(free->hdr.nvalid)) > |
1859 | mp->m_dirblksize) { | 1880 | mp->m_dirblksize) { |
1860 | xfs_da_brelse(tp, fbp); | 1881 | xfs_trans_brelse(tp, fbp); |
1861 | return 0; | 1882 | return 0; |
1862 | } | 1883 | } |
1863 | 1884 | ||
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c index b0f26780449d..6c7052406605 100644 --- a/fs/xfs/xfs_dir2_node.c +++ b/fs/xfs/xfs_dir2_node.c | |||
@@ -36,20 +36,20 @@ | |||
36 | /* | 36 | /* |
37 | * Function declarations. | 37 | * Function declarations. |
38 | */ | 38 | */ |
39 | static void xfs_dir2_free_log_header(xfs_trans_t *tp, xfs_dabuf_t *bp); | 39 | static int xfs_dir2_leafn_add(struct xfs_buf *bp, xfs_da_args_t *args, |
40 | static int xfs_dir2_leafn_add(xfs_dabuf_t *bp, xfs_da_args_t *args, int index); | 40 | int index); |
41 | #ifdef DEBUG | 41 | #ifdef DEBUG |
42 | static void xfs_dir2_leafn_check(xfs_inode_t *dp, xfs_dabuf_t *bp); | 42 | static void xfs_dir2_leafn_check(struct xfs_inode *dp, struct xfs_buf *bp); |
43 | #else | 43 | #else |
44 | #define xfs_dir2_leafn_check(dp, bp) | 44 | #define xfs_dir2_leafn_check(dp, bp) |
45 | #endif | 45 | #endif |
46 | static void xfs_dir2_leafn_moveents(xfs_da_args_t *args, xfs_dabuf_t *bp_s, | 46 | static void xfs_dir2_leafn_moveents(xfs_da_args_t *args, struct xfs_buf *bp_s, |
47 | int start_s, xfs_dabuf_t *bp_d, int start_d, | 47 | int start_s, struct xfs_buf *bp_d, |
48 | int count); | 48 | int start_d, int count); |
49 | static void xfs_dir2_leafn_rebalance(xfs_da_state_t *state, | 49 | static void xfs_dir2_leafn_rebalance(xfs_da_state_t *state, |
50 | xfs_da_state_blk_t *blk1, | 50 | xfs_da_state_blk_t *blk1, |
51 | xfs_da_state_blk_t *blk2); | 51 | xfs_da_state_blk_t *blk2); |
52 | static int xfs_dir2_leafn_remove(xfs_da_args_t *args, xfs_dabuf_t *bp, | 52 | static int xfs_dir2_leafn_remove(xfs_da_args_t *args, struct xfs_buf *bp, |
53 | int index, xfs_da_state_blk_t *dblk, | 53 | int index, xfs_da_state_blk_t *dblk, |
54 | int *rval); | 54 | int *rval); |
55 | static int xfs_dir2_node_addname_int(xfs_da_args_t *args, | 55 | static int xfs_dir2_node_addname_int(xfs_da_args_t *args, |
@@ -60,16 +60,16 @@ static int xfs_dir2_node_addname_int(xfs_da_args_t *args, | |||
60 | */ | 60 | */ |
61 | STATIC void | 61 | STATIC void |
62 | xfs_dir2_free_log_bests( | 62 | xfs_dir2_free_log_bests( |
63 | xfs_trans_t *tp, /* transaction pointer */ | 63 | struct xfs_trans *tp, |
64 | xfs_dabuf_t *bp, /* freespace buffer */ | 64 | struct xfs_buf *bp, |
65 | int first, /* first entry to log */ | 65 | int first, /* first entry to log */ |
66 | int last) /* last entry to log */ | 66 | int last) /* last entry to log */ |
67 | { | 67 | { |
68 | xfs_dir2_free_t *free; /* freespace structure */ | 68 | xfs_dir2_free_t *free; /* freespace structure */ |
69 | 69 | ||
70 | free = bp->data; | 70 | free = bp->b_addr; |
71 | ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC)); | 71 | ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC)); |
72 | xfs_da_log_buf(tp, bp, | 72 | xfs_trans_log_buf(tp, bp, |
73 | (uint)((char *)&free->bests[first] - (char *)free), | 73 | (uint)((char *)&free->bests[first] - (char *)free), |
74 | (uint)((char *)&free->bests[last] - (char *)free + | 74 | (uint)((char *)&free->bests[last] - (char *)free + |
75 | sizeof(free->bests[0]) - 1)); | 75 | sizeof(free->bests[0]) - 1)); |
@@ -80,14 +80,14 @@ xfs_dir2_free_log_bests( | |||
80 | */ | 80 | */ |
81 | static void | 81 | static void |
82 | xfs_dir2_free_log_header( | 82 | xfs_dir2_free_log_header( |
83 | xfs_trans_t *tp, /* transaction pointer */ | 83 | struct xfs_trans *tp, |
84 | xfs_dabuf_t *bp) /* freespace buffer */ | 84 | struct xfs_buf *bp) |
85 | { | 85 | { |
86 | xfs_dir2_free_t *free; /* freespace structure */ | 86 | xfs_dir2_free_t *free; /* freespace structure */ |
87 | 87 | ||
88 | free = bp->data; | 88 | free = bp->b_addr; |
89 | ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC)); | 89 | ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC)); |
90 | xfs_da_log_buf(tp, bp, (uint)((char *)&free->hdr - (char *)free), | 90 | xfs_trans_log_buf(tp, bp, (uint)((char *)&free->hdr - (char *)free), |
91 | (uint)(sizeof(xfs_dir2_free_hdr_t) - 1)); | 91 | (uint)(sizeof(xfs_dir2_free_hdr_t) - 1)); |
92 | } | 92 | } |
93 | 93 | ||
@@ -99,11 +99,11 @@ xfs_dir2_free_log_header( | |||
99 | int /* error */ | 99 | int /* error */ |
100 | xfs_dir2_leaf_to_node( | 100 | xfs_dir2_leaf_to_node( |
101 | xfs_da_args_t *args, /* operation arguments */ | 101 | xfs_da_args_t *args, /* operation arguments */ |
102 | xfs_dabuf_t *lbp) /* leaf buffer */ | 102 | struct xfs_buf *lbp) /* leaf buffer */ |
103 | { | 103 | { |
104 | xfs_inode_t *dp; /* incore directory inode */ | 104 | xfs_inode_t *dp; /* incore directory inode */ |
105 | int error; /* error return value */ | 105 | int error; /* error return value */ |
106 | xfs_dabuf_t *fbp; /* freespace buffer */ | 106 | struct xfs_buf *fbp; /* freespace buffer */ |
107 | xfs_dir2_db_t fdb; /* freespace block number */ | 107 | xfs_dir2_db_t fdb; /* freespace block number */ |
108 | xfs_dir2_free_t *free; /* freespace structure */ | 108 | xfs_dir2_free_t *free; /* freespace structure */ |
109 | __be16 *from; /* pointer to freespace entry */ | 109 | __be16 *from; /* pointer to freespace entry */ |
@@ -136,8 +136,8 @@ xfs_dir2_leaf_to_node( | |||
136 | return error; | 136 | return error; |
137 | } | 137 | } |
138 | ASSERT(fbp != NULL); | 138 | ASSERT(fbp != NULL); |
139 | free = fbp->data; | 139 | free = fbp->b_addr; |
140 | leaf = lbp->data; | 140 | leaf = lbp->b_addr; |
141 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); | 141 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); |
142 | /* | 142 | /* |
143 | * Initialize the freespace block header. | 143 | * Initialize the freespace block header. |
@@ -164,7 +164,6 @@ xfs_dir2_leaf_to_node( | |||
164 | xfs_dir2_leaf_log_header(tp, lbp); | 164 | xfs_dir2_leaf_log_header(tp, lbp); |
165 | xfs_dir2_free_log_header(tp, fbp); | 165 | xfs_dir2_free_log_header(tp, fbp); |
166 | xfs_dir2_free_log_bests(tp, fbp, 0, be32_to_cpu(free->hdr.nvalid) - 1); | 166 | xfs_dir2_free_log_bests(tp, fbp, 0, be32_to_cpu(free->hdr.nvalid) - 1); |
167 | xfs_da_buf_done(fbp); | ||
168 | xfs_dir2_leafn_check(dp, lbp); | 167 | xfs_dir2_leafn_check(dp, lbp); |
169 | return 0; | 168 | return 0; |
170 | } | 169 | } |
@@ -175,7 +174,7 @@ xfs_dir2_leaf_to_node( | |||
175 | */ | 174 | */ |
176 | static int /* error */ | 175 | static int /* error */ |
177 | xfs_dir2_leafn_add( | 176 | xfs_dir2_leafn_add( |
178 | xfs_dabuf_t *bp, /* leaf buffer */ | 177 | struct xfs_buf *bp, /* leaf buffer */ |
179 | xfs_da_args_t *args, /* operation arguments */ | 178 | xfs_da_args_t *args, /* operation arguments */ |
180 | int index) /* insertion pt for new entry */ | 179 | int index) /* insertion pt for new entry */ |
181 | { | 180 | { |
@@ -195,7 +194,7 @@ xfs_dir2_leafn_add( | |||
195 | dp = args->dp; | 194 | dp = args->dp; |
196 | mp = dp->i_mount; | 195 | mp = dp->i_mount; |
197 | tp = args->trans; | 196 | tp = args->trans; |
198 | leaf = bp->data; | 197 | leaf = bp->b_addr; |
199 | 198 | ||
200 | /* | 199 | /* |
201 | * Quick check just to make sure we are not going to index | 200 | * Quick check just to make sure we are not going to index |
@@ -261,15 +260,15 @@ xfs_dir2_leafn_add( | |||
261 | */ | 260 | */ |
262 | void | 261 | void |
263 | xfs_dir2_leafn_check( | 262 | xfs_dir2_leafn_check( |
264 | xfs_inode_t *dp, /* incore directory inode */ | 263 | struct xfs_inode *dp, |
265 | xfs_dabuf_t *bp) /* leaf buffer */ | 264 | struct xfs_buf *bp) |
266 | { | 265 | { |
267 | int i; /* leaf index */ | 266 | int i; /* leaf index */ |
268 | xfs_dir2_leaf_t *leaf; /* leaf structure */ | 267 | xfs_dir2_leaf_t *leaf; /* leaf structure */ |
269 | xfs_mount_t *mp; /* filesystem mount point */ | 268 | xfs_mount_t *mp; /* filesystem mount point */ |
270 | int stale; /* count of stale leaves */ | 269 | int stale; /* count of stale leaves */ |
271 | 270 | ||
272 | leaf = bp->data; | 271 | leaf = bp->b_addr; |
273 | mp = dp->i_mount; | 272 | mp = dp->i_mount; |
274 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); | 273 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); |
275 | ASSERT(be16_to_cpu(leaf->hdr.count) <= xfs_dir2_max_leaf_ents(mp)); | 274 | ASSERT(be16_to_cpu(leaf->hdr.count) <= xfs_dir2_max_leaf_ents(mp)); |
@@ -291,12 +290,12 @@ xfs_dir2_leafn_check( | |||
291 | */ | 290 | */ |
292 | xfs_dahash_t /* hash value */ | 291 | xfs_dahash_t /* hash value */ |
293 | xfs_dir2_leafn_lasthash( | 292 | xfs_dir2_leafn_lasthash( |
294 | xfs_dabuf_t *bp, /* leaf buffer */ | 293 | struct xfs_buf *bp, /* leaf buffer */ |
295 | int *count) /* count of entries in leaf */ | 294 | int *count) /* count of entries in leaf */ |
296 | { | 295 | { |
297 | xfs_dir2_leaf_t *leaf; /* leaf structure */ | 296 | xfs_dir2_leaf_t *leaf; /* leaf structure */ |
298 | 297 | ||
299 | leaf = bp->data; | 298 | leaf = bp->b_addr; |
300 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); | 299 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); |
301 | if (count) | 300 | if (count) |
302 | *count = be16_to_cpu(leaf->hdr.count); | 301 | *count = be16_to_cpu(leaf->hdr.count); |
@@ -311,12 +310,12 @@ xfs_dir2_leafn_lasthash( | |||
311 | */ | 310 | */ |
312 | STATIC int | 311 | STATIC int |
313 | xfs_dir2_leafn_lookup_for_addname( | 312 | xfs_dir2_leafn_lookup_for_addname( |
314 | xfs_dabuf_t *bp, /* leaf buffer */ | 313 | struct xfs_buf *bp, /* leaf buffer */ |
315 | xfs_da_args_t *args, /* operation arguments */ | 314 | xfs_da_args_t *args, /* operation arguments */ |
316 | int *indexp, /* out: leaf entry index */ | 315 | int *indexp, /* out: leaf entry index */ |
317 | xfs_da_state_t *state) /* state to fill in */ | 316 | xfs_da_state_t *state) /* state to fill in */ |
318 | { | 317 | { |
319 | xfs_dabuf_t *curbp = NULL; /* current data/free buffer */ | 318 | struct xfs_buf *curbp = NULL; /* current data/free buffer */ |
320 | xfs_dir2_db_t curdb = -1; /* current data block number */ | 319 | xfs_dir2_db_t curdb = -1; /* current data block number */ |
321 | xfs_dir2_db_t curfdb = -1; /* current free block number */ | 320 | xfs_dir2_db_t curfdb = -1; /* current free block number */ |
322 | xfs_inode_t *dp; /* incore directory inode */ | 321 | xfs_inode_t *dp; /* incore directory inode */ |
@@ -335,7 +334,7 @@ xfs_dir2_leafn_lookup_for_addname( | |||
335 | dp = args->dp; | 334 | dp = args->dp; |
336 | tp = args->trans; | 335 | tp = args->trans; |
337 | mp = dp->i_mount; | 336 | mp = dp->i_mount; |
338 | leaf = bp->data; | 337 | leaf = bp->b_addr; |
339 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); | 338 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); |
340 | #ifdef __KERNEL__ | 339 | #ifdef __KERNEL__ |
341 | ASSERT(be16_to_cpu(leaf->hdr.count) > 0); | 340 | ASSERT(be16_to_cpu(leaf->hdr.count) > 0); |
@@ -352,7 +351,7 @@ xfs_dir2_leafn_lookup_for_addname( | |||
352 | /* If so, it's a free block buffer, get the block number. */ | 351 | /* If so, it's a free block buffer, get the block number. */ |
353 | curbp = state->extrablk.bp; | 352 | curbp = state->extrablk.bp; |
354 | curfdb = state->extrablk.blkno; | 353 | curfdb = state->extrablk.blkno; |
355 | free = curbp->data; | 354 | free = curbp->b_addr; |
356 | ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC)); | 355 | ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC)); |
357 | } | 356 | } |
358 | length = xfs_dir2_data_entsize(args->namelen); | 357 | length = xfs_dir2_data_entsize(args->namelen); |
@@ -394,7 +393,7 @@ xfs_dir2_leafn_lookup_for_addname( | |||
394 | * If we had one before, drop it. | 393 | * If we had one before, drop it. |
395 | */ | 394 | */ |
396 | if (curbp) | 395 | if (curbp) |
397 | xfs_da_brelse(tp, curbp); | 396 | xfs_trans_brelse(tp, curbp); |
398 | /* | 397 | /* |
399 | * Read the free block. | 398 | * Read the free block. |
400 | */ | 399 | */ |
@@ -403,7 +402,7 @@ xfs_dir2_leafn_lookup_for_addname( | |||
403 | -1, &curbp, XFS_DATA_FORK); | 402 | -1, &curbp, XFS_DATA_FORK); |
404 | if (error) | 403 | if (error) |
405 | return error; | 404 | return error; |
406 | free = curbp->data; | 405 | free = curbp->b_addr; |
407 | ASSERT(be32_to_cpu(free->hdr.magic) == | 406 | ASSERT(be32_to_cpu(free->hdr.magic) == |
408 | XFS_DIR2_FREE_MAGIC); | 407 | XFS_DIR2_FREE_MAGIC); |
409 | ASSERT((be32_to_cpu(free->hdr.firstdb) % | 408 | ASSERT((be32_to_cpu(free->hdr.firstdb) % |
@@ -424,7 +423,7 @@ xfs_dir2_leafn_lookup_for_addname( | |||
424 | XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int", | 423 | XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int", |
425 | XFS_ERRLEVEL_LOW, mp); | 424 | XFS_ERRLEVEL_LOW, mp); |
426 | if (curfdb != newfdb) | 425 | if (curfdb != newfdb) |
427 | xfs_da_brelse(tp, curbp); | 426 | xfs_trans_brelse(tp, curbp); |
428 | return XFS_ERROR(EFSCORRUPTED); | 427 | return XFS_ERROR(EFSCORRUPTED); |
429 | } | 428 | } |
430 | curfdb = newfdb; | 429 | curfdb = newfdb; |
@@ -459,12 +458,12 @@ out: | |||
459 | */ | 458 | */ |
460 | STATIC int | 459 | STATIC int |
461 | xfs_dir2_leafn_lookup_for_entry( | 460 | xfs_dir2_leafn_lookup_for_entry( |
462 | xfs_dabuf_t *bp, /* leaf buffer */ | 461 | struct xfs_buf *bp, /* leaf buffer */ |
463 | xfs_da_args_t *args, /* operation arguments */ | 462 | xfs_da_args_t *args, /* operation arguments */ |
464 | int *indexp, /* out: leaf entry index */ | 463 | int *indexp, /* out: leaf entry index */ |
465 | xfs_da_state_t *state) /* state to fill in */ | 464 | xfs_da_state_t *state) /* state to fill in */ |
466 | { | 465 | { |
467 | xfs_dabuf_t *curbp = NULL; /* current data/free buffer */ | 466 | struct xfs_buf *curbp = NULL; /* current data/free buffer */ |
468 | xfs_dir2_db_t curdb = -1; /* current data block number */ | 467 | xfs_dir2_db_t curdb = -1; /* current data block number */ |
469 | xfs_dir2_data_entry_t *dep; /* data block entry */ | 468 | xfs_dir2_data_entry_t *dep; /* data block entry */ |
470 | xfs_inode_t *dp; /* incore directory inode */ | 469 | xfs_inode_t *dp; /* incore directory inode */ |
@@ -480,7 +479,7 @@ xfs_dir2_leafn_lookup_for_entry( | |||
480 | dp = args->dp; | 479 | dp = args->dp; |
481 | tp = args->trans; | 480 | tp = args->trans; |
482 | mp = dp->i_mount; | 481 | mp = dp->i_mount; |
483 | leaf = bp->data; | 482 | leaf = bp->b_addr; |
484 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); | 483 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); |
485 | #ifdef __KERNEL__ | 484 | #ifdef __KERNEL__ |
486 | ASSERT(be16_to_cpu(leaf->hdr.count) > 0); | 485 | ASSERT(be16_to_cpu(leaf->hdr.count) > 0); |
@@ -525,7 +524,7 @@ xfs_dir2_leafn_lookup_for_entry( | |||
525 | */ | 524 | */ |
526 | if (curbp && (args->cmpresult == XFS_CMP_DIFFERENT || | 525 | if (curbp && (args->cmpresult == XFS_CMP_DIFFERENT || |
527 | curdb != state->extrablk.blkno)) | 526 | curdb != state->extrablk.blkno)) |
528 | xfs_da_brelse(tp, curbp); | 527 | xfs_trans_brelse(tp, curbp); |
529 | /* | 528 | /* |
530 | * If needing the block that is saved with a CI match, | 529 | * If needing the block that is saved with a CI match, |
531 | * use it otherwise read in the new data block. | 530 | * use it otherwise read in the new data block. |
@@ -547,7 +546,7 @@ xfs_dir2_leafn_lookup_for_entry( | |||
547 | /* | 546 | /* |
548 | * Point to the data entry. | 547 | * Point to the data entry. |
549 | */ | 548 | */ |
550 | dep = (xfs_dir2_data_entry_t *)((char *)curbp->data + | 549 | dep = (xfs_dir2_data_entry_t *)((char *)curbp->b_addr + |
551 | xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); | 550 | xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); |
552 | /* | 551 | /* |
553 | * Compare the entry and if it's an exact match, return | 552 | * Compare the entry and if it's an exact match, return |
@@ -559,7 +558,7 @@ xfs_dir2_leafn_lookup_for_entry( | |||
559 | /* If there is a CI match block, drop it */ | 558 | /* If there is a CI match block, drop it */ |
560 | if (args->cmpresult != XFS_CMP_DIFFERENT && | 559 | if (args->cmpresult != XFS_CMP_DIFFERENT && |
561 | curdb != state->extrablk.blkno) | 560 | curdb != state->extrablk.blkno) |
562 | xfs_da_brelse(tp, state->extrablk.bp); | 561 | xfs_trans_brelse(tp, state->extrablk.bp); |
563 | args->cmpresult = cmp; | 562 | args->cmpresult = cmp; |
564 | args->inumber = be64_to_cpu(dep->inumber); | 563 | args->inumber = be64_to_cpu(dep->inumber); |
565 | *indexp = index; | 564 | *indexp = index; |
@@ -567,7 +566,7 @@ xfs_dir2_leafn_lookup_for_entry( | |||
567 | state->extrablk.bp = curbp; | 566 | state->extrablk.bp = curbp; |
568 | state->extrablk.blkno = curdb; | 567 | state->extrablk.blkno = curdb; |
569 | state->extrablk.index = (int)((char *)dep - | 568 | state->extrablk.index = (int)((char *)dep - |
570 | (char *)curbp->data); | 569 | (char *)curbp->b_addr); |
571 | state->extrablk.magic = XFS_DIR2_DATA_MAGIC; | 570 | state->extrablk.magic = XFS_DIR2_DATA_MAGIC; |
572 | if (cmp == XFS_CMP_EXACT) | 571 | if (cmp == XFS_CMP_EXACT) |
573 | return XFS_ERROR(EEXIST); | 572 | return XFS_ERROR(EEXIST); |
@@ -586,7 +585,7 @@ xfs_dir2_leafn_lookup_for_entry( | |||
586 | } else { | 585 | } else { |
587 | /* If the curbp is not the CI match block, drop it */ | 586 | /* If the curbp is not the CI match block, drop it */ |
588 | if (state->extrablk.bp != curbp) | 587 | if (state->extrablk.bp != curbp) |
589 | xfs_da_brelse(tp, curbp); | 588 | xfs_trans_brelse(tp, curbp); |
590 | } | 589 | } |
591 | } else { | 590 | } else { |
592 | state->extravalid = 0; | 591 | state->extravalid = 0; |
@@ -602,7 +601,7 @@ xfs_dir2_leafn_lookup_for_entry( | |||
602 | */ | 601 | */ |
603 | int | 602 | int |
604 | xfs_dir2_leafn_lookup_int( | 603 | xfs_dir2_leafn_lookup_int( |
605 | xfs_dabuf_t *bp, /* leaf buffer */ | 604 | struct xfs_buf *bp, /* leaf buffer */ |
606 | xfs_da_args_t *args, /* operation arguments */ | 605 | xfs_da_args_t *args, /* operation arguments */ |
607 | int *indexp, /* out: leaf entry index */ | 606 | int *indexp, /* out: leaf entry index */ |
608 | xfs_da_state_t *state) /* state to fill in */ | 607 | xfs_da_state_t *state) /* state to fill in */ |
@@ -620,9 +619,9 @@ xfs_dir2_leafn_lookup_int( | |||
620 | static void | 619 | static void |
621 | xfs_dir2_leafn_moveents( | 620 | xfs_dir2_leafn_moveents( |
622 | xfs_da_args_t *args, /* operation arguments */ | 621 | xfs_da_args_t *args, /* operation arguments */ |
623 | xfs_dabuf_t *bp_s, /* source leaf buffer */ | 622 | struct xfs_buf *bp_s, /* source leaf buffer */ |
624 | int start_s, /* source leaf index */ | 623 | int start_s, /* source leaf index */ |
625 | xfs_dabuf_t *bp_d, /* destination leaf buffer */ | 624 | struct xfs_buf *bp_d, /* destination leaf buffer */ |
626 | int start_d, /* destination leaf index */ | 625 | int start_d, /* destination leaf index */ |
627 | int count) /* count of leaves to copy */ | 626 | int count) /* count of leaves to copy */ |
628 | { | 627 | { |
@@ -640,8 +639,8 @@ xfs_dir2_leafn_moveents( | |||
640 | return; | 639 | return; |
641 | } | 640 | } |
642 | tp = args->trans; | 641 | tp = args->trans; |
643 | leaf_s = bp_s->data; | 642 | leaf_s = bp_s->b_addr; |
644 | leaf_d = bp_d->data; | 643 | leaf_d = bp_d->b_addr; |
645 | /* | 644 | /* |
646 | * If the destination index is not the end of the current | 645 | * If the destination index is not the end of the current |
647 | * destination leaf entries, open up a hole in the destination | 646 | * destination leaf entries, open up a hole in the destination |
@@ -702,14 +701,14 @@ xfs_dir2_leafn_moveents( | |||
702 | */ | 701 | */ |
703 | int /* sort order */ | 702 | int /* sort order */ |
704 | xfs_dir2_leafn_order( | 703 | xfs_dir2_leafn_order( |
705 | xfs_dabuf_t *leaf1_bp, /* leaf1 buffer */ | 704 | struct xfs_buf *leaf1_bp, /* leaf1 buffer */ |
706 | xfs_dabuf_t *leaf2_bp) /* leaf2 buffer */ | 705 | struct xfs_buf *leaf2_bp) /* leaf2 buffer */ |
707 | { | 706 | { |
708 | xfs_dir2_leaf_t *leaf1; /* leaf1 structure */ | 707 | xfs_dir2_leaf_t *leaf1; /* leaf1 structure */ |
709 | xfs_dir2_leaf_t *leaf2; /* leaf2 structure */ | 708 | xfs_dir2_leaf_t *leaf2; /* leaf2 structure */ |
710 | 709 | ||
711 | leaf1 = leaf1_bp->data; | 710 | leaf1 = leaf1_bp->b_addr; |
712 | leaf2 = leaf2_bp->data; | 711 | leaf2 = leaf2_bp->b_addr; |
713 | ASSERT(leaf1->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); | 712 | ASSERT(leaf1->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); |
714 | ASSERT(leaf2->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); | 713 | ASSERT(leaf2->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); |
715 | if (be16_to_cpu(leaf1->hdr.count) > 0 && | 714 | if (be16_to_cpu(leaf1->hdr.count) > 0 && |
@@ -757,8 +756,8 @@ xfs_dir2_leafn_rebalance( | |||
757 | blk1 = blk2; | 756 | blk1 = blk2; |
758 | blk2 = tmp; | 757 | blk2 = tmp; |
759 | } | 758 | } |
760 | leaf1 = blk1->bp->data; | 759 | leaf1 = blk1->bp->b_addr; |
761 | leaf2 = blk2->bp->data; | 760 | leaf2 = blk2->bp->b_addr; |
762 | oldsum = be16_to_cpu(leaf1->hdr.count) + be16_to_cpu(leaf2->hdr.count); | 761 | oldsum = be16_to_cpu(leaf1->hdr.count) + be16_to_cpu(leaf2->hdr.count); |
763 | #ifdef DEBUG | 762 | #ifdef DEBUG |
764 | oldstale = be16_to_cpu(leaf1->hdr.stale) + be16_to_cpu(leaf2->hdr.stale); | 763 | oldstale = be16_to_cpu(leaf1->hdr.stale) + be16_to_cpu(leaf2->hdr.stale); |
@@ -834,14 +833,14 @@ xfs_dir2_leafn_rebalance( | |||
834 | static int /* error */ | 833 | static int /* error */ |
835 | xfs_dir2_leafn_remove( | 834 | xfs_dir2_leafn_remove( |
836 | xfs_da_args_t *args, /* operation arguments */ | 835 | xfs_da_args_t *args, /* operation arguments */ |
837 | xfs_dabuf_t *bp, /* leaf buffer */ | 836 | struct xfs_buf *bp, /* leaf buffer */ |
838 | int index, /* leaf entry index */ | 837 | int index, /* leaf entry index */ |
839 | xfs_da_state_blk_t *dblk, /* data block */ | 838 | xfs_da_state_blk_t *dblk, /* data block */ |
840 | int *rval) /* resulting block needs join */ | 839 | int *rval) /* resulting block needs join */ |
841 | { | 840 | { |
842 | xfs_dir2_data_hdr_t *hdr; /* data block header */ | 841 | xfs_dir2_data_hdr_t *hdr; /* data block header */ |
843 | xfs_dir2_db_t db; /* data block number */ | 842 | xfs_dir2_db_t db; /* data block number */ |
844 | xfs_dabuf_t *dbp; /* data block buffer */ | 843 | struct xfs_buf *dbp; /* data block buffer */ |
845 | xfs_dir2_data_entry_t *dep; /* data block entry */ | 844 | xfs_dir2_data_entry_t *dep; /* data block entry */ |
846 | xfs_inode_t *dp; /* incore directory inode */ | 845 | xfs_inode_t *dp; /* incore directory inode */ |
847 | xfs_dir2_leaf_t *leaf; /* leaf structure */ | 846 | xfs_dir2_leaf_t *leaf; /* leaf structure */ |
@@ -858,7 +857,7 @@ xfs_dir2_leafn_remove( | |||
858 | dp = args->dp; | 857 | dp = args->dp; |
859 | tp = args->trans; | 858 | tp = args->trans; |
860 | mp = dp->i_mount; | 859 | mp = dp->i_mount; |
861 | leaf = bp->data; | 860 | leaf = bp->b_addr; |
862 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); | 861 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); |
863 | /* | 862 | /* |
864 | * Point to the entry we're removing. | 863 | * Point to the entry we're removing. |
@@ -884,7 +883,7 @@ xfs_dir2_leafn_remove( | |||
884 | * in the data block in case it changes. | 883 | * in the data block in case it changes. |
885 | */ | 884 | */ |
886 | dbp = dblk->bp; | 885 | dbp = dblk->bp; |
887 | hdr = dbp->data; | 886 | hdr = dbp->b_addr; |
888 | dep = (xfs_dir2_data_entry_t *)((char *)hdr + off); | 887 | dep = (xfs_dir2_data_entry_t *)((char *)hdr + off); |
889 | longest = be16_to_cpu(hdr->bestfree[0].length); | 888 | longest = be16_to_cpu(hdr->bestfree[0].length); |
890 | needlog = needscan = 0; | 889 | needlog = needscan = 0; |
@@ -905,7 +904,7 @@ xfs_dir2_leafn_remove( | |||
905 | */ | 904 | */ |
906 | if (longest < be16_to_cpu(hdr->bestfree[0].length)) { | 905 | if (longest < be16_to_cpu(hdr->bestfree[0].length)) { |
907 | int error; /* error return value */ | 906 | int error; /* error return value */ |
908 | xfs_dabuf_t *fbp; /* freeblock buffer */ | 907 | struct xfs_buf *fbp; /* freeblock buffer */ |
909 | xfs_dir2_db_t fdb; /* freeblock block number */ | 908 | xfs_dir2_db_t fdb; /* freeblock block number */ |
910 | int findex; /* index in freeblock entries */ | 909 | int findex; /* index in freeblock entries */ |
911 | xfs_dir2_free_t *free; /* freeblock structure */ | 910 | xfs_dir2_free_t *free; /* freeblock structure */ |
@@ -920,7 +919,7 @@ xfs_dir2_leafn_remove( | |||
920 | -1, &fbp, XFS_DATA_FORK))) { | 919 | -1, &fbp, XFS_DATA_FORK))) { |
921 | return error; | 920 | return error; |
922 | } | 921 | } |
923 | free = fbp->data; | 922 | free = fbp->b_addr; |
924 | ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC)); | 923 | ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC)); |
925 | ASSERT(be32_to_cpu(free->hdr.firstdb) == | 924 | ASSERT(be32_to_cpu(free->hdr.firstdb) == |
926 | xfs_dir2_free_max_bests(mp) * | 925 | xfs_dir2_free_max_bests(mp) * |
@@ -948,9 +947,7 @@ xfs_dir2_leafn_remove( | |||
948 | * In this case just drop the buffer and some one else | 947 | * In this case just drop the buffer and some one else |
949 | * will eventually get rid of the empty block. | 948 | * will eventually get rid of the empty block. |
950 | */ | 949 | */ |
951 | else if (error == ENOSPC && args->total == 0) | 950 | else if (!(error == ENOSPC && args->total == 0)) |
952 | xfs_da_buf_done(dbp); | ||
953 | else | ||
954 | return error; | 951 | return error; |
955 | } | 952 | } |
956 | /* | 953 | /* |
@@ -1018,11 +1015,6 @@ xfs_dir2_leafn_remove( | |||
1018 | */ | 1015 | */ |
1019 | if (logfree) | 1016 | if (logfree) |
1020 | xfs_dir2_free_log_bests(tp, fbp, findex, findex); | 1017 | xfs_dir2_free_log_bests(tp, fbp, findex, findex); |
1021 | /* | ||
1022 | * Drop the buffer if we still have it. | ||
1023 | */ | ||
1024 | if (fbp) | ||
1025 | xfs_da_buf_done(fbp); | ||
1026 | } | 1018 | } |
1027 | xfs_dir2_leafn_check(dp, bp); | 1019 | xfs_dir2_leafn_check(dp, bp); |
1028 | /* | 1020 | /* |
@@ -1114,7 +1106,7 @@ xfs_dir2_leafn_toosmall( | |||
1114 | { | 1106 | { |
1115 | xfs_da_state_blk_t *blk; /* leaf block */ | 1107 | xfs_da_state_blk_t *blk; /* leaf block */ |
1116 | xfs_dablk_t blkno; /* leaf block number */ | 1108 | xfs_dablk_t blkno; /* leaf block number */ |
1117 | xfs_dabuf_t *bp; /* leaf buffer */ | 1109 | struct xfs_buf *bp; /* leaf buffer */ |
1118 | int bytes; /* bytes in use */ | 1110 | int bytes; /* bytes in use */ |
1119 | int count; /* leaf live entry count */ | 1111 | int count; /* leaf live entry count */ |
1120 | int error; /* error return value */ | 1112 | int error; /* error return value */ |
@@ -1130,7 +1122,7 @@ xfs_dir2_leafn_toosmall( | |||
1130 | * to coalesce with a sibling. | 1122 | * to coalesce with a sibling. |
1131 | */ | 1123 | */ |
1132 | blk = &state->path.blk[state->path.active - 1]; | 1124 | blk = &state->path.blk[state->path.active - 1]; |
1133 | info = blk->bp->data; | 1125 | info = blk->bp->b_addr; |
1134 | ASSERT(info->magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); | 1126 | ASSERT(info->magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); |
1135 | leaf = (xfs_dir2_leaf_t *)info; | 1127 | leaf = (xfs_dir2_leaf_t *)info; |
1136 | count = be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale); | 1128 | count = be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale); |
@@ -1189,7 +1181,7 @@ xfs_dir2_leafn_toosmall( | |||
1189 | leaf = (xfs_dir2_leaf_t *)info; | 1181 | leaf = (xfs_dir2_leaf_t *)info; |
1190 | count = be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale); | 1182 | count = be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale); |
1191 | bytes = state->blocksize - (state->blocksize >> 2); | 1183 | bytes = state->blocksize - (state->blocksize >> 2); |
1192 | leaf = bp->data; | 1184 | leaf = bp->b_addr; |
1193 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); | 1185 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); |
1194 | count += be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale); | 1186 | count += be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale); |
1195 | bytes -= count * (uint)sizeof(leaf->ents[0]); | 1187 | bytes -= count * (uint)sizeof(leaf->ents[0]); |
@@ -1198,7 +1190,7 @@ xfs_dir2_leafn_toosmall( | |||
1198 | */ | 1190 | */ |
1199 | if (bytes >= 0) | 1191 | if (bytes >= 0) |
1200 | break; | 1192 | break; |
1201 | xfs_da_brelse(state->args->trans, bp); | 1193 | xfs_trans_brelse(state->args->trans, bp); |
1202 | } | 1194 | } |
1203 | /* | 1195 | /* |
1204 | * Didn't like either block, give up. | 1196 | * Didn't like either block, give up. |
@@ -1207,11 +1199,7 @@ xfs_dir2_leafn_toosmall( | |||
1207 | *action = 0; | 1199 | *action = 0; |
1208 | return 0; | 1200 | return 0; |
1209 | } | 1201 | } |
1210 | /* | 1202 | |
1211 | * Done with the sibling leaf block here, drop the dabuf | ||
1212 | * so path_shift can get it. | ||
1213 | */ | ||
1214 | xfs_da_buf_done(bp); | ||
1215 | /* | 1203 | /* |
1216 | * Make altpath point to the block we want to keep (the lower | 1204 | * Make altpath point to the block we want to keep (the lower |
1217 | * numbered block) and path point to the block we want to drop. | 1205 | * numbered block) and path point to the block we want to drop. |
@@ -1247,8 +1235,8 @@ xfs_dir2_leafn_unbalance( | |||
1247 | args = state->args; | 1235 | args = state->args; |
1248 | ASSERT(drop_blk->magic == XFS_DIR2_LEAFN_MAGIC); | 1236 | ASSERT(drop_blk->magic == XFS_DIR2_LEAFN_MAGIC); |
1249 | ASSERT(save_blk->magic == XFS_DIR2_LEAFN_MAGIC); | 1237 | ASSERT(save_blk->magic == XFS_DIR2_LEAFN_MAGIC); |
1250 | drop_leaf = drop_blk->bp->data; | 1238 | drop_leaf = drop_blk->bp->b_addr; |
1251 | save_leaf = save_blk->bp->data; | 1239 | save_leaf = save_blk->bp->b_addr; |
1252 | ASSERT(drop_leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); | 1240 | ASSERT(drop_leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); |
1253 | ASSERT(save_leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); | 1241 | ASSERT(save_leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); |
1254 | /* | 1242 | /* |
@@ -1356,13 +1344,13 @@ xfs_dir2_node_addname_int( | |||
1356 | { | 1344 | { |
1357 | xfs_dir2_data_hdr_t *hdr; /* data block header */ | 1345 | xfs_dir2_data_hdr_t *hdr; /* data block header */ |
1358 | xfs_dir2_db_t dbno; /* data block number */ | 1346 | xfs_dir2_db_t dbno; /* data block number */ |
1359 | xfs_dabuf_t *dbp; /* data block buffer */ | 1347 | struct xfs_buf *dbp; /* data block buffer */ |
1360 | xfs_dir2_data_entry_t *dep; /* data entry pointer */ | 1348 | xfs_dir2_data_entry_t *dep; /* data entry pointer */ |
1361 | xfs_inode_t *dp; /* incore directory inode */ | 1349 | xfs_inode_t *dp; /* incore directory inode */ |
1362 | xfs_dir2_data_unused_t *dup; /* data unused entry pointer */ | 1350 | xfs_dir2_data_unused_t *dup; /* data unused entry pointer */ |
1363 | int error; /* error return value */ | 1351 | int error; /* error return value */ |
1364 | xfs_dir2_db_t fbno; /* freespace block number */ | 1352 | xfs_dir2_db_t fbno; /* freespace block number */ |
1365 | xfs_dabuf_t *fbp; /* freespace buffer */ | 1353 | struct xfs_buf *fbp; /* freespace buffer */ |
1366 | int findex; /* freespace entry index */ | 1354 | int findex; /* freespace entry index */ |
1367 | xfs_dir2_free_t *free=NULL; /* freespace block structure */ | 1355 | xfs_dir2_free_t *free=NULL; /* freespace block structure */ |
1368 | xfs_dir2_db_t ifbno; /* initial freespace block no */ | 1356 | xfs_dir2_db_t ifbno; /* initial freespace block no */ |
@@ -1390,7 +1378,7 @@ xfs_dir2_node_addname_int( | |||
1390 | * Remember initial freespace block number. | 1378 | * Remember initial freespace block number. |
1391 | */ | 1379 | */ |
1392 | ifbno = fblk->blkno; | 1380 | ifbno = fblk->blkno; |
1393 | free = fbp->data; | 1381 | free = fbp->b_addr; |
1394 | ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC)); | 1382 | ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC)); |
1395 | findex = fblk->index; | 1383 | findex = fblk->index; |
1396 | /* | 1384 | /* |
@@ -1474,7 +1462,7 @@ xfs_dir2_node_addname_int( | |||
1474 | if (unlikely(fbp == NULL)) { | 1462 | if (unlikely(fbp == NULL)) { |
1475 | continue; | 1463 | continue; |
1476 | } | 1464 | } |
1477 | free = fbp->data; | 1465 | free = fbp->b_addr; |
1478 | ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC)); | 1466 | ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC)); |
1479 | findex = 0; | 1467 | findex = 0; |
1480 | } | 1468 | } |
@@ -1492,7 +1480,7 @@ xfs_dir2_node_addname_int( | |||
1492 | /* | 1480 | /* |
1493 | * Drop the block. | 1481 | * Drop the block. |
1494 | */ | 1482 | */ |
1495 | xfs_da_brelse(tp, fbp); | 1483 | xfs_trans_brelse(tp, fbp); |
1496 | fbp = NULL; | 1484 | fbp = NULL; |
1497 | if (fblk && fblk->bp) | 1485 | if (fblk && fblk->bp) |
1498 | fblk->bp = NULL; | 1486 | fblk->bp = NULL; |
@@ -1507,36 +1495,23 @@ xfs_dir2_node_addname_int( | |||
1507 | /* | 1495 | /* |
1508 | * Not allowed to allocate, return failure. | 1496 | * Not allowed to allocate, return failure. |
1509 | */ | 1497 | */ |
1510 | if ((args->op_flags & XFS_DA_OP_JUSTCHECK) || | 1498 | if ((args->op_flags & XFS_DA_OP_JUSTCHECK) || args->total == 0) |
1511 | args->total == 0) { | ||
1512 | /* | ||
1513 | * Drop the freespace buffer unless it came from our | ||
1514 | * caller. | ||
1515 | */ | ||
1516 | if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) | ||
1517 | xfs_da_buf_done(fbp); | ||
1518 | return XFS_ERROR(ENOSPC); | 1499 | return XFS_ERROR(ENOSPC); |
1519 | } | 1500 | |
1520 | /* | 1501 | /* |
1521 | * Allocate and initialize the new data block. | 1502 | * Allocate and initialize the new data block. |
1522 | */ | 1503 | */ |
1523 | if (unlikely((error = xfs_dir2_grow_inode(args, | 1504 | if (unlikely((error = xfs_dir2_grow_inode(args, |
1524 | XFS_DIR2_DATA_SPACE, | 1505 | XFS_DIR2_DATA_SPACE, |
1525 | &dbno)) || | 1506 | &dbno)) || |
1526 | (error = xfs_dir2_data_init(args, dbno, &dbp)))) { | 1507 | (error = xfs_dir2_data_init(args, dbno, &dbp)))) |
1527 | /* | ||
1528 | * Drop the freespace buffer unless it came from our | ||
1529 | * caller. | ||
1530 | */ | ||
1531 | if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) | ||
1532 | xfs_da_buf_done(fbp); | ||
1533 | return error; | 1508 | return error; |
1534 | } | 1509 | |
1535 | /* | 1510 | /* |
1536 | * If (somehow) we have a freespace block, get rid of it. | 1511 | * If (somehow) we have a freespace block, get rid of it. |
1537 | */ | 1512 | */ |
1538 | if (fbp) | 1513 | if (fbp) |
1539 | xfs_da_brelse(tp, fbp); | 1514 | xfs_trans_brelse(tp, fbp); |
1540 | if (fblk && fblk->bp) | 1515 | if (fblk && fblk->bp) |
1541 | fblk->bp = NULL; | 1516 | fblk->bp = NULL; |
1542 | 1517 | ||
@@ -1547,10 +1522,9 @@ xfs_dir2_node_addname_int( | |||
1547 | fbno = xfs_dir2_db_to_fdb(mp, dbno); | 1522 | fbno = xfs_dir2_db_to_fdb(mp, dbno); |
1548 | if (unlikely(error = xfs_da_read_buf(tp, dp, | 1523 | if (unlikely(error = xfs_da_read_buf(tp, dp, |
1549 | xfs_dir2_db_to_da(mp, fbno), -2, &fbp, | 1524 | xfs_dir2_db_to_da(mp, fbno), -2, &fbp, |
1550 | XFS_DATA_FORK))) { | 1525 | XFS_DATA_FORK))) |
1551 | xfs_da_buf_done(dbp); | ||
1552 | return error; | 1526 | return error; |
1553 | } | 1527 | |
1554 | /* | 1528 | /* |
1555 | * If there wasn't a freespace block, the read will | 1529 | * If there wasn't a freespace block, the read will |
1556 | * return a NULL fbp. Allocate and initialize a new one. | 1530 | * return a NULL fbp. Allocate and initialize a new one. |
@@ -1598,7 +1572,7 @@ xfs_dir2_node_addname_int( | |||
1598 | * Initialize the new block to be empty, and remember | 1572 | * Initialize the new block to be empty, and remember |
1599 | * its first slot as our empty slot. | 1573 | * its first slot as our empty slot. |
1600 | */ | 1574 | */ |
1601 | free = fbp->data; | 1575 | free = fbp->b_addr; |
1602 | free->hdr.magic = cpu_to_be32(XFS_DIR2_FREE_MAGIC); | 1576 | free->hdr.magic = cpu_to_be32(XFS_DIR2_FREE_MAGIC); |
1603 | free->hdr.firstdb = cpu_to_be32( | 1577 | free->hdr.firstdb = cpu_to_be32( |
1604 | (fbno - XFS_DIR2_FREE_FIRSTDB(mp)) * | 1578 | (fbno - XFS_DIR2_FREE_FIRSTDB(mp)) * |
@@ -1606,7 +1580,7 @@ xfs_dir2_node_addname_int( | |||
1606 | free->hdr.nvalid = 0; | 1580 | free->hdr.nvalid = 0; |
1607 | free->hdr.nused = 0; | 1581 | free->hdr.nused = 0; |
1608 | } else { | 1582 | } else { |
1609 | free = fbp->data; | 1583 | free = fbp->b_addr; |
1610 | ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC)); | 1584 | ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC)); |
1611 | } | 1585 | } |
1612 | 1586 | ||
@@ -1639,7 +1613,7 @@ xfs_dir2_node_addname_int( | |||
1639 | * We haven't allocated the data entry yet so this will | 1613 | * We haven't allocated the data entry yet so this will |
1640 | * change again. | 1614 | * change again. |
1641 | */ | 1615 | */ |
1642 | hdr = dbp->data; | 1616 | hdr = dbp->b_addr; |
1643 | free->bests[findex] = hdr->bestfree[0].length; | 1617 | free->bests[findex] = hdr->bestfree[0].length; |
1644 | logfree = 1; | 1618 | logfree = 1; |
1645 | } | 1619 | } |
@@ -1650,22 +1624,17 @@ xfs_dir2_node_addname_int( | |||
1650 | /* | 1624 | /* |
1651 | * If just checking, we succeeded. | 1625 | * If just checking, we succeeded. |
1652 | */ | 1626 | */ |
1653 | if (args->op_flags & XFS_DA_OP_JUSTCHECK) { | 1627 | if (args->op_flags & XFS_DA_OP_JUSTCHECK) |
1654 | if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) | ||
1655 | xfs_da_buf_done(fbp); | ||
1656 | return 0; | 1628 | return 0; |
1657 | } | 1629 | |
1658 | /* | 1630 | /* |
1659 | * Read the data block in. | 1631 | * Read the data block in. |
1660 | */ | 1632 | */ |
1661 | if (unlikely( | 1633 | error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, dbno), |
1662 | error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, dbno), | 1634 | -1, &dbp, XFS_DATA_FORK); |
1663 | -1, &dbp, XFS_DATA_FORK))) { | 1635 | if (error) |
1664 | if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) | ||
1665 | xfs_da_buf_done(fbp); | ||
1666 | return error; | 1636 | return error; |
1667 | } | 1637 | hdr = dbp->b_addr; |
1668 | hdr = dbp->data; | ||
1669 | logfree = 0; | 1638 | logfree = 0; |
1670 | } | 1639 | } |
1671 | ASSERT(be16_to_cpu(hdr->bestfree[0].length) >= length); | 1640 | ASSERT(be16_to_cpu(hdr->bestfree[0].length) >= length); |
@@ -1714,16 +1683,10 @@ xfs_dir2_node_addname_int( | |||
1714 | if (logfree) | 1683 | if (logfree) |
1715 | xfs_dir2_free_log_bests(tp, fbp, findex, findex); | 1684 | xfs_dir2_free_log_bests(tp, fbp, findex, findex); |
1716 | /* | 1685 | /* |
1717 | * If the caller didn't hand us the freespace block, drop it. | ||
1718 | */ | ||
1719 | if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) | ||
1720 | xfs_da_buf_done(fbp); | ||
1721 | /* | ||
1722 | * Return the data block and offset in args, then drop the data block. | 1686 | * Return the data block and offset in args, then drop the data block. |
1723 | */ | 1687 | */ |
1724 | args->blkno = (xfs_dablk_t)dbno; | 1688 | args->blkno = (xfs_dablk_t)dbno; |
1725 | args->index = be16_to_cpu(*tagp); | 1689 | args->index = be16_to_cpu(*tagp); |
1726 | xfs_da_buf_done(dbp); | ||
1727 | return 0; | 1690 | return 0; |
1728 | } | 1691 | } |
1729 | 1692 | ||
@@ -1761,22 +1724,23 @@ xfs_dir2_node_lookup( | |||
1761 | /* If a CI match, dup the actual name and return EEXIST */ | 1724 | /* If a CI match, dup the actual name and return EEXIST */ |
1762 | xfs_dir2_data_entry_t *dep; | 1725 | xfs_dir2_data_entry_t *dep; |
1763 | 1726 | ||
1764 | dep = (xfs_dir2_data_entry_t *)((char *)state->extrablk.bp-> | 1727 | dep = (xfs_dir2_data_entry_t *) |
1765 | data + state->extrablk.index); | 1728 | ((char *)state->extrablk.bp->b_addr + |
1729 | state->extrablk.index); | ||
1766 | rval = xfs_dir_cilookup_result(args, dep->name, dep->namelen); | 1730 | rval = xfs_dir_cilookup_result(args, dep->name, dep->namelen); |
1767 | } | 1731 | } |
1768 | /* | 1732 | /* |
1769 | * Release the btree blocks and leaf block. | 1733 | * Release the btree blocks and leaf block. |
1770 | */ | 1734 | */ |
1771 | for (i = 0; i < state->path.active; i++) { | 1735 | for (i = 0; i < state->path.active; i++) { |
1772 | xfs_da_brelse(args->trans, state->path.blk[i].bp); | 1736 | xfs_trans_brelse(args->trans, state->path.blk[i].bp); |
1773 | state->path.blk[i].bp = NULL; | 1737 | state->path.blk[i].bp = NULL; |
1774 | } | 1738 | } |
1775 | /* | 1739 | /* |
1776 | * Release the data block if we have it. | 1740 | * Release the data block if we have it. |
1777 | */ | 1741 | */ |
1778 | if (state->extravalid && state->extrablk.bp) { | 1742 | if (state->extravalid && state->extrablk.bp) { |
1779 | xfs_da_brelse(args->trans, state->extrablk.bp); | 1743 | xfs_trans_brelse(args->trans, state->extrablk.bp); |
1780 | state->extrablk.bp = NULL; | 1744 | state->extrablk.bp = NULL; |
1781 | } | 1745 | } |
1782 | xfs_da_state_free(state); | 1746 | xfs_da_state_free(state); |
@@ -1893,13 +1857,13 @@ xfs_dir2_node_replace( | |||
1893 | */ | 1857 | */ |
1894 | blk = &state->path.blk[state->path.active - 1]; | 1858 | blk = &state->path.blk[state->path.active - 1]; |
1895 | ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC); | 1859 | ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC); |
1896 | leaf = blk->bp->data; | 1860 | leaf = blk->bp->b_addr; |
1897 | lep = &leaf->ents[blk->index]; | 1861 | lep = &leaf->ents[blk->index]; |
1898 | ASSERT(state->extravalid); | 1862 | ASSERT(state->extravalid); |
1899 | /* | 1863 | /* |
1900 | * Point to the data entry. | 1864 | * Point to the data entry. |
1901 | */ | 1865 | */ |
1902 | hdr = state->extrablk.bp->data; | 1866 | hdr = state->extrablk.bp->b_addr; |
1903 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC)); | 1867 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC)); |
1904 | dep = (xfs_dir2_data_entry_t *) | 1868 | dep = (xfs_dir2_data_entry_t *) |
1905 | ((char *)hdr + | 1869 | ((char *)hdr + |
@@ -1916,14 +1880,14 @@ xfs_dir2_node_replace( | |||
1916 | * Didn't find it, and we're holding a data block. Drop it. | 1880 | * Didn't find it, and we're holding a data block. Drop it. |
1917 | */ | 1881 | */ |
1918 | else if (state->extravalid) { | 1882 | else if (state->extravalid) { |
1919 | xfs_da_brelse(args->trans, state->extrablk.bp); | 1883 | xfs_trans_brelse(args->trans, state->extrablk.bp); |
1920 | state->extrablk.bp = NULL; | 1884 | state->extrablk.bp = NULL; |
1921 | } | 1885 | } |
1922 | /* | 1886 | /* |
1923 | * Release all the buffers in the cursor. | 1887 | * Release all the buffers in the cursor. |
1924 | */ | 1888 | */ |
1925 | for (i = 0; i < state->path.active; i++) { | 1889 | for (i = 0; i < state->path.active; i++) { |
1926 | xfs_da_brelse(args->trans, state->path.blk[i].bp); | 1890 | xfs_trans_brelse(args->trans, state->path.blk[i].bp); |
1927 | state->path.blk[i].bp = NULL; | 1891 | state->path.blk[i].bp = NULL; |
1928 | } | 1892 | } |
1929 | xfs_da_state_free(state); | 1893 | xfs_da_state_free(state); |
@@ -1940,7 +1904,7 @@ xfs_dir2_node_trim_free( | |||
1940 | xfs_fileoff_t fo, /* free block number */ | 1904 | xfs_fileoff_t fo, /* free block number */ |
1941 | int *rvalp) /* out: did something */ | 1905 | int *rvalp) /* out: did something */ |
1942 | { | 1906 | { |
1943 | xfs_dabuf_t *bp; /* freespace buffer */ | 1907 | struct xfs_buf *bp; /* freespace buffer */ |
1944 | xfs_inode_t *dp; /* incore directory inode */ | 1908 | xfs_inode_t *dp; /* incore directory inode */ |
1945 | int error; /* error return code */ | 1909 | int error; /* error return code */ |
1946 | xfs_dir2_free_t *free; /* freespace structure */ | 1910 | xfs_dir2_free_t *free; /* freespace structure */ |
@@ -1965,13 +1929,13 @@ xfs_dir2_node_trim_free( | |||
1965 | if (bp == NULL) { | 1929 | if (bp == NULL) { |
1966 | return 0; | 1930 | return 0; |
1967 | } | 1931 | } |
1968 | free = bp->data; | 1932 | free = bp->b_addr; |
1969 | ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC)); | 1933 | ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC)); |
1970 | /* | 1934 | /* |
1971 | * If there are used entries, there's nothing to do. | 1935 | * If there are used entries, there's nothing to do. |
1972 | */ | 1936 | */ |
1973 | if (be32_to_cpu(free->hdr.nused) > 0) { | 1937 | if (be32_to_cpu(free->hdr.nused) > 0) { |
1974 | xfs_da_brelse(tp, bp); | 1938 | xfs_trans_brelse(tp, bp); |
1975 | *rvalp = 0; | 1939 | *rvalp = 0; |
1976 | return 0; | 1940 | return 0; |
1977 | } | 1941 | } |
@@ -1987,7 +1951,7 @@ xfs_dir2_node_trim_free( | |||
1987 | * pieces. This is the last block of an extent. | 1951 | * pieces. This is the last block of an extent. |
1988 | */ | 1952 | */ |
1989 | ASSERT(error != ENOSPC); | 1953 | ASSERT(error != ENOSPC); |
1990 | xfs_da_brelse(tp, bp); | 1954 | xfs_trans_brelse(tp, bp); |
1991 | return error; | 1955 | return error; |
1992 | } | 1956 | } |
1993 | /* | 1957 | /* |
diff --git a/fs/xfs/xfs_dir2_priv.h b/fs/xfs/xfs_dir2_priv.h index 067f403ecf8a..3523d3e15aa8 100644 --- a/fs/xfs/xfs_dir2_priv.h +++ b/fs/xfs/xfs_dir2_priv.h | |||
@@ -25,7 +25,7 @@ extern int xfs_dir2_isleaf(struct xfs_trans *tp, struct xfs_inode *dp, int *r); | |||
25 | extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space, | 25 | extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space, |
26 | xfs_dir2_db_t *dbp); | 26 | xfs_dir2_db_t *dbp); |
27 | extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db, | 27 | extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db, |
28 | struct xfs_dabuf *bp); | 28 | struct xfs_buf *bp); |
29 | extern int xfs_dir_cilookup_result(struct xfs_da_args *args, | 29 | extern int xfs_dir_cilookup_result(struct xfs_da_args *args, |
30 | const unsigned char *name, int len); | 30 | const unsigned char *name, int len); |
31 | 31 | ||
@@ -37,11 +37,11 @@ extern int xfs_dir2_block_lookup(struct xfs_da_args *args); | |||
37 | extern int xfs_dir2_block_removename(struct xfs_da_args *args); | 37 | extern int xfs_dir2_block_removename(struct xfs_da_args *args); |
38 | extern int xfs_dir2_block_replace(struct xfs_da_args *args); | 38 | extern int xfs_dir2_block_replace(struct xfs_da_args *args); |
39 | extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args, | 39 | extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args, |
40 | struct xfs_dabuf *lbp, struct xfs_dabuf *dbp); | 40 | struct xfs_buf *lbp, struct xfs_buf *dbp); |
41 | 41 | ||
42 | /* xfs_dir2_data.c */ | 42 | /* xfs_dir2_data.c */ |
43 | #ifdef DEBUG | 43 | #ifdef DEBUG |
44 | extern void xfs_dir2_data_check(struct xfs_inode *dp, struct xfs_dabuf *bp); | 44 | extern void xfs_dir2_data_check(struct xfs_inode *dp, struct xfs_buf *bp); |
45 | #else | 45 | #else |
46 | #define xfs_dir2_data_check(dp,bp) | 46 | #define xfs_dir2_data_check(dp,bp) |
47 | #endif | 47 | #endif |
@@ -51,43 +51,43 @@ xfs_dir2_data_freeinsert(struct xfs_dir2_data_hdr *hdr, | |||
51 | extern void xfs_dir2_data_freescan(struct xfs_mount *mp, | 51 | extern void xfs_dir2_data_freescan(struct xfs_mount *mp, |
52 | struct xfs_dir2_data_hdr *hdr, int *loghead); | 52 | struct xfs_dir2_data_hdr *hdr, int *loghead); |
53 | extern int xfs_dir2_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno, | 53 | extern int xfs_dir2_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno, |
54 | struct xfs_dabuf **bpp); | 54 | struct xfs_buf **bpp); |
55 | extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_dabuf *bp, | 55 | extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_buf *bp, |
56 | struct xfs_dir2_data_entry *dep); | 56 | struct xfs_dir2_data_entry *dep); |
57 | extern void xfs_dir2_data_log_header(struct xfs_trans *tp, | 57 | extern void xfs_dir2_data_log_header(struct xfs_trans *tp, |
58 | struct xfs_dabuf *bp); | 58 | struct xfs_buf *bp); |
59 | extern void xfs_dir2_data_log_unused(struct xfs_trans *tp, struct xfs_dabuf *bp, | 59 | extern void xfs_dir2_data_log_unused(struct xfs_trans *tp, struct xfs_buf *bp, |
60 | struct xfs_dir2_data_unused *dup); | 60 | struct xfs_dir2_data_unused *dup); |
61 | extern void xfs_dir2_data_make_free(struct xfs_trans *tp, struct xfs_dabuf *bp, | 61 | extern void xfs_dir2_data_make_free(struct xfs_trans *tp, struct xfs_buf *bp, |
62 | xfs_dir2_data_aoff_t offset, xfs_dir2_data_aoff_t len, | 62 | xfs_dir2_data_aoff_t offset, xfs_dir2_data_aoff_t len, |
63 | int *needlogp, int *needscanp); | 63 | int *needlogp, int *needscanp); |
64 | extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_dabuf *bp, | 64 | extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_buf *bp, |
65 | struct xfs_dir2_data_unused *dup, xfs_dir2_data_aoff_t offset, | 65 | struct xfs_dir2_data_unused *dup, xfs_dir2_data_aoff_t offset, |
66 | xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp); | 66 | xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp); |
67 | 67 | ||
68 | /* xfs_dir2_leaf.c */ | 68 | /* xfs_dir2_leaf.c */ |
69 | extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args, | 69 | extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args, |
70 | struct xfs_dabuf *dbp); | 70 | struct xfs_buf *dbp); |
71 | extern int xfs_dir2_leaf_addname(struct xfs_da_args *args); | 71 | extern int xfs_dir2_leaf_addname(struct xfs_da_args *args); |
72 | extern void xfs_dir2_leaf_compact(struct xfs_da_args *args, | 72 | extern void xfs_dir2_leaf_compact(struct xfs_da_args *args, |
73 | struct xfs_dabuf *bp); | 73 | struct xfs_buf *bp); |
74 | extern void xfs_dir2_leaf_compact_x1(struct xfs_dabuf *bp, int *indexp, | 74 | extern void xfs_dir2_leaf_compact_x1(struct xfs_buf *bp, int *indexp, |
75 | int *lowstalep, int *highstalep, int *lowlogp, int *highlogp); | 75 | int *lowstalep, int *highstalep, int *lowlogp, int *highlogp); |
76 | extern int xfs_dir2_leaf_getdents(struct xfs_inode *dp, void *dirent, | 76 | extern int xfs_dir2_leaf_getdents(struct xfs_inode *dp, void *dirent, |
77 | size_t bufsize, xfs_off_t *offset, filldir_t filldir); | 77 | size_t bufsize, xfs_off_t *offset, filldir_t filldir); |
78 | extern int xfs_dir2_leaf_init(struct xfs_da_args *args, xfs_dir2_db_t bno, | 78 | extern int xfs_dir2_leaf_init(struct xfs_da_args *args, xfs_dir2_db_t bno, |
79 | struct xfs_dabuf **bpp, int magic); | 79 | struct xfs_buf **bpp, int magic); |
80 | extern void xfs_dir2_leaf_log_ents(struct xfs_trans *tp, struct xfs_dabuf *bp, | 80 | extern void xfs_dir2_leaf_log_ents(struct xfs_trans *tp, struct xfs_buf *bp, |
81 | int first, int last); | 81 | int first, int last); |
82 | extern void xfs_dir2_leaf_log_header(struct xfs_trans *tp, | 82 | extern void xfs_dir2_leaf_log_header(struct xfs_trans *tp, |
83 | struct xfs_dabuf *bp); | 83 | struct xfs_buf *bp); |
84 | extern int xfs_dir2_leaf_lookup(struct xfs_da_args *args); | 84 | extern int xfs_dir2_leaf_lookup(struct xfs_da_args *args); |
85 | extern int xfs_dir2_leaf_removename(struct xfs_da_args *args); | 85 | extern int xfs_dir2_leaf_removename(struct xfs_da_args *args); |
86 | extern int xfs_dir2_leaf_replace(struct xfs_da_args *args); | 86 | extern int xfs_dir2_leaf_replace(struct xfs_da_args *args); |
87 | extern int xfs_dir2_leaf_search_hash(struct xfs_da_args *args, | 87 | extern int xfs_dir2_leaf_search_hash(struct xfs_da_args *args, |
88 | struct xfs_dabuf *lbp); | 88 | struct xfs_buf *lbp); |
89 | extern int xfs_dir2_leaf_trim_data(struct xfs_da_args *args, | 89 | extern int xfs_dir2_leaf_trim_data(struct xfs_da_args *args, |
90 | struct xfs_dabuf *lbp, xfs_dir2_db_t db); | 90 | struct xfs_buf *lbp, xfs_dir2_db_t db); |
91 | extern struct xfs_dir2_leaf_entry * | 91 | extern struct xfs_dir2_leaf_entry * |
92 | xfs_dir2_leaf_find_entry(struct xfs_dir2_leaf *leaf, int index, int compact, | 92 | xfs_dir2_leaf_find_entry(struct xfs_dir2_leaf *leaf, int index, int compact, |
93 | int lowstale, int highstale, | 93 | int lowstale, int highstale, |
@@ -96,13 +96,13 @@ extern int xfs_dir2_node_to_leaf(struct xfs_da_state *state); | |||
96 | 96 | ||
97 | /* xfs_dir2_node.c */ | 97 | /* xfs_dir2_node.c */ |
98 | extern int xfs_dir2_leaf_to_node(struct xfs_da_args *args, | 98 | extern int xfs_dir2_leaf_to_node(struct xfs_da_args *args, |
99 | struct xfs_dabuf *lbp); | 99 | struct xfs_buf *lbp); |
100 | extern xfs_dahash_t xfs_dir2_leafn_lasthash(struct xfs_dabuf *bp, int *count); | 100 | extern xfs_dahash_t xfs_dir2_leafn_lasthash(struct xfs_buf *bp, int *count); |
101 | extern int xfs_dir2_leafn_lookup_int(struct xfs_dabuf *bp, | 101 | extern int xfs_dir2_leafn_lookup_int(struct xfs_buf *bp, |
102 | struct xfs_da_args *args, int *indexp, | 102 | struct xfs_da_args *args, int *indexp, |
103 | struct xfs_da_state *state); | 103 | struct xfs_da_state *state); |
104 | extern int xfs_dir2_leafn_order(struct xfs_dabuf *leaf1_bp, | 104 | extern int xfs_dir2_leafn_order(struct xfs_buf *leaf1_bp, |
105 | struct xfs_dabuf *leaf2_bp); | 105 | struct xfs_buf *leaf2_bp); |
106 | extern int xfs_dir2_leafn_split(struct xfs_da_state *state, | 106 | extern int xfs_dir2_leafn_split(struct xfs_da_state *state, |
107 | struct xfs_da_state_blk *oldblk, struct xfs_da_state_blk *newblk); | 107 | struct xfs_da_state_blk *oldblk, struct xfs_da_state_blk *newblk); |
108 | extern int xfs_dir2_leafn_toosmall(struct xfs_da_state *state, int *action); | 108 | extern int xfs_dir2_leafn_toosmall(struct xfs_da_state *state, int *action); |
@@ -122,7 +122,7 @@ extern xfs_ino_t xfs_dir2_sfe_get_ino(struct xfs_dir2_sf_hdr *sfp, | |||
122 | struct xfs_dir2_sf_entry *sfep); | 122 | struct xfs_dir2_sf_entry *sfep); |
123 | extern int xfs_dir2_block_sfsize(struct xfs_inode *dp, | 123 | extern int xfs_dir2_block_sfsize(struct xfs_inode *dp, |
124 | struct xfs_dir2_data_hdr *block, struct xfs_dir2_sf_hdr *sfhp); | 124 | struct xfs_dir2_data_hdr *block, struct xfs_dir2_sf_hdr *sfhp); |
125 | extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_dabuf *bp, | 125 | extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_buf *bp, |
126 | int size, xfs_dir2_sf_hdr_t *sfhp); | 126 | int size, xfs_dir2_sf_hdr_t *sfhp); |
127 | extern int xfs_dir2_sf_addname(struct xfs_da_args *args); | 127 | extern int xfs_dir2_sf_addname(struct xfs_da_args *args); |
128 | extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino); | 128 | extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino); |
diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c index 19bf0c5e38f4..1b9fc3ec7e4b 100644 --- a/fs/xfs/xfs_dir2_sf.c +++ b/fs/xfs/xfs_dir2_sf.c | |||
@@ -222,7 +222,7 @@ xfs_dir2_block_sfsize( | |||
222 | int /* error */ | 222 | int /* error */ |
223 | xfs_dir2_block_to_sf( | 223 | xfs_dir2_block_to_sf( |
224 | xfs_da_args_t *args, /* operation arguments */ | 224 | xfs_da_args_t *args, /* operation arguments */ |
225 | xfs_dabuf_t *bp, /* block buffer */ | 225 | struct xfs_buf *bp, |
226 | int size, /* shortform directory size */ | 226 | int size, /* shortform directory size */ |
227 | xfs_dir2_sf_hdr_t *sfhp) /* shortform directory hdr */ | 227 | xfs_dir2_sf_hdr_t *sfhp) /* shortform directory hdr */ |
228 | { | 228 | { |
@@ -249,7 +249,7 @@ xfs_dir2_block_to_sf( | |||
249 | * and add local data. | 249 | * and add local data. |
250 | */ | 250 | */ |
251 | hdr = kmem_alloc(mp->m_dirblksize, KM_SLEEP); | 251 | hdr = kmem_alloc(mp->m_dirblksize, KM_SLEEP); |
252 | memcpy(hdr, bp->data, mp->m_dirblksize); | 252 | memcpy(hdr, bp->b_addr, mp->m_dirblksize); |
253 | logflags = XFS_ILOG_CORE; | 253 | logflags = XFS_ILOG_CORE; |
254 | if ((error = xfs_dir2_shrink_inode(args, mp->m_dirdatablk, bp))) { | 254 | if ((error = xfs_dir2_shrink_inode(args, mp->m_dirdatablk, bp))) { |
255 | ASSERT(error != ENOSPC); | 255 | ASSERT(error != ENOSPC); |
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 9f7ec15a6522..c4559c6e6f2c 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c | |||
@@ -236,7 +236,6 @@ xfs_file_aio_read( | |||
236 | ssize_t ret = 0; | 236 | ssize_t ret = 0; |
237 | int ioflags = 0; | 237 | int ioflags = 0; |
238 | xfs_fsize_t n; | 238 | xfs_fsize_t n; |
239 | unsigned long seg; | ||
240 | 239 | ||
241 | XFS_STATS_INC(xs_read_calls); | 240 | XFS_STATS_INC(xs_read_calls); |
242 | 241 | ||
@@ -247,19 +246,9 @@ xfs_file_aio_read( | |||
247 | if (file->f_mode & FMODE_NOCMTIME) | 246 | if (file->f_mode & FMODE_NOCMTIME) |
248 | ioflags |= IO_INVIS; | 247 | ioflags |= IO_INVIS; |
249 | 248 | ||
250 | /* START copy & waste from filemap.c */ | 249 | ret = generic_segment_checks(iovp, &nr_segs, &size, VERIFY_WRITE); |
251 | for (seg = 0; seg < nr_segs; seg++) { | 250 | if (ret < 0) |
252 | const struct iovec *iv = &iovp[seg]; | 251 | return ret; |
253 | |||
254 | /* | ||
255 | * If any segment has a negative length, or the cumulative | ||
256 | * length ever wraps negative then return -EINVAL. | ||
257 | */ | ||
258 | size += iv->iov_len; | ||
259 | if (unlikely((ssize_t)(size|iv->iov_len) < 0)) | ||
260 | return XFS_ERROR(-EINVAL); | ||
261 | } | ||
262 | /* END copy & waste from filemap.c */ | ||
263 | 252 | ||
264 | if (unlikely(ioflags & IO_ISDIRECT)) { | 253 | if (unlikely(ioflags & IO_ISDIRECT)) { |
265 | xfs_buftarg_t *target = | 254 | xfs_buftarg_t *target = |
@@ -273,7 +262,7 @@ xfs_file_aio_read( | |||
273 | } | 262 | } |
274 | } | 263 | } |
275 | 264 | ||
276 | n = XFS_MAXIOFFSET(mp) - iocb->ki_pos; | 265 | n = mp->m_super->s_maxbytes - iocb->ki_pos; |
277 | if (n <= 0 || size == 0) | 266 | if (n <= 0 || size == 0) |
278 | return 0; | 267 | return 0; |
279 | 268 | ||
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index 177a21a7ac49..21e37b55f7e5 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c | |||
@@ -442,14 +442,13 @@ xfs_ialloc_next_ag( | |||
442 | * Select an allocation group to look for a free inode in, based on the parent | 442 | * Select an allocation group to look for a free inode in, based on the parent |
443 | * inode and then mode. Return the allocation group buffer. | 443 | * inode and then mode. Return the allocation group buffer. |
444 | */ | 444 | */ |
445 | STATIC xfs_buf_t * /* allocation group buffer */ | 445 | STATIC xfs_agnumber_t |
446 | xfs_ialloc_ag_select( | 446 | xfs_ialloc_ag_select( |
447 | xfs_trans_t *tp, /* transaction pointer */ | 447 | xfs_trans_t *tp, /* transaction pointer */ |
448 | xfs_ino_t parent, /* parent directory inode number */ | 448 | xfs_ino_t parent, /* parent directory inode number */ |
449 | umode_t mode, /* bits set to indicate file type */ | 449 | umode_t mode, /* bits set to indicate file type */ |
450 | int okalloc) /* ok to allocate more space */ | 450 | int okalloc) /* ok to allocate more space */ |
451 | { | 451 | { |
452 | xfs_buf_t *agbp; /* allocation group header buffer */ | ||
453 | xfs_agnumber_t agcount; /* number of ag's in the filesystem */ | 452 | xfs_agnumber_t agcount; /* number of ag's in the filesystem */ |
454 | xfs_agnumber_t agno; /* current ag number */ | 453 | xfs_agnumber_t agno; /* current ag number */ |
455 | int flags; /* alloc buffer locking flags */ | 454 | int flags; /* alloc buffer locking flags */ |
@@ -459,6 +458,7 @@ xfs_ialloc_ag_select( | |||
459 | int needspace; /* file mode implies space allocated */ | 458 | int needspace; /* file mode implies space allocated */ |
460 | xfs_perag_t *pag; /* per allocation group data */ | 459 | xfs_perag_t *pag; /* per allocation group data */ |
461 | xfs_agnumber_t pagno; /* parent (starting) ag number */ | 460 | xfs_agnumber_t pagno; /* parent (starting) ag number */ |
461 | int error; | ||
462 | 462 | ||
463 | /* | 463 | /* |
464 | * Files of these types need at least one block if length > 0 | 464 | * Files of these types need at least one block if length > 0 |
@@ -474,7 +474,9 @@ xfs_ialloc_ag_select( | |||
474 | if (pagno >= agcount) | 474 | if (pagno >= agcount) |
475 | pagno = 0; | 475 | pagno = 0; |
476 | } | 476 | } |
477 | |||
477 | ASSERT(pagno < agcount); | 478 | ASSERT(pagno < agcount); |
479 | |||
478 | /* | 480 | /* |
479 | * Loop through allocation groups, looking for one with a little | 481 | * Loop through allocation groups, looking for one with a little |
480 | * free space in it. Note we don't look for free inodes, exactly. | 482 | * free space in it. Note we don't look for free inodes, exactly. |
@@ -486,51 +488,45 @@ xfs_ialloc_ag_select( | |||
486 | flags = XFS_ALLOC_FLAG_TRYLOCK; | 488 | flags = XFS_ALLOC_FLAG_TRYLOCK; |
487 | for (;;) { | 489 | for (;;) { |
488 | pag = xfs_perag_get(mp, agno); | 490 | pag = xfs_perag_get(mp, agno); |
491 | if (!pag->pagi_inodeok) { | ||
492 | xfs_ialloc_next_ag(mp); | ||
493 | goto nextag; | ||
494 | } | ||
495 | |||
489 | if (!pag->pagi_init) { | 496 | if (!pag->pagi_init) { |
490 | if (xfs_ialloc_read_agi(mp, tp, agno, &agbp)) { | 497 | error = xfs_ialloc_pagi_init(mp, tp, agno); |
491 | agbp = NULL; | 498 | if (error) |
492 | goto nextag; | 499 | goto nextag; |
493 | } | 500 | } |
494 | } else | ||
495 | agbp = NULL; | ||
496 | 501 | ||
497 | if (!pag->pagi_inodeok) { | 502 | if (pag->pagi_freecount) { |
498 | xfs_ialloc_next_ag(mp); | 503 | xfs_perag_put(pag); |
499 | goto unlock_nextag; | 504 | return agno; |
500 | } | 505 | } |
501 | 506 | ||
502 | /* | 507 | if (!okalloc) |
503 | * Is there enough free space for the file plus a block | 508 | goto nextag; |
504 | * of inodes (if we need to allocate some)? | 509 | |
505 | */ | 510 | if (!pag->pagf_init) { |
506 | ineed = pag->pagi_freecount ? 0 : XFS_IALLOC_BLOCKS(mp); | 511 | error = xfs_alloc_pagf_init(mp, tp, agno, flags); |
507 | if (ineed && !pag->pagf_init) { | 512 | if (error) |
508 | if (agbp == NULL && | ||
509 | xfs_ialloc_read_agi(mp, tp, agno, &agbp)) { | ||
510 | agbp = NULL; | ||
511 | goto nextag; | 513 | goto nextag; |
512 | } | ||
513 | (void)xfs_alloc_pagf_init(mp, tp, agno, flags); | ||
514 | } | 514 | } |
515 | if (!ineed || pag->pagf_init) { | 515 | |
516 | if (ineed && !(longest = pag->pagf_longest)) | 516 | /* |
517 | longest = pag->pagf_flcount > 0; | 517 | * Is there enough free space for the file plus a block of |
518 | if (!ineed || | 518 | * inodes? (if we need to allocate some)? |
519 | (pag->pagf_freeblks >= needspace + ineed && | 519 | */ |
520 | longest >= ineed && | 520 | ineed = XFS_IALLOC_BLOCKS(mp); |
521 | okalloc)) { | 521 | longest = pag->pagf_longest; |
522 | if (agbp == NULL && | 522 | if (!longest) |
523 | xfs_ialloc_read_agi(mp, tp, agno, &agbp)) { | 523 | longest = pag->pagf_flcount > 0; |
524 | agbp = NULL; | 524 | |
525 | goto nextag; | 525 | if (pag->pagf_freeblks >= needspace + ineed && |
526 | } | 526 | longest >= ineed) { |
527 | xfs_perag_put(pag); | 527 | xfs_perag_put(pag); |
528 | return agbp; | 528 | return agno; |
529 | } | ||
530 | } | 529 | } |
531 | unlock_nextag: | ||
532 | if (agbp) | ||
533 | xfs_trans_brelse(tp, agbp); | ||
534 | nextag: | 530 | nextag: |
535 | xfs_perag_put(pag); | 531 | xfs_perag_put(pag); |
536 | /* | 532 | /* |
@@ -538,13 +534,13 @@ nextag: | |||
538 | * down. | 534 | * down. |
539 | */ | 535 | */ |
540 | if (XFS_FORCED_SHUTDOWN(mp)) | 536 | if (XFS_FORCED_SHUTDOWN(mp)) |
541 | return NULL; | 537 | return NULLAGNUMBER; |
542 | agno++; | 538 | agno++; |
543 | if (agno >= agcount) | 539 | if (agno >= agcount) |
544 | agno = 0; | 540 | agno = 0; |
545 | if (agno == pagno) { | 541 | if (agno == pagno) { |
546 | if (flags == 0) | 542 | if (flags == 0) |
547 | return NULL; | 543 | return NULLAGNUMBER; |
548 | flags = 0; | 544 | flags = 0; |
549 | } | 545 | } |
550 | } | 546 | } |
@@ -607,195 +603,39 @@ xfs_ialloc_get_rec( | |||
607 | } | 603 | } |
608 | 604 | ||
609 | /* | 605 | /* |
610 | * Visible inode allocation functions. | 606 | * Allocate an inode. |
611 | */ | ||
612 | /* | ||
613 | * Find a free (set) bit in the inode bitmask. | ||
614 | */ | ||
615 | static inline int xfs_ialloc_find_free(xfs_inofree_t *fp) | ||
616 | { | ||
617 | return xfs_lowbit64(*fp); | ||
618 | } | ||
619 | |||
620 | /* | ||
621 | * Allocate an inode on disk. | ||
622 | * Mode is used to tell whether the new inode will need space, and whether | ||
623 | * it is a directory. | ||
624 | * | ||
625 | * The arguments IO_agbp and alloc_done are defined to work within | ||
626 | * the constraint of one allocation per transaction. | ||
627 | * xfs_dialloc() is designed to be called twice if it has to do an | ||
628 | * allocation to make more free inodes. On the first call, | ||
629 | * IO_agbp should be set to NULL. If an inode is available, | ||
630 | * i.e., xfs_dialloc() did not need to do an allocation, an inode | ||
631 | * number is returned. In this case, IO_agbp would be set to the | ||
632 | * current ag_buf and alloc_done set to false. | ||
633 | * If an allocation needed to be done, xfs_dialloc would return | ||
634 | * the current ag_buf in IO_agbp and set alloc_done to true. | ||
635 | * The caller should then commit the current transaction, allocate a new | ||
636 | * transaction, and call xfs_dialloc() again, passing in the previous | ||
637 | * value of IO_agbp. IO_agbp should be held across the transactions. | ||
638 | * Since the agbp is locked across the two calls, the second call is | ||
639 | * guaranteed to have a free inode available. | ||
640 | * | 607 | * |
641 | * Once we successfully pick an inode its number is returned and the | 608 | * The caller selected an AG for us, and made sure that free inodes are |
642 | * on-disk data structures are updated. The inode itself is not read | 609 | * available. |
643 | * in, since doing so would break ordering constraints with xfs_reclaim. | ||
644 | */ | 610 | */ |
645 | int | 611 | STATIC int |
646 | xfs_dialloc( | 612 | xfs_dialloc_ag( |
647 | xfs_trans_t *tp, /* transaction pointer */ | 613 | struct xfs_trans *tp, |
648 | xfs_ino_t parent, /* parent inode (directory) */ | 614 | struct xfs_buf *agbp, |
649 | umode_t mode, /* mode bits for new inode */ | 615 | xfs_ino_t parent, |
650 | int okalloc, /* ok to allocate more space */ | 616 | xfs_ino_t *inop) |
651 | xfs_buf_t **IO_agbp, /* in/out ag header's buffer */ | ||
652 | boolean_t *alloc_done, /* true if we needed to replenish | ||
653 | inode freelist */ | ||
654 | xfs_ino_t *inop) /* inode number allocated */ | ||
655 | { | 617 | { |
656 | xfs_agnumber_t agcount; /* number of allocation groups */ | 618 | struct xfs_mount *mp = tp->t_mountp; |
657 | xfs_buf_t *agbp; /* allocation group header's buffer */ | 619 | struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp); |
658 | xfs_agnumber_t agno; /* allocation group number */ | 620 | xfs_agnumber_t agno = be32_to_cpu(agi->agi_seqno); |
659 | xfs_agi_t *agi; /* allocation group header structure */ | 621 | xfs_agnumber_t pagno = XFS_INO_TO_AGNO(mp, parent); |
660 | xfs_btree_cur_t *cur; /* inode allocation btree cursor */ | 622 | xfs_agino_t pagino = XFS_INO_TO_AGINO(mp, parent); |
661 | int error; /* error return value */ | 623 | struct xfs_perag *pag; |
662 | int i; /* result code */ | 624 | struct xfs_btree_cur *cur, *tcur; |
663 | int ialloced; /* inode allocation status */ | 625 | struct xfs_inobt_rec_incore rec, trec; |
664 | int noroom = 0; /* no space for inode blk allocation */ | 626 | xfs_ino_t ino; |
665 | xfs_ino_t ino; /* fs-relative inode to be returned */ | 627 | int error; |
666 | /* REFERENCED */ | 628 | int offset; |
667 | int j; /* result code */ | 629 | int i, j; |
668 | xfs_mount_t *mp; /* file system mount structure */ | ||
669 | int offset; /* index of inode in chunk */ | ||
670 | xfs_agino_t pagino; /* parent's AG relative inode # */ | ||
671 | xfs_agnumber_t pagno; /* parent's AG number */ | ||
672 | xfs_inobt_rec_incore_t rec; /* inode allocation record */ | ||
673 | xfs_agnumber_t tagno; /* testing allocation group number */ | ||
674 | xfs_btree_cur_t *tcur; /* temp cursor */ | ||
675 | xfs_inobt_rec_incore_t trec; /* temp inode allocation record */ | ||
676 | struct xfs_perag *pag; | ||
677 | |||
678 | |||
679 | if (*IO_agbp == NULL) { | ||
680 | /* | ||
681 | * We do not have an agbp, so select an initial allocation | ||
682 | * group for inode allocation. | ||
683 | */ | ||
684 | agbp = xfs_ialloc_ag_select(tp, parent, mode, okalloc); | ||
685 | /* | ||
686 | * Couldn't find an allocation group satisfying the | ||
687 | * criteria, give up. | ||
688 | */ | ||
689 | if (!agbp) { | ||
690 | *inop = NULLFSINO; | ||
691 | return 0; | ||
692 | } | ||
693 | agi = XFS_BUF_TO_AGI(agbp); | ||
694 | ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC)); | ||
695 | } else { | ||
696 | /* | ||
697 | * Continue where we left off before. In this case, we | ||
698 | * know that the allocation group has free inodes. | ||
699 | */ | ||
700 | agbp = *IO_agbp; | ||
701 | agi = XFS_BUF_TO_AGI(agbp); | ||
702 | ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC)); | ||
703 | ASSERT(be32_to_cpu(agi->agi_freecount) > 0); | ||
704 | } | ||
705 | mp = tp->t_mountp; | ||
706 | agcount = mp->m_sb.sb_agcount; | ||
707 | agno = be32_to_cpu(agi->agi_seqno); | ||
708 | tagno = agno; | ||
709 | pagno = XFS_INO_TO_AGNO(mp, parent); | ||
710 | pagino = XFS_INO_TO_AGINO(mp, parent); | ||
711 | |||
712 | /* | ||
713 | * If we have already hit the ceiling of inode blocks then clear | ||
714 | * okalloc so we scan all available agi structures for a free | ||
715 | * inode. | ||
716 | */ | ||
717 | |||
718 | if (mp->m_maxicount && | ||
719 | mp->m_sb.sb_icount + XFS_IALLOC_INODES(mp) > mp->m_maxicount) { | ||
720 | noroom = 1; | ||
721 | okalloc = 0; | ||
722 | } | ||
723 | 630 | ||
724 | /* | ||
725 | * Loop until we find an allocation group that either has free inodes | ||
726 | * or in which we can allocate some inodes. Iterate through the | ||
727 | * allocation groups upward, wrapping at the end. | ||
728 | */ | ||
729 | *alloc_done = B_FALSE; | ||
730 | while (!agi->agi_freecount) { | ||
731 | /* | ||
732 | * Don't do anything if we're not supposed to allocate | ||
733 | * any blocks, just go on to the next ag. | ||
734 | */ | ||
735 | if (okalloc) { | ||
736 | /* | ||
737 | * Try to allocate some new inodes in the allocation | ||
738 | * group. | ||
739 | */ | ||
740 | if ((error = xfs_ialloc_ag_alloc(tp, agbp, &ialloced))) { | ||
741 | xfs_trans_brelse(tp, agbp); | ||
742 | if (error == ENOSPC) { | ||
743 | *inop = NULLFSINO; | ||
744 | return 0; | ||
745 | } else | ||
746 | return error; | ||
747 | } | ||
748 | if (ialloced) { | ||
749 | /* | ||
750 | * We successfully allocated some inodes, return | ||
751 | * the current context to the caller so that it | ||
752 | * can commit the current transaction and call | ||
753 | * us again where we left off. | ||
754 | */ | ||
755 | ASSERT(be32_to_cpu(agi->agi_freecount) > 0); | ||
756 | *alloc_done = B_TRUE; | ||
757 | *IO_agbp = agbp; | ||
758 | *inop = NULLFSINO; | ||
759 | return 0; | ||
760 | } | ||
761 | } | ||
762 | /* | ||
763 | * If it failed, give up on this ag. | ||
764 | */ | ||
765 | xfs_trans_brelse(tp, agbp); | ||
766 | /* | ||
767 | * Go on to the next ag: get its ag header. | ||
768 | */ | ||
769 | nextag: | ||
770 | if (++tagno == agcount) | ||
771 | tagno = 0; | ||
772 | if (tagno == agno) { | ||
773 | *inop = NULLFSINO; | ||
774 | return noroom ? ENOSPC : 0; | ||
775 | } | ||
776 | pag = xfs_perag_get(mp, tagno); | ||
777 | if (pag->pagi_inodeok == 0) { | ||
778 | xfs_perag_put(pag); | ||
779 | goto nextag; | ||
780 | } | ||
781 | error = xfs_ialloc_read_agi(mp, tp, tagno, &agbp); | ||
782 | xfs_perag_put(pag); | ||
783 | if (error) | ||
784 | goto nextag; | ||
785 | agi = XFS_BUF_TO_AGI(agbp); | ||
786 | ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC)); | ||
787 | } | ||
788 | /* | ||
789 | * Here with an allocation group that has a free inode. | ||
790 | * Reset agno since we may have chosen a new ag in the | ||
791 | * loop above. | ||
792 | */ | ||
793 | agno = tagno; | ||
794 | *IO_agbp = NULL; | ||
795 | pag = xfs_perag_get(mp, agno); | 631 | pag = xfs_perag_get(mp, agno); |
796 | 632 | ||
633 | ASSERT(pag->pagi_init); | ||
634 | ASSERT(pag->pagi_inodeok); | ||
635 | ASSERT(pag->pagi_freecount > 0); | ||
636 | |||
797 | restart_pagno: | 637 | restart_pagno: |
798 | cur = xfs_inobt_init_cursor(mp, tp, agbp, be32_to_cpu(agi->agi_seqno)); | 638 | cur = xfs_inobt_init_cursor(mp, tp, agbp, agno); |
799 | /* | 639 | /* |
800 | * If pagino is 0 (this is the root inode allocation) use newino. | 640 | * If pagino is 0 (this is the root inode allocation) use newino. |
801 | * This must work because we've just allocated some. | 641 | * This must work because we've just allocated some. |
@@ -995,7 +835,7 @@ newino: | |||
995 | } | 835 | } |
996 | 836 | ||
997 | alloc_inode: | 837 | alloc_inode: |
998 | offset = xfs_ialloc_find_free(&rec.ir_free); | 838 | offset = xfs_lowbit64(rec.ir_free); |
999 | ASSERT(offset >= 0); | 839 | ASSERT(offset >= 0); |
1000 | ASSERT(offset < XFS_INODES_PER_CHUNK); | 840 | ASSERT(offset < XFS_INODES_PER_CHUNK); |
1001 | ASSERT((XFS_AGINO_TO_OFFSET(mp, rec.ir_startino) % | 841 | ASSERT((XFS_AGINO_TO_OFFSET(mp, rec.ir_startino) % |
@@ -1028,6 +868,164 @@ error0: | |||
1028 | } | 868 | } |
1029 | 869 | ||
1030 | /* | 870 | /* |
871 | * Allocate an inode on disk. | ||
872 | * | ||
873 | * Mode is used to tell whether the new inode will need space, and whether it | ||
874 | * is a directory. | ||
875 | * | ||
876 | * This function is designed to be called twice if it has to do an allocation | ||
877 | * to make more free inodes. On the first call, *IO_agbp should be set to NULL. | ||
878 | * If an inode is available without having to performn an allocation, an inode | ||
879 | * number is returned. In this case, *IO_agbp would be NULL. If an allocation | ||
880 | * needes to be done, xfs_dialloc would return the current AGI buffer in | ||
881 | * *IO_agbp. The caller should then commit the current transaction, allocate a | ||
882 | * new transaction, and call xfs_dialloc() again, passing in the previous value | ||
883 | * of *IO_agbp. IO_agbp should be held across the transactions. Since the AGI | ||
884 | * buffer is locked across the two calls, the second call is guaranteed to have | ||
885 | * a free inode available. | ||
886 | * | ||
887 | * Once we successfully pick an inode its number is returned and the on-disk | ||
888 | * data structures are updated. The inode itself is not read in, since doing so | ||
889 | * would break ordering constraints with xfs_reclaim. | ||
890 | */ | ||
891 | int | ||
892 | xfs_dialloc( | ||
893 | struct xfs_trans *tp, | ||
894 | xfs_ino_t parent, | ||
895 | umode_t mode, | ||
896 | int okalloc, | ||
897 | struct xfs_buf **IO_agbp, | ||
898 | xfs_ino_t *inop) | ||
899 | { | ||
900 | struct xfs_mount *mp = tp->t_mountp; | ||
901 | struct xfs_buf *agbp; | ||
902 | xfs_agnumber_t agno; | ||
903 | int error; | ||
904 | int ialloced; | ||
905 | int noroom = 0; | ||
906 | xfs_agnumber_t start_agno; | ||
907 | struct xfs_perag *pag; | ||
908 | |||
909 | if (*IO_agbp) { | ||
910 | /* | ||
911 | * If the caller passes in a pointer to the AGI buffer, | ||
912 | * continue where we left off before. In this case, we | ||
913 | * know that the allocation group has free inodes. | ||
914 | */ | ||
915 | agbp = *IO_agbp; | ||
916 | goto out_alloc; | ||
917 | } | ||
918 | |||
919 | /* | ||
920 | * We do not have an agbp, so select an initial allocation | ||
921 | * group for inode allocation. | ||
922 | */ | ||
923 | start_agno = xfs_ialloc_ag_select(tp, parent, mode, okalloc); | ||
924 | if (start_agno == NULLAGNUMBER) { | ||
925 | *inop = NULLFSINO; | ||
926 | return 0; | ||
927 | } | ||
928 | |||
929 | /* | ||
930 | * If we have already hit the ceiling of inode blocks then clear | ||
931 | * okalloc so we scan all available agi structures for a free | ||
932 | * inode. | ||
933 | */ | ||
934 | if (mp->m_maxicount && | ||
935 | mp->m_sb.sb_icount + XFS_IALLOC_INODES(mp) > mp->m_maxicount) { | ||
936 | noroom = 1; | ||
937 | okalloc = 0; | ||
938 | } | ||
939 | |||
940 | /* | ||
941 | * Loop until we find an allocation group that either has free inodes | ||
942 | * or in which we can allocate some inodes. Iterate through the | ||
943 | * allocation groups upward, wrapping at the end. | ||
944 | */ | ||
945 | agno = start_agno; | ||
946 | for (;;) { | ||
947 | pag = xfs_perag_get(mp, agno); | ||
948 | if (!pag->pagi_inodeok) { | ||
949 | xfs_ialloc_next_ag(mp); | ||
950 | goto nextag; | ||
951 | } | ||
952 | |||
953 | if (!pag->pagi_init) { | ||
954 | error = xfs_ialloc_pagi_init(mp, tp, agno); | ||
955 | if (error) | ||
956 | goto out_error; | ||
957 | } | ||
958 | |||
959 | /* | ||
960 | * Do a first racy fast path check if this AG is usable. | ||
961 | */ | ||
962 | if (!pag->pagi_freecount && !okalloc) | ||
963 | goto nextag; | ||
964 | |||
965 | error = xfs_ialloc_read_agi(mp, tp, agno, &agbp); | ||
966 | if (error) | ||
967 | goto out_error; | ||
968 | |||
969 | /* | ||
970 | * Once the AGI has been read in we have to recheck | ||
971 | * pagi_freecount with the AGI buffer lock held. | ||
972 | */ | ||
973 | if (pag->pagi_freecount) { | ||
974 | xfs_perag_put(pag); | ||
975 | goto out_alloc; | ||
976 | } | ||
977 | |||
978 | if (!okalloc) { | ||
979 | xfs_trans_brelse(tp, agbp); | ||
980 | goto nextag; | ||
981 | } | ||
982 | |||
983 | error = xfs_ialloc_ag_alloc(tp, agbp, &ialloced); | ||
984 | if (error) { | ||
985 | xfs_trans_brelse(tp, agbp); | ||
986 | |||
987 | if (error != ENOSPC) | ||
988 | goto out_error; | ||
989 | |||
990 | xfs_perag_put(pag); | ||
991 | *inop = NULLFSINO; | ||
992 | return 0; | ||
993 | } | ||
994 | |||
995 | if (ialloced) { | ||
996 | /* | ||
997 | * We successfully allocated some inodes, return | ||
998 | * the current context to the caller so that it | ||
999 | * can commit the current transaction and call | ||
1000 | * us again where we left off. | ||
1001 | */ | ||
1002 | ASSERT(pag->pagi_freecount > 0); | ||
1003 | xfs_perag_put(pag); | ||
1004 | |||
1005 | *IO_agbp = agbp; | ||
1006 | *inop = NULLFSINO; | ||
1007 | return 0; | ||
1008 | } | ||
1009 | |||
1010 | nextag: | ||
1011 | xfs_perag_put(pag); | ||
1012 | if (++agno == mp->m_sb.sb_agcount) | ||
1013 | agno = 0; | ||
1014 | if (agno == start_agno) { | ||
1015 | *inop = NULLFSINO; | ||
1016 | return noroom ? ENOSPC : 0; | ||
1017 | } | ||
1018 | } | ||
1019 | |||
1020 | out_alloc: | ||
1021 | *IO_agbp = NULL; | ||
1022 | return xfs_dialloc_ag(tp, agbp, parent, inop); | ||
1023 | out_error: | ||
1024 | xfs_perag_put(pag); | ||
1025 | return XFS_ERROR(error); | ||
1026 | } | ||
1027 | |||
1028 | /* | ||
1031 | * Free disk inode. Carefully avoids touching the incore inode, all | 1029 | * Free disk inode. Carefully avoids touching the incore inode, all |
1032 | * manipulations incore are the caller's responsibility. | 1030 | * manipulations incore are the caller's responsibility. |
1033 | * The on-disk inode is not changed by this operation, only the | 1031 | * The on-disk inode is not changed by this operation, only the |
diff --git a/fs/xfs/xfs_ialloc.h b/fs/xfs/xfs_ialloc.h index 65ac57c8063c..1fd6ea4e9c91 100644 --- a/fs/xfs/xfs_ialloc.h +++ b/fs/xfs/xfs_ialloc.h | |||
@@ -75,8 +75,6 @@ xfs_dialloc( | |||
75 | umode_t mode, /* mode bits for new inode */ | 75 | umode_t mode, /* mode bits for new inode */ |
76 | int okalloc, /* ok to allocate more space */ | 76 | int okalloc, /* ok to allocate more space */ |
77 | struct xfs_buf **agbp, /* buf for a.g. inode header */ | 77 | struct xfs_buf **agbp, /* buf for a.g. inode header */ |
78 | boolean_t *alloc_done, /* an allocation was done to replenish | ||
79 | the free inodes */ | ||
80 | xfs_ino_t *inop); /* inode number allocated */ | 78 | xfs_ino_t *inop); /* inode number allocated */ |
81 | 79 | ||
82 | /* | 80 | /* |
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 1bb4365e8c25..784a803383ec 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
@@ -41,17 +41,6 @@ | |||
41 | 41 | ||
42 | 42 | ||
43 | /* | 43 | /* |
44 | * Define xfs inode iolock lockdep classes. We need to ensure that all active | ||
45 | * inodes are considered the same for lockdep purposes, including inodes that | ||
46 | * are recycled through the XFS_IRECLAIMABLE state. This is the the only way to | ||
47 | * guarantee the locks are considered the same when there are multiple lock | ||
48 | * initialisation siteѕ. Also, define a reclaimable inode class so it is | ||
49 | * obvious in lockdep reports which class the report is against. | ||
50 | */ | ||
51 | static struct lock_class_key xfs_iolock_active; | ||
52 | struct lock_class_key xfs_iolock_reclaimable; | ||
53 | |||
54 | /* | ||
55 | * Allocate and initialise an xfs_inode. | 44 | * Allocate and initialise an xfs_inode. |
56 | */ | 45 | */ |
57 | STATIC struct xfs_inode * | 46 | STATIC struct xfs_inode * |
@@ -80,8 +69,6 @@ xfs_inode_alloc( | |||
80 | ASSERT(ip->i_ino == 0); | 69 | ASSERT(ip->i_ino == 0); |
81 | 70 | ||
82 | mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); | 71 | mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); |
83 | lockdep_set_class_and_name(&ip->i_iolock.mr_lock, | ||
84 | &xfs_iolock_active, "xfs_iolock_active"); | ||
85 | 72 | ||
86 | /* initialise the xfs inode */ | 73 | /* initialise the xfs inode */ |
87 | ip->i_ino = ino; | 74 | ip->i_ino = ino; |
@@ -250,8 +237,6 @@ xfs_iget_cache_hit( | |||
250 | 237 | ||
251 | ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock)); | 238 | ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock)); |
252 | mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); | 239 | mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); |
253 | lockdep_set_class_and_name(&ip->i_iolock.mr_lock, | ||
254 | &xfs_iolock_active, "xfs_iolock_active"); | ||
255 | 240 | ||
256 | spin_unlock(&ip->i_flags_lock); | 241 | spin_unlock(&ip->i_flags_lock); |
257 | spin_unlock(&pag->pag_ici_lock); | 242 | spin_unlock(&pag->pag_ici_lock); |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index a59eea09930a..2778258fcfa2 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -132,23 +132,28 @@ xfs_inobp_check( | |||
132 | #endif | 132 | #endif |
133 | 133 | ||
134 | /* | 134 | /* |
135 | * Find the buffer associated with the given inode map | 135 | * This routine is called to map an inode to the buffer containing the on-disk |
136 | * We do basic validation checks on the buffer once it has been | 136 | * version of the inode. It returns a pointer to the buffer containing the |
137 | * retrieved from disk. | 137 | * on-disk inode in the bpp parameter, and in the dipp parameter it returns a |
138 | * pointer to the on-disk inode within that buffer. | ||
139 | * | ||
140 | * If a non-zero error is returned, then the contents of bpp and dipp are | ||
141 | * undefined. | ||
138 | */ | 142 | */ |
139 | STATIC int | 143 | int |
140 | xfs_imap_to_bp( | 144 | xfs_imap_to_bp( |
141 | xfs_mount_t *mp, | 145 | struct xfs_mount *mp, |
142 | xfs_trans_t *tp, | 146 | struct xfs_trans *tp, |
143 | struct xfs_imap *imap, | 147 | struct xfs_imap *imap, |
144 | xfs_buf_t **bpp, | 148 | struct xfs_dinode **dipp, |
145 | uint buf_flags, | 149 | struct xfs_buf **bpp, |
146 | uint iget_flags) | 150 | uint buf_flags, |
151 | uint iget_flags) | ||
147 | { | 152 | { |
148 | int error; | 153 | struct xfs_buf *bp; |
149 | int i; | 154 | int error; |
150 | int ni; | 155 | int i; |
151 | xfs_buf_t *bp; | 156 | int ni; |
152 | 157 | ||
153 | buf_flags |= XBF_UNMAPPED; | 158 | buf_flags |= XBF_UNMAPPED; |
154 | error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap->im_blkno, | 159 | error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap->im_blkno, |
@@ -189,8 +194,8 @@ xfs_imap_to_bp( | |||
189 | xfs_trans_brelse(tp, bp); | 194 | xfs_trans_brelse(tp, bp); |
190 | return XFS_ERROR(EINVAL); | 195 | return XFS_ERROR(EINVAL); |
191 | } | 196 | } |
192 | XFS_CORRUPTION_ERROR("xfs_imap_to_bp", | 197 | XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_HIGH, |
193 | XFS_ERRLEVEL_HIGH, mp, dip); | 198 | mp, dip); |
194 | #ifdef DEBUG | 199 | #ifdef DEBUG |
195 | xfs_emerg(mp, | 200 | xfs_emerg(mp, |
196 | "bad inode magic/vsn daddr %lld #%d (magic=%x)", | 201 | "bad inode magic/vsn daddr %lld #%d (magic=%x)", |
@@ -204,96 +209,9 @@ xfs_imap_to_bp( | |||
204 | } | 209 | } |
205 | 210 | ||
206 | xfs_inobp_check(mp, bp); | 211 | xfs_inobp_check(mp, bp); |
207 | *bpp = bp; | ||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | /* | ||
212 | * This routine is called to map an inode number within a file | ||
213 | * system to the buffer containing the on-disk version of the | ||
214 | * inode. It returns a pointer to the buffer containing the | ||
215 | * on-disk inode in the bpp parameter, and in the dip parameter | ||
216 | * it returns a pointer to the on-disk inode within that buffer. | ||
217 | * | ||
218 | * If a non-zero error is returned, then the contents of bpp and | ||
219 | * dipp are undefined. | ||
220 | * | ||
221 | * Use xfs_imap() to determine the size and location of the | ||
222 | * buffer to read from disk. | ||
223 | */ | ||
224 | int | ||
225 | xfs_inotobp( | ||
226 | xfs_mount_t *mp, | ||
227 | xfs_trans_t *tp, | ||
228 | xfs_ino_t ino, | ||
229 | xfs_dinode_t **dipp, | ||
230 | xfs_buf_t **bpp, | ||
231 | int *offset, | ||
232 | uint imap_flags) | ||
233 | { | ||
234 | struct xfs_imap imap; | ||
235 | xfs_buf_t *bp; | ||
236 | int error; | ||
237 | |||
238 | imap.im_blkno = 0; | ||
239 | error = xfs_imap(mp, tp, ino, &imap, imap_flags); | ||
240 | if (error) | ||
241 | return error; | ||
242 | |||
243 | error = xfs_imap_to_bp(mp, tp, &imap, &bp, 0, imap_flags); | ||
244 | if (error) | ||
245 | return error; | ||
246 | |||
247 | *dipp = (xfs_dinode_t *)xfs_buf_offset(bp, imap.im_boffset); | ||
248 | *bpp = bp; | ||
249 | *offset = imap.im_boffset; | ||
250 | return 0; | ||
251 | } | ||
252 | |||
253 | |||
254 | /* | ||
255 | * This routine is called to map an inode to the buffer containing | ||
256 | * the on-disk version of the inode. It returns a pointer to the | ||
257 | * buffer containing the on-disk inode in the bpp parameter, and in | ||
258 | * the dip parameter it returns a pointer to the on-disk inode within | ||
259 | * that buffer. | ||
260 | * | ||
261 | * If a non-zero error is returned, then the contents of bpp and | ||
262 | * dipp are undefined. | ||
263 | * | ||
264 | * The inode is expected to already been mapped to its buffer and read | ||
265 | * in once, thus we can use the mapping information stored in the inode | ||
266 | * rather than calling xfs_imap(). This allows us to avoid the overhead | ||
267 | * of looking at the inode btree for small block file systems | ||
268 | * (see xfs_imap()). | ||
269 | */ | ||
270 | int | ||
271 | xfs_itobp( | ||
272 | xfs_mount_t *mp, | ||
273 | xfs_trans_t *tp, | ||
274 | xfs_inode_t *ip, | ||
275 | xfs_dinode_t **dipp, | ||
276 | xfs_buf_t **bpp, | ||
277 | uint buf_flags) | ||
278 | { | ||
279 | xfs_buf_t *bp; | ||
280 | int error; | ||
281 | |||
282 | ASSERT(ip->i_imap.im_blkno != 0); | ||
283 | |||
284 | error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &bp, buf_flags, 0); | ||
285 | if (error) | ||
286 | return error; | ||
287 | 212 | ||
288 | if (!bp) { | ||
289 | ASSERT(buf_flags & XBF_TRYLOCK); | ||
290 | ASSERT(tp == NULL); | ||
291 | *bpp = NULL; | ||
292 | return EAGAIN; | ||
293 | } | ||
294 | |||
295 | *dipp = (xfs_dinode_t *)xfs_buf_offset(bp, ip->i_imap.im_boffset); | ||
296 | *bpp = bp; | 213 | *bpp = bp; |
214 | *dipp = (struct xfs_dinode *)xfs_buf_offset(bp, imap->im_boffset); | ||
297 | return 0; | 215 | return 0; |
298 | } | 216 | } |
299 | 217 | ||
@@ -796,10 +714,9 @@ xfs_iread( | |||
796 | /* | 714 | /* |
797 | * Get pointers to the on-disk inode and the buffer containing it. | 715 | * Get pointers to the on-disk inode and the buffer containing it. |
798 | */ | 716 | */ |
799 | error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &bp, 0, iget_flags); | 717 | error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &dip, &bp, 0, iget_flags); |
800 | if (error) | 718 | if (error) |
801 | return error; | 719 | return error; |
802 | dip = (xfs_dinode_t *)xfs_buf_offset(bp, ip->i_imap.im_boffset); | ||
803 | 720 | ||
804 | /* | 721 | /* |
805 | * If we got something that isn't an inode it means someone | 722 | * If we got something that isn't an inode it means someone |
@@ -876,7 +793,7 @@ xfs_iread( | |||
876 | /* | 793 | /* |
877 | * Use xfs_trans_brelse() to release the buffer containing the | 794 | * Use xfs_trans_brelse() to release the buffer containing the |
878 | * on-disk inode, because it was acquired with xfs_trans_read_buf() | 795 | * on-disk inode, because it was acquired with xfs_trans_read_buf() |
879 | * in xfs_itobp() above. If tp is NULL, this is just a normal | 796 | * in xfs_imap_to_bp() above. If tp is NULL, this is just a normal |
880 | * brelse(). If we're within a transaction, then xfs_trans_brelse() | 797 | * brelse(). If we're within a transaction, then xfs_trans_brelse() |
881 | * will only release the buffer if it is not dirty within the | 798 | * will only release the buffer if it is not dirty within the |
882 | * transaction. It will be OK to release the buffer in this case, | 799 | * transaction. It will be OK to release the buffer in this case, |
@@ -970,7 +887,6 @@ xfs_ialloc( | |||
970 | prid_t prid, | 887 | prid_t prid, |
971 | int okalloc, | 888 | int okalloc, |
972 | xfs_buf_t **ialloc_context, | 889 | xfs_buf_t **ialloc_context, |
973 | boolean_t *call_again, | ||
974 | xfs_inode_t **ipp) | 890 | xfs_inode_t **ipp) |
975 | { | 891 | { |
976 | xfs_ino_t ino; | 892 | xfs_ino_t ino; |
@@ -985,10 +901,10 @@ xfs_ialloc( | |||
985 | * the on-disk inode to be allocated. | 901 | * the on-disk inode to be allocated. |
986 | */ | 902 | */ |
987 | error = xfs_dialloc(tp, pip ? pip->i_ino : 0, mode, okalloc, | 903 | error = xfs_dialloc(tp, pip ? pip->i_ino : 0, mode, okalloc, |
988 | ialloc_context, call_again, &ino); | 904 | ialloc_context, &ino); |
989 | if (error) | 905 | if (error) |
990 | return error; | 906 | return error; |
991 | if (*call_again || ino == NULLFSINO) { | 907 | if (*ialloc_context || ino == NULLFSINO) { |
992 | *ipp = NULL; | 908 | *ipp = NULL; |
993 | return 0; | 909 | return 0; |
994 | } | 910 | } |
@@ -1207,7 +1123,9 @@ xfs_itruncate_extents( | |||
1207 | int error = 0; | 1123 | int error = 0; |
1208 | int done = 0; | 1124 | int done = 0; |
1209 | 1125 | ||
1210 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL)); | 1126 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
1127 | ASSERT(!atomic_read(&VFS_I(ip)->i_count) || | ||
1128 | xfs_isilocked(ip, XFS_IOLOCK_EXCL)); | ||
1211 | ASSERT(new_size <= XFS_ISIZE(ip)); | 1129 | ASSERT(new_size <= XFS_ISIZE(ip)); |
1212 | ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); | 1130 | ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); |
1213 | ASSERT(ip->i_itemp != NULL); | 1131 | ASSERT(ip->i_itemp != NULL); |
@@ -1226,7 +1144,7 @@ xfs_itruncate_extents( | |||
1226 | * then there is nothing to do. | 1144 | * then there is nothing to do. |
1227 | */ | 1145 | */ |
1228 | first_unmap_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size); | 1146 | first_unmap_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size); |
1229 | last_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp)); | 1147 | last_block = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes); |
1230 | if (first_unmap_block == last_block) | 1148 | if (first_unmap_block == last_block) |
1231 | return 0; | 1149 | return 0; |
1232 | 1150 | ||
@@ -1355,7 +1273,8 @@ xfs_iunlink( | |||
1355 | * Here we put the head pointer into our next pointer, | 1273 | * Here we put the head pointer into our next pointer, |
1356 | * and then we fall through to point the head at us. | 1274 | * and then we fall through to point the head at us. |
1357 | */ | 1275 | */ |
1358 | error = xfs_itobp(mp, tp, ip, &dip, &ibp, 0); | 1276 | error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &dip, &ibp, |
1277 | 0, 0); | ||
1359 | if (error) | 1278 | if (error) |
1360 | return error; | 1279 | return error; |
1361 | 1280 | ||
@@ -1429,16 +1348,16 @@ xfs_iunlink_remove( | |||
1429 | 1348 | ||
1430 | if (be32_to_cpu(agi->agi_unlinked[bucket_index]) == agino) { | 1349 | if (be32_to_cpu(agi->agi_unlinked[bucket_index]) == agino) { |
1431 | /* | 1350 | /* |
1432 | * We're at the head of the list. Get the inode's | 1351 | * We're at the head of the list. Get the inode's on-disk |
1433 | * on-disk buffer to see if there is anyone after us | 1352 | * buffer to see if there is anyone after us on the list. |
1434 | * on the list. Only modify our next pointer if it | 1353 | * Only modify our next pointer if it is not already NULLAGINO. |
1435 | * is not already NULLAGINO. This saves us the overhead | 1354 | * This saves us the overhead of dealing with the buffer when |
1436 | * of dealing with the buffer when there is no need to | 1355 | * there is no need to change it. |
1437 | * change it. | ||
1438 | */ | 1356 | */ |
1439 | error = xfs_itobp(mp, tp, ip, &dip, &ibp, 0); | 1357 | error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &dip, &ibp, |
1358 | 0, 0); | ||
1440 | if (error) { | 1359 | if (error) { |
1441 | xfs_warn(mp, "%s: xfs_itobp() returned error %d.", | 1360 | xfs_warn(mp, "%s: xfs_imap_to_bp returned error %d.", |
1442 | __func__, error); | 1361 | __func__, error); |
1443 | return error; | 1362 | return error; |
1444 | } | 1363 | } |
@@ -1472,34 +1391,45 @@ xfs_iunlink_remove( | |||
1472 | next_agino = be32_to_cpu(agi->agi_unlinked[bucket_index]); | 1391 | next_agino = be32_to_cpu(agi->agi_unlinked[bucket_index]); |
1473 | last_ibp = NULL; | 1392 | last_ibp = NULL; |
1474 | while (next_agino != agino) { | 1393 | while (next_agino != agino) { |
1475 | /* | 1394 | struct xfs_imap imap; |
1476 | * If the last inode wasn't the one pointing to | 1395 | |
1477 | * us, then release its buffer since we're not | 1396 | if (last_ibp) |
1478 | * going to do anything with it. | ||
1479 | */ | ||
1480 | if (last_ibp != NULL) { | ||
1481 | xfs_trans_brelse(tp, last_ibp); | 1397 | xfs_trans_brelse(tp, last_ibp); |
1482 | } | 1398 | |
1399 | imap.im_blkno = 0; | ||
1483 | next_ino = XFS_AGINO_TO_INO(mp, agno, next_agino); | 1400 | next_ino = XFS_AGINO_TO_INO(mp, agno, next_agino); |
1484 | error = xfs_inotobp(mp, tp, next_ino, &last_dip, | 1401 | |
1485 | &last_ibp, &last_offset, 0); | 1402 | error = xfs_imap(mp, tp, next_ino, &imap, 0); |
1403 | if (error) { | ||
1404 | xfs_warn(mp, | ||
1405 | "%s: xfs_imap returned error %d.", | ||
1406 | __func__, error); | ||
1407 | return error; | ||
1408 | } | ||
1409 | |||
1410 | error = xfs_imap_to_bp(mp, tp, &imap, &last_dip, | ||
1411 | &last_ibp, 0, 0); | ||
1486 | if (error) { | 1412 | if (error) { |
1487 | xfs_warn(mp, | 1413 | xfs_warn(mp, |
1488 | "%s: xfs_inotobp() returned error %d.", | 1414 | "%s: xfs_imap_to_bp returned error %d.", |
1489 | __func__, error); | 1415 | __func__, error); |
1490 | return error; | 1416 | return error; |
1491 | } | 1417 | } |
1418 | |||
1419 | last_offset = imap.im_boffset; | ||
1492 | next_agino = be32_to_cpu(last_dip->di_next_unlinked); | 1420 | next_agino = be32_to_cpu(last_dip->di_next_unlinked); |
1493 | ASSERT(next_agino != NULLAGINO); | 1421 | ASSERT(next_agino != NULLAGINO); |
1494 | ASSERT(next_agino != 0); | 1422 | ASSERT(next_agino != 0); |
1495 | } | 1423 | } |
1424 | |||
1496 | /* | 1425 | /* |
1497 | * Now last_ibp points to the buffer previous to us on | 1426 | * Now last_ibp points to the buffer previous to us on the |
1498 | * the unlinked list. Pull us from the list. | 1427 | * unlinked list. Pull us from the list. |
1499 | */ | 1428 | */ |
1500 | error = xfs_itobp(mp, tp, ip, &dip, &ibp, 0); | 1429 | error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &dip, &ibp, |
1430 | 0, 0); | ||
1501 | if (error) { | 1431 | if (error) { |
1502 | xfs_warn(mp, "%s: xfs_itobp(2) returned error %d.", | 1432 | xfs_warn(mp, "%s: xfs_imap_to_bp(2) returned error %d.", |
1503 | __func__, error); | 1433 | __func__, error); |
1504 | return error; | 1434 | return error; |
1505 | } | 1435 | } |
@@ -1749,7 +1679,8 @@ xfs_ifree( | |||
1749 | 1679 | ||
1750 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 1680 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
1751 | 1681 | ||
1752 | error = xfs_itobp(ip->i_mount, tp, ip, &dip, &ibp, 0); | 1682 | error = xfs_imap_to_bp(ip->i_mount, tp, &ip->i_imap, &dip, &ibp, |
1683 | 0, 0); | ||
1753 | if (error) | 1684 | if (error) |
1754 | return error; | 1685 | return error; |
1755 | 1686 | ||
@@ -2428,7 +2359,7 @@ xfs_iflush( | |||
2428 | /* | 2359 | /* |
2429 | * For stale inodes we cannot rely on the backing buffer remaining | 2360 | * For stale inodes we cannot rely on the backing buffer remaining |
2430 | * stale in cache for the remaining life of the stale inode and so | 2361 | * stale in cache for the remaining life of the stale inode and so |
2431 | * xfs_itobp() below may give us a buffer that no longer contains | 2362 | * xfs_imap_to_bp() below may give us a buffer that no longer contains |
2432 | * inodes below. We have to check this after ensuring the inode is | 2363 | * inodes below. We have to check this after ensuring the inode is |
2433 | * unpinned so that it is safe to reclaim the stale inode after the | 2364 | * unpinned so that it is safe to reclaim the stale inode after the |
2434 | * flush call. | 2365 | * flush call. |
@@ -2454,7 +2385,8 @@ xfs_iflush( | |||
2454 | /* | 2385 | /* |
2455 | * Get the buffer containing the on-disk inode. | 2386 | * Get the buffer containing the on-disk inode. |
2456 | */ | 2387 | */ |
2457 | error = xfs_itobp(mp, NULL, ip, &dip, &bp, XBF_TRYLOCK); | 2388 | error = xfs_imap_to_bp(mp, NULL, &ip->i_imap, &dip, &bp, XBF_TRYLOCK, |
2389 | 0); | ||
2458 | if (error || !bp) { | 2390 | if (error || !bp) { |
2459 | xfs_ifunlock(ip); | 2391 | xfs_ifunlock(ip); |
2460 | return error; | 2392 | return error; |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 1efff36a75b6..94b32f906e79 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -487,8 +487,6 @@ static inline int xfs_isiflocked(struct xfs_inode *ip) | |||
487 | #define XFS_IOLOCK_DEP(flags) (((flags) & XFS_IOLOCK_DEP_MASK) >> XFS_IOLOCK_SHIFT) | 487 | #define XFS_IOLOCK_DEP(flags) (((flags) & XFS_IOLOCK_DEP_MASK) >> XFS_IOLOCK_SHIFT) |
488 | #define XFS_ILOCK_DEP(flags) (((flags) & XFS_ILOCK_DEP_MASK) >> XFS_ILOCK_SHIFT) | 488 | #define XFS_ILOCK_DEP(flags) (((flags) & XFS_ILOCK_DEP_MASK) >> XFS_ILOCK_SHIFT) |
489 | 489 | ||
490 | extern struct lock_class_key xfs_iolock_reclaimable; | ||
491 | |||
492 | /* | 490 | /* |
493 | * For multiple groups support: if S_ISGID bit is set in the parent | 491 | * For multiple groups support: if S_ISGID bit is set in the parent |
494 | * directory, group of new file is set to that of the parent, and | 492 | * directory, group of new file is set to that of the parent, and |
@@ -517,7 +515,7 @@ void xfs_inode_free(struct xfs_inode *ip); | |||
517 | */ | 515 | */ |
518 | int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, umode_t, | 516 | int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, umode_t, |
519 | xfs_nlink_t, xfs_dev_t, prid_t, int, | 517 | xfs_nlink_t, xfs_dev_t, prid_t, int, |
520 | struct xfs_buf **, boolean_t *, xfs_inode_t **); | 518 | struct xfs_buf **, xfs_inode_t **); |
521 | 519 | ||
522 | uint xfs_ip2xflags(struct xfs_inode *); | 520 | uint xfs_ip2xflags(struct xfs_inode *); |
523 | uint xfs_dic2xflags(struct xfs_dinode *); | 521 | uint xfs_dic2xflags(struct xfs_dinode *); |
@@ -557,12 +555,9 @@ do { \ | |||
557 | #define XFS_IGET_UNTRUSTED 0x2 | 555 | #define XFS_IGET_UNTRUSTED 0x2 |
558 | #define XFS_IGET_DONTCACHE 0x4 | 556 | #define XFS_IGET_DONTCACHE 0x4 |
559 | 557 | ||
560 | int xfs_inotobp(struct xfs_mount *, struct xfs_trans *, | 558 | int xfs_imap_to_bp(struct xfs_mount *, struct xfs_trans *, |
561 | xfs_ino_t, struct xfs_dinode **, | 559 | struct xfs_imap *, struct xfs_dinode **, |
562 | struct xfs_buf **, int *, uint); | 560 | struct xfs_buf **, uint, uint); |
563 | int xfs_itobp(struct xfs_mount *, struct xfs_trans *, | ||
564 | struct xfs_inode *, struct xfs_dinode **, | ||
565 | struct xfs_buf **, uint); | ||
566 | int xfs_iread(struct xfs_mount *, struct xfs_trans *, | 561 | int xfs_iread(struct xfs_mount *, struct xfs_trans *, |
567 | struct xfs_inode *, uint); | 562 | struct xfs_inode *, uint); |
568 | void xfs_dinode_to_disk(struct xfs_dinode *, | 563 | void xfs_dinode_to_disk(struct xfs_dinode *, |
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index aadfce6681ee..915edf6639f0 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
@@ -285,7 +285,7 @@ xfs_iomap_eof_want_preallocate( | |||
285 | * do any speculative allocation. | 285 | * do any speculative allocation. |
286 | */ | 286 | */ |
287 | start_fsb = XFS_B_TO_FSBT(mp, ((xfs_ufsize_t)(offset + count - 1))); | 287 | start_fsb = XFS_B_TO_FSBT(mp, ((xfs_ufsize_t)(offset + count - 1))); |
288 | count_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp)); | 288 | count_fsb = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes); |
289 | while (count_fsb > 0) { | 289 | while (count_fsb > 0) { |
290 | imaps = nimaps; | 290 | imaps = nimaps; |
291 | firstblock = NULLFSBLOCK; | 291 | firstblock = NULLFSBLOCK; |
@@ -416,8 +416,8 @@ retry: | |||
416 | * Make sure preallocation does not create extents beyond the range we | 416 | * Make sure preallocation does not create extents beyond the range we |
417 | * actually support in this filesystem. | 417 | * actually support in this filesystem. |
418 | */ | 418 | */ |
419 | if (last_fsb > XFS_B_TO_FSB(mp, mp->m_maxioffset)) | 419 | if (last_fsb > XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes)) |
420 | last_fsb = XFS_B_TO_FSB(mp, mp->m_maxioffset); | 420 | last_fsb = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes); |
421 | 421 | ||
422 | ASSERT(last_fsb > offset_fsb); | 422 | ASSERT(last_fsb > offset_fsb); |
423 | 423 | ||
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 9c4340f5c3e0..4e00cf091d2c 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c | |||
@@ -897,6 +897,47 @@ xfs_vn_setattr( | |||
897 | return -xfs_setattr_nonsize(XFS_I(dentry->d_inode), iattr, 0); | 897 | return -xfs_setattr_nonsize(XFS_I(dentry->d_inode), iattr, 0); |
898 | } | 898 | } |
899 | 899 | ||
900 | STATIC int | ||
901 | xfs_vn_update_time( | ||
902 | struct inode *inode, | ||
903 | struct timespec *now, | ||
904 | int flags) | ||
905 | { | ||
906 | struct xfs_inode *ip = XFS_I(inode); | ||
907 | struct xfs_mount *mp = ip->i_mount; | ||
908 | struct xfs_trans *tp; | ||
909 | int error; | ||
910 | |||
911 | trace_xfs_update_time(ip); | ||
912 | |||
913 | tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS); | ||
914 | error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0); | ||
915 | if (error) { | ||
916 | xfs_trans_cancel(tp, 0); | ||
917 | return -error; | ||
918 | } | ||
919 | |||
920 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
921 | if (flags & S_CTIME) { | ||
922 | inode->i_ctime = *now; | ||
923 | ip->i_d.di_ctime.t_sec = (__int32_t)now->tv_sec; | ||
924 | ip->i_d.di_ctime.t_nsec = (__int32_t)now->tv_nsec; | ||
925 | } | ||
926 | if (flags & S_MTIME) { | ||
927 | inode->i_mtime = *now; | ||
928 | ip->i_d.di_mtime.t_sec = (__int32_t)now->tv_sec; | ||
929 | ip->i_d.di_mtime.t_nsec = (__int32_t)now->tv_nsec; | ||
930 | } | ||
931 | if (flags & S_ATIME) { | ||
932 | inode->i_atime = *now; | ||
933 | ip->i_d.di_atime.t_sec = (__int32_t)now->tv_sec; | ||
934 | ip->i_d.di_atime.t_nsec = (__int32_t)now->tv_nsec; | ||
935 | } | ||
936 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | ||
937 | xfs_trans_log_inode(tp, ip, XFS_ILOG_TIMESTAMP); | ||
938 | return -xfs_trans_commit(tp, 0); | ||
939 | } | ||
940 | |||
900 | #define XFS_FIEMAP_FLAGS (FIEMAP_FLAG_SYNC|FIEMAP_FLAG_XATTR) | 941 | #define XFS_FIEMAP_FLAGS (FIEMAP_FLAG_SYNC|FIEMAP_FLAG_XATTR) |
901 | 942 | ||
902 | /* | 943 | /* |
@@ -991,6 +1032,7 @@ static const struct inode_operations xfs_inode_operations = { | |||
991 | .removexattr = generic_removexattr, | 1032 | .removexattr = generic_removexattr, |
992 | .listxattr = xfs_vn_listxattr, | 1033 | .listxattr = xfs_vn_listxattr, |
993 | .fiemap = xfs_vn_fiemap, | 1034 | .fiemap = xfs_vn_fiemap, |
1035 | .update_time = xfs_vn_update_time, | ||
994 | }; | 1036 | }; |
995 | 1037 | ||
996 | static const struct inode_operations xfs_dir_inode_operations = { | 1038 | static const struct inode_operations xfs_dir_inode_operations = { |
@@ -1016,6 +1058,7 @@ static const struct inode_operations xfs_dir_inode_operations = { | |||
1016 | .getxattr = generic_getxattr, | 1058 | .getxattr = generic_getxattr, |
1017 | .removexattr = generic_removexattr, | 1059 | .removexattr = generic_removexattr, |
1018 | .listxattr = xfs_vn_listxattr, | 1060 | .listxattr = xfs_vn_listxattr, |
1061 | .update_time = xfs_vn_update_time, | ||
1019 | }; | 1062 | }; |
1020 | 1063 | ||
1021 | static const struct inode_operations xfs_dir_ci_inode_operations = { | 1064 | static const struct inode_operations xfs_dir_ci_inode_operations = { |
@@ -1041,6 +1084,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = { | |||
1041 | .getxattr = generic_getxattr, | 1084 | .getxattr = generic_getxattr, |
1042 | .removexattr = generic_removexattr, | 1085 | .removexattr = generic_removexattr, |
1043 | .listxattr = xfs_vn_listxattr, | 1086 | .listxattr = xfs_vn_listxattr, |
1087 | .update_time = xfs_vn_update_time, | ||
1044 | }; | 1088 | }; |
1045 | 1089 | ||
1046 | static const struct inode_operations xfs_symlink_inode_operations = { | 1090 | static const struct inode_operations xfs_symlink_inode_operations = { |
@@ -1054,6 +1098,7 @@ static const struct inode_operations xfs_symlink_inode_operations = { | |||
1054 | .getxattr = generic_getxattr, | 1098 | .getxattr = generic_getxattr, |
1055 | .removexattr = generic_removexattr, | 1099 | .removexattr = generic_removexattr, |
1056 | .listxattr = xfs_vn_listxattr, | 1100 | .listxattr = xfs_vn_listxattr, |
1101 | .update_time = xfs_vn_update_time, | ||
1057 | }; | 1102 | }; |
1058 | 1103 | ||
1059 | STATIC void | 1104 | STATIC void |
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index eff577a9b67f..01d10a66e302 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c | |||
@@ -555,7 +555,7 @@ xfs_bulkstat_single( | |||
555 | 555 | ||
556 | /* | 556 | /* |
557 | * note that requesting valid inode numbers which are not allocated | 557 | * note that requesting valid inode numbers which are not allocated |
558 | * to inodes will most likely cause xfs_itobp to generate warning | 558 | * to inodes will most likely cause xfs_imap_to_bp to generate warning |
559 | * messages about bad magic numbers. This is ok. The fact that | 559 | * messages about bad magic numbers. This is ok. The fact that |
560 | * the inode isn't actually an inode is handled by the | 560 | * the inode isn't actually an inode is handled by the |
561 | * error check below. Done this way to make the usual case faster | 561 | * error check below. Done this way to make the usual case faster |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index d90d4a388609..7f4f9370d0e7 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -45,51 +45,85 @@ xlog_commit_record( | |||
45 | struct xlog_in_core **iclog, | 45 | struct xlog_in_core **iclog, |
46 | xfs_lsn_t *commitlsnp); | 46 | xfs_lsn_t *commitlsnp); |
47 | 47 | ||
48 | STATIC xlog_t * xlog_alloc_log(xfs_mount_t *mp, | 48 | STATIC struct xlog * |
49 | xfs_buftarg_t *log_target, | 49 | xlog_alloc_log( |
50 | xfs_daddr_t blk_offset, | 50 | struct xfs_mount *mp, |
51 | int num_bblks); | 51 | struct xfs_buftarg *log_target, |
52 | xfs_daddr_t blk_offset, | ||
53 | int num_bblks); | ||
52 | STATIC int | 54 | STATIC int |
53 | xlog_space_left( | 55 | xlog_space_left( |
54 | struct xlog *log, | 56 | struct xlog *log, |
55 | atomic64_t *head); | 57 | atomic64_t *head); |
56 | STATIC int xlog_sync(xlog_t *log, xlog_in_core_t *iclog); | 58 | STATIC int |
57 | STATIC void xlog_dealloc_log(xlog_t *log); | 59 | xlog_sync( |
60 | struct xlog *log, | ||
61 | struct xlog_in_core *iclog); | ||
62 | STATIC void | ||
63 | xlog_dealloc_log( | ||
64 | struct xlog *log); | ||
58 | 65 | ||
59 | /* local state machine functions */ | 66 | /* local state machine functions */ |
60 | STATIC void xlog_state_done_syncing(xlog_in_core_t *iclog, int); | 67 | STATIC void xlog_state_done_syncing(xlog_in_core_t *iclog, int); |
61 | STATIC void xlog_state_do_callback(xlog_t *log,int aborted, xlog_in_core_t *iclog); | 68 | STATIC void |
62 | STATIC int xlog_state_get_iclog_space(xlog_t *log, | 69 | xlog_state_do_callback( |
63 | int len, | 70 | struct xlog *log, |
64 | xlog_in_core_t **iclog, | 71 | int aborted, |
65 | xlog_ticket_t *ticket, | 72 | struct xlog_in_core *iclog); |
66 | int *continued_write, | 73 | STATIC int |
67 | int *logoffsetp); | 74 | xlog_state_get_iclog_space( |
68 | STATIC int xlog_state_release_iclog(xlog_t *log, | 75 | struct xlog *log, |
69 | xlog_in_core_t *iclog); | 76 | int len, |
70 | STATIC void xlog_state_switch_iclogs(xlog_t *log, | 77 | struct xlog_in_core **iclog, |
71 | xlog_in_core_t *iclog, | 78 | struct xlog_ticket *ticket, |
72 | int eventual_size); | 79 | int *continued_write, |
73 | STATIC void xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog); | 80 | int *logoffsetp); |
81 | STATIC int | ||
82 | xlog_state_release_iclog( | ||
83 | struct xlog *log, | ||
84 | struct xlog_in_core *iclog); | ||
85 | STATIC void | ||
86 | xlog_state_switch_iclogs( | ||
87 | struct xlog *log, | ||
88 | struct xlog_in_core *iclog, | ||
89 | int eventual_size); | ||
90 | STATIC void | ||
91 | xlog_state_want_sync( | ||
92 | struct xlog *log, | ||
93 | struct xlog_in_core *iclog); | ||
74 | 94 | ||
75 | STATIC void | 95 | STATIC void |
76 | xlog_grant_push_ail( | 96 | xlog_grant_push_ail( |
77 | struct xlog *log, | 97 | struct xlog *log, |
78 | int need_bytes); | 98 | int need_bytes); |
79 | STATIC void xlog_regrant_reserve_log_space(xlog_t *log, | 99 | STATIC void |
80 | xlog_ticket_t *ticket); | 100 | xlog_regrant_reserve_log_space( |
81 | STATIC void xlog_ungrant_log_space(xlog_t *log, | 101 | struct xlog *log, |
82 | xlog_ticket_t *ticket); | 102 | struct xlog_ticket *ticket); |
103 | STATIC void | ||
104 | xlog_ungrant_log_space( | ||
105 | struct xlog *log, | ||
106 | struct xlog_ticket *ticket); | ||
83 | 107 | ||
84 | #if defined(DEBUG) | 108 | #if defined(DEBUG) |
85 | STATIC void xlog_verify_dest_ptr(xlog_t *log, char *ptr); | 109 | STATIC void |
110 | xlog_verify_dest_ptr( | ||
111 | struct xlog *log, | ||
112 | char *ptr); | ||
86 | STATIC void | 113 | STATIC void |
87 | xlog_verify_grant_tail( | 114 | xlog_verify_grant_tail( |
88 | struct xlog *log); | 115 | struct xlog *log); |
89 | STATIC void xlog_verify_iclog(xlog_t *log, xlog_in_core_t *iclog, | 116 | STATIC void |
90 | int count, boolean_t syncing); | 117 | xlog_verify_iclog( |
91 | STATIC void xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog, | 118 | struct xlog *log, |
92 | xfs_lsn_t tail_lsn); | 119 | struct xlog_in_core *iclog, |
120 | int count, | ||
121 | boolean_t syncing); | ||
122 | STATIC void | ||
123 | xlog_verify_tail_lsn( | ||
124 | struct xlog *log, | ||
125 | struct xlog_in_core *iclog, | ||
126 | xfs_lsn_t tail_lsn); | ||
93 | #else | 127 | #else |
94 | #define xlog_verify_dest_ptr(a,b) | 128 | #define xlog_verify_dest_ptr(a,b) |
95 | #define xlog_verify_grant_tail(a) | 129 | #define xlog_verify_grant_tail(a) |
@@ -97,7 +131,9 @@ STATIC void xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog, | |||
97 | #define xlog_verify_tail_lsn(a,b,c) | 131 | #define xlog_verify_tail_lsn(a,b,c) |
98 | #endif | 132 | #endif |
99 | 133 | ||
100 | STATIC int xlog_iclogs_empty(xlog_t *log); | 134 | STATIC int |
135 | xlog_iclogs_empty( | ||
136 | struct xlog *log); | ||
101 | 137 | ||
102 | static void | 138 | static void |
103 | xlog_grant_sub_space( | 139 | xlog_grant_sub_space( |
@@ -684,7 +720,7 @@ xfs_log_mount_finish(xfs_mount_t *mp) | |||
684 | int | 720 | int |
685 | xfs_log_unmount_write(xfs_mount_t *mp) | 721 | xfs_log_unmount_write(xfs_mount_t *mp) |
686 | { | 722 | { |
687 | xlog_t *log = mp->m_log; | 723 | struct xlog *log = mp->m_log; |
688 | xlog_in_core_t *iclog; | 724 | xlog_in_core_t *iclog; |
689 | #ifdef DEBUG | 725 | #ifdef DEBUG |
690 | xlog_in_core_t *first_iclog; | 726 | xlog_in_core_t *first_iclog; |
@@ -893,7 +929,7 @@ int | |||
893 | xfs_log_need_covered(xfs_mount_t *mp) | 929 | xfs_log_need_covered(xfs_mount_t *mp) |
894 | { | 930 | { |
895 | int needed = 0; | 931 | int needed = 0; |
896 | xlog_t *log = mp->m_log; | 932 | struct xlog *log = mp->m_log; |
897 | 933 | ||
898 | if (!xfs_fs_writable(mp)) | 934 | if (!xfs_fs_writable(mp)) |
899 | return 0; | 935 | return 0; |
@@ -1024,9 +1060,9 @@ xlog_space_left( | |||
1024 | void | 1060 | void |
1025 | xlog_iodone(xfs_buf_t *bp) | 1061 | xlog_iodone(xfs_buf_t *bp) |
1026 | { | 1062 | { |
1027 | xlog_in_core_t *iclog = bp->b_fspriv; | 1063 | struct xlog_in_core *iclog = bp->b_fspriv; |
1028 | xlog_t *l = iclog->ic_log; | 1064 | struct xlog *l = iclog->ic_log; |
1029 | int aborted = 0; | 1065 | int aborted = 0; |
1030 | 1066 | ||
1031 | /* | 1067 | /* |
1032 | * Race to shutdown the filesystem if we see an error. | 1068 | * Race to shutdown the filesystem if we see an error. |
@@ -1067,8 +1103,9 @@ xlog_iodone(xfs_buf_t *bp) | |||
1067 | */ | 1103 | */ |
1068 | 1104 | ||
1069 | STATIC void | 1105 | STATIC void |
1070 | xlog_get_iclog_buffer_size(xfs_mount_t *mp, | 1106 | xlog_get_iclog_buffer_size( |
1071 | xlog_t *log) | 1107 | struct xfs_mount *mp, |
1108 | struct xlog *log) | ||
1072 | { | 1109 | { |
1073 | int size; | 1110 | int size; |
1074 | int xhdrs; | 1111 | int xhdrs; |
@@ -1129,13 +1166,14 @@ done: | |||
1129 | * Its primary purpose is to fill in enough, so recovery can occur. However, | 1166 | * Its primary purpose is to fill in enough, so recovery can occur. However, |
1130 | * some other stuff may be filled in too. | 1167 | * some other stuff may be filled in too. |
1131 | */ | 1168 | */ |
1132 | STATIC xlog_t * | 1169 | STATIC struct xlog * |
1133 | xlog_alloc_log(xfs_mount_t *mp, | 1170 | xlog_alloc_log( |
1134 | xfs_buftarg_t *log_target, | 1171 | struct xfs_mount *mp, |
1135 | xfs_daddr_t blk_offset, | 1172 | struct xfs_buftarg *log_target, |
1136 | int num_bblks) | 1173 | xfs_daddr_t blk_offset, |
1174 | int num_bblks) | ||
1137 | { | 1175 | { |
1138 | xlog_t *log; | 1176 | struct xlog *log; |
1139 | xlog_rec_header_t *head; | 1177 | xlog_rec_header_t *head; |
1140 | xlog_in_core_t **iclogp; | 1178 | xlog_in_core_t **iclogp; |
1141 | xlog_in_core_t *iclog, *prev_iclog=NULL; | 1179 | xlog_in_core_t *iclog, *prev_iclog=NULL; |
@@ -1144,7 +1182,7 @@ xlog_alloc_log(xfs_mount_t *mp, | |||
1144 | int error = ENOMEM; | 1182 | int error = ENOMEM; |
1145 | uint log2_size = 0; | 1183 | uint log2_size = 0; |
1146 | 1184 | ||
1147 | log = kmem_zalloc(sizeof(xlog_t), KM_MAYFAIL); | 1185 | log = kmem_zalloc(sizeof(struct xlog), KM_MAYFAIL); |
1148 | if (!log) { | 1186 | if (!log) { |
1149 | xfs_warn(mp, "Log allocation failed: No memory!"); | 1187 | xfs_warn(mp, "Log allocation failed: No memory!"); |
1150 | goto out; | 1188 | goto out; |
@@ -1434,8 +1472,9 @@ xlog_bdstrat( | |||
1434 | */ | 1472 | */ |
1435 | 1473 | ||
1436 | STATIC int | 1474 | STATIC int |
1437 | xlog_sync(xlog_t *log, | 1475 | xlog_sync( |
1438 | xlog_in_core_t *iclog) | 1476 | struct xlog *log, |
1477 | struct xlog_in_core *iclog) | ||
1439 | { | 1478 | { |
1440 | xfs_caddr_t dptr; /* pointer to byte sized element */ | 1479 | xfs_caddr_t dptr; /* pointer to byte sized element */ |
1441 | xfs_buf_t *bp; | 1480 | xfs_buf_t *bp; |
@@ -1584,7 +1623,8 @@ xlog_sync(xlog_t *log, | |||
1584 | * Deallocate a log structure | 1623 | * Deallocate a log structure |
1585 | */ | 1624 | */ |
1586 | STATIC void | 1625 | STATIC void |
1587 | xlog_dealloc_log(xlog_t *log) | 1626 | xlog_dealloc_log( |
1627 | struct xlog *log) | ||
1588 | { | 1628 | { |
1589 | xlog_in_core_t *iclog, *next_iclog; | 1629 | xlog_in_core_t *iclog, *next_iclog; |
1590 | int i; | 1630 | int i; |
@@ -1616,10 +1656,11 @@ xlog_dealloc_log(xlog_t *log) | |||
1616 | */ | 1656 | */ |
1617 | /* ARGSUSED */ | 1657 | /* ARGSUSED */ |
1618 | static inline void | 1658 | static inline void |
1619 | xlog_state_finish_copy(xlog_t *log, | 1659 | xlog_state_finish_copy( |
1620 | xlog_in_core_t *iclog, | 1660 | struct xlog *log, |
1621 | int record_cnt, | 1661 | struct xlog_in_core *iclog, |
1622 | int copy_bytes) | 1662 | int record_cnt, |
1663 | int copy_bytes) | ||
1623 | { | 1664 | { |
1624 | spin_lock(&log->l_icloglock); | 1665 | spin_lock(&log->l_icloglock); |
1625 | 1666 | ||
@@ -2142,7 +2183,8 @@ xlog_write( | |||
2142 | * State Change: DIRTY -> ACTIVE | 2183 | * State Change: DIRTY -> ACTIVE |
2143 | */ | 2184 | */ |
2144 | STATIC void | 2185 | STATIC void |
2145 | xlog_state_clean_log(xlog_t *log) | 2186 | xlog_state_clean_log( |
2187 | struct xlog *log) | ||
2146 | { | 2188 | { |
2147 | xlog_in_core_t *iclog; | 2189 | xlog_in_core_t *iclog; |
2148 | int changed = 0; | 2190 | int changed = 0; |
@@ -2222,7 +2264,7 @@ xlog_state_clean_log(xlog_t *log) | |||
2222 | 2264 | ||
2223 | STATIC xfs_lsn_t | 2265 | STATIC xfs_lsn_t |
2224 | xlog_get_lowest_lsn( | 2266 | xlog_get_lowest_lsn( |
2225 | xlog_t *log) | 2267 | struct xlog *log) |
2226 | { | 2268 | { |
2227 | xlog_in_core_t *lsn_log; | 2269 | xlog_in_core_t *lsn_log; |
2228 | xfs_lsn_t lowest_lsn, lsn; | 2270 | xfs_lsn_t lowest_lsn, lsn; |
@@ -2245,9 +2287,9 @@ xlog_get_lowest_lsn( | |||
2245 | 2287 | ||
2246 | STATIC void | 2288 | STATIC void |
2247 | xlog_state_do_callback( | 2289 | xlog_state_do_callback( |
2248 | xlog_t *log, | 2290 | struct xlog *log, |
2249 | int aborted, | 2291 | int aborted, |
2250 | xlog_in_core_t *ciclog) | 2292 | struct xlog_in_core *ciclog) |
2251 | { | 2293 | { |
2252 | xlog_in_core_t *iclog; | 2294 | xlog_in_core_t *iclog; |
2253 | xlog_in_core_t *first_iclog; /* used to know when we've | 2295 | xlog_in_core_t *first_iclog; /* used to know when we've |
@@ -2467,7 +2509,7 @@ xlog_state_done_syncing( | |||
2467 | xlog_in_core_t *iclog, | 2509 | xlog_in_core_t *iclog, |
2468 | int aborted) | 2510 | int aborted) |
2469 | { | 2511 | { |
2470 | xlog_t *log = iclog->ic_log; | 2512 | struct xlog *log = iclog->ic_log; |
2471 | 2513 | ||
2472 | spin_lock(&log->l_icloglock); | 2514 | spin_lock(&log->l_icloglock); |
2473 | 2515 | ||
@@ -2521,12 +2563,13 @@ xlog_state_done_syncing( | |||
2521 | * is copied. | 2563 | * is copied. |
2522 | */ | 2564 | */ |
2523 | STATIC int | 2565 | STATIC int |
2524 | xlog_state_get_iclog_space(xlog_t *log, | 2566 | xlog_state_get_iclog_space( |
2525 | int len, | 2567 | struct xlog *log, |
2526 | xlog_in_core_t **iclogp, | 2568 | int len, |
2527 | xlog_ticket_t *ticket, | 2569 | struct xlog_in_core **iclogp, |
2528 | int *continued_write, | 2570 | struct xlog_ticket *ticket, |
2529 | int *logoffsetp) | 2571 | int *continued_write, |
2572 | int *logoffsetp) | ||
2530 | { | 2573 | { |
2531 | int log_offset; | 2574 | int log_offset; |
2532 | xlog_rec_header_t *head; | 2575 | xlog_rec_header_t *head; |
@@ -2631,8 +2674,9 @@ restart: | |||
2631 | * move grant reservation head forward. | 2674 | * move grant reservation head forward. |
2632 | */ | 2675 | */ |
2633 | STATIC void | 2676 | STATIC void |
2634 | xlog_regrant_reserve_log_space(xlog_t *log, | 2677 | xlog_regrant_reserve_log_space( |
2635 | xlog_ticket_t *ticket) | 2678 | struct xlog *log, |
2679 | struct xlog_ticket *ticket) | ||
2636 | { | 2680 | { |
2637 | trace_xfs_log_regrant_reserve_enter(log, ticket); | 2681 | trace_xfs_log_regrant_reserve_enter(log, ticket); |
2638 | 2682 | ||
@@ -2677,8 +2721,9 @@ xlog_regrant_reserve_log_space(xlog_t *log, | |||
2677 | * in the current reservation field. | 2721 | * in the current reservation field. |
2678 | */ | 2722 | */ |
2679 | STATIC void | 2723 | STATIC void |
2680 | xlog_ungrant_log_space(xlog_t *log, | 2724 | xlog_ungrant_log_space( |
2681 | xlog_ticket_t *ticket) | 2725 | struct xlog *log, |
2726 | struct xlog_ticket *ticket) | ||
2682 | { | 2727 | { |
2683 | int bytes; | 2728 | int bytes; |
2684 | 2729 | ||
@@ -2717,8 +2762,8 @@ xlog_ungrant_log_space(xlog_t *log, | |||
2717 | */ | 2762 | */ |
2718 | STATIC int | 2763 | STATIC int |
2719 | xlog_state_release_iclog( | 2764 | xlog_state_release_iclog( |
2720 | xlog_t *log, | 2765 | struct xlog *log, |
2721 | xlog_in_core_t *iclog) | 2766 | struct xlog_in_core *iclog) |
2722 | { | 2767 | { |
2723 | int sync = 0; /* do we sync? */ | 2768 | int sync = 0; /* do we sync? */ |
2724 | 2769 | ||
@@ -2768,9 +2813,10 @@ xlog_state_release_iclog( | |||
2768 | * that every data block. We have run out of space in this log record. | 2813 | * that every data block. We have run out of space in this log record. |
2769 | */ | 2814 | */ |
2770 | STATIC void | 2815 | STATIC void |
2771 | xlog_state_switch_iclogs(xlog_t *log, | 2816 | xlog_state_switch_iclogs( |
2772 | xlog_in_core_t *iclog, | 2817 | struct xlog *log, |
2773 | int eventual_size) | 2818 | struct xlog_in_core *iclog, |
2819 | int eventual_size) | ||
2774 | { | 2820 | { |
2775 | ASSERT(iclog->ic_state == XLOG_STATE_ACTIVE); | 2821 | ASSERT(iclog->ic_state == XLOG_STATE_ACTIVE); |
2776 | if (!eventual_size) | 2822 | if (!eventual_size) |
@@ -3114,7 +3160,9 @@ xfs_log_force_lsn( | |||
3114 | * disk. | 3160 | * disk. |
3115 | */ | 3161 | */ |
3116 | STATIC void | 3162 | STATIC void |
3117 | xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog) | 3163 | xlog_state_want_sync( |
3164 | struct xlog *log, | ||
3165 | struct xlog_in_core *iclog) | ||
3118 | { | 3166 | { |
3119 | assert_spin_locked(&log->l_icloglock); | 3167 | assert_spin_locked(&log->l_icloglock); |
3120 | 3168 | ||
@@ -3158,7 +3206,7 @@ xfs_log_ticket_get( | |||
3158 | /* | 3206 | /* |
3159 | * Allocate and initialise a new log ticket. | 3207 | * Allocate and initialise a new log ticket. |
3160 | */ | 3208 | */ |
3161 | xlog_ticket_t * | 3209 | struct xlog_ticket * |
3162 | xlog_ticket_alloc( | 3210 | xlog_ticket_alloc( |
3163 | struct xlog *log, | 3211 | struct xlog *log, |
3164 | int unit_bytes, | 3212 | int unit_bytes, |
@@ -3346,9 +3394,10 @@ xlog_verify_grant_tail( | |||
3346 | 3394 | ||
3347 | /* check if it will fit */ | 3395 | /* check if it will fit */ |
3348 | STATIC void | 3396 | STATIC void |
3349 | xlog_verify_tail_lsn(xlog_t *log, | 3397 | xlog_verify_tail_lsn( |
3350 | xlog_in_core_t *iclog, | 3398 | struct xlog *log, |
3351 | xfs_lsn_t tail_lsn) | 3399 | struct xlog_in_core *iclog, |
3400 | xfs_lsn_t tail_lsn) | ||
3352 | { | 3401 | { |
3353 | int blocks; | 3402 | int blocks; |
3354 | 3403 | ||
@@ -3385,10 +3434,11 @@ xlog_verify_tail_lsn(xlog_t *log, | |||
3385 | * the cycle numbers agree with the current cycle number. | 3434 | * the cycle numbers agree with the current cycle number. |
3386 | */ | 3435 | */ |
3387 | STATIC void | 3436 | STATIC void |
3388 | xlog_verify_iclog(xlog_t *log, | 3437 | xlog_verify_iclog( |
3389 | xlog_in_core_t *iclog, | 3438 | struct xlog *log, |
3390 | int count, | 3439 | struct xlog_in_core *iclog, |
3391 | boolean_t syncing) | 3440 | int count, |
3441 | boolean_t syncing) | ||
3392 | { | 3442 | { |
3393 | xlog_op_header_t *ophead; | 3443 | xlog_op_header_t *ophead; |
3394 | xlog_in_core_t *icptr; | 3444 | xlog_in_core_t *icptr; |
@@ -3482,7 +3532,7 @@ xlog_verify_iclog(xlog_t *log, | |||
3482 | */ | 3532 | */ |
3483 | STATIC int | 3533 | STATIC int |
3484 | xlog_state_ioerror( | 3534 | xlog_state_ioerror( |
3485 | xlog_t *log) | 3535 | struct xlog *log) |
3486 | { | 3536 | { |
3487 | xlog_in_core_t *iclog, *ic; | 3537 | xlog_in_core_t *iclog, *ic; |
3488 | 3538 | ||
@@ -3527,7 +3577,7 @@ xfs_log_force_umount( | |||
3527 | struct xfs_mount *mp, | 3577 | struct xfs_mount *mp, |
3528 | int logerror) | 3578 | int logerror) |
3529 | { | 3579 | { |
3530 | xlog_t *log; | 3580 | struct xlog *log; |
3531 | int retval; | 3581 | int retval; |
3532 | 3582 | ||
3533 | log = mp->m_log; | 3583 | log = mp->m_log; |
@@ -3634,7 +3684,8 @@ xfs_log_force_umount( | |||
3634 | } | 3684 | } |
3635 | 3685 | ||
3636 | STATIC int | 3686 | STATIC int |
3637 | xlog_iclogs_empty(xlog_t *log) | 3687 | xlog_iclogs_empty( |
3688 | struct xlog *log) | ||
3638 | { | 3689 | { |
3639 | xlog_in_core_t *iclog; | 3690 | xlog_in_core_t *iclog; |
3640 | 3691 | ||
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index 72eba2201b14..18a801d76a42 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h | |||
@@ -487,7 +487,7 @@ struct xlog_grant_head { | |||
487 | * overflow 31 bits worth of byte offset, so using a byte number will mean | 487 | * overflow 31 bits worth of byte offset, so using a byte number will mean |
488 | * that round off problems won't occur when releasing partial reservations. | 488 | * that round off problems won't occur when releasing partial reservations. |
489 | */ | 489 | */ |
490 | typedef struct xlog { | 490 | struct xlog { |
491 | /* The following fields don't need locking */ | 491 | /* The following fields don't need locking */ |
492 | struct xfs_mount *l_mp; /* mount point */ | 492 | struct xfs_mount *l_mp; /* mount point */ |
493 | struct xfs_ail *l_ailp; /* AIL log is working with */ | 493 | struct xfs_ail *l_ailp; /* AIL log is working with */ |
@@ -540,7 +540,7 @@ typedef struct xlog { | |||
540 | char *l_iclog_bak[XLOG_MAX_ICLOGS]; | 540 | char *l_iclog_bak[XLOG_MAX_ICLOGS]; |
541 | #endif | 541 | #endif |
542 | 542 | ||
543 | } xlog_t; | 543 | }; |
544 | 544 | ||
545 | #define XLOG_BUF_CANCEL_BUCKET(log, blkno) \ | 545 | #define XLOG_BUF_CANCEL_BUCKET(log, blkno) \ |
546 | ((log)->l_buf_cancel_table + ((__uint64_t)blkno % XLOG_BC_TABLE_SIZE)) | 546 | ((log)->l_buf_cancel_table + ((__uint64_t)blkno % XLOG_BC_TABLE_SIZE)) |
@@ -548,9 +548,17 @@ typedef struct xlog { | |||
548 | #define XLOG_FORCED_SHUTDOWN(log) ((log)->l_flags & XLOG_IO_ERROR) | 548 | #define XLOG_FORCED_SHUTDOWN(log) ((log)->l_flags & XLOG_IO_ERROR) |
549 | 549 | ||
550 | /* common routines */ | 550 | /* common routines */ |
551 | extern int xlog_recover(xlog_t *log); | 551 | extern int |
552 | extern int xlog_recover_finish(xlog_t *log); | 552 | xlog_recover( |
553 | extern void xlog_pack_data(xlog_t *log, xlog_in_core_t *iclog, int); | 553 | struct xlog *log); |
554 | extern int | ||
555 | xlog_recover_finish( | ||
556 | struct xlog *log); | ||
557 | extern void | ||
558 | xlog_pack_data( | ||
559 | struct xlog *log, | ||
560 | struct xlog_in_core *iclog, | ||
561 | int); | ||
554 | 562 | ||
555 | extern kmem_zone_t *xfs_log_ticket_zone; | 563 | extern kmem_zone_t *xfs_log_ticket_zone; |
556 | struct xlog_ticket * | 564 | struct xlog_ticket * |
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index a7be98abd6a9..5da3ace352bf 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -43,10 +43,18 @@ | |||
43 | #include "xfs_utils.h" | 43 | #include "xfs_utils.h" |
44 | #include "xfs_trace.h" | 44 | #include "xfs_trace.h" |
45 | 45 | ||
46 | STATIC int xlog_find_zeroed(xlog_t *, xfs_daddr_t *); | 46 | STATIC int |
47 | STATIC int xlog_clear_stale_blocks(xlog_t *, xfs_lsn_t); | 47 | xlog_find_zeroed( |
48 | struct xlog *, | ||
49 | xfs_daddr_t *); | ||
50 | STATIC int | ||
51 | xlog_clear_stale_blocks( | ||
52 | struct xlog *, | ||
53 | xfs_lsn_t); | ||
48 | #if defined(DEBUG) | 54 | #if defined(DEBUG) |
49 | STATIC void xlog_recover_check_summary(xlog_t *); | 55 | STATIC void |
56 | xlog_recover_check_summary( | ||
57 | struct xlog *); | ||
50 | #else | 58 | #else |
51 | #define xlog_recover_check_summary(log) | 59 | #define xlog_recover_check_summary(log) |
52 | #endif | 60 | #endif |
@@ -74,7 +82,7 @@ struct xfs_buf_cancel { | |||
74 | 82 | ||
75 | static inline int | 83 | static inline int |
76 | xlog_buf_bbcount_valid( | 84 | xlog_buf_bbcount_valid( |
77 | xlog_t *log, | 85 | struct xlog *log, |
78 | int bbcount) | 86 | int bbcount) |
79 | { | 87 | { |
80 | return bbcount > 0 && bbcount <= log->l_logBBsize; | 88 | return bbcount > 0 && bbcount <= log->l_logBBsize; |
@@ -87,7 +95,7 @@ xlog_buf_bbcount_valid( | |||
87 | */ | 95 | */ |
88 | STATIC xfs_buf_t * | 96 | STATIC xfs_buf_t * |
89 | xlog_get_bp( | 97 | xlog_get_bp( |
90 | xlog_t *log, | 98 | struct xlog *log, |
91 | int nbblks) | 99 | int nbblks) |
92 | { | 100 | { |
93 | struct xfs_buf *bp; | 101 | struct xfs_buf *bp; |
@@ -138,10 +146,10 @@ xlog_put_bp( | |||
138 | */ | 146 | */ |
139 | STATIC xfs_caddr_t | 147 | STATIC xfs_caddr_t |
140 | xlog_align( | 148 | xlog_align( |
141 | xlog_t *log, | 149 | struct xlog *log, |
142 | xfs_daddr_t blk_no, | 150 | xfs_daddr_t blk_no, |
143 | int nbblks, | 151 | int nbblks, |
144 | xfs_buf_t *bp) | 152 | struct xfs_buf *bp) |
145 | { | 153 | { |
146 | xfs_daddr_t offset = blk_no & ((xfs_daddr_t)log->l_sectBBsize - 1); | 154 | xfs_daddr_t offset = blk_no & ((xfs_daddr_t)log->l_sectBBsize - 1); |
147 | 155 | ||
@@ -155,10 +163,10 @@ xlog_align( | |||
155 | */ | 163 | */ |
156 | STATIC int | 164 | STATIC int |
157 | xlog_bread_noalign( | 165 | xlog_bread_noalign( |
158 | xlog_t *log, | 166 | struct xlog *log, |
159 | xfs_daddr_t blk_no, | 167 | xfs_daddr_t blk_no, |
160 | int nbblks, | 168 | int nbblks, |
161 | xfs_buf_t *bp) | 169 | struct xfs_buf *bp) |
162 | { | 170 | { |
163 | int error; | 171 | int error; |
164 | 172 | ||
@@ -189,10 +197,10 @@ xlog_bread_noalign( | |||
189 | 197 | ||
190 | STATIC int | 198 | STATIC int |
191 | xlog_bread( | 199 | xlog_bread( |
192 | xlog_t *log, | 200 | struct xlog *log, |
193 | xfs_daddr_t blk_no, | 201 | xfs_daddr_t blk_no, |
194 | int nbblks, | 202 | int nbblks, |
195 | xfs_buf_t *bp, | 203 | struct xfs_buf *bp, |
196 | xfs_caddr_t *offset) | 204 | xfs_caddr_t *offset) |
197 | { | 205 | { |
198 | int error; | 206 | int error; |
@@ -211,10 +219,10 @@ xlog_bread( | |||
211 | */ | 219 | */ |
212 | STATIC int | 220 | STATIC int |
213 | xlog_bread_offset( | 221 | xlog_bread_offset( |
214 | xlog_t *log, | 222 | struct xlog *log, |
215 | xfs_daddr_t blk_no, /* block to read from */ | 223 | xfs_daddr_t blk_no, /* block to read from */ |
216 | int nbblks, /* blocks to read */ | 224 | int nbblks, /* blocks to read */ |
217 | xfs_buf_t *bp, | 225 | struct xfs_buf *bp, |
218 | xfs_caddr_t offset) | 226 | xfs_caddr_t offset) |
219 | { | 227 | { |
220 | xfs_caddr_t orig_offset = bp->b_addr; | 228 | xfs_caddr_t orig_offset = bp->b_addr; |
@@ -241,10 +249,10 @@ xlog_bread_offset( | |||
241 | */ | 249 | */ |
242 | STATIC int | 250 | STATIC int |
243 | xlog_bwrite( | 251 | xlog_bwrite( |
244 | xlog_t *log, | 252 | struct xlog *log, |
245 | xfs_daddr_t blk_no, | 253 | xfs_daddr_t blk_no, |
246 | int nbblks, | 254 | int nbblks, |
247 | xfs_buf_t *bp) | 255 | struct xfs_buf *bp) |
248 | { | 256 | { |
249 | int error; | 257 | int error; |
250 | 258 | ||
@@ -378,8 +386,8 @@ xlog_recover_iodone( | |||
378 | */ | 386 | */ |
379 | STATIC int | 387 | STATIC int |
380 | xlog_find_cycle_start( | 388 | xlog_find_cycle_start( |
381 | xlog_t *log, | 389 | struct xlog *log, |
382 | xfs_buf_t *bp, | 390 | struct xfs_buf *bp, |
383 | xfs_daddr_t first_blk, | 391 | xfs_daddr_t first_blk, |
384 | xfs_daddr_t *last_blk, | 392 | xfs_daddr_t *last_blk, |
385 | uint cycle) | 393 | uint cycle) |
@@ -421,7 +429,7 @@ xlog_find_cycle_start( | |||
421 | */ | 429 | */ |
422 | STATIC int | 430 | STATIC int |
423 | xlog_find_verify_cycle( | 431 | xlog_find_verify_cycle( |
424 | xlog_t *log, | 432 | struct xlog *log, |
425 | xfs_daddr_t start_blk, | 433 | xfs_daddr_t start_blk, |
426 | int nbblks, | 434 | int nbblks, |
427 | uint stop_on_cycle_no, | 435 | uint stop_on_cycle_no, |
@@ -490,7 +498,7 @@ out: | |||
490 | */ | 498 | */ |
491 | STATIC int | 499 | STATIC int |
492 | xlog_find_verify_log_record( | 500 | xlog_find_verify_log_record( |
493 | xlog_t *log, | 501 | struct xlog *log, |
494 | xfs_daddr_t start_blk, | 502 | xfs_daddr_t start_blk, |
495 | xfs_daddr_t *last_blk, | 503 | xfs_daddr_t *last_blk, |
496 | int extra_bblks) | 504 | int extra_bblks) |
@@ -600,7 +608,7 @@ out: | |||
600 | */ | 608 | */ |
601 | STATIC int | 609 | STATIC int |
602 | xlog_find_head( | 610 | xlog_find_head( |
603 | xlog_t *log, | 611 | struct xlog *log, |
604 | xfs_daddr_t *return_head_blk) | 612 | xfs_daddr_t *return_head_blk) |
605 | { | 613 | { |
606 | xfs_buf_t *bp; | 614 | xfs_buf_t *bp; |
@@ -871,7 +879,7 @@ validate_head: | |||
871 | */ | 879 | */ |
872 | STATIC int | 880 | STATIC int |
873 | xlog_find_tail( | 881 | xlog_find_tail( |
874 | xlog_t *log, | 882 | struct xlog *log, |
875 | xfs_daddr_t *head_blk, | 883 | xfs_daddr_t *head_blk, |
876 | xfs_daddr_t *tail_blk) | 884 | xfs_daddr_t *tail_blk) |
877 | { | 885 | { |
@@ -1080,7 +1088,7 @@ done: | |||
1080 | */ | 1088 | */ |
1081 | STATIC int | 1089 | STATIC int |
1082 | xlog_find_zeroed( | 1090 | xlog_find_zeroed( |
1083 | xlog_t *log, | 1091 | struct xlog *log, |
1084 | xfs_daddr_t *blk_no) | 1092 | xfs_daddr_t *blk_no) |
1085 | { | 1093 | { |
1086 | xfs_buf_t *bp; | 1094 | xfs_buf_t *bp; |
@@ -1183,7 +1191,7 @@ bp_err: | |||
1183 | */ | 1191 | */ |
1184 | STATIC void | 1192 | STATIC void |
1185 | xlog_add_record( | 1193 | xlog_add_record( |
1186 | xlog_t *log, | 1194 | struct xlog *log, |
1187 | xfs_caddr_t buf, | 1195 | xfs_caddr_t buf, |
1188 | int cycle, | 1196 | int cycle, |
1189 | int block, | 1197 | int block, |
@@ -1205,7 +1213,7 @@ xlog_add_record( | |||
1205 | 1213 | ||
1206 | STATIC int | 1214 | STATIC int |
1207 | xlog_write_log_records( | 1215 | xlog_write_log_records( |
1208 | xlog_t *log, | 1216 | struct xlog *log, |
1209 | int cycle, | 1217 | int cycle, |
1210 | int start_block, | 1218 | int start_block, |
1211 | int blocks, | 1219 | int blocks, |
@@ -1305,7 +1313,7 @@ xlog_write_log_records( | |||
1305 | */ | 1313 | */ |
1306 | STATIC int | 1314 | STATIC int |
1307 | xlog_clear_stale_blocks( | 1315 | xlog_clear_stale_blocks( |
1308 | xlog_t *log, | 1316 | struct xlog *log, |
1309 | xfs_lsn_t tail_lsn) | 1317 | xfs_lsn_t tail_lsn) |
1310 | { | 1318 | { |
1311 | int tail_cycle, head_cycle; | 1319 | int tail_cycle, head_cycle; |
@@ -2050,11 +2058,11 @@ xfs_qm_dqcheck( | |||
2050 | */ | 2058 | */ |
2051 | STATIC void | 2059 | STATIC void |
2052 | xlog_recover_do_dquot_buffer( | 2060 | xlog_recover_do_dquot_buffer( |
2053 | xfs_mount_t *mp, | 2061 | struct xfs_mount *mp, |
2054 | xlog_t *log, | 2062 | struct xlog *log, |
2055 | xlog_recover_item_t *item, | 2063 | struct xlog_recover_item *item, |
2056 | xfs_buf_t *bp, | 2064 | struct xfs_buf *bp, |
2057 | xfs_buf_log_format_t *buf_f) | 2065 | struct xfs_buf_log_format *buf_f) |
2058 | { | 2066 | { |
2059 | uint type; | 2067 | uint type; |
2060 | 2068 | ||
@@ -2108,9 +2116,9 @@ xlog_recover_do_dquot_buffer( | |||
2108 | */ | 2116 | */ |
2109 | STATIC int | 2117 | STATIC int |
2110 | xlog_recover_buffer_pass2( | 2118 | xlog_recover_buffer_pass2( |
2111 | xlog_t *log, | 2119 | struct xlog *log, |
2112 | struct list_head *buffer_list, | 2120 | struct list_head *buffer_list, |
2113 | xlog_recover_item_t *item) | 2121 | struct xlog_recover_item *item) |
2114 | { | 2122 | { |
2115 | xfs_buf_log_format_t *buf_f = item->ri_buf[0].i_addr; | 2123 | xfs_buf_log_format_t *buf_f = item->ri_buf[0].i_addr; |
2116 | xfs_mount_t *mp = log->l_mp; | 2124 | xfs_mount_t *mp = log->l_mp; |
@@ -2189,9 +2197,9 @@ xlog_recover_buffer_pass2( | |||
2189 | 2197 | ||
2190 | STATIC int | 2198 | STATIC int |
2191 | xlog_recover_inode_pass2( | 2199 | xlog_recover_inode_pass2( |
2192 | xlog_t *log, | 2200 | struct xlog *log, |
2193 | struct list_head *buffer_list, | 2201 | struct list_head *buffer_list, |
2194 | xlog_recover_item_t *item) | 2202 | struct xlog_recover_item *item) |
2195 | { | 2203 | { |
2196 | xfs_inode_log_format_t *in_f; | 2204 | xfs_inode_log_format_t *in_f; |
2197 | xfs_mount_t *mp = log->l_mp; | 2205 | xfs_mount_t *mp = log->l_mp; |
@@ -2452,14 +2460,14 @@ error: | |||
2452 | } | 2460 | } |
2453 | 2461 | ||
2454 | /* | 2462 | /* |
2455 | * Recover QUOTAOFF records. We simply make a note of it in the xlog_t | 2463 | * Recover QUOTAOFF records. We simply make a note of it in the xlog |
2456 | * structure, so that we know not to do any dquot item or dquot buffer recovery, | 2464 | * structure, so that we know not to do any dquot item or dquot buffer recovery, |
2457 | * of that type. | 2465 | * of that type. |
2458 | */ | 2466 | */ |
2459 | STATIC int | 2467 | STATIC int |
2460 | xlog_recover_quotaoff_pass1( | 2468 | xlog_recover_quotaoff_pass1( |
2461 | xlog_t *log, | 2469 | struct xlog *log, |
2462 | xlog_recover_item_t *item) | 2470 | struct xlog_recover_item *item) |
2463 | { | 2471 | { |
2464 | xfs_qoff_logformat_t *qoff_f = item->ri_buf[0].i_addr; | 2472 | xfs_qoff_logformat_t *qoff_f = item->ri_buf[0].i_addr; |
2465 | ASSERT(qoff_f); | 2473 | ASSERT(qoff_f); |
@@ -2483,9 +2491,9 @@ xlog_recover_quotaoff_pass1( | |||
2483 | */ | 2491 | */ |
2484 | STATIC int | 2492 | STATIC int |
2485 | xlog_recover_dquot_pass2( | 2493 | xlog_recover_dquot_pass2( |
2486 | xlog_t *log, | 2494 | struct xlog *log, |
2487 | struct list_head *buffer_list, | 2495 | struct list_head *buffer_list, |
2488 | xlog_recover_item_t *item) | 2496 | struct xlog_recover_item *item) |
2489 | { | 2497 | { |
2490 | xfs_mount_t *mp = log->l_mp; | 2498 | xfs_mount_t *mp = log->l_mp; |
2491 | xfs_buf_t *bp; | 2499 | xfs_buf_t *bp; |
@@ -2578,9 +2586,9 @@ xlog_recover_dquot_pass2( | |||
2578 | */ | 2586 | */ |
2579 | STATIC int | 2587 | STATIC int |
2580 | xlog_recover_efi_pass2( | 2588 | xlog_recover_efi_pass2( |
2581 | xlog_t *log, | 2589 | struct xlog *log, |
2582 | xlog_recover_item_t *item, | 2590 | struct xlog_recover_item *item, |
2583 | xfs_lsn_t lsn) | 2591 | xfs_lsn_t lsn) |
2584 | { | 2592 | { |
2585 | int error; | 2593 | int error; |
2586 | xfs_mount_t *mp = log->l_mp; | 2594 | xfs_mount_t *mp = log->l_mp; |
@@ -2616,8 +2624,8 @@ xlog_recover_efi_pass2( | |||
2616 | */ | 2624 | */ |
2617 | STATIC int | 2625 | STATIC int |
2618 | xlog_recover_efd_pass2( | 2626 | xlog_recover_efd_pass2( |
2619 | xlog_t *log, | 2627 | struct xlog *log, |
2620 | xlog_recover_item_t *item) | 2628 | struct xlog_recover_item *item) |
2621 | { | 2629 | { |
2622 | xfs_efd_log_format_t *efd_formatp; | 2630 | xfs_efd_log_format_t *efd_formatp; |
2623 | xfs_efi_log_item_t *efip = NULL; | 2631 | xfs_efi_log_item_t *efip = NULL; |
@@ -2812,9 +2820,9 @@ xlog_recover_unmount_trans( | |||
2812 | */ | 2820 | */ |
2813 | STATIC int | 2821 | STATIC int |
2814 | xlog_recover_process_data( | 2822 | xlog_recover_process_data( |
2815 | xlog_t *log, | 2823 | struct xlog *log, |
2816 | struct hlist_head rhash[], | 2824 | struct hlist_head rhash[], |
2817 | xlog_rec_header_t *rhead, | 2825 | struct xlog_rec_header *rhead, |
2818 | xfs_caddr_t dp, | 2826 | xfs_caddr_t dp, |
2819 | int pass) | 2827 | int pass) |
2820 | { | 2828 | { |
@@ -2986,7 +2994,7 @@ abort_error: | |||
2986 | */ | 2994 | */ |
2987 | STATIC int | 2995 | STATIC int |
2988 | xlog_recover_process_efis( | 2996 | xlog_recover_process_efis( |
2989 | xlog_t *log) | 2997 | struct xlog *log) |
2990 | { | 2998 | { |
2991 | xfs_log_item_t *lip; | 2999 | xfs_log_item_t *lip; |
2992 | xfs_efi_log_item_t *efip; | 3000 | xfs_efi_log_item_t *efip; |
@@ -3098,7 +3106,7 @@ xlog_recover_process_one_iunlink( | |||
3098 | /* | 3106 | /* |
3099 | * Get the on disk inode to find the next inode in the bucket. | 3107 | * Get the on disk inode to find the next inode in the bucket. |
3100 | */ | 3108 | */ |
3101 | error = xfs_itobp(mp, NULL, ip, &dip, &ibp, 0); | 3109 | error = xfs_imap_to_bp(mp, NULL, &ip->i_imap, &dip, &ibp, 0, 0); |
3102 | if (error) | 3110 | if (error) |
3103 | goto fail_iput; | 3111 | goto fail_iput; |
3104 | 3112 | ||
@@ -3147,7 +3155,7 @@ xlog_recover_process_one_iunlink( | |||
3147 | */ | 3155 | */ |
3148 | STATIC void | 3156 | STATIC void |
3149 | xlog_recover_process_iunlinks( | 3157 | xlog_recover_process_iunlinks( |
3150 | xlog_t *log) | 3158 | struct xlog *log) |
3151 | { | 3159 | { |
3152 | xfs_mount_t *mp; | 3160 | xfs_mount_t *mp; |
3153 | xfs_agnumber_t agno; | 3161 | xfs_agnumber_t agno; |
@@ -3209,9 +3217,9 @@ xlog_recover_process_iunlinks( | |||
3209 | #ifdef DEBUG | 3217 | #ifdef DEBUG |
3210 | STATIC void | 3218 | STATIC void |
3211 | xlog_pack_data_checksum( | 3219 | xlog_pack_data_checksum( |
3212 | xlog_t *log, | 3220 | struct xlog *log, |
3213 | xlog_in_core_t *iclog, | 3221 | struct xlog_in_core *iclog, |
3214 | int size) | 3222 | int size) |
3215 | { | 3223 | { |
3216 | int i; | 3224 | int i; |
3217 | __be32 *up; | 3225 | __be32 *up; |
@@ -3234,8 +3242,8 @@ xlog_pack_data_checksum( | |||
3234 | */ | 3242 | */ |
3235 | void | 3243 | void |
3236 | xlog_pack_data( | 3244 | xlog_pack_data( |
3237 | xlog_t *log, | 3245 | struct xlog *log, |
3238 | xlog_in_core_t *iclog, | 3246 | struct xlog_in_core *iclog, |
3239 | int roundoff) | 3247 | int roundoff) |
3240 | { | 3248 | { |
3241 | int i, j, k; | 3249 | int i, j, k; |
@@ -3274,9 +3282,9 @@ xlog_pack_data( | |||
3274 | 3282 | ||
3275 | STATIC void | 3283 | STATIC void |
3276 | xlog_unpack_data( | 3284 | xlog_unpack_data( |
3277 | xlog_rec_header_t *rhead, | 3285 | struct xlog_rec_header *rhead, |
3278 | xfs_caddr_t dp, | 3286 | xfs_caddr_t dp, |
3279 | xlog_t *log) | 3287 | struct xlog *log) |
3280 | { | 3288 | { |
3281 | int i, j, k; | 3289 | int i, j, k; |
3282 | 3290 | ||
@@ -3299,8 +3307,8 @@ xlog_unpack_data( | |||
3299 | 3307 | ||
3300 | STATIC int | 3308 | STATIC int |
3301 | xlog_valid_rec_header( | 3309 | xlog_valid_rec_header( |
3302 | xlog_t *log, | 3310 | struct xlog *log, |
3303 | xlog_rec_header_t *rhead, | 3311 | struct xlog_rec_header *rhead, |
3304 | xfs_daddr_t blkno) | 3312 | xfs_daddr_t blkno) |
3305 | { | 3313 | { |
3306 | int hlen; | 3314 | int hlen; |
@@ -3343,7 +3351,7 @@ xlog_valid_rec_header( | |||
3343 | */ | 3351 | */ |
3344 | STATIC int | 3352 | STATIC int |
3345 | xlog_do_recovery_pass( | 3353 | xlog_do_recovery_pass( |
3346 | xlog_t *log, | 3354 | struct xlog *log, |
3347 | xfs_daddr_t head_blk, | 3355 | xfs_daddr_t head_blk, |
3348 | xfs_daddr_t tail_blk, | 3356 | xfs_daddr_t tail_blk, |
3349 | int pass) | 3357 | int pass) |
@@ -3595,7 +3603,7 @@ xlog_do_recovery_pass( | |||
3595 | */ | 3603 | */ |
3596 | STATIC int | 3604 | STATIC int |
3597 | xlog_do_log_recovery( | 3605 | xlog_do_log_recovery( |
3598 | xlog_t *log, | 3606 | struct xlog *log, |
3599 | xfs_daddr_t head_blk, | 3607 | xfs_daddr_t head_blk, |
3600 | xfs_daddr_t tail_blk) | 3608 | xfs_daddr_t tail_blk) |
3601 | { | 3609 | { |
@@ -3646,7 +3654,7 @@ xlog_do_log_recovery( | |||
3646 | */ | 3654 | */ |
3647 | STATIC int | 3655 | STATIC int |
3648 | xlog_do_recover( | 3656 | xlog_do_recover( |
3649 | xlog_t *log, | 3657 | struct xlog *log, |
3650 | xfs_daddr_t head_blk, | 3658 | xfs_daddr_t head_blk, |
3651 | xfs_daddr_t tail_blk) | 3659 | xfs_daddr_t tail_blk) |
3652 | { | 3660 | { |
@@ -3721,7 +3729,7 @@ xlog_do_recover( | |||
3721 | */ | 3729 | */ |
3722 | int | 3730 | int |
3723 | xlog_recover( | 3731 | xlog_recover( |
3724 | xlog_t *log) | 3732 | struct xlog *log) |
3725 | { | 3733 | { |
3726 | xfs_daddr_t head_blk, tail_blk; | 3734 | xfs_daddr_t head_blk, tail_blk; |
3727 | int error; | 3735 | int error; |
@@ -3767,7 +3775,7 @@ xlog_recover( | |||
3767 | */ | 3775 | */ |
3768 | int | 3776 | int |
3769 | xlog_recover_finish( | 3777 | xlog_recover_finish( |
3770 | xlog_t *log) | 3778 | struct xlog *log) |
3771 | { | 3779 | { |
3772 | /* | 3780 | /* |
3773 | * Now we're ready to do the transactions needed for the | 3781 | * Now we're ready to do the transactions needed for the |
@@ -3814,7 +3822,7 @@ xlog_recover_finish( | |||
3814 | */ | 3822 | */ |
3815 | void | 3823 | void |
3816 | xlog_recover_check_summary( | 3824 | xlog_recover_check_summary( |
3817 | xlog_t *log) | 3825 | struct xlog *log) |
3818 | { | 3826 | { |
3819 | xfs_mount_t *mp; | 3827 | xfs_mount_t *mp; |
3820 | xfs_agf_t *agfp; | 3828 | xfs_agf_t *agfp; |
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 536021fb3d4e..711ca51ca3d7 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -1200,8 +1200,6 @@ xfs_mountfs( | |||
1200 | 1200 | ||
1201 | xfs_set_maxicount(mp); | 1201 | xfs_set_maxicount(mp); |
1202 | 1202 | ||
1203 | mp->m_maxioffset = xfs_max_file_offset(sbp->sb_blocklog); | ||
1204 | |||
1205 | error = xfs_uuid_mount(mp); | 1203 | error = xfs_uuid_mount(mp); |
1206 | if (error) | 1204 | if (error) |
1207 | goto out; | 1205 | goto out; |
@@ -1531,6 +1529,15 @@ xfs_unmountfs( | |||
1531 | xfs_ail_push_all_sync(mp->m_ail); | 1529 | xfs_ail_push_all_sync(mp->m_ail); |
1532 | xfs_wait_buftarg(mp->m_ddev_targp); | 1530 | xfs_wait_buftarg(mp->m_ddev_targp); |
1533 | 1531 | ||
1532 | /* | ||
1533 | * The superblock buffer is uncached and xfsaild_push() will lock and | ||
1534 | * set the XBF_ASYNC flag on the buffer. We cannot do xfs_buf_iowait() | ||
1535 | * here but a lock on the superblock buffer will block until iodone() | ||
1536 | * has completed. | ||
1537 | */ | ||
1538 | xfs_buf_lock(mp->m_sb_bp); | ||
1539 | xfs_buf_unlock(mp->m_sb_bp); | ||
1540 | |||
1534 | xfs_log_unmount_write(mp); | 1541 | xfs_log_unmount_write(mp); |
1535 | xfs_log_unmount(mp); | 1542 | xfs_log_unmount(mp); |
1536 | xfs_uuid_unmount(mp); | 1543 | xfs_uuid_unmount(mp); |
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 90c1fc9eaea4..8724336a9a08 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h | |||
@@ -176,7 +176,6 @@ typedef struct xfs_mount { | |||
176 | uint m_qflags; /* quota status flags */ | 176 | uint m_qflags; /* quota status flags */ |
177 | xfs_trans_reservations_t m_reservations;/* precomputed res values */ | 177 | xfs_trans_reservations_t m_reservations;/* precomputed res values */ |
178 | __uint64_t m_maxicount; /* maximum inode count */ | 178 | __uint64_t m_maxicount; /* maximum inode count */ |
179 | __uint64_t m_maxioffset; /* maximum inode offset */ | ||
180 | __uint64_t m_resblks; /* total reserved blocks */ | 179 | __uint64_t m_resblks; /* total reserved blocks */ |
181 | __uint64_t m_resblks_avail;/* available reserved blocks */ | 180 | __uint64_t m_resblks_avail;/* available reserved blocks */ |
182 | __uint64_t m_resblks_save; /* reserved blks @ remount,ro */ | 181 | __uint64_t m_resblks_save; /* reserved blks @ remount,ro */ |
@@ -297,8 +296,6 @@ xfs_preferred_iosize(xfs_mount_t *mp) | |||
297 | PAGE_CACHE_SIZE)); | 296 | PAGE_CACHE_SIZE)); |
298 | } | 297 | } |
299 | 298 | ||
300 | #define XFS_MAXIOFFSET(mp) ((mp)->m_maxioffset) | ||
301 | |||
302 | #define XFS_LAST_UNMOUNT_WAS_CLEAN(mp) \ | 299 | #define XFS_LAST_UNMOUNT_WAS_CLEAN(mp) \ |
303 | ((mp)->m_flags & XFS_MOUNT_WAS_CLEAN) | 300 | ((mp)->m_flags & XFS_MOUNT_WAS_CLEAN) |
304 | #define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN) | 301 | #define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN) |
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 249db1987764..2e86fa0cfc0d 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c | |||
@@ -940,7 +940,7 @@ xfs_qm_dqiterate( | |||
940 | map = kmem_alloc(XFS_DQITER_MAP_SIZE * sizeof(*map), KM_SLEEP); | 940 | map = kmem_alloc(XFS_DQITER_MAP_SIZE * sizeof(*map), KM_SLEEP); |
941 | 941 | ||
942 | lblkno = 0; | 942 | lblkno = 0; |
943 | maxlblkcnt = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp)); | 943 | maxlblkcnt = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes); |
944 | do { | 944 | do { |
945 | nmaps = XFS_DQITER_MAP_SIZE; | 945 | nmaps = XFS_DQITER_MAP_SIZE; |
946 | /* | 946 | /* |
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 0d9de41a7151..bdaf4cb9f4a2 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
@@ -868,67 +868,14 @@ xfs_fs_inode_init_once( | |||
868 | "xfsino", ip->i_ino); | 868 | "xfsino", ip->i_ino); |
869 | } | 869 | } |
870 | 870 | ||
871 | /* | ||
872 | * This is called by the VFS when dirtying inode metadata. This can happen | ||
873 | * for a few reasons, but we only care about timestamp updates, given that | ||
874 | * we handled the rest ourselves. In theory no other calls should happen, | ||
875 | * but for example generic_write_end() keeps dirtying the inode after | ||
876 | * updating i_size. Thus we check that the flags are exactly I_DIRTY_SYNC, | ||
877 | * and skip this call otherwise. | ||
878 | * | ||
879 | * We'll hopefull get a different method just for updating timestamps soon, | ||
880 | * at which point this hack can go away, and maybe we'll also get real | ||
881 | * error handling here. | ||
882 | */ | ||
883 | STATIC void | ||
884 | xfs_fs_dirty_inode( | ||
885 | struct inode *inode, | ||
886 | int flags) | ||
887 | { | ||
888 | struct xfs_inode *ip = XFS_I(inode); | ||
889 | struct xfs_mount *mp = ip->i_mount; | ||
890 | struct xfs_trans *tp; | ||
891 | int error; | ||
892 | |||
893 | if (flags != I_DIRTY_SYNC) | ||
894 | return; | ||
895 | |||
896 | trace_xfs_dirty_inode(ip); | ||
897 | |||
898 | tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS); | ||
899 | error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0); | ||
900 | if (error) { | ||
901 | xfs_trans_cancel(tp, 0); | ||
902 | goto trouble; | ||
903 | } | ||
904 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
905 | /* | ||
906 | * Grab all the latest timestamps from the Linux inode. | ||
907 | */ | ||
908 | ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec; | ||
909 | ip->i_d.di_atime.t_nsec = (__int32_t)inode->i_atime.tv_nsec; | ||
910 | ip->i_d.di_ctime.t_sec = (__int32_t)inode->i_ctime.tv_sec; | ||
911 | ip->i_d.di_ctime.t_nsec = (__int32_t)inode->i_ctime.tv_nsec; | ||
912 | ip->i_d.di_mtime.t_sec = (__int32_t)inode->i_mtime.tv_sec; | ||
913 | ip->i_d.di_mtime.t_nsec = (__int32_t)inode->i_mtime.tv_nsec; | ||
914 | |||
915 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | ||
916 | xfs_trans_log_inode(tp, ip, XFS_ILOG_TIMESTAMP); | ||
917 | error = xfs_trans_commit(tp, 0); | ||
918 | if (error) | ||
919 | goto trouble; | ||
920 | return; | ||
921 | |||
922 | trouble: | ||
923 | xfs_warn(mp, "failed to update timestamps for inode 0x%llx", ip->i_ino); | ||
924 | } | ||
925 | |||
926 | STATIC void | 871 | STATIC void |
927 | xfs_fs_evict_inode( | 872 | xfs_fs_evict_inode( |
928 | struct inode *inode) | 873 | struct inode *inode) |
929 | { | 874 | { |
930 | xfs_inode_t *ip = XFS_I(inode); | 875 | xfs_inode_t *ip = XFS_I(inode); |
931 | 876 | ||
877 | ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock)); | ||
878 | |||
932 | trace_xfs_evict_inode(ip); | 879 | trace_xfs_evict_inode(ip); |
933 | 880 | ||
934 | truncate_inode_pages(&inode->i_data, 0); | 881 | truncate_inode_pages(&inode->i_data, 0); |
@@ -937,22 +884,6 @@ xfs_fs_evict_inode( | |||
937 | XFS_STATS_INC(vn_remove); | 884 | XFS_STATS_INC(vn_remove); |
938 | XFS_STATS_DEC(vn_active); | 885 | XFS_STATS_DEC(vn_active); |
939 | 886 | ||
940 | /* | ||
941 | * The iolock is used by the file system to coordinate reads, | ||
942 | * writes, and block truncates. Up to this point the lock | ||
943 | * protected concurrent accesses by users of the inode. But | ||
944 | * from here forward we're doing some final processing of the | ||
945 | * inode because we're done with it, and although we reuse the | ||
946 | * iolock for protection it is really a distinct lock class | ||
947 | * (in the lockdep sense) from before. To keep lockdep happy | ||
948 | * (and basically indicate what we are doing), we explicitly | ||
949 | * re-init the iolock here. | ||
950 | */ | ||
951 | ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock)); | ||
952 | mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); | ||
953 | lockdep_set_class_and_name(&ip->i_iolock.mr_lock, | ||
954 | &xfs_iolock_reclaimable, "xfs_iolock_reclaimable"); | ||
955 | |||
956 | xfs_inactive(ip); | 887 | xfs_inactive(ip); |
957 | } | 888 | } |
958 | 889 | ||
@@ -1436,7 +1367,6 @@ xfs_fs_free_cached_objects( | |||
1436 | static const struct super_operations xfs_super_operations = { | 1367 | static const struct super_operations xfs_super_operations = { |
1437 | .alloc_inode = xfs_fs_alloc_inode, | 1368 | .alloc_inode = xfs_fs_alloc_inode, |
1438 | .destroy_inode = xfs_fs_destroy_inode, | 1369 | .destroy_inode = xfs_fs_destroy_inode, |
1439 | .dirty_inode = xfs_fs_dirty_inode, | ||
1440 | .evict_inode = xfs_fs_evict_inode, | 1370 | .evict_inode = xfs_fs_evict_inode, |
1441 | .drop_inode = xfs_fs_drop_inode, | 1371 | .drop_inode = xfs_fs_drop_inode, |
1442 | .put_super = xfs_fs_put_super, | 1372 | .put_super = xfs_fs_put_super, |
@@ -1491,13 +1421,9 @@ xfs_init_zones(void) | |||
1491 | if (!xfs_da_state_zone) | 1421 | if (!xfs_da_state_zone) |
1492 | goto out_destroy_btree_cur_zone; | 1422 | goto out_destroy_btree_cur_zone; |
1493 | 1423 | ||
1494 | xfs_dabuf_zone = kmem_zone_init(sizeof(xfs_dabuf_t), "xfs_dabuf"); | ||
1495 | if (!xfs_dabuf_zone) | ||
1496 | goto out_destroy_da_state_zone; | ||
1497 | |||
1498 | xfs_ifork_zone = kmem_zone_init(sizeof(xfs_ifork_t), "xfs_ifork"); | 1424 | xfs_ifork_zone = kmem_zone_init(sizeof(xfs_ifork_t), "xfs_ifork"); |
1499 | if (!xfs_ifork_zone) | 1425 | if (!xfs_ifork_zone) |
1500 | goto out_destroy_dabuf_zone; | 1426 | goto out_destroy_da_state_zone; |
1501 | 1427 | ||
1502 | xfs_trans_zone = kmem_zone_init(sizeof(xfs_trans_t), "xfs_trans"); | 1428 | xfs_trans_zone = kmem_zone_init(sizeof(xfs_trans_t), "xfs_trans"); |
1503 | if (!xfs_trans_zone) | 1429 | if (!xfs_trans_zone) |
@@ -1514,9 +1440,8 @@ xfs_init_zones(void) | |||
1514 | * size possible under XFS. This wastes a little bit of memory, | 1440 | * size possible under XFS. This wastes a little bit of memory, |
1515 | * but it is much faster. | 1441 | * but it is much faster. |
1516 | */ | 1442 | */ |
1517 | xfs_buf_item_zone = kmem_zone_init((sizeof(xfs_buf_log_item_t) + | 1443 | xfs_buf_item_zone = kmem_zone_init(sizeof(struct xfs_buf_log_item), |
1518 | (((XFS_MAX_BLOCKSIZE / XFS_BLF_CHUNK) / | 1444 | "xfs_buf_item"); |
1519 | NBWORD) * sizeof(int))), "xfs_buf_item"); | ||
1520 | if (!xfs_buf_item_zone) | 1445 | if (!xfs_buf_item_zone) |
1521 | goto out_destroy_log_item_desc_zone; | 1446 | goto out_destroy_log_item_desc_zone; |
1522 | 1447 | ||
@@ -1561,8 +1486,6 @@ xfs_init_zones(void) | |||
1561 | kmem_zone_destroy(xfs_trans_zone); | 1486 | kmem_zone_destroy(xfs_trans_zone); |
1562 | out_destroy_ifork_zone: | 1487 | out_destroy_ifork_zone: |
1563 | kmem_zone_destroy(xfs_ifork_zone); | 1488 | kmem_zone_destroy(xfs_ifork_zone); |
1564 | out_destroy_dabuf_zone: | ||
1565 | kmem_zone_destroy(xfs_dabuf_zone); | ||
1566 | out_destroy_da_state_zone: | 1489 | out_destroy_da_state_zone: |
1567 | kmem_zone_destroy(xfs_da_state_zone); | 1490 | kmem_zone_destroy(xfs_da_state_zone); |
1568 | out_destroy_btree_cur_zone: | 1491 | out_destroy_btree_cur_zone: |
@@ -1590,7 +1513,6 @@ xfs_destroy_zones(void) | |||
1590 | kmem_zone_destroy(xfs_log_item_desc_zone); | 1513 | kmem_zone_destroy(xfs_log_item_desc_zone); |
1591 | kmem_zone_destroy(xfs_trans_zone); | 1514 | kmem_zone_destroy(xfs_trans_zone); |
1592 | kmem_zone_destroy(xfs_ifork_zone); | 1515 | kmem_zone_destroy(xfs_ifork_zone); |
1593 | kmem_zone_destroy(xfs_dabuf_zone); | ||
1594 | kmem_zone_destroy(xfs_da_state_zone); | 1516 | kmem_zone_destroy(xfs_da_state_zone); |
1595 | kmem_zone_destroy(xfs_btree_cur_zone); | 1517 | kmem_zone_destroy(xfs_btree_cur_zone); |
1596 | kmem_zone_destroy(xfs_bmap_free_item_zone); | 1518 | kmem_zone_destroy(xfs_bmap_free_item_zone); |
diff --git a/fs/xfs/xfs_sync.c b/fs/xfs/xfs_sync.c index 1e9ee064dbb2..97304f10e78a 100644 --- a/fs/xfs/xfs_sync.c +++ b/fs/xfs/xfs_sync.c | |||
@@ -359,6 +359,15 @@ xfs_quiesce_attr( | |||
359 | * added an item to the AIL, thus flush it again. | 359 | * added an item to the AIL, thus flush it again. |
360 | */ | 360 | */ |
361 | xfs_ail_push_all_sync(mp->m_ail); | 361 | xfs_ail_push_all_sync(mp->m_ail); |
362 | |||
363 | /* | ||
364 | * The superblock buffer is uncached and xfsaild_push() will lock and | ||
365 | * set the XBF_ASYNC flag on the buffer. We cannot do xfs_buf_iowait() | ||
366 | * here but a lock on the superblock buffer will block until iodone() | ||
367 | * has completed. | ||
368 | */ | ||
369 | xfs_buf_lock(mp->m_sb_bp); | ||
370 | xfs_buf_unlock(mp->m_sb_bp); | ||
362 | } | 371 | } |
363 | 372 | ||
364 | static void | 373 | static void |
@@ -712,8 +721,8 @@ restart: | |||
712 | * Note that xfs_iflush will never block on the inode buffer lock, as | 721 | * Note that xfs_iflush will never block on the inode buffer lock, as |
713 | * xfs_ifree_cluster() can lock the inode buffer before it locks the | 722 | * xfs_ifree_cluster() can lock the inode buffer before it locks the |
714 | * ip->i_lock, and we are doing the exact opposite here. As a result, | 723 | * ip->i_lock, and we are doing the exact opposite here. As a result, |
715 | * doing a blocking xfs_itobp() to get the cluster buffer would result | 724 | * doing a blocking xfs_imap_to_bp() to get the cluster buffer would |
716 | * in an ABBA deadlock with xfs_ifree_cluster(). | 725 | * result in an ABBA deadlock with xfs_ifree_cluster(). |
717 | * | 726 | * |
718 | * As xfs_ifree_cluser() must gather all inodes that are active in the | 727 | * As xfs_ifree_cluser() must gather all inodes that are active in the |
719 | * cache to mark them stale, if we hit this case we don't actually want | 728 | * cache to mark them stale, if we hit this case we don't actually want |
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index caf5dabfd553..e5795dd6013a 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h | |||
@@ -578,8 +578,8 @@ DEFINE_INODE_EVENT(xfs_ioctl_setattr); | |||
578 | DEFINE_INODE_EVENT(xfs_dir_fsync); | 578 | DEFINE_INODE_EVENT(xfs_dir_fsync); |
579 | DEFINE_INODE_EVENT(xfs_file_fsync); | 579 | DEFINE_INODE_EVENT(xfs_file_fsync); |
580 | DEFINE_INODE_EVENT(xfs_destroy_inode); | 580 | DEFINE_INODE_EVENT(xfs_destroy_inode); |
581 | DEFINE_INODE_EVENT(xfs_dirty_inode); | ||
582 | DEFINE_INODE_EVENT(xfs_evict_inode); | 581 | DEFINE_INODE_EVENT(xfs_evict_inode); |
582 | DEFINE_INODE_EVENT(xfs_update_time); | ||
583 | 583 | ||
584 | DEFINE_INODE_EVENT(xfs_dquot_dqalloc); | 584 | DEFINE_INODE_EVENT(xfs_dquot_dqalloc); |
585 | DEFINE_INODE_EVENT(xfs_dquot_dqdetach); | 585 | DEFINE_INODE_EVENT(xfs_dquot_dqdetach); |
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 7c37b533aa8e..bc2afd52a0b7 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h | |||
@@ -448,11 +448,51 @@ xfs_trans_t *xfs_trans_dup(xfs_trans_t *); | |||
448 | int xfs_trans_reserve(xfs_trans_t *, uint, uint, uint, | 448 | int xfs_trans_reserve(xfs_trans_t *, uint, uint, uint, |
449 | uint, uint); | 449 | uint, uint); |
450 | void xfs_trans_mod_sb(xfs_trans_t *, uint, int64_t); | 450 | void xfs_trans_mod_sb(xfs_trans_t *, uint, int64_t); |
451 | struct xfs_buf *xfs_trans_get_buf(xfs_trans_t *, struct xfs_buftarg *, xfs_daddr_t, | 451 | |
452 | int, uint); | 452 | struct xfs_buf *xfs_trans_get_buf_map(struct xfs_trans *tp, |
453 | int xfs_trans_read_buf(struct xfs_mount *, xfs_trans_t *, | 453 | struct xfs_buftarg *target, |
454 | struct xfs_buftarg *, xfs_daddr_t, int, uint, | 454 | struct xfs_buf_map *map, int nmaps, |
455 | struct xfs_buf **); | 455 | uint flags); |
456 | |||
457 | static inline struct xfs_buf * | ||
458 | xfs_trans_get_buf( | ||
459 | struct xfs_trans *tp, | ||
460 | struct xfs_buftarg *target, | ||
461 | xfs_daddr_t blkno, | ||
462 | int numblks, | ||
463 | uint flags) | ||
464 | { | ||
465 | struct xfs_buf_map map = { | ||
466 | .bm_bn = blkno, | ||
467 | .bm_len = numblks, | ||
468 | }; | ||
469 | return xfs_trans_get_buf_map(tp, target, &map, 1, flags); | ||
470 | } | ||
471 | |||
472 | int xfs_trans_read_buf_map(struct xfs_mount *mp, | ||
473 | struct xfs_trans *tp, | ||
474 | struct xfs_buftarg *target, | ||
475 | struct xfs_buf_map *map, int nmaps, | ||
476 | xfs_buf_flags_t flags, | ||
477 | struct xfs_buf **bpp); | ||
478 | |||
479 | static inline int | ||
480 | xfs_trans_read_buf( | ||
481 | struct xfs_mount *mp, | ||
482 | struct xfs_trans *tp, | ||
483 | struct xfs_buftarg *target, | ||
484 | xfs_daddr_t blkno, | ||
485 | int numblks, | ||
486 | xfs_buf_flags_t flags, | ||
487 | struct xfs_buf **bpp) | ||
488 | { | ||
489 | struct xfs_buf_map map = { | ||
490 | .bm_bn = blkno, | ||
491 | .bm_len = numblks, | ||
492 | }; | ||
493 | return xfs_trans_read_buf_map(mp, tp, target, &map, 1, flags, bpp); | ||
494 | } | ||
495 | |||
456 | struct xfs_buf *xfs_trans_getsb(xfs_trans_t *, struct xfs_mount *, int); | 496 | struct xfs_buf *xfs_trans_getsb(xfs_trans_t *, struct xfs_mount *, int); |
457 | 497 | ||
458 | void xfs_trans_brelse(xfs_trans_t *, struct xfs_buf *); | 498 | void xfs_trans_brelse(xfs_trans_t *, struct xfs_buf *); |
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index 9c514483e599..6011ee661339 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c | |||
@@ -383,6 +383,12 @@ xfsaild_push( | |||
383 | } | 383 | } |
384 | 384 | ||
385 | spin_lock(&ailp->xa_lock); | 385 | spin_lock(&ailp->xa_lock); |
386 | |||
387 | /* barrier matches the xa_target update in xfs_ail_push() */ | ||
388 | smp_rmb(); | ||
389 | target = ailp->xa_target; | ||
390 | ailp->xa_target_prev = target; | ||
391 | |||
386 | lip = xfs_trans_ail_cursor_first(ailp, &cur, ailp->xa_last_pushed_lsn); | 392 | lip = xfs_trans_ail_cursor_first(ailp, &cur, ailp->xa_last_pushed_lsn); |
387 | if (!lip) { | 393 | if (!lip) { |
388 | /* | 394 | /* |
@@ -397,7 +403,6 @@ xfsaild_push( | |||
397 | XFS_STATS_INC(xs_push_ail); | 403 | XFS_STATS_INC(xs_push_ail); |
398 | 404 | ||
399 | lsn = lip->li_lsn; | 405 | lsn = lip->li_lsn; |
400 | target = ailp->xa_target; | ||
401 | while ((XFS_LSN_CMP(lip->li_lsn, target) <= 0)) { | 406 | while ((XFS_LSN_CMP(lip->li_lsn, target) <= 0)) { |
402 | int lock_result; | 407 | int lock_result; |
403 | 408 | ||
@@ -527,8 +532,32 @@ xfsaild( | |||
527 | __set_current_state(TASK_KILLABLE); | 532 | __set_current_state(TASK_KILLABLE); |
528 | else | 533 | else |
529 | __set_current_state(TASK_INTERRUPTIBLE); | 534 | __set_current_state(TASK_INTERRUPTIBLE); |
530 | schedule_timeout(tout ? | 535 | |
531 | msecs_to_jiffies(tout) : MAX_SCHEDULE_TIMEOUT); | 536 | spin_lock(&ailp->xa_lock); |
537 | |||
538 | /* | ||
539 | * Idle if the AIL is empty and we are not racing with a target | ||
540 | * update. We check the AIL after we set the task to a sleep | ||
541 | * state to guarantee that we either catch an xa_target update | ||
542 | * or that a wake_up resets the state to TASK_RUNNING. | ||
543 | * Otherwise, we run the risk of sleeping indefinitely. | ||
544 | * | ||
545 | * The barrier matches the xa_target update in xfs_ail_push(). | ||
546 | */ | ||
547 | smp_rmb(); | ||
548 | if (!xfs_ail_min(ailp) && | ||
549 | ailp->xa_target == ailp->xa_target_prev) { | ||
550 | spin_unlock(&ailp->xa_lock); | ||
551 | schedule(); | ||
552 | tout = 0; | ||
553 | continue; | ||
554 | } | ||
555 | spin_unlock(&ailp->xa_lock); | ||
556 | |||
557 | if (tout) | ||
558 | schedule_timeout(msecs_to_jiffies(tout)); | ||
559 | |||
560 | __set_current_state(TASK_RUNNING); | ||
532 | 561 | ||
533 | try_to_freeze(); | 562 | try_to_freeze(); |
534 | 563 | ||
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c index 21c5a5e3700d..6311b99c267f 100644 --- a/fs/xfs/xfs_trans_buf.c +++ b/fs/xfs/xfs_trans_buf.c | |||
@@ -41,20 +41,26 @@ STATIC struct xfs_buf * | |||
41 | xfs_trans_buf_item_match( | 41 | xfs_trans_buf_item_match( |
42 | struct xfs_trans *tp, | 42 | struct xfs_trans *tp, |
43 | struct xfs_buftarg *target, | 43 | struct xfs_buftarg *target, |
44 | xfs_daddr_t blkno, | 44 | struct xfs_buf_map *map, |
45 | int len) | 45 | int nmaps) |
46 | { | 46 | { |
47 | struct xfs_log_item_desc *lidp; | 47 | struct xfs_log_item_desc *lidp; |
48 | struct xfs_buf_log_item *blip; | 48 | struct xfs_buf_log_item *blip; |
49 | int len = 0; | ||
50 | int i; | ||
51 | |||
52 | for (i = 0; i < nmaps; i++) | ||
53 | len += map[i].bm_len; | ||
49 | 54 | ||
50 | len = BBTOB(len); | ||
51 | list_for_each_entry(lidp, &tp->t_items, lid_trans) { | 55 | list_for_each_entry(lidp, &tp->t_items, lid_trans) { |
52 | blip = (struct xfs_buf_log_item *)lidp->lid_item; | 56 | blip = (struct xfs_buf_log_item *)lidp->lid_item; |
53 | if (blip->bli_item.li_type == XFS_LI_BUF && | 57 | if (blip->bli_item.li_type == XFS_LI_BUF && |
54 | blip->bli_buf->b_target == target && | 58 | blip->bli_buf->b_target == target && |
55 | XFS_BUF_ADDR(blip->bli_buf) == blkno && | 59 | XFS_BUF_ADDR(blip->bli_buf) == map[0].bm_bn && |
56 | BBTOB(blip->bli_buf->b_length) == len) | 60 | blip->bli_buf->b_length == len) { |
61 | ASSERT(blip->bli_buf->b_map_count == nmaps); | ||
57 | return blip->bli_buf; | 62 | return blip->bli_buf; |
63 | } | ||
58 | } | 64 | } |
59 | 65 | ||
60 | return NULL; | 66 | return NULL; |
@@ -128,21 +134,19 @@ xfs_trans_bjoin( | |||
128 | * If the transaction pointer is NULL, make this just a normal | 134 | * If the transaction pointer is NULL, make this just a normal |
129 | * get_buf() call. | 135 | * get_buf() call. |
130 | */ | 136 | */ |
131 | xfs_buf_t * | 137 | struct xfs_buf * |
132 | xfs_trans_get_buf(xfs_trans_t *tp, | 138 | xfs_trans_get_buf_map( |
133 | xfs_buftarg_t *target_dev, | 139 | struct xfs_trans *tp, |
134 | xfs_daddr_t blkno, | 140 | struct xfs_buftarg *target, |
135 | int len, | 141 | struct xfs_buf_map *map, |
136 | uint flags) | 142 | int nmaps, |
143 | xfs_buf_flags_t flags) | ||
137 | { | 144 | { |
138 | xfs_buf_t *bp; | 145 | xfs_buf_t *bp; |
139 | xfs_buf_log_item_t *bip; | 146 | xfs_buf_log_item_t *bip; |
140 | 147 | ||
141 | /* | 148 | if (!tp) |
142 | * Default to a normal get_buf() call if the tp is NULL. | 149 | return xfs_buf_get_map(target, map, nmaps, flags); |
143 | */ | ||
144 | if (tp == NULL) | ||
145 | return xfs_buf_get(target_dev, blkno, len, flags); | ||
146 | 150 | ||
147 | /* | 151 | /* |
148 | * If we find the buffer in the cache with this transaction | 152 | * If we find the buffer in the cache with this transaction |
@@ -150,7 +154,7 @@ xfs_trans_get_buf(xfs_trans_t *tp, | |||
150 | * have it locked. In this case we just increment the lock | 154 | * have it locked. In this case we just increment the lock |
151 | * recursion count and return the buffer to the caller. | 155 | * recursion count and return the buffer to the caller. |
152 | */ | 156 | */ |
153 | bp = xfs_trans_buf_item_match(tp, target_dev, blkno, len); | 157 | bp = xfs_trans_buf_item_match(tp, target, map, nmaps); |
154 | if (bp != NULL) { | 158 | if (bp != NULL) { |
155 | ASSERT(xfs_buf_islocked(bp)); | 159 | ASSERT(xfs_buf_islocked(bp)); |
156 | if (XFS_FORCED_SHUTDOWN(tp->t_mountp)) { | 160 | if (XFS_FORCED_SHUTDOWN(tp->t_mountp)) { |
@@ -167,7 +171,7 @@ xfs_trans_get_buf(xfs_trans_t *tp, | |||
167 | return (bp); | 171 | return (bp); |
168 | } | 172 | } |
169 | 173 | ||
170 | bp = xfs_buf_get(target_dev, blkno, len, flags); | 174 | bp = xfs_buf_get_map(target, map, nmaps, flags); |
171 | if (bp == NULL) { | 175 | if (bp == NULL) { |
172 | return NULL; | 176 | return NULL; |
173 | } | 177 | } |
@@ -246,26 +250,22 @@ int xfs_error_mod = 33; | |||
246 | * read_buf() call. | 250 | * read_buf() call. |
247 | */ | 251 | */ |
248 | int | 252 | int |
249 | xfs_trans_read_buf( | 253 | xfs_trans_read_buf_map( |
250 | xfs_mount_t *mp, | 254 | struct xfs_mount *mp, |
251 | xfs_trans_t *tp, | 255 | struct xfs_trans *tp, |
252 | xfs_buftarg_t *target, | 256 | struct xfs_buftarg *target, |
253 | xfs_daddr_t blkno, | 257 | struct xfs_buf_map *map, |
254 | int len, | 258 | int nmaps, |
255 | uint flags, | 259 | xfs_buf_flags_t flags, |
256 | xfs_buf_t **bpp) | 260 | struct xfs_buf **bpp) |
257 | { | 261 | { |
258 | xfs_buf_t *bp; | 262 | xfs_buf_t *bp; |
259 | xfs_buf_log_item_t *bip; | 263 | xfs_buf_log_item_t *bip; |
260 | int error; | 264 | int error; |
261 | 265 | ||
262 | *bpp = NULL; | 266 | *bpp = NULL; |
263 | 267 | if (!tp) { | |
264 | /* | 268 | bp = xfs_buf_read_map(target, map, nmaps, flags); |
265 | * Default to a normal get_buf() call if the tp is NULL. | ||
266 | */ | ||
267 | if (tp == NULL) { | ||
268 | bp = xfs_buf_read(target, blkno, len, flags); | ||
269 | if (!bp) | 269 | if (!bp) |
270 | return (flags & XBF_TRYLOCK) ? | 270 | return (flags & XBF_TRYLOCK) ? |
271 | EAGAIN : XFS_ERROR(ENOMEM); | 271 | EAGAIN : XFS_ERROR(ENOMEM); |
@@ -303,7 +303,7 @@ xfs_trans_read_buf( | |||
303 | * If the buffer is not yet read in, then we read it in, increment | 303 | * If the buffer is not yet read in, then we read it in, increment |
304 | * the lock recursion count, and return it to the caller. | 304 | * the lock recursion count, and return it to the caller. |
305 | */ | 305 | */ |
306 | bp = xfs_trans_buf_item_match(tp, target, blkno, len); | 306 | bp = xfs_trans_buf_item_match(tp, target, map, nmaps); |
307 | if (bp != NULL) { | 307 | if (bp != NULL) { |
308 | ASSERT(xfs_buf_islocked(bp)); | 308 | ASSERT(xfs_buf_islocked(bp)); |
309 | ASSERT(bp->b_transp == tp); | 309 | ASSERT(bp->b_transp == tp); |
@@ -349,7 +349,7 @@ xfs_trans_read_buf( | |||
349 | return 0; | 349 | return 0; |
350 | } | 350 | } |
351 | 351 | ||
352 | bp = xfs_buf_read(target, blkno, len, flags); | 352 | bp = xfs_buf_read_map(target, map, nmaps, flags); |
353 | if (bp == NULL) { | 353 | if (bp == NULL) { |
354 | *bpp = NULL; | 354 | *bpp = NULL; |
355 | return (flags & XBF_TRYLOCK) ? | 355 | return (flags & XBF_TRYLOCK) ? |
diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h index fb62377d1cbc..53b7c9b0f8f7 100644 --- a/fs/xfs/xfs_trans_priv.h +++ b/fs/xfs/xfs_trans_priv.h | |||
@@ -67,6 +67,7 @@ struct xfs_ail { | |||
67 | struct task_struct *xa_task; | 67 | struct task_struct *xa_task; |
68 | struct list_head xa_ail; | 68 | struct list_head xa_ail; |
69 | xfs_lsn_t xa_target; | 69 | xfs_lsn_t xa_target; |
70 | xfs_lsn_t xa_target_prev; | ||
70 | struct list_head xa_cursors; | 71 | struct list_head xa_cursors; |
71 | spinlock_t xa_lock; | 72 | spinlock_t xa_lock; |
72 | xfs_lsn_t xa_last_pushed_lsn; | 73 | xfs_lsn_t xa_last_pushed_lsn; |
diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h index 398cf681d025..7a41874f4c20 100644 --- a/fs/xfs/xfs_types.h +++ b/fs/xfs/xfs_types.h | |||
@@ -133,6 +133,20 @@ typedef __uint64_t xfs_filblks_t; /* number of blocks in a file */ | |||
133 | #define MAXAEXTNUM ((xfs_aextnum_t)0x7fff) /* signed short */ | 133 | #define MAXAEXTNUM ((xfs_aextnum_t)0x7fff) /* signed short */ |
134 | 134 | ||
135 | /* | 135 | /* |
136 | * Minimum and maximum blocksize and sectorsize. | ||
137 | * The blocksize upper limit is pretty much arbitrary. | ||
138 | * The sectorsize upper limit is due to sizeof(sb_sectsize). | ||
139 | */ | ||
140 | #define XFS_MIN_BLOCKSIZE_LOG 9 /* i.e. 512 bytes */ | ||
141 | #define XFS_MAX_BLOCKSIZE_LOG 16 /* i.e. 65536 bytes */ | ||
142 | #define XFS_MIN_BLOCKSIZE (1 << XFS_MIN_BLOCKSIZE_LOG) | ||
143 | #define XFS_MAX_BLOCKSIZE (1 << XFS_MAX_BLOCKSIZE_LOG) | ||
144 | #define XFS_MIN_SECTORSIZE_LOG 9 /* i.e. 512 bytes */ | ||
145 | #define XFS_MAX_SECTORSIZE_LOG 15 /* i.e. 32768 bytes */ | ||
146 | #define XFS_MIN_SECTORSIZE (1 << XFS_MIN_SECTORSIZE_LOG) | ||
147 | #define XFS_MAX_SECTORSIZE (1 << XFS_MAX_SECTORSIZE_LOG) | ||
148 | |||
149 | /* | ||
136 | * Min numbers of data/attr fork btree root pointers. | 150 | * Min numbers of data/attr fork btree root pointers. |
137 | */ | 151 | */ |
138 | #define MINDBTPTRS 3 | 152 | #define MINDBTPTRS 3 |
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c index 4e5b9ad5cb97..0025c78ac03c 100644 --- a/fs/xfs/xfs_utils.c +++ b/fs/xfs/xfs_utils.c | |||
@@ -65,7 +65,6 @@ xfs_dir_ialloc( | |||
65 | xfs_trans_t *ntp; | 65 | xfs_trans_t *ntp; |
66 | xfs_inode_t *ip; | 66 | xfs_inode_t *ip; |
67 | xfs_buf_t *ialloc_context = NULL; | 67 | xfs_buf_t *ialloc_context = NULL; |
68 | boolean_t call_again = B_FALSE; | ||
69 | int code; | 68 | int code; |
70 | uint log_res; | 69 | uint log_res; |
71 | uint log_count; | 70 | uint log_count; |
@@ -91,7 +90,7 @@ xfs_dir_ialloc( | |||
91 | * the inode(s) that we've just allocated. | 90 | * the inode(s) that we've just allocated. |
92 | */ | 91 | */ |
93 | code = xfs_ialloc(tp, dp, mode, nlink, rdev, prid, okalloc, | 92 | code = xfs_ialloc(tp, dp, mode, nlink, rdev, prid, okalloc, |
94 | &ialloc_context, &call_again, &ip); | 93 | &ialloc_context, &ip); |
95 | 94 | ||
96 | /* | 95 | /* |
97 | * Return an error if we were unable to allocate a new inode. | 96 | * Return an error if we were unable to allocate a new inode. |
@@ -102,19 +101,18 @@ xfs_dir_ialloc( | |||
102 | *ipp = NULL; | 101 | *ipp = NULL; |
103 | return code; | 102 | return code; |
104 | } | 103 | } |
105 | if (!call_again && (ip == NULL)) { | 104 | if (!ialloc_context && !ip) { |
106 | *ipp = NULL; | 105 | *ipp = NULL; |
107 | return XFS_ERROR(ENOSPC); | 106 | return XFS_ERROR(ENOSPC); |
108 | } | 107 | } |
109 | 108 | ||
110 | /* | 109 | /* |
111 | * If call_again is set, then we were unable to get an | 110 | * If the AGI buffer is non-NULL, then we were unable to get an |
112 | * inode in one operation. We need to commit the current | 111 | * inode in one operation. We need to commit the current |
113 | * transaction and call xfs_ialloc() again. It is guaranteed | 112 | * transaction and call xfs_ialloc() again. It is guaranteed |
114 | * to succeed the second time. | 113 | * to succeed the second time. |
115 | */ | 114 | */ |
116 | if (call_again) { | 115 | if (ialloc_context) { |
117 | |||
118 | /* | 116 | /* |
119 | * Normally, xfs_trans_commit releases all the locks. | 117 | * Normally, xfs_trans_commit releases all the locks. |
120 | * We call bhold to hang on to the ialloc_context across | 118 | * We call bhold to hang on to the ialloc_context across |
@@ -195,7 +193,7 @@ xfs_dir_ialloc( | |||
195 | * this call should always succeed. | 193 | * this call should always succeed. |
196 | */ | 194 | */ |
197 | code = xfs_ialloc(tp, dp, mode, nlink, rdev, prid, | 195 | code = xfs_ialloc(tp, dp, mode, nlink, rdev, prid, |
198 | okalloc, &ialloc_context, &call_again, &ip); | 196 | okalloc, &ialloc_context, &ip); |
199 | 197 | ||
200 | /* | 198 | /* |
201 | * If we get an error at this point, return to the caller | 199 | * If we get an error at this point, return to the caller |
@@ -206,12 +204,11 @@ xfs_dir_ialloc( | |||
206 | *ipp = NULL; | 204 | *ipp = NULL; |
207 | return code; | 205 | return code; |
208 | } | 206 | } |
209 | ASSERT ((!call_again) && (ip != NULL)); | 207 | ASSERT(!ialloc_context && ip); |
210 | 208 | ||
211 | } else { | 209 | } else { |
212 | if (committed != NULL) { | 210 | if (committed != NULL) |
213 | *committed = 0; | 211 | *committed = 0; |
214 | } | ||
215 | } | 212 | } |
216 | 213 | ||
217 | *ipp = ip; | 214 | *ipp = ip; |
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index b6a82d817a82..2a5c637344b4 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -146,11 +146,6 @@ xfs_readlink( | |||
146 | } | 146 | } |
147 | 147 | ||
148 | /* | 148 | /* |
149 | * Flags for xfs_free_eofblocks | ||
150 | */ | ||
151 | #define XFS_FREE_EOF_TRYLOCK (1<<0) | ||
152 | |||
153 | /* | ||
154 | * This is called by xfs_inactive to free any blocks beyond eof | 149 | * This is called by xfs_inactive to free any blocks beyond eof |
155 | * when the link count isn't zero and by xfs_dm_punch_hole() when | 150 | * when the link count isn't zero and by xfs_dm_punch_hole() when |
156 | * punching a hole to EOF. | 151 | * punching a hole to EOF. |
@@ -159,7 +154,7 @@ STATIC int | |||
159 | xfs_free_eofblocks( | 154 | xfs_free_eofblocks( |
160 | xfs_mount_t *mp, | 155 | xfs_mount_t *mp, |
161 | xfs_inode_t *ip, | 156 | xfs_inode_t *ip, |
162 | int flags) | 157 | bool need_iolock) |
163 | { | 158 | { |
164 | xfs_trans_t *tp; | 159 | xfs_trans_t *tp; |
165 | int error; | 160 | int error; |
@@ -174,7 +169,7 @@ xfs_free_eofblocks( | |||
174 | * of the file. If not, then there is nothing to do. | 169 | * of the file. If not, then there is nothing to do. |
175 | */ | 170 | */ |
176 | end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_ISIZE(ip)); | 171 | end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_ISIZE(ip)); |
177 | last_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp)); | 172 | last_fsb = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes); |
178 | if (last_fsb <= end_fsb) | 173 | if (last_fsb <= end_fsb) |
179 | return 0; | 174 | return 0; |
180 | map_len = last_fsb - end_fsb; | 175 | map_len = last_fsb - end_fsb; |
@@ -201,13 +196,11 @@ xfs_free_eofblocks( | |||
201 | */ | 196 | */ |
202 | tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); | 197 | tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); |
203 | 198 | ||
204 | if (flags & XFS_FREE_EOF_TRYLOCK) { | 199 | if (need_iolock) { |
205 | if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) { | 200 | if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) { |
206 | xfs_trans_cancel(tp, 0); | 201 | xfs_trans_cancel(tp, 0); |
207 | return 0; | 202 | return 0; |
208 | } | 203 | } |
209 | } else { | ||
210 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | ||
211 | } | 204 | } |
212 | 205 | ||
213 | error = xfs_trans_reserve(tp, 0, | 206 | error = xfs_trans_reserve(tp, 0, |
@@ -217,7 +210,8 @@ xfs_free_eofblocks( | |||
217 | if (error) { | 210 | if (error) { |
218 | ASSERT(XFS_FORCED_SHUTDOWN(mp)); | 211 | ASSERT(XFS_FORCED_SHUTDOWN(mp)); |
219 | xfs_trans_cancel(tp, 0); | 212 | xfs_trans_cancel(tp, 0); |
220 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | 213 | if (need_iolock) |
214 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
221 | return error; | 215 | return error; |
222 | } | 216 | } |
223 | 217 | ||
@@ -244,7 +238,10 @@ xfs_free_eofblocks( | |||
244 | error = xfs_trans_commit(tp, | 238 | error = xfs_trans_commit(tp, |
245 | XFS_TRANS_RELEASE_LOG_RES); | 239 | XFS_TRANS_RELEASE_LOG_RES); |
246 | } | 240 | } |
247 | xfs_iunlock(ip, XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL); | 241 | |
242 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
243 | if (need_iolock) | ||
244 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
248 | } | 245 | } |
249 | return error; | 246 | return error; |
250 | } | 247 | } |
@@ -282,23 +279,15 @@ xfs_inactive_symlink_rmt( | |||
282 | * free them all in one bunmapi call. | 279 | * free them all in one bunmapi call. |
283 | */ | 280 | */ |
284 | ASSERT(ip->i_d.di_nextents > 0 && ip->i_d.di_nextents <= 2); | 281 | ASSERT(ip->i_d.di_nextents > 0 && ip->i_d.di_nextents <= 2); |
285 | if ((error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, | 282 | |
286 | XFS_TRANS_PERM_LOG_RES, XFS_ITRUNCATE_LOG_COUNT))) { | ||
287 | ASSERT(XFS_FORCED_SHUTDOWN(mp)); | ||
288 | xfs_trans_cancel(tp, 0); | ||
289 | *tpp = NULL; | ||
290 | return error; | ||
291 | } | ||
292 | /* | 283 | /* |
293 | * Lock the inode, fix the size, and join it to the transaction. | 284 | * Lock the inode, fix the size, and join it to the transaction. |
294 | * Hold it so in the normal path, we still have it locked for | 285 | * Hold it so in the normal path, we still have it locked for |
295 | * the second transaction. In the error paths we need it | 286 | * the second transaction. In the error paths we need it |
296 | * held so the cancel won't rele it, see below. | 287 | * held so the cancel won't rele it, see below. |
297 | */ | 288 | */ |
298 | xfs_ilock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); | ||
299 | size = (int)ip->i_d.di_size; | 289 | size = (int)ip->i_d.di_size; |
300 | ip->i_d.di_size = 0; | 290 | ip->i_d.di_size = 0; |
301 | xfs_trans_ijoin(tp, ip, 0); | ||
302 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 291 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
303 | /* | 292 | /* |
304 | * Find the block(s) so we can inval and unmap them. | 293 | * Find the block(s) so we can inval and unmap them. |
@@ -385,114 +374,14 @@ xfs_inactive_symlink_rmt( | |||
385 | ASSERT(XFS_FORCED_SHUTDOWN(mp)); | 374 | ASSERT(XFS_FORCED_SHUTDOWN(mp)); |
386 | goto error0; | 375 | goto error0; |
387 | } | 376 | } |
388 | /* | 377 | |
389 | * Return with the inode locked but not joined to the transaction. | 378 | xfs_trans_ijoin(tp, ip, 0); |
390 | */ | ||
391 | *tpp = tp; | 379 | *tpp = tp; |
392 | return 0; | 380 | return 0; |
393 | 381 | ||
394 | error1: | 382 | error1: |
395 | xfs_bmap_cancel(&free_list); | 383 | xfs_bmap_cancel(&free_list); |
396 | error0: | 384 | error0: |
397 | /* | ||
398 | * Have to come here with the inode locked and either | ||
399 | * (held and in the transaction) or (not in the transaction). | ||
400 | * If the inode isn't held then cancel would iput it, but | ||
401 | * that's wrong since this is inactive and the vnode ref | ||
402 | * count is 0 already. | ||
403 | * Cancel won't do anything to the inode if held, but it still | ||
404 | * needs to be locked until the cancel is done, if it was | ||
405 | * joined to the transaction. | ||
406 | */ | ||
407 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); | ||
408 | xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); | ||
409 | *tpp = NULL; | ||
410 | return error; | ||
411 | |||
412 | } | ||
413 | |||
414 | STATIC int | ||
415 | xfs_inactive_symlink_local( | ||
416 | xfs_inode_t *ip, | ||
417 | xfs_trans_t **tpp) | ||
418 | { | ||
419 | int error; | ||
420 | |||
421 | ASSERT(ip->i_d.di_size <= XFS_IFORK_DSIZE(ip)); | ||
422 | /* | ||
423 | * We're freeing a symlink which fit into | ||
424 | * the inode. Just free the memory used | ||
425 | * to hold the old symlink. | ||
426 | */ | ||
427 | error = xfs_trans_reserve(*tpp, 0, | ||
428 | XFS_ITRUNCATE_LOG_RES(ip->i_mount), | ||
429 | 0, XFS_TRANS_PERM_LOG_RES, | ||
430 | XFS_ITRUNCATE_LOG_COUNT); | ||
431 | |||
432 | if (error) { | ||
433 | xfs_trans_cancel(*tpp, 0); | ||
434 | *tpp = NULL; | ||
435 | return error; | ||
436 | } | ||
437 | xfs_ilock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | ||
438 | |||
439 | /* | ||
440 | * Zero length symlinks _can_ exist. | ||
441 | */ | ||
442 | if (ip->i_df.if_bytes > 0) { | ||
443 | xfs_idata_realloc(ip, | ||
444 | -(ip->i_df.if_bytes), | ||
445 | XFS_DATA_FORK); | ||
446 | ASSERT(ip->i_df.if_bytes == 0); | ||
447 | } | ||
448 | return 0; | ||
449 | } | ||
450 | |||
451 | STATIC int | ||
452 | xfs_inactive_attrs( | ||
453 | xfs_inode_t *ip, | ||
454 | xfs_trans_t **tpp) | ||
455 | { | ||
456 | xfs_trans_t *tp; | ||
457 | int error; | ||
458 | xfs_mount_t *mp; | ||
459 | |||
460 | ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); | ||
461 | tp = *tpp; | ||
462 | mp = ip->i_mount; | ||
463 | ASSERT(ip->i_d.di_forkoff != 0); | ||
464 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | ||
465 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
466 | if (error) | ||
467 | goto error_unlock; | ||
468 | |||
469 | error = xfs_attr_inactive(ip); | ||
470 | if (error) | ||
471 | goto error_unlock; | ||
472 | |||
473 | tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); | ||
474 | error = xfs_trans_reserve(tp, 0, | ||
475 | XFS_IFREE_LOG_RES(mp), | ||
476 | 0, XFS_TRANS_PERM_LOG_RES, | ||
477 | XFS_INACTIVE_LOG_COUNT); | ||
478 | if (error) | ||
479 | goto error_cancel; | ||
480 | |||
481 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
482 | xfs_trans_ijoin(tp, ip, 0); | ||
483 | xfs_idestroy_fork(ip, XFS_ATTR_FORK); | ||
484 | |||
485 | ASSERT(ip->i_d.di_anextents == 0); | ||
486 | |||
487 | *tpp = tp; | ||
488 | return 0; | ||
489 | |||
490 | error_cancel: | ||
491 | ASSERT(XFS_FORCED_SHUTDOWN(mp)); | ||
492 | xfs_trans_cancel(tp, 0); | ||
493 | error_unlock: | ||
494 | *tpp = NULL; | ||
495 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
496 | return error; | 385 | return error; |
497 | } | 386 | } |
498 | 387 | ||
@@ -574,8 +463,7 @@ xfs_release( | |||
574 | if (xfs_iflags_test(ip, XFS_IDIRTY_RELEASE)) | 463 | if (xfs_iflags_test(ip, XFS_IDIRTY_RELEASE)) |
575 | return 0; | 464 | return 0; |
576 | 465 | ||
577 | error = xfs_free_eofblocks(mp, ip, | 466 | error = xfs_free_eofblocks(mp, ip, true); |
578 | XFS_FREE_EOF_TRYLOCK); | ||
579 | if (error) | 467 | if (error) |
580 | return error; | 468 | return error; |
581 | 469 | ||
@@ -604,7 +492,7 @@ xfs_inactive( | |||
604 | xfs_trans_t *tp; | 492 | xfs_trans_t *tp; |
605 | xfs_mount_t *mp; | 493 | xfs_mount_t *mp; |
606 | int error; | 494 | int error; |
607 | int truncate; | 495 | int truncate = 0; |
608 | 496 | ||
609 | /* | 497 | /* |
610 | * If the inode is already free, then there can be nothing | 498 | * If the inode is already free, then there can be nothing |
@@ -616,17 +504,6 @@ xfs_inactive( | |||
616 | return VN_INACTIVE_CACHE; | 504 | return VN_INACTIVE_CACHE; |
617 | } | 505 | } |
618 | 506 | ||
619 | /* | ||
620 | * Only do a truncate if it's a regular file with | ||
621 | * some actual space in it. It's OK to look at the | ||
622 | * inode's fields without the lock because we're the | ||
623 | * only one with a reference to the inode. | ||
624 | */ | ||
625 | truncate = ((ip->i_d.di_nlink == 0) && | ||
626 | ((ip->i_d.di_size != 0) || XFS_ISIZE(ip) != 0 || | ||
627 | (ip->i_d.di_nextents > 0) || (ip->i_delayed_blks > 0)) && | ||
628 | S_ISREG(ip->i_d.di_mode)); | ||
629 | |||
630 | mp = ip->i_mount; | 507 | mp = ip->i_mount; |
631 | 508 | ||
632 | error = 0; | 509 | error = 0; |
@@ -643,99 +520,100 @@ xfs_inactive( | |||
643 | (!(ip->i_d.di_flags & | 520 | (!(ip->i_d.di_flags & |
644 | (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) || | 521 | (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) || |
645 | ip->i_delayed_blks != 0))) { | 522 | ip->i_delayed_blks != 0))) { |
646 | error = xfs_free_eofblocks(mp, ip, 0); | 523 | error = xfs_free_eofblocks(mp, ip, false); |
647 | if (error) | 524 | if (error) |
648 | return VN_INACTIVE_CACHE; | 525 | return VN_INACTIVE_CACHE; |
649 | } | 526 | } |
650 | goto out; | 527 | goto out; |
651 | } | 528 | } |
652 | 529 | ||
653 | ASSERT(ip->i_d.di_nlink == 0); | 530 | if (S_ISREG(ip->i_d.di_mode) && |
531 | (ip->i_d.di_size != 0 || XFS_ISIZE(ip) != 0 || | ||
532 | ip->i_d.di_nextents > 0 || ip->i_delayed_blks > 0)) | ||
533 | truncate = 1; | ||
654 | 534 | ||
655 | error = xfs_qm_dqattach(ip, 0); | 535 | error = xfs_qm_dqattach(ip, 0); |
656 | if (error) | 536 | if (error) |
657 | return VN_INACTIVE_CACHE; | 537 | return VN_INACTIVE_CACHE; |
658 | 538 | ||
659 | tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); | 539 | tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); |
660 | if (truncate) { | 540 | error = xfs_trans_reserve(tp, 0, |
661 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | 541 | (truncate || S_ISLNK(ip->i_d.di_mode)) ? |
662 | 542 | XFS_ITRUNCATE_LOG_RES(mp) : | |
663 | error = xfs_trans_reserve(tp, 0, | 543 | XFS_IFREE_LOG_RES(mp), |
664 | XFS_ITRUNCATE_LOG_RES(mp), | 544 | 0, |
665 | 0, XFS_TRANS_PERM_LOG_RES, | 545 | XFS_TRANS_PERM_LOG_RES, |
666 | XFS_ITRUNCATE_LOG_COUNT); | 546 | XFS_ITRUNCATE_LOG_COUNT); |
667 | if (error) { | 547 | if (error) { |
668 | /* Don't call itruncate_cleanup */ | 548 | ASSERT(XFS_FORCED_SHUTDOWN(mp)); |
669 | ASSERT(XFS_FORCED_SHUTDOWN(mp)); | 549 | xfs_trans_cancel(tp, 0); |
670 | xfs_trans_cancel(tp, 0); | 550 | return VN_INACTIVE_CACHE; |
671 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | 551 | } |
672 | return VN_INACTIVE_CACHE; | ||
673 | } | ||
674 | 552 | ||
675 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 553 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
676 | xfs_trans_ijoin(tp, ip, 0); | 554 | xfs_trans_ijoin(tp, ip, 0); |
677 | 555 | ||
556 | if (S_ISLNK(ip->i_d.di_mode)) { | ||
557 | /* | ||
558 | * Zero length symlinks _can_ exist. | ||
559 | */ | ||
560 | if (ip->i_d.di_size > XFS_IFORK_DSIZE(ip)) { | ||
561 | error = xfs_inactive_symlink_rmt(ip, &tp); | ||
562 | if (error) | ||
563 | goto out_cancel; | ||
564 | } else if (ip->i_df.if_bytes > 0) { | ||
565 | xfs_idata_realloc(ip, -(ip->i_df.if_bytes), | ||
566 | XFS_DATA_FORK); | ||
567 | ASSERT(ip->i_df.if_bytes == 0); | ||
568 | } | ||
569 | } else if (truncate) { | ||
678 | ip->i_d.di_size = 0; | 570 | ip->i_d.di_size = 0; |
679 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 571 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
680 | 572 | ||
681 | error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK, 0); | 573 | error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK, 0); |
682 | if (error) { | 574 | if (error) |
683 | xfs_trans_cancel(tp, | 575 | goto out_cancel; |
684 | XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); | ||
685 | xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); | ||
686 | return VN_INACTIVE_CACHE; | ||
687 | } | ||
688 | 576 | ||
689 | ASSERT(ip->i_d.di_nextents == 0); | 577 | ASSERT(ip->i_d.di_nextents == 0); |
690 | } else if (S_ISLNK(ip->i_d.di_mode)) { | 578 | } |
691 | 579 | ||
692 | /* | 580 | /* |
693 | * If we get an error while cleaning up a | 581 | * If there are attributes associated with the file then blow them away |
694 | * symlink we bail out. | 582 | * now. The code calls a routine that recursively deconstructs the |
695 | */ | 583 | * attribute fork. We need to just commit the current transaction |
696 | error = (ip->i_d.di_size > XFS_IFORK_DSIZE(ip)) ? | 584 | * because we can't use it for xfs_attr_inactive(). |
697 | xfs_inactive_symlink_rmt(ip, &tp) : | 585 | */ |
698 | xfs_inactive_symlink_local(ip, &tp); | 586 | if (ip->i_d.di_anextents > 0) { |
587 | ASSERT(ip->i_d.di_forkoff != 0); | ||
699 | 588 | ||
700 | if (error) { | 589 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); |
701 | ASSERT(tp == NULL); | 590 | if (error) |
702 | return VN_INACTIVE_CACHE; | 591 | goto out_unlock; |
703 | } | ||
704 | 592 | ||
705 | xfs_trans_ijoin(tp, ip, 0); | 593 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
706 | } else { | 594 | |
595 | error = xfs_attr_inactive(ip); | ||
596 | if (error) | ||
597 | goto out; | ||
598 | |||
599 | tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); | ||
707 | error = xfs_trans_reserve(tp, 0, | 600 | error = xfs_trans_reserve(tp, 0, |
708 | XFS_IFREE_LOG_RES(mp), | 601 | XFS_IFREE_LOG_RES(mp), |
709 | 0, XFS_TRANS_PERM_LOG_RES, | 602 | 0, XFS_TRANS_PERM_LOG_RES, |
710 | XFS_INACTIVE_LOG_COUNT); | 603 | XFS_INACTIVE_LOG_COUNT); |
711 | if (error) { | 604 | if (error) { |
712 | ASSERT(XFS_FORCED_SHUTDOWN(mp)); | ||
713 | xfs_trans_cancel(tp, 0); | 605 | xfs_trans_cancel(tp, 0); |
714 | return VN_INACTIVE_CACHE; | 606 | goto out; |
715 | } | 607 | } |
716 | 608 | ||
717 | xfs_ilock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | 609 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
718 | xfs_trans_ijoin(tp, ip, 0); | 610 | xfs_trans_ijoin(tp, ip, 0); |
719 | } | 611 | } |
720 | 612 | ||
721 | /* | 613 | if (ip->i_afp) |
722 | * If there are attributes associated with the file | ||
723 | * then blow them away now. The code calls a routine | ||
724 | * that recursively deconstructs the attribute fork. | ||
725 | * We need to just commit the current transaction | ||
726 | * because we can't use it for xfs_attr_inactive(). | ||
727 | */ | ||
728 | if (ip->i_d.di_anextents > 0) { | ||
729 | error = xfs_inactive_attrs(ip, &tp); | ||
730 | /* | ||
731 | * If we got an error, the transaction is already | ||
732 | * cancelled, and the inode is unlocked. Just get out. | ||
733 | */ | ||
734 | if (error) | ||
735 | return VN_INACTIVE_CACHE; | ||
736 | } else if (ip->i_afp) { | ||
737 | xfs_idestroy_fork(ip, XFS_ATTR_FORK); | 614 | xfs_idestroy_fork(ip, XFS_ATTR_FORK); |
738 | } | 615 | |
616 | ASSERT(ip->i_d.di_anextents == 0); | ||
739 | 617 | ||
740 | /* | 618 | /* |
741 | * Free the inode. | 619 | * Free the inode. |
@@ -779,10 +657,13 @@ xfs_inactive( | |||
779 | * Release the dquots held by inode, if any. | 657 | * Release the dquots held by inode, if any. |
780 | */ | 658 | */ |
781 | xfs_qm_dqdetach(ip); | 659 | xfs_qm_dqdetach(ip); |
782 | xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); | 660 | out_unlock: |
783 | 661 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | |
784 | out: | 662 | out: |
785 | return VN_INACTIVE_CACHE; | 663 | return VN_INACTIVE_CACHE; |
664 | out_cancel: | ||
665 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); | ||
666 | goto out_unlock; | ||
786 | } | 667 | } |
787 | 668 | ||
788 | /* | 669 | /* |
@@ -2262,10 +2143,10 @@ xfs_change_file_space( | |||
2262 | 2143 | ||
2263 | llen = bf->l_len > 0 ? bf->l_len - 1 : bf->l_len; | 2144 | llen = bf->l_len > 0 ? bf->l_len - 1 : bf->l_len; |
2264 | 2145 | ||
2265 | if ( (bf->l_start < 0) | 2146 | if (bf->l_start < 0 || |
2266 | || (bf->l_start > XFS_MAXIOFFSET(mp)) | 2147 | bf->l_start > mp->m_super->s_maxbytes || |
2267 | || (bf->l_start + llen < 0) | 2148 | bf->l_start + llen < 0 || |
2268 | || (bf->l_start + llen > XFS_MAXIOFFSET(mp))) | 2149 | bf->l_start + llen > mp->m_super->s_maxbytes) |
2269 | return XFS_ERROR(EINVAL); | 2150 | return XFS_ERROR(EINVAL); |
2270 | 2151 | ||
2271 | bf->l_whence = 0; | 2152 | bf->l_whence = 0; |