]> Zhao Yanbai Git Server - minix.git/commitdiff
MFS: use libfsdriver 50/2750/3
authorDavid van Moolenbroek <david@minix3.org>
Sun, 24 Aug 2014 10:06:03 +0000 (10:06 +0000)
committerDavid van Moolenbroek <david@minix3.org>
Thu, 18 Sep 2014 12:46:27 +0000 (12:46 +0000)
Change-Id: Ib658c7dea47b81a417755b0554a75288117b431a

24 files changed:
minix/commands/fsck.mfs/fsck.c
minix/fs/mfs/Makefile
minix/fs/mfs/const.h
minix/fs/mfs/fs.h
minix/fs/mfs/glo.h
minix/fs/mfs/inode.c
minix/fs/mfs/link.c
minix/fs/mfs/main.c
minix/fs/mfs/misc.c
minix/fs/mfs/mount.c
minix/fs/mfs/open.c
minix/fs/mfs/path.c
minix/fs/mfs/pipe.c [deleted file]
minix/fs/mfs/protect.c
minix/fs/mfs/proto.h
minix/fs/mfs/read.c
minix/fs/mfs/stadir.c
minix/fs/mfs/super.c
minix/fs/mfs/super.h
minix/fs/mfs/table.c
minix/fs/mfs/time.c
minix/fs/mfs/utility.c
minix/fs/mfs/write.c
minix/lib/libc/gen/fslib.c

index 1a1bbd531d500b0c207e9bb91f2a1c51f73743d2..e68e5d98b7165a31b86d1cbc6ed4eb0f42b16644 100644 (file)
@@ -46,6 +46,7 @@
 #include <minix/config.h>
 #include <minix/const.h>
 #include <minix/type.h>
+#include <minix/ipc.h>
 #include "mfs/const.h"
 #include "mfs/inode.h"
 #include "mfs/type.h"
index 7c0195bb2368d241b7b1f8841364d0b758e2d1ba..f2d60b7e38d9e0c61cde00953c78e6f09f476b49 100644 (file)
@@ -5,8 +5,8 @@ SRCS=   cache.c link.c \
        stadir.c stats.c table.c time.c utility.c \
        write.c inode.c main.c path.c super.c
 
-DPADD+=        ${LIBMINIXFS} ${LIBBDEV} ${LIBSYS}
-LDADD+= -lminixfs -lbdev -lsys
+DPADD+=        ${LIBMINIXFS} ${LIBFSDRIVER} ${LIBBDEV} ${LIBSYS}
+LDADD+= -lminixfs -lfsdriver -lbdev -lsys
 
 CPPFLAGS+= -DDEFAULT_NR_BUFS=1024
 
index 5ea8e5eefc61686c845a2f33d838a6a47e5d15d9..23b74719bede0da697aedbc3ee2344d68ef8710d 100644 (file)
 #define MFS_NAME_MAX    MFS_DIRSIZ
 
 
-/* The type of sizeof may be (unsigned) long.  Use the following macro for
- * taking the sizes of small objects so that there are no surprises like
- * (small) long constants being passed to routines expecting an int.
- */
-#define usizeof(t) ((unsigned) sizeof(t))
-
 /* File system types. */
 #define SUPER_MAGIC   0x137F   /* magic number contained in super-block */
 #define SUPER_REV     0x7F13   /* magic # when 68000 disk read on PC or vv */
@@ -35,8 +29,6 @@
 #define V3                3    /* version number of V3 file systems */ 
 
 /* Miscellaneous constants */
-#define SU_UID          ((uid_t) 0)    /* super_user's uid_t */
-
 #define NO_BIT   ((bit_t) 0)   /* returned by alloc_bit() to signal failure */
 
 #define LOOK_UP            0 /* tells search_dir to lookup string */
 /* write_map() args */
 #define WMAP_FREE      (1 << 0)
 
-#define IGN_PERM       0
-#define CHK_PERM       1
-
 #define IN_CLEAN        0      /* in-block inode and memory copies identical */
 #define IN_DIRTY        1      /* in-block inode and memory copies differ */
 #define ATIME            002   /* set if atime field needs updating */
 #define CTIME            004   /* set if ctime field needs updating */
 #define MTIME            010   /* set if mtime field needs updating */
 
-#define BYTE_SWAP          0   /* tells conv2/conv4 to swap bytes */
-
-#define END_OF_FILE   (-104)   /* eof detected */
-
 #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 ((block_t) 2)      /* first block of FS (not counting SB) */
 
-#define DIR_ENTRY_SIZE       usizeof (struct direct)  /* # bytes/dir entry   */
+#define DIR_ENTRY_SIZE       sizeof (struct direct)  /* # bytes/dir entry   */
 #define NR_DIR_ENTRIES(b)   ((b)/DIR_ENTRY_SIZE)  /* # dir entries/blk   */
-#define SUPER_SIZE      usizeof (struct super_block)  /* super_block size    */
+#define SUPER_SIZE      sizeof (struct super_block)  /* super_block size    */
 
-#define FS_BITMAP_CHUNKS(b) ((b)/usizeof (bitchunk_t))/* # map chunks/blk   */
-#define FS_BITCHUNK_BITS               (usizeof(bitchunk_t) * CHAR_BIT)
+#define FS_BITMAP_CHUNKS(b) ((b)/sizeof (bitchunk_t))/* # map chunks/blk   */
+#define FS_BITCHUNK_BITS               (sizeof(bitchunk_t) * CHAR_BIT)
 #define FS_BITS_PER_BLOCK(b)   (FS_BITMAP_CHUNKS(b) * FS_BITCHUNK_BITS)
 
 /* Derived sizes pertaining to the V2 file system. */
-#define V2_ZONE_NUM_SIZE            usizeof (zone_t)  /* # bytes in V2 zone  */
-#define V2_INODE_SIZE             usizeof (d2_inode)  /* bytes in V2 dsk ino */
+#define V2_ZONE_NUM_SIZE            sizeof (zone_t)  /* # bytes in V2 zone  */
+#define V2_INODE_SIZE             sizeof (d2_inode)  /* bytes in V2 dsk ino */
 #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 NUL(str,l,m) mfs_nul_f(__FILE__,__LINE__,(str), (l), (m))
-
 #endif
 
index 571dc03ed07dc13d6af444df728ccb3f9e8d6284..75a4a6d8fb93840e2a8f543ac4e880d1f4e89d15 100644 (file)
 #include <sys/types.h>
 #include <minix/const.h>
 #include <minix/type.h>
-#include <minix/dmap.h>
 
 #include <lib.h>
 #include <limits.h>
 #include <errno.h>
 
-#include <minix/vfsif.h>
 #include <minix/syslib.h>
 #include <minix/sysutil.h>
 
+#include <minix/fsdriver.h>
+
 #include "mfsdir.h"
 #include "const.h"
 #include "type.h"
index f6a7e99f1e5e1eff93e14ac5859f2b838024661c..8e50d387da185dbfd945783f715f195bec118313 100644 (file)
@@ -7,35 +7,14 @@
 #define EXTERN
 #endif
 
-#include <minix/vfsif.h>
-
 /* The following variables are used for returning results to the caller. */
 EXTERN int err_code;           /* temporary storage for error number */
 
 EXTERN int cch[NR_INODES];
 
-extern char dot1[2];   /* dot1 (&dot1[0]) and dot2 (&dot2[0]) have a special */
-extern char dot2[3];   /* meaning to search_dir: no access permission check. */
-
-extern int(*fs_call_vec[]) (void);
-
-EXTERN message fs_m_in;
-EXTERN message fs_m_out;
-EXTERN vfs_ucred_t credentials;
-
-EXTERN uid_t caller_uid;
-EXTERN gid_t caller_gid;
-
-EXTERN int req_nr;
-
-EXTERN char user_path[PATH_MAX];  /* pathname to be processed */
-
 EXTERN dev_t fs_dev;           /* The device that is handled by this FS proc.
                                 */
-EXTERN char fs_dev_label[16];  /* Name of the device driver that is handled
-                                * by this FS proc.
-                                */
-EXTERN int unmountdone;
-EXTERN int exitsignaled;
+
+extern struct fsdriver mfs_table;
 
 #endif
index 95a05e535a77606ddd4d28aa985b360670c83f75..7c5a60c832fc3aa8bc72c44079608f13eb95df2d 100644 (file)
@@ -35,27 +35,21 @@ static void wipe_inode(struct inode *rip);
 /*===========================================================================*
  *                             fs_putnode                                   *
  *===========================================================================*/
-int fs_putnode(void)
+int fs_putnode(ino_t ino_nr, unsigned int count)
 {
 /* Find the inode specified by the request message and decrease its counter.*/
 
   struct inode *rip;
-  int count;
   
-  rip = find_inode(fs_dev, fs_m_in.m_vfs_fs_putnode.inode);
+  rip = find_inode(fs_dev, ino_nr);
 
   if(!rip) {
          printf("%s:%d put_inode: inode #%llu dev: %llx not found\n", __FILE__,
-                __LINE__, fs_m_in.m_vfs_fs_putnode.inode, fs_dev);
+                __LINE__, ino_nr, fs_dev);
          panic("fs_putnode failed");
   }
 
