]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/xfs/xfs_attr_leaf.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6.25
[linux-2.6-omap-h63xx.git] / fs / xfs / xfs_attr_leaf.c
index 9719bbef122ce355c20894a51d424e4b264be933..b08e2a2a8addb24df3c5bfa8f229c792400c632d 100644 (file)
@@ -94,7 +94,7 @@ STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index);
  * Namespace helper routines
  *========================================================================*/
 
-STATIC inline attrnames_t *
+STATIC_INLINE attrnames_t *
 xfs_attr_flags_namesp(int flags)
 {
        return ((flags & XFS_ATTR_SECURE) ? &attr_secure:
@@ -105,7 +105,7 @@ xfs_attr_flags_namesp(int flags)
  * If namespace bits don't match return 0.
  * If all match then return 1.
  */
-STATIC inline int
+STATIC_INLINE int
 xfs_attr_namesp_match(int arg_flags, int ondisk_flags)
 {
        return XFS_ATTR_NSP_ONDISK(ondisk_flags) == XFS_ATTR_NSP_ARGS_TO_ONDISK(arg_flags);
@@ -116,7 +116,7 @@ xfs_attr_namesp_match(int arg_flags, int ondisk_flags)
  * then return 0.
  * If all match or are overridable then return 1.
  */
-STATIC inline int
+STATIC_INLINE int
 xfs_attr_namesp_match_overrides(int arg_flags, int ondisk_flags)
 {
        if (((arg_flags & ATTR_SECURE) == 0) !=
@@ -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 */
@@ -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 */
@@ -190,17 +226,15 @@ xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes)
 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);
+               spin_lock(&mp->m_sb_lock);
                if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb)) {
                        XFS_SB_VERSION_ADDATTR2(&mp->m_sb);
-                       XFS_SB_UNLOCK(mp, s);
+                       spin_unlock(&mp->m_sb_lock);
                        xfs_mod_sb(tp, XFS_SB_VERSIONNUM | XFS_SB_FEATURES2);
                } else
-                       XFS_SB_UNLOCK(mp, s);
+                       spin_unlock(&mp->m_sb_lock);
        }
 }
 
@@ -283,7 +317,7 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff)
        memcpy(sfe->nameval, args->name, args->namelen);
        memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen);
        sf->hdr.count++;
-       be16_add(&sf->hdr.totsize, size);
+       be16_add_cpu(&sf->hdr.totsize, size);
        xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
 
        xfs_sbversion_add_attr2(mp, args->trans);
@@ -329,14 +363,15 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
        if (end != totsize)
                memmove(&((char *)sf)[base], &((char *)sf)[end], totsize - end);
        sf->hdr.count--;
-       be16_add(&sf->hdr.totsize, -size);
+       be16_add_cpu(&sf->hdr.totsize, -size);
 
        /*
         * 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)) {
+           (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
@@ -355,7 +390,8 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
                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));
+                       !(mp->m_flags & XFS_MOUNT_ATTR2) ||
+                       dp->i_d.di_format == XFS_DINODE_FMT_BTREE);
                dp->i_afp->if_ext_max =
                        XFS_IFORK_ASIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
                dp->i_df.if_ext_max =
@@ -748,6 +784,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));
@@ -786,6 +823,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
@@ -1095,7 +1133,7 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex)
                xfs_da_log_buf(args->trans, bp,
                    XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry)));
        }
-       be16_add(&hdr->count, 1);
+       be16_add_cpu(&hdr->count, 1);
 
        /*
         * Allocate space for the new string (at the end of the run).
@@ -1109,7 +1147,7 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex)
                                         mp->m_sb.sb_blocksize, NULL));
        ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp));
        ASSERT((be16_to_cpu(map->size) & 0x3) == 0);
-       be16_add(&map->size,
+       be16_add_cpu(&map->size,
                -xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
                                          mp->m_sb.sb_blocksize, &tmp));
        entry->nameidx = cpu_to_be16(be16_to_cpu(map->base) +
@@ -1176,12 +1214,12 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex)
        map = &hdr->freemap[0];
        for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; map++, i++) {
                if (be16_to_cpu(map->base) == tmp) {
-                       be16_add(&map->base, sizeof(xfs_attr_leaf_entry_t));
-                       be16_add(&map->size,
+                       be16_add_cpu(&map->base, sizeof(xfs_attr_leaf_entry_t));
+                       be16_add_cpu(&map->size,
                                 -((int)sizeof(xfs_attr_leaf_entry_t)));
                }
        }
-       be16_add(&hdr->usedbytes, xfs_attr_leaf_entsize(leaf, args->index));
+       be16_add_cpu(&hdr->usedbytes, xfs_attr_leaf_entsize(leaf, args->index));
        xfs_da_log_buf(args->trans, bp,
                XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr)));
        return(0);
@@ -1689,9 +1727,9 @@ xfs_attr_leaf_remove(xfs_dabuf_t *bp, xfs_da_args_t *args)
                ASSERT(be16_to_cpu(map->base) < XFS_LBSIZE(mp));
                ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp));
                if (be16_to_cpu(map->base) == tablesize) {
-                       be16_add(&map->base,
+                       be16_add_cpu(&map->base,
                                 -((int)sizeof(xfs_attr_leaf_entry_t)));
-                       be16_add(&map->size, sizeof(xfs_attr_leaf_entry_t));
+                       be16_add_cpu(&map->size, sizeof(xfs_attr_leaf_entry_t));
                }
 
                if ((be16_to_cpu(map->base) + be16_to_cpu(map->size))
@@ -1713,19 +1751,19 @@ xfs_attr_leaf_remove(xfs_dabuf_t *bp, xfs_da_args_t *args)
        if ((before >= 0) || (after >= 0)) {
                if ((before >= 0) && (after >= 0)) {
                        map = &hdr->freemap[before];
-                       be16_add(&map->size, entsize);
-                       be16_add(&map->size,
+                       be16_add_cpu(&map->size, entsize);
+                       be16_add_cpu(&map->size,
                                 be16_to_cpu(hdr->freemap[after].size));
                        hdr->freemap[after].base = 0;
                        hdr->freemap[after].size = 0;
                } else if (before >= 0) {
                        map = &hdr->freemap[before];
-                       be16_add(&map->size, entsize);
+                       be16_add_cpu(&map->size, entsize);
                } else {
                        map = &hdr->freemap[after];
                        /* both on-disk, don't endian flip twice */
                        map->base = entry->nameidx;
