⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 store_dir_ufs.c

📁 一个功能非常全面的代理服务器源代码程序,
💻 C
📖 第 1 页 / 共 4 页
字号:
			time_t timestamp;			time_t lastref;			time_t expires;			time_t lastmod;			size_t swap_file_sz;			u_short refcount;			u_short flags;		    }     *tmp = t->value;		    assert(sizeof(*tmp) == STORE_HDR_METASIZE_OLD);		    tmpe.timestamp = tmp->timestamp;		    tmpe.lastref = tmp->lastref;		    tmpe.expires = tmp->expires;		    tmpe.lastmod = tmp->lastmod;		    tmpe.swap_file_sz = tmp->swap_file_sz;		    tmpe.refcount = tmp->refcount;		    tmpe.flags = tmp->flags;		}		break;#endif	    default:		break;	    }	}	storeSwapTLVFree(tlv_list);	tlv_list = NULL;	if (storeKeyNull(key)) {	    debug(47, 1) ("storeUfsDirRebuildFromDirectory: NULL key\n");	    storeUfsDirUnlinkFile(SD, filn);	    continue;	}	tmpe.hash.key = key;	/* check sizes */	if (tmpe.swap_file_sz == 0) {	    tmpe.swap_file_sz = sb.st_size;	} else if (tmpe.swap_file_sz == sb.st_size - swap_hdr_len) {	    tmpe.swap_file_sz = sb.st_size;	} else if (tmpe.swap_file_sz != sb.st_size) {	    debug(47, 1) ("storeUfsDirRebuildFromDirectory: SIZE MISMATCH %ld!=%ld\n",		(long int) tmpe.swap_file_sz, (long int) sb.st_size);	    storeUfsDirUnlinkFile(SD, filn);	    continue;	}	if (EBIT_TEST(tmpe.flags, KEY_PRIVATE)) {	    storeUfsDirUnlinkFile(SD, filn);	    rb->counts.badflags++;	    continue;	}	e = storeGet(key);	if (e && e->lastref >= tmpe.lastref) {	    /* key already exists, current entry is newer */	    /* keep old, ignore new */	    rb->counts.dupcount++;	    continue;	} else if (NULL != e) {	    /* URL already exists, this swapfile not being used */	    /* junk old, load new */	    storeRelease(e);	/* release old entry */	    rb->counts.dupcount++;	}	rb->counts.objcount++;	storeEntryDump(&tmpe, 5);	e = storeUfsDirAddDiskRestore(SD, key,	    filn,	    tmpe.swap_file_sz,	    tmpe.expires,	    tmpe.timestamp,	    tmpe.lastref,	    tmpe.lastmod,	    tmpe.refcount,	/* refcount */	    tmpe.flags,		/* flags */	    (int) rb->flags.clean);	storeDirSwapLog(e, SWAP_LOG_ADD);    }    eventAdd("storeRebuild", storeUfsDirRebuildFromDirectory, rb, 0.0, 1);}static voidstoreUfsDirRebuildFromSwapLog(void *data){    RebuildState *rb = data;    SwapDir *SD = rb->sd;    StoreEntry *e = NULL;    storeSwapLogData s;    size_t ss = sizeof(storeSwapLogData);    int count;    int used;			/* is swapfile already in use? */    int disk_entry_newer;	/* is the log entry newer than current entry? */    double x;    assert(rb != NULL);    /* load a number of objects per invocation */    for (count = 0; count < rb->speed; count++) {	if (fread(&s, ss, 1, rb->log) != 1) {	    storeUfsDirRebuildComplete(rb);	    return;	}	rb->n_read++;	/*	 * BC: during 2.4 development, we changed the way swap file	 * numbers are assigned and stored.  The high 16 bits used	 * to encode the SD index number.  There used to be a call	 * to storeDirProperFileno here that re-assigned the index 	 * bits.  Now, for backwards compatibility, we just need	 * to mask it off.	 */	s.swap_filen &= 0x00FFFFFF;	debug(47, 3) ("storeUfsDirRebuildFromSwapLog: %s %s %08X\n",	    swap_log_op_str[(int) s.op],	    storeKeyText(s.key),	    s.swap_filen);	if (s.op == SWAP_LOG_ADD) {	    (void) 0;	} else if (s.op == SWAP_LOG_DEL) {	    /* Delete unless we already have a newer copy */	    if ((e = storeGet(s.key)) != NULL && s.lastref > e->lastref) {		/*		 * Make sure we don't unlink the file, it might be		 * in use by a subsequent entry.  Also note that		 * we don't have to subtract from store_swap_size		 * because adding to store_swap_size happens in		 * the cleanup procedure.		 */		storeRecycle(e);		/*		 * XXX considering we might've canceled an object from another store;		 * XXX what should happen with these stats?		 */		rb->counts.objcount--;		rb->counts.cancelcount++;	    }	    continue;	} else {	    x = log(++rb->counts.bad_log_op) / log(10.0);	    if (0.0 == x - (double) (int) x)		debug(47, 1) ("WARNING: %d invalid swap log entries found\n",		    rb->counts.bad_log_op);	    rb->counts.invalid++;	    continue;	}	if ((++rb->counts.scancount & 0xFFF) == 0) {	    struct stat sb;	    if (0 == fstat(fileno(rb->log), &sb))		storeRebuildProgress(SD->index,		    (int) sb.st_size / ss, rb->n_read);	}	if (!storeUfsDirValidFileno(SD, s.swap_filen, 0)) {	    rb->counts.invalid++;	    continue;	}	if (EBIT_TEST(s.flags, KEY_PRIVATE)) {	    rb->counts.badflags++;	    continue;	}	e = storeGet(s.key);	used = storeUfsDirMapBitTest(SD, s.swap_filen);	/* If this URL already exists in the cache, does the swap log	 * appear to have a newer entry?  Compare 'lastref' from the	 * swap log to e->lastref. */	disk_entry_newer = e ? (s.lastref > e->lastref ? 1 : 0) : 0;	if (used && !disk_entry_newer) {	    /* log entry is old, ignore it */	    rb->counts.clashcount++;	    continue;	} else if (used && e && e->swap_filen == s.swap_filen && e->swap_dirn == SD->index) {	    /* swapfile taken, same URL, newer, update meta */	    if (e->store_status == STORE_OK) {		e->lastref = s.timestamp;		e->timestamp = s.timestamp;		e->expires = s.expires;		e->lastmod = s.lastmod;		e->flags = s.flags;		e->refcount += s.refcount;		storeUfsDirUnrefObj(SD, e);	    } else {		debug_trap("storeUfsDirRebuildFromSwapLog: bad condition");		debug(47, 1) ("\tSee %s:%d\n", __FILE__, __LINE__);	    }	    continue;	} else if (used) {	    /* swapfile in use, not by this URL, log entry is newer */	    /* This is sorta bad: the log entry should NOT be newer at this	     * point.  If the log is dirty, the filesize check should have	     * caught this.  If the log is clean, there should never be a	     * newer entry. */	    debug(47, 1) ("WARNING: newer swaplog entry for dirno %d, fileno %08X\n",		SD->index, s.swap_filen);	    /* I'm tempted to remove the swapfile here just to be safe,	     * but there is a bad race condition in the NOVM version if	     * the swapfile has recently been opened for writing, but	     * not yet opened for reading.  Because we can't map	     * swapfiles back to StoreEntrys, we don't know the state	     * of the entry using that file.  */	    /* We'll assume the existing entry is valid, probably because	     * were in a slow rebuild and the the swap file number got taken	     * and the validation procedure hasn't run. */	    assert(rb->flags.need_to_validate);	    rb->counts.clashcount++;	    continue;	} else if (e && !disk_entry_newer) {	    /* key already exists, current entry is newer */	    /* keep old, ignore new */	    rb->counts.dupcount++;	    continue;	} else if (e) {	    /* key already exists, this swapfile not being used */	    /* junk old, load new */	    storeRecycle(e);	    rb->counts.dupcount++;	} else {	    /* URL doesnt exist, swapfile not in use */	    /* load new */	    (void) 0;	}	/* update store_swap_size */	rb->counts.objcount++;	e = storeUfsDirAddDiskRestore(SD, s.key,	    s.swap_filen,	    s.swap_file_sz,	    s.expires,	    s.timestamp,	    s.lastref,	    s.lastmod,	    s.refcount,	    s.flags,	    (int) rb->flags.clean);	storeDirSwapLog(e, SWAP_LOG_ADD);    }    eventAdd("storeRebuild", storeUfsDirRebuildFromSwapLog, rb, 0.0, 1);}#if SIZEOF_SQUID_FILE_SZ != SIZEOF_SIZE_T/* This is an exact copy of the above, but using storeSwapLogDataOld entry type */static voidstoreUfsDirRebuildFromSwapLogOld(void *data){    RebuildState *rb = data;    SwapDir *SD = rb->sd;    StoreEntry *e = NULL;    storeSwapLogDataOld s;    size_t ss = sizeof(storeSwapLogDataOld);    int count;    int used;			/* is swapfile already in use? */    int disk_entry_newer;	/* is the log entry newer than current entry? */    double x;    assert(rb != NULL);    /* load a number of objects per invocation */    for (count = 0; count < rb->speed; count++) {	if (fread(&s, ss, 1, rb->log) != 1) {	    storeUfsDirRebuildComplete(rb);	    return;	}	rb->n_read++;	/*	 * BC: during 2.4 development, we changed the way swap file	 * numbers are assigned and stored.  The high 16 bits used	 * to encode the SD index number.  There used to be a call	 * to storeDirProperFileno here that re-assigned the index 	 * bits.  Now, for backwards compatibility, we just need	 * to mask it off.	 */	s.swap_filen &= 0x00FFFFFF;	debug(47, 3) ("storeUfsDirRebuildFromSwapLog: %s %s %08X\n",	    swap_log_op_str[(int) s.op],	    storeKeyText(s.key),	    s.swap_filen);	if (s.op == SWAP_LOG_ADD) {	    (void) 0;	} else if (s.op == SWAP_LOG_DEL) {	    /* Delete unless we already have a newer copy */	    if ((e = storeGet(s.key)) != NULL && s.lastref > e->lastref) {		/*		 * Make sure we don't unlink the file, it might be		 * in use by a subsequent entry.  Also note that		 * we don't have to subtract from store_swap_size		 * because adding to store_swap_size happens in		 * the cleanup procedure.		 */		storeRecycle(e);		/* XXX are these counters valid since e could be from another swapfs? */		rb->counts.objcount--;		rb->counts.cancelcount++;	    }	    continue;	} else {	    x = log(++rb->counts.bad_log_op) / log(10.0);	    if (0.0 == x - (double) (int) x)		debug(47, 1) ("WARNING: %d invalid swap log entries found\n",		    rb->counts.bad_log_op);	    rb->counts.invalid++;	    continue;	}	if ((++rb->counts.scancount & 0xFFF) == 0) {	    struct stat sb;	    if (0 == fstat(fileno(rb->log), &sb))		storeRebuildProgress(SD->index,		    (int) sb.st_size / ss, rb->n_read);	}	if (!storeUfsDirValidFileno(SD, s.swap_filen, 0)) {	    rb->counts.invalid++;	    continue;	}	if (EBIT_TEST(s.flags, KEY_PRIVATE)) {	    rb->counts.badflags++;	    continue;	}	e = storeGet(s.key);	used = storeUfsDirMapBitTest(SD, s.swap_filen);	/* If this URL already exists in the cache, does the swap log	 * appear to have a newer entry?  Compare 'lastref' from the	 * swap log to e->lastref. */	disk_entry_newer = e ? (s.lastref > e->lastref ? 1 : 0) : 0;	if (used && !disk_entry_newer) {	    /* log entry is old, ignore it */	    rb->counts.clashcount++;	    continue;	} else if (used && e && e->swap_filen == s.swap_filen && e->swap_dirn == SD->index) {	    /* swapfile taken, same URL, newer, update meta */	    if (e->store_status == STORE_OK) {		e->lastref = s.timestamp;		e->timestamp = s.timestamp;		e->expires = s.expires;		e->lastmod = s.lastmod;		e->flags = s.flags;		e->refcount += s.refcount;		storeUfsDirUnrefObj(SD, e);	    } else {		debug_trap("storeUfsDirRebuildFromSwapLog: bad condition");		debug(47, 1) ("\tSee %s:%d\n", __FILE__, __LINE__);	    }	    continue;	} else if (used) {	    /* swapfile in use, not by this URL, log entry is newer */	    /* This is sorta bad: the log entry should NOT be newer at this	     * point.  If the log is dirty, the filesize check should have	     * caught this.  If the log is clean, there should never be a	     * newer entry. */	    debug(47, 1) ("WARNING: newer swaplog entry for dirno %d, fileno %08X\n",		SD->index, s.swap_filen);	    /* I'm tempted to remove the swapfile here just to be safe,	     * but there is a bad race condition in the NOVM version if	     * the swapfile has recently been opened for writing, but	     * not yet opened for reading.  Because we can't map	     * swapfiles back to StoreEntrys, we don't know the state	     * of the entry using that file.  */	    /* We'll assume the existing entry is valid, probably because	     * were in a slow rebuild and the the swap file number got taken	     * and the validation procedure hasn't run. */	    assert(rb->flags.need_to_validate);	    rb->counts.clashcount++;	    continue;	} else if (e && !disk_entry_newer) {	    /* key already exists, current entry is newer */	    /* keep old, ignore new */	    rb->counts.dupcount++;	    continue;	} else if (e) {	    /* key already exists, this swapfile not being used */	    /* junk old, load new */	    storeRecycle(e);	    rb->counts.dupcount++;	} else {	    /* URL doesnt exist, swapfile not in use */	    /* load new */	    (void) 0;	}	/* update store_swap_size */	rb->counts.objcount++;	e = storeUfsDirAddDiskRestore(SD, s.key,	    s.swap_filen,	    s.swap_file_sz,	    s.expires,	    s.timestamp,	    s.lastref,	    s.lastmod,	    s.refcount,	    s.flags,	    (int) rb->flags.clean);	storeDirSwapLog(e, SWAP_LOG_ADD);    }    eventAdd("storeRebuild", storeUfsDirRebuildFromSwapLogOld, rb, 0.0, 1);}#endifstatic voidstoreUfsDirRebuildFromSwapLogCheckVersion(void *data){    RebuildState *rb = data;    storeSwapLogHeader hdr;    if (fread(&hdr, sizeof(hdr), 1, rb->log) != 1) {	storeUfsDirRebuildComplete(rb);	return;    }    if (hdr.op == SWAP_LOG_VERSION) {	if (fseek(rb->log, hdr.record_size, SEEK_SET) != 0) {	    storeUfsDirRebuildComplete(rb);	    return;	}	if (hdr.version == 1 && hdr.record_size == sizeof(storeSwapLogData)) {	    eventAdd("storeRebuild", storeUfsDirRebuildFromSwapLog, rb, 0.0, 1);	    return;	}#if SIZEOF_SQUID_FILE_SZ != SIZEOF_SIZE_T	if (hdr.version == 1 && hdr.record_size == sizeof(storeSwapLogDataOld)) {	    debug(47, 1) ("storeUfsDirRebuildFromSwapLog: Found current version but without large file support. Upgrading\n");	    eventAdd("storeRebuild", storeUfsDirRebuildFromSwapLogOld, rb, 0.0, 1);	    return;	}#endif	debug(47, 1) ("storeUfsDirRebuildFromSwapLog: Unsupported swap.state version %d size %d\n",	    hdr.version, hdr.record_size);	storeUfsDirRebuildComplete(rb);	return;    }    rewind(rb->log);    debug(47, 1) ("storeUfsDirRebuildFromSwapLog: Old version detected. Upgrading\n");#if SIZEOF_SQUID_FILE_SZ == SIZEOF_SIZE_T    eventAdd("storeRebuild", storeUfsDirRebuildFromSwapLog, rb, 0.0, 1);#else    eventAdd("storeRebuild", storeUfsDirRebuildFromSwapLogOld, rb, 0.0, 1);#endif}static intstoreUfsDirGetNextFile(RebuildState * rb, sfileno * filn_p, int *size){    SwapDir *SD = rb->sd;    ufsinfo_t *ufsinfo = (ufsinfo_t *) SD->fsdata;    int fd = -1;    int used = 0;    int dirs_opened = 0;    debug(47, 3) ("storeUfsDirGetNextFile: flag=%d, %d: /%02X/%02X\n",	rb->flags.init,	rb->sd->index,	rb->curlvl1, rb->curlvl2);    if (rb->done)	return -2;    while (fd < 0 && rb->done == 0) {	fd = -1;	if (0 == rb->flags.init) {	/* initialize, open first file */	    rb->done = 0;	    rb->curlvl1 = 0;	    rb->curlvl2 = 0;	    rb->in_dir = 0;	    rb->flags.init = 1;	    assert(Config.cacheSwap.n_configured > 0);	}	if (0 == rb->in_dir) {	/* we need to read in a new directory */	    snprintf(rb->fullpath, SQUID_MAXPATHLEN, "%s/%02X/%02X",		rb->sd->path,		rb->curlvl1,		rb->curlvl2);	    if (dirs_opened)		return -1;	    rb->td = opendir(rb->fullpath);	    dirs_opened++;	    if (rb->td == NULL) {		debug(47, 1) ("storeUfsDirGetNextFile: opendir: %s: %s\n",		    rb->fullpath, xstrerror());	    } else {		rb->entry = readdir(rb->td);	/* skip . and .. */		rb->entry = readdir(rb->td);		if (rb->entry == NULL && errno == ENOENT)		    debug(47, 1) ("storeUfsDirGetNextFile: directory does not exist!.\n");		debug(47, 3) ("storeUfsDirGetNextFile: Directory %s\n", rb->fullpath);	    }	}	if (rb->td != NULL && (rb->entry = readdir(rb->td)) != NULL) {	    rb->in_dir++;	    if (sscanf(rb->entry->d_name, "%x", &rb->fn) != 1) {		debug(47, 3) ("storeUfsDirGetNextFile: invalid %s\n",		    rb->entry->d_name);		continue;	    }	    if (!storeUfsFilenoBelongsHere(rb->fn, rb->sd->index, rb->curlvl1, rb->curlvl2)) {		debug(47, 3) ("storeUfsDirGetNextFile: %08X does not belong in %d/%d/%d\n",		    rb->fn, rb->sd->index, rb->curlvl1, rb->curlvl2);		continue;	    }	    used = storeUfsDirMapBitTest(SD, rb->fn);	    if (used) {		debug(47, 3) ("storeUfsDirGetNextFile: Locked, continuing with next.\n");		continue;	    }	    snprintf(rb->fullfilename, SQUID_MAXPATHLEN, "%s/%s",		rb->fullpath, rb->entry->d_name);	    debug(47, 3) ("storeUfsDirGetNextFile: Opening %s\n", rb->fullfilename);	    fd = file_open(rb->fullfilename, O_RDONLY | O_BINARY);	    if (fd < 0)		debug(47, 1) ("storeUfsDirGetNextFile: %s: %s\n", rb->fullfilename, xstrerror());	    else		store_open_disk_fd++;	    continue;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -