]> Zhao Yanbai Git Server - minix.git/commitdiff
VFS: simplify stat for pipes
authorThomas Veerman <thomas@minix3.org>
Wed, 18 Apr 2012 13:44:33 +0000 (13:44 +0000)
committerThomas Veerman <thomas@minix3.org>
Fri, 27 Apr 2012 08:50:49 +0000 (08:50 +0000)
According to POSIX the st_size field of struct stat is undefined for
fifos and anonymous pipes. Thus we can do anything we want. We save a
copy by not being accurate on pipe sizes.

include/sys/stat.h
servers/vfs/exec.c
servers/vfs/proto.h
servers/vfs/request.c
servers/vfs/stadir.c

index c10014e3b6bcbbd1ca7444dfc66d509a8a02b18b..b6d81843c76c32557682836c3b51f4b429170f50 100644 (file)
@@ -8,7 +8,6 @@
 #include <sys/time.h>
 #endif
 
-
 struct stat {
   big_dev_t     st_dev;               /* inode's device */
   big_mode_t    st_mode;              /* inode protection mode */
@@ -40,7 +39,6 @@ struct stat {
   u32_t     st_spare[2];
 };
 
-
 struct minix_prev_stat {
   short st_dev;                        /* major/minor device number */
   ino_t st_ino;                        /* i-node number */
@@ -55,20 +53,17 @@ struct minix_prev_stat {
   time_t st_ctime;             /* time of last file status change */
 };
 
-
 #if defined(_NETBSD_SOURCE)
-/* XXX after updating stat struct we don't want to update all the code */
 #define st_atime               st_atimespec.tv_sec
-#define st_mtime               st_mtimespec.tv_sec
-#define st_ctime               st_ctimespec.tv_sec
-#define st_birthtime            st_birthtimespec.tv_sec
 #define st_atimensec            st_atimespec.tv_nsec
+#define st_mtime               st_mtimespec.tv_sec
 #define st_mtimensec            st_mtimespec.tv_nsec
+#define st_ctime               st_ctimespec.tv_sec
 #define st_ctimensec            st_ctimespec.tv_nsec
+#define st_birthtime            st_birthtimespec.tv_sec
 #define st_birthtimensec        st_birthtimespec.tv_nsec
 #endif
 
-
 #define        S_ISUID 0004000                 /* set user id on execution */
 #define        S_ISGID 0002000                 /* set group id on execution */
 #if defined(_NETBSD_SOURCE)
index fe174e5f0c19d2b72c198f7397a8ef88ff6fb80e..0e55eb7dfa9b69e5ccd3bc6d9aa8b1012f947f3d 100644 (file)
@@ -155,7 +155,7 @@ static int get_read_vp(struct exec_info *execi, char *fullpath,
                return r;
        else
                r = req_stat(execi->vp->v_fs_e, execi->vp->v_inode_nr,
-                       VFS_PROC_NR, (vir_bytes) &(execi->sb), 0, 0);
+                       VFS_PROC_NR, (vir_bytes) &(execi->sb), 0);
 
        if (r != OK) return r;
 
index 0e11470a06613ef51361eedda6dce8589d3bcfa2..e41883b2a482627b198b2142fb0e95406571bc03 100644 (file)
@@ -253,7 +253,7 @@ int req_rmdir(endpoint_t fs_e, ino_t inode_nr, char *lastc);
 int req_slink(endpoint_t fs_e, ino_t inode_nr, char *lastc, endpoint_t proc_e,
        vir_bytes path_addr, size_t path_length, uid_t uid, gid_t gid);
 int req_stat(endpoint_t fs_e, ino_t inode_nr, endpoint_t proc_e, vir_bytes buf,
-       int pos, int stat_version);
+       int old_stat);
 int req_sync(endpoint_t fs_e);
 int req_unlink(endpoint_t fs_e, ino_t inode_nr, char *lastc);
 int req_unmount(endpoint_t fs_e);
index a311256b1674fcf2c9f65a2f61600473bcbe7405..c28a75cf843b0c30026f3edc5563eacdf241b5e6 100644 (file)
@@ -923,7 +923,7 @@ int req_slink(
  *                             req_stat                                     *
  *===========================================================================*/
 int req_stat(endpoint_t fs_e, ino_t inode_nr, endpoint_t proc_e, vir_bytes buf,
-       int pos, int stat_version)
+       int old_stat)
 {
   cp_grant_id_t grant_id;
   int r;
@@ -931,12 +931,17 @@ int req_stat(endpoint_t fs_e, ino_t inode_nr, endpoint_t proc_e, vir_bytes buf,
   struct stat sb;
   struct minix_prev_stat old_sb; /* for backward compatibility */
 
-  if (pos != 0 || stat_version != 0)
-         grant_id = cpf_grant_direct(fs_e, (vir_bytes) &sb,
-                                     sizeof(struct stat), CPF_WRITE);
-  else
-         grant_id = cpf_grant_magic(fs_e, proc_e, buf, sizeof(struct stat),
-                                    CPF_WRITE);
+  if (old_stat == 1) {
+       /* We're dealing with the old stat() call. First copy stat structure
+        * to VFS so we can convert the new struct stat to the old version.
+        */
+       grant_id = cpf_grant_direct(fs_e, (vir_bytes) &sb, sizeof(struct stat),
+                                   CPF_WRITE);
+  } else {
+       /* Grant FS access to copy straight into user provided buffer */
+       grant_id = cpf_grant_magic(fs_e, proc_e, buf, sizeof(struct stat),
+                                  CPF_WRITE);
+  }
 
   if (grant_id < 0)
        panic("req_stat: cpf_grant_* failed");
@@ -950,29 +955,16 @@ int req_stat(endpoint_t fs_e, ino_t inode_nr, endpoint_t proc_e, vir_bytes buf,
   r = fs_sendrec(fs_e, &m);
   cpf_revoke(grant_id);
 
-  if (r != OK || (pos == 0 && stat_version == 0))
+  if (r != OK || old_stat == 0)
        return(r);
 
-  if (pos != 0)
-       sb.st_size -= pos;
-  if (stat_version == 0) {
-       r = sys_vircopy(SELF, D, (vir_bytes) &sb, proc_e, D, buf,
-                       sizeof(struct stat));
-       return(r);
-  }
-
-  /* User needs old struct stat.
-   * Just 1 prev version at this moment */
-  assert(stat_version == 1);
-
-/* XXX until that st_Xtime macroses used, we have to undefine them,
- * because of minix_prev_stat
- */
+#if defined(_NETBSD_SOURCE)
 #undef st_atime
 #undef st_ctime
 #undef st_mtime
+#endif
 
-/* Copy field by field because of st_gid type mismath and
+/* Copy field by field because of st_gid type mismatch and
  * difference in order after atime.
  */
   old_sb.st_dev = sb.st_dev;
index 793b7a82577498632dd32fc3c4ac8d77d4d23abb..3d1c367b9b16256d140826545f7b2e0f7b51fd45 100644 (file)
@@ -181,7 +181,7 @@ int do_stat()
 
   if (fetch_name(vname1, vname1_length, fullpath) != OK) return(err_code);
   if ((vp = eat_path(&resolve, fp)) == NULL) return(err_code);
-  r = req_stat(vp->v_fs_e, vp->v_inode_nr, who_e, statbuf, 0, old_stat);
+  r = req_stat(vp->v_fs_e, vp->v_inode_nr, who_e, statbuf, old_stat);
 
   unlock_vnode(vp);
   unlock_vmnt(vmp);
@@ -197,7 +197,7 @@ int do_fstat()
 {
 /* Perform the fstat(fd, buf) system call. */
   register struct filp *rfilp;
-  int r, pipe_pos = 0, old_stat = 0, rfd;
+  int r, old_stat = 0, rfd;
   vir_bytes statbuf;
 
   statbuf = (vir_bytes) job_m_in.buffer;
@@ -209,17 +209,8 @@ int do_fstat()
   /* Is the file descriptor valid? */
   if ((rfilp = get_filp(rfd, VNODE_READ)) == NULL) return(err_code);
 
-  /* If we read from a pipe, send position too */
-  if (S_ISFIFO(rfilp->filp_vno->v_mode)) {
-       if (rfilp->filp_mode & R_BIT)
-               if (ex64hi(rfilp->filp_pos) != 0) {
-                       panic("do_fstat: bad position in pipe");
-               }
-       pipe_pos = ex64lo(rfilp->filp_pos);
-  }
-
   r = req_stat(rfilp->filp_vno->v_fs_e, rfilp->filp_vno->v_inode_nr,
-              who_e, statbuf, pipe_pos, old_stat);
+              who_e, statbuf, old_stat);
 
   unlock_filp(rfilp);
 
@@ -331,7 +322,7 @@ int do_lstat()
        old_stat = 1;
   if (fetch_name(vname1, vname1_length, fullpath) != OK) return(err_code);
   if ((vp = eat_path(&resolve, fp)) == NULL) return(err_code);
-  r = req_stat(vp->v_fs_e, vp->v_inode_nr, who_e, statbuf, 0, old_stat);
+  r = req_stat(vp->v_fs_e, vp->v_inode_nr, who_e, statbuf, old_stat);
 
   unlock_vnode(vp);
   unlock_vmnt(vmp);