From 99d668d87ffa5e6ccb7f7aa806d0db8f978fb3eb Mon Sep 17 00:00:00 2001 From: Ben Gras Date: Thu, 3 Oct 2013 17:22:07 +0200 Subject: [PATCH] avoid alloc_contig() for iovec, mfs superblock . initial workaround for assert() firing on iovec size on ARM. likely due to alloc_contig() allocating unusually mapped memory in STATICINIT. . for the same reason use the regular cache i/o functions to read the superblock in mfs - avoid the alloc_contig() that STATICINIT does. Change-Id: I3d8dc635b1cf2666e55b0393feae74cc25b8fed4 --- lib/libminixfs/cache.c | 6 ++---- servers/mfs/super.c | 32 +++++++++++++++++++++++--------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/lib/libminixfs/cache.c b/lib/libminixfs/cache.c index 2ff548faa..008ea8d09 100644 --- a/lib/libminixfs/cache.c +++ b/lib/libminixfs/cache.c @@ -38,7 +38,7 @@ static struct buf **buf_hash; /* the buffer hash table */ static unsigned int nr_bufs; static int may_use_vmcache; -static int fs_block_size = 1024; /* raw i/o block size */ +static int fs_block_size = PAGE_SIZE; /* raw i/o block size */ static int rdwt_err; @@ -616,12 +616,10 @@ void lmfs_rw_scattered( int gap; register int i; register iovec_t *iop; - static iovec_t *iovec = NULL; + static iovec_t iovec[NR_IOREQS]; u64_t pos; int iov_per_block; - STATICINIT(iovec, NR_IOREQS); - assert(dev != NO_DEV); assert(!(fs_block_size % PAGE_SIZE)); assert(fs_block_size > 0); diff --git a/servers/mfs/super.c b/servers/mfs/super.c index 2f8101c98..6f8903dcb 100644 --- a/servers/mfs/super.c +++ b/servers/mfs/super.c @@ -192,8 +192,9 @@ static int rw_super(struct super_block *sp, int writing) { /* Read/write a superblock. */ int r; - static char *sbbuf; dev_t save_dev = sp->s_dev; + struct buf *bp; + char *sbbuf; /* To keep the 1kb on disk clean, only read/write up to and including * this field. @@ -202,8 +203,6 @@ static int rw_super(struct super_block *sp, int writing) int ondisk_bytes = (int) ((char *) &sp->LAST_ONDISK_FIELD - (char *) sp) + sizeof(sp->LAST_ONDISK_FIELD); - STATICINIT(sbbuf, _MIN_BLOCK_SIZE); - assert(ondisk_bytes > 0); assert(ondisk_bytes < _MIN_BLOCK_SIZE); assert(ondisk_bytes < sizeof(struct super_block)); @@ -211,21 +210,36 @@ static int rw_super(struct super_block *sp, int writing) if (sp->s_dev == NO_DEV) panic("request for super_block of NO_DEV"); + /* we rely on the cache blocksize, before reading the + * superblock, being big enough that our complete superblock + * is in block 0. + * + * copy between the disk block and the superblock buffer (depending + * on direction). mark the disk block dirty if the copy is into the + * disk block. + */ + assert(lmfs_fs_block_size() >= sizeof(struct super_block) + SUPER_BLOCK_BYTES); + assert(lmfs_fs_block_size() >= _MIN_BLOCK_SIZE + SUPER_BLOCK_BYTES); + assert(SUPER_BLOCK_BYTES >= sizeof(struct super_block)); + assert(SUPER_BLOCK_BYTES >= ondisk_bytes); + if(!(bp = get_block(sp->s_dev, 0, NORMAL))) + panic("get_block of superblock failed"); + + /* sbbuf points to the disk block at the superblock offset */ + sbbuf = (char *) b_data(bp) + SUPER_BLOCK_BYTES; + if(writing) { memset(sbbuf, 0, _MIN_BLOCK_SIZE); memcpy(sbbuf, sp, ondisk_bytes); - r = bdev_write(sp->s_dev, ((u64_t)(SUPER_BLOCK_BYTES)), sbbuf, _MIN_BLOCK_SIZE, - BDEV_NOFLAGS); + lmfs_markdirty(bp); } else { - r = bdev_read(sp->s_dev, ((u64_t)(SUPER_BLOCK_BYTES)), sbbuf, _MIN_BLOCK_SIZE, - BDEV_NOFLAGS); memset(sp, 0, sizeof(*sp)); memcpy(sp, sbbuf, ondisk_bytes); sp->s_dev = save_dev; } - if (r != _MIN_BLOCK_SIZE) - return(EINVAL); + put_block(bp, FULL_DATA_BLOCK); + lmfs_flushall(); return OK; } -- 2.44.0