aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_dir2_sf.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_dir2_sf.c')
-rw-r--r--fs/xfs/xfs_dir2_sf.c121
1 files changed, 44 insertions, 77 deletions
diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c
index 38fc4f22b76d..c67d73572905 100644
--- a/fs/xfs/xfs_dir2_sf.c
+++ b/fs/xfs/xfs_dir2_sf.c
@@ -695,19 +695,18 @@ xfs_dir2_sf_create(
695int /* error */ 695int /* error */
696xfs_dir2_sf_getdents( 696xfs_dir2_sf_getdents(
697 xfs_inode_t *dp, /* incore directory inode */ 697 xfs_inode_t *dp, /* incore directory inode */
698 uio_t *uio, /* caller's buffer control */ 698 void *dirent,
699 int *eofp, /* eof reached? (out) */ 699 xfs_off_t *offset,
700 xfs_dirent_t *dbp, /* caller's buffer */ 700 filldir_t filldir)
701 xfs_dir2_put_t put) /* abi's formatting function */
702{ 701{
703 int error; /* error return value */
704 int i; /* shortform entry number */ 702 int i; /* shortform entry number */
705 xfs_mount_t *mp; /* filesystem mount point */ 703 xfs_mount_t *mp; /* filesystem mount point */
706 xfs_dir2_dataptr_t off; /* current entry's offset */ 704 xfs_dir2_dataptr_t off; /* current entry's offset */
707 xfs_dir2_put_args_t p; /* arg package for put rtn */
708 xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ 705 xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */
709 xfs_dir2_sf_t *sfp; /* shortform structure */ 706 xfs_dir2_sf_t *sfp; /* shortform structure */
710 xfs_off_t dir_offset; 707 xfs_dir2_dataptr_t dot_offset;
708 xfs_dir2_dataptr_t dotdot_offset;
709 xfs_ino_t ino;
711 710
712 mp = dp->i_mount; 711 mp = dp->i_mount;
713 712
@@ -720,8 +719,6 @@ xfs_dir2_sf_getdents(
720 return XFS_ERROR(EIO); 719 return XFS_ERROR(EIO);
721 } 720 }
722 721
723 dir_offset = uio->uio_offset;
724
725 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); 722 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
726 ASSERT(dp->i_df.if_u1.if_data != NULL); 723 ASSERT(dp->i_df.if_u1.if_data != NULL);
727 724
@@ -732,108 +729,78 @@ xfs_dir2_sf_getdents(
732 /* 729 /*
733 * If the block number in the offset is out of range, we're done. 730 * If the block number in the offset is out of range, we're done.
734 */ 731 */
735 if (xfs_dir2_dataptr_to_db(mp, dir_offset) > mp->m_dirdatablk) { 732 if (xfs_dir2_dataptr_to_db(mp, *offset) > mp->m_dirdatablk)
736 *eofp = 1;
737 return 0; 733 return 0;
738 }
739 734
740 /* 735 /*
741 * Set up putargs structure. 736 * Precalculate offsets for . and .. as we will always need them.
737 *
738 * XXX(hch): the second argument is sometimes 0 and sometimes
739 * mp->m_dirdatablk.
742 */ 740 */
743 p.dbp = dbp; 741 dot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
744 p.put = put; 742 XFS_DIR2_DATA_DOT_OFFSET);
745 p.uio = uio; 743 dotdot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
744 XFS_DIR2_DATA_DOTDOT_OFFSET);
745
746 /* 746 /*
747 * Put . entry unless we're starting past it. 747 * Put . entry unless we're starting past it.
748 */ 748 */
749 if (dir_offset <= 749 if (*offset <= dot_offset) {
750 xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 750 ino = dp->i_ino;
751 XFS_DIR2_DATA_DOT_OFFSET)) {
752 p.cook = xfs_dir2_db_off_to_dataptr(mp, 0,
753 XFS_DIR2_DATA_DOTDOT_OFFSET);
754 p.ino = dp->i_ino;
755#if XFS_BIG_INUMS 751#if XFS_BIG_INUMS
756 p.ino += mp->m_inoadd; 752 ino += mp->m_inoadd;
757#endif 753#endif
758 p.name = "."; 754 if (filldir(dirent, ".", 1, dotdot_offset, ino, DT_DIR)) {
759 p.namelen = 1; 755 *offset = dot_offset;
760 756 return 0;
761 error = p.put(&p);
762
763 if (!p.done) {
764 uio->uio_offset =
765 xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
766 XFS_DIR2_DATA_DOT_OFFSET);
767 return error;
768 } 757 }
769 } 758 }
770 759
771 /* 760 /*
772 * Put .. entry unless we're starting past it. 761 * Put .. entry unless we're starting past it.
773 */ 762 */
774 if (dir_offset <= 763 if (*offset <= dotdot_offset) {
775 xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 764 off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
776 XFS_DIR2_DATA_DOTDOT_OFFSET)) { 765 XFS_DIR2_DATA_FIRST_OFFSET);
777 p.cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 766 ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent);
778 XFS_DIR2_DATA_FIRST_OFFSET);
779 p.ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent);
780#if XFS_BIG_INUMS 767#if XFS_BIG_INUMS
781 p.ino += mp->m_inoadd; 768 ino += mp->m_inoadd;
782#endif 769#endif
783 p.name = ".."; 770 if (filldir(dirent, "..", 2, off, ino, DT_DIR)) {
784 p.namelen = 2; 771 *offset = dotdot_offset;
785 772 return 0;
786 error = p.put(&p);
787
788 if (!p.done) {
789 uio->uio_offset =
790 xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
791 XFS_DIR2_DATA_DOTDOT_OFFSET);
792 return error;
793 } 773 }
794 } 774 }
795 775
796 /* 776 /*
797 * Loop while there are more entries and put'ing works. 777 * Loop while there are more entries and put'ing works.
798 */ 778 */
799 for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); 779 sfep = xfs_dir2_sf_firstentry(sfp);
800 i < sfp->hdr.count; 780 for (i = 0; i < sfp->hdr.count; i++) {
801 i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) {
802
803 off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 781 off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
804 xfs_dir2_sf_get_offset(sfep)); 782 xfs_dir2_sf_get_offset(sfep));
805 783
806 if (dir_offset > off) 784 if (*offset > off) {
785 sfep = xfs_dir2_sf_nextentry(sfp, sfep);
807 continue; 786 continue;
787 }
808 788
809 p.namelen = sfep->namelen; 789 ino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep));
810
811 p.cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
812 xfs_dir2_sf_get_offset(sfep) +
813 xfs_dir2_data_entsize(p.namelen));
814
815 p.ino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep));
816#if XFS_BIG_INUMS 790#if XFS_BIG_INUMS
817 p.ino += mp->m_inoadd; 791 ino += mp->m_inoadd;
818#endif 792#endif
819 p.name = (char *)sfep->name;
820
821 error = p.put(&p);
822 793
823 if (!p.done) { 794 if (filldir(dirent, sfep->name, sfep->namelen,
824 uio->uio_offset = off; 795 off + xfs_dir2_data_entsize(sfep->namelen),
825 return error; 796 ino, DT_UNKNOWN)) {
797 *offset = off;
798 return 0;
826 } 799 }
800 sfep = xfs_dir2_sf_nextentry(sfp, sfep);
827 } 801 }
828 802
829 /* 803 *offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0);
830 * They all fit.
831 */
832 *eofp = 1;
833
834 uio->uio_offset =
835 xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0);
836
837 return 0; 804 return 0;
838} 805}
839 806