Message ID | 20170909171606.20029-4-robdclark@gmail.com |
---|---|
State | Accepted |
Delegated to: | Tom Rini |
Headers | show |
Series | fs/fat: cleanups + readdir implementation | expand |
On 9 September 2017 at 11:15, Rob Clark <robdclark@gmail.com> wrote: > And drop a whole lot of ugly code! > > Signed-off-by: Rob Clark <robdclark@gmail.com> > Reviewed-by: Łukasz Majewski <lukma@denx.de> > --- > fs/fat/fat.c | 722 +++++++--------------------------------------------------- > include/fat.h | 6 - > 2 files changed, 76 insertions(+), 652 deletions(-) Reviewed-by: Simon Glass <sjg@chromium.org>
On Sat, Sep 09, 2017 at 01:15:54PM -0400, Rob Clark wrote: > And drop a whole lot of ugly code! > > Signed-off-by: Rob Clark <robdclark@gmail.com> > Reviewed-by: Łukasz Majewski <lukma@denx.de> > Reviewed-by: Simon Glass <sjg@chromium.org> Applied to u-boot/master, thanks!
On Fri, Sep 15, 2017 at 9:32 PM, Tom Rini <trini@konsulko.com> wrote: > > On Sat, Sep 09, 2017 at 01:15:54PM -0400, Rob Clark wrote: > > > And drop a whole lot of ugly code! > > > > Signed-off-by: Rob Clark <robdclark@gmail.com> > > Reviewed-by: Łukasz Majewski <lukma@denx.de> > > Reviewed-by: Simon Glass <sjg@chromium.org> > > Applied to u-boot/master, thanks! > According to git bisect, this patch seems to break the booting of am3517_evm It just displays: U-Boot SPL 2017.09-00135-g8eafae2 (Sep 16 2017 - 15:23:16) Trying to boot from MMC1 Then hangs. It does, however the same patch boots just fine on omap3_logic_defconfig which is an OMAP3630/DM3730 board. da850evm_defconfig (OMAP-L138) is also booting just fine. I'm going to investigate it further to see why just 1/3 boards seems impacted. adam > > -- > Tom > > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > https://lists.denx.de/listinfo/u-boot >
On Sat, Sep 16, 2017 at 4:32 PM, Adam Ford <aford173@gmail.com> wrote: > On Fri, Sep 15, 2017 at 9:32 PM, Tom Rini <trini@konsulko.com> wrote: >> >> On Sat, Sep 09, 2017 at 01:15:54PM -0400, Rob Clark wrote: >> >> > And drop a whole lot of ugly code! >> > >> > Signed-off-by: Rob Clark <robdclark@gmail.com> >> > Reviewed-by: Łukasz Majewski <lukma@denx.de> >> > Reviewed-by: Simon Glass <sjg@chromium.org> >> >> Applied to u-boot/master, thanks! >> > > According to git bisect, this patch seems to break the booting of am3517_evm > > It just displays: > > U-Boot SPL 2017.09-00135-g8eafae2 (Sep 16 2017 - 15:23:16) > Trying to boot from MMC1 > > Then hangs. > > It does, however the same patch boots just fine on > omap3_logic_defconfig which is an OMAP3630/DM3730 board. > > da850evm_defconfig (OMAP-L138) is also booting just fine. > > I'm going to investigate it further to see why just 1/3 boards seems impacted. > Tom reported a similar fail.. although I am failing to reproduce it in sandbox w/ a copy of his partition, so maybe it is somehow hw specific? If you could, debug logs w/ https://hastebin.com/raw/fijazebiso applied in before/after case would be useful.. maybe I could spot something from that? BR, -R
On Sat, Sep 16, 2017 at 3:42 PM, Rob Clark <robdclark@gmail.com> wrote: > On Sat, Sep 16, 2017 at 4:32 PM, Adam Ford <aford173@gmail.com> wrote: >> On Fri, Sep 15, 2017 at 9:32 PM, Tom Rini <trini@konsulko.com> wrote: >>> >>> On Sat, Sep 09, 2017 at 01:15:54PM -0400, Rob Clark wrote: >>> >>> > And drop a whole lot of ugly code! >>> > >>> > Signed-off-by: Rob Clark <robdclark@gmail.com> >>> > Reviewed-by: Łukasz Majewski <lukma@denx.de> >>> > Reviewed-by: Simon Glass <sjg@chromium.org> >>> >>> Applied to u-boot/master, thanks! >>> >> >> According to git bisect, this patch seems to break the booting of am3517_evm >> >> It just displays: >> >> U-Boot SPL 2017.09-00135-g8eafae2 (Sep 16 2017 - 15:23:16) >> Trying to boot from MMC1 >> >> Then hangs. >> >> It does, however the same patch boots just fine on >> omap3_logic_defconfig which is an OMAP3630/DM3730 board. >> >> da850evm_defconfig (OMAP-L138) is also booting just fine. >> >> I'm going to investigate it further to see why just 1/3 boards seems impacted. >> > > Tom reported a similar fail.. although I am failing to reproduce it in > sandbox w/ a copy of his partition, so maybe it is somehow hw > specific? If you could, debug logs w/ > https://hastebin.com/raw/fijazebiso applied in before/after case would > be useful.. maybe I could spot something from that? > Adding the debug to master made no difference. No debug messages appeared. Interestingly enough, some junk appeard, and the name of U-Boot name wasn't correctly displayed: **Sș017.09-00178-g08cebee-dirty (Sep 17 2017 - 06:01:07) Trying to boot from MMC1 (hang) Could there a be some memory overflow somewhere? Adding the debug to the last working commit, yielded the following: U-Boot SPL 2017.09-00134-ge71f88d-dirty (Sep 17 2017 - 06:03:28) Trying to boot from MMC1 reading u-boot.img VFAT Support enabled FAT16, fat_sect: 1, fatlength: 200 Rootdir begins at cluster: 536870910, sector: 401, offset: 32200 Data begins at: 417 Sector size: 512, cluster size: 8 FAT read(sect=401, cnt:2), clust_size=8, DIRENTSPERBLOCK=d RootMismatch: |mlo|| Rootvfatname: |u-boot.img| RootName: u-boot.img, start: 0x98, size: 0x83708 Filesize: u bytes u bytes gc - clustnum: 152, startsect: 1633 Size: 538376, got: u reading u-boot.img VFAT Support enabled FAT16, fat_sect: 1, fatlength: 200 Rootdir begins at cluster: 536870910, sector: 401, offset: 32200 Data begins at: 417 Sector size: 512, cluster size: 8 FAT read(sect=401, cnt:2), clust_size=8, DIRENTSPERBLOCK=d RootMismatch: |mlo|| Rootvfatname: |u-boot.img| RootName: u-boot.img, start: 0x98, size: 0x83708 Filesize: u bytes u bytes I truncated it, because after that, it seems to just be showing entries and offsets over and over again. adam > BR, > -R
On Sun, Sep 17, 2017 at 7:08 AM, Adam Ford <aford173@gmail.com> wrote: > On Sat, Sep 16, 2017 at 3:42 PM, Rob Clark <robdclark@gmail.com> wrote: >> On Sat, Sep 16, 2017 at 4:32 PM, Adam Ford <aford173@gmail.com> wrote: >>> On Fri, Sep 15, 2017 at 9:32 PM, Tom Rini <trini@konsulko.com> wrote: >>>> >>>> On Sat, Sep 09, 2017 at 01:15:54PM -0400, Rob Clark wrote: >>>> >>>> > And drop a whole lot of ugly code! >>>> > >>>> > Signed-off-by: Rob Clark <robdclark@gmail.com> >>>> > Reviewed-by: Łukasz Majewski <lukma@denx.de> >>>> > Reviewed-by: Simon Glass <sjg@chromium.org> >>>> >>>> Applied to u-boot/master, thanks! >>>> >>> >>> According to git bisect, this patch seems to break the booting of am3517_evm >>> >>> It just displays: >>> >>> U-Boot SPL 2017.09-00135-g8eafae2 (Sep 16 2017 - 15:23:16) >>> Trying to boot from MMC1 >>> >>> Then hangs. >>> >>> It does, however the same patch boots just fine on >>> omap3_logic_defconfig which is an OMAP3630/DM3730 board. >>> >>> da850evm_defconfig (OMAP-L138) is also booting just fine. >>> >>> I'm going to investigate it further to see why just 1/3 boards seems impacted. >>> >> >> Tom reported a similar fail.. although I am failing to reproduce it in >> sandbox w/ a copy of his partition, so maybe it is somehow hw >> specific? If you could, debug logs w/ >> https://hastebin.com/raw/fijazebiso applied in before/after case would >> be useful.. maybe I could spot something from that? >> > > Adding the debug to master made no difference. No debug messages appeared. > Interestingly enough, some junk appeard, and the name of U-Boot name > wasn't correctly displayed: > > **Sș017.09-00178-g08cebee-dirty (Sep 17 2017 - 06:01:07) > Trying to boot from MMC1 > > (hang) > > Could there a be some memory overflow somewhere? > > Adding the debug to the last working commit, yielded the following: > > U-Boot SPL 2017.09-00134-ge71f88d-dirty (Sep 17 2017 - 06:03:28) > Trying to boot from MMC1 > reading u-boot.img > VFAT Support enabled > FAT16, fat_sect: 1, fatlength: 200 > Rootdir begins at cluster: 536870910, sector: 401, offset: 32200 > Data begins at: 417 > Sector size: 512, cluster size: 8 > FAT read(sect=401, cnt:2), clust_size=8, DIRENTSPERBLOCK=d > RootMismatch: |mlo|| > Rootvfatname: |u-boot.img| > RootName: u-boot.img, start: 0x98, size: 0x83708 > Filesize: u bytes > u bytes > gc - clustnum: 152, startsect: 1633 > Size: 538376, got: u > reading u-boot.img > VFAT Support enabled > FAT16, fat_sect: 1, fatlength: 200 > Rootdir begins at cluster: 536870910, sector: 401, offset: 32200 > Data begins at: 417 > Sector size: 512, cluster size: 8 > FAT read(sect=401, cnt:2), clust_size=8, DIRENTSPERBLOCK=d > RootMismatch: |mlo|| > Rootvfatname: |u-boot.img| > RootName: u-boot.img, start: 0x98, size: 0x83708 > Filesize: u bytes > u bytes > > I truncated it, because after that, it seems to just be showing > entries and offsets over and over again. > Thanks, this first part is what I was looking for. Not sure why DEBUG would make it hang on master. I don't know much about spl, but is there a way you can get it to just do 'ls mmc 1:1' instead of loading u-boot.img? ls should give me the same information about the partition, without so many repeating entries/offsets. Alternately, is it possible to boot w/ old spl image but new u-boot.img to debug this once we get into main u-boot image?? BR, -R
On Sun, Sep 17, 2017 at 8:28 AM, Rob Clark <robdclark@gmail.com> wrote: > On Sun, Sep 17, 2017 at 7:08 AM, Adam Ford <aford173@gmail.com> wrote: >> On Sat, Sep 16, 2017 at 3:42 PM, Rob Clark <robdclark@gmail.com> wrote: >>> On Sat, Sep 16, 2017 at 4:32 PM, Adam Ford <aford173@gmail.com> wrote: >>>> On Fri, Sep 15, 2017 at 9:32 PM, Tom Rini <trini@konsulko.com> wrote: >>>>> >>>>> On Sat, Sep 09, 2017 at 01:15:54PM -0400, Rob Clark wrote: >>>>> >>>>> > And drop a whole lot of ugly code! >>>>> > >>>>> > Signed-off-by: Rob Clark <robdclark@gmail.com> >>>>> > Reviewed-by: Łukasz Majewski <lukma@denx.de> >>>>> > Reviewed-by: Simon Glass <sjg@chromium.org> >>>>> >>>>> Applied to u-boot/master, thanks! >>>>> >>>> >>>> According to git bisect, this patch seems to break the booting of am3517_evm >>>> >>>> It just displays: >>>> >>>> U-Boot SPL 2017.09-00135-g8eafae2 (Sep 16 2017 - 15:23:16) >>>> Trying to boot from MMC1 >>>> >>>> Then hangs. >>>> >>>> It does, however the same patch boots just fine on >>>> omap3_logic_defconfig which is an OMAP3630/DM3730 board. >>>> >>>> da850evm_defconfig (OMAP-L138) is also booting just fine. >>>> >>>> I'm going to investigate it further to see why just 1/3 boards seems impacted. >>>> >>> >>> Tom reported a similar fail.. although I am failing to reproduce it in >>> sandbox w/ a copy of his partition, so maybe it is somehow hw >>> specific? If you could, debug logs w/ >>> https://hastebin.com/raw/fijazebiso applied in before/after case would >>> be useful.. maybe I could spot something from that? >>> >> >> Adding the debug to master made no difference. No debug messages appeared. >> Interestingly enough, some junk appeard, and the name of U-Boot name >> wasn't correctly displayed: >> >> **Sș017.09-00178-g08cebee-dirty (Sep 17 2017 - 06:01:07) >> Trying to boot from MMC1 >> >> (hang) >> >> Could there a be some memory overflow somewhere? >> >> Adding the debug to the last working commit, yielded the following: >> >> U-Boot SPL 2017.09-00134-ge71f88d-dirty (Sep 17 2017 - 06:03:28) >> Trying to boot from MMC1 >> reading u-boot.img >> VFAT Support enabled >> FAT16, fat_sect: 1, fatlength: 200 >> Rootdir begins at cluster: 536870910, sector: 401, offset: 32200 >> Data begins at: 417 >> Sector size: 512, cluster size: 8 >> FAT read(sect=401, cnt:2), clust_size=8, DIRENTSPERBLOCK=d >> RootMismatch: |mlo|| >> Rootvfatname: |u-boot.img| >> RootName: u-boot.img, start: 0x98, size: 0x83708 >> Filesize: u bytes >> u bytes >> gc - clustnum: 152, startsect: 1633 >> Size: 538376, got: u >> reading u-boot.img >> VFAT Support enabled >> FAT16, fat_sect: 1, fatlength: 200 >> Rootdir begins at cluster: 536870910, sector: 401, offset: 32200 >> Data begins at: 417 >> Sector size: 512, cluster size: 8 >> FAT read(sect=401, cnt:2), clust_size=8, DIRENTSPERBLOCK=d >> RootMismatch: |mlo|| >> Rootvfatname: |u-boot.img| >> RootName: u-boot.img, start: 0x98, size: 0x83708 >> Filesize: u bytes >> u bytes >> >> I truncated it, because after that, it seems to just be showing >> entries and offsets over and over again. >> > > Thanks, this first part is what I was looking for. > > Not sure why DEBUG would make it hang on master. I don't know much > about spl, but is there a way you can get it to just do 'ls mmc 1:1' > instead of loading u-boot.img? ls should give me the same information > about the partition, without so many repeating entries/offsets. > Alternately, is it possible to boot w/ old spl image but new > u-boot.img to debug this once we get into main u-boot image?? I suppose another benefit if it is possible to use old spl and new u-boot.img is the presumably u-boot.img isn't using TINY_PRINTF so the debug prints about the partition parameters would be more complete.. BR, -R
On Sun, Sep 17, 2017 at 7:08 AM, Adam Ford <aford173@gmail.com> wrote: > > Adding the debug to master made no difference. No debug messages appeared. > Interestingly enough, some junk appeard, and the name of U-Boot name > wasn't correctly displayed: > > **Sș017.09-00178-g08cebee-dirty (Sep 17 2017 - 06:01:07) > Trying to boot from MMC1 > > (hang) > hmm, one thing I noticed in doc/README.SPL: "When building SPL with DEBUG set you may also need to set CONFIG_PANIC_HANG as in most cases do_reset is not defined within SPL." not sure if that would help. Also, it has a section about estimating stack usage.. not sure if this implies that stack size is constrained in spl? If so, maybe that is related. The new directory iterators do move the buffer for current block of dir_entry's to the stack. Reducing CONFIG_FS_FAT_MAX_CLUSTSIZE might help. BR, -R
On Sun, Sep 17, 2017 at 08:53:23AM -0400, Rob Clark wrote: > On Sun, Sep 17, 2017 at 7:08 AM, Adam Ford <aford173@gmail.com> wrote: > > > > Adding the debug to master made no difference. No debug messages appeared. > > Interestingly enough, some junk appeard, and the name of U-Boot name > > wasn't correctly displayed: > > > > **Sș017.09-00178-g08cebee-dirty (Sep 17 2017 - 06:01:07) > > Trying to boot from MMC1 > > > > (hang) > > > > hmm, one thing I noticed in doc/README.SPL: > > "When building SPL with DEBUG set you may also need to set CONFIG_PANIC_HANG > as in most cases do_reset is not defined within SPL." > > not sure if that would help. > > Also, it has a section about estimating stack usage.. not sure if this > implies that stack size is constrained in spl? If so, maybe that is > related. The new directory iterators do move the buffer for current > block of dir_entry's to the stack. Reducing > CONFIG_FS_FAT_MAX_CLUSTSIZE might help. Yes, in SPL we don't require stack being in SDRAM and unless SPL_STACK_R is set we have a very limited stack available. And that looks to be the common thread between functional and non-functional platforms. In the case of what Adam and I both have, we could move to SPL_STACK_R easily enough. What needs to be done next 'tho would be to see if making SPL_FAT_SUPPORT depend on SPL_STACK_R, migrating the various TI platforms (and possibly others) that could butdon't use SPL_STACK_R, and seeing if we have platforms that have now lost FAT support. Or, how hard would it be to make that code not use the stack so much?
On Sun, Sep 17, 2017 at 7:53 AM, Rob Clark <robdclark@gmail.com> wrote: > On Sun, Sep 17, 2017 at 7:08 AM, Adam Ford <aford173@gmail.com> wrote: >> >> Adding the debug to master made no difference. No debug messages appeared. >> Interestingly enough, some junk appeard, and the name of U-Boot name >> wasn't correctly displayed: >> >> **Sș017.09-00178-g08cebee-dirty (Sep 17 2017 - 06:01:07) >> Trying to boot from MMC1 >> >> (hang) >> > With the TINY_PRINTF disabled (except in SPL), the log looks better: Trying to boot from MMC1 reading u-boot.img VFAT Support enabled FAT16, fat_sect: 1, fatlength: 200 Rootdir begins at cluster: 536870910, sector: 401, offset: 32200 Data begins at: 417 Sector size: 512, cluster size: 8 FAT read(sect=401, cnt:2), clust_size=8, DIRENTSPERBLOCK=16 RootMismatch: |mlo|| Rootvfatname: |u-boot.img| RootName: u-boot.img, start: 0x12, size: 0x83708 Filesize: 538376 bytes 64 bytes gc - clustnum: 18, startsect: 561 Size: 538376, got: 64 reading u-boot.img VFAT Support enabled FAT16, fat_sect: 1, fatlength: 200 Rootdir begins at cluster: 536870910, sector: 401, offset: 32200 Data begins at: 417 Sector size: 512, cluster size: 8 FAT read(sect=401, cnt:2), clust_size=8, DIRENTSPERBLOCK=16 RootMismatch: |mlo|| Rootvfatname: |u-boot.img| RootName: u-boot.img, start: 0x12, size: 0x83708 Filesize: 538376 bytes > hmm, one thing I noticed in doc/README.SPL: > > "When building SPL with DEBUG set you may also need to set CONFIG_PANIC_HANG > as in most cases do_reset is not defined within SPL." > > not sure if that would help. > I did try your experiment with keeping the working SPL and using the newer u-boot.img file and that worked, so I am guessing it's probably related to tight memory in SPL. I looked up the mapping in doc/SPL/README.omap3 and it shows: 0x40200800 - 0x4020BBFF: Area for SPL text, data and rodata 0x4020E000 - 0x4020FFFC: Area for the SPL stack. 0x80000000 - 0x8007FFFF: Area for the SPL BSS. 0x80100000: CONFIG_SYS_TEXT_BASE of U-Boot 0x80208000 - 0x80307FFF: malloc() pool available to SPL. For this board, CONFIG_SYS_SPL_MALLOC_SIZE is set to 0x100000 I don't know if any of this is helpful information to you or not. > Also, it has a section about estimating stack usage.. not sure if this > implies that stack size is constrained in spl? If so, maybe that is > related. The new directory iterators do move the buffer for current > block of dir_entry's to the stack. Reducing > CONFIG_FS_FAT_MAX_CLUSTSIZE might help. Any recommendations on how small this can go and still operate reliably? I don't want to just arbitrarily choose something. > > BR, > -R adam
On Sun, Sep 17, 2017 at 9:42 AM, Adam Ford <aford173@gmail.com> wrote: > On Sun, Sep 17, 2017 at 7:53 AM, Rob Clark <robdclark@gmail.com> wrote: >> On Sun, Sep 17, 2017 at 7:08 AM, Adam Ford <aford173@gmail.com> wrote: >>> >>> Adding the debug to master made no difference. No debug messages appeared. >>> Interestingly enough, some junk appeard, and the name of U-Boot name >>> wasn't correctly displayed: >>> >>> **Sș017.09-00178-g08cebee-dirty (Sep 17 2017 - 06:01:07) >>> Trying to boot from MMC1 >>> >>> (hang) >>> >> > > With the TINY_PRINTF disabled (except in SPL), the log looks better: > > Trying to boot from MMC1 > reading u-boot.img > VFAT Support enabled > FAT16, fat_sect: 1, fatlength: 200 > Rootdir begins at cluster: 536870910, sector: 401, offset: 32200 > Data begins at: 417 > Sector size: 512, cluster size: 8 > FAT read(sect=401, cnt:2), clust_size=8, DIRENTSPERBLOCK=16 > RootMismatch: |mlo|| > Rootvfatname: |u-boot.img| > RootName: u-boot.img, start: 0x12, size: 0x83708 > Filesize: 538376 bytes > 64 bytes > gc - clustnum: 18, startsect: 561 > Size: 538376, got: 64 > reading u-boot.img > VFAT Support enabled > FAT16, fat_sect: 1, fatlength: 200 > Rootdir begins at cluster: 536870910, sector: 401, offset: 32200 > Data begins at: 417 > Sector size: 512, cluster size: 8 > FAT read(sect=401, cnt:2), clust_size=8, DIRENTSPERBLOCK=16 > RootMismatch: |mlo|| > Rootvfatname: |u-boot.img| > RootName: u-boot.img, start: 0x12, size: 0x83708 > Filesize: 538376 bytes > > > >> hmm, one thing I noticed in doc/README.SPL: >> >> "When building SPL with DEBUG set you may also need to set CONFIG_PANIC_HANG >> as in most cases do_reset is not defined within SPL." >> >> not sure if that would help. >> > > I did try your experiment with keeping the working SPL and using the > newer u-boot.img file and that worked, so I am guessing it's probably > related to tight memory in SPL. > I looked up the mapping in doc/SPL/README.omap3 and it shows: > > 0x40200800 - 0x4020BBFF: Area for SPL text, data and rodata > 0x4020E000 - 0x4020FFFC: Area for the SPL stack. > 0x80000000 - 0x8007FFFF: Area for the SPL BSS. > 0x80100000: CONFIG_SYS_TEXT_BASE of U-Boot > 0x80208000 - 0x80307FFF: malloc() pool available to SPL. > > For this board, CONFIG_SYS_SPL_MALLOC_SIZE is set to 0x100000 > > I don't know if any of this is helpful information to you or not. I think we narrowed it down to stack usage.. Tom tested the "please test" patch I just sent and it works for him. If reducing SPL_MALLOC_SIZE increases available stack size, that might also work. But I think for next release we can just go with my patch that moves itrblock off the stack. >> Also, it has a section about estimating stack usage.. not sure if this >> implies that stack size is constrained in spl? If so, maybe that is >> related. The new directory iterators do move the buffer for current >> block of dir_entry's to the stack. Reducing >> CONFIG_FS_FAT_MAX_CLUSTSIZE might help. > > Any recommendations on how small this can go and still operate > reliably? I don't want to just arbitrarily choose something. Sector size: 512, cluster size: 8 FAT read(sect=401, cnt:2), clust_size=8, DIRENTSPERBLOCK=16 So I think 512 * 8 = 4096 would work for your filesys.. what I'm not entirely sure is what range of sector sizes and cluster sizes are possible. 64k seems *way* too much. Maybe in the end I should switch to malloc() so we can allocate just what is needed. I'll give it some thought for my next batch of fs/fat work.. but suggestions welcome. BR, -R
On Sun, Sep 17, 2017 at 8:50 AM, Rob Clark <robdclark@gmail.com> wrote: > On Sun, Sep 17, 2017 at 9:42 AM, Adam Ford <aford173@gmail.com> wrote: >> On Sun, Sep 17, 2017 at 7:53 AM, Rob Clark <robdclark@gmail.com> wrote: >>> On Sun, Sep 17, 2017 at 7:08 AM, Adam Ford <aford173@gmail.com> wrote: >>>> >>>> Adding the debug to master made no difference. No debug messages appeared. >>>> Interestingly enough, some junk appeard, and the name of U-Boot name >>>> wasn't correctly displayed: >>>> >>>> **Sș017.09-00178-g08cebee-dirty (Sep 17 2017 - 06:01:07) >>>> Trying to boot from MMC1 >>>> >>>> (hang) >>>> >>> >> >> With the TINY_PRINTF disabled (except in SPL), the log looks better: >> >> Trying to boot from MMC1 >> reading u-boot.img >> VFAT Support enabled >> FAT16, fat_sect: 1, fatlength: 200 >> Rootdir begins at cluster: 536870910, sector: 401, offset: 32200 >> Data begins at: 417 >> Sector size: 512, cluster size: 8 >> FAT read(sect=401, cnt:2), clust_size=8, DIRENTSPERBLOCK=16 >> RootMismatch: |mlo|| >> Rootvfatname: |u-boot.img| >> RootName: u-boot.img, start: 0x12, size: 0x83708 >> Filesize: 538376 bytes >> 64 bytes >> gc - clustnum: 18, startsect: 561 >> Size: 538376, got: 64 >> reading u-boot.img >> VFAT Support enabled >> FAT16, fat_sect: 1, fatlength: 200 >> Rootdir begins at cluster: 536870910, sector: 401, offset: 32200 >> Data begins at: 417 >> Sector size: 512, cluster size: 8 >> FAT read(sect=401, cnt:2), clust_size=8, DIRENTSPERBLOCK=16 >> RootMismatch: |mlo|| >> Rootvfatname: |u-boot.img| >> RootName: u-boot.img, start: 0x12, size: 0x83708 >> Filesize: 538376 bytes >> >> >> >>> hmm, one thing I noticed in doc/README.SPL: >>> >>> "When building SPL with DEBUG set you may also need to set CONFIG_PANIC_HANG >>> as in most cases do_reset is not defined within SPL." >>> >>> not sure if that would help. >>> >> >> I did try your experiment with keeping the working SPL and using the >> newer u-boot.img file and that worked, so I am guessing it's probably >> related to tight memory in SPL. >> I looked up the mapping in doc/SPL/README.omap3 and it shows: >> >> 0x40200800 - 0x4020BBFF: Area for SPL text, data and rodata >> 0x4020E000 - 0x4020FFFC: Area for the SPL stack. >> 0x80000000 - 0x8007FFFF: Area for the SPL BSS. >> 0x80100000: CONFIG_SYS_TEXT_BASE of U-Boot >> 0x80208000 - 0x80307FFF: malloc() pool available to SPL. >> >> For this board, CONFIG_SYS_SPL_MALLOC_SIZE is set to 0x100000 >> >> I don't know if any of this is helpful information to you or not. > > I think we narrowed it down to stack usage.. Tom tested the "please > test" patch I just sent and it works for him. > > If reducing SPL_MALLOC_SIZE increases available stack size, that might > also work. But I think for next release we can just go with my patch > that moves itrblock off the stack. > >>> Also, it has a section about estimating stack usage.. not sure if this >>> implies that stack size is constrained in spl? If so, maybe that is >>> related. The new directory iterators do move the buffer for current >>> block of dir_entry's to the stack. Reducing >>> CONFIG_FS_FAT_MAX_CLUSTSIZE might help. >> >> Any recommendations on how small this can go and still operate >> reliably? I don't want to just arbitrarily choose something. > > > Sector size: 512, cluster size: 8 > FAT read(sect=401, cnt:2), clust_size=8, DIRENTSPERBLOCK=16 > > So I think 512 * 8 = 4096 would work for your filesys.. what I'm not > entirely sure is what range of sector sizes and cluster sizes are > possible. 64k seems *way* too much. Maybe in the end I should switch > to malloc() so we can allocate just what is needed. > > I'll give it some thought for my next batch of fs/fat work.. but > suggestions welcome. > When I wrote that, I didn't see either Tom's comments or you updated patch yet, but you can go ahead and add my tested-by because I'm satisfied with that. adam > BR, > -R
diff --git a/fs/fat/fat.c b/fs/fat/fat.c index ee2bbe38f1..bbba7947ee 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -119,22 +119,6 @@ int fat_register_device(struct blk_desc *dev_desc, int part_no) } /* - * Get the first occurence of a directory delimiter ('/' or '\') in a string. - * Return index into string if found, -1 otherwise. - */ -static int dirdelim(char *str) -{ - char *start = str; - - while (*str != '\0') { - if (ISDIRDELIM(*str)) - return str - start; - str++; - } - return -1; -} - -/* * Extract zero terminated short name from a directory entry. */ static void get_name(dir_entry *dirent, char *s_name) @@ -468,95 +452,6 @@ static int slot2str(dir_slot *slotptr, char *l_name, int *idx) return 0; } -/* - * Extract the full long filename starting at 'retdent' (which is really - * a slot) into 'l_name'. If successful also copy the real directory entry - * into 'retdent' - * Return 0 on success, -1 otherwise. - */ -static int -get_vfatname(fsdata *mydata, int curclust, __u8 *cluster, - dir_entry *retdent, char *l_name) -{ - dir_entry *realdent; - dir_slot *slotptr = (dir_slot *)retdent; - __u8 *buflimit = cluster + mydata->sect_size * ((curclust == 0) ? - PREFETCH_BLOCKS : - mydata->clust_size); - __u8 counter = (slotptr->id & ~LAST_LONG_ENTRY_MASK) & 0xff; - int idx = 0; - - if (counter > VFAT_MAXSEQ) { - debug("Error: VFAT name is too long\n"); - return -1; - } - - while ((__u8 *)slotptr < buflimit) { - if (counter == 0) - break; - if (((slotptr->id & ~LAST_LONG_ENTRY_MASK) & 0xff) != counter) - return -1; - slotptr++; - counter--; - } - - if ((__u8 *)slotptr >= buflimit) { - dir_slot *slotptr2; - - if (curclust == 0) - return -1; - curclust = get_fatent(mydata, curclust); - if (CHECK_CLUST(curclust, mydata->fatsize)) { - debug("curclust: 0x%x\n", curclust); - printf("Invalid FAT entry\n"); - return -1; - } - - if (get_cluster(mydata, curclust, get_contents_vfatname_block, - mydata->clust_size * mydata->sect_size) != 0) { - debug("Error: reading directory block\n"); - return -1; - } - - slotptr2 = (dir_slot *)get_contents_vfatname_block; - while (counter > 0) { - if (((slotptr2->id & ~LAST_LONG_ENTRY_MASK) - & 0xff) != counter) - return -1; - slotptr2++; - counter--; - } - - /* Save the real directory entry */ - realdent = (dir_entry *)slotptr2; - while ((__u8 *)slotptr2 > get_contents_vfatname_block) { - slotptr2--; - slot2str(slotptr2, l_name, &idx); - } - } else { - /* Save the real directory entry */ - realdent = (dir_entry *)slotptr; - } - - do { - slotptr--; - if (slot2str(slotptr, l_name, &idx)) - break; - } while (!(slotptr->id & LAST_LONG_ENTRY_MASK)); - - l_name[idx] = '\0'; - if (*l_name == DELETED_FLAG) - *l_name = '\0'; - else if (*l_name == aRING) - *l_name = DELETED_FLAG; - downcase(l_name); - - /* Return the real directory entry */ - memcpy(retdent, realdent, sizeof(dir_entry)); - - return 0; -} - /* Calculate short name checksum */ static __u8 mkcksum(const char name[8], const char ext[3]) { @@ -573,169 +468,13 @@ static __u8 mkcksum(const char name[8], const char ext[3]) } /* - * Get the directory entry associated with 'filename' from the directory - * starting at 'startsect' + * TODO these should go away once fat_write is reworked to use the + * directory iterator */ __u8 get_dentfromdir_block[MAX_CLUSTSIZE] __aligned(ARCH_DMA_MINALIGN); - -static dir_entry *get_dentfromdir(fsdata *mydata, int startsect, - char *filename, dir_entry *retdent, - int dols) -{ - __u16 prevcksum = 0xffff; - __u32 curclust = START(retdent); - int files = 0, dirs = 0; - - debug("get_dentfromdir: %s\n", filename); - - while (1) { - dir_entry *dentptr; - - int i; - - if (get_cluster(mydata, curclust, get_dentfromdir_block, - mydata->clust_size * mydata->sect_size) != 0) { - debug("Error: reading directory block\n"); - return NULL; - } - - dentptr = (dir_entry *)get_dentfromdir_block; - - for (i = 0; i < DIRENTSPERCLUST; i++) { - char s_name[14], l_name[VFAT_MAXLEN_BYTES]; - - l_name[0] = '\0'; - if (dentptr->name[0] == DELETED_FLAG) { - dentptr++; - continue; - } - if ((dentptr->attr & ATTR_VOLUME)) { - if (vfat_enabled && - (dentptr->attr & ATTR_VFAT) == ATTR_VFAT && - (dentptr->name[0] & LAST_LONG_ENTRY_MASK)) { - prevcksum = ((dir_slot *)dentptr)->alias_checksum; - get_vfatname(mydata, curclust, - get_dentfromdir_block, - dentptr, l_name); - if (dols) { - int isdir; - char dirc; - int doit = 0; - - isdir = (dentptr->attr & ATTR_DIR); - - if (isdir) { - dirs++; - dirc = '/'; - doit = 1; - } else { - dirc = ' '; - if (l_name[0] != 0) { - files++; - doit = 1; - } - } - if (doit) { - if (dirc == ' ') { - printf(" %8u %s%c\n", - FAT2CPU32(dentptr->size), - l_name, - dirc); - } else { - printf(" %s%c\n", - l_name, - dirc); - } - } - dentptr++; - continue; - } - debug("vfatname: |%s|\n", l_name); - } else { - /* Volume label or VFAT entry */ - dentptr++; - continue; - } - } - if (dentptr->name[0] == 0) { - if (dols) { - printf("\n%d file(s), %d dir(s)\n\n", - files, dirs); - } - debug("Dentname == NULL - %d\n", i); - return NULL; - } - if (vfat_enabled) { - __u8 csum = mkcksum(dentptr->name, dentptr->ext); - if (dols && csum == prevcksum) { - prevcksum = 0xffff; - dentptr++; - continue; - } - } - - get_name(dentptr, s_name); - if (dols) { - int isdir = (dentptr->attr & ATTR_DIR); - char dirc; - int doit = 0; - - if (isdir) { - dirs++; - dirc = '/'; - doit = 1; - } else { - dirc = ' '; - if (s_name[0] != 0) { - files++; - doit = 1; - } - } - - if (doit) { - if (dirc == ' ') { - printf(" %8u %s%c\n", - FAT2CPU32(dentptr->size), - s_name, dirc); - } else { - printf(" %s%c\n", - s_name, dirc); - } - } - - dentptr++; - continue; - } - - if (strcmp(filename, s_name) - && strcmp(filename, l_name)) { - debug("Mismatch: |%s|%s|\n", s_name, l_name); - dentptr++; - continue; - } - - memcpy(retdent, dentptr, sizeof(dir_entry)); - - debug("DentName: %s", s_name); - debug(", start: 0x%x", START(dentptr)); - debug(", size: 0x%x %s\n", - FAT2CPU32(dentptr->size), - (dentptr->attr & ATTR_DIR) ? "(DIR)" : ""); - - return retdent; - } - - curclust = get_fatent(mydata, curclust); - if (CHECK_CLUST(curclust, mydata->fatsize)) { - debug("curclust: 0x%x\n", curclust); - printf("Invalid FAT entry\n"); - return NULL; - } - } - - return NULL; -} +__u8 do_fat_read_at_block[MAX_CLUSTSIZE] + __aligned(ARCH_DMA_MINALIGN); /* * Read boot sector and volume info from a FAT filesystem @@ -879,374 +618,6 @@ static int get_fs_info(fsdata *mydata) return 0; } -__u8 do_fat_read_at_block[MAX_CLUSTSIZE] - __aligned(ARCH_DMA_MINALIGN); - -int do_fat_read_at(const char *filename, loff_t pos, void *buffer, - loff_t maxsize, int dols, int dogetsize, loff_t *size) -{ - char fnamecopy[2048]; - fsdata datablock; - fsdata *mydata = &datablock; - dir_entry *dentptr = NULL; - __u16 prevcksum = 0xffff; - char *subname = ""; - __u32 cursect; - int idx, isdir = 0; - int files = 0, dirs = 0; - int ret = -1; - int firsttime; - __u32 root_cluster = 0; - __u32 read_blk; - int rootdir_size = 0; - int buffer_blk_cnt; - int do_read; - __u8 *dir_ptr; - - if (get_fs_info(mydata)) - return -1; - - cursect = mydata->rootdir_sect; - - /* "cwd" is always the root... */ - while (ISDIRDELIM(*filename)) - filename++; - - /* Make a copy of the filename and convert it to lowercase */ - strcpy(fnamecopy, filename); - downcase(fnamecopy); - -root_reparse: - if (*fnamecopy == '\0') { - if (!dols) - goto exit; - - dols = LS_ROOT; - } else if ((idx = dirdelim(fnamecopy)) >= 0) { - isdir = 1; - fnamecopy[idx] = '\0'; - subname = fnamecopy + idx + 1; - - /* Handle multiple delimiters */ - while (ISDIRDELIM(*subname)) - subname++; - } else if (dols) { - isdir = 1; - } - - buffer_blk_cnt = 0; - firsttime = 1; - while (1) { - int i; - - if (mydata->fatsize == 32 || firsttime) { - dir_ptr = do_fat_read_at_block; - firsttime = 0; - } else { - /** - * FAT16 sector buffer modification: - * Each loop, the second buffered block is moved to - * the buffer begin, and two next sectors are read - * next to the previously moved one. So the sector - * buffer keeps always 3 sectors for fat16. - * And the current sector is the buffer second sector - * beside the "firsttime" read, when it is the first one. - * - * PREFETCH_BLOCKS is 2 for FAT16 == loop[0:1] - * n = computed root dir sector - * loop | cursect-1 | cursect | cursect+1 | - * 0 | sector n+0 | sector n+1 | none | - * 1 | none | sector n+0 | sector n+1 | - * 0 | sector n+1 | sector n+2 | sector n+3 | - * 1 | sector n+3 | ... - */ - dir_ptr = (do_fat_read_at_block + mydata->sect_size); - memcpy(do_fat_read_at_block, dir_ptr, mydata->sect_size); - } - - do_read = 1; - - if (mydata->fatsize == 32 && buffer_blk_cnt) - do_read = 0; - - if (do_read) { - read_blk = (mydata->fatsize == 32) ? - mydata->clust_size : PREFETCH_BLOCKS; - - debug("FAT read(sect=%d, cnt:%d), clust_size=%d, DIRENTSPERBLOCK=%zd\n", - cursect, read_blk, mydata->clust_size, DIRENTSPERBLOCK); - - if (disk_read(cursect, read_blk, dir_ptr) < 0) { - debug("Error: reading rootdir block\n"); - goto exit; - } - - dentptr = (dir_entry *)dir_ptr; - } - - for (i = 0; i < DIRENTSPERBLOCK; i++) { - char s_name[14], l_name[VFAT_MAXLEN_BYTES]; - __u8 csum; - - l_name[0] = '\0'; - if (dentptr->name[0] == DELETED_FLAG) { - dentptr++; - continue; - } - - if (vfat_enabled) - csum = mkcksum(dentptr->name, dentptr->ext); - - if (dentptr->attr & ATTR_VOLUME) { - if (vfat_enabled && - (dentptr->attr & ATTR_VFAT) == ATTR_VFAT && - (dentptr->name[0] & LAST_LONG_ENTRY_MASK)) { - prevcksum = - ((dir_slot *)dentptr)->alias_checksum; - - get_vfatname(mydata, - root_cluster, - dir_ptr, - dentptr, l_name); - - if (dols == LS_ROOT) { - char dirc; - int doit = 0; - int isdir = - (dentptr->attr & ATTR_DIR); - - if (isdir) { - dirs++; - dirc = '/'; - doit = 1; - } else { - dirc = ' '; - if (l_name[0] != 0) { - files++; - doit = 1; - } - } - if (doit) { - if (dirc == ' ') { - printf(" %8u %s%c\n", - FAT2CPU32(dentptr->size), - l_name, - dirc); - } else { - printf(" %s%c\n", - l_name, - dirc); - } - } - dentptr++; - continue; - } - debug("Rootvfatname: |%s|\n", - l_name); - } else { - /* Volume label or VFAT entry */ - dentptr++; - continue; - } - } else if (dentptr->name[0] == 0) { - debug("RootDentname == NULL - %d\n", i); - if (dols == LS_ROOT) { - printf("\n%d file(s), %d dir(s)\n\n", - files, dirs); - ret = 0; - } - goto exit; - } - else if (vfat_enabled && - dols == LS_ROOT && csum == prevcksum) { - prevcksum = 0xffff; - dentptr++; - continue; - } - - get_name(dentptr, s_name); - - if (dols == LS_ROOT) { - int isdir = (dentptr->attr & ATTR_DIR); - char dirc; - int doit = 0; - - if (isdir) { - dirc = '/'; - if (s_name[0] != 0) { - dirs++; - doit = 1; - } - } else { - dirc = ' '; - if (s_name[0] != 0) { - files++; - doit = 1; - } - } - if (doit) { - if (dirc == ' ') { - printf(" %8u %s%c\n", - FAT2CPU32(dentptr->size), - s_name, dirc); - } else { - printf(" %s%c\n", - s_name, dirc); - } - } - dentptr++; - continue; - } - - if (strcmp(fnamecopy, s_name) - && strcmp(fnamecopy, l_name)) { - debug("RootMismatch: |%s|%s|\n", s_name, - l_name); - dentptr++; - continue; - } - - if (isdir && !(dentptr->attr & ATTR_DIR)) - goto exit; - - debug("RootName: %s", s_name); - debug(", start: 0x%x", START(dentptr)); - debug(", size: 0x%x %s\n", - FAT2CPU32(dentptr->size), - isdir ? "(DIR)" : ""); - - goto rootdir_done; /* We got a match */ - } - debug("END LOOP: buffer_blk_cnt=%d clust_size=%d\n", buffer_blk_cnt, - mydata->clust_size); - - /* - * On FAT32 we must fetch the FAT entries for the next - * root directory clusters when a cluster has been - * completely processed. - */ - ++buffer_blk_cnt; - int rootdir_end = 0; - if (mydata->fatsize == 32) { - if (buffer_blk_cnt == mydata->clust_size) { - int nxtsect = 0; - int nxt_clust = 0; - - nxt_clust = get_fatent(mydata, root_cluster); - rootdir_end = CHECK_CLUST(nxt_clust, 32); - - nxtsect = mydata->data_begin + - (nxt_clust * mydata->clust_size); - - root_cluster = nxt_clust; - - cursect = nxtsect; - buffer_blk_cnt = 0; - } - } else { - if (buffer_blk_cnt == PREFETCH_BLOCKS) - buffer_blk_cnt = 0; - - rootdir_end = (++cursect - mydata->rootdir_sect >= - rootdir_size); - } - - /* If end of rootdir reached */ - if (rootdir_end) { - if (dols == LS_ROOT) { - printf("\n%d file(s), %d dir(s)\n\n", - files, dirs); - *size = 0; - } - goto exit; - } - } -rootdir_done: - - firsttime = 1; - - while (isdir) { - int startsect = mydata->data_begin - + START(dentptr) * mydata->clust_size; - dir_entry dent; - char *nextname = NULL; - - dent = *dentptr; - dentptr = &dent; - - idx = dirdelim(subname); - - if (idx >= 0) { - subname[idx] = '\0'; - nextname = subname + idx + 1; - /* Handle multiple delimiters */ - while (ISDIRDELIM(*nextname)) - nextname++; - if (dols && *nextname == '\0') - firsttime = 0; - } else { - if (dols && firsttime) { - firsttime = 0; - } else { - isdir = 0; - } - } - - if (get_dentfromdir(mydata, startsect, subname, dentptr, - isdir ? 0 : dols) == NULL) { - if (dols && !isdir) - *size = 0; - goto exit; - } - - if (isdir && !(dentptr->attr & ATTR_DIR)) - goto exit; - - /* - * If we are looking for a directory, and found a directory - * type entry, and the entry is for the root directory (as - * denoted by a cluster number of 0), jump back to the start - * of the function, since at least on FAT12/16, the root dir - * lives in a hard-coded location and needs special handling - * to parse, rather than simply following the cluster linked - * list in the FAT, like other directories. - */ - if (isdir && (dentptr->attr & ATTR_DIR) && !START(dentptr)) { - /* - * Modify the filename to remove the prefix that gets - * back to the root directory, so the initial root dir - * parsing code can continue from where we are without - * confusion. - */ - strcpy(fnamecopy, nextname ?: ""); - /* - * Set up state the same way as the function does when - * first started. This is required for the root dir - * parsing code operates in its expected environment. - */ - subname = ""; - cursect = mydata->rootdir_sect; - isdir = 0; - goto root_reparse; - } - - if (idx >= 0) - subname = nextname; - } - - if (dogetsize) { - *size = FAT2CPU32(dentptr->size); - ret = 0; - } else { - ret = get_contents(mydata, dentptr, pos, buffer, maxsize, size); - } - debug("Size: %u, got: %llu\n", FAT2CPU32(dentptr->size), *size); - -exit: - free(mydata->fatbuf); - return ret; -} - /* * Directory iterator, to simplify filesystem traversal @@ -1595,12 +966,6 @@ static int fat_itr_resolve(fat_itr *itr, const char *path, unsigned type) return -ENOENT; } -int do_fat_read(const char *filename, void *buffer, loff_t maxsize, int dols, - loff_t *actread) -{ - return do_fat_read_at(filename, 0, buffer, maxsize, dols, 0, actread); -} - int file_fat_detectfs(void) { boot_sector bs; @@ -1665,31 +1030,96 @@ int file_fat_detectfs(void) int file_fat_ls(const char *dir) { - loff_t size; + fsdata fsdata; + fat_itr itrblock, *itr = &itrblock; + int files = 0, dirs = 0; + int ret; + + ret = fat_itr_root(itr, &fsdata); + if (ret) + return ret; + + ret = fat_itr_resolve(itr, dir, TYPE_DIR); + if (ret) + return ret; + + while (fat_itr_next(itr)) { + if (fat_itr_isdir(itr)) { + printf(" %s/\n", itr->name); + dirs++; + } else { + printf(" %8u %s\n", + FAT2CPU32(itr->dent->size), + itr->name); + files++; + } + } - return do_fat_read(dir, NULL, 0, LS_YES, &size); + printf("\n%d file(s), %d dir(s)\n\n", files, dirs); + + return 0; } int fat_exists(const char *filename) { + fsdata fsdata; + fat_itr itrblock, *itr = &itrblock; int ret; - loff_t size; - ret = do_fat_read_at(filename, 0, NULL, 0, LS_NO, 1, &size); + ret = fat_itr_root(itr, &fsdata); + if (ret) + return 0; + + ret = fat_itr_resolve(itr, filename, TYPE_ANY); return ret == 0; } int fat_size(const char *filename, loff_t *size) { - return do_fat_read_at(filename, 0, NULL, 0, LS_NO, 1, size); + fsdata fsdata; + fat_itr itrblock, *itr = &itrblock; + int ret; + + ret = fat_itr_root(itr, &fsdata); + if (ret) + return ret; + + ret = fat_itr_resolve(itr, filename, TYPE_FILE); + if (ret) { + /* + * Directories don't have size, but fs_size() is not + * expected to fail if passed a directory path: + */ + fat_itr_root(itr, &fsdata); + if (!fat_itr_resolve(itr, filename, TYPE_DIR)) { + *size = 0; + return 0; + } + return ret; + } + + *size = FAT2CPU32(itr->dent->size); + + return 0; } int file_fat_read_at(const char *filename, loff_t pos, void *buffer, loff_t maxsize, loff_t *actread) { + fsdata fsdata; + fat_itr itrblock, *itr = &itrblock; + int ret; + + ret = fat_itr_root(itr, &fsdata); + if (ret) + return ret; + + ret = fat_itr_resolve(itr, filename, TYPE_FILE); + if (ret) + return ret; + printf("reading %s\n", filename); - return do_fat_read_at(filename, pos, buffer, maxsize, LS_NO, 0, - actread); + return get_contents(&fsdata, itr->dent, pos, buffer, maxsize, actread); } int file_fat_read(const char *filename, void *buffer, int maxsize) diff --git a/include/fat.h b/include/fat.h index 21bb6666cf..18d8981c48 100644 --- a/include/fat.h +++ b/include/fat.h @@ -58,12 +58,6 @@ */ #define LAST_LONG_ENTRY_MASK 0x40 -/* Flags telling whether we should read a file or list a directory */ -#define LS_NO 0 -#define LS_YES 1 -#define LS_DIR 1 -#define LS_ROOT 2 - #define ISDIRDELIM(c) ((c) == '/' || (c) == '\\') #define FSTYPE_NONE (-1)