From: Thomas Veerman Date: Wed, 18 Apr 2012 13:44:33 +0000 (+0000) Subject: VFS: simplify stat for pipes X-Git-Tag: v3.2.1~566 X-Git-Url: http://zhaoyanbai.com/repos/html/index.html?a=commitdiff_plain;h=7b812540697fd371128f0a731e48cf390ab3b5e1;p=minix.git VFS: simplify stat for pipes 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. --- diff --git a/include/sys/stat.h b/include/sys/stat.h index c10014e3b..b6d81843c 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -8,7 +8,6 @@ #include #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) diff --git a/servers/vfs/exec.c b/servers/vfs/exec.c index fe174e5f0..0e55eb7df 100644 --- a/servers/vfs/exec.c +++ b/servers/vfs/exec.c @@ -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; diff --git a/servers/vfs/proto.h b/servers/vfs/proto.h index 0e11470a0..e41883b2a 100644 --- a/servers/vfs/proto.h +++ b/servers/vfs/proto.h @@ -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); diff --git a/servers/vfs/request.c b/servers/vfs/request.c index a311256b1..c28a75cf8 100644 --- a/servers/vfs/request.c +++ b/servers/vfs/request.c @@ -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; diff --git a/servers/vfs/stadir.c b/servers/vfs/stadir.c index 793b7a825..3d1c367b9 100644 --- a/servers/vfs/stadir.c +++ b/servers/vfs/stadir.c @@ -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);