Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 47847
b: refs/heads/master
c: e5889e9
h: refs/heads/master
i:
  47845: a1dcc44
  47843: e12bf76
  47839: 0d982f3
v: v3
  • Loading branch information
Barry Naujok authored and Tim Shimmin committed Feb 10, 2007
1 parent 5355eb0 commit 45d8d1e
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 12 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: 7666ab5fb378678a9d5eb3c0dc8d3170e274e7a4
refs/heads/master: e5889e90dda328443161e9512f1123c9814d03de
19 changes: 11 additions & 8 deletions trunk/fs/xfs/xfs_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,19 +198,15 @@ xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen,
if ((error = XFS_QM_DQATTACH(mp, dp, 0)))
return (error);

/*
* 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);

/*
* If the inode doesn't have an attribute fork, add one.
* (inode must not be locked when we call this routine)
*/
if (XFS_IFORK_Q(dp) == 0) {
if ((error = xfs_bmap_add_attrfork(dp, size, rsvd)))
int sf_size = sizeof(xfs_attr_sf_hdr_t) +
XFS_ATTR_SF_ENTSIZE_BYNAME(namelen, valuelen);

if ((error = xfs_bmap_add_attrfork(dp, sf_size, rsvd)))
return(error);
}

Expand All @@ -231,6 +227,13 @@ xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen,
args.addname = 1;
args.oknoent = 1;

/*
* 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)) {
Expand Down
45 changes: 42 additions & 3 deletions trunk/fs/xfs/xfs_attr_leaf.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,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;
xfs_mount_t *mp = dp->i_mount;

offset = (XFS_LITINO(mp) - bytes) >> 3; /* rounded down */
Expand All @@ -169,8 +170,43 @@ xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes)
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));
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
* the btree root.
*/
if (!dp->i_d.di_forkoff && dp->i_df.if_bytes > mp->m_attroffset)
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
* plenty of room for attrs
*/
if (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);
break;
}

/*
* 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));
minforkoff = roundup(minforkoff, 8) >> 3;

/* attr fork btree root can have at least this many key/ptr pairs */
Expand Down Expand Up @@ -336,7 +372,8 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
*/
totsize -= size;
if (totsize == sizeof(xfs_attr_sf_hdr_t) && !args->addname &&
(mp->m_flags & XFS_MOUNT_ATTR2)) {
(mp->m_flags & XFS_MOUNT_ATTR2) &&
(dp->i_d.di_format != XFS_DINODE_FMT_BTREE)) {
/*
* Last attribute now removed, revert to original
* inode format making all literal area available
Expand Down Expand Up @@ -748,6 +785,7 @@ xfs_attr_shortform_allfit(xfs_dabuf_t *bp, xfs_inode_t *dp)
+ be16_to_cpu(name_loc->valuelen);
}
if ((dp->i_mount->m_flags & XFS_MOUNT_ATTR2) &&
(dp->i_d.di_format != XFS_DINODE_FMT_BTREE) &&
(bytes == sizeof(struct xfs_attr_sf_hdr)))
return(-1);
return(xfs_attr_shortform_bytesfit(dp, bytes));
Expand Down Expand Up @@ -786,6 +824,7 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff)

if (forkoff == -1) {
ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2);
ASSERT(dp->i_d.di_format != XFS_DINODE_FMT_BTREE);

/*
* Last attribute was removed, revert to original
Expand Down
1 change: 1 addition & 0 deletions trunk/fs/xfs/xfs_bmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -3543,6 +3543,7 @@ xfs_bmap_forkoff_reset(
if (whichfork == XFS_ATTR_FORK &&
(ip->i_d.di_format != XFS_DINODE_FMT_DEV) &&
(ip->i_d.di_format != XFS_DINODE_FMT_UUID) &&
(ip->i_d.di_format != XFS_DINODE_FMT_BTREE) &&
((mp->m_attroffset >> 3) > ip->i_d.di_forkoff)) {
ip->i_d.di_forkoff = mp->m_attroffset >> 3;
ip->i_df.if_ext_max = XFS_IFORK_DSIZE(ip) /
Expand Down

0 comments on commit 45d8d1e

Please sign in to comment.