2 * Copyright 2006, Sine Nomine Associates and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
12 * fileserver state serialization
15 #include <afsconfig.h>
16 #include <afs/param.h>
25 #include <afs/afsint.h>
26 #include <afs/rxgen_consts.h>
28 #include <afs/errors.h>
29 #include <afs/ihandle.h>
31 #include <afs/ptclient.h>
32 #include <afs/prs_fs.h>
33 #include <afs/afsutil.h>
35 #include <afs/cellconfig.h>
37 #include "../viced/viced_prototypes.h"
38 #include "../viced/viced.h"
39 #include "../viced/host.h"
40 #include "../viced/callback.h"
41 #include "serialize_state.h"
43 #ifdef AFS_DEMAND_ATTACH_FS
49 * in order to make state dump/restore as fast as possible,
50 * we use memory mapped files
52 * if this causes problems on certain platforms, the APIs
53 * have been written so that it will be very simple to go
54 * back to standard I/O for just those poorly written platforms
57 #define FS_STATE_USE_MMAP 1
60 #ifdef FS_STATE_USE_MMAP
61 #define FS_STATE_INIT_FILESIZE (8 * 1024 * 1024) /* truncate to 8MB initially */
67 static int fs_stateCreateDump(struct fs_dump_state * state);
68 static int fs_stateLoadDump(struct fs_dump_state * state);
69 static int fs_stateInvalidateDump(struct fs_dump_state * state);
70 static int fs_stateCommitDump(struct fs_dump_state * state);
71 static int fs_stateCloseDump(struct fs_dump_state * state);
73 #ifdef FS_STATE_USE_MMAP
74 static int fs_stateSizeFile(struct fs_dump_state * state);
75 static int fs_stateResizeFile(struct fs_dump_state * state, size_t min_add);
76 static int fs_stateTruncateFile(struct fs_dump_state * state);
78 static int fs_stateMapFile(struct fs_dump_state * state);
79 static int fs_stateUnmapFile(struct fs_dump_state * state);
81 static int fs_stateIncCursor(struct fs_dump_state * state, size_t len);
82 static int fs_stateCheckIOSafety(struct fs_dump_state * state,
86 static int fs_stateFillHeader(struct fs_state_header * hdr);
87 static int fs_stateCheckHeader(struct fs_state_header * hdr);
89 static int fs_stateAlloc(struct fs_dump_state * state);
90 static int fs_stateFree(struct fs_dump_state * state);
92 extern afsUUID FS_HostUUID;
93 extern char cml_version_number[];
96 fs_stateFileOpen(struct fs_dump_state *state)
99 return(state->fd != -1);
101 return(state->fd >= 0);
108 * save all fileserver state
113 int ret = 0, verified = 1;
114 struct fs_dump_state state;
116 /* save and restore need to be atomic wrt other host package operations */
119 ViceLog(0, ("fs_stateSave: commencing fileserver state dump\n"));
121 if (fs_stateAlloc(&state)) {
122 ViceLog(0, ("fs_stateSave: memory allocation failed; dump aborted\n"));
128 * on busy servers, these checks will inevitably fail since stuff drops H_LOCK
129 * all over the place (with structs left in inconsistent states) while RPCs to
130 * clients happen (grumble, grumble, the host package needs to be rewritten...)
132 * the current hack is to force the background threads that deal with host and
133 * callback state offline early in the shutdown process, do VShutdown, come
134 * back and wait for those threads to die, THEN do the state dump
136 * BUT, this still has one flaw -- what do we do about rx worker threads that
137 * are blocked in the host package making an RPC call to a cm???
139 * currently we try to detect if a host struct is in an inconsistent state
140 * when we go to save it to disk, and just skip the hosts that we think may
141 * be inconsistent (see h_isBusy_r in host.c). This has the problem of causing
142 * more InitCallBackState's when we come back up, but the number of hosts in
143 * such a state should be small. In the future, we could try to lock hosts
144 * (with some deadline so we don't wait forever) before serializing, but at
145 * least for now it does not seem worth the trouble.
148 if (fs_state.options.fs_state_verify_before_save) {
149 ViceLog(0, ("fs_stateSave: performing internal consistency checks before proceeding with state dump\n"));
151 if (h_stateVerify(&state)) {
152 ViceLog(0, ("fs_stateSave: error: host table consistency checks failed; state dump will not be marked clean\n"));
157 if (cb_stateVerify(&state)) {
158 ViceLog(0, ("fs_stateSave: error: callback table consistency checks failed; state dump will not be marked clean\n"));
163 /* if a consistency check asserted the bail flag, reset it */
166 ViceLog(0, ("fs_stateSave: proceeding with dump\n"));
169 if (fs_stateCreateDump(&state)) {
170 ViceLog(0, ("fs_stateSave: error: dump create failed\n"));
175 if (h_stateSave(&state)) {
176 ViceLog(0, ("fs_stateSave: error: host state dump failed\n"));
181 if (cb_stateSave(&state)) {
182 ViceLog(0, ("fs_stateSave: error: callback state dump failed\n"));
191 if (fs_stateCommitDump(&state)) {
192 ViceLog(0, ("fs_stateSave: error: dump commit failed\n"));
198 ViceLog(0, ("fs_stateSave: fileserver state dump completed successfully\n"));
200 ViceLog(0, ("fs_stateSave: fileserver state dump completed, but not marked clean.\n"));
201 ViceLog(0, ("fs_stateSave: please save a copy of '%s' for use by technical support\n",
206 if (fs_stateFileOpen(&state))
207 fs_stateCloseDump(&state);
208 fs_stateFree(&state);
215 * restore all fileserver state
217 * this function must appear as one atomic operation to the host and callback
218 * packages, hence H_LOCK is held for the entirety of the process.
221 fs_stateRestore(void)
224 struct fs_dump_state state;
226 /* save and restore need to be atomic wrt other host package operations */
229 ViceLog(0, ("fs_stateRestore: commencing fileserver state restore\n"));
231 if (fs_stateAlloc(&state)) {
232 ViceLog(0, ("fs_stateRestore: memory allocation failed\n"));
237 if (fs_stateLoadDump(&state)) {
238 ViceLog(0, ("fs_stateRestore: failed to load dump file '%s'\n", state.fn));
243 if (fs_stateInvalidateDump(&state)) {
244 ViceLog(0, ("fs_stateRestore: failed to invalidate dump file '%s'\n", state.fn));
250 if (state.flags.do_host_restore) {
251 if (h_stateRestore(&state)) {
252 ViceLog(0, ("fs_stateRestore: error: host state restore failed. exiting avoid further corruption\n"));
255 ViceLog(0, ("fs_stateRestore: host table restored\n"));
257 if (cb_stateRestore(&state)) {
258 ViceLog(0, ("fs_stateRestore: error: callback state restore failed. exiting to avoid further corruption\n"));
261 ViceLog(0, ("fs_stateRestore: FileEntry and CallBack tables restored\n"));
263 if (h_stateRestoreIndices(&state)) {
264 ViceLog(0, ("fs_stateRestore: error: host index remapping failed. exiting to avoid further corruption\n"));
267 ViceLog(0, ("fs_stateRestore: host table indices remapped\n"));
269 if (cb_stateRestoreIndices(&state)) {
270 ViceLog(0, ("fs_stateRestore: error: callback index remapping failed. exiting to avoid further corruption\n"));
273 ViceLog(0, ("fs_stateRestore: FileEntry and CallBack indices remapped\n"));
276 ViceLog(0, ("fs_stateRestore: restore phase complete\n"));
278 if (fs_state.options.fs_state_verify_after_restore) {
279 ViceLog(0, ("fs_stateRestore: beginning state verification phase\n"));
281 if (state.flags.do_host_restore) {
282 if (h_stateVerify(&state)) {
283 ViceLog(0, ("fs_stateRestore: error: host table consistency checks failed; exiting to avoid further corruption\n"));
287 if (cb_stateVerify(&state)) {
288 ViceLog(0, ("fs_stateRestore: error: callback table consistency checks failed; exiting to avoid further corruption\n"));
293 ViceLog(0, ("fs_stateRestore: fileserver state verification complete\n"));
296 ViceLog(0, ("fs_stateRestore: restore was successful\n"));
300 fs_stateInvalidateDump(&state);
301 fs_stateCloseDump(&state);
303 fs_stateFree(&state);
309 fs_stateCreateDump(struct fs_dump_state * state)
312 char savedump[MAXPATHLEN];
313 struct afs_stat status;
315 snprintf(savedump, sizeof(savedump), "%s.old", state->fn);
317 if (afs_stat(state->fn, &status) == 0) {
318 rk_rename(state->fn, savedump);
321 if (((fd = afs_open(state->fn,
322 O_RDWR | O_CREAT | O_TRUNC,
323 S_IRUSR | S_IWUSR)) == -1) ||
324 (afs_fstat(fd, &status) == -1)) {
325 ViceLog(0, ("fs_stateCreateDump: failed to create state dump file '%s'\n",
332 state->mode = FS_STATE_DUMP_MODE;
333 memset(state->hdr, 0, sizeof(struct fs_state_header));
334 fs_stateIncEOF(state, sizeof(struct fs_state_header));
336 #ifdef FS_STATE_USE_MMAP
337 if (fs_stateSizeFile(state)) {
338 ViceLog(0, ("fs_stateCreateDump: failed to resize state dump file '%s'\n",
344 if (fs_stateMapFile(state)) {
345 ViceLog(0, ("fs_stateCreateDump: failed to memory map state dump file '%s'\n",
352 ret = fs_stateInvalidateDump(state);
359 fs_stateInvalidateDump(struct fs_dump_state * state)
363 struct fs_state_header hdr;
365 #ifdef FS_STATE_USE_MMAP
366 if (state->mmap.map == NULL) {
371 memcpy(&hdr, state->hdr, sizeof(hdr));
375 /* write a bogus header to flag dump in progress */
376 if (fs_stateWriteHeader(state, &z, &hdr, sizeof(hdr))) {
377 ViceLog(0, ("fs_stateInvalidateDump: failed to invalidate old dump file header '%s'\n",
382 if (fs_stateSync(state)) {
383 ViceLog(0, ("fs_stateInvalidateDump: failed to sync changes to disk\n"));
393 fs_stateCommitDump(struct fs_dump_state * state)
400 #ifdef FS_STATE_USE_MMAP
401 if (fs_stateTruncateFile(state)) {
402 ViceLog(0, ("fs_stateCommitDump: failed to truncate dump file to proper size\n"));
408 /* ensure that all pending data I/Os for the state file have been committed
409 * _before_ we make the metadata I/Os */
410 if (fs_stateSync(state)) {
411 ViceLog(0, ("fs_stateCommitDump: failed to sync changes to disk\n"));
416 #ifdef FS_STATE_USE_MMAP
417 /* XXX madvise may not exist on all platforms, so
418 * we may need to add some ifdefs at some point... */
420 madvise((((char *)state->mmap.map) + sizeof(struct fs_state_header)),
421 state->mmap.size - sizeof(struct fs_state_header),
426 /* build the header, and write it to disk */
427 fs_stateFillHeader(state->hdr);
429 state->hdr->valid = 0;
431 if (fs_stateWriteHeader(state, &z, state->hdr, sizeof(struct fs_state_header))) {
432 ViceLog(0, ("fs_stateCommitDump: failed to write header to dump file '%s'\n",
437 if (fs_stateSync(state)) {
438 ViceLog(0, ("fs_stateCommitDump: failed to sync new header to disk\n"));
448 fs_stateLoadDump(struct fs_dump_state * state)
452 struct afs_stat status;
453 afs_int32 now = time(NULL);
457 if ((fd = afs_open(state->fn, O_RDWR)) == -1 ||
458 (afs_fstat(fd, &status) == -1)) {
459 ViceLog(0, ("fs_stateLoadDump: failed to load state dump file '%s'\n",
465 state->mode = FS_STATE_LOAD_MODE;
466 state->file_len = status.st_size;
468 #ifdef FS_STATE_USE_MMAP
469 if (fs_stateMapFile(state)) {
470 ViceLog(0, ("fs_stateLoadDump: failed to memory map state dump file '%s'\n",
477 if (fs_stateReadHeader(state, &z, state->hdr, sizeof(struct fs_state_header))) {
478 ViceLog(0, ("fs_stateLoadDump: failed to read header from dump file '%s'\n",
484 /* check the validity of the header */
485 if (fs_stateCheckHeader(state->hdr)) {
486 ViceLog(1, ("fs_stateLoadDump: header failed validity checks; not restoring '%s'\n",
492 if ((state->hdr->timestamp + HOST_STATE_VALID_WINDOW) >= now) {
493 state->flags.do_host_restore = 1;
495 ViceLog(0, ("fs_stateLoadDump: warning: dump is too old for host and callback restore; skipping those steps\n"));
503 fs_stateCloseDump(struct fs_dump_state * state)
505 #ifdef FS_STATE_USE_MMAP
506 fs_stateUnmapFile(state);
513 fs_stateWrite(struct fs_dump_state * state,
514 void * buf, size_t len)
518 #ifdef FS_STATE_USE_MMAP
519 if (fs_stateCheckIOSafety(state, len)) {
520 if (fs_stateResizeFile(state, len)) {
521 ViceLog(0, ("fs_stateWrite: could not resize dump file '%s'\n",
528 memcpy(state->mmap.cursor, buf, len);
529 fs_stateIncCursor(state, len);
531 if (write(state->fd, buf, len) != len) {
532 ViceLog(0, ("fs_stateWrite: write failed\n"));
543 fs_stateRead(struct fs_dump_state * state,
544 void * buf, size_t len)
548 #ifdef FS_STATE_USE_MMAP
549 if (fs_stateCheckIOSafety(state, len)) {
550 ViceLog(0, ("fs_stateRead: read beyond EOF for dump file '%s'\n",
556 memcpy(buf, state->mmap.cursor, len);
557 fs_stateIncCursor(state, len);
559 if (read(state->fd, buf, len) != len) {
560 ViceLog(0, ("fs_stateRead: read failed\n"));
571 fs_stateWriteV(struct fs_dump_state * state,
572 struct iovec * iov, int niov)
577 for (i=0; i < niov; i++) {
578 len += iov[i].iov_len;
581 #ifdef FS_STATE_USE_MMAP
582 if (fs_stateCheckIOSafety(state, len)) {
583 if (fs_stateResizeFile(state, len)) {
584 ViceLog(0, ("fs_stateWrite: could not resize dump file '%s'\n",
591 for (i=0; i < niov; i++) {
592 memcpy(state->mmap.cursor, iov[i].iov_base, iov[i].iov_len);
593 fs_stateIncCursor(state, iov[i].iov_len);
597 if (writev(state->fd, iov, niov) != len) {
598 ViceLog(0, ("fs_stateWriteV: write failed\n"));
602 #else /* AFS_NT40_ENV */
603 for (i=0; i < niov; i++) {
604 if (write(state->fd, iov[i].iov_base, iov[i].iov_len) != iov[i].iov_len) {
605 ViceLog(0, ("fs_stateWriteV: write failed\n"));
610 #endif /* AFS_NT40_ENV */
618 fs_stateReadV(struct fs_dump_state * state,
619 struct iovec * iov, int niov)
624 for (i=0; i < niov; i++) {
625 len += iov[i].iov_len;
628 #ifdef FS_STATE_USE_MMAP
629 if (fs_stateCheckIOSafety(state, len)) {
630 ViceLog(0, ("fs_stateRead: read beyond EOF for dump file '%s'\n",
636 for (i=0; i < niov; i++) {
637 memcpy(iov[i].iov_base, state->mmap.cursor, iov[i].iov_len);
638 fs_stateIncCursor(state, iov[i].iov_len);
642 if (readv(state->fd, iov, niov) != len) {
643 ViceLog(0, ("fs_stateReadV: read failed\n"));
648 for (i=0; i < niov; i++) {
649 if (read(state->fd, iov[i].iov_base, iov[i].iov_len) != iov[i].iov_len) {
650 ViceLog(0, ("fs_stateReadV: read failed\n"));
655 #endif /* AFS_NT40_ENV */
663 fs_stateWriteHeader(struct fs_dump_state * state,
665 void * hdr, size_t len)
669 if (fs_stateSeek(state, offset)) {
670 ViceLog(0, ("fs_stateWriteHeader: could not seek to correct position in dump file '%s'\n",
676 if (fs_stateWrite(state, hdr, len)) {
677 ViceLog(0, ("fs_stateWriteHeader: write failed\n"));
687 fs_stateReadHeader(struct fs_dump_state * state,
689 void * hdr, size_t len)
693 if (fs_stateSeek(state, offset)) {
694 ViceLog(0, ("fs_stateReadHeader: could not seek to correct position in dump file '%s'\n",
700 if (fs_stateRead(state, hdr,len)) {
701 ViceLog(0, ("fs_stateReadHeader: read failed\n"));
710 #ifdef FS_STATE_USE_MMAP
712 fs_stateSizeFile(struct fs_dump_state * state)
715 state->file_len = FS_STATE_INIT_FILESIZE;
716 if (afs_ftruncate(state->fd, state->file_len) != 0)
722 fs_stateResizeFile(struct fs_dump_state * state, size_t min_add)
727 fs_stateUnmapFile(state);
729 inc = ((min_add / FS_STATE_INIT_FILESIZE)+1) * FS_STATE_INIT_FILESIZE;
730 state->file_len += inc;
732 if (afs_ftruncate(state->fd, state->file_len) != 0) {
733 ViceLog(0, ("fs_stateResizeFile: truncate failed\n"));
738 if (fs_stateMapFile(state)) {
739 ViceLog(0, ("fs_stateResizeFile: remapping memory mapped file failed\n"));
749 fs_stateTruncateFile(struct fs_dump_state * state)
753 if (afs_ftruncate(state->fd, state->eof_offset) != 0) {
761 fs_stateMapFile(struct fs_dump_state * state)
765 switch(state->mode) {
766 case FS_STATE_LOAD_MODE:
767 flags = PROT_READ | PROT_WRITE; /* loading involves a header invalidation */
769 case FS_STATE_DUMP_MODE:
773 ViceLog(0, ("fs_stateMapFile: invalid dump state mode\n"));
777 state->mmap.map = afs_mmap(NULL,
784 if (state->mmap.map == MAP_FAILED) {
785 state->mmap.size = 0;
786 state->mmap.map = NULL;
787 ViceLog(0, ("fs_stateMapFile: failed to memory map file '%s'\n",
793 state->mmap.size = state->file_len;
794 state->mmap.cursor = state->mmap.map;
795 state->mmap.offset = 0;
797 /* for state loading, accesses will be sequential, so let's give
798 * the VM subsystem a heads up */
799 if (state->mode == FS_STATE_LOAD_MODE) {
800 /* XXX madvise may not exist on all platforms, so
801 * we may need to add some ifdefs at some point... */
802 flags = MADV_SEQUENTIAL | MADV_WILLNEED;
803 #ifdef AFS_SUN510_ENV
804 flags |= MADV_ACCESS_LWP; /* added in solaris 9 12/02 */
806 madvise(state->mmap.map, state->mmap.size, flags);
814 fs_stateUnmapFile(struct fs_dump_state * state)
818 if (munmap(state->mmap.map, state->mmap.size) == -1) {
819 ViceLog(0, ("fs_stateUnmapFile: failed to unmap dump file '%s'\n",
830 fs_stateSync(struct fs_dump_state * state)
834 msync(state->mmap.map, state->mmap.size, MS_SYNC);
838 #else /* !FS_STATE_USE_MMAP */
840 fs_stateSync(struct fs_dump_state * state)
844 if (fsync(state->fd) == -1)
849 #endif /* !FS_STATE_USE_MMAP */
852 fs_stateIncEOF(struct fs_dump_state * state, afs_int32 len)
855 FillInt64(temp, 0, len);
856 AddUInt64(state->eof_offset, temp, &state->eof_offset);
860 #ifdef FS_STATE_USE_MMAP
862 fs_stateIncCursor(struct fs_dump_state * state, size_t len)
866 state->mmap.offset += len;
868 p = (char *) state->mmap.cursor;
870 state->mmap.cursor = (void *) p;
876 fs_stateCheckIOSafety(struct fs_dump_state * state, size_t len)
880 if ((state->mmap.offset + len) > state->mmap.size) {
885 #endif /* FS_STATE_USE_MMAP */
887 #ifdef FS_STATE_USE_MMAP
889 fs_stateSeek(struct fs_dump_state * state, afs_uint64 * offset)
895 p = (char *) state->mmap.map;
897 state->mmap.cursor = (void *) p;
900 state->mmap.offset = *offset;
904 #else /* !FS_STATE_USE_MMAP */
906 fs_stateSeek(struct fs_dump_state * state, afs_uint64 * offset)
910 if (afs_lseek(state->fd, *offset, SEEK_SET) == -1)
915 #endif /* !FS_STATE_USE_MMAP */
918 fs_stateFillHeader(struct fs_state_header * hdr)
920 hdr->stamp.magic = FS_STATE_MAGIC;
921 hdr->stamp.version = FS_STATE_VERSION;
923 hdr->sys_name = SYS_NAME_ID;
925 hdr->sys_name = 0xFFFFFFFF;
927 hdr->timestamp = time(NULL);
928 hdr->server_uuid = FS_HostUUID;
930 #ifdef WORDS_BIGENDIAN
935 hdr->stats_detailed = 1;
936 if (strlcpy(hdr->server_version_string, cml_version_number, sizeof(hdr->server_version_string))
937 >= sizeof(hdr->server_version_string)) {
938 ViceLog(0, ("fs_stateFillHeader: WARNING -- cml_version_number field truncated\n"));
944 fs_stateCheckHeader(struct fs_state_header * hdr)
949 ViceLog(0, ("fs_stateCheckHeader: dump was previously flagged invalid\n"));
952 #ifdef WORDS_BIGENDIAN
953 else if (!hdr->endianness) {
954 ViceLog(0, ("fs_stateCheckHeader: wrong endianness\n"));
957 #else /* AFSLITTLE_ENDIAN */
958 else if (hdr->endianness) {
959 ViceLog(0, ("fs_stateCheckHeader: wrong endianness\n"));
962 #endif /* AFSLITTLE_ENDIAN */
964 else if (hdr->stamp.magic != FS_STATE_MAGIC) {
965 ViceLog(0, ("fs_stateCheckHeader: invalid dump header\n"));
968 else if (hdr->stamp.version != FS_STATE_VERSION) {
969 ViceLog(0, ("fs_stateCheckHeader: unknown dump format version number\n"));
973 else if (!hdr->stats_detailed) {
974 ViceLog(0, ("fs_stateCheckHeader: wrong config flags\n"));
978 else if (!afs_uuid_equal(&hdr->server_uuid, &FS_HostUUID)) {
979 ViceLog(0, ("fs_stateCheckHeader: server UUID does not match this server's UUID\n"));
983 /* the cml_version_string is included for informational purposes only. If someone ever
984 * wants to limit state dump reloading based upon the contents of this string, just
985 * uncomment the following code. uncommenting this code is _strongly discouraged_ because
986 * we already make use of the version stamps in the various dump headers to deal with
987 * data structure version incompatabilities.
988 else if (strncmp(hdr->server_version_string, cml_version_number,
989 sizeof(hdr->server_version_string)) != 0) {
990 ViceLog(0, ("fs_stateCheckHeader: dump from different server version\n"));
995 else if (strncmp(hdr->server_version_string, cml_version_number,
996 sizeof(hdr->server_version_string)) != 0) {
997 ViceLog(0, ("fs_stateCheckHeader: dump from different server version ; attempting state reload anyway\n"));
1005 fs_stateAlloc(struct fs_dump_state * state)
1008 memset(state, 0, sizeof(struct fs_dump_state));
1010 state->fn = (char *)AFSDIR_SERVER_FSSTATE_FILEPATH;
1011 state->hdr = malloc(sizeof(struct fs_state_header));
1012 state->h_hdr = malloc(sizeof(struct host_state_header));
1013 state->cb_hdr = malloc(sizeof(struct callback_state_header));
1014 state->cb_timeout_hdr =
1015 malloc(sizeof(struct callback_state_timeout_header));
1016 state->cb_fehash_hdr =
1017 malloc(sizeof(struct callback_state_fehash_header));
1018 if ((state->hdr == NULL) || (state->h_hdr == NULL) || (state->cb_hdr == NULL) ||
1019 (state->cb_timeout_hdr == NULL) || (state->cb_fehash_hdr == NULL))
1025 fs_stateFree(struct fs_dump_state * state)
1032 free(state->cb_hdr);
1033 if (state->cb_timeout_hdr)
1034 free(state->cb_timeout_hdr);
1035 if (state->cb_fehash_hdr)
1036 free(state->cb_fehash_hdr);
1037 if (state->h_map.entries)
1038 free(state->h_map.entries);
1039 if (state->fe_map.entries)
1040 free(state->fe_map.entries);
1041 if (state->cb_map.entries)
1042 free(state->cb_map.entries);
1046 #endif /* AFS_DEMAND_ATTACH_FS */