diff options
Diffstat (limited to 'fs/xfs/xfs_dir2_block.c')
-rw-r--r-- | fs/xfs/xfs_dir2_block.c | 37 |
1 files changed, 19 insertions, 18 deletions
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c index e59f5fc816fe..5e7fbd72cf52 100644 --- a/fs/xfs/xfs_dir2_block.c +++ b/fs/xfs/xfs_dir2_block.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "xfs_dinode.h" | 29 | #include "xfs_dinode.h" |
30 | #include "xfs_inode.h" | 30 | #include "xfs_inode.h" |
31 | #include "xfs_inode_item.h" | 31 | #include "xfs_inode_item.h" |
32 | #include "xfs_bmap.h" | ||
32 | #include "xfs_buf_item.h" | 33 | #include "xfs_buf_item.h" |
33 | #include "xfs_dir2.h" | 34 | #include "xfs_dir2.h" |
34 | #include "xfs_dir2_format.h" | 35 | #include "xfs_dir2_format.h" |
@@ -569,9 +570,7 @@ xfs_dir2_block_addname( | |||
569 | int /* error */ | 570 | int /* error */ |
570 | xfs_dir2_block_getdents( | 571 | xfs_dir2_block_getdents( |
571 | xfs_inode_t *dp, /* incore inode */ | 572 | xfs_inode_t *dp, /* incore inode */ |
572 | void *dirent, | 573 | struct dir_context *ctx) |
573 | xfs_off_t *offset, | ||
574 | filldir_t filldir) | ||
575 | { | 574 | { |
576 | xfs_dir2_data_hdr_t *hdr; /* block header */ | 575 | xfs_dir2_data_hdr_t *hdr; /* block header */ |
577 | struct xfs_buf *bp; /* buffer for block */ | 576 | struct xfs_buf *bp; /* buffer for block */ |
@@ -589,7 +588,7 @@ xfs_dir2_block_getdents( | |||
589 | /* | 588 | /* |
590 | * If the block number in the offset is out of range, we're done. | 589 | * If the block number in the offset is out of range, we're done. |
591 | */ | 590 | */ |
592 | if (xfs_dir2_dataptr_to_db(mp, *offset) > mp->m_dirdatablk) | 591 | if (xfs_dir2_dataptr_to_db(mp, ctx->pos) > mp->m_dirdatablk) |
593 | return 0; | 592 | return 0; |
594 | 593 | ||
595 | error = xfs_dir3_block_read(NULL, dp, &bp); | 594 | error = xfs_dir3_block_read(NULL, dp, &bp); |
@@ -600,7 +599,7 @@ xfs_dir2_block_getdents( | |||
600 | * Extract the byte offset we start at from the seek pointer. | 599 | * Extract the byte offset we start at from the seek pointer. |
601 | * We'll skip entries before this. | 600 | * We'll skip entries before this. |
602 | */ | 601 | */ |
603 | wantoff = xfs_dir2_dataptr_to_off(mp, *offset); | 602 | wantoff = xfs_dir2_dataptr_to_off(mp, ctx->pos); |
604 | hdr = bp->b_addr; | 603 | hdr = bp->b_addr; |
605 | xfs_dir3_data_check(dp, bp); | 604 | xfs_dir3_data_check(dp, bp); |
606 | /* | 605 | /* |
@@ -639,13 +638,12 @@ xfs_dir2_block_getdents( | |||
639 | cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, | 638 | cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, |
640 | (char *)dep - (char *)hdr); | 639 | (char *)dep - (char *)hdr); |
641 | 640 | ||
641 | ctx->pos = cook & 0x7fffffff; | ||
642 | /* | 642 | /* |
643 | * If it didn't fit, set the final offset to here & return. | 643 | * If it didn't fit, set the final offset to here & return. |
644 | */ | 644 | */ |
645 | if (filldir(dirent, (char *)dep->name, dep->namelen, | 645 | if (!dir_emit(ctx, (char *)dep->name, dep->namelen, |
646 | cook & 0x7fffffff, be64_to_cpu(dep->inumber), | 646 | be64_to_cpu(dep->inumber), DT_UNKNOWN)) { |
647 | DT_UNKNOWN)) { | ||
648 | *offset = cook & 0x7fffffff; | ||
649 | xfs_trans_brelse(NULL, bp); | 647 | xfs_trans_brelse(NULL, bp); |
650 | return 0; | 648 | return 0; |
651 | } | 649 | } |
@@ -655,7 +653,7 @@ xfs_dir2_block_getdents( | |||
655 | * Reached the end of the block. | 653 | * Reached the end of the block. |
656 | * Set the offset to a non-existent block 1 and return. | 654 | * Set the offset to a non-existent block 1 and return. |
657 | */ | 655 | */ |
658 | *offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) & | 656 | ctx->pos = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) & |
659 | 0x7fffffff; | 657 | 0x7fffffff; |
660 | xfs_trans_brelse(NULL, bp); | 658 | xfs_trans_brelse(NULL, bp); |
661 | return 0; | 659 | return 0; |
@@ -1167,13 +1165,15 @@ xfs_dir2_sf_to_block( | |||
1167 | __be16 *tagp; /* end of data entry */ | 1165 | __be16 *tagp; /* end of data entry */ |
1168 | xfs_trans_t *tp; /* transaction pointer */ | 1166 | xfs_trans_t *tp; /* transaction pointer */ |
1169 | struct xfs_name name; | 1167 | struct xfs_name name; |
1168 | struct xfs_ifork *ifp; | ||
1170 | 1169 | ||
1171 | trace_xfs_dir2_sf_to_block(args); | 1170 | trace_xfs_dir2_sf_to_block(args); |
1172 | 1171 | ||
1173 | dp = args->dp; | 1172 | dp = args->dp; |
1174 | tp = args->trans; | 1173 | tp = args->trans; |
1175 | mp = dp->i_mount; | 1174 | mp = dp->i_mount; |
1176 | ASSERT(dp->i_df.if_flags & XFS_IFINLINE); | 1175 | ifp = XFS_IFORK_PTR(dp, XFS_DATA_FORK); |
1176 | ASSERT(ifp->if_flags & XFS_IFINLINE); | ||
1177 | /* | 1177 | /* |
1178 | * Bomb out if the shortform directory is way too short. | 1178 | * Bomb out if the shortform directory is way too short. |
1179 | */ | 1179 | */ |
@@ -1182,22 +1182,23 @@ xfs_dir2_sf_to_block( | |||
1182 | return XFS_ERROR(EIO); | 1182 | return XFS_ERROR(EIO); |
1183 | } | 1183 | } |
1184 | 1184 | ||
1185 | oldsfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; | 1185 | oldsfp = (xfs_dir2_sf_hdr_t *)ifp->if_u1.if_data; |
1186 | 1186 | ||
1187 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); | 1187 | ASSERT(ifp->if_bytes == dp->i_d.di_size); |
1188 | ASSERT(dp->i_df.if_u1.if_data != NULL); | 1188 | ASSERT(ifp->if_u1.if_data != NULL); |
1189 | ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(oldsfp->i8count)); | 1189 | ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(oldsfp->i8count)); |
1190 | ASSERT(dp->i_d.di_nextents == 0); | ||
1190 | 1191 | ||
1191 | /* | 1192 | /* |
1192 | * Copy the directory into a temporary buffer. | 1193 | * Copy the directory into a temporary buffer. |
1193 | * Then pitch the incore inode data so we can make extents. | 1194 | * Then pitch the incore inode data so we can make extents. |
1194 | */ | 1195 | */ |
1195 | sfp = kmem_alloc(dp->i_df.if_bytes, KM_SLEEP); | 1196 | sfp = kmem_alloc(ifp->if_bytes, KM_SLEEP); |
1196 | memcpy(sfp, oldsfp, dp->i_df.if_bytes); | 1197 | memcpy(sfp, oldsfp, ifp->if_bytes); |
1197 | 1198 | ||
1198 | xfs_idata_realloc(dp, -dp->i_df.if_bytes, XFS_DATA_FORK); | 1199 | xfs_idata_realloc(dp, -ifp->if_bytes, XFS_DATA_FORK); |
1200 | xfs_bmap_local_to_extents_empty(dp, XFS_DATA_FORK); | ||
1199 | dp->i_d.di_size = 0; | 1201 | dp->i_d.di_size = 0; |
1200 | xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); | ||
1201 | 1202 | ||
1202 | /* | 1203 | /* |
1203 | * Add block 0 to the inode. | 1204 | * Add block 0 to the inode. |