From ce9255cc9f9ab24e1433f13fe1e776b3bb232468 Mon Sep 17 00:00:00 2001
From: dchagin <dchagin@FreeBSD.org>
Date: Sun, 27 Mar 2016 06:10:51 +0000
Subject: MFC r297061;

Implement fstatfs64 system call.

PR:		181012
Submitted by:	John Wehle
---
 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 f96acc0..fe31a9b 100644
--- a/sys/compat/linux/linux_stats.c
+++ b/sys/compat/linux/linux_stats.c
@@ -459,6 +459,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 c1237fc26ea15df3a3b3c65770fabc5a7080edf0 Mon Sep 17 00:00:00 2001
From: dchagin <dchagin@FreeBSD.org>
Date: Sun, 27 Mar 2016 06:21:05 +0000
Subject: MFC r297063:    Whitespaces, style(9) fixes. No functional changes.

MFC r297070:
  Return EOVERFLOW in case when actual statfs values are large enough and
  not fit into 32 bit fileds of a Linux struct statfs.

MFC r297072:

  Check bsd_to_linux_statfs() return value.
---
 sys/compat/linux/linux_stats.c | 38 ++++++++++++++++++++++++++++----------
 1 file changed, 28 insertions(+), 10 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 fe31a9b..2684d82 100644
--- a/sys/compat/linux/linux_stats.c
+++ b/sys/compat/linux/linux_stats.c
@@ -256,7 +256,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;
@@ -302,7 +302,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
@@ -324,7 +324,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) */
 
@@ -380,10 +380,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;
@@ -394,6 +406,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
@@ -414,8 +428,10 @@ linux_statfs(struct thread *td, struct linux_statfs_args *args)
 	LFREEPATH(path);
 	if (error)
 		return (error);
-	bsd_to_linux_statfs(&bsd_statfs, &linux_statfs);
-	return copyout(&linux_statfs, args->buf, sizeof(linux_statfs));
+	error = bsd_to_linux_statfs(&bsd_statfs, &linux_statfs);
+	if (error)
+		return (error);
+	return (copyout(&linux_statfs, args->buf, sizeof(linux_statfs)));
 }
 
 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
@@ -457,7 +473,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
@@ -495,9 +511,11 @@ 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 copyout(&linux_statfs, args->buf, sizeof(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)));
 }
 
 struct l_ustat
-- 
cgit v1.1