--------------------- PatchSet 1404 Date: 2001/01/27 10:19:23 Author: darius Branch: sfs Tag: (none) Log: Mostly work on read and write routines - making the code easier to read, streamlining some of the calculations, and making read correctly report the amounts it's read. A day's tinkering, basically. Members: src/fs/sfs/sfs_llo.c:1.1.2.6->1.1.2.7 Index: squid/src/fs/sfs/sfs_llo.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/fs/sfs/Attic/sfs_llo.c,v retrieving revision 1.1.2.6 retrieving revision 1.1.2.7 diff -u -r1.1.2.6 -r1.1.2.7 --- squid/src/fs/sfs/sfs_llo.c 26 Jan 2001 19:28:21 -0000 1.1.2.6 +++ squid/src/fs/sfs/sfs_llo.c 27 Jan 2001 10:19:23 -0000 1.1.2.7 @@ -76,15 +76,12 @@ mount_point->accepting_requests = 1; i = 0; while (1) { - printf("DEBUG: Going into wait... (%d pending)\n",mount_point->pending_requests); pthread_cond_wait(&(mount_point->req_signal), &(mount_point->req_signal_lock)); - printf("DEBUG: Coming out of wait... (%d pending)\n",mount_point->pending_requests); tnode = mount_point->request_queue.head; /* Should I lock the request queue while I cycle through these? * Probably wise, but slow... */ while ((mount_point->pending_requests > 0) && (tnode != NULL)) { - printf("DEBUG: %d pending requests left\n",mount_point->pending_requests); req = tnode->data; if (req->request_state == _SFS_PENDING) { /* If we're not accepting requests, return fail for each @@ -137,8 +134,8 @@ { sfs_blockbuf_t *new; sfs_openfile_t *openfd; - sfsblock_t diskpos; - int offset, retlen, fragsize; + int bytes_read, fragsize; + uint diskpos; void *buf; if (!(openfd = _sfs_find_fd(req->sfsfd))) { @@ -146,38 +143,53 @@ return; } - if (req->offset == -1) - offset = openfd->pos; - else - offset = req->offset; + if (req->offset > -1) + openfd->pos = req->offset; - retlen = 0; + bytes_read = 0; buf = NULL; - while (retlen < req->buflen) { - if (!(diskpos = _sfs_calculate_diskpos(req->sfsid, openfd, offset+retlen))) { - _sfs_done_request(req,retlen); + /* one block at a time */ + /* We _could_ alloc the space required for the entire file in one go, + * at least if the filesize was below a certain watermark - should be + * a significant speed boost if my understanding of realloc issues is + * correct... */ + while ((bytes_read < req->buflen) && (bytes_read < openfd->inode->len)) { + if (!(diskpos = _sfs_calculate_diskpos(openfd,openfd->pos))) { + req->buf = buf; + req->buflen = bytes_read; + _sfs_done_request(req,bytes_read); return; } - if (!(new = _sfs_read_block(req->sfsid, diskpos))) { + if (!(new = _sfs_read_block(openfd->sfsid,diskpos))) { req->buf = buf; - _sfs_done_request(req,retlen); + req->buflen = bytes_read; + _sfs_done_request(req,bytes_read); return; } /* In case of request only wanting a certain amount, work out how much * to copy into req->buf */ - fragsize = min(req->buflen - retlen,new->buflen); + fragsize = min(req->buflen - bytes_read, new->buflen); + fragsize = min(fragsize, openfd->inode->len); if (new->type == _SFS_INODE) - fragsize = min(fragsize,inode_data_size); - buf = (char *)xrealloc(buf, retlen + fragsize); + fragsize = min(fragsize, inode_data_size); + else { + if ((openfd->pos + bytes_read) == openfd->inode->len) { + fragsize = min(fragsize, (openfd->inode->len % FRAGSIZE)); + } + } + buf = (char *)xrealloc(buf, bytes_read + fragsize); if (new->type == _SFS_INODE) - memcpy(((char *)buf)+retlen, new->buf+sizeof(sfs_inode_t), fragsize); + memcpy(((char *)buf)+bytes_read, new->buf+sizeof(sfs_inode_t), fragsize); else - memcpy(((char *)buf)+retlen, new->buf, fragsize); - retlen += fragsize; + memcpy(((char *)buf)+bytes_read, new->buf, fragsize); + bytes_read += fragsize; openfd->pos += fragsize; + if (fragsize == 0) + abort(); } req->buf = buf; - _sfs_done_request(req,retlen); + req->buflen = bytes_read; + _sfs_done_request(req,bytes_read); } void @@ -185,7 +197,8 @@ { sfs_openfile_t *openfd; sfs_blockbuf_t *new, *current = NULL; - int offset, written, fragsize, inblock, maxfragsize; + int offset, written, fragsize, inblock; + int bytes_left, leader; sfsblock_t diskpos; void *buf; int type; @@ -198,10 +211,15 @@ if (req->offset == -1) offset = openfd->pos; else - offset = req->offset; + offset = openfd->pos = req->offset; /* written tracks how much we've written so far in total. */ + /* offset tells us where we start writing, minus the inode. */ + /* bytes_left gets set to the number of bytes left to write. */ + /* leader is the offset plus the inode - actual starting location. */ written = 0; + leader = offset + sizeof(sfs_inode_t); + bytes_left = req->buflen; buf = NULL; /* We write one block at a time - the process to find which block to write * to next is a little, um, involved at present. */ @@ -209,41 +227,44 @@ /* Work out type and where in the block this write should go. * If the total file is smaller than the inode block data size, then * we're best off storing it in an inode data block - fastest retrieval - * and all that. */ - if (offset + written < inode_data_size) { + * and all that. + * + * offset + written + sizeof(sfs_inode_t) = position in file (filepos) + * filepos % FRAGSIZE = remainder (thisblock) + * fragsize indicates the maximum amount of data to write in this + * block. */ + if (openfd->pos < inode_data_size) { type = _SFS_INODE; - inblock = offset + written + sizeof(sfs_inode_t); + inblock = leader; + fragsize = min(inode_data_size - openfd->pos,bytes_left); } else { type = _SFS_DATA; - inblock = ((offset + written) - sizeof(sfs_inode_t)) - ((((offset + written) - sizeof(sfs_inode_t)) / FRAGSIZE) * FRAGSIZE); + inblock = leader % FRAGSIZE; + fragsize = min(FRAGSIZE - inblock,bytes_left); } - /* maxfragsize indicates the maximum amount of data to write in this - * block. */ - maxfragsize = FRAGSIZE - inblock; current = NULL; /* Figure out where on disk it should be... */ - if (!(diskpos = _sfs_calculate_diskpos(req->sfsid, openfd, offset+written))) { + if (!(diskpos = _sfs_calculate_diskpos(openfd, openfd->pos))) { /* If we're not within the file, allocate a new block */ if (!(diskpos = _sfs_allocate_block(req->sfsid, type))) { _sfs_done_request(req,written); return; } - /* Magic number? What magic number? */ /* This sets the appropriate inode block pointer */ - if ((offset + written) < 261632) { - openfd->inode->dip[(offset + written - inode_data_size) / FRAGSIZE] = diskpos; - } else { - /* XXX indirect pointer - youch. This has not yet been - * implemented :( */ + if (type != _SFS_INODE) { + if (openfd->pos < direct_pointer_threshold) { + openfd->inode->dip[(openfd->pos - inode_data_size) / FRAGSIZE] = diskpos; + } else { + /* XXX indirect pointer - youch. This has not yet been + * implemented :( */ + } } } else { - printf("DEBUG: sfs_do_write Reading in old block\n"); - current = _sfs_read_block(req->sfsid,diskpos); + current = _sfs_read_block(openfd->sfsid,diskpos); } /* How much more to write? */ - fragsize = min(req->buflen - written,maxfragsize); if (current) { printf("DEBUG: current block found\n"); buf = current->buf; @@ -251,7 +272,6 @@ printf("DEBUG: sfs_do_write new buf created\n"); buf = (char *)xcalloc(1, FRAGSIZE); } - printf("DEBUG: buf = %p, inblock = %d, fragsize = %d, written = %d, buflen = %d\n",buf,inblock,fragsize,written,req->buflen); memcpy(((char *)buf)+inblock,((char *)req->buf)+written,fragsize); if (!current) { if (!(new = _sfs_write_block(req->sfsid, diskpos, buf, fragsize, type))) { @@ -264,7 +284,11 @@ } written += fragsize; openfd->pos += fragsize; + bytes_left -= fragsize; } + /* $DEITY forbid two people try to write at once - maybe I need some + * locking to prevent that... */ + openfd->inode->len = max(openfd->inode->len,openfd->pos); printf("DEBUG: written %d bytes to fd %d (%s)\n",req->buflen,req->sfsfd,current->buf+sizeof(sfs_inode_t)); _sfs_done_request(req,written); } @@ -284,7 +308,7 @@ openfd = _sfs_openfiles[req->sfsid]; while(openfd) { /* flush_file has to get rid of stuff then, which is bad :( - * The structures get kinda confused at this point */ + * The structures get kinda confused at this point */ printf("DEBUG: flushing file...\n"); _sfs_flush_file(req->sfsid,openfd); _sfs_openfiles[req->sfsid] = openfd->next; @@ -354,10 +378,11 @@ } fd->sfsid = req->sfsid; fd->sfsfd = _sfs_allocate_fd(fd); + fd->pos = 0; if (req->request_type == _SFS_OP_OPEN_READ) { fd->sfsinode = req->sfsinode; - fd->inodebuf_p = _sfs_read_block(req->sfsid, req->sfsinode); + fd->inodebuf_p = _sfs_read_block(fd->sfsid,fd->sfsinode); } else { /* Doesn't need to lock, as all allocation is within thread. */ if (!(fd->sfsinode = _sfs_allocate_block(req->sfsid, _SFS_INODE))) { @@ -375,11 +400,13 @@ fd->inodebuf_p->type = _SFS_INODE; fd->inodebuf_p->buf = (char *)xcalloc(1, FRAGSIZE); fd->inodebuf_p->diskpos = fd->inodebuf_p->sfsinode = fd->sfsinode; + fd->inodebuf_p->buflen = 0; _sfs_mounted[req->sfsid].clean = sfs_splay_insert(req->sfsid, fd->inodebuf_p, _sfs_mounted[req->sfsid].clean); } + /* Nasty cast */ fd->inode = (sfs_inode_t *)fd->inodebuf_p->buf; if (req->request_type != _SFS_OP_OPEN_READ) { - fd->inode->len = 1; + fd->inode->len = 0; fd->rwbuf_list_p = NULL; fd->sibuf_list_p = NULL; fd->dibuf_p = NULL;