Ejemplo n.º 1
0
/*===========================================================================*
 *				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;
}
Ejemplo n.º 2
0
int
fstatvfs(int fd, struct statvfs *statvfs)
{
	struct stat stat;
	if (fstat(fd, &stat) < 0)
		return -1;

	return fill_statvfs(stat.st_dev, statvfs);
}
Ejemplo n.º 3
0
int
statvfs(const char *path, struct statvfs *statvfs)
{
	dev_t device = dev_for_path(path);
	if (device < 0)
		return -1;

	return fill_statvfs(device, statvfs);
}
Ejemplo n.º 4
0
/*===========================================================================*
 *				do_fstatvfs				     *
 *===========================================================================*/
int do_fstatvfs(void)
{
/* Perform the fstatvfs1(fd, buf, flags) system call. */
  register struct filp *rfilp;
  int r, rfd, flags;
  vir_bytes statbuf;

  rfd = job_m_in.m_lc_vfs_statvfs1.fd;
  statbuf = job_m_in.m_lc_vfs_statvfs1.buf;
  flags = job_m_in.m_lc_vfs_statvfs1.flags;

  /* Is the file descriptor valid? */
  if ((rfilp = get_filp(rfd, VNODE_READ)) == NULL) return(err_code);
  r = fill_statvfs(rfilp->filp_vno->v_vmnt, who_e, statbuf, flags);

  unlock_filp(rfilp);

  return(r);
}
Ejemplo n.º 5
0
/*===========================================================================*
 *				do_getvfsstat				     *
 *===========================================================================*/
int do_getvfsstat(void)
{
/* Perform the getvfsstat(buf, bufsize, flags) system call. */
  struct vmnt *vmp;
  vir_bytes buf;
  size_t bufsize;
  int r, flags, count, do_lock;

  buf = job_m_in.m_lc_vfs_getvfsstat.buf;
  bufsize = job_m_in.m_lc_vfs_getvfsstat.len;
  flags = job_m_in.m_lc_vfs_getvfsstat.flags;

  count = 0;

  if (buf != 0) {
	/* We only need to lock target file systems if we are going to query
	 * them.  This will only happen if ST_NOWAIT is not given.  If we do
	 * not lock, we rely on the VMNT_CANSTAT flag to protect us from
	 * concurrent (un)mount operations.  Note that procfs relies on
	 * ST_NOWAIT calls being lock free, as it is a file system itself.
	 */
	do_lock = !(flags & ST_NOWAIT);

	for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; vmp++) {
		/* If there is no more space, return the count so far. */
		if (bufsize < sizeof(struct statvfs))
			break;

		/* Lock the file system before checking any fields. */
		if (do_lock && (r = lock_vmnt(vmp, VMNT_READ)) != OK)
			return r;

		/* Obtain information for this file system, if it is in use and
		 * can be reported.  File systems that are being (un)mounted
		 * are skipped, as is PFS.  The fill call will block only if
		 * ST_NOWAIT was not given.
		 */
		if (vmp->m_dev != NO_DEV && (vmp->m_flags & VMNT_CANSTAT)) {
			if ((r = fill_statvfs(vmp, who_e, buf, flags)) != OK) {
				if (do_lock)
					unlock_vmnt(vmp);

				return r;
			}

			count++;
			buf += sizeof(struct statvfs);
			bufsize -= sizeof(struct statvfs);
		}

		if (do_lock)
			unlock_vmnt(vmp);
	}
  } else {
	/* Just report a file system count.  No need to lock, as above. */
	for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; vmp++) {
		if (vmp->m_dev != NO_DEV && (vmp->m_flags & VMNT_CANSTAT))
			count++;
	}
  }

  return count;
}