~ubuntu-branches/ubuntu/hoary/xfsprogs/hoary

« back to all changes in this revision

Viewing changes to libxfs/xfs_attr_leaf.c

  • Committer: Bazaar Package Importer
  • Author(s): Nathan Scott
  • Date: 2004-07-28 21:11:38 UTC
  • Revision ID: james.westby@ubuntu.com-20040728211138-0v4pdnunnp7na5lm
Tags: 2.6.20-1
* New upstream release.
* Fix xfs_io segfault on non-XFS files.  (closes: #260470)
* Fix packaging botch, deleted files included.  (closes: #260491)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
3
 
 * 
 
2
 * Copyright (c) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
 
3
 *
4
4
 * This program is free software; you can redistribute it and/or modify it
5
5
 * under the terms of version 2 of the GNU General Public License as
6
6
 * published by the Free Software Foundation.
7
 
 * 
 
7
 *
8
8
 * This program is distributed in the hope that it would be useful, but
9
9
 * WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
 
 * 
 
11
 *
12
12
 * Further, this software is distributed without any warranty that it is
13
13
 * free of the rightful claim of any third person regarding infringement
14
 
 * or the like.  Any license provided herein, whether implied or
 
14
 * or the like.  Any license provided herein, whether implied or
15
15
 * otherwise, applies only to this software file.  Patent licenses, if
16
16
 * any, provided herein do not apply to combinations of this program with
17
17
 * other software, or any other product whatsoever.
18
 
 * 
 
18
 *
19
19
 * You should have received a copy of the GNU General Public License along
20
20
 * with this program; if not, write the Free Software Foundation, Inc., 59
21
21
 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22
 
 * 
 
22
 *
23
23
 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24
24
 * Mountain View, CA  94043, or:
25
 
 * 
26
 
 * http://www.sgi.com 
27
 
 * 
28
 
 * For further information regarding this notice, see: 
29
 
 * 
 
25
 *
 
26
 * http://www.sgi.com
 
27
 *
 
28
 * For further information regarding this notice, see:
 
29
 *
30
30
 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31
31
 */
32
32
 
63
63
                return(error);
64
64
        ASSERT(bp != NULL);
65
65
        leaf = bp->data;
66
 
        bzero((char *)leaf, XFS_LBSIZE(dp->i_mount));
 
66
        memset((char *)leaf, 0, XFS_LBSIZE(dp->i_mount));
67
67
        hdr = &leaf->hdr;
68
68
        INT_SET(hdr->info.magic, ARCH_CONVERT, XFS_ATTR_LEAF_MAGIC);
69
69
        INT_SET(hdr->firstused, ARCH_CONVERT, XFS_LBSIZE(dp->i_mount));
70
 
        if (INT_GET(hdr->firstused, ARCH_CONVERT) == 0) {
 
70
        if (INT_ISZERO(hdr->firstused, ARCH_CONVERT)) {
71
71
                INT_SET(hdr->firstused, ARCH_CONVERT,
72
72
                        XFS_LBSIZE(dp->i_mount) - XFS_ATTR_LEAF_NAME_ALIGN);
73
73
        }
170
170
                        sum += INT_GET(map->size, ARCH_CONVERT);
171
171
                        continue;
172
172
                }
173
 
                if (INT_GET(map->size, ARCH_CONVERT) == 0)
 
173
                if (INT_ISZERO(map->size, ARCH_CONVERT))
174
174
                        continue;       /* no space in this map */
175
175
                tmp = entsize;
176
176
                if (INT_GET(map->base, ARCH_CONVERT)
238
238
        if (args->index < INT_GET(hdr->count, ARCH_CONVERT)) {
239
239
                tmp  = INT_GET(hdr->count, ARCH_CONVERT) - args->index;
240
240
                tmp *= sizeof(xfs_attr_leaf_entry_t);
241
 
                ovbcopy((char *)entry, (char *)(entry+1), tmp);
 
241
                memmove((char *)(entry+1), (char *)entry, tmp);
242
242
                xfs_da_log_buf(args->trans, bp,
243
243
                    XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry)));
244
244
        }
263
263
                                      + INT_GET(map->size, ARCH_CONVERT));
264
264
        INT_SET(entry->hashval, ARCH_CONVERT, args->hashval);
265
265
        entry->flags = tmp ? XFS_ATTR_LOCAL : 0;
