From: David van Moolenbroek Date: Mon, 19 Aug 2013 23:35:35 +0000 (+0200) Subject: Align "struct statvfs" with NetBSD X-Git-Tag: v3.3.0~628 X-Git-Url: http://zhaoyanbai.com/repos/?a=commitdiff_plain;h=refs%2Fchanges%2F30%2F930%2F2;p=minix.git 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 --- diff --git a/lib/libpuffs/stadir.c b/lib/libpuffs/stadir.c index f232aae0b..5e7f2fd17 100644 --- a/lib/libpuffs/stadir.c +++ b/lib/libpuffs/stadir.c @@ -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); diff --git a/lib/libsffs/misc.c b/lib/libsffs/misc.c index acb06c8b3..89d43b19c 100644 --- a/lib/libsffs/misc.c +++ b/lib/libsffs/misc.c @@ -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, diff --git a/lib/libvtreefs/stadir.c b/lib/libvtreefs/stadir.c index 35b720391..82c313334 100644 --- a/lib/libvtreefs/stadir.c +++ b/lib/libvtreefs/stadir.c @@ -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, diff --git a/servers/ext2/stadir.c b/servers/ext2/stadir.c index c675dfd56..cc08c872f 100644 --- a/servers/ext2/stadir.c +++ b/servers/ext2/stadir.c @@ -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. */ diff --git a/servers/iso9660fs/stadir.c b/servers/iso9660fs/stadir.c index bffe2221e..2db8eb30b 100644 --- a/servers/iso9660fs/stadir.c +++ b/servers/iso9660fs/stadir.c @@ -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. */ diff --git a/servers/mfs/stadir.c b/servers/mfs/stadir.c index 9597acf99..85d55d2b1 100644 --- a/servers/mfs/stadir.c +++ b/servers/mfs/stadir.c @@ -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. */ diff --git a/servers/vfs/proto.h b/servers/vfs/proto.h index 3b503a000..d4281543f 100644 --- a/servers/vfs/proto.h +++ b/servers/vfs/proto.h @@ -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); diff --git a/servers/vfs/request.c b/servers/vfs/request.c index ba97b373b..819c6bbef 100644 --- a/servers/vfs/request.c +++ b/servers/vfs/request.c @@ -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; diff --git a/servers/vfs/stadir.c b/servers/vfs/stadir.c index 0977d9ec4..0ebad883e 100644 --- a/servers/vfs/stadir.c +++ b/servers/vfs/stadir.c @@ -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); diff --git a/sys/sys/statvfs.h b/sys/sys/statvfs.h index f663f152f..c1cd4df6a 100644 --- a/sys/sys/statvfs.h +++ b/sys/sys/statvfs.h @@ -37,6 +37,7 @@ #include #include #include +#include #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_ */