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.c122
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(
695int /* error */ 696int /* error */
696xfs_dir2_sf_getdents( 697xfs_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