266
 
        entry->flags |= (args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0;
 
266
        entry->flags |= (args->flags & ATTR_SECURE) ? XFS_ATTR_SECURE :
 
267
                        ((args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0);
267
268
        if (args->rename) {
268
269
                entry->flags |= XFS_ATTR_INCOMPLETE;
269
270
                if ((args->blkno2 == args->blkno) &&
283
284
        /*
284
285
         * Copy the attribute name and value into the new space.
285
286
         *
286
 
         * For "remote" attribute values, simply note that we need to 
 
287
         * For "remote" attribute values, simply note that we need to
287
288
         * allocate space for the "remote" value.  We can't actually
288
289
         * allocate the extents in this transaction, and we can't decide
289
290
         * which blocks they should be as we might allocate more blocks
293
294
                name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, args->index);
294
295
                name_loc->namelen = args->namelen;
295
296
                INT_SET(name_loc->valuelen, ARCH_CONVERT, args->valuelen);
296
 
                bcopy(args->name, (char *)name_loc->nameval, args->namelen);
297
 
                bcopy(args->value, (char *)&name_loc->nameval[args->namelen],
 
297
                memcpy((char *)name_loc->nameval, args->name, args->namelen);
 
298
                memcpy((char *)&name_loc->nameval[args->namelen], args->value,
298
299
                                   INT_GET(name_loc->valuelen, ARCH_CONVERT));
299
300
        } else {
300
301
                name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, args->index);
301
302
                name_rmt->namelen = args->namelen;
302
 
                bcopy(args->name, (char *)name_rmt->name, args->namelen);
 
303
                memcpy((char *)name_rmt->name, args->name, args->namelen);
303
304
                entry->flags |= XFS_ATTR_INCOMPLETE;
304
305
                /* just in case */
305
 
                INT_SET(name_rmt->valuelen, ARCH_CONVERT, 0);
306
 
                INT_SET(name_rmt->valueblk, ARCH_CONVERT, 0);
 
306
                INT_ZERO(name_rmt->valuelen, ARCH_CONVERT);
 
307
                INT_ZERO(name_rmt->valueblk, ARCH_CONVERT);
307
308
                args->rmtblkno = 1;
308
309
                args->rmtblkcnt = XFS_B_TO_FSB(mp, args->valuelen);
309
310
        }
316
317
         */
317
318
        if (INT_GET(entry->nameidx, ARCH_CONVERT)
318
319
                                < INT_GET(hdr->firstused, ARCH_CONVERT)) {
319
 
                INT_SET(hdr->firstused, ARCH_CONVERT,
320
 
                                        INT_GET(entry->nameidx, ARCH_CONVERT));
 
320
                /* both on-disk, don't endian-flip twice */
 
321
                hdr->firstused = entry->nameidx;
321
322
        }
322
323
        ASSERT(INT_GET(hdr->firstused, ARCH_CONVERT)
323
324
                                >= ((INT_GET(hdr->count, ARCH_CONVERT)
355
356
        mp = trans->t_mountp;
356
357
        tmpbuffer = kmem_alloc(XFS_LBSIZE(mp), KM_SLEEP);
357
358
        ASSERT(tmpbuffer != NULL);
358
 
        bcopy(bp->data, tmpbuffer, XFS_LBSIZE(mp));
359
 
        bzero(bp->data, XFS_LBSIZE(mp));
 
359
        memcpy(tmpbuffer, bp->data, XFS_LBSIZE(mp));
 
360
        memset(bp->data, 0, XFS_LBSIZE(mp));
360
361
 
361
362
        /*
362
363
         * Copy basic information
368
369
        hdr_d->info = hdr_s->info;      /* struct copy */
369
370
        INT_SET(hdr_d->firstused, ARCH_CONVERT, XFS_LBSIZE(mp));
370
371
        /* handle truncation gracefully */
371
 
        if (INT_GET(hdr_d->firstused, ARCH_CONVERT) == 0) {
 
372
        if (INT_ISZERO(hdr_d->firstused, ARCH_CONVERT)) {
372
373
                INT_SET(hdr_d->firstused, ARCH_CONVERT,
373
374
                                XFS_LBSIZE(mp) - XFS_ATTR_LEAF_NAME_ALIGN);
374
375
        }
375
 
        INT_SET(hdr_d->usedbytes, ARCH_CONVERT, 0);
376
 
        INT_SET(hdr_d->count, ARCH_CONVERT, 0);
 
376
        INT_ZERO(hdr_d->usedbytes, ARCH_CONVERT);
 
377
        INT_ZERO(hdr_d->count, ARCH_CONVERT);
377
378
        hdr_d->holes = 0;
378
379
        INT_SET(hdr_d->freemap[0].base, ARCH_CONVERT,
379
380
                                        sizeof(xfs_attr_leaf_hdr_t));
662
663
         */
663
664
        totallen -= count * sizeof(*entry);
664
665
        if (foundit) {
665
 
                totallen -= sizeof(*entry) + 
 
666
                totallen -= sizeof(*entry) +
666
667
                                xfs_attr_leaf_newentsize(state->args,
667
668
                                                         state->blocksize,
668
669
                                                         NULL);
712
713
                count * sizeof(xfs_attr_leaf_entry_t) +
713
714
                INT_GET(leaf->hdr.usedbytes, ARCH_CONVERT);
714
715
        if (bytes > (state->blocksize >> 1)) {
715
 
                *action = 0;    /* blk over 50%, dont try to join */
 
716
                *action = 0;    /* blk over 50%, don't try to join */
716
717
                return(0);
717
718
        }
718
719
 
727
728
                 * Make altpath point to the block we want to keep and
728
729
                 * path point to the block we want to drop (this one).
729
730
                 */
730
 
                forward = (INT_GET(info->forw, ARCH_CONVERT) != 0);
731
 
                bcopy(&state->path, &state->altpath, sizeof(state->path));
 
731
                forward = (!INT_ISZERO(info->forw, ARCH_CONVERT));
 
732
                memcpy(&state->altpath, &state->path, sizeof(state->path));
732
733
                error = xfs_da_path_shift(state, &state->altpath, forward,
733
734
                                                 0, &retval);
734
735
                if (error)
788
789
         * Make altpath point to the block we want to keep (the lower
789
790
         * numbered block) and path point to the block we want to drop.
790
791
         */
791
 
        bcopy(&state->path, &state->altpath, sizeof(state->path));
 
792
        memcpy(&state->altpath, &state->path, sizeof(state->path));
792
793
        if (blkno < blk->blkno) {
793
794
                error = xfs_da_path_shift(state, &state->altpath, forward,
794
795
                                                 0, &retval);
867
868
                 */
868
869
                tmpbuffer = kmem_alloc(state->blocksize, KM_SLEEP);
869
870
                ASSERT(tmpbuffer != NULL);
870
 
                bzero(tmpbuffer, state->blocksize);
 
871
                memset(tmpbuffer, 0, state->blocksize);
871
872
                tmp_leaf = (xfs_attr_leafblock_t *)tmpbuffer;
872
873
                tmp_hdr = &tmp_leaf->hdr;
873
874
                tmp_hdr->info = save_hdr->info; /* struct copy */
874
 
                INT_SET(tmp_hdr->count, ARCH_CONVERT, 0);
 
875
                INT_ZERO(tmp_hdr->count, ARCH_CONVERT);
875
876
                INT_SET(tmp_hdr->firstused, ARCH_CONVERT, state->blocksize);
876
 
                if (INT_GET(tmp_hdr->firstused, ARCH_CONVERT) == 0) {
 
877
                if (INT_ISZERO(tmp_hdr->firstused, ARCH_CONVERT)) {
877
878
                        INT_SET(tmp_hdr->firstused, ARCH_CONVERT,
878
879
                                state->blocksize - XFS_ATTR_LEAF_NAME_ALIGN);
879
880
                }
880
 
                INT_SET(tmp_hdr->usedbytes, ARCH_CONVERT, 0);
 
881
                INT_ZERO(tmp_hdr->usedbytes, ARCH_CONVERT);
881
882
                if (xfs_attr_leaf_order(save_blk->bp, drop_blk->bp)) {
882
883
                        xfs_attr_leaf_moveents(drop_leaf, 0, tmp_leaf, 0,
883
884
                                (int)INT_GET(drop_hdr->count, ARCH_CONVERT),
895
896
                                (int)INT_GET(drop_hdr->count, ARCH_CONVERT),
896
897
                                mp);
897
898
                }
898
 
                bcopy((char *)tmp_leaf, (char *)save_leaf, state->blocksize);
 
899
                memcpy((char *)save_leaf, (char *)tmp_leaf, state->blocksize);
899
900
                kmem_free(tmpbuffer, state->blocksize);
900
901
        }
901
902
 
948
949
        ASSERT((INT_GET(hdr_s->count, ARCH_CONVERT) > 0)
949
950
                                && (INT_GET(hdr_s->count, ARCH_CONVERT)
950
951
                                                < (XFS_LBSIZE(mp)/8)));
951
 
        ASSERT(INT_GET(hdr_s->firstused, ARCH_CONVERT) >= 
 
952
        ASSERT(INT_GET(hdr_s->firstused, ARCH_CONVERT) >=
952
953
                ((INT_GET(hdr_s->count, ARCH_CONVERT)
953
954
                                        * sizeof(*entry_s))+sizeof(*hdr_s)));
954
955
        ASSERT(INT_GET(hdr_d->count, ARCH_CONVERT) < (XFS_LBSIZE(mp)/8));
955
 
        ASSERT(INT_GET(hdr_d->firstused, ARCH_CONVERT) >= 
 
956
        ASSERT(INT_GET(hdr_d->firstused, ARCH_CONVERT) >=
956
957
                ((INT_GET(hdr_d->count, ARCH_CONVERT)
957
958
                                        * sizeof(*entry_d))+sizeof(*hdr_d)));
958
959
 
968
969
                tmp *= sizeof(xfs_attr_leaf_entry_t);
969
970
                entry_s = &leaf_d->entries[start_d];
970
971
                entry_d = &leaf_d->entries[start_d + count];
971
 
                ovbcopy((char *)entry_s, (char *)entry_d, tmp);
 
972
                memmove((char *)entry_d, (char *)entry_s, tmp);
972
973
        }
973
974
 
974
975
        /*
989
990
                 * off for 6.2, should be revisited later.
990
991
                 */
991
992
                if (entry_s->flags & XFS_ATTR_INCOMPLETE) { /* skip partials? */
992
 
                        bzero(XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), tmp);
 
993
                        memset(XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), 0, tmp);
993
994
                        INT_MOD(hdr_s->usedbytes, ARCH_CONVERT, -tmp);
994
995
                        INT_MOD(hdr_s->count, ARCH_CONVERT, -1);
995
996
                        entry_d--;      /* to compensate for ++ in loop hdr */
999
1000
                } else {
1000
1001
#endif /* GROT */
1001
1002
                        INT_MOD(hdr_d->firstused, ARCH_CONVERT, -tmp);
1002
 
                        INT_SET(entry_d->hashval, ARCH_CONVERT,
1003
 
                                    INT_GET(entry_s->hashval, ARCH_CONVERT));
1004
 
                        INT_SET(entry_d->nameidx, ARCH_CONVERT,
1005
 
                                                INT_GET(hdr_d->firstused,
1006
 
                                                                ARCH_CONVERT));
 
1003
                        /* both on-disk, don't endian flip twice */
 
1004
                        entry_d->hashval = entry_s->hashval;
 
1005
                        /* both on-disk, don't endian flip twice */
 
1006
                        entry_d->nameidx = hdr_d->firstused;
1007
1007
                        entry_d->flags = entry_s->flags;
1008
1008
                        ASSERT(INT_GET(entry_d->nameidx, ARCH_CONVERT) + tmp
1009
1009
                                                        <= XFS_LBSIZE(mp));
1010
 
                        ovbcopy(XFS_ATTR_LEAF_NAME(leaf_s, start_s + i),
1011
 
                              XFS_ATTR_LEAF_NAME(leaf_d, desti), tmp);
 
1010
                        memmove(XFS_ATTR_LEAF_NAME(leaf_d, desti),
 
1011
                                XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), tmp);
1012
1012
                        ASSERT(INT_GET(entry_s->nameidx, ARCH_CONVERT) + tmp
1013
1013
                                                        <= XFS_LBSIZE(mp));
1014
 
                        bzero(XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), tmp);
 
1014
                        memset(XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), 0, tmp);
1015
1015
                        INT_MOD(hdr_s->usedbytes, ARCH_CONVERT, -tmp);
1016
1016
                        INT_MOD(hdr_d->usedbytes, ARCH_CONVERT, tmp);
1017
1017
                        INT_MOD(hdr_s->count, ARCH_CONVERT, -1);
1033
1033
                entry_s = &leaf_s->entries[start_s];
1034
1034
                ASSERT(((char *)entry_s + tmp) <=
1035
1035
                       ((char *)leaf_s + XFS_LBSIZE(mp)));
1036
 
                bzero((char *)entry_s, tmp);
 
1036
                memset((char *)entry_s, 0, tmp);
1037
1037
        } else {
1038
1038
                /*
1039
1039
                 * Move the remaining entries down to fill the hole,
1043
1043
                tmp *= sizeof(xfs_attr_leaf_entry_t);
1044
1044
                entry_s = &leaf_s->entries[start_s + count];
1045
1045
                entry_d = &leaf_s->entries[start_s];
1046
 
                ovbcopy((char *)entry_s, (char *)entry_d, tmp);
 
1046
                memmove((char *)entry_d, (char *)entry_s, tmp);
1047
1047
 
1048
1048
                tmp = count * sizeof(xfs_attr_leaf_entry_t);
1049
1049
                entry_s = &leaf_s->entries[INT_GET(hdr_s->count,
1050
1050
                                                        ARCH_CONVERT)];
1051
1051
                ASSERT(((char *)entry_s + tmp) <=
1052
1052
                       ((char *)leaf_s + XFS_LBSIZE(mp)));
1053
 
                bzero((char *)entry_s, tmp);
 
1053
                memset((char *)entry_s, 0, tmp);
1054
1054
        }
1055
1055
 
1056
1056
        /*
1064
1064
        INT_SET(hdr_d->freemap[0].size, ARCH_CONVERT,
1065
1065
                                INT_GET(hdr_d->firstused, ARCH_CONVERT)
1066
1066
                              - INT_GET(hdr_d->freemap[0].base, ARCH_CONVERT));
1067
 
        INT_SET(hdr_d->freemap[1].base, ARCH_CONVERT, 0);
1068
 
        INT_SET(hdr_d->freemap[2].base, ARCH_CONVERT, 0);
1069
 
        INT_SET(hdr_d->freemap[1].size, ARCH_CONVERT, 0);
1070
 
        INT_SET(hdr_d->freemap[2].size, ARCH_CONVERT, 0);
 
1067
        INT_ZERO(hdr_d->freemap[1].base, ARCH_CONVERT);
 
1068
        INT_ZERO(hdr_d->freemap[2].base, ARCH_CONVERT);
 
1069
        INT_ZERO(hdr_d->freemap[1].size, ARCH_CONVERT);
 
1070
        INT_ZERO(hdr_d->freemap[2].size, ARCH_CONVERT);
1071
1071
        hdr_s->holes = 1;       /* leaf may not be compact */
1072
1072
}
1073
1073
 
1090
1090
            && (INT_GET(leaf2->hdr.count, ARCH_CONVERT) > 0)
1091
1091
            && (   (INT_GET(leaf2->entries[ 0 ].hashval, ARCH_CONVERT) <
1092
1092
                      INT_GET(leaf1->entries[ 0 ].hashval, ARCH_CONVERT))
1093
 
                || (INT_GET(leaf2->entries[INT_GET(leaf2->hdr.count,
 
1093
                || (INT_GET(leaf2->entries[INT_GET(leaf2->hdr.count,
1094
1094
                                ARCH_CONVERT)-1].hashval, ARCH_CONVERT) <
1095
1095
                      INT_GET(leaf1->entries[INT_GET(leaf1->hdr.count,
1096
1096
                                ARCH_CONVERT)-1].hashval, ARCH_CONVERT))) ) {
1112
1112
                                                == XFS_ATTR_LEAF_MAGIC);
1113
1113
        if (count)
1114
1114
                *count = INT_GET(leaf->hdr.count, ARCH_CONVERT);
1115
 
        if (INT_GET(leaf->hdr.count, ARCH_CONVERT) == 0)
 
1115
        if (INT_ISZERO(leaf->hdr.count, ARCH_CONVERT))
1116
1116
                return(0);
1117
1117
        return(INT_GET(leaf->entries[INT_GET(leaf->hdr.count,
1118
1118
                                ARCH_CONVERT)-1].hashval, ARCH_CONVERT));
1155
1155
        int size;
1156
1156
 
1157
1157
        size = XFS_ATTR_LEAF_ENTSIZE_LOCAL(args->namelen, args->valuelen);
1158
 
        if (size < XFS_ATTR_LEAF_ENTSIZE_LOCAL_MAX(blocksize)) { 
 
1158
        if (size < XFS_ATTR_LEAF_ENTSIZE_LOCAL_MAX(blocksize)) {
1159
1159
                if (local) {
1160
1160
                        *local = 1;
1161
1161
                }