First cut at 64-bit file offsets in block devices for mkfs/fsck.
This commit is contained in:
parent
828e87862f
commit
bafc45a309
|
@ -47,6 +47,7 @@
|
|||
#include <minix/config.h>
|
||||
#include <minix/const.h>
|
||||
#include <minix/type.h>
|
||||
#include <minix/u64.h>
|
||||
#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 = cinoaddr(inn);
|
||||
a = cinoblock(inn);
|
||||
return a;
|
||||
}
|
||||
|
||||
int inooff(int inn)
|
||||
{
|
||||
int a;
|
||||
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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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) );
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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? */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "fs.h"
|
||||
#include <minix/com.h>
|
||||
#include <minix/u64.h>
|
||||
#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.
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <minix/endpoint.h>
|
||||
#include <minix/ioctl.h>
|
||||
#include <minix/safecopies.h>
|
||||
#include <minix/u64.h>
|
||||
#include <string.h>
|
||||
#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);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
#include "fs.h"
|
||||
#include <fcntl.h>
|
||||
#include <minix/vfsif.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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) );
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <minix/com.h>
|
||||
#include <minix/u64.h>
|
||||
#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++;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "fs.h"
|
||||
#include <string.h>
|
||||
#include <minix/com.h>
|
||||
#include <minix/u64.h>
|
||||
#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;
|
||||
|
|
|
@ -59,5 +59,6 @@ PUBLIC _PROTOTYPE (int (*fs_call_vec[]), (void) ) = {
|
|||
fs_breadwrite, /* 38 */
|
||||
fs_breadwrite, /* 39 */
|
||||
fs_getdents, /* 40 */
|
||||
fs_flush, /* 41 */
|
||||
};
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <minix/com.h>
|
||||
#include <minix/endpoint.h>
|
||||
#include <minix/ioctl.h>
|
||||
#include <minix/u64.h>
|
||||
#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));
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <minix/callnr.h>
|
||||
#include <minix/endpoint.h>
|
||||
#include <minix/com.h>
|
||||
#include <minix/u64.h>
|
||||
#include <a.out.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
|
@ -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;
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/select.h>
|
||||
#include <minix/u64.h>
|
||||
|
||||
#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;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "fs.h"
|
||||
#include <minix/com.h>
|
||||
#include <minix/u64.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.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. */
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <minix/safecopies.h>
|
||||
#include <minix/endpoint.h>
|
||||
#include <minix/com.h>
|
||||
#include <minix/u64.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/svrctl.h>
|
||||
#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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <unistd.h>
|
||||
#include <minix/callnr.h>
|
||||
#include <minix/com.h>
|
||||
#include <minix/u64.h>
|
||||
#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);
|
||||
}
|
||||
|
||||
/* Check for overflow. */
|
||||
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;
|
||||
newpos= add64(pos, make64(m_in.offset_lo, m_in.offset_high));
|
||||
|
||||
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 */
|
||||
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 {
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <minix/callnr.h>
|
||||
#include <minix/endpoint.h>
|
||||
#include <minix/com.h>
|
||||
#include <minix/u64.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/time.h>
|
||||
#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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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) );
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <minix/com.h>
|
||||
#include <minix/u64.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <minix/keymap.h>
|
||||
#include <minix/const.h>
|
||||
#include <minix/endpoint.h>
|
||||
#include <minix/u64.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <minix/vfsif.h>
|
||||
|
@ -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: */
|
||||
/*===========================================================================*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <sys/time.h>
|
||||
#include <sys/select.h>
|
||||
#include <minix/com.h>
|
||||
#include <minix/u64.h>
|
||||
#include <string.h>
|
||||
|
||||
/* 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;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <sys/statfs.h>
|
||||
#include <minix/com.h>
|
||||
#include <minix/u64.h>
|
||||
#include <string.h>
|
||||
#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 */
|
||||
|
|
Loading…
Reference in a new issue