Hi,
This has been on my drawing board for a while, but I've only recently
started to tidy it up.
A while back I created IFS - the Inode Filesystem - for FreeBSD.
Basically its FFS without the directory namespace. You work with
inode numbers as your directory.
I've been curious to see what effect this would have on squid.
Combined with changing the block/fragment sizes from their
default 8192/1024 to say, 32768/8192 and possibly upping the
disk IO blocks to use this size, we might be able to squeeze
some more disk performance and cut back the memory requirements
in the existing codebase.
Unfortunately its only in freebsd-current right now, but I hope
to MFC the code and support utilities back to freebsd-stable
so people can actually start to use it.
If people are interested in ifs, take a look at
http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/ufs/ifs/README#rev1.1
Here's a diff to squid-head that implements a working IFS. I believe
that the rebuilds and directory cleaning are currently broken.
It uses diskd for IO, so to enable ifs you stick 'ifs' at the end
of the cache_dir line. l1 and l2 are ignored.
Adrian
--- Index: configure =================================================================== RCS file: /server/cvs-server/squid/squid/configure,v retrieving revision 1.219 diff -u -r1.219 configure --- configure 2001/01/18 17:57:04 1.219 +++ configure 2001/01/21 10:31:16 @@ -979,13 +979,13 @@ CFLAGS="$ac_save_CFLAGS" elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then - CFLAGS="-g -O2" + CFLAGS="-g" else CFLAGS="-g" fi else if test "$GCC" = yes; then - CFLAGS="-O2" + CFLAGS="" else CFLAGS= fi @@ -1025,7 +1025,7 @@ alpha-dec-osf4.*) # Mogul says DEC compilers take both -g and -O2 CFLAGS=`echo $CFLAGS | sed -e 's/-g/-g3/'` - CFLAGS="$CFLAGS -O2" + CFLAGS="$CFLAGS" ;; *) ;; Index: src/fs/diskd/diskd.c =================================================================== RCS file: /server/cvs-server/squid/squid/src/fs/diskd/diskd.c,v retrieving revision 1.9 diff -u -r1.9 diskd.c --- src/fs/diskd/diskd.c 2001/01/12 00:37:33 1.9 +++ src/fs/diskd/diskd.c 2001/01/21 10:31:16 @@ -67,6 +67,8 @@ { int fd; file_state *fs; + struct stat sb; + int retval; /* * note r->offset holds open() flags */ @@ -78,17 +80,30 @@ } return -errno; } + /* + * For a create, we open newfile, and stat the fd to get the inode number. + * This is then the file number used for subsequent open/unlink. + */ + retval = fstat(fd, &sb); + if (retval < 0) { + fprintf(stderr, "%d %s: ", (int)mypid, buf); + perror("stat"); + close(fd); + return -errno; + } + r->f_ino = sb.st_ino; fs = xcalloc(1, sizeof(*fs)); fs->id = r->id; fs->key = &fs->id; /* gack */ fs->fd = fd; hash_join(hash, (hash_link *) fs); DEBUG(2) - fprintf(stderr, "%d OPEN id %d, FD %d, fs %p\n", - (int) mypid, - fs->id, - fs->fd, - fs); + fprintf(stderr, "%d OPEN id %d, FD %d, INODE %d, fs %p\n", + (int) mypid, + fs->id, + fs->fd, + r->f_ino, + fs); return fd; } @@ -224,11 +239,13 @@ s->callback_data = r->callback_data; s->shm_offset = r->shm_offset; s->id = r->id; + s->f_ino = -1; /* Nice default! */ if (s->shm_offset > -1) buf = shmbuf + s->shm_offset; switch (r->mtype) { case _MQD_OPEN: s->status = do_open(r, rl, buf); + s->f_ino = r->f_ino; /* make sure we return the inode number! */ break; case _MQD_CLOSE: s->status = do_close(r, rl); Index: src/fs/diskd/store_dir_diskd.c =================================================================== RCS file: /server/cvs-server/squid/squid/src/fs/diskd/store_dir_diskd.c,v retrieving revision 1.37 diff -u -r1.37 store_dir_diskd.c --- src/fs/diskd/store_dir_diskd.c 2001/01/15 22:37:10 1.37 +++ src/fs/diskd/store_dir_diskd.c 2001/01/21 10:31:17 @@ -85,6 +85,7 @@ static int storeDiskdDirVerifyDirectory(const char *path); static void storeDiskdDirCreateSwapSubDirs(SwapDir *); static char *storeDiskdDirSwapLogFile(SwapDir *, const char *); +static EVH storeDiskdDirRebuildFromIfsDirectory; static EVH storeDiskdDirRebuildFromDirectory; static EVH storeDiskdDirRebuildFromSwapLog; static int storeDiskdDirGetNextFile(RebuildState *, int *sfileno, int *size); @@ -430,7 +431,7 @@ commSetTimeout(diskdinfo->wfd, -1, NULL, NULL); commSetNonBlocking(diskdinfo->wfd); storeDiskdDirInitBitmap(sd); - if (storeDiskdDirVerifyCacheDirs(sd) < 0) + if (!diskdinfo->doifs && storeDiskdDirVerifyCacheDirs(sd) < 0) fatal(errmsg); storeDiskdDirOpenSwapLog(sd); storeDiskdDirRebuild(sd); @@ -535,6 +536,19 @@ } +static void +storeDiskdDirRebuildFromIfsDirectory(void *data) +{ + RebuildState *rb = data; + + /* For now, fake it */ + debug(20, 1) ("Done scanning %s swaplog (%d entries)\n", + rb->sd->path, rb->n_read); + store_dirs_rebuilding--; + storeDiskdDirCloseTmpSwapLog(rb->sd); + storeRebuildComplete(&rb->counts); + cbdataFree(rb); +} static void storeDiskdDirRebuildFromDirectory(void *data) @@ -1016,6 +1030,7 @@ RebuildState *rb; int clean = 0; int zero = 0; + diskdinfo_t *diskdinfo = sd->fsdata; FILE *fp; EVH *func = NULL; CBDATA_INIT_TYPE(RebuildState); @@ -1032,7 +1047,11 @@ if (fp == NULL || zero) { if (fp != NULL) fclose(fp); - func = storeDiskdDirRebuildFromDirectory; + /* If we're doing IFS, do a different rebuild */ + if (diskdinfo->doifs) + func = storeDiskdDirRebuildFromIfsDirectory; + else + func = storeDiskdDirRebuildFromDirectory; } else { func = storeDiskdDirRebuildFromSwapLog; rb->log = fp; @@ -1313,9 +1332,15 @@ static void storeDiskdDirNewfs(SwapDir * sd) { - debug(47, 3) ("Creating swap space in %s\n", sd->path); - storeDiskdDirCreateDirectory(sd->path, 0); - storeDiskdDirCreateSwapSubDirs(sd); + diskdinfo_t *diskdinfo = sd->fsdata; + + if (diskdinfo->doifs) { + debug(47, 3) ("No need to newfs for ifs in %s\n", sd->path); + } else { + debug(47, 3) ("Creating swap space in %s\n", sd->path); + storeDiskdDirCreateDirectory(sd->path, 0); + storeDiskdDirCreateSwapSubDirs(sd); + } } static int @@ -1345,6 +1370,7 @@ int D0, D1, D2; SwapDir *SD; diskdinfo_t *diskdinfo; + N0 = n_diskd_dirs; D0 = diskd_dir_index[swap_index % N0]; SD = &Config.cacheSwap.swapDirs[D0]; @@ -1353,6 +1379,11 @@ D1 = (swap_index / N0) % N1; N2 = diskdinfo->l2; D2 = ((swap_index / N0) / N1) % N2; + + /* If we're doing ifs on this partition, ignore it */ + if (diskdinfo->doifs) + return 0; + snprintf(p1, SQUID_MAXPATHLEN, "%s/%02X/%02X", Config.cacheSwap.swapDirs[D0].path, D1, D2); debug(36, 3) ("storeDirClean: Cleaning directory %s\n", p1); @@ -1424,10 +1455,10 @@ diskd_dir_index = xcalloc(n_diskd_dirs, sizeof(*diskd_dir_index)); for (i = 0, n = 0; i < Config.cacheSwap.n_configured; i++) { sd = &Config.cacheSwap.swapDirs[i]; + diskdinfo = sd->fsdata; if (!storeDiskdDirIs(sd)) continue; diskd_dir_index[n++] = i; - diskdinfo = sd->fsdata; j += (diskdinfo->l1 * diskdinfo->l2); } assert(n == n_diskd_dirs); @@ -1484,6 +1515,9 @@ diskdinfo_t *diskdinfo = SD->fsdata; if (filn < 0) return 0; + /* If we are doing IFS, we don't know whether its valid .. */ + if (diskdinfo->doifs) + return 1; /* * If flag is set it means out-of-range file number should * be considered invalid. @@ -1688,9 +1722,12 @@ storeAppendPrintf(sentry, "Current Size: %d KB\n", SD->cur_size); storeAppendPrintf(sentry, "Percent Used: %0.2f%%\n", 100.0 * SD->cur_size / SD->max_size); - storeAppendPrintf(sentry, "Filemap bits in use: %d of %d (%d%%)\n", - diskdinfo->map->n_files_in_map, diskdinfo->map->max_n_files, - percent(diskdinfo->map->n_files_in_map, diskdinfo->map->max_n_files)); + /* These stats are meaningless when doing IFS */ + if (!diskdinfo->doifs) { + storeAppendPrintf(sentry, "Filemap bits in use: %d of %d (%d%%)\n", + diskdinfo->map->n_files_in_map, diskdinfo->map->max_n_files, + percent(diskdinfo->map->n_files_in_map, diskdinfo->map->max_n_files)); + } x = storeDirGetUFSStats(SD->path, &totl_kb, &free_kb, &totl_in, &free_in); if (0 == x) { storeAppendPrintf(sentry, "Filesystem Space in use: %d/%d KB (%d%%)\n", @@ -1783,6 +1820,7 @@ storeDiskdDirDump(StoreEntry * entry, const char *name, SwapDir * s) { diskdinfo_t *diskdinfo = s->fsdata; + /* XXXX need to put whether we're doing IFS or not here! */ storeAppendPrintf(entry, "%s %s %s %d %d %d\n", name, "diskd", @@ -1819,11 +1857,15 @@ if (!fullpath) fullpath = fullfilename; fullpath[0] = '\0'; - snprintf(fullpath, SQUID_MAXPATHLEN, "%s/%02X/%02X/%08X", - SD->path, - ((filn / L2) / L2) % L1, - (filn / L2) % L2, - filn); + if (diskdinfo->doifs) + snprintf(fullpath, SQUID_MAXPATHLEN, "%s/%d", SD->path, filn); + else { + snprintf(fullpath, SQUID_MAXPATHLEN, "%s/%02X/%02X/%08X", + SD->path, + ((filn / L2) / L2) % L1, + (filn / L2) % L2, + filn); + } return fullpath; } @@ -1871,6 +1913,7 @@ int l1; int l2; int magic1, magic2; + int doifs = 0; unsigned int read_only = 0; diskdinfo_t *diskdinfo; @@ -1896,9 +1939,16 @@ fatal("storeDiskdDirParse: invalid magic2 value"); - if ((token = strtok(NULL, w_space))) - if (!strcasecmp(token, "read-only")) + if ((token = strtok(NULL, w_space))) { + if (!strcasecmp(token, "read-only")) { read_only = 1; + token = strtok(NULL, w_space); + } + /* Check IFS */ + if (token && !strcasecmp(token, "ifs")) { + doifs = 1; + } + } sd->fsdata = diskdinfo = xcalloc(1, sizeof(*diskdinfo)); sd->index = index; @@ -1936,6 +1986,9 @@ sd->log.clean.start = storeDiskdDirWriteCleanStart; sd->log.clean.nextentry = storeDiskdDirCleanLogNextEntry; sd->log.clean.done = storeDiskdDirWriteCleanDone; + + /* Now, are we ifs or not? */ + diskdinfo->doifs = doifs; /* Initialise replacement policy stuff */ sd->repl = createRemovalPolicy(Config.replPolicy); Index: src/fs/diskd/store_diskd.h =================================================================== RCS file: /server/cvs-server/squid/squid/src/fs/diskd/store_diskd.h,v retrieving revision 1.5 diff -u -r1.5 store_diskd.h --- src/fs/diskd/store_diskd.h 2000/07/16 07:28:38 1.5 +++ src/fs/diskd/store_diskd.h 2001/01/21 10:31:17 @@ -32,6 +32,7 @@ } shm; int magic1; int magic2; + int doifs; /* Are we doing ifs or not ? */ }; struct _diskdstate_t { @@ -62,6 +63,7 @@ int offset; int status; int shm_offset; + int f_ino; /* used for the ifs option */ } diomsg; struct _diskd_stats { Index: src/fs/diskd/store_io_diskd.c =================================================================== RCS file: /server/cvs-server/squid/squid/src/fs/diskd/store_io_diskd.c,v retrieving revision 1.20 diff -u -r1.20 store_io_diskd.c --- src/fs/diskd/store_io_diskd.c 2001/01/12 00:37:33 1.20 +++ src/fs/diskd/store_io_diskd.c 2001/01/21 10:31:18 @@ -75,6 +75,7 @@ sio->swap_dirn = SD->index; sio->mode = O_RDONLY; sio->callback = callback; + sio->file_callback = file_callback; sio->callback_data = callback_data; sio->e = e; cbdataLock(callback_data); @@ -122,10 +123,16 @@ diskd_stats.open_fail_queue_len++; return NULL; } - /* Allocate a number */ - f = storeDiskdDirMapBitAllocate(SD); - debug(81, 3) ("storeDiskdCreate: fileno %08X\n", f); + /* If we are in ifs mode, the FS gives us the file number */ + if (diskdinfo->doifs) + f = -1; + else { + /* Allocate a number */ + f = storeDiskdDirMapBitAllocate(SD); + debug(81, 3) ("storeDiskdCreate: fileno %08X\n", f); + } + sio = CBDATA_ALLOC(storeIOState, storeDiskdIOFreeEntry); sio->fsstate = diskdstate = memPoolAlloc(diskd_state_pool); @@ -134,6 +141,7 @@ sio->mode = O_WRONLY | O_CREAT | O_TRUNC; sio->callback = callback; sio->callback_data = callback_data; + sio->file_callback = file_callback; sio->e = e; cbdataLock(callback_data); @@ -143,7 +151,15 @@ diskdstate->id = diskd_stats.sio_id++; buf = storeDiskdShmGet(SD, &shm_offset); - xstrncpy(buf, storeDiskdDirFullPath(SD, f, NULL), SHMBUF_BLKSZ); + /* + * If we are in ifs mode, we open 'newfile', and do a delayed sfileno + * assignment once the open has completed + */ + if (diskdinfo->doifs) + snprintf(buf, SHMBUF_BLKSZ, "%s/newfile", SD->path); + else + xstrncpy(buf, storeDiskdDirFullPath(SD, f, NULL), SHMBUF_BLKSZ); + x = storeDiskdSend(_MQD_OPEN, SD, diskdstate->id, @@ -270,7 +286,10 @@ debug(81, 3) ("storeDiskdUnlink: dirno %d, fileno %08X\n", SD->index, e->swap_filen); storeDiskdDirReplRemove(e); - storeDiskdDirMapBitReset(SD, e->swap_filen); + if (!diskdinfo->doifs) { + /* If we are in ifs mode, we don't need to do this! */ + storeDiskdDirMapBitReset(SD, e->swap_filen); + } if (diskdinfo->away >= diskdinfo->magic1) { /* Damn, we need to issue a sync unlink here :( */ debug(50, 2) ("storeDiskUnlink: Out of queue space, sync unlink\n"); @@ -302,7 +321,14 @@ storeDiskdOpenDone(diomsg * M) { storeIOState *sio = M->callback_data; + diskdinfo_t *diskdinfo = INDEXSD(sio->swap_dirn)->fsdata; statCounter.syscalls.disk.opens++; + /* If we are in IFS mode, we get f_ino and set the swap filenumber there */ + if (diskdinfo->doifs) { + sio->swap_filen = M->f_ino; + /* Notify the upper levels that we've changed file number */ + sio->file_callback(sio->callback_data, 0, sio); + } debug(81, 3) ("storeDiskdOpenDone: dirno %d, fileno %08x status %d\n", sio->swap_dirn, sio->swap_filen, M->status); if (M->status < 0) {Received on Sun Jan 21 2001 - 03:44:54 MST
This archive was generated by hypermail pre-2.1.9 : Tue Dec 09 2003 - 16:13:25 MST