From b65ad59e08ac27ca960e12652419259fc52ad6fc Mon Sep 17 00:00:00 2001 From: David van Moolenbroek Date: Mon, 30 Mar 2015 10:44:09 +0000 Subject: [PATCH] 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 --- minix/include/minix/libminixfs.h | 6 +++--- minix/lib/libminixfs/bio.c | 11 +++++++---- minix/lib/libminixfs/cache.c | 28 ++++++++++++++++------------ sys/sys/types.h | 1 + 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/minix/include/minix/libminixfs.h b/minix/include/minix/libminixfs.h index 20fff4152..8b361aa84 100644 --- a/minix/include/minix/libminixfs.h +++ b/minix/include/minix/libminixfs.h @@ -13,8 +13,8 @@ struct buf { 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_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 */ + block64_t lmfs_blocknr; /* block number of its (minor) device */ char lmfs_count; /* number of users of this buffer */ char lmfs_needsetcache; /* to be identified to VM */ 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); int lmfs_rdwt_err(void); 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_ino(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, block64_t block,int only_search, ino_t ino, u64_t off); void lmfs_invalidate(dev_t device); void lmfs_put_block(struct buf *bp, int block_type); diff --git a/minix/lib/libminixfs/bio.c b/minix/lib/libminixfs/bio.c index 5b47e8f8f..8f0b72aa4 100644 --- a/minix/lib/libminixfs/bio.c +++ b/minix/lib/libminixfs/bio.c @@ -56,7 +56,7 @@ lmfs_driver(dev_t dev, char *label) * TODO: limit according to the number of available buffers. */ 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]; unsigned int count; @@ -103,8 +103,9 @@ ssize_t lmfs_bio(dev_t dev, struct fsdriver_data * data, size_t bytes, off_t pos, int call) { - block_t block, blocks_left; + block64_t block; size_t block_size, off, block_off, chunk; + unsigned int blocks_left; struct buf *bp; 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); - /* FIXME: block_t is 32-bit, so we have to impose a limit here. */ - if (pos < 0 || pos / block_size > UINT32_MAX || bytes > SSIZE_MAX) + if (bytes == 0) + return 0; /* just in case */ + + if (pos < 0 || bytes > SSIZE_MAX || pos > INT64_MAX - bytes + 1) return EINVAL; off = 0; diff --git a/minix/lib/libminixfs/cache.c b/minix/lib/libminixfs/cache.c index 408c26175..9c6533d54 100644 --- a/minix/lib/libminixfs/cache.c +++ b/minix/lib/libminixfs/cache.c @@ -18,7 +18,7 @@ #include #include -#define BUFHASH(b) ((b) % nr_bufs) +#define BUFHASH(b) ((unsigned int)((b) % nr_bufs)) #define MARKCLEAN lmfs_markclean #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 * *===========================================================================*/ -struct buf *lmfs_get_block(register dev_t dev, register block_t block, - int only_search) +struct buf *lmfs_get_block(dev_t dev, block64_t block, int only_search) { 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 * *===========================================================================*/ -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) { /* 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; static struct buf *bp; - u64_t dev_off = (u64_t) block * fs_block_size; + uint64_t dev_off; struct buf *prev_ptr; 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(block <= UINT64_MAX / fs_block_size); + + dev_off = block * fs_block_size; + if((ino_off % fs_block_size)) { 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. */ dev_t dev; - off_t dev_off; + uint64_t dev_off; int r; if (bp == NULL) return; /* it is easier to check here than in caller */ dev = bp->lmfs_dev; - dev_off = (off_t) bp->lmfs_blocknr * fs_block_size; + dev_off = bp->lmfs_blocknr * fs_block_size; lowercount(bp); if (bp->lmfs_count != 0) return; /* block is still in use */ @@ -535,8 +538,8 @@ static void read_block( BDEV_NOFLAGS); } if (r < 0) { - printf("fs cache: I/O error on device %d/%d, block %u\n", - major(dev), minor(dev), bp->lmfs_blocknr); + printf("fs cache: I/O error on device %d/%d, block %"PRIu64"\n", + major(dev), minor(dev), bp->lmfs_blocknr); op_failed = 1; } else if (r != (ssize_t) fs_block_size) { r = END_OF_FILE; @@ -679,7 +682,7 @@ void lmfs_rw_scattered( int p; vir_bytes vdata, blockrem; bp = bufq[nblocks]; - if (bp->lmfs_blocknr != (block_t) bufq[0]->lmfs_blocknr + nblocks) + if (bp->lmfs_blocknr != bufq[0]->lmfs_blocknr + nblocks) break; if(niovecs >= NR_IOREQS-iov_per_block) break; vdata = (vir_bytes) bp->data; @@ -710,8 +713,9 @@ void lmfs_rw_scattered( * may have done less than what we asked for. */ if (r < 0) { - printf("fs cache: I/O error %d on device %d/%d, block %u\n", - r, major(dev), minor(dev), bufq[0]->lmfs_blocknr); + printf("fs cache: I/O error %d on device %d/%d, " + "block %"PRIu64"\n", + r, major(dev), minor(dev), bufq[0]->lmfs_blocknr); } for (i = 0; i < nblocks; i++) { bp = bufq[i]; diff --git a/sys/sys/types.h b/sys/sys/types.h index b3657d494..aea1867f1 100644 --- a/sys/sys/types.h +++ b/sys/sys/types.h @@ -118,6 +118,7 @@ typedef int64_t i64_t; /* some Minix specific types that do not conflict with posix */ typedef uint32_t zone_t; /* zone 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 uint16_t zone1_t; /* zone number for V1 file systems */ typedef uint32_t bitchunk_t; /* collection of bits in a bitmap */