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
This commit is contained in:
parent
031dfef23c
commit
890f1034e0
@ -188,6 +188,59 @@ static inline int romfs_checkentry(struct romfs_mountpt_s *rm, uint32 offset,
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* 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
|
||||
*
|
||||
@ -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++)
|
||||
sector = SEC_NSECTORS(rm, offset);
|
||||
ndx = offset & SEC_NDXMASK(rm);
|
||||
|
||||
/* Read the sector into memory */
|
||||
|
||||
ret = romfs_devcacheread(rm, sector);
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Is this a hardlink? */
|
||||
|
||||
if (IS_HARDLINK(next))
|
||||
{
|
||||
/* Yes.. then the info field is the offset to the actual entry
|
||||
* that we are interested in.
|
||||
*/
|
||||
|
||||
offset = info;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No... then break returning the directory information.
|
||||
* Retaining the original offset
|
||||
*/
|
||||
|
||||
*poffset = offset;
|
||||
*pnext = (save & RFNEXT_OFFSETMASK) | (next & RFNEXT_ALLMODEMASK);
|
||||
*pinfo = info;
|
||||
*psize = size;
|
||||
return OK;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Too many hard links -- probably an infinite loop */
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
return -ELOOP;
|
||||
save = romfs_devread32(rm, ndx + ROMFS_FHDR_NEXT);
|
||||
|
||||
/* Traverse hardlinks as necesssary to get to the real file header */
|
||||
|
||||
ret = romfs_followhardlinks(rm, offset, poffset);
|
||||
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);
|
||||
*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. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user