2
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
2
* Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
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.
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.
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.
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.
23
23
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24
24
* Mountain View, CA 94043, or:
28
* For further information regarding this notice, see:
28
* For further information regarding this notice, see:
30
30
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
64
64
ASSERT(bp != NULL);
66
bzero((char *)leaf, XFS_LBSIZE(dp->i_mount));
66
memset((char *)leaf, 0, XFS_LBSIZE(dp->i_mount));
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);
170
170
sum += INT_GET(map->size, ARCH_CONVERT);
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 */
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)));
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) &&
284
285
* Copy the attribute name and value into the new space.
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));
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);
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;
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));
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);
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));
663
664
totallen -= count * sizeof(*entry);
665
totallen -= sizeof(*entry) +
666
totallen -= sizeof(*entry) +
666
667
xfs_attr_leaf_newentsize(state->args,
667
668
state->blocksize,
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 */
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).
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,
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.
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,
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);
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),
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);
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)));
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);
989
990
* off for 6.2, should be revisited later.
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 */
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,
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);
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);
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);
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 */
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);
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))
1117
1117
return(INT_GET(leaf->entries[INT_GET(leaf->hdr.count,
1118
1118
ARCH_CONVERT)-1].hashval, ARCH_CONVERT));