/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * 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.
+ * 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.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-/*
- * xfs_attr_leaf.c
- *
- * GROT: figure out how to recover gracefully when bmap returns ENOSPC.
+ * 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_macros.h"
+#include "xfs_fs.h"
#include "xfs_types.h"
-#include "xfs_inum.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_alloc_btree.h"
+#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_alloc.h"
#include "xfs_btree.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
-#include "xfs_inode_item.h"
#include "xfs_inode.h"
+#include "xfs_inode_item.h"
#include "xfs_bmap.h"
-#include "xfs_da_btree.h"
#include "xfs_attr.h"
#include "xfs_attr_leaf.h"
#include "xfs_error.h"
-#include "xfs_bit.h"
/*
* xfs_attr_leaf.c
/*
* Routines used for growing the Btree.
*/
+STATIC int xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t which_block,
+ xfs_dabuf_t **bpp);
STATIC int xfs_attr_leaf_add_work(xfs_dabuf_t *leaf_buffer, xfs_da_args_t *args,
int freemap_index);
STATIC void xfs_attr_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *leaf_buffer);
int *number_entries_in_blk1,
int *number_usedbytes_in_blk1);
+/*
+ * Routines used for shrinking the Btree.
+ */
+STATIC int xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp,
+ xfs_dabuf_t *bp, int level);
+STATIC int xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp,
+ xfs_dabuf_t *bp);
+STATIC int xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp,
+ xfs_dablk_t blkno, int blkcnt);
+
/*
* Utility routines.
*/
xfs_attr_leafblock_t *dst_leaf,
int dst_start, int move_count,
xfs_mount_t *mp);
+STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index);
+STATIC int xfs_attr_put_listent(xfs_attr_list_context_t *context,
+ attrnames_t *, char *name, int namelen,
+ int valuelen);
/*========================================================================
- * External routines when dirsize < XFS_LITINO(mp).
+ * External routines when attribute fork size < XFS_LITINO(mp).
*========================================================================*/
/*
- * Create the initial contents of a shortform attribute list.
+ * Query whether the requested number of additional bytes of extended
+ * attribute space will be able to fit inline.
+ * Returns zero if not, else the di_forkoff fork offset to be used in the
+ * literal area for attribute data once the new bytes have been added.
+ *
+ * di_forkoff must be 8 byte aligned, hence is stored as a >>3 value;
+ * special case for dev/uuid inodes, they have fixed size data forks.
*/
int
+xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes)
+{
+ int offset;
+ int minforkoff; /* lower limit on valid forkoff locations */
+ int maxforkoff; /* upper limit on valid forkoff locations */
+ xfs_mount_t *mp = dp->i_mount;
+
+ offset = (XFS_LITINO(mp) - bytes) >> 3; /* rounded down */
+
+ switch (dp->i_d.di_format) {
+ case XFS_DINODE_FMT_DEV:
+ minforkoff = roundup(sizeof(xfs_dev_t), 8) >> 3;
+ return (offset >= minforkoff) ? minforkoff : 0;
+ case XFS_DINODE_FMT_UUID:
+ minforkoff = roundup(sizeof(uuid_t), 8) >> 3;
+ return (offset >= minforkoff) ? minforkoff : 0;
+ }
+
+ if (!(mp->m_flags & XFS_MOUNT_ATTR2)) {
+ if (bytes <= XFS_IFORK_ASIZE(dp))
+ return mp->m_attroffset >> 3;
+ return 0;
+ }
+
+ /* data fork btree root can have at least this many key/ptr pairs */
+ minforkoff = MAX(dp->i_df.if_bytes, XFS_BMDR_SPACE_CALC(MINDBTPTRS));
+ minforkoff = roundup(minforkoff, 8) >> 3;
+
+ /* attr fork btree root can have at least this many key/ptr pairs */
+ maxforkoff = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS);
+ maxforkoff = maxforkoff >> 3; /* rounded down */
+
+ if (offset >= minforkoff && offset < maxforkoff)
+ return offset;
+ if (offset >= maxforkoff)
+ return maxforkoff;
+ return 0;
+}
+
+/*
+ * Switch on the ATTR2 superblock bit (implies also FEATURES2)
+ */
+STATIC void
+xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp)
+{
+ unsigned long s;
+
+ if ((mp->m_flags & XFS_MOUNT_ATTR2) &&
+ !(XFS_SB_VERSION_HASATTR2(&mp->m_sb))) {
+ s = XFS_SB_LOCK(mp);
+ if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb)) {
+ XFS_SB_VERSION_ADDATTR2(&mp->m_sb);
+ XFS_SB_UNLOCK(mp, s);
+ xfs_mod_sb(tp, XFS_SB_VERSIONNUM | XFS_SB_FEATURES2);
+ } else
+ XFS_SB_UNLOCK(mp, s);
+ }
+}
+
+/*
+ * Create the initial contents of a shortform attribute list.
+ */
+void
xfs_attr_shortform_create(xfs_da_args_t *args)
{
xfs_attr_sf_hdr_t *hdr;
}
xfs_idata_realloc(dp, sizeof(*hdr), XFS_ATTR_FORK);
hdr = (xfs_attr_sf_hdr_t *)ifp->if_u1.if_data;
- INT_ZERO(hdr->count, ARCH_CONVERT);
+ hdr->count = 0;
INT_SET(hdr->totsize, ARCH_CONVERT, sizeof(*hdr));
xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
- return(0);
}
/*
* Add a name/value pair to the shortform attribute list.
* Overflow from the inode has already been checked for.
*/
-int
-xfs_attr_shortform_add(xfs_da_args_t *args)
+void
+xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff)
{
xfs_attr_shortform_t *sf;
xfs_attr_sf_entry_t *sfe;
int i, offset, size;
+ xfs_mount_t *mp;
xfs_inode_t *dp;
xfs_ifork_t *ifp;
dp = args->dp;
+ mp = dp->i_mount;
+ dp->i_d.di_forkoff = forkoff;
+ dp->i_df.if_ext_max =
+ XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
+ dp->i_afp->if_ext_max =
+ XFS_IFORK_ASIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
+
ifp = dp->i_afp;
ASSERT(ifp->if_flags & XFS_IFINLINE);
sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data;
sfe = &sf->list[0];
for (i = 0; i < INT_GET(sf->hdr.count, ARCH_CONVERT);
sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) {
+#ifdef DEBUG
if (sfe->namelen != args->namelen)
continue;
if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
if (((args->flags & ATTR_ROOT) != 0) !=
((sfe->flags & XFS_ATTR_ROOT) != 0))
continue;
- return(XFS_ERROR(EEXIST));
+ ASSERT(0);
+#endif
}
offset = (char *)sfe - (char *)sf;
INT_MOD(sf->hdr.totsize, ARCH_CONVERT, size);
xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
- return(0);
+ xfs_sbversion_add_attr2(mp, args->trans);
}
/*
- * Remove a name from the shortform attribute list structure.
+ * Remove an attribute from the shortform attribute list structure.
*/
int
xfs_attr_shortform_remove(xfs_da_args_t *args)
xfs_attr_shortform_t *sf;
xfs_attr_sf_entry_t *sfe;
int base, size=0, end, totsize, i;
+ xfs_mount_t *mp;
xfs_inode_t *dp;
- /*
- * Remove the attribute.
- */
dp = args->dp;
+ mp = dp->i_mount;
base = sizeof(xfs_attr_sf_hdr_t);
sf = (xfs_attr_shortform_t *)dp->i_afp->if_u1.if_data;
sfe = &sf->list[0];
- for (i = 0; i < INT_GET(sf->hdr.count, ARCH_CONVERT);
- sfe = XFS_ATTR_SF_NEXTENTRY(sfe),
+ end = INT_GET(sf->hdr.count, ARCH_CONVERT);
+ for (i = 0; i < end; sfe = XFS_ATTR_SF_NEXTENTRY(sfe),
base += size, i++) {
size = XFS_ATTR_SF_ENTSIZE(sfe);
if (sfe->namelen != args->namelen)
continue;
break;
}
- if (i == INT_GET(sf->hdr.count, ARCH_CONVERT))
+ if (i == end)
return(XFS_ERROR(ENOATTR));
+ /*
+ * Fix up the attribute fork data, covering the hole
+ */
end = base + size;
totsize = INT_GET(sf->hdr.totsize, ARCH_CONVERT);
- if (end != totsize) {
- memmove(&((char *)sf)[base], &((char *)sf)[end],
- totsize - end);
- }
+ if (end != totsize)
+ memmove(&((char *)sf)[base], &((char *)sf)[end], totsize - end);
INT_MOD(sf->hdr.count, ARCH_CONVERT, -1);
INT_MOD(sf->hdr.totsize, ARCH_CONVERT, -size);
- xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
- xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
+
+ /*
+ * Fix up the start offset of the attribute fork
+ */
+ totsize -= size;
+ if (totsize == sizeof(xfs_attr_sf_hdr_t) && !args->addname &&
+ (mp->m_flags & XFS_MOUNT_ATTR2)) {
+ /*
+ * Last attribute now removed, revert to original
+ * inode format making all literal area available
+ * to the data fork once more.
+ */
+ xfs_idestroy_fork(dp, XFS_ATTR_FORK);
+ dp->i_d.di_forkoff = 0;
+ dp->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
+ ASSERT(dp->i_d.di_anextents == 0);
+ ASSERT(dp->i_afp == NULL);
+ dp->i_df.if_ext_max =
+ XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
+ xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
+ } else {
+ xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
+ dp->i_d.di_forkoff = xfs_attr_shortform_bytesfit(dp, totsize);
+ ASSERT(dp->i_d.di_forkoff);
+ ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) || args->addname ||
+ !(mp->m_flags & XFS_MOUNT_ATTR2));
+ dp->i_afp->if_ext_max =
+ XFS_IFORK_ASIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
+ dp->i_df.if_ext_max =
+ XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
+ xfs_trans_log_inode(args->trans, dp,
+ XFS_ILOG_CORE | XFS_ILOG_ADATA);
+ }
+
+ xfs_sbversion_add_attr2(mp, args->trans);
return(0);
}
ASSERT(dp->i_afp != NULL);
sf = (xfs_attr_shortform_t *)dp->i_afp->if_u1.if_data;
ASSERT(sf != NULL);
- if (INT_ISZERO(sf->hdr.count, ARCH_CONVERT))
+ if (!sf->hdr.count)
return(0);
cursor = context->cursor;
ASSERT(cursor != NULL);
/*
* Sort the entries on hash then entno.
*/
- qsort(sbuf, nsbuf, sizeof(*sbuf), xfs_attr_shortform_compare);
+ xfs_sort(sbuf, nsbuf, sizeof(*sbuf), xfs_attr_shortform_compare);
/*
* Re-find our place IN THE SORTED LIST.
+ name_loc->namelen
+ INT_GET(name_loc->valuelen, ARCH_CONVERT);
}
- return( bytes < XFS_IFORK_ASIZE(dp) );
+ if ((dp->i_mount->m_flags & XFS_MOUNT_ATTR2) &&
+ (bytes == sizeof(struct xfs_attr_sf_hdr)))
+ return(-1);
+ return(xfs_attr_shortform_bytesfit(dp, bytes));
}
/*
* Convert a leaf attribute list to shortform attribute list
*/
int
-xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args)
+xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff)
{
xfs_attr_leafblock_t *leaf;
xfs_attr_leaf_entry_t *entry;
error = xfs_da_shrink_inode(args, 0, bp);
if (error)
goto out;
- error = xfs_attr_shortform_create(args);
- if (error)
+
+ if (forkoff == -1) {
+ ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2);
+
+ /*
+ * Last attribute was removed, revert to original
+ * inode format making all literal area available
+ * to the data fork once more.
+ */
+ xfs_idestroy_fork(dp, XFS_ATTR_FORK);
+ dp->i_d.di_forkoff = 0;
+ dp->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
+ ASSERT(dp->i_d.di_anextents == 0);
+ ASSERT(dp->i_afp == NULL);
+ dp->i_df.if_ext_max =
+ XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
+ xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
goto out;
+ }
+
+ xfs_attr_shortform_create(args);
/*
* Copy the attributes
for (i = 0; i < INT_GET(leaf->hdr.count, ARCH_CONVERT); entry++, i++) {
if (entry->flags & XFS_ATTR_INCOMPLETE)
continue; /* don't copy partial entries */
- if (INT_ISZERO(entry->nameidx, ARCH_CONVERT))
+ if (!entry->nameidx)
continue;
ASSERT(entry->flags & XFS_ATTR_LOCAL);
name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, i);
nargs.hashval = INT_GET(entry->hashval, ARCH_CONVERT);
nargs.flags = (entry->flags & XFS_ATTR_SECURE) ? ATTR_SECURE :
((entry->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0);
- xfs_attr_shortform_add(&nargs);
+ xfs_attr_shortform_add(&nargs, forkoff);
}
error = 0;
* Create the initial contents of a leaf attribute list
* or a leaf in a node attribute list.
*/
-int
+STATIC int
xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp)
{
xfs_attr_leafblock_t *leaf;
hdr = &leaf->hdr;
INT_SET(hdr->info.magic, ARCH_CONVERT, XFS_ATTR_LEAF_MAGIC);
INT_SET(hdr->firstused, ARCH_CONVERT, XFS_LBSIZE(dp->i_mount));
- if (INT_ISZERO(hdr->firstused, ARCH_CONVERT)) {
+ if (!hdr->firstused) {
INT_SET(hdr->firstused, ARCH_CONVERT,
XFS_LBSIZE(dp->i_mount) - XFS_ATTR_LEAF_NAME_ALIGN);
}
ASSERT((args->index >= 0)
&& (args->index <= INT_GET(leaf->hdr.count, ARCH_CONVERT)));
hdr = &leaf->hdr;
- entsize = xfs_attr_leaf_newentsize(args,
+ entsize = xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
args->trans->t_mountp->m_sb.sb_blocksize, NULL);
/*
sum += INT_GET(map->size, ARCH_CONVERT);
continue;
}
- if (INT_ISZERO(map->size, ARCH_CONVERT))
+ if (!map->size)
continue; /* no space in this map */
tmp = entsize;
if (INT_GET(map->base, ARCH_CONVERT)
mp = args->trans->t_mountp;
ASSERT(INT_GET(map->base, ARCH_CONVERT) < XFS_LBSIZE(mp));
ASSERT((INT_GET(map->base, ARCH_CONVERT) & 0x3) == 0);
- ASSERT(INT_GET(map->size, ARCH_CONVERT)
- >= xfs_attr_leaf_newentsize(args,
- mp->m_sb.sb_blocksize, NULL));
+ ASSERT(INT_GET(map->size, ARCH_CONVERT) >=
+ xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
+ mp->m_sb.sb_blocksize, NULL));
ASSERT(INT_GET(map->size, ARCH_CONVERT) < XFS_LBSIZE(mp));
ASSERT((INT_GET(map->size, ARCH_CONVERT) & 0x3) == 0);
INT_MOD(map->size, ARCH_CONVERT,
- -xfs_attr_leaf_newentsize(args, mp->m_sb.sb_blocksize, &tmp));
+ -xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
+ mp->m_sb.sb_blocksize, &tmp));
INT_SET(entry->nameidx, ARCH_CONVERT,
INT_GET(map->base, ARCH_CONVERT)
+ INT_GET(map->size, ARCH_CONVERT));
memcpy((char *)name_rmt->name, args->name, args->namelen);
entry->flags |= XFS_ATTR_INCOMPLETE;
/* just in case */
- INT_ZERO(name_rmt->valuelen, ARCH_CONVERT);
- INT_ZERO(name_rmt->valueblk, ARCH_CONVERT);
+ name_rmt->valuelen = 0;
+ name_rmt->valueblk = 0;
args->rmtblkno = 1;
args->rmtblkcnt = XFS_B_TO_FSB(mp, args->valuelen);
}
hdr_d->info = hdr_s->info; /* struct copy */
INT_SET(hdr_d->firstused, ARCH_CONVERT, XFS_LBSIZE(mp));
/* handle truncation gracefully */
- if (INT_ISZERO(hdr_d->firstused, ARCH_CONVERT)) {
+ if (!hdr_d->firstused) {
INT_SET(hdr_d->firstused, ARCH_CONVERT,
XFS_LBSIZE(mp) - XFS_ATTR_LEAF_NAME_ALIGN);
}
- INT_ZERO(hdr_d->usedbytes, ARCH_CONVERT);
- INT_ZERO(hdr_d->count, ARCH_CONVERT);
+ hdr_d->usedbytes = 0;
+ hdr_d->count = 0;
hdr_d->holes = 0;
INT_SET(hdr_d->freemap[0].base, ARCH_CONVERT,
sizeof(xfs_attr_leaf_hdr_t));
half = (max+1) * sizeof(*entry);
half += INT_GET(hdr1->usedbytes, ARCH_CONVERT)
+ INT_GET(hdr2->usedbytes, ARCH_CONVERT)
- + xfs_attr_leaf_newentsize(state->args,
- state->blocksize, NULL);
+ + xfs_attr_leaf_newentsize(
+ state->args->namelen,
+ state->args->valuelen,
+ state->blocksize, NULL);
half /= 2;
lastdelta = state->blocksize;
entry = &leaf1->entries[0];
*/
if (count == blk1->index) {
tmp = totallen + sizeof(*entry) +
- xfs_attr_leaf_newentsize(state->args,
- state->blocksize,
- NULL);
+ xfs_attr_leaf_newentsize(
+ state->args->namelen,
+ state->args->valuelen,
+ state->blocksize, NULL);
if (XFS_ATTR_ABS(half - tmp) > lastdelta)
break;
lastdelta = XFS_ATTR_ABS(half - tmp);
totallen -= count * sizeof(*entry);
if (foundit) {
totallen -= sizeof(*entry) +
- xfs_attr_leaf_newentsize(state->args,
- state->blocksize,
- NULL);
+ xfs_attr_leaf_newentsize(
+ state->args->namelen,
+ state->args->valuelen,
+ state->blocksize, NULL);
}
*countarg = count;
* Make altpath point to the block we want to keep and
* path point to the block we want to drop (this one).
*/
- forward = (!INT_ISZERO(info->forw, ARCH_CONVERT));
+ forward = info->forw;
memcpy(&state->altpath, &state->path, sizeof(state->path));
error = xfs_da_path_shift(state, &state->altpath, forward,
0, &retval);
INT_MOD(map->size, ARCH_CONVERT,
INT_GET(hdr->freemap[after].size,
ARCH_CONVERT));
- INT_ZERO(hdr->freemap[after].base, ARCH_CONVERT);
- INT_ZERO(hdr->freemap[after].size, ARCH_CONVERT);
+ hdr->freemap[after].base = 0;
+ hdr->freemap[after].size = 0;
} else if (before >= 0) {
map = &hdr->freemap[before];
INT_MOD(map->size, ARCH_CONVERT, entsize);
tmp = INT_GET(entry->nameidx, ARCH_CONVERT);
}
INT_SET(hdr->firstused, ARCH_CONVERT, tmp);
- if (INT_ISZERO(hdr->firstused, ARCH_CONVERT)) {
+ if (!hdr->firstused) {
INT_SET(hdr->firstused, ARCH_CONVERT,
tmp - XFS_ATTR_LEAF_NAME_ALIGN);
}
tmp_leaf = (xfs_attr_leafblock_t *)tmpbuffer;
tmp_hdr = &tmp_leaf->hdr;
tmp_hdr->info = save_hdr->info; /* struct copy */
- INT_ZERO(tmp_hdr->count, ARCH_CONVERT);
+ tmp_hdr->count = 0;
INT_SET(tmp_hdr->firstused, ARCH_CONVERT, state->blocksize);
- if (INT_ISZERO(tmp_hdr->firstused, ARCH_CONVERT)) {
+ if (!tmp_hdr->firstused) {
INT_SET(tmp_hdr->firstused, ARCH_CONVERT,
state->blocksize - XFS_ATTR_LEAF_NAME_ALIGN);
}
- INT_ZERO(tmp_hdr->usedbytes, ARCH_CONVERT);
+ tmp_hdr->usedbytes = 0;
if (xfs_attr_leaf_order(save_blk->bp, drop_blk->bp)) {
xfs_attr_leaf_moveents(drop_leaf, 0, tmp_leaf, 0,
(int)INT_GET(drop_hdr->count, ARCH_CONVERT),
else
break;
}
- ASSERT((probe >= 0) && \
- ((INT_ISZERO(leaf->hdr.count, ARCH_CONVERT))
+ ASSERT((probe >= 0) &&
+ (!leaf->hdr.count
|| (probe < INT_GET(leaf->hdr.count, ARCH_CONVERT))));
ASSERT((span <= 4) || (INT_GET(entry->hashval, ARCH_CONVERT)
== hashval));
INT_SET(hdr_d->freemap[0].size, ARCH_CONVERT,
INT_GET(hdr_d->firstused, ARCH_CONVERT)
- INT_GET(hdr_d->freemap[0].base, ARCH_CONVERT));
- INT_ZERO(hdr_d->freemap[1].base, ARCH_CONVERT);
- INT_ZERO(hdr_d->freemap[2].base, ARCH_CONVERT);
- INT_ZERO(hdr_d->freemap[1].size, ARCH_CONVERT);
- INT_ZERO(hdr_d->freemap[2].size, ARCH_CONVERT);
+ hdr_d->freemap[1].base = 0;
+ hdr_d->freemap[2].base = 0;
+ hdr_d->freemap[1].size = 0;
+ hdr_d->freemap[2].size = 0;
hdr_s->holes = 1; /* leaf may not be compact */
}
== XFS_ATTR_LEAF_MAGIC);
if (count)
*count = INT_GET(leaf->hdr.count, ARCH_CONVERT);
- if (INT_ISZERO(leaf->hdr.count, ARCH_CONVERT))
+ if (!leaf->hdr.count)
return(0);
return(INT_GET(leaf->entries[INT_GET(leaf->hdr.count,
ARCH_CONVERT)-1].hashval, ARCH_CONVERT));
* Calculate the number of bytes used to store the indicated attribute
* (whether local or remote only calculate bytes in this block).
*/
-int
+STATIC int
xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index)
{
xfs_attr_leaf_name_local_t *name_loc;
* a "local" or a "remote" attribute.
*/
int
-xfs_attr_leaf_newentsize(xfs_da_args_t *args, int blocksize, int *local)
+xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, int *local)
{
int size;
- size = XFS_ATTR_LEAF_ENTSIZE_LOCAL(args->namelen, args->valuelen);
+ size = XFS_ATTR_LEAF_ENTSIZE_LOCAL(namelen, valuelen);
if (size < XFS_ATTR_LEAF_ENTSIZE_LOCAL_MAX(blocksize)) {
if (local) {
*local = 1;
}
} else {
- size = XFS_ATTR_LEAF_ENTSIZE_REMOTE(args->namelen);
+ size = XFS_ATTR_LEAF_ENTSIZE_REMOTE(namelen);
if (local) {
*local = 0;
}
* we may be reading them directly out of a user buffer.
*/
/*ARGSUSED*/
-int
+STATIC int
xfs_attr_put_listent(xfs_attr_list_context_t *context,
attrnames_t *namesp, char *name, int namelen, int valuelen)
{
XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
if ((entry->flags & XFS_ATTR_LOCAL) == 0) {
name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, args->index);
- INT_ZERO(name_rmt->valueblk, ARCH_CONVERT);
- INT_ZERO(name_rmt->valuelen, ARCH_CONVERT);
+ name_rmt->valueblk = 0;
+ name_rmt->valuelen = 0;
xfs_da_log_buf(args->trans, bp,
XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt)));
}
XFS_DA_LOGRANGE(leaf2, entry2, sizeof(*entry2)));
if ((entry2->flags & XFS_ATTR_LOCAL) == 0) {
name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf2, args->index2);
- INT_ZERO(name_rmt->valueblk, ARCH_CONVERT);
- INT_ZERO(name_rmt->valuelen, ARCH_CONVERT);
+ name_rmt->valueblk = 0;
+ name_rmt->valuelen = 0;
xfs_da_log_buf(args->trans, bp2,
XFS_DA_LOGRANGE(leaf2, name_rmt, sizeof(*name_rmt)));
}
* Recurse (gasp!) through the attribute nodes until we find leaves.
* We're doing a depth-first traversal in order to invalidate everything.
*/
-int
+STATIC int
xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp,
int level)
{
* Note that we must release the lock on the buffer so that we are not
* caught holding something that the logging code wants to flush to disk.
*/
-int
+STATIC int
xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp)
{
xfs_attr_leafblock_t *leaf;
if ( INT_GET(entry->nameidx, ARCH_CONVERT)
&& ((entry->flags & XFS_ATTR_LOCAL) == 0)) {
name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, i);
- if (!INT_ISZERO(name_rmt->valueblk, ARCH_CONVERT))
+ if (name_rmt->valueblk)
count++;
}
}
if ( INT_GET(entry->nameidx, ARCH_CONVERT)
&& ((entry->flags & XFS_ATTR_LOCAL) == 0)) {
name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, i);
- if (!INT_ISZERO(name_rmt->valueblk, ARCH_CONVERT)) {
+ if (name_rmt->valueblk) {
/* both on-disk, don't endian flip twice */
lp->valueblk = name_rmt->valueblk;
INT_SET(lp->valuelen, ARCH_CONVERT,
* Look at all the extents for this logical region,
* invalidate any buffers that are incore/in transactions.
*/
-int
+STATIC int
xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp,
xfs_dablk_t blkno, int blkcnt)
{