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 */
41 #include <afs/afsint.h>
45 #include <afs/afssyscalls.h>
49 #include "partition.h"
50 #include "viceinode.h"
55 #include "volser_prototypes.h"
56 #ifdef AFS_RXOSD_SUPPORT
59 #include "../vol/vol_osd_prototypes.h"
64 #define CHANGEPARENT 4
66 #define NAMEI_VNODEMASK 0x03ffffff
67 #define NAMEI_TAGMASK 0x7
68 #define NAMEI_TAGSHIFT 26
69 #define NAMEI_UNIQMASK 0xffffffff
70 #define NAMEI_UNIQSHIFT 32
79 struct rx_call * call;
85 ExtractVnodes(struct Msg *m, Volume *vol, afs_int32 class,
86 struct VnodeExtract **list,
87 afs_int32 *length, afs_uint32 where,
88 struct VnodeDiskObject *vd,
89 afs_int32 *parent, struct VnodeDiskObject *parentvd)
92 char buf[SIZEOF_LARGEDISKVNODE];
93 struct VnodeDiskObject *vnode = (struct VnodeDiskObject *)&buf;
95 StreamHandle_t *stream = 0;
96 struct VnodeClassInfo *vcp = &VnodeClassInfo[class];
97 struct VnodeExtract *e;
105 fdP = IH_OPEN(vol->vnodeIndex[class].handle);
107 sprintf(m->line, "Couldn't open %s Index of volume %u\n",
108 class ? "small":"large", V_id(vol));
109 rx_Write(m->call, m->line, strlen(m->line));
113 size = FDH_SIZE(fdP);
114 *list = (struct VnodeExtract *) malloc(size / vcp->diskSize
115 * sizeof(struct VnodeExtract));
120 memset(*list, 0, size / vcp->diskSize * sizeof(struct VnodeExtract));
121 stream = FDH_FDOPEN(fdP, "r");
123 sprintf(m->line, "Couldn't stream open %s Index of volume %u\n",
124 class ? "small":"large", V_id(vol));
125 rx_Write(m->call, m->line, strlen(m->line));
129 code = STREAM_SEEK(stream, vcp->diskSize, 0);
133 offset = vcp->diskSize;
135 while (!STREAM_EOF(stream)) {
136 afs_int32 vN = (offset >> (vcp->logSize -1)) - 1 + class;
137 if (STREAM_READ(vnode, vcp->diskSize, 1, stream) == 1) {
138 if (vnode->type != vNull) {
140 e->parent = vnode->parent;
141 if (vN == where && class == vLarge) {
142 memcpy(vd, vnode, vcp->diskSize);
143 *parent = vnode->parent;
147 offset += vcp->diskSize;
150 *length = (e - *list);
151 if (class == vLarge) {
153 offset = (*parent + 1 - class) << (vcp->logSize -1);
154 code = STREAM_SEEK(stream, offset, 0);
155 if (STREAM_READ(vnode, vcp->diskSize, 1, stream) == 1)
156 memcpy(parentvd, vnode, vcp->diskSize);
160 sprintf(m->line, "SplitVolume: extract didn't see directory %u\n", where);
161 rx_Write(m->call, m->line, strlen(m->line));
166 sprintf(m->line, "Volume %u has %u %s vnodes in volume %u\n",
167 V_parentId(vol), *length, class? "small":"large",
169 rx_Write(m->call, m->line, strlen(m->line));
174 STREAM_CLOSE(stream);
185 FindVnodes(struct Msg *m, afs_uint32 where,
186 struct VnodeExtract *list, afs_int32 length,
187 struct VnodeExtract *dlist, afs_int32 dlength,
188 afs_int32 *needed, afs_int32 class)
190 afs_int32 i, j, found = 0;
191 afs_int32 parent = 0;
194 for (i=0; i<length; i++) {
195 if (list[i].vN == where) { /* dir to be replaced by mount point */
196 list[i].flag |= NEEDED;
197 parent = list[i].parent;
201 if (list[i].parent == where) { /* all 1st generation children */
202 list[i].flag |= (NEEDED + CHANGEPARENT);
206 if (list[0].vN & 1) { /* only for directories */
209 "SplitVolume: directory %u where to start new volume not found\n",
211 rx_Write(m->call, m->line, strlen(m->line));
215 for (i=0; i<length; i++) {
216 if (list[i].vN == parent) { /* dir where to create mount point */
217 list[i].flag |= PARENT;
223 sprintf(m->line, "SplitVolume: parent directory %u not found\n",
225 rx_Write(m->call, m->line, strlen(m->line));
232 for (i=0; i<dlength; i++) {
233 if (!(dlist[i].flag & NEEDED)) /* dirs to remain in old volume */
235 for (j=0; j<length; j++) {
236 if (list[j].parent == dlist[i].vN && !(list[j].flag & NEEDED)) {
237 list[j].flag |= NEEDED;
245 sprintf(m->line, "%u %s vnodes will go into the new volume\n",
246 *needed, class ? "small" : "large");
247 rx_Write(m->call, m->line, strlen(m->line));
253 copyDir(struct Msg *m, IHandle_t *inh, IHandle_t *outh)
255 FdHandle_t *infdP, *outfdP;
259 infdP = IH_OPEN(inh);
261 sprintf(m->line, "Couldn't open input directory %u.%u.%u\n",
262 infdP->fd_ih->ih_vid,
263 (afs_uint32)(infdP->fd_ih->ih_ino & NAMEI_VNODEMASK),
264 (afs_uint32)(infdP->fd_ih->ih_ino >> NAMEI_UNIQSHIFT));
265 rx_Write(m->call, m->line, strlen(m->line));
268 outfdP = IH_OPEN(outh);
270 sprintf(m->line, "Couldn't open output directory %u.%u.%u\n",
271 outfdP->fd_ih->ih_vid,
272 (afs_uint32)(outfdP->fd_ih->ih_ino & NAMEI_VNODEMASK),
273 (afs_uint32)(outfdP->fd_ih->ih_ino >> NAMEI_UNIQSHIFT));
274 rx_Write(m->call, m->line, strlen(m->line));
275 FDH_REALLYCLOSE(infdP);
279 FDH_SEEK(infdP, 0, 0);
280 FDH_SEEK(outfdP, 0, 0);
281 size = FDH_SIZE(infdP);
284 tlen = size > 2048 ? 2048 : size;
285 if (FDH_READ(infdP, tbuf, tlen) != tlen) {
286 sprintf(m->line, "Couldn't read directory %u.%u.%u\n",
287 infdP->fd_ih->ih_vid,
288 (afs_uint32)(infdP->fd_ih->ih_ino & NAMEI_VNODEMASK),
289 (afs_uint32)(infdP->fd_ih->ih_ino >> NAMEI_UNIQSHIFT));
290 rx_Write(m->call, m->line, strlen(m->line));
291 FDH_REALLYCLOSE(infdP);
292 FDH_REALLYCLOSE(outfdP);
296 if (FDH_WRITE(outfdP, tbuf, tlen) != tlen) {
297 sprintf(m->line, "Couldn't write directory %u.%u.%u\n",
298 outfdP->fd_ih->ih_vid,
299 (afs_uint32)(outfdP->fd_ih->ih_ino & NAMEI_VNODEMASK),
300 (afs_uint32)(outfdP->fd_ih->ih_ino >> NAMEI_UNIQSHIFT));
301 rx_Write(m->call, m->line, strlen(m->line));
302 FDH_REALLYCLOSE(infdP);
303 FDH_REALLYCLOSE(outfdP);
311 FDH_REALLYCLOSE(infdP);
315 afs_int32 copyVnodes(struct Msg *m, Volume *vol, Volume *newvol,
317 struct VnodeExtract *list, afs_int32 length,
318 afs_int32 where, afs_uint64 *blocks,
319 struct VnodeDiskObject *parVnode)
321 afs_int32 i, code = 0;
322 char buf[SIZEOF_LARGEDISKVNODE];
323 struct VnodeDiskObject *vnode = (struct VnodeDiskObject *)&buf;
325 FdHandle_t *newfdP = 0;
326 struct VnodeClassInfo *vcp = &VnodeClassInfo[class];
327 struct VnodeExtract *e;
332 fdP = IH_OPEN(vol->vnodeIndex[class].handle);
334 Log("Couldn't open %s Index of volume %u\n",
335 class ? "small":"large", V_id(vol));
339 newfdP = IH_OPEN(newvol->vnodeIndex[class].handle);
341 Log("Couldn't open %s Index of volume %u\n",
342 class ? "small":"large", V_id(newvol));
346 size = FDH_SIZE(fdP);
348 for (i=0; i<length; i++) {
352 offset = (e->vN + 1 - class) << (vcp->logSize -1);
353 if (FDH_SEEK(fdP, offset, 0) != offset
354 || FDH_READ(fdP, vnode, vcp->diskSize) != vcp->diskSize) {
355 Log("Couldn't read in %s Index of volume %u at offset\n",
356 class ? "small":"large", V_id(vol), offset);
360 if (e->flag & PARENT) {
362 * do a preventive copy on write for later update
366 #if defined(NEARINODE_HINT) && !defined(AFS_NAMEI_ENV)
368 V_pref(vol,nearInode)
371 newino = IH_CREATE(V_linkHandle(vol), V_device(vol),
372 VPartitionPath(V_partition(vol)),
373 nearInode, V_parentId(vol),
374 e->vN, vnode->uniquifier,
376 IH_INIT(newh, V_device(vol), V_parentId(vol), newino);
377 ino = VNDISK_GET_INO(vnode);
378 IH_INIT(h, V_device(vol), V_parentId(vol), ino);
379 code = copyDir(m, h, newh);
382 /* Now update the vnode and write it back to disk */
383 VNDISK_SET_INO(vnode, newino);
385 if (FDH_SEEK(fdP, offset, 0) != offset
386 || FDH_WRITE(fdP, vnode, vcp->diskSize) != vcp->diskSize) {
387 Log("Couldn't write in %s Index of volume %u at offset\n",
388 class ? "small":"large", V_id(vol), offset);
392 memcpy(parVnode, vnode, sizeof(struct VnodeDiskObject));
394 if (e->flag & NEEDED && e->vN != where) {
395 VNDISK_GET_LEN(size, vnode);
396 *blocks += (size + 0x3ff) >> 10;
397 ino = VNDISK_GET_INO(vnode);
401 #if defined(NEARINODE_HINT) && !defined(AFS_NAMEI_ENV)
402 V_pref(vol,nearInode)
404 IH_INIT(h, vol->device, V_parentId(vol), ino);
405 if (e->parent == where)
407 newino = IH_CREATE(V_linkHandle(newvol), V_device(newvol),
408 VPartitionPath(V_partition(newvol)),
409 nearInode, V_parentId(newvol),
410 e->vN, vnode->uniquifier,
412 if (!VALID_INO(newino)) {
413 Log("IH_CREATE failed for %u.%u.%u\n",
414 V_id(newvol), e->vN, vnode->uniquifier);
419 IH_INIT(newh, newvol->device, V_parentId(newvol), newino);
420 code = namei_replace_file_by_hardlink(newh, h);
421 VNDISK_SET_INO(vnode, newino);
422 #ifdef AFS_RXOSD_SUPPORT
424 code = osd_split_objects(vol, newvol, vnode, e->vN);
425 #endif /* AFS_RXOSD_SUPPORT */
429 if (e->flag & CHANGEPARENT)
430 vnode->parent = 1; /* in new root-directory */
432 if (FDH_SEEK(newfdP, offset, 0) != offset
433 || FDH_WRITE(newfdP, vnode, vcp->diskSize) != vcp->diskSize) {
434 Log("Couldn't write in %s Index of volume %u to offset\n",
435 class ? "small":"large", V_id(newvol),
444 * Now copy the root directory from old to new volume
446 if (class == vLarge) {
448 char buf2[SIZEOF_LARGEDISKVNODE];
449 struct VnodeDiskObject *vnode2 = (struct VnodeDiskObject *)&buf2;
450 afs_uint64 newoffset;
452 newoffset = vcp->diskSize;
453 if (FDH_SEEK(newfdP, newoffset, 0) != newoffset
454 || FDH_READ(newfdP, vnode2, vcp->diskSize) != vcp->diskSize) {
455 Log("splitvolume: couldn't read in large Index of new volume %u at offset %u\n",
456 V_id(newvol), vcp->diskSize);
460 offset = (where + 1 - class) << (vcp->logSize -1);
461 if (FDH_SEEK(fdP, offset, 0) != offset
462 || FDH_READ(fdP, vnode, vcp->diskSize) != vcp->diskSize) {
463 Log("Couldn't read in large Index of old volume %u at offset\n",
468 VNDISK_GET_LEN(size, vnode);
469 *blocks += (size + 0x3ff) >> 10;
470 ino = VNDISK_GET_INO(vnode);
471 IH_INIT(h, vol->device, V_parentId(vol), ino);
472 newino = VNDISK_GET_INO(vnode2);
473 IH_INIT(newh, newvol->device, V_parentId(newvol), newino);
474 code = copyDir(m, h, newh);
476 Log("splitvolume: copyDir failed for new root from %u.u.u to %u.1.1\n",
477 V_id(vol), where, vnode->uniquifier, V_id(newvol));
481 VNDISK_SET_INO(vnode, newino);
482 vnode->uniquifier = 1;
484 vnode->parent = vnode2->parent;
485 vnode->serverModifyTime = vnode2->serverModifyTime;
486 if (FDH_SEEK(newfdP, newoffset, 0) != newoffset
487 || FDH_WRITE(newfdP, vnode, vcp->diskSize) != vcp->diskSize) {
488 Log("splitvolume: couldn't write in large Index of %u at offset %u\n",
489 V_id(newvol), vcp->diskSize);
502 findName(Volume *vol, struct VnodeDiskObject *vd, afs_uint32 vN,
503 afs_uint32 un, char *name,afs_int32 length)
509 ino = VNDISK_GET_INO(vd);
510 SetSalvageDirHandle(&dir, V_id(vol), V_device(vol), ino);
512 code = InverseLookup(&dir, vN, un, name, length);
518 createMountpoint(Volume *vol, Volume *newvol, struct VnodeDiskObject *parent,
519 afs_uint32 vN, struct VnodeDiskObject *vd, char *name)
525 struct VnodeDiskObject vnode;
526 FdHandle_t *fdP, *fdP2;
527 afs_uint64 offset, size;
528 afs_int32 class = vSmall;
529 struct VnodeClassInfo *vcp = &VnodeClassInfo[class];
530 #if defined(NEARINODE_HINT) && !defined(AFS_NAMEI_ENV)
538 FT_GetTimeOfDay(&now, 0);
539 fdP = IH_OPEN(vol->vnodeIndex[vSmall].handle);
541 Log("split volume: error opening small vnode index of %u\n", V_id(vol));
544 offset = vcp->diskSize;
545 if (FDH_SEEK(fdP, offset, 0) != offset) {
546 Log("split volume: error seeking in small vnode index of %u\n", V_id(vol));
550 if (FDH_READ(fdP, &vnode, vcp->diskSize) != vcp->diskSize)
552 if (vnode.type == vNull)
554 offset += vcp->diskSize;
556 memset(&vnode, 0, sizeof(vnode));
557 vnode.type = vSymlink;
558 V_nextVnodeUnique(vol)++;
559 vnode.uniquifier = V_nextVnodeUnique(vol);
560 vnode.author = vd->author;
561 vnode.owner = vd->owner;
562 vnode.group = vd->group;
563 vnode.modeBits = 0644;
564 vnode.unixModifyTime = now.tv_sec;
565 vnode.serverModifyTime = now.tv_sec;
566 vnode.dataVersion = 1;
570 newvN = (offset >> (VnodeClassInfo[class].logSize - 1)) - 1 + class;
571 #if defined(NEARINODE_HINT) && !defined(AFS_NAMEI_ENV)
572 V_pref(vol,nearInode)
574 newino = IH_CREATE(V_linkHandle(vol), V_device(vol),
575 VPartitionPath(V_partition(vol)), nearInode,
576 V_parentId(vol), newvN, vnode.uniquifier, 1);
578 IH_INIT(h, V_device(vol), V_parentId(vol), newino);
581 Log("split volume: couldn't open inode for mountpoint %u.%u.%u\n",
582 V_id(vol), newvN, vnode.uniquifier);
585 FDH_SEEK(fdP2, 0, 0);
586 sprintf(symlink, "#%s", V_name(newvol));
587 size = strlen(symlink) + 1;
588 if (FDH_WRITE(fdP2, symlink, size) != size) {
589 Log("split volume: couldn't write mountpoint %u.%u.%u\n",
590 V_id(vol), newvN, vnode.uniquifier);
593 FDH_REALLYCLOSE(fdP2);
595 VNDISK_SET_INO(&vnode, newino);
596 VNDISK_SET_LEN(&vnode, size);
597 #ifndef AFS_RXOSD_SUPPORT
598 vnode.vnodeMagic = SMALLVNODEMAGIC;
600 if (FDH_SEEK(fdP, offset, 0) != offset
601 || FDH_WRITE(fdP, &vnode, vcp->diskSize) != vcp->diskSize) {
602 Log("split volume: couldn't write vnode for mountpoint %u.%u.%u\n",
603 V_id(vol), newvN, vnode.uniquifier);
606 FDH_REALLYCLOSE(fdP);
608 fid.Volume = V_id(vol);
610 fid.Unique = vnode.uniquifier;
613 * Now update the parent directory.
616 ino = VNDISK_GET_INO(parent);
617 SetSalvageDirHandle(&dir, V_id(vol), V_device(vol), ino);
619 code = Delete(&dir, name);
621 Log("splitvolume: couldn't delete directory entry for %s in %u.%u.%u, code = %d\n",
622 name, V_id(vol), vN, parent->uniquifier, code);
625 code = Create(&dir, name, &fid);
629 vcp = &VnodeClassInfo[class];
630 fdP = IH_OPEN(vol->vnodeIndex[class].handle);
631 offset = (vN + 1 - class) << (vcp->logSize -1);
632 parent->dataVersion++;
633 if (FDH_SEEK(fdP, offset, 0) != offset
634 || FDH_WRITE(fdP, parent, vcp->diskSize) != vcp->diskSize) {
635 Log("split volume: couldn't write vnode for parent directory %u.%u.%u\n",
636 V_id(vol), vN, parent->uniquifier);
639 FDH_REALLYCLOSE(fdP);
644 deleteVnodes(Volume *vol, afs_int32 class,
645 struct VnodeExtract *list, afs_int32 length,
648 afs_int32 i, code = 0;
649 char buf[SIZEOF_LARGEDISKVNODE];
650 struct VnodeDiskObject *vnode = (struct VnodeDiskObject *)&buf;
652 struct VnodeClassInfo *vcp = &VnodeClassInfo[class];
653 struct VnodeExtract *e;
658 fdP = IH_OPEN(vol->vnodeIndex[class].handle);
660 Log("Couldn't open %s Index of volume %u\n",
661 class ? "small":"large", V_id(vol));
665 size = FDH_SIZE(fdP);
667 for (i=0; i<length; i++) {
669 if (e->flag & NEEDED) {
671 offset = (e->vN + 1 - class) << (vcp->logSize -1);
672 if (FDH_SEEK(fdP, offset, 0) != offset) {
673 Log("Couldn't seek in %s Index of volume %u to offset\n",
674 class ? "small":"large", V_id(vol), offset);
678 if (FDH_READ(fdP, vnode, vcp->diskSize) != vcp->diskSize) {
679 Log("Couldn't read in %s Index of volume %u at offset\n",
680 class ? "small":"large", V_id(vol), offset);
684 VNDISK_GET_LEN(size, vnode);
685 *blocks += (size + 0x3ff) >> 10;
686 ino = VNDISK_GET_INO(vnode);
689 IH_INIT(h, vol->device, V_parentId(vol), ino);
690 IH_DEC(h, ino, V_parentId(vol));
691 #ifdef AFS_RXOSD_SUPPORT
693 code = osdRemove(vol, vnode, e->vN);
694 #endif /* AFS_RXOSD_SUPPORT */
696 memset(vnode, 0, vcp->diskSize);
698 if (FDH_SEEK(fdP, offset, 0) != offset
699 || FDH_WRITE(fdP, vnode, vcp->diskSize) != vcp->diskSize) {
700 Log("Couldn't write in %s Index of volume %u to offset\n",
701 class ? "small":"large", V_id(vol),
713 split_volume(struct rx_call *call, Volume *vol, Volume *newvol,
714 afs_uint32 where, afs_int32 verbose)
717 struct VnodeExtract *dirList = 0;
718 struct VnodeExtract *fileList = 0;
719 afs_uint64 blocks = 0;
720 afs_uint32 filesNeeded, dirsNeeded;
722 char buf[SIZEOF_LARGEDISKVNODE];
723 char buf2[SIZEOF_LARGEDISKVNODE];
724 struct VnodeDiskObject *rootVnode = (struct VnodeDiskObject *)&buf;
725 struct VnodeDiskObject *parVnode = (struct VnodeDiskObject *)&buf2;
730 m = (struct Msg *) malloc(sizeof(struct Msg));
731 memset(m, 0, sizeof(struct Msg));
733 m->verbose = verbose;
736 * First step: planning
738 * Find out which directories will belong to the new volume
743 "1st step: extract vnode essence from large vnode file\n");
744 rx_Write(m->call, m->line, strlen(m->line));
747 code = ExtractVnodes(m, vol, vLarge, &dirList, &dl, where, rootVnode,
751 "ExtractVnodes failed for %u for directories with code %d\n",
753 rx_Write(m->call, m->line, strlen(m->line));
758 sprintf(m->line, "2nd step: look for name of vnode %u in directory %u.%u.%u\n",
759 where, V_id(vol), parent, parVnode->uniquifier);
760 rx_Write(m->call, m->line, strlen(m->line));
762 code = findName(vol, parVnode, where, rootVnode->uniquifier,
766 "splitvolume: could'nt find name of %u in directory %u.%u.%u.\n",
767 where, V_id(vol), parent, parVnode->uniquifier);
768 rx_Write(m->call, m->line, strlen(m->line));
772 sprintf(m->line, "name of %u is %s\n", where, name);
773 rx_Write(m->call, m->line, strlen(m->line));
777 sprintf(m->line, "3rd step: find all directory vnodes belonging to the subtree under %u \"%s\"\n",
779 rx_Write(m->call, m->line, strlen(m->line));
781 code = FindVnodes(m, where, dirList, dl, dirList, dl, &dirsNeeded, 1);
784 "FindVnodes for directories failed with code %d\n", code);
785 rx_Write(m->call, m->line, strlen(m->line));
790 sprintf(m->line, "4th step extract vnode essence from small vnode file\n");
791 rx_Write(m->call, m->line, strlen(m->line));
793 code = ExtractVnodes(m, vol, vSmall, &fileList, &fl, where, 0, 0, 0);
796 "ExtractVnodes failed for %u for files with code %d\n",
798 rx_Write(m->call, m->line, strlen(m->line));
802 sprintf(m->line, "5th step: find all small vnodes belonging to the subtree under %u \"%s\"\n",
804 rx_Write(m->call, m->line, strlen(m->line));
806 FindVnodes(m, where, fileList, fl, dirList, dl, &filesNeeded, 0);
809 * Third step: create hard links for all files needed
813 V_destroyMe(newvol) = DESTROY_ME;
814 V_inService(newvol) = 0;
816 sprintf(m->line, "6th step: create hard links in the AFSIDat tree between files of the old and new volume\n");
817 rx_Write(m->call, m->line, strlen(m->line));
819 code = copyVnodes(m, vol, newvol, 1, fileList, fl, where, &blocks, 0);
821 sprintf(m->line, "copyVnodes for files failed with code %d\n", code);
822 rx_Write(m->call, m->line, strlen(m->line));
827 * Forth step: create hard links for all directories and copy
828 * split directory to new root directory
832 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",
834 rx_Write(m->call, m->line, strlen(m->line));
836 code = copyVnodes(m, vol, newvol, 0, dirList, dl, where, &blocks, parVnode);
838 sprintf(m->line, "copyVnodes for directories failed with code %d\n", code);
839 rx_Write(m->call, m->line, strlen(m->line));
844 * Finalize new volume
848 sprintf(m->line, "8th step: write new volume's metadata to disk\n");
849 rx_Write(m->call, m->line, strlen(m->line));
852 V_diskused(newvol) = blocks;
853 #ifdef AFS_RXOSD_SUPPORT
854 V_osdFlag(newvol) = V_osdFlag(vol);
856 V_filecount(newvol) = filesNeeded + dirsNeeded;
857 V_destroyMe(newvol) = 0;
858 V_maxquota(newvol) = V_maxquota(vol);
859 V_uniquifier(newvol) = V_uniquifier(vol);
860 V_inService(newvol) = 1;
861 VUpdateVolume(&code, newvol);
864 * Sixth step: change directory entry in old volume:
865 * rename old tree and create mount point for new volume.
868 sprintf(m->line, "9th step: create mountpoint \"%s\" for new volume in old volume's directory %u.\n", name, parent);
869 rx_Write(m->call, m->line, strlen(m->line));
872 code = createMountpoint(vol, newvol, parVnode, parent, rootVnode, name);
874 sprintf(m->line, "createMountpoint failed with code %d\n", code);
875 rx_Write(m->call, m->line, strlen(m->line));
879 * Now both volumes should be ready and consistent, but the old volume
880 * contains still the vnodes and data we transferred into the new one.
881 * Delete orphaned vnodes and data.
886 sprintf(m->line, "10th step: delete large vnodes belonging to subtree in the old volume.\n");
887 rx_Write(m->call, m->line, strlen(m->line));
889 deleteVnodes(vol, vLarge, dirList, dl, &blocks);
891 sprintf(m->line, "11th step: delete small vnodes belonging to subtree in the old volume.\n");
892 rx_Write(m->call, m->line, strlen(m->line));
894 deleteVnodes(vol, vSmall, fileList, fl, &blocks);
895 V_diskused(vol) -= blocks;
896 V_filecount(vol) -= (filesNeeded + dirsNeeded + 1);
897 VUpdateVolume(&code, vol);
899 sprintf(m->line, "Finished!\n");
900 rx_Write(m->call, m->line, strlen(m->line));
905 rx_Write(m->call, m->line, 4);