-  count = fs_m_in.m_vfs_fs_putnode.count;
-  if (count <= 0) {
-       printf("%s:%d put_inode: bad value for count: %d\n", __FILE__,
-              __LINE__, count);
-       panic("fs_putnode failed");
-  } else if(count > rip->i_count) {
+  if (count > rip->i_count) {
        printf("%s:%d put_inode: count too high: %d > %d\n", __FILE__,
               __LINE__, count, rip->i_count);
        panic("fs_putnode failed");
@@ -255,7 +249,7 @@ register struct inode *rip; /* pointer to inode to be released */
 /*===========================================================================*
  *                             alloc_inode                                  *
  *===========================================================================*/
-struct inode *alloc_inode(dev_t dev, mode_t bits)
+struct inode *alloc_inode(dev_t dev, mode_t bits, uid_t uid, gid_t gid)
 {
 /* Allocate a free inode on 'dev', and return a pointer to it. */
 
@@ -290,8 +284,8 @@ struct inode *alloc_inode(dev_t dev, mode_t bits)
        /* An inode slot is available. Put the inode just allocated into it. */
        rip->i_mode = bits;             /* set up RWX bits */
        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_uid = uid;               /* file's uid is owner's */
+       rip->i_gid = gid;               /* ditto group id */
        rip->i_dev = dev;               /* mark which device it is on */
        rip->i_ndzones = sp->s_ndzones; /* number of direct zones */
        rip->i_nindirs = sp->s_nindirs; /* number of indirect zones per blk*/
index b76356e13aa754118697a24f6cd28dd869151963..a634e73da296af91aacd9be729fcc68e806b0440 100644 (file)
@@ -29,25 +29,16 @@ static void zerozone_range(struct inode *rip, off_t pos, off_t len);
 /*===========================================================================*
  *                             fs_link                                      *
  *===========================================================================*/
-int fs_link()
+int fs_link(ino_t dir_nr, char *name, ino_t ino_nr)
 {
 /* Perform the link(name1, name2) system call. */
 
   struct inode *ip, *rip;
   register int r;
-  char string[MFS_NAME_MAX];
   struct inode *new_ip;
-  phys_bytes len;
-
-  len = min(fs_m_in.m_vfs_fs_link.path_len, sizeof(string));
-  /* Copy the link name's last component */
-  r = sys_safecopyfrom(VFS_PROC_NR, fs_m_in.m_vfs_fs_link.grant,
-                      (vir_bytes) 0, (vir_bytes) string, (size_t) len);
-  if (r != OK) return r;
-  NUL(string, len, sizeof(string));
-  
+
   /* Temporarily open the file. */
-  if( (rip = get_inode(fs_dev, fs_m_in.m_vfs_fs_link.inode)) == NULL)
+  if( (rip = get_inode(fs_dev, ino_nr)) == NULL)
          return(EINVAL);
   
   /* Check to see if the file has maximum number of links already. */
@@ -55,9 +46,9 @@ int fs_link()
   if(rip->i_nlinks >= LINK_MAX)
          r = EMLINK;
 
-  /* Only super_user may link to directories. */
+  /* Linking to directories is too dangerous to allow. */
   if(r == OK)
-         if( (rip->i_mode & I_TYPE) == I_DIRECTORY && caller_uid != SU_UID) 
+         if( (rip->i_mode & I_TYPE) == I_DIRECTORY)
                  r = EPERM;
 
   /* If error with 'name', return the inode. */
@@ -67,7 +58,7 @@ int fs_link()
   }
 
   /* Temporarily open the last dir */
-  if( (ip = get_inode(fs_dev, fs_m_in.m_vfs_fs_link.dir_ino)) == NULL) {
+  if( (ip = get_inode(fs_dev, dir_nr)) == NULL) {
        put_inode(rip);
        return(EINVAL);
   }
@@ -79,7 +70,7 @@ int fs_link()
   }
 
   /* If 'name2' exists in full (even if no space) set 'r' to error. */
-  if((new_ip = advance(ip, string, IGN_PERM)) == NULL) {
+  if((new_ip = advance(ip, name)) == NULL) {
          r = err_code;
          if(r == ENOENT)
                  r = OK;
@@ -90,7 +81,7 @@ int fs_link()
   
   /* Try to link. */
   if(r == OK)
-         r = search_dir(ip, string, &rip->i_num, ENTER, IGN_PERM);
+         r = search_dir(ip, name, &rip->i_num, ENTER);
 
   /* If success, register the linking. */
   if(r == OK) {
@@ -109,56 +100,43 @@ int fs_link()
 /*===========================================================================*
  *                             fs_unlink                                    *
  *===========================================================================*/
-int fs_unlink()
+int fs_unlink(ino_t dir_nr, char *name, int call)
 {
 /* Perform the unlink(name) or rmdir(name) system call. The code for these two
- * is almost the same.  They differ only in some condition testing.  Unlink()
- * may be used by the superuser to do dangerous things; rmdir() may not.
+ * is almost the same.  They differ only in some condition testing.
  */
   register struct inode *rip;
   struct inode *rldirp;
   int r;
-  char string[MFS_NAME_MAX];
-  phys_bytes len;
-  
-  /* Copy the last component */
-  len = min(fs_m_in.m_vfs_fs_unlink.path_len, sizeof(string));
-  r = sys_safecopyfrom(VFS_PROC_NR, fs_m_in.m_vfs_fs_unlink.grant,
-                      (vir_bytes) 0, (vir_bytes) string, (size_t) len);
-  if (r != OK) return r;
-  NUL(string, len, sizeof(string));
   
   /* Temporarily open the dir. */
-  if((rldirp = get_inode(fs_dev, fs_m_in.m_vfs_fs_unlink.inode)) == NULL)
+  if((rldirp = get_inode(fs_dev, dir_nr)) == NULL)
          return(EINVAL);
   
   /* The last directory exists.  Does the file also exist? */
-  rip = advance(rldirp, string, IGN_PERM);
+  rip = advance(rldirp, name);
   r = err_code;
 
   /* If error, return inode. */
   if(r != OK) {
-         /* Mount point? */
-       if (r == EENTERMOUNT || r == ELEAVEMOUNT) {
-               put_inode(rip);
-               r = EBUSY;
-       }
        put_inode(rldirp);
        return(r);
   }
+  if (rip->i_mountpoint) {
+       put_inode(rip);
+       put_inode(rldirp);
+       return(EBUSY);
+  }
   
   if(rip->i_sp->s_rd_only) {
        r = EROFS;
-  }  else if(fs_m_in.m_type == REQ_UNLINK) {
-  /* Now test if the call is allowed, separately for unlink() and rmdir(). */
-         /* Only the su may unlink directories, but the su can unlink any
-          * dir.*/
+  }  else if (call == FSC_UNLINK) {
          if( (rip->i_mode & I_TYPE) == I_DIRECTORY) r = EPERM;
 
          /* Actually try to unlink the file; fails if parent is mode 0 etc. */
-         if (r == OK) r = unlink_file(rldirp, rip, string);
+         if (r == OK) r = unlink_file(rldirp, rip, name);
   } else {
-         r = remove_dir(rldirp, rip, string); /* call is RMDIR */
+         r = remove_dir(rldirp, rip, name); /* call is RMDIR */
   }
 
   /* If unlink was possible, it has been done, otherwise it has not. */
@@ -171,17 +149,14 @@ int fs_unlink()
 /*===========================================================================*
  *                             fs_rdlink                                     *
  *===========================================================================*/
-int fs_rdlink()
+ssize_t fs_rdlink(ino_t ino_nr, struct fsdriver_data *data, size_t bytes)
 {
   struct buf *bp;              /* buffer containing link text */
   register struct inode *rip;  /* target inode */
   register int r;              /* return value */
-  size_t copylen;
   
-  copylen = min(fs_m_in.m_vfs_fs_rdlink.mem_size, UMAX_FILE_POS);
-
   /* Temporarily open the file. */
-  if( (rip = get_inode(fs_dev, fs_m_in.m_vfs_fs_rdlink.inode)) == NULL)
+  if( (rip = get_inode(fs_dev, ino_nr)) == NULL)
          return(EINVAL);
 
   if(!S_ISLNK(rip->i_mode))
@@ -190,15 +165,12 @@ int fs_rdlink()
        if(!(bp = get_block_map(rip, 0)))
                return EIO;
        /* Passed all checks */
-       /* We can safely cast to unsigned, because copylen is guaranteed to be
-          below max file size */
-       copylen = min( copylen, (unsigned) rip->i_size);
-       r = sys_safecopyto(VFS_PROC_NR, fs_m_in.m_vfs_fs_rdlink.grant,
-                          (vir_bytes) 0, (vir_bytes) b_data(bp),
-                          (size_t) copylen);
+       if (bytes > rip->i_size)
+               bytes = rip->i_size;
+       r = fsdriver_copyout(data, 0, b_data(bp), bytes);
        put_block(bp, DIRECTORY_BLOCK);
        if (r == OK)
-               fs_m_out.m_fs_vfs_rdlink.nbytes = copylen;
+               r = bytes;
   }
   
   put_inode(rip);
@@ -224,10 +196,9 @@ char dir_name[MFS_NAME_MAX];               /* name of directory to be removed */
   int r;
 
   /* search_dir checks that rip is a directory too. */
-  if ((r = search_dir(rip, "", NULL, IS_EMPTY, IGN_PERM)) != OK)
+  if ((r = search_dir(rip, "", NULL, IS_EMPTY)) != OK)
        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' */
  
   /* Actually try to unlink the file; fails if parent is mode 0 etc. */
@@ -236,8 +207,8 @@ char dir_name[MFS_NAME_MAX];                /* name of directory to be removed */
   /* Unlink . and .. from the dir. The super user can link and unlink any dir,
    * so don't make too many assumptions about them.
    */
-  (void) unlink_file(rip, NULL, dot1);
-  (void) unlink_file(rip, NULL, dot2);
+  (void) unlink_file(rip, NULL, ".");
+  (void) unlink_file(rip, NULL, "..");
   return(OK);
 }
 
@@ -258,14 +229,14 @@ char file_name[MFS_NAME_MAX];     /* name of file to be removed */
   /* If rip is not NULL, it is used to get faster access to the inode. */
   if (rip == NULL) {
        /* Search for file in directory and try to get its inode. */
-       err_code = search_dir(dirp, file_name, &numb, LOOK_UP, IGN_PERM);
+       err_code = search_dir(dirp, file_name, &numb, LOOK_UP);
        if (err_code == OK) rip = get_inode(dirp->i_dev, (int) numb);
        if (err_code != OK || rip == NULL) return(err_code);
   } else {
        dup_inode(rip);         /* inode will be returned with put_inode */
   }
 
-  r = search_dir(dirp, file_name, NULL, DELETE, IGN_PERM);
+  r = search_dir(dirp, file_name, NULL, DELETE);
 
   if (r == OK) {
        rip->i_nlinks--;        /* entry deleted from parent's dir */
@@ -281,7 +252,8 @@ char file_name[MFS_NAME_MAX];       /* name of file to be removed */
 /*===========================================================================*
  *                             fs_rename                                    *
  *===========================================================================*/
-int fs_rename()
+int fs_rename(ino_t old_dir_nr, char *old_name, ino_t new_dir_nr,
+       char *new_name)
 {
 /* Perform the rename(name1, name2) system call. */
   struct inode *old_dirp, *old_ip;     /* ptrs to old dir, file inodes */
@@ -290,50 +262,33 @@ int fs_rename()
   int r = OK;                          /* error flag; initially no error */
   int odir, ndir;                      /* TRUE iff {old|new} file is dir */
   int same_pdir;                       /* TRUE iff parent dirs are the same */
-  char old_name[MFS_NAME_MAX], new_name[MFS_NAME_MAX];
   ino_t numb;
-  phys_bytes len;
-  
-  /* Copy the last component of the old name */
-  len = min( (unsigned) fs_m_in.m_vfs_fs_rename.len_old, sizeof(old_name));
-  r = sys_safecopyfrom(VFS_PROC_NR, fs_m_in.m_vfs_fs_rename.grant_old,
-                      (vir_bytes) 0, (vir_bytes) old_name, (size_t) len);
-  if (r != OK) return r;
-  NUL(old_name, len, sizeof(old_name));
   
-  /* Copy the last component of the new name */
-  len = min( (unsigned) fs_m_in.m_vfs_fs_rename.len_new, sizeof(new_name));
-  r = sys_safecopyfrom(VFS_PROC_NR, fs_m_in.m_vfs_fs_rename.grant_new,
-                      (vir_bytes) 0, (vir_bytes) new_name, (size_t) len);
-  if (r != OK) return r;
-  NUL(new_name, len, sizeof(new_name));
-
   /* Get old dir inode */ 
-  if ((old_dirp = get_inode(fs_dev, fs_m_in.m_vfs_fs_rename.dir_old)) == NULL)
+  if ((old_dirp = get_inode(fs_dev, old_dir_nr)) == NULL)
        return(err_code);
 
-  old_ip = advance(old_dirp, old_name, IGN_PERM);
+  old_ip = advance(old_dirp, old_name);
   r = err_code;
 
-  if (r == EENTERMOUNT || r == ELEAVEMOUNT) {
-       put_inode(old_ip);
-       old_ip = NULL;
-       if (r == EENTERMOUNT) r = EXDEV;        /* should this fail at all? */
-       else if (r == ELEAVEMOUNT) r = EINVAL;  /* rename on dot-dot */
-  }
-
   if (old_ip == NULL) {
        put_inode(old_dirp);
        return(r);
   }
 
+  if (old_ip->i_mountpoint) {
+       put_inode(old_ip);
+       put_inode(old_dirp);
+       return(EBUSY);
+  }
+
   /* Get new dir inode */ 
-  if ((new_dirp = get_inode(fs_dev, fs_m_in.m_vfs_fs_rename.dir_new)) == NULL){
+  if ((new_dirp = get_inode(fs_dev, new_dir_nr)) == NULL) {
         put_inode(old_ip);
         put_inode(old_dirp);
         return(err_code);
   } else {
-       if (new_dirp->i_nlinks == NO_LINK) {    /* Dir does not actually exist */
+       if (new_dirp->i_nlinks == NO_LINK) { /* Dir does not actually exist */
                put_inode(old_ip);
                put_inode(old_dirp);
                put_inode(new_dirp);
@@ -341,11 +296,10 @@ int fs_rename()
        }
   }
   
-  new_ip = advance(new_dirp, new_name, IGN_PERM); /* not required to exist */
+  new_ip = advance(new_dirp, new_name); /* not required to exist */
 
-  /* However, if the check failed because the file does exist, don't continue.
-   * Note that ELEAVEMOUNT is covered by the dot-dot check later. */
-  if(err_code == EENTERMOUNT) {
+  /* If the node does exist, make sure it's not a mountpoint. */
+  if (new_ip != NULL && new_ip->i_mountpoint) {
        put_inode(new_ip);
        new_ip = NULL;
        r = EBUSY;
@@ -366,17 +320,14 @@ int fs_rename()
                                r = EINVAL;
                                break;
                        }
-                       next_new_superdirp = advance(new_superdirp, dot2,
-                                                    IGN_PERM);
+                       next_new_superdirp = advance(new_superdirp, "..");
 
                        put_inode(new_superdirp);
                        if(next_new_superdirp == new_superdirp) {
                                put_inode(new_superdirp);
                                break;  
                        }
-                       if(err_code == ELEAVEMOUNT) {
-                               /* imitate that we are back at the root,
-                                * cross device checked already on VFS */
+                       if(next_new_superdirp->i_num == ROOT_INODE) {
                                put_inode(next_new_superdirp);
                                err_code = OK;
                                break;
@@ -390,18 +341,8 @@ int fs_rename()
                }       
        }       
          
-       /* The old or new name must not be . or .. */
-       if(strcmp(old_name, ".") == 0 || strcmp(old_name, "..") == 0 ||
-          strcmp(new_name, ".") == 0 || strcmp(new_name, "..") == 0) {
-               r = EINVAL;
-       }
-       /* Both parent directories must be on the same device. 
-       if(old_dirp->i_dev != new_dirp->i_dev) r = EXDEV; */
-
        /* Some tests apply only if the new path exists. */
        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 >= LINK_MAX &&
                    !same_pdir && r == OK) { 
                        r = EMLINK;
@@ -448,16 +389,14 @@ int fs_rename()
        numb = old_ip->i_num;           /* inode number of old file */
          
        if(same_pdir) {
-               r = search_dir(old_dirp, old_name, NULL, DELETE, IGN_PERM);
+               r = search_dir(old_dirp, old_name, NULL, DELETE);
                                                /* shouldn't go wrong. */
                if(r == OK)
-                       (void) search_dir(old_dirp, new_name, &numb, ENTER,
-                                         IGN_PERM);
+                       (void) search_dir(old_dirp, new_name, &numb, ENTER);
        } else {
-               r = search_dir(new_dirp, new_name, &numb, ENTER, IGN_PERM);
+               r = search_dir(new_dirp, new_name, &numb, ENTER);
                if(r == OK)
-                       (void) search_dir(old_dirp, old_name, NULL, DELETE,
-                                         IGN_PERM);
+                       (void) search_dir(old_dirp, old_name, NULL, DELETE);
        }
   }
   /* If r is OK, the ctime and mtime of old_dirp and new_dirp have been marked
@@ -466,8 +405,8 @@ int fs_rename()
   if(r == OK && odir && !same_pdir) {
        /* Update the .. entry in the directory (still points to old_dirp).*/
        numb = new_dirp->i_num;
-       (void) unlink_file(old_ip, NULL, dot2);
-       if(search_dir(old_ip, dot2, &numb, ENTER, IGN_PERM) == OK) {
+       (void) unlink_file(old_ip, NULL, "..");
+       if(search_dir(old_ip, "..", &numb, ENTER) == OK) {
                /* New link created. */
                new_dirp->i_nlinks++;
                IN_MARKDIRTY(new_dirp);
@@ -484,23 +423,19 @@ int fs_rename()
 
 
 /*===========================================================================*
- *                             fs_ftrunc                                    *
+ *                             fs_trunc                                     *
  *===========================================================================*/
-int fs_ftrunc(void)
+int fs_trunc(ino_t ino_nr, off_t start, off_t end)
 {
   struct inode *rip;
-  off_t start, end;
   int r;
   
-  if( (rip = find_inode(fs_dev, fs_m_in.m_vfs_fs_ftrunc.inode)) == NULL)
+  if( (rip = find_inode(fs_dev, ino_nr)) == NULL)
          return(EINVAL);
 
   if(rip->i_sp->s_rd_only) {
        r = EROFS;
   } else {
-    start = fs_m_in.m_vfs_fs_ftrunc.trc_start;
-    end = fs_m_in.m_vfs_fs_ftrunc.trc_end;
-
     if (end == 0)
          r = truncate_inode(rip, start);
     else 
index 43c881dd073ead4ddf4228cb0e0f1c1801f1735e..da34ba9e2892002f2eb7de33b9e4bb0b6768fe27 100644 (file)
@@ -1,20 +1,8 @@
 #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 "buf.h"
 #include "inode.h"
 
 
-/* Declare some local functions. */
-static void get_work(message *m_in);
-static void reply(endpoint_t who, message *m_out);
-
 /* SEF functions and variables. */
 static void sef_local_startup(void);
 static int sef_cb_init_fresh(int type, sef_init_info_t *info);
@@ -25,60 +13,16 @@ static void sef_cb_signal_handler(int signo);
  *===========================================================================*/
 int main(int argc, char *argv[])
 {
-/* This is the main routine of this service. The main loop consists of 
- * three major activities: getting new work, processing the work, and
- * sending the reply. The loop never terminates, unless a panic occurs.
- */
-  int error = OK, ind, transid;
+/* This is the main routine of this service. */
 
   /* SEF local startup. */
   env_setargs(argc, argv);
   sef_local_startup();
 
-  while(!unmountdone || !exitsignaled) {
-       endpoint_t src;
-
-       /* Wait for request message. */
-       get_work(&fs_m_in);
-       
-       transid = TRNS_GET_ID(fs_m_in.m_type);
-       fs_m_in.m_type = TRNS_DEL_ID(fs_m_in.m_type);
-       if (fs_m_in.m_type == 0) {
-               assert(!IS_VFS_FS_TRANSID(transid));
-               fs_m_in.m_type = transid;       /* Backwards compat. */
-               transid = 0;
-       } else
-               assert(IS_VFS_FS_TRANSID(transid));
-
-       src = fs_m_in.m_source;
-       caller_uid = INVAL_UID; /* To trap errors */
-       caller_gid = INVAL_GID;
-       req_nr = fs_m_in.m_type;
-
-       if (req_nr < FS_BASE) {
-               fs_m_in.m_type += FS_BASE;
-               req_nr = fs_m_in.m_type;
-       }
-       ind = req_nr - FS_BASE;
-
-       if (ind < 0 || ind >= NREQS) {
-               printf("MFS: bad request %d from %d\n", req_nr, src);
-               printf("ind = %d\n", ind);
-               error = EINVAL;
-       } else {
-               error = (*fs_call_vec[ind])();
-               /*cch_check();*/
-       }
-
-       fs_m_out.m_type = error; 
-       if (IS_VFS_FS_TRANSID(transid)) {
-               /* If a transaction ID was set, reset it */
-               fs_m_out.m_type = TRNS_ADD_ID(fs_m_out.m_type, transid);
-       }
-       reply(src, &fs_m_out);
-  }
+  /* The fsdriver library does the actual work here. */
+  fsdriver_task(&mfs_table);
 
-  return(OK);
+  return(0);
 }
 
 /*===========================================================================*
@@ -130,53 +74,9 @@ static void sef_cb_signal_handler(int signo)
   /* Only check for termination signal, ignore anything else. */
   if (signo != SIGTERM) return;
 
-  exitsignaled = 1;
-  (void) fs_sync();
-
-  /* If unmounting has already been performed, exit immediately.
-   * We might not get another message.
-   */
-  if (unmountdone) exit(0);
-}
-
-/*===========================================================================*
- *                             get_work                                     *
- *===========================================================================*/
-static void get_work(m_in)
-message *m_in;                         /* pointer to message */
-{
-  int r, srcok = 0;
-  endpoint_t src;
-
-  do {
-       if ((r = sef_receive(ANY, m_in)) != OK)         /* wait for message */
-               panic("sef_receive failed: %d", r);
-       src = m_in->m_source;
-
-       if(src == VFS_PROC_NR) {
-               if(unmountdone) 
-                       printf("MFS: unmounted: unexpected message from FS\n");
-               else 
-                       srcok = 1;              /* Normal FS request. */
-               
-       } else
-               printf("MFS: unexpected source %d\n", src);
-  } while(!srcok);
-
-   assert((src == VFS_PROC_NR && !unmountdone));
-}
-
+  fs_sync();
 
-/*===========================================================================*
- *                             reply                                        *
- *===========================================================================*/
-static void reply(
-  endpoint_t who,
-  message *m_out                               /* report result */
-)
-{
-  if (OK != ipc_send(who, m_out))    /* send the message */
-       printf("MFS(%d) was unable to send reply\n", sef_self());
+  fsdriver_terminate();
 }
 
 
index e4bcbc31b2a5c4a0af314ccd82c5c3fee9e2f9ce..48d85ec49448a5354555b8edd6b7e388c05c9628 100644 (file)
@@ -1,14 +1,12 @@
 #include "fs.h"
-#include <assert.h>
-#include <minix/vfsif.h>
-#include <minix/bdev.h>
 #include "inode.h"
 #include "clean.h"
+#include <assert.h>
 
 /*===========================================================================*
  *                             fs_sync                                      *
  *===========================================================================*/
-int fs_sync()
+void fs_sync(void)
 {
 /* Perform the sync() system call.  Flush all the tables. 
  * The order in which the various tables are flushed is critical.  The
@@ -25,62 +23,4 @@ int fs_sync()
 
   /* Write all the dirty blocks to the disk. */
   lmfs_flushall();
-
-  return(OK);          /* sync() can't fail */
-}
-
-
-/*===========================================================================*
- *                             fs_flush                                     *
- *===========================================================================*/
-int fs_flush()
-{
-/* Flush the blocks of a device from the cache after writing any dirty blocks
- * to disk.
- */
-  dev_t dev = fs_m_in.m_vfs_fs_flush.device;
-  if(dev == fs_dev && lmfs_bufs_in_use() > 0) return(EBUSY);
-  lmfs_flushall();
-  lmfs_invalidate(dev);
-
-  return(OK);
-}
-
-
-/*===========================================================================*
- *                             fs_new_driver                                *
- *===========================================================================*/
-int fs_new_driver(void)
-{
-/* Set a new driver endpoint for this device. */
-  dev_t dev;
-  cp_grant_id_t label_gid;
-  size_t label_len;
-  char label[sizeof(fs_dev_label)];
-  int r;
-
-  dev = fs_m_in.m_vfs_fs_new_driver.device;
-  label_gid = fs_m_in.m_vfs_fs_new_driver.grant;
-  label_len = fs_m_in.m_vfs_fs_new_driver.path_len;
-
-  if (label_len > sizeof(label))
-       return(EINVAL);
-
-  r = sys_safecopyfrom(fs_m_in.m_source, label_gid, (vir_bytes) 0,
-       (vir_bytes) label, label_len);
-
-  if (r != OK) {
-       printf("MFS: fs_new_driver safecopyfrom failed (%d)\n", r);
-       return(EINVAL);
-  }
-
-  bdev_driver(dev, label);
-
-  return(OK);
-}
-
-int fs_bpeek(void)
-{
-       return lmfs_do_bpeek(&fs_m_in);
 }
index 797b81854c7b5613e455591e9aae8b2ec02a1055..544576f2c921356f2608a7ecd412a8f4f98ce108 100644 (file)
@@ -4,44 +4,20 @@
 #include <minix/vfsif.h>
 #include <minix/bdev.h>
 
-static int cleanmount = 1;
-
 /*===========================================================================*
- *                             fs_readsuper                                 *
+ *                             fs_mount                                     *
  *===========================================================================*/
-int fs_readsuper()
+int fs_mount(dev_t dev, unsigned int flags, struct fsdriver_node *root_node,
+       unsigned int *res_flags)
 {
 /* This function reads the superblock of the partition, gets the root inode
- * and sends back the details of them. Note, that the FS process does not
- * know the index of the vmnt object which refers to it, whenever the pathname 
- * lookup leaves a partition an ELEAVEMOUNT error is transferred back 
- * so that the VFS knows that it has to find the vnode on which this FS 
- * process' partition is mounted on.
+ * and sends back the details of them.
  */
   struct inode *root_ip;
-  cp_grant_id_t label_gid;
-  size_t label_len;
-  int r;
-  int readonly, isroot;
-
-  fs_dev    = fs_m_in.m_vfs_fs_readsuper.device;
-  label_gid = fs_m_in.m_vfs_fs_readsuper.grant;
-  label_len = fs_m_in.m_vfs_fs_readsuper.path_len;
-  readonly  = (fs_m_in.m_vfs_fs_readsuper.flags & REQ_RDONLY) ? 1 : 0;
-  isroot    = (fs_m_in.m_vfs_fs_readsuper.flags & REQ_ISROOT) ? 1 : 0;
-
-  if (label_len > sizeof(fs_dev_label))
-       return(EINVAL);
+  int r, readonly;
 
-  r = sys_safecopyfrom(fs_m_in.m_source, label_gid, (vir_bytes) 0,
-                      (vir_bytes) fs_dev_label, label_len);
-  if (r != OK) {
-       printf("MFS %s:%d safecopyfrom failed: %d\n", __FILE__, __LINE__, r);
-       return(EINVAL);
-  }
-
-  /* Map the driver label for this major. */
-  bdev_driver(fs_dev, fs_dev_label);
+  fs_dev = dev;
+  readonly = (flags & REQ_RDONLY) ? 1 : 0;
 
   /* Open the device the file system lives on. */
   if (bdev_open(fs_dev, readonly ? BDEV_R_BIT : (BDEV_R_BIT|BDEV_W_BIT) ) !=
@@ -60,12 +36,6 @@ int fs_readsuper()
        return(r);
   }
 
-  /* Remember whether we were mounted cleanly so we know what to
-   * do at unmount time
-   */
-  if(superblock.s_flags & MFSFLAG_CLEAN)
-       cleanmount = 1;
-
   /* clean check: if rw and not clean, switch to readonly */
   if(!(superblock.s_flags & MFSFLAG_CLEAN) && !readonly) {
        if(bdev_close(fs_dev) != OK)
@@ -98,15 +68,16 @@ int fs_readsuper()
   }
 
   superblock.s_rd_only = readonly;
-  superblock.s_is_root = isroot;
   
   /* Root inode properties */
-  fs_m_out.m_fs_vfs_readsuper.inode = root_ip->i_num;
-  fs_m_out.m_fs_vfs_readsuper.mode = root_ip->i_mode;
-  fs_m_out.m_fs_vfs_readsuper.file_size = root_ip->i_size;
-  fs_m_out.m_fs_vfs_readsuper.uid = root_ip->i_uid;
-  fs_m_out.m_fs_vfs_readsuper.gid = root_ip->i_gid;
-  fs_m_out.m_fs_vfs_readsuper.flags = RES_HASPEEK;
+  root_node->fn_ino_nr = root_ip->i_num;
+  root_node->fn_mode = root_ip->i_mode;
+  root_node->fn_size = root_ip->i_size;
+  root_node->fn_uid = root_ip->i_uid;
+  root_node->fn_gid = root_ip->i_gid;
+  root_node->fn_dev = NO_DEV;
+
+  *res_flags = RES_NOFLAGS;
 
   /* Mark it dirty */
   if(!superblock.s_rd_only) {
@@ -120,9 +91,9 @@ int fs_readsuper()
 
 
 /*===========================================================================*
- *                             fs_mountpoint                                *
+ *                             fs_mountpt                                   *
  *===========================================================================*/
-int fs_mountpoint()
+int fs_mountpt(ino_t ino_nr)
 {
 /* This function looks up the mount point, it checks the condition whether
  * the partition can be mounted on the inode or not. 
@@ -132,10 +103,9 @@ int fs_mountpoint()
   mode_t bits;
   
   /* Temporarily open the file. */
-  if( (rip = get_inode(fs_dev, fs_m_in.m_vfs_fs_mountpoint.inode)) == NULL)
+  if( (rip = get_inode(fs_dev, ino_nr)) == NULL)
          return(EINVAL);
   
-  
   if(rip->i_mountpoint) r = EBUSY;
 
   /* It may not be special. */
@@ -153,33 +123,32 @@ int fs_mountpoint()
 /*===========================================================================*
  *                             fs_unmount                                   *
  *===========================================================================*/
-int fs_unmount()
+void fs_unmount(void)
 {
-/* Unmount a file system by device number. */
+/* Unmount a file system. */
   int count;
   struct inode *rip, *root_ip;
 
-  if(superblock.s_dev != fs_dev) return(EINVAL);
-  
   /* See if the mounted device is busy.  Only 1 inode using it should be
-   * open --the root inode-- and that inode only 1 time. */
+   * open --the root inode-- and that inode only 1 time.  This is an integrity
+   * check only: VFS expects the unmount to succeed either way.
+   */
   count = 0;
   for (rip = &inode[0]; rip < &inode[NR_INODES]; rip++) 
          if (rip->i_count > 0 && rip->i_dev == fs_dev) count += rip->i_count;
+  if (count != 1)
+       printf("MFS: file system has %d in-use inodes!\n", count);
 
-  if ((root_ip = find_inode(fs_dev, ROOT_INODE)) == NULL) {
-       panic("MFS: couldn't find root inode\n");
-       return(EINVAL);
-  }
+  if ((root_ip = find_inode(fs_dev, ROOT_INODE)) == NULL)
+       panic("MFS: couldn't find root inode\n");
    
-  if (count > 1) return(EBUSY);        /* can't umount a busy file system */
   put_inode(root_ip);
 
   /* force any cached blocks out of memory */
-  (void) fs_sync();
+  fs_sync();
 
   /* Mark it clean if we're allowed to write _and_ it was clean originally. */
-  if(cleanmount && !superblock.s_rd_only) {
+  if (!superblock.s_rd_only) {
        superblock.s_flags |= MFSFLAG_CLEAN;
        write_super(&superblock);
   }
@@ -192,8 +161,5 @@ int fs_unmount()
 
   /* Finish off the unmount. */
   superblock.s_dev = NO_DEV;
-  unmountdone = TRUE;
-
-  return(OK);
 }
 
index fba0d3094fbe3121d8115cb5bd5ee5f87fde1cc1..67c8225aee20e531c4b7e2aa735e1176ddde5a15 100644 (file)
@@ -1,47 +1,31 @@
 #include "fs.h"
 #include <sys/stat.h>
 #include <string.h>
-#include <minix/com.h>
 #include "buf.h"
 #include "inode.h"
 #include "super.h"
-#include <minix/vfsif.h>
 
 static struct inode *new_node(struct inode *ldirp, char *string, mode_t
-       bits, zone_t z0);
+       bits, uid_t uid, gid_t gid, zone_t z0);
 
 /*===========================================================================*
  *                             fs_create                                    *
  *===========================================================================*/
-int fs_create()
+int fs_create(ino_t dir_nr, char *name, mode_t mode, uid_t uid, gid_t gid,
+       struct fsdriver_node *node)
 {
-  size_t len;
   int r;
   struct inode *ldirp;
   struct inode *rip;
-  mode_t omode;
-  char lastc[MFS_NAME_MAX];
-  
-  /* Read request message */
-  omode = fs_m_in.m_vfs_fs_create.mode;
-  caller_uid = fs_m_in.m_vfs_fs_create.uid;
-  caller_gid = fs_m_in.m_vfs_fs_create.gid;
   
   /* Try to make the file. */ 
 
-  /* Copy the last component (i.e., file name) */
-  len = min(fs_m_in.m_vfs_fs_create.path_len, sizeof(lastc));
-  err_code = sys_safecopyfrom(VFS_PROC_NR, fs_m_in.m_vfs_fs_create.grant,
-                             (vir_bytes) 0, (vir_bytes) lastc, len);
-  if (err_code != OK) return err_code;
-  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.m_vfs_fs_create.inode)) == NULL)
-         return(ENOENT);
+  if ((ldirp = get_inode(fs_dev, dir_nr)) == NULL)
+         return(EINVAL);
 
   /* Create a new inode by calling new_node(). */
-  rip = new_node(ldirp, lastc, omode, NO_ZONE);
+  rip = new_node(ldirp, name, mode, uid, gid, NO_ZONE);
   r = err_code;
 
   /* If an error occurred, release inode. */
@@ -52,13 +36,12 @@ int fs_create()
   }
   
   /* Reply message */
-  fs_m_out.m_fs_vfs_create.inode = rip->i_num;
-  fs_m_out.m_fs_vfs_create.mode = rip->i_mode;
-  fs_m_out.m_fs_vfs_create.file_size = rip->i_size;
-
-  /* These values are needed for the execution */
-  fs_m_out.m_fs_vfs_create.uid = rip->i_uid;
-  fs_m_out.m_fs_vfs_create.gid = rip->i_gid;
+  node->fn_ino_nr = rip->i_num;
+  node->fn_mode = rip->i_mode;
+  node->fn_size = rip->i_size;
+  node->fn_uid = rip->i_uid;
+  node->fn_gid = rip->i_gid;
+  node->fn_dev = NO_DEV;
 
   /* Drop parent dir */
   put_inode(ldirp);
@@ -70,29 +53,17 @@ int fs_create()
 /*===========================================================================*
  *                             fs_mknod                                     *
  *===========================================================================*/
-int fs_mknod()
+int fs_mknod(ino_t dir_nr, char *name, mode_t mode, uid_t uid, gid_t gid,
+       dev_t dev)
 {
   struct inode *ip, *ldirp;
-  char lastc[MFS_NAME_MAX];
-  phys_bytes len;
-
-  /* Copy the last component and set up caller's user and group id */
-  len = min(fs_m_in.m_vfs_fs_mknod.path_len, sizeof(lastc));
-  err_code = sys_safecopyfrom(VFS_PROC_NR, fs_m_in.m_vfs_fs_mknod.grant,
-                           (vir_bytes) 0, (vir_bytes) lastc, (size_t) len);
-  if (err_code != OK) return err_code;
-  NUL(lastc, len, sizeof(lastc));
-  
-  caller_uid = fs_m_in.m_vfs_fs_mknod.uid;
-  caller_gid = fs_m_in.m_vfs_fs_mknod.gid;
-  
+
   /* Get last directory inode */
-  if((ldirp = get_inode(fs_dev, fs_m_in.m_vfs_fs_mknod.inode)) == NULL)
-         return(ENOENT);
+  if((ldirp = get_inode(fs_dev, dir_nr)) == NULL)
+         return(EINVAL);
 
   /* Try to create the new node */
-  ip = new_node(ldirp, lastc, fs_m_in.m_vfs_fs_mknod.mode,
-               (zone_t) fs_m_in.m_vfs_fs_mknod.device);
+  ip = new_node(ldirp, name, mode, uid, gid, (zone_t) dev);
 
   put_inode(ip);
   put_inode(ldirp);
@@ -103,30 +74,18 @@ int fs_mknod()
 /*===========================================================================*
  *                             fs_mkdir                                     *
  *===========================================================================*/
-int fs_mkdir()
+int fs_mkdir(ino_t dir_nr, char *name, mode_t mode, uid_t uid, gid_t gid)
 {
   int r1, r2;                  /* status codes */
   ino_t dot, dotdot;           /* inode numbers for . and .. */
   struct inode *rip, *ldirp;
-  char lastc[MFS_NAME_MAX];         /* last component */
-  phys_bytes len;
-
-  /* Copy the last component and set up caller's user and group id */
-  len = min(fs_m_in.m_vfs_fs_mkdir.path_len, sizeof(lastc));
-  err_code = sys_safecopyfrom(VFS_PROC_NR, fs_m_in.m_vfs_fs_mkdir.grant,
-                          (vir_bytes) 0, (vir_bytes) lastc, (size_t) len);
-  if(err_code != OK) return(err_code);
-  NUL(lastc, len, sizeof(lastc));
-
-  caller_uid = fs_m_in.m_vfs_fs_mkdir.uid;
-  caller_gid = fs_m_in.m_vfs_fs_mkdir.gid;
-  
+
   /* Get last directory inode */
-  if((ldirp = get_inode(fs_dev, fs_m_in.m_vfs_fs_mkdir.inode)) == NULL)
-      return(ENOENT);
+  if((ldirp = get_inode(fs_dev, dir_nr)) == NULL)
+      return(EINVAL);
   
   /* Next make the inode. If that fails, return error code. */
-  rip = new_node(ldirp, lastc, fs_m_in.m_vfs_fs_mkdir.mode, (zone_t) 0);
+  rip = new_node(ldirp, name, mode, uid, gid, (zone_t) 0);
   
   if(rip == NULL || err_code == EEXIST) {
          put_inode(rip);               /* can't make dir: it already exists */
@@ -139,11 +98,8 @@ int fs_mkdir()
   dot = rip->i_num;            /* inode number of the new dir itself */
 
   /* 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.m_vfs_fs_mkdir.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 */
+  r1 = search_dir(rip, ".", &dot, ENTER);      /* enter . in the new dir */
+  r2 = search_dir(rip, "..", &dotdot, ENTER);  /* enter .. in the new dir */
 
   /* If both . and .. were successfully entered, increment the link counts. */
   if (r1 == OK && r2 == OK) {
@@ -154,7 +110,7 @@ int fs_mkdir()
   } else {
          /* It was not possible to enter . or .. probably disk was full -
           * links counts haven't been touched. */
-         if(search_dir(ldirp, lastc, NULL, DELETE, IGN_PERM) != OK)
+         if(search_dir(ldirp, name, NULL, DELETE) != OK)
                  panic("Dir disappeared: %llu", rip->i_num);
          rip->i_nlinks--;      /* undo the increment done in new_node() */
   }
@@ -169,54 +125,39 @@ int fs_mkdir()
 /*===========================================================================*
  *                             fs_slink                                     *
  *===========================================================================*/
-int fs_slink()
+int fs_slink(ino_t dir_nr, char *name, uid_t uid, gid_t gid,
+       struct fsdriver_data *data, size_t bytes)
 {
-  phys_bytes len;
   struct inode *sip;           /* inode containing symbolic link */
   struct inode *ldirp;         /* directory containing link */
   register int r;              /* error code */
-  char string[MFS_NAME_MAX];       /* last component of the new dir's path name */
   struct buf *bp;              /* disk buffer for link */
     
-  caller_uid = fs_m_in.m_vfs_fs_slink.uid;
-  caller_gid = fs_m_in.m_vfs_fs_slink.gid;
-  
-  /* Copy the link name's last component */
-  len = min( (unsigned) fs_m_in.m_vfs_fs_slink.path_len, sizeof(string));
-  r = sys_safecopyfrom(VFS_PROC_NR, fs_m_in.m_vfs_fs_slink.grant_path,
-                       (vir_bytes) 0, (vir_bytes) string, (size_t) len);
-  if (r != OK) return(r);
-  NUL(string, len, sizeof(string));
-  
   /* Temporarily open the dir. */
-  if( (ldirp = get_inode(fs_dev, fs_m_in.m_vfs_fs_slink.inode)) == NULL)
+  if( (ldirp = get_inode(fs_dev, dir_nr)) == NULL)
          return(EINVAL);
 
   /* Create the inode for the symlink. */
-  sip = new_node(ldirp, string, (I_SYMBOLIC_LINK | RWX_MODES), 0);
+  sip = new_node(ldirp, name, (I_SYMBOLIC_LINK | RWX_MODES), uid, gid, 0);
 
   /* 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) {
-       size_t namelen = fs_m_in.m_vfs_fs_slink.mem_size;
        bp = new_block(sip, (off_t) 0);
        if (bp == NULL)
                r = err_code;
        else {
-               if(get_block_size(sip->i_dev) <= namelen) {
+               if(get_block_size(sip->i_dev) <= bytes) {
                        r = ENAMETOOLONG;
                } else {
-                       r = sys_safecopyfrom(VFS_PROC_NR,
-                                    fs_m_in.m_vfs_fs_slink.grant_target,
-                                    (vir_bytes) 0, (vir_bytes) b_data(bp),
-                                    namelen);
-                       b_data(bp)[namelen] = '\0';
+                       r = fsdriver_copyin(data, 0, b_data(bp), bytes);
+                       b_data(bp)[bytes] = '\0';
                }
        }
 
        if(bp != NULL && r == OK) {
                sip->i_size = (off_t) strlen(b_data(bp));
-               if(sip->i_size != fs_m_in.m_vfs_fs_slink.mem_size) {
+               if(sip->i_size != bytes) {
                        /* 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
@@ -233,7 +174,7 @@ int fs_slink()
   
        if(r != OK) {
                sip->i_nlinks = NO_LINK;
-               if(search_dir(ldirp, string, NULL, DELETE, IGN_PERM) != OK)
+               if(search_dir(ldirp, name, NULL, DELETE) != OK)
                          panic("Symbolic link vanished");
        } 
   }
@@ -249,7 +190,7 @@ int fs_slink()
  *                             new_node                                     *
  *===========================================================================*/
 static struct inode *new_node(struct inode *ldirp,
-       char *string, mode_t bits, zone_t z0)
+       char *string, mode_t bits, uid_t uid, gid_t gid, zone_t z0)
 {
 /* New_node() is called by fs_open(), fs_mknod(), and fs_mkdir().  
  * In all cases it allocates a new inode, makes a directory entry for it in
@@ -261,7 +202,6 @@ static struct inode *new_node(struct inode *ldirp,
  * The parsed path rest is returned in 'parsed' if parsed is nonzero. It
  * has to hold at least MFS_NAME_MAX bytes.
  */
-
   register struct inode *rip;
   register int r;
 
@@ -270,19 +210,18 @@ static struct inode *new_node(struct inode *ldirp,
        return(NULL);
   }
 
-  /* Get final component of the path. */
-  rip = advance(ldirp, string, IGN_PERM);
-
   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;
         return(NULL);
   }
 
+  /* Get final component of the path. */
+  rip = advance(ldirp, string);
+
   if ( rip == NULL && err_code == ENOENT) {
        /* Last path component does not exist.  Make new directory entry. */
-       if ( (rip = alloc_inode((ldirp)->i_dev, bits)) == NULL) {
+       if ( (rip = alloc_inode((ldirp)->i_dev, bits, uid, gid)) == NULL) {
                /* Can't creat new inode: out of inodes. */
                return(NULL);
        }
@@ -296,7 +235,7 @@ static struct inode *new_node(struct inode *ldirp,
        rw_inode(rip, WRITING);         /* force inode to disk now */
 
        /* New inode acquired.  Try to make directory entry. */
-       if((r=search_dir(ldirp, string, &rip->i_num, ENTER, IGN_PERM)) != OK) {
+       if((r=search_dir(ldirp, string, &rip->i_num, ENTER)) != OK) {
                rip->i_nlinks--;        /* pity, have to free disk inode */
                IN_MARKDIRTY(rip);      /* dirty inodes are written out */
                put_inode(rip); /* this call frees the inode */
@@ -304,8 +243,6 @@ static struct inode *new_node(struct inode *ldirp,
                return(NULL);
        }
 
-  } else if (err_code == EENTERMOUNT || err_code == ELEAVEMOUNT) {
-       r = EEXIST;
   } else { 
        /* Either last component exists, or there is some problem. */
        if (rip != NULL)
@@ -321,18 +258,13 @@ static struct inode *new_node(struct inode *ldirp,
 
 
 /*===========================================================================*
- *                             fs_inhibread                                 *
+ *                             fs_seek                                      *
  *===========================================================================*/
-int fs_inhibread()
+void fs_seek(ino_t ino_nr)
 {
   struct inode *rip;
   
-  if((rip = find_inode(fs_dev, fs_m_in.m_vfs_fs_inhibread.inode)) == NULL)
-         return(EINVAL);
-
   /* inhibit read ahead */
-  rip->i_seek = ISEEK; 
-  
-  return(OK);
+  if ((rip = find_inode(fs_dev, ino_nr)) != NULL)
+         rip->i_seek = ISEEK;
 }
-
index 14800a4e2c0256591a8c72ec0e4309d4bb685770..92328e748458b76ba7fc2270279770198510b3ec 100644 (file)
 /* This file contains the procedures that look up path names in the directory
  * system and determine the inode number that goes with a given path name.
- *
- *  The entry points into this file are
- *   eat_path:  the 'main' routine of the path-to-inode conversion mechanism
- *   last_dir:  find the final directory on a given path
- *   advance:   parse one component of a path name
- *   search_dir: search a directory for a string and return its inode number
- *
  */
  
 #include "fs.h"
-#include "assert.h"
+#include <assert.h>
 #include <string.h>
-#include <minix/endpoint.h>
-#include <sys/stat.h>
-#include <sys/types.h>
 #include "buf.h"
 #include "inode.h"
 #include "super.h"
-#include <minix/vfsif.h>
-#include <minix/libminixfs.h>
-
-
-char dot1[2] = ".";    /* used for search_dir to bypass the access */
-char dot2[3] = "..";   /* permissions for . and ..                 */
-
-static char *get_name(char *name, char string[MFS_NAME_MAX+1]);
-static int ltraverse(struct inode *rip, char *suffix);
-static int parse_path(ino_t dir_ino, ino_t root_ino, int flags, struct
-       inode **res_inop, size_t *offsetp, int *symlinkp);
 
 
 /*===========================================================================*
  *                             fs_lookup                                    *
  *===========================================================================*/
-int fs_lookup()
+int fs_lookup(ino_t dir_nr, char *name, struct fsdriver_node *node,
+       int *is_mountpt)
 {
-  cp_grant_id_t grant;
-  int r, r1, flags, symlinks;
-  unsigned int len;
-  size_t offset = 0, path_size;
-  ino_t dir_ino, root_ino;
-  struct inode *rip;
-
-  grant                = fs_m_in.m_vfs_fs_lookup.grant_path;
-  path_size    = fs_m_in.m_vfs_fs_lookup.path_size; /* Size of the buffer */
-  len          = fs_m_in.m_vfs_fs_lookup.path_len; /* including terminating nul */
-  dir_ino      = fs_m_in.m_vfs_fs_lookup.dir_ino;
-  root_ino     = fs_m_in.m_vfs_fs_lookup.root_ino;
-  flags                = fs_m_in.m_vfs_fs_lookup.flags;
-
-  /* Check length. */
-  if(len > sizeof(user_path)) return(E2BIG);   /* too big for buffer */
-  if(len == 0) return(EINVAL);                 /* too small */
-
-  /* Copy the pathname and set up caller's user and group id */
-  r = sys_safecopyfrom(VFS_PROC_NR, grant, /*offset*/ (vir_bytes) 0, 
-            (vir_bytes) user_path, (size_t) len);
-  if(r != OK) return(r);
-
-  /* Verify this is a null-terminated path. */
-  if(user_path[len - 1] != '\0') return(EINVAL);
-
-  memset(&credentials, 0, sizeof(credentials));
-  if(!(flags & PATH_GET_UCRED)) { /* Do we have to copy uid/gid credentials? */
-        caller_uid     = fs_m_in.m_vfs_fs_lookup.uid;
-        caller_gid     = fs_m_in.m_vfs_fs_lookup.gid;
-  } else {
-         if((r=fs_lookup_credentials(&credentials,
-               &caller_uid, &caller_gid,
-               fs_m_in.m_vfs_fs_lookup.grant_ucred,
-               fs_m_in.m_vfs_fs_lookup.ucred_size)) != OK)
-               return r;
-  }
-
-  /* Lookup inode */
-  rip = NULL;
-  r = parse_path(dir_ino, root_ino, flags, &rip, &offset, &symlinks);
-
-  if(symlinks != 0 && (r == ELEAVEMOUNT || r == EENTERMOUNT || r == ESYMLINK)){
-       len = strlen(user_path)+1;
-       if(len > path_size) return(ENAMETOOLONG);
-
-       r1 = sys_safecopyto(VFS_PROC_NR, grant, (vir_bytes) 0,
-                           (vir_bytes) user_path, (size_t) len);
-       if(r1 != OK) return(r1);
-  }
-
-  if(r == ELEAVEMOUNT || r == ESYMLINK) {
-         /* Report offset and the error */
-         fs_m_out.m_fs_vfs_lookup.offset = offset;
-         fs_m_out.m_fs_vfs_lookup.symloop = symlinks;
-
-         return(r);
-  }
-
-  if (r != OK && r != EENTERMOUNT) return(r);
-
-  fs_m_out.m_fs_vfs_lookup.inode               = rip->i_num;
-  fs_m_out.m_fs_vfs_lookup.mode                        = rip->i_mode;
-  fs_m_out.m_fs_vfs_lookup.file_size           = rip->i_size;
-  fs_m_out.m_fs_vfs_lookup.symloop             = symlinks;
-  fs_m_out.m_fs_vfs_lookup.uid                 = rip->i_uid;
-  fs_m_out.m_fs_vfs_lookup.gid                 = rip->i_gid;
-  
+  struct inode *dirp, *rip;
+
+  /* Find the starting inode. */
+  if ((dirp = find_inode(fs_dev, dir_nr)) == NULL)
+       return EINVAL;
+
+  /* Look up the directory entry. */
+  if ((rip = advance(dirp, name)) == NULL)
+       return err_code;
+
+  /* On success, leave the resulting inode open and return its details. */
+  node->fn_ino_nr = rip->i_num;
+  node->fn_mode = rip->i_mode;
+  node->fn_size = rip->i_size;
+  node->fn_uid = rip->i_uid;
+  node->fn_gid = rip->i_gid;
   /* This is only valid for block and character specials. But it doesn't
    * cause any harm to always set the device field. */
-  fs_m_out.m_fs_vfs_lookup.device              = (dev_t) rip->i_zone[0];
+  node->fn_dev = (dev_t) rip->i_zone[0];
 
-  if(r == EENTERMOUNT) {
-         fs_m_out.m_fs_vfs_lookup.offset       = offset;
-         put_inode(rip); /* Only return a reference to the final object */
-  }
+  *is_mountpt = rip->i_mountpoint;
 
-  return(r);
-}
-
-
-/*===========================================================================*
- *                             parse_path                                   *
- *===========================================================================*/
-static int parse_path(
-ino_t dir_ino,
-ino_t root_ino,
-int flags,
-struct inode **res_inop,
-size_t *offsetp,
-int *symlinkp
-) {
-  /* Parse the path in user_path, starting at dir_ino. If the path is the empty
-   * string, just return dir_ino. It is upto the caller to treat an empty
-   * path in a special way. Otherwise, if the path consists of just one or
-   * more slash ('/') characters, the path is replaced with ".". Otherwise,
-   * just look up the first (or only) component in path after skipping any
-   * leading slashes. 
-   */
-  int r, leaving_mount;
-  struct inode *rip, *dir_ip;
-  char *cp, *next_cp; /* component and next component */
-  char component[MFS_NAME_MAX+1];
-
-  /* Start parsing path at the first component in user_path */
-  cp = user_path;  
-
-  /* No symlinks encountered yet */
-  *symlinkp = 0;
-
-  /* Find starting inode inode according to the request message */
-  if((rip = find_inode(fs_dev, dir_ino)) == NULL) 
-       return(ENOENT);
-
-  /* If dir has been removed return ENOENT. */
-  if (rip->i_nlinks == NO_LINK) return(ENOENT);
-  dup_inode(rip);
-
-  /* If the given start inode is a mountpoint, we must be here because the file
-   * system mounted on top returned an ELEAVEMOUNT error. In this case, we must
-   * only accept ".." as the first path component.
-   */
-  leaving_mount = rip->i_mountpoint; /* True iff rip is a mountpoint */
-
-  /* Scan the path component by component. */
-  while (TRUE) {
-       if(cp[0] == '\0') {
-               /* We're done; either the path was empty or we've parsed all 
-                  components of the path */
-               
-               *res_inop = rip;
-               *offsetp += cp - user_path;
-
-               /* Return EENTERMOUNT if we are at a mount point */
-               if (rip->i_mountpoint) return(EENTERMOUNT);
-               
-               return(OK);
-       }
-
-       while(cp[0] == '/') cp++;
-       next_cp = get_name(cp, component);
-
-       /* Special code for '..'. A process is not allowed to leave a chrooted
-        * environment. A lookup of '..' at the root of a mounted filesystem
-        * has to return ELEAVEMOUNT. In both cases, the caller needs search
-        * permission for the current inode, as it is used as directory.
-        */
-       if(strcmp(component, "..") == 0) {
-               /* 'rip' is now accessed as directory */
-               if ((r = forbidden(rip, X_BIT)) != OK) {
-                       put_inode(rip);
-                       return(r);
-               }
-
-               if (rip->i_num == root_ino) {
-                       cp = next_cp;
-                       continue;       /* Ignore the '..' at a process' root 
-                                          and move on to the next component */
-               }
-               
-               if (rip->i_num == ROOT_INODE && !rip->i_sp->s_is_root) {
-                       /* Climbing up to parent FS */
-
-                       put_inode(rip);
-                       *offsetp += cp - user_path; 
-                       return(ELEAVEMOUNT);
-               }
-       }
-
-       /* Only check for a mount point if we are not coming from one. */
-       if (!leaving_mount && rip->i_mountpoint) {
-               /* Going to enter a child FS */
-
-               *res_inop = rip;
-               *offsetp += cp - user_path;
-               return(EENTERMOUNT);
-       }
-
-       /* There is more path.  Keep parsing.
-        * If we're leaving a mountpoint, skip directory permission checks.
-        */
-       dir_ip = rip;
-       rip = advance(dir_ip, leaving_mount ? dot2 : component, CHK_PERM);
-       if(err_code == ELEAVEMOUNT || err_code == EENTERMOUNT)
-               err_code = OK;
-
-       if (err_code != OK) {
-               put_inode(dir_ip);
-               return(err_code);
-       }
-       
-       leaving_mount = 0;
-
-       /* The call to advance() succeeded.  Fetch next component. */
-       if (S_ISLNK(rip->i_mode)) {
-
-               if (next_cp[0] == '\0' && (flags & PATH_RET_SYMLINK)) {
-                       put_inode(dir_ip);
-                       *res_inop = rip;
-                       *offsetp += next_cp - user_path;
-                       return(OK);
-               }
-
-               /* Extract path name from the symlink file */
-               r = ltraverse(rip, next_cp);
-               next_cp = user_path;
-               *offsetp = 0;
-
-               /* Symloop limit reached? */
-               if (++(*symlinkp) > _POSIX_SYMLOOP_MAX)
-                       r = ELOOP;
-
-               if (r != OK) {
-                       put_inode(dir_ip);
-                       put_inode(rip);
-                       return(r);
-               }
-
-               if (next_cp[0] == '/') {
-                        put_inode(dir_ip);
-                        put_inode(rip);
-                        return(ESYMLINK);
-               }
-       
-               put_inode(rip);
-               dup_inode(dir_ip);
-               rip = dir_ip;
-       } 
-
-       put_inode(dir_ip);
-       cp = next_cp; /* Process subsequent component in next round */
-  }
-}
-
-
-/*===========================================================================*
- *                             ltraverse                                    *
- *===========================================================================*/
-static int ltraverse(rip, suffix)
-register struct inode *rip;    /* symbolic link */
-char *suffix;                  /* current remaining path. Has to point in the
-                                * user_path buffer
-                                */
-{
-/* Traverse a symbolic link. Copy the link text from the inode and insert
- * the text into the path. Return error code or report success. Base 
- * directory has to be determined according to the first character of the
- * new pathname.
- */
-  
-  size_t llen;         /* length of link */
-  size_t slen;         /* length of suffix */
-  struct buf *bp;      /* buffer containing link text */
-  char *sp;            /* start of link text */
-
-  if(!(bp = get_block_map(rip, 0)))
-       return(EIO);
-  llen = (size_t) rip->i_size;
-  sp = b_data(bp);
-  slen = strlen(suffix);
-
-  /* The path we're parsing looks like this:
-   * /already/processed/path/<link> or
-   * /already/processed/path/<link>/not/yet/processed/path
-   * After expanding the <link>, the path will look like
-   * <expandedlink> or
-   * <expandedlink>/not/yet/processed
-   * In both cases user_path must have enough room to hold <expandedlink>.
-   * However, in the latter case we have to move /not/yet/processed to 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.
-   */ 
-
-  if (slen > 0) { /* Do we have path after the link? */
-       /* For simplicity we require that suffix starts with a slash */
-       if (suffix[0] != '/') {
-               panic("ltraverse: suffix does not start with a slash");
-       }
-
-       /* To be able to expand the <link>, we have to move the 'suffix'
-        * to the right place.
-        */
-       if (slen + llen + 1 > sizeof(user_path))
-               return(ENAMETOOLONG);/* <expandedlink>+suffix+\0 does not fit*/
-       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 */
-               
-       /* Set terminating nul */
-       user_path[llen]= '\0';
-  }
-
-  /* Everything is set, now copy the expanded link to user_path */
-  memmove(user_path, sp, llen);
-
-  put_block(bp, DIRECTORY_BLOCK);
-  return(OK);
+  return OK;
 }
 
 
 /*===========================================================================*
  *                             advance                                      *
  *===========================================================================*/
-struct inode *advance(dirp, string, chk_perm)
+struct inode *advance(dirp, string)
 struct inode *dirp;            /* inode for directory to be searched */
-char string[MFS_NAME_MAX];             /* component name to look for */
-int chk_perm;                  /* check permissions when string is looked up*/
+const char *string;            /* component name to look for */
 {
 /* Given a directory and a component of a path, look up the component in
  * the directory, find the inode, open it, and return a pointer to its inode
@@ -358,114 +56,44 @@ int chk_perm;                     /* check permissions when string is looked up*/
   ino_t numb;
   struct inode *rip;
 
+  assert(dirp != NULL);
+
   /* If 'string' is empty, return an error. */
   if (string[0] == '\0') {
        err_code = ENOENT;
        return(NULL);
   }
 
-  /* Check for NULL. */
-  if (dirp == NULL) return(NULL);
+  /* If dir has been removed return ENOENT. */
+  if (dirp->i_nlinks == NO_LINK) {
+       err_code = ENOENT;
+       return(NULL);
+  }
 
   /* If 'string' is not present in the directory, signal error. */
-  if ( (err_code = search_dir(dirp, string, &numb, LOOK_UP, chk_perm)) != OK) {
+  if ( (err_code = search_dir(dirp, string, &numb, LOOK_UP)) != OK) {
        return(NULL);
   }
 
   /* The component has been found in the directory.  Get inode. */
   if ( (rip = get_inode(dirp->i_dev, (int) numb)) == NULL)  {
+       assert(err_code != OK);
        return(NULL);
   }
 
-  /* The following test is for "mountpoint/.." where mountpoint is a
-   * mountpoint. ".." will refer to the root of the mounted filesystem,
-   * but has to become a reference to the parent of the 'mountpoint'
-   * directory.
-   *
-   * This case is recognized by the looked up name pointing to a
-   * root inode, and the directory in which it is held being a
-   * root inode, _and_ the name[1] being '.'. (This is a test for '..'
-   * and excludes '.'.)
-   */
-  if (rip->i_num == ROOT_INODE) {
-         if (dirp->i_num == ROOT_INODE) {
-                 if (string[1] == '.') {
-                         if (!rip->i_sp->s_is_root) {
-                                 /* Climbing up mountpoint */
-                                 err_code = ELEAVEMOUNT;
-                         }
-                 }
-         }
-  }
-
-  /* See if the inode is mounted on.  If so, switch to root directory of the
-   * 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->i_mountpoint) {
-         /* Mountpoint encountered, report it */
-         err_code = EENTERMOUNT;
-  }
-
+  assert(err_code == OK);
   return(rip);
 }
 
 
-/*===========================================================================*
- *                             get_name                                     *
- *===========================================================================*/
-static char *get_name(path_name, string)
-char *path_name;               /* path name to parse */
-char string[MFS_NAME_MAX+1];   /* component extracted from 'old_name' */
-{
-/* Given a pointer to a path name in fs space, 'path_name', copy the first
- * component to 'string' (truncated if necessary, always nul terminated).
- * A pointer to the string after the first component of the name as yet
- * unparsed is returned.  Roughly speaking,
- * 'get_name' = 'path_name' - 'string'.
- *
- * This routine follows the standard convention that /usr/ast, /usr//ast,
- * //usr///ast and /usr/ast/ are all equivalent.
- */
-  size_t len;
-  char *cp, *ep;
-
-  cp = path_name;
-
-  /* Skip leading slashes */
-  while (cp[0] == '/') cp++;
-
-  /* Find the end of the first component */
-  ep = cp;
-  while(ep[0] != '\0' && ep[0] != '/')
-       ep++;
-
-  len = (size_t) (ep - cp);
-
-  /* Truncate the amount to be copied if it exceeds MFS_NAME_MAX */
-  if (len > MFS_NAME_MAX) len = MFS_NAME_MAX;
-
-  /* Special case of the string at cp is empty */
-  if (len == 0) 
-       strlcpy(string, ".", MFS_NAME_MAX + 1);  /* Return "." */
-  else {
-       memcpy(string, cp, len);
-       string[len]= '\0';
-  }
-
-  return(ep);
-}
-
-
 /*===========================================================================*
  *                             search_dir                                   *
  *===========================================================================*/
-int search_dir(ldir_ptr, string, numb, flag, check_permissions)
+int search_dir(ldir_ptr, string, numb, flag)
 register struct inode *ldir_ptr; /* ptr to inode for dir to search */
-char string[MFS_NAME_MAX];              /* component to search for */
+const char *string;             /* component to search for */
 ino_t *numb;                    /* pointer to inode number */
 int flag;                       /* LOOK_UP, ENTER, DELETE or IS_EMPTY */
-int check_permissions;          /* check permissions when flag is !IS_EMPTY */
 {
 /* This function searches the directory whose inode is pointed to by 'ldip':
  * if (flag == ENTER)  enter 'string' in the directory with inode # '*numb';
@@ -473,13 +101,12 @@ int check_permissions;             /* check permissions when flag is !IS_EMPTY */
  * if (flag == LOOK_UP) search for 'string' and return inode # in 'numb';
  * if (flag == IS_EMPTY) return OK if only . and .. in dir else ENOTEMPTY;
  *
- *    if 'string' is dot1 or dot2, no access permissions are checked.
+ * This function, and this function alone, implements name truncation,
+ * by simply considering only the first MFS_NAME_MAX bytes from 'string'.
  */
-
   register struct direct *dp = NULL;
   register struct buf *bp = NULL;
   int i, r, e_hit, t, match;
-  mode_t bits;
   off_t pos;
   unsigned new_slots, old_slots;
   struct super_block *sp;
@@ -493,20 +120,6 @@ int check_permissions;              /* check permissions when flag is !IS_EMPTY */
   if((flag == DELETE || flag == ENTER) && ldir_ptr->i_sp->s_rd_only)
        return EROFS;
   
-  r = OK;
-
-  if (flag != IS_EMPTY) {
-       bits = (flag == LOOK_UP ? X_BIT : W_BIT | X_BIT);
-
-       if (string == dot1 || string == dot2) {
-               if (flag != LOOK_UP) r = read_only(ldir_ptr);
-                                    /* only a writable device is required. */
-        } else if(check_permissions) {
-               r = forbidden(ldir_ptr, bits); /* check access permissions */
-       }
-  }
-  if (r != OK) return(r);
-  
   /* Step through the directory one block at a time. */
   old_slots = (unsigned) (ldir_ptr->i_size/DIR_ENTRY_SIZE);
   new_slots = 0;
@@ -543,7 +156,8 @@ int check_permissions;               /* check permissions when flag is !IS_EMPTY */
                        if (flag == IS_EMPTY) {
                                /* If this test succeeds, dir is not empty. */
                                if (strcmp(dp->mfs_d_name, "." ) != 0 &&
-                                   strcmp(dp->mfs_d_name, "..") != 0) match = 1;
+                                   strcmp(dp->mfs_d_name, "..") != 0)
+                                       match = 1;
                        } else {
                                if (strncmp(dp->mfs_d_name, string,
                                        sizeof(dp->mfs_d_name)) == 0){
@@ -560,7 +174,7 @@ int check_permissions;               /* check permissions when flag is !IS_EMPTY */
                                /* Save d_ino for recovery. */
                                t = MFS_NAME_MAX - sizeof(ino_t);
                                *((ino_t *) &dp->mfs_d_name[t]) = dp->mfs_d_ino;
-                               dp->mfs_d_ino = NO_ENTRY;       /* erase entry */
+                               dp->mfs_d_ino = NO_ENTRY; /* erase entry */
                                MARKDIRTY(bp);
                                ldir_ptr->i_update |= CTIME | MTIME;
                                IN_MARKDIRTY(ldir_ptr);
diff --git a/minix/fs/mfs/pipe.c b/minix/fs/mfs/pipe.c
deleted file mode 100644 (file)
index 8b13789..0000000
+++ /dev/null
@@ -1 +0,0 @@
-
index ee069e26db89ca10aed5aed896bfd99bdc034a0e..5deb7637bcafff75ec20c441562381721ceffdff 100644 (file)
@@ -1,25 +1,18 @@
 #include "fs.h"
 #include "inode.h"
 #include "super.h"
-#include <minix/vfsif.h>
-
-static int in_group(gid_t grp);
 
 
 /*===========================================================================*
  *                             fs_chmod                                     *
  *===========================================================================*/
-int fs_chmod()
+int fs_chmod(ino_t ino_nr, mode_t *mode)
 {
 /* Perform the chmod(name, mode) system call. */
-
   register struct inode *rip;
-  mode_t mode;
 
-  mode = fs_m_in.m_vfs_fs_chmod.mode;
-  
   /* Temporarily open the file. */
-  if( (rip = get_inode(fs_dev, fs_m_in.m_vfs_fs_chmod.inode)) == NULL)
+  if( (rip = get_inode(fs_dev, ino_nr)) == NULL)
          return(EINVAL);
  
   if(rip->i_sp->s_rd_only) {
@@ -28,12 +21,12 @@ int fs_chmod()
   }
 
   /* Now make the change. Clear setgid bit if file is not in caller's grp */
-  rip->i_mode = (rip->i_mode & ~ALL_MODES) | (mode & ALL_MODES);
+  rip->i_mode = (rip->i_mode & ~ALL_MODES) | (*mode & ALL_MODES);
   rip->i_update |= CTIME;
   IN_MARKDIRTY(rip);
 
   /* Return full new mode to caller. */
-  fs_m_out.m_fs_vfs_chmod.mode = rip->i_mode;
+  *mode = rip->i_mode;
 
   put_inode(rip);
   return(OK);
@@ -43,116 +36,23 @@ int fs_chmod()
 /*===========================================================================*
  *                             fs_chown                                     *
  *===========================================================================*/
-int fs_chown()
+int fs_chown(ino_t ino_nr, uid_t uid, gid_t gid, mode_t *mode)
 {
   register struct inode *rip;
-  register int r;
 
   /* Temporarily open the file. */
-  if( (rip = get_inode(fs_dev, fs_m_in.m_vfs_fs_chown.inode)) == NULL)
+  if( (rip = get_inode(fs_dev, ino_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.m_vfs_fs_chown.uid;
-         rip->i_gid = fs_m_in.m_vfs_fs_chown.gid;
-         rip->i_mode &= ~(I_SET_UID_BIT | I_SET_GID_BIT);
-         rip->i_update |= CTIME;
-          IN_MARKDIRTY(rip);
-  }
+  rip->i_uid = uid;
+  rip->i_gid = gid;
+  rip->i_mode &= ~(I_SET_UID_BIT | I_SET_GID_BIT);
+  rip->i_update |= CTIME;
+  IN_MARKDIRTY(rip);
 
   /* Update caller on current mode, as it may have changed. */
-  fs_m_out.m_fs_vfs_chown.mode = rip->i_mode;
+  *mode = rip->i_mode;
   put_inode(rip);
   
-  return(r);
-}
-
-
-/*===========================================================================*
- *                             forbidden                                    *
- *===========================================================================*/
-int forbidden(struct inode *rip, mode_t access_desired)
-{
-/* Given a pointer to an inode, 'rip', and the access desired, determine
- * if the access is allowed, and if not why not.  The routine looks up the
- * caller's uid in the 'fproc' table.  If access is allowed, OK is returned
- * if it is forbidden, EACCES is returned.
- */
-
-  register struct inode *old_rip = rip;
-  mode_t bits, perm_bits;
-  int r, shift;
-
-  /* Isolate the relevant rwx bits from the mode. */
-  bits = rip->i_mode;
-  if (caller_uid == SU_UID) {
-       /* Grant read and write permission.  Grant search permission for
-        * directories.  Grant execute permission (for non-directories) if
-        * and only if one of the 'X' bits is set.
-        */
-       if ( (bits & I_TYPE) == I_DIRECTORY ||
-            bits & ((X_BIT << 6) | (X_BIT << 3) | X_BIT))
-               perm_bits = R_BIT | W_BIT | X_BIT;
-       else
-               perm_bits = R_BIT | W_BIT;
-  } else {
-       if (caller_uid == rip->i_uid) shift = 6;        /* owner */
-       else if (caller_gid == rip->i_gid) shift = 3;   /* group */
-       else if (in_group(rip->i_gid) == OK) shift = 3; /* other groups */
-       else shift = 0;                                 /* other */
-       perm_bits = (bits >> shift) & (R_BIT | W_BIT | X_BIT);
-  }
-
-  /* If access desired is not a subset of what is allowed, it is refused. */
-  r = OK;
-  if ((perm_bits | access_desired) != perm_bits) r = EACCES;
-
-  /* Check to see if someone is trying to write on a file system that is
-   * mounted read-only.
-   */
-  if (r == OK)
-       if (access_desired & W_BIT)
-               r = read_only(rip);
-
-  if (rip != old_rip) put_inode(rip);
-
-  return(r);
-}
-
-
-/*===========================================================================*
- *                             in_group                                     *
- *===========================================================================*/
-static int in_group(gid_t grp)
-{
-  int i;
-
-  if (credentials.vu_ngroups > NGROUPS_MAX)
-       return(EINVAL);
-
-  for (i = 0; i < credentials.vu_ngroups; i++)
-       if (credentials.vu_sgroups[i] == grp)
-               return(OK);
-
-  return(EINVAL);
-}
-
-
-/*===========================================================================*
- *                             read_only                                    *
- *===========================================================================*/
-int read_only(ip)
-struct inode *ip;              /* ptr to inode whose file sys is to be cked */
-{
-/* Check to see if the file system on which the inode 'ip' resides is mounted
- * read only.  If so, return EROFS, else return OK.
- */
-
-  register struct super_block *sp;
-
-  sp = ip->i_sp;
-  return(sp->s_rd_only ? EROFS : OK);
+  return(OK);
 }
-
index 3b16c308856ae8eafe4f8d486a816a07af9c4797..b196638173a6e348c1c90ce6ff3abdf498eb4bf7 100644 (file)
@@ -13,16 +13,15 @@ struct filp;
 struct inode;
 struct super_block;
 
-
 /* cache.c */
 zone_t alloc_zone(dev_t dev, zone_t z);
 void free_zone(dev_t dev, zone_t numb);
 
 /* inode.c */
-struct inode *alloc_inode(dev_t dev, mode_t bits);
+struct inode *alloc_inode(dev_t dev, mode_t bits, uid_t uid, gid_t gid);
 void dup_inode(struct inode *ip);
 struct inode *find_inode(dev_t dev, ino_t numb);
-int fs_putnode(void);
+int fs_putnode(ino_t ino_nr, unsigned int count);
 void init_inode_cache(void);
 struct inode *get_inode(dev_t dev, ino_t numb);
 void put_inode(struct inode *rip);
@@ -30,57 +29,56 @@ void update_times(struct inode *rip);
 void rw_inode(struct inode *rip, int rw_flag);
 
 /* link.c */
-int fs_ftrunc(void);
-int fs_link(void);
-int fs_rdlink(void);
-int fs_rename(void);
-int fs_unlink(void);
+int fs_trunc(ino_t ino_nr, off_t start, off_t end);
+int fs_link(ino_t dir_nr, char *name, ino_t ino_nr);
+ssize_t fs_rdlink(ino_t ino_nr, struct fsdriver_data *data, size_t bytes);
+int fs_rename(ino_t old_dir_nr, char *old_name, ino_t new_dir_nr,
+       char *new_name);
+int fs_unlink(ino_t dir_nr, char *name, int call);
 int truncate_inode(struct inode *rip, off_t len);
 
 /* misc.c */
-int fs_flush(void);
-int fs_sync(void);
-int fs_new_driver(void);
-int fs_bpeek(void);
+void fs_sync(void);
 
 /* mount.c */
-int fs_mountpoint(void);
-int fs_readsuper(void);
-int fs_unmount(void);
+int fs_mount(dev_t dev, unsigned int flags, struct fsdriver_node *root_node,
+       unsigned int *res_flags);
+void fs_unmount(void);
+int fs_mountpt(ino_t ino_nr);
 
 /* open.c */
-int fs_create(void);
-int fs_inhibread(void);
-int fs_mkdir(void);
-int fs_mknod(void);
-int fs_slink(void);
+int fs_create(ino_t dir_nr, char *name, mode_t mode, uid_t uid, gid_t gid,
+       struct fsdriver_node *node);
+int fs_mkdir(ino_t dir_nr, char *name, mode_t mode, uid_t uid, gid_t gid);
+int fs_mknod(ino_t dir_nr, char *name, mode_t mode, uid_t uid, gid_t gid,
+       dev_t dev);
+int fs_slink(ino_t dir_nr, char *name, uid_t uid, gid_t gid,
+       struct fsdriver_data *data, size_t bytes);
+void fs_seek(ino_t ino_nr);
 
 /* path.c */
-int fs_lookup(void);
-struct inode *advance(struct inode *dirp, char string[MFS_NAME_MAX], int
-       chk_perm);
-int search_dir(struct inode *ldir_ptr, char string [MFS_NAME_MAX], ino_t
-       *numb, int flag, int check_permissions);
-
+int fs_lookup(ino_t dir_nr, char *name, struct fsdriver_node *node,
+       int *is_mountpt);
+struct inode *advance(struct inode *dirp, const char *string);
+int search_dir(struct inode *ldir_ptr, const char *string, ino_t *numb,
+       int flag);
 
 /* protect.c */
-int fs_chmod(void);
-int fs_chown(void);
-int fs_getdents(void);
-int forbidden(struct inode *rip, mode_t access_desired);
-int read_only(struct inode *ip);
+int fs_chmod(ino_t ino, mode_t *mode);
+int fs_chown(ino_t ino, uid_t uid, gid_t gid, mode_t *mode);
 
 /* read.c */
-int fs_breadwrite(void);
-int fs_readwrite(void);
-void read_ahead(void);
+ssize_t fs_readwrite(ino_t ino_nr, struct fsdriver_data *data, size_t bytes,
+       off_t pos, int call);
 block_t read_map(struct inode *rip, off_t pos, int opportunistic);
 struct buf *get_block_map(register struct inode *rip, u64_t position);
 zone_t rd_indir(struct buf *bp, int index);
+ssize_t fs_getdents(ino_t ino_nr, struct fsdriver_data *data, size_t bytes,
+       off_t *posp);
 
 /* stadir.c */
-int fs_stat(void);
-int fs_statvfs(void);
+int fs_stat(ino_t ino_nr, struct stat *statbuf);
+int fs_statvfs(struct statvfs *st);
 
 /* super.c */
 bit_t alloc_bit(struct super_block *sp, int map, bit_t origin);
@@ -95,17 +93,11 @@ u32_t get_used_blocks(struct super_block *sp);
 bit_t count_free_bits(struct super_block *sp, int map);
 
 /* time.c */
-int fs_utime(void);
+int fs_utime(ino_t ino_t, struct timespec *atime, struct timespec *mtime);
 
 /* utility.c */
 unsigned conv2(int norm, int w);
 long conv4(int norm, long x);
-void mfs_nul_f(char *file, int line, char *str, unsigned int len,
-       unsigned int maxlen);
-int min(unsigned int l, unsigned int r);
-int no_sys(void);
-void sanitycheck(char *file, int line);
-#define SANITYCHECK sanitycheck(__FILE__, __LINE__)
 
 /* write.c */
 void clear_zone(struct inode *rip, off_t pos, int flag);
index 694e3caf7bf230872e1c4770d30200e08d8f55b0..86fc3a8c8992bbc861de23471bafc9e7c211cc4e 100644 (file)
@@ -2,13 +2,9 @@
 #include <stddef.h>
 #include <string.h>
 #include <stdlib.h>
-#include <minix/com.h>
-#include <minix/u64.h>
 #include "buf.h"
 #include "inode.h"
 #include "super.h"
-#include <minix/vfsif.h>
-#include <minix/minlib.h>
 #include <sys/param.h>
 #include <assert.h>
 
 static struct buf *rahead(struct inode *rip, block_t baseblock, u64_t
        position, unsigned bytes_ahead);
 static int rw_chunk(struct inode *rip, u64_t position, unsigned off,
-       size_t chunk, unsigned left, int rw_flag, cp_grant_id_t gid, unsigned
-       buf_off, unsigned int block_size, int *completed);
+       size_t chunk, unsigned left, int call, struct fsdriver_data *data,
+       unsigned buf_off, unsigned int block_size, int *completed);
 
 
 /*===========================================================================*
  *                             fs_readwrite                                 *
  *===========================================================================*/
-int fs_readwrite(void)
+ssize_t fs_readwrite(ino_t ino_nr, struct fsdriver_data *data, size_t nrbytes,
+       off_t position, int call)
 {
-  int r, rw_flag, block_spec;
+  int r;
   int regular;
-  cp_grant_id_t gid;
-  off_t position, f_size, bytes_left;
-  unsigned int off, cum_io, block_size, chunk;
+  off_t f_size, bytes_left;
+  size_t off, cum_io, block_size, chunk;
   mode_t mode_word;
   int completed;
   struct inode *rip;
-  size_t nrbytes;
   
   r = OK;
   
   /* Find the inode referred */
-  if ((rip = find_inode(fs_dev, fs_m_in.m_vfs_fs_readwrite.inode)) == NULL)
+  if ((rip = find_inode(fs_dev, ino_nr)) == NULL)
        return(EINVAL);
 
   mode_word = rip->i_mode & I_TYPE;
-  regular = (mode_word == I_REGULAR || mode_word == I_NAMED_PIPE);
-  block_spec = (mode_word == I_BLOCK_SPECIAL ? 1 : 0);
+  regular = (mode_word == I_REGULAR);
   
   /* Determine blocksize */
-  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;
-  }
-
-  /* Get the values from the request message */ 
-  switch(fs_m_in.m_type) {
-       case REQ_READ: rw_flag = READING; break;
-       case REQ_WRITE: rw_flag = WRITING; break;
-       case REQ_PEEK: rw_flag = PEEKING; break;
-       default: panic("odd request");
-  }
-  gid = fs_m_in.m_vfs_fs_readwrite.grant;
-  position = fs_m_in.m_vfs_fs_readwrite.seek_pos;
-  nrbytes = fs_m_in.m_vfs_fs_readwrite.nbytes;
+  block_size = rip->i_sp->s_block_size;
+  f_size = rip->i_size;
 
   lmfs_reset_rdwt_err();
 
   /* If this is file i/o, check we can write */
-  if (rw_flag == WRITING && !block_spec) {
+  if (call == FSC_WRITE) {
          if(rip->i_sp->s_rd_only) 
                  return EROFS;
 
@@ -83,18 +61,15 @@ int fs_readwrite(void)
          if(position > f_size) clear_zone(rip, f_size, 0);
   }
 
-  /* If this is block i/o, check we can write */
-  if(block_spec && rw_flag == WRITING &&
-       (dev_t) rip->i_zone[0] == superblock.s_dev && superblock.s_rd_only)
-               return EROFS;
-             
   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);
+         chunk = block_size - off;
+         if (chunk > nrbytes)
+               chunk = nrbytes;
 
-         if (rw_flag == READING) {
+         if (call == FSC_READ) {
                  bytes_left = f_size - position;
                  if (position >= f_size) break;        /* we are beyond EOF */
                  if (chunk > (unsigned int) bytes_left) chunk = bytes_left;
@@ -102,7 +77,7 @@ int fs_readwrite(void)
          
          /* Read or write 'chunk' bytes. */
          r = rw_chunk(rip, ((u64_t)((unsigned long)position)), off, chunk,
-                      nrbytes, rw_flag, gid, cum_io, block_size, &completed);
+               nrbytes, call, data, cum_io, block_size, &completed);
 
          if (r != OK) break;   /* EOF reached */
          if (lmfs_rdwt_err() < 0) break;
@@ -113,12 +88,8 @@ int fs_readwrite(void)
          position += (off_t) chunk;    /* position within the file */
   }
 
-  fs_m_out.m_fs_vfs_readwrite.seek_pos = position; /* It might change later and
-                                                   the VFS has to know this
-                                                   value */
-  
   /* On write, update file size and access time. */
-  if (rw_flag == WRITING) {
+  if (call == FSC_WRITE) {
          if (regular || mode_word == I_DIRECTORY) {
                  if (position > f_size) rip->i_size = position;
          }
@@ -126,104 +97,38 @@ int fs_readwrite(void)
 
   rip->i_seek = NO_SEEK;
 
-  if (lmfs_rdwt_err() != OK) r = lmfs_rdwt_err();      /* check for disk error */
+  if (lmfs_rdwt_err() != OK) r = lmfs_rdwt_err(); /* check for disk error */
   if (lmfs_rdwt_err() == END_OF_FILE) r = OK;
 
+  if (r != OK)
+       return r;
+
   /* even on a ROFS, writing to a device node on it is fine, 
    * just don't update the inode stats for it. And dito for reading.
    */
-  if (r == OK && !rip->i_sp->s_rd_only) {
-         if (rw_flag == READING) rip->i_update |= ATIME;
-         if (rw_flag == WRITING) rip->i_update |= CTIME | MTIME;
+  if (!rip->i_sp->s_rd_only) {
+         if (call == FSC_READ) rip->i_update |= ATIME;
+         if (call == FSC_WRITE) rip->i_update |= CTIME | MTIME;
          IN_MARKDIRTY(rip);            /* inode is thus now dirty */
   }
   
-  fs_m_out.m_fs_vfs_readwrite.nbytes = cum_io;
-  
-  return(r);
-}
-
-
-/*===========================================================================*
- *                             fs_breadwrite                                *
- *===========================================================================*/
-int fs_breadwrite(void)
-{
-  int r, rw_flag, completed;
-  cp_grant_id_t gid;
-  u64_t position;
-  unsigned int off, cum_io, chunk, block_size;
-  size_t nrbytes;
-  dev_t target_dev;
-
-  /* Pseudo inode for rw_chunk */
-  struct inode rip;
-  
-  r = OK;
-
-  target_dev = fs_m_in.m_vfs_fs_breadwrite.device;
-  
-  /* Get the values from the request message */ 
-  rw_flag = (fs_m_in.m_type == REQ_BREAD ? READING : WRITING);
-  gid = fs_m_in.m_vfs_fs_breadwrite.grant;
-  position = fs_m_in.m_vfs_fs_breadwrite.seek_pos;
-  nrbytes = fs_m_in.m_vfs_fs_breadwrite.nbytes;
-  
-  block_size = get_block_size(target_dev);
-
-  /* Don't block-write to a RO-mounted filesystem. */
-  if(superblock.s_dev == target_dev && superblock.s_rd_only)
-       return EROFS;
-
-  rip.i_zone[0] = (zone_t) target_dev;
-  rip.i_mode = I_BLOCK_SPECIAL;
-  rip.i_size = 0;
-
-  lmfs_reset_rdwt_err();
-  
-  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);
-
-         /* Read or write 'chunk' bytes. */
-         r = rw_chunk(&rip, position, off, chunk, nrbytes, rw_flag, gid,
-                      cum_io, block_size, &completed);
-
-         if (r != OK) break;   /* EOF reached */
-         if (lmfs_rdwt_err() < 0) break;
-
-         /* Update counters and pointers. */
-         nrbytes -= chunk;     /* bytes yet to be read */
-         cum_io += chunk;      /* bytes read so far */
-         position += chunk;    /* position within the file */
-  }
-  
-  fs_m_out.m_fs_vfs_breadwrite.seek_pos = position;
-  
-  if (lmfs_rdwt_err() != OK) r = lmfs_rdwt_err();      /* check for disk error */
-  if (lmfs_rdwt_err() == END_OF_FILE) r = OK;
-
-  fs_m_out.m_fs_vfs_breadwrite.nbytes = cum_io;
-  
-  return(r);
+  return cum_io;
 }
 
 
 /*===========================================================================*
  *                             rw_chunk                                     *
  *===========================================================================*/
-static int rw_chunk(rip, position, off, chunk, left, rw_flag, gid,
buf_off, block_size, completed)
+static int rw_chunk(rip, position, off, chunk, left, call, data, buf_off,
      block_size, completed)
 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 */
-unsigned int chunk;            /* number of bytes to read or write */
+size_t chunk;                  /* number of bytes to read or write */
 unsigned left;                 /* max number of bytes wanted after position */
-int rw_flag;                   /* READING, WRITING or PEEKING */
-cp_grant_id_t gid;             /* grant */
-unsigned buf_off;              /* offset in grant */
+int call;                      /* FSC_READ, FSC_WRITE, or FSC_PEEK */
+struct fsdriver_data *data;    /* structure for (remote) user buffer */
+unsigned buf_off;              /* offset in user buffer */
 unsigned int block_size;       /* block size of FS operating on */
 int *completed;                        /* number of bytes copied */
 {
@@ -231,41 +136,27 @@ int *completed;                   /* number of bytes copied */
 
   register struct buf *bp = NULL;
   register int r = OK;
-  int n, block_spec;
+  int n;
   block_t b;
   dev_t dev;
   ino_t ino = VMC_NO_INODE;
   u64_t ino_off = rounddown(position, block_size);
 
-  /* rw_flag:
-   *   READING: read from FS, copy to user
-   *   WRITING: copy from user, write to FS
-   *   PEEKING: try to get all the blocks into the cache, no copying
-   */
-
   *completed = 0;
 
-  block_spec = (rip->i_mode & I_TYPE) == I_BLOCK_SPECIAL;
+  if (ex64hi(position) != 0)
+       panic("rw_chunk: position too high");
+  b = read_map(rip, (off_t) ex64lo(position), 0);
+  dev = rip->i_dev;
+  ino = rip->i_num;
+  assert(ino != VMC_NO_INODE);
 
-  if (block_spec) {
-       b = (unsigned long)(position / block_size);
-       dev = (dev_t) rip->i_zone[0];
-  } else {
-       if (ex64hi(position) != 0)
-               panic("rw_chunk: position too high");
-       b = read_map(rip, (off_t) ex64lo(position), 0);
-       dev = rip->i_dev;
-       ino = rip->i_num;
-       assert(ino != VMC_NO_INODE);
-  }
-
-  if (!block_spec && b == NO_BLOCK) {
-       if (rw_flag == READING) {
+  if (b == NO_BLOCK) {
+       if (call == FSC_READ) {
                /* Reading from a nonexistent block.  Must read as all zeros.*/
-               r = sys_safememset(VFS_PROC_NR, gid, (vir_bytes) buf_off,
-                          0, (size_t) chunk);
+               r = fsdriver_zero(data, buf_off, chunk);
                if(r != OK) {
-                       printf("MFS: sys_safememset failed\n");
+                       printf("MFS: fsdriver_zero failed\n");
                }
                return r;
        } else {
@@ -275,7 +166,7 @@ int *completed;                     /* number of bytes copied */
                if ((bp = new_block(rip, (off_t) ex64lo(position))) == NULL)
                        return(err_code);
        }
-  } else if (rw_flag == READING || rw_flag == PEEKING) {
+  } else if (call != FSC_WRITE) {
        /* Read and read ahead if convenient. */
        bp = rahead(rip, b, position, left);
   } else {
@@ -284,34 +175,27 @@ 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 && (off_t) ex64lo(position) >= rip->i_size) 
+       if (off == 0 && (off_t) ex64lo(position) >= rip->i_size)
                n = NO_READ;
-       if(block_spec) {
-               assert(ino == VMC_NO_INODE);
-               bp = get_block(dev, b, n);
-       } else {
-               assert(ino != VMC_NO_INODE);
-               assert(!(ino_off % block_size));
-               bp = lmfs_get_block_ino(dev, b, n, ino, ino_off);
-       }
+       assert(ino != VMC_NO_INODE);
+       assert(!(ino_off % block_size));
+       bp = lmfs_get_block_ino(dev, b, n, ino, ino_off);
   }
 
   /* In all cases, bp now points to a valid buffer. */
   assert(bp != NULL);
   
-  if (rw_flag == WRITING && chunk != block_size && !block_spec &&
+  if (call == FSC_WRITE && chunk != block_size &&
       (off_t) ex64lo(position) >= rip->i_size && off == 0) {
        zero_block(bp);
   }
 
-  if (rw_flag == READING) {
+  if (call == FSC_READ) {
        /* Copy a chunk from the block buffer to user space. */
-       r = sys_safecopyto(VFS_PROC_NR, gid, (vir_bytes) buf_off,
-                          (vir_bytes) (b_data(bp)+off), (size_t) chunk);
-  } else if(rw_flag == WRITING) {
+       r = fsdriver_copyout(data, buf_off, b_data(bp)+off, chunk);
+  } else if (call == FSC_WRITE) {
        /* Copy a chunk from user space to the block buffer. */
-       r = sys_safecopyfrom(VFS_PROC_NR, gid, (vir_bytes) buf_off,
-                            (vir_bytes) (b_data(bp)+off), (size_t) chunk);
+       r = fsdriver_copyin(data, buf_off, b_data(bp)+off, chunk);
        MARKDIRTY(bp);
   }
   
@@ -461,7 +345,7 @@ unsigned bytes_ahead;               /* bytes beyond position for immediate use */
 /* Minimum number of blocks to prefetch. */
   int nr_bufs = lmfs_nr_bufs();
 # define BLOCKS_MINIMUM                (nr_bufs < 50 ? 18 : 32)
-  int block_spec, scale, read_q_size;
+  int scale, read_q_size;
   unsigned int blocks_ahead, fragment, block_size;
   block_t block, blocks_left;
   off_t ind1_pos;
@@ -482,12 +366,7 @@ unsigned bytes_ahead;              /* bytes beyond position for immediate use */
        readqsize = nr_bufs;
   }
 
-  block_spec = (rip->i_mode & I_TYPE) == I_BLOCK_SPECIAL;
-  if (block_spec) 
-       dev = (dev_t) rip->i_zone[0];
-  else 
-       dev = rip->i_dev;
-
+  dev = rip->i_dev;
   assert(dev != NO_DEV);
   
   block_size = get_block_size(dev);
@@ -500,11 +379,7 @@ unsigned bytes_ahead;              /* bytes beyond position for immediate use */
   bytes_ahead += fragment;
   blocks_ahead = (bytes_ahead + block_size - 1) / block_size;
 
-  if(block_spec)
-         bp = get_block(dev, block, PREFETCH);
-  else
-         bp = lmfs_get_block_ino(dev, block, PREFETCH, rip->i_num, position);
-
+  bp = lmfs_get_block_ino(dev, block, PREFETCH, rip->i_num, position);
   assert(bp != NULL);
   assert(bp->lmfs_count > 0);
   if (lmfs_dev(bp) != NO_DEV) return(bp);
@@ -529,22 +404,15 @@ unsigned bytes_ahead;             /* bytes beyond position for immediate use */
    * indirect blocks (but don't call read_map!).
    */
 
-  if (block_spec && rip->i_size == 0) {
-       blocks_left = (block_t) NR_IOREQS;
-  } else {
-       blocks_left = (block_t) (rip->i_size-ex64lo(position)+(block_size-1)) /
+  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 ((off_t) ex64lo(position) <= ind1_pos &&
-                    rip->i_size > ind1_pos) {
-                       blocks_ahead++;
-                       blocks_left++;
-               }
-       }
+  /* Go for the first indirect block if we are in its neighborhood. */
+  scale = rip->i_sp->s_log_zone_size;
+  ind1_pos = (off_t) rip->i_ndzones * (block_size << scale);
+  if ((off_t) ex64lo(position) <= ind1_pos && rip->i_size > ind1_pos) {
+       blocks_ahead++;
+       blocks_left++;
   }
 
   /* No more than the maximum request. */
@@ -573,9 +441,10 @@ unsigned bytes_ahead;              /* bytes beyond position for immediate use */
        block++;
        position_running += block_size;
 
-       if(!block_spec && 
-         (thisblock = read_map(rip, (off_t) ex64lo(position_running), 1)) != NO_BLOCK) {
-               bp = lmfs_get_block_ino(dev, thisblock, PREFETCH, rip->i_num, position_running);
+       thisblock = read_map(rip, (off_t) ex64lo(position_running), 1);
+       if (thisblock != NO_BLOCK) {
+               bp = lmfs_get_block_ino(dev, thisblock, PREFETCH, rip->i_num,
+                       position_running);
        } else {
                bp = get_block(dev, block, PREFETCH);
        }
@@ -591,8 +460,6 @@ unsigned bytes_ahead;               /* bytes beyond position for immediate use */
 
   assert(inuse_before == lmfs_bufs_in_use());
 
-  if(block_spec)
-         return get_block(dev, baseblock, NORMAL);
   return(lmfs_get_block_ino(dev, baseblock, NORMAL, rip->i_num, position));
 }
 
@@ -600,33 +467,27 @@ unsigned bytes_ahead;             /* bytes beyond position for immediate use */
 /*===========================================================================*
  *                             fs_getdents                                  *
  *===========================================================================*/
-int fs_getdents(void)
+ssize_t fs_getdents(ino_t ino_nr, struct fsdriver_data *data, size_t bytes,
+       off_t *posp)
 {
 #define GETDENTS_BUFSIZE       (sizeof(struct dirent) + MFS_NAME_MAX + 1)
 #define GETDENTS_ENTRIES       8
   static char getdents_buf[GETDENTS_BUFSIZE * GETDENTS_ENTRIES];
-  register struct inode *rip;
-  int o, r, done;
-  unsigned int block_size, len, reclen;
-  ino_t ino;
-  cp_grant_id_t gid;
-  size_t size, tmpbuf_off, userbuf_off;
+  struct fsdriver_dentry fsdentry;
+  struct inode *rip, *entrip;
+  int r, done;
+  unsigned int block_size, len, type;
   off_t pos, off, block_pos, new_pos, ent_pos;
   struct buf *bp;
   struct direct *dp;
-  struct dirent *dep;
   char *cp;
 
-  ino = fs_m_in.m_vfs_fs_getdents.inode;
-  gid = fs_m_in.m_vfs_fs_getdents.grant;
-  size = fs_m_in.m_vfs_fs_getdents.mem_size;
-  pos = fs_m_in.m_vfs_fs_getdents.seek_pos;
-
   /* Check whether the position is properly aligned */
+  pos = *posp;
   if( (unsigned int) pos % DIR_ENTRY_SIZE)
          return(ENOENT);
   
-  if( (rip = get_inode(fs_dev, ino)) == NULL) 
+  if( (rip = get_inode(fs_dev, ino_nr)) == NULL)
          return(EINVAL);
 
   block_size = rip->i_sp->s_block_size;
@@ -634,81 +495,63 @@ int fs_getdents(void)
   block_pos = pos - off;
   done = FALSE;                /* Stop processing directory blocks when done is set */
 
-  tmpbuf_off = 0;      /* Offset in getdents_buf */
-  memset(getdents_buf, '\0', sizeof(getdents_buf));    /* Avoid leaking any data */
-  userbuf_off = 0;     /* Offset in the user's buffer */
+  fsdriver_dentry_init(&fsdentry, data, bytes, getdents_buf,
+       sizeof(getdents_buf));
 
   /* The default position for the next request is EOF. If the user's buffer
    * fills up before EOF, new_pos will be modified. */
   new_pos = rip->i_size;
 
+  r = 0;
+
   for(; block_pos < rip->i_size; block_pos += block_size) {
        /* Since directories don't have holes, 'bp' cannot be NULL. */
        bp = get_block_map(rip, block_pos);     /* get a dir block */
        assert(bp != NULL);
 
-         /* Search a directory block. */
-         if (block_pos < pos)
-                 dp = &b_dir(bp)[off / DIR_ENTRY_SIZE];
-         else
-                 dp = &b_dir(bp)[0];
-         for (; dp < &b_dir(bp)[NR_DIR_ENTRIES(block_size)]; dp++) {
-                 if (dp->mfs_d_ino == 0) 
-                         continue;     /* Entry is not in use */
-
-                 /* Compute the length of the name */
-                 cp = memchr(dp->mfs_d_name, '\0', sizeof(dp->mfs_d_name));
-                 if (cp == NULL)
-                         len = sizeof(dp->mfs_d_name);
-                 else
-                         len = cp - (dp->mfs_d_name);
-               
-                 /* Compute record length; also does alignment. */
-                 reclen = _DIRENT_RECLEN(dep, len);
-
-                 /* Need the position of this entry in the directory */
-                 ent_pos = block_pos + ((char *) dp - (char *) bp->data);
-
-               if (userbuf_off + tmpbuf_off + reclen >= size) {
-                         /* The user has no space for one more record */
-                         done = TRUE;
-
-                         /* Record the position of this entry, it is the
-                          * starting point of the next request (unless the
-                          * postion is modified with lseek).
-                          */
-                         new_pos = ent_pos;
-                         break;
-               }
-
-               if (tmpbuf_off + reclen >= GETDENTS_BUFSIZE*GETDENTS_ENTRIES) {
-                         r = sys_safecopyto(VFS_PROC_NR, gid,
-                                            (vir_bytes) userbuf_off, 
-                                            (vir_bytes) getdents_buf,
-                                            (size_t) tmpbuf_off);
-                         if (r != OK) {
-                               put_inode(rip);
-                               return(r);
-                         }
-
-                         userbuf_off += tmpbuf_off;
-                         tmpbuf_off = 0;
-               }
-
-               dep = (struct dirent *) &getdents_buf[tmpbuf_off];
-               dep->d_fileno = (ino_t) dp->mfs_d_ino;
-               dep->d_reclen = (unsigned short) reclen;
-               dep->d_namlen = len;
-               memcpy(dep->d_name, dp->mfs_d_name, len);
-               {
-                       struct inode *entrip;
-                       if(!(entrip = get_inode(fs_dev, dep->d_fileno)))
-                               panic("unexpected get_inode failure");
-                       dep->d_type = fs_mode_to_type(entrip->i_mode);
-                       put_inode(entrip);
+       /* Search a directory block. */
+       if (block_pos < pos)
+               dp = &b_dir(bp)[off / DIR_ENTRY_SIZE];
+       else
+               dp = &b_dir(bp)[0];
+       for (; dp < &b_dir(bp)[NR_DIR_ENTRIES(block_size)]; dp++) {
+               if (dp->mfs_d_ino == 0)
+                       continue;       /* Entry is not in use */
+
+               /* Compute the length of the name */
+               cp = memchr(dp->mfs_d_name, '\0', sizeof(dp->mfs_d_name));
+               if (cp == NULL)
+                       len = sizeof(dp->mfs_d_name);
+               else
+                       len = cp - (dp->mfs_d_name);
+
+               /* Need the position of this entry in the directory */
+               ent_pos = block_pos + ((char *) dp - (char *) bp->data);
+
+               /* We also need(?) the file type of the target inode. */
+               if (!(entrip = get_inode(fs_dev, (ino_t) dp->mfs_d_ino)))
+                       panic("unexpected get_inode failure");
+               type = IFTODT(entrip->i_mode);
+               put_inode(entrip);
+
+               /* MFS does not store file types in its directory entries, and
+                * fetching the mode from the inode is seriously expensive.
+                * Userland should always be prepared to receive DT_UNKNOWN.
+                */
+               r = fsdriver_dentry_add(&fsdentry, (ino_t) dp->mfs_d_ino,
+                       dp->mfs_d_name, len, type);
+
+               /* If the user buffer is full, or an error occurred, stop. */
+               if (r <= 0) {
+                       done = TRUE;
+
+                       /* Record the position of this entry, it is the
+                        * starting point of the next request (unless the
+                        * postion is modified with lseek).
+                        */
+                       new_pos = ent_pos;
+                       break;
                }
-               dep->d_name[len] = '\0';
-               tmpbuf_off += reclen;
        }
 
        put_block(bp, DIRECTORY_BLOCK);
@@ -716,30 +559,14 @@ int fs_getdents(void)
                break;
   }
 
-  if (tmpbuf_off != 0) {
-       r = sys_safecopyto(VFS_PROC_NR, gid, (vir_bytes) userbuf_off,
-                            (vir_bytes) getdents_buf, (size_t) tmpbuf_off);
-       if (r != OK) {
-               put_inode(rip);
-               return(r);
-       }
-
-       userbuf_off += tmpbuf_off;
-  }
-
-  if (done && userbuf_off == 0)
-         r = EINVAL;           /* The user's buffer is too small */
-  else {
-         fs_m_out.m_fs_vfs_getdents.nbytes = userbuf_off;
-         fs_m_out.m_fs_vfs_getdents.seek_pos = new_pos;
+  if (r >= 0 && (r = fsdriver_dentry_finish(&fsdentry)) >= 0) {
+         *posp = new_pos;
          if(!rip->i_sp->s_rd_only) {
                  rip->i_update |= ATIME;
                  IN_MARKDIRTY(rip);
          }
-         r = OK;
   }
 
   put_inode(rip);              /* release the inode */
   return(r);
 }
-
index 446697e53abd23621fdcc97985b19d0b023ccbde..91be2280a1ad87f8a57048a5795e67229a34f2b7 100644 (file)
@@ -5,7 +5,6 @@
 #include <sys/statvfs.h>
 #include "inode.h"
 #include "super.h"
-#include <minix/vfsif.h>
 
 /*===========================================================================*
  *                             estimate_blocks                              *
@@ -38,20 +37,18 @@ static blkcnt_t estimate_blocks(struct inode *rip)
   return (zones + sindirs + dindirs) * (blkcnt_t) (zone_size / 512);
 }
 
+
 /*===========================================================================*
- *                             stat_inode                                   *
+ *                             fs_stat                                      *
  *===========================================================================*/
-static int stat_inode(
-  register struct inode *rip,  /* pointer to inode to stat */
-  endpoint_t who_e,            /* Caller endpoint */
-  cp_grant_id_t gid            /* grant for the stat buf */
-)
+int fs_stat(ino_t ino_nr, struct stat *statbuf)
 {
-/* Common code for stat and fstat system calls. */
-
-  struct stat statbuf;
+  struct inode *rip;
   mode_t mo;
-  int r, s;
+  int s;
+
+  if ((rip = get_inode(fs_dev, ino_nr)) == NULL)
+       return(EINVAL);
 
   /* Update the atime, ctime, and mtime fields in the inode, if need be. */
   if (rip->i_update) update_times(rip);
@@ -62,76 +59,49 @@ static int stat_inode(
   /* true iff special */
   s = (mo == I_CHAR_SPECIAL || mo == I_BLOCK_SPECIAL);
 
-  memset(&statbuf, 0, sizeof(struct stat));
-
-  statbuf.st_dev = rip->i_dev;
-  statbuf.st_ino = (ino_t) rip->i_num;
-  statbuf.st_mode = (mode_t) rip->i_mode;
-  statbuf.st_nlink = (nlink_t) rip->i_nlinks;
-  statbuf.st_uid = rip->i_uid;
-  statbuf.st_gid = rip->i_gid;
-  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;
-  statbuf.st_blksize = lmfs_fs_block_size();
-  statbuf.st_blocks = estimate_blocks(rip);
-
-  /* Copy the struct to user space. */
-  r = sys_safecopyto(who_e, gid, (vir_bytes) 0, (vir_bytes) &statbuf,
-               (size_t) sizeof(statbuf));
-
-  return(r);
+  statbuf->st_dev = rip->i_dev;
+  statbuf->st_ino = (ino_t) rip->i_num;
+  statbuf->st_mode = (mode_t) rip->i_mode;
+  statbuf->st_nlink = (nlink_t) rip->i_nlinks;
+  statbuf->st_uid = rip->i_uid;
+  statbuf->st_gid = rip->i_gid;
+  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;
+  statbuf->st_blksize = lmfs_fs_block_size();
+  statbuf->st_blocks = estimate_blocks(rip);
+
+  put_inode(rip);              /* release the inode */
+
+  return(OK);
 }
 
+
 /*===========================================================================*
  *                             fs_statvfs                                   *
  *===========================================================================*/
-int fs_statvfs()
+int fs_statvfs(struct statvfs *st)
 {
-  struct statvfs st;
   struct super_block *sp;
-  int r, scale;
+  int scale;
   u64_t used;
 
   sp = get_super(fs_dev);
 
   scale = sp->s_log_zone_size;
 
-  memset(&st, 0, sizeof(st));
-
-  fs_blockstats(&st.f_blocks, &st.f_bfree, &used);
-  st.f_bavail = st.f_bfree;
+  fs_blockstats(&st->f_blocks, &st->f_bfree, &used);
+  st->f_bavail = st->f_bfree;
 
-  st.f_bsize =  sp->s_block_size << scale;
-  st.f_frsize = sp->s_block_size;
-  st.f_iosize = st.f_frsize;
-  st.f_files = sp->s_ninodes;
-  st.f_ffree = count_free_bits(sp, IMAP);
-  st.f_favail = st.f_ffree;
-  st.f_namemax = MFS_DIRSIZ;
+  st->f_bsize = sp->s_block_size << scale;
+  st->f_frsize = sp->s_block_size;
+  st->f_iosize = st->f_frsize;
+  st->f_files = sp->s_ninodes;
+  st->f_ffree = count_free_bits(sp, IMAP);
+  st->f_favail = st->f_ffree;
+  st->f_namemax = MFS_DIRSIZ;
 
-  /* Copy the struct to user space. */
-  r = sys_safecopyto(fs_m_in.m_source, fs_m_in.m_vfs_fs_statvfs.grant, 0,
-                       (vir_bytes) &st, (phys_bytes) sizeof(st));
-  
-  return(r);
+  return(OK);
 }
-
-/*===========================================================================*
- *                             fs_stat                                      *
- *===========================================================================*/
-int fs_stat()
-{
-  register int r;              /* return value */
-  register struct inode *rip;  /* target inode */
-
-  if ((rip = get_inode(fs_dev, fs_m_in.m_vfs_fs_stat.inode)) == NULL)
-       return(EINVAL);
-  
-  r = stat_inode(rip, fs_m_in.m_source, fs_m_in.m_vfs_fs_stat.grant);
-  put_inode(rip);              /* release the inode */
-  return(r);
-}
-
index b31edb2c7330b42673cc5af8a368828feebbde37..68543a4b34967b8975379b338591ee9de4891a0f 100644 (file)
@@ -193,7 +193,6 @@ unsigned int get_block_size(dev_t dev)
 static int rw_super(struct super_block *sp, int writing)
 {
 /* Read/write a superblock. */
-  int r;
   dev_t save_dev = sp->s_dev;
   struct buf *bp;
   char *sbbuf;
index 5b142515b8c171e6b0528805368a9464ea6b2150..27ceec4926642136e8e254c2f73f65d33075dae7 100644 (file)
@@ -57,7 +57,6 @@ EXTERN struct super_block {
   int s_nindirs;               /* # indirect zones per indirect block */
   bit_t s_isearch;             /* inodes below this bit number are in use */
   bit_t s_zsearch;             /* all zones below this bit number are in use*/
-  char s_is_root;
 } superblock;
 
 #define IMAP           0       /* operating on the inode bit map */
index 058aa23d8a39b9fd2774d91ce2f3a336a31b6b3f..077595c635c45291e7726b6118f004f1d7dd8502 100644 (file)
@@ -1,10 +1,8 @@
 
-/* This file contains the table used to map system call numbers onto the
+/* This file contains the table used to map file system calls onto the
  * routines that perform them.
  */
 
-#include <minix/libminixfs.h>
-
 #define _TABLE
 
 #include "fs.h"
 #include "buf.h"
 #include "super.h"
 
-int (*fs_call_vec[])(void) = {
-        no_sys,             /* 0   not used */
-        no_sys,             /* 1   */          /* Was: fs_getnode */
-        fs_putnode,         /* 2   */
-        fs_slink,           /* 3   */
-        fs_ftrunc,          /* 4   */
-        fs_chown,           /* 5   */
-       fs_chmod,           /* 6   */
-        fs_inhibread,       /* 7   */
-        fs_stat,            /* 8   */
-        fs_utime,           /* 9   */
-        fs_statvfs,         /* 10  */
-        fs_breadwrite,      /* 11  */
-        fs_breadwrite,      /* 12  */
-        fs_unlink,         /* 13  */
-        fs_unlink,          /* 14  */
-        fs_unmount,         /* 15  */
-       fs_sync,            /* 16  */
-        fs_new_driver,      /* 17  */
-        fs_flush,          /* 18  */
-        fs_readwrite,      /* 19  */
-        fs_readwrite,      /* 20  */
-        fs_mknod,           /* 21  */
-        fs_mkdir,           /* 22  */
-        fs_create,          /* 23  */
-        fs_link,            /* 24  */
-        fs_rename,          /* 25  */
-        fs_lookup,          /* 26  */
-        fs_mountpoint,      /* 27  */
-        fs_readsuper,      /* 28  */
-        no_sys,                    /* 29  */           /* Was: fs_newnode */
-        fs_rdlink,         /* 30  */
-        fs_getdents,       /* 31  */
-        fs_readwrite,       /* 32  */
-        fs_bpeek,           /* 33  */
+struct fsdriver mfs_table = {
+       .fdr_mount      = fs_mount,
+       .fdr_unmount    = fs_unmount,
+       .fdr_lookup     = fs_lookup,
+       .fdr_putnode    = fs_putnode,
+       .fdr_read       = fs_readwrite,
+       .fdr_write      = fs_readwrite,
+       .fdr_peek       = fs_readwrite,
+       .fdr_getdents   = fs_getdents,
+       .fdr_trunc      = fs_trunc,
+       .fdr_seek       = fs_seek,
+       .fdr_create     = fs_create,
+       .fdr_mkdir      = fs_mkdir,
+       .fdr_mknod      = fs_mknod,
+       .fdr_link       = fs_link,
+       .fdr_unlink     = fs_unlink,
+       .fdr_rmdir      = fs_unlink,
+       .fdr_rename     = fs_rename,
+       .fdr_slink      = fs_slink,
+       .fdr_rdlink     = fs_rdlink,
+       .fdr_stat       = fs_stat,
+       .fdr_chown      = fs_chown,
+       .fdr_chmod      = fs_chmod,
+       .fdr_utime      = fs_utime,
+       .fdr_mountpt    = fs_mountpt,
+       .fdr_statvfs    = fs_statvfs,
+       .fdr_sync       = fs_sync,
+       .fdr_driver     = lmfs_driver,
+       .fdr_bread      = lmfs_bio,
+       .fdr_bwrite     = lmfs_bio,
+       .fdr_bpeek      = lmfs_bio,
+       .fdr_bflush     = lmfs_bflush
 };
-
index d70e4b57843c2e63de4fdbc7fee1c86fb2ee736f..a52b577106aab59cbaad4aba681623325efd548d 100644 (file)
@@ -1,72 +1,49 @@
 #include "fs.h"
 #include "inode.h"
+#include <sys/time.h>
 #include <sys/stat.h>
-#include <minix/vfsif.h>
 
 
 /*===========================================================================*
  *                             fs_utime                                     *
  *===========================================================================*/
-int fs_utime()
+int fs_utime(ino_t ino_nr, struct timespec *atime, struct timespec *mtime)
 {
   register struct inode *rip;
-  register int r;
 
   /* Temporarily open the file. */
-  if( (rip = get_inode(fs_dev, fs_m_in.m_vfs_fs_utime.inode)) == NULL)
+  if( (rip = get_inode(fs_dev, ino_nr)) == NULL)
         return(EINVAL);
 
-  /*
-   * Only the owner of a file or the super_user can change the timestamps.
-   * Here we assume VFS did that check before.
-   */
-
-  r = OK;
-  if(read_only(rip) != OK) r = EROFS;  /* not even su can touch if R/O */
-  if(r == OK) {
-       rip->i_update = CTIME; /* discard any stale ATIME and MTIME flags */
-       switch(fs_m_in.m_vfs_fs_utime.acnsec) {
-       case UTIME_NOW:
-               rip->i_update |= ATIME;
-               break;
-       case UTIME_OMIT: /* do not touch */
-               break;
-       default:
-               /*
-                * cases fs_m_in.m_vfs_fs_utime.acnsec < 0 || fs_m_in.m_vfs_fs_utime.acnsec >= 1E9
-                * are caught by VFS to cooperate with old instances of MFS
-                */
-               rip->i_atime = fs_m_in.m_vfs_fs_utime.actime;
-               /*
-                * MFS does not support better than second resolution,
-                * so we discard ACNSEC to round down
-                */
-               break;
-       }
-
-       switch(fs_m_in.m_vfs_fs_utime.modnsec) {
-       case UTIME_NOW:
-               rip->i_update |= MTIME;
-               break;
-       case UTIME_OMIT: /* do not touch */
-               break;
-       default:
-               /*
-                * cases fs_m_in.m_vfs_fs_utime.modnsec < 0 || fs_m_in.m_vfs_fs_utime.modnsec >= 1E9
-                * are caught by VFS to cooperate with old instances of MFS
-                */
-               rip->i_mtime = fs_m_in.m_vfs_fs_utime.modtime;
-               /*
-                * MFS does not support better than second resolution,
-                * so we discard MODNSEC to round down
-                */
-               break;
-       }
+  rip->i_update = CTIME; /* discard any stale ATIME and MTIME flags */
+
+  switch (atime->tv_nsec) {
+  case UTIME_NOW:
+       rip->i_update |= ATIME;
+       break;
+  case UTIME_OMIT: /* do not touch */
+       break;
+  default:
+       /* MFS does not support subsecond resolution, so we round down. */
+       rip->i_atime = atime->tv_sec;
+       break;
+  }
 
-       IN_MARKDIRTY(rip);
+  switch (mtime->tv_nsec) {
+  case UTIME_NOW:
+       rip->i_update |= MTIME;
+       break;
+  case UTIME_OMIT: /* do not touch */
+       break;
+  default:
+       /* MFS does not support subsecond resolution, so we round down. */
+       rip->i_mtime = mtime->tv_sec;
+       break;
   }
 
+  IN_MARKDIRTY(rip);
+
   put_inode(rip);
-  return(r);
+  return(OK);
 }
 
index 31b68f9890063898415bd461464eb3f4e51f0000..b4c96b68a83dbba22036fe7d12d9d38e0ce4c6f9 100644 (file)
@@ -4,17 +4,6 @@
 #include "super.h"
 
 
-/*===========================================================================*
- *                             no_sys                                       *
- *===========================================================================*/
-int no_sys()
-{
-/* Somebody has used an illegal system call number */
-  printf("no_sys: invalid call %d\n", req_nr);
-  return(EINVAL);
-}
-
-
 /*===========================================================================*
  *                             conv2                                        *
  *===========================================================================*/
@@ -45,31 +34,3 @@ long x;                              /* 32-bit long to be byte swapped */
   l = ( (long) lo <<16) | hi;
   return(l);
 }
-
-
-/*===========================================================================*
- *                             mfs_min                                      *
- *===========================================================================*/
-int min(unsigned int l, unsigned int r)
-{
-       if(r >= l) return(l);
-
-       return(r);
-}
-
-
-/*===========================================================================*
- *                             mfs_nul                                      *
- *===========================================================================*/
-void mfs_nul_f(char *file, int line, char *str, unsigned int len,
-unsigned int 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", \
-  file, line, #c); panic("sanity check " #c " failed: %d", __LINE__); }
-
index d6cd91a150855b846f49a7f10a63bf836f02155d..3015b8b3d5563f7f11a95bcd33c0094479551fab 100644 (file)
@@ -233,8 +233,8 @@ struct super_block *sb;             /* superblock of device block resides on */
  *===========================================================================*/
 void clear_zone(rip, pos, flag)
 register struct inode *rip;    /* inode to clear */
-off_t pos;                     /* points to block to clear */
-int flag;                      /* 1 if called by new_block, 0 otherwise */
+off_t __unused pos;            /* points to block to clear */
+int __unused flag;             /* 1 if called by new_block, 0 otherwise */
 {
 /* Zero a zone, possibly starting in the middle.  The parameter 'pos' gives
  * a byte in the first block to be zeroed.  Clearzone() is called from 
index dcc99815ed1f33986fda6b77810bdce881fb2705..4e54cae16a39232f136e12bb55d9c8ceeb879e41 100644 (file)
@@ -10,6 +10,7 @@
 #include <minix/type.h>                /* for unshort :-( */
 #include <minix/sysutil.h>
 #include <minix/minlib.h>
+#include <minix/ipc.h>
 #include "mfs/const.h"         /* depends of -I flag in Makefile */
 #include "mfs/type.h"          /* ditto */
 #include "mfs/inode.h"         /* ditto */