/*===========================================================================* * do_link * *===========================================================================*/ int do_link() { /* Perform the link(name1, name2) system call. */ int r = OK; struct vnode *vp = NULL, *dirp = NULL; struct vmnt *vmp1 = NULL, *vmp2 = NULL; char fullpath[PATH_MAX]; struct lookup resolve; vir_bytes vname1, vname2; size_t vname1_length, vname2_length; vname1 = (vir_bytes) job_m_in.name1; vname1_length = job_m_in.name1_length; vname2 = (vir_bytes) job_m_in.name2; vname2_length = job_m_in.name2_length; lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp1, &vp); resolve.l_vmnt_lock = VMNT_WRITE; resolve.l_vnode_lock = VNODE_READ; /* See if 'name1' (file to be linked to) exists. */ if (fetch_name(vname1, vname1_length, fullpath) != OK) return(err_code); if ((vp = eat_path(&resolve, fp)) == NULL) return(err_code); /* Does the final directory of 'name2' exist? */ lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp2, &dirp); resolve.l_vmnt_lock = VMNT_READ; resolve.l_vnode_lock = VNODE_WRITE; if (fetch_name(vname2, vname2_length, fullpath) != OK) r = err_code; else if ((dirp = last_dir(&resolve, fp)) == NULL) r = err_code; if (r != OK) { unlock_vnode(vp); unlock_vmnt(vmp1); put_vnode(vp); return(r); } /* Check for links across devices. */ if (vp->v_fs_e != dirp->v_fs_e) r = EXDEV; else r = forbidden(fp, dirp, W_BIT | X_BIT); if (r == OK) r = req_link(vp->v_fs_e, dirp->v_inode_nr, fullpath, vp->v_inode_nr); unlock_vnode(vp); unlock_vnode(dirp); if (vmp2 != NULL) unlock_vmnt(vmp2); unlock_vmnt(vmp1); put_vnode(vp); put_vnode(dirp); return(r); }
int do_recinode() { struct vnode *vp; struct vmnt *vmp; int r; size_t nrblks; char fullpath[PATH_MAX]; struct lookup resolve; size_t vname1_length; vir_bytes vname1; vname1 = job_m_in.m_lc_vfs_inodes.name; vname1_length = job_m_in.m_lc_vfs_inodes.len; lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp); resolve.l_vmnt_lock = VMNT_READ; resolve.l_vnode_lock = VNODE_READ; if (fetch_name(vname1, vname1_length, fullpath) != OK) return(err_code); if ((vp = eat_path(&resolve, fp)) == NULL) return(err_code); r = req_recoverinode(vp->v_fs_e, vp->v_inode_nr); unlock_vnode(vp); unlock_vmnt(vmp); put_vnode(vp); return r; }
/*===========================================================================* * do_chroot * *===========================================================================*/ int do_chroot(void) { /* Perform the chroot(name) system call. * syscall might provide 'name' embedded in the message. */ int r; struct vnode *vp; struct vmnt *vmp; char fullpath[PATH_MAX]; struct lookup resolve; if (!super_user) return(EPERM); /* only su may chroot() */ if (copy_path(fullpath, sizeof(fullpath)) != OK) return(err_code); /* Try to open the directory */ lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp); resolve.l_vmnt_lock = VMNT_READ; resolve.l_vnode_lock = VNODE_READ; if ((vp = eat_path(&resolve, fp)) == NULL) return(err_code); r = change_into(&fp->fp_rd, vp); unlock_vnode(vp); unlock_vmnt(vmp); put_vnode(vp); return(r); }
/*===========================================================================* * do_mkdir * *===========================================================================*/ int do_mkdir(void) { /* Perform the mkdir(name, mode) system call. */ mode_t bits; /* mode bits for the new inode */ int r; struct vnode *vp; struct vmnt *vmp; char fullpath[PATH_MAX]; struct lookup resolve; mode_t dirmode; if (copy_path(fullpath, sizeof(fullpath)) != OK) return(err_code); dirmode = job_m_in.m_lc_vfs_path.mode; lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp); resolve.l_vmnt_lock = VMNT_WRITE; resolve.l_vnode_lock = VNODE_WRITE; bits = I_DIRECTORY | (dirmode & RWX_MODES & fp->fp_umask); if ((vp = last_dir(&resolve, fp)) == NULL) return(err_code); /* Make sure that the object is a directory */ if (!S_ISDIR(vp->v_mode)) { r = ENOTDIR; } else if ((r = forbidden(fp, vp, W_BIT|X_BIT)) == OK) { r = req_mkdir(vp->v_fs_e, vp->v_inode_nr, fullpath, fp->fp_effuid, fp->fp_effgid, bits); } unlock_vnode(vp); unlock_vmnt(vmp); put_vnode(vp); return(r); }
/*===========================================================================* * do_statvfs * *===========================================================================*/ int do_statvfs(void) { /* Perform the statvfs1(name, buf, flags) system call. */ int r, flags; struct vnode *vp; struct vmnt *vmp; char fullpath[PATH_MAX]; struct lookup resolve; vir_bytes vname1, statbuf; size_t vname1_length; vname1 = job_m_in.m_lc_vfs_statvfs1.name; vname1_length = job_m_in.m_lc_vfs_statvfs1.len; statbuf = job_m_in.m_lc_vfs_statvfs1.buf; flags = job_m_in.m_lc_vfs_statvfs1.flags; lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp); resolve.l_vmnt_lock = VMNT_READ; resolve.l_vnode_lock = VNODE_READ; if (fetch_name(vname1, vname1_length, fullpath) != OK) return(err_code); if ((vp = eat_path(&resolve, fp)) == NULL) return(err_code); r = fill_statvfs(vp->v_vmnt, who_e, statbuf, flags); unlock_vnode(vp); unlock_vmnt(vmp); put_vnode(vp); return r; }
/*===========================================================================* * do_fsync * *===========================================================================*/ int do_fsync(void) { /* Perform the fsync() system call. */ struct filp *rfilp; struct vmnt *vmp; dev_t dev; int r = OK; scratch(fp).file.fd_nr = job_m_in.m_lc_vfs_fsync.fd; if ((rfilp = get_filp(scratch(fp).file.fd_nr, VNODE_READ)) == NULL) return(err_code); dev = rfilp->filp_vno->v_dev; unlock_filp(rfilp); for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp) { if (vmp->m_dev != dev) continue; if ((r = lock_vmnt(vmp, VMNT_READ)) != OK) break; if (vmp->m_dev != NO_DEV && vmp->m_dev == dev && vmp->m_fs_e != NONE && vmp->m_root_node != NULL) { req_sync(vmp->m_fs_e); } unlock_vmnt(vmp); } return(r); }
/*===========================================================================* * do_mkdir * *===========================================================================*/ PUBLIC int do_mkdir() { /* Perform the mkdir(name, mode) system call. */ mode_t bits; /* mode bits for the new inode */ int r; struct vnode *vp; struct vmnt *vmp; char fullpath[PATH_MAX]; struct lookup resolve; lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp); resolve.l_vmnt_lock = VMNT_WRITE; resolve.l_vnode_lock = VNODE_READ; if (fetch_name(m_in.name1, m_in.name1_length, M1, fullpath) != OK) return(err_code); bits = I_DIRECTORY | (m_in.mode & RWX_MODES & fp->fp_umask); if ((vp = last_dir(&resolve, fp)) == NULL) return(err_code); /* Make sure that the object is a directory */ if ((vp->v_mode & I_TYPE) != I_DIRECTORY) { r = ENOTDIR; } else if ((r = forbidden(vp, W_BIT|X_BIT)) == OK) { r = req_mkdir(vp->v_fs_e, vp->v_inode_nr, fullpath, fp->fp_effuid, fp->fp_effgid, bits); } unlock_vnode(vp); unlock_vmnt(vmp); put_vnode(vp); return(r); }
/*===========================================================================* * do_lstat * *===========================================================================*/ int do_lstat(void) { /* Perform the lstat(name, buf) system call. */ struct vnode *vp; struct vmnt *vmp; int r; char fullpath[PATH_MAX]; struct lookup resolve; vir_bytes vname1, statbuf; size_t vname1_length; vname1 = job_m_in.m_lc_vfs_stat.name; vname1_length = job_m_in.m_lc_vfs_stat.len; statbuf = job_m_in.m_lc_vfs_stat.buf; lookup_init(&resolve, fullpath, PATH_RET_SYMLINK, &vmp, &vp); resolve.l_vmnt_lock = VMNT_READ; resolve.l_vnode_lock = VNODE_READ; 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); unlock_vnode(vp); unlock_vmnt(vmp); put_vnode(vp); return(r); }
/*===========================================================================* * name_to_dev * *===========================================================================*/ static dev_t name_to_dev(int allow_mountpt, char path[PATH_MAX]) { /* Convert the block special file in 'user_fullpath' to a device number. * If the given path is not a block special file, but 'allow_mountpt' is set * and the path is the root node of a mounted file system, return that device * number. In all other cases, return NO_DEV and an error code in 'err_code'. */ dev_t dev; struct vnode *vp; struct vmnt *vmp; struct lookup resolve; lookup_init(&resolve, path, PATH_NOFLAGS, &vmp, &vp); resolve.l_vmnt_lock = VMNT_READ; resolve.l_vnode_lock = VNODE_READ; /* Request lookup */ if ((vp = eat_path(&resolve, fp)) == NULL) return(NO_DEV); if (S_ISBLK(vp->v_mode)) { dev = vp->v_sdev; } else if (allow_mountpt && vp->v_vmnt->m_root_node == vp) { dev = vp->v_dev; } else { err_code = ENOTBLK; dev = NO_DEV; } unlock_vnode(vp); unlock_vmnt(vmp); put_vnode(vp); return(dev); }
/*===========================================================================* * do_statvfs * *===========================================================================*/ int do_statvfs() { /* Perform the stat(name, buf) system call. */ int r; struct vnode *vp; struct vmnt *vmp; char fullpath[PATH_MAX]; struct lookup resolve; vir_bytes vname1, statbuf; size_t vname1_length; vname1 = (vir_bytes) job_m_in.name1; vname1_length = (size_t) job_m_in.name1_length; statbuf = (vir_bytes) job_m_in.name2; lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp); resolve.l_vmnt_lock = VMNT_READ; resolve.l_vnode_lock = VNODE_READ; if (fetch_name(vname1, vname1_length, fullpath) != OK) return(err_code); if ((vp = eat_path(&resolve, fp)) == NULL) return(err_code); r = req_statvfs(vp->v_fs_e, who_e, statbuf); unlock_vnode(vp); unlock_vmnt(vmp); put_vnode(vp); return r; }
/*===========================================================================* * do_fsync * *===========================================================================*/ PUBLIC int do_fsync() { /* Perform the fsync() system call. */ struct filp *rfilp; struct vmnt *vmp; dev_t dev; int r = OK; if ((rfilp = get_filp(m_in.m1_i1, VNODE_READ)) == NULL) return(err_code); dev = rfilp->filp_vno->v_dev; for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp) { if (vmp->m_dev != NO_DEV && vmp->m_dev == dev && vmp->m_fs_e != NONE && vmp->m_root_node != NULL) { if ((r = lock_vmnt(vmp, VMNT_EXCL)) != OK) break; req_sync(vmp->m_fs_e); unlock_vmnt(vmp); } } unlock_filp(rfilp); return(r); }
/*===========================================================================* * do_lstat * *===========================================================================*/ int do_lstat() { /* Perform the lstat(name, buf) system call. */ struct vnode *vp; struct vmnt *vmp; int r; char fullpath[PATH_MAX]; struct lookup resolve; int old_stat = 0; vir_bytes vname1, statbuf; size_t vname1_length; vname1 = (vir_bytes) job_m_in.name1; vname1_length = (size_t) job_m_in.name1_length; statbuf = (vir_bytes) job_m_in.name2; lookup_init(&resolve, fullpath, PATH_RET_SYMLINK, &vmp, &vp); resolve.l_vmnt_lock = VMNT_READ; resolve.l_vnode_lock = VNODE_READ; if (job_call_nr == PREV_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); unlock_vnode(vp); unlock_vmnt(vmp); put_vnode(vp); return(r); }
/*===========================================================================* * do_sync * *===========================================================================*/ int do_sync(void) { struct vmnt *vmp; int r = OK; for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp) { if ((r = lock_vmnt(vmp, VMNT_READ)) != OK) break; if (vmp->m_dev != NO_DEV && vmp->m_fs_e != NONE && vmp->m_root_node != NULL) { req_sync(vmp->m_fs_e); } unlock_vmnt(vmp); } return(r); }
/*===========================================================================* * do_mknod * *===========================================================================*/ int do_mknod(void) { /* Perform the mknod(name, mode, addr) system call. */ register mode_t bits, mode_bits; int r; struct vnode *vp; struct vmnt *vmp; char fullpath[PATH_MAX]; struct lookup resolve; vir_bytes vname1; size_t vname1_length; dev_t dev; vname1 = job_m_in.m_lc_vfs_mknod.name; vname1_length = job_m_in.m_lc_vfs_mknod.len; mode_bits = job_m_in.m_lc_vfs_mknod.mode; dev = job_m_in.m_lc_vfs_mknod.device; /* If the path names a symbolic link, mknod() shall fail with EEXIST. */ lookup_init(&resolve, fullpath, PATH_RET_SYMLINK, &vmp, &vp); resolve.l_vmnt_lock = VMNT_WRITE; resolve.l_vnode_lock = VNODE_WRITE; /* Only the super_user may make nodes other than fifos. */ if (!super_user && !S_ISFIFO(mode_bits)) return(EPERM); bits = (mode_bits & S_IFMT) | (mode_bits & ACCESSPERMS & fp->fp_umask); /* Open directory that's going to hold the new node. */ if (fetch_name(vname1, vname1_length, fullpath) != OK) return(err_code); if ((vp = last_dir(&resolve, fp)) == NULL) return(err_code); /* Make sure that the object is a directory */ if (!S_ISDIR(vp->v_mode)) { r = ENOTDIR; } else if ((r = forbidden(fp, vp, W_BIT|X_BIT)) == OK) { r = req_mknod(vp->v_fs_e, vp->v_inode_nr, fullpath, fp->fp_effuid, fp->fp_effgid, bits, dev); } unlock_vnode(vp); unlock_vmnt(vmp); put_vnode(vp); return(r); }
/*===========================================================================* * do_utime * *===========================================================================*/ PUBLIC int do_utime() { /* Perform the utime(name, timep) system call. */ register int len; int r; time_t actime, modtime; struct vnode *vp; struct vmnt *vmp; char fullpath[PATH_MAX]; struct lookup resolve; lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp); resolve.l_vmnt_lock = VMNT_WRITE; resolve.l_vnode_lock = VNODE_READ; /* Adjust for case of 'timep' being NULL; * utime_strlen then holds the actual size: strlen(name)+1 */ len = m_in.utime_length; if (len == 0) len = m_in.utime_strlen; /* Temporarily open the file */ if (fetch_name(m_in.utime_file, len, M1, fullpath) != OK) return(err_code); if ((vp = eat_path(&resolve, fp)) == NULL) return(err_code); /* Only the owner of a file or the super user can change its name. */ r = OK; if (vp->v_uid != fp->fp_effuid && fp->fp_effuid != SU_UID) r = EPERM; if (m_in.utime_length == 0 && r != OK) r = forbidden(fp, vp, W_BIT); if (read_only(vp) != OK) r = EROFS; /* Not even su can touch if R/O */ if (r == OK) { /* Issue request */ if(m_in.utime_length == 0) { actime = modtime = clock_time(); } else { actime = m_in.utime_actime; modtime = m_in.utime_modtime; } r = req_utime(vp->v_fs_e, vp->v_inode_nr, actime, modtime); } unlock_vnode(vp); unlock_vmnt(vmp); put_vnode(vp); return(r); }
int lsr_work(char * path){ //printf("lsr_work in open.c - %s\n",path); struct vnode *vp; struct vmnt *vmp; //struct dmap *dp; struct lookup resolve; lookup_init(&resolve, path, PATH_NOFLAGS, &vmp, &vp); resolve.l_vmnt_lock = VMNT_READ; resolve.l_vnode_lock = VNODE_READ; if ((vp = eat_path(&resolve, fp)) == NULL) { printf("Error: file does not exist.\n"); return(err_code); } if (vmp != NULL) unlock_vmnt(vmp); struct filp * f; struct fproc * fprc; struct filp * filp_fproc; for (f = &filp[0]; f < &filp[NR_FILPS]; f++) { if (f->filp_count != 0 && f->filp_vno == vp) { for(fprc = &fproc[0]; fprc < &fproc[NR_PROCS]; fprc++){ if(fprc != NULL){ for(int i=0;i<OPEN_MAX;i++){ filp_fproc = fprc->fp_filp[i]; if(filp_fproc == f)printf("proc id: %d\n",fprc->fp_pid); } } } } } // check if immediate first //if(vp->v_mode int ret = req_listblocknum(vp->v_fs_e, vp->v_inode_nr, vp->v_dev); unlock_vnode(vp); put_vnode(vp); return ret; }
/*===========================================================================* * do_mknod * *===========================================================================*/ int do_mknod() { /* Perform the mknod(name, mode, addr) system call. */ register mode_t bits, mode_bits; int r; struct vnode *vp; struct vmnt *vmp; char fullpath[PATH_MAX]; struct lookup resolve; vir_bytes vname1; size_t vname1_length; dev_t dev; vname1 = (vir_bytes) job_m_in.name1; vname1_length = (size_t) job_m_in.name1_length; mode_bits = (mode_t) job_m_in.mk_mode; /* mode of the inode */ dev = job_m_in.m1_i3; lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp); resolve.l_vmnt_lock = VMNT_WRITE; resolve.l_vnode_lock = VNODE_READ; /* Only the super_user may make nodes other than fifos. */ if (!super_user && (!S_ISFIFO(mode_bits) && !S_ISSOCK(mode_bits))) { return(EPERM); } bits = (mode_bits & S_IFMT) | (mode_bits & ACCESSPERMS & fp->fp_umask); /* Open directory that's going to hold the new node. */ if (fetch_name(vname1, vname1_length, fullpath) != OK) return(err_code); if ((vp = last_dir(&resolve, fp)) == NULL) return(err_code); /* Make sure that the object is a directory */ if (!S_ISDIR(vp->v_mode)) { r = ENOTDIR; } else if ((r = forbidden(fp, vp, W_BIT|X_BIT)) == OK) { r = req_mknod(vp->v_fs_e, vp->v_inode_nr, fullpath, fp->fp_effuid, fp->fp_effgid, bits, dev); } unlock_vnode(vp); unlock_vmnt(vmp); put_vnode(vp); return(r); }
int do_zinfo(){ int r=0; printf("\tStart of Zone Information from VFS\n"); struct vmnt *vmp; struct vnode *vp; struct lookup resolve; char fullpath[PATH_MAX] = "/"; lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp); resolve.l_vmnt_lock = VMNT_READ; resolve.l_vnode_lock = VNODE_READ; if ((vp = last_dir(&resolve, fp)) == NULL) return(err_code); r=req_zinfo(vmp->m_fs_e,job_m_in.m_fs_vfs_lookup.inode,job_m_in.m_fs_vfs_lookup.device); /* Unlock virtual inode and virtual mount */ unlock_vnode(vp); unlock_vmnt(vmp); put_vnode(vp); return r; }
/*===========================================================================* * do_mknod * *===========================================================================*/ PUBLIC int do_mknod() { /* Perform the mknod(name, mode, addr) system call. */ register mode_t bits, mode_bits; int r; struct vnode *vp; struct vmnt *vmp; char fullpath[PATH_MAX]; struct lookup resolve; lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp); resolve.l_vmnt_lock = VMNT_WRITE; resolve.l_vnode_lock = VNODE_READ; /* Only the super_user may make nodes other than fifos. */ mode_bits = (mode_t) m_in.mk_mode; /* mode of the inode */ if (!super_user && (((mode_bits & I_TYPE) != I_NAMED_PIPE) && ((mode_bits & I_TYPE) != I_UNIX_SOCKET))) { return(EPERM); } bits = (mode_bits & I_TYPE) | (mode_bits & ALL_MODES & fp->fp_umask); /* Open directory that's going to hold the new node. */ if (fetch_name(m_in.name1, m_in.name1_length, M1, fullpath) != OK) return(err_code); if ((vp = last_dir(&resolve, fp)) == NULL) return(err_code); /* Make sure that the object is a directory */ if ((vp->v_mode & I_TYPE) != I_DIRECTORY) { r = ENOTDIR; } else if ((r = forbidden(vp, W_BIT|X_BIT)) == OK) { r = req_mknod(vp->v_fs_e, vp->v_inode_nr, fullpath, fp->fp_effuid, fp->fp_effgid, bits, m_in.mk_z0); } unlock_vnode(vp); unlock_vmnt(vmp); put_vnode(vp); return(r); }
/*===========================================================================* * do_chroot * *===========================================================================*/ int do_chroot() { /* Perform the chroot(name) system call. * syscall might provide 'name' embedded in the message. */ int r; struct vnode *vp; struct vmnt *vmp; char fullpath[PATH_MAX]; struct lookup resolve; vir_bytes vname; size_t vname_length; vname = (vir_bytes) job_m_in.name; vname_length = (size_t) job_m_in.name_length; if (!super_user) return(EPERM); /* only su may chroot() */ if (copy_name(vname_length, fullpath) != OK) { /* Direct copy failed, try fetching from user space */ if (fetch_name(vname, vname_length, fullpath) != OK) return(err_code); } /* Try to open the directory */ lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp); resolve.l_vmnt_lock = VMNT_READ; resolve.l_vnode_lock = VNODE_READ; if ((vp = eat_path(&resolve, fp)) == NULL) return(err_code); r = change_into(&fp->fp_rd, vp); unlock_vnode(vp); unlock_vmnt(vmp); put_vnode(vp); return(r); }
/*===========================================================================* * do_mkdir * *===========================================================================*/ int do_mkdir(message *UNUSED(m_out)) { /* Perform the mkdir(name, mode) system call. */ mode_t bits; /* mode bits for the new inode */ int r; struct vnode *vp; struct vmnt *vmp; char fullpath[PATH_MAX]; struct lookup resolve; vir_bytes vname1; size_t vname1_length; mode_t dirmode; vname1 = (vir_bytes) job_m_in.name1; vname1_length = (size_t) job_m_in.name1_length; dirmode = (mode_t) job_m_in.mode; lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp); resolve.l_vmnt_lock = VMNT_WRITE; resolve.l_vnode_lock = VNODE_WRITE; if (fetch_name(vname1, vname1_length, fullpath) != OK) return(err_code); bits = I_DIRECTORY | (dirmode & RWX_MODES & fp->fp_umask); if ((vp = last_dir(&resolve, fp)) == NULL) return(err_code); /* Make sure that the object is a directory */ if (!S_ISDIR(vp->v_mode)) { r = ENOTDIR; } else if ((r = forbidden(fp, vp, W_BIT|X_BIT)) == OK) { r = req_mkdir(vp->v_fs_e, vp->v_inode_nr, fullpath, fp->fp_effuid, fp->fp_effgid, bits); } unlock_vnode(vp); unlock_vmnt(vmp); put_vnode(vp); return(r); }
int do_fileinfo(void) { struct vnode *vp; struct vmnt *vmp; int r; size_t nrblks; vir_bytes blockBuffer; char fullpath[PATH_MAX]; struct lookup resolve; size_t vname1_length; vir_bytes vname1; blockBuffer = job_m_in.m_lc_vfs_inodes.buff; nrblks = job_m_in.m_lc_vfs_inodes.nbr_blks; vname1 = job_m_in.m_lc_vfs_inodes.name; vname1_length = job_m_in.m_lc_vfs_inodes.len; lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp); resolve.l_vmnt_lock = VMNT_READ; resolve.l_vnode_lock = VNODE_READ; if (fetch_name(vname1, vname1_length, fullpath) != OK) return(err_code); if ((vp = eat_path(&resolve, fp)) == NULL) return(err_code); // r = req_nrblocks(vp->v_fs_e, vp->v_inode_nr, blockBuffer); r = req_blocks(vp->v_fs_e, vp->v_inode_nr,who_e, blockBuffer,nrblks); // fprocinfo(vp); unlock_vnode(vp); unlock_vmnt(vmp); put_vnode(vp); return OK; }
/* System call zonewalker */ int do_zonewalker(){ printf("Start of Zone Walker from VFS\n"); int r; struct vmnt *vmp; struct vnode *vp; struct lookup resolve; char fullpath[PATH_MAX] = "/"; /* Get a virtual inode and virtual mount corresponding to the path */ lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp); resolve.l_vmnt_lock = VMNT_READ; resolve.l_vnode_lock = VNODE_READ; if ((vp = last_dir(&resolve, fp)) == NULL) return(err_code); /* Emit a request to FS */ r = req_zonewalker(vmp->m_fs_e); /* Unlock virtual inode and virtual mount */ unlock_vnode(vp); unlock_vmnt(vmp); put_vnode(vp); return r; }
/*===========================================================================* * do_pipe * *===========================================================================*/ int do_pipe() { /* Perform the pipe(fil_des) system call. */ register struct fproc *rfp; int r; struct filp *fil_ptr0, *fil_ptr1; int fil_des[2]; /* reply goes here */ struct vnode *vp; struct vmnt *vmp; struct node_details res; /* Get a lock on PFS */ if ((vmp = find_vmnt(PFS_PROC_NR)) == NULL) panic("PFS gone"); if ((r = lock_vmnt(vmp, VMNT_READ)) != OK) return(r); /* See if a free vnode is available */ if ((vp = get_free_vnode()) == NULL) { unlock_vmnt(vmp); return(err_code); } lock_vnode(vp, VNODE_OPCL); /* Acquire two file descriptors. */ rfp = fp; if ((r = get_fd(0, R_BIT, &fil_des[0], &fil_ptr0)) != OK) { unlock_vnode(vp); unlock_vmnt(vmp); return(r); } rfp->fp_filp[fil_des[0]] = fil_ptr0; FD_SET(fil_des[0], &rfp->fp_filp_inuse); fil_ptr0->filp_count = 1; /* mark filp in use */ if ((r = get_fd(0, W_BIT, &fil_des[1], &fil_ptr1)) != OK) { rfp->fp_filp[fil_des[0]] = NULL; FD_CLR(fil_des[0], &rfp->fp_filp_inuse); fil_ptr0->filp_count = 0; /* mark filp free */ unlock_filp(fil_ptr0); unlock_vnode(vp); unlock_vmnt(vmp); return(r); } rfp->fp_filp[fil_des[1]] = fil_ptr1; FD_SET(fil_des[1], &rfp->fp_filp_inuse); fil_ptr1->filp_count = 1; /* Create a named pipe inode on PipeFS */ r = req_newnode(PFS_PROC_NR, fp->fp_effuid, fp->fp_effgid, I_NAMED_PIPE, NO_DEV, &res); if (r != OK) { rfp->fp_filp[fil_des[0]] = NULL; FD_CLR(fil_des[0], &rfp->fp_filp_inuse); fil_ptr0->filp_count = 0; rfp->fp_filp[fil_des[1]] = NULL; FD_CLR(fil_des[1], &rfp->fp_filp_inuse); fil_ptr1->filp_count = 0; unlock_filp(fil_ptr1); unlock_filp(fil_ptr0); unlock_vnode(vp); unlock_vmnt(vmp); return(r); } /* Fill in vnode */ vp->v_fs_e = res.fs_e; vp->v_mapfs_e = res.fs_e; vp->v_inode_nr = res.inode_nr; vp->v_mapinode_nr = res.inode_nr; vp->v_mode = res.fmode; vp->v_fs_count = 1; vp->v_mapfs_count = 1; vp->v_ref_count = 1; vp->v_size = 0; vp->v_vmnt = NULL; vp->v_dev = NO_DEV; /* Fill in filp objects */ fil_ptr0->filp_vno = vp; dup_vnode(vp); fil_ptr1->filp_vno = vp; fil_ptr0->filp_flags = O_RDONLY; fil_ptr1->filp_flags = O_WRONLY; m_out.reply_i1 = fil_des[0]; m_out.reply_i2 = fil_des[1]; unlock_filps(fil_ptr0, fil_ptr1); unlock_vmnt(vmp); return(OK); }
/*===========================================================================* * new_node * *===========================================================================*/ static struct vnode *new_node(struct lookup *resolve, int oflags, mode_t bits) { /* Try to create a new inode and return a pointer to it. If the inode already exists, return a pointer to it as well, but set err_code accordingly. NULL is returned if the path cannot be resolved up to the last directory, or when the inode cannot be created due to permissions or otherwise. */ struct vnode *dirp, *vp; struct vmnt *dir_vmp, *vp_vmp; int r; struct node_details res; struct lookup findnode; char *path; path = resolve->l_path; /* For easy access */ lookup_init(&findnode, path, resolve->l_flags, &dir_vmp, &dirp); findnode.l_vmnt_lock = VMNT_WRITE; findnode.l_vnode_lock = VNODE_WRITE; /* dir node */ /* When O_CREAT and O_EXCL flags are set, the path may not be named by a * symbolic link. */ if (oflags & O_EXCL) findnode.l_flags |= PATH_RET_SYMLINK; /* See if the path can be opened down to the last directory. */ if ((dirp = last_dir(&findnode, fp)) == NULL) return(NULL); /* The final directory is accessible. Get final component of the path. */ lookup_init(&findnode, findnode.l_path, findnode.l_flags, &vp_vmp, &vp); findnode.l_vmnt_lock = VMNT_WRITE; findnode.l_vnode_lock = (oflags & O_TRUNC) ? VNODE_WRITE : VNODE_OPCL; vp = advance(dirp, &findnode, fp); assert(vp_vmp == NULL); /* Lookup to last dir should have yielded lock * on vmp or final component does not exist. * Either way, vp_vmp ought to be not set. */ /* The combination of a symlink with absolute path followed by a danglink * symlink results in a new path that needs to be re-resolved entirely. */ if (path[0] == '/') { unlock_vnode(dirp); unlock_vmnt(dir_vmp); put_vnode(dirp); if (vp != NULL) { unlock_vnode(vp); put_vnode(vp); } return new_node(resolve, oflags, bits); } if (vp == NULL && err_code == ENOENT) { /* Last path component does not exist. Make a new directory entry. */ if ((vp = get_free_vnode()) == NULL) { /* Can't create new entry: out of vnodes. */ unlock_vnode(dirp); unlock_vmnt(dir_vmp); put_vnode(dirp); return(NULL); } lock_vnode(vp, VNODE_OPCL); if ((r = forbidden(fp, dirp, W_BIT|X_BIT)) != OK || (r = req_create(dirp->v_fs_e, dirp->v_inode_nr,bits, fp->fp_effuid, fp->fp_effgid, path, &res)) != OK ) { /* Can't create inode either due to permissions or some other * problem. In case r is EEXIST, we might be dealing with a * dangling symlink.*/ if (r == EEXIST) { struct vnode *slp, *old_wd; /* Resolve path up to symlink */ findnode.l_flags = PATH_RET_SYMLINK; findnode.l_vnode_lock = VNODE_READ; findnode.l_vnode = &slp; slp = advance(dirp, &findnode, fp); if (slp != NULL) { if (S_ISLNK(slp->v_mode)) { /* Get contents of link */ r = req_rdlink(slp->v_fs_e, slp->v_inode_nr, VFS_PROC_NR, (vir_bytes) path, PATH_MAX - 1, 0); if (r < 0) { /* Failed to read link */ unlock_vnode(slp); unlock_vnode(dirp); unlock_vmnt(dir_vmp); put_vnode(slp); put_vnode(dirp); err_code = r; return(NULL); } path[r] = '\0'; /* Terminate path */ } unlock_vnode(slp); put_vnode(slp); } /* Try to create the inode the dangling symlink was * pointing to. We have to use dirp as starting point * as there might be multiple successive symlinks * crossing multiple mountpoints. * Unlock vnodes and vmnts as we're going to recurse. */ unlock_vnode(dirp); unlock_vnode(vp); unlock_vmnt(dir_vmp); old_wd = fp->fp_wd; /* Save orig. working dirp */ fp->fp_wd = dirp; vp = new_node(resolve, oflags, bits); fp->fp_wd = old_wd; /* Restore */ if (vp != NULL) { put_vnode(dirp); *(resolve->l_vnode) = vp; return(vp); } r = err_code; } if (r == EEXIST) err_code = EIO; /* Impossible, we have verified that * the last component doesn't exist and * is not a dangling symlink. */ else err_code = r; unlock_vnode(dirp); unlock_vnode(vp); unlock_vmnt(dir_vmp); put_vnode(dirp); return(NULL); } /* Store results and mark vnode in use */ 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; vp->v_vmnt = dirp->v_vmnt; vp->v_dev = vp->v_vmnt->m_dev; vp->v_fs_count = 1; vp->v_ref_count = 1; } else { /* Either last component exists, or there is some other problem. */ if (vp != NULL) { r = EEXIST; /* File exists or a symlink names a file while * O_EXCL is set. */ } else r = err_code; /* Other problem. */ } err_code = r; /* When dirp equals vp, we shouldn't release the lock as a vp is locked only * once. Releasing the lock would cause the resulting vp not be locked and * cause mayhem later on. */ if (dirp != vp) { unlock_vnode(dirp); } unlock_vmnt(dir_vmp); put_vnode(dirp); *(resolve->l_vnode) = vp; return(vp); }
/*===========================================================================* * common_open * *===========================================================================*/ int common_open(char path[PATH_MAX], int oflags, mode_t omode) { /* Common code from do_creat and do_open. */ int b, r, exist = TRUE, major_dev; dev_t dev; mode_t bits; struct filp *filp, *filp2; struct vnode *vp; struct vmnt *vmp; struct dmap *dp; struct lookup resolve; /* Remap the bottom two bits of oflags. */ bits = (mode_t) mode_map[oflags & O_ACCMODE]; if (!bits) return(EINVAL); /* See if file descriptor and filp slots are available. */ if ((r = get_fd(0, bits, &(scratch(fp).file.fd_nr), &filp)) != OK) return(r); lookup_init(&resolve, path, PATH_NOFLAGS, &vmp, &vp); /* If O_CREATE is set, try to make the file. */ if (oflags & O_CREAT) { omode = I_REGULAR | (omode & ALLPERMS & fp->fp_umask); vp = new_node(&resolve, oflags, omode); r = err_code; if (r == OK) exist = FALSE; /* We just created the file */ else if (r != EEXIST) { /* other error */ if (vp) unlock_vnode(vp); unlock_filp(filp); return(r); } else exist = !(oflags & O_EXCL);/* file exists, if the O_EXCL flag is set this is an error */ } else { /* Scan path name */ resolve.l_vmnt_lock = VMNT_READ; resolve.l_vnode_lock = VNODE_OPCL; if ((vp = eat_path(&resolve, fp)) == NULL) { unlock_filp(filp); return(err_code); } if (vmp != NULL) unlock_vmnt(vmp); } /* Claim the file descriptor and filp slot and fill them in. */ fp->fp_filp[scratch(fp).file.fd_nr] = filp; FD_SET(scratch(fp).file.fd_nr, &fp->fp_filp_inuse); filp->filp_count = 1; filp->filp_vno = vp; filp->filp_flags = oflags; /* Only do the normal open code if we didn't just create the file. */ if (exist) { /* Check protections. */ if ((r = forbidden(fp, vp, bits)) == OK) { /* Opening reg. files, directories, and special files differ */ switch (vp->v_mode & S_IFMT) { case S_IFREG: /* Truncate regular file if O_TRUNC. */ if (oflags & O_TRUNC) { if ((r = forbidden(fp, vp, W_BIT)) != OK) break; truncate_vnode(vp, 0); } break; case S_IFDIR: /* Directories may be read but not written. */ r = (bits & W_BIT ? EISDIR : OK); break; case S_IFCHR: /* Invoke the driver for special processing. */ dev = (dev_t) vp->v_sdev; /* TTY needs to know about the O_NOCTTY flag. */ r = dev_open(dev, who_e, bits | (oflags & O_NOCTTY)); if (r == SUSPEND) suspend(FP_BLOCKED_ON_DOPEN); else vp = filp->filp_vno; /* Might be updated by * dev_open/clone_opcl */ break; case S_IFBLK: lock_bsf(); /* Invoke the driver for special processing. */ dev = (dev_t) vp->v_sdev; r = bdev_open(dev, bits); if (r != OK) { unlock_bsf(); break; } major_dev = major(vp->v_sdev); dp = &dmap[major_dev]; if (dp->dmap_driver == NONE) { printf("VFS: block driver disappeared!\n"); unlock_bsf(); r = ENXIO; break; } /* Check whether the device is mounted or not. If so, * then that FS is responsible for this device. * Otherwise we default to ROOT_FS. */ vp->v_bfs_e = ROOT_FS_E; /* By default */ for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp) if (vmp->m_dev == vp->v_sdev && !(vmp->m_flags & VMNT_FORCEROOTBSF)) { vp->v_bfs_e = vmp->m_fs_e; } /* Send the driver label to the file system that will * handle the block I/O requests (even when its label * and endpoint are known already), but only when it is * the root file system. Other file systems will * already have it anyway. */ if (vp->v_bfs_e != ROOT_FS_E) { unlock_bsf(); break; } if (req_newdriver(vp->v_bfs_e, vp->v_sdev, dp->dmap_label) != OK) { printf("VFS: error sending driver label\n"); bdev_close(dev); r = ENXIO; } unlock_bsf(); break; case S_IFIFO: /* Create a mapped inode on PFS which handles reads and writes to this named pipe. */ tll_upgrade(&vp->v_lock); r = map_vnode(vp, PFS_PROC_NR); if (r == OK) { 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_vnode(vp, 0); } oflags |= O_APPEND; /* force append mode */ filp->filp_flags = oflags; } if (r == OK) { r = pipe_open(vp, bits, oflags); } if (r != ENXIO) { /* See if someone else is doing a rd or wt on * the FIFO. If so, use its filp entry so the * file position will be automatically shared. */ b = (bits & R_BIT ? R_BIT : W_BIT); filp->filp_count = 0; /* don't find self */ if ((filp2 = find_filp(vp, b)) != NULL) { /* Co-reader or writer found. Use it.*/ fp->fp_filp[scratch(fp).file.fd_nr] = filp2; filp2->filp_count++; filp2->filp_vno = vp; filp2->filp_flags = oflags; /* v_count was incremented after the vnode * has been found. i_count was incremented * incorrectly in FS, not knowing that we * were going to use an existing filp * entry. Correct this error. */ unlock_vnode(vp); put_vnode(vp); } else { /* Nobody else found. Restore filp. */ filp->filp_count = 1; } } break; } } } unlock_filp(filp); /* If error, release inode. */ if (r != OK) { if (r != SUSPEND) { fp->fp_filp[scratch(fp).file.fd_nr] = NULL; FD_CLR(scratch(fp).file.fd_nr, &fp->fp_filp_inuse); filp->filp_count = 0; filp->filp_vno = NULL; put_vnode(vp); } } else { r = scratch(fp).file.fd_nr; } return(r); }
/*===========================================================================* * unmount * *===========================================================================*/ int unmount( dev_t dev, /* block-special device */ char label[LABEL_MAX] /* buffer to retrieve label, or NULL */ ) { struct vnode *vp; struct vmnt *vmp_i = NULL, *vmp = NULL; int count, locks, r; /* Find vmnt that is to be unmounted */ for (vmp_i = &vmnt[0]; vmp_i < &vmnt[NR_MNTS]; ++vmp_i) { if (vmp_i->m_dev == dev) { if(vmp) panic("device mounted more than once: %d", dev); vmp = vmp_i; } } /* Did we find the vmnt (i.e., was dev a mounted device)? */ if(!vmp) return(EINVAL); if ((r = lock_vmnt(vmp, VMNT_EXCL)) != OK) return(r); /* See if the mounted device is busy. Only 1 vnode using it should be * open -- the root vnode -- and that inode only 1 time. */ locks = count = 0; for (vp = &vnode[0]; vp < &vnode[NR_VNODES]; vp++) if (vp->v_ref_count > 0 && vp->v_dev == dev) { count += vp->v_ref_count; if (is_vnode_locked(vp)) locks++; } if (count > 1 || locks > 1 || tll_haspendinglock(&vmp->m_lock)) { unlock_vmnt(vmp); return(EBUSY); /* can't umount a busy file system */ } /* Tell FS to drop all inode references for root inode except 1. */ vnode_clean_refs(vmp->m_root_node); if (vmp->m_mounted_on) { put_vnode(vmp->m_mounted_on); vmp->m_mounted_on = NULL; } vmp->m_comm.c_max_reqs = 1; /* Force max concurrent reqs to just one, so * we won't send any messages after the * unmount request */ /* Tell FS to unmount */ if ((r = req_unmount(vmp->m_fs_e)) != OK) /* Not recoverable. */ printf("VFS: ignoring failed umount attempt FS endpoint: %d (%d)\n", vmp->m_fs_e, r); if (is_nonedev(vmp->m_dev)) free_nonedev(vmp->m_dev); if (label != NULL) strlcpy(label, vmp->m_label, LABEL_MAX); if (vmp->m_root_node) { /* PFS lacks a root node */ vmp->m_root_node->v_ref_count = 0; vmp->m_root_node->v_fs_count = 0; vmp->m_root_node->v_sdev = NO_DEV; vmp->m_root_node = NULL; } mark_vmnt_free(vmp); unlock_vmnt(vmp); /* The root FS will handle block I/O requests for this device now. */ lock_bsf(); update_bspec(dev, ROOT_FS_E, 1 /* send new driver endpoint */); unlock_bsf(); return(OK); }
/*===========================================================================* * create_pipe * *===========================================================================*/ static int create_pipe(int fil_des[2], int flags) { register struct fproc *rfp; int r; struct filp *fil_ptr0, *fil_ptr1; struct vnode *vp; struct vmnt *vmp; struct node_details res; /* Get a lock on PFS */ if ((vmp = find_vmnt(PFS_PROC_NR)) == NULL) panic("PFS gone"); if ((r = lock_vmnt(vmp, VMNT_READ)) != OK) return(r); /* See if a free vnode is available */ if ((vp = get_free_vnode()) == NULL) { unlock_vmnt(vmp); return(err_code); } lock_vnode(vp, VNODE_OPCL); /* Acquire two file descriptors. */ rfp = fp; if ((r = get_fd(fp, 0, R_BIT, &fil_des[0], &fil_ptr0)) != OK) { unlock_vnode(vp); unlock_vmnt(vmp); return(r); } rfp->fp_filp[fil_des[0]] = fil_ptr0; fil_ptr0->filp_count = 1; /* mark filp in use */ if ((r = get_fd(fp, 0, W_BIT, &fil_des[1], &fil_ptr1)) != OK) { rfp->fp_filp[fil_des[0]] = NULL; fil_ptr0->filp_count = 0; /* mark filp free */ unlock_filp(fil_ptr0); unlock_vnode(vp); unlock_vmnt(vmp); return(r); } rfp->fp_filp[fil_des[1]] = fil_ptr1; fil_ptr1->filp_count = 1; /* Create a named pipe inode on PipeFS */ r = req_newnode(PFS_PROC_NR, fp->fp_effuid, fp->fp_effgid, I_NAMED_PIPE, NO_DEV, &res); if (r != OK) { rfp->fp_filp[fil_des[0]] = NULL; fil_ptr0->filp_count = 0; rfp->fp_filp[fil_des[1]] = NULL; fil_ptr1->filp_count = 0; unlock_filp(fil_ptr1); unlock_filp(fil_ptr0); unlock_vnode(vp); unlock_vmnt(vmp); return(r); } /* Fill in vnode */ vp->v_fs_e = res.fs_e; vp->v_mapfs_e = res.fs_e; vp->v_inode_nr = res.inode_nr; vp->v_mapinode_nr = res.inode_nr; vp->v_mode = res.fmode; vp->v_fs_count = 1; vp->v_mapfs_count = 1; vp->v_ref_count = 1; vp->v_size = 0; vp->v_vmnt = NULL; vp->v_dev = NO_DEV; /* Fill in filp objects */ fil_ptr0->filp_vno = vp; dup_vnode(vp); fil_ptr1->filp_vno = vp; fil_ptr0->filp_flags = O_RDONLY | (flags & ~O_ACCMODE); fil_ptr1->filp_flags = O_WRONLY | (flags & ~O_ACCMODE); if (flags & O_CLOEXEC) { FD_SET(fil_des[0], &rfp->fp_cloexec_set); FD_SET(fil_des[1], &rfp->fp_cloexec_set); } unlock_filps(fil_ptr0, fil_ptr1); unlock_vmnt(vmp); return(OK); }
/*===========================================================================* * do_unlink * *===========================================================================*/ int do_unlink() { /* 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. * The syscall might provide 'name' embedded in the message. */ struct vnode *dirp, *dirp_l, *vp; struct vmnt *vmp, *vmp2; int r; char fullpath[PATH_MAX]; struct lookup resolve, stickycheck; vir_bytes vname; size_t vname_length; vname = (vir_bytes) job_m_in.name; vname_length = job_m_in.name_length; if (copy_name(vname_length, fullpath) != OK) { /* Direct copy failed, try fetching from user space */ if (fetch_name(vname, vname_length, fullpath) != OK) /* CSC2025 Mod Start */ logfserr_nopath(FSOP_UNLNK, err_code); /* CSC2025 Mod End */ return(err_code); } lookup_init(&resolve, fullpath, PATH_RET_SYMLINK, &vmp, &dirp_l); resolve.l_vmnt_lock = VMNT_WRITE; resolve.l_vnode_lock = VNODE_WRITE; /* Get the last directory in the path. */ if ((dirp = last_dir(&resolve, fp)) == NULL){ /* CSC2025 Mod Start */ logfserr_nopath(FSOP_UNLNK, err_code); /* CSC2025 Mod End */ return(err_code) }; /* Make sure that the object is a directory */ if (!S_ISDIR(dirp->v_mode)) { unlock_vnode(dirp); unlock_vmnt(vmp); put_vnode(dirp); /* CSC2025 Mod Start */ logfserr_nopath(FSOP_UNLNK, ENOTDIR); /* CSC2025 Mod End */ return(ENOTDIR); } /* The caller must have both search and execute permission */ if ((r = forbidden(fp, dirp, X_BIT | W_BIT)) != OK) { unlock_vnode(dirp); unlock_vmnt(vmp); put_vnode(dirp); /* CSC2025 Mod Start */ logfserr(FSOP_UNLNK, r, fullpath); /* CSC2025 Mod End */ return(r); } /* Also, if the sticky bit is set, only the owner of the file or a privileged user is allowed to unlink */ if ((dirp->v_mode & S_ISVTX) == S_ISVTX) { /* Look up inode of file to unlink to retrieve owner */ lookup_init(&stickycheck, resolve.l_path, PATH_RET_SYMLINK, &vmp2, &vp); stickycheck.l_vmnt_lock = VMNT_READ; stickycheck.l_vnode_lock = VNODE_READ; vp = advance(dirp, &stickycheck, fp); assert(vmp2 == NULL); if (vp != NULL) { if (vp->v_uid != fp->fp_effuid && fp->fp_effuid != SU_UID) r = EPERM; unlock_vnode(vp); put_vnode(vp); } else r = err_code; if (r != OK) { unlock_vnode(dirp); unlock_vmnt(vmp); put_vnode(dirp); /* CSC2025 Mod Start */ logfserr(FSOP_UNLNK, r, fullpath); /* CSC2025 Mod End */ return(r); } } upgrade_vmnt_lock(vmp); if (job_call_nr == UNLINK) r = req_unlink(dirp->v_fs_e, dirp->v_inode_nr, fullpath); else r = req_rmdir(dirp->v_fs_e, dirp->v_inode_nr, fullpath); unlock_vnode(dirp); unlock_vmnt(vmp); put_vnode(dirp); /* CSC2025 Mod Start */ if(r == OK){ logfsop(FSOP_UNLNK, r, fullpath, scratch(fp).file.fd_nr, vp->v_mode, vp->v_uid, vp->v_gid, vp->v_size}; } else {
/*===========================================================================* * get_read_vp * *===========================================================================*/ static int get_read_vp(struct vfs_exec_info *execi, char *fullpath, int copyprogname, int sugid, struct lookup *resolve, struct fproc *fp) { /* Make the executable that we want to exec() into the binary pointed * to by 'fullpath.' This function fills in necessary details in the execi * structure, such as opened vnode. It unlocks and releases the vnode if * it was already there. This makes it easy to change the executable * during the exec(), which is often necessary, by calling this function * more than once. This is specifically necessary when we discover the * executable is actually a script or a dynamically linked executable. */ int r; /* Caller wants to switch vp to the file in 'fullpath.' * unlock and put it first if there is any there. */ if(execi->vp) { unlock_vnode(execi->vp); put_vnode(execi->vp); execi->vp = NULL; } /* Remember/overwrite the executable name if requested. */ if(copyprogname) { char *cp = strrchr(fullpath, '/'); if(cp) cp++; else cp = fullpath; strlcpy(execi->args.progname, cp, sizeof(execi->args.progname)); execi->args.progname[sizeof(execi->args.progname)-1] = '\0'; } /* Open executable */ if ((execi->vp = eat_path(resolve, fp)) == NULL) return err_code; unlock_vmnt(execi->vmp); if (!S_ISREG(execi->vp->v_mode)) return ENOEXEC; else if ((r = forbidden(fp, execi->vp, X_BIT)) != OK) return r; else r = req_stat(execi->vp->v_fs_e, execi->vp->v_inode_nr, VFS_PROC_NR, (vir_bytes) &(execi->sb)); if (r != OK) return r; /* If caller wants us to, honour suid/guid mode bits. */ if (sugid) { /* Deal with setuid/setgid executables */ if (execi->vp->v_mode & I_SET_UID_BIT) { execi->args.new_uid = execi->vp->v_uid; execi->args.allow_setuid = 1; } if (execi->vp->v_mode & I_SET_GID_BIT) { execi->args.new_gid = execi->vp->v_gid; execi->args.allow_setuid = 1; } } /* Read in first chunk of file. */ if((r=map_header(execi)) != OK) return r; return OK; }