From owner-freebsd-bugs@FreeBSD.ORG Sun Aug 4 10:50:01 2013 Return-Path: Delivered-To: freebsd-bugs@smarthost.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 3C3AAECD for ; Sun, 4 Aug 2013 10:50:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:1900:2254:206c::16:87]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 1AFB324E0 for ; Sun, 4 Aug 2013 10:50:01 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.7/8.14.7) with ESMTP id r74Ao05Q021369 for ; Sun, 4 Aug 2013 10:50:00 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.7/8.14.7/Submit) id r74Ao0ai021367; Sun, 4 Aug 2013 10:50:00 GMT (envelope-from gnats) Resent-Date: Sun, 4 Aug 2013 10:50:00 GMT Resent-Message-Id: <201308041050.r74Ao0ai021367@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Yuri Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 5E4DFEB8 for ; Sun, 4 Aug 2013 10:46:14 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from oldred.freebsd.org (oldred.freebsd.org [8.8.178.121]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 3C74C24D3 for ; Sun, 4 Aug 2013 10:46:14 +0000 (UTC) Received: from oldred.freebsd.org ([127.0.1.6]) by oldred.freebsd.org (8.14.5/8.14.7) with ESMTP id r74AkD9V068144 for ; Sun, 4 Aug 2013 10:46:13 GMT (envelope-from nobody@oldred.freebsd.org) Received: (from nobody@localhost) by oldred.freebsd.org (8.14.5/8.14.5/Submit) id r74AkDF4068143; Sun, 4 Aug 2013 10:46:13 GMT (envelope-from nobody) Message-Id: <201308041046.r74AkDF4068143@oldred.freebsd.org> Date: Sun, 4 Aug 2013 10:46:13 GMT From: Yuri To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Subject: kern/181012: [patch] Implemented linux system call fstatfs64 X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 04 Aug 2013 10:50:01 -0000 >Number: 181012 >Category: kern >Synopsis: [patch] Implemented linux system call fstatfs64 >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: update >Submitter-Id: current-users >Arrival-Date: Sun Aug 04 10:50:00 UTC 2013 >Closed-Date: >Last-Modified: >Originator: Yuri >Release: 9.1 >Organization: n/a >Environment: >Description: This patch implements linux call fstatfs64. Patch also fixes the problem when linux call fstatfs would return wrong values when actual FS stat value(s) are large enough to not fit into 32 bits. Patch is against rev.251126 Please also merge it into 9.X stable branch. >How-To-Repeat: >Fix: Patch attached with submission follows: --- sys/compat/linux/linux_stats.c (revision 251126) +++ sys/compat/linux/linux_stats.c (working copy) @@ -377,20 +377,27 @@ return (0L); } -static void +static int bsd_to_linux_statfs(struct statfs *bsd_statfs, struct l_statfs *linux_statfs) { - 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; linux_statfs->f_bfree = bsd_statfs->f_bfree; linux_statfs->f_bavail = bsd_statfs->f_bavail; + linux_statfs->f_files = bsd_statfs->f_files; linux_statfs->f_ffree = bsd_statfs->f_ffree; - linux_statfs->f_files = bsd_statfs->f_files; 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; + + if ((uint64_t)linux_statfs->f_blocks != bsd_statfs->f_blocks || + (uint64_t)linux_statfs->f_bfree != bsd_statfs->f_bfree || + (int64_t)linux_statfs->f_bavail != bsd_statfs->f_bavail || + (uint64_t)linux_statfs->f_files != bsd_statfs->f_files || + (int64_t)linux_statfs->f_ffree != bsd_statfs->f_ffree) + return EOVERFLOW; + return 0; } int @@ -415,23 +422,44 @@ 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); if (dev_shm) linux_statfs.f_type = LINUX_SHMFS_MAGIC; return copyout(&linux_statfs, args->buf, sizeof(linux_statfs)); } +int +linux_fstatfs(struct thread *td, struct linux_fstatfs_args *args) +{ + struct l_statfs linux_statfs; + struct statfs bsd_statfs; + int error; + +#ifdef DEBUG + if (ldebug(fstatfs)) + printf(ARGS(fstatfs, "%d, *"), args->fd); +#endif + error = kern_fstatfs(td, args->fd, &bsd_statfs); + if (error) + return error; + bsd_to_linux_statfs(&bsd_statfs, &linux_statfs); + if (error) + return (error); + return copyout(&linux_statfs, args->buf, sizeof(linux_statfs)); +} + static void bsd_to_linux_statfs64(struct statfs *bsd_statfs, struct l_statfs64 *linux_statfs) { - 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; linux_statfs->f_bfree = bsd_statfs->f_bfree; linux_statfs->f_bavail = bsd_statfs->f_bavail; + linux_statfs->f_files = bsd_statfs->f_files; linux_statfs->f_ffree = bsd_statfs->f_ffree; - linux_statfs->f_files = bsd_statfs->f_files; 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; @@ -463,9 +491,9 @@ } int -linux_fstatfs(struct thread *td, struct linux_fstatfs_args *args) +linux_fstatfs64(struct thread *td, struct linux_fstatfs64_args *args) { - struct l_statfs linux_statfs; + struct l_statfs64 linux_statfs; struct statfs bsd_statfs; int error; @@ -476,7 +504,7 @@ error = kern_fstatfs(td, args->fd, &bsd_statfs); if (error) return error; - bsd_to_linux_statfs(&bsd_statfs, &linux_statfs); + bsd_to_linux_statfs64(&bsd_statfs, &linux_statfs); return copyout(&linux_statfs, args->buf, sizeof(linux_statfs)); } --- sys/amd64/linux32/linux32_proto.h (revision 251126) +++ sys/amd64/linux32/linux32_proto.h (working copy) @@ -820,7 +820,8 @@ char buf_l_[PADL_(struct l_statfs64_buf *)]; struct l_statfs64_buf * buf; char buf_r_[PADR_(struct l_statfs64_buf *)]; }; struct linux_fstatfs64_args { - register_t dummy; + char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)]; + char buf_l_[PADL_(struct l_statfs_buf *)]; struct l_statfs_buf * buf; char buf_r_[PADR_(struct l_statfs_buf *)]; }; struct linux_tgkill_args { char tgid_l_[PADL_(int)]; int tgid; char tgid_r_[PADR_(int)]; --- sys/i386/linux/linux_proto.h (revision 251126) +++ sys/i386/linux/linux_proto.h (working copy) @@ -825,7 +825,8 @@ char buf_l_[PADL_(struct l_statfs64_buf *)]; struct l_statfs64_buf * buf; char buf_r_[PADR_(struct l_statfs64_buf *)]; }; struct linux_fstatfs64_args { - register_t dummy; + char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)]; + char buf_l_[PADL_(struct l_statfs_buf *)]; struct l_statfs_buf * buf; char buf_r_[PADR_(struct l_statfs_buf *)]; }; struct linux_tgkill_args { char tgid_l_[PADL_(int)]; int tgid; char tgid_r_[PADR_(int)]; --- sys/amd64/linux32/linux32_dummy.c (revision 251126) +++ sys/amd64/linux32/linux32_dummy.c (working copy) @@ -79,7 +79,6 @@ DUMMY(timer_gettime); DUMMY(timer_getoverrun); DUMMY(timer_delete); -DUMMY(fstatfs64); DUMMY(mbind); DUMMY(get_mempolicy); DUMMY(set_mempolicy); --- sys/i386/linux/linux_dummy.c (revision 251126) +++ sys/i386/linux/linux_dummy.c (working copy) @@ -76,7 +76,6 @@ DUMMY(epoll_ctl); DUMMY(epoll_wait); DUMMY(remap_file_pages); -DUMMY(fstatfs64); DUMMY(mbind); DUMMY(get_mempolicy); DUMMY(set_mempolicy); >Release-Note: >Audit-Trail: >Unformatted: