Example #1
0
/* WARNING: This write function is far beyond complete, 
 * data block allocation and vnode expansion support should be added
 */
ssize_t write(int fildes, void *buf, size_t nbyte)
{
	blkcnt_t blk, oldblk;
	off_t disp;
	size_t xfer = nbyte, i=0;
	struct scache *scp;
	struct ofile *ofp = (struct ofile*)fildes;

	/* do the data copy */
	while(xfer) {
		/* calculate pos defined block number
		 * and displacement.
		 */
		blk  = ofp->pos/ofp->mount->blksize;
		blk += ofp->node->blkentry;
		blk += fs_daddr(ofp->mount->fs, ofp->mount->sblk);
		disp = ofp->pos%ofp->mount->blksize;

		/* load block to cache if not loaded */
		if(oldblk != blk) {
			scp = scache_get(ofp->node->dev,
						blk, ofp->mount->blksize);
			oldblk = blk;
		}
	
		/* do the copy */
		if((xfer+disp) > ofp->mount->blksize) {
			memcpy(&scp->buf[disp], &((char*)buf)[i],
					ofp->mount->blksize - disp);
			scp->mode |= S_CHANGED;
			ofp->pos  += ofp->mount->blksize - disp;
			disp  = 0;
			xfer -= ofp->mount->blksize - disp;
			i    += ofp->mount->blksize - disp;
		} else {
			memcpy(&scp->buf[disp], &((char*)buf)[i], xfer);
			scp->mode |= S_CHANGED;
			ofp->pos  += xfer;
			disp  = 0;
			xfer -= xfer;
			i    += xfer;
		}

		/* check end of file with pos */
		if(ofp->pos > ofp->node->size) {
			ofp->pos = ofp->node->size;
			break;
		}
	}
	return nbyte;
}
Example #2
0
interface_info* get_iinfo(const char* iname, bool add_if_need)
{
	interface_info *ret = 0;
	ret = scache_get(&statistic, iname, 0);
	if (!ret && add_if_need)
	{
		ret = (interface_info*)malloc(sizeof(interface_info));
		ret->ibytes = 0;
		ret->obytes = 0;
		ret->last_time = 0;
		scache_set(&statistic, iname, ret);
	}

	return ret;
}
Example #3
0
off_t lseek(int fildes, off_t offset, int whence)
{
	blkcnt_t blk;
	struct ofile *ofp = (struct ofile*)fildes;

	/* general methods: 
	 *  1. setup displacement
	 *  2. update sector buffer
	 */
	switch(whence) {
	case SEEK_SET:
		ofp->pos = offset;
		break;
	case SEEK_CUR:
		ofp->pos+= offset;
		break;
	case SEEK_END:
		ofp->pos = ofp->node->size;
		ofp->pos+= offset;
		break;
	}

	/* boundary checks */
	if((ofp->pos > ofp->node->size) ||
	   (ofp->pos < 0)) {
		return -1;	/* offset out of boundary */
	}

	/* calculate block index */
	blk = ofp->pos/ofp->mount->blksize;
	blk+= ofp->node->blkentry;
	blk+= fs_daddr(ofp->mount->fs, ofp->mount->sblk);

	/* load block if not in buffer */
	scache_get(ofp->node->dev, blk, ofp->mount->blksize);

	return ofp->pos;
}
Example #4
0
/* flags to support:
 * O_RDONLY
 * O_WRONLY
 * O_RDWR
 * O_CREAT
 * O_EXCL
 * O_TRUNC
 * O_APPEND
 */
int open(char *path, int oflag, ...)
{
	struct vnode *vp;
	struct scache *scp;
	struct mountab *mtp;
	struct ofile *ofp;

	/* first, find the corresponding vnode of *path */
	vp = vget(path, 0);
	if((vp == (struct vnode*)-1)||(vp == 0)) {
		/* file not found */
		if(oflag&O_CREAT) {
			if((oflag&O_EXCL) == O_EXCL) {
				return 0;
			}
			/* create the file and continue the process */
		}
	} else if(((oflag&O_CREAT) == O_CREAT) && ((oflag&O_EXCL) == O_EXCL)) {
		return -1;
	}

	/* checking read/write permitions, 
	 * kernel is the owner of all files */
	if(((oflag&O_RDONLY) == O_RDONLY) && ((vp->mode&S_IRUSR) != S_IRUSR)) {
		return -1;
	}
	if(((oflag&O_WRONLY) == O_WRONLY) && ((vp->mode&S_IWUSR) != S_IWUSR)) {
		return -1;
	}

	/* load sectors containing the requested data position */
	mtp = mountab_get(vp->dev);
	if(mtp == 0) {
		return -1;	/* mount point not found */
	}
	scp = scache_get(vp->dev, vp->blkentry, mtp->blksize);
	if(scp == 0) {
		return -1;	/* cannot locate data block */
	}

	/* request a open file descriptor 
	 * describing kernel file operation,
	 * which containing vnode data, 
	 * mount data and beginning sector cache data*/
	ofp = ofile_alloc();
	if(ofp == 0) {
		MSG(1, "no open file descriptor available\n");
		return -1;	/* no ofile available */
	}
	ofp->node   = vp;
	ofp->mount  = mtp;
	ofp->oflag  = oflag;

	/* setup pos value, load pos sector to buffer */
	if((oflag&&O_APPEND) == O_APPEND) {
		/* set pos to end of file */
		ofp->pos = vp->size;
	} else if((oflag&&O_TRUNC) == O_TRUNC) {
		/* release all data blocks allocated,
		 * setup file size to 0 and block data to 0*/
		ofp->pos = 0;
		vp->size = 0;
		blkcnt_t bc;
		for(bc=vp->blkentry; bc<=vp->blkentry+vp->blocks; bc++) {
			fs_dfree(mtp->fs, mtp->sblk, vp->dev, bc);
		}
		vp->blkentry = 0;
		vp->blocks   = 0;
	} else {
		ofp->pos = 0;
	}
	lseek((int)ofp, ofp->pos, SEEK_SET);

	return (int)ofp;
}