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

📄 inode.c

📁 lustre 1.6.5 source code
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifdef ZERO_SUM_MEMORY/* * Shutdown */void_sysio_i_shutdown(){	struct pnodes_block *pnblk;	while ((pnblk = pnblocks.lh_first)) {		LIST_REMOVE(pnblk, pnblk_links);		free(pnblk);	}}#endif/* * Allocate, initialize and establish appropriate links for new path (alias) * node. */struct pnode *_sysio_p_new_alias(struct pnode *parent,		   struct pnode_base *pb,		   struct mount *mnt){	struct pnode *pno;	assert(!pb->pb_name.name || pb->pb_name.hashval);	pno = free_pnodes.lh_first;	if (!pno) {		more_pnodes();		pno = free_pnodes.lh_first;	}	if (!pno)		return NULL;	LIST_REMOVE(pno, p_links);	pno->p_ref = 1;	pno->p_parent = parent;	if (!pno->p_parent)		pno->p_parent = pno;	pno->p_base = pb;	pno->p_mount = mnt;	pno->p_cover = NULL;	LIST_INSERT_HEAD(&pb->pb_aliases, pno, p_links);	TAILQ_INSERT_TAIL(&_sysio_pnodes, pno, p_nodes);	return pno;}/* * For reclamation of idle path (alias) node. */void_sysio_p_gone(struct pnode *pno){	struct pnode_base *pb;	assert(!pno->p_ref);	assert(!pno->p_cover);	TAILQ_REMOVE(&_sysio_pnodes, pno, p_nodes);	LIST_REMOVE(pno, p_links);	pb = pno->p_base;	if (!(pb->pb_aliases.lh_first || pb->pb_children.lh_first))		_sysio_pb_gone(pb);	LIST_INSERT_HEAD(&free_pnodes, pno, p_links);}/* * (Re)Validate passed path node. */int_sysio_p_validate(struct pnode *pno, struct intent *intnt, const char *path){	struct inode *ino;	struct pnode_base *rootpb;	int	err;	ino = pno->p_base->pb_ino;	/*	 * An invalid pnode will not have an associated inode. We'll use	 * the FS root inode, then -- It *must* be valid.	 */	rootpb = pno->p_mount->mnt_root->p_base;	assert(rootpb->pb_ino);	err =	    rootpb->pb_ino->i_ops.inop_lookup(pno,					      &ino,					      intnt,					      path);	/*	 * If the inode lookup returns a different inode, release the old if	 * present and point to the new.	 */	if (err || pno->p_base->pb_ino != ino) {		if (pno->p_base->pb_ino)			I_RELE(pno->p_base->pb_ino);		pno->p_base->pb_ino = ino;	}	return err;}/* * Find (or create!) an alias for the given parent and name. A misnomer, * really -- This is a "get". Returned path node is referenced. */int_sysio_p_find_alias(struct pnode *parent,		    struct qstr *name,		    struct pnode **pnop){	struct pnode_base *pb;	int	err;	struct pnode *pno;	/*	 * Find the named child.	 */	if (name->len) {		/*		 * Try the names table.		 */		pb = names[name->hashval % NAMES_TABLE_LEN].lh_first;		while (pb) {			if (pb->pb_parent == parent->p_base &&			    pb->pb_name.len == name->len &&			    strncmp(pb->pb_name.name,				    name->name,				    name->len) == 0)				break;			pb = pb->pb_names.le_next;		}	} else {		/*		 * Brute force through the parent's list of children.		 */		pb = parent->p_base->pb_children.lh_first;		while (pb) {			if (pb->pb_parent == parent->p_base &&			    pb->pb_name.len == name->len &&			    strncmp(pb->pb_name.name,				    name->name,				    name->len) == 0)				break;			pb = pb->pb_sibs.le_next;		}	}	if (!pb) {		/*		 * None found, create new child.		 */		pb = _sysio_pb_new(name, parent->p_base, NULL);		if (!pb)			return -ENOMEM;	}	/*	 * Now find the proper alias. It's the one with the passed	 * parent.	 */	err = 0;	pno = pb->pb_aliases.lh_first;	while (pno) {		if (pno->p_parent == parent) {			P_REF(pno);			break;		}		pno = pno->p_links.le_next;	}	if (!pno) {		/*		 * Hmm. No alias. Just create an invalid one, to be		 * validated later.		 */		pno = _sysio_p_new_alias(parent, pb, parent->p_mount);		if (!pno)			err = -ENOMEM;	}	if (!err)		*pnop = pno;	return err;}/* * Prune idle path base nodes freom the passed sub-tree, including the root. */static void_sysio_prune(struct pnode_base *rpb){	struct pnode_base *nxtpb, *pb;	nxtpb = rpb->pb_children.lh_first;	while ((pb = nxtpb)) {		nxtpb = pb->pb_sibs.le_next;		if (pb->pb_aliases.lh_first)			continue;		if (pb->pb_children.lh_first) {			_sysio_prune(pb);			continue;		}		_sysio_pb_gone(pb);	}	if (rpb->pb_children.lh_first)		return;	_sysio_pb_gone(rpb);}/* * Prune idle nodes from the passed sub-tree, including the root. * * Returns the number of aliases on the same mount that could not be pruned. * i.e. a zero return means the entire sub-tree is gone. */size_t_sysio_p_prune(struct pnode *root){	size_t	count;	struct pnode_base *nxtpb, *pb;	struct pnode *nxtpno, *pno;	count = 0;	nxtpb = root->p_base->pb_children.lh_first;	while ((pb = nxtpb)) {		nxtpb = pb->pb_sibs.le_next;		nxtpno = pb->pb_aliases.lh_first;		if (!nxtpno) {			_sysio_prune(pb);			continue;		}		while ((pno = nxtpno)) {			nxtpno = pno->p_links.le_next;			if (pno->p_mount != root->p_mount) {				/*				 * Not the alias we were looking for.				 */				continue;			}			if (pno->p_base->pb_children.lh_first) {				/*				 * Node is interior. Recurse.				 */				count += _sysio_p_prune(pno);				continue;			}			if (pno->p_ref) {				/*				 * Can't prune; It's active.				 */				count++;				continue;			}			assert(!pno->p_cover);		/* covered => ref'd! */			assert(!pno->p_base->pb_name.name ||			       pno->p_base->pb_name.hashval);			/*			 * Ok to prune.			 */			if (pno->p_mount->mnt_root == pno) {#ifndef AUTOMOUNT_FILE_NAME				count++;				continue;#else				/*				 * This is an automount-point. Must				 * unmount before relcaim.				 */				P_REF(pno);				if (_sysio_do_unmount(pno->p_mount) != 0) {					P_RELE(pno);					count++;				}				continue;#endif			}			_sysio_p_gone(pno);		}	}	if (count) {		/*		 * Can't get the root or we disconnect the sub-trees.		 */		return count + (root->p_ref ? 1 : 0);	}	/*	 * All that is left is the root. Try for it too.	 */	if (root->p_ref) {		count++;	} else if (root->p_mount->mnt_root == root) {#ifndef AUTOMOUNT_FILE_NAME		count++;#else		/*		 * This is an automount-point. Must		 * unmount before relcaim.		 */		P_REF(root);		if (_sysio_do_unmount(root->p_mount) != 0) {			P_RELE(root);			count++;		}#endif	} else		_sysio_p_gone(root);	return count;}/* * Return path tracked by the base path node ancestor chain. * * Remember, base path nodes track the path relative to the file system and * path (alias) nodes track path relative to our name space -- They cross * mount points. */char *_sysio_pb_path(struct pnode_base *pb, const char separator){	char	*buf;	size_t	len, n;	struct pnode_base *tmp;	char	*cp;	/*	 * First pass: Traverse to the root of the sub-tree, remembering	 * lengths.	 */	len = 0;	tmp = pb;	do {		n = tmp->pb_name.len;		len += tmp->pb_name.len;		if (n)			len++;		tmp = tmp->pb_parent;	} while (tmp);	if (!len)		len++;	/*	 * Alloc space.	 */	buf = malloc(len + 1);	if (!buf)		return NULL;	/*	 * Fill in the path buffer -- Backwards, since we're starting	 * from the end.	 */	cp = buf;	*cp = separator;	cp += len;	*cp = '\0';					/* NUL term */	tmp = pb;	do {		cp -= tmp->pb_name.len;		n = tmp->pb_name.len;		if (n) {			(void )strncpy(cp, tmp->pb_name.name, n);			*--cp = separator;		}		tmp = tmp->pb_parent;	} while (tmp);	return buf;}/* * Common set attributes routine. */int_sysio_setattr(struct pnode *pno,	       struct inode *ino,	       unsigned mask,	       struct intnl_stat *stbuf){	/*	 * It is possible that pno is null (for ftruncate call).	 */	if (pno)		assert(!ino || pno->p_base->pb_ino == ino);	if (!ino)		ino = pno->p_base->pb_ino;	assert(ino);	if (pno && IS_RDONLY(pno))		return -EROFS;	/*	 * Determining permission to change the attributes is	 * difficult, at best. Just try it.	 */	return (*ino->i_ops.inop_setattr)(pno, ino, mask, stbuf);}/* * Do nothing. */void_sysio_do_noop(){	return;}/* * Abort. */void_sysio_do_illop(){	abort();}/* * Return -EBADF */int_sysio_do_ebadf(){	return -EBADF;}/* * Return -EINVAL */int_sysio_do_einval(){	return -EINVAL;}/* * Return -ENOENT */int_sysio_do_enoent(){	return -ENOENT;}/* * Return -ESPIPE */int_sysio_do_espipe(){	return -ESPIPE;}/* * Return -EISDIR */int_sysio_do_eisdir(){	return -EISDIR;}/* * Return -ENOSYS */int_sysio_do_enosys(){	return -ENOSYS;}/* * Return -ENODEV */int_sysio_do_enodev(){	return -ENODEV;}

⌨️ 快捷键说明

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