Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 276313
b: refs/heads/master
c: 4c393a6
h: refs/heads/master
i:
  276311: 993af75
v: v3
  • Loading branch information
Christoph Hellwig authored and Ben Myers committed Nov 29, 2011
1 parent 9158acd commit fc90ca6
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 26 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4dd2cb4a28b7ab1f37163a4eba280926a13a8749
refs/heads/master: 4c393a6059f8442a70512a48ce4639b882b6f6ad
64 changes: 39 additions & 25 deletions trunk/fs/xfs/xfs_attr_leaf.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ xfs_attr_namesp_match(int arg_flags, int ondisk_flags)
/*
* 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.
*
Expand All @@ -122,7 +123,7 @@ 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 */
int dsize;
int dsize;
xfs_mount_t *mp = dp->i_mount;

offset = (XFS_LITINO(mp) - bytes) >> 3; /* rounded down */
Expand All @@ -136,47 +137,60 @@ xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes)
return (offset >= minforkoff) ? minforkoff : 0;
}

if (!(mp->m_flags & XFS_MOUNT_ATTR2)) {
if (bytes <= XFS_IFORK_ASIZE(dp))
return dp->i_d.di_forkoff;
/*
* If the requested numbers of bytes is smaller or equal to the
* current attribute fork size we can always proceed.
*
* Note that if_bytes in the data fork might actually be larger than
* the current data fork size is due to delalloc extents. In that
* case either the extent count will go down when they are converted
* to real extents, or the delalloc conversion will take care of the
* literal area rebalancing.
*/
if (bytes <= XFS_IFORK_ASIZE(dp))
return dp->i_d.di_forkoff;

/*
* For attr2 we can try to move the forkoff if there is space in the
* literal area, but for the old format we are done if there is no
* space in the fixed attribute fork.
*/
if (!(mp->m_flags & XFS_MOUNT_ATTR2))
return 0;
}

dsize = dp->i_df.if_bytes;

switch (dp->i_d.di_format) {
case XFS_DINODE_FMT_EXTENTS:
/*
/*
* If there is no attr fork and the data fork is extents,
* determine if creating the default attr fork will result
* in the extents form migrating to btree. If so, the
* minimum offset only needs to be the space required for
* determine if creating the default attr fork will result
* in the extents form migrating to btree. If so, the
* minimum offset only needs to be the space required for
* the btree root.
*/
*/
if (!dp->i_d.di_forkoff && dp->i_df.if_bytes >
xfs_default_attroffset(dp))
dsize = XFS_BMDR_SPACE_CALC(MINDBTPTRS);
break;

case XFS_DINODE_FMT_BTREE:
/*
* If have data btree then keep forkoff if we have one,
* otherwise we are adding a new attr, so then we set
* minforkoff to where the btree root can finish so we have
* If we have a data btree then keep forkoff if we have one,
* otherwise we are adding a new attr, so then we set
* minforkoff to where the btree root can finish so we have
* plenty of room for attrs
*/
if (dp->i_d.di_forkoff) {
if (offset < dp->i_d.di_forkoff)
if (offset < dp->i_d.di_forkoff)
return 0;
else
return dp->i_d.di_forkoff;
} else
dsize = XFS_BMAP_BROOT_SPACE(dp->i_df.if_broot);
return dp->i_d.di_forkoff;
}
dsize = XFS_BMAP_BROOT_SPACE(dp->i_df.if_broot);
break;
}
/*
* A data fork btree root must have space for at least

/*
* A data fork btree root must have space for at least
* MINDBTPTRS key/ptr pairs if the data fork is small or empty.
*/
minforkoff = MAX(dsize, XFS_BMDR_SPACE_CALC(MINDBTPTRS));
Expand All @@ -186,10 +200,10 @@ xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes)
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;
if (offset >= minforkoff)
return offset;
return 0;
}

Expand Down

0 comments on commit fc90ca6

Please sign in to comment.