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

📄 fs_native.c

📁 非常经典的一个分布式系统
💻 C
📖 第 1 页 / 共 3 页
字号:
			fd = err;		}	}	free(path);	if (fd < 0)		return -errno;	/*	 * Remember this new open.	 */	nino = I2NI(pno->p_base->pb_ino);	nino->ni_nopens++;	assert(nino->ni_nopens);	if (nino->ni_fd >= 0) {		if ((nino->ni_oflags & O_RDWR) ||		    (flags & (O_RDONLY|O_WRONLY|O_RDWR)) == O_RDONLY) {			/*			 * Keep existing.			 */			(void )syscall(SYSIO_SYS_close, fd);			return 0;		}		(void )syscall(SYSIO_SYS_close, nino->ni_fd);	}	/*	 * Invariant; First open. Must init.	 */	nino->ni_resetfpos = 0;	nino->ni_fpos = 0;	nino->ni_fd = fd;	/*	 * Need to know whether we can seek on this	 * descriptor.	 */	nino->ni_seekok =	    native_pos(nino->ni_fd, &nino->ni_fpos, SEEK_CUR) != 0 ? 0 : 1;	return 0;}static intnative_inop_close(struct inode *ino){	struct native_inode *nino = I2NI(ino);	int	err;	if (nino->ni_fd < 0)		abort();	assert(nino->ni_nopens);	if (--nino->ni_nopens) {		/*		 * Hmmm. We really don't need anything else. However, some		 * filesystems try to implement a sync-on-close semantic.		 * As this appears now, that is lost. Might want to change		 * it somehow in the future?		 */		return 0;	}	err = syscall(SYSIO_SYS_close, nino->ni_fd);	if (err)		return -errno;	nino->ni_fd = -1;	nino->ni_resetfpos = 0;	nino->ni_fpos = 0;	return 0;}static intnative_inop_link(struct pnode *old, struct pnode *new){	int	err;	char	*opath, *npath;	err = 0;	opath = _sysio_pb_path(old->p_base, '/');	npath = _sysio_pb_path(new->p_base, '/');	if (!(opath && npath)) {		err = -ENOMEM;		goto out;	}	err = syscall(SYSIO_SYS_link, opath, npath);	if (err != 0)		err = -errno;out:	if (opath)		free(opath);	if (npath)		free(npath);	return err;}static intnative_inop_unlink(struct pnode *pno){	char	*path;	int	err = 0;	path = _sysio_pb_path(pno->p_base, '/');	if (!path)		return -ENOMEM;	/*	 * For this driver, unlink is easy with open files. Since the	 * file remains open to the system, too, the descriptors are still	 * valid.	 *	 * Other drivers will have some difficulty here as the entry in the	 * file system name space must be removed without sacrificing access	 * to the file itself. In NFS this is done with a mechanism referred	 * to as a `silly delete'. The file is moved to a temporary name	 * (usually .NFSXXXXXX, where the X's are replaced by the PID and some	 * unique characters) in order to simulate the proper semantic.	 */	if (syscall(SYSIO_SYS_unlink, path) != 0)		err = -errno;	free(path);	return err;}static intnative_inop_rename(struct pnode *old, struct pnode *new){	int	err;	char	*opath, *npath;	opath = _sysio_pb_path(old->p_base, '/');	npath = _sysio_pb_path(new->p_base, '/');	if (!(opath && npath)) {		err = -ENOMEM;		goto out;	}	err = syscall(SYSIO_SYS_rename, opath, npath);	if (err != 0)		err = -errno;out:	if (opath)		free(opath);	if (npath)		free(npath);	return err;}static ssize_tdopio(void *buf, size_t count, _SYSIO_OFF_T off, struct native_io *nio){	ssize_t	cc;	if (!nio->nio_nino->ni_seekok) {		if (off != nio->nio_nino->ni_fpos) {			/*			 * They're trying to reposition. Can't			 * seek on this descriptor so we err out now.			 */			errno = ESPIPE;			return -1;		}		cc =		    syscall(nio->nio_op == 'r'			      ? SYSIO_SYS_read			      : SYSIO_SYS_write,			    nio->nio_nino->ni_fd,			    buf,			    count);		if (cc > 0)			nio->nio_nino->ni_fpos += cc;	} else		cc =		    syscall((nio->nio_op == 'r'			       ? SYSIO_SYS_pread			       : SYSIO_SYS_pwrite),			    nio->nio_nino->ni_fd,			    buf,			    count,			    off);	return cc;}static ssize_tdoiov(const struct iovec *iov,      int count,      _SYSIO_OFF_T off,      ssize_t limit,      struct native_io *nio){	ssize_t	cc;#if !(defined(REDSTORM) || defined(MAX_IOVEC))#define MAX_IOVEC      INT_MAX#endif	if (count <= 0)		return -EINVAL;	/*	 * Avoid the reposition call if we're already at the right place.	 * Allows us to access pipes and fifos.	 */	if (off != nio->nio_nino->ni_fpos) {		int	err;		err = native_pos(nio->nio_nino->ni_fd, &off, SEEK_SET);		if (err) {			nio->nio_nino->ni_resetfpos = 1;			return err;		}		nio->nio_nino->ni_resetfpos = 0;		nio->nio_nino->ni_fpos = off;	}	/*	 * The {read,write}v is safe as this routine is only ever called	 * by _sysio_enumerate_extents() and that routine is exact. It never	 * passes iovectors including tails.	 */	cc =#ifndef REDSTORM	    count <= MAX_IOVEC	      ? syscall(nio->nio_op == 'r' ? SYSIO_SYS_readv : SYSIO_SYS_writev,			nio->nio_nino->ni_fd,			iov,			count)	      :#endif	        _sysio_enumerate_iovec(iov,				       count,				       off,				       limit,				       (ssize_t (*)(void *,						    size_t,						    _SYSIO_OFF_T,						    void *))dopio,				       nio);	if (cc < 0)		cc = -errno;	else		nio->nio_nino->ni_fpos += cc;	return cc;#if !(defined(REDSTORM) || defined(MAX_IOVEC))#undef MAX_IOVEC#endif}#if 0static intlockop_all(struct native_inode *nino,	   struct intnl_xtvec *xtv,	   size_t count,	   short op){	struct flock flock;	int	err;	if (!count)		return -EINVAL;	flock.l_type = op;	flock.l_whence = SEEK_SET;	while (count--) {		flock.l_start = xtv->xtv_off;		flock.l_len = xtv->xtv_len;		xtv++;		err =		    syscall(SYSIO_SYS_fcntl,			    nino->ni_fd,			    F_SETLK,			    &flock);		if (err != 0)			return -errno;	}	return 0;}static intorder_xtv(const struct intnl_xtvec *xtv1, const struct intnl_xtvec *xtv2){	if (xtv1->xtv_off < xtv2->xtv_off)		return -1;	if (xtv1->xtv_off > xtv2->xtv_off)		return 1;	return 0;}#endifstatic intdoio(char op, struct ioctx *ioctx){	struct native_inode *nino;#if 0	int	dolocks;	struct intnl_xtvec *oxtv;	int	err;#endif	struct native_io arguments;	ssize_t	cc;#if 0	struct intnl_xtvec *front, *rear, tmp;#endif	nino = I2NI(ioctx->ioctx_ino);#if 0	dolocks = ioctx->ioctx_xtvlen > 1 && nino->ni_seekok;	if (dolocks) {		/*		 * Must lock the regions (in order!) since we can't do		 * strided-IO as a single atomic operation.		 */		oxtv = malloc(ioctx->ioctx_xtvlen * sizeof(struct intnl_xtvec));		if (!oxtv)			return -ENOMEM;		(void )memcpy(oxtv,			      ioctx->ioctx_xtv, 			      ioctx->ioctx_xtvlen * sizeof(struct intnl_xtvec));		qsort(oxtv,		      ioctx->ioctx_xtvlen,		      sizeof(struct intnl_xtvec),		      (int (*)(const void *, const void *))order_xtv);		err =	            lockop_all(nino,			       oxtv, ioctx->ioctx_xtvlen,			       op == 'r' ? F_RDLCK : F_WRLCK);		if (err) {			free(oxtv);			return err;		}	}#endif	arguments.nio_op = op;	arguments.nio_nino = nino;	cc =	    _sysio_enumerate_extents(ioctx->ioctx_xtv, ioctx->ioctx_xtvlen, 				     ioctx->ioctx_iov, ioctx->ioctx_iovlen,				     (ssize_t (*)(const struct iovec *,						  int,						  _SYSIO_OFF_T,						  ssize_t,						  void *))doiov,				     &arguments);#if 0	if (dolocks) {		/*		 * Must unlock in reverse order.		 */		front = oxtv;		rear = front + ioctx->ioctx_xtvlen - 1;		while (front < rear) {			tmp = *front;			*front++ = *rear;			*rear-- = tmp;		}		if (lockop_all(nino, oxtv, ioctx->ioctx_xtvlen, F_UNLCK) != 0)			abort();		free(oxtv);	}#endif	if ((ioctx->ioctx_cc = cc) < 0) {		ioctx->ioctx_errno = -ioctx->ioctx_cc;		ioctx->ioctx_cc = -1;	}	return 0;}static intnative_inop_read(struct inode *ino __IS_UNUSED, struct ioctx *ioctx){	return doio('r', ioctx);}static intnative_inop_write(struct inode *ino __IS_UNUSED, struct ioctx *ioctx){	return doio('w', ioctx);}static _SYSIO_OFF_Tnative_inop_pos(struct inode *ino, _SYSIO_OFF_T off){	struct native_inode *nino = I2NI(ino);	int	err;	err = native_pos(nino->ni_fd, &off, SEEK_SET);	return err < 0 ? err : off;}static intnative_inop_iodone(struct ioctx *ioctxp __IS_UNUSED){	/*	 * It's always done in this driver. It completed when posted.	 */	return 1;}static intnative_inop_fcntl(struct inode *ino,		  int cmd,		  va_list ap,		  int *rtn){	struct native_inode *nino = I2NI(ino);	long	arg;	int	err;	if (nino->ni_fd < 0)		abort();	err = 0;	switch (cmd) {	case F_GETFD:	case F_GETFL:#ifdef F_GETOWN	case F_GETOWN:#endif		*rtn = syscall(SYSIO_SYS_fcntl, nino->ni_fd, cmd);		if (*rtn == -1)			err = -errno;		break;	case F_DUPFD:	case F_SETFD:	case F_SETFL:	case F_GETLK:	case F_SETLK:	case F_SETLKW:#ifdef F_SETOWN	case F_SETOWN:#endif		arg = va_arg(ap, long);		*rtn = syscall(SYSIO_SYS_fcntl, nino->ni_fd, cmd, arg);		if (*rtn == -1)			err = -errno;		break;	default:		*rtn = -1;		err = -EINVAL;	}	return err;}static intnative_inop_mknod(struct pnode *pno __IS_UNUSED,		  mode_t mode __IS_UNUSED,		  dev_t dev __IS_UNUSED){	return -ENOSYS;}#ifdef _HAVE_STATVFSstatic intnative_inop_statvfs(struct pnode *pno,		    struct inode *ino,		    struct intnl_statvfs *buf){	char	*path;	int    rc;	struct statfs fs;	path = NULL;	if (!ino || I2NI(ino)->ni_fd < 0) {		path = _sysio_pb_path(pno->p_base, '/');		if (!path)			return -ENOMEM;	}	/*	 * The syscall interface does not support SYSIO_SYS_fstatvfs.	 * Should possibly return ENOSYS, but thought it	 * better to use SYSIO_SYS_fstatfs and fill in as much of	 * the statvfs structure as possible.  This allows	 * for more of a test of the sysio user interface.	 */	rc =	    path	      ? syscall(SYSIO_SYS_statfs, path, &fs)	      : syscall(SYSIO_SYS_fstatfs, I2NI(ino)->ni_fd, &fs);	if (path)		free(path);	if (rc < 0)		return -errno;	buf->f_bsize = fs.f_bsize;  /* file system block size */	buf->f_frsize = fs.f_bsize; /* file system fundamental block size */	buf->f_blocks = fs.f_blocks;	buf->f_bfree = fs.f_bfree;	buf->f_bavail = fs.f_bavail;	buf->f_files = fs.f_files;  /* Total number serial numbers */	buf->f_ffree = fs.f_ffree;  /* Number free serial numbers */	buf->f_favail = fs.f_ffree; /* Number free ser num for non-privileged*/	buf->f_fsid = fs.f_fsid.__val[1];	buf->f_flag = 0;            /* No equiv in statfs; maybe use type? */	buf->f_namemax = fs.f_namelen;	return 0;}#endifstatic intnative_inop_sync(struct inode *ino){	int	err;	assert(I2NI(ino)->ni_fd >= 0);	err = syscall(SYSIO_SYS_fsync, I2NI(ino)->ni_fd);	if (err)		err = -errno;	return err;}static intnative_inop_datasync(struct inode *ino){	struct native_inode *nino;	int	err;	nino = I2NI(ino);	assert(nino->ni_fd >= 0);#ifdef SYSIO_SYS_fdatasync	err = syscall(SYSIO_SYS_fdatasync, I2NI(ino)->ni_fd);#else#if 0#warning No fdatasync system call -- Using fsync instead!#endif	err = syscall(SYSIO_SYS_fsync, I2NI(ino)->ni_fd);#endif	if (err)		err = -errno;	return err;}#ifdef HAVE_LUSTRE_HACKstatic intnative_inop_ioctl(struct inode *ino,		  unsigned long int request,		  va_list ap){	struct native_inode *nino;	long arg1, arg2, arg3, arg4;	int	rtn;	nino = I2NI(ino);	assert(nino->ni_fd >= 0);	arg1 = va_arg(ap, long);	arg2 = va_arg(ap, long);	arg3 = va_arg(ap, long);	arg4 = va_arg(ap, long);	rtn =	    syscall(SYSIO_SYS_ioctl, I2NI(ino)->ni_fd, request,		    arg1, arg2, arg3, arg4);	if (rtn < 0)		rtn = -errno;	return rtn;}#elsestatic intnative_inop_ioctl(struct inode *ino __IS_UNUSED,		  unsigned long int request __IS_UNUSED,		  va_list ap __IS_UNUSED){	/*	 * I'm lazy. Maybe implemented later.	 */	return -ENOTTY;}#endifstatic voidnative_inop_gone(struct inode *ino){	struct native_inode *nino = I2NI(ino);	if (nino->ni_fd >= 0)		(void )syscall(SYSIO_SYS_close, nino->ni_fd);	free(ino->i_private);}static voidnative_fsop_gone(struct filesys *fs __IS_UNUSED){	free(fs->fs_private);	/*	 * Do nothing. There is no private part maintained for the	 * native file interface.	 */}

⌨️ 快捷键说明

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