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

📄 fs_incore.c

📁 非常经典的一个分布式系统
💻 C
📖 第 1 页 / 共 3 页
字号:
	return 0;}static int_sysio_incore_dirop_mkdir(struct pnode *pno, mode_t mode){	struct intnl_stat stat;	struct incore_inode *icino, *parent;	ino_t	inum;	int	err;	struct intnl_dirent *de = NULL;	struct inode *ino;	ino = pno->p_parent->p_base->pb_ino;	parent = I2IC(ino);	if (!S_ISDIR(parent->ici_st.st_mode))		return -ENOTDIR;	(void )memset(&stat, 0, sizeof(stat));	stat.st_dev = pno->p_parent->p_base->pb_ino->i_fs->fs_dev;	inum = incore_inum_alloc();#ifdef HAVE__ST_INO	stat.__st_ino = inum;#endif	stat.st_mode = S_IFDIR | (mode & 07777);	stat.st_nlink = 2;	stat.st_uid = getuid();	stat.st_gid = getgid();	stat.st_size = 0;	stat.st_blksize = 4096;	stat.st_blocks = 0;	stat.st_ctime = stat.st_mtime = stat.st_atime = 0;	stat.st_ino = inum;	icino = incore_directory_new(FS2ICFS(ino->i_fs), parent, &stat);	if (!icino)		return -ENOSPC;	/*	 * Tell the system about the new inode.	 *	 * Persistent across remounts because we ask for immunity.	 */	ino =	    _sysio_i_new(pno->p_parent->p_base->pb_ino->i_fs,			 &icino->ici_fileid,			 &stat,			 1,			 &_sysio_incore_dir_ops,			 icino);	if (!ino) {		incore_i_destroy(icino);		return -ENOMEM;	}	/*	 * Insert into parent.	 */	err =	    incore_directory_insert(parent,				    &pno->p_base->pb_name,				    stat.st_ino,				    INCORE_D_TYPEOF(S_IFDIR));	if (err) {		de->d_ino = 0;				/* bad parent */		I_RELE(ino);		_sysio_i_gone(ino);		return err;	}	pno->p_base->pb_ino = ino;	return 0;}static intincore_unlink_entry(struct incore_inode *icino,		    struct qstr *name){	struct lookup_data lookup_data;	struct intnl_dirent *de;	size_t	reclen;#ifdef _DIRENT_HAVE_D_OFF	size_t	off;#endif	if (!S_ISDIR(icino->ici_st.st_mode))		return -ENOTDIR;	INCORE_LD_INIT(&lookup_data, 0, name);	de =	    incore_directory_probe(icino->ici_data,				   icino->ici_st.st_size,				   0,				   (probe_ty )incore_directory_match,				   NULL,				   &lookup_data);	if (!de)		return -ENOENT;	assert((size_t )((char *)de - (char *)icino->ici_data) >=	       sizeof(incore_dir_template));#ifndef _DIRENT_HAVE_D_OFF	reclen = de->d_reclen;#else	off = de->d_off;	reclen = off - ((char *)de - (char *)icino->ici_data);#endif	(void )memset(de, 0, reclen);#ifndef _DIRENT_HAVE_D_OFF	de->d_type = (__uint8_t )DTTOIF(DT_WHT);	de->d_reclen = reclen;#else	lookup_data.de->d_off = off;#endif	/*	 * Adjust link count.	 */	assert(icino->ici_st.st_nlink > 2);	icino->ici_st.st_nlink--;	return 0;}static int_sysio_incore_dirop_rmdir(struct pnode *pno){	struct inode *ino = pno->p_base->pb_ino;	struct incore_inode *icino = I2IC(ino);	int	err;	if (!pno->p_base->pb_name.len ||	    (pno->p_base->pb_name.name[0] == '.' &&	     (pno->p_base->pb_name.len == 1 ||	      (pno->p_base->pb_name.len == 2 &&	       pno->p_base->pb_name.name[1] == '.'))))		return -EINVAL;	if (!S_ISDIR(icino->ici_st.st_mode))		return -ENOTDIR;	if (icino->ici_st.st_nlink > 2)		return -ENOTEMPTY;	pno->p_base->pb_ino = NULL;	err =	    incore_unlink_entry(I2IC(pno->p_parent->p_base->pb_ino),				&pno->p_base->pb_name);	return err;}static intincore_create(struct pnode *pno, struct intnl_stat *stat){	struct inode *dino, *ino;	struct incore_inode *icino;	int	err;	dino = pno->p_parent->p_base->pb_ino;	assert(dino);	icino = incore_i_alloc(FS2ICFS(dino->i_fs), stat);	if (!icino)		return -ENOSPC;	/*	 * Tell the system about the new inode.	 */	ino =	    _sysio_i_new(dino->i_fs,			 &icino->ici_fileid,			 stat,			 1,			 S_ISREG(stat->st_mode)			   ? &_sysio_incore_file_ops			   : &_sysio_incore_dev_ops,			 icino);	if (!ino) {		incore_i_destroy(icino);		return -ENOMEM;	}	/*	 * Insert into parent.	 */	err =	    incore_directory_insert(I2IC(dino),				    &pno->p_base->pb_name,				    stat->st_ino,				    INCORE_D_TYPEOF(icino->ici_st.st_mode));	if (err) {		I_RELE(ino);		_sysio_i_gone(ino);		return err;	}	pno->p_base->pb_ino = ino;	return 0;}static int_sysio_incore_inop_open(struct pnode *pno, int flags __IS_UNUSED, mode_t mode){	struct intnl_stat stat;	ino_t	inum;	/*	 * File exists. Nothing to do.	 */	if (pno->p_base->pb_ino)		return 0;	/*	 * Must create a new, regular, file.	 */	(void )memset(&stat, 0, sizeof(stat));	stat.st_dev = pno->p_parent->p_base->pb_ino->i_fs->fs_dev;	inum = incore_inum_alloc();#ifdef HAVE__ST_INO	stat.__st_ino = inum;#endif	stat.st_mode = S_IFREG | (mode & 07777);	stat.st_nlink = 1;	stat.st_uid = getuid();	stat.st_gid = getgid();	stat.st_rdev = 0;	stat.st_size = 0;	stat.st_blksize = 4096;	stat.st_blocks = 0;	stat.st_ctime = stat.st_mtime = stat.st_atime = 0;	stat.st_ino = inum;	return incore_create(pno, &stat);}static int_sysio_incore_inop_close(struct inode *ino __IS_UNUSED){	return 0;}static int_sysio_incore_dirop_link(struct pnode *old, struct pnode *new){	struct incore_inode *icino = I2IC(old->p_base->pb_ino);	int	err;	assert(!new->p_base->pb_ino);	assert(!S_ISDIR(old->p_base->pb_ino->i_stbuf.st_mode));	/*	 * Can bump the link count?	 */	if (!(icino->ici_st.st_nlink + 1))		return -EMLINK;	/*	 * Insert into parent.	 */	err =	    incore_directory_insert(I2IC(new->p_parent->p_base->pb_ino),				    &new->p_base->pb_name,				    icino->ici_st.st_ino,				    INCORE_D_TYPEOF(icino->ici_st.st_mode));	if (err)		return err;	/*	 * Bump the link count.	 */	icino->ici_st.st_nlink++;	return 0;}static int_sysio_incore_dirop_rename(struct pnode *old, struct pnode *new){	int	err;	struct incore_inode *icino = I2IC(old->p_base->pb_ino);	if (new->p_base->pb_ino) {		/*		 * Have to kill off the target first.		 */		if (S_ISDIR(I2IC(new->p_base->pb_ino)->ici_st.st_mode) &&		    I2IC(new->p_base->pb_ino)->ici_st.st_nlink > 2)			return -ENOTEMPTY;		err =		    incore_unlink_entry(I2IC(new->p_parent->p_base->pb_ino),					&new->p_base->pb_name);		if (err)			return err;	}	/*	 * Insert into new parent.	 */	err =	    incore_directory_insert(I2IC(new->p_parent->p_base->pb_ino),				    &new->p_base->pb_name,				    icino->ici_st.st_ino,				    INCORE_D_TYPEOF(icino->ici_st.st_mode));	if (err)		abort();	/*	 * Remove from the old parent.	 */	err =	    incore_unlink_entry(I2IC(old->p_parent->p_base->pb_ino),				&old->p_base->pb_name);	if (err)		abort();	if (S_ISDIR(icino->ici_st.st_mode)) {		struct intnl_dirent *de;		/*		 * We moved a directory. The entry for `..' must be corrected.		 */		de = icino->ici_data;		de++;		assert(strcmp(de->d_name, "..") == 0);		de->d_ino = I2IC(new->p_parent->p_base->pb_ino)->ici_st.st_ino;	}	return 0;}static int_sysio_incore_dirop_unlink(struct pnode *pno){	struct inode *ino = pno->p_base->pb_ino;	struct incore_inode *icino = I2IC(ino);	int	err;	if (S_ISDIR(icino->ici_st.st_mode))		return -EISDIR;	err =	    incore_unlink_entry(I2IC(pno->p_parent->p_base->pb_ino),				&pno->p_base->pb_name);	return err;}static intdoio(ssize_t (*f)(void *, size_t, _SYSIO_OFF_T, struct incore_inode *),     struct inode *ino,     struct ioctx *ioctx){	ioctx->ioctx_cc =	    _sysio_doio(ioctx->ioctx_xtv, ioctx->ioctx_xtvlen,			ioctx->ioctx_iov, ioctx->ioctx_iovlen,			(ssize_t (*)(void *, size_t, _SYSIO_OFF_T, void *))f,			I2IC(ino));	if (ioctx->ioctx_cc  < 0) {		ioctx->ioctx_errno = -ioctx->ioctx_cc;		ioctx->ioctx_cc = -1;	}	ioctx->ioctx_done = 1;	return 0;}static ssize_tincore_read(void *buf, size_t nbytes,	    _SYSIO_OFF_T off,	    struct incore_inode *icino){	size_t	n;	if (off < 0)		return -EINVAL;	if (!nbytes || off > icino->ici_st.st_size)		return 0;	n = icino->ici_st.st_size - (size_t )off;	if (n > nbytes)		n = nbytes;	(void )memcpy(buf, (char *)icino->ici_data + off, (size_t )n);	return (ssize_t )n;}static int_sysio_incore_filop_read(struct inode *ino, struct ioctx *ioctx){		return doio(incore_read, ino, ioctx);}static ssize_tincore_write(const void *buf, size_t nbytes,	     _SYSIO_OFF_T off,	     struct incore_inode *icino){	_SYSIO_OFF_T pos;	if (off < 0)		return -EINVAL;	if (!nbytes || off > icino->ici_st.st_size)		return 0;	pos = off + nbytes;	if (off && pos <= off) {		/*		 * It's all or nothing. We won't write just part of		 * the buffer.		 */		return -EFBIG;	}	if (pos > icino->ici_st.st_size) {		int	err;		err = incore_trunc(icino, (size_t )pos, 0);		if (err)			return err;	}	(void )memcpy((char *)icino->ici_data + off, buf, nbytes);	return (ssize_t )nbytes;}static int_sysio_incore_filop_write(struct inode *ino, struct ioctx *ioctx){	return doio((ssize_t (*)(void *, size_t,				 _SYSIO_OFF_T,				 struct incore_inode *))incore_write,		    ino,		    ioctx);}static _SYSIO_OFF_T_sysio_incore_filop_pos(struct inode *ino __IS_UNUSED, _SYSIO_OFF_T off){	return off;}static int_sysio_incore_filop_iodone(struct ioctx *iocp __IS_UNUSED){	/*	 * It's always done in this driver. It completed when posted.	 */	return 1;}static int_sysio_incore_filop_fcntl(struct inode *ino __IS_UNUSED,			  int cmd __IS_UNUSED,			  va_list ap __IS_UNUSED,			  int *rtn){	/*	 * No fcntl's supported.	 */	*rtn = -1;	return -ENOTTY;}static int_sysio_incore_inop_sync(struct inode *ino __IS_UNUSED){	/*	 * With what?	 */	return 0;}static int_sysio_incore_filop_ioctl(struct inode *ino __IS_UNUSED,			  unsigned long int request __IS_UNUSED,			  va_list ap __IS_UNUSED){	/*	 * No ioctl's supported.	 */	return -ENOTTY;}static int_sysio_incore_dirop_mknod(struct pnode *pno, mode_t mode, dev_t dev){	mode_t	m;	struct intnl_stat stat;	ino_t	inum;	assert(!pno->p_base->pb_ino);	m = mode & S_IFMT;	if (S_ISCHR(m))		m &= ~S_IFCHR;	else if (S_ISFIFO(m))		m &= ~S_IFIFO;	else if (S_ISBLK(m))		m &= ~S_IFCHR;	else		return -EINVAL;	if (m)		return -EINVAL;	/*	 * Initialize attributes.	 */	(void )memset(&stat, 0, sizeof(stat));	stat.st_dev = pno->p_parent->p_base->pb_ino->i_fs->fs_dev;	inum = incore_inum_alloc();#ifdef HAVE__ST_INO	stat.__st_ino = inum;#endif	stat.st_mode = mode;	stat.st_nlink = 1;	stat.st_uid = getuid();	stat.st_gid = getgid();	stat.st_rdev = dev;	stat.st_size = 0;	stat.st_blksize = 4096;	stat.st_blocks = 0;	stat.st_ctime = stat.st_mtime = stat.st_atime = 0;	stat.st_ino = inum;	return incore_create(pno, &stat);}#ifdef _HAVE_STATVFSstatic int_sysio_incore_inop_statvfs(struct pnode *pno,			   struct inode *ino,			   struct intnl_statvfs *buf){	struct filesys *fs;	if (!ino)		ino = pno->p_base->pb_ino;	assert(ino);	fs = pno->p_base->pb_ino->i_fs;	(void )memset(buf, 0, sizeof(struct intnl_statvfs));	/*	 * Mostly, we lie.	 */	buf->f_bsize = fs->fs_bsize;	buf->f_frsize = buf->f_bsize;	buf->f_blocks = ~0;	buf->f_blocks /= buf->f_bsize;	buf->f_bfree = buf->f_blocks - 1;	buf->f_bavail = buf->f_bfree;	buf->f_files = buf->f_blocks;	buf->f_ffree = buf->f_files - 1;	buf->f_favail = buf->f_ffree;	buf->f_fsid = fs->fs_id;	buf->f_flag = 0;	buf->f_namemax = ULONG_MAX;	return 0;}#endifvoid_sysio_incore_inop_gone(struct inode *ino){	struct incore_inode *icino = I2IC(ino);	incore_i_destroy(icino);}

⌨️ 快捷键说明

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