FreeBSD Bugzilla – Attachment 17914 Details for
Bug 32389
add ufs write support to /boot/loader and associated changes
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
file.diff
file.diff (text/plain), 21.63 KB, created by
haikugeek
on 2001-11-30 06:30:00 UTC
(
hide
)
Description:
file.diff
Filename:
MIME Type:
Creator:
haikugeek
Created:
2001-11-30 06:30:00 UTC
Size:
21.63 KB
patch
obsolete
>Index: sys/boot/common/bcache.c >=================================================================== >RCS file: /usr/FreeBSD/src/sys/boot/common/bcache.c,v >retrieving revision 1.8 >diff -c -r1.8 bcache.c >*** sys/boot/common/bcache.c 2000/08/03 09:13:53 1.8 >--- sys/boot/common/bcache.c 2001/11/22 00:26:58 >*************** >*** 63,68 **** >--- 63,69 ---- > static u_int bcache_flushes; > static u_int bcache_bcount; > >+ static void bcache_invalidate(daddr_t blkno); > static void bcache_insert(caddr_t buf, daddr_t blkno); > static int bcache_lookup(caddr_t buf, daddr_t blkno); > >*************** >*** 116,131 **** > } > } > >! /* >! * Handle a transfer request; fill in parts of the request that can > * be satisfied by the cache, use the supplied strategy routine to do > * device I/O and then use the I/O results to populate the cache. >- * >- * Requests larger than 1/2 the cache size will be bypassed and go >- * directly to the disk. XXX tune this. > */ >! int >! bcache_strategy(void *devdata, int unit, int rw, daddr_t blk, size_t size, > char *buf, size_t *rsize) > { > static int bcache_unit = -1; >--- 117,161 ---- > } > } > >! /* >! * Handle a write request; write directly to the disk, and populate the >! * cache with the new values. >! */ >! static int >! write_strategy(void *devdata, int unit, int rw, daddr_t blk, size_t size, >! char *buf, size_t *rsize) >! { >! struct bcache_devdata *dd = (struct bcache_devdata *)devdata; >! daddr_t i, nblk; >! int err; >! >! nblk = size / bcache_blksize; >! >! /* Invalidate the blocks being written */ >! for (i = 0; i < nblk; i++) { >! bcache_invalidate(blk + i); >! } >! >! /* Write the blocks */ >! err = dd->dv_strategy(dd->dv_devdata, rw, blk, size, buf, rsize); >! >! /* Populate the block cache with the new data */ >! if (err == 0) { >! for (i = 0; i < nblk; i++) { >! bcache_insert(buf + (i * bcache_blksize),blk + i); >! } >! } >! >! return err; >! } >! >! /* >! * Handle a read request; fill in parts of the request that can > * be satisfied by the cache, use the supplied strategy routine to do > * device I/O and then use the I/O results to populate the cache. > */ >! static int >! read_strategy(void *devdata, int unit, int rw, daddr_t blk, size_t size, > char *buf, size_t *rsize) > { > static int bcache_unit = -1; >*************** >*** 134,153 **** > daddr_t p_blk, i, j, nblk; > caddr_t p_buf; > >- bcache_ops++; >- >- if(bcache_unit != unit) { >- bcache_flush(); >- bcache_unit = unit; >- } >- >- /* bypass large requests, or when the cache is inactive */ >- if ((bcache_data == NULL) || ((size * 2 / bcache_blksize) > bcache_nblks)) { >- DEBUG("bypass %d from %d", size / bcache_blksize, blk); >- bcache_bypasses++; >- return(dd->dv_strategy(dd->dv_devdata, rw, blk, size, buf, rsize)); >- } >- > nblk = size / bcache_blksize; > result = 0; > >--- 164,169 ---- >*************** >*** 201,207 **** >--- 217,260 ---- > return(result); > } > >+ /* >+ * Requests larger than 1/2 the cache size will be bypassed and go >+ * directly to the disk. XXX tune this. >+ */ >+ int >+ bcache_strategy(void *devdata, int unit, int rw, daddr_t blk, size_t size, >+ char *buf, size_t *rsize) >+ { >+ static int bcache_unit = -1; >+ struct bcache_devdata *dd = (struct bcache_devdata *)devdata; >+ int p_size, result; >+ daddr_t p_blk, i, j, nblk; >+ caddr_t p_buf; > >+ bcache_ops++; >+ >+ if(bcache_unit != unit) { >+ bcache_flush(); >+ bcache_unit = unit; >+ } >+ >+ /* bypass large requests, or when the cache is inactive */ >+ if ((bcache_data == NULL) || ((size * 2 / bcache_blksize) > bcache_nblks)) { >+ DEBUG("bypass %d from %d", size / bcache_blksize, blk); >+ bcache_bypasses++; >+ return(dd->dv_strategy(dd->dv_devdata, rw, blk, size, buf, rsize)); >+ } >+ >+ switch (rw) { >+ case F_READ: >+ return read_strategy(devdata, unit, rw, blk, size, buf, rsize); >+ case F_WRITE: >+ return write_strategy(devdata, unit, rw, blk, size, buf, rsize); >+ } >+ return -1; >+ } >+ >+ > /* > * Insert a block into the cache. Retire the oldest block to do so, if required. > * >*************** >*** 259,264 **** >--- 312,335 ---- > return(0); > } > return(ENOENT); >+ } >+ >+ /* >+ * Invalidate a block from the cache. >+ */ >+ static void >+ bcache_invalidate(daddr_t blkno) >+ { >+ u_int i; >+ >+ for (i = 0; i < bcache_nblks; i++) { >+ if (bcache_ctl[i].bc_blkno == blkno) { >+ bcache_ctl[i].bc_count = -1; >+ bcache_ctl[i].bc_blkno = -1; >+ DEBUG("invalidate blk %d", blkno); >+ break; >+ } >+ } > } > > COMMAND_SET(bcachestat, "bcachestat", "get disk block cache stats", command_bcache); >Index: sys/boot/ficl/loader.c >=================================================================== >RCS file: /usr/FreeBSD/src/sys/boot/ficl/loader.c,v >retrieving revision 1.5 >diff -c -r1.5 loader.c >*** sys/boot/ficl/loader.c 2001/09/04 08:51:15 1.5 >--- sys/boot/ficl/loader.c 2001/11/16 06:31:45 >*************** >*** 371,392 **** > > /* fopen - open a file and return new fd on stack. > * >! * fopen ( count ptr -- fd ) > */ > static void pfopen(FICL_VM *pVM) > { >! int fd; >! char *p; > > #if FICL_ROBUST > 1 >! vmCheckStack(pVM, 2, 1); > #endif >! (void)stackPopINT(pVM->pStack); /* don't need count value */ >! p = stackPopPtr(pVM->pStack); >! fd = open(p, O_RDONLY); > stackPushINT(pVM->pStack, fd); > return; >! } > > /* fclose - close a file who's fd is on stack. > * >--- 371,407 ---- > > /* fopen - open a file and return new fd on stack. > * >! * fopen ( ptr count mode -- fd ) > */ > static void pfopen(FICL_VM *pVM) > { >! int mode, fd, count; >! char *ptr, *name; > > #if FICL_ROBUST > 1 >! vmCheckStack(pVM, 3, 1); > #endif >! >! mode = stackPopINT(pVM->pStack); /* get mode */ >! count = stackPopINT(pVM->pStack); /* get count */ >! ptr = stackPopPtr(pVM->pStack); /* get ptr */ >! >! if ((count < 0) || (ptr == NULL)) { >! stackPushINT(pVM->pStack, -1); >! return; >! } >! >! /* ensure that the string is null terminated */ >! name = (char *)malloc(count+1); >! bcopy(ptr,name,count); >! name[count] = 0; >! >! /* open the file */ >! fd = open(name, mode); >! free(name); > stackPushINT(pVM->pStack, fd); > return; >! } > > /* fclose - close a file who's fd is on stack. > * >*************** >*** 444,449 **** >--- 459,504 ---- > return; > } > >+ /* fwrite - write file contents >+ * >+ * fwrite ( fd buf nbytes -- nwritten ) >+ */ >+ static void pfwrite(FICL_VM *pVM) >+ { >+ int fd, len; >+ char *buf; >+ >+ #if FICL_ROBUST > 1 >+ vmCheckStack(pVM, 3, 1); >+ #endif >+ len = stackPopINT(pVM->pStack); /* get number of bytes to read */ >+ buf = stackPopPtr(pVM->pStack); /* get buffer */ >+ fd = stackPopINT(pVM->pStack); /* get fd */ >+ if (len > 0 && buf && fd != -1) >+ stackPushINT(pVM->pStack, write(fd, buf, len)); >+ else >+ stackPushINT(pVM->pStack, -1); >+ return; >+ } >+ >+ /* fseek - seek to a new position in a file >+ * >+ * fseek ( fd ofs whence -- pos ) >+ */ >+ static void pfseek(FICL_VM *pVM) >+ { >+ int fd, pos, whence; >+ >+ #if FICL_ROBUST > 1 >+ vmCheckStack(pVM, 3, 1); >+ #endif >+ whence = stackPopINT(pVM->pStack); >+ pos = stackPopINT(pVM->pStack); >+ fd = stackPopINT(pVM->pStack); >+ stackPushINT(pVM->pStack, lseek(fd, pos, whence)); >+ return; >+ } >+ > /* key - get a character from stdin > * > * key ( -- char ) >*************** >*** 568,573 **** >--- 623,630 ---- > dictAppendWord(dp, "fread", pfread, FW_DEFAULT); > dictAppendWord(dp, "fload", pfload, FW_DEFAULT); > dictAppendWord(dp, "fkey", fkey, FW_DEFAULT); >+ dictAppendWord(dp, "fseek", pfseek, FW_DEFAULT); >+ dictAppendWord(dp, "fwrite", pfwrite, FW_DEFAULT); > dictAppendWord(dp, "key", key, FW_DEFAULT); > dictAppendWord(dp, "key?", keyQuestion, FW_DEFAULT); > dictAppendWord(dp, "ms", ms, FW_DEFAULT); >Index: sys/boot/forth/pnp.4th >=================================================================== >RCS file: /usr/FreeBSD/src/sys/boot/forth/pnp.4th,v >retrieving revision 1.1 >diff -c -r1.1 pnp.4th >*** sys/boot/forth/pnp.4th 2000/09/08 17:13:24 1.1 >--- sys/boot/forth/pnp.4th 2001/11/15 20:26:57 >*************** >*** 158,164 **** > : load-pnp > 0 to end_of_file? > reset_line_reading >! s" /boot/pnpid.conf" fopen fd ! > fd @ -1 <> if > begin > end_of_file? 0= >--- 158,164 ---- > : load-pnp > 0 to end_of_file? > reset_line_reading >! s" /boot/pnpid.conf" O_RDONLY fopen fd ! > fd @ -1 <> if > begin > end_of_file? 0= >Index: sys/boot/forth/support.4th >=================================================================== >RCS file: /usr/FreeBSD/src/sys/boot/forth/support.4th,v >retrieving revision 1.13 >diff -c -r1.13 support.4th >*** sys/boot/forth/support.4th 2000/09/25 11:36:55 1.13 >--- sys/boot/forth/support.4th 2001/11/15 20:43:41 >*************** >*** 80,85 **** >--- 80,95 ---- > 8 constant before_load_error > 9 constant after_load_error > >+ \ I/O constants >+ >+ 0 constant SEEK_SET >+ 1 constant SEEK_CUR >+ 2 constant SEEK_END >+ >+ 0 constant O_RDONLY >+ 1 constant O_WRONLY >+ 2 constant O_RDWR >+ > \ Crude structure support > > : structure: >*************** >*** 931,952 **** > > only forth also support-functions definitions > >- : create_null_terminated_string { addr len -- addr' len } >- len char+ allocate if out_of_memory throw then >- >r >- addr r@ len move >- 0 r@ len + c! >- r> len >- ; >- > \ Interface to loading conf files > > : load_conf ( addr len -- ) > 0 to end_of_file? > reset_line_reading >- create_null_terminated_string > over >r >! fopen fd ! > r> free-memory > fd @ -1 = if open_error throw then > ['] process_conf catch >--- 941,954 ---- > > only forth also support-functions definitions > > \ Interface to loading conf files > > : load_conf ( addr len -- ) >+ ." load_conf" cr > 0 to end_of_file? > reset_line_reading > over >r >! O_RDONLY fopen fd ! > r> free-memory > fd @ -1 = if open_error throw then > ['] process_conf catch >Index: sys/boot/i386/libi386/biosdisk.c >=================================================================== >RCS file: /usr/FreeBSD/src/sys/boot/i386/libi386/biosdisk.c,v >retrieving revision 1.33 >diff -c -r1.33 biosdisk.c >*** sys/boot/i386/libi386/biosdisk.c 2000/11/02 23:28:12 1.33 >--- sys/boot/i386/libi386/biosdisk.c 2001/11/22 00:33:45 >*************** >*** 100,105 **** >--- 100,107 ---- > static int bd_getgeom(struct open_disk *od); > static int bd_read(struct open_disk *od, daddr_t dblk, int blks, > caddr_t dest); >+ static int bd_write(struct open_disk *od, daddr_t dblk, int blks, >+ caddr_t dest); > > static int bd_int13probe(struct bdinfo *bd); > >*************** >*** 779,788 **** > > DEBUG("open_disk %p", od); > >- if (rw != F_READ) >- return(EROFS); > >! > blks = size / BIOSDISK_SECSIZE; > DEBUG("read %d from %d to %p", blks, dblk, buf); > >--- 781,789 ---- > > DEBUG("open_disk %p", od); > > >! switch(rw){ >! case F_READ: > blks = size / BIOSDISK_SECSIZE; > DEBUG("read %d from %d to %p", blks, dblk, buf); > >*************** >*** 804,809 **** >--- 805,837 ---- > if (rsize) > *rsize = size; > return (0); >+ break; >+ >+ case F_WRITE : >+ blks = size / BIOSDISK_SECSIZE; >+ DEBUG("write %d from %d to %p", blks, dblk, buf); >+ >+ if (rsize) >+ *rsize = 0; >+ if (blks && bd_write(od, dblk, blks, buf)) { >+ DEBUG("write error"); >+ return (EIO); >+ } >+ #ifdef BD_SUPPORT_FRAGS >+ if(fragsize) { >+ DEBUG("Attempted to write a frag"); >+ return (EIO); >+ } >+ #endif >+ >+ if (rsize) >+ *rsize = size; >+ return (0); >+ default: >+ /* DO NOTHING */ >+ } >+ >+ return EROFS; > } > > /* Max number of sectors to bounce-buffer if the request crosses a 64k boundary */ >*************** >*** 940,945 **** >--- 968,1111 ---- > return(0); > } > >+ >+ static int >+ bd_write(struct open_disk *od, daddr_t dblk, int blks, caddr_t dest) >+ { >+ u_int x, bpc, cyl, hd, sec, result, resid, retry, maxfer; >+ caddr_t p, xp, bbuf, breg; >+ >+ /* Just in case some idiot actually tries to read -1 blocks... */ >+ if (blks < 0) >+ return (-1); >+ >+ bpc = (od->od_sec * od->od_hds); /* blocks per cylinder */ >+ resid = blks; >+ p = dest; >+ >+ /* Decide whether we have to bounce */ >+ if ((od->od_unit < 0x80) && >+ ((VTOP(dest) >> 16) != (VTOP(dest + blks * BIOSDISK_SECSIZE) >> 16))) { >+ >+ /* >+ * There is a 64k physical boundary somewhere in the destination buffer, so we have >+ * to arrange a suitable bounce buffer. Allocate a buffer twice as large as we >+ * need to. Use the bottom half unless there is a break there, in which case we >+ * use the top half. >+ */ >+ >+ x = min(FLOPPY_BOUNCEBUF, (unsigned)blks); >+ bbuf = malloc(x * 2 * BIOSDISK_SECSIZE); >+ if (((u_int32_t)VTOP(bbuf) & 0xffff0000) == ((u_int32_t)VTOP(dest + x * BIOSDISK_SECSIZE) & 0xffff0000)) { >+ breg = bbuf; >+ } else { >+ breg = bbuf + x * BIOSDISK_SECSIZE; >+ } >+ maxfer = x; /* limit transfers to bounce region size */ >+ } else { >+ breg = bbuf = NULL; >+ maxfer = 0; >+ } >+ >+ while (resid > 0) { >+ x = dblk; >+ cyl = x / bpc; /* block # / blocks per cylinder */ >+ x %= bpc; /* block offset into cylinder */ >+ hd = x / od->od_sec; /* offset / blocks per track */ >+ sec = x % od->od_sec; /* offset into track */ >+ >+ /* play it safe and don't cross track boundaries (XXX this is probably unnecessary) */ >+ x = min(od->od_sec - sec, resid); >+ if (maxfer > 0) >+ x = min(x, maxfer); /* fit bounce buffer */ >+ >+ /* where do we transfer to? */ >+ xp = bbuf == NULL ? p : breg; >+ >+ /* correct sector number for 1-based BIOS numbering */ >+ sec++; >+ >+ >+ /* Put your Data In, Put your Data out, >+ Put your Data In, and shake it all about >+ */ >+ if (bbuf != NULL) >+ bcopy(p, breg, x * BIOSDISK_SECSIZE); >+ p += (x * BIOSDISK_SECSIZE); >+ dblk += x; >+ resid -= x; >+ >+ /* Loop retrying the operation a couple of times. The BIOS may also retry. */ >+ for (retry = 0; retry < 3; retry++) { >+ /* if retrying, reset the drive */ >+ if (retry > 0) { >+ v86.ctl = V86_FLAGS; >+ v86.addr = 0x13; >+ v86.eax = 0; >+ v86.edx = od->od_unit; >+ v86int(); >+ } >+ >+ if(cyl > 1023) { >+ /* use EDD if the disk supports it, otherwise, return error */ >+ if(od->od_flags & BD_MODEEDD1) { >+ static unsigned short packet[8]; >+ >+ packet[0] = 0x10; >+ packet[1] = x; >+ packet[2] = VTOPOFF(xp); >+ packet[3] = VTOPSEG(xp); >+ packet[4] = dblk & 0xffff; >+ packet[5] = dblk >> 16; >+ packet[6] = 0; >+ packet[7] = 0; >+ v86.ctl = V86_FLAGS; >+ v86.addr = 0x13; >+ /* Should we Write with verify ?? 0x4302 ? */ >+ v86.eax = 0x4300; >+ v86.edx = od->od_unit; >+ v86.ds = VTOPSEG(packet); >+ v86.esi = VTOPOFF(packet); >+ v86int(); >+ result = (v86.efl & 0x1); >+ if(result == 0) >+ break; >+ } else { >+ result = 1; >+ break; >+ } >+ } else { >+ /* Use normal CHS addressing */ >+ v86.ctl = V86_FLAGS; >+ v86.addr = 0x13; >+ v86.eax = 0x300 | x; >+ v86.ecx = ((cyl & 0xff) << 8) | ((cyl & 0x300) >> 2) | sec; >+ v86.edx = (hd << 8) | od->od_unit; >+ v86.es = VTOPSEG(xp); >+ v86.ebx = VTOPOFF(xp); >+ v86int(); >+ result = (v86.efl & 0x1); >+ if (result == 0) >+ break; >+ } >+ } >+ >+ DEBUG("%d sectors from %d/%d/%d to %p (0x%x) %s", x, cyl, hd, sec - 1, p, VTOP(p), result ? "failed" : "ok"); >+ /* BUG here, cannot use v86 in printf because putchar uses it too */ >+ DEBUG("ax = 0x%04x cx = 0x%04x dx = 0x%04x status 0x%x", >+ 0x200 | x, ((cyl & 0xff) << 8) | ((cyl & 0x300) >> 2) | sec, (hd << 8) | od->od_unit, (v86.eax >> 8) & 0xff); >+ if (result) { >+ if (bbuf != NULL) >+ free(bbuf); >+ return(-1); >+ } >+ } >+ >+ /* hexdump(dest, (blks * BIOSDISK_SECSIZE)); */ >+ if (bbuf != NULL) >+ free(bbuf); >+ return(0); >+ } > static int > bd_getgeom(struct open_disk *od) > { >Index: lib/libstand/stand.h >=================================================================== >RCS file: /usr/FreeBSD/src/lib/libstand/stand.h,v >retrieving revision 1.26 >diff -c -r1.26 stand.h >*** lib/libstand/stand.h 2001/09/18 13:01:12 1.26 >--- lib/libstand/stand.h 2001/11/16 01:43:52 >*************** >*** 256,262 **** > > extern int open(const char *, int); > #define O_RDONLY 0x0 >! #define O_WRONLY 0x1 /* writing not (yet?) supported */ > #define O_RDWR 0x2 > extern int close(int); > extern void closeall(void); >--- 257,263 ---- > > extern int open(const char *, int); > #define O_RDONLY 0x0 >! #define O_WRONLY 0x1 > #define O_RDWR 0x2 > extern int close(int); > extern void closeall(void); >Index: lib/libstand/ufs.c >=================================================================== >RCS file: /usr/FreeBSD/src/lib/libstand/ufs.c,v >retrieving revision 1.7 >diff -c -r1.7 ufs.c >*** lib/libstand/ufs.c 2001/09/30 22:28:01 1.7 >--- lib/libstand/ufs.c 2001/11/16 01:43:52 >*************** >*** 82,87 **** >--- 82,88 ---- > #endif > > static int ufs_open(const char *path, struct open_file *f); >+ static int ufs_write(struct open_file *f, void *buf, size_t size, size_t *resid); > static int ufs_close(struct open_file *f); > static int ufs_read(struct open_file *f, void *buf, size_t size, size_t *resid); > static off_t ufs_seek(struct open_file *f, off_t offset, int where); >*************** >*** 93,99 **** > ufs_open, > ufs_close, > ufs_read, >! null_write, > ufs_seek, > ufs_stat, > ufs_readdir >--- 94,100 ---- > ufs_open, > ufs_close, > ufs_read, >! ufs_write, > ufs_seek, > ufs_stat, > ufs_readdir >*************** >*** 122,127 **** >--- 123,129 ---- > static int read_inode(ino_t, struct open_file *); > static int block_map(struct open_file *, daddr_t, daddr_t *); > static int buf_read_file(struct open_file *, char **, size_t *); >+ static int buf_write_file(struct open_file *, char *, size_t *); > static int search_directory(char *, struct open_file *, ino_t *); > #ifdef COMPAT_UFS > static void ffs_oldfscompat(struct fs *); >*************** >*** 288,293 **** >--- 290,371 ---- > } > > /* >+ * Write a portion of a file from an internal buffer. >+ */ >+ static int >+ buf_write_file(f, buf_p, size_p) >+ struct open_file *f; >+ char *buf_p; >+ size_t *size_p; /* out */ >+ { >+ register struct file *fp = (struct file *)f->f_fsdata; >+ register struct fs *fs = fp->f_fs; >+ long off; >+ register daddr_t file_block; >+ daddr_t disk_block; >+ size_t block_size; >+ int rc; >+ >+ /* >+ * Calculate the starting block address and offset. >+ */ >+ off = blkoff(fs, fp->f_seekp); >+ file_block = lblkno(fs, fp->f_seekp); >+ block_size = dblksize(fs, &fp->f_di, file_block); >+ >+ rc = block_map(f, file_block, &disk_block); >+ if (rc) >+ return (rc); >+ >+ if (disk_block == 0) >+ return (EFBIG); /* Because we can't allocate space on the drive */ >+ >+ /* >+ * Truncate buffer at end of file, and at the end of >+ * this block. >+ */ >+ if (*size_p > fp->f_di.di_size - fp->f_seekp) >+ *size_p = fp->f_di.di_size - fp->f_seekp; >+ if (*size_p > block_size - off) >+ *size_p = block_size - off; >+ >+ /* >+ * If we don't entirely occlude the block and it's not >+ * in memory already, read it in first. >+ */ >+ if (((off > 0) || (*size_p + off < block_size)) && >+ (file_block != fp->f_buf_blkno)) { >+ >+ if (fp->f_buf == (char *)0) >+ fp->f_buf = malloc(fs->fs_bsize); >+ >+ twiddle(); >+ rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, >+ fsbtodb(fs, disk_block), >+ block_size, fp->f_buf, &fp->f_buf_size); >+ if (rc) >+ return (rc); >+ >+ fp->f_buf_blkno = file_block; >+ } >+ >+ /* >+ * Copy the user data into the cached block. >+ */ >+ bcopy(buf_p,fp->f_buf + off,*size_p); >+ >+ /* >+ * Write the block out to storage. >+ */ >+ >+ twiddle(); >+ rc = (f->f_dev->dv_strategy)(f->f_devdata, F_WRITE, >+ fsbtodb(fs, disk_block), >+ block_size, fp->f_buf, &fp->f_buf_size); >+ return (rc); >+ } >+ >+ /* > * Read a portion of a file into an internal buffer. Return > * the location in the buffer and the amount in the buffer. > */ >*************** >*** 310,322 **** > block_size = dblksize(fs, &fp->f_di, file_block); > > if (file_block != fp->f_buf_blkno) { > rc = block_map(f, file_block, &disk_block); > if (rc) > return (rc); > >- if (fp->f_buf == (char *)0) >- fp->f_buf = malloc(fs->fs_bsize); >- > if (disk_block == 0) { > bzero(fp->f_buf, block_size); > fp->f_buf_size = block_size; >--- 388,400 ---- > block_size = dblksize(fs, &fp->f_di, file_block); > > if (file_block != fp->f_buf_blkno) { >+ if (fp->f_buf == (char *)0) >+ fp->f_buf = malloc(fs->fs_bsize); >+ > rc = block_map(f, file_block, &disk_block); > if (rc) > return (rc); > > if (disk_block == 0) { > bzero(fp->f_buf, block_size); > fp->f_buf_size = block_size; >*************** >*** 648,653 **** >--- 726,768 ---- > csize = buf_size; > > bcopy(buf, addr, csize); >+ >+ fp->f_seekp += csize; >+ addr += csize; >+ size -= csize; >+ } >+ if (resid) >+ *resid = size; >+ return (rc); >+ } >+ >+ /* >+ * Write to a portion of an already allocated file. >+ * Cross block boundaries when necessary. Can not >+ * extend the file. >+ */ >+ static int >+ ufs_write(f, start, size, resid) >+ struct open_file *f; >+ void *start; >+ size_t size; >+ size_t *resid; /* out */ >+ { >+ register struct file *fp = (struct file *)f->f_fsdata; >+ size_t csize; >+ int rc = 0; >+ register char *addr = start; >+ >+ csize = size; >+ while ((size != 0) && (csize != 0)) { >+ if (fp->f_seekp >= fp->f_di.di_size) >+ break; >+ >+ if (csize >= 512) csize = 512; /* XXX */ >+ >+ rc = buf_write_file(f, addr, &csize); >+ if (rc) >+ break; > > fp->f_seekp += csize; > addr += csize;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 32389
: 17914