}
#endif
fdCacheSize = MIN(fdMaxCacheSize, FD_DEFAULT_CACHESIZE);
+
+ {
+ void *ih_sync_thread();
+#ifdef AFS_PTHREAD_ENV
+ pthread_t syncer;
+ pthread_attr_t tattr;
+
+ pthread_attr_init(&tattr);
+ pthread_attr_setdetachstate(&tattr,PTHREAD_CREATE_DETACHED);
+
+ pthread_create(&syncer, &tattr, ih_sync_thread, NULL);
+#else /* AFS_PTHREAD_ENV */
+ PROCESS syncer;
+ LWP_CreateProcess(ih_sync_thread, 16*1024, LWP_MAX_PRIORITY - 2,
+ NULL, "ih_syncer", &syncer);
+#endif /* AFS_PTHREAD_ENV */
+ }
+
}
/* Make the file descriptor cache as big as possible. Don't this call
return code;
}
+void
+ih_sync_all() {
+ int ihash;
+
+ IH_LOCK;
+ for (ihash = 0; ihash < I_HANDLE_HASH_SIZE; ihash++) {
+ IHandle_t *ihP, *ihPnext;
+
+ ihP = ihashTable[ihash].ihash_head;
+ if (ihP)
+ ihP->ih_refcnt++; /* must not disappear over unlock */
+ for (; ihP; ihP = ihPnext) {
+
+ if (ihP->ih_synced) {
+ FdHandle_t *fdP;
+
+ ihP->ih_synced = 0;
+ IH_UNLOCK;
+
+ fdP = IH_OPEN(ihP);
+ if (fdP) OS_SYNC(fdP->fd_fd);
+ FDH_CLOSE(fdP);
+
+ IH_LOCK;
+ }
+
+ /* when decrementing the refcount, the ihandle might disappear
+ and we might not even be able to proceed to the next one.
+ Hence the gymnastics putting a hold on the next one already */
+ ihPnext = ihP->ih_next;
+ if (ihPnext) ihPnext->ih_refcnt++;
+
+ if (ihP->ih_refcnt > 1) {
+ ihP->ih_refcnt--;
+ } else {
+ IH_UNLOCK;
+ ih_release(ihP);
+ IH_LOCK;
+ }
+
+ }
+ }
+ IH_UNLOCK;
+}
+
+void *
+ih_sync_thread() {
+ while(1) {
+
+#ifdef AFS_PTHREAD_ENV
+ sleep(10);
+#else /* AFS_PTHREAD_ENV */
+ IOMGR_Sleep(60);
+#endif /* AFS_PTHREAD_ENV */
+
+ sync();
+ ih_sync_all();
+ }
+}
/*************************************************************************
int ih_vid; /* Parent volume id. */
int ih_dev; /* device id. */
int ih_flags; /* Flags */
+ int ih_synced; /* should be synced next time */
Inode ih_ino; /* Inode number */
int ih_refcnt; /* reference count */
struct FdHandle_s *ih_fdhead; /* List of open file desciptors */
#define FDH_WRITE(H, B, S) OS_WRITE((H)->fd_fd, B, S)
#define FDH_SEEK(H, O, F) OS_SEEK((H)->fd_fd, O, F)
-#define FDH_SYNC(H) OS_SYNC((H)->fd_fd)
+#define FDH_SYNC(H) ((H->fd_ih!=NULL) ? ( H->fd_ih->ih_synced = 1) - 1 : 1)
#define FDH_TRUNC(H, L) OS_TRUNC((H)->fd_fd, L)
#define FDH_SIZE(H) OS_SIZE((H)->fd_fd)
if (p2 == -1 && p3 == VI_LINKTABLE) {
/* hack at tmp to setup for set link count call. */
+ memset((void *)&tfd, 0, sizeof(FdHandle_t)); /* minimalistic still, but a little cleaner */
+ tfd.fd_ih = &tmp;
tfd.fd_fd = fd;
code = namei_SetLinkCount(&tfd, (Inode) 0, 1, 0);
}
vnodeIndexOffset(vcp, dir->vnodeNumber), (char *)&vnode,
sizeof(vnode));
assert(lcode == sizeof(vnode));
+#if 0
#ifdef AFS_NT40_ENV
nt_sync(fileSysDevice);
#else
sync(); /* this is slow, but hopefully rarely called. We don't have
* an open FD on the file itself to fsync.
*/
+#endif
+#else
+ vnodeInfo[vLarge].handle->ih_synced = 1;
#endif
code = IH_DEC(dir->ds_linkH, oldinode, dir->rwVid);
assert(code == 0);
SalvageDir(volHeader.name, vid, dirVnodeInfo, alinkH, i, &rootdir,
&rootdirfound);
}
+#ifdef AFS_NT40_ENV
+ nt_sync(fileSysDevice);
+#else
+ sync(); /* This used to be done lower level, for every dir */
+#endif
if (Showmode) {
IH_RELEASE(h);
return 0;