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

📄 disk.c

📁 -
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (q == NULL)		/* Someone aborted then write completed */	return;    if (len == -2 && errcode == -2) {	/* Write cancelled - cleanup */	do {	    fdd->write_q = q->next;	    if (q->free_func)		(q->free_func) (q->buf);	    safe_free(q);	} while ((q = fdd->write_q));	return;    }    fd_bytes(fd, len, FD_WRITE);    if (len < 0) {	if (!ignoreErrno(errno)) {	    status = errno == ENOSPC ? DISK_NO_SPACE_LEFT : DISK_ERROR;	    debug(50, 1) ("diskHandleWrite: FD %d: disk write error: %s\n",		fd, xstrerror());	    /*	     * If there is no write callback, then this file is	     * most likely something important like a log file, or	     * an interprocess pipe.  Its not a swapfile.  We feel	     * that a write failure on a log file is rather important,	     * and Squid doesn't otherwise deal with this condition.	     * So to get the administrators attention, we exit with	     * a fatal message.	     */	    if (fdd->wrt_handle == NULL)		fatal("Write failure -- check your disk space and cache.log");	    /*	     * If there is a write failure, then we notify the	     * upper layer via the callback, at the end of this	     * function.  Meanwhile, flush all pending buffers	     * here.  Let the upper layer decide how to handle the	     * failure.  This will prevent experiencing multiple,	     * repeated write failures for the same FD because of	     * the queued data.	     */	    do {		fdd->write_q = q->next;		if (q->free_func)		    (q->free_func) (q->buf);		safe_free(q);	    } while ((q = fdd->write_q));	}	len = 0;    }    if (q != NULL) {	/* q might become NULL from write failure above */	q->buf_offset += len;	if (q->buf_offset > q->len)	    debug(50, 1) ("diskHandleWriteComplete: q->buf_offset > q->len (%p,%d, %d, %d FD %d)\n",		q, (int) q->buf_offset, q->len, len, fd);	assert(q->buf_offset <= q->len);	if (q->buf_offset == q->len) {	    /* complete write */	    fdd->write_q = q->next;	    if (q->free_func)		(q->free_func) (q->buf);	    safe_free(q);	}    }    if (fdd->write_q == NULL) {	/* no more data */	fdd->write_q_tail = NULL;	F->flags.write_daemon = 0;    } else {	/* another block is queued */	diskCombineWrites(fdd);	cbdataLock(fdd->wrt_handle_data);	commSetSelect(fd, COMM_SELECT_WRITE, diskHandleWrite, NULL, 0);	F->flags.write_daemon = 1;    }    do_close = F->flags.close_request;    if (fdd->wrt_handle) {	if (fdd->wrt_handle_data == NULL)	    do_callback = 1;	else if (cbdataValid(fdd->wrt_handle_data))	    do_callback = 1;	else	    do_callback = 0;	if (fdd->wrt_handle_data != NULL)	    cbdataUnlock(fdd->wrt_handle_data);	if (do_callback) {#ifdef OPTIMISTIC_IO	    F->flags.calling_io_handler = 1;#endif	    fdd->wrt_handle(fd, status, len, fdd->wrt_handle_data);	    /*	     * NOTE, this callback can close the FD, so we must	     * not touch 'F', 'fdd', etc. after this.	     */#ifdef OPTIMISTIC_IO	    F->flags.calling_io_handler = 0;#endif	    return;	}    }    if (do_close)	file_close(fd);}/* write block to a file *//* write back queue. Only one writer at a time. *//* call a handle when writing is complete. */voidfile_write(int fd,    off_t file_offset,    void *ptr_to_buf,    int len,    DWCB handle,    void *handle_data,    FREE * free_func){    dwrite_q *wq = NULL;    fde *F = &fd_table[fd];    assert(fd >= 0);    assert(F->flags.open);    /* if we got here. Caller is eligible to write. */    wq = xcalloc(1, sizeof(dwrite_q));    wq->file_offset = file_offset;    wq->buf = ptr_to_buf;    wq->len = len;    wq->buf_offset = 0;    wq->next = NULL;    wq->free_func = free_func;    F->disk.wrt_handle = handle;    F->disk.wrt_handle_data = handle_data;    /* add to queue */    if (F->disk.write_q == NULL) {	/* empty queue */	F->disk.write_q = F->disk.write_q_tail = wq;    } else {	F->disk.write_q_tail->next = wq;	F->disk.write_q_tail = wq;    }    if (!F->flags.write_daemon) {	cbdataLock(F->disk.wrt_handle_data);#if USE_ASYNC_IO	diskHandleWrite(fd, NULL);#else#ifdef OPTIMISTIC_IO	if (F->flags.calling_io_handler)#endif	    commSetSelect(fd, COMM_SELECT_WRITE, diskHandleWrite, NULL, 0);#ifdef OPTIMISTIC_IO	else	    diskHandleWrite(fd, NULL);#endif#endif#ifndef OPTIMISTIC_IO	F->flags.write_daemon = 1;#endif    }}/* * a wrapper around file_write to allow for MemBuf to be file_written * in a snap */voidfile_write_mbuf(int fd, off_t off, MemBuf mb, DWCB * handler, void *handler_data){    file_write(fd, off, mb.buf, mb.size, handler, handler_data, memBufFreeFunc(&mb));}/* Read from FD */static voiddiskHandleRead(int fd, void *data){    dread_ctrl *ctrl_dat = data;#if !USE_ASYNC_IO    fde *F = &fd_table[fd];    int len;#endif#ifdef OPTIMISTIC_IO    assert(!F->flags.calling_io_handler);#endif /* OPTIMISTIC_IO */    /*     * FD < 0 indicates premature close; we just have to free     * the state data.     */    if (fd < 0) {	memFree(ctrl_dat, MEM_DREAD_CTRL);	return;    }#if USE_ASYNC_IO    aioRead(fd,	ctrl_dat->offset,	ctrl_dat->buf,	ctrl_dat->req_len,	diskHandleReadComplete,	ctrl_dat);#else    if (F->disk.offset != ctrl_dat->offset) {	debug(6, 3) ("diskHandleRead: FD %d seeking to offset %d\n",	    fd, (int) ctrl_dat->offset);	lseek(fd, ctrl_dat->offset, SEEK_SET);	/* XXX ignore return? */	Counter.syscalls.disk.seeks++;	F->disk.offset = ctrl_dat->offset;    }    errno = 0;    len = read(fd, ctrl_dat->buf, ctrl_dat->req_len);    if (len > 0)	F->disk.offset += len;    diskHandleReadComplete(fd, ctrl_dat, len, errno);#endif}static voiddiskHandleReadComplete(int fd, void *data, int len, int errcode){    dread_ctrl *ctrl_dat = data;    int rc = DISK_OK;#ifdef OPTIMISTIC_IO    fde *F = &fd_table[fd];#endif /* OPTIMISTIC_IO */    Counter.syscalls.disk.reads++;    errno = errcode;    if (len == -2 && errcode == -2) {	/* Read cancelled - cleanup */	cbdataUnlock(ctrl_dat->client_data);	memFree(ctrl_dat, MEM_DREAD_CTRL);	return;    }    fd_bytes(fd, len, FD_READ);    if (len < 0) {	if (ignoreErrno(errno)) {	    commSetSelect(fd, COMM_SELECT_READ, diskHandleRead, ctrl_dat, 0);	    return;	}	debug(50, 1) ("diskHandleRead: FD %d: %s\n", fd, xstrerror());	len = 0;	rc = DISK_ERROR;    } else if (len == 0) {	rc = DISK_EOF;    }#ifdef OPTIMISTIC_IO    F->flags.calling_io_handler = 1;#endif /* OPTIMISTIC_IO */    if (cbdataValid(ctrl_dat->client_data))	ctrl_dat->handler(fd, ctrl_dat->buf, len, rc, ctrl_dat->client_data);#ifdef OPTIMISTIC_IO    F->flags.calling_io_handler = 0;#endif /* OPTIMISTIC_IO */    cbdataUnlock(ctrl_dat->client_data);    memFree(ctrl_dat, MEM_DREAD_CTRL);}/* start read operation *//* buffer must be allocated from the caller.  * It must have at least req_len space in there.  * call handler when a reading is complete. */intfile_read(int fd, char *buf, int req_len, off_t offset, DRCB * handler, void *client_data){    dread_ctrl *ctrl_dat;#ifdef OPTIMISTIC_IO    fde *F = &fd_table[fd];#endif /* OPTIMISTIC_IO */    assert(fd >= 0);    ctrl_dat = memAllocate(MEM_DREAD_CTRL);    ctrl_dat->fd = fd;    ctrl_dat->offset = offset;    ctrl_dat->req_len = req_len;    ctrl_dat->buf = buf;    ctrl_dat->end_of_file = 0;    ctrl_dat->handler = handler;    ctrl_dat->client_data = client_data;    cbdataLock(client_data);#if USE_ASYNC_IO    diskHandleRead(fd, ctrl_dat);#else#ifndef OPTIMISTIC_IO    commSetSelect(fd,	COMM_SELECT_READ,	diskHandleRead,	ctrl_dat,	0);#else    if (F->flags.calling_io_handler)	commSetSelect(fd, COMM_SELECT_READ, diskHandleRead, ctrl_dat, 0);    else	diskHandleRead(fd, ctrl_dat);#endif /* OPTIMISTIC_IO */#endif    return DISK_OK;}intdiskWriteIsComplete(int fd){    return fd_table[fd].disk.write_q ? 0 : 1;}

⌨️ 快捷键说明

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