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

📄 xfs_attr.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
 * Read the value associated with an attribute from the out-of-line buffer * that we stored it in. */intxfs_attr_rmtval_get(xfs_da_args_t *args){	xfs_bmbt_irec_t map[ATTR_RMTVALUE_MAPSIZE];	xfs_mount_t *mp;	xfs_daddr_t dblkno;	xfs_caddr_t dst;	xfs_buf_t *bp;	int nmap, error, tmp, valuelen, blkcnt, i;	xfs_dablk_t lblkno;	ASSERT(!(args->flags & ATTR_KERNOVAL));	mp = args->dp->i_mount;	dst = args->value;	valuelen = args->valuelen;	lblkno = args->rmtblkno;	while (valuelen > 0) {		nmap = ATTR_RMTVALUE_MAPSIZE;		error = xfs_bmapi(args->trans, args->dp, (xfs_fileoff_t)lblkno,				  args->rmtblkcnt,				  XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,				  NULL, 0, map, &nmap, NULL, NULL);		if (error)			return(error);		ASSERT(nmap >= 1);		for (i = 0; (i < nmap) && (valuelen > 0); i++) {			ASSERT((map[i].br_startblock != DELAYSTARTBLOCK) &&			       (map[i].br_startblock != HOLESTARTBLOCK));			dblkno = XFS_FSB_TO_DADDR(mp, map[i].br_startblock);			blkcnt = XFS_FSB_TO_BB(mp, map[i].br_blockcount);			error = xfs_read_buf(mp, mp->m_ddev_targp, dblkno,					     blkcnt, XFS_BUF_LOCK, &bp);			if (error)				return(error);			tmp = (valuelen < XFS_BUF_SIZE(bp))				? valuelen : XFS_BUF_SIZE(bp);			xfs_biomove(bp, 0, tmp, dst, XFS_B_READ);			xfs_buf_relse(bp);			dst += tmp;			valuelen -= tmp;			lblkno += map[i].br_blockcount;		}	}	ASSERT(valuelen == 0);	return(0);}/* * Write the value associated with an attribute into the out-of-line buffer * that we have defined for it. */STATIC intxfs_attr_rmtval_set(xfs_da_args_t *args){	xfs_mount_t *mp;	xfs_fileoff_t lfileoff;	xfs_inode_t *dp;	xfs_bmbt_irec_t map;	xfs_daddr_t dblkno;	xfs_caddr_t src;	xfs_buf_t *bp;	xfs_dablk_t lblkno;	int blkcnt, valuelen, nmap, error, tmp, committed;	dp = args->dp;	mp = dp->i_mount;	src = args->value;	/*	 * Find a "hole" in the attribute address space large enough for	 * us to drop the new attribute's value into.	 */	blkcnt = XFS_B_TO_FSB(mp, args->valuelen);	lfileoff = 0;	error = xfs_bmap_first_unused(args->trans, args->dp, blkcnt, &lfileoff,						   XFS_ATTR_FORK);	if (error) {		return(error);	}	args->rmtblkno = lblkno = (xfs_dablk_t)lfileoff;	args->rmtblkcnt = blkcnt;	/*	 * Roll through the "value", allocating blocks on disk as required.	 */	while (blkcnt > 0) {		/*		 * Allocate a single extent, up to the size of the value.		 */		XFS_BMAP_INIT(args->flist, args->firstblock);		nmap = 1;		error = xfs_bmapi(args->trans, dp, (xfs_fileoff_t)lblkno,				  blkcnt,				  XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA |							XFS_BMAPI_WRITE,				  args->firstblock, args->total, &map, &nmap,				  args->flist, NULL);		if (!error) {			error = xfs_bmap_finish(&args->trans, args->flist,						&committed);		}		if (error) {			ASSERT(committed);			args->trans = NULL;			xfs_bmap_cancel(args->flist);			return(error);		}		/*		 * bmap_finish() may have committed the last trans and started		 * a new one.  We need the inode to be in all transactions.		 */		if (committed) {			xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);			xfs_trans_ihold(args->trans, dp);		}		ASSERT(nmap == 1);		ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&		       (map.br_startblock != HOLESTARTBLOCK));		lblkno += map.br_blockcount;		blkcnt -= map.br_blockcount;		/*		 * Start the next trans in the chain.		 */		if ((error = xfs_attr_rolltrans(&args->trans, dp)))			return (error);	}	/*	 * Roll through the "value", copying the attribute value to the	 * already-allocated blocks.  Blocks are written synchronously	 * so that we can know they are all on disk before we turn off	 * the INCOMPLETE flag.	 */	lblkno = args->rmtblkno;	valuelen = args->valuelen;	while (valuelen > 0) {		/*		 * Try to remember where we decided to put the value.		 */		XFS_BMAP_INIT(args->flist, args->firstblock);		nmap = 1;		error = xfs_bmapi(NULL, dp, (xfs_fileoff_t)lblkno,				  args->rmtblkcnt,				  XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,				  args->firstblock, 0, &map, &nmap,				  NULL, NULL);		if (error) {			return(error);		}		ASSERT(nmap == 1);		ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&		       (map.br_startblock != HOLESTARTBLOCK));		dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock),		blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount);		bp = xfs_buf_get_flags(mp->m_ddev_targp, dblkno,							blkcnt, XFS_BUF_LOCK);		ASSERT(bp);		ASSERT(!XFS_BUF_GETERROR(bp));		tmp = (valuelen < XFS_BUF_SIZE(bp)) ? valuelen :							XFS_BUF_SIZE(bp);		xfs_biomove(bp, 0, tmp, src, XFS_B_WRITE);		if (tmp < XFS_BUF_SIZE(bp))			xfs_biozero(bp, tmp, XFS_BUF_SIZE(bp) - tmp);		if ((error = xfs_bwrite(mp, bp))) {/* GROT: NOTE: synchronous write */			return (error);		}		src += tmp;		valuelen -= tmp;		lblkno += map.br_blockcount;	}	ASSERT(valuelen == 0);	return(0);}/* * Remove the value associated with an attribute by deleting the * out-of-line buffer that it is stored on. */STATIC intxfs_attr_rmtval_remove(xfs_da_args_t *args){	xfs_mount_t *mp;	xfs_bmbt_irec_t map;	xfs_buf_t *bp;	xfs_daddr_t dblkno;	xfs_dablk_t lblkno;	int valuelen, blkcnt, nmap, error, done, committed;	mp = args->dp->i_mount;	/*	 * Roll through the "value", invalidating the attribute value's	 * blocks.	 */	lblkno = args->rmtblkno;	valuelen = args->rmtblkcnt;	while (valuelen > 0) {		/*		 * Try to remember where we decided to put the value.		 */		XFS_BMAP_INIT(args->flist, args->firstblock);		nmap = 1;		error = xfs_bmapi(NULL, args->dp, (xfs_fileoff_t)lblkno,					args->rmtblkcnt,					XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,					args->firstblock, 0, &map, &nmap,					args->flist, NULL);		if (error) {			return(error);		}		ASSERT(nmap == 1);		ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&		       (map.br_startblock != HOLESTARTBLOCK));		dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock),		blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount);		/*		 * If the "remote" value is in the cache, remove it.		 */		bp = xfs_incore(mp->m_ddev_targp, dblkno, blkcnt,				XFS_INCORE_TRYLOCK);		if (bp) {			XFS_BUF_STALE(bp);			XFS_BUF_UNDELAYWRITE(bp);			xfs_buf_relse(bp);			bp = NULL;		}		valuelen -= map.br_blockcount;		lblkno += map.br_blockcount;	}	/*	 * Keep de-allocating extents until the remote-value region is gone.	 */	lblkno = args->rmtblkno;	blkcnt = args->rmtblkcnt;	done = 0;	while (!done) {		XFS_BMAP_INIT(args->flist, args->firstblock);		error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt,				    XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,				    1, args->firstblock, args->flist,				    NULL, &done);		if (!error) {			error = xfs_bmap_finish(&args->trans, args->flist,						&committed);		}		if (error) {			ASSERT(committed);			args->trans = NULL;			xfs_bmap_cancel(args->flist);			return(error);		}		/*		 * bmap_finish() may have committed the last trans and started		 * a new one.  We need the inode to be in all transactions.		 */		if (committed) {			xfs_trans_ijoin(args->trans, args->dp, XFS_ILOCK_EXCL);			xfs_trans_ihold(args->trans, args->dp);		}		/*		 * Close out trans and start the next one in the chain.		 */		if ((error = xfs_attr_rolltrans(&args->trans, args->dp)))			return (error);	}	return(0);}#if defined(XFS_ATTR_TRACE)/* * Add a trace buffer entry for an attr_list context structure. */voidxfs_attr_trace_l_c(char *where, struct xfs_attr_list_context *context){	xfs_attr_trace_enter(XFS_ATTR_KTRACE_L_C, where,		(__psunsigned_t)context->dp,		(__psunsigned_t)context->cursor->hashval,		(__psunsigned_t)context->cursor->blkno,		(__psunsigned_t)context->cursor->offset,		(__psunsigned_t)context->alist,		(__psunsigned_t)context->bufsize,		(__psunsigned_t)context->count,		(__psunsigned_t)context->firstu,		(__psunsigned_t)			((context->count > 0) &&			!(context->flags & (ATTR_KERNAMELS|ATTR_KERNOVAL)))				? (ATTR_ENTRY(context->alist,					      context->count-1)->a_valuelen)				: 0,		(__psunsigned_t)context->dupcnt,		(__psunsigned_t)context->flags,		(__psunsigned_t)NULL,		(__psunsigned_t)NULL,		(__psunsigned_t)NULL);}/* * Add a trace buffer entry for a context structure and a Btree node. */voidxfs_attr_trace_l_cn(char *where, struct xfs_attr_list_context *context,			 struct xfs_da_intnode *node){	xfs_attr_trace_enter(XFS_ATTR_KTRACE_L_CN, where,		(__psunsigned_t)context->dp,		(__psunsigned_t)context->cursor->hashval,		(__psunsigned_t)context->cursor->blkno,		(__psunsigned_t)context->cursor->offset,		(__psunsigned_t)context->alist,		(__psunsigned_t)context->bufsize,		(__psunsigned_t)context->count,		(__psunsigned_t)context->firstu,		(__psunsigned_t)			((context->count > 0) &&			!(context->flags & (ATTR_KERNAMELS|ATTR_KERNOVAL)))				? (ATTR_ENTRY(context->alist,					      context->count-1)->a_valuelen)				: 0,		(__psunsigned_t)context->dupcnt,		(__psunsigned_t)context->flags,		(__psunsigned_t)be16_to_cpu(node->hdr.count),		(__psunsigned_t)be32_to_cpu(node->btree[0].hashval),		(__psunsigned_t)be32_to_cpu(node->btree[				    be16_to_cpu(node->hdr.count)-1].hashval));}/* * Add a trace buffer entry for a context structure and a Btree element. */voidxfs_attr_trace_l_cb(char *where, struct xfs_attr_list_context *context,			  struct xfs_da_node_entry *btree){	xfs_attr_trace_enter(XFS_ATTR_KTRACE_L_CB, where,		(__psunsigned_t)context->dp,		(__psunsigned_t)context->cursor->hashval,		(__psunsigned_t)context->cursor->blkno,		(__psunsigned_t)context->cursor->offset,		(__psunsigned_t)context->alist,		(__psunsigned_t)context->bufsize,		(__psunsigned_t)context->count,		(__psunsigned_t)context->firstu,		(__psunsigned_t)			((context->count > 0) &&			!(context->flags & (ATTR_KERNAMELS|ATTR_KERNOVAL)))				? (ATTR_ENTRY(context->alist,					      context->count-1)->a_valuelen)				: 0,		(__psunsigned_t)context->dupcnt,		(__psunsigned_t)context->flags,		(__psunsigned_t)be32_to_cpu(btree->hashval),		(__psunsigned_t)be32_to_cpu(btree->before),		(__psunsigned_t)NULL);}/* * Add a trace buffer entry for a context structure and a leaf block. */voidxfs_attr_trace_l_cl(char *where, struct xfs_attr_list_context *context,			      struct xfs_attr_leafblock *leaf){	xfs_attr_trace_enter(XFS_ATTR_KTRACE_L_CL, where,		(__psunsigned_t)context->dp,		(__psunsigned_t)context->cursor->hashval,		(__psunsigned_t)context->cursor->blkno,		(__psunsigned_t)context->cursor->offset,		(__psunsigned_t)context->alist,		(__psunsigned_t)context->bufsize,		(__psunsigned_t)context->count,		(__psunsigned_t)context->firstu,		(__psunsigned_t)			((context->count > 0) &&			!(context->flags & (ATTR_KERNAMELS|ATTR_KERNOVAL)))				? (ATTR_ENTRY(context->alist,					      context->count-1)->a_valuelen)				: 0,		(__psunsigned_t)context->dupcnt,		(__psunsigned_t)context->flags,		(__psunsigned_t)be16_to_cpu(leaf->hdr.count),		(__psunsigned_t)be32_to_cpu(leaf->entries[0].hashval),		(__psunsigned_t)be32_to_cpu(leaf->entries[				be16_to_cpu(leaf->hdr.count)-1].hashval));}/* * Add a trace buffer entry for the arguments given to the routine, * generic form. */voidxfs_attr_trace_enter(int type, char *where,			 __psunsigned_t a2, __psunsigned_t a3,			 __psunsigned_t a4, __psunsigned_t a5,			 __psunsigned_t a6, __psunsigned_t a7,			 __psunsigned_t a8, __psunsigned_t a9,			 __psunsigned_t a10, __psunsigned_t a11,			 __psunsigned_t a12, __psunsigned_t a13,			 __psunsigned_t a14, __psunsigned_t a15){	ASSERT(xfs_attr_trace_buf);	ktrace_enter(xfs_attr_trace_buf, (void *)((__psunsigned_t)type),					 (void *)where,					 (void *)a2,  (void *)a3,  (void *)a4,					 (void *)a5,  (void *)a6,  (void *)a7,					 (void *)a8,  (void *)a9,  (void *)a10,					 (void *)a11, (void *)a12, (void *)a13,					 (void *)a14, (void *)a15);}#endif	/* XFS_ATTR_TRACE *//*======================================================================== * System (pseudo) namespace attribute interface routines. *========================================================================*/STATIC intposix_acl_access_set(	bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags){	return xfs_acl_vset(vp, data, size, _ACL_TYPE_ACCESS);}STATIC intposix_acl_access_remove(	bhv_vnode_t *vp, char *name, int xflags){	return xfs_acl_vremove(vp, _ACL_TYPE_ACCESS);}STATIC intposix_acl_access_get(	bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags){	return xfs_acl_vget(vp, data, size, _ACL_TYPE_ACCESS);}STATIC intposix_acl_access_exists(	bhv_vnode_t *vp){	return xfs_acl_vhasacl_access(vp);}STATIC intposix_acl_default_set(	bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags){	return xfs_acl_vset(vp, data, size, _ACL_TYPE_DEFAULT);}STATIC intposix_acl_default_get(	bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags){	return xfs_acl_vget(vp, data, size, _ACL_TYPE_DEFAULT);}STATIC intposix_acl_default_remove(	bhv_vnode_t *vp, char *name, int xflags){	return xfs_acl_vremove(vp, _ACL_TYPE_DEFAULT);}STATIC intposix_acl_default_exists(	bhv_vnode_t *vp){	return xfs_acl_vhasacl_default(vp);}static struct attrnames posix_acl_access = {	.attr_name	= "posix_acl_access",	.attr_namelen	= sizeof("posix_acl_access") - 1,	.attr_get	= posix_acl_access_get,	.attr_set	= posix_acl_

⌨️ 快捷键说明

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