mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 16:54:21 +00:00 
			
		
		
		
	[XFS] Move attr log alloc size calculator to another function.
We will need that to be able to calculate the size of log we need for a specific attr (for Create+EA). The local flag is needed so that we can fail if we run into ENOSPC when trying to alloc blocks. SGI-PV: 981498 SGI-Modid: xfs-linux-melb:xfs-kern:31727a Signed-off-by: Niv Sardi <xaiki@sgi.com> Signed-off-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Tim Shimmin <tes@sgi.com> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
This commit is contained in:
		
							parent
							
								
									6785073ba1
								
							
						
					
					
						commit
						5e9da7b7a1
					
				
					 2 changed files with 49 additions and 32 deletions
				
			
		|  | @ -194,6 +194,46 @@ xfs_attr_get( | |||
| 	return(error); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Calculate how many blocks we need for the new attribute, | ||||
|  */ | ||||
| int | ||||
| xfs_attr_calc_size( | ||||
| 	struct xfs_inode 	*ip, | ||||
| 	int			namelen, | ||||
| 	int			valuelen, | ||||
| 	int			*local) | ||||
| { | ||||
| 	struct xfs_mount 	*mp = ip->i_mount; | ||||
| 	int			size; | ||||
| 	int			nblks; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Determine space new attribute will use, and if it would be | ||||
| 	 * "local" or "remote" (note: local != inline). | ||||
| 	 */ | ||||
| 	size = xfs_attr_leaf_newentsize(namelen, valuelen, | ||||
| 					mp->m_sb.sb_blocksize, local); | ||||
| 
 | ||||
| 	nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); | ||||
| 	if (*local) { | ||||
| 		if (size > (mp->m_sb.sb_blocksize >> 1)) { | ||||
| 			/* Double split possible */ | ||||
| 			nblks *= 2; | ||||
| 		} | ||||
| 	} else { | ||||
| 		/*
 | ||||
| 		 * Out of line attribute, cannot double split, but | ||||
| 		 * make room for the attribute value itself. | ||||
| 		 */ | ||||
| 		uint	dblocks = XFS_B_TO_FSB(mp, valuelen); | ||||
| 		nblks += dblocks; | ||||
| 		nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK); | ||||
| 	} | ||||
| 
 | ||||
| 	return nblks; | ||||
| } | ||||
| 
 | ||||
| STATIC int | ||||
| xfs_attr_set_int(xfs_inode_t *dp, struct xfs_name *name, | ||||
| 		char *value, int valuelen, int flags) | ||||
|  | @ -202,10 +242,9 @@ xfs_attr_set_int(xfs_inode_t *dp, struct xfs_name *name, | |||
| 	xfs_fsblock_t	firstblock; | ||||
| 	xfs_bmap_free_t flist; | ||||
| 	int		error, err2, committed; | ||||
| 	int		local, size; | ||||
| 	uint		nblks; | ||||
| 	xfs_mount_t	*mp = dp->i_mount; | ||||
| 	int             rsvd = (flags & ATTR_ROOT) != 0; | ||||
| 	int		local; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Attach the dquots to the inode. | ||||
|  | @ -241,30 +280,8 @@ xfs_attr_set_int(xfs_inode_t *dp, struct xfs_name *name, | |||
| 	args.whichfork = XFS_ATTR_FORK; | ||||
| 	args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Determine space new attribute will use, and if it would be | ||||
| 	 * "local" or "remote" (note: local != inline). | ||||
| 	 */ | ||||
| 	size = xfs_attr_leaf_newentsize(name->len, valuelen, | ||||
| 					mp->m_sb.sb_blocksize, &local); | ||||
| 
 | ||||
| 	nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); | ||||
| 	if (local) { | ||||
| 		if (size > (mp->m_sb.sb_blocksize >> 1)) { | ||||
| 			/* Double split possible */ | ||||
| 			nblks <<= 1; | ||||
| 		} | ||||
| 	} else { | ||||
| 		uint	dblocks = XFS_B_TO_FSB(mp, valuelen); | ||||
| 		/* Out of line attribute, cannot double split, but make
 | ||||
| 		 * room for the attribute value itself. | ||||
| 		 */ | ||||
| 		nblks += dblocks; | ||||
| 		nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Size is now blocks for attribute data */ | ||||
| 	args.total = nblks; | ||||
| 	args.total = xfs_attr_calc_size(dp, name->len, valuelen, &local); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Start our first transaction of the day. | ||||
|  | @ -286,18 +303,17 @@ xfs_attr_set_int(xfs_inode_t *dp, struct xfs_name *name, | |||
| 	if (rsvd) | ||||
| 		args.trans->t_flags |= XFS_TRANS_RESERVE; | ||||
| 
 | ||||
| 	if ((error = xfs_trans_reserve(args.trans, (uint) nblks, | ||||
| 				      XFS_ATTRSET_LOG_RES(mp, nblks), | ||||
| 				      0, XFS_TRANS_PERM_LOG_RES, | ||||
| 				      XFS_ATTRSET_LOG_COUNT))) { | ||||
| 	if ((error = xfs_trans_reserve(args.trans, args.total, | ||||
| 			XFS_ATTRSET_LOG_RES(mp, args.total), 0, | ||||
| 			XFS_TRANS_PERM_LOG_RES, XFS_ATTRSET_LOG_COUNT))) { | ||||
| 		xfs_trans_cancel(args.trans, 0); | ||||
| 		return(error); | ||||
| 	} | ||||
| 	xfs_ilock(dp, XFS_ILOCK_EXCL); | ||||
| 
 | ||||
| 	error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, args.trans, dp, nblks, 0, | ||||
| 			 rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES : | ||||
| 				XFS_QMOPT_RES_REGBLKS); | ||||
| 	error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, args.trans, dp, args.total, 0, | ||||
| 				rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES : | ||||
| 				       XFS_QMOPT_RES_REGBLKS); | ||||
| 	if (error) { | ||||
| 		xfs_iunlock(dp, XFS_ILOCK_EXCL); | ||||
| 		xfs_trans_cancel(args.trans, XFS_TRANS_RELEASE_LOG_RES); | ||||
|  |  | |||
|  | @ -129,6 +129,7 @@ typedef struct xfs_attr_list_context { | |||
| /*
 | ||||
|  * Overall external interface routines. | ||||
|  */ | ||||
| int xfs_attr_calc_size(struct xfs_inode *, int, int, int *); | ||||
| int xfs_attr_inactive(struct xfs_inode *dp); | ||||
| int xfs_attr_fetch(struct xfs_inode *, struct xfs_name *, char *, int *, int); | ||||
| int xfs_attr_rmtval_get(struct xfs_da_args *args); | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Niv Sardi
						Niv Sardi