2 * Copyright (c) 2007, Hartmut Reuter,
3 * RZG, Max-Planck-Institut f. Plasmaphysik.
11 #if defined(AFS_NAMEI_ENV) && !defined(AFS_NT40_ENV)
12 #include <sys/types.h>
14 #ifdef AFS_PTHREAD_ENV
16 #else /* AFS_PTHREAD_ENV */
17 #include <afs/assert.h>
18 #endif /* AFS_PTHREAD_ENV */
40 #include <afs/afsint.h>
44 #include <afs/afssyscalls.h>
48 #include "partition.h"
49 #include "viceinode.h"
54 #include "volser_prototypes.h"
55 #ifdef AFS_RXOSD_SUPPORT
58 #include "../vol/vol_osd_prototypes.h"
63 #define CHANGEPARENT 4
65 #define NAMEI_VNODEMASK 0x03ffffff
66 #define NAMEI_TAGMASK 0x7
67 #define NAMEI_TAGSHIFT 26
68 #define NAMEI_UNIQMASK 0xffffffff
69 #define NAMEI_UNIQSHIFT 32
78 struct rx_call * call;
84 ExtractVnodes(struct Msg *m, Volume *vol, afs_int32 class,
85 struct VnodeExtract **list,
86 afs_int32 *length, afs_uint32 where,
87 struct VnodeDiskObject *vd,
88 afs_int32 *parent, struct VnodeDiskObject *parentvd)
91 char buf[SIZEOF_LARGEDISKVNODE];
92 struct VnodeDiskObject *vnode = (struct VnodeDiskObject *)&buf;
94 StreamHandle_t *stream = 0;
95 struct VnodeClassInfo *vcp = &VnodeClassInfo[class];
96 struct VnodeExtract *e;
104 fdP = IH_OPEN(vol->vnodeIndex[class].handle);
106 sprintf(m->line, "Couldn't open %s Index of volume %u\n",
107 class ? "small":"large", V_id(vol));
108 rx_Write(m->call, m->line, strlen(m->line));
112 size = FDH_SIZE(fdP);
113 *list = (struct VnodeExtract *) malloc(size / vcp->diskSize
114 * sizeof(struct VnodeExtract));
119 memset(*list, 0, size / vcp->diskSize * sizeof(struct VnodeExtract));
120 stream = FDH_FDOPEN(fdP, "r");
122 sprintf(m->line, "Couldn't stream open %s Index of volume %u\n",
123 class ? "small":"large", V_id(vol));
124 rx_Write(m->call, m->line, strlen(m->line));
128 code = STREAM_SEEK(stream, vcp->diskSize, 0);
132 offset = vcp->diskSize;
134 while (!STREAM_EOF(stream)) {
135 afs_int32 vN = (offset >> (vcp->logSize -1)) - 1 + class;
136 if (STREAM_READ(vnode, vcp->diskSize, 1, stream) == 1) {
137 if (vnode->type != vNull) {
139 e->parent = vnode->parent;
140 if (vN == where && class == vLarge) {
141 memcpy(vd, vnode, vcp->diskSize);
142 *parent = vnode->parent;
146 offset += vcp->diskSize;
149 *length = (e - *list);
150 if (class == vLarge) {
152 offset = (*parent + 1 - class) << (vcp->logSize -1);
153 code = STREAM_SEEK(stream, offset, 0);
154 if (STREAM_READ(vnode, vcp->diskSize, 1, stream) == 1)
155 memcpy(parentvd, vnode, vcp->diskSize);
159 sprintf(m->line, "SplitVolume: extract didn't see directory %u\n", where);
160 rx_Write(m->call, m->line, strlen(m->line));
165 sprintf(m->line, "Volume %u has %u %s vnodes in volume %u\n",
166 V_parentId(vol), *length, class? "small":"large",
168 rx_Write(m->call, m->line, strlen(m->line));
173 STREAM_CLOSE(stream);
184 FindVnodes(struct Msg *m, afs_uint32 where,
185 struct VnodeExtract *list, afs_int32 length,
186 struct VnodeExtract *dlist, afs_int32 dlength,
187 afs_int32 *needed, afs_int32 class)
189 afs_int32 i, j, found = 0;
190 afs_int32 parent = 0;
193 for (i=0; i<length; i++) {
194 if (list[i].vN == where) { /* dir to be replaced by mount point */
195 list[i].flag |= NEEDED;
196 parent = list[i].parent;
200 if (list[i].parent == where) { /* all 1st generation children */
201 list[i].flag |= (NEEDED + CHANGEPARENT);
205 if (list[0].vN & 1) { /* only for directories */
208 "SplitVolume: directory %u where to start new volume not found\n",
210 rx_Write(m->call, m->line, strlen(m->line));
214 for (i=0; i<length; i++) {
215 if (list[i].vN == parent) { /* dir where to create mount point */
216 list[i].flag |= PARENT;
222 sprintf(m->line, "SplitVolume: parent directory %u not found\n",
224 rx_Write(m->call, m->line, strlen(m->line));
231 for (i=0; i<dlength; i++) {
232 if (!(dlist[i].flag & NEEDED)) /* dirs to remain in old volume */
234 for (j=0; j<length; j++) {
235 if (list[j].parent == dlist[i].vN && !(list[j].flag & NEEDED)) {
236 list[j].flag |= NEEDED;
244 sprintf(m->line, "%u %s vnodes will go into the new volume\n",
245 *needed, class ? "small" : "large");
246 rx_Write(m->call, m->line, strlen(m->line));
252 copyDir(struct Msg *m, IHandle_t *inh, IHandle_t *outh)
254 FdHandle_t *infdP, *outfdP;
258 infdP = IH_OPEN(inh);
260 sprintf(m->line, "Couldn't open input directory %u.%u.%u\n",
261 infdP->fd_ih->ih_vid,
262 (afs_uint32)(infdP->fd_ih->ih_ino & NAMEI_VNODEMASK),
263 (afs_uint32)(infdP->fd_ih->ih_ino >> NAMEI_UNIQSHIFT));
264 rx_Write(m->call, m->line, strlen(m->line));
267 outfdP = IH_OPEN(outh);
269 sprintf(m->line, "Couldn't open output directory %u.%u.%u\n",
270 outfdP->fd_ih->ih_vid,
271 (afs_uint32)(outfdP->fd_ih->ih_ino & NAMEI_VNODEMASK),
272 (afs_uint32)(outfdP->fd_ih->ih_ino >> NAMEI_UNIQSHIFT));
273 rx_Write(m->call, m->line, strlen(m->line));
274 FDH_REALLYCLOSE(infdP);
278 FDH_SEEK(infdP, 0, 0);
279 FDH_SEEK(outfdP, 0, 0);
280 size = FDH_SIZE(infdP);
283 tlen = size > 2048 ? 2048 : size;
284 if (FDH_READ(infdP, tbuf, tlen) != tlen) {
285 sprintf(m->line, "Couldn't read directory %u.%u.%u\n",
286 infdP->fd_ih->ih_vid,
287 (afs_uint32)(infdP->fd_ih->ih_ino & NAMEI_VNODEMASK),
288 (afs_uint32)(infdP->fd_ih->ih_ino >> NAMEI_UNIQSHIFT));
289 rx_Write(m->call, m->line, strlen(m->line));
290 FDH_REALLYCLOSE(infdP);
291 FDH_REALLYCLOSE(outfdP);
295 if (FDH_WRITE(outfdP, tbuf, tlen) != tlen) {
296 sprintf(m->line, "Couldn't write directory %u.%u.%u\n",
297 outfdP->fd_ih->ih_vid,
298 (afs_uint32)(outfdP->fd_ih->ih_ino & NAMEI_VNODEMASK),
299 (afs_uint32)(outfdP->fd_ih->ih_ino >> NAMEI_UNIQSHIFT));
300 rx_Write(m->call, m->line, strlen(m->line));
301 FDH_REALLYCLOSE(infdP);
302 FDH_REALLYCLOSE(outfdP);
310 FDH_REALLYCLOSE(infdP);
314 afs_int32 copyVnodes(struct Msg *m, Volume *vol, Volume *newvol,
316 struct VnodeExtract *list, afs_int32 length,
317 afs_int32 where, afs_uint64 *blocks,
318 struct VnodeDiskObject *parVnode)
320 afs_int32 i, code = 0;
321 char buf[SIZEOF_LARGEDISKVNODE];
322 struct VnodeDiskObject *vnode = (struct VnodeDiskObject *)&buf;
324 FdHandle_t *newfdP = 0;
325 struct VnodeClassInfo *vcp = &VnodeClassInfo[class];
326 struct VnodeExtract *e;
331 fdP = IH_OPEN(vol->vnodeIndex[class].handle);
333 Log("Couldn't open %s Index of volume %u\n",
334 class ? "small":"large", V_id(vol));
338 newfdP = IH_OPEN(newvol->vnodeIndex[class].handle);
340 Log("Couldn't open %s Index of volume %u\n",
341 class ? "small":"large", V_id(newvol));
345 size = FDH_SIZE(fdP);
347 for (i=0; i<length; i++) {
351 offset = (e->vN + 1 - class) << (vcp->logSize -1);
352 if (FDH_SEEK(fdP, offset, 0) != offset
353 || FDH_READ(fdP, vnode, vcp->diskSize) != vcp->diskSize) {
354 Log("Couldn't read in %s Index of volume %u at offset\n",
355 class ? "small":"large", V_id(vol), offset);
359 if (e->flag & PARENT) {
361 * do a preventive copy on write for later update
365 #if defined(NEARINODE_HINT) && !defined(AFS_NAMEI_ENV)
367 V_pref(vol,nearInode)
370 newino = IH_CREATE(V_linkHandle(vol), V_device(vol),
371 VPartitionPath(V_partition(vol)),
372 nearInode, V_parentId(vol),
373 e->vN, vnode->uniquifier,
375 IH_INIT(newh, V_device(vol), V_parentId(vol), newino);
376 ino = VNDISK_GET_INO(vnode);
377 IH_INIT(h, V_device(vol), V_parentId(vol), ino);
378 code = copyDir(m, h, newh);
381 /* Now update the vnode and write it back to disk */
382 VNDISK_SET_INO(vnode, newino);
384 if (FDH_SEEK(fdP, offset, 0) != offset
385 || FDH_WRITE(fdP, vnode, vcp->diskSize) != vcp->diskSize) {
386 Log("Couldn't write in %s Index of volume %u at offset\n",
387 class ? "small":"large", V_id(vol), offset);
391 memcpy(parVnode, vnode, sizeof(struct VnodeDiskObject));
393 if (e->flag & NEEDED && e->vN != where) {
394 VNDISK_GET_LEN(size, vnode);
395 *blocks += (size + 0x3ff) >> 10;
396 ino = VNDISK_GET_INO(vnode);
400 #if defined(NEARINODE_HINT) && !defined(AFS_NAMEI_ENV)
401 V_pref(vol,nearInode)
403 IH_INIT(h, vol->device, V_parentId(vol), ino);
404 if (e->parent == where)
406 newino = IH_CREATE(V_linkHandle(newvol), V_device(newvol),
407 VPartitionPath(V_partition(newvol)),
408 nearInode, V_parentId(newvol),
409 e->vN, vnode->uniquifier,
411 if (!VALID_INO(newino)) {
412 Log("IH_CREATE failed for %u.%u.%u\n",
413 V_id(newvol), e->vN, vnode->uniquifier);
418 IH_INIT(newh, newvol->device, V_parentId(newvol), newino);
419 code = namei_replace_file_by_hardlink(newh, h);
420 VNDISK_SET_INO(vnode, newino);
421 #ifdef AFS_RXOSD_SUPPORT
423 code = osd_split_objects(vol, newvol, vnode, e->vN);
424 #endif /* AFS_RXOSD_SUPPORT */
428 if (e->flag & CHANGEPARENT)
429 vnode->parent = 1; /* in new root-directory */
431 if (FDH_SEEK(newfdP, offset, 0) != offset
432 || FDH_WRITE(newfdP, vnode, vcp->diskSize) != vcp->diskSize) {
433 Log("Couldn't write in %s Index of volume %u to offset\n",
434 class ? "small":"large", V_id(newvol),
443 * Now copy the root directory from old to new volume
445 if (class == vLarge) {
447 char buf2[SIZEOF_LARGEDISKVNODE];
448 struct VnodeDiskObject *vnode2 = (struct VnodeDiskObject *)&buf2;
449 afs_uint64 newoffset;
451 newoffset = vcp->diskSize;
452 if (FDH_SEEK(newfdP, newoffset, 0) != newoffset
453 || FDH_READ(newfdP, vnode2, vcp->diskSize) != vcp->diskSize) {
454 Log("splitvolume: couldn't read in large Index of new volume %u at offset %u\n",
455 V_id(newvol), vcp->diskSize);
459 offset = (where + 1 - class) << (vcp->logSize -1);
460 if (FDH_SEEK(fdP, offset, 0) != offset
461 || FDH_READ(fdP, vnode, vcp->diskSize) != vcp->diskSize) {
462 Log("Couldn't read in large Index of old volume %u at offset\n",
467 VNDISK_GET_LEN(size, vnode);
468 *blocks += (size + 0x3ff) >> 10;
469 ino = VNDISK_GET_INO(vnode);
470 IH_INIT(h, vol->device, V_parentId(vol), ino);
471 newino = VNDISK_GET_INO(vnode2);
472 IH_INIT(newh, newvol->device, V_parentId(newvol), newino);
473 code = copyDir(m, h, newh);
475 Log("splitvolume: copyDir failed for new root from %u.u.u to %u.1.1\n",
476 V_id(vol), where, vnode->uniquifier, V_id(newvol));
480 VNDISK_SET_INO(vnode, newino);
481 vnode->uniquifier = 1;
483 vnode->parent = vnode2->parent;
484 vnode->serverModifyTime = vnode2->serverModifyTime;
485 if (FDH_SEEK(newfdP, newoffset, 0) != newoffset
486 || FDH_WRITE(newfdP, vnode, vcp->diskSize) != vcp->diskSize) {
487 Log("splitvolume: couldn't write in large Index of %u at offset %u\n",
488 V_id(newvol), vcp->diskSize);
501 findName(Volume *vol, struct VnodeDiskObject *vd, afs_uint32 vN,
502 afs_uint32 un, char *name,afs_int32 length)
508 ino = VNDISK_GET_INO(vd);
509 SetSalvageDirHandle(&dir, V_id(vol), V_device(vol), ino);
511 code = InverseLookup(&dir, vN, un, name, length);
517 createMountpoint(Volume *vol, Volume *newvol, struct VnodeDiskObject *parent,
518 afs_uint32 vN, struct VnodeDiskObject *vd, char *name)
524 struct VnodeDiskObject vnode;
525 FdHandle_t *fdP, *fdP2;
526 afs_uint64 offset, size;
527 afs_int32 class = vSmall;
528 struct VnodeClassInfo *vcp = &VnodeClassInfo[class];
529 #if defined(NEARINODE_HINT) && !defined(AFS_NAMEI_ENV)
537 FT_GetTimeOfDay(&now, 0);
538 fdP = IH_OPEN(vol->vnodeIndex[vSmall].handle);
540 Log("split volume: error opening small vnode index of %u\n", V_id(vol));
543 offset = vcp->diskSize;
544 if (FDH_SEEK(fdP, offset, 0) != offset) {
545 Log("split volume: error seeking in small vnode index of %u\n", V_id(vol));
549 if (FDH_READ(fdP, &vnode, vcp->diskSize) != vcp->diskSize)
551 if (vnode.type == vNull)
553 offset += vcp->diskSize;
555 memset(&vnode, 0, sizeof(vnode));
556 vnode.type = vSymlink;
557 V_nextVnodeUnique(vol)++;
558 vnode.uniquifier = V_nextVnodeUnique(vol);
559 vnode.author = vd->author;
560 vnode.owner = vd->owner;
561 vnode.group = vd->group;
562 vnode.modeBits = 0644;
563 vnode.unixModifyTime = now.tv_sec;
564 vnode.serverModifyTime = now.tv_sec;
565 vnode.dataVersion = 1;
569 newvN = (offset >> (VnodeClassInfo[class].logSize - 1)) - 1 + class;
570 #if defined(NEARINODE_HINT) && !defined(AFS_NAMEI_ENV)
571 V_pref(vol,nearInode)
573 newino = IH_CREATE(V_linkHandle(vol), V_device(vol),
574 VPartitionPath(V_partition(vol)), nearInode,
575 V_parentId(vol), newvN, vnode.uniquifier, 1);
577 IH_INIT(h, V_device(vol), V_parentId(vol), newino);
580 Log("split volume: couldn't open inode for mountpoint %u.%u.%u\n",
581 V_id(vol), newvN, vnode.uniquifier);
584 FDH_SEEK(fdP2, 0, 0);
585 sprintf(symlink, "#%s", V_name(newvol));
586 size = strlen(symlink) + 1;
587 if (FDH_WRITE(fdP2, symlink, size) != size) {
588 Log("split volume: couldn't write mountpoint %u.%u.%u\n",
589 V_id(vol), newvN, vnode.uniquifier);
592 FDH_REALLYCLOSE(fdP2);
594 VNDISK_SET_INO(&vnode, newino);
595 VNDISK_SET_LEN(&vnode, size);
596 #ifndef AFS_RXOSD_SUPPORT
597 vnode.vnodeMagic = SMALLVNODEMAGIC;
599 if (FDH_SEEK(fdP, offset, 0) != offset
600 || FDH_WRITE(fdP, &vnode, vcp->diskSize) != vcp->diskSize) {
601 Log("split volume: couldn't write vnode for mountpoint %u.%u.%u\n",
602 V_id(vol), newvN, vnode.uniquifier);
605 FDH_REALLYCLOSE(fdP);
607 fid.Volume = V_id(vol);
609 fid.Unique = vnode.uniquifier;
612 * Now update the parent directory.
615 ino = VNDISK_GET_INO(parent);
616 SetSalvageDirHandle(&dir, V_id(vol), V_device(vol), ino);
618 code = Delete(&dir, name);
620 Log("splitvolume: couldn't delete directory entry for %s in %u.%u.%u, code = %d\n",
621 name, V_id(vol), vN, parent->uniquifier, code);
624 code = Create(&dir, name, &fid);
628 vcp = &VnodeClassInfo[class];
629 fdP = IH_OPEN(vol->vnodeIndex[class].handle);
630 offset = (vN + 1 - class) << (vcp->logSize -1);
631 parent->dataVersion++;
632 if (FDH_SEEK(fdP, offset, 0) != offset
633 || FDH_WRITE(fdP, parent, vcp->diskSize) != vcp->diskSize) {
634 Log("split volume: couldn't write vnode for parent directory %u.%u.%u\n",
635 V_id(vol), vN, parent->uniquifier);
638 FDH_REALLYCLOSE(fdP);
643 deleteVnodes(Volume *vol, afs_int32 class,
644 struct VnodeExtract *list, afs_int32 length,
647 afs_int32 i, code = 0;
648 char buf[SIZEOF_LARGEDISKVNODE];
649 struct VnodeDiskObject *vnode = (struct VnodeDiskObject *)&buf;
651 struct VnodeClassInfo *vcp = &VnodeClassInfo[class];
652 struct VnodeExtract *e;
657 fdP = IH_OPEN(vol->vnodeIndex[class].handle);
659 Log("Couldn't open %s Index of volume %u\n",
660 class ? "small":"large", V_id(vol));
664 size = FDH_SIZE(fdP);
666 for (i=0; i<length; i++) {
668 if (e->flag & NEEDED) {
670 offset = (e->vN + 1 - class) << (vcp->logSize -1);
671 if (FDH_SEEK(fdP, offset, 0) != offset) {
672 Log("Couldn't seek in %s Index of volume %u to offset\n",
673 class ? "small":"large", V_id(vol), offset);
677 if (FDH_READ(fdP, vnode, vcp->diskSize) != vcp->diskSize) {
678 Log("Couldn't read in %s Index of volume %u at offset\n",
679 class ? "small":"large", V_id(vol), offset);
683 VNDISK_GET_LEN(size, vnode);
684 *blocks += (size + 0x3ff) >> 10;
685 ino = VNDISK_GET_INO(vnode);
688 IH_INIT(h, vol->device, V_parentId(vol), ino);
689 IH_DEC(h, ino, V_parentId(vol));
690 #ifdef AFS_RXOSD_SUPPORT
692 code = osdRemove(vol, vnode, e->vN);
693 #endif /* AFS_RXOSD_SUPPORT */
695 memset(vnode, 0, vcp->diskSize);
697 if (FDH_SEEK(fdP, offset, 0) != offset
698 || FDH_WRITE(fdP, vnode, vcp->diskSize) != vcp->diskSize) {
699 Log("Couldn't write in %s Index of volume %u to offset\n",
700 class ? "small":"large", V_id(vol),
712 split_volume(struct rx_call *call, Volume *vol, Volume *newvol,
713 afs_uint32 where, afs_int32 verbose)
716 struct VnodeExtract *dirList = 0;
717 struct VnodeExtract *fileList = 0;
718 afs_uint64 blocks = 0;
719 afs_uint32 filesNeeded, dirsNeeded;
721 char buf[SIZEOF_LARGEDISKVNODE];
722 char buf2[SIZEOF_LARGEDISKVNODE];
723 struct VnodeDiskObject *rootVnode = (struct VnodeDiskObject *)&buf;
724 struct VnodeDiskObject *parVnode = (struct VnodeDiskObject *)&buf2;
729 m = (struct Msg *) malloc(sizeof(struct Msg));
730 memset(m, 0, sizeof(struct Msg));
732 m->verbose = verbose;
735 * First step: planning
737 * Find out which directories will belong to the new volume
742 "1st step: extract vnode essence from large vnode file\n");
743 rx_Write(m->call, m->line, strlen(m->line));
746 code = ExtractVnodes(m, vol, vLarge, &dirList, &dl, where, rootVnode,
750 "ExtractVnodes failed for %u for directories with code %d\n",
752 rx_Write(m->call, m->line, strlen(m->line));
757 sprintf(m->line, "2nd step: look for name of vnode %u in directory %u.%u.%u\n",
758 where, V_id(vol), parent, parVnode->uniquifier);
759 rx_Write(m->call, m->line, strlen(m->line));
761 code = findName(vol, parVnode, where, rootVnode->uniquifier,
765 "splitvolume: could'nt find name of %u in directory %u.%u.%u.\n",
766 where, V_id(vol), parent, parVnode->uniquifier);
767 rx_Write(m->call, m->line, strlen(m->line));
771 sprintf(m->line, "name of %u is %s\n", where, name);
772 rx_Write(m->call, m->line, strlen(m->line));
776 sprintf(m->line, "3rd step: find all directory vnodes belonging to the subtree under %u \"%s\"\n",
778 rx_Write(m->call, m->line, strlen(m->line));
780 code = FindVnodes(m, where, dirList, dl, dirList, dl, &dirsNeeded, 1);
783 "FindVnodes for directories failed with code %d\n", code);
784 rx_Write(m->call, m->line, strlen(m->line));
789 sprintf(m->line, "4th step extract vnode essence from small vnode file\n");
790 rx_Write(m->call, m->line, strlen(m->line));
792 code = ExtractVnodes(m, vol, vSmall, &fileList, &fl, where, 0, 0, 0);
795 "ExtractVnodes failed for %u for files with code %d\n",
797 rx_Write(m->call, m->line, strlen(m->line));
801 sprintf(m->line, "5th step: find all small vnodes belonging to the subtree under %u \"%s\"\n",
803 rx_Write(m->call, m->line, strlen(m->line));
805 FindVnodes(m, where, fileList, fl, dirList, dl, &filesNeeded, 0);
808 * Third step: create hard links for all files needed
812 V_destroyMe(newvol) = DESTROY_ME;
813 V_inService(newvol) = 0;
815 sprintf(m->line, "6th step: create hard links in the AFSIDat tree between files of the old and new volume\n");
816 rx_Write(m->call, m->line, strlen(m->line));
818 code = copyVnodes(m, vol, newvol, 1, fileList, fl, where, &blocks, 0);
820 sprintf(m->line, "copyVnodes for files failed with code %d\n", code);
821 rx_Write(m->call, m->line, strlen(m->line));
826 * Forth step: create hard links for all directories and copy
827 * split directory to new root directory
831 sprintf(m->line, "7th step: create hard links in the AFSIDat tree between directories of the old and new volume and make dir %u to new volume's root directory.\n",
833 rx_Write(m->call, m->line, strlen(m->line));
835 code = copyVnodes(m, vol, newvol, 0, dirList, dl, where, &blocks, parVnode);
837 sprintf(m->line, "copyVnodes for directories failed with code %d\n", code);
838 rx_Write(m->call, m->line, strlen(m->line));
843 * Finalize new volume
847 sprintf(m->line, "8th step: write new volume's metadata to disk\n");
848 rx_Write(m->call, m->line, strlen(m->line));
851 V_diskused(newvol) = blocks;
852 #ifdef AFS_RXOSD_SUPPORT
853 V_osdFlag(newvol) = V_osdFlag(vol);
855 V_filecount(newvol) = filesNeeded + dirsNeeded;
856 V_destroyMe(newvol) = 0;
857 V_maxquota(newvol) = V_maxquota(vol);
858 V_uniquifier(newvol) = V_uniquifier(vol);
859 V_inService(newvol) = 1;
860 VUpdateVolume(&code, newvol);
863 * Sixth step: change directory entry in old volume:
864 * rename old tree and create mount point for new volume.
867 sprintf(m->line, "9th step: create mountpoint \"%s\" for new volume in old volume's directory %u.\n", name, parent);
868 rx_Write(m->call, m->line, strlen(m->line));
871 code = createMountpoint(vol, newvol, parVnode, parent, rootVnode, name);
873 sprintf(m->line, "createMountpoint failed with code %d\n", code);
874 rx_Write(m->call, m->line, strlen(m->line));
878 * Now both volumes should be ready and consistent, but the old volume
879 * contains still the vnodes and data we transferred into the new one.
880 * Delete orphaned vnodes and data.
885 sprintf(m->line, "10th step: delete large vnodes belonging to subtree in the old volume.\n");
886 rx_Write(m->call, m->line, strlen(m->line));
888 deleteVnodes(vol, vLarge, dirList, dl, &blocks);
890 sprintf(m->line, "11th step: delete small vnodes belonging to subtree in the old volume.\n");
891 rx_Write(m->call, m->line, strlen(m->line));
893 deleteVnodes(vol, vSmall, fileList, fl, &blocks);
894 V_diskused(vol) -= blocks;
895 V_filecount(vol) -= (filesNeeded + dirsNeeded + 1);
896 VUpdateVolume(&code, vol);
898 sprintf(m->line, "Finished!\n");
899 rx_Write(m->call, m->line, strlen(m->line));
904 rx_Write(m->call, m->line, 4);