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
This commit is contained in:
Ben Gras 2013-10-03 17:22:07 +02:00 committed by Gerrit Code Review
parent 982405fef1
commit 99d668d87f
2 changed files with 25 additions and 13 deletions

View file

@ -38,7 +38,7 @@ static struct buf **buf_hash; /* the buffer hash table */
static unsigned int nr_bufs; static unsigned int nr_bufs;
static int may_use_vmcache; 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; static int rdwt_err;
@ -616,12 +616,10 @@ void lmfs_rw_scattered(
int gap; int gap;
register int i; register int i;
register iovec_t *iop; register iovec_t *iop;
static iovec_t *iovec = NULL; static iovec_t iovec[NR_IOREQS];
u64_t pos; u64_t pos;
int iov_per_block; int iov_per_block;
STATICINIT(iovec, NR_IOREQS);
assert(dev != NO_DEV); assert(dev != NO_DEV);
assert(!(fs_block_size % PAGE_SIZE)); assert(!(fs_block_size % PAGE_SIZE));
assert(fs_block_size > 0); assert(fs_block_size > 0);

View file

@ -192,8 +192,9 @@ static int rw_super(struct super_block *sp, int writing)
{ {
/* Read/write a superblock. */ /* Read/write a superblock. */
int r; int r;
static char *sbbuf;
dev_t save_dev = sp->s_dev; 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 /* To keep the 1kb on disk clean, only read/write up to and including
* this field. * 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) int ondisk_bytes = (int) ((char *) &sp->LAST_ONDISK_FIELD - (char *) sp)
+ sizeof(sp->LAST_ONDISK_FIELD); + sizeof(sp->LAST_ONDISK_FIELD);
STATICINIT(sbbuf, _MIN_BLOCK_SIZE);
assert(ondisk_bytes > 0); assert(ondisk_bytes > 0);
assert(ondisk_bytes < _MIN_BLOCK_SIZE); assert(ondisk_bytes < _MIN_BLOCK_SIZE);
assert(ondisk_bytes < sizeof(struct super_block)); 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) if (sp->s_dev == NO_DEV)
panic("request for super_block of 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) { if(writing) {
memset(sbbuf, 0, _MIN_BLOCK_SIZE); memset(sbbuf, 0, _MIN_BLOCK_SIZE);
memcpy(sbbuf, sp, ondisk_bytes); memcpy(sbbuf, sp, ondisk_bytes);
r = bdev_write(sp->s_dev, ((u64_t)(SUPER_BLOCK_BYTES)), sbbuf, _MIN_BLOCK_SIZE, lmfs_markdirty(bp);
BDEV_NOFLAGS);
} else { } else {
r = bdev_read(sp->s_dev, ((u64_t)(SUPER_BLOCK_BYTES)), sbbuf, _MIN_BLOCK_SIZE,
BDEV_NOFLAGS);
memset(sp, 0, sizeof(*sp)); memset(sp, 0, sizeof(*sp));
memcpy(sp, sbbuf, ondisk_bytes); memcpy(sp, sbbuf, ondisk_bytes);
sp->s_dev = save_dev; sp->s_dev = save_dev;
} }
if (r != _MIN_BLOCK_SIZE) put_block(bp, FULL_DATA_BLOCK);
return(EINVAL); lmfs_flushall();
return OK; return OK;
} }