From c9176d7f38994b39464e08ffbb6b8967069a437f Mon Sep 17 00:00:00 2001 From: Derek Atkins Date: Mon, 1 Oct 2001 23:58:59 +0000 Subject: [PATCH] linux-generate-struct-vnode-dyanmically-from-kernel-headers-instead-of-by-perverting-configure-to-test-for-every-one-of-alan-coxs-additions-some-of-which-will-doubtless-never-make-it-into-mainline-kernels-20011001 hopefully this will be the end (at least for a while) of problems where every linux version requires a new openafs release. the struct vnode is now dynamically generated by parsing the linux/fs.h file and pulling out the struct inode, then rewriting osi_vfs.h --- Makefile.in | 5 + NEWS | 5 + acconfig.h | 7 -- configure-libafs.in | 29 +---- configure.in | 29 +---- src/afs/LINUX/osi_vfs.h | 231 -------------------------------------- src/afs/LINUX/osi_vfs.hin | 110 ++++++++++++++++++ src/cf/linux-test2.m4 | 11 ++ src/config/make_vnode.pl | 113 +++++++++++++++++++ 9 files changed, 246 insertions(+), 294 deletions(-) delete mode 100644 src/afs/LINUX/osi_vfs.h create mode 100644 src/afs/LINUX/osi_vfs.hin create mode 100644 src/config/make_vnode.pl diff --git a/Makefile.in b/Makefile.in index 37ddfb1bc3..17f4263dc2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -368,6 +368,11 @@ libafs_tree: libafs_setup ${KERNELDIR} ${INSTALL} -c src/config/Makefile.${SYS_NAME}.in libafs_tree/config ${INSTALL} -c src/config/afsconfig.h.in libafs_tree/config ${INSTALL} -c -f -ns configure-libafs libafs_tree/configure + case ${SYS_NAME} in \ + *linux*) \ + ${INSTALL} -c src/config/make_vnode.pl libafs_tree/config ; \ + ${INSTALL} -c src/afs/LINUX/osi_vfs.hin libafs_tree/afs ;; \ + esac libuafs: libuafs_setup ${UKERNELDIR} set -x; \ diff --git a/NEWS b/NEWS index 734e71eca0..2a2c3ece35 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,11 @@ Openafs News -- history of user Visible changes. September 17, 2001 of partitions and will attach and display accordingly. Creating the file "AlwaysAttach" in the /vicepX directory is used as the trigger to attach it. +** Linux builds no longer require source changes every time the kernel + inode structure changes; the OpenAFS sources will now configure + itself to the actual inode structure as defined in the kernel + sources. + * Changes incorporated in OpenAFS 1.2.1 ** vfsck on Digital UNIX and Solaris will now refuse to fsck mounted diff --git a/acconfig.h b/acconfig.h index 38198b4e39..e02e143df1 100644 --- a/acconfig.h +++ b/acconfig.h @@ -30,13 +30,6 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } #undef INODE_SETATTR_NOT_VOID #undef STRUCT_ADDRESS_SPACE_HAS_PAGE_LOCK -#undef STRUCT_INODE_HAS_I_BYTES -#undef STRUCT_INODE_HAS_I_CDEV -#undef STRUCT_INODE_HAS_I_DEVICES -#undef STRUCT_INODE_HAS_I_DIRTY_DATA_BUFFERS -#undef STRUCT_INODE_HAS_I_MAPPING_OVERLOAD -#undef STRUCT_INODE_HAS_I_MMAP_SHARED -#undef STRUCT_INODE_HAS_I_TRUNCATE_SEM /* glue for RedHat kernel bug */ #undef ENABLE_REDHAT_BUILDSYS diff --git a/configure-libafs.in b/configure-libafs.in index f337340d36..83bc926336 100644 --- a/configure-libafs.in +++ b/configure-libafs.in @@ -112,41 +112,14 @@ case $system in fi AC_MSG_RESULT(linux) if test "x$enable_kernel_module" = "xyes"; then - LINUX_FS_STRUCT_INODE_HAS_I_BYTES + LINUX_BUILD_VNODE_FROM_INODE(config,afs) LINUX_FS_STRUCT_ADDRESS_SPACE_HAS_PAGE_LOCK - LINUX_FS_STRUCT_INODE_HAS_I_CDEV - LINUX_FS_STRUCT_INODE_HAS_I_DEVICES - LINUX_FS_STRUCT_INODE_HAS_I_TRUNCATE_SEM - LINUX_FS_STRUCT_INODE_HAS_I_DIRTY_DATA_BUFFERS - LINUX_FS_STRUCT_INODE_HAS_I_MAPPING_OVERLOAD - LINUX_FS_STRUCT_INODE_HAS_I_MMAP_SHARED LINUX_INODE_SETATTR_RETURN_TYPE LINUX_NEED_RHCONFIG LINUX_WHICH_MODULES if test "x$ac_cv_linux_func_inode_setattr_returns_int" = "xyes" ; then AC_DEFINE(INODE_SETATTR_NOT_VOID) fi - if test "x$ac_cv_linux_fs_struct_inode_has_i_dirty_data_buffers" = "xyes"; then - AC_DEFINE(STRUCT_INODE_HAS_I_DIRTY_DATA_BUFFERS) - fi - if test "x$ac_cv_linux_fs_struct_inode_has_i_mmap_shared" = "xyes"; then - AC_DEFINE(STRUCT_INODE_HAS_I_MMAP_SHARED) - fi - if test "x$ac_cv_linux_fs_struct_inode_has_i_mapping_overload" = "xyes"; then - AC_DEFINE(STRUCT_INODE_HAS_I_MAPPING_OVERLOAD) - fi - if test "x$ac_cv_linux_fs_struct_inode_has_i_devices" = "xyes"; then - AC_DEFINE(STRUCT_INODE_HAS_I_DEVICES) - fi - if test "x$ac_cv_linux_fs_struct_inode_has_i_cdev" = "xyes"; then - AC_DEFINE(STRUCT_INODE_HAS_I_CDEV) - fi - if test "x$ac_cv_linux_fs_struct_inode_has_i_truncate_sem" = "xyes"; then - AC_DEFINE(STRUCT_INODE_HAS_I_TRUNCATE_SEM) - fi - if test "x$ac_cv_linux_fs_struct_inode_has_i_bytes" = "xyes"; then - AC_DEFINE(STRUCT_INODE_HAS_I_BYTES) - fi if test "x$ac_cv_linux_fs_struct_address_space_has_page_lock" = "xyes"; then AC_DEFINE(STRUCT_ADDRESS_SPACE_HAS_PAGE_LOCK) fi diff --git a/configure.in b/configure.in index aaeb6e4b4d..797286ab38 100644 --- a/configure.in +++ b/configure.in @@ -112,41 +112,14 @@ case $system in fi AC_MSG_RESULT(linux) if test "x$enable_kernel_module" = "xyes"; then - LINUX_FS_STRUCT_INODE_HAS_I_BYTES + LINUX_BUILD_VNODE_FROM_INODE(src/config,src/afs/LINUX) LINUX_FS_STRUCT_ADDRESS_SPACE_HAS_PAGE_LOCK - LINUX_FS_STRUCT_INODE_HAS_I_CDEV - LINUX_FS_STRUCT_INODE_HAS_I_DEVICES - LINUX_FS_STRUCT_INODE_HAS_I_TRUNCATE_SEM - LINUX_FS_STRUCT_INODE_HAS_I_DIRTY_DATA_BUFFERS - LINUX_FS_STRUCT_INODE_HAS_I_MAPPING_OVERLOAD - LINUX_FS_STRUCT_INODE_HAS_I_MMAP_SHARED LINUX_INODE_SETATTR_RETURN_TYPE LINUX_NEED_RHCONFIG LINUX_WHICH_MODULES if test "x$ac_cv_linux_func_inode_setattr_returns_int" = "xyes" ; then AC_DEFINE(INODE_SETATTR_NOT_VOID) fi - if test "x$ac_cv_linux_fs_struct_inode_has_i_dirty_data_buffers" = "xyes"; then - AC_DEFINE(STRUCT_INODE_HAS_I_DIRTY_DATA_BUFFERS) - fi - if test "x$ac_cv_linux_fs_struct_inode_has_i_mmap_shared" = "xyes"; then - AC_DEFINE(STRUCT_INODE_HAS_I_MMAP_SHARED) - fi - if test "x$ac_cv_linux_fs_struct_inode_has_i_mapping_overload" = "xyes"; then - AC_DEFINE(STRUCT_INODE_HAS_I_MAPPING_OVERLOAD) - fi - if test "x$ac_cv_linux_fs_struct_inode_has_i_devices" = "xyes"; then - AC_DEFINE(STRUCT_INODE_HAS_I_DEVICES) - fi - if test "x$ac_cv_linux_fs_struct_inode_has_i_cdev" = "xyes"; then - AC_DEFINE(STRUCT_INODE_HAS_I_CDEV) - fi - if test "x$ac_cv_linux_fs_struct_inode_has_i_truncate_sem" = "xyes"; then - AC_DEFINE(STRUCT_INODE_HAS_I_TRUNCATE_SEM) - fi - if test "x$ac_cv_linux_fs_struct_inode_has_i_bytes" = "xyes"; then - AC_DEFINE(STRUCT_INODE_HAS_I_BYTES) - fi if test "x$ac_cv_linux_fs_struct_address_space_has_page_lock" = "xyes"; then AC_DEFINE(STRUCT_ADDRESS_SPACE_HAS_PAGE_LOCK) fi diff --git a/src/afs/LINUX/osi_vfs.h b/src/afs/LINUX/osi_vfs.h deleted file mode 100644 index 962e3b1bb1..0000000000 --- a/src/afs/LINUX/osi_vfs.h +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright 2000, International Business Machines Corporation and others. - * All Rights Reserved. - * - * This software has been released under the terms of the IBM Public - * License. For details, see the LICENSE file in the top-level source - * directory or online at http://www.openafs.org/dl/license10.html - */ - -/* - * Linux interpretations of vnode and vfs structs. - * - * The Linux "inode" has been abstracted to the fs independent part to avoid - * wasting 100+bytes per vnode. - */ - -#ifndef OSI_VFS_H_ -#define OSI_VFS_H_ - -/* The vnode should match the current implementation of the fs independent - * part of the Linux inode. - */ -/* The first cut is to continue to use a separate vnode pool. */ -typedef struct vnode { - struct list_head i_hash; - struct list_head i_list; - struct list_head i_dentry; -#if defined(AFS_LINUX24_ENV) - struct list_head i_dirty_buffers; -#endif -#if defined(STRUCT_INODE_HAS_I_DIRTY_DATA_BUFFERS) - struct list_head i_dirty_data_buffers; -#endif - unsigned long i_ino; - unsigned int i_count; - kdev_t i_dev; - umode_t i_mode; - nlink_t i_nlink; - uid_t i_uid; - gid_t i_gid; - kdev_t i_rdev; -#if defined(AFS_LINUX24_ENV) || defined(pgoff2loff) - loff_t i_size; -#else - off_t i_size; -#endif - time_t i_atime; - time_t i_mtime; - time_t i_ctime; - unsigned long i_blksize; - unsigned long i_blocks; - unsigned long i_version; -#if !defined(AFS_LINUX24_ENV) - unsigned long i_nrpages; -#endif -#ifdef STRUCT_INODE_HAS_I_BYTES - unsigned short i_bytes; -#endif - struct semaphore i_sem; -#ifdef STRUCT_INODE_HAS_I_TRUNCATE_SEM - struct rw_semaphore i_truncate_sem; -#endif -#if defined(AFS_LINUX24_ENV) - struct semaphore i_zombie; -#else - struct semaphore i_atomic_write; -#endif - struct inode_operations *i_op; -#if defined(AFS_LINUX24_ENV) - struct file_operations *i_fop; -#endif - struct super_block *i_sb; -#if defined(AFS_LINUX24_ENV) - wait_queue_head_t i_wait; -#else - struct wait_queue *i_wait; -#endif - struct file_lock *i_flock; -#if defined(AFS_LINUX24_ENV) - struct address_space *i_mapping; - struct address_space i_data; -#else - struct vm_area_struct *i_mmap; -#if defined(STRUCT_INODE_HAS_I_MMAP_SHARED) - struct vm_area_struct *i_mmap_shared; -#endif - struct page *i_pages; -#endif -#if defined(STRUCT_INODE_HAS_I_MAPPING_OVERLOAD) - int i_mapping_overload; -#endif - struct dquot *i_dquot[MAXQUOTAS]; -#if defined(AFS_LINUX24_ENV) -#if defined(STRUCT_INODE_HAS_I_DEVICES) - struct list_head i_devices; -#endif - struct pipe_inode_info *i_pipe; - struct block_device *i_bdev; -#if defined(STRUCT_INODE_HAS_I_CDEV) - struct char_device *i_cdev; -#endif - unsigned long i_dnotify_mask; - struct dnotify_struct *i_dnotify; -#endif - - unsigned long i_state; - - unsigned int i_flags; -#if !defined(AFS_LINUX24_ENV) - unsigned char i_pipe; -#endif - unsigned char i_sock; - -#if defined(AFS_LINUX24_ENV) - atomic_t i_writecount; -#else - int i_writecount; -#endif - unsigned int i_attr_flags; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,10) - __u32 i_generation; -#endif -#ifdef notdef - union { - struct pipe_inode_info pipe_i; - struct minix_inode_info minix_i; - struct ext2_inode_info ext2_i; - struct hpfs_inode_info hpfs_i; - struct ntfs_inode_info ntfs_i; - struct msdos_inode_info msdos_i; - struct umsdos_inode_info umsdos_i; - struct iso_inode_info isofs_i; - struct nfs_inode_info nfs_i; - struct sysv_inode_info sysv_i; - struct affs_inode_info affs_i; - struct ufs_inode_info ufs_i; - struct romfs_inode_info romfs_i; - struct coda_inode_info coda_i; - struct smb_inode_info smbfs_i; - struct hfs_inode_info hfs_i; - struct adfs_inode_info adfs_i; - struct qnx4_inode_info qnx4_i; - struct socket socket_i; - void *generic_ip; - } u; -#endif -} vnode_t; - -/* Map vnode fields to inode fields. */ -#define i_number i_ino -#define v_count i_count -#define v_op i_op -#if defined(AFS_LINUX24_ENV) -#define v_fop i_fop -#endif -#define v_type i_mode -#define v_vfsp i_sb -#define vfs_vnodecovered s_covered - -/* v_type bits map to mode bits: */ -#define VNON 0 -#define VREG S_IFREG -#define VDIR S_IFDIR -#define VBLK S_IFBLK -#define VCHR S_IFCHR -#define VLNK S_IFLNK -#define VSOCK S_IFSOCK - -/* vcexcl - used only by afs_create */ -enum vcexcl { EXCL, NONEXCL } ; - -/* afs_open and afs_close needs to distinguish these cases */ -#define FWRITE O_WRONLY|O_RDWR|O_APPEND -#define FTRUNC O_TRUNC - - -#define IO_APPEND O_APPEND -#define FSYNC O_SYNC - -#define VTOI(V) ((struct inode*)V) -#define VN_HOLD(V) ((vnode_t*)V)->i_count++; -#define VN_RELE(V) osi_iput((struct inode *)V); -#define VFS_STATFS(V, S) ((V)->s_op->statfs)((V), (S), sizeof(*(S))) - - - -/* Various mode bits */ -#define VWRITE S_IWUSR -#define VREAD S_IRUSR -#define VEXEC S_IXUSR -#define VSUID S_ISUID -#define VSGID S_ISGID - - -#define vfs super_block - -typedef struct vattr { - int va_type; /* One of v_types above. */ - size_t va_size; - unsigned long va_blocks; - unsigned long va_blocksize; - int va_mask; /* AT_xxx operation to perform. */ - umode_t va_mode; /* mode bits. */ - uid_t va_uid; - gid_t va_gid; - int va_fsid; /* Not used? */ - dev_t va_rdev; - ino_t va_nodeid; /* Inode number */ - nlink_t va_nlink; /* link count for file. */ - struct timeval va_atime; - struct timeval va_mtime; - struct timeval va_ctime; -} vattr_t; - -#define VATTR_NULL(A) memset(A, 0, sizeof(struct vattr)) - - -/* va_masks - these should match their respective ATTR_xxx #defines in fs.h. - * afs_notify_change has to use the attr bits in both the Linux and AFS - * meanings. The glue layer code uses the ATTR_xxx style names. - */ -#define AT_SIZE ATTR_SIZE -#define AT_MODE ATTR_MODE -#define AT_UID ATTR_UID -#define AT_GID ATTR_GID -#define AT_MTIME ATTR_MTIME - - -#define vnodeops inode_operations - -#endif /* OSI_VFS_H_ */ diff --git a/src/afs/LINUX/osi_vfs.hin b/src/afs/LINUX/osi_vfs.hin new file mode 100644 index 0000000000..99d8e3fe6c --- /dev/null +++ b/src/afs/LINUX/osi_vfs.hin @@ -0,0 +1,110 @@ +/* + * Copyright 2000, International Business Machines Corporation and others. + * All Rights Reserved. + * + * This software has been released under the terms of the IBM Public + * License. For details, see the LICENSE file in the top-level source + * directory or online at http://www.openafs.org/dl/license10.html + */ + +/* + * Linux interpretations of vnode and vfs structs. + * + * The Linux "inode" has been abstracted to the fs independent part to avoid + * wasting 100+bytes per vnode. + */ + +#ifndef OSI_VFS_H_ +#define OSI_VFS_H_ + +/* The vnode should match the current implementation of the fs independent + * part of the Linux inode. + */ +/* The first cut is to continue to use a separate vnode pool. */ +/* LINUX VNODE INCLUDED BELOW -- DO NOT MODIFY */ + +typedef struct vnode vnode_t; + +/* Map vnode fields to inode fields. */ +#define i_number i_ino +#define v_count i_count +#define v_op i_op +#if defined(AFS_LINUX24_ENV) +#define v_fop i_fop +#endif +#define v_type i_mode +#define v_vfsp i_sb +#define vfs_vnodecovered s_covered + +/* v_type bits map to mode bits: */ +#define VNON 0 +#define VREG S_IFREG +#define VDIR S_IFDIR +#define VBLK S_IFBLK +#define VCHR S_IFCHR +#define VLNK S_IFLNK +#define VSOCK S_IFSOCK + +/* vcexcl - used only by afs_create */ +enum vcexcl { EXCL, NONEXCL } ; + +/* afs_open and afs_close needs to distinguish these cases */ +#define FWRITE O_WRONLY|O_RDWR|O_APPEND +#define FTRUNC O_TRUNC + + +#define IO_APPEND O_APPEND +#define FSYNC O_SYNC + +#define VTOI(V) ((struct inode*)V) +#define VN_HOLD(V) ((vnode_t*)V)->i_count++; +#define VN_RELE(V) osi_iput((struct inode *)V); +#define VFS_STATFS(V, S) ((V)->s_op->statfs)((V), (S), sizeof(*(S))) + + + +/* Various mode bits */ +#define VWRITE S_IWUSR +#define VREAD S_IRUSR +#define VEXEC S_IXUSR +#define VSUID S_ISUID +#define VSGID S_ISGID + + +#define vfs super_block + +typedef struct vattr { + int va_type; /* One of v_types above. */ + size_t va_size; + unsigned long va_blocks; + unsigned long va_blocksize; + int va_mask; /* AT_xxx operation to perform. */ + umode_t va_mode; /* mode bits. */ + uid_t va_uid; + gid_t va_gid; + int va_fsid; /* Not used? */ + dev_t va_rdev; + ino_t va_nodeid; /* Inode number */ + nlink_t va_nlink; /* link count for file. */ + struct timeval va_atime; + struct timeval va_mtime; + struct timeval va_ctime; +} vattr_t; + +#define VATTR_NULL(A) memset(A, 0, sizeof(struct vattr)) + + +/* va_masks - these should match their respective ATTR_xxx #defines in fs.h. + * afs_notify_change has to use the attr bits in both the Linux and AFS + * meanings. The glue layer code uses the ATTR_xxx style names. + */ +#define AT_SIZE ATTR_SIZE +#define AT_MODE ATTR_MODE +#define AT_UID ATTR_UID +#define AT_GID ATTR_GID +#define AT_MTIME ATTR_MTIME + + +#define vnodeops inode_operations + +#endif /* OSI_VFS_H_ */ diff --git a/src/cf/linux-test2.m4 b/src/cf/linux-test2.m4 index beefbae3f6..8e0753b111 100644 --- a/src/cf/linux-test2.m4 +++ b/src/cf/linux-test2.m4 @@ -28,3 +28,14 @@ ac_cv_linux_fs_struct_address_space_has_page_lock=no)]) AC_MSG_RESULT($ac_cv_linux_fs_struct_address_space_has_page_lock) CPPFLAGS="$save_CPPFLAGS"]) + +dnl LINUX_BUILD_VNODE_FROM_INODE (configdir, outputdir) +dnl defaults: (src/config, src/afs/LINUX) + +AC_DEFUN(LINUX_BUILD_VNODE_FROM_INODE, [ +AC_MSG_CHECKING(whether to build osi_vfs.h) +configdir=ifelse([$1], ,src/config,$1) +outputdir=ifelse([$2], ,src/afs/LINUX,$2) +chmod +x $configdir/make_vnode.pl +$configdir/make_vnode.pl -i $LINUX_KERNEL_PATH -o $outputdir +]) diff --git a/src/config/make_vnode.pl b/src/config/make_vnode.pl new file mode 100644 index 0000000000..c020861557 --- /dev/null +++ b/src/config/make_vnode.pl @@ -0,0 +1,113 @@ +#!/usr/bin/perl +# +# Make VNODE structure from INODE structure +# +# Created By: Derek Atkins +# + +$linux_header_dir="/usr/src/linux"; +$outdir="./src/afs/LINUX"; + +$sepline="/* LINUX VNODE INCLUDED BELOW -- DO NOT MODIFY */\n"; + +# makeVfs (fs.h, vfs.hin, vfs.out) +sub makeVfs { + my ($in,$base,$out) = @_; + my ($seplinefound); + + open (IN, "$in") || die "Cannot open $in for reading"; + open (BASE, "$base" ) || die "Cannot open base file $base"; + open (OUT, ">$out") || die "Cannot open tempfile $out"; + + while () { + print OUT; + if ($_ eq $sepline) { + $seplinefound = 1; + last; + } + } + + print OUT $sepline if !$seplinefound; + + my ($state) = 0; + while () { + + # Look for 'struct inode' definition + if ($state == 0) { + next unless m/^struct\s+inode\s*\{/; + $state++; + s/inode/vnode/; + # Fallthrough + } + + # Look for 'union {' -- print otherwise + if ($state == 1) { + if (m/^\s*union\s*\{/) { + $state++; + print OUT "#ifdef notdef\n"; + } + print OUT; + next; + } + + # Look for the end of the union -- ignore otherwise + if ($state == 2) { + print OUT; + next unless (m/^\s+\}\s*u;/); + $state++; + print OUT "#endif /* notdef */\n"; + next; + } + + # Look for end brace -- print until we find it + if ($state == 3) { + print OUT; + if (m/^\s*\};/) { $state++ } + } + } + + while () { print OUT; } + + close (IN); + close (BASE); + close (OUT); +} + +sub usage { + print "usage: $0 [-i linux_header_dir] [-o output_dir] [-h]\n"; + exit 1; +} + +sub testArg { + my ($arg) = @_; + return $arg if ($arg && $arg ne ""); + usage; +} + +while ($_ = shift @ARGV) { + if (m/^-i/) { $linux_header_dir = testArg(shift @ARGV); next; } + if (m/^-o/) { $outdir = testArg(shift @ARGV); next; } + usage; +} + +$linux_fs_h="$linux_header_dir/include/linux/fs.h"; +$vfs_h="$outdir/osi_vfs.h"; +$vfs_hin="$outdir/osi_vfs.hin"; + +makeVfs ($linux_fs_h, $vfs_hin, "$vfs_h.new"); + +system ("cmp", "-s", $vfs_h, "$vfs_h.new"); +$exit_value = $? >> 8; +$signal_num = $? & 127; +$core_dump = $? & 128; + +if ($exit_value == 0 || $signal_num > 0) { + unlink "$vfs_h.new"; + print "nothing to do... $vfs_h not changed.\n" +} else { + unlink "$vfs_h"; + rename ("$vfs_h.new", $vfs_h); + print "wrote $vfs_h\n"; +} + +exit 0;