diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2008-09-12 20:54:14 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2008-09-12 20:54:14 +0000 |
commit | 20aae3065cc24a73c3ef14171bb327c3ae62214d (patch) | |
tree | 28f51fd2433b1291da3b52e768c8af89daf16678 /nuttx/fs | |
parent | bd5c6bfbaee32b963be80d872f9365d70d3b6ed8 (diff) | |
download | px4-nuttx-20aae3065cc24a73c3ef14171bb327c3ae62214d.tar.gz px4-nuttx-20aae3065cc24a73c3ef14171bb327c3ae62214d.tar.bz2 px4-nuttx-20aae3065cc24a73c3ef14171bb327c3ae62214d.zip |
Combine hard link traversal into one common function
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@918 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/fs')
-rw-r--r-- | nuttx/fs/romfs/fs_romfsutil.c | 170 |
1 files changed, 85 insertions, 85 deletions
diff --git a/nuttx/fs/romfs/fs_romfsutil.c b/nuttx/fs/romfs/fs_romfsutil.c index 6debb78cc..07a7689dd 100644 --- a/nuttx/fs/romfs/fs_romfsutil.c +++ b/nuttx/fs/romfs/fs_romfsutil.c @@ -189,6 +189,59 @@ static inline int romfs_checkentry(struct romfs_mountpt_s *rm, uint32 offset, } /**************************************************************************** + * Name: romfs_followhardlinks + * + * Desciption: + * Given the offset to a file header, check if the file is a hardlink. + * If so, traverse the hard links until the terminal, non-linked header + * so found and return that offset. + * + ****************************************************************************/ + +static int romfs_followhardlinks(struct romfs_mountpt_s *rm, uint32 offset, + uint32 *poffset) +{ + uint32 sector; + uint32 next; + uint16 ndx; + int ret; + int i; + + /* Loop while we are redirected by hardlinks */ + + for (i = 0; i < ROMF_MAX_LINKS; i++) + { + /* Convert the offset into sector + index */ + + sector = SEC_NSECTORS(rm, offset); + ndx = offset & SEC_NDXMASK(rm); + + /* Read the sector into memory */ + + ret = romfs_devcacheread(rm, sector); + if (ret < 0) + { + return ret; + } + + /* Check if this is a hard link */ + + next = romfs_devread32(rm, ndx + ROMFS_FHDR_NEXT); + if (!IS_HARDLINK(next)) + { + *poffset = offset; + return OK; + } + + /* Follow the hard-link */ + + offset = romfs_devread32(rm, ndx + ROMFS_FHDR_INFO); + } + + return -ELOOP; +} + +/**************************************************************************** * Name: romfs_searchdir * * Desciption: @@ -760,76 +813,47 @@ int romfs_parsedirentry(struct romfs_mountpt_s *rm, uint32 offset, uint32 *poffs uint32 sector; uint32 save; uint32 next; - uint32 info; - uint32 size; uint16 ndx; int ret; - int i; - /* Loop while we are redirected by hardlinks */ + /* Convert the offset into sector + index */ - for (i = 0; i < ROMF_MAX_LINKS; i++) - { - /* Convert the offset into sector + index */ + sector = SEC_NSECTORS(rm, offset); + ndx = offset & SEC_NDXMASK(rm); - sector = SEC_NSECTORS(rm, offset); - ndx = offset & SEC_NDXMASK(rm); - - /* Read the sector into memory */ + /* Read the sector into memory */ - ret = romfs_devcacheread(rm, sector); - if (ret < 0) - { - return ret; - } - - /* Because everything is chunked and aligned to 16-bit boundaries, - * we know that most the basic node info fits into the sector. The - * associated name may not, however. - */ - - next = romfs_devread32(rm, ndx + ROMFS_FHDR_NEXT); - info = romfs_devread32(rm, ndx + ROMFS_FHDR_INFO); - size = romfs_devread32(rm, ndx + ROMFS_FHDR_SIZE); - - /* Is this the first offset we have tried? */ - - if (i == 0) - { - /* Yes.. Save the first 'next' value. That has the offset needed to - * traverse the parent directory. - */ - - save = next; - } + ret = romfs_devcacheread(rm, sector); + if (ret < 0) + { + return ret; + } - /* Is this a hardlink? */ + /* Yes.. Save the first 'next' value. That has the offset needed to + * traverse the parent directory. But we may need to change the type + * after we follow the hard links. + */ - if (IS_HARDLINK(next)) - { - /* Yes.. then the info field is the offset to the actual entry - * that we are interested in. - */ + save = romfs_devread32(rm, ndx + ROMFS_FHDR_NEXT); - offset = info; - } - else - { - /* No... then break returning the directory information. - * Retaining the original offset - */ + /* Traverse hardlinks as necesssary to get to the real file header */ - *poffset = offset; - *pnext = (save & RFNEXT_OFFSETMASK) | (next & RFNEXT_ALLMODEMASK); - *pinfo = info; - *psize = size; - return OK; - } + ret = romfs_followhardlinks(rm, offset, poffset); + if (ret < 0) + { + return ret; } - /* Too many hard links -- probably an infinite loop */ + /* Because everything is chunked and aligned to 16-bit boundaries, + * we know that most the basic node info fits into the sector. The + * associated name may not, however. + */ - return -ELOOP; + next = romfs_devread32(rm, ndx + ROMFS_FHDR_NEXT); + *pnext = (save & RFNEXT_OFFSETMASK) | (next & RFNEXT_ALLMODEMASK); + *pinfo = romfs_devread32(rm, ndx + ROMFS_FHDR_INFO); + *psize = romfs_devread32(rm, ndx + ROMFS_FHDR_SIZE); + return OK; } /**************************************************************************** @@ -917,39 +941,15 @@ int romfs_parsefilename(struct romfs_mountpt_s *rm, uint32 offset, char *pname) int romfs_datastart(struct romfs_mountpt_s *rm, uint32 offset, uint32 *start) { uint32 sector; - uint32 next; - uint32 info; uint16 ndx; int ret; - /* Loop while we traverse any hardlinks */ + /* Traverse hardlinks as necesssary to get to the real file header */ - for (;;) + ret = romfs_followhardlinks(rm, offset, &offset); + if (ret < 0) { - /* Convert the offset into sector + index */ - - sector = SEC_NSECTORS(rm, offset); - ndx = offset & SEC_NDXMASK(rm); - - /* Read the sector into memory */ - - ret = romfs_devcacheread(rm, sector); - if (ret < 0) - { - return ret; - } - - /* Check if this is a hard link */ - - next = romfs_devread32(rm, ndx + ROMFS_FHDR_NEXT); - if ((next & RFNEXT_MODEMASK) != RFNEXT_HARDLINK) - { - break; - } - - /* Follow the hard-link */ - - offset = romfs_devread32(rm, ndx + ROMFS_FHDR_INFO); + return ret; } /* Loop until the header size is obtained. */ |