libminixfs: add support for 64-bit block numbers

There are currently no devices out there that require this change.
The change is merely needed to support subsequent changes.

Change-Id: I64214c5f46ff4a2260815d15c15e4a17709b9036
This commit is contained in:
David van Moolenbroek 2015-03-30 10:44:09 +00:00
parent bd851af48f
commit b65ad59e08
4 changed files with 27 additions and 19 deletions

View file

@ -13,8 +13,8 @@ struct buf {
struct buf *lmfs_next; /* used to link all free bufs in a chain */ struct buf *lmfs_next; /* used to link all free bufs in a chain */
struct buf *lmfs_prev; /* used to link all free bufs the other way */ struct buf *lmfs_prev; /* used to link all free bufs the other way */
struct buf *lmfs_hash; /* used to link bufs on hash chains */ struct buf *lmfs_hash; /* used to link bufs on hash chains */
block_t lmfs_blocknr; /* block number of its (minor) device */
dev_t lmfs_dev; /* major | minor device where block resides */ dev_t lmfs_dev; /* major | minor device where block resides */
block64_t lmfs_blocknr; /* block number of its (minor) device */
char lmfs_count; /* number of users of this buffer */ char lmfs_count; /* number of users of this buffer */
char lmfs_needsetcache; /* to be identified to VM */ char lmfs_needsetcache; /* to be identified to VM */
unsigned int lmfs_bytes; /* Number of bytes allocated in bp */ unsigned int lmfs_bytes; /* Number of bytes allocated in bp */
@ -42,8 +42,8 @@ void lmfs_set_blocksize(int blocksize, int major);
void lmfs_reset_rdwt_err(void); void lmfs_reset_rdwt_err(void);
int lmfs_rdwt_err(void); int lmfs_rdwt_err(void);
void lmfs_buf_pool(int new_nr_bufs); void lmfs_buf_pool(int new_nr_bufs);
struct buf *lmfs_get_block(dev_t dev, block_t block,int only_search); struct buf *lmfs_get_block(dev_t dev, block64_t block,int only_search);
struct buf *lmfs_get_block_ino(dev_t dev, block_t block,int only_search, struct buf *lmfs_get_block_ino(dev_t dev, block64_t block,int only_search,
ino_t ino, u64_t off); ino_t ino, u64_t off);
void lmfs_invalidate(dev_t device); void lmfs_invalidate(dev_t device);
void lmfs_put_block(struct buf *bp, int block_type); void lmfs_put_block(struct buf *bp, int block_type);

View file

@ -56,7 +56,7 @@ lmfs_driver(dev_t dev, char *label)
* TODO: limit according to the number of available buffers. * TODO: limit according to the number of available buffers.
*/ */
static void static void
block_prefetch(dev_t dev, block_t block, block_t nblocks) block_prefetch(dev_t dev, block64_t block, unsigned int nblocks)
{ {
struct buf *bp, *bufs[NR_IOREQS]; struct buf *bp, *bufs[NR_IOREQS];
unsigned int count; unsigned int count;
@ -103,8 +103,9 @@ ssize_t
lmfs_bio(dev_t dev, struct fsdriver_data * data, size_t bytes, off_t pos, lmfs_bio(dev_t dev, struct fsdriver_data * data, size_t bytes, off_t pos,
int call) int call)
{ {
block_t block, blocks_left; block64_t block;
size_t block_size, off, block_off, chunk; size_t block_size, off, block_off, chunk;
unsigned int blocks_left;
struct buf *bp; struct buf *bp;
int r, write, how; int r, write, how;
@ -116,8 +117,10 @@ lmfs_bio(dev_t dev, struct fsdriver_data * data, size_t bytes, off_t pos,
assert(block_size > 0); assert(block_size > 0);
/* FIXME: block_t is 32-bit, so we have to impose a limit here. */ if (bytes == 0)
if (pos < 0 || pos / block_size > UINT32_MAX || bytes > SSIZE_MAX) return 0; /* just in case */
if (pos < 0 || bytes > SSIZE_MAX || pos > INT64_MAX - bytes + 1)
return EINVAL; return EINVAL;
off = 0; off = 0;

View file

@ -18,7 +18,7 @@
#include <minix/u64.h> #include <minix/u64.h>
#include <minix/bdev.h> #include <minix/bdev.h>
#define BUFHASH(b) ((b) % nr_bufs) #define BUFHASH(b) ((unsigned int)((b) % nr_bufs))
#define MARKCLEAN lmfs_markclean #define MARKCLEAN lmfs_markclean
#define MINBUFS 6 /* minimal no of bufs for sanity check */ #define MINBUFS 6 /* minimal no of bufs for sanity check */
@ -178,8 +178,7 @@ static void lmfs_alloc_block(struct buf *bp)
/*===========================================================================* /*===========================================================================*
* lmfs_get_block * * lmfs_get_block *
*===========================================================================*/ *===========================================================================*/
struct buf *lmfs_get_block(register dev_t dev, register block_t block, struct buf *lmfs_get_block(dev_t dev, block64_t block, int only_search)
int only_search)
{ {
return lmfs_get_block_ino(dev, block, only_search, VMC_NO_INODE, 0); return lmfs_get_block_ino(dev, block, only_search, VMC_NO_INODE, 0);
} }
@ -243,7 +242,7 @@ static void freeblock(struct buf *bp)
/*===========================================================================* /*===========================================================================*
* lmfs_get_block_ino * * lmfs_get_block_ino *
*===========================================================================*/ *===========================================================================*/
struct buf *lmfs_get_block_ino(dev_t dev, block_t block, int only_search, struct buf *lmfs_get_block_ino(dev_t dev, block64_t block, int only_search,
ino_t ino, u64_t ino_off) ino_t ino, u64_t ino_off)
{ {
/* Check to see if the requested block is in the block cache. If so, return /* Check to see if the requested block is in the block cache. If so, return
@ -263,7 +262,7 @@ struct buf *lmfs_get_block_ino(dev_t dev, block_t block, int only_search,
int b; int b;
static struct buf *bp; static struct buf *bp;
u64_t dev_off = (u64_t) block * fs_block_size; uint64_t dev_off;
struct buf *prev_ptr; struct buf *prev_ptr;
assert(buf_hash); assert(buf_hash);
@ -274,6 +273,10 @@ struct buf *lmfs_get_block_ino(dev_t dev, block_t block, int only_search,
assert(dev != NO_DEV); assert(dev != NO_DEV);
assert(block <= UINT64_MAX / fs_block_size);
dev_off = block * fs_block_size;
if((ino_off % fs_block_size)) { if((ino_off % fs_block_size)) {
printf("cache: unaligned lmfs_get_block_ino ino_off %llu\n", printf("cache: unaligned lmfs_get_block_ino ino_off %llu\n",
@ -424,14 +427,14 @@ void lmfs_put_block(
* disk immediately if they are dirty. * disk immediately if they are dirty.
*/ */
dev_t dev; dev_t dev;
off_t dev_off; uint64_t dev_off;
int r; int r;
if (bp == NULL) return; /* it is easier to check here than in caller */ if (bp == NULL) return; /* it is easier to check here than in caller */
dev = bp->lmfs_dev; dev = bp->lmfs_dev;
dev_off = (off_t) bp->lmfs_blocknr * fs_block_size; dev_off = bp->lmfs_blocknr * fs_block_size;
lowercount(bp); lowercount(bp);
if (bp->lmfs_count != 0) return; /* block is still in use */ if (bp->lmfs_count != 0) return; /* block is still in use */
@ -535,8 +538,8 @@ static void read_block(
BDEV_NOFLAGS); BDEV_NOFLAGS);
} }
if (r < 0) { if (r < 0) {
printf("fs cache: I/O error on device %d/%d, block %u\n", printf("fs cache: I/O error on device %d/%d, block %"PRIu64"\n",
major(dev), minor(dev), bp->lmfs_blocknr); major(dev), minor(dev), bp->lmfs_blocknr);
op_failed = 1; op_failed = 1;
} else if (r != (ssize_t) fs_block_size) { } else if (r != (ssize_t) fs_block_size) {
r = END_OF_FILE; r = END_OF_FILE;
@ -679,7 +682,7 @@ void lmfs_rw_scattered(
int p; int p;
vir_bytes vdata, blockrem; vir_bytes vdata, blockrem;
bp = bufq[nblocks]; bp = bufq[nblocks];
if (bp->lmfs_blocknr != (block_t) bufq[0]->lmfs_blocknr + nblocks) if (bp->lmfs_blocknr != bufq[0]->lmfs_blocknr + nblocks)
break; break;
if(niovecs >= NR_IOREQS-iov_per_block) break; if(niovecs >= NR_IOREQS-iov_per_block) break;
vdata = (vir_bytes) bp->data; vdata = (vir_bytes) bp->data;
@ -710,8 +713,9 @@ void lmfs_rw_scattered(
* may have done less than what we asked for. * may have done less than what we asked for.
*/ */
if (r < 0) { if (r < 0) {
printf("fs cache: I/O error %d on device %d/%d, block %u\n", printf("fs cache: I/O error %d on device %d/%d, "
r, major(dev), minor(dev), bufq[0]->lmfs_blocknr); "block %"PRIu64"\n",
r, major(dev), minor(dev), bufq[0]->lmfs_blocknr);
} }
for (i = 0; i < nblocks; i++) { for (i = 0; i < nblocks; i++) {
bp = bufq[i]; bp = bufq[i];

View file

@ -118,6 +118,7 @@ typedef int64_t i64_t;
/* some Minix specific types that do not conflict with posix */ /* some Minix specific types that do not conflict with posix */
typedef uint32_t zone_t; /* zone number */ typedef uint32_t zone_t; /* zone number */
typedef uint32_t block_t; /* block number */ typedef uint32_t block_t; /* block number */
typedef uint64_t block64_t; /* block number, 64-bit */
typedef uint32_t bit_t; /* bit number in a bit map */ typedef uint32_t bit_t; /* bit number in a bit map */
typedef uint16_t zone1_t; /* zone number for V1 file systems */ typedef uint16_t zone1_t; /* zone number for V1 file systems */
typedef uint32_t bitchunk_t; /* collection of bits in a bitmap */ typedef uint32_t bitchunk_t; /* collection of bits in a bitmap */