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

📄 nfsdrv.c

📁 vxworks的完整的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		nCacheRead = nfsFileRead (nfsFd->nfsDev->host,					  &nfsFd->fileHandle,					  nfsFd->fileCurByte, nfsCacheSize,					  nfsFd->cacheBuf, &nfsFd->fileAttr);		if (nCacheRead < 0)		    {		    semGive (nfsFd->nfsFdSem);		    return (ERROR);		    }		nfsFd->cacheCurByte = nfsFd->cacheBuf;	/* update cache ptrs */		nfsFd->cacheBytesLeft = nCacheRead;		nfsFd->cacheValid = TRUE;		/* cache is valid */		}	    /* read as many bytes as possible from what's left in the cache,	     * up to the amount requested	     */	    if (nfsFd->cacheBytesLeft > 0)		{		if (maxBytes - readCount < nfsFd->cacheBytesLeft)		    nRead = maxBytes - readCount;		else		    nRead = nfsFd->cacheBytesLeft;		/* copy bytes into user's buffer */		bcopy (nfsFd->cacheCurByte, (char *) ((int) buf + readCount),		       nRead);		/* update file pointer */		status = nfsSeek (nfsFd, (int) nfsFd->fileCurByte + nRead);		/* how many bytes have we read so far? */		readCount += nRead;		}	    else		break;		/* we've hit the end of the file */	    } /* while */	} /* else */    semGive (nfsFd->nfsFdSem);    return (status == ERROR ? ERROR : readCount);    }/********************************************************************************* nfsWrite - write bytes to remote file** nfsWrite copies the specified number of bytes from the buffer* to the nfs file.  Bytes are written starting at the current file pointer.* The file pointer is updated to point immediately after the last* character that was written.** A cache is used for keeping nfs network reads and writes down to a minimum.* If all goes well, the entire buffer is written to the cache and/or actual* file.** Called only by the I/O system.** SIDE EFFECTS: moves file pointer** RETURNS:*    Number of bytes written (error if != nBytes)*    ERROR if nBytes < 0, or nfs write is not successful*/LOCAL int nfsWrite    (    FAST NFS_FD *nfsFd, /* open file descriptor */    char *buf,          /* buffer being written from */    FAST int nBytes     /* number of bytes to write to file */    )    {    FAST unsigned int nWrite;	/* number of bytes to write */    FAST unsigned int newPos;	/* new position of file pointer */    unsigned int cacheMargin;	/* margin left in cache for writing */    int		nCacheRead;	/* number of bytes read into cache */    FAST char	*pBuf = buf;	/* ptr to spot in user's buffer */    FAST int	writeCount = 0;	/* number of bytes written so far */    /* check for valid number of bytes */    if (nBytes < 0)	{	errnoSet (S_nfsDrv_INVALID_NUMBER_OF_BYTES);	return (ERROR);	}    /* if file opened for O_RDONLY, don't write */    if (nfsFd->mode == O_RDONLY)	{	errnoSet (S_nfsDrv_READ_ONLY_CANNOT_WRITE);	return (ERROR);	}    semTake (nfsFd->nfsFdSem, WAIT_FOREVER);    /* do the write, until entire buffer has been written out */    if (nfsCacheSize == 0)	{	writeCount = nfsFileWrite (nfsFd->nfsDev->host, &nfsFd->fileHandle,			       nfsFd->fileCurByte, (unsigned) nBytes, buf,			       &nfsFd->fileAttr);	if (writeCount == ERROR)	    {	    semGive (nfsFd->nfsFdSem);	    return (ERROR);	    }	/* where will the new file pointer be? */	newPos = nfsFd->fileCurByte + writeCount;	/* update the file pointer.  */	if (nfsSeek (nfsFd, (int) newPos) == ERROR)	    {	    semGive (nfsFd->nfsFdSem);	    return (ERROR);	    }	}    else	{	while (writeCount < nBytes)	    {	    /* fill cache before writing to it, keep cache in sync w/file */	    if (!nfsFd->cacheValid)		{		if ((nBytes - writeCount) < nfsCacheSize)		    {		    nCacheRead = nfsFileRead (nfsFd->nfsDev->host,					      &nfsFd->fileHandle,					      nfsFd->fileCurByte,					      nfsCacheSize, nfsFd->cacheBuf,					      &nfsFd->fileAttr);		    if (nCacheRead < 0)			{			semGive (nfsFd->nfsFdSem);			return (ERROR);			}		    nfsFd->cacheBytesLeft = nCacheRead;		    }		else		    {		    nfsFd->cacheBytesLeft = nfsCacheSize;		    }		/* update cache pointers */		nfsFd->cacheCurByte = nfsFd->cacheBuf;		nfsFd->cacheDirty = FALSE;		nfsFd->cacheValid = TRUE;		}	    /* margin allowable for writing */	    cacheMargin = (unsigned) nfsFd->cacheBuf + nfsCacheSize			  - (unsigned) nfsFd->cacheCurByte;	    if (nBytes - writeCount < cacheMargin)		nWrite = nBytes - writeCount;	    else		nWrite = cacheMargin;	    /* copy the bytes into the cache */	    bcopy (pBuf, nfsFd->cacheCurByte, (int) nWrite);	    if (nWrite > nfsFd->cacheBytesLeft)		nfsFd->cacheBytesLeft = nWrite;	    /* cache has been written in, it is soiled */	    nfsFd->cacheDirty = TRUE;	    /* what's the new position of the file pointer? */	    newPos = nfsFd->fileCurByte + nWrite;	    /* if the new file pointer reaches past the end of the file,	     * the file has grown, update the size of the file	     */	    if (newPos > nfsFd->fileAttr.size)		nfsFd->fileAttr.size = newPos;	    /* update the file pointer.	     * any cache flushes will occur during the seek.	     */	    if (nfsSeek (nfsFd, (int) newPos) == ERROR)		{		semGive (nfsFd->nfsFdSem);		return (ERROR);		}	    writeCount += nWrite;	    pBuf += nWrite;	    } /* while entire buffer has not been written */	} /* else */    semGive (nfsFd->nfsFdSem);    return (writeCount);    }/********************************************************************************* nfsIoctl - do device specific control function** Called only by the I/O system.** RETURNS: whatever the called function returns*/LOCAL int nfsIoctl    (    FAST NFS_FD *nfsFd, /* open nfs file descriptor */    FAST int function,  /* function code */    FAST int arg        /* argument for function */    )    {    FAST struct stat *pStat;    int status = OK;    switch (function)	{	case FIOSYNC:	    semTake (nfsFd->nfsFdSem, WAIT_FOREVER);	    if (nfsFd->cacheDirty)		status = nfsCacheFlush (nfsFd);	    semGive (nfsFd->nfsFdSem);	    break;	case FIOSEEK:	    status = nfsSeek (nfsFd, arg);	    break;	case FIOWHERE:    	    status = nfsFd->fileCurByte;	    break;	case FIONREAD:    	    *((int *) arg) = nfsFd->fileAttr.size - nfsFd->fileCurByte;	    break;	case FIOREADDIR:	    /* read a directory entry */	    status = nfsDirReadOne (nfsFd->nfsDev->host, &nfsFd->fileHandle,				    (DIR *) arg);	    break;	case FIOFSTATGET:	    /* get status of a file */	    pStat = (struct stat *) arg;	    /* get file attributes returned in pStat */	    nfsFileAttrGet (&nfsFd->fileAttr, pStat);	    pStat->st_dev         = (ULONG) nfsFd->nfsDev;	    break;        case FIOFSTATFSGET:            status = nfsFsAttrGet(nfsFd->nfsDev->host, &nfsFd->fileHandle,                                  (struct statfs *)arg);            break;	case FIOGETFL:	    *((int *) arg) = nfsFd->mode;	    break;	    	default:	    errnoSet (S_ioLib_UNKNOWN_REQUEST);	    status = ERROR;	    break;	}    return (status);    }/********************************************************************************* nfsSeek - change file's current character position** This routine moves the file pointer by the offset to a new position.* If the new position moves the file pointer out of the range of what's* in the cache and the cache is dirty (i.e. the cache has been written* in), then the cache is written out to the nfs file and the cache is* marked as invalid.  If the new position is beyond EOF, then an empty* area is created that will read as zeros.** Called only by the I/O system.** RETURNS: OK | ERROR*/LOCAL int nfsSeek    (    FAST NFS_FD *nfsFd,    FAST int newPos    )    {    FAST int interval;    if (newPos < 0)	return (ERROR);    if (newPos == nfsFd->fileCurByte)	return (OK);    semTake (nfsFd->nfsFdSem, WAIT_FOREVER);    if (nfsFd->cacheValid)	/* if cache is valid, update cache pointer */	{	/* how far will file pointer be moved? */	interval = newPos - nfsFd->fileCurByte;	/* if the new pointer precedes what's in the cache,	 * OR if the new ptr points past what's in the cache,	 * OR if the new ptr points past the end of the valid cache bytes,	 * THEN the cache is no longer valid.	 *	 * NOTE:  The cache is still valid if the new pointer points	 * IMMEDIATELY after the valid bytes in the cache, but still	 * hasn't reached the end of the cache buffer.  The cache can	 * still be written to and should not be flushed until it is full	 * or the file is closed (a similar technique is used in some states	 * during drought conditions).	 */	if (((interval < 0) && (nfsFd->cacheCurByte + interval <				nfsFd->cacheBuf))	    || ((interval > 0) && (interval > nfsFd->cacheBytesLeft))	    || ((nfsFd->cacheBuf + nfsCacheSize) <= (nfsFd->cacheCurByte +						    interval)))	    {	    /* if the new cache pointer goes out of range of the cache,	     * mark the cache as invalid, and flush if necessary.	     */	    if (nfsFd->cacheDirty)		if (nfsCacheFlush (nfsFd) == ERROR)		    {		    semGive (nfsFd->nfsFdSem);		    return (ERROR);		    }	    nfsFd->cacheValid = FALSE;	    nfsFd->cacheBytesLeft = 0;	    nfsFd->cacheCurByte = nfsFd->cacheBuf;	    nfsFd->cacheDirty = FALSE;	    }	else	    {	    /* if the new position stays within range of the cache,	     * update the cache pointers.	     */	    nfsFd->cacheCurByte += interval;	    nfsFd->cacheBytesLeft -= interval;	    }	}    nfsFd->fileCurByte = newPos;    semGive (nfsFd->nfsFdSem);    return (OK);    }/********************************************************************************* nfsCacheFlush - flush the cache to the remote NFS file** Called only by the I/O system.** RETURNS: number of bytes written or ERROR*/LOCAL int nfsCacheFlush    (    FAST NFS_FD *nfsFd    )    {    int nWrite;		/* how many bytes are written with nfs? */    unsigned int offset;/* offset in the file where cache gets written */    unsigned int count;	/* number of bytes to write with nfs */    unsigned int dist;	/* distance between beginning of cache and current file			 * pointer (number of bytes) */    if (!nfsFd->cacheValid)	{	errnoSet (S_nfsDrv_FATAL_ERR_FLUSH_INVALID_CACHE);	return (ERROR);	}    dist   = nfsFd->cacheCurByte - nfsFd->cacheBuf;    offset = nfsFd->fileCurByte - dist;    count  = dist + nfsFd->cacheBytesLeft;    nWrite = nfsFileWrite (nfsFd->nfsDev->host, &nfsFd->fileHandle,			   offset, count, nfsFd->cacheBuf, &nfsFd->fileAttr);    return (nWrite);    }

⌨️ 快捷键说明

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