First cut at 64-bit file offsets in block devices for mkfs/fsck.

This commit is contained in:
Philip Homburg 2006-11-27 14:21:43 +00:00
parent 828e87862f
commit bafc45a309
35 changed files with 456 additions and 227 deletions

View File

@ -47,6 +47,7 @@
#include <minix/config.h> #include <minix/config.h>
#include <minix/const.h> #include <minix/const.h>
#include <minix/type.h> #include <minix/type.h>
#include <minix/u64.h>
#include "../../servers/mfs/const.h" #include "../../servers/mfs/const.h"
#include "../../servers/mfs/inode.h" #include "../../servers/mfs/inode.h"
#include "../../servers/mfs/type.h" #include "../../servers/mfs/type.h"
@ -93,10 +94,10 @@ static struct super_block sb;
#define STICKY_BIT 01000 /* not defined anywhere else */ #define STICKY_BIT 01000 /* not defined anywhere else */
/* Ztob gives the block address of a zone /* 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 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 SCALE ((int) ztob(1)) /* # blocks in a zone */
#define FIRST ((zone_nr) sb.s_firstdatazone) /* as the name says */ #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) #define NLEVEL (NR_ZONE_NUMS - NR_DZONE_NUM + 1)
/* Byte address of a zone/of an inode */ /* Byte address of a zone/of an inode */
#define zaddr(z) btoa(ztob(z)) #define cinoblock(i) (((i - 1)*INODE_SIZE) / block_size + BLK_ILIST)
#define cinoaddr(i) ((long) (i - 1) * INODE_SIZE + (long) btoa(BLK_ILIST)) #define cinooff(i) (((i - 1)*INODE_SIZE) % block_size)
#define INDCHUNK ((int) (CINDIR * ZONE_NUM_SIZE)) #define INDCHUNK ((int) (CINDIR * ZONE_NUM_SIZE))
#define DIRCHUNK ((int) (CDIRECT * DIR_ENTRY_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 devopen, (void));
_PROTOTYPE(void devclose, (void)); _PROTOTYPE(void devclose, (void));
_PROTOTYPE(void devio, (block_nr bno, int dir)); _PROTOTYPE(void devio, (block_nr bno, int dir));
_PROTOTYPE(void devread, (long offset, char *buf, int size)); _PROTOTYPE(void devread, (long block, long offset, char *buf, int size));
_PROTOTYPE(void devwrite, (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 pr, (char *fmt, int cnt, char *s, char *p));
_PROTOTYPE(void lpr, (char *fmt, long cnt, char *s, char *p)); _PROTOTYPE(void lpr, (char *fmt, long cnt, char *s, char *p));
_PROTOTYPE(bit_nr getnumber, (char *s)); _PROTOTYPE(bit_nr getnumber, (char *s));
@ -394,6 +395,8 @@ void devio(bno, dir)
block_nr bno; block_nr bno;
int dir; int dir;
{ {
int r;
if(!block_size) fatal("devio() with unknown block size"); if(!block_size) fatal("devio() with unknown block size");
if (dir == READING && bno == thisblk) return; if (dir == READING && bno == thisblk) return;
thisblk = bno; thisblk = bno;
@ -401,7 +404,9 @@ int dir;
#if 0 #if 0
printf("%s at block %5d\n", dir == READING ? "reading " : "writing", bno); printf("%s at block %5d\n", dir == READING ? "reading " : "writing", bno);
#endif #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 (dir == READING) {
if (read(dev, rwbuf, block_size) == block_size) if (read(dev, rwbuf, block_size) == block_size)
return; return;
@ -420,28 +425,44 @@ printf("%s at block %5d\n", dir == READING ? "reading " : "writing", bno);
fatal(""); fatal("");
} }
/* Read `size' bytes from the disk starting at byte `offset'. */ /* Read `size' bytes from the disk starting at block 'block' and
void devread(offset, buf, size) * byte `offset'.
*/
void devread(block, offset, buf, size)
long block;
long offset; long offset;
char *buf; char *buf;
int size; int size;
{ {
if(!block_size) fatal("devread() with unknown block size"); if(!block_size) fatal("devread() with unknown block size");
devio((block_nr) (offset / block_size), READING); if (offset >= block_size)
memmove(buf, &rwbuf[(int) (offset % block_size)], (size_t)size); /* lint but OK */ {
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'. */ /* Write `size' bytes to the disk starting at block 'block' and
void devwrite(offset, buf, size) * byte `offset'.
*/
void devwrite(block, offset, buf, size)
long block;
long offset; long offset;
char *buf; char *buf;
int size; int size;
{ {
if(!block_size) fatal("devwrite() with unknown block size"); if(!block_size) fatal("devwrite() with unknown block size");
if (!repair) fatal("internal error (devwrite)"); if (!repair) fatal("internal error (devwrite)");
if (size != block_size) devio((block_nr) (offset / block_size), READING); if (offset >= block_size)
memmove(&rwbuf[(int) (offset % block_size)], buf, (size_t)size); /* lint but OK */ {
devio((block_nr) (offset / block_size), WRITING); block += offset/block_size;
offset %= block_size;
}
if (size != block_size) devio(block, READING);
memmove(&rwbuf[offset], buf, size);
devio(block, WRITING);
changed = 1; changed = 1;
} }
@ -518,7 +539,7 @@ void lsuper()
printf("block size = %ld", sb.s_block_size); printf("block size = %ld", sb.s_block_size);
if (input(buf, 80)) sb.s_block_size = atol(buf); if (input(buf, 80)) sb.s_block_size = atol(buf);
if (yes("ok now")) { if (yes("ok now")) {
devwrite(OFFSET_SUPER_BLOCK, (char *) &sb, sizeof(sb)); devwrite(0, OFFSET_SUPER_BLOCK, (char *) &sb, sizeof(sb));
return; return;
} }
} while (yes("Do you want to try again")); } while (yes("Do you want to try again"));
@ -601,10 +622,17 @@ void chksuper()
} }
} }
int inoaddr(int inn) int inoblock(int inn)
{ {
int a; int a;
a = cinoaddr(inn); a = cinoblock(inn);
return a;
}
int inooff(int inn)
{
int a;
a = cinooff(inn);
return a; return a;
} }
@ -624,7 +652,7 @@ char **clist;
setbit(spec_imap, bit); setbit(spec_imap, bit);
ino = bit; ino = bit;
do { do {
devread(inoaddr(ino), (char *) ip, INODE_SIZE); devread(inoblock(ino), inooff(ino), (char *) ip, INODE_SIZE);
printf("inode %u:\n", ino); printf("inode %u:\n", ino);
printf(" mode = %6o", ip->i_mode); printf(" mode = %6o", ip->i_mode);
if (input(buf, 80)) ip->i_mode = atoo(buf); if (input(buf, 80)) ip->i_mode = atoo(buf);
@ -633,7 +661,8 @@ char **clist;
printf(" size = %6ld", ip->i_size); printf(" size = %6ld", ip->i_size);
if (input(buf, 80)) ip->i_size = atol(buf); if (input(buf, 80)) ip->i_size = atol(buf);
if (yes("Write this back")) { if (yes("Write this back")) {
devwrite(inoaddr(ino), (char *) ip, INODE_SIZE); devwrite(inoblock(ino), inooff(ino), (char *) ip,
INODE_SIZE);
break; break;
} }
} while (yes("Do you want to change it again")); } while (yes("Do you want to change it again"));
@ -662,7 +691,7 @@ int nblk;
p = bitmap; p = bitmap;
for (i = 0; i < nblk; i++, bno++, p += WORDS_PER_BLOCK) 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; *bitmap |= 1;
} }
@ -676,7 +705,7 @@ int nblk;
register bitchunk_t *p = bitmap; register bitchunk_t *p = bitmap;
for (i = 0; i < nblk; i++, bno++, p += WORDS_PER_BLOCK) 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. */ /* Set the bits given by `list' in the bitmap. */
@ -787,11 +816,12 @@ void chkilist()
printf("Checking inode list\n"); printf("Checking inode list\n");
do do
if (!bitset(imap, (bit_nr) ino)) { 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) { if (mode != I_NOT_ALLOC) {
printf("mode inode %u not cleared", ino); printf("mode inode %u not cleared", ino);
if (yes(". clear")) devwrite(inoaddr(ino), nullbuf, if (yes(". clear")) devwrite(inoblock(ino),
INODE_SIZE); inooff(ino), nullbuf, INODE_SIZE);
} }
} }
while (++ino <= sb.s_ninodes && ino != 0); while (++ino <= sb.s_ninodes && ino != 0);
@ -814,7 +844,7 @@ ino_t ino;
printf("INODE NLINK COUNT\n"); printf("INODE NLINK COUNT\n");
firstcnterr = 0; 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 */ count[ino] += inode.i_nlinks; /* it was already subtracted; add it back */
printf("%5u %5u %5u", ino, (unsigned) inode.i_nlinks, count[ino]); printf("%5u %5u %5u", ino, (unsigned) inode.i_nlinks, count[ino]);
if (yes(" adjust")) { if (yes(" adjust")) {
@ -823,7 +853,7 @@ ino_t ino;
inode.i_mode = I_NOT_ALLOC; inode.i_mode = I_NOT_ALLOC;
clrbit(imap, (bit_nr) ino); 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]; dir_struct dirblk[CDIRECT];
register dir_struct *dp; register dir_struct *dp;
register n, dirty; register n, dirty;
register long offset = zaddr(zno); long block= ztob(zno);
register long offset = 0;
register off_t size = 0; register off_t size = 0;
n = SCALE * (NR_DIR_ENTRIES(block_size) / CDIRECT); n = SCALE * (NR_DIR_ENTRIES(block_size) / CDIRECT);
do { do {
devread(offset, (char *) dirblk, DIRCHUNK); devread(block, offset, (char *) dirblk, DIRCHUNK);
dirty = 0; dirty = 0;
for (dp = dirblk; dp < &dirblk[CDIRECT]; dp++) { for (dp = dirblk; dp < &dirblk[CDIRECT]; dp++) {
if (dp->d_inum != NO_ENTRY && !chkentry(ino, pos, dp)) if (dp->d_inum != NO_ENTRY && !chkentry(ino, pos, dp))
@ -1096,7 +1127,7 @@ zone_nr zno;
pos += DIR_ENTRY_SIZE; pos += DIR_ENTRY_SIZE;
if (dp->d_inum != NO_ENTRY) size = pos; 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; offset += DIRCHUNK;
n--; n--;
} while (n > 0); } while (n > 0);
@ -1107,7 +1138,7 @@ zone_nr zno;
if (yes(". extend")) { if (yes(". extend")) {
setbit(spec_imap, (bit_nr) ino); setbit(spec_imap, (bit_nr) ino);
ip->i_size = size; ip->i_size = size;
devwrite(inoaddr(ino), (char *) ip, INODE_SIZE); devwrite(inoblock(ino), inooff(ino), (char *) ip, INODE_SIZE);
} }
} }
return(1); return(1);
@ -1120,14 +1151,14 @@ d_inode *ip;
off_t pos; off_t pos;
zone_nr zno; zone_nr zno;
{ {
long offset; long block;
size_t len; size_t len;
char target[PATH_MAX+1]; char target[PATH_MAX+1];
if (ip->i_size > PATH_MAX) if (ip->i_size > PATH_MAX)
fatal("chksymlinkzone: fsck program inconsistency\n"); fatal("chksymlinkzone: fsck program inconsistency\n");
offset = zaddr(zno); block= ztob(zno);
devread(offset, target, ip->i_size); devread(block, 0, target, ip->i_size);
target[ip->i_size]= '\0'; target[ip->i_size]= '\0';
len= strlen(target); len= strlen(target);
if (len != ip->i_size) if (len != ip->i_size)
@ -1138,7 +1169,8 @@ zone_nr zno;
if (yes(". update")) { if (yes(". update")) {
setbit(spec_imap, (bit_nr) ino); setbit(spec_imap, (bit_nr) ino);
ip->i_size = len; ip->i_size = len;
devwrite(inoaddr(ino), (char *) ip, INODE_SIZE); devwrite(inoblock(ino), inooff(ino),
(char *) ip, INODE_SIZE);
} }
} }
return 1; return 1;
@ -1201,10 +1233,11 @@ int level;
{ {
zone_nr indirect[CINDIR]; zone_nr indirect[CINDIR];
register n = NR_INDIRECTS / CINDIR; register n = NR_INDIRECTS / CINDIR;
register long offset = zaddr(zno); long block= ztob(zno);
register long offset = 0;
do { do {
devread(offset, (char *) indirect, INDCHUNK); devread(block, offset, (char *) indirect, INDCHUNK);
if (!chkzones(ino, ip, pos, indirect, CINDIR, level - 1)) return(0); if (!chkzones(ino, ip, pos, indirect, CINDIR, level - 1)) return(0);
offset += INDCHUNK; offset += INDCHUNK;
} while (--n && *pos < ip->i_size); } while (--n && *pos < ip->i_size);
@ -1442,14 +1475,15 @@ dir_struct *dp;
} }
visited = bitset(imap, (bit_nr) ino); visited = bitset(imap, (bit_nr) ino);
if (!visited || listing) { 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 (listing) list(ino, &inode);
if (!visited && !chkinode(ino, &inode)) { if (!visited && !chkinode(ino, &inode)) {
setbit(spec_imap, (bit_nr) ino); setbit(spec_imap, (bit_nr) ino);
if (yes("remove")) { if (yes("remove")) {
count[ino] += inode.i_nlinks - 1; count[ino] += inode.i_nlinks - 1;
clrbit(imap, (bit_nr) ino); 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)); memset((void *) dp, 0, sizeof(dir_struct));
ftop = ftop->st_next; ftop = ftop->st_next;
return(0); return(0);

View File

@ -317,12 +317,6 @@ char *argv[];
simple = 1; 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; nrblocks = blocks;
nrinodes = inodes; nrinodes = inodes;
@ -337,7 +331,7 @@ char *argv[];
testb = (short *) alloc_block(); testb = (short *) alloc_block();
/* Try writing the last block of partition or diskette. */ /* 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)"); pexit("couldn't seek to last block to test size (1)");
} }
testb[0] = 0x3245; testb[0] = 0x3245;
@ -349,7 +343,7 @@ char *argv[];
pexit("File system is too big for minor device (write)"); pexit("File system is too big for minor device (write)");
} }
sync(); /* flush write, so if error next read fails */ 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)"); pexit("couldn't seek to last block to test size (2)");
} }
testb[0] = 0; testb[0] = 0;
@ -358,9 +352,11 @@ char *argv[];
if (nread != block_size || testb[0] != 0x3245 || testb[1] != 0x11FF || if (nread != block_size || testb[0] != 0x3245 || testb[1] != 0x11FF ||
testb[block_size-1] != 0x1F2F) { testb[block_size-1] != 0x1F2F) {
if(nread < 0) perror("read"); 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)"); 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[0] = 0;
testb[1] = 0; testb[1] = 0;
if (write(fd, (char *) testb, block_size) != block_size) if (write(fd, (char *) testb, block_size) != block_size)
@ -1536,7 +1532,7 @@ char *buf;
copy(zero, buf, block_size); copy(zero, buf, block_size);
return; 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); k = read(fd, buf, block_size);
if (k != block_size) { if (k != block_size) {
pexit("get_block couldn't read"); pexit("get_block couldn't read");
@ -1569,7 +1565,7 @@ char *buf;
(void) read_and_set(n); (void) read_and_set(n);
/* XXX - check other lseeks too. */ /* 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"); pexit("put_block couldn't seek");
} }
if (write(fd, buf, block_size) != block_size) { if (write(fd, buf, block_size) != block_size) {

View File

@ -346,7 +346,7 @@ FORWARD _PROTOTYPE( int w_identify, (void) );
FORWARD _PROTOTYPE( char *w_name, (void) ); FORWARD _PROTOTYPE( char *w_name, (void) );
FORWARD _PROTOTYPE( int w_specify, (void) ); FORWARD _PROTOTYPE( int w_specify, (void) );
FORWARD _PROTOTYPE( int w_io_test, (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)); iovec_t *iov, unsigned nr_req, int safe));
FORWARD _PROTOTYPE( int com_out, (struct command *cmd) ); FORWARD _PROTOTYPE( int com_out, (struct command *cmd) );
FORWARD _PROTOTYPE( int com_out_ext, (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( int atapi_open, (void) );
FORWARD _PROTOTYPE( void atapi_close, (void) ); FORWARD _PROTOTYPE( void atapi_close, (void) );
FORWARD _PROTOTYPE( int atapi_transfer, (int proc_nr, int opcode, 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 #endif
/* Entry points to this driver. */ /* 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) if ((s=sys_insw(wn->base_cmd + REG_DATA, SELF, tmp_buf, SECTOR_SIZE)) != OK)
panic(w_name(),"Call to sys_insw() failed", s); panic(w_name(),"Call to sys_insw() failed", s);
#if 0
if (id_word(0) & ID_GEN_NOT_ATA) if (id_word(0) & ID_GEN_NOT_ATA)
{ {
printf("%s: not an ATA device?\n", w_name()); printf("%s: not an ATA device?\n", w_name());
return ERR; return ERR;
} }
#endif
/* This is an ATA device. */ /* This is an ATA device. */
wn->state |= SMART; wn->state |= SMART;
@ -1049,7 +1051,7 @@ PRIVATE int w_io_test(void)
if (w_prepare(w_drive * DEV_PER_DRIVE) == NIL_DEV) if (w_prepare(w_drive * DEV_PER_DRIVE) == NIL_DEV)
panic(w_name(), "Couldn't switch devices", NO_NUM); 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. */ /* Switch back. */
if (w_prepare(save_dev) == NIL_DEV) 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) PRIVATE int w_transfer(proc_nr, opcode, position, iov, nr_req, safe)
int proc_nr; /* process doing the request */ int proc_nr; /* process doing the request */
int opcode; /* DEV_GATHER or DEV_SCATTER */ 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 */ iovec_t *iov; /* pointer to read or write request vector */
unsigned nr_req; /* length of request vector */ unsigned nr_req; /* length of request vector */
int safe; /* iov contains addresses (0) or grants? */ 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; iovec_t *iop, *iov_end = iov + nr_req;
int n, r, s, errors, do_dma, do_write, do_copyout; int n, r, s, errors, do_dma, do_write, do_copyout;
unsigned long v, block, w_status; 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 cylinder, head, sector, nbytes;
unsigned dma_buf_offset; unsigned dma_buf_offset;
size_t addr_offset = 0; size_t addr_offset = 0;
@ -1213,7 +1215,7 @@ int safe; /* iov contains addresses (0) or grants? */
#endif #endif
/* Check disk address. */ /* Check disk address. */
if ((position & SECTOR_MASK) != 0) return(EINVAL); if (rem64u(position, SECTOR_SIZE) != 0) return(EINVAL);
errors = 0; errors = 0;
@ -1224,9 +1226,10 @@ int safe; /* iov contains addresses (0) or grants? */
if ((nbytes & SECTOR_MASK) != 0) return(EINVAL); if ((nbytes & SECTOR_MASK) != 0) return(EINVAL);
/* Which block on disk and how close to EOF? */ /* Which block on disk and how close to EOF? */
if (position >= dv_size) return(OK); /* At EOF */ if (cmp64(position, dv_size) >= 0) return(OK); /* At EOF */
if (position + nbytes > dv_size) nbytes = dv_size - position; if (cmp64(add64ul(position, nbytes), dv_size) > 0)
block = div64u(add64ul(w_dv->dv_base, position), SECTOR_SIZE); nbytes = diff64(dv_size, position);
block = div64u(add64(w_dv->dv_base, position), SECTOR_SIZE);
do_dma= wn->dma; do_dma= wn->dma;
do_write= (opcode == DEV_SCATTER); do_write= (opcode == DEV_SCATTER);
@ -1338,7 +1341,7 @@ int safe; /* iov contains addresses (0) or grants? */
/* Book the bytes successfully transferred. */ /* Book the bytes successfully transferred. */
nbytes -= n; nbytes -= n;
position += n; position= add64ul(position, n);
if ((iov->iov_size -= n) == 0) { if ((iov->iov_size -= n) == 0) {
iov++; nr_req--; addr_offset = 0; iov++; nr_req--; addr_offset = 0;
} }
@ -1412,7 +1415,7 @@ int safe; /* iov contains addresses (0) or grants? */
/* Book the bytes successfully transferred. */ /* Book the bytes successfully transferred. */
nbytes -= SECTOR_SIZE; nbytes -= SECTOR_SIZE;
position += SECTOR_SIZE; position= add64u(position, SECTOR_SIZE);
addr_offset += SECTOR_SIZE; addr_offset += SECTOR_SIZE;
if ((iov->iov_size -= SECTOR_SIZE) == 0) { if ((iov->iov_size -= SECTOR_SIZE) == 0) {
iov++; iov++;
@ -2113,7 +2116,7 @@ void sense_request(void)
PRIVATE int atapi_transfer(proc_nr, opcode, position, iov, nr_req, safe) PRIVATE int atapi_transfer(proc_nr, opcode, position, iov, nr_req, safe)
int proc_nr; /* process doing the request */ int proc_nr; /* process doing the request */
int opcode; /* DEV_GATHER or DEV_SCATTER */ 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 */ iovec_t *iov; /* pointer to read or write request vector */
unsigned nr_req; /* length of request vector */ unsigned nr_req; /* length of request vector */
int safe; /* use safecopies? */ int safe; /* use safecopies? */
@ -2123,7 +2126,7 @@ int safe; /* use safecopies? */
int r, s, errors, fresh; int r, s, errors, fresh;
u64_t pos; u64_t pos;
unsigned long block; 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; unsigned nbytes, nblocks, count, before, chunk;
static u8_t packet[ATAPI_PACKETSIZE]; static u8_t packet[ATAPI_PACKETSIZE];
size_t addr_offset = 0; 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 /* The Minix block size is smaller than the CD block size, so we
* may have to read extra before or after the good data. * 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); block = div64u(pos, CD_SECTOR_SIZE);
before = rem64u(pos, CD_SECTOR_SIZE); before = rem64u(pos, CD_SECTOR_SIZE);
@ -2152,8 +2155,9 @@ int safe; /* use safecopies? */
if ((before | nbytes) & 1) return(EINVAL); if ((before | nbytes) & 1) return(EINVAL);
/* Which block on disk and how close to EOF? */ /* Which block on disk and how close to EOF? */
if (position >= dv_size) return(OK); /* At EOF */ if (cmp64(position, dv_size) >= 0) return(OK); /* At EOF */
if (position + nbytes > dv_size) nbytes = dv_size - position; if (cmp64(add64ul(position, nbytes), dv_size) > 0)
nbytes = diff64(dv_size, position);
nblocks = (before + nbytes + CD_SECTOR_SIZE - 1) / CD_SECTOR_SIZE; nblocks = (before + nbytes + CD_SECTOR_SIZE - 1) / CD_SECTOR_SIZE;
if (ATAPI_DEBUG) { if (ATAPI_DEBUG) {
@ -2214,7 +2218,7 @@ int safe; /* use safecopies? */
} }
if (s != OK) if (s != OK)
panic(w_name(),"Call to sys_insw() failed", s); panic(w_name(),"Call to sys_insw() failed", s);
position += chunk; position= add64ul(position, chunk);
nbytes -= chunk; nbytes -= chunk;
count -= chunk; count -= chunk;
addr_offset += chunk; addr_offset += chunk;

View File

@ -68,7 +68,7 @@ PRIVATE cp_grant_id_t my_bios_grant_id;
_PROTOTYPE(int main, (void) ); _PROTOTYPE(int main, (void) );
FORWARD _PROTOTYPE( struct device *w_prepare, (int device) ); FORWARD _PROTOTYPE( struct device *w_prepare, (int device) );
FORWARD _PROTOTYPE( char *w_name, (void) ); 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) ); 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_open, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( int w_do_close, (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 * * 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 proc_nr; /* process doing the request */
int opcode; /* DEV_GATHER or DEV_SCATTER */ 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 */ iovec_t *iov; /* pointer to read or write request vector */
unsigned nr_req; /* length of request vector */ unsigned nr_req; /* length of request vector */
int safe; /* use safecopies? */ int safe; /* use safecopies? */
@ -216,6 +216,7 @@ int safe; /* use safecopies? */
size_t vir_offset = 0; size_t vir_offset = 0;
unsigned long dv_size = cv64ul(w_dv->dv_size); unsigned long dv_size = cv64ul(w_dv->dv_size);
unsigned secspcyl = wn->heads * wn->sectors; unsigned secspcyl = wn->heads * wn->sectors;
off_t position;
struct int13ext_rw { struct int13ext_rw {
u8_t len; u8_t len;
u8_t res1; u8_t res1;
@ -225,6 +226,10 @@ int safe; /* use safecopies? */
} i13e_rw; } i13e_rw;
struct reg86u reg86; struct reg86u reg86;
if (ex64hi(pos64))
panic(__FILE__, "should handle 64-bit offsets", NO_NUM);
position= ex64lo(pos64);
/* Check disk address. */ /* Check disk address. */
if ((position & SECTOR_MASK) != 0) return(EINVAL); if ((position & SECTOR_MASK) != 0) return(EINVAL);

View File

@ -247,7 +247,7 @@ FORWARD _PROTOTYPE( void f_timeout, (timer_t *tp) );
FORWARD _PROTOTYPE( struct device *f_prepare, (int device) ); FORWARD _PROTOTYPE( struct device *f_prepare, (int device) );
FORWARD _PROTOTYPE( char *f_name, (void) ); FORWARD _PROTOTYPE( char *f_name, (void) );
FORWARD _PROTOTYPE( void f_cleanup, (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) ); iovec_t *iov, unsigned nr_req, int) );
FORWARD _PROTOTYPE( int dma_setup, (int opcode) ); FORWARD _PROTOTYPE( int dma_setup, (int opcode) );
FORWARD _PROTOTYPE( void start_motor, (void) ); FORWARD _PROTOTYPE( void start_motor, (void) );
@ -433,10 +433,10 @@ PRIVATE void f_cleanup()
/*===========================================================================* /*===========================================================================*
* f_transfer * * 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 proc_nr; /* process doing the request */
int opcode; /* DEV_GATHER or DEV_SCATTER */ 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 */ iovec_t *iov; /* pointer to read or write request vector */
unsigned nr_req; /* length of request vector */ unsigned nr_req; /* length of request vector */
int safe; int safe;
@ -449,10 +449,15 @@ int safe;
unsigned nbytes, count, chunk, sector; unsigned nbytes, count, chunk, sector;
unsigned long dv_size = cv64ul(f_dv->dv_size); unsigned long dv_size = cv64ul(f_dv->dv_size);
vir_bytes user_offset, iov_offset = 0, iop_offset; vir_bytes user_offset, iov_offset = 0, iop_offset;
off_t position;
signed long uoffsets[MAX_SECTORS], *up; signed long uoffsets[MAX_SECTORS], *up;
cp_grant_id_t ugrants[MAX_SECTORS], *ug; cp_grant_id_t ugrants[MAX_SECTORS], *ug;
u8_t cmd[3]; u8_t cmd[3];
if (ex64hi(pos64) != 0)
return OK; /* Way beyond EOF */
position= cv64ul(pos64);
/* Check disk address. */ /* Check disk address. */
if ((position & SECTOR_MASK) != 0) return(EINVAL); if ((position & SECTOR_MASK) != 0) return(EINVAL);
@ -1307,7 +1312,7 @@ int density;
position = (off_t) f_dp->test << SECTOR_SHIFT; position = (off_t) f_dp->test << SECTOR_SHIFT;
iovec1.iov_addr = (vir_bytes) tmp_buf; iovec1.iov_addr = (vir_bytes) tmp_buf;
iovec1.iov_size = SECTOR_SIZE; 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); if (iovec1.iov_size != 0) return(EIO);

View File

@ -182,6 +182,7 @@ int safe; /* use safecopies? */
iovec_t iovec1; iovec_t iovec1;
int r, opcode; int r, opcode;
phys_bytes phys_addr; phys_bytes phys_addr;
u64_t position;
/* Disk address? Address and length of the user buffer? */ /* Disk address? Address and length of the user buffer? */
if (mp->COUNT < 0) return(EINVAL); if (mp->COUNT < 0) return(EINVAL);
@ -203,7 +204,8 @@ int safe; /* use safecopies? */
iovec1.iov_size = mp->COUNT; iovec1.iov_size = mp->COUNT;
/* Transfer bytes from/to the device. */ /* 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 the number of bytes transferred or an error code. */
return(r == OK ? (mp->COUNT - iovec1.iov_size) : r); return(r == OK ? (mp->COUNT - iovec1.iov_size) : r);
@ -226,7 +228,7 @@ int safe; /* use safecopies? */
phys_bytes iovec_size; phys_bytes iovec_size;
unsigned nr_req; unsigned nr_req;
int r, j, opcode; int r, j, opcode;
u64_t position;
nr_req = mp->COUNT; /* Length of I/O vector */ nr_req = mp->COUNT; /* Length of I/O vector */
@ -257,7 +259,8 @@ int safe; /* use safecopies? */
opcode = mp->m_type; opcode = mp->m_type;
if(opcode == DEV_GATHER_S) opcode = DEV_GATHER; if(opcode == DEV_GATHER_S) opcode = DEV_GATHER;
if(opcode == DEV_SCATTER_S) opcode = DEV_SCATTER; 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); nr_req, safe);
/* Copy the I/O vector back to the caller. */ /* Copy the I/O vector back to the caller. */

View File

@ -33,8 +33,8 @@ struct driver {
_PROTOTYPE( int (*dr_close), (struct driver *dp, message *m_ptr) ); _PROTOTYPE( int (*dr_close), (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int (*dr_ioctl), (struct driver *dp, message *m_ptr, int safe) ); _PROTOTYPE( int (*dr_ioctl), (struct driver *dp, message *m_ptr, int safe) );
_PROTOTYPE( struct device *(*dr_prepare), (int device) ); _PROTOTYPE( struct device *(*dr_prepare), (int device) );
_PROTOTYPE( int (*dr_transfer), (int proc_nr, int opcode, off_t position, _PROTOTYPE( int (*dr_transfer), (int proc_nr, int opcode, u64_t position,
iovec_t *iov, unsigned nr_req, int safe) ); iovec_t *iov, unsigned nr_req, int safe) );
_PROTOTYPE( void (*dr_cleanup), (void) ); _PROTOTYPE( void (*dr_cleanup), (void) );
_PROTOTYPE( void (*dr_geometry), (struct partition *entry) ); _PROTOTYPE( void (*dr_geometry), (struct partition *entry) );
_PROTOTYPE( void (*dr_signal), (struct driver *dp, message *m_ptr) ); _PROTOTYPE( void (*dr_signal), (struct driver *dp, message *m_ptr) );

View File

@ -157,10 +157,10 @@ struct part_entry *table; /* four entries */
* errors. * errors.
*/ */
iovec_t iovec1; iovec_t iovec1;
off_t position; u64_t position;
static unsigned char partbuf[CD_SECTOR_SIZE]; static unsigned char partbuf[CD_SECTOR_SIZE];
position = offset << SECTOR_SHIFT; position = mul64u(offset, SECTOR_SIZE);
iovec1.iov_addr = (vir_bytes) partbuf; iovec1.iov_addr = (vir_bytes) partbuf;
iovec1.iov_size = CD_SECTOR_SIZE; iovec1.iov_size = CD_SECTOR_SIZE;
if ((*dp->dr_prepare)(device) != NIL_DEV) { if ((*dp->dr_prepare)(device) != NIL_DEV) {

View File

@ -25,7 +25,7 @@ PRIVATE int log_device = -1; /* current device */
FORWARD _PROTOTYPE( char *log_name, (void) ); FORWARD _PROTOTYPE( char *log_name, (void) );
FORWARD _PROTOTYPE( struct device *log_prepare, (int device) ); 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) ); iovec_t *iov, unsigned nr_req, int safe) );
FORWARD _PROTOTYPE( int log_do_open, (struct driver *dp, message *m_ptr) ); FORWARD _PROTOTYPE( int log_do_open, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( int log_cancel, (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) PRIVATE int log_transfer(proc_nr, opcode, position, iov, nr_req, safe)
int proc_nr; /* process doing the request */ int proc_nr; /* process doing the request */
int opcode; /* DEV_GATHER or DEV_SCATTER */ 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 */ iovec_t *iov; /* pointer to read or write request vector */
unsigned nr_req; /* length of request vector */ unsigned nr_req; /* length of request vector */
int safe; /* safe copies? */ int safe; /* safe copies? */

View File

@ -43,7 +43,7 @@ extern int errno; /* error number for PM calls */
FORWARD _PROTOTYPE( char *m_name, (void) ); FORWARD _PROTOTYPE( char *m_name, (void) );
FORWARD _PROTOTYPE( struct device *m_prepare, (int device) ); 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)); iovec_t *iov, unsigned nr_req, int safe));
FORWARD _PROTOTYPE( int m_do_open, (struct driver *dp, message *m_ptr) ); FORWARD _PROTOTYPE( int m_do_open, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( void m_init, (void) ); FORWARD _PROTOTYPE( void m_init, (void) );
@ -119,10 +119,10 @@ int device;
/*===========================================================================* /*===========================================================================*
* m_transfer * * 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 proc_nr; /* process doing the request */
int opcode; /* DEV_GATHER or DEV_SCATTER */ 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 */ iovec_t *iov; /* pointer to read or write request vector */
unsigned nr_req; /* length of request vector */ unsigned nr_req; /* length of request vector */
int safe; /* safe copies */ int safe; /* safe copies */
@ -136,9 +136,14 @@ int safe; /* safe copies */
struct device *dv; struct device *dv;
unsigned long dv_size; unsigned long dv_size;
int s, r; int s, r;
off_t position;
static int n = 0; static int n = 0;
if (ex64hi(pos64) != 0)
return OK; /* Beyond EOF */
position= cv64ul(pos64);
/* Get minor device number and check for /dev/null. */ /* Get minor device number and check for /dev/null. */
dv = &m_geom[m_device]; dv = &m_geom[m_device];
dv_size = cv64ul(dv->dv_size); dv_size = cv64ul(dv->dv_size);

View File

@ -111,7 +111,7 @@
#define MAX_BLOCK_NR ((block_t) 077777777) /* largest block number */ #define MAX_BLOCK_NR ((block_t) 077777777) /* largest block number */
#define HIGHEST_ZONE ((zone_t) 077777777) /* largest zone number */ #define HIGHEST_ZONE ((zone_t) 077777777) /* largest zone number */
#define MAX_INODE_NR ((ino_t) 037777777777) /* largest inode 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 */ #define MAX_SYM_LOOPS 8 /* how many symbolic links are recursed */

View File

@ -52,9 +52,15 @@
#define REQ_FD_START m2_i2 #define REQ_FD_START m2_i2
#define REQ_FD_END m2_i3 #define REQ_FD_END m2_i3
#define REQ_FD_BLOCK_SIZE m2_s1
#define REQ_FD_BDRIVER_E m2_i1 #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 */ /* For REQ_GETDENTS */
#define REQ_GDE_INODE m2_i1 #define REQ_GDE_INODE m2_i1
@ -82,6 +88,10 @@
#define RES_FD_CUM_IO m2_i2 #define RES_FD_CUM_IO m2_i2
#define RES_FD_SIZE m2_i3 #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_DIR m6_l1
#define RES_FILE m6_l2 #define RES_FILE m6_l2
@ -135,10 +145,10 @@
#define REQ_BREAD 38 #define REQ_BREAD 38
#define REQ_BWRITE 39 #define REQ_BWRITE 39
#define REQ_GETDENTS 40 #define REQ_GETDENTS 40
#define REQ_FLUSH 41
#define NREQS 41 #define NREQS 42
#define FS_READY 57 #define FS_READY 57

View File

@ -52,7 +52,7 @@ typedef char gid_t; /* group id */
typedef unsigned long ino_t; /* i-node number (V3 filesystem) */ typedef unsigned long ino_t; /* i-node number (V3 filesystem) */
typedef unsigned short mode_t; /* file type and permissions bits */ typedef unsigned short mode_t; /* file type and permissions bits */
typedef short nlink_t; /* number of links to a file */ 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 int pid_t; /* process id (must be signed) */
typedef short uid_t; /* user id */ typedef short uid_t; /* user id */
typedef unsigned long zone_t; /* zone number */ typedef unsigned long zone_t; /* zone number */

View File

@ -16,6 +16,7 @@
#include "fs.h" #include "fs.h"
#include <minix/com.h> #include <minix/com.h>
#include <minix/u64.h>
#include "buf.h" #include "buf.h"
#include "super.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. * from the cache, it is not clear what the caller could do about it anyway.
*/ */
int r, op; int r, op;
off_t pos; u64_t pos;
dev_t dev; dev_t dev;
int block_size; int block_size;
block_size = get_block_size(bp->b_dev); block_size = get_block_size(bp->b_dev);
if ( (dev = bp->b_dev) != NO_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); op = (rw_flag == READING ? DEV_READ : DEV_WRITE);
r = block_dev_io(op, dev, SELF_E, bp->b_data, pos, block_size, 0); r = block_dev_io(op, dev, SELF_E, bp->b_data, pos, block_size, 0);
if (r != block_size) { 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, r = block_dev_io(rw_flag == WRITING ? DEV_SCATTER : DEV_GATHER,
dev, SELF_E, iovec, 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 /* 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. * encountered, but we only care if it's the first block that failed.

View File

@ -7,6 +7,7 @@
#include <minix/endpoint.h> #include <minix/endpoint.h>
#include <minix/ioctl.h> #include <minix/ioctl.h>
#include <minix/safecopies.h> #include <minix/safecopies.h>
#include <minix/u64.h>
#include <string.h> #include <string.h>
#include "inode.h" #include "inode.h"
#include "super.h" #include "super.h"
@ -19,7 +20,7 @@ PRIVATE int dummyproc;
FORWARD _PROTOTYPE( int safe_io_conversion, (endpoint_t, FORWARD _PROTOTYPE( int safe_io_conversion, (endpoint_t,
cp_grant_id_t *, int *, cp_grant_id_t *, int, 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 *, FORWARD _PROTOTYPE( void safe_io_cleanup, (cp_grant_id_t, cp_grant_id_t *,
int)); int));
@ -65,7 +66,7 @@ PUBLIC int fs_new_driver(void)
* safe_io_conversion * * safe_io_conversion *
*===========================================================================*/ *===========================================================================*/
PRIVATE int safe_io_conversion(driver, gid, op, gids, gids_size, 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; endpoint_t driver;
cp_grant_id_t *gid; cp_grant_id_t *gid;
int *op; int *op;
@ -75,7 +76,6 @@ endpoint_t *io_ept;
void **buf; void **buf;
int *vec_grants; int *vec_grants;
vir_bytes bytes; vir_bytes bytes;
off_t *pos;
{ {
int access = 0, size; int access = 0, size;
int j; int j;
@ -135,21 +135,6 @@ off_t *pos;
/* Set user's vector to the new one. */ /* Set user's vector to the new one. */
*buf = new_iovec; *buf = new_iovec;
break; 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 /* 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 */ dev_t dev; /* major-minor device number */
int proc_e; /* in whose address space is buf? */ int proc_e; /* in whose address space is buf? */
void *buf; /* virtual address of the buffer */ 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 bytes; /* how many bytes to transfer */
int flags; /* special flags, like O_NONBLOCK */ int flags; /* special flags, like O_NONBLOCK */
{ {
@ -208,7 +193,7 @@ int flags; /* special flags, like O_NONBLOCK */
void *buf_used; void *buf_used;
static cp_grant_id_t gids[NR_IOREQS]; static cp_grant_id_t gids[NR_IOREQS];
endpoint_t driver_e; endpoint_t driver_e;
/* Determine driver endpoint for this device */ /* Determine driver endpoint for this device */
driver_e = driver_endpoints[(dev >> MAJOR) & BYTE].driver_e; driver_e = driver_endpoints[(dev >> MAJOR) & BYTE].driver_e;
@ -233,16 +218,16 @@ int flags; /* special flags, like O_NONBLOCK */
op_used = op; op_used = op;
safe = safe_io_conversion(driver_e, &gid, safe = safe_io_conversion(driver_e, &gid,
&op_used, gids, NR_IOREQS, &m.IO_ENDPT, &buf_used, &op_used, gids, NR_IOREQS, &m.IO_ENDPT, &buf_used,
&vec_grants, bytes, &pos); &vec_grants, bytes);
/* Set up rest of the message. */ /* Set up rest of the message. */
if (safe) m.IO_GRANT = (char *) gid; if (safe) m.IO_GRANT = (char *) gid;
m.m_type = op_used; m.m_type = op_used;
m.DEVICE = (dev >> MINOR) & BYTE; m.DEVICE = (dev >> MINOR) & BYTE;
m.POSITION = pos; m.POSITION = ex64lo(pos);
m.COUNT = bytes; m.COUNT = bytes;
m.HIGHPOS = 0; m.HIGHPOS = ex64hi(pos);
/* Call the task. */ /* Call the task. */
r = sendrec(driver_e, &m); r = sendrec(driver_e, &m);

View File

@ -1,6 +1,7 @@
#include "fs.h" #include "fs.h"
#include <fcntl.h> #include <fcntl.h>
#include <minix/vfsif.h>
#include "buf.h" #include "buf.h"
#include "inode.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);
}

View File

@ -47,6 +47,7 @@ int fs_slink(void);
int fs_rdlink(void); int fs_rdlink(void);
int fs_breadwrite(void); int fs_breadwrite(void);
int fs_getdents(void); int fs_getdents(void);
int fs_flush(void);
void init_inode_cache(void); void init_inode_cache(void);
@ -70,7 +71,7 @@ _PROTOTYPE( void invalidate2, (Dev_t device) );
/* device.c */ /* device.c */
_PROTOTYPE( int block_dev_io, (int op, Dev_t dev, int proc, void *buf, _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 */ /* inode.c */
@ -146,7 +147,7 @@ _PROTOTYPE( int read_only, (struct inode *ip) );
/* read.c */ /* read.c */
_PROTOTYPE( int do_read, (void) ); _PROTOTYPE( int do_read, (void) );
_PROTOTYPE( struct buf *rahead, (struct inode *rip, block_t baseblock, _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( void read_ahead, (void) );
_PROTOTYPE( block_t read_map, (struct inode *rip, off_t pos) ); _PROTOTYPE( block_t read_map, (struct inode *rip, off_t pos) );
_PROTOTYPE( int read_write, (int rw_flag) ); _PROTOTYPE( int read_write, (int rw_flag) );

View File

@ -6,6 +6,7 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <minix/com.h> #include <minix/com.h>
#include <minix/u64.h>
#include "buf.h" #include "buf.h"
#include "inode.h" #include "inode.h"
#include "super.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, unsigned off, int chunk, unsigned left, int rw_flag,
char *buff, int seg, int usr, int block_size, int *completed)); 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. */ /* 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); rw_flag, user_addr, seg, usr, block_size, &completed);
if (r != OK) break; /* EOF reached */ if (r != OK) break; /* EOF reached */
@ -166,7 +167,7 @@ PUBLIC int fs_breadwrite(void)
{ {
int r, usr, rw_flag, chunk, block_size; int r, usr, rw_flag, chunk, block_size;
int nrbytes; int nrbytes;
off_t position, f_size, bytes_left; u64_t position;
unsigned int off, cum_io; unsigned int off, cum_io;
mode_t mode_word; mode_t mode_word;
int completed, r2 = OK; int completed, r2 = OK;
@ -176,37 +177,30 @@ PUBLIC int fs_breadwrite(void)
struct inode rip; struct inode rip;
r = OK; r = OK;
f_size = ULONG_MAX;
/* Get the values from the request message */ /* Get the values from the request message */
rw_flag = (fs_m_in.m_type == REQ_BREAD ? READING : WRITING); rw_flag = (fs_m_in.m_type == REQ_BREAD ? READING : WRITING);
usr = fs_m_in.REQ_FD_WHO_E; usr = fs_m_in.REQ_XFD_WHO_E;
position = fs_m_in.REQ_FD_POS; position = make64(fs_m_in.REQ_XFD_POS_LO, fs_m_in.REQ_XFD_POS_HI);
nrbytes = (unsigned) fs_m_in.REQ_FD_NBYTES; nrbytes = (unsigned) fs_m_in.REQ_XFD_NBYTES;
user_addr = fs_m_in.REQ_FD_USER_ADDR; 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_mode = I_BLOCK_SPECIAL;
rip.i_size = f_size; rip.i_size = 0;
rdwt_err = OK; /* set to EIO if disk error occurs */ rdwt_err = OK; /* set to EIO if disk error occurs */
cum_io = 0; cum_io = 0;
/* Split the transfer into chunks that don't span two blocks. */ /* Split the transfer into chunks that don't span two blocks. */
while (nrbytes != 0) { 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); chunk = MIN(nrbytes, block_size - off);
if (chunk < 0) chunk = 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. */ /* Read or write 'chunk' bytes. */
r = rw_chunk(&rip, position, off, chunk, (unsigned) nrbytes, r = rw_chunk(&rip, position, off, chunk, (unsigned) nrbytes,
rw_flag, user_addr, D, usr, block_size, &completed); rw_flag, user_addr, D, usr, block_size, &completed);
@ -218,16 +212,16 @@ PUBLIC int fs_breadwrite(void)
user_addr += chunk; /* user buffer address */ user_addr += chunk; /* user buffer address */
nrbytes -= chunk; /* bytes yet to be read */ nrbytes -= chunk; /* bytes yet to be read */
cum_io += chunk; /* bytes read so far */ 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 != OK) r = rdwt_err; /* check for disk error */
if (rdwt_err == END_OF_FILE) r = OK; if (rdwt_err == END_OF_FILE) r = OK;
fs_m_out.RES_FD_CUM_IO = cum_io; fs_m_out.RES_XFD_CUM_IO = cum_io;
fs_m_out.RES_FD_SIZE = rip.i_size;
return(r); return(r);
} }
@ -239,7 +233,7 @@ PUBLIC int fs_breadwrite(void)
PRIVATE int rw_chunk(rip, position, off, chunk, left, rw_flag, buff, PRIVATE int rw_chunk(rip, position, off, chunk, left, rw_flag, buff,
seg, usr, block_size, completed) seg, usr, block_size, completed)
register struct inode *rip; /* pointer to inode for file to be rd/wr */ 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 */ unsigned off; /* off within the current block */
int chunk; /* number of bytes to read or write */ int chunk; /* number of bytes to read or write */
unsigned left; /* max number of bytes wanted after position */ 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; block_spec = (rip->i_mode & I_TYPE) == I_BLOCK_SPECIAL;
if (block_spec) { if (block_spec) {
b = position/block_size; b = div64u(position, block_size);
dev = (dev_t) rip->i_zone[0]; dev = (dev_t) rip->i_zone[0];
} }
else { 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; dev = rip->i_dev;
} }
@ -279,7 +275,8 @@ int *completed; /* number of bytes copied */
} }
else { else {
/* Writing to a nonexistent block. Create and enter in inode.*/ /* 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) { 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. * the cache, acquire it, otherwise just acquire a free buffer.
*/ */
n = (chunk == block_size ? NO_READ : NORMAL); 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); 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 && 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); zero_block(bp);
} }
@ -439,7 +437,7 @@ PUBLIC void read_ahead()
block_size = get_block_size(rip->i_dev); block_size = get_block_size(rip->i_dev);
rdahed_inode = NIL_INODE; /* turn off read ahead */ rdahed_inode = NIL_INODE; /* turn off read ahead */
if ( (b = read_map(rip, rdahedpos)) == NO_BLOCK) return; /* at EOF */ 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); put_block(bp, PARTIAL_DATA_BLOCK);
} }
@ -449,7 +447,7 @@ PUBLIC void read_ahead()
PUBLIC struct buf *rahead(rip, baseblock, position, bytes_ahead) PUBLIC struct buf *rahead(rip, baseblock, position, bytes_ahead)
register struct inode *rip; /* pointer to inode for file to be read */ register struct inode *rip; /* pointer to inode for file to be read */
block_t baseblock; /* block at current position */ 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 */ unsigned bytes_ahead; /* bytes beyond position for immediate use */
{ {
/* Fetch a block from the cache or the device. If a physical read is /* 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!). * indirect blocks (but don't call read_map!).
*/ */
fragment = position % block_size; fragment = rem64u(position, block_size);
position -= fragment; position= sub64u(position, fragment);
bytes_ahead += fragment; bytes_ahead += fragment;
blocks_ahead = (bytes_ahead + block_size - 1) / block_size; 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) { if (block_spec && rip->i_size == 0) {
blocks_left = NR_IOREQS; blocks_left = NR_IOREQS;
} else { } 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. */ /* Go for the first indirect block if we are in its neighborhood. */
if (!block_spec) { if (!block_spec) {
scale = rip->i_sp->s_log_zone_size; scale = rip->i_sp->s_log_zone_size;
ind1_pos = (off_t) rip->i_ndzones * (block_size << scale); 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_ahead++;
blocks_left++; blocks_left++;
} }

View File

@ -14,6 +14,7 @@
#include "fs.h" #include "fs.h"
#include <string.h> #include <string.h>
#include <minix/com.h> #include <minix/com.h>
#include <minix/u64.h>
#include "buf.h" #include "buf.h"
#include "inode.h" #include "inode.h"
#include "super.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); panic(__FILE__,"request for super_block of NO_DEV", NO_NUM);
r = block_dev_io(DEV_READ, dev, SELF_E, 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) { if (r != _MIN_BLOCK_SIZE) {
printf("MFSread_super r != _MIN_BLOCK_SIZE\n"); printf("MFSread_super r != _MIN_BLOCK_SIZE\n");
return EINVAL; return EINVAL;
@ -312,6 +313,13 @@ printf("MFSread_super block_sizr % INODE_SIZE notOK \n");
return EINVAL; 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_isearch = 0; /* inode searches initially start at 0 */
sp->s_zsearch = 0; /* zone searches initially start at 0 */ sp->s_zsearch = 0; /* zone searches initially start at 0 */
sp->s_version = version; sp->s_version = version;

View File

@ -59,5 +59,6 @@ PUBLIC _PROTOTYPE (int (*fs_call_vec[]), (void) ) = {
fs_breadwrite, /* 38 */ fs_breadwrite, /* 38 */
fs_breadwrite, /* 39 */ fs_breadwrite, /* 39 */
fs_getdents, /* 40 */ fs_getdents, /* 40 */
fs_flush, /* 41 */
}; };

View File

@ -24,6 +24,7 @@
#include <minix/com.h> #include <minix/com.h>
#include <minix/endpoint.h> #include <minix/endpoint.h>
#include <minix/ioctl.h> #include <minix/ioctl.h>
#include <minix/u64.h>
#include "file.h" #include "file.h"
#include "fproc.h" #include "fproc.h"
@ -415,17 +416,18 @@ int bytes; /* how many bytes to transfer */
/*===========================================================================* /*===========================================================================*
* dev_io * * 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. */ int op; /* DEV_READ, DEV_WRITE, DEV_IOCTL, etc. */
dev_t dev; /* major-minor device number */ dev_t dev; /* major-minor device number */
int proc_e; /* in whose address space is buf? */ int proc_e; /* in whose address space is buf? */
void *buf; /* virtual address of the buffer */ 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 bytes; /* how many bytes to transfer */
int flags; /* special flags, like O_NONBLOCK */ int flags; /* special flags, like O_NONBLOCK */
{ {
/* Read or write from a device. The parameter 'dev' tells which one. */ /* Read or write from a device. The parameter 'dev' tells which one. */
struct dmap *dp; struct dmap *dp;
off_t pos;
message dev_mess; message dev_mess;
cp_grant_id_t gid = GRANT_INVALID; cp_grant_id_t gid = GRANT_INVALID;
static cp_grant_id_t gids[NR_IOREQS]; static cp_grant_id_t gids[NR_IOREQS];
@ -433,6 +435,10 @@ int flags; /* special flags, like O_NONBLOCK */
void *buf_used; void *buf_used;
endpoint_t ioproc; endpoint_t ioproc;
if (ex64hi(posX) != 0)
panic(__FILE__, "dev_io: postition too high", NO_NUM);
pos= ex64lo(posX);
/* Determine task dmap. */ /* Determine task dmap. */
dp = &dmap[(dev >> MAJOR) & BYTE]; dp = &dmap[(dev >> MAJOR) & BYTE];
orig_op = op; orig_op = op;
@ -648,7 +654,7 @@ PUBLIC int do_ioctl()
&& (vp->v_mode & I_TYPE) != I_BLOCK_SPECIAL) return(ENOTTY); && (vp->v_mode & I_TYPE) != I_BLOCK_SPECIAL) return(ENOTTY);
dev = (dev_t) vp->v_sdev; 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)); m_in.REQUEST, f->filp_flags));
} }

