From a116b3aa55f58150cf21e4ccdcc7bb63cbdc7a6d Mon Sep 17 00:00:00 2001 From: Philip Homburg Date: Wed, 8 Aug 2007 14:01:36 +0000 Subject: [PATCH] To return the right error, check first is an object is a directory (for mkdir, rmdir/unlink, mknod), simply pipe code by using v_pipe_rd_pos and v_pipe_wr_pos directly. Some cleanup work in open.c --- servers/vfs/filedes.c | 1 - servers/vfs/link.c | 7 ++ servers/vfs/open.c | 192 ++++++------------------------------------ servers/vfs/pipe.c | 2 + servers/vfs/read.c | 34 ++++---- servers/vfs/vnode.h | 1 - 6 files changed, 53 insertions(+), 184 deletions(-) diff --git a/servers/vfs/filedes.c b/servers/vfs/filedes.c index 2503d2a62..6e57d8f6c 100644 --- a/servers/vfs/filedes.c +++ b/servers/vfs/filedes.c @@ -103,7 +103,6 @@ PUBLIC struct filp *find_filp(register struct vnode *vp, mode_t bits) for (f = &filp[0]; f < &filp[NR_FILPS]; f++) { if (f->filp_count != 0 && f->filp_vno == vp && (f->filp_mode & bits)){ - assert(f->filp_count > 0); return(f); } } diff --git a/servers/vfs/link.c b/servers/vfs/link.c index 56e632c58..b61bfb217 100644 --- a/servers/vfs/link.c +++ b/servers/vfs/link.c @@ -104,6 +104,13 @@ PUBLIC int do_unlink() if (r != OK) return r; + /* Make sure that the object is a directory */ + if ((vp->v_mode & I_TYPE) != I_DIRECTORY) + { + put_vnode(vp); + return ENOTDIR; + } + /* The caller must have both search and execute permission */ r= forbidden(vp, X_BIT|W_BIT, 0 /*!use_realuid*/); if (r != OK) diff --git a/servers/vfs/open.c b/servers/vfs/open.c index ebacf5c2f..9312b13c4 100644 --- a/servers/vfs/open.c +++ b/servers/vfs/open.c @@ -35,12 +35,10 @@ #define offset_lo m2_l1 #define offset_high m2_l2 -FORWARD _PROTOTYPE( int x_open, (int bits, int oflags, int omode, - char *lastc, struct vnode **vpp) ); FORWARD _PROTOTYPE( int common_open, (int oflags, mode_t omode) ); FORWARD _PROTOTYPE( int create_open, (_mnx_Mode_t omode, int excl, struct vnode **vpp, int *created) ); -FORWARD _PROTOTYPE( int y_open, (struct vnode *vp, _mnx_Mode_t bits, +FORWARD _PROTOTYPE( int exists_open, (struct vnode *vp, _mnx_Mode_t bits, int oflags)); FORWARD _PROTOTYPE( int pipe_open, (struct vnode *vp,mode_t bits,int oflags)); @@ -126,7 +124,7 @@ PRIVATE int common_open(register int oflags, mode_t omode) if (!created) { - r= y_open(vp, bits, oflags); + r= exists_open(vp, bits, oflags); if (r != OK) { put_vnode(vp); @@ -141,7 +139,6 @@ PRIVATE int common_open(register int oflags, mode_t omode) fil_ptr->filp_flags = oflags; fil_ptr->filp_vno = vp; - vp->v_isfifo= FALSE; switch (vp->v_mode & I_TYPE) { case I_CHAR_SPECIAL: /* Invoke the driver for special processing. */ @@ -189,7 +186,6 @@ PRIVATE int common_open(register int oflags, mode_t omode) case I_NAMED_PIPE: vp->v_pipe = I_PIPE; - vp->v_isfifo= TRUE; oflags |= O_APPEND; /* force append mode */ fil_ptr->filp_flags = oflags; r = pipe_open(vp, bits, oflags); @@ -215,12 +211,8 @@ PRIVATE int common_open(register int oflags, mode_t omode) */ put_vnode(vp); } else { - /* Nobody else found. Restore filp. */ + /* Nobody else found. Claim filp. */ fil_ptr->filp_count = 1; - if (fil_ptr->filp_mode == R_BIT) - fil_ptr->filp_pos = cvul64(vp->v_pipe_rd_pos); - else - fil_ptr->filp_pos = cvul64(vp->v_pipe_wr_pos); } } break; @@ -430,143 +422,14 @@ int *created; /*===========================================================================* - * x_open * + * exists_open * *===========================================================================*/ -PRIVATE int x_open(bits, oflags, omode, lastc, vpp) -mode_t bits; -int oflags; -mode_t omode; -char *lastc; -struct vnode **vpp; -{ - int r, b, exist = TRUE; - struct vnode *vp, *dvp, *tmp_vp; - struct vmnt *vmp; - struct node_details res; - - /* If O_CREATE is set, try to make the file. */ - if ((oflags & O_CREAT) && lastc[0] != '\0') { - dvp= *vpp; /* Parent directory */ - - /* See if a free vnode is available */ - if ((vp = get_free_vnode(__FILE__, __LINE__)) == NIL_VNODE) { - printf("VFS x_open: no free vnode available\n"); - return EINVAL; - } - - r= req_create(dvp->v_fs_e, dvp->v_inode_nr, omode, fp->fp_effuid, - fp->fp_effgid, lastc, &res); - if (r != OK) - return r; - exist = FALSE; - - /* Check whether vnode is already in use or not */ - if ((tmp_vp = find_vnode(res.fs_e, res.inode_nr)) != NIL_VNODE) { - vp= tmp_vp; - vp->v_ref_count++; - vp->v_fs_count++; - } - else - { - /* Fill in the free vnode's fields */ - vp->v_fs_e = res.fs_e; - vp->v_inode_nr = res.inode_nr; - vp->v_mode = res.fmode; - vp->v_size = res.fsize; - vp->v_uid = res.uid; - vp->v_gid = res.gid; - vp->v_sdev = res.dev; - - if ( (vmp = find_vmnt(vp->v_fs_e)) == NIL_VMNT) - panic(__FILE__, "x_open: vmnt not found", NO_NUM); - - vp->v_vmnt = vmp; - vp->v_dev = vmp->m_dev; - vp->v_fs_count = 1; - vp->v_ref_count = 1; - } - - /* Release dvp */ - put_vnode(dvp); - - /* Update *vpp */ - *vpp= vp; - } - else { - vp= *vpp; - } - - /* Only do the normal open code if we didn't just create the file. */ - if (!exist) - return OK; - - /* Check protections. */ - if ((r = forbidden(vp, bits, 0 /*!use_realuid*/)) != OK) - return r; - - /* Opening reg. files directories and special files differ. */ - switch (vp->v_mode & I_TYPE) { - case I_REGULAR: - /* Truncate regular file if O_TRUNC. */ - if (oflags & O_TRUNC) { - if ((r = forbidden(vp, W_BIT, 0 /*!use_realuid*/)) !=OK) break; - truncate_vn(vp, 0); - } - break; - - case I_DIRECTORY: - /* Directories may be read but not written. */ - r = (bits & W_BIT ? EISDIR : OK); - break; - - case I_CHAR_SPECIAL: - case I_BLOCK_SPECIAL: - if (vp->v_sdev == (dev_t)-1) - panic(__FILE__, "x_open: bad special", NO_NUM); - break; - - case I_NAMED_PIPE: - if (vp->v_ref_count == 1) - { - if (vp->v_size != 0) - { - r= truncate_vn(vp, 0); - if (r != OK) - { - printf( - "x_open (fifo): truncate_vn failed: %d\n", - r); - } - } - } - break; - } - - return(r); -} - - -/*===========================================================================* - * y_open * - *===========================================================================*/ -PRIVATE int y_open(vp, bits, oflags /*, omode, lastc, vpp */) +PRIVATE int exists_open(vp, bits, oflags /*, omode, lastc, vpp */) struct vnode *vp; mode_t bits; int oflags; - -#if 0 -mode_t omode; -char *lastc; -struct vnode **vpp; -#endif { int r; -#if 0 - int r, b, exist = TRUE; - struct vnode *vp, *dvp, *tmp_vp; - struct vmnt *vmp; - struct node_details res; -#endif /* Check protections. */ if ((r = forbidden(vp, bits, 0 /*!use_realuid*/)) != OK) @@ -590,22 +453,20 @@ struct vnode **vpp; case I_CHAR_SPECIAL: case I_BLOCK_SPECIAL: if (vp->v_sdev == (dev_t)-1) - panic(__FILE__, "y_open: bad special", NO_NUM); + panic(__FILE__, "vfs:exists_open: bad special", NO_NUM); break; case I_NAMED_PIPE: +#if 0 + printf("vfs:exists_open: fifo vp 0x%x, for %s\n", + vp, ((bits & W_BIT) ? "writing" : "reading")); +#endif if (vp->v_ref_count == 1) { + vp->v_pipe_rd_pos= 0; + vp->v_pipe_wr_pos= 0; if (vp->v_size != 0) - { r= truncate_vn(vp, 0); - if (r != OK) - { - printf( - "x_open (fifo): truncate_vn failed: %d\n", - r); - } - } } break; } @@ -669,6 +530,13 @@ PUBLIC int do_mknod() /* Request lookup */ if ((r = lookup_lastdir(0 /*!use_realuid*/, &vp)) != OK) return r; + /* Make sure that the object is a directory */ + if ((vp->v_mode & I_TYPE) != I_DIRECTORY) + { + put_vnode(vp); + return ENOTDIR; + } + r= forbidden(vp, W_BIT|X_BIT, 0 /*!use_realuid*/); if (r != OK) { @@ -701,6 +569,13 @@ PUBLIC int do_mkdir() /* Request lookup */ if ((r = lookup_lastdir(0 /*!use_realuid*/, &vp)) != OK) return r; + /* Make sure that the object is a directory */ + if ((vp->v_mode & I_TYPE) != I_DIRECTORY) + { + put_vnode(vp); + return ENOTDIR; + } + r= forbidden(vp, W_BIT|X_BIT, 0 /*!use_realuid*/); if (r != OK) { @@ -874,21 +749,6 @@ int fd_nr; */ truncate_vn(vp, vp->v_size); } - if (vp->v_pipe == I_PIPE && vp->v_ref_count > 1) { - /* Save the file position in the v-node in case needed later. - * The read and write positions are saved separately. - */ - if (rfilp->filp_mode == R_BIT) - vp->v_pipe_rd_pos = ex64lo(rfilp->filp_pos); - else - vp->v_pipe_wr_pos = ex64lo(rfilp->filp_pos); - - } - else { - /* Otherwise zero the pipe position fields */ - vp->v_pipe_rd_pos = 0; - vp->v_pipe_wr_pos = 0; - } put_vnode(rfilp->filp_vno); } diff --git a/servers/vfs/pipe.c b/servers/vfs/pipe.c index a3f4ec3e4..d89948497 100644 --- a/servers/vfs/pipe.c +++ b/servers/vfs/pipe.c @@ -98,6 +98,8 @@ PUBLIC int do_pipe() vp->v_mode = res.fmode; vp->v_index = res.inode_index; vp->v_pipe = I_PIPE; + vp->v_pipe_rd_pos= 0; + vp->v_pipe_wr_pos= 0; vp->v_fs_count = 1; vp->v_ref_count = 1; vp->v_size = 0; diff --git a/servers/vfs/read.c b/servers/vfs/read.c index c37e06b42..46ee6c88d 100644 --- a/servers/vfs/read.c +++ b/servers/vfs/read.c @@ -89,14 +89,10 @@ int rw_flag; /* READING or WRITING */ if (vp->v_pipe) { - if (rw_flag == WRITING) - { - if (fp->fp_cum_io_partial != 0) - { - panic(__FILE__, - "read_write: fp_cum_io_partial not clear for new pipe writer", - NO_NUM); - } + if (fp->fp_cum_io_partial != 0) + { + panic(__FILE__, "read_write: fp_cum_io_partial not clear", + NO_NUM); } return rw_pipe(rw_flag, usr, m_in.fd, f, m_in.buffer, m_in.nbytes); } @@ -260,19 +256,19 @@ size_t req_size; { int r, oflags, op, partial_pipe; size_t size, cum_io, cum_io_incr; - struct filp *wf; struct vnode *vp; u64_t position, new_pos; - position = f->filp_pos; oflags = f->filp_flags; vp = f->filp_vno; + position = cvu64((rw_flag == READING) ? vp->v_pipe_rd_pos : + vp->v_pipe_wr_pos); #if 0 - printf("vfs:rw_pipe: pipe %s, buf 0x%x, size %d\n", - rw_flag == READING ? "read" : "write", buf, req_size); - printf("vfs:rw_pipe: pipe vp 00x%x, dev/num 0x%x/%d size %d, pos 0x%x:%08x\n", + printf("vfs:rw_pipe: filp 0x%x pipe %s, buf 0x%x, size %d\n", + f, rw_flag == READING ? "read" : "write", buf, req_size); + printf("vfs:rw_pipe: pipe vp 0x%x, dev/num 0x%x/%d size %d, pos 0x%x:%08x\n", vp, vp->v_dev, vp->v_inode_nr, vp->v_size, ex64hi(position), ex64lo(position)); #endif @@ -339,14 +335,20 @@ size_t req_size; else { if (cmp64ul(position, vp->v_size) >= 0) { /* Reset pipe pointers */ +#if 0 + printf("vfs:rw_pipe: resetting pipe size/positions\n"); +#endif vp->v_size = 0; + vp->v_pipe_rd_pos= 0; + vp->v_pipe_wr_pos= 0; position = cvu64(0); - wf = find_filp(vp, W_BIT); - if (wf != NIL_FILP) wf->filp_pos = cvu64(0); } } - f->filp_pos = position; + if (rw_flag == READING) + vp->v_pipe_rd_pos= cv64ul(position); + else + vp->v_pipe_wr_pos= cv64ul(position); if (r == OK) { if (partial_pipe) { diff --git a/servers/vfs/vnode.h b/servers/vfs/vnode.h index 2b66c9420..02d4472e5 100644 --- a/servers/vfs/vnode.h +++ b/servers/vfs/vnode.h @@ -26,7 +26,6 @@ EXTERN struct vnode { /* For debugging */ char *v_file; int v_line; - int v_isfifo; } vnode[NR_VNODES]; #define NIL_VNODE (struct vnode *) 0 /* indicates absence of vnode slot */