From owner-freebsd-fs@FreeBSD.ORG Sun Nov 23 01:49:20 2014 Return-Path: Delivered-To: freebsd-fs@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 55516FEC; Sun, 23 Nov 2014 01:49:20 +0000 (UTC) Received: from mail-pa0-x230.google.com (mail-pa0-x230.google.com [IPv6:2607:f8b0:400e:c03::230]) (using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 1D865FEE; Sun, 23 Nov 2014 01:49:20 +0000 (UTC) Received: by mail-pa0-f48.google.com with SMTP id rd3so7336275pab.35 for ; Sat, 22 Nov 2014 17:49:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:date:from:to:cc:subject:message-id:references:mime-version :content-type:content-disposition:in-reply-to:user-agent; bh=MnBQSPP76Q0ketcdt4nQD9DjNM4/J/oYJyoYqhzdMzE=; b=STL6McbGjKqcT5tCRmzmC267ki1DD8VlcEXPqPSBUIqpqk3lbG8Ro2Q/uGdZzWBvjE IsJ4cYGh0kRMTqDSZ2L7kYeJKbKLCGtx8GFmKKcllgidxfvXcGpEdERe0OncqtfvTibf G+gXJvjDeWe+gQbW0e1HD8339yovlWB14U8qmpPE51hh39sovDT5LauPQQhT7bOVyag8 +7Xk6c4Av6J112O38b1oS6iyS+fCAz5JcGlU0ws4ThXrL4BtKC4HbQoiR+95nufbel5d HKQyXcqOKGbCAsuN5pB6LRd6UX2GdZe2eDkak4Hp4NhV1YRntaoXTrHuT1O4TssK+n/H r3pA== X-Received: by 10.66.66.42 with SMTP id c10mr7339057pat.4.1416707359755; Sat, 22 Nov 2014 17:49:19 -0800 (PST) Received: from localhost (c-76-21-76-83.hsd1.ca.comcast.net. [76.21.76.83]) by mx.google.com with ESMTPSA id j6sm8538751pdm.16.2014.11.22.17.49.18 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 22 Nov 2014 17:49:18 -0800 (PST) Sender: Gleb Kurtsou Date: Sat, 22 Nov 2014 17:50:22 -0800 From: Gleb Kurtsou To: Rick Macklem Subject: Re: RFC: patch to make d_fileno 64bits Message-ID: <20141123015021.GA1658@reks> References: <20141121182219.GA1076@reks> <1346064334.5234809.1416616386575.JavaMail.root@uoguelph.ca> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="SUOF0GtieIMvvwua" Content-Disposition: inline In-Reply-To: <1346064334.5234809.1416616386575.JavaMail.root@uoguelph.ca> User-Agent: Mutt/1.5.23 (2014-03-12) Cc: freebsd-fs@freebsd.org X-BeenThere: freebsd-fs@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Filesystems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 23 Nov 2014 01:49:20 -0000 --SUOF0GtieIMvvwua Content-Type: text/plain; charset=utf-8 Content-Disposition: inline On (21/11/2014 19:33), Rick Macklem wrote: > Gleb Kurtsou wrote: > > On (21/11/2014 10:25), John Baldwin wrote: [...] > > > > > > I think this is already done (along with several other changes) > > > more fully in > > > the projects/ino64 branch in svn? > > > > projects/ino64 was created by mdf for merging GSoC commits, and it > > didn't even get half way through. > > > > I'm currently working on merging the code to CURRENT. It's been more > > than 2 years, so there is quite some work in there. I intend to > > update > > the branch as soon as code is ready for review. > > > Btw, I just took a quick look and I didn't find any changes to "struct dirent" > in projects/ino64, so I think my original assumption that this piece of the > puzzle hadn't yet been solved, is correct. (Gleb, if you had changes to > "struct dirent" and related fs changes, please let me know.) projects/ino64 was created for merging GSoC commits. The branch is incomplete to say the least.. There are preparatory changes in there only. In case you are interested please refer to https://github.com/glk/freebsd-ino64/commits/projects/ino64 BTW original GSoC branch also changes VOP_READDIR for all file systems to populate dirent.d_off. I've attached the patch for some of the system headers generated by git diff -r 531f5069a9b0f61b8ecd08e4ed744cec3b022606 -r github/projects/ino64 sys/sys/{_types,dirent,mount,stat}.h > ~/ino64-sys-sys.patch > > Oh, and thanks to some comments, the new struct dirent has already changed to: > > struct dirent { > __uint64_t d_cookie; /* dir cookie for next dir entry */ > __uint64_t d_fileno; > __uint16_t d_reclen; > __uint8_t d_type; > __uint8_t d_namlen; > __uint8_t d_pad[4]; /* align d_name to 8 byte boundary */ > __uint8_t d_name[MAXNAMLEN + 1]; > }; GSoC'2011 code: struct dirent { ino_t d_fileno; /* file number of entry */ off_t d_off; /* next entry seek offset */ __uint16_t d_reclen; /* length of this record */ __uint16_t d_namlen; /* length of string in d_name */ __uint8_t d_type; /* file type, see below */ __uint8_t d_unused1; __uint16_t d_unused2; char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */ }; > > It was pointed out that C would pad the structure to a multiple of 8 bytes > for some arches and without d_pad that would imply d_name wasn't at the end > of the structure. (Apparently code somewhere find d_name by subtracting MAXNAMLEN + 1 > from sizeof(struct dirent) and this fails if d_name isn't at the end. Yuck, > but the above fixes it.) > > However, the size of d_namlen could become uint16_t, if anyone thinks MAXNAMLEN > might want to be greater than 255 someday (long away, since that's another ABI change). Somebody has already mentioned it previously so I've bumped it to uint16 back than. > > rick > > > Besides branch also changes dev_t to 64-bit, bumps MNAMELEN to 1024 > > and > > has complete ABI compatibility shims (probably except openaudit which > > had > > issues). > > > > > > _______________________________________________ > > freebsd-fs@freebsd.org mailing list > > http://lists.freebsd.org/mailman/listinfo/freebsd-fs > > To unsubscribe, send any mail to "freebsd-fs-unsubscribe@freebsd.org" > > --SUOF0GtieIMvvwua Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="ino64-sys-sys.patch" diff --git a/sys/sys/_types.h b/sys/sys/_types.h index c59afd3..2d757f5 100644 --- a/sys/sys/_types.h +++ b/sys/sys/_types.h @@ -32,37 +32,37 @@ #include #include /* * Standard type definitions. */ typedef __uint32_t __blksize_t; /* file block size */ typedef __int64_t __blkcnt_t; /* file block count */ typedef __int32_t __clockid_t; /* clock_gettime()... */ typedef __uint64_t __cap_rights_t; /* capability rights */ typedef __uint32_t __fflags_t; /* file flags */ typedef __uint64_t __fsblkcnt_t; typedef __uint64_t __fsfilcnt_t; typedef __uint32_t __gid_t; typedef __int64_t __id_t; /* can hold a gid_t, pid_t, or uid_t */ -typedef __uint32_t __ino_t; /* inode number */ +typedef __uint64_t __ino_t; /* inode number */ typedef long __key_t; /* IPC key (for Sys V IPC) */ typedef __int32_t __lwpid_t; /* Thread ID (a.k.a. LWP) */ typedef __uint16_t __mode_t; /* permissions */ typedef int __accmode_t; /* access permissions */ typedef int __nl_item; -typedef __uint16_t __nlink_t; /* link count */ +typedef __uint32_t __nlink_t; /* link count */ typedef __int64_t __off_t; /* file offset */ typedef __int32_t __pid_t; /* process [group] */ typedef __int64_t __rlim_t; /* resource limit - intentionally */ /* signed, because of legacy code */ /* that uses -1 for RLIM_INFINITY */ typedef __uint8_t __sa_family_t; typedef __uint32_t __socklen_t; typedef long __suseconds_t; /* microseconds (signed) */ typedef struct __timer *__timer_t; /* timer_gettime()... */ typedef struct __mq *__mqd_t; /* mq_open()... */ typedef __uint32_t __uid_t; typedef unsigned int __useconds_t; /* microseconds (unsigned) */ typedef int __cpuwhich_t; /* which parameter for cpuset. */ typedef int __cpulevel_t; /* level parameter for cpuset. */ typedef int __cpusetid_t; /* cpuset identifier. */ @@ -78,29 +78,29 @@ typedef int __cpusetid_t; /* cpuset identifier. */ * ints cannot hold 32 bits, you will be in trouble. The reason an int was * chosen over a long is that the is*() and to*() routines take ints (says * ANSI C), but they use __ct_rune_t instead of int. * * NOTE: rune_t is not covered by ANSI nor other standards, and should not * be instantiated outside of lib/libc/locale. Use wchar_t. wchar_t and * rune_t must be the same type. Also, wint_t must be no narrower than * wchar_t, and should be able to hold all members of the largest * character set plus one extra value (WEOF), and must be at least 16 bits. */ typedef int __ct_rune_t; /* arg type for ctype funcs */ typedef __ct_rune_t __rune_t; /* rune_t (see above) */ typedef __ct_rune_t __wchar_t; /* wchar_t (see above) */ typedef __ct_rune_t __wint_t; /* wint_t (see above) */ -typedef __uint32_t __dev_t; /* device number */ +typedef __uint64_t __dev_t; /* device number */ typedef __uint32_t __fixpt_t; /* fixed point number */ /* * mbstate_t is an opaque object to keep conversion state during multibyte * stream conversions. */ typedef union { char __mbstate8[128]; __int64_t _mbstateL; /* for alignment */ } __mbstate_t; #endif /* !_SYS__TYPES_H_ */ diff --git a/sys/sys/dirent.h b/sys/sys/dirent.h index dfaacff..107936b 100644 --- a/sys/sys/dirent.h +++ b/sys/sys/dirent.h @@ -24,55 +24,76 @@ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)dirent.h 8.3 (Berkeley) 8/10/94 * $FreeBSD$ */ #ifndef _SYS_DIRENT_H_ #define _SYS_DIRENT_H_ #include #include +#ifndef _INO_T_DECLARED +typedef __ino_t ino_t; +#define _INO_T_DECLARED +#endif + +#ifndef _OFF_T_DECLARED +typedef __off_t off_t; +#define _OFF_T_DECLARED +#endif + /* * The dirent structure defines the format of directory entries returned by * the getdirentries(2) system call. * * A directory entry has a struct dirent at the front of it, containing its * inode number, the length of the entry, and the length of the name * contained in the entry. These are followed by the name padded to a 4 * byte boundary with null bytes. All names are guaranteed null terminated. * The maximum length of a name in a directory is MAXNAMLEN. */ struct dirent { - __uint32_t d_fileno; /* file number of entry */ + ino_t d_fileno; /* file number of entry */ + off_t d_off; /* next entry seek offset */ __uint16_t d_reclen; /* length of this record */ + __uint16_t d_namlen; /* length of string in d_name */ __uint8_t d_type; /* file type, see below */ - __uint8_t d_namlen; /* length of string in d_name */ + __uint8_t d_unused1; + __uint16_t d_unused2; #if __BSD_VISIBLE #define MAXNAMLEN 255 char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */ #else char d_name[255 + 1]; /* name must be no longer than this */ #endif }; #if __BSD_VISIBLE +struct freebsd9_dirent { + __uint32_t d_fileno; /* file number of entry */ + __uint16_t d_reclen; /* length of this record */ + __uint8_t d_type; /* file type, see below */ + __uint8_t d_namlen; /* length of string in d_name */ + char d_name[255 + 1]; /* name must be no longer than this */ +}; + /* * File types */ #define DT_UNKNOWN 0 #define DT_FIFO 1 #define DT_CHR 2 #define DT_DIR 4 #define DT_BLK 6 #define DT_REG 8 #define DT_LNK 10 #define DT_SOCK 12 #define DT_WHT 14 /* * Convert between stat structure types and directory types. diff --git a/sys/sys/mount.h b/sys/sys/mount.h index ecaf7b8..01f9e04 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -52,57 +52,83 @@ typedef struct fsid { int32_t val[2]; } fsid_t; /* filesystem id type */ * File identifier. * These are unique per filesystem on a single machine. */ #define MAXFIDSZ 16 struct fid { u_short fid_len; /* length of data in bytes */ u_short fid_data0; /* force longword alignment */ char fid_data[MAXFIDSZ]; /* data (variable length) */ }; /* * filesystem statistics */ #define MFSNAMELEN 16 /* length of type name including null */ -#define MNAMELEN 88 /* size of on/from name bufs */ -#define STATFS_VERSION 0x20030518 /* current version number */ +#define MNAMELEN 1024 /* size of on/from name bufs */ +#define STATFS_VERSION 0x20110618 /* current version number */ struct statfs { uint32_t f_version; /* structure version number */ uint32_t f_type; /* type of filesystem */ uint64_t f_flags; /* copy of mount exported flags */ uint64_t f_bsize; /* filesystem fragment size */ uint64_t f_iosize; /* optimal transfer block size */ uint64_t f_blocks; /* total data blocks in filesystem */ uint64_t f_bfree; /* free blocks in filesystem */ int64_t f_bavail; /* free blocks avail to non-superuser */ uint64_t f_files; /* total file nodes in filesystem */ int64_t f_ffree; /* free nodes avail to non-superuser */ uint64_t f_syncwrites; /* count of sync writes since mount */ uint64_t f_asyncwrites; /* count of async writes since mount */ uint64_t f_syncreads; /* count of sync reads since mount */ uint64_t f_asyncreads; /* count of async reads since mount */ uint64_t f_spare[10]; /* unused spare */ uint32_t f_namemax; /* maximum filename length */ uid_t f_owner; /* user that mounted the filesystem */ fsid_t f_fsid; /* filesystem id */ char f_charspare[80]; /* spare string space */ char f_fstypename[MFSNAMELEN]; /* filesystem type name */ char f_mntfromname[MNAMELEN]; /* mounted filesystem */ char f_mntonname[MNAMELEN]; /* directory on which mounted */ }; +#define FREEBSD9_STATFS_VERSION 0x20030518 /* current version number */ +struct freebsd9_statfs { + uint32_t f_version; /* structure version number */ + uint32_t f_type; /* type of filesystem */ + uint64_t f_flags; /* copy of mount exported flags */ + uint64_t f_bsize; /* filesystem fragment size */ + uint64_t f_iosize; /* optimal transfer block size */ + uint64_t f_blocks; /* total data blocks in filesystem */ + uint64_t f_bfree; /* free blocks in filesystem */ + int64_t f_bavail; /* free blocks avail to non-superuser */ + uint64_t f_files; /* total file nodes in filesystem */ + int64_t f_ffree; /* free nodes avail to non-superuser */ + uint64_t f_syncwrites; /* count of sync writes since mount */ + uint64_t f_asyncwrites; /* count of async writes since mount */ + uint64_t f_syncreads; /* count of sync reads since mount */ + uint64_t f_asyncreads; /* count of async reads since mount */ + uint64_t f_spare[10]; /* unused spare */ + uint32_t f_namemax; /* maximum filename length */ + uid_t f_owner; /* user that mounted the filesystem */ + fsid_t f_fsid; /* filesystem id */ + char f_charspare[80]; /* spare string space */ + char f_fstypename[16]; /* filesystem type name */ + char f_mntfromname[88]; /* mounted filesystem */ + char f_mntonname[88]; /* directory on which mounted */ +}; + #ifdef _KERNEL #define OMFSNAMELEN 16 /* length of fs type name, including null */ #define OMNAMELEN (88 - 2 * sizeof(long)) /* size of on/from name bufs */ /* XXX getfsstat.2 is out of date with write and read counter changes here. */ /* XXX statfs.2 is out of date with read counter changes here. */ struct ostatfs { long f_spare2; /* placeholder */ long f_bsize; /* fundamental filesystem block size */ long f_iosize; /* optimal transfer block size */ long f_blocks; /* total data blocks in filesystem */ long f_bfree; /* free blocks in fs */ long f_bavail; /* free blocks avail to non-superuser */ long f_files; /* total file nodes in filesystem */ long f_ffree; /* free file nodes in fs */ diff --git a/sys/sys/stat.h b/sys/sys/stat.h index 1b03bd2..a9b5ff4 100644 --- a/sys/sys/stat.h +++ b/sys/sys/stat.h @@ -90,86 +90,117 @@ typedef __off_t off_t; #ifndef _UID_T_DECLARED typedef __uid_t uid_t; #define _UID_T_DECLARED #endif #if !defined(_KERNEL) && __BSD_VISIBLE /* * XXX We get miscellaneous namespace pollution with this. */ #include #endif #if __BSD_VISIBLE struct ostat { __uint16_t st_dev; /* inode's device */ - ino_t st_ino; /* inode's number */ + __uint32_t st_ino; /* inode's number */ mode_t st_mode; /* inode protection mode */ - nlink_t st_nlink; /* number of hard links */ + __uint16_t st_nlink; /* number of hard links */ __uint16_t st_uid; /* user ID of the file's owner */ __uint16_t st_gid; /* group ID of the file's group */ __uint16_t st_rdev; /* device type */ __int32_t st_size; /* file size, in bytes */ struct timespec st_atim; /* time of last access */ struct timespec st_mtim; /* time of last data modification */ struct timespec st_ctim; /* time of last file status change */ __int32_t st_blksize; /* optimal blocksize for I/O */ __int32_t st_blocks; /* blocks allocated for file */ fflags_t st_flags; /* user defined flags for file */ __uint32_t st_gen; /* file generation number */ }; + +struct freebsd9_stat { + __uint32_t st_dev; /* inode's device */ + __uint32_t st_ino; /* inode's number */ + mode_t st_mode; /* inode protection mode */ + __uint16_t st_nlink; /* number of hard links */ + uid_t st_uid; /* user ID of the file's owner */ + gid_t st_gid; /* group ID of the file's group */ + __uint32_t st_rdev; /* device type */ + struct timespec st_atim; /* time of last access */ + struct timespec st_mtim; /* time of last data modification */ + struct timespec st_ctim; /* time of last file status change */ + off_t st_size; /* file size, in bytes */ + blkcnt_t st_blocks; /* blocks allocated for file */ + blksize_t st_blksize; /* optimal blocksize for I/O */ + fflags_t st_flags; /* user defined flags for file */ + __uint32_t st_gen; /* file generation number */ + __int32_t st_lspare; + struct timespec st_birthtim; /* time of file creation */ + /* + * Explicitly pad st_birthtim to 16 bytes so that the size of + * struct stat is backwards compatible. We use bitfields instead + * of an array of chars so that this doesn't require a C99 compiler + * to compile if the size of the padding is 0. We use 2 bitfields + * to cover up to 64 bits on 32-bit machines. We assume that + * CHAR_BIT is 8... + */ + unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); + unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); +}; #endif /* __BSD_VISIBLE */ struct stat { - __dev_t st_dev; /* inode's device */ + dev_t st_dev; /* inode's device */ ino_t st_ino; /* inode's number */ - mode_t st_mode; /* inode protection mode */ nlink_t st_nlink; /* number of hard links */ + mode_t st_mode; /* inode protection mode */ + __int16_t st_padding0; uid_t st_uid; /* user ID of the file's owner */ gid_t st_gid; /* group ID of the file's group */ - __dev_t st_rdev; /* device type */ + dev_t st_rdev; /* device type */ struct timespec st_atim; /* time of last access */ struct timespec st_mtim; /* time of last data modification */ struct timespec st_ctim; /* time of last file status change */ off_t st_size; /* file size, in bytes */ blkcnt_t st_blocks; /* blocks allocated for file */ blksize_t st_blksize; /* optimal blocksize for I/O */ fflags_t st_flags; /* user defined flags for file */ __uint32_t st_gen; /* file generation number */ __int32_t st_lspare; struct timespec st_birthtim; /* time of file creation */ /* * Explicitly pad st_birthtim to 16 bytes so that the size of * struct stat is backwards compatible. We use bitfields instead * of an array of chars so that this doesn't require a C99 compiler * to compile if the size of the padding is 0. We use 2 bitfields * to cover up to 64 bits on 32-bit machines. We assume that * CHAR_BIT is 8... */ unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); }; #if __BSD_VISIBLE struct nstat { - __dev_t st_dev; /* inode's device */ - ino_t st_ino; /* inode's number */ + __uint32_t st_dev; /* inode's device */ + __uint32_t st_ino; /* inode's number */ __uint32_t st_mode; /* inode protection mode */ __uint32_t st_nlink; /* number of hard links */ uid_t st_uid; /* user ID of the file's owner */ gid_t st_gid; /* group ID of the file's group */ - __dev_t st_rdev; /* device type */ + __uint32_t st_rdev; /* device type */ struct timespec st_atim; /* time of last access */ struct timespec st_mtim; /* time of last data modification */ struct timespec st_ctim; /* time of last file status change */ off_t st_size; /* file size, in bytes */ blkcnt_t st_blocks; /* blocks allocated for file */ blksize_t st_blksize; /* optimal blocksize for I/O */ fflags_t st_flags; /* user defined flags for file */ __uint32_t st_gen; /* file generation number */ struct timespec st_birthtim; /* time of file creation */ /* * See above about the following padding. */ unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); }; --SUOF0GtieIMvvwua--