void unlinkdUnlink(const char *path) { #if USE_UNLINKD char buf[MAXPATHLEN]; int l; int x; static int queuelen = 0; if (unlinkd_wfd < 0) { debug_trap("unlinkdUnlink: unlinkd_wfd < 0"); safeunlink(path, 0); return; } /* * If the queue length is greater than our limit, then * we pause for up to 100ms, hoping that unlinkd * has some feedback for us. Maybe it just needs a slice * of the CPU's time. */ if (queuelen >= UNLINKD_QUEUE_LIMIT) { struct timeval to; fd_set R; int x; FD_ZERO(&R); FD_SET(unlinkd_rfd, &R); to.tv_sec = 0; to.tv_usec = 100000; x = select(unlinkd_rfd + 1, &R, NULL, NULL, &to); } /* * If there is at least one outstanding unlink request, then * try to read a response. If there's nothing to read we'll * get an EWOULDBLOCK or whatever. If we get a response, then * decrement the queue size by the number of newlines read. */ if (queuelen > 0) { int x; int i; char rbuf[512]; x = read(unlinkd_rfd, rbuf, 511); if (x > 0) { rbuf[x] = '\0'; for (i = 0; i < x; i++) if ('\n' == rbuf[i]) queuelen--; assert(queuelen >= 0); } } l = strlen(path); assert(l < MAXPATHLEN); xstrncpy(buf, path, MAXPATHLEN); buf[l++] = '\n'; x = write(unlinkd_wfd, buf, l); if (x < 0) { debug(50, 1) ("unlinkdUnlink: write FD %d failed: %s\n", unlinkd_wfd, xstrerror()); safeunlink(path, 0); return; } else if (x != l) { debug(50, 1) ("unlinkdUnlink: FD %d only wrote %d of %d bytes\n", unlinkd_wfd, x, l); safeunlink(path, 0); return; } Counter.unlink.requests++; queuelen++; #endif }
static void storeAufsDirClean() { debug(187, 1) ("mod_disk_cleanup: Begining store dir clean !!!!!\n"); count = 0; static int l1 = 0, l2 = 0; static int swap_index = 0; int N1, N2; while (swap_index < Config.cacheSwap.n_configured) { SwapDir *SD = &Config.cacheSwap.swapDirs[swap_index]; if(strcmp(SD->type, "aufs")) { debug(187,2)("mod_disk_cleanup: thia cache_dir not aufs, skip it\n"); swap_index++; continue; } DIR *dp = NULL; struct dirent *de = NULL; LOCAL_ARRAY(char, p1, MAXPATHLEN + 1); LOCAL_ARRAY(char, p2, MAXPATHLEN + 1); #if USE_TRUNCATE struct stat sb; #endif int files[1024]; int swapfileno; int fn; /* same as swapfileno, but with dirn bits set */ int n = 0; int k = 0; squidaioinfo_t *aioinfo = (squidaioinfo_t *) SD->fsdata; N1 = aioinfo->l1; N2 = aioinfo->l2; while(l1 < N1) { while(l2 < N2) { snprintf(p1, SQUID_MAXPATHLEN, "%s/%02X/%02X", Config.cacheSwap.swapDirs[swap_index].path, l1, l2); debug(187, 3) ("mod_disk_cleanup: storeDirClean: Cleaning directory %s\n", p1); dp = opendir(p1); if (dp == NULL) { /* if (errno == ENOENT) { debug(187, 0) ("mod_disk_cleanup: storeDirClean: WARNING: Creating %s\n", p1); if (mkdir(p1, 0777) == 0) continue ; } debug(187, 0) ("mod_disk_cleanup: storeDirClean: %s: %s\n", p1, xstrerror()); safeunlink(p1, 1); */ debug(187,2)("mod_disk_cleanup: opendir [%s] failed %s\n ",p1, xstrerror()); goto next; } k = 0; while ((de = readdir(dp)) != NULL && k < 20) { if (sscanf(de->d_name, "%X", &swapfileno) != 1) continue; fn = swapfileno; /* XXX should remove this cruft ! */ if (storeAufsDirValidFileno(SD, fn, 1)) if (storeAufsDirMapBitTest(SD, fn)) if (storeAufsFilenoBelongsHere(fn, swap_index, l1, l2)) continue; #if USE_TRUNCATE if (!stat(de->d_name, &sb)) if (sb.st_size == 0) continue; #endif files[k++] = swapfileno; } closedir(dp); //no file need process in current dir? out! then next dir loop! if (k > 0) { qsort(files, k, sizeof(int), rev_int_sort); for (n = 0; n < k; n++) { debug(187, 3) ("mod_disk_cleanup: storeDirClean: Cleaning file %08X\n", files[n]); snprintf(p2, MAXPATHLEN + 1, "%s/%08X", p1, files[n]); #if USE_TRUNCATE truncate(p2, 0); #else safeunlink(p2, 0); #endif statCounter.swap.files_cleaned++; count++; } } debug(187, 3)("mod_disk_cleanup: Cleaned %d unused files from %s\n", k, p1); goto next; } } } next: // update value of l1, l2, swap_index debug(187, 3)("mod_disk_cleanup: finish one loop\n"); if(++l2 == N2) { l2 = 0; if(++l1 == N1) { l1 = 0; if(++swap_index == Config.cacheSwap.n_configured) { debug(187, 0)("mod_disk_cleanup: storeDirClean has checked all the cache_dir....\n"); swap_index = 0; } } } }
void unlinkdUnlink(const char *path) { char buf[MAXPATHLEN]; int l; int x; static int queuelen = 0; if (unlinkd_wfd < 0) { debug_trap("unlinkdUnlink: unlinkd_wfd < 0"); safeunlink(path, 0); return; } /* * If the queue length is greater than our limit, then * we pause for up to 10ms, hoping that unlinkd * has some feedback for us. Maybe it just needs a slice * of the CPU's time. */ if (queuelen >= UNLINKD_QUEUE_LIMIT) xusleep(10000); /* * If there is at least one outstanding unlink request, then * try to read a response. If there's nothing to read we'll * get an EWOULDBLOCK or whatever. If we get a response, then * decrement the queue size by the number of newlines read. */ if (queuelen > 0) { int x; int i; char rbuf[512]; #ifdef _SQUID_MSWIN_ x = recv(unlinkd_rfd, rbuf, 511, 0); #else x = read(unlinkd_rfd, rbuf, 511); #endif if (x > 0) { rbuf[x] = '\0'; for (i = 0; i < x; i++) if ('\n' == rbuf[i]) queuelen--; assert(queuelen >= 0); } } l = strlen(path); assert(l < MAXPATHLEN); xstrncpy(buf, path, MAXPATHLEN); buf[l++] = '\n'; #ifdef _SQUID_MSWIN_ x = send(unlinkd_wfd, buf, l, 0); #else x = write(unlinkd_wfd, buf, l); #endif if (x < 0) { debug(2, 1) ("unlinkdUnlink: write FD %d failed: %s\n", unlinkd_wfd, xstrerror()); safeunlink(path, 0); return; } else if (x != l) { debug(2, 1) ("unlinkdUnlink: FD %d only wrote %d of %d bytes\n", unlinkd_wfd, x, l); safeunlink(path, 0); return; } statCounter.unlink.requests++; statCounter.syscalls.disk.unlinks++; queuelen++; }