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

📄 xfs_dir2.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */#include "xfs.h"#include "xfs_fs.h"#include "xfs_types.h"#include "xfs_bit.h"#include "xfs_log.h"#include "xfs_inum.h"#include "xfs_trans.h"#include "xfs_sb.h"#include "xfs_ag.h"#include "xfs_dir2.h"#include "xfs_dmapi.h"#include "xfs_mount.h"#include "xfs_da_btree.h"#include "xfs_bmap_btree.h"#include "xfs_alloc_btree.h"#include "xfs_dir2_sf.h"#include "xfs_attr_sf.h"#include "xfs_dinode.h"#include "xfs_inode.h"#include "xfs_inode_item.h"#include "xfs_bmap.h"#include "xfs_dir2_data.h"#include "xfs_dir2_leaf.h"#include "xfs_dir2_block.h"#include "xfs_dir2_node.h"#include "xfs_dir2_trace.h"#include "xfs_error.h"voidxfs_dir_mount(	xfs_mount_t	*mp){	ASSERT(XFS_SB_VERSION_HASDIRV2(&mp->m_sb));	ASSERT((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) <=	       XFS_MAX_BLOCKSIZE);	mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog);	mp->m_dirblkfsbs = 1 << mp->m_sb.sb_dirblklog;	mp->m_dirdatablk = xfs_dir2_db_to_da(mp, XFS_DIR2_DATA_FIRSTDB(mp));	mp->m_dirleafblk = xfs_dir2_db_to_da(mp, XFS_DIR2_LEAF_FIRSTDB(mp));	mp->m_dirfreeblk = xfs_dir2_db_to_da(mp, XFS_DIR2_FREE_FIRSTDB(mp));	mp->m_attr_node_ents =		(mp->m_sb.sb_blocksize - (uint)sizeof(xfs_da_node_hdr_t)) /		(uint)sizeof(xfs_da_node_entry_t);	mp->m_dir_node_ents =		(mp->m_dirblksize - (uint)sizeof(xfs_da_node_hdr_t)) /		(uint)sizeof(xfs_da_node_entry_t);	mp->m_dir_magicpct = (mp->m_dirblksize * 37) / 100;}/* * Return 1 if directory contains only "." and "..". */intxfs_dir_isempty(	xfs_inode_t	*dp){	xfs_dir2_sf_t	*sfp;	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);	if (dp->i_d.di_size == 0)	/* might happen during shutdown. */		return 1;	if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp))		return 0;	sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;	return !sfp->hdr.count;}/* * Validate a given inode number. */intxfs_dir_ino_validate(	xfs_mount_t	*mp,	xfs_ino_t	ino){	xfs_agblock_t	agblkno;	xfs_agino_t	agino;	xfs_agnumber_t	agno;	int		ino_ok;	int		ioff;	agno = XFS_INO_TO_AGNO(mp, ino);	agblkno = XFS_INO_TO_AGBNO(mp, ino);	ioff = XFS_INO_TO_OFFSET(mp, ino);	agino = XFS_OFFBNO_TO_AGINO(mp, agblkno, ioff);	ino_ok =		agno < mp->m_sb.sb_agcount &&		agblkno < mp->m_sb.sb_agblocks &&		agblkno != 0 &&		ioff < (1 << mp->m_sb.sb_inopblog) &&		XFS_AGINO_TO_INO(mp, agno, agino) == ino;	if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE,			XFS_RANDOM_DIR_INO_VALIDATE))) {		xfs_fs_cmn_err(CE_WARN, mp, "Invalid inode number 0x%Lx",				(unsigned long long) ino);		XFS_ERROR_REPORT("xfs_dir_ino_validate", XFS_ERRLEVEL_LOW, mp);		return XFS_ERROR(EFSCORRUPTED);	}	return 0;}/* * Initialize a directory with its "." and ".." entries. */intxfs_dir_init(	xfs_trans_t	*tp,	xfs_inode_t	*dp,	xfs_inode_t	*pdp){	xfs_da_args_t	args;	int		error;	memset((char *)&args, 0, sizeof(args));	args.dp = dp;	args.trans = tp;	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);	if ((error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino)))		return error;	return xfs_dir2_sf_create(&args, pdp->i_ino);}/*  Enter a name in a directory. */intxfs_dir_createname(	xfs_trans_t		*tp,	xfs_inode_t		*dp,	char			*name,	int			namelen,	xfs_ino_t		inum,		/* new entry inode number */	xfs_fsblock_t		*first,		/* bmap's firstblock */	xfs_bmap_free_t		*flist,		/* bmap's freeblock list */	xfs_extlen_t		total)		/* bmap's total block count */{	xfs_da_args_t		args;	int			rval;	int			v;		/* type-checking value */	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);	if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum)))		return rval;	XFS_STATS_INC(xs_dir_create);	args.name = name;	args.namelen = namelen;	args.hashval = xfs_da_hashname(name, namelen);	args.inumber = inum;	args.dp = dp;	args.firstblock = first;	args.flist = flist;	args.total = total;	args.whichfork = XFS_DATA_FORK;	args.trans = tp;	args.justcheck = 0;	args.addname = args.oknoent = 1;	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)		rval = xfs_dir2_sf_addname(&args);	else if ((rval = xfs_dir2_isblock(tp, dp, &v)))		return rval;	else if (v)		rval = xfs_dir2_block_addname(&args);	else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))		return rval;	else if (v)		rval = xfs_dir2_leaf_addname(&args);	else		rval = xfs_dir2_node_addname(&args);	return rval;}/* * Lookup a name in a directory, give back the inode number. */intxfs_dir_lookup(	xfs_trans_t	*tp,	xfs_inode_t	*dp,	char		*name,	int		namelen,	xfs_ino_t	*inum)		/* out: inode number */{	xfs_da_args_t	args;	int		rval;	int		v;		/* type-checking value */	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);	XFS_STATS_INC(xs_dir_lookup);	args.name = name;	args.namelen = namelen;	args.hashval = xfs_da_hashname(name, namelen);	args.inumber = 0;	args.dp = dp;	args.firstblock = NULL;	args.flist = NULL;	args.total = 0;	args.whichfork = XFS_DATA_FORK;	args.trans = tp;	args.justcheck = args.addname = 0;	args.oknoent = 1;	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)		rval = xfs_dir2_sf_lookup(&args);	else if ((rval = xfs_dir2_isblock(tp, dp, &v)))		return rval;	else if (v)		rval = xfs_dir2_block_lookup(&args);	else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))		return rval;	else if (v)		rval = xfs_dir2_leaf_lookup(&args);	else		rval = xfs_dir2_node_lookup(&args);	if (rval == EEXIST)		rval = 0;	if (rval == 0)		*inum = args.inumber;	return rval;}/* * Remove an entry from a directory. */intxfs_dir_removename(	xfs_trans_t	*tp,	xfs_inode_t	*dp,	char		*name,	int		namelen,	xfs_ino_t	ino,	xfs_fsblock_t	*first,		/* bmap's firstblock */	xfs_bmap_free_t	*flist,		/* bmap's freeblock list */	xfs_extlen_t	total)		/* bmap's total block count */{	xfs_da_args_t	args;	int		rval;	int		v;		/* type-checking value */	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);	XFS_STATS_INC(xs_dir_remove);	args.name = name;	args.namelen = namelen;	args.hashval = xfs_da_hashname(name, namelen);	args.inumber = ino;	args.dp = dp;	args.firstblock = first;	args.flist = flist;	args.total = total;	args.whichfork = XFS_DATA_FORK;	args.trans = tp;	args.justcheck = args.addname = args.oknoent = 0;	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)		rval = xfs_dir2_sf_removename(&args);	else if ((rval = xfs_dir2_isblock(tp, dp, &v)))		return rval;	else if (v)		rval = xfs_dir2_block_removename(&args);	else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))		return rval;	else if (v)		rval = xfs_dir2_leaf_removename(&args);	else		rval = xfs_dir2_node_removename(&args);	return rval;}/* * Read a directory. */intxfs_readdir(	xfs_inode_t	*dp,	void		*dirent,	size_t		bufsize,	xfs_off_t	*offset,	filldir_t	filldir){	int		rval;		/* return value */	int		v;		/* type-checking value */	vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address);	if (XFS_FORCED_SHUTDOWN(dp->i_mount))		return XFS_ERROR(EIO);	ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);	XFS_STATS_INC(xs_dir_getdents);	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)		rval = xfs_dir2_sf_getdents(dp, dirent, offset, filldir);	else if ((rval = xfs_dir2_isblock(NULL, dp, &v)))		;	else if (v)		rval = xfs_dir2_block_getdents(dp, dirent, offset, filldir);	else		rval = xfs_dir2_leaf_getdents(dp, dirent, bufsize, offset,					      filldir);	return rval;}/* * Replace the inode number of a directory entry. */intxfs_dir_replace(	xfs_trans_t	*tp,	xfs_inode_t	*dp,	char		*name,		/* name of entry to replace */	int		namelen,	xfs_ino_t	inum,		/* new inode number */	xfs_fsblock_t	*first,		/* bmap's firstblock */	xfs_bmap_free_t	*flist,		/* bmap's freeblock list */	xfs_extlen_t	total)		/* bmap's total block count */{	xfs_da_args_t	args;	int		rval;

⌨️ 快捷键说明

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