View File

@ -22,6 +22,7 @@
#include <minix/callnr.h> #include <minix/callnr.h>
#include <minix/endpoint.h> #include <minix/endpoint.h>
#include <minix/com.h> #include <minix/com.h>
#include <minix/u64.h>
#include <a.out.h> #include <a.out.h>
#include <signal.h> #include <signal.h>
#include <string.h> #include <string.h>
@ -400,7 +401,7 @@ int *hdrlenp;
req.inode_nr = vp->v_inode_nr; req.inode_nr = vp->v_inode_nr;
req.user_e = FS_PROC_NR; req.user_e = FS_PROC_NR;
req.seg = D; req.seg = D;
req.pos = pos; req.pos = cvul64(pos);
req.num_of_bytes = sizeof(hdr); req.num_of_bytes = sizeof(hdr);
req.user_addr = (char*)&hdr; req.user_addr = (char*)&hdr;
req.inode_index = vp->v_index; 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.inode_nr = vp->v_inode_nr;
req.user_e = FS_PROC_NR; req.user_e = FS_PROC_NR;
req.seg = D; req.seg = D;
req.pos = pos; req.pos = cvul64(pos);
req.num_of_bytes = _MAX_BLOCK_SIZE; req.num_of_bytes = _MAX_BLOCK_SIZE;
req.user_addr = buf; req.user_addr = buf;
req.inode_index = vp->v_index; 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.inode_nr = vp->v_inode_nr;
req.user_e = proc_e; req.user_e = proc_e;
req.seg = seg; req.seg = seg;
req.pos = off; req.pos = cvul64(off);
req.num_of_bytes = seg_bytes; req.num_of_bytes = seg_bytes;
req.user_addr = 0; req.user_addr = 0;
req.inode_index = vp->v_index; req.inode_index = vp->v_index;

