/* * Called for stat(). * Set the type and the size (block devices only). * The link count for a device is always 1. */ static int dev_stat(struct vnode *v, struct stat *statbuf) { struct device *d = v->vn_data; int result; bzero(statbuf, sizeof(struct stat)); result = VOP_GETTYPE(v, &statbuf->st_mode); if (result) { return result; } statbuf->st_nlink = 1; statbuf->st_blocks = d->d_blocks; if (d->d_blocks > 0) { statbuf->st_size = d->d_blocks * d->d_blocksize; } else { statbuf->st_size = 0; } return 0; }
/* * Called for stat(). * Set the type and the size (block devices only). * The link count for a device is always 1. */ static int dev_stat(struct vnode *v, struct stat *statbuf) { struct device *d = v->vn_data; int result; bzero(statbuf, sizeof(struct stat)); if (d->d_blocks > 0) { statbuf->st_size = d->d_blocks * d->d_blocksize; statbuf->st_blksize = d->d_blocksize; } else { statbuf->st_size = 0; } result = VOP_GETTYPE(v, &statbuf->st_mode); if (result) { return result; } /* Make up some plausible default permissions. */ statbuf->st_mode |= 0600; statbuf->st_nlink = 1; statbuf->st_blocks = d->d_blocks; /* The device number this device sits on (in OS/161, it doesn't) */ statbuf->st_dev = 0; /* The device number this device *is* */ statbuf->st_rdev = d->d_devnumber; return 0; }
/* * Called for stat/fstat/lstat. */ static int sfs_stat(struct vnode *v, struct stat *statbuf) { struct sfs_vnode *sv = v->vn_data; int result; /* Fill in the stat structure */ bzero(statbuf, sizeof(struct stat)); result = VOP_GETTYPE(v, &statbuf->st_mode); if (result) { return result; } statbuf->st_size = sv->sv_i.sfi_size; /* We don't support these yet; you get to implement them */ statbuf->st_nlink = 0; statbuf->st_blocks = 0; /* Fill in other field as desired/possible... */ return 0; }
/* * Set current directory as a vnode. * The passed vnode must in fact be a directory. */ int vfs_setcurdir(struct vnode *dir) { struct vnode *old; mode_t vtype; int result; result = VOP_GETTYPE(dir, &vtype); if (result) { return result; } if (vtype != S_IFDIR) { return ENOTDIR; } VOP_INCREF(dir); spinlock_acquire(&curproc->p_lock); old = curproc->p_cwd; curproc->p_cwd = dir; spinlock_release(&curproc->p_lock); if (old!=NULL) { VOP_DECREF(old); } return 0; }
/* * Called for stat/fstat/lstat. * * Locking: gets/releases vnode lock. * * Requires 1 buffer. */ static int sfs_stat(struct vnode *v, struct stat *statbuf) { struct sfs_vnode *sv = v->vn_data; struct sfs_dinode *inodeptr; int result; /* Fill in the stat structure */ bzero(statbuf, sizeof(struct stat)); result = VOP_GETTYPE(v, &statbuf->st_mode); if (result) { return result; } lock_acquire(sv->sv_lock); reserve_buffers(SFS_BLOCKSIZE); result = sfs_dinode_load(sv); if (result) { unreserve_buffers(SFS_BLOCKSIZE); lock_release(sv->sv_lock); return result; } inodeptr = sfs_dinode_map(sv); statbuf->st_size = inodeptr->sfi_size; statbuf->st_nlink = inodeptr->sfi_linkcount; /* We don't support this yet */ statbuf->st_blocks = 0; /* Fill in other fields as desired/possible... */ sfs_dinode_unload(sv); unreserve_buffers(SFS_BLOCKSIZE); lock_release(sv->sv_lock); return 0; }
/* * VOP_STAT */ static int emufs_stat(struct vnode *v, struct stat *statbuf) { struct emufs_vnode *ev = v->vn_data; int result; bzero(statbuf, sizeof(struct stat)); result = emu_getsize(ev->ev_emu, ev->ev_handle, &statbuf->st_size); if (result) { return result; } result = VOP_GETTYPE(v, &statbuf->st_mode); if (result) { return result; } statbuf->st_mode |= 0644; /* possibly a lie */ statbuf->st_nlink = 1; /* might be a lie, but doesn't matter much */ statbuf->st_blocks = 0; /* almost certainly a lie */ return 0; }