From 6aee9bb2b457e5615395d8e3a5527d87e6fe441f Mon Sep 17 00:00:00 2001 From: dchagin Date: Sun, 20 Mar 2016 13:21:20 +0000 Subject: Implement fstatfs64 system call. PR: 181012 Submitted by: John Wehle MFC after: 1 week --- sys/compat/linux/linux_stats.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'sys/compat/linux/linux_stats.c') diff --git a/sys/compat/linux/linux_stats.c b/sys/compat/linux/linux_stats.c index 84ade7b..6adaba9 100644 --- a/sys/compat/linux/linux_stats.c +++ b/sys/compat/linux/linux_stats.c @@ -460,6 +460,27 @@ linux_statfs64(struct thread *td, struct linux_statfs64_args *args) bsd_to_linux_statfs64(&bsd_statfs, &linux_statfs); return copyout(&linux_statfs, args->buf, sizeof(linux_statfs)); } + +int +linux_fstatfs64(struct thread *td, struct linux_fstatfs64_args *args) +{ + struct l_statfs64 linux_statfs; + struct statfs bsd_statfs; + int error; + +#ifdef DEBUG + if (ldebug(fstatfs64)) + printf(ARGS(fstatfs64, "%d, *"), args->fd); +#endif + if (args->bufsize != sizeof(struct l_statfs64)) + return (EINVAL); + + error = kern_fstatfs(td, args->fd, &bsd_statfs); + if (error) + return error; + bsd_to_linux_statfs64(&bsd_statfs, &linux_statfs); + return (copyout(&linux_statfs, args->buf, sizeof(linux_statfs))); +} #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ int -- cgit v1.1 From 92b588e58f2f0be41d0f5566ea5b4a97e681b33d Mon Sep 17 00:00:00 2001 From: dchagin Date: Sun, 20 Mar 2016 14:06:27 +0000 Subject: Whitespaces, style(9) fixes. No functional changes. MFC after: 1 week --- sys/compat/linux/linux_stats.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'sys/compat/linux/linux_stats.c') diff --git a/sys/compat/linux/linux_stats.c b/sys/compat/linux/linux_stats.c index 6adaba9..f27e342 100644 --- a/sys/compat/linux/linux_stats.c +++ b/sys/compat/linux/linux_stats.c @@ -257,7 +257,7 @@ static int stat_copyout(struct stat *buf, void *ubuf) { struct l_stat lbuf; - + bzero(&lbuf, sizeof(lbuf)); lbuf.st_dev = buf->st_dev; lbuf.st_ino = buf->st_ino; @@ -303,7 +303,7 @@ linux_stat(struct thread *td, struct linux_stat_args *args) return (error); } LFREEPATH(path); - return(stat_copyout(&buf, args->up)); + return (stat_copyout(&buf, args->up)); } int @@ -325,7 +325,7 @@ linux_lstat(struct thread *td, struct linux_lstat_args *args) return (error); } LFREEPATH(path); - return(stat_copyout(&buf, args->up)); + return (stat_copyout(&buf, args->up)); } #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ @@ -416,7 +416,7 @@ linux_statfs(struct thread *td, struct linux_statfs_args *args) if (error) return (error); bsd_to_linux_statfs(&bsd_statfs, &linux_statfs); - return copyout(&linux_statfs, args->buf, sizeof(linux_statfs)); + return (copyout(&linux_statfs, args->buf, sizeof(linux_statfs))); } #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) @@ -458,7 +458,7 @@ linux_statfs64(struct thread *td, struct linux_statfs64_args *args) if (error) return (error); bsd_to_linux_statfs64(&bsd_statfs, &linux_statfs); - return copyout(&linux_statfs, args->buf, sizeof(linux_statfs)); + return (copyout(&linux_statfs, args->buf, sizeof(linux_statfs))); } int @@ -498,7 +498,7 @@ linux_fstatfs(struct thread *td, struct linux_fstatfs_args *args) if (error) return error; bsd_to_linux_statfs(&bsd_statfs, &linux_statfs); - return copyout(&linux_statfs, args->buf, sizeof(linux_statfs)); + return (copyout(&linux_statfs, args->buf, sizeof(linux_statfs))); } struct l_ustat -- cgit v1.1 From ac3634b69618f44c63bcbe384b0504160fe6debc Mon Sep 17 00:00:00 2001 From: dchagin Date: Sun, 20 Mar 2016 18:31:30 +0000 Subject: Return EOVERFLOW in case when actual statfs values are large enough and not fit into 32 bit fileds of a Linux struct statfs. PR: 181012 MFC after: 1 week --- sys/compat/linux/linux_stats.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'sys/compat/linux/linux_stats.c') diff --git a/sys/compat/linux/linux_stats.c b/sys/compat/linux/linux_stats.c index f27e342..7b4017e 100644 --- a/sys/compat/linux/linux_stats.c +++ b/sys/compat/linux/linux_stats.c @@ -381,10 +381,22 @@ bsd_to_linux_ftype(const char *fstypename) return (0L); } -static void +static int bsd_to_linux_statfs(struct statfs *bsd_statfs, struct l_statfs *linux_statfs) { +#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) + uint64_t tmp; +#define LINUX_HIBITS 0xffffffff00000000ULL + + tmp = bsd_statfs->f_blocks | bsd_statfs->f_bfree | bsd_statfs->f_files | + bsd_statfs->f_bsize; + if ((bsd_statfs->f_bavail != -1 && (bsd_statfs->f_bavail & LINUX_HIBITS)) || + (bsd_statfs->f_ffree != -1 && (bsd_statfs->f_ffree & LINUX_HIBITS)) || + (tmp & LINUX_HIBITS)) + return (EOVERFLOW); +#undef LINUX_HIBITS +#endif linux_statfs->f_type = bsd_to_linux_ftype(bsd_statfs->f_fstypename); linux_statfs->f_bsize = bsd_statfs->f_bsize; linux_statfs->f_blocks = bsd_statfs->f_blocks; @@ -395,6 +407,8 @@ bsd_to_linux_statfs(struct statfs *bsd_statfs, struct l_statfs *linux_statfs) linux_statfs->f_fsid.val[0] = bsd_statfs->f_fsid.val[0]; linux_statfs->f_fsid.val[1] = bsd_statfs->f_fsid.val[1]; linux_statfs->f_namelen = MAXNAMLEN; + + return (0); } int -- cgit v1.1 From 7490a137dd8aaed169fa6c9f170a8d77f824ce73 Mon Sep 17 00:00:00 2001 From: dchagin Date: Sun, 20 Mar 2016 19:06:21 +0000 Subject: Check bsd_to_linux_statfs() return value. Forgotten in r297070. MFC after: 1 week --- sys/compat/linux/linux_stats.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'sys/compat/linux/linux_stats.c') diff --git a/sys/compat/linux/linux_stats.c b/sys/compat/linux/linux_stats.c index 7b4017e..3638c6b 100644 --- a/sys/compat/linux/linux_stats.c +++ b/sys/compat/linux/linux_stats.c @@ -429,7 +429,9 @@ linux_statfs(struct thread *td, struct linux_statfs_args *args) LFREEPATH(path); if (error) return (error); - bsd_to_linux_statfs(&bsd_statfs, &linux_statfs); + error = bsd_to_linux_statfs(&bsd_statfs, &linux_statfs); + if (error) + return (error); return (copyout(&linux_statfs, args->buf, sizeof(linux_statfs))); } @@ -510,8 +512,10 @@ linux_fstatfs(struct thread *td, struct linux_fstatfs_args *args) #endif error = kern_fstatfs(td, args->fd, &bsd_statfs); if (error) - return error; - bsd_to_linux_statfs(&bsd_statfs, &linux_statfs); + return (error); + error = bsd_to_linux_statfs(&bsd_statfs, &linux_statfs); + if (error) + return (error); return (copyout(&linux_statfs, args->buf, sizeof(linux_statfs))); } -- cgit v1.1