View File

@ -10,7 +10,7 @@ EXTERN struct filp {
struct vnode *filp_vno; 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 /* 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). * select() code (i.e., fd-type-specific select() code can't touch these).

View File

@ -9,6 +9,7 @@
*/ */
#include <sys/select.h> #include <sys/select.h>
#include <minix/u64.h>
#include "fs.h" #include "fs.h"
#include "file.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++) { for (f = &filp[0]; f < &filp[NR_FILPS]; f++) {
if (f->filp_count == 0) { if (f->filp_count == 0) {
f->filp_mode = bits; f->filp_mode = bits;
f->filp_pos = 0L; f->filp_pos = cvu64(0);
f->filp_selectors = 0; f->filp_selectors = 0;
f->filp_select_ops = 0; f->filp_select_ops = 0;
f->filp_pipe_select_ops = 0; f->filp_pipe_select_ops = 0;

View File

@ -7,6 +7,7 @@
#include "fs.h" #include "fs.h"
#include <minix/com.h> #include <minix/com.h>
#include <minix/u64.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include "file.h" #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. */ /* Compute the first and last bytes in the lock region. */
switch (flock.l_whence) { switch (flock.l_whence) {
case SEEK_SET: first = 0; break; 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; case SEEK_END: first = f->filp_vno->v_size; break;
default: return(EINVAL); default: return(EINVAL);
} }

View File

@ -26,6 +26,7 @@
#include <minix/safecopies.h> #include <minix/safecopies.h>
#include <minix/endpoint.h> #include <minix/endpoint.h>
#include <minix/com.h> #include <minix/com.h>
#include <minix/u64.h>
#include <sys/ptrace.h> #include <sys/ptrace.h>
#include <sys/svrctl.h> #include <sys/svrctl.h>
#include "file.h" #include "file.h"
@ -231,7 +232,14 @@ PUBLIC int do_fcntl()
/* Figure out starting position base. */ /* Figure out starting position base. */
switch(flock_arg.l_whence) { switch(flock_arg.l_whence) {
case SEEK_SET: start = 0; if(offset < 0) return EINVAL; break; 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; case SEEK_END: start = f->filp_vno->v_size; break;
default: return EINVAL; default: return EINVAL;
} }

View File

@ -77,7 +77,7 @@ PUBLIC int do_mount()
/* FS process' endpoint number */ /* FS process' endpoint number */
fs_e = (unsigned long)m_in.m1_p3; fs_e = (unsigned long)m_in.m1_p3;
/* Do the actual job */ /* Do the actual job */
r = mount_fs(fs_e); r = mount_fs(fs_e);

View File

@ -20,6 +20,7 @@
#include <unistd.h> #include <unistd.h>
#include <minix/callnr.h> #include <minix/callnr.h>
#include <minix/com.h> #include <minix/com.h>
#include <minix/u64.h>
#include "file.h" #include "file.h"
#include "fproc.h" #include "fproc.h"
#include "lock.h" #include "lock.h"
@ -30,7 +31,8 @@
#include "vnode.h" #include "vnode.h"
#include "vmnt.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) ); FORWARD _PROTOTYPE( int common_open, (int oflags, mode_t omode) );
@ -248,9 +250,9 @@ printf("the root FS...\n");
/* Nobody else found. Restore filp. */ /* Nobody else found. Restore filp. */
fil_ptr->filp_count = 1; fil_ptr->filp_count = 1;
if (fil_ptr->filp_mode == R_BIT) 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 else
fil_ptr->filp_pos = vp->v_pipe_wr_pos; fil_ptr->filp_pos = cvul64(vp->v_pipe_wr_pos);
} }
} }
break; break;
@ -399,7 +401,61 @@ PUBLIC int do_lseek()
{ {
/* Perform the lseek(ls_fd, offset, whence) system call. */ /* Perform the lseek(ls_fd, offset, whence) system call. */
register struct filp *rfilp; 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; struct node_req req;
int r; int r;
@ -411,20 +467,21 @@ PUBLIC int do_lseek()
/* The value of 'whence' determines the start position to use. */ /* The value of 'whence' determines the start position to use. */
switch(m_in.whence) { 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_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); default: return(EINVAL);
} }
/* Check for overflow. */ newpos= add64(pos, make64(m_in.offset_lo, m_in.offset_high));
if (((long)m_in.offset > 0) && ((long)(pos + m_in.offset) < (long)pos))
return(EINVAL);
if (((long)m_in.offset < 0) && ((long)(pos + m_in.offset) > (long)pos))
return(EINVAL);
pos = pos + m_in.offset;
if (pos != rfilp->filp_pos) { /* Inhibit read ahead request */ /* Check for overflow. */
if (((long)m_in.offset_high > 0) && cmp64(newpos, pos) < 0)
return(EINVAL);
if (((long)m_in.offset_high < 0) && cmp64(newpos, pos) > 0)
return(EINVAL);
if (cmp64(newpos, rfilp->filp_pos) != 0) { /* Inhibit read ahead request */
/* Fill in request message */ /* Fill in request message */
req.fs_e = rfilp->filp_vno->v_fs_e; req.fs_e = rfilp->filp_vno->v_fs_e;
req.inode_nr = rfilp->filp_vno->v_inode_nr; 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; if ((r = req_inhibread(&req)) != OK) return r;
} }
rfilp->filp_pos = pos; rfilp->filp_pos = newpos;
m_out.reply_l1 = pos; /* insert the long into the output message */ m_out.reply_l1 = ex64lo(newpos);
m_out.reply_l2 = ex64hi(newpos);
return(OK); return(OK);
} }
@ -474,11 +532,16 @@ int fd_nr;
if (mode_word == I_CHAR_SPECIAL || mode_word == I_BLOCK_SPECIAL) { if (mode_word == I_CHAR_SPECIAL || mode_word == I_BLOCK_SPECIAL) {
dev = (dev_t) vp->v_sdev; dev = (dev_t) vp->v_sdev;
if (mode_word == I_BLOCK_SPECIAL) { if (mode_word == I_BLOCK_SPECIAL) {
/* Invalidate cache entries unless special is mounted printf("VFSclose: closing block spec 0x%x\n", dev);
* or ROOT if (vp->v_bfs_e == ROOT_FS_E)
*/ {
req_sync(vp->v_bfs_e); /* Invalidate the cache unless the special is
printf("VFSclose: closed block spec %d\n", dev); * 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. */ /* Do any special processing on device close. */
dev_close(dev); dev_close(dev);
@ -498,9 +561,9 @@ printf("VFSclose: closed block spec %d\n", dev);
* The read and write positions are saved separately. * The read and write positions are saved separately.
*/ */
if (rfilp->filp_mode == R_BIT) if (rfilp->filp_mode == R_BIT)
vp->v_pipe_rd_pos = rfilp->filp_pos; vp->v_pipe_rd_pos = ex64lo(rfilp->filp_pos);
else else
vp->v_pipe_wr_pos = rfilp->filp_pos; vp->v_pipe_wr_pos = ex64lo(rfilp->filp_pos);
} }
else { else {

View File

@ -25,6 +25,7 @@
#include <minix/callnr.h> #include <minix/callnr.h>
#include <minix/endpoint.h> #include <minix/endpoint.h>
#include <minix/com.h> #include <minix/com.h>
#include <minix/u64.h>
#include <sys/select.h> #include <sys/select.h>
#include <sys/time.h> #include <sys/time.h>
#include "file.h" #include "file.h"
@ -136,7 +137,7 @@ register struct vnode *vp; /* the inode of the pipe */
int rw_flag; /* READING or WRITING */ int rw_flag; /* READING or WRITING */
int oflags; /* flags set by open or fcntl */ int oflags; /* flags set by open or fcntl */
register int bytes; /* bytes to be read or written (all chunks) */ 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 *canwrite; /* return: number of bytes we can write */
int notouch; /* check only */ 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 * 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. * 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 reading, check for empty pipe. */
if (rw_flag == READING) { if (rw_flag == READING) {
if (position >= vp->v_size) { if (pos >= vp->v_size) {
/* Process is reading from an empty pipe. */ /* Process is reading from an empty pipe. */
int r = 0; int r = 0;
if (find_filp(vp, W_BIT) != NIL_FILP) { if (find_filp(vp, W_BIT) != NIL_FILP) {
@ -176,7 +182,7 @@ int notouch; /* check only */
return(EPIPE); 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) if ((oflags & O_NONBLOCK)
&& bytes <= PIPE_SIZE(vp->v_vmnt->m_block_size)) { && bytes <= PIPE_SIZE(vp->v_vmnt->m_block_size)) {
return(EAGAIN); return(EAGAIN);
@ -184,7 +190,7 @@ int notouch; /* check only */
else if ((oflags & O_NONBLOCK) else if ((oflags & O_NONBLOCK)
&& bytes > PIPE_SIZE(vp->v_vmnt->m_block_size)) { && bytes > PIPE_SIZE(vp->v_vmnt->m_block_size)) {
if ( (*canwrite = (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 */ /* Do a partial write. Need to wakeup reader */
if (!notouch) if (!notouch)
release(vp, READ, susp_count); release(vp, READ, susp_count);
@ -195,7 +201,7 @@ int notouch; /* check only */
} }
if (bytes > PIPE_SIZE(vp->v_vmnt->m_block_size)) { if (bytes > PIPE_SIZE(vp->v_vmnt->m_block_size)) {
if ((*canwrite = 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 /* Do a partial write. Need to wakeup reader
* since we'll suspend ourself in read_write() * 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. */ /* Writing to an empty pipe. Search for suspended reader. */
if (position == 0 && !notouch) if (pos == 0 && !notouch)
release(vp, READ, susp_count); release(vp, READ, susp_count);
} }

View File

@ -15,7 +15,7 @@ _PROTOTYPE( void dev_close, (Dev_t dev) );
_PROTOTYPE( int dev_bio, (int op, Dev_t dev, int proc, void *buf, _PROTOTYPE( int dev_bio, (int op, Dev_t dev, int proc, void *buf,
off_t pos, int bytes) ); off_t pos, int bytes) );
_PROTOTYPE( int dev_io, (int op, Dev_t dev, int proc, void *buf, _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_opcl, (int op, Dev_t dev, int proc, int flags) );
_PROTOTYPE( int gen_io, (int task_nr, message *mess_ptr) ); _PROTOTYPE( int gen_io, (int task_nr, message *mess_ptr) );
_PROTOTYPE( int no_dev, (int op, Dev_t dev, int proc, int flags) ); _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 close_fd, (struct fproc *rfp, int fd_nr) );
_PROTOTYPE( int do_creat, (void) ); _PROTOTYPE( int do_creat, (void) );
_PROTOTYPE( int do_lseek, (void) ); _PROTOTYPE( int do_lseek, (void) );
_PROTOTYPE( int do_llseek, (void) );
_PROTOTYPE( int do_mknod, (void) ); _PROTOTYPE( int do_mknod, (void) );
_PROTOTYPE( int do_mkdir, (void) ); _PROTOTYPE( int do_mkdir, (void) );
_PROTOTYPE( int do_open, (void) ); _PROTOTYPE( int do_open, (void) );
@ -105,7 +106,7 @@ _PROTOTYPE( int do_pipe, (void) );
_PROTOTYPE( int do_unpause, (void) ); _PROTOTYPE( int do_unpause, (void) );
_PROTOTYPE( int unpause, (int proc_nr_e) ); _PROTOTYPE( int unpause, (int proc_nr_e) );
_PROTOTYPE( int pipe_check, (struct vnode *vp, int rw_flag, _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 release, (struct vnode *vp, int call_nr, int count) );
_PROTOTYPE( void revive, (int proc_nr, int bytes) ); _PROTOTYPE( void revive, (int proc_nr, int bytes) );
_PROTOTYPE( void suspend, (int task) ); _PROTOTYPE( void suspend, (int task) );
@ -168,6 +169,7 @@ _PROTOTYPE( int req_breadwrite, (breadwrite_req_t *req,
readwrite_res_t *res) ); readwrite_res_t *res) );
_PROTOTYPE( int req_getdents, (endpoint_t fs_e, ino_t inode_nr, _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) ); 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 */ /* stadir.c */
_PROTOTYPE( int do_chdir, (void) ); _PROTOTYPE( int do_chdir, (void) );

View File

@ -16,6 +16,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <minix/com.h> #include <minix/com.h>
#include <minix/u64.h>
#include "file.h" #include "file.h"
#include "fproc.h" #include "fproc.h"
#include "param.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. */ /* Perform read(fd, buffer, nbytes) or write(fd, buffer, nbytes) call. */
register struct filp *f; register struct filp *f;
register struct vnode *vp; 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; unsigned int off, cum_io;
int op, oflags, r, chunk, usr, seg, block_spec, char_spec; int op, oflags, r, chunk, usr, seg, block_spec, char_spec;
int regular, partial_pipe = 0, partial_cnt = 0; 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. /* check if user process has the memory it needs.
* if not, copying will fail later. * if not, copying will fail later.
* do this after 0-check above because umap doesn't want to map 0 bytes. */ * 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); printf("VFS: read_write: umap failed for process %d\n", usr);
return r; return r;
} }
position = f->filp_pos; position = f->filp_pos;
oflags = f->filp_flags; 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); r = dev_io(op, dev, usr, m_in.buffer, position, m_in.nbytes, oflags);
if (r >= 0) { if (r >= 0) {
cum_io = r; cum_io = r;
position += r; position = add64ul(position, r);
r = OK; r = OK;
} }
} }
@ -154,12 +158,13 @@ int rw_flag; /* READING or WRITING */
/* Regular files */ /* Regular files */
else { else {
if (rw_flag == WRITING && block_spec == 0) { 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. */ /* 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); return(EFBIG);
/* Check for O_APPEND flag. */
if (oflags & O_APPEND) position = f_size;
} }
/* Pipes are a little different. Check. */ /* Pipes are a little different. Check. */
@ -190,24 +195,39 @@ int rw_flag; /* READING or WRITING */
/* Issue request */ /* Issue request */
r = req_readwrite(&req, &res); r = req_readwrite(&req, &res);
position = res.new_pos; if (r >= 0)
cum_io += res.cum_io; {
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. */ /* On write, update file size and access time. */
if (rw_flag == WRITING) { if (rw_flag == WRITING) {
if (regular || mode_word == I_DIRECTORY) { 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 { else {
if (vp->v_pipe == I_PIPE) { if (vp->v_pipe == I_PIPE) {
if (position >= vp->v_size) { if (cmp64ul(position, vp->v_size) >= 0) {
/* Reset pipe pointers */ /* Reset pipe pointers */
vp->v_size = 0; vp->v_size = 0;
position = 0; position = cvu64(0);
wf = find_filp(vp, W_BIT); 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); if (gid < 0) panic(__FILE__, "cpf_grant_magic failed", gid);
/* Issue request */ /* 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, 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); cpf_revoke(gid);
if (r > 0) if (r > 0)
rfilp->filp_pos += pos_change; rfilp->filp_pos= add64ul(rfilp->filp_pos, pos_change);
return r; return r;
} }

View File

@ -17,6 +17,7 @@
#include <minix/keymap.h> #include <minix/keymap.h>
#include <minix/const.h> #include <minix/const.h>
#include <minix/endpoint.h> #include <minix/endpoint.h>
#include <minix/u64.h>
#include <unistd.h> #include <unistd.h>
#include <minix/vfsif.h> #include <minix/vfsif.h>
@ -118,13 +119,16 @@ readwrite_res_t *res;
{ {
int r; int r;
message m; message m;
if (ex64hi(req->pos) != 0)
panic(__FILE__, "req_readwrite: pos too large", NO_NUM);
/* Fill in request message */ /* Fill in request message */
m.m_type = req->rw_flag == READING ? REQ_READ : REQ_WRITE; m.m_type = req->rw_flag == READING ? REQ_READ : REQ_WRITE;
m.REQ_FD_INODE_NR = req->inode_nr; m.REQ_FD_INODE_NR = req->inode_nr;
m.REQ_FD_WHO_E = req->user_e; m.REQ_FD_WHO_E = req->user_e;
m.REQ_FD_SEG = req->seg; 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_NBYTES = req->num_of_bytes;
m.REQ_FD_USER_ADDR = req->user_addr; m.REQ_FD_USER_ADDR = req->user_addr;
m.REQ_FD_INODE_INDEX = req->inode_index; 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; if ((r = fs_sendrec(req->fs_e, &m)) != OK) return r;
/* Fill in response structure */ /* 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; res->cum_io = m.RES_FD_CUM_IO;
return OK; return OK;
@ -810,22 +814,23 @@ readwrite_res_t *res;
{ {
int r; int r;
message m; message m;
/* Fill in request message */ /* Fill in request message */
m.m_type = req->rw_flag == READING ? REQ_BREAD : REQ_BWRITE; m.m_type = req->rw_flag == READING ? REQ_BREAD : REQ_BWRITE;
m.REQ_FD_BDEV = req->dev; m.REQ_XFD_BDEV = req->dev;
m.REQ_FD_BLOCK_SIZE = req->blocksize; m.REQ_XFD_BLOCK_SIZE = req->blocksize;
m.REQ_FD_WHO_E = req->user_e; m.REQ_XFD_WHO_E = req->user_e;
m.REQ_FD_POS = req->pos; m.REQ_XFD_POS_LO = ex64lo(req->pos);
m.REQ_FD_NBYTES = req->num_of_bytes; m.REQ_XFD_POS_HI = ex64hi(req->pos);
m.REQ_FD_USER_ADDR = req->user_addr; m.REQ_XFD_NBYTES = req->num_of_bytes;
m.REQ_XFD_USER_ADDR = req->user_addr;
/* Send/rec request */ /* Send/rec request */
if ((r = fs_sendrec(req->fs_e, &m)) != OK) return r; if ((r = fs_sendrec(req->fs_e, &m)) != OK) return r;
/* Fill in response structure */ /* Fill in response structure */
res->new_pos = m.RES_FD_POS; res->new_pos = make64(m.RES_XFD_POS_LO, m.RES_XFD_POS_HI);
res->cum_io = m.RES_FD_CUM_IO; res->cum_io = m.RES_XFD_CUM_IO;
return OK; 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 #if 0
/* Wrapper pattern: */ /* Wrapper pattern: */
/*===========================================================================* /*===========================================================================*

View File

@ -51,7 +51,7 @@ typedef struct readwrite_req {
ino_t inode_nr; ino_t inode_nr;
unsigned short inode_index; unsigned short inode_index;
int seg; int seg;
off_t pos; u64_t pos;
unsigned int num_of_bytes; unsigned int num_of_bytes;
char *user_addr; char *user_addr;
} readwrite_req_t; } readwrite_req_t;
@ -59,7 +59,7 @@ typedef struct readwrite_req {
/* Structure for response of REQ_READ and REQ_WRITE */ /* Structure for response of REQ_READ and REQ_WRITE */
typedef struct readwrite_res { typedef struct readwrite_res {
off_t new_pos; u64_t new_pos;
unsigned int cum_io; unsigned int cum_io;
} readwrite_res_t; } readwrite_res_t;
@ -311,7 +311,7 @@ typedef struct breadwrite_req {
endpoint_t user_e; endpoint_t user_e;
endpoint_t driver_e; endpoint_t driver_e;
dev_t dev; dev_t dev;
off_t pos; u64_t pos;
unsigned int num_of_bytes; unsigned int num_of_bytes;
char *user_addr; char *user_addr;
} breadwrite_req_t; } breadwrite_req_t;

View File

@ -20,6 +20,7 @@
#include <sys/time.h> #include <sys/time.h>
#include <sys/select.h> #include <sys/select.h>
#include <minix/com.h> #include <minix/com.h>
#include <minix/u64.h>
#include <string.h> #include <string.h>
/* max. number of simultaneously pending select() calls */ /* 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; int rops = *ops;
if (block) rops |= SEL_NOTIFY; 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) if (*ops < 0)
return SEL_ERR; return SEL_ERR;
return SEL_OK; return SEL_OK;

View File

@ -17,6 +17,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/statfs.h> #include <sys/statfs.h>
#include <minix/com.h> #include <minix/com.h>
#include <minix/u64.h>
#include <string.h> #include <string.h>
#include "file.h" #include "file.h"
#include "fproc.h" #include "fproc.h"
@ -257,7 +258,12 @@ PUBLIC int do_fstat()
/* If we read from a pipe, send position too */ /* If we read from a pipe, send position too */
if (rfilp->filp_vno->v_pipe == I_PIPE) { if (rfilp->filp_vno->v_pipe == I_PIPE) {
if (rfilp->filp_mode & R_BIT) 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 */ /* Fill in request message */