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

📄 init.c

📁 lustre 1.6.5 source code
💻 C
📖 第 1 页 / 共 2 页
字号:
		CREATE_CHR	= 2,		CREATE_BLK	= 3,		CREATE_FILE	= 4	} op;	int	intent_mode;	struct inode *ino;	int	i;  	len = strlen(args);	if (_sysio_get_args(args, v) - args != (ssize_t )len ||	    !(v[0].ovi_value &&	      v[1].ovi_value &&	      v[2].ovi_value))		return -EINVAL;	perms = strtol(v[2].ovi_value, (char **)&cp, 0);	if (*cp ||	    perms < 0 ||	    (perms == LONG_MAX && errno == ERANGE) ||	    ((unsigned)perms & ~07777))		return -EINVAL;	if (v[3].ovi_value) {		owner = strtol(v[3].ovi_value, (char **)&cp, 0);		if (*cp ||		    ((owner == LONG_MIN || owner == LONG_MAX)		     && errno == ERANGE))			return -EINVAL;	} else		owner = getuid();	if (v[4].ovi_value) {		group = strtol(v[4].ovi_value, (char **)&cp, 0);		if (*cp ||		    ((group == LONG_MIN || group == LONG_MAX) &&		     errno == ERANGE))			return -EINVAL;	} else		group = getegid();	if (!(dir = _sysio_cwd) && !(dir = _sysio_root))		return -ENOENT;	/*	 * Init, get the operation, setup the intent.	 */	err = 0;	mode = perms;	op = 0;	if (strcmp(v[0].ovi_value, "dir") == 0) {		op = CREATE_DIR;		INTENT_INIT(&intent, INT_CREAT, &mode, NULL);	} else if (strcmp(v[0].ovi_value, "chr") == 0) {		op = CREATE_CHR;		mode |= S_IFCHR;		INTENT_INIT(&intent, INT_CREAT, &mode, NULL);		if (!(v[5].ovi_value && parse_mm(v[5].ovi_value, &dev) == 0))			err = -EINVAL;	} else if (strcmp(v[0].ovi_value, "blk") == 0) {		op = CREATE_BLK;		mode |= S_IFBLK;		INTENT_INIT(&intent, INT_CREAT, &mode, NULL);		if (!(v[5].ovi_value && parse_mm(v[5].ovi_value, &dev) == 0))			err = -EINVAL;	} else if (strcmp(v[0].ovi_value, "file") == 0) {		op = CREATE_FILE;		intent_mode = O_CREAT|O_EXCL;		INTENT_INIT(&intent, INT_CREAT, &mode, &intent_mode);	} else		err = -EINVAL;	if (err)		return err;	/*	 * Lookup the given path.	 */	err =	    _sysio_namei(dir,			 v[1].ovi_value,			 ND_NEGOK|ND_NOPERMCHECK,			 &intent,			 &pno);	if (err)		return err;	/*	 * Perform.	 */	switch (op) {	case CREATE_DIR:		err = _sysio_mkdir(pno, mode);		break;	case CREATE_CHR:	case CREATE_BLK:		err = _sysio_mknod(pno, mode, dev);		break;	case CREATE_FILE:		err = _sysio_open(pno, O_CREAT|O_EXCL, mode);		if (err)			break;		ino = pno->p_base->pb_ino;		if (v[6].ovi_value) {			struct iovec iovec;			struct intnl_xtvec xtvec;			struct ioctx io_context;			/*			 * Deposit optional file content.			 */			iovec.iov_base = v[6].ovi_value;			iovec.iov_len = strlen(v[6].ovi_value);			xtvec.xtv_off = 0;			xtvec.xtv_len = iovec.iov_len;			IOCTX_INIT(&io_context,				   1,				   1,				   ino,				   &iovec, 1,				   &xtvec, 1);			_sysio_ioctx_enter(&io_context);			err =			    (*ino->i_ops.inop_write)(pno->p_base->pb_ino,						     &io_context);			if (!err) {				ssize_t	cc;				cc = _sysio_ioctx_wait(&io_context);				if (cc < 0)					err = cc;				else if ((size_t )cc != iovec.iov_len)					err = -EIO;		/* huh? */			} else				_sysio_ioctx_complete(&io_context);		}		i = (*ino->i_ops.inop_close)(ino);		if (!err)			err = i;		break;	default:		abort();	}	P_RELE(pno);	return err;}/* * Do mount. * * NB: The passed buffer is altered. */static int do_mnt(char *args) {	size_t	len;	struct option_value_info v[] = {		{ "dev",	NULL },			/* source (type:dev) */		{ "dir",	NULL },			/* target dir */		{ "fl",		NULL },			/* flags */		{ "da",		NULL },			/* mount data */		{ NULL,		NULL }	};	char	*ty, *name;	unsigned long flags;	struct pnode *dir;  	len = strlen(args);	if (_sysio_get_args(args, v) - args != (ssize_t )len ||	    !(v[0].ovi_value && v[1].ovi_value))		return -EINVAL;	ty =	    (char *)_sysio_get_token(v[0].ovi_value,				     1,				     ":",				     "",				     name = v[0].ovi_value);	flags = 0;	if (v[2].ovi_value) {		char	*cp;		/*		 * Optional flags.		 */		flags = strtoul(v[2].ovi_value, &cp, 0);		if (*cp || (flags == ULONG_MAX && errno == ERANGE))			return -EINVAL;	}	if (strlen(v[1].ovi_value) == 1 && v[1].ovi_value[0] == PATH_SEPARATOR) {		/*		 * Aha! It's root they want. Have to do that special.		 */		return _sysio_mount_root(ty, name, flags, v[3].ovi_value);	}	if (!(dir = _sysio_cwd) && !(dir = _sysio_root))		return -ENOENT;	return _sysio_mount(dir,			    ty,			    v[1].ovi_value,			    name,			    flags,			    v[3].ovi_value);}#if 0/* * Chdir * * NB: Alters the passed buffer. */static int do_cd(char *args) {	size_t	len;	struct option_value_info v[] = {		{ "dir",	NULL },			/* directory */		{ NULL,		NULL }	};	int	err;	struct pnode *dir, *pno;	len = strlen(args);	if (_sysio_get_args(args, v) - args != (ssize_t )len || !v[0].ovi_value)		return -EINVAL;	if (!(dir = _sysio_cwd) && !(dir = _sysio_root)) {		/*		 * We have no namespace yet. They really need to give us		 * something to work with.		 */		return -ENOENT;	}	err = _sysio_namei(dir, v[0].ovi_value, 0, NULL, &pno);	if (err)		return err;	err = _sysio_p_chdir(pno);	if (err)		P_RELE(pno);	return err;}#endif/* * Does a chmod * * NB: Alters passed buffer. */static int do_chmd(char *args){	size_t	len;	struct option_value_info v[] = {		{ "src",	NULL },			/* path */		{ "pm",		NULL },			/* perms */		{ NULL,		NULL }	};	long	perms;	char	*cp;	struct intnl_stat stbuf;	int	err;	struct pnode *dir, *pno;  	len = strlen(args);	if (_sysio_get_args(args, v) - args != (ssize_t )len ||	    !(v[0].ovi_value && v[1].ovi_value))		return -EINVAL;	perms = strtol(v[1].ovi_value, &cp, 0);	if (*cp ||	    perms < 0 ||	    (perms == LONG_MAX && errno == ERANGE) ||	    ((unsigned)perms & ~07777))		return -EINVAL;	(void )memset(&stbuf, 0, sizeof(stbuf));	stbuf.st_mode = (mode_t)perms;	if (!(dir = _sysio_cwd) && !(dir = _sysio_root))		return -ENOENT;	err = _sysio_namei(dir, v[0].ovi_value, ND_NOPERMCHECK, NULL, &pno);	if (err)		return err;	err = _sysio_setattr(pno, pno->p_base->pb_ino, SETATTR_MODE, &stbuf);	P_RELE(pno);	return err;}static intdo_open(char *args){	size_t	len;	struct option_value_info v[] = {		{ "nm",		NULL },			/* path */		{ "fd",		NULL },			/* fildes */		{ "m",		NULL },			/* mode */		{ NULL,		NULL }	};	char	*cp;	long	l;	int	fd;	unsigned long ul;	mode_t	m;	struct pnode *dir, *pno;	struct intent intent;	int	err;	struct file *fil;	len = strlen(args);	if (_sysio_get_args(args, v) - args != (ssize_t )len ||	    !(v[0].ovi_value && v[1].ovi_value && v[2].ovi_value))		return -EINVAL;	l = strtol(v[1].ovi_value, (char **)&cp, 0);	if (*cp || l < 0 || _irecheck(l, errno))		return -EINVAL;	fd = (int )l;	ul = strtoul(v[1].ovi_value, (char **)&cp, 0);	if (*cp ||	    (ul == ULONG_MAX && errno == ERANGE))		return -EINVAL;	m = (mode_t )ul & (O_RDONLY|O_WRONLY|O_RDWR);	if (!(dir = _sysio_cwd) && !(dir = _sysio_root))		return -ENOENT;	INTENT_INIT(&intent, INT_OPEN, &m, NULL);	pno = NULL;	err = _sysio_namei(dir, v[0].ovi_value, ND_NOPERMCHECK, &intent, &pno);	if (err)		return err;	fil = NULL;	do {		err = _sysio_open(pno, m, 0);		if (err)			break;		fil = _sysio_fnew(pno->p_base->pb_ino, m);		if (!fil) {			err = -ENOMEM;			break;		}		err = _sysio_fd_set(fil, fd, 1);		if (err < 0)			break;		P_RELE(pno);		return 0;	} while (0);	if (fil)		F_RELE(fil);	if (pno)		P_RELE(pno);	return err;}/* * Execute the given cmd. * * NB: Buf is altered. */static int do_command(char *buf){	size_t	len;	char	*args, *cmd;	len = strlen(buf);	args = (char *)_sysio_get_token(buf, 1, ",", IGNORE_WHITE, cmd = buf);	if (args) {		if (strcmp("creat", cmd) == 0)			return do_creat(args);		if (strcmp("mnt", cmd) == 0)			return do_mnt(args);#if 0		if (strcmp("cd", cmd) == 0)			return do_cd(args);#endif		if (strcmp("chmd", cmd) == 0)			return do_chmd(args);		if (strcmp("open", cmd) == 0)			return do_open(args);	}	return -EINVAL;}#ifdef SYSIO_TRACING/* * Set/Unset tracing. */static int_sysio_boot_tracing(const char *arg){	long	l;	char	*cp;	static struct trace_callback		*entcb = NULL,		*exitcb = NULL;	l = 0;	if (arg) {		l = strtol(arg, (char **)&cp, 0);		if (*cp || !(l == 0 || l == 1))			return -EINVAL;	}	if (l) {		if (entcb == NULL)			entcb =			    _sysio_register_trace(_sysio_entry_trace_q,						  _sysio_trace_entry,						  NULL,						  NULL);		if (entcb == NULL)			return -errno;		if (exitcb == NULL)			exitcb =			    _sysio_register_trace(_sysio_exit_trace_q,						  _sysio_trace_exit,						  NULL,						  NULL);		if (exitcb == NULL)			return -errno;	} else {		if (entcb != NULL)			_sysio_remove_trace(_sysio_entry_trace_q, entcb);		entcb = NULL;		if (exitcb != NULL)			_sysio_remove_trace(_sysio_exit_trace_q, exitcb);		exitcb = NULL;	}	return 0;}#endif/* * Initialize the namespace. */static int_sysio_boot_namespace(const char *arg){	char	c, *tok;	ssize_t	len;	int	err;	unsigned count;	/*	 * Allocate token buffer.	 */	len = strlen(arg);	tok = malloc(len ? len : 1);	if (!tok)		return -ENOMEM;	err = 0;	count = 0;	while (1) {		/*		 * Discard leading white space.		 */		while ((c = *arg) != '\0' && strchr(IGNORE_WHITE, c))			arg++;		if (COMMENT_INTRO == c) {			/*			 * Discard comment.			 */			while (*arg && (*arg != '\n')) {				++arg;			}			continue;		}		if (c == '\0')			break;		if (c != '{') {			err = -EINVAL;			break;		}		/*		 * Get the command.		 */		*tok = '\0';		arg =		    (char *)_sysio_get_token(arg + 1,					     0,					     "}",					     IGNORE_WHITE,					     tok);		if (!arg) {			err = -EINVAL;			break;		}		count++;		/*		 * Perform.		 */		err = do_command(tok);		if (err)			break;	}#ifdef SYSIO_TRACING	if (err)		_sysio_cprintf("+NS init+ failed at expr %u (last = %s): %s\n", 			       count,			       tok && *tok ? tok : "NULL",			       strerror(-err));#endif	free(tok);	return err;}#ifdef DEFER_INIT_CWD/* * Set deferred initial working directory. */static int_sysio_boot_cwd(const char *arg){	_sysio_init_cwd = arg;	return 0;}#endif/* * Given an identifier and it's arguments, perform optional initializations. */int_sysio_boot(const char *opt, const char *arg){	struct option_value_info vec[] = {#ifdef SYSIO_TRACING		{ "trace",	NULL },			/* tracing? */#endif		{ "namespace",	NULL },			/* init namespace? */#ifdef DEFER_INIT_CWD		{ "cwd",	NULL },			/* init working dir */#endif		{ NULL,		NULL }	};	struct option_value_info *v;	unsigned u;	static int (*f[])(const char *) = {#ifdef SYSIO_TRACING		_sysio_boot_tracing,#endif		_sysio_boot_namespace,#ifdef DEFER_INIT_CWD		_sysio_boot_cwd,#endif		NULL					/* can't happen */	};	for (v = vec, u = 0; v->ovi_name; v++, u++)		if (strcmp(v->ovi_name, opt) == 0)			break;	if (!v->ovi_name)		return -EINVAL;	return (*f[u])(arg);}

⌨️ 快捷键说明

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