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

📄 nfs.c

📁 newos is new operation system
💻 C
📖 第 1 页 / 共 2 页
字号:
	sem_acquire(v->sem, 1);	err = _nfs_readdir(fs, v, cookie, buf, len);	sem_acquire(v->sem, 1);	return err;}int nfs_open(fs_cookie fs, fs_vnode _v, file_cookie *_cookie, int oflags){	nfs_fs *nfs = (nfs_fs *)fs;	nfs_vnode *v = (nfs_vnode *)_v;	nfs_cookie *cookie;	int err;	TOUCH(nfs);	TRACE("nfs_open: fsid 0x%x, vnid 0x%Lx, oflags 0x%x\n", nfs->id, VNODETOVNID(v), oflags);	if(v->st == STREAM_TYPE_DIR) {		err = ERR_VFS_IS_DIR;		goto err;	}	cookie = kmalloc(sizeof(nfs_cookie));	if(cookie == NULL) {		err = ERR_NO_MEMORY;		goto err;	}	cookie->v = v;	cookie->u.file.pos = 0;	cookie->u.file.oflags = oflags;	*_cookie = (file_cookie)cookie;	err = NO_ERROR;err:	return err;}int nfs_close(fs_cookie fs, fs_vnode _v, file_cookie _cookie){	nfs_fs *nfs = (nfs_fs *)fs;	nfs_vnode *v = (nfs_vnode *)_v;	TOUCH(nfs);TOUCH(v);	TRACE("nfs_close: fsid 0x%x, vnid 0x%Lx\n", nfs->id, VNODETOVNID(v));	return NO_ERROR;}int nfs_freecookie(fs_cookie fs, fs_vnode _v, file_cookie _cookie){	nfs_fs *nfs = (nfs_fs *)fs;	nfs_vnode *v = (nfs_vnode *)_v;	nfs_cookie *cookie = (nfs_cookie *)_cookie;	TOUCH(nfs);TOUCH(v);	TRACE("nfs_freecookie: fsid 0x%x, vnid 0x%Lx\n", nfs->id, VNODETOVNID(v));	kfree(cookie);	return NO_ERROR;}int nfs_fsync(fs_cookie fs, fs_vnode _v){	nfs_fs *nfs = (nfs_fs *)fs;	nfs_vnode *v = (nfs_vnode *)_v;	TOUCH(nfs);TOUCH(v);	TRACE("nfs_fsync: fsid 0x%x, vnid 0x%Lx\n", nfs->id, VNODETOVNID(v));	return NO_ERROR;}#define READ_BUF_SIZE 1024static ssize_t nfs_readfile(nfs_fs *nfs, nfs_vnode *v, nfs_cookie *cookie, void *buf, off_t pos, ssize_t len){	uint8 abuf[4 + sizeof(nfs_fattr) + READ_BUF_SIZE];	nfs_readargs *args = (nfs_readargs *)abuf;	nfs_readres  *res  = (nfs_readres *)abuf;	int err;	ssize_t total_read = 0;	/* check args */	if(pos < 0)		pos = cookie->u.file.pos;	/* can't do more than 32-bit offsets right now */	if(pos > 0xffffffff)		return 0;	/* negative or zero length means nothing */	if(len <= 0)		return 0;	while(len > 0) {		ssize_t to_read = min(len, READ_BUF_SIZE);		/* put together the message */		memcpy(&args->file, &v->nfs_handle, sizeof(args->file));		args->offset = htonl(pos);		args->count = htonl(to_read);		args->totalcount = 0; // unused		err = rpc_call(&nfs->rpc, NFSPROG, NFSVERS, NFSPROC_READ, args, sizeof(*args), abuf, sizeof(abuf));		if(err < 0)			break;		/* get response */		if(ntohl(res->status) != NFS_OK)			break;		/* see how much we read */		err = user_memcpy((uint8 *)buf + total_read, res->data, ntohl(res->len));		if(err < 0) {			total_read = err; // bad user give me bad buffer			break;		}		pos += ntohl(res->len);		len -= ntohl(res->len);		total_read += ntohl(res->len);		/* short read, we're done */		if((ssize_t)ntohl(res->len) != to_read)			break;	}	cookie->u.file.pos = pos;	return total_read;}ssize_t nfs_read(fs_cookie fs, fs_vnode _v, file_cookie _cookie, void *buf, off_t pos, ssize_t len){	nfs_fs *nfs = (nfs_fs *)fs;	nfs_vnode *v = (nfs_vnode *)_v;	nfs_cookie *cookie = (nfs_cookie *)_cookie;	ssize_t err;	TRACE("nfs_read: fsid 0x%x, vnid 0x%Lx, buf %p, pos 0x%Lx, len %ld\n", nfs->id, VNODETOVNID(v), buf, pos, len);	if(v->st == STREAM_TYPE_DIR)		return ERR_VFS_IS_DIR;	sem_acquire(v->sem, 1);	err = nfs_readfile(nfs, v, cookie, buf, pos, len);	sem_release(v->sem, 1);	return err;}#define WRITE_BUF_SIZE 1024static ssize_t nfs_writefile(nfs_fs *nfs, nfs_vnode *v, nfs_cookie *cookie, const void *buf, off_t pos, ssize_t len){	uint8 abuf[sizeof(nfs_writeargs) + WRITE_BUF_SIZE];	nfs_writeargs *args = (nfs_writeargs *)abuf;	nfs_attrstat  *res  = (nfs_attrstat *)abuf;	int err;	ssize_t total_written = 0;	/* check args */	if(pos < 0)		pos = cookie->u.file.pos;	/* can't do more than 32-bit offsets right now */	if(pos > 0xffffffff)		return 0;	/* negative or zero length means nothing */	if(len <= 0)		return 0;	while(len > 0) {		ssize_t to_write = min(len, WRITE_BUF_SIZE);		/* put together the message */		memcpy(&args->file, &v->nfs_handle, sizeof(args->file));		args->beginoffset = 0; // unused		args->offset = htonl(pos);		args->totalcount = 0; // unused		args->len = htonl(to_write);		err = user_memcpy(args->data, (const uint8 *)buf + total_written, to_write);		if(err < 0) {			total_written = err;			break;		}		err = rpc_call(&nfs->rpc, NFSPROG, NFSVERS, NFSPROC_WRITE, args, sizeof(*args) + to_write, abuf, sizeof(abuf));		if(err < 0)			break;		/* get response */		if(ntohl(res->status) != NFS_OK)			break;		pos += to_write;		len -= to_write;		total_written += to_write;	}	cookie->u.file.pos = pos;	return total_written;}ssize_t nfs_write(fs_cookie fs, fs_vnode _v, file_cookie _cookie, const void *buf, off_t pos, ssize_t len){	nfs_fs *nfs = (nfs_fs *)fs;	nfs_vnode *v = (nfs_vnode *)_v;	nfs_cookie *cookie = (nfs_cookie *)_cookie;	ssize_t err;	TRACE("nfs_write: fsid 0x%x, vnid 0x%Lx, buf %p, pos 0x%Lx, len %ld\n", nfs->id, VNODETOVNID(v), buf, pos, len);	sem_acquire(v->sem, 1);	switch(v->st) {		case STREAM_TYPE_FILE:			err = nfs_writefile(nfs, v, cookie, buf, pos, len);			break;		case STREAM_TYPE_DIR:			err = ERR_NOT_ALLOWED;			break;		default:			err = ERR_GENERAL;	}	sem_release(v->sem, 1);	return err;}int nfs_seek(fs_cookie fs, fs_vnode _v, file_cookie _cookie, off_t pos, seek_type st){	nfs_fs *nfs = (nfs_fs *)fs;	nfs_vnode *v = (nfs_vnode *)_v;	nfs_cookie *cookie = (nfs_cookie *)_cookie;	int err = NO_ERROR;	TRACE("nfs_seek: fsid 0x%x, vnid 0x%Lx, pos 0x%Lx, seek_type %d\n", nfs->id, VNODETOVNID(v), pos, st);	sem_acquire(v->sem, 1);	switch(v->st) {		case STREAM_TYPE_FILE: {			nfs_attrstat attrstat;			off_t file_len;			err = nfs_getattr(nfs, v, &attrstat);			if(err < 0)				goto out;			file_len = ntohl(attrstat.attributes.size);			switch(st) {				case _SEEK_SET:					if(pos < 0)						pos = 0;					if(pos > file_len)						pos = file_len;					cookie->u.file.pos = pos;					break;				case _SEEK_CUR:					if(pos + cookie->u.file.pos > file_len)						cookie->u.file.pos = file_len;					else if(pos + cookie->u.file.pos < 0)						cookie->u.file.pos = 0;					else						cookie->u.file.pos += pos;					break;				case _SEEK_END:					if(pos > 0)						cookie->u.file.pos = file_len;					else if(pos + file_len < 0)						cookie->u.file.pos = 0;					else						cookie->u.file.pos = pos + file_len;					break;				default:					err = ERR_INVALID_ARGS;			}			break;		}		case STREAM_TYPE_DIR:			switch(st) {				// only valid args are seek_type _SEEK_SET, pos 0.				// this rewinds to beginning of directory				case _SEEK_SET:					if(pos == 0) {						cookie->u.dir.nfscookie = 0;						cookie->u.dir.at_end = false;					} else {						err = ERR_INVALID_ARGS;					}					break;				case _SEEK_CUR:				case _SEEK_END:				default:					err = ERR_INVALID_ARGS;			}		default:			err = ERR_INVALID_ARGS;	}out:	sem_release(v->sem, 1);	return err;}int nfs_ioctl(fs_cookie fs, fs_vnode _v, file_cookie cookie, int op, void *buf, size_t len){	nfs_fs *nfs = (nfs_fs *)fs;	nfs_vnode *v = (nfs_vnode *)_v;	TOUCH(nfs);TOUCH(v);	TRACE("nfs_ioctl: fsid 0x%x, vnid 0x%Lx, op %d, buf %p, len %ld\n", nfs->id, VNODETOVNID(v), op, buf, len);	return ERR_UNIMPLEMENTED;}int nfs_canpage(fs_cookie fs, fs_vnode _v){	nfs_fs *nfs = (nfs_fs *)fs;	nfs_vnode *v = (nfs_vnode *)_v;	TOUCH(nfs);TOUCH(v);	TRACE("nfs_canpage: fsid 0x%x, vnid 0x%Lx\n", nfs->id, VNODETOVNID(v));	return ERR_UNIMPLEMENTED;}ssize_t nfs_readpage(fs_cookie fs, fs_vnode _v, iovecs *vecs, off_t pos){	nfs_fs *nfs = (nfs_fs *)fs;	nfs_vnode *v = (nfs_vnode *)_v;	TOUCH(nfs);TOUCH(v);	TRACE("nfs_readpage: fsid 0x%x, vnid 0x%Lx, vecs %p, pos 0x%Lx\n", nfs->id, VNODETOVNID(v), vecs, pos);	return ERR_UNIMPLEMENTED;}ssize_t nfs_writepage(fs_cookie fs, fs_vnode _v, iovecs *vecs, off_t pos){	nfs_fs *nfs = (nfs_fs *)fs;	nfs_vnode *v = (nfs_vnode *)_v;	TOUCH(nfs);TOUCH(v);	TRACE("nfs_writepage: fsid 0x%x, vnid 0x%Lx, vecs %p, pos 0x%Lx\n", nfs->id, VNODETOVNID(v), vecs, pos);	return ERR_UNIMPLEMENTED;}int nfs_create(fs_cookie fs, fs_vnode _dir, const char *name, void *create_args, vnode_id *new_vnid){	nfs_fs *nfs = (nfs_fs *)fs;	nfs_vnode *dir = (nfs_vnode *)_dir;	TOUCH(nfs);TOUCH(dir);	TRACE("nfs_create: fsid 0x%x, vnid 0x%Lx, name '%s'\n", nfs->id, VNODETOVNID(dir), name);	return ERR_UNIMPLEMENTED;}int nfs_unlink(fs_cookie fs, fs_vnode _dir, const char *name){	nfs_fs *nfs = (nfs_fs *)fs;	nfs_vnode *dir = (nfs_vnode *)_dir;	TOUCH(nfs);TOUCH(dir);	TRACE("nfs_unlink: fsid 0x%x, vnid 0x%Lx, name '%s'\n", nfs->id, VNODETOVNID(dir), name);	return ERR_UNIMPLEMENTED;}int nfs_rename(fs_cookie fs, fs_vnode _olddir, const char *oldname, fs_vnode _newdir, const char *newname){	nfs_fs *nfs = (nfs_fs *)fs;	nfs_vnode *olddir = (nfs_vnode *)_olddir;	nfs_vnode *newdir = (nfs_vnode *)_newdir;	TOUCH(nfs);TOUCH(olddir);TOUCH(newdir);	TRACE("nfs_rename: fsid 0x%x, vnid 0x%Lx, oldname '%s', newdir 0x%Lx, newname '%s'\n", nfs->id, VNODETOVNID(olddir), oldname, VNODETOVNID(newdir), newname);	return ERR_UNIMPLEMENTED;}int nfs_mkdir(fs_cookie _fs, fs_vnode _base_dir, const char *name){	nfs_fs *nfs = (nfs_fs *)_fs;	nfs_vnode *dir = (nfs_vnode *)_base_dir;	TOUCH(nfs);TOUCH(dir);	TRACE("nfs_mkdir: fsid 0x%x, vnid 0x%Lx, name '%s'\n", nfs->id, VNODETOVNID(dir), name);	return ERR_UNIMPLEMENTED;}int nfs_rmdir(fs_cookie _fs, fs_vnode _base_dir, const char *name){	nfs_fs *nfs = (nfs_fs *)_fs;	nfs_vnode *dir = (nfs_vnode *)_base_dir;	TOUCH(nfs);TOUCH(dir);	TRACE("nfs_rmdir: fsid 0x%x, vnid 0x%Lx, name '%s'\n", nfs->id, VNODETOVNID(dir), name);	return ERR_UNIMPLEMENTED;}static int nfs_getattr(nfs_fs *nfs, nfs_vnode *v, nfs_attrstat *attrstat){	return rpc_call(&nfs->rpc, NFSPROG, NFSVERS, NFSPROC_GETATTR, &v->nfs_handle, sizeof(v->nfs_handle), attrstat, sizeof(nfs_attrstat));}int nfs_rstat(fs_cookie fs, fs_vnode _v, struct file_stat *stat){	nfs_fs *nfs = (nfs_fs *)fs;	nfs_vnode *v = (nfs_vnode *)_v;	nfs_attrstat attrstat;	int err;	TRACE("nfs_rstat: fsid 0x%x, vnid 0x%Lx, stat %p\n", nfs->id, VNODETOVNID(v), stat);	sem_acquire(v->sem, 1);	err = nfs_getattr(nfs, v, &attrstat);	if(err < 0)		goto out;	if(ntohl(attrstat.status) != NFS_OK) {		err = ERR_IO_ERROR;		goto out;	}	/* copy the stat over from the nfs attrstat */	stat->vnid = VNODETOVNID(v);	stat->size = ntohl(attrstat.attributes.size);	switch(ntohl(attrstat.attributes.ftype)) {		case NFREG:			stat->type = STREAM_TYPE_FILE;			break;		case NFDIR:			stat->type = STREAM_TYPE_DIR;			break;		default:			stat->type = STREAM_TYPE_DEVICE; // XXX should have unknown type			break;	}	err = NO_ERROR;out:	sem_release(v->sem, 1);	return err;}int nfs_wstat(fs_cookie fs, fs_vnode _v, struct file_stat *stat, int stat_mask){	nfs_fs *nfs = (nfs_fs *)fs;	nfs_vnode *v = (nfs_vnode *)_v;	TOUCH(nfs);TOUCH(v);	TRACE("nfs_wstat: fsid 0x%x, vnid 0x%Lx, stat %p, stat_mask 0x%x\n", nfs->id, VNODETOVNID(v), stat, stat_mask);	return ERR_UNIMPLEMENTED;}static struct fs_calls nfs_calls = {	&nfs_mount,	&nfs_unmount,	&nfs_sync,	&nfs_lookup,	&nfs_getvnode,	&nfs_putvnode,	&nfs_removevnode,	&nfs_opendir,	&nfs_closedir,	&nfs_rewinddir,	&nfs_readdir,	&nfs_open,	&nfs_close,	&nfs_freecookie,	&nfs_fsync,	&nfs_read,	&nfs_write,	&nfs_seek,	&nfs_ioctl,	&nfs_canpage,	&nfs_readpage,	&nfs_writepage,	&nfs_create,	&nfs_unlink,	&nfs_rename,	&nfs_mkdir,	&nfs_rmdir,	&nfs_rstat,	&nfs_wstat};int fs_bootstrap(void);int fs_bootstrap(void){	dprintf("bootstrap_nfs: entry\n");	return vfs_register_filesystem("nfs", &nfs_calls);}

⌨️ 快捷键说明

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