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