#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"
#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 */
#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))
_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));
block_nr bno;
int dir;
{
+ int r;
+
if(!block_size) fatal("devio() with unknown block size");
if (dir == READING && bno == thisblk) return;
thisblk = bno;
#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;
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;
}
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"));
}
}
-int inoaddr(int inn)
+int inoblock(int inn)
+{
+ int a;
+ a = cinoblock(inn);
+ return a;
+}
+
+int inooff(int inn)
{
int a;
- a = cinoaddr(inn);
+ a = cinooff(inn);
return a;
}
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);
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"));
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;
}
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. */
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);
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")) {
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);
}
}
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))
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);
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);
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)
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;
{
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);
}
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);
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;
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;
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;
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)
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");
(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) {
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) );
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. */
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;
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)
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? */
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;
#endif
/* Check disk address. */
- if ((position & SECTOR_MASK) != 0) return(EINVAL);
+ if (rem64u(position, SECTOR_SIZE) != 0) return(EINVAL);
errors = 0;
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);
/* 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;
}
/* 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++;
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? */
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;
/* 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);
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) {
}
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;
_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) );
/*===========================================================================*
* 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? */
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;
} 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);
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) );
/*===========================================================================*
* 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;
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);
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);
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);
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);
phys_bytes iovec_size;
unsigned nr_req;
int r, j, opcode;
-
+ u64_t position;
nr_req = mp->COUNT; /* Length of I/O vector */
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. */
_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) );
* 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) {
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) );
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? */
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) );
/*===========================================================================*
* 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 */
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);
#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 */
#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
#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
#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
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 */
#include "fs.h"
#include <minix/com.h>
+#include <minix/u64.h>
#include "buf.h"
#include "super.h"
* 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) {
}
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.
#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"
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));
* 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;
void **buf;
int *vec_grants;
vir_bytes bytes;
-off_t *pos;
{
int access = 0, size;
int j;
/* 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
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 */
{
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;
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);
#include "fs.h"
#include <fcntl.h>
+#include <minix/vfsif.h>
#include "buf.h"
#include "inode.h"
}
+/*===========================================================================*
+ * 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);
+}
+
+
int fs_rdlink(void);
int fs_breadwrite(void);
int fs_getdents(void);
+int fs_flush(void);
void init_inode_cache(void);
/* 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 */
/* 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) );
#include <string.h>
#include <unistd.h>
#include <minix/com.h>
+#include <minix/u64.h>
#include "buf.h"
#include "inode.h"
#include "super.h"
-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));
}
/* 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 */
{
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;
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);
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);
}
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 */
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;
}
}
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) {
* 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);
}
}
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);
}
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);
}
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
* 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;
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++;
}
#include "fs.h"
#include <string.h>
#include <minix/com.h>
+#include <minix/u64.h>
#include "buf.h"
#include "inode.h"
#include "super.h"
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;
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;
fs_breadwrite, /* 38 */
fs_breadwrite, /* 39 */
fs_getdents, /* 40 */
+ fs_flush, /* 41 */
};
#include <minix/com.h>
#include <minix/endpoint.h>
#include <minix/ioctl.h>
+#include <minix/u64.h>
#include "file.h"
#include "fproc.h"
/*===========================================================================*
* 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];
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;
&& (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));
}
#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>
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;
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;
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;
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).
*/
#include <sys/select.h>
+#include <minix/u64.h>
#include "fs.h"
#include "file.h"
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;
#include "fs.h"
#include <minix/com.h>
+#include <minix/u64.h>
#include <fcntl.h>
#include <unistd.h>
#include "file.h"
/* 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);
}
#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"
/* 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;
}
/* FS process' endpoint number */
fs_e = (unsigned long)m_in.m1_p3;
-
+
/* Do the actual job */
r = mount_fs(fs_e);
#include <unistd.h>
#include <minix/callnr.h>
#include <minix/com.h>
+#include <minix/u64.h>
#include "file.h"
#include "fproc.h"
#include "lock.h"
#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) );
/* 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;
{
/* 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;
/* The value of 'whence' determines the start position to use. */
switch(m_in.whence) {
- case SEEK_SET: pos = 0; break;
+ case SEEK_SET: pos = cvu64(0); break;
case SEEK_CUR: pos = rfilp->filp_pos; break;
- case SEEK_END: pos = rfilp->filp_vno->v_size; break;
+ case SEEK_END: pos = cvul64(rfilp->filp_vno->v_size); break;
default: return(EINVAL);
}
+ newpos= add64(pos, make64(m_in.offset_lo, m_in.offset_high));
+
/* Check for overflow. */
- if (((long)m_in.offset > 0) && ((long)(pos + m_in.offset) < (long)pos))
+ if (((long)m_in.offset_high > 0) && cmp64(newpos, pos) < 0)
return(EINVAL);
- if (((long)m_in.offset < 0) && ((long)(pos + m_in.offset) > (long)pos))
+ if (((long)m_in.offset_high < 0) && cmp64(newpos, pos) > 0)
return(EINVAL);
- pos = pos + m_in.offset;
- if (pos != rfilp->filp_pos) { /* Inhibit read ahead request */
+ if (cmp64(newpos, rfilp->filp_pos) != 0) { /* Inhibit read ahead request */
/* Fill in request message */
req.fs_e = rfilp->filp_vno->v_fs_e;
req.inode_nr = rfilp->filp_vno->v_inode_nr;
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);
}
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);
* 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 {
#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"
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 */
{
* 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) {
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);
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);
}
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()
*/
}
/* Writing to an empty pipe. Search for suspended reader. */
- if (position == 0 && !notouch)
+ if (pos == 0 && !notouch)
release(vp, READ, susp_count);
}
_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) );
_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) );
_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) );
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) );
#include <fcntl.h>
#include <unistd.h>
#include <minix/com.h>
+#include <minix/u64.h>
#include "file.h"
#include "fproc.h"
#include "param.h"
/* 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;
/* 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;
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;
}
}
/* 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. */
/* 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);
}
}
}
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;
}
#include <minix/keymap.h>
#include <minix/const.h>
#include <minix/endpoint.h>
+#include <minix/u64.h>
#include <unistd.h>
#include <minix/vfsif.h>
{
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;
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;
{
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;
}
}
+/*===========================================================================*
+ * 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: */
/*===========================================================================*
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;
/* 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;
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;
#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 */
{
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;
#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"
/* 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 */