1: /*
   2:  * Do full cylinder buffered writes to slow devices.  Uses a simple
   3:  * buffered read/delayed write algorithm
   4:  */
   5: 
   6: #include <stdio.h>
   7: #include "msdos.h"
   8: 
   9: extern int fd, disk_size, disk_dirty, dir_start, dir_len;
  10: extern int clus_size;
  11: extern long disk_offset, disk_current;
  12: extern unsigned char *disk_buf;
  13: static int blank_cyl();
  14: 
  15: void
  16: disk_write(start, buf, len)
  17: long start;
  18: unsigned char *buf;
  19: int len;
  20: {
  21:     register long i;
  22:     int length;
  23:     unsigned char *buf_ptr, *disk_ptr;
  24:     char *memcpy();
  25:     void perror(), exit(), disk_flush();
  26:     long where, tail, lseek();
  27: 
  28:                     /* don't use cache? */
  29:     if (disk_size == 1) {
  30:         where = (start * MSECTOR_SIZE) + disk_offset;
  31:         if (lseek(fd, where, 0) < 0) {
  32:             perror("disk_write: lseek");
  33:             exit(1);
  34:         }
  35:                     /* write it! */
  36:         if (write(fd, (char *) buf, (unsigned int) len) != len) {
  37:             perror("disk_write: write");
  38:             exit(1);
  39:         }
  40:         return;
  41:     }
  42: 
  43:     tail = start + (len / MSECTOR_SIZE) - 1;
  44:     for (i = start; i <= tail; i++) {
  45:                     /* a cache miss... */
  46:         if (i < disk_current || i >= disk_current + disk_size) {
  47: 
  48:             if (disk_dirty)
  49:                 disk_flush();
  50: 
  51:             /*
  52: 			 * If there is something on the new cylinder that
  53: 			 * you want to keep, you'll have to read it first
  54: 			 * before writing.
  55: 			 */
  56:             if (blank_cyl(i))
  57:                 disk_current = (i / disk_size) * disk_size;
  58:             else {
  59:                 disk_current = (i / disk_size) * disk_size;
  60:                 where = (disk_current * MSECTOR_SIZE) + disk_offset;
  61:                 length = disk_size * MSECTOR_SIZE;
  62: 
  63:                     /* move to next location */
  64:                 if (lseek(fd, where, 0) < 0) {
  65:                     perror("disk_write: lseek");
  66:                     exit(1);
  67:                 }
  68:                     /* read it! */
  69:                 if (read(fd, (char *) disk_buf, (unsigned int) length) != length) {
  70:                     perror("disk_write: read");
  71:                     exit(1);
  72:                 }
  73:             }
  74:         }
  75:                     /* a cache hit ... */
  76:         buf_ptr = buf + ((i - start) * MSECTOR_SIZE);
  77:         disk_ptr = disk_buf + ((i - disk_current) * MSECTOR_SIZE);
  78:         memcpy((char *) disk_ptr, (char *) buf_ptr, MSECTOR_SIZE);
  79:         disk_dirty = 1;
  80:     }
  81:     return;
  82: }
  83: 
  84: /*
  85:  * Flush a dirty buffer to disk.  Resets disk_dirty to zero.
  86:  * All errors are fatal.
  87:  */
  88: 
  89: void
  90: disk_flush()
  91: {
  92:     int len;
  93:     long where, lseek();
  94:     void perror(), exit();
  95: 
  96:     if (fd < 0 || disk_current < 0L || !disk_dirty)
  97:         return;
  98: 
  99:     where = (disk_current * MSECTOR_SIZE) + disk_offset;
 100:     if (lseek(fd, where, 0) < 0) {
 101:         perror("disk_flush: lseek");
 102:         exit(1);
 103:     }
 104:                     /* write it! */
 105:     len = disk_size * MSECTOR_SIZE;
 106:     if (write(fd, (char *) disk_buf, (unsigned int) len) != len) {
 107:         perror("disk_flush: write");
 108:         exit(1);
 109:     }
 110:     disk_dirty = 0;
 111:     return;
 112: }
 113: 
 114: /*
 115:  * Determine if the cylinder has some useful information on it.  Returns a 1
 116:  * if it is blank.
 117:  */
 118: 
 119: static int
 120: blank_cyl(num)
 121: long num;
 122: {
 123:     register unsigned int i;
 124:     unsigned int start, end, fat_decode();
 125:     long sector;
 126: 
 127:     sector = (num / disk_size) * disk_size;
 128:     if (!sector)
 129:         return(0);
 130: 
 131:     start = ((sector - dir_start - dir_len) / clus_size) + 2;
 132:     end = ((sector + disk_size - dir_start - dir_len) / clus_size) + 2;
 133: 
 134:     for (i = start; i < end; i++) {
 135:                     /* if fat_decode returns non-zero */
 136:         if (fat_decode(i))
 137:             return(0);
 138:     }
 139:     return(1);
 140: }

Defined functions

blank_cyl defined in line 119; used 2 times
disk_flush defined in line 89; used 2 times
disk_write defined in line 15; never used
Last modified: 1992-06-24
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2454
Valid CSS Valid XHTML 1.0 Strict