-                       be16_add(&map->size, entsize);
+                       be16_add_cpu(&map->size, entsize);
                }
        } else {
                /*
@@ -1750,7 +1788,7 @@ xfs_attr_leaf_remove(xfs_dabuf_t *bp, xfs_da_args_t *args)
         * Compress the remaining entries and zero out the removed stuff.
         */
        memset(XFS_ATTR_LEAF_NAME(leaf, args->index), 0, entsize);
-       be16_add(&hdr->usedbytes, -entsize);
+       be16_add_cpu(&hdr->usedbytes, -entsize);
        xfs_da_log_buf(args->trans, bp,
             XFS_DA_LOGRANGE(leaf, XFS_ATTR_LEAF_NAME(leaf, args->index),
                                   entsize));
@@ -1758,7 +1796,7 @@ xfs_attr_leaf_remove(xfs_dabuf_t *bp, xfs_da_args_t *args)
        tmp = (be16_to_cpu(hdr->count) - args->index)
                                        * sizeof(xfs_attr_leaf_entry_t);
        memmove((char *)entry, (char *)(entry+1), tmp);
-       be16_add(&hdr->count, -1);
+       be16_add_cpu(&hdr->count, -1);
        xfs_da_log_buf(args->trans, bp,
            XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry)));
        entry = &leaf->entries[be16_to_cpu(hdr->count)];
@@ -2144,15 +2182,15 @@ xfs_attr_leaf_moveents(xfs_attr_leafblock_t *leaf_s, int start_s,
                 */
                if (entry_s->flags & XFS_ATTR_INCOMPLETE) { /* skip partials? */
                        memset(XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), 0, tmp);
-                       be16_add(&hdr_s->usedbytes, -tmp);
-                       be16_add(&hdr_s->count, -1);
+                       be16_add_cpu(&hdr_s->usedbytes, -tmp);
+                       be16_add_cpu(&hdr_s->count, -1);
                        entry_d--;      /* to compensate for ++ in loop hdr */
                        desti--;
                        if ((start_s + i) < offset)
                                result++;       /* insertion index adjustment */
                } else {
 #endif /* GROT */
-                       be16_add(&hdr_d->firstused, -tmp);
+                       be16_add_cpu(&hdr_d->firstused, -tmp);
                        /* both on-disk, don't endian flip twice */
                        entry_d->hashval = entry_s->hashval;
                        /* both on-disk, don't endian flip twice */
@@ -2165,10 +2203,10 @@ xfs_attr_leaf_moveents(xfs_attr_leafblock_t *leaf_s, int start_s,
                        ASSERT(be16_to_cpu(entry_s->nameidx) + tmp
                                                        <= XFS_LBSIZE(mp));
                        memset(XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), 0, tmp);
-                       be16_add(&hdr_s->usedbytes, -tmp);
-                       be16_add(&hdr_d->usedbytes, tmp);
-                       be16_add(&hdr_s->count, -1);
-                       be16_add(&hdr_d->count, 1);
+                       be16_add_cpu(&hdr_s->usedbytes, -tmp);
+                       be16_add_cpu(&hdr_d->usedbytes, tmp);
+                       be16_add_cpu(&hdr_s->count, -1);
+                       be16_add_cpu(&hdr_d->count, 1);
                        tmp = be16_to_cpu(hdr_d->count)
                                                * sizeof(xfs_attr_leaf_entry_t)
                                                + sizeof(xfs_attr_leaf_hdr_t);
@@ -2209,7 +2247,7 @@ xfs_attr_leaf_moveents(xfs_attr_leafblock_t *leaf_s, int start_s,
         * Fill in the freemap information
         */
        hdr_d->freemap[0].base = cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t));
-       be16_add(&hdr_d->freemap[0].base, be16_to_cpu(hdr_d->count) *
+       be16_add_cpu(&hdr_d->freemap[0].base, be16_to_cpu(hdr_d->count) *
                        sizeof(xfs_attr_leaf_entry_t));
        hdr_d->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr_d->firstused)
                              - be16_to_cpu(hdr_d->freemap[0].base));
@@ -3013,7 +3051,7 @@ xfs_attr_rolltrans(xfs_trans_t **transp, xfs_inode_t *dp)
         * is in progress. The caller takes the responsibility to cancel
         * the duplicate transaction that gets returned.
         */
-       if ((error = xfs_trans_commit(trans, 0, NULL)))
+       if ((error = xfs_trans_commit(trans, 0)))
                return (error);
 
        trans = *transp;