From: Philip Homburg Date: Mon, 27 Nov 2006 14:21:43 +0000 (+0000) Subject: First cut at 64-bit file offsets in block devices for mkfs/fsck. X-Git-Tag: v3.1.3~137 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/soc.html?a=commitdiff_plain;h=bafc45a3099f1270b17df9260d5bd7b05540754b;p=minix.git First cut at 64-bit file offsets in block devices for mkfs/fsck. --- diff --git a/commands/simple/fsck.c b/commands/simple/fsck.c index c23bbc21e..5135de513 100755 --- a/commands/simple/fsck.c +++ b/commands/simple/fsck.c @@ -47,6 +47,7 @@ #include #include #include +#include #include "../../servers/mfs/const.h" #include "../../servers/mfs/inode.h" #include "../../servers/mfs/type.h" @@ -93,10 +94,10 @@ static struct super_block sb; #define STICKY_BIT 01000 /* not defined anywhere else */ /* Ztob gives the block address of a zone - * btoa gives the byte address of a block + * btoa64 gives the byte address of a block */ #define ztob(z) ((block_nr) (z) << sb.s_log_zone_size) -#define btoa(b) ((long) (b) * block_size) +#define btoa64(b) (mul64u(b, block_size)) #define SCALE ((int) ztob(1)) /* # blocks in a zone */ #define FIRST ((zone_nr) sb.s_firstdatazone) /* as the name says */ @@ -116,8 +117,8 @@ static struct super_block sb; #define NLEVEL (NR_ZONE_NUMS - NR_DZONE_NUM + 1) /* Byte address of a zone/of an inode */ -#define zaddr(z) btoa(ztob(z)) -#define cinoaddr(i) ((long) (i - 1) * INODE_SIZE + (long) btoa(BLK_ILIST)) +#define cinoblock(i) (((i - 1)*INODE_SIZE) / block_size + BLK_ILIST) +#define cinooff(i) (((i - 1)*INODE_SIZE) % block_size) #define INDCHUNK ((int) (CINDIR * ZONE_NUM_SIZE)) #define DIRCHUNK ((int) (CDIRECT * DIR_ENTRY_SIZE)) @@ -166,8 +167,8 @@ _PROTOTYPE(void printpath, (int mode, int nlcr)); _PROTOTYPE(void devopen, (void)); _PROTOTYPE(void devclose, (void)); _PROTOTYPE(void devio, (block_nr bno, int dir)); -_PROTOTYPE(void devread, (long offset, char *buf, int size)); -_PROTOTYPE(void devwrite, (long offset, char *buf, int size)); +_PROTOTYPE(void devread, (long block, long offset, char *buf, int size)); +_PROTOTYPE(void devwrite, (long block, long offset, char *buf, int size)); _PROTOTYPE(void pr, (char *fmt, int cnt, char *s, char *p)); _PROTOTYPE(void lpr, (char *fmt, long cnt, char *s, char *p)); _PROTOTYPE(bit_nr getnumber, (char *s)); @@ -394,6 +395,8 @@ void devio(bno, dir) block_nr bno; int dir; { + int r; + if(!block_size) fatal("devio() with unknown block size"); if (dir == READING && bno == thisblk) return; thisblk = bno; @@ -401,7 +404,9 @@ int dir; #if 0 printf("%s at block %5d\n", dir == READING ? "reading " : "writing", bno); #endif - lseek(dev, (off_t) btoa(bno), SEEK_SET); + r= lseek64(dev, btoa64(bno), SEEK_SET, NULL); + if (r != 0) + fatal("lseek64 failed"); if (dir == READING) { if (read(dev, rwbuf, block_size) == block_size) return; @@ -420,28 +425,44 @@ printf("%s at block %5d\n", dir == READING ? "reading " : "writing", bno); fatal(""); } -/* Read `size' bytes from the disk starting at byte `offset'. */ -void devread(offset, buf, size) +/* Read `size' bytes from the disk starting at block 'block' and + * byte `offset'. + */ +void devread(block, offset, buf, size) +long block; long offset; char *buf; int size; { if(!block_size) fatal("devread() with unknown block size"); - devio((block_nr) (offset / block_size), READING); - memmove(buf, &rwbuf[(int) (offset % block_size)], (size_t)size); /* lint but OK */ + if (offset >= block_size) + { + block += offset/block_size; + offset %= block_size; + } + devio(block, READING); + memmove(buf, &rwbuf[offset], size); } -/* Write `size' bytes to the disk starting at byte `offset'. */ -void devwrite(offset, buf, size) +/* Write `size' bytes to the disk starting at block 'block' and + * byte `offset'. + */ +void devwrite(block, offset, buf, size) +long block; long offset; char *buf; int size; { if(!block_size) fatal("devwrite() with unknown block size"); if (!repair) fatal("internal error (devwrite)"); - if (size != block_size) devio((block_nr) (offset / block_size), READING); - memmove(&rwbuf[(int) (offset % block_size)], buf, (size_t)size); /* lint but OK */ - devio((block_nr) (offset / block_size), WRITING); + if (offset >= block_size) + { + block += offset/block_size; + offset %= block_size; + } + if (size != block_size) devio(block, READING); + memmove(&rwbuf[offset], buf, size); + devio(block, WRITING); changed = 1; } @@ -518,7 +539,7 @@ void lsuper() printf("block size = %ld", sb.s_block_size); if (input(buf, 80)) sb.s_block_size = atol(buf); if (yes("ok now")) { - devwrite(OFFSET_SUPER_BLOCK, (char *) &sb, sizeof(sb)); + devwrite(0, OFFSET_SUPER_BLOCK, (char *) &sb, sizeof(sb)); return; } } while (yes("Do you want to try again")); @@ -601,10 +622,17 @@ void chksuper() } } -int inoaddr(int inn) +int inoblock(int inn) +{ + int a; + a = cinoblock(inn); + return a; +} + +int inooff(int inn) { int a; - a = cinoaddr(inn); + a = cinooff(inn); return a; } @@ -624,7 +652,7 @@ char **clist; setbit(spec_imap, bit); ino = bit; do { - devread(inoaddr(ino), (char *) ip, INODE_SIZE); + devread(inoblock(ino), inooff(ino), (char *) ip, INODE_SIZE); printf("inode %u:\n", ino); printf(" mode = %6o", ip->i_mode); if (input(buf, 80)) ip->i_mode = atoo(buf); @@ -633,7 +661,8 @@ char **clist; printf(" size = %6ld", ip->i_size); if (input(buf, 80)) ip->i_size = atol(buf); if (yes("Write this back")) { - devwrite(inoaddr(ino), (char *) ip, INODE_SIZE); + devwrite(inoblock(ino), inooff(ino), (char *) ip, + INODE_SIZE); break; } } while (yes("Do you want to change it again")); @@ -662,7 +691,7 @@ int nblk; p = bitmap; for (i = 0; i < nblk; i++, bno++, p += WORDS_PER_BLOCK) - devread(btoa(bno), (char *) p, block_size); + devread(bno, 0, (char *) p, block_size); *bitmap |= 1; } @@ -676,7 +705,7 @@ int nblk; register bitchunk_t *p = bitmap; for (i = 0; i < nblk; i++, bno++, p += WORDS_PER_BLOCK) - devwrite(btoa(bno), (char *) p, block_size); + devwrite(bno, 0, (char *) p, block_size); } /* Set the bits given by `list' in the bitmap. */ @@ -787,11 +816,12 @@ void chkilist() printf("Checking inode list\n"); do if (!bitset(imap, (bit_nr) ino)) { - devread(inoaddr(ino), (char *) &mode, sizeof(mode)); + devread(inoblock(ino), inooff(ino), (char *) &mode, + sizeof(mode)); if (mode != I_NOT_ALLOC) { printf("mode inode %u not cleared", ino); - if (yes(". clear")) devwrite(inoaddr(ino), nullbuf, - INODE_SIZE); + if (yes(". clear")) devwrite(inoblock(ino), + inooff(ino), nullbuf, INODE_SIZE); } } while (++ino <= sb.s_ninodes && ino != 0); @@ -814,7 +844,7 @@ ino_t ino; printf("INODE NLINK COUNT\n"); firstcnterr = 0; } - devread(inoaddr(ino), (char *) &inode, INODE_SIZE); + devread(inoblock(ino), inooff(ino), (char *) &inode, INODE_SIZE); count[ino] += inode.i_nlinks; /* it was already subtracted; add it back */ printf("%5u %5u %5u", ino, (unsigned) inode.i_nlinks, count[ino]); if (yes(" adjust")) { @@ -823,7 +853,7 @@ ino_t ino; inode.i_mode = I_NOT_ALLOC; clrbit(imap, (bit_nr) ino); } - devwrite(inoaddr(ino), (char *) &inode, INODE_SIZE); + devwrite(inoblock(ino), inooff(ino), (char *) &inode, INODE_SIZE); } } @@ -1083,12 +1113,13 @@ zone_nr zno; dir_struct dirblk[CDIRECT]; register dir_struct *dp; register n, dirty; - register long offset = zaddr(zno); + long block= ztob(zno); + register long offset = 0; register off_t size = 0; n = SCALE * (NR_DIR_ENTRIES(block_size) / CDIRECT); do { - devread(offset, (char *) dirblk, DIRCHUNK); + devread(block, offset, (char *) dirblk, DIRCHUNK); dirty = 0; for (dp = dirblk; dp < &dirblk[CDIRECT]; dp++) { if (dp->d_inum != NO_ENTRY && !chkentry(ino, pos, dp)) @@ -1096,7 +1127,7 @@ zone_nr zno; pos += DIR_ENTRY_SIZE; if (dp->d_inum != NO_ENTRY) size = pos; } - if (dirty) devwrite(offset, (char *) dirblk, DIRCHUNK); + if (dirty) devwrite(block, offset, (char *) dirblk, DIRCHUNK); offset += DIRCHUNK; n--; } while (n > 0); @@ -1107,7 +1138,7 @@ zone_nr zno; if (yes(". extend")) { setbit(spec_imap, (bit_nr) ino); ip->i_size = size; - devwrite(inoaddr(ino), (char *) ip, INODE_SIZE); + devwrite(inoblock(ino), inooff(ino), (char *) ip, INODE_SIZE); } } return(1); @@ -1120,14 +1151,14 @@ d_inode *ip; off_t pos; zone_nr zno; { - long offset; + long block; size_t len; char target[PATH_MAX+1]; if (ip->i_size > PATH_MAX) fatal("chksymlinkzone: fsck program inconsistency\n"); - offset = zaddr(zno); - devread(offset, target, ip->i_size); + block= ztob(zno); + devread(block, 0, target, ip->i_size); target[ip->i_size]= '\0'; len= strlen(target); if (len != ip->i_size) @@ -1138,7 +1169,8 @@ zone_nr zno; if (yes(". update")) { setbit(spec_imap, (bit_nr) ino); ip->i_size = len; - devwrite(inoaddr(ino), (char *) ip, INODE_SIZE); + devwrite(inoblock(ino), inooff(ino), + (char *) ip, INODE_SIZE); } } return 1; @@ -1201,10 +1233,11 @@ int level; { zone_nr indirect[CINDIR]; register n = NR_INDIRECTS / CINDIR; - register long offset = zaddr(zno); + long block= ztob(zno); + register long offset = 0; do { - devread(offset, (char *) indirect, INDCHUNK); + devread(block, offset, (char *) indirect, INDCHUNK); if (!chkzones(ino, ip, pos, indirect, CINDIR, level - 1)) return(0); offset += INDCHUNK; } while (--n && *pos < ip->i_size); @@ -1442,14 +1475,15 @@ dir_struct *dp; } visited = bitset(imap, (bit_nr) ino); if (!visited || listing) { - devread(inoaddr(ino), (char *) &inode, INODE_SIZE); + devread(inoblock(ino), inooff(ino), (char *) &inode, INODE_SIZE); if (listing) list(ino, &inode); if (!visited && !chkinode(ino, &inode)) { setbit(spec_imap, (bit_nr) ino); if (yes("remove")) { count[ino] += inode.i_nlinks - 1; clrbit(imap, (bit_nr) ino); - devwrite(inoaddr(ino), nullbuf, INODE_SIZE); + devwrite(inoblock(ino), inooff(ino), + nullbuf, INODE_SIZE); memset((void *) dp, 0, sizeof(dir_struct)); ftop = ftop->st_next; return(0); diff --git a/commands/simple/mkfs.c b/commands/simple/mkfs.c index de7882489..a36a6a580 100755 --- a/commands/simple/mkfs.c +++ b/commands/simple/mkfs.c @@ -317,12 +317,6 @@ char *argv[]; simple = 1; } - if(ULONG_MAX / block_size <= blocks-1) { - fprintf(stderr, "Warning: too big for filesystem to currently\n"); - fprintf(stderr, "run on (max 4GB), truncating.\n"); - blocks = ULONG_MAX / block_size; - } - nrblocks = blocks; nrinodes = inodes; @@ -337,7 +331,7 @@ char *argv[]; testb = (short *) alloc_block(); /* Try writing the last block of partition or diskette. */ - if(lseek(fd, (off_t) (blocks - 1) * block_size, SEEK_SET) < 0) { + if(lseek64(fd, mul64u(blocks - 1, block_size), SEEK_SET, NULL) < 0) { pexit("couldn't seek to last block to test size (1)"); } testb[0] = 0x3245; @@ -349,7 +343,7 @@ char *argv[]; pexit("File system is too big for minor device (write)"); } sync(); /* flush write, so if error next read fails */ - if(lseek(fd, (off_t) (blocks - 1) * block_size, SEEK_SET) < 0) { + if(lseek64(fd, mul64u(blocks - 1, block_size), SEEK_SET, NULL) < 0) { pexit("couldn't seek to last block to test size (2)"); } testb[0] = 0; @@ -358,9 +352,11 @@ char *argv[]; if (nread != block_size || testb[0] != 0x3245 || testb[1] != 0x11FF || testb[block_size-1] != 0x1F2F) { if(nread < 0) perror("read"); +printf("nread = %d\n", nread); +printf("testb = 0x%x 0x%x 0x%x\n", testb[0], testb[1], testb[block_size-1]); pexit("File system is too big for minor device (read)"); } - lseek(fd, (off_t) (blocks - 1) * block_size, SEEK_SET); + lseek64(fd, mul64u(blocks - 1, block_size), SEEK_SET, NULL); testb[0] = 0; testb[1] = 0; if (write(fd, (char *) testb, block_size) != block_size) @@ -1536,7 +1532,7 @@ char *buf; copy(zero, buf, block_size); return; } - lseek(fd, (off_t) n * block_size, SEEK_SET); + lseek64(fd, mul64u(n, block_size), SEEK_SET, NULL); k = read(fd, buf, block_size); if (k != block_size) { pexit("get_block couldn't read"); @@ -1569,7 +1565,7 @@ char *buf; (void) read_and_set(n); /* XXX - check other lseeks too. */ - if (lseek(fd, (off_t) n * block_size, SEEK_SET) == (off_t) -1) { + if (lseek64(fd, mul64u(n, block_size), SEEK_SET, NULL) == (off_t) -1) { pexit("put_block couldn't seek"); } if (write(fd, buf, block_size) != block_size) { diff --git a/drivers/at_wini/at_wini.c b/drivers/at_wini/at_wini.c index 3ea656f19..b7ed00cbc 100644 --- a/drivers/at_wini/at_wini.c +++ b/drivers/at_wini/at_wini.c @@ -346,7 +346,7 @@ FORWARD _PROTOTYPE( int w_identify, (void) ); FORWARD _PROTOTYPE( char *w_name, (void) ); FORWARD _PROTOTYPE( int w_specify, (void) ); FORWARD _PROTOTYPE( int w_io_test, (void) ); -FORWARD _PROTOTYPE( int w_transfer, (int proc_nr, int opcode, off_t position, +FORWARD _PROTOTYPE( int w_transfer, (int proc_nr, int opcode, u64_t position, iovec_t *iov, unsigned nr_req, int safe)); FORWARD _PROTOTYPE( int com_out, (struct command *cmd) ); FORWARD _PROTOTYPE( int com_out_ext, (struct command *cmd) ); @@ -371,7 +371,7 @@ FORWARD _PROTOTYPE( int atapi_intr_wait, (void) ); FORWARD _PROTOTYPE( int atapi_open, (void) ); FORWARD _PROTOTYPE( void atapi_close, (void) ); FORWARD _PROTOTYPE( int atapi_transfer, (int proc_nr, int opcode, - off_t position, iovec_t *iov, unsigned nr_req, int safe)); + u64_t position, iovec_t *iov, unsigned nr_req, int safe)); #endif /* Entry points to this driver. */ @@ -806,11 +806,13 @@ PRIVATE int w_identify() if ((s=sys_insw(wn->base_cmd + REG_DATA, SELF, tmp_buf, SECTOR_SIZE)) != OK) panic(w_name(),"Call to sys_insw() failed", s); +#if 0 if (id_word(0) & ID_GEN_NOT_ATA) { printf("%s: not an ATA device?\n", w_name()); return ERR; } +#endif /* This is an ATA device. */ wn->state |= SMART; @@ -1049,7 +1051,7 @@ PRIVATE int w_io_test(void) if (w_prepare(w_drive * DEV_PER_DRIVE) == NIL_DEV) panic(w_name(), "Couldn't switch devices", NO_NUM); - r = w_transfer(SELF, DEV_GATHER, 0, &iov, 1, 0); + r = w_transfer(SELF, DEV_GATHER, cvu64(0), &iov, 1, 0); /* Switch back. */ if (w_prepare(save_dev) == NIL_DEV) @@ -1192,7 +1194,7 @@ PRIVATE int do_transfer(struct wini *wn, unsigned int precomp, PRIVATE int w_transfer(proc_nr, opcode, position, iov, nr_req, safe) int proc_nr; /* process doing the request */ int opcode; /* DEV_GATHER or DEV_SCATTER */ -off_t position; /* offset on device to read or write */ +u64_t position; /* offset on device to read or write */ iovec_t *iov; /* pointer to read or write request vector */ unsigned nr_req; /* length of request vector */ int safe; /* iov contains addresses (0) or grants? */ @@ -1201,7 +1203,7 @@ int safe; /* iov contains addresses (0) or grants? */ iovec_t *iop, *iov_end = iov + nr_req; int n, r, s, errors, do_dma, do_write, do_copyout; unsigned long v, block, w_status; - unsigned long dv_size = cv64ul(w_dv->dv_size); + u64_t dv_size = w_dv->dv_size; unsigned cylinder, head, sector, nbytes; unsigned dma_buf_offset; size_t addr_offset = 0; @@ -1213,7 +1215,7 @@ int safe; /* iov contains addresses (0) or grants? */ #endif /* Check disk address. */ - if ((position & SECTOR_MASK) != 0) return(EINVAL); + if (rem64u(position, SECTOR_SIZE) != 0) return(EINVAL); errors = 0; @@ -1224,9 +1226,10 @@ int safe; /* iov contains addresses (0) or grants? */ if ((nbytes & SECTOR_MASK) != 0) return(EINVAL); /* Which block on disk and how close to EOF? */ - if (position >= dv_size) return(OK); /* At EOF */ - if (position + nbytes > dv_size) nbytes = dv_size - position; - block = div64u(add64ul(w_dv->dv_base, position), SECTOR_SIZE); + if (cmp64(position, dv_size) >= 0) return(OK); /* At EOF */ + if (cmp64(add64ul(position, nbytes), dv_size) > 0) + nbytes = diff64(dv_size, position); + block = div64u(add64(w_dv->dv_base, position), SECTOR_SIZE); do_dma= wn->dma; do_write= (opcode == DEV_SCATTER); @@ -1338,7 +1341,7 @@ int safe; /* iov contains addresses (0) or grants? */ /* Book the bytes successfully transferred. */ nbytes -= n; - position += n; + position= add64ul(position, n); if ((iov->iov_size -= n) == 0) { iov++; nr_req--; addr_offset = 0; } @@ -1412,7 +1415,7 @@ int safe; /* iov contains addresses (0) or grants? */ /* Book the bytes successfully transferred. */ nbytes -= SECTOR_SIZE; - position += SECTOR_SIZE; + position= add64u(position, SECTOR_SIZE); addr_offset += SECTOR_SIZE; if ((iov->iov_size -= SECTOR_SIZE) == 0) { iov++; @@ -2113,7 +2116,7 @@ void sense_request(void) PRIVATE int atapi_transfer(proc_nr, opcode, position, iov, nr_req, safe) int proc_nr; /* process doing the request */ int opcode; /* DEV_GATHER or DEV_SCATTER */ -off_t position; /* offset on device to read or write */ +u64_t position; /* offset on device to read or write */ iovec_t *iov; /* pointer to read or write request vector */ unsigned nr_req; /* length of request vector */ int safe; /* use safecopies? */ @@ -2123,7 +2126,7 @@ int safe; /* use safecopies? */ int r, s, errors, fresh; u64_t pos; unsigned long block; - unsigned long dv_size = cv64ul(w_dv->dv_size); + u64_t dv_size = w_dv->dv_size; unsigned nbytes, nblocks, count, before, chunk; static u8_t packet[ATAPI_PACKETSIZE]; size_t addr_offset = 0; @@ -2134,7 +2137,7 @@ int safe; /* use safecopies? */ /* The Minix block size is smaller than the CD block size, so we * may have to read extra before or after the good data. */ - pos = add64ul(w_dv->dv_base, position); + pos = add64(w_dv->dv_base, position); block = div64u(pos, CD_SECTOR_SIZE); before = rem64u(pos, CD_SECTOR_SIZE); @@ -2152,8 +2155,9 @@ int safe; /* use safecopies? */ if ((before | nbytes) & 1) return(EINVAL); /* Which block on disk and how close to EOF? */ - if (position >= dv_size) return(OK); /* At EOF */ - if (position + nbytes > dv_size) nbytes = dv_size - position; + if (cmp64(position, dv_size) >= 0) return(OK); /* At EOF */ + if (cmp64(add64ul(position, nbytes), dv_size) > 0) + nbytes = diff64(dv_size, position); nblocks = (before + nbytes + CD_SECTOR_SIZE - 1) / CD_SECTOR_SIZE; if (ATAPI_DEBUG) { @@ -2214,7 +2218,7 @@ int safe; /* use safecopies? */ } if (s != OK) panic(w_name(),"Call to sys_insw() failed", s); - position += chunk; + position= add64ul(position, chunk); nbytes -= chunk; count -= chunk; addr_offset += chunk; diff --git a/drivers/bios_wini/bios_wini.c b/drivers/bios_wini/bios_wini.c index dbc8593f5..f6f4565d2 100644 --- a/drivers/bios_wini/bios_wini.c +++ b/drivers/bios_wini/bios_wini.c @@ -68,7 +68,7 @@ PRIVATE cp_grant_id_t my_bios_grant_id; _PROTOTYPE(int main, (void) ); FORWARD _PROTOTYPE( struct device *w_prepare, (int device) ); FORWARD _PROTOTYPE( char *w_name, (void) ); -FORWARD _PROTOTYPE( int w_transfer, (int proc_nr, int opcode, off_t position, +FORWARD _PROTOTYPE( int w_transfer, (int proc_nr, int opcode, u64_t position, iovec_t *iov, unsigned nr_req, int safe) ); FORWARD _PROTOTYPE( int w_do_open, (struct driver *dp, message *m_ptr) ); FORWARD _PROTOTYPE( int w_do_close, (struct driver *dp, message *m_ptr) ); @@ -199,10 +199,10 @@ size_t size; /*===========================================================================* * w_transfer * *===========================================================================*/ -PRIVATE int w_transfer(proc_nr, opcode, position, iov, nr_req, safe) +PRIVATE int w_transfer(proc_nr, opcode, pos64, iov, nr_req, safe) int proc_nr; /* process doing the request */ int opcode; /* DEV_GATHER or DEV_SCATTER */ -off_t position; /* offset on device to read or write */ +u64_t pos64; /* offset on device to read or write */ iovec_t *iov; /* pointer to read or write request vector */ unsigned nr_req; /* length of request vector */ int safe; /* use safecopies? */ @@ -216,6 +216,7 @@ int safe; /* use safecopies? */ size_t vir_offset = 0; unsigned long dv_size = cv64ul(w_dv->dv_size); unsigned secspcyl = wn->heads * wn->sectors; + off_t position; struct int13ext_rw { u8_t len; u8_t res1; @@ -225,6 +226,10 @@ int safe; /* use safecopies? */ } i13e_rw; struct reg86u reg86; + if (ex64hi(pos64)) + panic(__FILE__, "should handle 64-bit offsets", NO_NUM); + position= ex64lo(pos64); + /* Check disk address. */ if ((position & SECTOR_MASK) != 0) return(EINVAL); diff --git a/drivers/floppy/floppy.c b/drivers/floppy/floppy.c index 120722b3a..1d9f59938 100644 --- a/drivers/floppy/floppy.c +++ b/drivers/floppy/floppy.c @@ -247,7 +247,7 @@ FORWARD _PROTOTYPE( void f_timeout, (timer_t *tp) ); FORWARD _PROTOTYPE( struct device *f_prepare, (int device) ); FORWARD _PROTOTYPE( char *f_name, (void) ); FORWARD _PROTOTYPE( void f_cleanup, (void) ); -FORWARD _PROTOTYPE( int f_transfer, (int proc_nr, int opcode, off_t position, +FORWARD _PROTOTYPE( int f_transfer, (int proc_nr, int opcode, u64_t position, iovec_t *iov, unsigned nr_req, int) ); FORWARD _PROTOTYPE( int dma_setup, (int opcode) ); FORWARD _PROTOTYPE( void start_motor, (void) ); @@ -433,10 +433,10 @@ PRIVATE void f_cleanup() /*===========================================================================* * f_transfer * *===========================================================================*/ -PRIVATE int f_transfer(proc_nr, opcode, position, iov, nr_req, safe) +PRIVATE int f_transfer(proc_nr, opcode, pos64, iov, nr_req, safe) int proc_nr; /* process doing the request */ int opcode; /* DEV_GATHER or DEV_SCATTER */ -off_t position; /* offset on device to read or write */ +u64_t pos64; /* offset on device to read or write */ iovec_t *iov; /* pointer to read or write request vector */ unsigned nr_req; /* length of request vector */ int safe; @@ -449,10 +449,15 @@ int safe; unsigned nbytes, count, chunk, sector; unsigned long dv_size = cv64ul(f_dv->dv_size); vir_bytes user_offset, iov_offset = 0, iop_offset; + off_t position; signed long uoffsets[MAX_SECTORS], *up; cp_grant_id_t ugrants[MAX_SECTORS], *ug; u8_t cmd[3]; + if (ex64hi(pos64) != 0) + return OK; /* Way beyond EOF */ + position= cv64ul(pos64); + /* Check disk address. */ if ((position & SECTOR_MASK) != 0) return(EINVAL); @@ -1307,7 +1312,7 @@ int density; position = (off_t) f_dp->test << SECTOR_SHIFT; iovec1.iov_addr = (vir_bytes) tmp_buf; iovec1.iov_size = SECTOR_SIZE; - result = f_transfer(SELF, DEV_GATHER, position, &iovec1, 1, 0); + result = f_transfer(SELF, DEV_GATHER, cvul64(position), &iovec1, 1, 0); if (iovec1.iov_size != 0) return(EIO); diff --git a/drivers/libdriver/driver.c b/drivers/libdriver/driver.c index 60a8161d7..58e7f5929 100644 --- a/drivers/libdriver/driver.c +++ b/drivers/libdriver/driver.c @@ -182,6 +182,7 @@ int safe; /* use safecopies? */ iovec_t iovec1; int r, opcode; phys_bytes phys_addr; + u64_t position; /* Disk address? Address and length of the user buffer? */ if (mp->COUNT < 0) return(EINVAL); @@ -203,7 +204,8 @@ int safe; /* use safecopies? */ iovec1.iov_size = mp->COUNT; /* Transfer bytes from/to the device. */ - r = (*dp->dr_transfer)(mp->IO_ENDPT, opcode, mp->POSITION, &iovec1, 1, safe); + position= make64(mp->POSITION, mp->HIGHPOS); + r = (*dp->dr_transfer)(mp->IO_ENDPT, opcode, position, &iovec1, 1, safe); /* Return the number of bytes transferred or an error code. */ return(r == OK ? (mp->COUNT - iovec1.iov_size) : r); @@ -226,7 +228,7 @@ int safe; /* use safecopies? */ phys_bytes iovec_size; unsigned nr_req; int r, j, opcode; - + u64_t position; nr_req = mp->COUNT; /* Length of I/O vector */ @@ -257,7 +259,8 @@ int safe; /* use safecopies? */ opcode = mp->m_type; if(opcode == DEV_GATHER_S) opcode = DEV_GATHER; if(opcode == DEV_SCATTER_S) opcode = DEV_SCATTER; - r = (*dp->dr_transfer)(mp->IO_ENDPT, opcode, mp->POSITION, iov, + position= make64(mp->POSITION, mp->HIGHPOS); + r = (*dp->dr_transfer)(mp->IO_ENDPT, opcode, position, iov, nr_req, safe); /* Copy the I/O vector back to the caller. */ diff --git a/drivers/libdriver/driver.h b/drivers/libdriver/driver.h index 3507e9695..1d71672ab 100644 --- a/drivers/libdriver/driver.h +++ b/drivers/libdriver/driver.h @@ -33,8 +33,8 @@ struct driver { _PROTOTYPE( int (*dr_close), (struct driver *dp, message *m_ptr) ); _PROTOTYPE( int (*dr_ioctl), (struct driver *dp, message *m_ptr, int safe) ); _PROTOTYPE( struct device *(*dr_prepare), (int device) ); - _PROTOTYPE( int (*dr_transfer), (int proc_nr, int opcode, off_t position, - iovec_t *iov, unsigned nr_req, int safe) ); + _PROTOTYPE( int (*dr_transfer), (int proc_nr, int opcode, u64_t position, + iovec_t *iov, unsigned nr_req, int safe) ); _PROTOTYPE( void (*dr_cleanup), (void) ); _PROTOTYPE( void (*dr_geometry), (struct partition *entry) ); _PROTOTYPE( void (*dr_signal), (struct driver *dp, message *m_ptr) ); diff --git a/drivers/libdriver/drvlib.c b/drivers/libdriver/drvlib.c index 6135896ad..1e1bc8ab7 100644 --- a/drivers/libdriver/drvlib.c +++ b/drivers/libdriver/drvlib.c @@ -157,10 +157,10 @@ struct part_entry *table; /* four entries */ * errors. */ iovec_t iovec1; - off_t position; + u64_t position; static unsigned char partbuf[CD_SECTOR_SIZE]; - position = offset << SECTOR_SHIFT; + position = mul64u(offset, SECTOR_SIZE); iovec1.iov_addr = (vir_bytes) partbuf; iovec1.iov_size = CD_SECTOR_SIZE; if ((*dp->dr_prepare)(device) != NIL_DEV) { diff --git a/drivers/log/log.c b/drivers/log/log.c index 6fed82bd8..043fa55ad 100644 --- a/drivers/log/log.c +++ b/drivers/log/log.c @@ -25,7 +25,7 @@ PRIVATE int log_device = -1; /* current device */ FORWARD _PROTOTYPE( char *log_name, (void) ); FORWARD _PROTOTYPE( struct device *log_prepare, (int device) ); -FORWARD _PROTOTYPE( int log_transfer, (int proc_nr, int opcode, off_t position, +FORWARD _PROTOTYPE( int log_transfer, (int proc_nr, int opcode, u64_t position, iovec_t *iov, unsigned nr_req, int safe) ); FORWARD _PROTOTYPE( int log_do_open, (struct driver *dp, message *m_ptr) ); FORWARD _PROTOTYPE( int log_cancel, (struct driver *dp, message *m_ptr) ); @@ -227,7 +227,7 @@ subread(struct logdevice *log, int count, int proc_nr, PRIVATE int log_transfer(proc_nr, opcode, position, iov, nr_req, safe) int proc_nr; /* process doing the request */ int opcode; /* DEV_GATHER or DEV_SCATTER */ -off_t position; /* offset on device to read or write */ +u64_t position; /* offset on device to read or write */ iovec_t *iov; /* pointer to read or write request vector */ unsigned nr_req; /* length of request vector */ int safe; /* safe copies? */ diff --git a/drivers/memory/memory.c b/drivers/memory/memory.c index 906699e8a..d4b165942 100644 --- a/drivers/memory/memory.c +++ b/drivers/memory/memory.c @@ -43,7 +43,7 @@ extern int errno; /* error number for PM calls */ FORWARD _PROTOTYPE( char *m_name, (void) ); FORWARD _PROTOTYPE( struct device *m_prepare, (int device) ); -FORWARD _PROTOTYPE( int m_transfer, (int proc_nr, int opcode, off_t position, +FORWARD _PROTOTYPE( int m_transfer, (int proc_nr, int opcode, u64_t position, iovec_t *iov, unsigned nr_req, int safe)); FORWARD _PROTOTYPE( int m_do_open, (struct driver *dp, message *m_ptr) ); FORWARD _PROTOTYPE( void m_init, (void) ); @@ -119,10 +119,10 @@ int device; /*===========================================================================* * m_transfer * *===========================================================================*/ -PRIVATE int m_transfer(proc_nr, opcode, position, iov, nr_req, safe) +PRIVATE int m_transfer(proc_nr, opcode, pos64, iov, nr_req, safe) int proc_nr; /* process doing the request */ int opcode; /* DEV_GATHER or DEV_SCATTER */ -off_t position; /* offset on device to read or write */ +u64_t pos64; /* offset on device to read or write */ iovec_t *iov; /* pointer to read or write request vector */ unsigned nr_req; /* length of request vector */ int safe; /* safe copies */ @@ -136,9 +136,14 @@ int safe; /* safe copies */ struct device *dv; unsigned long dv_size; int s, r; + off_t position; static int n = 0; + if (ex64hi(pos64) != 0) + return OK; /* Beyond EOF */ + position= cv64ul(pos64); + /* Get minor device number and check for /dev/null. */ dv = &m_geom[m_device]; dv_size = cv64ul(dv->dv_size); diff --git a/include/minix/const.h b/include/minix/const.h index 4e18ead18..57d35deb3 100755 --- a/include/minix/const.h +++ b/include/minix/const.h @@ -111,7 +111,7 @@ #define MAX_BLOCK_NR ((block_t) 077777777) /* largest block number */ #define HIGHEST_ZONE ((zone_t) 077777777) /* largest zone number */ #define MAX_INODE_NR ((ino_t) 037777777777) /* largest inode number */ -#define MAX_FILE_POS ((off_t) 037777777777) /* largest legal file offset */ +#define MAX_FILE_POS ((off_t) 0x7FFFFFFF) /* largest legal file offset */ #define MAX_SYM_LOOPS 8 /* how many symbolic links are recursed */ diff --git a/include/minix/vfsif.h b/include/minix/vfsif.h index 0f55eadce..5409f0d30 100644 --- a/include/minix/vfsif.h +++ b/include/minix/vfsif.h @@ -52,9 +52,15 @@ #define REQ_FD_START m2_i2 #define REQ_FD_END m2_i3 -#define REQ_FD_BLOCK_SIZE m2_s1 #define REQ_FD_BDRIVER_E m2_i1 -#define REQ_FD_BDEV m2_l2 + +#define REQ_XFD_BDEV m2_i1 +#define REQ_XFD_WHO_E m2_i2 +#define REQ_XFD_NBYTES m2_i3 +#define REQ_XFD_POS_LO m2_l1 +#define REQ_XFD_POS_HI m2_l2 +#define REQ_XFD_USER_ADDR m2_p1 +#define REQ_XFD_BLOCK_SIZE m2_s1 /* For REQ_GETDENTS */ #define REQ_GDE_INODE m2_i1 @@ -82,6 +88,10 @@ #define RES_FD_CUM_IO m2_i2 #define RES_FD_SIZE m2_i3 +#define RES_XFD_POS_LO m2_l1 +#define RES_XFD_POS_HI m2_l2 +#define RES_XFD_CUM_IO m2_i1 + #define RES_DIR m6_l1 #define RES_FILE m6_l2 @@ -135,10 +145,10 @@ #define REQ_BREAD 38 #define REQ_BWRITE 39 - #define REQ_GETDENTS 40 +#define REQ_FLUSH 41 -#define NREQS 41 +#define NREQS 42 #define FS_READY 57 diff --git a/include/sys/types.h b/include/sys/types.h index 6c222f25c..06b553e59 100755 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -52,7 +52,7 @@ typedef char gid_t; /* group id */ typedef unsigned long ino_t; /* i-node number (V3 filesystem) */ typedef unsigned short mode_t; /* file type and permissions bits */ typedef short nlink_t; /* number of links to a file */ -typedef unsigned long off_t; /* offset within a file */ +typedef long off_t; /* offset within a file */ typedef int pid_t; /* process id (must be signed) */ typedef short uid_t; /* user id */ typedef unsigned long zone_t; /* zone number */ diff --git a/servers/mfs/cache.c b/servers/mfs/cache.c index 02e2a8c2c..5f5b85e1e 100644 --- a/servers/mfs/cache.c +++ b/servers/mfs/cache.c @@ -16,6 +16,7 @@ #include "fs.h" #include +#include #include "buf.h" #include "super.h" @@ -259,14 +260,14 @@ int rw_flag; /* READING or WRITING */ * from the cache, it is not clear what the caller could do about it anyway. */ int r, op; - off_t pos; + u64_t pos; dev_t dev; int block_size; block_size = get_block_size(bp->b_dev); if ( (dev = bp->b_dev) != NO_DEV) { - pos = (off_t) bp->b_blocknr * block_size; + pos = mul64u(bp->b_blocknr, block_size); op = (rw_flag == READING ? DEV_READ : DEV_WRITE); r = block_dev_io(op, dev, SELF_E, bp->b_data, pos, block_size, 0); if (r != block_size) { @@ -374,7 +375,7 @@ int rw_flag; /* READING or WRITING */ } r = block_dev_io(rw_flag == WRITING ? DEV_SCATTER : DEV_GATHER, dev, SELF_E, iovec, - (off_t) bufq[0]->b_blocknr * block_size, j, 0); + mul64u(bufq[0]->b_blocknr, block_size), j, 0); /* Harvest the results. Dev_io reports the first error it may have * encountered, but we only care if it's the first block that failed. diff --git a/servers/mfs/device.c b/servers/mfs/device.c index 5a8662a20..5d6acd83e 100644 --- a/servers/mfs/device.c +++ b/servers/mfs/device.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include "inode.h" #include "super.h" @@ -19,7 +20,7 @@ PRIVATE int dummyproc; FORWARD _PROTOTYPE( int safe_io_conversion, (endpoint_t, cp_grant_id_t *, int *, cp_grant_id_t *, int, endpoint_t *, - void **, int *, vir_bytes, off_t *)); + void **, int *, vir_bytes)); FORWARD _PROTOTYPE( void safe_io_cleanup, (cp_grant_id_t, cp_grant_id_t *, int)); @@ -65,7 +66,7 @@ PUBLIC int fs_new_driver(void) * safe_io_conversion * *===========================================================================*/ PRIVATE int safe_io_conversion(driver, gid, op, gids, gids_size, - io_ept, buf, vec_grants, bytes, pos) + io_ept, buf, vec_grants, bytes) endpoint_t driver; cp_grant_id_t *gid; int *op; @@ -75,7 +76,6 @@ endpoint_t *io_ept; void **buf; int *vec_grants; vir_bytes bytes; -off_t *pos; { int access = 0, size; int j; @@ -135,21 +135,6 @@ off_t *pos; /* Set user's vector to the new one. */ *buf = new_iovec; break; - /* - case DEV_IOCTL: - *pos = *io_ept; - *op = DEV_IOCTL_S; - if(_MINIX_IOCTL_IOR(m_in.REQUEST)) access |= CPF_WRITE; - if(_MINIX_IOCTL_IOW(m_in.REQUEST)) access |= CPF_READ; - size = _MINIX_IOCTL_SIZE(m_in.REQUEST); - - if((*gid=cpf_grant_magic(driver, *io_ept, - (vir_bytes) *buf, size, access)) < 0) { - panic(__FILE__, - "cpf_grant_magic failed (ioctl)\n", - NO_NUM); - } - */ } /* If we have converted to a safe operation, I/O @@ -193,7 +178,7 @@ int op; /* DEV_READ, DEV_WRITE, DEV_IOCTL, etc. */ dev_t dev; /* major-minor device number */ int proc_e; /* in whose address space is buf? */ void *buf; /* virtual address of the buffer */ -off_t pos; /* byte position */ +u64_t pos; /* byte position */ int bytes; /* how many bytes to transfer */ int flags; /* special flags, like O_NONBLOCK */ { @@ -208,7 +193,7 @@ int flags; /* special flags, like O_NONBLOCK */ void *buf_used; static cp_grant_id_t gids[NR_IOREQS]; endpoint_t driver_e; - + /* Determine driver endpoint for this device */ driver_e = driver_endpoints[(dev >> MAJOR) & BYTE].driver_e; @@ -233,16 +218,16 @@ int flags; /* special flags, like O_NONBLOCK */ op_used = op; safe = safe_io_conversion(driver_e, &gid, &op_used, gids, NR_IOREQS, &m.IO_ENDPT, &buf_used, - &vec_grants, bytes, &pos); + &vec_grants, bytes); /* Set up rest of the message. */ if (safe) m.IO_GRANT = (char *) gid; m.m_type = op_used; m.DEVICE = (dev >> MINOR) & BYTE; - m.POSITION = pos; + m.POSITION = ex64lo(pos); m.COUNT = bytes; - m.HIGHPOS = 0; + m.HIGHPOS = ex64hi(pos); /* Call the task. */ r = sendrec(driver_e, &m); diff --git a/servers/mfs/misc.c b/servers/mfs/misc.c index 3613fc71f..b6e296fa5 100644 --- a/servers/mfs/misc.c +++ b/servers/mfs/misc.c @@ -1,6 +1,7 @@ #include "fs.h" #include +#include #include "buf.h" #include "inode.h" @@ -32,3 +33,26 @@ PUBLIC int fs_sync() } +/*===========================================================================* + * fs_flush * + *===========================================================================*/ +PUBLIC int fs_flush() +{ +/* Flush the blocks of a device from the cache after writing any dirty blocks + * to disk. + */ + dev_t dev; + + dev= fs_m_in.REQ_DEV; + if (dev == fs_dev) + { + printf("fs_flush: not flushing block for mounted filsystem\n"); + return EBUSY; + } + flushall(dev); + invalidate(dev); + + return(OK); +} + + diff --git a/servers/mfs/proto.h b/servers/mfs/proto.h index dd3fbb1ca..e8aef47d9 100644 --- a/servers/mfs/proto.h +++ b/servers/mfs/proto.h @@ -47,6 +47,7 @@ int fs_slink(void); int fs_rdlink(void); int fs_breadwrite(void); int fs_getdents(void); +int fs_flush(void); void init_inode_cache(void); @@ -70,7 +71,7 @@ _PROTOTYPE( void invalidate2, (Dev_t device) ); /* device.c */ _PROTOTYPE( int block_dev_io, (int op, Dev_t dev, int proc, void *buf, - off_t pos, int bytes, int flags) ); + u64_t pos, int bytes, int flags) ); /* inode.c */ @@ -146,7 +147,7 @@ _PROTOTYPE( int read_only, (struct inode *ip) ); /* read.c */ _PROTOTYPE( int do_read, (void) ); _PROTOTYPE( struct buf *rahead, (struct inode *rip, block_t baseblock, - off_t position, unsigned bytes_ahead) ); + u64_t position, unsigned bytes_ahead) ); _PROTOTYPE( void read_ahead, (void) ); _PROTOTYPE( block_t read_map, (struct inode *rip, off_t pos) ); _PROTOTYPE( int read_write, (int rw_flag) ); diff --git a/servers/mfs/read.c b/servers/mfs/read.c index 920c22c1b..453a226ef 100644 --- a/servers/mfs/read.c +++ b/servers/mfs/read.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "buf.h" #include "inode.h" #include "super.h" @@ -14,7 +15,7 @@ -FORWARD _PROTOTYPE( int rw_chunk, (struct inode *rip, off_t position, +FORWARD _PROTOTYPE( int rw_chunk, (struct inode *rip, u64_t position, unsigned off, int chunk, unsigned left, int rw_flag, char *buff, int seg, int usr, int block_size, int *completed)); @@ -98,7 +99,7 @@ PUBLIC int fs_readwrite(void) } /* Read or write 'chunk' bytes. */ - r = rw_chunk(rip, position, off, chunk, (unsigned) nrbytes, + r = rw_chunk(rip, cvul64(position), off, chunk, (unsigned) nrbytes, rw_flag, user_addr, seg, usr, block_size, &completed); if (r != OK) break; /* EOF reached */ @@ -166,7 +167,7 @@ PUBLIC int fs_breadwrite(void) { int r, usr, rw_flag, chunk, block_size; int nrbytes; - off_t position, f_size, bytes_left; + u64_t position; unsigned int off, cum_io; mode_t mode_word; int completed, r2 = OK; @@ -176,37 +177,30 @@ PUBLIC int fs_breadwrite(void) struct inode rip; r = OK; - f_size = ULONG_MAX; /* Get the values from the request message */ rw_flag = (fs_m_in.m_type == REQ_BREAD ? READING : WRITING); - usr = fs_m_in.REQ_FD_WHO_E; - position = fs_m_in.REQ_FD_POS; - nrbytes = (unsigned) fs_m_in.REQ_FD_NBYTES; - user_addr = fs_m_in.REQ_FD_USER_ADDR; + usr = fs_m_in.REQ_XFD_WHO_E; + position = make64(fs_m_in.REQ_XFD_POS_LO, fs_m_in.REQ_XFD_POS_HI); + nrbytes = (unsigned) fs_m_in.REQ_XFD_NBYTES; + user_addr = fs_m_in.REQ_XFD_USER_ADDR; - block_size = get_block_size(fs_m_in.REQ_FD_BDEV); + block_size = get_block_size(fs_m_in.REQ_XFD_BDEV); - rip.i_zone[0] = fs_m_in.REQ_FD_BDEV; + rip.i_zone[0] = fs_m_in.REQ_XFD_BDEV; rip.i_mode = I_BLOCK_SPECIAL; - rip.i_size = f_size; + rip.i_size = 0; rdwt_err = OK; /* set to EIO if disk error occurs */ cum_io = 0; /* Split the transfer into chunks that don't span two blocks. */ while (nrbytes != 0) { - off = (unsigned int) (position % block_size);/* offset in blk*/ + off = rem64u(position, block_size); /* offset in blk*/ chunk = MIN(nrbytes, block_size - off); if (chunk < 0) chunk = block_size - off; - if (rw_flag == READING) { - bytes_left = f_size - position; - if (position >= f_size) break; /* we are beyond EOF */ - if (chunk > bytes_left) chunk = (int) bytes_left; - } - /* Read or write 'chunk' bytes. */ r = rw_chunk(&rip, position, off, chunk, (unsigned) nrbytes, rw_flag, user_addr, D, usr, block_size, &completed); @@ -218,16 +212,16 @@ PUBLIC int fs_breadwrite(void) user_addr += chunk; /* user buffer address */ nrbytes -= chunk; /* bytes yet to be read */ cum_io += chunk; /* bytes read so far */ - position += chunk; /* position within the file */ + position= add64ul(position, chunk); /* position within the file */ } - fs_m_out.RES_FD_POS = position; + fs_m_out.RES_XFD_POS_LO = ex64lo(position); + fs_m_out.RES_XFD_POS_HI = ex64hi(position); if (rdwt_err != OK) r = rdwt_err; /* check for disk error */ if (rdwt_err == END_OF_FILE) r = OK; - fs_m_out.RES_FD_CUM_IO = cum_io; - fs_m_out.RES_FD_SIZE = rip.i_size; + fs_m_out.RES_XFD_CUM_IO = cum_io; return(r); } @@ -239,7 +233,7 @@ PUBLIC int fs_breadwrite(void) PRIVATE int rw_chunk(rip, position, off, chunk, left, rw_flag, buff, seg, usr, block_size, completed) register struct inode *rip; /* pointer to inode for file to be rd/wr */ -off_t position; /* position within file to read or write */ +u64_t position; /* position within file to read or write */ unsigned off; /* off within the current block */ int chunk; /* number of bytes to read or write */ unsigned left; /* max number of bytes wanted after position */ @@ -263,11 +257,13 @@ int *completed; /* number of bytes copied */ block_spec = (rip->i_mode & I_TYPE) == I_BLOCK_SPECIAL; if (block_spec) { - b = position/block_size; + b = div64u(position, block_size); dev = (dev_t) rip->i_zone[0]; } else { - b = read_map(rip, position); + if (ex64hi(position) != 0) + panic(__FILE__, "rw_chunk: position too high", NO_NUM); + b = read_map(rip, ex64lo(position)); dev = rip->i_dev; } @@ -279,7 +275,8 @@ int *completed; /* number of bytes copied */ } else { /* Writing to a nonexistent block. Create and enter in inode.*/ - if ((bp= new_block(rip, position)) == NIL_BUF)return(err_code); + if ((bp= new_block(rip, ex64lo(position))) == NIL_BUF) + return(err_code); } } else if (rw_flag == READING) { @@ -292,7 +289,8 @@ int *completed; /* number of bytes copied */ * the cache, acquire it, otherwise just acquire a free buffer. */ n = (chunk == block_size ? NO_READ : NORMAL); - if (!block_spec && off == 0 && position >= rip->i_size) n = NO_READ; + if (!block_spec && off == 0 && ex64lo(position) >= rip->i_size) + n = NO_READ; bp = get_block(dev, b, n); } @@ -302,7 +300,7 @@ int *completed; /* number of bytes copied */ } if (rw_flag == WRITING && chunk != block_size && !block_spec && - position >= rip->i_size && off == 0) { + ex64lo(position) >= rip->i_size && off == 0) { zero_block(bp); } @@ -439,7 +437,7 @@ PUBLIC void read_ahead() block_size = get_block_size(rip->i_dev); rdahed_inode = NIL_INODE; /* turn off read ahead */ if ( (b = read_map(rip, rdahedpos)) == NO_BLOCK) return; /* at EOF */ - bp = rahead(rip, b, rdahedpos, block_size); + bp = rahead(rip, b, cvul64(rdahedpos), block_size); put_block(bp, PARTIAL_DATA_BLOCK); } @@ -449,7 +447,7 @@ PUBLIC void read_ahead() PUBLIC struct buf *rahead(rip, baseblock, position, bytes_ahead) register struct inode *rip; /* pointer to inode for file to be read */ block_t baseblock; /* block at current position */ -off_t position; /* position within file */ +u64_t position; /* position within file */ unsigned bytes_ahead; /* bytes beyond position for immediate use */ { /* Fetch a block from the cache or the device. If a physical read is @@ -502,8 +500,8 @@ unsigned bytes_ahead; /* bytes beyond position for immediate use */ * indirect blocks (but don't call read_map!). */ - fragment = position % block_size; - position -= fragment; + fragment = rem64u(position, block_size); + position= sub64u(position, fragment); bytes_ahead += fragment; blocks_ahead = (bytes_ahead + block_size - 1) / block_size; @@ -511,13 +509,14 @@ unsigned bytes_ahead; /* bytes beyond position for immediate use */ if (block_spec && rip->i_size == 0) { blocks_left = NR_IOREQS; } else { - blocks_left = (rip->i_size - position + block_size - 1) / block_size; + blocks_left = (rip->i_size - ex64lo(position) + block_size - 1) / + block_size; /* Go for the first indirect block if we are in its neighborhood. */ if (!block_spec) { scale = rip->i_sp->s_log_zone_size; ind1_pos = (off_t) rip->i_ndzones * (block_size << scale); - if (position <= ind1_pos && rip->i_size > ind1_pos) { + if (ex64lo(position) <= ind1_pos && rip->i_size > ind1_pos) { blocks_ahead++; blocks_left++; } diff --git a/servers/mfs/super.c b/servers/mfs/super.c index bc94da198..23272ef3a 100644 --- a/servers/mfs/super.c +++ b/servers/mfs/super.c @@ -14,6 +14,7 @@ #include "fs.h" #include #include +#include #include "buf.h" #include "inode.h" #include "super.h" @@ -224,7 +225,7 @@ register struct super_block *sp; /* pointer to a superblock */ panic(__FILE__,"request for super_block of NO_DEV", NO_NUM); r = block_dev_io(DEV_READ, dev, SELF_E, - sbbuf, SUPER_BLOCK_BYTES, _MIN_BLOCK_SIZE, 0); + sbbuf, cvu64(SUPER_BLOCK_BYTES), _MIN_BLOCK_SIZE, 0); if (r != _MIN_BLOCK_SIZE) { printf("MFSread_super r != _MIN_BLOCK_SIZE\n"); return EINVAL; @@ -312,6 +313,13 @@ printf("MFSread_super block_sizr % INODE_SIZE notOK \n"); return EINVAL; } + /* Limit s_max_size to LONG_MAX */ + if ((unsigned long)sp->s_max_size > LONG_MAX) + { + printf("read_super: reducing s_max_size to LONG_MAX\n"); + sp->s_max_size= LONG_MAX; + } + sp->s_isearch = 0; /* inode searches initially start at 0 */ sp->s_zsearch = 0; /* zone searches initially start at 0 */ sp->s_version = version; diff --git a/servers/mfs/table.c b/servers/mfs/table.c index 1db0b907d..a86739fb9 100644 --- a/servers/mfs/table.c +++ b/servers/mfs/table.c @@ -59,5 +59,6 @@ PUBLIC _PROTOTYPE (int (*fs_call_vec[]), (void) ) = { fs_breadwrite, /* 38 */ fs_breadwrite, /* 39 */ fs_getdents, /* 40 */ + fs_flush, /* 41 */ }; diff --git a/servers/vfs/device.c b/servers/vfs/device.c index 914af39b0..efe4441e6 100644 --- a/servers/vfs/device.c +++ b/servers/vfs/device.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "file.h" #include "fproc.h" @@ -415,17 +416,18 @@ int bytes; /* how many bytes to transfer */ /*===========================================================================* * dev_io * *===========================================================================*/ -PUBLIC int dev_io(op, dev, proc_e, buf, pos, bytes, flags) +PUBLIC int dev_io(op, dev, proc_e, buf, posX, bytes, flags) int op; /* DEV_READ, DEV_WRITE, DEV_IOCTL, etc. */ dev_t dev; /* major-minor device number */ int proc_e; /* in whose address space is buf? */ void *buf; /* virtual address of the buffer */ -off_t pos; /* byte position */ +u64_t posX; /* byte position */ int bytes; /* how many bytes to transfer */ int flags; /* special flags, like O_NONBLOCK */ { /* Read or write from a device. The parameter 'dev' tells which one. */ struct dmap *dp; + off_t pos; message dev_mess; cp_grant_id_t gid = GRANT_INVALID; static cp_grant_id_t gids[NR_IOREQS]; @@ -433,6 +435,10 @@ int flags; /* special flags, like O_NONBLOCK */ void *buf_used; endpoint_t ioproc; + if (ex64hi(posX) != 0) + panic(__FILE__, "dev_io: postition too high", NO_NUM); + pos= ex64lo(posX); + /* Determine task dmap. */ dp = &dmap[(dev >> MAJOR) & BYTE]; orig_op = op; @@ -648,7 +654,7 @@ PUBLIC int do_ioctl() && (vp->v_mode & I_TYPE) != I_BLOCK_SPECIAL) return(ENOTTY); dev = (dev_t) vp->v_sdev; - return(dev_io(DEV_IOCTL, dev, who_e, m_in.ADDRESS, 0L, + return(dev_io(DEV_IOCTL, dev, who_e, m_in.ADDRESS, cvu64(0), m_in.REQUEST, f->filp_flags)); } diff --git a/servers/vfs/exec.c b/servers/vfs/exec.c index 10ca92d90..6b2174a6f 100644 --- a/servers/vfs/exec.c +++ b/servers/vfs/exec.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -400,7 +401,7 @@ int *hdrlenp; req.inode_nr = vp->v_inode_nr; req.user_e = FS_PROC_NR; req.seg = D; - req.pos = pos; + req.pos = cvul64(pos); req.num_of_bytes = sizeof(hdr); req.user_addr = (char*)&hdr; req.inode_index = vp->v_index; @@ -475,7 +476,7 @@ vir_bytes *stk_bytes; /* size of initial stack */ req.inode_nr = vp->v_inode_nr; req.user_e = FS_PROC_NR; req.seg = D; - req.pos = pos; + req.pos = cvul64(pos); req.num_of_bytes = _MAX_BLOCK_SIZE; req.user_addr = buf; req.inode_index = vp->v_index; @@ -636,7 +637,7 @@ phys_bytes seg_bytes; /* how much is to be transferred? */ req.inode_nr = vp->v_inode_nr; req.user_e = proc_e; req.seg = seg; - req.pos = off; + req.pos = cvul64(off); req.num_of_bytes = seg_bytes; req.user_addr = 0; req.inode_index = vp->v_index; diff --git a/servers/vfs/file.h b/servers/vfs/file.h index 4b1e692f4..74552a58e 100644 --- a/servers/vfs/file.h +++ b/servers/vfs/file.h @@ -10,7 +10,7 @@ EXTERN struct filp { struct vnode *filp_vno; - off_t filp_pos; /* file position */ + u64_t filp_pos; /* file position */ /* the following fields are for select() and are owned by the generic * select() code (i.e., fd-type-specific select() code can't touch these). diff --git a/servers/vfs/filedes.c b/servers/vfs/filedes.c index 4b137c969..b070e517d 100644 --- a/servers/vfs/filedes.c +++ b/servers/vfs/filedes.c @@ -9,6 +9,7 @@ */ #include +#include #include "fs.h" #include "file.h" @@ -47,7 +48,7 @@ PUBLIC int get_fd(int start, mode_t bits, int *k, struct filp **fpt) for (f = &filp[0]; f < &filp[NR_FILPS]; f++) { if (f->filp_count == 0) { f->filp_mode = bits; - f->filp_pos = 0L; + f->filp_pos = cvu64(0); f->filp_selectors = 0; f->filp_select_ops = 0; f->filp_pipe_select_ops = 0; diff --git a/servers/vfs/lock.c b/servers/vfs/lock.c index d8e93cb49..6a3233a1c 100644 --- a/servers/vfs/lock.c +++ b/servers/vfs/lock.c @@ -7,6 +7,7 @@ #include "fs.h" #include +#include #include #include #include "file.h" @@ -50,7 +51,13 @@ int req; /* either F_SETLK or F_SETLKW */ /* Compute the first and last bytes in the lock region. */ switch (flock.l_whence) { case SEEK_SET: first = 0; break; - case SEEK_CUR: first = f->filp_pos; break; + case SEEK_CUR: + if (ex64hi(f->filp_pos) != 0) + { + panic(__FILE__, "lock_op: position in file too high", + NO_NUM); + } + first = ex64lo(f->filp_pos); break; case SEEK_END: first = f->filp_vno->v_size; break; default: return(EINVAL); } diff --git a/servers/vfs/misc.c b/servers/vfs/misc.c index 7ad28ca57..87729f0ae 100644 --- a/servers/vfs/misc.c +++ b/servers/vfs/misc.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include "file.h" @@ -231,7 +232,14 @@ PUBLIC int do_fcntl() /* Figure out starting position base. */ switch(flock_arg.l_whence) { case SEEK_SET: start = 0; if(offset < 0) return EINVAL; break; - case SEEK_CUR: start = f->filp_pos; break; + case SEEK_CUR: + if (ex64hi(f->filp_pos) != 0) + { + panic(__FILE__, + "do_fcntl: position in file too high", + NO_NUM); + } + start = ex64lo(f->filp_pos); break; case SEEK_END: start = f->filp_vno->v_size; break; default: return EINVAL; } diff --git a/servers/vfs/mount.c b/servers/vfs/mount.c index fd59686f1..5639da98d 100644 --- a/servers/vfs/mount.c +++ b/servers/vfs/mount.c @@ -77,7 +77,7 @@ PUBLIC int do_mount() /* FS process' endpoint number */ fs_e = (unsigned long)m_in.m1_p3; - + /* Do the actual job */ r = mount_fs(fs_e); diff --git a/servers/vfs/open.c b/servers/vfs/open.c index cd8a0ea1b..a8966d592 100644 --- a/servers/vfs/open.c +++ b/servers/vfs/open.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "file.h" #include "fproc.h" #include "lock.h" @@ -30,7 +31,8 @@ #include "vnode.h" #include "vmnt.h" -#define offset m2_l1 +#define offset_lo m2_l1 +#define offset_high m2_l2 FORWARD _PROTOTYPE( int common_open, (int oflags, mode_t omode) ); @@ -248,9 +250,9 @@ printf("the root FS...\n"); /* Nobody else found. Restore filp. */ fil_ptr->filp_count = 1; if (fil_ptr->filp_mode == R_BIT) - fil_ptr->filp_pos = vp->v_pipe_rd_pos; + fil_ptr->filp_pos = cvul64(vp->v_pipe_rd_pos); else - fil_ptr->filp_pos = vp->v_pipe_wr_pos; + fil_ptr->filp_pos = cvul64(vp->v_pipe_wr_pos); } } break; @@ -399,7 +401,61 @@ PUBLIC int do_lseek() { /* Perform the lseek(ls_fd, offset, whence) system call. */ register struct filp *rfilp; - register off_t pos; + int r; + long offset; + u64_t pos, newpos; + struct node_req req; + + /* Check to see if the file descriptor is valid. */ + if ( (rfilp = get_filp(m_in.ls_fd)) == NIL_FILP) return(err_code); + + /* No lseek on pipes. */ + if (rfilp->filp_vno->v_pipe == I_PIPE) return(ESPIPE); + + /* The value of 'whence' determines the start position to use. */ + switch(m_in.whence) { + case SEEK_SET: pos = cvu64(0); break; + case SEEK_CUR: pos = rfilp->filp_pos; break; + case SEEK_END: pos = cvul64(rfilp->filp_vno->v_size); break; + default: return(EINVAL); + } + + offset= m_in.offset_lo; + if (offset >= 0) + newpos= add64ul(pos, offset); + else + newpos= sub64ul(pos, -offset); + + /* Check for overflow. */ + if (ex64hi(newpos) != 0) + return EINVAL; + + if (cmp64(newpos, rfilp->filp_pos) != 0) { /* Inhibit read ahead request */ + /* Fill in request message */ + req.fs_e = rfilp->filp_vno->v_fs_e; + req.inode_nr = rfilp->filp_vno->v_inode_nr; + + /* Issue request */ + if ((r = req_inhibread(&req)) != OK) return r; + } + + rfilp->filp_pos = newpos; + + /* insert the new position into the output message */ + m_out.reply_l1 = ex64lo(newpos); + + return(OK); +} + + +/*===========================================================================* + * do_llseek * + *===========================================================================*/ +PUBLIC int do_llseek() +{ +/* Perform the llseek(ls_fd, offset, whence) system call. */ + register struct filp *rfilp; + u64_t pos, newpos; struct node_req req; int r; @@ -411,20 +467,21 @@ PUBLIC int do_lseek() /* The value of 'whence' determines the start position to use. */ switch(m_in.whence) { - case SEEK_SET: pos = 0; break; + case SEEK_SET: pos = cvu64(0); break; case SEEK_CUR: pos = rfilp->filp_pos; break; - case SEEK_END: pos = rfilp->filp_vno->v_size; break; + case SEEK_END: pos = cvul64(rfilp->filp_vno->v_size); break; default: return(EINVAL); } + newpos= add64(pos, make64(m_in.offset_lo, m_in.offset_high)); + /* Check for overflow. */ - if (((long)m_in.offset > 0) && ((long)(pos + m_in.offset) < (long)pos)) + if (((long)m_in.offset_high > 0) && cmp64(newpos, pos) < 0) return(EINVAL); - if (((long)m_in.offset < 0) && ((long)(pos + m_in.offset) > (long)pos)) + if (((long)m_in.offset_high < 0) && cmp64(newpos, pos) > 0) return(EINVAL); - pos = pos + m_in.offset; - if (pos != rfilp->filp_pos) { /* Inhibit read ahead request */ + if (cmp64(newpos, rfilp->filp_pos) != 0) { /* Inhibit read ahead request */ /* Fill in request message */ req.fs_e = rfilp->filp_vno->v_fs_e; req.inode_nr = rfilp->filp_vno->v_inode_nr; @@ -433,8 +490,9 @@ PUBLIC int do_lseek() if ((r = req_inhibread(&req)) != OK) return r; } - rfilp->filp_pos = pos; - m_out.reply_l1 = pos; /* insert the long into the output message */ + rfilp->filp_pos = newpos; + m_out.reply_l1 = ex64lo(newpos); + m_out.reply_l2 = ex64hi(newpos); return(OK); } @@ -474,11 +532,16 @@ int fd_nr; if (mode_word == I_CHAR_SPECIAL || mode_word == I_BLOCK_SPECIAL) { dev = (dev_t) vp->v_sdev; if (mode_word == I_BLOCK_SPECIAL) { - /* Invalidate cache entries unless special is mounted - * or ROOT - */ - req_sync(vp->v_bfs_e); -printf("VFSclose: closed block spec %d\n", dev); +printf("VFSclose: closing block spec 0x%x\n", dev); + if (vp->v_bfs_e == ROOT_FS_E) + { + /* Invalidate the cache unless the special is + * mounted. Assume that the root filesystem's + * is open only for fsck. + */ +printf("VFSclose: flushing block spec 0x%x\n", dev); + req_flush(vp->v_bfs_e, dev); + } } /* Do any special processing on device close. */ dev_close(dev); @@ -498,9 +561,9 @@ printf("VFSclose: closed block spec %d\n", dev); * The read and write positions are saved separately. */ if (rfilp->filp_mode == R_BIT) - vp->v_pipe_rd_pos = rfilp->filp_pos; + vp->v_pipe_rd_pos = ex64lo(rfilp->filp_pos); else - vp->v_pipe_wr_pos = rfilp->filp_pos; + vp->v_pipe_wr_pos = ex64lo(rfilp->filp_pos); } else { diff --git a/servers/vfs/pipe.c b/servers/vfs/pipe.c index 430f97f61..af327dc51 100644 --- a/servers/vfs/pipe.c +++ b/servers/vfs/pipe.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include "file.h" @@ -136,7 +137,7 @@ register struct vnode *vp; /* the inode of the pipe */ int rw_flag; /* READING or WRITING */ int oflags; /* flags set by open or fcntl */ register int bytes; /* bytes to be read or written (all chunks) */ -register off_t position; /* current file position */ +u64_t position; /* current file position */ int *canwrite; /* return: number of bytes we can write */ int notouch; /* check only */ { @@ -145,10 +146,15 @@ int notouch; /* check only */ * and there is no writer, return 0 bytes. If a process is writing to a * pipe and no one is reading from it, give a broken pipe error. */ + off_t pos; + + if (ex64hi(position) != 0) + panic(__FILE__, "pipe_check: position too large in pipe", NO_NUM); + pos= ex64lo(position); /* If reading, check for empty pipe. */ if (rw_flag == READING) { - if (position >= vp->v_size) { + if (pos >= vp->v_size) { /* Process is reading from an empty pipe. */ int r = 0; if (find_filp(vp, W_BIT) != NIL_FILP) { @@ -176,7 +182,7 @@ int notouch; /* check only */ return(EPIPE); } - if (position + bytes > PIPE_SIZE(vp->v_vmnt->m_block_size)) { + if (pos + bytes > PIPE_SIZE(vp->v_vmnt->m_block_size)) { if ((oflags & O_NONBLOCK) && bytes <= PIPE_SIZE(vp->v_vmnt->m_block_size)) { return(EAGAIN); @@ -184,7 +190,7 @@ int notouch; /* check only */ else if ((oflags & O_NONBLOCK) && bytes > PIPE_SIZE(vp->v_vmnt->m_block_size)) { if ( (*canwrite = (PIPE_SIZE(vp->v_vmnt->m_block_size) - - position)) > 0) { + - pos)) > 0) { /* Do a partial write. Need to wakeup reader */ if (!notouch) release(vp, READ, susp_count); @@ -195,7 +201,7 @@ int notouch; /* check only */ } if (bytes > PIPE_SIZE(vp->v_vmnt->m_block_size)) { if ((*canwrite = PIPE_SIZE(vp->v_vmnt->m_block_size) - - position) > 0) { + - pos) > 0) { /* Do a partial write. Need to wakeup reader * since we'll suspend ourself in read_write() */ @@ -210,7 +216,7 @@ int notouch; /* check only */ } /* Writing to an empty pipe. Search for suspended reader. */ - if (position == 0 && !notouch) + if (pos == 0 && !notouch) release(vp, READ, susp_count); } diff --git a/servers/vfs/proto.h b/servers/vfs/proto.h index f117a2470..c886cea90 100644 --- a/servers/vfs/proto.h +++ b/servers/vfs/proto.h @@ -15,7 +15,7 @@ _PROTOTYPE( void dev_close, (Dev_t dev) ); _PROTOTYPE( int dev_bio, (int op, Dev_t dev, int proc, void *buf, off_t pos, int bytes) ); _PROTOTYPE( int dev_io, (int op, Dev_t dev, int proc, void *buf, - off_t pos, int bytes, int flags) ); + u64_t pos, int bytes, int flags) ); _PROTOTYPE( int gen_opcl, (int op, Dev_t dev, int proc, int flags) ); _PROTOTYPE( int gen_io, (int task_nr, message *mess_ptr) ); _PROTOTYPE( int no_dev, (int op, Dev_t dev, int proc, int flags) ); @@ -92,6 +92,7 @@ _PROTOTYPE( int do_close, (void) ); _PROTOTYPE( int close_fd, (struct fproc *rfp, int fd_nr) ); _PROTOTYPE( int do_creat, (void) ); _PROTOTYPE( int do_lseek, (void) ); +_PROTOTYPE( int do_llseek, (void) ); _PROTOTYPE( int do_mknod, (void) ); _PROTOTYPE( int do_mkdir, (void) ); _PROTOTYPE( int do_open, (void) ); @@ -105,7 +106,7 @@ _PROTOTYPE( int do_pipe, (void) ); _PROTOTYPE( int do_unpause, (void) ); _PROTOTYPE( int unpause, (int proc_nr_e) ); _PROTOTYPE( int pipe_check, (struct vnode *vp, int rw_flag, - int oflags, int bytes, off_t position, int *canwrite, int notouch)); + int oflags, int bytes, u64_t position, int *canwrite, int notouch)); _PROTOTYPE( void release, (struct vnode *vp, int call_nr, int count) ); _PROTOTYPE( void revive, (int proc_nr, int bytes) ); _PROTOTYPE( void suspend, (int task) ); @@ -168,6 +169,7 @@ _PROTOTYPE( int req_breadwrite, (breadwrite_req_t *req, readwrite_res_t *res) ); _PROTOTYPE( int req_getdents, (endpoint_t fs_e, ino_t inode_nr, off_t pos, cp_grant_id_t gid, size_t size, off_t *pos_change) ); +_PROTOTYPE( int req_flush, (endpoint_t fs_e, Dev_t) ); /* stadir.c */ _PROTOTYPE( int do_chdir, (void) ); diff --git a/servers/vfs/read.c b/servers/vfs/read.c index d860f6ac0..3f755cfeb 100644 --- a/servers/vfs/read.c +++ b/servers/vfs/read.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "file.h" #include "fproc.h" #include "param.h" @@ -44,7 +45,8 @@ int rw_flag; /* READING or WRITING */ /* Perform read(fd, buffer, nbytes) or write(fd, buffer, nbytes) call. */ register struct filp *f; register struct vnode *vp; - off_t bytes_left, f_size, position; + off_t bytes_left, f_size; + u64_t position; unsigned int off, cum_io; int op, oflags, r, chunk, usr, seg, block_spec, char_spec; int regular, partial_pipe = 0, partial_cnt = 0; @@ -85,10 +87,12 @@ int rw_flag; /* READING or WRITING */ /* check if user process has the memory it needs. * if not, copying will fail later. * do this after 0-check above because umap doesn't want to map 0 bytes. */ - if ((r = sys_umap(usr, seg, (vir_bytes) m_in.buffer, m_in.nbytes, &p)) != OK) { + if ((r = sys_umap(usr, seg, (vir_bytes) m_in.buffer, m_in.nbytes, &p)) != OK) + { printf("VFS: read_write: umap failed for process %d\n", usr); return r; } + position = f->filp_pos; oflags = f->filp_flags; @@ -129,7 +133,7 @@ int rw_flag; /* READING or WRITING */ r = dev_io(op, dev, usr, m_in.buffer, position, m_in.nbytes, oflags); if (r >= 0) { cum_io = r; - position += r; + position = add64ul(position, r); r = OK; } } @@ -154,12 +158,13 @@ int rw_flag; /* READING or WRITING */ /* Regular files */ else { if (rw_flag == WRITING && block_spec == 0) { + /* Check for O_APPEND flag. */ + if (oflags & O_APPEND) position = cvul64(f_size); + /* Check in advance to see if file will grow too big. */ - if (position > vp->v_vmnt->m_max_file_size - m_in.nbytes) + if (cmp64ul(position, vp->v_vmnt->m_max_file_size - m_in.nbytes) > 0) return(EFBIG); - /* Check for O_APPEND flag. */ - if (oflags & O_APPEND) position = f_size; } /* Pipes are a little different. Check. */ @@ -190,24 +195,39 @@ int rw_flag; /* READING or WRITING */ /* Issue request */ r = req_readwrite(&req, &res); - position = res.new_pos; - cum_io += res.cum_io; + if (r >= 0) + { + if (ex64hi(res.new_pos)) + panic(__FILE__, "read_write: bad new pos", NO_NUM); + + position = res.new_pos; + cum_io += res.cum_io; + } } /* On write, update file size and access time. */ if (rw_flag == WRITING) { if (regular || mode_word == I_DIRECTORY) { - if (position > f_size) vp->v_size = position; + if (cmp64ul(position, f_size) > 0) + { + if (ex64hi(position) != 0) + { + panic(__FILE__, + "read_write: file size too big for v_size", + NO_NUM); + } + vp->v_size = ex64lo(position); + } } } else { if (vp->v_pipe == I_PIPE) { - if (position >= vp->v_size) { + if (cmp64ul(position, vp->v_size) >= 0) { /* Reset pipe pointers */ vp->v_size = 0; - position = 0; + position = cvu64(0); wf = find_filp(vp, W_BIT); - if (wf != NIL_FILP) wf->filp_pos = 0; + if (wf != NIL_FILP) wf->filp_pos = cvu64(0); } } } @@ -319,13 +339,16 @@ PUBLIC int do_getdents() if (gid < 0) panic(__FILE__, "cpf_grant_magic failed", gid); /* Issue request */ + if (ex64hi(rfilp->filp_pos) != 0) + panic(__FILE__, "do_getdents: should handle large offsets", NO_NUM); + r= req_getdents(rfilp->filp_vno->v_fs_e, rfilp->filp_vno->v_inode_nr, - rfilp->filp_pos, gid, m_in.nbytes, &pos_change); + ex64lo(rfilp->filp_pos), gid, m_in.nbytes, &pos_change); cpf_revoke(gid); if (r > 0) - rfilp->filp_pos += pos_change; + rfilp->filp_pos= add64ul(rfilp->filp_pos, pos_change); return r; } diff --git a/servers/vfs/request.c b/servers/vfs/request.c index cb7bc69a8..28d850f11 100644 --- a/servers/vfs/request.c +++ b/servers/vfs/request.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -118,13 +119,16 @@ readwrite_res_t *res; { int r; message m; + + if (ex64hi(req->pos) != 0) + panic(__FILE__, "req_readwrite: pos too large", NO_NUM); /* Fill in request message */ m.m_type = req->rw_flag == READING ? REQ_READ : REQ_WRITE; m.REQ_FD_INODE_NR = req->inode_nr; m.REQ_FD_WHO_E = req->user_e; m.REQ_FD_SEG = req->seg; - m.REQ_FD_POS = req->pos; + m.REQ_FD_POS = ex64lo(req->pos); m.REQ_FD_NBYTES = req->num_of_bytes; m.REQ_FD_USER_ADDR = req->user_addr; m.REQ_FD_INODE_INDEX = req->inode_index; @@ -133,7 +137,7 @@ readwrite_res_t *res; if ((r = fs_sendrec(req->fs_e, &m)) != OK) return r; /* Fill in response structure */ - res->new_pos = m.RES_FD_POS; + res->new_pos = cvul64(m.RES_FD_POS); res->cum_io = m.RES_FD_CUM_IO; return OK; @@ -810,22 +814,23 @@ readwrite_res_t *res; { int r; message m; - + /* Fill in request message */ m.m_type = req->rw_flag == READING ? REQ_BREAD : REQ_BWRITE; - m.REQ_FD_BDEV = req->dev; - m.REQ_FD_BLOCK_SIZE = req->blocksize; - m.REQ_FD_WHO_E = req->user_e; - m.REQ_FD_POS = req->pos; - m.REQ_FD_NBYTES = req->num_of_bytes; - m.REQ_FD_USER_ADDR = req->user_addr; + m.REQ_XFD_BDEV = req->dev; + m.REQ_XFD_BLOCK_SIZE = req->blocksize; + m.REQ_XFD_WHO_E = req->user_e; + m.REQ_XFD_POS_LO = ex64lo(req->pos); + m.REQ_XFD_POS_HI = ex64hi(req->pos); + m.REQ_XFD_NBYTES = req->num_of_bytes; + m.REQ_XFD_USER_ADDR = req->user_addr; /* Send/rec request */ if ((r = fs_sendrec(req->fs_e, &m)) != OK) return r; /* Fill in response structure */ - res->new_pos = m.RES_FD_POS; - res->cum_io = m.RES_FD_CUM_IO; + res->new_pos = make64(m.RES_XFD_POS_LO, m.RES_XFD_POS_HI); + res->cum_io = m.RES_XFD_CUM_IO; return OK; } @@ -854,6 +859,24 @@ off_t *pos_change; } +/*===========================================================================* + * req_flush * + *===========================================================================*/ +PUBLIC int req_flush(fs_e, dev) +endpoint_t fs_e; +dev_t dev; +{ + message m; + + /* Fill in request message */ + m.m_type = REQ_FLUSH; + m.REQ_DEV = dev; + + /* Send/rec request */ + return fs_sendrec(fs_e, &m); +} + + #if 0 /* Wrapper pattern: */ /*===========================================================================* diff --git a/servers/vfs/request.h b/servers/vfs/request.h index 16795f342..a41a278f5 100644 --- a/servers/vfs/request.h +++ b/servers/vfs/request.h @@ -51,7 +51,7 @@ typedef struct readwrite_req { ino_t inode_nr; unsigned short inode_index; int seg; - off_t pos; + u64_t pos; unsigned int num_of_bytes; char *user_addr; } readwrite_req_t; @@ -59,7 +59,7 @@ typedef struct readwrite_req { /* Structure for response of REQ_READ and REQ_WRITE */ typedef struct readwrite_res { - off_t new_pos; + u64_t new_pos; unsigned int cum_io; } readwrite_res_t; @@ -311,7 +311,7 @@ typedef struct breadwrite_req { endpoint_t user_e; endpoint_t driver_e; dev_t dev; - off_t pos; + u64_t pos; unsigned int num_of_bytes; char *user_addr; } breadwrite_req_t; diff --git a/servers/vfs/select.c b/servers/vfs/select.c index 44dd00a67..efb03949d 100644 --- a/servers/vfs/select.c +++ b/servers/vfs/select.c @@ -20,6 +20,7 @@ #include #include #include +#include #include /* max. number of simultaneously pending select() calls */ @@ -103,7 +104,8 @@ PRIVATE int select_request_general(struct filp *f, int *ops, int block) { int rops = *ops; if (block) rops |= SEL_NOTIFY; - *ops = dev_io(DEV_SELECT, f->filp_vno->v_sdev, rops, NULL, 0, 0, 0); + *ops = dev_io(DEV_SELECT, f->filp_vno->v_sdev, rops, NULL, cvu64(0), + 0, 0); if (*ops < 0) return SEL_ERR; return SEL_OK; diff --git a/servers/vfs/stadir.c b/servers/vfs/stadir.c index 91d2ee430..40889a3bf 100644 --- a/servers/vfs/stadir.c +++ b/servers/vfs/stadir.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "file.h" #include "fproc.h" @@ -257,7 +258,12 @@ PUBLIC int do_fstat() /* If we read from a pipe, send position too */ if (rfilp->filp_vno->v_pipe == I_PIPE) { if (rfilp->filp_mode & R_BIT) - pipe_pos = rfilp->filp_pos; + if (ex64hi(rfilp->filp_pos) != 0) + { + panic(__FILE__, "do_fstat: bad position in pipe", + NO_NUM); + } + pipe_pos = ex64lo(rfilp->filp_pos); } /* Fill in request message */