/*************************************************************************** * * Copyright (C) 2001 International Business Machines * All rights reserved. * * This file is part of the GPFS mmfslinux kernel module. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) 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. * *************************************************************************** */ /* @(#)88 1.84.1.4 src/avs/fs/mmfs/ts/kernext/gpl-linux/opsdeclare.c, mmfs, avs_rgpfs24, rgpfs24s007a 10/24/06 17:58:00 */ #include /* Linux headers */ #include #include /* vm operations */ /* GPFS headers */ #include #include struct super_operations gpfs_sops = { read_inode: gpfs_s_read_inode, #if HAS_SOP_READ_INODE2 read_inode2: gpfs_s_read_inode2, #endif write_inode: NULL, delete_inode: gpfs_s_delete_inode, put_super: gpfs_s_put_super, /* unmount (not force) */ write_super: gpfs_s_write_super, /* sync */ statfs: gpfs_s_statfs, /* statfs */ remount_fs: NULL, clear_inode: gpfs_s_clear_inode, /* inode completely unused */ umount_begin: gpfs_s_umount_begin, /* unmount (force) */ #if LINUX_KERNEL_VERSION < 2060000 fh_to_dentry: gpfs_fh_to_dentry, dentry_to_fh: gpfs_dentry_to_fh, #endif #if HAS_SOP_ALLOC_INODE alloc_inode: gpfs_alloc_inode, destroy_inode: gpfs_destroy_inode, #endif }; #if LINUX_KERNEL_VERSION > 2060000 struct export_operations gpfs_export_ops = { encode_fh: gpfs_encode_fh, decode_fh: gpfs_decode_fh, get_dentry: gpfs_get_dentry, get_parent: gpfs_get_dparent, #ifdef NFS_CLUSTER_LOCKS lock: gpfs_f_lock, #endif #ifdef P_NFS4 get_devicelist: gpfs_get_devicelist, layout_get: gpfs_layout_get, get_deviceinfo: gpfs_get_deviceinfo, layout_return: gpfs_layout_return, get_state: gpfs_get_state, layout_type: gpfs_layout_type, get_verifier: gpfs_get_verifier, #endif }; #endif #if LINUX_KERNEL_VERSION >= 2050000 struct file_system_type gpfs_fs_type = { .owner = THIS_MODULE, .name = "gpfs", .get_sb = gpfs_get_sb, .kill_sb = kill_anon_super, }; #else DECLARE_FSTYPE_DEV(gpfs_fs_type, "gpfs", gpfs_fill_super); /* DECLARE_FSTYPE(gpfs_fs_type, "gpfs", gpfs_fill_super, 0); */ #endif struct super_operations null_sops = { }; struct file_operations gpfs_cleanup_fops = { release: gpfs_f_cleanup }; /* Inode operations for non-symlinks, non-directory with standard Unix permissions (no extended acls) and valid inode attributes (valid owner and mode cached in the Linux inode structure). */ struct inode_operations gpfs_iops_stdperm = { create: gpfs_i_create, // lookup: no lookup op for non-directory link: gpfs_i_link, unlink: gpfs_i_unlink, symlink: gpfs_i_symlink, mkdir: gpfs_i_mkdir, rmdir: gpfs_i_rmdir, mknod: gpfs_i_mknod, rename: gpfs_i_rename, readlink: gpfs_i_readlink, truncate: gpfs_i_truncate, /* noop (done by setattr) */ permission: GENERIC_PERMISSION, #if HAS_IOP_REVALIDATE revalidate: gpfs_i_revalidate, #endif setattr: gpfs_i_setattr, getattr: gpfs_i_getattr #if LINUX_KERNEL_VERSION > 2060000 , setxattr: gpfs_i_setxattr, getxattr: gpfs_i_getxattr, listxattr: gpfs_i_listxattr, removexattr: gpfs_i_removexattr #endif }; /* Inode operations for non-symlinks, non-directory that require a gpfs call to do permission checking either because the file/dir has extended acls or because the owner and mode cached in the Linux inode structure are not known to be valid. */ struct inode_operations gpfs_iops_xperm = { create: gpfs_i_create, // lookup: no lookup op for non-directory link: gpfs_i_link, unlink: gpfs_i_unlink, symlink: gpfs_i_symlink, mkdir: gpfs_i_mkdir, rmdir: gpfs_i_rmdir, mknod: gpfs_i_mknod, rename: gpfs_i_rename, readlink: gpfs_i_readlink, truncate: gpfs_i_truncate, /* noop (done by setattr) */ permission: gpfs_i_permission, #if HAS_IOP_REVALIDATE revalidate: gpfs_i_revalidate, #endif setattr: gpfs_i_setattr, getattr: gpfs_i_getattr #if LINUX_KERNEL_VERSION > 2060000 , setxattr: gpfs_i_setxattr, getxattr: gpfs_i_getxattr, listxattr: gpfs_i_listxattr, removexattr: gpfs_i_removexattr #endif }; /* Inode operations for directory with standard Unix permissions (no extended acls) and valid inode attributes (valid owner and mode cached in the Linux inode structure). */ struct inode_operations gpfs_dir_iops_stdperm = { create: gpfs_i_create, lookup: gpfs_i_lookup, link: gpfs_i_link, unlink: gpfs_i_unlink, symlink: gpfs_i_symlink, mkdir: gpfs_i_mkdir, rmdir: gpfs_i_rmdir, mknod: gpfs_i_mknod, rename: gpfs_i_rename, readlink: gpfs_i_readlink, truncate: gpfs_i_truncate, /* noop (done by setattr) */ permission: GENERIC_PERMISSION, #if HAS_IOP_REVALIDATE revalidate: gpfs_i_revalidate, #endif setattr: gpfs_i_setattr, getattr: gpfs_i_getattr #if LINUX_KERNEL_VERSION > 2060000 , setxattr: gpfs_i_setxattr, getxattr: gpfs_i_getxattr, listxattr: gpfs_i_listxattr, removexattr: gpfs_i_removexattr #endif }; /* Inode operations for directory that require a gpfs call to do permission checking either because the file/dir has extended acls or because the owner and mode cached in the Linux inode structure are not known to be valid. */ struct inode_operations gpfs_dir_iops_xperm = { create: gpfs_i_create, lookup: gpfs_i_lookup, link: gpfs_i_link, unlink: gpfs_i_unlink, symlink: gpfs_i_symlink, mkdir: gpfs_i_mkdir, rmdir: gpfs_i_rmdir, mknod: gpfs_i_mknod, rename: gpfs_i_rename, readlink: gpfs_i_readlink, truncate: gpfs_i_truncate, /* noop (done by setattr) */ permission: gpfs_i_permission, #if HAS_IOP_REVALIDATE revalidate: gpfs_i_revalidate, #endif setattr: gpfs_i_setattr, getattr: gpfs_i_getattr #if LINUX_KERNEL_VERSION > 2060000 , setxattr: gpfs_i_setxattr, getxattr: gpfs_i_getxattr, listxattr: gpfs_i_listxattr, removexattr: gpfs_i_removexattr #endif }; /* inode operations for symlinks */ struct inode_operations gpfs_link_iops = { create: gpfs_i_create, /* create */ // lookup: no lookup op for symlink link: gpfs_i_link, /* link */ unlink: gpfs_i_unlink, /* remove */ symlink: gpfs_i_symlink, /* symlink */ mkdir: gpfs_i_mkdir, /* mkdir */ rmdir: gpfs_i_rmdir, /* rmdir */ mknod: gpfs_i_mknod, /* mknod */ rename: gpfs_i_rename, /* rename */ readlink: gpfs_i_readlink, /* readlink */ follow_link: gpfs_i_follow_link,/* readlink... */ #ifdef HAS_IOP_PUT_LINK put_link: gpfs_i_put_link, /* delete link */ #endif truncate: gpfs_i_truncate, /* noop (done by setattr) */ // permission: no permission checking for symlink #if HAS_IOP_REVALIDATE revalidate: gpfs_i_revalidate, #endif setattr: gpfs_i_setattr, /* setattr */ getattr: gpfs_i_getattr /* getattr */ #if LINUX_KERNEL_VERSION > 2060000 , setxattr: gpfs_i_setxattr, getxattr: gpfs_i_getxattr, listxattr: gpfs_i_listxattr, removexattr: gpfs_i_removexattr #endif // no truncate_range }; /* Default file operations, the other operations for the device * come from the bare device */ struct file_operations gpfs_fops = { llseek: gpfs_f_llseek, read: gpfs_f_read, write: gpfs_f_write, readdir: gpfs_f_readdir, /*poll: gpfs_f_poll, let Linux handle poll by doing nothing */ ioctl: gpfs_f_ioctl, /* ENOSYS */ mmap: gpfs_f_mmap, /* ENOSYS */ open: gpfs_f_open, release: gpfs_f_release, fsync: gpfs_f_fsync, fasync: gpfs_f_fasync, lock: gpfs_f_lock, #ifdef NFS4_CLUSTER flock: gpfs_f_flock, #endif #if LINUX_KERNEL_VERSION >= 2060000 sendfile: generic_file_sendfile, #endif aio_read: gpfs_f_readv, aio_write: gpfs_f_writev }; struct file_operations gpfs_fops_no_sendfile = { llseek: gpfs_f_llseek, read: gpfs_f_read, write: gpfs_f_write, readdir: gpfs_f_readdir, /*poll: gpfs_f_poll, let Linux handle poll by doing nothing */ ioctl: gpfs_f_ioctl, /* ENOSYS */ mmap: gpfs_f_mmap, /* ENOSYS */ open: gpfs_f_open, release: gpfs_f_release, fsync: gpfs_f_fsync, fasync: gpfs_f_fasync, lock: gpfs_f_lock, #ifdef NFS4_CLUSTER flock: gpfs_f_flock, #endif aio_read: gpfs_f_readv, aio_write: gpfs_f_writev }; /* Directory file operations are the same as regular file operations, but read (as opposed to readdir) is not allowed */ struct file_operations gpfs_dir_fops = { llseek: gpfs_f_llseek, read: gpfs_f_dir_read, write: gpfs_f_write, readdir: gpfs_f_readdir, /*poll: gpfs_f_poll, let Linux handle poll by doing nothing */ ioctl: gpfs_f_ioctl, /* ENOSYS */ mmap: gpfs_f_mmap, /* ENOSYS */ open: gpfs_f_open, release: gpfs_f_release, fsync: gpfs_f_fsync, fasync: gpfs_f_fasync, lock: gpfs_f_lock, #ifdef NFS4_CLUSTER flock: gpfs_f_flock, #endif aio_read: gpfs_f_readv, aio_write: gpfs_f_writev }; /* dcache operations for a valid dentry: A valid dentry has no gpfs-specific operations defined; linux2gpfs.h #defines gpfs_dops_valid so that the assignement "d_op = &gpfs_dops_valid" will assign NULL to d_op instead of assigning a pointer to a table that only contains NULL function pointers. This saves a few instructions on each potential call to one of the d_op callbacks. The declaration below is left here ifdef'ed out so that a search for gpfs_dops_valid will find our comment here. */ #if 0 struct dentry_operations gpfs_dops_valid = { }; #endif /* dcache operations for a valid dentry for a file that has been or will be unlinked shortly; a BR token revoke on the directory containing this entry should invalidate this entry even if it does not look like a negative dcache entry yet (call to d_delete has not yet happened); see also comment in gpfs_i_unlink. */ struct dentry_operations gpfs_dops_ddeletepending = { /* No operations defined. There are explicit tests in the code for "d_op == &gpfs_dops_ddeletepending", so this structure cannot be removed as gpfs_dops_valid was. */ }; /* dcache operations for a dentry that has been invalidated by an inode token revoke on the file that this dentry refers to, or (in case of a negative dcache entry) by a BR token revoke on the directory containing this entry */ struct dentry_operations gpfs_dops_invalid = { d_revalidate: gpfs_d_invalid, }; struct dentry_operations gpfs_dops_revalidate = { d_revalidate: gpfs_d_revalidate, }; #ifdef CCL /* dcache operations for a positive dentry that was created for an inexact caseless file name match which succeeded for a Samba client. The d_revalidate returns "true" for subsequent Samba clients indicating that the dcache entry is still valid. It returns "false" for local or NFS clients indicating that the dcache entry is no longer valid which forces a new lookup. */ struct dentry_operations gpfs_dops_valid_if_Samba = { d_revalidate: gpfs_d_valid_if_Samba, }; /* dcache operations for a negative dentry that was created for an exact file name match which failed for a local or NFS client. The d_revalidate returns "true" for subsequent local or NFS clients indicating that the negative dcache entry is still valid. It returns "false" for Samba clients indicating that the dcache entry is no longer valid which forces a new lookup. */ struct dentry_operations gpfs_dops_invalid_if_Samba = { d_revalidate: gpfs_d_invalid_if_Samba, }; #endif #if LINUX_KERNEL_VERSION < 2050000 /* The other operations for the device come from the bare device */ struct block_device_operations gpfs_bops = { open: gpfs_b_open, release: gpfs_b_release, ioctl: gpfs_b_ioctl, }; struct file_operations gpfs_fbps = { open: gpfs_fb_open, release: gpfs_fb_release, ioctl: gpfs_fb_ioctl, read: gpfs_fb_read, write: gpfs_fb_write, }; #endif struct address_space_operations gpfs_aops = { readpage: gpfs_i_readpage, writepage: gpfs_i_writepage, #if LINUX_KERNEL_VERSION >= 2060000 sync_page: block_sync_page, #endif #if LINUX_KERNEL_VERSION >= 2060000 || defined(SUSE_LINUX) direct_IO: gpfs_f_direct_IO, #endif }; /* address_space_operations after inode deletion */ struct address_space_operations gpfs_aops_after_inode_delete = { }; /* * filemap nopage callback function */ struct vm_operations_struct gpfs_vmop = { nopage: gpfs_filemap_nopage, #if defined(MMAP_LINUX_PATCH) && LINUX_KERNEL_VERSION < 2060000 nopagedone: gpfs_filemap_nopagedone, #endif open: gpfs_filemap_open, close: gpfs_filemap_close, };