2005-08-29 18:47:18 +02:00
|
|
|
/* This file manages the super block table and the related data structures,
|
|
|
|
* namely, the bit maps that keep track of which zones and which inodes are
|
2005-04-21 16:53:53 +02:00
|
|
|
* allocated and which are free. When a new inode or zone is needed, the
|
|
|
|
* appropriate bit map is searched for a free entry.
|
|
|
|
*
|
|
|
|
* The entry points into this file are
|
|
|
|
* alloc_bit: somebody wants to allocate a zone or inode; find one
|
|
|
|
* free_bit: indicate that a zone or inode is available for allocation
|
|
|
|
* get_super: search the 'superblock' table for a device
|
|
|
|
* mounted: tells if file inode is on mounted (or ROOT) file system
|
|
|
|
* read_super: read a superblock
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "fs.h"
|
|
|
|
#include <string.h>
|
2011-12-22 01:29:27 +01:00
|
|
|
#include <assert.h>
|
2005-04-21 16:53:53 +02:00
|
|
|
#include <minix/com.h>
|
2006-11-27 15:21:43 +01:00
|
|
|
#include <minix/u64.h>
|
2011-11-09 14:29:12 +01:00
|
|
|
#include <minix/bdev.h>
|
2005-04-21 16:53:53 +02:00
|
|
|
#include "buf.h"
|
|
|
|
#include "inode.h"
|
|
|
|
#include "super.h"
|
|
|
|
#include "const.h"
|
|
|
|
|
2013-04-26 11:54:33 +02:00
|
|
|
static u32_t used_blocks = 0;
|
2006-10-25 15:40:36 +02:00
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* alloc_bit *
|
|
|
|
*===========================================================================*/
|
2012-03-25 20:25:53 +02:00
|
|
|
bit_t alloc_bit(sp, map, origin)
|
2005-04-21 16:53:53 +02:00
|
|
|
struct super_block *sp; /* the filesystem to allocate from */
|
|
|
|
int map; /* IMAP (inode map) or ZMAP (zone map) */
|
|
|
|
bit_t origin; /* number of bit to start searching at */
|
|
|
|
{
|
|
|
|
/* Allocate a bit from a bit map and return its bit number. */
|
|
|
|
|
|
|
|
block_t start_block; /* first bit block */
|
2010-06-01 14:35:33 +02:00
|
|
|
block_t block;
|
2005-04-21 16:53:53 +02:00
|
|
|
bit_t map_bits; /* how many bits are there in the bit map? */
|
2010-06-01 14:35:33 +02:00
|
|
|
short bit_blocks; /* how many blocks are there in the bit map? */
|
|
|
|
unsigned word, bcount;
|
2005-04-21 16:53:53 +02:00
|
|
|
struct buf *bp;
|
|
|
|
bitchunk_t *wptr, *wlim, k;
|
|
|
|
bit_t i, b;
|
|
|
|
|
|
|
|
if (sp->s_rd_only)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("can't allocate bit on read-only filesys");
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
if (map == IMAP) {
|
|
|
|
start_block = START_BLOCK;
|
2010-06-01 14:35:33 +02:00
|
|
|
map_bits = (bit_t) (sp->s_ninodes + 1);
|
2005-04-21 16:53:53 +02:00
|
|
|
bit_blocks = sp->s_imap_blocks;
|
|
|
|
} else {
|
|
|
|
start_block = START_BLOCK + sp->s_imap_blocks;
|
2010-06-01 14:35:33 +02:00
|
|
|
map_bits = (bit_t) (sp->s_zones - (sp->s_firstdatazone - 1));
|
2005-04-21 16:53:53 +02:00
|
|
|
bit_blocks = sp->s_zmap_blocks;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Figure out where to start the bit search (depends on 'origin'). */
|
|
|
|
if (origin >= map_bits) origin = 0; /* for robustness */
|
|
|
|
|
|
|
|
/* Locate the starting place. */
|
2010-06-01 14:35:33 +02:00
|
|
|
block = (block_t) (origin / FS_BITS_PER_BLOCK(sp->s_block_size));
|
2005-06-06 15:51:50 +02:00
|
|
|
word = (origin % FS_BITS_PER_BLOCK(sp->s_block_size)) / FS_BITCHUNK_BITS;
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
/* Iterate over all blocks plus one, because we start in the middle. */
|
|
|
|
bcount = bit_blocks + 1;
|
|
|
|
do {
|
|
|
|
bp = get_block(sp->s_dev, start_block + block, NORMAL);
|
2012-10-16 17:40:39 +02:00
|
|
|
wlim = &b_bitmap(bp)[FS_BITMAP_CHUNKS(sp->s_block_size)];
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
/* Iterate over the words in block. */
|
2012-10-16 17:40:39 +02:00
|
|
|
for (wptr = &b_bitmap(bp)[word]; wptr < wlim; wptr++) {
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
/* Does this word contain a free bit? */
|
|
|
|
if (*wptr == (bitchunk_t) ~0) continue;
|
|
|
|
|
|
|
|
/* Find and allocate the free bit. */
|
2010-12-21 11:44:45 +01:00
|
|
|
k = (bitchunk_t) conv4(sp->s_native, (int) *wptr);
|
2005-04-21 16:53:53 +02:00
|
|
|
for (i = 0; (k & (1 << i)) != 0; ++i) {}
|
|
|
|
|
|
|
|
/* Bit number from the start of the bit map. */
|
2005-06-06 15:51:50 +02:00
|
|
|
b = ((bit_t) block * FS_BITS_PER_BLOCK(sp->s_block_size))
|
2012-10-16 17:40:39 +02:00
|
|
|
+ (wptr - &b_bitmap(bp)[0]) * FS_BITCHUNK_BITS
|
2005-04-21 16:53:53 +02:00
|
|
|
+ i;
|
|
|
|
|
|
|
|
/* Don't allocate bits beyond the end of the map. */
|
|
|
|
if (b >= map_bits) break;
|
|
|
|
|
|
|
|
/* Allocate and return bit number. */
|
|
|
|
k |= 1 << i;
|
2010-12-21 11:44:45 +01:00
|
|
|
*wptr = (bitchunk_t) conv4(sp->s_native, (int) k);
|
2011-12-22 01:29:27 +01:00
|
|
|
MARKDIRTY(bp);
|
2005-04-21 16:53:53 +02:00
|
|
|
put_block(bp, MAP_BLOCK);
|
2013-04-26 11:54:33 +02:00
|
|
|
if(map == ZMAP) {
|
|
|
|
used_blocks++;
|
|
|
|
lmfs_blockschange(sp->s_dev, 1);
|
|
|
|
}
|
2005-04-21 16:53:53 +02:00
|
|
|
return(b);
|
|
|
|
}
|
|
|
|
put_block(bp, MAP_BLOCK);
|
2010-06-01 14:35:33 +02:00
|
|
|
if (++block >= (unsigned int) bit_blocks) /* last block, wrap around */
|
|
|
|
block = 0;
|
2005-04-21 16:53:53 +02:00
|
|
|
word = 0;
|
|
|
|
} while (--bcount > 0);
|
|
|
|
return(NO_BIT); /* no bit could be allocated */
|
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* free_bit *
|
|
|
|
*===========================================================================*/
|
2012-03-25 20:25:53 +02:00
|
|
|
void free_bit(sp, map, bit_returned)
|
2005-04-21 16:53:53 +02:00
|
|
|
struct super_block *sp; /* the filesystem to operate on */
|
|
|
|
int map; /* IMAP (inode map) or ZMAP (zone map) */
|
|
|
|
bit_t bit_returned; /* number of bit to insert into the map */
|
|
|
|
{
|
|
|
|
/* Return a zone or inode by turning off its bitmap bit. */
|
|
|
|
|
|
|
|
unsigned block, word, bit;
|
|
|
|
struct buf *bp;
|
|
|
|
bitchunk_t k, mask;
|
|
|
|
block_t start_block;
|
|
|
|
|
|
|
|
if (sp->s_rd_only)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("can't free bit on read-only filesys");
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
if (map == IMAP) {
|
|
|
|
start_block = START_BLOCK;
|
|
|
|
} else {
|
|
|
|
start_block = START_BLOCK + sp->s_imap_blocks;
|
|
|
|
}
|
2005-06-06 15:51:50 +02:00
|
|
|
block = bit_returned / FS_BITS_PER_BLOCK(sp->s_block_size);
|
2005-08-29 18:47:18 +02:00
|
|
|
word = (bit_returned % FS_BITS_PER_BLOCK(sp->s_block_size))
|
|
|
|
/ FS_BITCHUNK_BITS;
|
|
|
|
|
2005-06-06 15:51:50 +02:00
|
|
|
bit = bit_returned % FS_BITCHUNK_BITS;
|
2005-04-21 16:53:53 +02:00
|
|
|
mask = 1 << bit;
|
|
|
|
|
|
|
|
bp = get_block(sp->s_dev, start_block + block, NORMAL);
|
|
|
|
|
2012-10-16 17:40:39 +02:00
|
|
|
k = (bitchunk_t) conv4(sp->s_native, (int) b_bitmap(bp)[word]);
|
2005-04-21 16:53:53 +02:00
|
|
|
if (!(k & mask)) {
|
2010-06-01 14:35:33 +02:00
|
|
|
if (map == IMAP) panic("tried to free unused inode");
|
|
|
|
else panic("tried to free unused block: %u", bit_returned);
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
k &= ~mask;
|
2012-10-16 17:40:39 +02:00
|
|
|
b_bitmap(bp)[word] = (bitchunk_t) conv4(sp->s_native, (int) k);
|
2011-12-22 01:29:27 +01:00
|
|
|
MARKDIRTY(bp);
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
put_block(bp, MAP_BLOCK);
|
|
|
|
|
2013-04-26 11:54:33 +02:00
|
|
|
if(map == ZMAP) {
|
|
|
|
used_blocks--;
|
|
|
|
lmfs_blockschange(sp->s_dev, -1);
|
|
|
|
}
|
|
|
|
}
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* get_super *
|
|
|
|
*===========================================================================*/
|
2012-03-25 20:25:53 +02:00
|
|
|
struct super_block *get_super(
|
2010-04-13 12:58:41 +02:00
|
|
|
dev_t dev /* device number whose super_block is sought */
|
|
|
|
)
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
2005-09-11 18:45:46 +02:00
|
|
|
if (dev == NO_DEV)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("request for super_block of NO_DEV");
|
2005-04-21 16:53:53 +02:00
|
|
|
|
2008-11-19 13:26:10 +01:00
|
|
|
if(superblock.s_dev != dev)
|
2011-12-22 01:29:27 +01:00
|
|
|
panic("wrong superblock: 0x%x", (int) dev);
|
2005-04-21 16:53:53 +02:00
|
|
|
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
return(&superblock);
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* get_block_size *
|
|
|
|
*===========================================================================*/
|
2012-03-25 20:25:53 +02:00
|
|
|
unsigned int get_block_size(dev_t dev)
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
2005-09-11 18:45:46 +02:00
|
|
|
if (dev == NO_DEV)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("request for block size of NO_DEV");
|
2005-04-21 16:53:53 +02:00
|
|
|
|
2012-10-16 17:40:39 +02:00
|
|
|
return(lmfs_fs_block_size());
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*===========================================================================*
|
2011-12-22 01:29:27 +01:00
|
|
|
* rw_super *
|
2005-04-21 16:53:53 +02:00
|
|
|
*===========================================================================*/
|
2012-03-25 20:25:53 +02:00
|
|
|
static int rw_super(struct super_block *sp, int writing)
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
2011-12-22 01:29:27 +01:00
|
|
|
/* Read/write a superblock. */
|
|
|
|
int r;
|
2008-11-19 13:26:10 +01:00
|
|
|
static char *sbbuf;
|
2011-12-22 01:29:27 +01:00
|
|
|
dev_t save_dev = sp->s_dev;
|
|
|
|
|
|
|
|
/* To keep the 1kb on disk clean, only read/write up to and including
|
|
|
|
* this field.
|
|
|
|
*/
|
|
|
|
#define LAST_ONDISK_FIELD s_disk_version
|
|
|
|
int ondisk_bytes = (int) ((char *) &sp->LAST_ONDISK_FIELD - (char *) sp)
|
|
|
|
+ sizeof(sp->LAST_ONDISK_FIELD);
|
2008-11-19 13:26:10 +01:00
|
|
|
|
|
|
|
STATICINIT(sbbuf, _MIN_BLOCK_SIZE);
|
2005-04-21 16:53:53 +02:00
|
|
|
|
2011-12-22 01:29:27 +01:00
|
|
|
assert(ondisk_bytes > 0);
|
|
|
|
assert(ondisk_bytes < _MIN_BLOCK_SIZE);
|
|
|
|
assert(ondisk_bytes < sizeof(struct super_block));
|
|
|
|
|
|
|
|
if (sp->s_dev == NO_DEV)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("request for super_block of NO_DEV");
|
2011-12-22 01:29:27 +01:00
|
|
|
|
|
|
|
if(writing) {
|
|
|
|
memset(sbbuf, 0, _MIN_BLOCK_SIZE);
|
|
|
|
memcpy(sbbuf, sp, ondisk_bytes);
|
|
|
|
r = bdev_write(sp->s_dev, cvu64(SUPER_BLOCK_BYTES), sbbuf, _MIN_BLOCK_SIZE,
|
|
|
|
BDEV_NOFLAGS);
|
|
|
|
} else {
|
|
|
|
r = bdev_read(sp->s_dev, cvu64(SUPER_BLOCK_BYTES), sbbuf, _MIN_BLOCK_SIZE,
|
|
|
|
BDEV_NOFLAGS);
|
|
|
|
memset(sp, 0, sizeof(*sp));
|
|
|
|
memcpy(sp, sbbuf, ondisk_bytes);
|
|
|
|
sp->s_dev = save_dev;
|
|
|
|
}
|
|
|
|
|
Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.
The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.
After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
reintroduced
As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.
Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-22 13:27:53 +01:00
|
|
|
if (r != _MIN_BLOCK_SIZE)
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
return(EINVAL);
|
2011-12-22 01:29:27 +01:00
|
|
|
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* read_super *
|
|
|
|
*===========================================================================*/
|
2012-03-25 20:25:53 +02:00
|
|
|
int read_super(struct super_block *sp)
|
2011-12-22 01:29:27 +01:00
|
|
|
{
|
|
|
|
unsigned int magic;
|
|
|
|
block_t offset;
|
|
|
|
int version, native, r;
|
|
|
|
|
|
|
|
if((r=rw_super(sp, 0)) != OK)
|
|
|
|
return r;
|
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
magic = sp->s_magic; /* determines file system type */
|
|
|
|
|
|
|
|
/* Get file system version and type. */
|
|
|
|
if (magic == SUPER_MAGIC || magic == conv2(BYTE_SWAP, SUPER_MAGIC)) {
|
|
|
|
version = V1;
|
|
|
|
native = (magic == SUPER_MAGIC);
|
|
|
|
} else if (magic == SUPER_V2 || magic == conv2(BYTE_SWAP, SUPER_V2)) {
|
|
|
|
version = V2;
|
|
|
|
native = (magic == SUPER_V2);
|
|
|
|
} else if (magic == SUPER_V3) {
|
|
|
|
version = V3;
|
|
|
|
native = 1;
|
|
|
|
} else {
|
|
|
|
return(EINVAL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If the super block has the wrong byte order, swap the fields; the magic
|
|
|
|
* number doesn't need conversion. */
|
2010-06-01 14:35:33 +02:00
|
|
|
sp->s_ninodes = (ino_t) conv4(native, (int) sp->s_ninodes);
|
|
|
|
sp->s_nzones = (zone1_t) conv2(native, (int) sp->s_nzones);
|
|
|
|
sp->s_imap_blocks = (short) conv2(native, (int) sp->s_imap_blocks);
|
|
|
|
sp->s_zmap_blocks = (short) conv2(native, (int) sp->s_zmap_blocks);
|
|
|
|
sp->s_firstdatazone_old =(zone1_t)conv2(native,(int)sp->s_firstdatazone_old);
|
|
|
|
sp->s_log_zone_size = (short) conv2(native, (int) sp->s_log_zone_size);
|
|
|
|
sp->s_max_size = (off_t) conv4(native, sp->s_max_size);
|
|
|
|
sp->s_zones = (zone_t)conv4(native, sp->s_zones);
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
/* In V1, the device size was kept in a short, s_nzones, which limited
|
|
|
|
* devices to 32K zones. For V2, it was decided to keep the size as a
|
|
|
|
* long. However, just changing s_nzones to a long would not work, since
|
|
|
|
* then the position of s_magic in the super block would not be the same
|
|
|
|
* in V1 and V2 file systems, and there would be no way to tell whether
|
|
|
|
* a newly mounted file system was V1 or V2. The solution was to introduce
|
|
|
|
* a new variable, s_zones, and copy the size there.
|
|
|
|
*
|
|
|
|
* Calculate some other numbers that depend on the version here too, to
|
|
|
|
* hide some of the differences.
|
|
|
|
*/
|
|
|
|
if (version == V1) {
|
2005-11-14 19:41:27 +01:00
|
|
|
sp->s_block_size = _STATIC_BLOCK_SIZE;
|
2010-06-01 14:35:33 +02:00
|
|
|
sp->s_zones = (zone_t) sp->s_nzones; /* only V1 needs this copy */
|
2005-04-21 16:53:53 +02:00
|
|
|
sp->s_inodes_per_block = V1_INODES_PER_BLOCK;
|
|
|
|
sp->s_ndzones = V1_NR_DZONES;
|
|
|
|
sp->s_nindirs = V1_INDIRECTS;
|
|
|
|
} else {
|
2012-01-08 20:52:57 +01:00
|
|
|
if (version == V2) {
|
2005-11-14 19:41:27 +01:00
|
|
|
sp->s_block_size = _STATIC_BLOCK_SIZE;
|
2012-01-08 20:52:57 +01:00
|
|
|
} else {
|
|
|
|
sp->s_block_size = (unsigned short)
|
|
|
|
conv2(native,(int) sp->s_block_size);
|
|
|
|
}
|
2006-10-25 15:40:36 +02:00
|
|
|
if (sp->s_block_size < _MIN_BLOCK_SIZE) {
|
2005-04-21 16:53:53 +02:00
|
|
|
return EINVAL;
|
2006-10-25 15:40:36 +02:00
|
|
|
}
|
2005-04-21 16:53:53 +02:00
|
|
|
sp->s_inodes_per_block = V2_INODES_PER_BLOCK(sp->s_block_size);
|
|
|
|
sp->s_ndzones = V2_NR_DZONES;
|
|
|
|
sp->s_nindirs = V2_INDIRECTS(sp->s_block_size);
|
|
|
|
}
|
|
|
|
|
2009-12-21 12:20:30 +01:00
|
|
|
/* For even larger disks, a similar problem occurs with s_firstdatazone.
|
|
|
|
* If the on-disk field contains zero, we assume that the value was too
|
|
|
|
* large to fit, and compute it on the fly.
|
|
|
|
*/
|
|
|
|
if (sp->s_firstdatazone_old == 0) {
|
|
|
|
offset = START_BLOCK + sp->s_imap_blocks + sp->s_zmap_blocks;
|
|
|
|
offset += (sp->s_ninodes + sp->s_inodes_per_block - 1) /
|
|
|
|
sp->s_inodes_per_block;
|
|
|
|
|
|
|
|
sp->s_firstdatazone = (offset + (1 << sp->s_log_zone_size) - 1) >>
|
|
|
|
sp->s_log_zone_size;
|
|
|
|
} else {
|
2010-06-01 14:35:33 +02:00
|
|
|
sp->s_firstdatazone = (zone_t) sp->s_firstdatazone_old;
|
2009-12-21 12:20:30 +01:00
|
|
|
}
|
|
|
|
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
if (sp->s_block_size < _MIN_BLOCK_SIZE)
|
|
|
|
return(EINVAL);
|
|
|
|
|
|
|
|
if ((sp->s_block_size % 512) != 0)
|
|
|
|
return(EINVAL);
|
|
|
|
|
|
|
|
if (SUPER_SIZE > sp->s_block_size)
|
|
|
|
return(EINVAL);
|
|
|
|
|
2005-09-11 18:45:46 +02:00
|
|
|
if ((sp->s_block_size % V2_INODE_SIZE) != 0 ||
|
2005-04-21 16:53:53 +02:00
|
|
|
(sp->s_block_size % V1_INODE_SIZE) != 0) {
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
return(EINVAL);
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
|
2006-11-27 15:21:43 +01:00
|
|
|
/* Limit s_max_size to LONG_MAX */
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
if ((unsigned long)sp->s_max_size > LONG_MAX)
|
|
|
|
sp->s_max_size = LONG_MAX;
|
2006-11-27 15:21:43 +01:00
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
sp->s_isearch = 0; /* inode searches initially start at 0 */
|
|
|
|
sp->s_zsearch = 0; /* zone searches initially start at 0 */
|
|
|
|
sp->s_version = version;
|
|
|
|
sp->s_native = native;
|
|
|
|
|
|
|
|
/* Make a few basic checks to see if super block looks reasonable. */
|
|
|
|
if (sp->s_imap_blocks < 1 || sp->s_zmap_blocks < 1
|
|
|
|
|| sp->s_ninodes < 1 || sp->s_zones < 1
|
2009-10-26 14:35:39 +01:00
|
|
|
|| sp->s_firstdatazone <= 4
|
|
|
|
|| sp->s_firstdatazone >= sp->s_zones
|
2005-04-21 16:53:53 +02:00
|
|
|
|| (unsigned) sp->s_log_zone_size > 4) {
|
|
|
|
printf("not enough imap or zone map blocks, \n");
|
2009-10-26 14:35:39 +01:00
|
|
|
printf("or not enough inodes, or not enough zones, \n"
|
|
|
|
"or invalid first data zone, or zone size too large\n");
|
2005-04-21 16:53:53 +02:00
|
|
|
return(EINVAL);
|
|
|
|
}
|
2011-12-22 01:29:27 +01:00
|
|
|
|
|
|
|
|
|
|
|
/* Check any flags we don't understand but are required to. Currently
|
|
|
|
* these don't exist so all such unknown bits are fatal.
|
|
|
|
*/
|
|
|
|
if(sp->s_flags & MFSFLAG_MANDATORY_MASK) {
|
|
|
|
printf("MFS: unsupported feature flags on this FS.\n"
|
|
|
|
"Please use a newer MFS to mount it.\n");
|
|
|
|
return(EINVAL);
|
|
|
|
}
|
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
return(OK);
|
|
|
|
}
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
|
2011-12-22 01:29:27 +01:00
|
|
|
/*===========================================================================*
|
|
|
|
* write_super *
|
|
|
|
*===========================================================================*/
|
2012-03-25 20:25:53 +02:00
|
|
|
int write_super(struct super_block *sp)
|
2011-12-22 01:29:27 +01:00
|
|
|
{
|
|
|
|
if(sp->s_rd_only)
|
|
|
|
panic("can't write superblock of readonly filesystem");
|
|
|
|
return rw_super(sp, 1);
|
|
|
|
}
|
|
|
|
|
2013-04-26 11:54:33 +02:00
|
|
|
static int blocks_known = 0;
|
|
|
|
|
|
|
|
u32_t get_used_blocks(struct super_block *sp)
|
|
|
|
{
|
|
|
|
if(!blocks_known) {
|
|
|
|
/* how many blocks are in use? */
|
|
|
|
used_blocks = sp->s_zones - count_free_bits(sp, ZMAP);
|
|
|
|
blocks_known = 1;
|
|
|
|
}
|
|
|
|
return used_blocks;
|
|
|
|
}
|