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
This commit is contained in:
parent
c2bf536a55
commit
a116b3aa55
@ -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++) {
|
for (f = &filp[0]; f < &filp[NR_FILPS]; f++) {
|
||||||
if (f->filp_count != 0 && f->filp_vno == vp && (f->filp_mode & bits)){
|
if (f->filp_count != 0 && f->filp_vno == vp && (f->filp_mode & bits)){
|
||||||
assert(f->filp_count > 0);
|
|
||||||
return(f);
|
return(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,6 +104,13 @@ PUBLIC int do_unlink()
|
|||||||
if (r != OK)
|
if (r != OK)
|
||||||
return r;
|
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 */
|
/* The caller must have both search and execute permission */
|
||||||
r= forbidden(vp, X_BIT|W_BIT, 0 /*!use_realuid*/);
|
r= forbidden(vp, X_BIT|W_BIT, 0 /*!use_realuid*/);
|
||||||
if (r != OK)
|
if (r != OK)
|
||||||
|
@ -35,12 +35,10 @@
|
|||||||
#define offset_lo m2_l1
|
#define offset_lo m2_l1
|
||||||
#define offset_high m2_l2
|
#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 common_open, (int oflags, mode_t omode) );
|
||||||
FORWARD _PROTOTYPE( int create_open, (_mnx_Mode_t omode, int excl,
|
FORWARD _PROTOTYPE( int create_open, (_mnx_Mode_t omode, int excl,
|
||||||
struct vnode **vpp, int *created) );
|
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));
|
int oflags));
|
||||||
FORWARD _PROTOTYPE( int pipe_open, (struct vnode *vp,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)
|
if (!created)
|
||||||
{
|
{
|
||||||
r= y_open(vp, bits, oflags);
|
r= exists_open(vp, bits, oflags);
|
||||||
if (r != OK)
|
if (r != OK)
|
||||||
{
|
{
|
||||||
put_vnode(vp);
|
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_flags = oflags;
|
||||||
fil_ptr->filp_vno = vp;
|
fil_ptr->filp_vno = vp;
|
||||||
|
|
||||||
vp->v_isfifo= FALSE;
|
|
||||||
switch (vp->v_mode & I_TYPE) {
|
switch (vp->v_mode & I_TYPE) {
|
||||||
case I_CHAR_SPECIAL:
|
case I_CHAR_SPECIAL:
|
||||||
/* Invoke the driver for special processing. */
|
/* Invoke the driver for special processing. */
|
||||||
@ -189,7 +186,6 @@ PRIVATE int common_open(register int oflags, mode_t omode)
|
|||||||
|
|
||||||
case I_NAMED_PIPE:
|
case I_NAMED_PIPE:
|
||||||
vp->v_pipe = I_PIPE;
|
vp->v_pipe = I_PIPE;
|
||||||
vp->v_isfifo= TRUE;
|
|
||||||
oflags |= O_APPEND; /* force append mode */
|
oflags |= O_APPEND; /* force append mode */
|
||||||
fil_ptr->filp_flags = oflags;
|
fil_ptr->filp_flags = oflags;
|
||||||
r = pipe_open(vp, bits, oflags);
|
r = pipe_open(vp, bits, oflags);
|
||||||
@ -215,12 +211,8 @@ PRIVATE int common_open(register int oflags, mode_t omode)
|
|||||||
*/
|
*/
|
||||||
put_vnode(vp);
|
put_vnode(vp);
|
||||||
} else {
|
} else {
|
||||||
/* Nobody else found. Restore filp. */
|
/* Nobody else found. Claim filp. */
|
||||||
fil_ptr->filp_count = 1;
|
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;
|
break;
|
||||||
@ -430,143 +422,14 @@ int *created;
|
|||||||
|
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* x_open *
|
* exists_open *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PRIVATE int x_open(bits, oflags, omode, lastc, vpp)
|
PRIVATE int exists_open(vp, 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 */)
|
|
||||||
struct vnode *vp;
|
struct vnode *vp;
|
||||||
mode_t bits;
|
mode_t bits;
|
||||||
int oflags;
|
int oflags;
|
||||||
|
|
||||||
#if 0
|
|
||||||
mode_t omode;
|
|
||||||
char *lastc;
|
|
||||||
struct vnode **vpp;
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
int r;
|
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. */
|
/* Check protections. */
|
||||||
if ((r = forbidden(vp, bits, 0 /*!use_realuid*/)) != OK)
|
if ((r = forbidden(vp, bits, 0 /*!use_realuid*/)) != OK)
|
||||||
@ -590,22 +453,20 @@ struct vnode **vpp;
|
|||||||
case I_CHAR_SPECIAL:
|
case I_CHAR_SPECIAL:
|
||||||
case I_BLOCK_SPECIAL:
|
case I_BLOCK_SPECIAL:
|
||||||
if (vp->v_sdev == (dev_t)-1)
|
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;
|
break;
|
||||||
|
|
||||||
case I_NAMED_PIPE:
|
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)
|
if (vp->v_ref_count == 1)
|
||||||
{
|
{
|
||||||
|
vp->v_pipe_rd_pos= 0;
|
||||||
|
vp->v_pipe_wr_pos= 0;
|
||||||
if (vp->v_size != 0)
|
if (vp->v_size != 0)
|
||||||
{
|
|
||||||
r= truncate_vn(vp, 0);
|
r= truncate_vn(vp, 0);
|
||||||
if (r != OK)
|
|
||||||
{
|
|
||||||
printf(
|
|
||||||
"x_open (fifo): truncate_vn failed: %d\n",
|
|
||||||
r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -669,6 +530,13 @@ PUBLIC int do_mknod()
|
|||||||
/* Request lookup */
|
/* Request lookup */
|
||||||
if ((r = lookup_lastdir(0 /*!use_realuid*/, &vp)) != OK) return r;
|
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*/);
|
r= forbidden(vp, W_BIT|X_BIT, 0 /*!use_realuid*/);
|
||||||
if (r != OK)
|
if (r != OK)
|
||||||
{
|
{
|
||||||
@ -701,6 +569,13 @@ PUBLIC int do_mkdir()
|
|||||||
/* Request lookup */
|
/* Request lookup */
|
||||||
if ((r = lookup_lastdir(0 /*!use_realuid*/, &vp)) != OK) return r;
|
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*/);
|
r= forbidden(vp, W_BIT|X_BIT, 0 /*!use_realuid*/);
|
||||||
if (r != OK)
|
if (r != OK)
|
||||||
{
|
{
|
||||||
@ -874,21 +749,6 @@ int fd_nr;
|
|||||||
*/
|
*/
|
||||||
truncate_vn(vp, vp->v_size);
|
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);
|
put_vnode(rfilp->filp_vno);
|
||||||
}
|
}
|
||||||
|
@ -98,6 +98,8 @@ PUBLIC int do_pipe()
|
|||||||
vp->v_mode = res.fmode;
|
vp->v_mode = res.fmode;
|
||||||
vp->v_index = res.inode_index;
|
vp->v_index = res.inode_index;
|
||||||
vp->v_pipe = I_PIPE;
|
vp->v_pipe = I_PIPE;
|
||||||
|
vp->v_pipe_rd_pos= 0;
|
||||||
|
vp->v_pipe_wr_pos= 0;
|
||||||
vp->v_fs_count = 1;
|
vp->v_fs_count = 1;
|
||||||
vp->v_ref_count = 1;
|
vp->v_ref_count = 1;
|
||||||
vp->v_size = 0;
|
vp->v_size = 0;
|
||||||
|
@ -89,14 +89,10 @@ int rw_flag; /* READING or WRITING */
|
|||||||
|
|
||||||
if (vp->v_pipe)
|
if (vp->v_pipe)
|
||||||
{
|
{
|
||||||
if (rw_flag == WRITING)
|
if (fp->fp_cum_io_partial != 0)
|
||||||
{
|
{
|
||||||
if (fp->fp_cum_io_partial != 0)
|
panic(__FILE__, "read_write: fp_cum_io_partial not clear",
|
||||||
{
|
NO_NUM);
|
||||||
panic(__FILE__,
|
|
||||||
"read_write: fp_cum_io_partial not clear for new pipe writer",
|
|
||||||
NO_NUM);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return rw_pipe(rw_flag, usr, m_in.fd, f, m_in.buffer, m_in.nbytes);
|
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;
|
int r, oflags, op, partial_pipe;
|
||||||
size_t size, cum_io, cum_io_incr;
|
size_t size, cum_io, cum_io_incr;
|
||||||
struct filp *wf;
|
|
||||||
struct vnode *vp;
|
struct vnode *vp;
|
||||||
u64_t position, new_pos;
|
u64_t position, new_pos;
|
||||||
|
|
||||||
position = f->filp_pos;
|
|
||||||
oflags = f->filp_flags;
|
oflags = f->filp_flags;
|
||||||
|
|
||||||
vp = f->filp_vno;
|
vp = f->filp_vno;
|
||||||
|
position = cvu64((rw_flag == READING) ? vp->v_pipe_rd_pos :
|
||||||
|
vp->v_pipe_wr_pos);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
printf("vfs:rw_pipe: pipe %s, buf 0x%x, size %d\n",
|
printf("vfs:rw_pipe: filp 0x%x pipe %s, buf 0x%x, size %d\n",
|
||||||
rw_flag == READING ? "read" : "write", buf, req_size);
|
f, 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: 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, vp->v_dev, vp->v_inode_nr,
|
||||||
vp->v_size, ex64hi(position), ex64lo(position));
|
vp->v_size, ex64hi(position), ex64lo(position));
|
||||||
#endif
|
#endif
|
||||||
@ -339,14 +335,20 @@ size_t req_size;
|
|||||||
else {
|
else {
|
||||||
if (cmp64ul(position, vp->v_size) >= 0) {
|
if (cmp64ul(position, vp->v_size) >= 0) {
|
||||||
/* Reset pipe pointers */
|
/* Reset pipe pointers */
|
||||||
|
#if 0
|
||||||
|
printf("vfs:rw_pipe: resetting pipe size/positions\n");
|
||||||
|
#endif
|
||||||
vp->v_size = 0;
|
vp->v_size = 0;
|
||||||
|
vp->v_pipe_rd_pos= 0;
|
||||||
|
vp->v_pipe_wr_pos= 0;
|
||||||
position = cvu64(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 (r == OK) {
|
||||||
if (partial_pipe) {
|
if (partial_pipe) {
|
||||||
|
@ -26,7 +26,6 @@ EXTERN struct vnode {
|
|||||||
/* For debugging */
|
/* For debugging */
|
||||||
char *v_file;
|
char *v_file;
|
||||||
int v_line;
|
int v_line;
|
||||||
int v_isfifo;
|
|
||||||
} vnode[NR_VNODES];
|
} vnode[NR_VNODES];
|
||||||
|
|
||||||
#define NIL_VNODE (struct vnode *) 0 /* indicates absence of vnode slot */
|
#define NIL_VNODE (struct vnode *) 0 /* indicates absence of vnode slot */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user