⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nfshash.c

📁 This is a source code of VxWorks
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (lseek (pTbl->fd, (pTbl->numBlocks + 1) *  HASH_BKT_SZ - 1, 	    SEEK_SET) == ERROR)	    {	    return (BAD_OFFSET);	    }        pTbl->numBlocks ++;	return ((pTbl->numBlocks - 1) * HASH_BKT_SZ);	}    else        {	/* existing free block available */	/* scan byte wise then bit wise */	pIx = (char *) pBits;	for (; *pIx == 0; ++pIx)	    {};        for (ix = 0; ix < CHAR_BIT_LEN; ++ix)	    {	    if (*pIx & (0x1 << ix))		{		bitPos =  (pIx - (char*)pTbl->allocBits) * CHAR_BIT_LEN + 			  (CHAR_BIT_LEN - ix) - 1;		*pIx &= ~(0x1 << ix);  		return (bitPos * HASH_BKT_SZ);		}            }	/* impossible to reach here */        }    return (BAD_OFFSET);    }/*******************************************************************************  * namehashFn - hash by name function** RETURNS: index into hash table*/LOCAL int  nameHashFn     (    char *  pName    )    {    int   i = strlen (pName);    return (pName[i - 2] + pName[i - 1]) % NAME_HASH_TBL_LEN;    }/*******************************************************************************  * namehashFn - hash by file handle function** Index into hash table, must be multiplies by the hash file bucket size* to get the actual file offset.** RETURNS: index into hash table*/LOCAL int fhHashFn     (    int   fh     )    {    return  fh % FH_HASH_TBL_LEN;    }/*******************************************************************************  * name2Fh - convert name to file handle ** Given a file name <pName>, convert that to a file handle, using the hash * table given by <ptbl>. We only do a lookup, so if the name does not exist * in the lookup structure we do not create the file handle for it. ** RETURNS: N/A*/LOCAL int  name2Fh    (    TBL_DESC *   pTbl,    char *       pName    )    {    off_t        off_1 = 0;    char         buf [NFS_MAXPATHLEN + 1 + sizeof (HNDL_NAME)];    HNDL_NAME *  pEnt;    int          nameLen = strlen (pName);    semTake (pTbl->sem, WAIT_FOREVER);    for (off_1 = pTbl->nameHash [nameHashFn(pName)];	off_1 != BAD_OFFSET;	off_1 = pEnt->next	)	{	if (blkRead (pTbl->fd, off_1, buf, sizeof buf) == ERROR)	    {	    semGive (pTbl->sem);	    return (ERROR);	    }        pEnt = (HNDL_NAME*)buf;        if (pEnt->nameLen == nameLen && (strcmp (pEnt->name, pName) == 					 0))             {	    semGive (pTbl->sem);	    return (pEnt->fh);	    }        }    semGive (pTbl->sem);    return (ERROR);    }/*******************************************************************************  * fh2Name - convert  file handle  to name** Find the file name corresponding to a file handle <fh> using hahs table* <pTbl> and return name in <pName>.** RETURNS: OK else ERROR if name not found.*/LOCAL STATUS  fh2Name    (    TBL_DESC *  pTbl,            /* hash file descriptor ptr */    int         fh,             /* file handle */    char *      pName            /* name output buffer */    )    {    off_t              off_1 ;    HNDL_NAME *        pEnt;    HASH_BKT  *        pBlk;    char               buf [HASH_BKT_SZ];    struct stat        statBuf;    HNDL_NAME *        pTmpEnt;    char               entBuf [NFS_MAXPATHLEN + 1 + sizeof (HNDL_NAME)];    semTake (pTbl->sem, WAIT_FOREVER);    for (off_1 = fhHashFn(fh) *  HASH_BKT_SZ; off_1 != BAD_OFFSET;	 off_1 = pBlk->next	)	{	if (blkRead (pTbl->fd, off_1, buf, sizeof buf) == ERROR)	    {	    semGive (pTbl->sem);	    return (ERROR);	    }	pBlk = (HASH_BKT *) buf;        pEnt = (HNDL_NAME*) pBlk->entries;	for (pEnt = (HNDL_NAME *)pBlk->entries; 	     (char*)pEnt < (buf + sizeof(buf) - MIN_ENTRY_SZ);              pEnt = (HNDL_NAME*) ((char *)pEnt + pEnt->totalLen))	    {            if (pEnt->fh == fh)                 {		strcpy (pName, pEnt->name);                semGive (pTbl->sem);		if (stat(pName, &statBuf) == ERROR)		    {		    /* delete from hash file since handle is not valid */                    if (blkRead (pTbl->fd, pEnt->next, entBuf, sizeof (entBuf))			== ERROR)			{			return (ERROR);			}		    pTmpEnt = (HNDL_NAME*)entBuf;		    pTmpEnt->prev = pEnt->prev;                    if (blkWrite (pTbl->fd, pEnt->next, entBuf, sizeof (entBuf))			== ERROR)			{			return (ERROR);			}                    if (blkRead (pTbl->fd, pEnt->prev, entBuf, sizeof (entBuf))			== ERROR)			{			return (ERROR);			}		    pTmpEnt->next = pEnt->next;                    if (blkWrite (pTbl->fd, pEnt->prev, entBuf, sizeof (entBuf))			== ERROR)			{			return (ERROR);			}		    pEnt->nameLen = 0;		    pBlk->freeSpace += pEnt->totalLen;		    /* if all entries in a block are gone then we could free		     * the block however that is not done currently  since the 		     * space will most likely be used up again unless		     * the hash table gets unbalanced.		     */		    }    	        return (OK);    	        }            }        }    semGive (pTbl->sem);    return (ERROR);    }/*******************************************************************************  * fhInsert - insert a file handle and name pair into hash table* Inser the file handle <fh> and name <pName> into the hash table* <pTbl>.** RETURNS: OK or ERROR if unable to insert entry.*/LOCAL STATUS   fhInsert     (    TBL_DESC *  pTbl,    int         fh,    char *      pName    )    {    /* first select block based on hash by fh , insert into blk       then onto list of entries by name */    off_t            offPrev  = 0;    off_t            offNow ;    HNDL_NAME *      pEnt = 0;    HNDL_NAME *      pTmpEnt;    HASH_BKT *       pBlk = (HASH_BKT *) NULL;    char             buf [HASH_BKT_SZ];    int              need;    int              ix;    int              newEntryLen;    char             entBuf [NFS_MAXPATHLEN + 1 + sizeof (HNDL_NAME)];    need = ENTRY_HDR_SZ  +  STR_ALIGN_LEN (pName) ;    semTake (pTbl->sem, WAIT_FOREVER);    for (offNow = fhHashFn (fh) * HASH_BKT_SZ ; offNow != BAD_OFFSET;	offPrev = offNow,  offNow = pBlk->next	)	{	if (blkRead (pTbl->fd, offNow, buf, sizeof buf) == ERROR)	    {            semGive (pTbl->sem);	    return (ERROR);	    }	pBlk = (HASH_BKT *)buf;	if (pBlk->freeSpace < need)	    {	    continue;	    }	for (pEnt = (HNDL_NAME *)pBlk->entries; 	     (char*)pEnt <= (buf + sizeof(buf) - need);              pEnt = (HNDL_NAME*) ((char *)pEnt + pEnt->totalLen))	    {	    if (pEnt->nameLen == 0 && pEnt->totalLen >= need)		{		/* found an empty entry big enough */		goto scanDone;                }            }        }    /* At this point we may need to allocate a new blk */    /* allocate new block and link it in then set pEnt and offNow     * as in earlier case     */scanDone:    if (offNow == BAD_OFFSET)	{        offNow = blockAlloc (pTbl);	/* link new block into prev block */	if (blkRead (pTbl->fd, offPrev, buf, sizeof buf) == ERROR)	    {	    semGive (pTbl->sem);	    return (ERROR);	    }        pBlk = (HASH_BKT*)buf;	pBlk->next = offNow;	if (blkWrite (pTbl->fd, offPrev, buf, sizeof buf) == ERROR)	    {	    semGive (pTbl->sem);	    return (ERROR);	    }	/* Now convert buf into a new empty block. 	   initially the whole block is just one full sized empty entry */	pBlk->next = BAD_OFFSET;	pBlk->freeSpace = HASH_BKT_SZ -  HASH_BKT_HDR_SZ;	pEnt = (HNDL_NAME*) (pBlk->entries);        pEnt->totalLen = HASH_BKT_SZ -  HASH_BKT_HDR_SZ ;	pEnt->nameLen = 0;	}    /* At this point offNow points to the block to be updated and       pEnt points to the correct entry in the buffered bucket     */    ix = nameHashFn (pName);    pEnt->next = pTbl->nameHash [ix];    pEnt->prev = BAD_OFFSET;    pTbl->nameHash[ix] = offNow + ((char *)pEnt - buf);    /* update back ptr of next entry if there is one */    if (pEnt->next != BAD_OFFSET)	{        if (blkRead (pTbl->fd, pEnt->next, entBuf, sizeof (entBuf) == ERROR))	    {	    return (ERROR);	    };        pTmpEnt = (HNDL_NAME*)entBuf;        pTmpEnt->prev = pTbl->nameHash[ix];        if (blkWrite (pTbl->fd, pEnt->next, entBuf, sizeof (entBuf) == ERROR))	    {	    return (ERROR);	    };	}    /* if there is sufficient space in this entry to accomodate     * another entry at this end then divide this to get an empty entry     * at the end of first entry     */    newEntryLen = ENTRY_HDR_SZ + STR_ALIGN_LEN (pName);    if (pEnt->totalLen - newEntryLen >= MIN_ENTRY_SZ)       {       pTmpEnt = (HNDL_NAME*) ((char*)pEnt + newEntryLen);       pTmpEnt->totalLen = pEnt->totalLen - newEntryLen;       pTmpEnt->nameLen = 0;       pEnt->totalLen = newEntryLen;       }    pBlk->freeSpace -= pEnt->totalLen;    strcpy (pEnt->name, pName);    pEnt->fh = fh;    pEnt->nameLen = strlen (pName);    if (blkWrite (pTbl->fd, offNow, buf, sizeof buf) == ERROR)        {        return (ERROR);        }    semGive (pTbl->sem);    return (OK);    }/*******************************************************************************  * blkRead - read block from file* * Read block from file with file descriptor <fd>, offset <offset>* buffer <buf> and buffer len <len>* * RETURNS: num chars read or ERROR.*/LOCAL   int blkRead     (    int      fd,    off_t    offset,    char *   buf,    int      len    )    {    if (lseek (fd, offset, SEEK_SET) == ERROR)        {        return (ERROR);        }    return (read ( fd, buf, len));    }/*******************************************************************************  * blkWrite - write block to file* * Write block to file with file descriptor <fd>, offset <offset>* buffer <buf> and buffer len <len>* * RETURNS: num chars written or ERROR. */LOCAL int blkWrite     (    int      fd,    off_t    offset,    char *   buf,    int      len    )    {    if (lseek (fd, offset, SEEK_SET) == ERROR)        {        return (ERROR);        }    return (write ( fd, buf, len));    }/*******************************************************************************  * nfsFhLkup - find name corresponding to file handle ** using file handle <fh> as the key get corresponding file name* in <pName>.** RETURNS: OK or ERROR if name not found*/STATUS nfsFhLkup    (    NFS_FILE_HANDLE *   pFh,  /* key for lookup */    char *              pName  /* output name */    )    {    TBL_DESC *    pT;    pT = tblDescGet (pFh->volumeId);    if (pT == NULL)       {       return (ERROR);	}    if (fh2Name (pT, pFh->inode, pName) == ERROR)	{	return (ERROR);	}    else	{	return OK;	}    }/*******************************************************************************  * nfsNmLkupIns - find fh corresponding to file name** Find the file handle  corresponding to the given file name  <Pname> with* nfs mount volume id <mntId> and create and insert an entry in the table* if not found.** RETURNS: file handle or ERROR;* NOMANUAL*/int nfsNmLkupIns     (    int    mntId,     /* mount id no */    char * pName      /* seach key */    )    {    TBL_DESC *    pT;    int           in;    pT = tblDescGet (mntId);    if (pT == NULL)       return (ERROR);    if ((in = name2Fh (pT, pName)) == ERROR)	{	in = ++pT->nextInode;	if (fhInsert (pT, pT->nextInode, pName)== ERROR)	   return (ERROR);	}    return (in);    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -