Clean up MFS a bit:

- Remove unused includes.
 - Add include guards to headers.
 - Use unsigned variables in case they're never going to hold a negative
   value. This causes GCC's complaints to disappear and should make flexelint
   a lot happier, too.
 - Make functions private when they're used only within a module.
 - Remove unused variables.
 - Add casts where appropriate.
This commit is contained in:
Thomas Veerman 2010-06-01 12:35:33 +00:00
parent cc6fed4c51
commit 6bbcab3ec4
31 changed files with 685 additions and 744 deletions

View file

@ -150,6 +150,7 @@
/* Some limits. */
#define MAX_INODE_NR ((ino_t) 037777777777) /* largest inode number */
#define MAX_FILE_POS ((off_t) 0x7FFFFFFF) /* largest legal file offset */
#define UMAX_FILE_POS ((unsigned) 0x7FFFFFF) /* largest legal file offset */
#define MAX_SYM_LOOPS 8 /* how many symbolic links are recursed */
@ -158,6 +159,8 @@
#define NO_ZONE ((zone_t) 0) /* absence of a zone number */
#define NO_DEV ((dev_t) 0) /* absence of a device numb */
#define NO_LINK ((nlink_t) 0) /* absence of incoming links */
#define INVAL_UID ((uid_t) -1) /* invalid uid value */
#define INVAL_GID ((gid_t) -1) /* invalid gid value */
#define SERVARNAME "cttyline"

View file

@ -52,8 +52,8 @@ enum dev_style { STYLE_NDEV, STYLE_DEV, STYLE_DEVA, STYLE_TTY, STYLE_CTTY,
# define IS_KLOG_DEV 0 /* minor device for /dev/klog */
/* Full device numbers that are special to the boot monitor and FS. */
# define DEV_RAM 0x0100 /* device number of /dev/ram */
# define DEV_IMGRD 0x0106 /* device number of /dev/imgrd */
# define DEV_RAM ((dev_t) 0x0100) /* device number of /dev/ram */
# define DEV_IMGRD ((dev_t) 0x0106) /* device number of /dev/imgrd */
#endif /* _DMAP_H */

View file

@ -137,7 +137,7 @@ cpf_grant_direct(endpoint_t who_to, vir_bytes addr, size_t bytes, int access)
/* Get new slot to put new grant in. */
if((g = cpf_new_grantslot()) < 0)
return -1;
return(GRANT_INVALID);
assert(GRANT_VALID(g));
assert(g >= 0);
@ -146,7 +146,7 @@ cpf_grant_direct(endpoint_t who_to, vir_bytes addr, size_t bytes, int access)
if((r=cpf_setgrant_direct(g, who_to, addr, bytes, access)) < 0) {
cpf_revoke(g);
return GRANT_INVALID;
return(GRANT_INVALID);
}
return g;

View file

@ -1,3 +1,6 @@
#ifndef __MFS_BUF_H__
#define __MFS_BUF_H__
/* Buffer (block) cache. To acquire a block, a routine calls get_block(),
* telling which block it wants. The block is then regarded as "in use"
* and has its 'b_count' field incremented. All the blocks that are not
@ -46,7 +49,7 @@ union fsdata_u {
EXTERN struct buf *front; /* points to least recently used free block */
EXTERN struct buf *rear; /* points to most recently used free block */
EXTERN int bufs_in_use; /* # bufs currently in use (not on free list)*/
EXTERN unsigned int bufs_in_use;/* # bufs currently in use (not on free list)*/
/* When a block is released, the type of usage is passed to put_block(). */
#define WRITE_IMMED 0100 /* block should be written to disk now */
@ -59,3 +62,5 @@ EXTERN int bufs_in_use; /* # bufs currently in use (not on free list)*/
#define FULL_DATA_BLOCK 5 /* data, fully used */
#define PARTIAL_DATA_BLOCK 6 /* data, partly used*/
#endif

View file

@ -15,9 +15,7 @@
*/
#include "fs.h"
#include <minix/com.h>
#include <minix/u64.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "buf.h"
@ -25,7 +23,7 @@
#include "inode.h"
FORWARD _PROTOTYPE( void rm_lru, (struct buf *bp) );
FORWARD _PROTOTYPE( int rw_block, (struct buf *, int) );
FORWARD _PROTOTYPE( void rw_block, (struct buf *, int) );
PRIVATE int vmcache_avail = -1; /* 0 if not available, >0 if available. */
@ -111,7 +109,7 @@ PUBLIC struct buf *get_block(
if(bp->b_bytes < fs_block_size) {
ASSERT(!bp->bp);
ASSERT(bp->b_bytes == 0);
if(!(bp->bp = alloc_contig(fs_block_size, 0, NULL))) {
if(!(bp->bp = alloc_contig( (size_t) fs_block_size, 0, NULL))) {
printf("MFS: couldn't allocate a new block.\n");
for(bp = front;
bp && bp->b_bytes < fs_block_size; bp = bp->b_next)
@ -303,7 +301,7 @@ PUBLIC zone_t alloc_zone(
if (z == sp->s_firstdatazone) {
bit = sp->s_zsearch;
} else {
bit = (bit_t) z - (sp->s_firstdatazone - 1);
bit = (bit_t) (z - (sp->s_firstdatazone - 1));
}
b = alloc_bit(sp, ZMAP, bit);
if (b == NO_BIT) {
@ -314,7 +312,7 @@ PUBLIC zone_t alloc_zone(
return(NO_ZONE);
}
if (z == sp->s_firstdatazone) sp->s_zsearch = b; /* for next time */
return(sp->s_firstdatazone - 1 + (zone_t) b);
return( (zone_t) (sp->s_firstdatazone - 1) + (zone_t) b);
}
/*===========================================================================*
@ -333,7 +331,7 @@ PUBLIC void free_zone(
/* Locate the appropriate super_block and return bit. */
sp = get_super(dev);
if (numb < sp->s_firstdatazone || numb >= sp->s_zones) return;
bit = (bit_t) (numb - (sp->s_firstdatazone - 1));
bit = (bit_t) (numb - (zone_t) (sp->s_firstdatazone - 1));
free_bit(sp, ZMAP, bit);
if (bit < sp->s_zsearch) sp->s_zsearch = bit;
}
@ -341,7 +339,7 @@ PUBLIC void free_zone(
/*===========================================================================*
* rw_block *
*===========================================================================*/
PRIVATE int rw_block(bp, rw_flag)
PRIVATE void rw_block(bp, rw_flag)
register struct buf *bp; /* buffer pointer */
int rw_flag; /* READING or WRITING */
{
@ -350,31 +348,35 @@ int rw_flag; /* READING or WRITING */
* is not reported to the caller. If the error occurred while purging a block
* from the cache, it is not clear what the caller could do about it anyway.
*/
int r, op;
int r, op, op_failed;
u64_t pos;
dev_t dev;
if ( (dev = bp->b_dev) != NO_DEV) {
pos = mul64u(bp->b_blocknr, fs_block_size);
op = (rw_flag == READING ? MFS_DEV_READ : MFS_DEV_WRITE);
r = block_dev_io(op, dev, SELF_E, bp->b_data, pos, fs_block_size, 0);
if (r != fs_block_size) {
if (r >= 0) r = END_OF_FILE;
if (r != END_OF_FILE)
printf("MFS(%d) I/O error on device %d/%d, block %ld\n",
SELF_E, (dev>>MAJOR)&BYTE, (dev>>MINOR)&BYTE,
bp->b_blocknr);
bp->b_dev = NO_DEV; /* invalidate block */
op_failed = 0;
/* Report read errors to interested parties. */
if (rw_flag == READING) rdwt_err = r;
}
if ( (dev = bp->b_dev) != NO_DEV) {
pos = mul64u(bp->b_blocknr, fs_block_size);
op = (rw_flag == READING ? MFS_DEV_READ : MFS_DEV_WRITE);
r = block_dev_io(op, dev, SELF_E, bp->b_data, pos, fs_block_size);
if (r < 0) {
printf("MFS(%d) I/O error on device %d/%d, block %lu\n",
SELF_E, major(dev), minor(dev), bp->b_blocknr);
op_failed = 1;
} else if( (unsigned) r != fs_block_size) {
r = END_OF_FILE;
op_failed = 1;
}
if (op_failed) {
bp->b_dev = NO_DEV; /* invalidate block */
/* Report read errors to interested parties. */
if (rw_flag == READING) rdwt_err = r;
}
}
bp->b_dirt = CLEAN;
return OK;
}
/*===========================================================================*
@ -405,12 +407,14 @@ PUBLIC void flushall(
register struct buf *bp;
static struct buf **dirty; /* static so it isn't on stack */
static int dirtylistsize = 0;
static unsigned int dirtylistsize = 0;
int ndirty;
if(dirtylistsize != nr_bufs) {
if(dirtylistsize > 0)
if(dirtylistsize > 0) {
assert(dirty != NULL);
free(dirty);
}
if(!(dirty = malloc(sizeof(dirty[0])*nr_bufs)))
panic("couldn't allocate dirty buf list");
dirtylistsize = nr_bufs;
@ -466,13 +470,13 @@ PUBLIC void rw_scattered(
while (bufqsize > 0) {
for (j = 0, iop = iovec; j < NR_IOREQS && j < bufqsize; j++, iop++) {
bp = bufq[j];
if (bp->b_blocknr != bufq[0]->b_blocknr + j) break;
if (bp->b_blocknr != (block_t) bufq[0]->b_blocknr + j) break;
iop->iov_addr = (vir_bytes) bp->b_data;
iop->iov_size = fs_block_size;
iop->iov_size = (vir_bytes) fs_block_size;
}
r = block_dev_io(rw_flag == WRITING ? MFS_DEV_SCATTER : MFS_DEV_GATHER,
dev, SELF_E, iovec,
mul64u(bufq[0]->b_blocknr, fs_block_size), j, 0);
mul64u(bufq[0]->b_blocknr, fs_block_size), j);
/* Harvest the results. Dev_io reports the first error it may have
* encountered, but we only care if it's the first block that failed.
@ -484,8 +488,7 @@ PUBLIC void rw_scattered(
if (r != OK && i == 0) {
printf(
"fs: I/O error on device %d/%d, block %lu\n",
(dev>>MAJOR)&BYTE, (dev>>MINOR)&BYTE,
bp->b_blocknr);
major(dev), minor(dev), bp->b_blocknr);
bp->b_dev = NO_DEV; /* invalidate block */
vm_forgetblocks();
}
@ -546,23 +549,21 @@ struct buf *bp;
/*===========================================================================*
* set_blocksize *
*===========================================================================*/
PUBLIC void set_blocksize(int blocksize)
PUBLIC void set_blocksize(unsigned int blocksize)
{
struct buf *bp;
struct inode *rip;
struct buf *bp;
struct inode *rip;
ASSERT(blocksize > 0);
ASSERT(blocksize > 0);
for (bp = &buf[0]; bp < &buf[nr_bufs]; bp++)
if(bp->b_count != 0)
panic("change blocksize with buffer in use");
for (bp = &buf[0]; bp < &buf[nr_bufs]; bp++)
if(bp->b_count != 0) panic("change blocksize with buffer in use");
for (rip = &inode[0]; rip < &inode[NR_INODES]; rip++)
if (rip->i_count > 0)
panic("change blocksize with inode in use");
for (rip = &inode[0]; rip < &inode[NR_INODES]; rip++)
if (rip->i_count > 0) panic("change blocksize with inode in use");
buf_pool(nr_bufs);
fs_block_size = blocksize;
buf_pool(nr_bufs);
fs_block_size = blocksize;
}
/*===========================================================================*
@ -577,7 +578,7 @@ PUBLIC void buf_pool(int new_nr_bufs)
if(nr_bufs > 0) {
assert(buf);
fs_sync();
(void) fs_sync();
for (bp = &buf[0]; bp < &buf[nr_bufs]; bp++) {
if(bp->bp) {
assert(bp->b_bytes > 0);
@ -611,8 +612,8 @@ PUBLIC void buf_pool(int new_nr_bufs)
bp->bp = NULL;
bp->b_bytes = 0;
}
buf[0].b_prev = NULL;
buf[nr_bufs - 1].b_next = NULL;
front->b_prev = NULL;
rear->b_next = NULL;
for (bp = &buf[0]; bp < &buf[nr_bufs]; bp++) bp->b_hash = bp->b_next;
buf_hash[0] = front;

View file

@ -1,3 +1,6 @@
#ifndef __MFS_CONST_H__
#define __MFS_CONST_H__
/* Tables sizes */
#define V1_NR_DZONES 7 /* # direct zone numbers in a V1 inode */
#define V1_NR_TZONES 9 /* total # zone numbers in a V1 inode */
@ -31,8 +34,6 @@
/* Miscellaneous constants */
#define SU_UID ((uid_t) 0) /* super_user's uid_t */
#define SYS_UID ((uid_t) 0) /* uid_t for processes MM and INIT */
#define SYS_GID ((gid_t) 0) /* gid_t for processes MM and INIT */
#define NORMAL 0 /* forces get_block to do disk read */
#define NO_READ 1 /* prevents get_block from doing disk read */
#define PREFETCH 2 /* tells get_block not to read or mark dev */
@ -50,17 +51,6 @@
#define IGN_PERM 0
#define CHK_PERM 1
#define PATH_TRANSPARENT 000 /* parse_path stops at final object */
#define PATH_PENULTIMATE 001 /* parse_path stops at last but one name */
#define PATH_OPAQUE 002 /* parse_path stops at final name */
#define PATH_NONSYMBOLIC 004 /* parse_path scans final name if symbolic */
#define PATH_STRIPDOT 010 /* parse_path strips /. from path */
#define EAT_PATH PATH_TRANSPARENT
#define EAT_PATH_OPAQUE PATH_OPAQUE
#define LAST_DIR PATH_PENULTIMATE
#define LAST_DIR_NOTDOT PATH_PENULTIMATE | PATH_STRIPDOT
#define LAST_DIR_EATSYM PATH_NONSYMBOLIC
#define CLEAN 0 /* disk and memory copies identical */
#define DIRTY 1 /* disk and memory copies differ */
#define ATIME 002 /* set if atime field needs updating */
@ -71,10 +61,10 @@
#define END_OF_FILE (-104) /* eof detected */
#define ROOT_INODE 1 /* inode number for root directory */
#define ROOT_INODE ((ino_t) 1) /* inode number for root directory */
#define BOOT_BLOCK ((block_t) 0) /* block number of boot block */
#define SUPER_BLOCK_BYTES (1024) /* bytes offset */
#define START_BLOCK 2 /* first block of FS (not counting SB) */
#define SUPER_BLOCK_BYTES (1024) /* bytes offset */
#define START_BLOCK ((block_t) 2) /* first block of FS (not counting SB) */
#define DIR_ENTRY_SIZE usizeof (struct direct) /* # bytes/dir entry */
#define NR_DIR_ENTRIES(b) ((b)/DIR_ENTRY_SIZE) /* # dir entries/blk */
@ -100,8 +90,7 @@
#define V2_INDIRECTS(b) ((b)/V2_ZONE_NUM_SIZE) /* # zones/indir block */
#define V2_INODES_PER_BLOCK(b) ((b)/V2_INODE_SIZE)/* # V2 dsk inodes/blk */
#define MFS_MIN(a,b) mfs_min_f(__FILE__,__LINE__,(a), (b))
#define MFS_NUL(str,l,m) mfs_nul_f(__FILE__,__LINE__,(str), (l), (m))
#define NUL(str,l,m) mfs_nul_f(__FILE__,__LINE__,(str), (l), (m))
/* Args to dev_bio/dev_io */
#define MFS_DEV_READ 10001
@ -109,3 +98,5 @@
#define MFS_DEV_SCATTER 10003
#define MFS_DEV_GATHER 10004
#endif

View file

@ -1,10 +1,6 @@
#include "fs.h"
#include <fcntl.h>
#include <assert.h>
#include <minix/callnr.h>
#include <minix/com.h>
#include <minix/endpoint.h>
#include <minix/ioctl.h>
#include <minix/safecopies.h>
#include <minix/u64.h>
#include <string.h>
@ -15,15 +11,13 @@
#include <minix/vfsif.h>
PRIVATE int dummyproc;
FORWARD _PROTOTYPE( int safe_io_conversion, (endpoint_t,
cp_grant_id_t *, int *, cp_grant_id_t *, int, endpoint_t *,
void **, int *, vir_bytes));
FORWARD _PROTOTYPE( int safe_io_conversion, (endpoint_t driver,
cp_grant_id_t *gid, int *op, cp_grant_id_t *gids, endpoint_t *io_ept,
void **buffer, int *vec_grants, size_t bytes));
FORWARD _PROTOTYPE( void safe_io_cleanup, (cp_grant_id_t, cp_grant_id_t *,
int));
FORWARD _PROTOTYPE( int gen_opcl, (endpoint_t driver_e, int op,
dev_t dev, int proc_e, int flags) );
dev_t dev, endpoint_t proc_e, int flags) );
FORWARD _PROTOTYPE( int gen_io, (endpoint_t task_nr, message *mess_ptr) );
@ -33,8 +27,9 @@ FORWARD _PROTOTYPE( int gen_io, (endpoint_t task_nr, message *mess_ptr) );
PUBLIC int fs_new_driver(void)
{
/* New driver endpoint for this device */
driver_endpoints[(fs_m_in.REQ_DEV >> MAJOR) & BYTE].driver_e =
fs_m_in.REQ_DRIVER_E;
dev_t dev;
dev = (dev_t) fs_m_in.REQ_DEV;
driver_endpoints[major(dev)].driver_e = (endpoint_t) fs_m_in.REQ_DRIVER_E;
return(OK);
}
@ -42,19 +37,19 @@ PUBLIC int fs_new_driver(void)
/*===========================================================================*
* safe_io_conversion *
*===========================================================================*/
PRIVATE int safe_io_conversion(driver, gid, op, gids, gids_size,
io_ept, buf, vec_grants, bytes)
PRIVATE int safe_io_conversion(driver, gid, op, gids, io_ept, buffer,
vec_grants, bytes)
endpoint_t driver;
cp_grant_id_t *gid;
int *op;
cp_grant_id_t *gids;
int gids_size;
endpoint_t *io_ept;
void **buf;
void **buffer;
int *vec_grants;
vir_bytes bytes;
size_t bytes;
{
int j;
unsigned int j;
int access;
iovec_t *v;
static iovec_t *new_iovec;
@ -72,9 +67,9 @@ vir_bytes bytes;
case MFS_DEV_WRITE:
/* Change to safe op. */
*op = *op == MFS_DEV_READ ? DEV_READ_S : DEV_WRITE_S;
if((*gid=cpf_grant_direct(driver, (vir_bytes) *buf, bytes,
*op == DEV_READ_S?CPF_WRITE:CPF_READ))<0) {
*gid = cpf_grant_direct(driver, (vir_bytes) *buffer, bytes,
*op == DEV_READ_S ? CPF_WRITE : CPF_READ);
if(*gid == GRANT_INVALID) {
panic("cpf_grant_magic of buffer failed");
}
@ -85,20 +80,23 @@ vir_bytes bytes;
*op = *op == MFS_DEV_GATHER ? DEV_GATHER_S : DEV_SCATTER_S;
/* Grant access to my new i/o vector. */
if((*gid = cpf_grant_direct(driver, (vir_bytes) new_iovec,
bytes * sizeof(iovec_t),
CPF_READ | CPF_WRITE)) < 0) {
*gid = cpf_grant_direct(driver, (vir_bytes) new_iovec,
bytes * sizeof(iovec_t), CPF_READ|CPF_WRITE);
if(*gid == GRANT_INVALID) {
panic("cpf_grant_direct of vector failed");
}
v = (iovec_t *) *buf;
v = (iovec_t *) *buffer;
/* Grant access to i/o buffers. */
for(j = 0; j < bytes; j++) {
if(j >= NR_IOREQS)
panic("vec too big: %d", bytes);
panic("vec too big: %u", bytes);
access = (*op == DEV_GATHER_S) ? CPF_WRITE : CPF_READ;
new_iovec[j].iov_addr = gids[j] =
cpf_grant_direct(driver, (vir_bytes) v[j].iov_addr,
v[j].iov_size,
*op == DEV_GATHER_S ? CPF_WRITE : CPF_READ);
cpf_grant_direct(driver, (vir_bytes) v[j].iov_addr,
(size_t) v[j].iov_size, access);
if(!GRANT_VALID(gids[j])) {
panic("mfs: grant to iovec buf failed");
}
@ -107,7 +105,10 @@ vir_bytes bytes;
}
/* Set user's vector to the new one. */
*buf = new_iovec;
*buffer = new_iovec;
break;
default:
panic("Illegal operation %d\n", *op);
break;
}
@ -136,10 +137,10 @@ int gids_size;
/* Free resources (specifically, grants) allocated by safe_io_conversion(). */
int j;
cpf_revoke(gid);
(void) cpf_revoke(gid);
for(j = 0; j < gids_size; j++)
cpf_revoke(gids[j]);
(void) cpf_revoke(gids[j]);
return;
}
@ -150,11 +151,10 @@ int gids_size;
PUBLIC int block_dev_io(
int op, /* MFS_DEV_READ, MFS_DEV_WRITE, etc. */
dev_t dev, /* major-minor device number */
int proc_e, /* in whose address space is buf? */
void *buf, /* virtual address of the buffer */
endpoint_t proc_e, /* in whose address space is buf? */
void *buffer, /* virtual address of the buffer */
u64_t pos, /* byte position */
int bytes, /* how many bytes to transfer */
int flags /* special flags, like O_NONBLOCK */
size_t bytes /* how many bytes to transfer */
)
{
/* Read or write from a device. The parameter 'dev' tells which one. */
@ -170,36 +170,35 @@ PUBLIC int block_dev_io(
STATICINIT(gids, NR_IOREQS);
/* Determine driver endpoint for this device */
driver_e = driver_endpoints[(dev >> MAJOR) & BYTE].driver_e;
driver_e = driver_endpoints[major(dev)].driver_e;
/* See if driver is roughly valid. */
if (driver_e == NONE) {
printf("MFS(%d) block_dev_io: no driver for dev %x\n", SELF_E, dev);
return(EDEADSRCDST);
printf("MFS(%d) block_dev_io: no driver for dev %x\n", SELF_E, dev);
return(EDEADSRCDST);
}
/* The io vector copying relies on this I/O being for FS itself. */
if(proc_e != SELF_E) {
printf("MFS(%d) doing block_dev_io for non-self %d\n", SELF_E, proc_e);
panic("doing block_dev_io for non-self: %d", proc_e);
printf("MFS(%d) doing block_dev_io for non-self %d\n", SELF_E, proc_e);
panic("doing block_dev_io for non-self: %d", proc_e);
}
/* By default, these are right. */
m.IO_ENDPT = proc_e;
m.ADDRESS = buf;
buf_used = buf;
m.ADDRESS = buffer;
buf_used = buffer;
/* Convert parameters to 'safe mode'. */
op_used = op;
safe = safe_io_conversion(driver_e, &gid,
&op_used, gids, NR_IOREQS, &m.IO_ENDPT, &buf_used,
&vec_grants, bytes);
safe = safe_io_conversion(driver_e, &gid, &op_used, gids, &m.IO_ENDPT,
&buf_used, &vec_grants, bytes);
/* Set up rest of the message. */
if (safe) m.IO_GRANT = (char *) gid;
m.m_type = op_used;
m.DEVICE = (dev >> MINOR) & BYTE;
m.DEVICE = minor(dev);
m.POSITION = ex64lo(pos);
m.COUNT = bytes;
m.HIGHPOS = ex64hi(pos);
@ -218,34 +217,32 @@ PUBLIC int block_dev_io(
* - VFS sends the new driver endp for the FS proc and the request again
*/
if (r != OK) {
if (r == EDEADSRCDST) {
printf("MFS(%d) dead driver %d\n", SELF_E, driver_e);
driver_endpoints[(dev >> MAJOR) & BYTE].driver_e = NONE;
return r;
/*dmap_unmap_by_endpt(task_nr); <- in the VFS proc... */
}
else if (r == ELOCKED) {
printf("MFS(%d) ELOCKED talking to %d\n", SELF_E, driver_e);
return r;
}
else
panic("call_task: can't send/receive: %d", r);
}
else {
/* Did the process we did the sendrec() for get a result? */
if (m.REP_ENDPT != proc_e) {
printf("MFS(%d) strange device reply from %d, type = %d, proc = %d (not %d) (2) ignored\n", SELF_E, m.m_source, m.m_type, proc_e, m.REP_ENDPT);
r = EIO;
}
if (r == EDEADSRCDST) {
printf("MFS(%d) dead driver %d\n", SELF_E, driver_e);
driver_endpoints[major(dev)].driver_e = NONE;
return(r);
} else if (r == ELOCKED) {
printf("MFS(%d) ELOCKED talking to %d\n", SELF_E, driver_e);
return(r);
} else
panic("call_task: can't send/receive: %d", r);
} else {
/* Did the process we did the sendrec() for get a result? */
if (m.REP_ENDPT != proc_e) {
printf("MFS(%d) strange device reply from %d, type = %d, proc "
"= %d (not %d) (2) ignored\n", SELF_E, m.m_source,
m.m_type, proc_e, m.REP_ENDPT);
r = EIO;
}
}
/* Task has completed. See if call completed. */
if (m.REP_STATUS == SUSPEND) {
panic("MFS block_dev_io: driver returned SUSPEND");
panic("MFS block_dev_io: driver returned SUSPEND");
}
if(buf != buf_used && r == OK) {
memcpy(buf, buf_used, bytes * sizeof(iovec_t));
if(buffer != buf_used && r == OK) {
memcpy(buffer, buf_used, bytes * sizeof(iovec_t));
}
return(m.REP_STATUS);
@ -257,7 +254,7 @@ PUBLIC int block_dev_io(
PUBLIC int dev_open(
endpoint_t driver_e,
dev_t dev, /* device to open */
int proc, /* process to open for */
endpoint_t proc_e, /* process to open for */
int flags /* mode bits and flags */
)
{
@ -267,9 +264,12 @@ PUBLIC int dev_open(
* open/close routine. (This is the only routine that must check the
* device number for being in range. All others can trust this check.)
*/
major = (dev >> MAJOR) & BYTE;
if (major >= NR_DEVICES) major = 0;
r = gen_opcl(driver_e, DEV_OPEN, dev, proc, flags);
major = major(dev);
if (major >= NR_DEVICES) {
printf("Major device number %d not in range\n", major(dev));
return(EIO);
}
r = gen_opcl(driver_e, DEV_OPEN, dev, proc_e, flags);
if (r == SUSPEND) panic("suspend on open from");
return(r);
}
@ -294,7 +294,7 @@ PRIVATE int gen_opcl(
endpoint_t driver_e,
int op, /* operation, DEV_OPEN or DEV_CLOSE */
dev_t dev, /* device to open or close */
int proc_e, /* process to open/close for */
endpoint_t proc_e, /* process to open/close for */
int flags /* mode bits and flags */
)
{
@ -302,12 +302,12 @@ PRIVATE int gen_opcl(
message dev_mess;
dev_mess.m_type = op;
dev_mess.DEVICE = (dev >> MINOR) & BYTE;
dev_mess.DEVICE = minor(dev);
dev_mess.IO_ENDPT = proc_e;
dev_mess.COUNT = flags;
/* Call the task. */
gen_io(driver_e, &dev_mess);
(void) gen_io(driver_e, &dev_mess);
return(dev_mess.REP_STATUS);
}
@ -330,31 +330,30 @@ PRIVATE int gen_io(
proc_e = mess_ptr->IO_ENDPT;
r = sendrec(task_nr, mess_ptr);
if(r == OK && mess_ptr->REP_STATUS == ERESTART) r = EDEADSRCDST;
if (r != OK) {
if (r == EDEADSRCDST) {
printf("fs: dead driver %d\n", task_nr);
panic("should handle crashed drivers");
/* dmap_unmap_by_endpt(task_nr); */
return r;
}
if (r == ELOCKED) {
printf("fs: ELOCKED talking to %d\n", task_nr);
return r;
}
panic("call_task: can't send/receive: %d", r);
}
if(r == OK && mess_ptr->REP_STATUS == ERESTART)
r = EDEADSRCDST;
/* Did the process we did the sendrec() for get a result? */
if (mess_ptr->REP_ENDPT != proc_e) {
printf(
"fs: strange device reply from %d, type = %d, proc = %d (not %d) (2) ignored\n",
mess_ptr->m_source,
mess_ptr->m_type,
proc_e,
mess_ptr->REP_ENDPT);
return(EIO);
if (r != OK) {
if (r == EDEADSRCDST) {
printf("fs: dead driver %d\n", task_nr);
panic("should handle crashed drivers");
return(r);
}
if (r == ELOCKED) {
printf("fs: ELOCKED talking to %d\n", task_nr);
return(r);
}
panic("call_task: can't send/receive: %d", r);
}
/* Did the process we did the sendrec() for get a result? */
if (mess_ptr->REP_ENDPT != proc_e) {
printf("fs: strange device reply from %d, type = %d, proc = %d (not "
"%d) (2) ignored\n", mess_ptr->m_source, mess_ptr->m_type,
proc_e,
mess_ptr->REP_ENDPT);
return(EIO);
}
return(OK);
}

View file

@ -1,3 +1,5 @@
#ifndef __MFS_DRIVERS_H__
#define __MFS_DRIVERS_H__
/* Driver endpoints for major devices. Only the block devices
* are mapped here, it's a subset of the mapping in the VFS */
@ -6,4 +8,4 @@ EXTERN struct driver_endpoints {
endpoint_t driver_e;
} driver_endpoints[NR_DEVICES];
#endif

View file

@ -1,3 +1,6 @@
#ifndef __MFS_FS_H__
#define __MFS_FS_H__
/* This is the master header for fs. It includes some other files
* and defines the principal constants.
*/
@ -25,3 +28,6 @@
#include "type.h"
#include "proto.h"
#include "glo.h"
#endif

View file

@ -1,3 +1,6 @@
#ifndef __MFS_GLO_H__
#define __MFS_GLO_H__
/* EXTERN should be extern except for the table file */
#ifdef _TABLE
#undef EXTERN
@ -22,25 +25,16 @@ extern _PROTOTYPE (int (*fs_call_vec[]), (void) ); /* fs call table */
EXTERN message fs_m_in;
EXTERN message fs_m_out;
EXTERN int FS_STATE;
EXTERN vfs_ucred_t credentials;
EXTERN uid_t caller_uid;
EXTERN gid_t caller_gid;
EXTERN time_t boottime; /* time in seconds at system boot */
EXTERN int use_getuptime2; /* Should be removed togetherwith boottime */
EXTERN int req_nr;
EXTERN int SELF_E;
EXTERN endpoint_t SELF_E;
EXTERN struct inode *chroot_dir;
EXTERN short path_processed; /* number of characters processed */
EXTERN char user_path[PATH_MAX+1]; /* pathname to be processed */
EXTERN char *vfs_slink_storage;
EXTERN int Xsymloop;
EXTERN dev_t fs_dev; /* The device that is handled by this FS proc.
*/
@ -51,10 +45,12 @@ EXTERN int unmountdone;
EXTERN int exitsignaled;
/* our block size. */
EXTERN int fs_block_size;
EXTERN unsigned int fs_block_size;
/* Buffer cache. */
EXTERN struct buf *buf;
EXTERN struct buf **buf_hash; /* the buffer hash table */
EXTERN int nr_bufs;
EXTERN unsigned int nr_bufs;
EXTERN int may_use_vmcache;
#endif

View file

@ -1,31 +0,0 @@
#define _SYSTEM 1 /* get OK and negative error codes */
#define _MINIX 1 /* tell headers to include MINIX stuff */
#define VERBOSE 0 /* display diagnostics */
#include <ansi.h>
#include <sys/types.h>
#include <limits.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <minix/callnr.h>
#include <minix/config.h>
#include <minix/type.h>
#include <minix/const.h>
#include <minix/com.h>
#include <minix/syslib.h>
#include <minix/sysutil.h>
#include <minix/keymap.h>
#include <minix/bitmap.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include "proto.h"

View file

@ -22,12 +22,15 @@
#include "super.h"
#include <minix/vfsif.h>
FORWARD _PROTOTYPE( int addhash_inode, (struct inode *node) );
FORWARD _PROTOTYPE( void addhash_inode, (struct inode *node) );
FORWARD _PROTOTYPE( void free_inode, (dev_t dev, ino_t numb) );
FORWARD _PROTOTYPE( void new_icopy, (struct inode *rip, d2_inode *dip,
int direction, int norm));
FORWARD _PROTOTYPE( void old_icopy, (struct inode *rip, d1_inode *dip,
int direction, int norm));
FORWARD _PROTOTYPE( int unhash_inode, (struct inode *node) );
FORWARD _PROTOTYPE( void unhash_inode, (struct inode *node) );
FORWARD _PROTOTYPE( void wipe_inode, (struct inode *rip) );
/*===========================================================================*
@ -40,11 +43,11 @@ PUBLIC int fs_putnode(void)
struct inode *rip;
int count;
rip = find_inode(fs_dev, fs_m_in.REQ_INODE_NR);
rip = find_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR);
if(!rip) {
printf("%s:%d put_inode: inode #%d dev: %d not found\n", __FILE__,
__LINE__, fs_m_in.REQ_INODE_NR, fs_dev);
printf("%s:%d put_inode: inode #%ul dev: %d not found\n", __FILE__,
__LINE__, (ino_t) fs_m_in.REQ_INODE_NR, fs_dev);
panic("fs_putnode failed");
}
@ -88,7 +91,7 @@ PUBLIC void init_inode_cache()
/* add free inodes to unused/free list */
for (rip = &inode[0]; rip < &inode[NR_INODES]; ++rip) {
rip->i_num = 0;
rip->i_num = NO_ENTRY;
TAILQ_INSERT_HEAD(&unused_inodes, rip, i_unused);
}
}
@ -97,24 +100,22 @@ PUBLIC void init_inode_cache()
/*===========================================================================*
* addhash_inode *
*===========================================================================*/
PRIVATE int addhash_inode(struct inode *node)
PRIVATE void addhash_inode(struct inode *node)
{
int hashi = node->i_num & INODE_HASH_MASK;
int hashi = (int) (node->i_num & INODE_HASH_MASK);
/* insert into hash table */
LIST_INSERT_HEAD(&hash_inodes[hashi], node, i_hash);
return(OK);
}
/*===========================================================================*
* unhash_inode *
*===========================================================================*/
PRIVATE int unhash_inode(struct inode *node)
PRIVATE void unhash_inode(struct inode *node)
{
/* remove from hash table */
LIST_REMOVE(node, i_hash);
return(OK);
}
@ -123,7 +124,7 @@ PRIVATE int unhash_inode(struct inode *node)
*===========================================================================*/
PUBLIC struct inode *get_inode(
dev_t dev, /* device on which inode resides */
int numb /* inode number (ANSI: may not be unshort) */
ino_t numb /* inode number */
)
{
/* Find the inode in the hash table. If it is not there, get a free inode
@ -132,7 +133,7 @@ PUBLIC struct inode *get_inode(
register struct inode *rip;
int hashi;
hashi = numb & INODE_HASH_MASK;
hashi = (int) (numb & INODE_HASH_MASK);
/* Search inode in the hash table */
LIST_FOREACH(rip, &hash_inodes[hashi], i_hash) {
@ -157,7 +158,7 @@ PUBLIC struct inode *get_inode(
rip = TAILQ_FIRST(&unused_inodes);
/* If not free unhash it */
if (rip->i_num != 0)
if (rip->i_num != NO_ENTRY)
unhash_inode(rip);
/* Inode is not unused any more */
@ -184,7 +185,7 @@ PUBLIC struct inode *get_inode(
*===========================================================================*/
PUBLIC struct inode *find_inode(
dev_t dev, /* device on which inode resides */
int numb /* inode number (ANSI: may not be unshort) */
ino_t numb /* inode number */
)
{
/* Find the inode specified by the inode and device number.
@ -192,7 +193,7 @@ PUBLIC struct inode *find_inode(
struct inode *rip;
int hashi;
hashi = numb & INODE_HASH_MASK;
hashi = (int) (numb & INODE_HASH_MASK);
/* Search inode in the hash table */
LIST_FOREACH(rip, &hash_inodes[hashi], i_hash) {
@ -222,10 +223,11 @@ register struct inode *rip; /* pointer to inode to be released */
panic("put_inode: i_count already below 1: %d", rip->i_count);
if (--rip->i_count == 0) { /* i_count == 0 means no one is using it now */
if (rip->i_nlinks == 0) {
/* i_nlinks == 0 means free the inode. */
truncate_inode(rip, 0); /* return all the disk blocks */
rip->i_mode = I_NOT_ALLOC; /* clear I_TYPE field */
if (rip->i_nlinks == NO_LINK) {
/* i_nlinks == NO_LINK means free the inode. */
/* return all the disk blocks */
if (truncate_inode(rip, (off_t) 0) != OK) return;
rip->i_mode = I_NOT_ALLOC; /* clear I_TYPE field */
rip->i_dirt = DIRTY;
free_inode(rip->i_dev, rip->i_num);
}
@ -233,10 +235,10 @@ register struct inode *rip; /* pointer to inode to be released */
rip->i_mountpoint = FALSE;
if (rip->i_dirt == DIRTY) rw_inode(rip, WRITING);
if (rip->i_nlinks == 0) {
if (rip->i_nlinks == NO_LINK) {
/* free, put at the front of the LRU list */
unhash_inode(rip);
rip->i_num = 0;
rip->i_num = NO_ENTRY;
TAILQ_INSERT_HEAD(&unused_inodes, rip, i_unused);
} else {
/* unused, put at the back of the LRU (cache it) */
@ -283,7 +285,7 @@ PUBLIC struct inode *alloc_inode(dev_t dev, mode_t bits)
} else {
/* An inode slot is available. Put the inode just allocated into it. */
rip->i_mode = bits; /* set up RWX bits */
rip->i_nlinks = 0; /* initial no links */
rip->i_nlinks = NO_LINK; /* initial no links */
rip->i_uid = caller_uid; /* file's uid is owner's */
rip->i_gid = caller_gid; /* ditto group id */
rip->i_dev = dev; /* mark which device it is on */
@ -306,7 +308,7 @@ PUBLIC struct inode *alloc_inode(dev_t dev, mode_t bits)
/*===========================================================================*
* wipe_inode *
*===========================================================================*/
PUBLIC void wipe_inode(rip)
PRIVATE void wipe_inode(rip)
register struct inode *rip; /* the inode to be erased */
{
/* Erase some fields in the inode. This function is called from alloc_inode()
@ -325,7 +327,7 @@ register struct inode *rip; /* the inode to be erased */
/*===========================================================================*
* free_inode *
*===========================================================================*/
PUBLIC void free_inode(
PRIVATE void free_inode(
dev_t dev, /* on which device is the inode? */
ino_t inumb /* number of the inode to be freed */
)
@ -337,8 +339,8 @@ PUBLIC void free_inode(
/* Locate the appropriate super_block. */
sp = get_super(dev);
if (inumb <= 0 || inumb > sp->s_ninodes) return;
b = inumb;
if (inumb > sp->s_ninodes) return;
b = (bit_t) inumb;
free_bit(sp, IMAP, b);
if (b < sp->s_isearch) sp->s_isearch = b;
}
@ -434,28 +436,28 @@ int norm; /* TRUE = do not swap bytes; FALSE = swap */
if (direction == READING) {
/* Copy V1.x inode to the in-core table, swapping bytes if need be. */
rip->i_mode = conv2(norm, (int) dip->d1_mode);
rip->i_uid = conv2(norm, (int) dip->d1_uid );
rip->i_size = conv4(norm, dip->d1_size);
rip->i_mtime = conv4(norm, dip->d1_mtime);
rip->i_atime = rip->i_mtime;
rip->i_ctime = rip->i_mtime;
rip->i_nlinks = dip->d1_nlinks; /* 1 char */
rip->i_gid = dip->d1_gid; /* 1 char */
rip->i_mode = (mode_t) conv2(norm, (int) dip->d1_mode);
rip->i_uid = (uid_t) conv2(norm, (int) dip->d1_uid );
rip->i_size = (off_t) conv4(norm, dip->d1_size);
rip->i_mtime = (time_t) conv4(norm, dip->d1_mtime);
rip->i_atime = (time_t) rip->i_mtime;
rip->i_ctime = (time_t) rip->i_mtime;
rip->i_nlinks = (nlink_t) dip->d1_nlinks; /* 1 char */
rip->i_gid = (gid_t) dip->d1_gid; /* 1 char */
rip->i_ndzones = V1_NR_DZONES;
rip->i_nindirs = V1_INDIRECTS;
for (i = 0; i < V1_NR_TZONES; i++)
rip->i_zone[i] = conv2(norm, (int) dip->d1_zone[i]);
rip->i_zone[i] = (zone_t) conv2(norm, (int) dip->d1_zone[i]);
} else {
/* Copying V1.x inode to disk from the in-core table. */
dip->d1_mode = conv2(norm, (int) rip->i_mode);
dip->d1_uid = conv2(norm, (int) rip->i_uid );
dip->d1_size = conv4(norm, rip->i_size);
dip->d1_mtime = conv4(norm, rip->i_mtime);
dip->d1_nlinks = rip->i_nlinks; /* 1 char */
dip->d1_gid = rip->i_gid; /* 1 char */
dip->d1_mode = (u16_t) conv2(norm, (int) rip->i_mode);
dip->d1_uid = (i16_t) conv2(norm, (int) rip->i_uid );
dip->d1_size = (i32_t) conv4(norm, rip->i_size);
dip->d1_mtime = (i32_t) conv4(norm, rip->i_mtime);
dip->d1_nlinks = (u8_t) rip->i_nlinks; /* 1 char */
dip->d1_gid = (u8_t) rip->i_gid; /* 1 char */
for (i = 0; i < V1_NR_TZONES; i++)
dip->d1_zone[i] = conv2(norm, (int) rip->i_zone[i]);
dip->d1_zone[i] = (u16_t) conv2(norm, (int) rip->i_zone[i]);
}
}
@ -475,30 +477,30 @@ int norm; /* TRUE = do not swap bytes; FALSE = swap */
if (direction == READING) {
/* Copy V2.x inode to the in-core table, swapping bytes if need be. */
rip->i_mode = conv2(norm,dip->d2_mode);
rip->i_uid = conv2(norm,dip->d2_uid);
rip->i_nlinks = conv2(norm,dip->d2_nlinks);
rip->i_gid = conv2(norm,dip->d2_gid);
rip->i_size = conv4(norm,dip->d2_size);
rip->i_atime = conv4(norm,dip->d2_atime);
rip->i_ctime = conv4(norm,dip->d2_ctime);
rip->i_mtime = conv4(norm,dip->d2_mtime);
rip->i_mode = (mode_t) conv2(norm,dip->d2_mode);
rip->i_uid = (uid_t) conv2(norm,dip->d2_uid);
rip->i_nlinks = (nlink_t) conv2(norm,dip->d2_nlinks);
rip->i_gid = (gid_t) conv2(norm,dip->d2_gid);
rip->i_size = (off_t) conv4(norm,dip->d2_size);
rip->i_atime = (time_t) conv4(norm,dip->d2_atime);
rip->i_ctime = (time_t) conv4(norm,dip->d2_ctime);
rip->i_mtime = (time_t) conv4(norm,dip->d2_mtime);
rip->i_ndzones = V2_NR_DZONES;
rip->i_nindirs = V2_INDIRECTS(rip->i_sp->s_block_size);
for (i = 0; i < V2_NR_TZONES; i++)
rip->i_zone[i] = conv4(norm, (long) dip->d2_zone[i]);
rip->i_zone[i] = (zone_t) conv4(norm, (long) dip->d2_zone[i]);
} else {
/* Copying V2.x inode to disk from the in-core table. */
dip->d2_mode = conv2(norm,rip->i_mode);
dip->d2_uid = conv2(norm,rip->i_uid);
dip->d2_nlinks = conv2(norm,rip->i_nlinks);
dip->d2_gid = conv2(norm,rip->i_gid);
dip->d2_size = conv4(norm,rip->i_size);
dip->d2_atime = conv4(norm,rip->i_atime);
dip->d2_ctime = conv4(norm,rip->i_ctime);
dip->d2_mtime = conv4(norm,rip->i_mtime);
dip->d2_mode = (u16_t) conv2(norm,rip->i_mode);
dip->d2_uid = (i16_t) conv2(norm,rip->i_uid);
dip->d2_nlinks = (u16_t) conv2(norm,rip->i_nlinks);
dip->d2_gid = (u16_t) conv2(norm,rip->i_gid);
dip->d2_size = (i32_t) conv4(norm,rip->i_size);
dip->d2_atime = (i32_t) conv4(norm,rip->i_atime);
dip->d2_ctime = (i32_t) conv4(norm,rip->i_ctime);
dip->d2_mtime = (i32_t) conv4(norm,rip->i_mtime);
for (i = 0; i < V2_NR_TZONES; i++)
dip->d2_zone[i] = conv4(norm, (long) rip->i_zone[i]);
dip->d2_zone[i] = (zone_t) conv4(norm, (long) rip->i_zone[i]);
}
}

View file

@ -1,3 +1,6 @@
#ifndef __MFS_INODE_H__
#define __MFS_INODE_H__
/* Inode table. This table holds inodes that are currently in use. In some
* cases they have been opened by an open() or creat() system call, in other
* cases the file system itself needs the inode for one reason or another,
@ -28,11 +31,11 @@ EXTERN struct inode {
dev_t i_dev; /* which device is the inode on */
ino_t i_num; /* inode number on its (minor) device */
int i_count; /* # times inode used; 0 means slot is free */
int i_ndzones; /* # direct zones (Vx_NR_DZONES) */
int i_nindirs; /* # indirect zones per indirect block */
unsigned int i_ndzones; /* # direct zones (Vx_NR_DZONES) */
unsigned int i_nindirs; /* # indirect zones per indirect block */
struct super_block *i_sp; /* pointer to super block for inode's device */
char i_dirt; /* CLEAN or DIRTY */
bit_t i_zsearch; /* where to start search for new zones */
zone_t i_zsearch; /* where to start search for new zones */
char i_mountpoint; /* true if mounted on */
@ -57,3 +60,5 @@ EXTERN unsigned int inode_cache_miss;
/* Field values. Note that CLEAN and DIRTY are defined in "const.h" */
#define NO_SEEK 0 /* i_seek = NO_SEEK if last op was not SEEK */
#define ISEEK 1 /* i_seek = ISEEK if last op was SEEK */
#endif

View file

@ -2,7 +2,6 @@
#include <sys/stat.h>
#include <string.h>
#include <minix/com.h>
#include <minix/callnr.h>
#include "buf.h"
#include "inode.h"
#include "super.h"
@ -10,6 +9,9 @@
#define SAME 1000
FORWARD _PROTOTYPE( int freesp_inode, (struct inode *rip, off_t st,
off_t end) );
FORWARD _PROTOTYPE( int remove_dir, (struct inode *rldirp,
struct inode *rip, char dir_name[NAME_MAX]) );
FORWARD _PROTOTYPE( int unlink_file, (struct inode *dirp,
@ -38,20 +40,20 @@ PUBLIC int fs_link()
struct inode *new_ip;
phys_bytes len;
len = MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(string));
len = min( (unsigned) fs_m_in.REQ_PATH_LEN, sizeof(string));
/* Copy the link name's last component */
r = sys_safecopyfrom(FS_PROC_NR, fs_m_in.REQ_GRANT, 0,
(vir_bytes) string, (phys_bytes) len, D);
r = sys_safecopyfrom(FS_PROC_NR, (cp_grant_id_t) fs_m_in.REQ_GRANT,
(vir_bytes) 0, (vir_bytes) string, (size_t) len, D);
if (r != OK) return r;
MFS_NUL(string, len, sizeof(string));
NUL(string, len, sizeof(string));
/* Temporarily open the file. */
if( (rip = get_inode(fs_dev, fs_m_in.REQ_INODE_NR)) == NULL)
if( (rip = get_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL)
return(EINVAL);
/* Check to see if the file has maximum number of links already. */
r = OK;
if(rip->i_nlinks >= (rip->i_sp->s_version == V1 ? CHAR_MAX : SHRT_MAX))
if(rip->i_nlinks >= LINK_MAX)
r = EMLINK;
/* Only super_user may link to directories. */
@ -66,19 +68,17 @@ PUBLIC int fs_link()
}
/* Temporarily open the last dir */
if( (ip = get_inode(fs_dev, fs_m_in.REQ_DIR_INO)) == NULL)
if( (ip = get_inode(fs_dev, (ino_t) fs_m_in.REQ_DIR_INO)) == NULL)
return(EINVAL);
/* If 'name2' exists in full (even if no space) set 'r' to error. */
if (r == OK) {
if((new_ip = advance(ip, string, IGN_PERM)) == NULL) {
r = err_code;
if(r == ENOENT)
r = OK;
} else {
put_inode(new_ip);
r = EEXIST;
}
if((new_ip = advance(ip, string, IGN_PERM)) == NULL) {
r = err_code;
if(r == ENOENT)
r = OK;
} else {
put_inode(new_ip);
r = EEXIST;
}
/* Try to link. */
@ -115,18 +115,17 @@ PUBLIC int fs_unlink()
phys_bytes len;
/* Copy the last component */
len = MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(string));
r = sys_safecopyfrom(FS_PROC_NR, fs_m_in.REQ_GRANT, 0,
(vir_bytes) string, (phys_bytes) len, D);
len = min( (unsigned) fs_m_in.REQ_PATH_LEN, sizeof(string));
r = sys_safecopyfrom(FS_PROC_NR, (cp_grant_id_t) fs_m_in.REQ_GRANT,
(vir_bytes) 0, (vir_bytes) string, (size_t) len, D);
if (r != OK) return r;
MFS_NUL(string, len, sizeof(string));
NUL(string, len, sizeof(string));
/* Temporarily open the dir. */
if( (rldirp = get_inode(fs_dev, fs_m_in.REQ_INODE_NR)) == NULL)
if( (rldirp = get_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL)
return(EINVAL);
/* The last directory exists. Does the file also exist? */
r = OK;
rip = advance(rldirp, string, IGN_PERM);
r = err_code;
@ -169,13 +168,12 @@ PUBLIC int fs_rdlink()
struct buf *bp; /* buffer containing link text */
register struct inode *rip; /* target inode */
register int r; /* return value */
int copylen;
size_t copylen;
copylen = fs_m_in.REQ_MEM_SIZE;
if (copylen <= 0) return(EINVAL);
copylen = min( (size_t) fs_m_in.REQ_MEM_SIZE, UMAX_FILE_POS);
/* Temporarily open the file. */
if( (rip = get_inode(fs_dev, fs_m_in.REQ_INODE_NR)) == NULL)
if( (rip = get_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL)
return(EINVAL);
if(!S_ISLNK(rip->i_mode))
@ -184,14 +182,16 @@ PUBLIC int fs_rdlink()
r = EIO;
else {
/* Passed all checks */
if (copylen > rip->i_size)
copylen = rip->i_size;
bp = get_block(rip->i_dev, b, NORMAL);
r = sys_safecopyto(FS_PROC_NR, fs_m_in.REQ_GRANT, 0,
(vir_bytes) bp->b_data, (vir_bytes) copylen, D);
put_block(bp, DIRECTORY_BLOCK);
if (r == OK)
fs_m_out.RES_NBYTES = copylen;
/* We can safely cast to unsigned, because copylen is guaranteed to be
below max file size */
copylen = min( copylen, (unsigned) rip->i_size);
bp = get_block(rip->i_dev, b, NORMAL);
r = sys_safecopyto(FS_PROC_NR, (cp_grant_id_t) fs_m_in.REQ_GRANT,
(vir_bytes) 0, (vir_bytes) bp->b_data,
(size_t) copylen, D);
put_block(bp, DIRECTORY_BLOCK);
if (r == OK)
fs_m_out.RES_NBYTES = copylen;
}
put_inode(rip);
@ -218,7 +218,7 @@ char dir_name[NAME_MAX]; /* name of directory to be removed */
/* search_dir checks that rip is a directory too. */
if ((r = search_dir(rip, "", (ino_t *) 0, IS_EMPTY, IGN_PERM)) != OK)
return r;
return(r);
if (strcmp(dir_name, ".") == 0 || strcmp(dir_name, "..") == 0)return(EINVAL);
if (rip->i_num == ROOT_INODE) return(EBUSY); /* can't remove 'root' */
@ -288,21 +288,21 @@ PUBLIC int fs_rename()
phys_bytes len;
/* Copy the last component of the old name */
len = MFS_MIN(fs_m_in.REQ_REN_LEN_OLD, sizeof(old_name));
r = sys_safecopyfrom(FS_PROC_NR, fs_m_in.REQ_REN_GRANT_OLD, 0,
(vir_bytes) old_name, (phys_bytes) len, D);
len = min( (unsigned) fs_m_in.REQ_REN_LEN_OLD, sizeof(old_name));
r = sys_safecopyfrom(FS_PROC_NR, (cp_grant_id_t) fs_m_in.REQ_REN_GRANT_OLD,
(vir_bytes) 0, (vir_bytes) old_name, (size_t) len, D);
if (r != OK) return r;
MFS_NUL(old_name, len, sizeof(old_name));
NUL(old_name, len, sizeof(old_name));
/* Copy the last component of the new name */
len = MFS_MIN(fs_m_in.REQ_REN_LEN_NEW, sizeof(new_name));
r = sys_safecopyfrom(FS_PROC_NR, fs_m_in.REQ_REN_GRANT_NEW, 0,
(vir_bytes) new_name, (phys_bytes) len, D);
len = min( (unsigned) fs_m_in.REQ_REN_LEN_NEW, sizeof(new_name));
r = sys_safecopyfrom(FS_PROC_NR, (cp_grant_id_t) fs_m_in.REQ_REN_GRANT_NEW,
(vir_bytes) 0, (vir_bytes) new_name, (size_t) len, D);
if (r != OK) return r;
MFS_NUL(new_name, len, sizeof(new_name));
NUL(new_name, len, sizeof(new_name));
/* Get old dir inode */
if( (old_dirp = get_inode(fs_dev, fs_m_in.REQ_REN_OLD_DIR)) == NULL)
if( (old_dirp = get_inode(fs_dev, (ino_t) fs_m_in.REQ_REN_OLD_DIR)) == NULL)
return(err_code);
old_ip = advance(old_dirp, old_name, IGN_PERM);
@ -315,7 +315,7 @@ PUBLIC int fs_rename()
}
/* Get new dir inode */
if( (new_dirp = get_inode(fs_dev, fs_m_in.REQ_REN_NEW_DIR)) == NULL)
if( (new_dirp = get_inode(fs_dev, (ino_t) fs_m_in.REQ_REN_NEW_DIR)) == NULL)
r = err_code;
new_ip = advance(new_dirp, new_name, IGN_PERM); /* not required to exist */
@ -325,11 +325,11 @@ PUBLIC int fs_rename()
put_inode(new_ip);
r = EBUSY;
}
if(old_ip != NULL)
odir = ((old_ip->i_mode & I_TYPE) == I_DIRECTORY); /* TRUE iff dir */
else
odir = FALSE; /* FIXME: is this a safe default? */
odir = FALSE;
/* If it is ok, check for a variety of possible errors. */
if(r == OK) {
@ -380,9 +380,8 @@ PUBLIC int fs_rename()
if(new_ip == NULL) {
/* don't rename a file with a file system mounted on it.
if (old_ip->i_dev != old_dirp->i_dev) r = EXDEV;*/
if(odir && new_dirp->i_nlinks >=
(new_dirp->i_sp->s_version == V1 ? CHAR_MAX : SHRT_MAX) &&
!same_pdir && r == OK) {
if (odir && new_dirp->i_nlinks >= LINK_MAX &&
!same_pdir && r == OK) {
r = EMLINK;
}
} else {
@ -427,15 +426,16 @@ PUBLIC int fs_rename()
numb = old_ip->i_num; /* inode number of old file */
if(same_pdir) {
r = search_dir(old_dirp,old_name,(ino_t *) 0,DELETE,IGN_PERM);
r = search_dir(old_dirp, old_name, NULL, DELETE, IGN_PERM);
/* shouldn't go wrong. */
if(r == OK)
search_dir(old_dirp, new_name, &numb, ENTER, IGN_PERM);
(void) search_dir(old_dirp, new_name, &numb, ENTER,
IGN_PERM);
} else {
r = search_dir(new_dirp, new_name, &numb, ENTER, IGN_PERM);
if(r == OK)
search_dir(old_dirp, old_name, (ino_t *) 0, DELETE,
IGN_PERM);
(void) search_dir(old_dirp, old_name, NULL, DELETE,
IGN_PERM);
}
}
/* If r is OK, the ctime and mtime of old_dirp and new_dirp have been marked
@ -470,7 +470,7 @@ PUBLIC int fs_ftrunc(void)
off_t start, end;
int r;
if( (rip = find_inode(fs_dev, fs_m_in.REQ_INODE_NR)) == NULL)
if( (rip = find_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL)
return(EINVAL);
start = fs_m_in.REQ_TRC_START_LO;
@ -500,7 +500,8 @@ off_t newsize; /* inode must become this size */
* O_APPEND mode, as this is different per fd and is checked when
* writing is done.
*/
int scale, file_type;
int r;
mode_t file_type;
file_type = rip->i_mode & I_TYPE; /* check to see if file is special */
if (file_type == I_CHAR_SPECIAL || file_type == I_BLOCK_SPECIAL)
@ -508,10 +509,11 @@ off_t newsize; /* inode must become this size */
if(newsize > rip->i_sp->s_max_size) /* don't let inode grow too big */
return(EFBIG);
scale = rip->i_sp->s_log_zone_size;
/* Free the actual space if truncating. */
if(newsize < rip->i_size) freesp_inode(rip, newsize, rip->i_size);
if(newsize < rip->i_size) {
if ((r = freesp_inode(rip, newsize, rip->i_size)) != OK)
return(r);
}
/* Clear the rest of the last zone if expanding. */
if(newsize > rip->i_size) clear_zone(rip, rip->i_size, 0);
@ -528,7 +530,7 @@ off_t newsize; /* inode must become this size */
/*===========================================================================*
* freesp_inode *
*===========================================================================*/
PUBLIC int freesp_inode(rip, start, end)
PRIVATE int freesp_inode(rip, start, end)
register struct inode *rip; /* pointer to inode to be partly freed */
off_t start, end; /* range of bytes to free (end uninclusive) */
{
@ -544,7 +546,7 @@ off_t start, end; /* range of bytes to free (end uninclusive) */
* fcntl().
*/
off_t p, e;
int zone_size;
int zone_size, r;
int zero_last, zero_first;
if(end > rip->i_size) /* freeing beyond end makes no sense */
@ -575,8 +577,11 @@ off_t start, end; /* range of bytes to free (end uninclusive) */
*/
e = end/zone_size;
if(end == rip->i_size && (end % zone_size)) e++;
for(p = nextblock(start, zone_size)/zone_size; p < e; p ++)
write_map(rip, p*zone_size, NO_ZONE, WMAP_FREE);
for(p = nextblock(start, zone_size)/zone_size; p < e; p ++) {
if((r = write_map(rip, p*zone_size, NO_ZONE, WMAP_FREE)) != OK)
return(r);
}
}
rip->i_update |= CTIME | MTIME;
@ -619,7 +624,7 @@ int zone_size;
* FIRST_HALF: 0..pos-1 will be zeroed
* LAST_HALF: pos..zone_size-1 will be zeroed
*/
int offset, len;
off_t offset, len;
/* Offset of zeroing boundary. */
offset = pos % zone_size;
@ -648,7 +653,8 @@ off_t len;
block_t b;
struct buf *bp;
off_t offset;
int bytes, block_size;
unsigned short block_size;
size_t bytes;
block_size = rip->i_sp->s_block_size;
@ -659,7 +665,7 @@ off_t len;
panic("zerozone_range: no block");
offset = pos % block_size;
bytes = block_size - offset;
if (bytes > len)
if (bytes > (size_t) len)
bytes = len;
memset(bp->b_data + offset, 0, bytes);
bp->b_dirt = DIRTY;

View file

@ -1,9 +1,12 @@
#include "inc.h"
#include "fs.h"
#include <assert.h>
#include <minix/callnr.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <minix/dmap.h>
#include <minix/endpoint.h>
#include <minix/vfsif.h>
#include "fs.h"
#include "buf.h"
#include "inode.h"
#include "drivers.h"
@ -12,6 +15,7 @@
/* Declare some local functions. */
FORWARD _PROTOTYPE(void get_work, (message *m_in) );
FORWARD _PROTOTYPE(void cch_check, (void) );
FORWARD _PROTOTYPE( void reply, (endpoint_t who, message *m_out) );
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
@ -41,8 +45,8 @@ PUBLIC int main(int argc, char *argv[])
src = fs_m_in.m_source;
error = OK;
caller_uid = -1; /* To trap errors */
caller_gid = -1;
caller_uid = INVAL_UID; /* To trap errors */
caller_gid = INVAL_GID;
req_nr = fs_m_in.m_type;
if (req_nr < VFS_BASE) {
@ -131,7 +135,7 @@ PRIVATE void sef_cb_signal_handler(int signo)
if (signo != SIGTERM) return;
exitsignaled = 1;
fs_sync();
(void) fs_sync();
/* If unmounting has already been performed, exit immediately.
* We might not get another message.
@ -170,7 +174,7 @@ message *m_in; /* pointer to message */
/*===========================================================================*
* reply *
*===========================================================================*/
PUBLIC void reply(
PRIVATE void reply(
endpoint_t who,
message *m_out /* report result */
)
@ -188,16 +192,15 @@ PRIVATE void cch_check(void)
int i;
for (i = 0; i < NR_INODES; ++i) {
if (inode[i].i_count != cch[i] &&
req_nr != REQ_GETNODE &&
req_nr != REQ_PUTNODE &&
req_nr != REQ_READSUPER &&
req_nr != REQ_MOUNTPOINT && req_nr != REQ_UNMOUNT &&
req_nr != REQ_SYNC && req_nr != REQ_LOOKUP)
printf("MFS(%d) inode(%d) cc: %d req_nr: %d\n",
SELF_E, inode[i].i_num, inode[i].i_count - cch[i], req_nr);
if (inode[i].i_count != cch[i] && req_nr != REQ_GETNODE &&
req_nr != REQ_PUTNODE && req_nr != REQ_READSUPER &&
req_nr != REQ_MOUNTPOINT && req_nr != REQ_UNMOUNT &&
req_nr != REQ_SYNC && req_nr != REQ_LOOKUP) {
printf("MFS(%d) inode(%ul) cc: %d req_nr: %d\n", SELF_E,
inode[i].i_num, inode[i].i_count - cch[i], req_nr);
}
cch[i] = inode[i].i_count;
cch[i] = inode[i].i_count;
}
}

View file

@ -1,8 +1,6 @@
#include "fs.h"
#include <fcntl.h>
#include <assert.h>
#include <minix/vfsif.h>
#include "buf.h"
#include "inode.h"
@ -43,9 +41,7 @@ PUBLIC int fs_flush()
/* Flush the blocks of a device from the cache after writing any dirty blocks
* to disk.
*/
dev_t dev;
dev = fs_m_in.REQ_DEV;
dev_t dev = (dev_t) fs_m_in.REQ_DEV;
if(dev == fs_dev) return(EBUSY);
flushall(dev);

View file

@ -1,9 +1,4 @@
#include "fs.h"
#include <fcntl.h>
#include <string.h>
#include <minix/com.h>
#include <sys/stat.h>
#include "buf.h"
#include "inode.h"
#include "super.h"
#include "drivers.h"
@ -26,45 +21,39 @@ PUBLIC int fs_readsuper()
struct inode *root_ip;
cp_grant_id_t label_gid;
size_t label_len;
int r = OK;
int r;
endpoint_t driver_e;
int readonly, isroot;
fs_dev = fs_m_in.REQ_DEV;
label_gid = fs_m_in.REQ_GRANT;
label_len = fs_m_in.REQ_PATH_LEN;
fs_dev = (dev_t) fs_m_in.REQ_DEV;
label_gid = (cp_grant_id_t) fs_m_in.REQ_GRANT;
label_len = (size_t) fs_m_in.REQ_PATH_LEN;
readonly = (fs_m_in.REQ_FLAGS & REQ_RDONLY) ? 1 : 0;
isroot = (fs_m_in.REQ_FLAGS & REQ_ISROOT) ? 1 : 0;
if (label_len > sizeof(fs_dev_label))
return(EINVAL);
r = sys_safecopyfrom(fs_m_in.m_source, label_gid, 0,
(vir_bytes)fs_dev_label, label_len, D);
r = sys_safecopyfrom(fs_m_in.m_source, label_gid, (vir_bytes) 0,
(vir_bytes) fs_dev_label, label_len, D);
if (r != OK) {
printf("%s:%d fs_readsuper: safecopyfrom failed: %d\n",
__FILE__, __LINE__, r);
printf("MFS %s:%d safecopyfrom failed: %d\n", __FILE__, __LINE__, r);
return(EINVAL);
}
r= ds_retrieve_label_endpt(fs_dev_label, &driver_e);
if (r != OK)
{
printf("mfs:fs_readsuper: ds_retrieve_label_endpt failed for '%s': %d\n",
fs_dev_label, r);
return EINVAL;
r = ds_retrieve_label_endpt(fs_dev_label, &driver_e);
if (r != OK) {
printf("MFS %s:%d ds_retrieve_label_endpt failed for '%s': %d\n",
__FILE__, __LINE__, fs_dev_label, r);
return(EINVAL);
}
/* Map the driver endpoint for this major */
driver_endpoints[(fs_dev >> MAJOR) & BYTE].driver_e = driver_e;
use_getuptime2 = TRUE; /* Should be removed with old getuptime call. */
vfs_slink_storage = (char *)0xdeadbeef; /* Should be removed together
* with old lookup code.
*/;
driver_endpoints[major(fs_dev)].driver_e = driver_e;
/* Open the device the file system lives on. */
if (dev_open(driver_e, fs_dev, driver_e,
readonly ? R_BIT : (R_BIT|W_BIT)) != OK) {
if (dev_open(driver_e, fs_dev, driver_e,
readonly ? R_BIT : (R_BIT|W_BIT) ) != OK) {
return(EINVAL);
}
@ -89,7 +78,7 @@ PUBLIC int fs_readsuper()
return(EINVAL);
}
if(root_ip != NULL && root_ip->i_mode == 0) {
if(root_ip->i_mode == 0) {
printf("%s:%d zero mode for root inode?\n", __FILE__, __LINE__);
put_inode(root_ip);
superblock.s_dev = NO_DEV;
@ -124,7 +113,7 @@ PUBLIC int fs_mountpoint()
mode_t bits;
/* Temporarily open the file. */
if( (rip = get_inode(fs_dev, fs_m_in.REQ_INODE_NR)) == NULL)
if( (rip = get_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL)
return(EINVAL);
@ -160,8 +149,7 @@ PUBLIC int fs_unmount()
if (rip->i_count > 0 && rip->i_dev == fs_dev) count += rip->i_count;
if ((root_ip = find_inode(fs_dev, ROOT_INODE)) == NULL) {
printf("MFS: couldn't find root inode. Unmount failed.\n");
panic("MFS: couldn't find root inode: %d", EINVAL);
panic("MFS: couldn't find root inode\n");
return(EINVAL);
}
@ -172,7 +160,7 @@ PUBLIC int fs_unmount()
(void) fs_sync();
/* Close the device the file system lives on. */
dev_close(driver_endpoints[(fs_dev >> MAJOR) & BYTE].driver_e, fs_dev);
dev_close(driver_endpoints[major(fs_dev)].driver_e, fs_dev);
/* Finish off the unmount. */
superblock.s_dev = NO_DEV;

View file

@ -1,16 +1,12 @@
#include "fs.h"
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <minix/callnr.h>
#include <minix/com.h>
#include "buf.h"
#include "inode.h"
#include "super.h"
#include <minix/vfsif.h>
PRIVATE char mode_map[] = {R_BIT, W_BIT, R_BIT|W_BIT, 0};
FORWARD _PROTOTYPE( struct inode *new_node, (struct inode *ldirp,
char *string, mode_t bits, zone_t z0));
@ -28,21 +24,21 @@ PUBLIC int fs_create()
char lastc[NAME_MAX];
/* Read request message */
omode = fs_m_in.REQ_MODE;
caller_uid = fs_m_in.REQ_UID;
caller_gid = fs_m_in.REQ_GID;
omode = (mode_t) fs_m_in.REQ_MODE;
caller_uid = (uid_t) fs_m_in.REQ_UID;
caller_gid = (gid_t) fs_m_in.REQ_GID;
/* Try to make the file. */
/* Copy the last component (i.e., file name) */
len = MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(lastc));
err_code = sys_safecopyfrom(FS_PROC_NR, fs_m_in.REQ_GRANT, 0,
(vir_bytes) lastc, (phys_bytes) len, D);
len = min( (unsigned) fs_m_in.REQ_PATH_LEN, sizeof(lastc));
err_code = sys_safecopyfrom(FS_PROC_NR, (cp_grant_id_t) fs_m_in.REQ_GRANT,
(vir_bytes) 0, (vir_bytes) lastc, (size_t) len, D);
if (err_code != OK) return err_code;
MFS_NUL(lastc, len, sizeof(lastc));
NUL(lastc, len, sizeof(lastc));
/* Get last directory inode (i.e., directory that will hold the new inode) */
if ((ldirp = get_inode(fs_dev, fs_m_in.REQ_INODE_NR)) == NULL)
if ((ldirp = get_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL)
return(ENOENT);
/* Create a new inode by calling new_node(). */
@ -57,7 +53,6 @@ PUBLIC int fs_create()
}
/* Reply message */
fs_m_out.m_source = rip->i_dev; /* filled with FS endpoint by the system */
fs_m_out.RES_INODE_NR = rip->i_num;
fs_m_out.RES_MODE = rip->i_mode;
fs_m_out.RES_FILE_SIZE_LO = rip->i_size;
@ -83,21 +78,22 @@ PUBLIC int fs_mknod()
phys_bytes len;
/* Copy the last component and set up caller's user and group id */
len = MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(lastc));
err_code = sys_safecopyfrom(FS_PROC_NR, fs_m_in.REQ_GRANT, 0,
(vir_bytes) lastc, (phys_bytes) len, D);
len = min( (unsigned) fs_m_in.REQ_PATH_LEN, sizeof(lastc));
err_code = sys_safecopyfrom(FS_PROC_NR, (cp_grant_id_t) fs_m_in.REQ_GRANT,
(vir_bytes) 0, (vir_bytes) lastc, (size_t) len, D);
if (err_code != OK) return err_code;
MFS_NUL(lastc, len, sizeof(lastc));
NUL(lastc, len, sizeof(lastc));
caller_uid = fs_m_in.REQ_UID;
caller_gid = fs_m_in.REQ_GID;
caller_uid = (uid_t) fs_m_in.REQ_UID;
caller_gid = (gid_t) fs_m_in.REQ_GID;
/* Get last directory inode */
if((ldirp = get_inode(fs_dev, fs_m_in.REQ_INODE_NR)) == NULL)
if((ldirp = get_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL)
return(ENOENT);
/* Try to create the new node */
ip = new_node(ldirp, lastc, fs_m_in.REQ_MODE, (zone_t) fs_m_in.REQ_DEV);
ip = new_node(ldirp, lastc, (mode_t) fs_m_in.REQ_MODE,
(zone_t) fs_m_in.REQ_DEV);
put_inode(ip);
put_inode(ldirp);
@ -117,21 +113,21 @@ PUBLIC int fs_mkdir()
phys_bytes len;
/* Copy the last component and set up caller's user and group id */
len = MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(lastc));
err_code = sys_safecopyfrom(FS_PROC_NR, fs_m_in.REQ_GRANT, 0,
(vir_bytes) lastc, (phys_bytes) len, D);
len = min( (unsigned) fs_m_in.REQ_PATH_LEN, sizeof(lastc));
err_code = sys_safecopyfrom(FS_PROC_NR, (cp_grant_id_t) fs_m_in.REQ_GRANT,
(vir_bytes) 0, (vir_bytes) lastc, (size_t) len, D);
if(err_code != OK) return(err_code);
MFS_NUL(lastc, len, sizeof(lastc));
NUL(lastc, len, sizeof(lastc));
caller_uid = fs_m_in.REQ_UID;
caller_gid = fs_m_in.REQ_GID;
caller_uid = (uid_t) fs_m_in.REQ_UID;
caller_gid = (gid_t) fs_m_in.REQ_GID;
/* Get last directory inode */
if((ldirp = get_inode(fs_dev, fs_m_in.REQ_INODE_NR)) == NULL)
if((ldirp = get_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL)
return(ENOENT);
/* Next make the inode. If that fails, return error code. */
rip = new_node(ldirp, lastc, fs_m_in.REQ_MODE, (zone_t) 0);
rip = new_node(ldirp, lastc, (mode_t) fs_m_in.REQ_MODE, (zone_t) 0);
if(rip == NULL || err_code == EEXIST) {
put_inode(rip); /* can't make dir: it already exists */
@ -145,7 +141,7 @@ PUBLIC int fs_mkdir()
/* Now make dir entries for . and .. unless the disk is completely full. */
/* Use dot1 and dot2, so the mode of the directory isn't important. */
rip->i_mode = fs_m_in.REQ_MODE; /* set mode */
rip->i_mode = (mode_t) fs_m_in.REQ_MODE; /* set mode */
r1 = search_dir(rip, dot1, &dot, ENTER, IGN_PERM);/* enter . in the new dir*/
r2 = search_dir(rip, dot2, &dotdot, ENTER, IGN_PERM); /* enter .. in the new
dir */
@ -160,7 +156,7 @@ PUBLIC int fs_mkdir()
/* It was not possible to enter . or .. probably disk was full -
* links counts haven't been touched. */
if(search_dir(ldirp, lastc, (ino_t *) 0, DELETE, IGN_PERM) != OK)
panic("Dir disappeared: %d", rip->i_num);
panic("Dir disappeared: %ul", rip->i_num);
rip->i_nlinks--; /* undo the increment done in new_node() */
}
rip->i_dirt = DIRTY; /* either way, i_nlinks has changed */
@ -183,18 +179,18 @@ PUBLIC int fs_slink()
char string[NAME_MAX]; /* last component of the new dir's path name */
struct buf *bp; /* disk buffer for link */
caller_uid = fs_m_in.REQ_UID;
caller_gid = fs_m_in.REQ_GID;
caller_uid = (uid_t) fs_m_in.REQ_UID;
caller_gid = (gid_t) fs_m_in.REQ_GID;
/* Copy the link name's last component */
len = MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(string));
r = sys_safecopyfrom(FS_PROC_NR, fs_m_in.REQ_GRANT, 0,
(vir_bytes) string, (phys_bytes) len, D);
len = min( (unsigned) fs_m_in.REQ_PATH_LEN, sizeof(string));
r = sys_safecopyfrom(FS_PROC_NR, (cp_grant_id_t) fs_m_in.REQ_GRANT,
(vir_bytes) 0, (vir_bytes) string, (size_t) len, D);
if (r != OK) return(r);
MFS_NUL(string, len, sizeof(string));
NUL(string, len, sizeof(string));
/* Temporarily open the dir. */
if( (ldirp = get_inode(fs_dev, fs_m_in.REQ_INODE_NR)) == NULL)
if( (ldirp = get_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL)
return(EINVAL);
/* Create the inode for the symlink. */
@ -204,36 +200,38 @@ PUBLIC int fs_slink()
/* Allocate a disk block for the contents of the symlink.
* Copy contents of symlink (the name pointed to) into first disk block. */
if( (r = err_code) == OK) {
r = (bp = new_block(sip, (off_t) 0)) == NULL ? err_code :
sys_safecopyfrom(FS_PROC_NR, fs_m_in.REQ_GRANT3, 0,
(vir_bytes) bp->b_data,
(vir_bytes) fs_m_in.REQ_MEM_SIZE, D);
bp = new_block(sip, (off_t) 0);
if (bp == NULL)
r = err_code;
else
r = sys_safecopyfrom(FS_PROC_NR,
(cp_grant_id_t) fs_m_in.REQ_GRANT3,
(vir_bytes) 0, (vir_bytes) bp->b_data,
(size_t) fs_m_in.REQ_MEM_SIZE, D);
if(r == OK) {
bp->b_data[_MIN_BLOCK_SIZE-1] = '\0';
sip->i_size = strlen(bp->b_data);
if(sip->i_size != fs_m_in.REQ_MEM_SIZE) {
/* This can happen if the user provides a buffer
* with a \0 in it. This can cause a lot of trouble
* when the symlink is used later. We could just use
* the strlen() value, but we want to let the user
* know he did something wrong. ENAMETOOLONG doesn't
* exactly describe the error, but there is no
* ENAMETOOWRONG.
*/
r = ENAMETOOLONG;
}
}
if(bp != NULL && r == OK) {
bp->b_data[_MIN_BLOCK_SIZE-1] = '\0';
sip->i_size = (off_t) strlen(bp->b_data);
if(sip->i_size != fs_m_in.REQ_MEM_SIZE) {
/* This can happen if the user provides a buffer
* with a \0 in it. This can cause a lot of trouble
* when the symlink is used later. We could just use
* the strlen() value, but we want to let the user
* know he did something wrong. ENAMETOOLONG doesn't
* exactly describe the error, but there is no
* ENAMETOOWRONG.
*/
r = ENAMETOOLONG;
}
}
put_block(bp, DIRECTORY_BLOCK); /* put_block() accepts NULL. */
put_block(bp, DIRECTORY_BLOCK); /* put_block() accepts NULL. */
if(r != OK) {
sip->i_nlinks = 0;
if(search_dir(ldirp, string, (ino_t *) 0, DELETE,
IGN_PERM) != OK)
if(r != OK) {
sip->i_nlinks = NO_LINK;
if(search_dir(ldirp, string, NULL, DELETE, IGN_PERM) != OK)
panic("Symbolic link vanished");
}
}
}
/* put_inode() accepts NULL as a noop, so the below are safe. */
@ -266,9 +264,7 @@ PRIVATE struct inode *new_node(struct inode *ldirp,
/* Get final component of the path. */
rip = advance(ldirp, string, IGN_PERM);
if (S_ISDIR(bits) &&
(ldirp)->i_nlinks >= ((ldirp)->i_sp->s_version == V1 ?
CHAR_MAX : SHRT_MAX)) {
if (S_ISDIR(bits) && (ldirp->i_nlinks >= LINK_MAX)) {
/* New entry is a directory, alas we can't give it a ".." */
put_inode(rip);
err_code = EMLINK;
@ -322,7 +318,7 @@ PUBLIC int fs_inhibread()
{
struct inode *rip;
if((rip = find_inode(fs_dev, fs_m_in.REQ_INODE_NR)) == NULL)
if((rip = find_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL)
return(EINVAL);
/* inhibit read ahead */

View file

@ -10,12 +10,11 @@
*/
#include "fs.h"
#include "assert.h"
#include <string.h>
#include <minix/callnr.h>
#include <minix/endpoint.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "buf.h"
#include "inode.h"
#include "super.h"
@ -38,52 +37,46 @@ FORWARD _PROTOTYPE( int parse_path, (ino_t dir_ino, ino_t root_ino,
PUBLIC int fs_lookup()
{
cp_grant_id_t grant, grant2;
int r, r1, len, flags, symlinks;
int r, r1, flags, symlinks;
unsigned int len;
size_t offset = 0, path_size, cred_size;
ino_t dir_ino, root_ino;
struct inode *rip;
grant = fs_m_in.REQ_GRANT;
path_size = fs_m_in.REQ_PATH_SIZE; /* Size of the buffer */
len = fs_m_in.REQ_PATH_LEN; /* including terminating nul */
dir_ino = fs_m_in.REQ_DIR_INO;
root_ino = fs_m_in.REQ_ROOT_INO;
flags = fs_m_in.REQ_FLAGS;
grant = (cp_grant_id_t) fs_m_in.REQ_GRANT;
path_size = (size_t) fs_m_in.REQ_PATH_SIZE; /* Size of the buffer */
len = (int) fs_m_in.REQ_PATH_LEN; /* including terminating nul */
dir_ino = (ino_t) fs_m_in.REQ_DIR_INO;
root_ino = (ino_t) fs_m_in.REQ_ROOT_INO;
flags = (int) fs_m_in.REQ_FLAGS;
/* Check length. */
if(len > sizeof(user_path)) return(E2BIG); /* too big for buffer */
if(len < 1) return(EINVAL); /* too small */
if(len == 0) return(EINVAL); /* too small */
/* Copy the pathname and set up caller's user and group id */
r = sys_safecopyfrom(FS_PROC_NR, grant, /*offset*/ 0,
(vir_bytes) user_path, (phys_bytes) len, D);
if(r != OK) {
printf("MFS %s:%d sys_safecopyfrom failed: %d\n",
__FILE__, __LINE__, r);
return(r);
}
r = sys_safecopyfrom(FS_PROC_NR, grant, /*offset*/ (vir_bytes) 0,
(vir_bytes) user_path, (size_t) len, D);
if(r != OK) return(r);
/* Verify this is a null-terminated path. */
if(user_path[len - 1] != '\0') return(EINVAL);
if(flags & PATH_GET_UCRED) { /* Do we have to copy uid/gid credentials? */
grant2 = fs_m_in.REQ_GRANT2;
cred_size = fs_m_in.REQ_UCRED_SIZE;
grant2 = (cp_grant_id_t) fs_m_in.REQ_GRANT2;
cred_size = (size_t) fs_m_in.REQ_UCRED_SIZE;
if (cred_size > sizeof(credentials)) return(EINVAL); /* Too big. */
r = sys_safecopyfrom(FS_PROC_NR, grant2, 0, (vir_bytes) &credentials,
(phys_bytes) cred_size, D);
if (r != OK) {
printf("MFS %s:%d sys_safecopyfrom failed: %d\n",
__FILE__, __LINE__, r);
return(r);
}
r = sys_safecopyfrom(FS_PROC_NR, grant2, (vir_bytes) 0,
(vir_bytes) &credentials, cred_size, D);
if (r != OK) return(r);
caller_uid = credentials.vu_uid;
caller_gid = credentials.vu_gid;
} else {
memset(&credentials, 0, sizeof(credentials));
caller_uid = fs_m_in.REQ_UID;
caller_gid = fs_m_in.REQ_GID;
caller_uid = (uid_t) fs_m_in.REQ_UID;
caller_gid = (gid_t) fs_m_in.REQ_GID;
}
/* Lookup inode */
@ -94,13 +87,9 @@ PUBLIC int fs_lookup()
len = strlen(user_path)+1;
if(len > path_size) return(ENAMETOOLONG);
r1 = sys_safecopyto(FS_PROC_NR, grant, 0, (vir_bytes) user_path,
(phys_bytes) len, D);
if(r1 != OK) {
printf("%s:%d fs_lookup: sys_safecopyto failed: %d\n",
__FILE__, __LINE__, r1);
return(r1);
}
r1 = sys_safecopyto(FS_PROC_NR, grant, (vir_bytes) 0,
(vir_bytes) user_path, (size_t) len, D);
if(r1 != OK) return(r1);
}
if(r == ELEAVEMOUNT || r == ESYMLINK) {
@ -167,8 +156,7 @@ int *symlinkp;
return(ENOENT);
/* If dir has been removed return ENOENT. */
if (rip->i_nlinks == 0)
return(ENOENT);
if (rip->i_nlinks == NO_LINK) return(ENOENT);
dup_inode(rip);
@ -310,13 +298,11 @@ char *suffix; /* current remaining path. Has to point in the
struct buf *bp; /* buffer containing link text */
char *sp; /* start of link text */
bp = NULL;
if ((blink = read_map(rip, (off_t) 0)) == NO_BLOCK)
return(EIO);
bp = get_block(rip->i_dev, blink, NORMAL);
llen = rip->i_size;
llen = (size_t) rip->i_size;
sp = bp->b_data;
slen = strlen(suffix);
@ -331,7 +317,8 @@ char *suffix; /* current remaining path. Has to point in the
* right place first, before we expand <link>. When strlen(<expandedlink>) is
* smaller than strlen(/already/processes/path), we move the suffix to the
* left. Is strlen(<expandedlink>) greater then we move it to the right. Else
* we do nothing. */
* we do nothing.
*/
if (slen > 0) { /* Do we have path after the link? */
/* For simplicity we require that suffix starts with a slash */
@ -340,11 +327,14 @@ char *suffix; /* current remaining path. Has to point in the
}
/* To be able to expand the <link>, we have to move the 'suffix'
* to the right place. */
* to the right place.
*/
if (slen + llen + 1 > sizeof(user_path))
return(ENAMETOOLONG);/* <expandedlink>+suffix+\0 does not fit*/
if (suffix-user_path != llen) /* Move suffix left or right if needed */
if ((unsigned) (suffix-user_path) != llen) {
/* Move suffix left or right */
memmove(&user_path[llen], suffix, slen+1);
}
} else {
if (llen + 1 > sizeof(user_path))
return(ENAMETOOLONG); /* <expandedlink> + \0 does not fix */
@ -420,7 +410,7 @@ int chk_perm; /* check permissions when string is looked up*/
* mounted file system. The super_block provides the linkage between the
* inode mounted on and the root directory of the mounted file system.
*/
if (rip != NULL && rip->i_mountpoint) {
if (rip->i_mountpoint) {
/* Mountpoint encountered, report it */
err_code = EENTERMOUNT;
}
@ -458,11 +448,10 @@ char string[NAME_MAX+1]; /* component extracted from 'old_name' */
while(ep[0] != '\0' && ep[0] != '/')
ep++;
len = ep - cp;
len = (size_t) (ep - cp);
/* Truncate the amount to be copied if it exceeds NAME_MAX */
if (len > NAME_MAX)
len = NAME_MAX;
if (len > NAME_MAX) len = NAME_MAX;
/* Special case of the string at cp is empty */
if (len == 0)
@ -536,8 +525,7 @@ int check_permissions; /* check permissions when flag is !IS_EMPTY */
/* Since directories don't have holes, 'b' cannot be NO_BLOCK. */
bp = get_block(ldir_ptr->i_dev, b, NORMAL); /* get a dir block */
if (bp == NO_BLOCK)
panic("get_block returned NO_BLOCK");
assert(bp != NULL);
/* Search a directory block. */
for (dp = &bp->b_dir[0];
@ -549,7 +537,7 @@ int check_permissions; /* check permissions when flag is !IS_EMPTY */
}
/* Match occurs if string found. */
if (flag != ENTER && dp->d_ino != 0) {
if (flag != ENTER && dp->d_ino != NO_ENTRY) {
if (flag == IS_EMPTY) {
/* If this test succeeds, dir is not empty. */
if (strcmp(dp->d_name, "." ) != 0 &&
@ -569,13 +557,14 @@ int check_permissions; /* check permissions when flag is !IS_EMPTY */
/* Save d_ino for recovery. */
t = NAME_MAX - sizeof(ino_t);
*((ino_t *) &dp->d_name[t]) = dp->d_ino;
dp->d_ino = 0; /* erase entry */
dp->d_ino = NO_ENTRY; /* erase entry */
bp->b_dirt = DIRTY;
ldir_ptr->i_update |= CTIME | MTIME;
ldir_ptr->i_dirt = DIRTY;
} else {
sp = ldir_ptr->i_sp; /* 'flag' is LOOK_UP */
*numb = conv4(sp->s_native, (int) dp->d_ino);
*numb = (ino_t) conv4(sp->s_native,
(int) dp->d_ino);
}
put_block(bp, DIRECTORY_BLOCK);
return(r);

View file

@ -1,12 +1,9 @@
#include "fs.h"
#include <unistd.h>
#include <minix/callnr.h>
#include "buf.h"
#include "inode.h"
#include "super.h"
#include <minix/vfsif.h>
FORWARD _PROTOTYPE( in_group, (gid_t grp) );
FORWARD _PROTOTYPE( int in_group, (gid_t grp) );
/*===========================================================================*
@ -17,13 +14,16 @@ PUBLIC int fs_chmod()
/* Perform the chmod(name, mode) system call. */
register struct inode *rip;
mode_t mode;
mode = (mode_t) fs_m_in.REQ_MODE;
/* Temporarily open the file. */
if( (rip = get_inode(fs_dev, fs_m_in.REQ_INODE_NR)) == NULL)
if( (rip = get_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL)
return(EINVAL);
/* Now make the change. Clear setgid bit if file is not in caller's grp */
rip->i_mode = (rip->i_mode & ~ALL_MODES) | (fs_m_in.REQ_MODE & ALL_MODES);
rip->i_mode = (rip->i_mode & ~ALL_MODES) | (mode & ALL_MODES);
rip->i_update |= CTIME;
rip->i_dirt = DIRTY;
@ -44,14 +44,14 @@ PUBLIC int fs_chown()
register int r;
/* Temporarily open the file. */
if( (rip = get_inode(fs_dev, fs_m_in.REQ_INODE_NR)) == NULL)
if( (rip = get_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL)
return(EINVAL);
/* Not permitted to change the owner of a file on a read-only file sys. */
r = read_only(rip);
if (r == OK) {
rip->i_uid = fs_m_in.REQ_UID;
rip->i_gid = fs_m_in.REQ_GID;
rip->i_uid = (uid_t) fs_m_in.REQ_UID;
rip->i_gid = (gid_t) fs_m_in.REQ_GID;
rip->i_mode &= ~(I_SET_UID_BIT | I_SET_GID_BIT);
rip->i_update |= CTIME;
rip->i_dirt = DIRTY;

View file

@ -1,3 +1,6 @@
#ifndef __MFS_PROTO_H__
#define __MFS_PROTO_H__
/* Function prototypes. */
/* Structs used in prototypes must be declared as such first. */
@ -15,35 +18,30 @@ _PROTOTYPE( void free_zone, (dev_t dev, zone_t numb) );
_PROTOTYPE( struct buf *get_block, (dev_t dev, block_t block,int only_search));
_PROTOTYPE( void invalidate, (dev_t device) );
_PROTOTYPE( void put_block, (struct buf *bp, int block_type) );
_PROTOTYPE( void set_blocksize, (int blocksize) );
_PROTOTYPE( void set_blocksize, (unsigned int blocksize) );
_PROTOTYPE( void rw_scattered, (dev_t dev,
struct buf **bufq, int bufqsize, int rw_flag) );
/* device.c */
_PROTOTYPE( int block_dev_io, (int op, dev_t dev, int proc, void *buf,
u64_t pos, int bytes, int flags) );
_PROTOTYPE( int dev_open, (endpoint_t driver_e, dev_t dev, int proc,
_PROTOTYPE( int block_dev_io, (int op, dev_t dev, endpoint_t proc_e,
void *buf, u64_t pos, size_t bytes) );
_PROTOTYPE( int dev_open, (endpoint_t driver_e, dev_t dev, endpoint_t proc_e,
int flags) );
_PROTOTYPE( void dev_close, (endpoint_t driver_e, dev_t dev) );
_PROTOTYPE( int fs_clone_opcl, (void) );
_PROTOTYPE( int fs_new_driver, (void) );
/* inode.c */
_PROTOTYPE( struct inode *alloc_inode, (dev_t dev, mode_t bits) );
_PROTOTYPE( void dup_inode, (struct inode *ip) );
_PROTOTYPE( struct inode *find_inode, (dev_t dev, int numb) );
_PROTOTYPE( void free_inode, (dev_t dev, ino_t numb) );
_PROTOTYPE( int fs_getnode, (void) );
_PROTOTYPE( struct inode *find_inode, (dev_t dev, ino_t numb) );
_PROTOTYPE( int fs_putnode, (void) );
_PROTOTYPE( void init_inode_cache, (void) );
_PROTOTYPE( struct inode *get_inode, (dev_t dev, int numb) );
_PROTOTYPE( struct inode *get_inode, (dev_t dev, ino_t numb) );
_PROTOTYPE( void put_inode, (struct inode *rip) );
_PROTOTYPE( void update_times, (struct inode *rip) );
_PROTOTYPE( void rw_inode, (struct inode *rip, int rw_flag) );
_PROTOTYPE( void wipe_inode, (struct inode *rip) );
/* link.c */
_PROTOTYPE( int freesp_inode, (struct inode *rip, off_t st, off_t end) );
_PROTOTYPE( int fs_ftrunc, (void) );
_PROTOTYPE( int fs_link, (void) );
_PROTOTYPE( int fs_rdlink, (void) );
@ -51,9 +49,6 @@ _PROTOTYPE( int fs_rename, (void) );
_PROTOTYPE( int fs_unlink, (void) );
_PROTOTYPE( int truncate_inode, (struct inode *rip, off_t len) );
/* main.c */
_PROTOTYPE( void reply, (endpoint_t who, message *m_out) );
/* misc.c */
_PROTOTYPE( int fs_flush, (void) );
_PROTOTYPE( int fs_sync, (void) );
@ -89,8 +84,6 @@ _PROTOTYPE( int read_only, (struct inode *ip) );
/* read.c */
_PROTOTYPE( int fs_breadwrite, (void) );
_PROTOTYPE( int fs_readwrite, (void) );
_PROTOTYPE( struct buf *rahead, (struct inode *rip, block_t baseblock,
u64_t position, unsigned bytes_ahead) );
_PROTOTYPE( void read_ahead, (void) );
_PROTOTYPE( block_t read_map, (struct inode *rip, off_t pos) );
_PROTOTYPE( zone_t rd_indir, (struct buf *bp, int index) );
@ -103,9 +96,8 @@ _PROTOTYPE( int fs_stat, (void) );
_PROTOTYPE( bit_t alloc_bit, (struct super_block *sp, int map, bit_t origin));
_PROTOTYPE( void free_bit, (struct super_block *sp, int map,
bit_t bit_returned) );
_PROTOTYPE( int get_block_size, (dev_t dev) );
_PROTOTYPE( unsigned int get_block_size, (dev_t dev) );
_PROTOTYPE( struct super_block *get_super, (dev_t dev) );
_PROTOTYPE( int mounted, (struct inode *rip) );
_PROTOTYPE( int read_super, (struct super_block *sp) );
/* time.c */
@ -115,12 +107,10 @@ _PROTOTYPE( int fs_utime, (void) );
_PROTOTYPE( time_t clock_time, (void) );
_PROTOTYPE( unsigned conv2, (int norm, int w) );
_PROTOTYPE( long conv4, (int norm, long x) );
_PROTOTYPE( int fetch_name, (char *path, int len, int flag) );
_PROTOTYPE( void mfs_nul_f, (char *file, int line, char *str, int len,
int maxlen) );
_PROTOTYPE( int mfs_min_f, (char *file, int line, int len1, int len2) );
_PROTOTYPE( void mfs_nul_f, (char *file, int line, char *str, unsigned int len,
unsigned int maxlen) );
_PROTOTYPE( int min, (unsigned int l, unsigned int r) );
_PROTOTYPE( int no_sys, (void) );
_PROTOTYPE( int isokendpt_f, (char *f, int l, int e, int *p, int ft));
_PROTOTYPE( void sanitycheck, (char *file, int line) );
#define SANITYCHECK sanitycheck(__FILE__, __LINE__)
@ -130,3 +120,5 @@ _PROTOTYPE( struct buf *new_block, (struct inode *rip, off_t position) );
_PROTOTYPE( void zero_block, (struct buf *bp) );
_PROTOTYPE( int write_map, (struct inode *, off_t, zone_t, int) );
#endif

View file

@ -1,8 +1,6 @@
#include "fs.h"
#include <fcntl.h>
#include <stddef.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <minix/com.h>
#include <minix/u64.h>
@ -10,10 +8,15 @@
#include "inode.h"
#include "super.h"
#include <minix/vfsif.h>
#include <assert.h>
FORWARD _PROTOTYPE( struct buf *rahead, (struct inode *rip, block_t baseblock,
u64_t position, unsigned bytes_ahead) );
FORWARD _PROTOTYPE( int rw_chunk, (struct inode *rip, u64_t position,
unsigned off, int chunk, unsigned left, int rw_flag,
cp_grant_id_t gid, unsigned buf_off, int block_size, int *completed));
unsigned off, size_t chunk, unsigned left, int rw_flag,
cp_grant_id_t gid, unsigned buf_off, unsigned int block_size,
int *completed) );
PRIVATE char getdents_buf[GETDENTS_BUFSIZ];
@ -22,19 +25,20 @@ PRIVATE char getdents_buf[GETDENTS_BUFSIZ];
*===========================================================================*/
PUBLIC int fs_readwrite(void)
{
int r, rw_flag, chunk, block_size, block_spec;
int regular, nrbytes;
int r, rw_flag, block_spec;
int regular;
cp_grant_id_t gid;
off_t position, f_size, bytes_left;
unsigned int off, cum_io;
unsigned int off, cum_io, block_size, chunk;
mode_t mode_word;
int completed, r2 = OK;
int completed;
struct inode *rip;
size_t nrbytes;
r = OK;
/* Find the inode referred */
if ((rip = find_inode(fs_dev, fs_m_in.REQ_INODE_NR)) == NULL)
if ((rip = find_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL)
return(EINVAL);
mode_word = rip->i_mode & I_TYPE;
@ -42,47 +46,49 @@ PUBLIC int fs_readwrite(void)
block_spec = (mode_word == I_BLOCK_SPECIAL ? 1 : 0);
/* Determine blocksize */
block_size = (block_spec ?
get_block_size(rip->i_zone[0]) : rip->i_sp->s_block_size);
if (block_spec) {
block_size = get_block_size( (dev_t) rip->i_zone[0]);
f_size = MAX_FILE_POS;
} else {
block_size = rip->i_sp->s_block_size;
f_size = rip->i_size;
}
f_size = (block_spec ? ULONG_MAX : rip->i_size);
/* Get the values from the request message */
rw_flag = (fs_m_in.m_type == REQ_READ ? READING : WRITING);
gid = fs_m_in.REQ_GRANT;
position = fs_m_in.REQ_SEEK_POS_LO;
nrbytes = (unsigned) fs_m_in.REQ_NBYTES;
gid = (cp_grant_id_t) fs_m_in.REQ_GRANT;
position = (off_t) fs_m_in.REQ_SEEK_POS_LO;
nrbytes = (size_t) fs_m_in.REQ_NBYTES;
rdwt_err = OK; /* set to EIO if disk error occurs */
if (rw_flag == WRITING && block_spec == 0) {
if (rw_flag == WRITING && !block_spec) {
/* Check in advance to see if file will grow too big. */
if (position > rip->i_sp->s_max_size - nrbytes)
if (position > (off_t) (rip->i_sp->s_max_size - nrbytes))
return(EFBIG);
/* Clear the zone containing present EOF if hole about
* to be created. This is necessary because all unwritten
* blocks prior to the EOF must read as zeros. */
* blocks prior to the EOF must read as zeros.
*/
if(position > f_size) clear_zone(rip, f_size, 0);
}
cum_io = 0;
/* Split the transfer into chunks that don't span two blocks. */
while (nrbytes != 0) {
off = (unsigned int) (position % block_size);/* offset in blk*/
chunk = MIN(nrbytes, block_size - off);
if (chunk < 0) chunk = block_size - off;
while (nrbytes > 0) {
off = ((unsigned int) position) % block_size; /* offset in blk*/
chunk = min(nrbytes, block_size - off);
if (rw_flag == READING) {
bytes_left = f_size - position;
if (position >= f_size) break; /* we are beyond EOF */
if (chunk > bytes_left) chunk = (int) bytes_left;
if (chunk > (unsigned int) bytes_left) chunk = bytes_left;
}
/* Read or write 'chunk' bytes. */
r = rw_chunk(rip, cvul64(position), off, chunk, (unsigned) nrbytes,
rw_flag, gid, cum_io, block_size, &completed);
r = rw_chunk(rip, cvul64((unsigned long) position), off, chunk,
nrbytes, rw_flag, gid, cum_io, block_size, &completed);
if (r != OK) break; /* EOF reached */
if (rdwt_err < 0) break;
@ -90,7 +96,7 @@ PUBLIC int fs_readwrite(void)
/* Update counters and pointers. */
nrbytes -= chunk; /* bytes yet to be read */
cum_io += chunk; /* bytes read so far */
position += chunk; /* position within the file */
position += (off_t) chunk; /* position within the file */
}
fs_m_out.RES_SEEK_POS_LO = position; /* It might change later and the VFS
@ -105,7 +111,8 @@ PUBLIC int fs_readwrite(void)
/* Check to see if read-ahead is called for, and if so, set it up. */
if(rw_flag == READING && rip->i_seek == NO_SEEK &&
position % block_size == 0 && (regular || mode_word == I_DIRECTORY)) {
(unsigned int) position % block_size == 0 &&
(regular || mode_word == I_DIRECTORY)) {
rdahed_inode = rip;
rdahedpos = position;
}
@ -115,10 +122,6 @@ PUBLIC int fs_readwrite(void)
if (rdwt_err != OK) r = rdwt_err; /* check for disk error */
if (rdwt_err == END_OF_FILE) r = OK;
/* if user-space copying failed, read/write failed. */
if (r == OK && r2 != OK)
r = r2;
if (r == OK) {
if (rw_flag == READING) rip->i_update |= ATIME;
if (rw_flag == WRITING) rip->i_update |= CTIME | MTIME;
@ -136,12 +139,11 @@ PUBLIC int fs_readwrite(void)
*===========================================================================*/
PUBLIC int fs_breadwrite(void)
{
int r, rw_flag, chunk, block_size;
int r, rw_flag, completed;
cp_grant_id_t gid;
int nrbytes;
u64_t position;
unsigned int off, cum_io;
int completed;
unsigned int off, cum_io, chunk, block_size;
size_t nrbytes;
/* Pseudo inode for rw_chunk */
struct inode rip;
@ -150,13 +152,14 @@ PUBLIC int fs_breadwrite(void)
/* Get the values from the request message */
rw_flag = (fs_m_in.m_type == REQ_BREAD ? READING : WRITING);
gid = fs_m_in.REQ_GRANT;
position = make64(fs_m_in.REQ_SEEK_POS_LO, fs_m_in.REQ_SEEK_POS_HI);
nrbytes = (unsigned) fs_m_in.REQ_NBYTES;
gid = (cp_grant_id_t) fs_m_in.REQ_GRANT;
position = make64((unsigned long) fs_m_in.REQ_SEEK_POS_LO,
(unsigned long) fs_m_in.REQ_SEEK_POS_HI);
nrbytes = (size_t) fs_m_in.REQ_NBYTES;
block_size = get_block_size(fs_m_in.REQ_DEV2);
block_size = get_block_size( (dev_t) fs_m_in.REQ_DEV2);
rip.i_zone[0] = fs_m_in.REQ_DEV2;
rip.i_zone[0] = (zone_t) fs_m_in.REQ_DEV2;
rip.i_mode = I_BLOCK_SPECIAL;
rip.i_size = 0;
@ -164,15 +167,13 @@ PUBLIC int fs_breadwrite(void)
cum_io = 0;
/* Split the transfer into chunks that don't span two blocks. */
while (nrbytes != 0) {
while (nrbytes > 0) {
off = rem64u(position, block_size); /* offset in blk*/
chunk = MIN(nrbytes, block_size - off);
if (chunk < 0) chunk = block_size - off;
chunk = min(nrbytes, block_size - off);
/* Read or write 'chunk' bytes. */
r = rw_chunk(&rip, position, off, chunk, (unsigned) nrbytes,
rw_flag, gid, cum_io, block_size, &completed);
r = rw_chunk(&rip, position, off, chunk, nrbytes, rw_flag, gid,
cum_io, block_size, &completed);
if (r != OK) break; /* EOF reached */
if (rdwt_err < 0) break;
@ -180,7 +181,7 @@ PUBLIC int fs_breadwrite(void)
/* Update counters and pointers. */
nrbytes -= chunk; /* bytes yet to be read */
cum_io += chunk; /* bytes read so far */
position= add64ul(position, chunk); /* position within the file */
position = add64ul(position, chunk); /* position within the file */
}
fs_m_out.RES_SEEK_POS_LO = ex64lo(position);
@ -203,12 +204,12 @@ PRIVATE int rw_chunk(rip, position, off, chunk, left, rw_flag, gid,
register struct inode *rip; /* pointer to inode for file to be rd/wr */
u64_t position; /* position within file to read or write */
unsigned off; /* off within the current block */
int chunk; /* number of bytes to read or write */
unsigned int chunk; /* number of bytes to read or write */
unsigned left; /* max number of bytes wanted after position */
int rw_flag; /* READING or WRITING */
cp_grant_id_t gid; /* grant */
unsigned buf_off; /* offset in grant */
int block_size; /* block size of FS operating on */
unsigned int block_size; /* block size of FS operating on */
int *completed; /* number of bytes copied */
{
/* Read or write (part of) a block. */
@ -229,7 +230,7 @@ int *completed; /* number of bytes copied */
} else {
if (ex64hi(position) != 0)
panic("rw_chunk: position too high");
b = read_map(rip, ex64lo(position));
b = read_map(rip, (off_t) ex64lo(position));
dev = rip->i_dev;
}
@ -240,7 +241,7 @@ int *completed; /* number of bytes copied */
zero_block(bp);
} else {
/* Writing to a nonexistent block. Create and enter in inode.*/
if ((bp= new_block(rip, ex64lo(position))) == NULL)
if ((bp = new_block(rip, (off_t) ex64lo(position))) == NULL)
return(err_code);
}
} else if (rw_flag == READING) {
@ -252,7 +253,7 @@ int *completed; /* number of bytes copied */
* the cache, acquire it, otherwise just acquire a free buffer.
*/
n = (chunk == block_size ? NO_READ : NORMAL);
if (!block_spec && off == 0 && ex64lo(position) >= rip->i_size)
if (!block_spec && off == 0 && (off_t) ex64lo(position) >= rip->i_size)
n = NO_READ;
bp = get_block(dev, b, n);
}
@ -262,18 +263,18 @@ int *completed; /* number of bytes copied */
panic("bp not valid in rw_chunk; this can't happen");
if (rw_flag == WRITING && chunk != block_size && !block_spec &&
ex64lo(position) >= rip->i_size && off == 0) {
(off_t) ex64lo(position) >= rip->i_size && off == 0) {
zero_block(bp);
}
if (rw_flag == READING) {
/* Copy a chunk from the block buffer to user space. */
r = sys_safecopyto(FS_PROC_NR, gid, buf_off,
(vir_bytes) (bp->b_data+off), (phys_bytes) chunk, D);
r = sys_safecopyto(FS_PROC_NR, gid, (vir_bytes) buf_off,
(vir_bytes) (bp->b_data+off), (size_t) chunk, D);
} else {
/* Copy a chunk from user space to the block buffer. */
r = sys_safecopyfrom(FS_PROC_NR, gid, buf_off,
(vir_bytes) (bp->b_data+off), (phys_bytes) chunk, D);
r = sys_safecopyfrom(FS_PROC_NR, gid, (vir_bytes) buf_off,
(vir_bytes) (bp->b_data+off), (size_t) chunk, D);
bp->b_dirt = DIRTY;
}
@ -295,11 +296,12 @@ off_t position; /* position in file whose blk wanted */
* block (not zone) number in which that position is to be found and return it.
*/
register struct buf *bp;
register zone_t z;
int scale, boff, dzones, nr_indirects, index, zind, ex;
struct buf *bp;
zone_t z;
int scale, boff, index, zind, ex;
unsigned int dzones, nr_indirects;
block_t b;
long excess, zone, block_pos;
unsigned long excess, zone, block_pos;
scale = rip->i_sp->s_log_zone_size; /* for block-zone conversion */
block_pos = position/rip->i_sp->s_block_size; /* relative blk # in file */
@ -313,7 +315,7 @@ off_t position; /* position in file whose blk wanted */
zind = (int) zone; /* index should be an int */
z = rip->i_zone[zind];
if (z == NO_ZONE) return(NO_BLOCK);
b = ((block_t) z << scale) + boff;
b = (block_t) ((z << scale) + boff);
return(b);
}
@ -346,7 +348,7 @@ off_t position; /* position in file whose blk wanted */
z = rd_indir(bp, ex); /* get block pointed to */
put_block(bp, INDIRECT_BLOCK); /* release single indir blk */
if (z == NO_ZONE) return(NO_BLOCK);
b = ((block_t) z << scale) + boff;
b = (block_t) ((z << scale) + boff);
return(b);
}
@ -394,7 +396,7 @@ int index; /* index into *bp */
PUBLIC void read_ahead()
{
/* Read a block into the cache before it is needed. */
int block_size;
unsigned int block_size;
register struct inode *rip;
struct buf *bp;
block_t b;
@ -403,7 +405,10 @@ PUBLIC void read_ahead()
block_size = get_block_size(rip->i_dev);
rdahed_inode = NULL; /* turn off read ahead */
if ( (b = read_map(rip, rdahedpos)) == NO_BLOCK) return; /* at EOF */
bp = rahead(rip, b, cvul64(rdahedpos), block_size);
assert(rdahedpos > 0); /* So we can safely cast it to unsigned below */
bp = rahead(rip, b, cvul64( (unsigned long) rdahedpos), block_size);
put_block(bp, PARTIAL_DATA_BLOCK);
}
@ -411,7 +416,7 @@ PUBLIC void read_ahead()
/*===========================================================================*
* rahead *
*===========================================================================*/
PUBLIC struct buf *rahead(rip, baseblock, position, bytes_ahead)
PRIVATE struct buf *rahead(rip, baseblock, position, bytes_ahead)
register struct inode *rip; /* pointer to inode for file to be read */
block_t baseblock; /* block at current position */
u64_t position; /* position within file */
@ -424,21 +429,22 @@ unsigned bytes_ahead; /* bytes beyond position for immediate use */
* cylinder boundary (or after an error). Rw_scattered() puts an optional
* flag on all reads to allow this.
*/
int block_size;
/* Minimum number of blocks to prefetch. */
# define BLOCKS_MINIMUM (nr_bufs < 50 ? 18 : 32)
int block_spec, scale, read_q_size;
unsigned int blocks_ahead, fragment;
unsigned int blocks_ahead, fragment, block_size;
block_t block, blocks_left;
off_t ind1_pos;
dev_t dev;
struct buf *bp;
static int readqsize = 0;
static unsigned int readqsize = 0;
static struct buf **read_q;
if(readqsize != nr_bufs) {
if(readqsize > 0)
if(readqsize > 0) {
assert(read_q != NULL);
free(read_q);
}
if(!(read_q = malloc(sizeof(read_q[0])*nr_bufs)))
panic("couldn't allocate read_q");
readqsize = nr_bufs;
@ -477,22 +483,23 @@ unsigned bytes_ahead; /* bytes beyond position for immediate use */
*/
fragment = rem64u(position, block_size);
position= sub64u(position, fragment);
position = sub64u(position, fragment);
bytes_ahead += fragment;
blocks_ahead = (bytes_ahead + block_size - 1) / block_size;
if (block_spec && rip->i_size == 0) {
blocks_left = NR_IOREQS;
blocks_left = (block_t) NR_IOREQS;
} else {
blocks_left = (rip->i_size - ex64lo(position) + block_size - 1) /
block_size;
blocks_left = (block_t) (rip->i_size-ex64lo(position)+(block_size-1)) /
block_size;
/* Go for the first indirect block if we are in its neighborhood. */
if (!block_spec) {
scale = rip->i_sp->s_log_zone_size;
ind1_pos = (off_t) rip->i_ndzones * (block_size << scale);
if (ex64lo(position) <= ind1_pos && rip->i_size > ind1_pos) {
if ((off_t) ex64lo(position) <= ind1_pos &&
rip->i_size > ind1_pos) {
blocks_ahead++;
blocks_left++;
}
@ -540,7 +547,8 @@ unsigned bytes_ahead; /* bytes beyond position for immediate use */
PUBLIC int fs_getdents(void)
{
register struct inode *rip;
int o, r, block_size, len, reclen, done;
int o, r, done;
unsigned int block_size, len, reclen;
ino_t ino;
block_t b;
cp_grant_id_t gid;
@ -551,13 +559,13 @@ PUBLIC int fs_getdents(void)
struct dirent *dep;
char *cp;
ino = fs_m_in.REQ_INODE_NR;
gid = fs_m_in.REQ_GRANT;
size = fs_m_in.REQ_MEM_SIZE;
pos = fs_m_in.REQ_SEEK_POS_LO;
ino = (ino_t) fs_m_in.REQ_INODE_NR;
gid = (gid_t) fs_m_in.REQ_GRANT;
size = (size_t) fs_m_in.REQ_MEM_SIZE;
pos = (off_t) fs_m_in.REQ_SEEK_POS_LO;
/* Check whether the position is properly aligned */
if(pos % DIR_ENTRY_SIZE)
if( (unsigned int) pos % DIR_ENTRY_SIZE)
return(ENOENT);
if( (rip = get_inode(fs_dev, ino)) == NULL)
@ -577,13 +585,12 @@ PUBLIC int fs_getdents(void)
new_pos = rip->i_size;
for(; block_pos < rip->i_size; block_pos += block_size) {
b = read_map(rip, block_pos); /* get block number */
b = read_map(rip, block_pos); /* get block number */
/* Since directories don't have holes, 'b' cannot be NO_BLOCK. */
bp = get_block(rip->i_dev, b, NORMAL); /* get a dir block */
/* Since directories don't have holes, 'b' cannot be NO_BLOCK. */
bp = get_block(rip->i_dev, b, NORMAL); /* get a dir block */
if(bp == NO_BLOCK)
panic("get_block returned NO_BLOCK");
assert(bp != NULL);
/* Search a directory block. */
if (block_pos < pos)
@ -599,7 +606,7 @@ PUBLIC int fs_getdents(void)
if (cp == NULL)
len = NAME_MAX;
else
len = cp-dp->d_name;
len = cp - (dp->d_name);
/* Compute record length */
reclen = offsetof(struct dirent, d_name) + len + 1;
@ -608,14 +615,17 @@ PUBLIC int fs_getdents(void)
reclen += sizeof(long) - o;
/* Need the position of this entry in the directory */
ent_pos = block_pos + ((char *)dp - bp->b_data);
ent_pos = block_pos + ((char *) dp - (bp->b_data));
if(tmpbuf_off + reclen > GETDENTS_BUFSIZ) {
r = sys_safecopyto(FS_PROC_NR, gid, userbuf_off,
(vir_bytes)getdents_buf,
tmpbuf_off, D);
if (r != OK)
panic("fs_getdents: sys_safecopyto failed: %d", r);
r = sys_safecopyto(FS_PROC_NR, gid,
(vir_bytes) userbuf_off,
(vir_bytes) getdents_buf,
(size_t) tmpbuf_off, D);
if (r != OK) {
put_inode(rip);
return(r);
}
userbuf_off += tmpbuf_off;
tmpbuf_off = 0;
@ -633,10 +643,10 @@ PUBLIC int fs_getdents(void)
break;
}
dep = (struct dirent *)&getdents_buf[tmpbuf_off];
dep = (struct dirent *) &getdents_buf[tmpbuf_off];
dep->d_ino = dp->d_ino;
dep->d_off = ent_pos;
dep->d_reclen = reclen;
dep->d_reclen = (unsigned short) reclen;
memcpy(dep->d_name, dp->d_name, len);
dep->d_name[len] = '\0';
tmpbuf_off += reclen;
@ -648,10 +658,12 @@ PUBLIC int fs_getdents(void)
}
if(tmpbuf_off != 0) {
r = sys_safecopyto(FS_PROC_NR, gid, userbuf_off,
(vir_bytes) getdents_buf, tmpbuf_off, D);
if (r != OK)
panic("fs_getdents: sys_safecopyto failed: %d", r);
r = sys_safecopyto(FS_PROC_NR, gid, (vir_bytes) userbuf_off,
(vir_bytes) getdents_buf, (size_t) tmpbuf_off, D);
if (r != OK) {
put_inode(rip);
return(r);
}
userbuf_off += tmpbuf_off;
}

View file

@ -1,9 +1,6 @@
#include "fs.h"
#include <sys/stat.h>
#include <sys/statfs.h>
#include <minix/com.h>
#include <string.h>
#include "buf.h"
#include "inode.h"
#include "super.h"
#include <minix/vfsif.h>
@ -38,16 +35,16 @@ PRIVATE int stat_inode(
statbuf.st_mode = rip->i_mode;
statbuf.st_nlink = rip->i_nlinks;
statbuf.st_uid = rip->i_uid;
statbuf.st_gid = rip->i_gid;
statbuf.st_rdev = (dev_t) (s ? rip->i_zone[0] : NO_DEV);
statbuf.st_gid = (short) rip->i_gid; /* FIXME: should become gid_t */
statbuf.st_rdev = (s ? (dev_t) rip->i_zone[0] : NO_DEV);
statbuf.st_size = rip->i_size;
statbuf.st_atime = rip->i_atime;
statbuf.st_mtime = rip->i_mtime;
statbuf.st_ctime = rip->i_ctime;
/* Copy the struct to user space. */
r = sys_safecopyto(who_e, gid, 0, (vir_bytes) &statbuf,
(phys_bytes) sizeof(statbuf), D);
r = sys_safecopyto(who_e, gid, (vir_bytes) 0, (vir_bytes) &statbuf,
(size_t) sizeof(statbuf), D);
return(r);
}
@ -68,8 +65,8 @@ PUBLIC int fs_fstatfs()
st.f_bsize = rip->i_sp->s_block_size;
/* Copy the struct to user space. */
r = sys_safecopyto(fs_m_in.m_source, fs_m_in.REQ_GRANT, 0, (vir_bytes) &st,
(phys_bytes) sizeof(st), D);
r = sys_safecopyto(fs_m_in.m_source, (cp_grant_id_t) fs_m_in.REQ_GRANT,
(vir_bytes) 0, (vir_bytes) &st, (size_t) sizeof(st), D);
return(r);
}
@ -83,10 +80,10 @@ PUBLIC int fs_stat()
register int r; /* return value */
register struct inode *rip; /* target inode */
if ((rip = get_inode(fs_dev, fs_m_in.REQ_INODE_NR)) == NULL)
if ((rip = get_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL)
return(EINVAL);
r = stat_inode(rip, fs_m_in.m_source, fs_m_in.REQ_GRANT);
r = stat_inode(rip, fs_m_in.m_source, (cp_grant_id_t) fs_m_in.REQ_GRANT);
put_inode(rip); /* release the inode */
return(r);
}

View file

@ -32,9 +32,10 @@ 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 */
block_t block;
bit_t map_bits; /* how many bits are there in the bit map? */
unsigned bit_blocks; /* how many blocks are there in the bit map? */
unsigned block, word, bcount;
short bit_blocks; /* how many blocks are there in the bit map? */
unsigned word, bcount;
struct buf *bp;
bitchunk_t *wptr, *wlim, k;
bit_t i, b;
@ -44,11 +45,11 @@ bit_t origin; /* number of bit to start searching at */
if (map == IMAP) {
start_block = START_BLOCK;
map_bits = sp->s_ninodes + 1;
map_bits = (bit_t) (sp->s_ninodes + 1);
bit_blocks = sp->s_imap_blocks;
} else {
start_block = START_BLOCK + sp->s_imap_blocks;
map_bits = sp->s_zones - (sp->s_firstdatazone - 1);
map_bits = (bit_t) (sp->s_zones - (sp->s_firstdatazone - 1));
bit_blocks = sp->s_zmap_blocks;
}
@ -56,7 +57,7 @@ bit_t origin; /* number of bit to start searching at */
if (origin >= map_bits) origin = 0; /* for robustness */
/* Locate the starting place. */
block = origin / FS_BITS_PER_BLOCK(sp->s_block_size);
block = (block_t) (origin / FS_BITS_PER_BLOCK(sp->s_block_size));
word = (origin % FS_BITS_PER_BLOCK(sp->s_block_size)) / FS_BITCHUNK_BITS;
/* Iterate over all blocks plus one, because we start in the middle. */
@ -72,7 +73,7 @@ bit_t origin; /* number of bit to start searching at */
if (*wptr == (bitchunk_t) ~0) continue;
/* Find and allocate the free bit. */
k = conv2(sp->s_native, (int) *wptr);
k = (bitchunk_t) conv2(sp->s_native, (int) *wptr);
for (i = 0; (k & (1 << i)) != 0; ++i) {}
/* Bit number from the start of the bit map. */
@ -85,13 +86,14 @@ bit_t origin; /* number of bit to start searching at */
/* Allocate and return bit number. */
k |= 1 << i;
*wptr = conv2(sp->s_native, (int) k);
*wptr = (bitchunk_t) conv2(sp->s_native, (int) k);
bp->b_dirt = DIRTY;
put_block(bp, MAP_BLOCK);
return(b);
}
put_block(bp, MAP_BLOCK);
if (++block >= bit_blocks) block = 0; /* last block, wrap around */
if (++block >= (unsigned int) bit_blocks) /* last block, wrap around */
block = 0;
word = 0;
} while (--bcount > 0);
return(NO_BIT); /* no bit could be allocated */
@ -129,13 +131,14 @@ bit_t bit_returned; /* number of bit to insert into the map */
bp = get_block(sp->s_dev, start_block + block, NORMAL);
k = conv2(sp->s_native, (int) bp->b_bitmap[word]);
k = (bitchunk_t) conv2(sp->s_native, (int) bp->b_bitmap[word]);
if (!(k & mask)) {
panic(map == IMAP ? "tried to free unused inode" : "tried to free unused block: %d", bit_returned);
if (map == IMAP) panic("tried to free unused inode");
else panic("tried to free unused block: %u", bit_returned);
}
k &= ~mask;
bp->b_bitmap[word] = conv2(sp->s_native, (int) k);
bp->b_bitmap[word] = (bitchunk_t) conv2(sp->s_native, (int) k);
bp->b_dirt = DIRTY;
put_block(bp, MAP_BLOCK);
@ -162,7 +165,7 @@ PUBLIC struct super_block *get_super(
/*===========================================================================*
* get_block_size *
*===========================================================================*/
PUBLIC int get_block_size(dev_t dev)
PUBLIC unsigned int get_block_size(dev_t dev)
{
if (dev == NO_DEV)
panic("request for block size of NO_DEV");
@ -180,7 +183,7 @@ register struct super_block *sp; /* pointer to a superblock */
{
/* Read a superblock. */
dev_t dev;
int magic;
unsigned int magic;
int version, native, r;
static char *sbbuf;
block_t offset;
@ -191,8 +194,8 @@ register struct super_block *sp; /* pointer to a superblock */
if (dev == NO_DEV)
panic("request for super_block of NO_DEV");
r = block_dev_io(MFS_DEV_READ, dev, SELF_E,
sbbuf, cvu64(SUPER_BLOCK_BYTES), _MIN_BLOCK_SIZE, 0);
r = block_dev_io(MFS_DEV_READ, dev, SELF_E, sbbuf, cvu64(SUPER_BLOCK_BYTES),
_MIN_BLOCK_SIZE);
if (r != _MIN_BLOCK_SIZE)
return(EINVAL);
@ -216,14 +219,14 @@ register struct super_block *sp; /* pointer to a superblock */
/* If the super block has the wrong byte order, swap the fields; the magic
* number doesn't need conversion. */
sp->s_ninodes = conv4(native, sp->s_ninodes);
sp->s_nzones = conv2(native, (int) sp->s_nzones);
sp->s_imap_blocks = conv2(native, (int) sp->s_imap_blocks);
sp->s_zmap_blocks = conv2(native, (int) sp->s_zmap_blocks);
sp->s_firstdatazone_old = conv2(native, (int) sp->s_firstdatazone_old);
sp->s_log_zone_size = conv2(native, (int) sp->s_log_zone_size);
sp->s_max_size = conv4(native, sp->s_max_size);
sp->s_zones = conv4(native, sp->s_zones);
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);
/* 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
@ -238,7 +241,7 @@ register struct super_block *sp; /* pointer to a superblock */
*/
if (version == V1) {
sp->s_block_size = _STATIC_BLOCK_SIZE;
sp->s_zones = sp->s_nzones; /* only V1 needs this copy */
sp->s_zones = (zone_t) sp->s_nzones; /* only V1 needs this copy */
sp->s_inodes_per_block = V1_INODES_PER_BLOCK;
sp->s_ndzones = V1_NR_DZONES;
sp->s_nindirs = V1_INDIRECTS;
@ -265,7 +268,7 @@ register struct super_block *sp; /* pointer to a superblock */
sp->s_firstdatazone = (offset + (1 << sp->s_log_zone_size) - 1) >>
sp->s_log_zone_size;
} else {
sp->s_firstdatazone = sp->s_firstdatazone_old;
sp->s_firstdatazone = (zone_t) sp->s_firstdatazone_old;
}
if (sp->s_block_size < _MIN_BLOCK_SIZE)

View file

@ -1,3 +1,6 @@
#ifndef __MFS_SUPER_H__
#define __MFS_SUPER_H__
/* Super block table. The root file system and every mounted file system
* has an entry here. The entry holds information about the sizes of the bit
* maps and inodes. The s_ninodes field gives the number of inodes available
@ -59,3 +62,6 @@ EXTERN struct super_block {
#define IMAP 0 /* operating on the inode bit map */
#define ZMAP 1 /* operating on the zone bit map */
#endif

View file

@ -6,8 +6,6 @@
#define _TABLE
#include "fs.h"
#include <minix/callnr.h>
#include <minix/com.h>
#include "inode.h"
#include "buf.h"
#include "super.h"

View file

@ -1,6 +1,4 @@
#include "fs.h"
#include <minix/callnr.h>
#include <minix/com.h>
#include "inode.h"
#include <minix/vfsif.h>
@ -14,7 +12,7 @@ PUBLIC int fs_utime()
register int r;
/* Temporarily open the file. */
if( (rip = get_inode(fs_dev, fs_m_in.REQ_INODE_NR)) == NULL)
if( (rip = get_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL)
return(EINVAL);
/* Only the owner of a file or the super_user can change its time. */

View file

@ -1,3 +1,6 @@
#ifndef __MFS_TYPE_H__
#define __MFS_TYPE_H__
/* Declaration of the V1 inode as it is on the disk (not in core). */
typedef struct { /* V1.x disk inode */
u16_t d1_mode; /* file type, protection, etc. */
@ -34,6 +37,8 @@ struct buf {
dev_t b_dev; /* major | minor device where block resides */
char b_dirt; /* CLEAN or DIRTY */
char b_count; /* number of users of this buffer */
int b_bytes; /* Number of bytes allocated in bp */
unsigned int b_bytes; /* Number of bytes allocated in bp */
};
#endif

View file

@ -1,13 +1,7 @@
#include "fs.h"
#include <sys/stat.h>
#include <string.h>
#include <minix/com.h>
#include <minix/callnr.h>
#include <stdlib.h>
#include "buf.h"
#include "inode.h"
#include "super.h"
#include <minix/vfsif.h>
/*===========================================================================*
@ -65,14 +59,10 @@ PUBLIC time_t clock_time()
register int k;
clock_t uptime;
time_t boottime;
if (use_getuptime2) {
if ( (k=getuptime2(&uptime,&boottime)) != OK)
if ( (k=getuptime2(&uptime, &boottime)) != OK)
panic("clock_time: getuptme2 failed: %d", k);
} else {
if ( (k=getuptime(&uptime)) != OK)
panic("clock_time err: %d", k);
}
return( (time_t) (boottime + (uptime/sys_hz())));
}
@ -81,33 +71,24 @@ PUBLIC time_t clock_time()
/*===========================================================================*
* mfs_min *
*===========================================================================*/
PUBLIC int mfs_min_f(char *file, int line, int v1, int v2)
PUBLIC int min(unsigned int l, unsigned int r)
{
if(v1 < 0 || v2 < 0) {
printf("mfs:%s:%d: strange string lengths: %d, %d\n",
file, line, v1, v2);
panic("strange string lengths");
}
if(v2 >= v1) return v1;
if(r >= l) return(l);
return v2;
return(r);
}
/*===========================================================================*
* mfs_nul *
*===========================================================================*/
PUBLIC void mfs_nul_f(char *file, int line, char *str, int len, int maxlen)
PUBLIC void mfs_nul_f(char *file, int line, char *str, unsigned int len,
unsigned int maxlen)
{
if(len < 1) {
printf("mfs:%s:%d: %d-length string?!\n", file, line, len);
panic("strange string length");
}
if(len < maxlen && str[len-1] != '\0') {
printf("mfs:%s:%d: string (length %d, maxlen %d) "
"not null-terminated\n",
file, line, len, maxlen);
}
if(len < maxlen && str[len-1] != '\0') {
printf("MFS %s:%d string (length %d, maxlen %d) not null-terminated\n",
file, line, len, maxlen);
}
}
#define MYASSERT(c) if(!(c)) { printf("MFS:%s:%d: sanity check: %s failed\n", \

View file

@ -218,16 +218,10 @@ struct super_block *sb; /* superblock of device block resides on */
/* Return nonzero if the indirect block pointed to by bp contains
* only NO_ZONE entries.
*/
int i;
if(sb->s_version == V1) {
for(i = 0; i < V1_INDIRECTS; i++)
if(bp->b_v1_ind[i] != NO_ZONE)
return(0);
} else {
for(i = 0; i < V2_INDIRECTS(sb->s_block_size); i++)
if(bp->b_v2_ind[i] != NO_ZONE)
return(0);
}
unsigned int i;
for(i = 0; i < V2_INDIRECTS(sb->s_block_size); i++)
if( bp->b_v2_ind[i] != NO_ZONE)
return(0);
return(1);
}
@ -246,24 +240,23 @@ int flag; /* 1 if called by new_block, 0 otherwise */
* fs_readwrite(), truncate_inode(), and new_block().
*/
register struct buf *bp;
register block_t b, blo, bhi;
register off_t next;
register int scale;
register zone_t zone_size;
struct buf *bp;
block_t b, blo, bhi;
off_t next;
int scale, zone_size;
/* If the block size and zone size are the same, clear_zone() not needed. */
scale = rip->i_sp->s_log_zone_size;
if (scale == 0) return;
zone_size = (zone_t) rip->i_sp->s_block_size << scale;
if (flag == 1) pos = (pos/zone_size) * zone_size;
zone_size = rip->i_sp->s_block_size << scale;
if (flag == 1) pos = (off_t) ((pos/zone_size) * zone_size);
next = pos + rip->i_sp->s_block_size - 1;
/* If 'pos' is in the last block of a zone, do not clear the zone. */
if (next/zone_size != pos/zone_size) return;
if ( (blo = read_map(rip, next)) == NO_BLOCK) return;
bhi = ( ((blo>>scale)+1) << scale) - 1;
bhi = (block_t) ( ((blo>>scale)+1) << scale) - 1;
/* Clear all the blocks between 'blo' and 'bhi'. */
for (b = blo; b <= bhi; b++) {
@ -298,9 +291,10 @@ off_t position; /* file pointer */
/* First search for this file. Start looking from
* the file's first data zone to prevent fragmentation
*/
if ( (z = rip->i_zone[0]) == NO_ZONE) {
/* no first zone for file either */
z = rip->i_sp->s_firstdatazone; /* let alloc_zone decide */
if ( (z = rip->i_zone[0]) == NO_ZONE) {
/* No first zone for file either, let alloc_zone
* decide. */
z = (zone_t) rip->i_sp->s_firstdatazone;
}
} else {
/* searched before, start from last find */
@ -337,7 +331,7 @@ register struct buf *bp; /* pointer to buffer to zero */
/* Zero a block. */
ASSERT(bp->b_bytes > 0);
ASSERT(bp->bp);
memset(bp->b_data, 0, bp->b_bytes);
memset(bp->b_data, 0, (size_t) bp->b_bytes);
bp->b_dirt = DIRTY;
}

View file

@ -32,8 +32,6 @@
#define SYMLOOP 16
#define ROOT_INODE 1 /* inode number for root directory */
#define LABEL_MAX 16 /* maximum label size (including '\0'). Should
* not be smaller than 16 or bigger than
* M3_LONG_STRING.