Align "struct statvfs" with NetBSD

This is a requirement for implementing calls such as getmntinfo(3).
VFS is now responsible for filling in some of the structure's fields.

Change-Id: I0c1fa78019587efefd2949b3be38cd9a7ddc2ced
This commit is contained in:
David van Moolenbroek 2013-08-20 01:35:35 +02:00 committed by Lionel Sambuc
parent f10229eafb
commit 61ed526374
10 changed files with 97 additions and 48 deletions

View file

@ -83,6 +83,8 @@ int fs_statvfs()
int r;
struct statvfs st;
memset(&st, 0, sizeof(st));
if (global_pu->pu_ops.puffs_fs_statvfs(global_pu, &st) != 0) {
lpuffs_debug("statvfs failed\n");
return(EINVAL);

View file

@ -43,17 +43,13 @@ int do_statvfs()
/* Returning zero for unknown values seems to be the convention. However, we
* do have to use a nonzero block size, even though it is entirely arbitrary.
*/
statvfs.f_flag = ST_NOTRUNC;
statvfs.f_bsize = BLOCK_SIZE;
statvfs.f_frsize = BLOCK_SIZE;
statvfs.f_iosize = BLOCK_SIZE;
statvfs.f_blocks = div64u(total, BLOCK_SIZE);
statvfs.f_bfree = div64u(free, BLOCK_SIZE);
statvfs.f_bavail = statvfs.f_bfree;
statvfs.f_files = 0;
statvfs.f_ffree = 0;
statvfs.f_favail = 0;
statvfs.f_fsid = state.s_dev;
statvfs.f_flag = state.s_read_only ? ST_RDONLY : 0;
statvfs.f_flag |= ST_NOTRUNC;
statvfs.f_namemax = NAME_MAX;
return sys_safecopyto(m_in.m_source, m_in.REQ_GRANT, 0,

View file

@ -65,8 +65,7 @@ int fs_statvfs(void)
memset(&statvfs, 0, sizeof(statvfs));
statvfs.f_fsid = fs_dev;
statvfs.f_flag = ST_RDONLY | ST_NOTRUNC;
statvfs.f_flag = ST_NOTRUNC;
statvfs.f_namemax = PNAME_MAX;
return sys_safecopyto(fs_m_in.m_source, fs_m_in.REQ_GRANT, 0,

View file

@ -84,19 +84,20 @@ int fs_statvfs()
struct super_block *sp;
int r;
memset(&st, 0, sizeof(st));
sp = get_super(fs_dev);
st.f_flag = ST_NOTRUNC;
st.f_bsize = sp->s_block_size;
st.f_frsize = sp->s_block_size;
st.f_iosize = sp->s_block_size;
st.f_blocks = sp->s_blocks_count;
st.f_bfree = sp->s_free_blocks_count;
st.f_bavail = sp->s_free_blocks_count - sp->s_r_blocks_count;
st.f_files = sp->s_inodes_count;
st.f_ffree = sp->s_free_inodes_count;
st.f_favail = sp->s_free_inodes_count;
st.f_fsid = fs_dev;
st.f_flag = (sp->s_rd_only == 1 ? ST_RDONLY : 0);
st.f_flag |= ST_NOTRUNC;
st.f_namemax = NAME_MAX;
/* Copy the struct to user space. */

View file

@ -100,17 +100,12 @@ int fs_statvfs()
struct statvfs st;
int r;
memset(&st, 0, sizeof(st));
st.f_bsize = v_pri.logical_block_size_l;
st.f_frsize = st.f_bsize;
st.f_iosize = st.f_bsize;
st.f_blocks = v_pri.volume_space_size_l;
st.f_bfree = 0;
st.f_bavail = 0;
st.f_files = 0;
st.f_ffree = 0;
st.f_favail = 0;
st.f_fsid = fs_dev;
st.f_flag = ST_RDONLY;
st.f_namemax = NAME_MAX;
/* Copy the struct to user space. */

View file

@ -99,16 +99,17 @@ int fs_statvfs()
scale = sp->s_log_zone_size;
memset(&st, 0, sizeof(st));
fs_blockstats(&st.f_blocks, &st.f_bfree, &used);
st.f_bavail = st.f_bfree;
st.f_bsize = sp->s_block_size << scale;
st.f_frsize = sp->s_block_size;
st.f_iosize = st.f_frsize;
st.f_files = sp->s_ninodes;
st.f_ffree = count_free_bits(sp, IMAP);
st.f_favail = st.f_ffree;
st.f_fsid = fs_dev;
st.f_flag = (sp->s_rd_only == 1 ? ST_RDONLY : 0);
st.f_namemax = MFS_DIRSIZ;
/* Copy the struct to user space. */

View file

@ -238,7 +238,7 @@ int req_chown(endpoint_t fs_e, ino_t inode_nr, uid_t newuid, gid_t newgid,
int req_create(endpoint_t fs_e, ino_t inode_nr, int omode, uid_t uid,
gid_t gid, char *path, node_details_t *res);
int req_flush(endpoint_t fs_e, dev_t dev);
int req_statvfs(endpoint_t fs_e, endpoint_t proc_e, vir_bytes buf);
int req_statvfs(endpoint_t fs_e, struct statvfs *buf);
int req_ftrunc(endpoint_t fs_e, ino_t inode_nr, off_t start, off_t end);
int req_getdents(endpoint_t fs_e, ino_t inode_nr, off_t pos, char *buf,
size_t size, off_t *new_pos, int direct, int getdents_321);

View file

@ -226,16 +226,16 @@ int req_flush(endpoint_t fs_e, dev_t dev)
/*===========================================================================*
* req_statvfs *
*===========================================================================*/
int req_statvfs(endpoint_t fs_e, endpoint_t proc_e, vir_bytes buf)
int req_statvfs(endpoint_t fs_e, struct statvfs *buf)
{
int r;
cp_grant_id_t grant_id;
message m;
grant_id = cpf_grant_magic(fs_e, proc_e, buf, sizeof(struct statvfs),
grant_id = cpf_grant_direct(fs_e, (vir_bytes) buf, sizeof(struct statvfs),
CPF_WRITE);
if(grant_id == GRANT_INVALID)
panic("req_statvfs: cpf_grant_magic failed");
panic("req_statvfs: cpf_grant_direct failed");
/* Fill in request message */
m.m_type = REQ_STATVFS;

View file

@ -208,12 +208,43 @@ int do_fstat(message *UNUSED(m_out))
return(r);
}
/*===========================================================================*
* fill_statvfs *
*===========================================================================*/
static int fill_statvfs(struct vnode *vp, endpoint_t endpt, vir_bytes buf_addr)
{
/* Fill a statvfs structure in a userspace process. First let the target file
* server (as identified by the given vnode) fill in most fields. Then fill in
* some remaining fields with local information. Finally, copy the result to
* user space.
*/
struct statvfs buf;
struct vmnt *vmp;
int r;
vmp = vp->v_vmnt;
if ((r = req_statvfs(vp->v_fs_e, &buf)) != OK)
return r;
if (vmp->m_flags & VMNT_READONLY)
buf.f_flag |= ST_RDONLY;
buf.f_fsid = vmp->m_dev;
strlcpy(buf.f_fstypename, "", sizeof(buf.f_fstypename)); /* FIXME */
strlcpy(buf.f_mntonname, vmp->m_mount_path, sizeof(buf.f_mntonname));
strlcpy(buf.f_mntfromname, vmp->m_mount_dev, sizeof(buf.f_mntfromname));
return sys_datacopy(SELF, (vir_bytes) &buf, endpt, buf_addr, sizeof(buf));
}
/*===========================================================================*
* do_statvfs *
*===========================================================================*/
int do_statvfs(message *UNUSED(m_out))
{
/* Perform the stat(name, buf) system call. */
/* Perform the statvfs(name, buf) system call. */
int r;
struct vnode *vp;
struct vmnt *vmp;
@ -232,7 +263,7 @@ int do_statvfs(message *UNUSED(m_out))
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);
r = fill_statvfs(vp, who_e, statbuf);
unlock_vnode(vp);
unlock_vmnt(vmp);
@ -246,7 +277,7 @@ int do_statvfs(message *UNUSED(m_out))
*===========================================================================*/
int do_fstatvfs(message *UNUSED(m_out))
{
/* Perform the fstat(fd, buf) system call. */
/* Perform the fstatvfs(fd, buf) system call. */
register struct filp *rfilp;
int r, rfd;
vir_bytes statbuf;
@ -256,7 +287,7 @@ int do_fstatvfs(message *UNUSED(m_out))
/* Is the file descriptor valid? */
if ((rfilp = get_filp(rfd, VNODE_READ)) == NULL) return(err_code);
r = req_statvfs(rfilp->filp_vno->v_fs_e, who_e, statbuf);
r = fill_statvfs(rfilp->filp_vno, who_e, statbuf);
unlock_filp(rfilp);

View file

@ -37,6 +37,7 @@
#include <sys/stdint.h>
#include <machine/ansi.h>
#include <sys/ansi.h>
#include <sys/fstypes.h>
#define _VFS_NAMELEN 32
#define _VFS_MNAMELEN 1024
@ -63,28 +64,51 @@ typedef _BSD_SIZE_T_ size_t;
#endif
struct statvfs {
unsigned long f_bsize; /* File system block size. */
unsigned long f_frsize; /* Fundamental file system block size. */
fsblkcnt_t f_blocks; /* Total number of blocks on file system */
/* in units of f_frsize. */
fsblkcnt_t f_bfree; /* Total number of free blocks. */
fsblkcnt_t f_bavail; /* Number of free blocks available to */
/* non-privileged process. */
fsfilcnt_t f_files; /* Total number of file serial numbers. */
fsfilcnt_t f_ffree; /* Total number of free file serial numbers. */
fsfilcnt_t f_favail; /* Number of file serial numbers available */
/* to non-privileged process. */
unsigned long f_fsid; /* File system ID. */
unsigned long f_flag; /* Bit mask of f_flag values. */
unsigned long f_namemax; /* Maximum filename length. */
unsigned char __padding[32]; /* Padding for future compatibility */
unsigned long f_flag; /* copy of mount exported flags */
unsigned long f_bsize; /* file system block size */
unsigned long f_frsize; /* fundamental file system block size */
unsigned long f_iosize; /* optimal file system block size */
/* The following are in units of f_frsize */
fsblkcnt_t f_blocks; /* number of blocks in file system, */
fsblkcnt_t f_bfree; /* free blocks avail in file system */
fsblkcnt_t f_bavail; /* free blocks avail to non-root */
fsblkcnt_t f_bresvd; /* blocks reserved for root */
fsfilcnt_t f_files; /* total file nodes in file system */
fsfilcnt_t f_ffree; /* free file nodes in file system */
fsfilcnt_t f_favail; /* free file nodes avail to non-root */
fsfilcnt_t f_fresvd; /* file nodes reserved for root */
uint64_t f_syncreads; /* count of sync reads since mount */
uint64_t f_syncwrites; /* count of sync writes since mount */
uint64_t f_asyncreads; /* count of async reads since mount */
uint64_t f_asyncwrites; /* count of async writes since mount */
fsid_t f_fsidx; /* NetBSD compatible fsid */
unsigned long f_fsid; /* Posix compatible fsid */
unsigned long f_namemax; /* maximum filename length */
uid_t f_owner; /* user that mounted the file system */
uint32_t f_spare[4]; /* spare space */
char f_fstypename[_VFS_NAMELEN]; /* fs type name */
char f_mntonname[_VFS_MNAMELEN]; /* directory on which mounted */
char f_mntfromname[_VFS_MNAMELEN]; /* mounted file system */
};
/* Possible values for statvfs->f_flag */
#define ST_RDONLY 0x1
#define ST_NOSUID 0x2
#if defined(_NETBSD_SOURCE) && !defined(_POSIX_SOURCE) && \
!defined(_XOPEN_SOURCE)
#define VFS_NAMELEN _VFS_NAMELEN
#define VFS_MNAMELEN _VFS_MNAMELEN
#endif
#define ST_RDONLY MNT_RDONLY
#define ST_NOSUID MNT_NOSUID
#ifdef __minix
#define ST_NOTRUNC 0x4
#define ST_NOTRUNC __MNT_UNUSED1
#endif /* !__minix*/
__BEGIN_DECLS
@ -92,4 +116,4 @@ int statvfs(const char *__restrict, struct statvfs *__restrict);
int fstatvfs(int, struct statvfs *);
__END_DECLS
#endif /* _SYS_STATVFS_H_ */
#endif /* !_SYS_STATVFS_H_ */