/* * Calculate how many blocks we need for the new attribute, */ STATIC int xfs_attr_calc_size( struct xfs_da_args *args, int *local) { struct xfs_mount *mp = args->dp->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(args, local); nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); if (*local) { if (size > (args->geo->blksize / 2)) { /* Double split possible */ nblks *= 2; } } else { /* * Out of line attribute, cannot double split, but * make room for the attribute value itself. */ uint dblocks = xfs_attr3_rmt_blocks(mp, args->valuelen); nblks += dblocks; nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK); } return nblks; }
/* * Calculate the maximum length in bytes that would be required for a local * attribute value as large attributes out of line are not logged. */ STATIC int xfs_log_calc_max_attrsetm_res( struct xfs_mount *mp) { int size; int nblks; size = xfs_attr_leaf_entsize_local_max(mp->m_sb.sb_blocksize) - MAXNAMELEN - 1; nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); nblks += XFS_B_TO_FSB(mp, size); nblks += XFS_NEXTENTADD_SPACE_RES(mp, size, XFS_ATTR_FORK); return M_RES(mp)->tr_attrsetm.tr_logres + M_RES(mp)->tr_attrsetrt.tr_logres * nblks; }
static int max_trans_res( xfs_mount_t *mp, int *mul) { uint *p; uint *q; int rval; xfs_trans_reservations_t *tr; xfs_da_args_t args; int local; int size; int nblks; int res; nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); /* * Fill in the arg structure for this request. */ bzero(&args, sizeof(args)); args.name = NULL; args.namelen = MAXNAMELEN; args.value = NULL; args.valuelen = 65536; args.flags = 0; args.hashval = 0; args.dp = NULL; args.firstblock = NULL; args.flist = NULL; args.whichfork = XFS_ATTR_FORK; args.oknoent = 1; /* * Determine space new attribute will use, and if it will be * inline or out of line. */ size = libxfs_attr_leaf_newentsize( &args, mp->m_sb.sb_blocksize, &local); if (local) { printf("Uh-oh.. attribute is local\n"); } else { /* Out of line attribute, cannot double split, but make * room for the attribute value itself. */ nblks += XFS_B_TO_FSB(mp, size); nblks += XFS_NEXTENTADD_SPACE_RES(mp, size, XFS_ATTR_FORK); } res = XFS_ATTRSET_LOG_RES(mp, nblks); #if 0 printf("size = %d nblks = %d res = %d\n", size, nblks, res); #endif mp->m_reservations.tr_attrset = res; for (rval = 0, tr = &mp->m_reservations, p = (uint *)tr, q = (uint *)&tr_count; p < (uint *)(tr + 1); p++, q++) { if ((int)*p > rval) { rval = (int)*p; *mul = (int)*q; } } return rval; }