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>
30 #include <afs/vnode.h>
31 #include <afs/volume.h>
33 #include <afs/ptclient.h>
34 #include <afs/prs_fs.h>
35 #include <afs/afsutil.h>
37 #include <afs/cellconfig.h>
39 #include "../viced/viced_prototypes.h"
40 #include "../viced/viced.h"
41 #include "../viced/host.h"
42 #include "../viced/callback.h"
43 #include "serialize_state.h"
45 #ifdef AFS_DEMAND_ATTACH_FS
51 * in order to make state dump/restore as fast as possible,
52 * we use memory mapped files
54 * if this causes problems on certain platforms, the APIs
55 * have been written so that it will be very simple to go
56 * back to standard I/O for just those poorly written platforms
59 #define FS_STATE_USE_MMAP 1
62 #ifdef FS_STATE_USE_MMAP
63 #define FS_STATE_INIT_FILESIZE (8 * 1024 * 1024) /* truncate to 8MB initially */
69 static int fs_stateCreateDump(struct fs_dump_state * state);
70 static int fs_stateLoadDump(struct fs_dump_state * state);
71 static int fs_stateInvalidateDump(struct fs_dump_state * state);
72 static int fs_stateCommitDump(struct fs_dump_state * state);
73 static int fs_stateCloseDump(struct fs_dump_state * state);
75 #ifdef FS_STATE_USE_MMAP
76 static int fs_stateSizeFile(struct fs_dump_state * state);
77 static int fs_stateResizeFile(struct fs_dump_state * state, size_t min_add);
78 static int fs_stateTruncateFile(struct fs_dump_state * state);
80 static int fs_stateMapFile(struct fs_dump_state * state);
81 static int fs_stateUnmapFile(struct fs_dump_state * state);
83 static int fs_stateIncCursor(struct fs_dump_state * state, size_t len);
84 static int fs_stateCheckIOSafety(struct fs_dump_state * state,
88 static int fs_stateFillHeader(struct fs_state_header * hdr);
89 static int fs_stateCheckHeader(struct fs_state_header * hdr);
91 static int fs_stateAlloc(struct fs_dump_state * state);
92 static int fs_stateFree(struct fs_dump_state * state);
94 extern afsUUID FS_HostUUID;
95 extern char cml_version_number[];
98 fs_stateFileOpen(struct fs_dump_state *state)
101 return(state->fd != -1);
103 return(state->fd >= 0);
110 * save all fileserver state
115 int ret = 0, verified = 1;
116 struct fs_dump_state state;
118 /* save and restore need to be atomic wrt other host package operations */
121 ViceLog(0, ("fs_stateSave: commencing fileserver state dump\n"));
123 if (fs_stateAlloc(&state)) {
124 ViceLog(0, ("fs_stateSave: memory allocation failed; dump aborted\n"));
130 * on busy servers, these checks will inevitably fail since stuff drops H_LOCK
131 * all over the place (with structs left in inconsistent states) while RPCs to
132 * clients happen (grumble, grumble, the host package needs to be rewritten...)
134 * the current hack is to force the background threads that deal with host and
135 * callback state offline early in the shutdown process, do VShutdown, come
136 * back and wait for those threads to die, THEN do the state dump
138 * BUT, this still has one flaw -- what do we do about rx worker threads that
139 * are blocked in the host package making an RPC call to a cm???
141 * currently we try to detect if a host struct is in an inconsistent state
142 * when we go to save it to disk, and just skip the hosts that we think may
143 * be inconsistent (see h_isBusy_r in host.c). This has the problem of causing
144 * more InitCallBackState's when we come back up, but the number of hosts in
145 * such a state should be small. In the future, we could try to lock hosts
146 * (with some deadline so we don't wait forever) before serializing, but at
147 * least for now it does not seem worth the trouble.
150 if (fs_state.options.fs_state_verify_before_save) {
151 ViceLog(0, ("fs_stateSave: performing internal consistency checks before proceeding with state dump\n"));
153 if (h_stateVerify(&state)) {
154 ViceLog(0, ("fs_stateSave: error: host table consistency checks failed; state dump will not be marked clean\n"));
159 if (cb_stateVerify(&state)) {
160 ViceLog(0, ("fs_stateSave: error: callback table consistency checks failed; state dump will not be marked clean\n"));
165 /* if a consistency check asserted the bail flag, reset it */
168 ViceLog(0, ("fs_stateSave: proceeding with dump\n"));
171 if (fs_stateCreateDump(&state)) {
172 ViceLog(0, ("fs_stateSave: error: dump create failed\n"));
177 if (h_stateSave(&state)) {
178 ViceLog(0, ("fs_stateSave: error: host state dump failed\n"));
183 if (cb_stateSave(&state)) {
184 ViceLog(0, ("fs_stateSave: error: callback state dump failed\n"));
193 if (fs_stateCommitDump(&state)) {
194 ViceLog(0, ("fs_stateSave: error: dump commit failed\n"));
200 ViceLog(0, ("fs_stateSave: fileserver state dump completed successfully\n"));
202 ViceLog(0, ("fs_stateSave: fileserver state dump completed, but not marked clean.\n"));
203 ViceLog(0, ("fs_stateSave: please save a copy of '%s' for use by technical support\n",
208 if (fs_stateFileOpen(&state))
209 fs_stateCloseDump(&state);
210 fs_stateFree(&state);
217 * restore all fileserver state
219 * this function must appear as one atomic operation to the host and callback
220 * packages, hence H_LOCK is held for the entirety of the process.
223 fs_stateRestore(void)
226 struct fs_dump_state state;
228 /* save and restore need to be atomic wrt other host package operations */
231 ViceLog(0, ("fs_stateRestore: commencing fileserver state restore\n"));
233 if (fs_stateAlloc(&state)) {
234 ViceLog(0, ("fs_stateRestore: memory allocation failed\n"));
239 if (fs_stateLoadDump(&state)) {
240 ViceLog(0, ("fs_stateRestore: failed to load dump file '%s'\n", state.fn));
245 if (fs_stateInvalidateDump(&state)) {
246 ViceLog(0, ("fs_stateRestore: failed to invalidate dump file '%s'\n", state.fn));
252 if (state.flags.do_host_restore) {
253 if (h_stateRestore(&state)) {
254 ViceLog(0, ("fs_stateRestore: error: host state restore failed. exiting avoid further corruption\n"));
257 ViceLog(0, ("fs_stateRestore: host table restored\n"));
259 if (cb_stateRestore(&state)) {
260 ViceLog(0, ("fs_stateRestore: error: callback state restore failed. exiting to avoid further corruption\n"));
263 ViceLog(0, ("fs_stateRestore: FileEntry and CallBack tables restored\n"));
265 if (h_stateRestoreIndices(&state)) {
266 ViceLog(0, ("fs_stateRestore: error: host index remapping failed. exiting to avoid further corruption\n"));
269 ViceLog(0, ("fs_stateRestore: host table indices remapped\n"));
271 if (cb_stateRestoreIndices(&state)) {
272 ViceLog(0, ("fs_stateRestore: error: callback index remapping failed. exiting to avoid further corruption\n"));
275 ViceLog(0, ("fs_stateRestore: FileEntry and CallBack indices remapped\n"));
278 ViceLog(0, ("fs_stateRestore: restore phase complete\n"));
280 if (fs_state.options.fs_state_verify_after_restore) {
281 ViceLog(0, ("fs_stateRestore: beginning state verification phase\n"));
283 if (state.flags.do_host_restore) {
284 if (h_stateVerify(&state)) {
285 ViceLog(0, ("fs_stateRestore: error: host table consistency checks failed; exiting to avoid further corruption\n"));
289 if (cb_stateVerify(&state)) {
290 ViceLog(0, ("fs_stateRestore: error: callback table consistency checks failed; exiting to avoid further corruption\n"));
295 ViceLog(0, ("fs_stateRestore: fileserver state verification complete\n"));
298 ViceLog(0, ("fs_stateRestore: restore was successful\n"));
302 fs_stateInvalidateDump(&state);
303 fs_stateCloseDump(&state);
305 fs_stateFree(&state);
311 fs_stateCreateDump(struct fs_dump_state * state)
314 char savedump[MAXPATHLEN];
315 struct afs_stat status;
317 snprintf(savedump, sizeof(savedump), "%s.old", state->fn);
319 if (afs_stat(state->fn, &status) == 0) {
320 rk_rename(state->fn, savedump);
323 if (((fd = afs_open(state->fn,
324 O_RDWR | O_CREAT | O_TRUNC,
325 S_IRUSR | S_IWUSR)) == -1) ||
326 (afs_fstat(fd, &status) == -1)) {
327 ViceLog(0, ("fs_stateCreateDump: failed to create state dump file '%s'\n",
334 state->mode = FS_STATE_DUMP_MODE;
335 memset(state->hdr, 0, sizeof(struct fs_state_header));
336 fs_stateIncEOF(state, sizeof(struct fs_state_header));
338 #ifdef FS_STATE_USE_MMAP
339 if (fs_stateSizeFile(state)) {
340 ViceLog(0, ("fs_stateCreateDump: failed to resize state dump file '%s'\n",
346 if (fs_stateMapFile(state)) {
347 ViceLog(0, ("fs_stateCreateDump: failed to memory map state dump file '%s'\n",
354 ret = fs_stateInvalidateDump(state);
361 fs_stateInvalidateDump(struct fs_dump_state * state)
365 struct fs_state_header hdr;
367 #ifdef FS_STATE_USE_MMAP
368 if (state->mmap.map == NULL) {
373 memcpy(&hdr, state->hdr, sizeof(hdr));
377 /* write a bogus header to flag dump in progress */
378 if (fs_stateWriteHeader(state, &z, &hdr, sizeof(hdr))) {
379 ViceLog(0, ("fs_stateInvalidateDump: failed to invalidate old dump file header '%s'\n",
384 if (fs_stateSync(state)) {
385 ViceLog(0, ("fs_stateInvalidateDump: failed to sync changes to disk\n"));
395 fs_stateCommitDump(struct fs_dump_state * state)
402 #ifdef FS_STATE_USE_MMAP
403 if (fs_stateTruncateFile(state)) {
404 ViceLog(0, ("fs_stateCommitDump: failed to truncate dump file to proper size\n"));
410 /* ensure that all pending data I/Os for the state file have been committed
411 * _before_ we make the metadata I/Os */
412 if (fs_stateSync(state)) {
413 ViceLog(0, ("fs_stateCommitDump: failed to sync changes to disk\n"));
418 #ifdef FS_STATE_USE_MMAP
419 /* XXX madvise may not exist on all platforms, so
420 * we may need to add some ifdefs at some point... */
422 madvise((((char *)state->mmap.map) + sizeof(struct fs_state_header)),
423 state->mmap.size - sizeof(struct fs_state_header),
428 /* build the header, and write it to disk */
429 fs_stateFillHeader(state->hdr);
431 state->hdr->valid = 0;
433 if (fs_stateWriteHeader(state, &z, state->hdr, sizeof(struct fs_state_header))) {
434 ViceLog(0, ("fs_stateCommitDump: failed to write header to dump file '%s'\n",
439 if (fs_stateSync(state)) {
440 ViceLog(0, ("fs_stateCommitDump: failed to sync new header to disk\n"));
450 fs_stateLoadDump(struct fs_dump_state * state)
454 struct afs_stat status;
455 afs_int32 now = time(NULL);
459 if ((fd = afs_open(state->fn, O_RDWR)) == -1 ||
460 (afs_fstat(fd, &status) == -1)) {
461 ViceLog(0, ("fs_stateLoadDump: failed to load state dump file '%s'\n",
467 state->mode = FS_STATE_LOAD_MODE;
468 state->file_len = status.st_size;
470 #ifdef FS_STATE_USE_MMAP
471 if (fs_stateMapFile(state)) {
472 ViceLog(0, ("fs_stateLoadDump: failed to memory map state dump file '%s'\n",
479 if (fs_stateReadHeader(state, &z, state->hdr, sizeof(struct fs_state_header))) {
480 ViceLog(0, ("fs_stateLoadDump: failed to read header from dump file '%s'\n",
486 /* check the validity of the header */
487 if (fs_stateCheckHeader(state->hdr)) {
488 ViceLog(1, ("fs_stateLoadDump: header failed validity checks; not restoring '%s'\n",
494 if ((state->hdr->timestamp + HOST_STATE_VALID_WINDOW) >= now) {
495 state->flags.do_host_restore = 1;
497 ViceLog(0, ("fs_stateLoadDump: warning: dump is too old for host and callback restore; skipping those steps\n"));
505 fs_stateCloseDump(struct fs_dump_state * state)
507 #ifdef FS_STATE_USE_MMAP
508 fs_stateUnmapFile(state);
515 fs_stateWrite(struct fs_dump_state * state,
516 void * buf, size_t len)
520 #ifdef FS_STATE_USE_MMAP
521 if (fs_stateCheckIOSafety(state, len)) {
522 if (fs_stateResizeFile(state, len)) {
523 ViceLog(0, ("fs_stateWrite: could not resize dump file '%s'\n",
530 memcpy(state->mmap.cursor, buf, len);
531 fs_stateIncCursor(state, len);
533 if (write(state->fd, buf, len) != len) {
534 ViceLog(0, ("fs_stateWrite: write failed\n"));
545 fs_stateRead(struct fs_dump_state * state,
546 void * buf, size_t len)
550 #ifdef FS_STATE_USE_MMAP
551 if (fs_stateCheckIOSafety(state, len)) {
552 ViceLog(0, ("fs_stateRead: read beyond EOF for dump file '%s'\n",
558 memcpy(buf, state->mmap.cursor, len);
559 fs_stateIncCursor(state, len);
561 if (read(state->fd, buf, len) != len) {
562 ViceLog(0, ("fs_stateRead: read failed\n"));
573 fs_stateWriteV(struct fs_dump_state * state,
574 struct iovec * iov, int niov)
579 for (i=0; i < niov; i++) {
580 len += iov[i].iov_len;
583 #ifdef FS_STATE_USE_MMAP
584 if (fs_stateCheckIOSafety(state, len)) {
585 if (fs_stateResizeFile(state, len)) {
586 ViceLog(0, ("fs_stateWrite: could not resize dump file '%s'\n",
593 for (i=0; i < niov; i++) {
594 memcpy(state->mmap.cursor, iov[i].iov_base, iov[i].iov_len);
595 fs_stateIncCursor(state, iov[i].iov_len);
599 if (writev(state->fd, iov, niov) != len) {
600 ViceLog(0, ("fs_stateWriteV: write failed\n"));
604 #else /* AFS_NT40_ENV */
605 for (i=0; i < niov; i++) {
606 if (write(state->fd, iov[i].iov_base, iov[i].iov_len) != iov[i].iov_len) {
607 ViceLog(0, ("fs_stateWriteV: write failed\n"));
612 #endif /* AFS_NT40_ENV */
620 fs_stateReadV(struct fs_dump_state * state,
621 struct iovec * iov, int niov)
626 for (i=0; i < niov; i++) {
627 len += iov[i].iov_len;
630 #ifdef FS_STATE_USE_MMAP
631 if (fs_stateCheckIOSafety(state, len)) {
632 ViceLog(0, ("fs_stateRead: read beyond EOF for dump file '%s'\n",
638 for (i=0; i < niov; i++) {
639 memcpy(iov[i].iov_base, state->mmap.cursor, iov[i].iov_len);
640 fs_stateIncCursor(state, iov[i].iov_len);
644 if (readv(state->fd, iov, niov) != len) {
645 ViceLog(0, ("fs_stateReadV: read failed\n"));
650 for (i=0; i < niov; i++) {
651 if (read(state->fd, iov[i].iov_base, iov[i].iov_len) != iov[i].iov_len) {
652 ViceLog(0, ("fs_stateReadV: read failed\n"));
657 #endif /* AFS_NT40_ENV */
665 fs_stateWriteHeader(struct fs_dump_state * state,
667 void * hdr, size_t len)
671 if (fs_stateSeek(state, offset)) {
672 ViceLog(0, ("fs_stateWriteHeader: could not seek to correct position in dump file '%s'\n",
678 if (fs_stateWrite(state, hdr, len)) {
679 ViceLog(0, ("fs_stateWriteHeader: write failed\n"));
689 fs_stateReadHeader(struct fs_dump_state * state,
691 void * hdr, size_t len)
695 if (fs_stateSeek(state, offset)) {
696 ViceLog(0, ("fs_stateReadHeader: could not seek to correct position in dump file '%s'\n",
702 if (fs_stateRead(state, hdr,len)) {
703 ViceLog(0, ("fs_stateReadHeader: read failed\n"));
712 #ifdef FS_STATE_USE_MMAP
714 fs_stateSizeFile(struct fs_dump_state * state)
717 state->file_len = FS_STATE_INIT_FILESIZE;
718 if (afs_ftruncate(state->fd, state->file_len) != 0)
724 fs_stateResizeFile(struct fs_dump_state * state, size_t min_add)
729 fs_stateUnmapFile(state);
731 inc = ((min_add / FS_STATE_INIT_FILESIZE)+1) * FS_STATE_INIT_FILESIZE;
732 state->file_len += inc;
734 if (afs_ftruncate(state->fd, state->file_len) != 0) {
735 ViceLog(0, ("fs_stateResizeFile: truncate failed\n"));
740 if (fs_stateMapFile(state)) {
741 ViceLog(0, ("fs_stateResizeFile: remapping memory mapped file failed\n"));
751 fs_stateTruncateFile(struct fs_dump_state * state)
755 if (afs_ftruncate(state->fd, state->eof_offset) != 0) {
763 fs_stateMapFile(struct fs_dump_state * state)
767 switch(state->mode) {
768 case FS_STATE_LOAD_MODE:
769 flags = PROT_READ | PROT_WRITE; /* loading involves a header invalidation */
771 case FS_STATE_DUMP_MODE:
775 ViceLog(0, ("fs_stateMapFile: invalid dump state mode\n"));
779 state->mmap.map = afs_mmap(NULL,
786 if (state->mmap.map == MAP_FAILED) {
787 state->mmap.size = 0;
788 state->mmap.map = NULL;
789 ViceLog(0, ("fs_stateMapFile: failed to memory map file '%s'\n",
795 state->mmap.size = state->file_len;
796 state->mmap.cursor = state->mmap.map;
797 state->mmap.offset = 0;
799 /* for state loading, accesses will be sequential, so let's give
800 * the VM subsystem a heads up */
801 if (state->mode == FS_STATE_LOAD_MODE) {
802 /* XXX madvise may not exist on all platforms, so
803 * we may need to add some ifdefs at some point... */
804 flags = MADV_SEQUENTIAL | MADV_WILLNEED;
805 #ifdef AFS_SUN510_ENV
806 flags |= MADV_ACCESS_LWP; /* added in solaris 9 12/02 */
808 madvise(state->mmap.map, state->mmap.size, flags);
816 fs_stateUnmapFile(struct fs_dump_state * state)
820 if (munmap(state->mmap.map, state->mmap.size) == -1) {
821 ViceLog(0, ("fs_stateUnmapFile: failed to unmap dump file '%s'\n",
832 fs_stateSync(struct fs_dump_state * state)
836 msync(state->mmap.map, state->mmap.size, MS_SYNC);
840 #else /* !FS_STATE_USE_MMAP */
842 fs_stateSync(struct fs_dump_state * state)
846 if (fsync(state->fd) == -1)
851 #endif /* !FS_STATE_USE_MMAP */
854 fs_stateIncEOF(struct fs_dump_state * state, afs_int32 len)
857 FillInt64(temp, 0, len);
858 AddUInt64(state->eof_offset, temp, &state->eof_offset);
862 #ifdef FS_STATE_USE_MMAP
864 fs_stateIncCursor(struct fs_dump_state * state, size_t len)
868 state->mmap.offset += len;
870 p = (char *) state->mmap.cursor;
872 state->mmap.cursor = (void *) p;
878 fs_stateCheckIOSafety(struct fs_dump_state * state, size_t len)
882 if ((state->mmap.offset + len) > state->mmap.size) {
887 #endif /* FS_STATE_USE_MMAP */
889 #ifdef FS_STATE_USE_MMAP
891 fs_stateSeek(struct fs_dump_state * state, afs_uint64 * offset)
897 p = (char *) state->mmap.map;
899 state->mmap.cursor = (void *) p;
902 state->mmap.offset = *offset;
906 #else /* !FS_STATE_USE_MMAP */
908 fs_stateSeek(struct fs_dump_state * state, afs_uint64 * offset)
912 if (afs_lseek(state->fd, *offset, SEEK_SET) == -1)
917 #endif /* !FS_STATE_USE_MMAP */
920 fs_stateFillHeader(struct fs_state_header * hdr)
922 hdr->stamp.magic = FS_STATE_MAGIC;
923 hdr->stamp.version = FS_STATE_VERSION;
925 hdr->sys_name = SYS_NAME_ID;
927 hdr->sys_name = 0xFFFFFFFF;
929 hdr->timestamp = time(NULL);
930 hdr->server_uuid = FS_HostUUID;
932 #ifdef WORDS_BIGENDIAN
937 hdr->stats_detailed = 1;
938 if (strlcpy(hdr->server_version_string, cml_version_number, sizeof(hdr->server_version_string))
939 >= sizeof(hdr->server_version_string)) {
940 ViceLog(0, ("fs_stateFillHeader: WARNING -- cml_version_number field truncated\n"));
946 fs_stateCheckHeader(struct fs_state_header * hdr)
951 ViceLog(0, ("fs_stateCheckHeader: dump was previously flagged invalid\n"));
954 #ifdef WORDS_BIGENDIAN
955 else if (!hdr->endianness) {
956 ViceLog(0, ("fs_stateCheckHeader: wrong endianness\n"));
959 #else /* AFSLITTLE_ENDIAN */
960 else if (hdr->endianness) {
961 ViceLog(0, ("fs_stateCheckHeader: wrong endianness\n"));
964 #endif /* AFSLITTLE_ENDIAN */
966 else if (hdr->stamp.magic != FS_STATE_MAGIC) {
967 ViceLog(0, ("fs_stateCheckHeader: invalid dump header\n"));
970 else if (hdr->stamp.version != FS_STATE_VERSION) {
971 ViceLog(0, ("fs_stateCheckHeader: unknown dump format version number\n"));
975 else if (!hdr->stats_detailed) {
976 ViceLog(0, ("fs_stateCheckHeader: wrong config flags\n"));
980 else if (!afs_uuid_equal(&hdr->server_uuid, &FS_HostUUID)) {
981 ViceLog(0, ("fs_stateCheckHeader: server UUID does not match this server's UUID\n"));
985 /* the cml_version_string is included for informational purposes only. If someone ever
986 * wants to limit state dump reloading based upon the contents of this string, just
987 * uncomment the following code. uncommenting this code is _strongly discouraged_ because
988 * we already make use of the version stamps in the various dump headers to deal with
989 * data structure version incompatabilities.
990 else if (strncmp(hdr->server_version_string, cml_version_number,
991 sizeof(hdr->server_version_string)) != 0) {
992 ViceLog(0, ("fs_stateCheckHeader: dump from different server version\n"));
997 else if (strncmp(hdr->server_version_string, cml_version_number,
998 sizeof(hdr->server_version_string)) != 0) {
999 ViceLog(0, ("fs_stateCheckHeader: dump from different server version ; attempting state reload anyway\n"));
1007 fs_stateAlloc(struct fs_dump_state * state)
1010 memset(state, 0, sizeof(struct fs_dump_state));
1012 state->fn = (char *)AFSDIR_SERVER_FSSTATE_FILEPATH;
1013 state->hdr = malloc(sizeof(struct fs_state_header));
1014 state->h_hdr = malloc(sizeof(struct host_state_header));
1015 state->cb_hdr = malloc(sizeof(struct callback_state_header));
1016 state->cb_timeout_hdr =
1017 malloc(sizeof(struct callback_state_timeout_header));
1018 state->cb_fehash_hdr =
1019 malloc(sizeof(struct callback_state_fehash_header));
1020 if ((state->hdr == NULL) || (state->h_hdr == NULL) || (state->cb_hdr == NULL) ||
1021 (state->cb_timeout_hdr == NULL) || (state->cb_fehash_hdr == NULL))
1027 fs_stateFree(struct fs_dump_state * state)
1034 free(state->cb_hdr);
1035 if (state->cb_timeout_hdr)
1036 free(state->cb_timeout_hdr);
1037 if (state->cb_fehash_hdr)
1038 free(state->cb_fehash_hdr);
1039 if (state->h_map.entries)
1040 free(state->h_map.entries);
1041 if (state->fe_map.entries)
1042 free(state->fe_map.entries);
1043 if (state->cb_map.entries)
1044 free(state->cb_map.entries);
1048 #endif /* AFS_DEMAND_ATTACH_FS */