diff options
author | Brian Behlendorf <[email protected]> | 2011-01-26 12:03:58 -0800 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2011-02-10 09:27:21 -0800 |
commit | 1efb473f8919c5f195e127136b79c6d3b1eb1c81 (patch) | |
tree | 69937c80a49233c6ef948d3abf5bc19f52beeaee | |
parent | 633e8030b3582f3579a457a803c1382fc81f56e5 (diff) |
Add Hooks for Linux File Operations
The Linux specific file operations have all been located in the
file zpl_file.c. These functions primarily rely on the reworked
zfs_* functions to do their job. They are also responsible for
converting the possible Solaris style error codes to negative
Linux errors.
This first zpl_* commit also includes a common zpl.h header with
minimal entries to register the Linux specific hooks. In also
adds all the new zpl_* file to the Makefile.in. This is not a
standalone commit, you required the following zpl_* commits.
-rw-r--r-- | include/sys/Makefile.am | 1 | ||||
-rw-r--r-- | include/sys/Makefile.in | 2 | ||||
-rw-r--r-- | include/sys/zpl.h | 63 | ||||
-rw-r--r-- | lib/libzpool/Makefile.am | 4 | ||||
-rw-r--r-- | lib/libzpool/Makefile.in | 4 | ||||
-rw-r--r-- | module/zfs/Makefile.in | 4 | ||||
-rw-r--r-- | module/zfs/zpl_file.c | 173 |
7 files changed, 251 insertions, 0 deletions
diff --git a/include/sys/Makefile.am b/include/sys/Makefile.am index 63dc24e5b..bde71b75e 100644 --- a/include/sys/Makefile.am +++ b/include/sys/Makefile.am @@ -75,6 +75,7 @@ KERNEL_H = \ $(top_srcdir)/include/sys/blkdev.h \ $(top_srcdir)/include/sys/zfs_ioctl.h \ $(top_srcdir)/include/sys/zfs_onexit.h \ + ${top_srcdir}/include/sys/zpl.h \ $(top_srcdir)/include/sys/zvol.h USER_H = diff --git a/include/sys/Makefile.in b/include/sys/Makefile.in index 9243f75ab..1525d1d07 100644 --- a/include/sys/Makefile.in +++ b/include/sys/Makefile.in @@ -163,6 +163,7 @@ am__kernel_HEADERS_DIST = $(top_srcdir)/include/sys/arc.h \ $(top_srcdir)/include/sys/blkdev.h \ $(top_srcdir)/include/sys/zfs_ioctl.h \ $(top_srcdir)/include/sys/zfs_onexit.h \ + ${top_srcdir}/include/sys/zpl.h \ $(top_srcdir)/include/sys/zvol.h am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ @@ -531,6 +532,7 @@ KERNEL_H = \ $(top_srcdir)/include/sys/blkdev.h \ $(top_srcdir)/include/sys/zfs_ioctl.h \ $(top_srcdir)/include/sys/zfs_onexit.h \ + ${top_srcdir}/include/sys/zpl.h \ $(top_srcdir)/include/sys/zvol.h USER_H = diff --git a/include/sys/zpl.h b/include/sys/zpl.h new file mode 100644 index 000000000..33f4f621f --- /dev/null +++ b/include/sys/zpl.h @@ -0,0 +1,63 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2011, Lawrence Livermore National Security, LLC. + */ + +#ifndef _SYS_ZPL_H +#define _SYS_ZPL_H + +#include <sys/vfs.h> + +/* zpl_inode.c */ +extern const struct inode_operations zpl_inode_operations; +extern const struct inode_operations zpl_dir_inode_operations; +extern const struct inode_operations zpl_symlink_inode_operations; +extern const struct inode_operations zpl_special_inode_operations; + +/* zpl_file.c */ +extern ssize_t zpl_read_common(struct inode *ip, const char *buf, + size_t len, loff_t pos, uio_seg_t segment, int flags, cred_t *cr); +extern ssize_t zpl_write_common(struct inode *ip, const char *buf, + size_t len, loff_t pos, uio_seg_t segment, int flags, cred_t *cr); + +extern const struct address_space_operations zpl_address_space_operations; +extern const struct file_operations zpl_file_operations; +extern const struct file_operations zpl_dir_file_operations; + +/* zpl_super.c */ +typedef struct zpl_mount_data { + const char *z_osname; /* Dataset name */ + void *z_data; /* Mount options string */ + struct vfsmount *z_vfs; /* VFS mount point */ +} zpl_mount_data_t; + +extern const struct super_operations zpl_super_operations; +/* extern const struct export_operations zpl_export_operations; */ +extern struct file_system_type zpl_fs_type; + +/* zpl_xattr.c */ +extern ssize_t zpl_xattr_list(struct dentry *dentry, char *buf, size_t size); +extern int zpl_xattr_security_init(struct inode *ip, struct inode *dip); + +extern struct xattr_handler *zpl_xattr_handlers[]; + +#endif /* _SYS_ZPL_H */ diff --git a/lib/libzpool/Makefile.am b/lib/libzpool/Makefile.am index 450f4cca1..b15830ded 100644 --- a/lib/libzpool/Makefile.am +++ b/lib/libzpool/Makefile.am @@ -106,5 +106,9 @@ EXTRA_DIST = \ $(top_srcdir)/module/zfs/zfs_rlock.c \ $(top_srcdir)/module/zfs/zfs_vfsops.c \ $(top_srcdir)/module/zfs/zfs_vnops.c \ + $(top_srcdir)/module/zfs/zpl_file.c \ + $(top_srcdir)/module/zfs/zpl_inode.c \ + $(top_srcdir)/module/zfs/zpl_super.c \ + $(top_srcdir)/module/zfs/zpl_xattr.c \ $(top_srcdir)/module/zfs/zvol.c \ $(top_srcdir)/module/zpios/pios.c diff --git a/lib/libzpool/Makefile.in b/lib/libzpool/Makefile.in index 29d312f9d..344612d31 100644 --- a/lib/libzpool/Makefile.in +++ b/lib/libzpool/Makefile.in @@ -427,6 +427,10 @@ EXTRA_DIST = \ $(top_srcdir)/module/zfs/zfs_rlock.c \ $(top_srcdir)/module/zfs/zfs_vfsops.c \ $(top_srcdir)/module/zfs/zfs_vnops.c \ + $(top_srcdir)/module/zfs/zpl_file.c \ + $(top_srcdir)/module/zfs/zpl_inode.c \ + $(top_srcdir)/module/zfs/zpl_super.c \ + $(top_srcdir)/module/zfs/zpl_xattr.c \ $(top_srcdir)/module/zfs/zvol.c \ $(top_srcdir)/module/zpios/pios.c diff --git a/module/zfs/Makefile.in b/module/zfs/Makefile.in index 7d42481d1..5a99852a1 100644 --- a/module/zfs/Makefile.in +++ b/module/zfs/Makefile.in @@ -83,5 +83,9 @@ $(MODULE)-objs += @top_srcdir@/module/zfs/zio_checksum.o $(MODULE)-objs += @top_srcdir@/module/zfs/zio_compress.o $(MODULE)-objs += @top_srcdir@/module/zfs/zio_inject.o $(MODULE)-objs += @top_srcdir@/module/zfs/zle.o +$(MODULE)-objs += @top_srcdir@/module/zfs/zpl_file.o +$(MODULE)-objs += @top_srcdir@/module/zfs/zpl_inode.o +$(MODULE)-objs += @top_srcdir@/module/zfs/zpl_super.o +$(MODULE)-objs += @top_srcdir@/module/zfs/zpl_xattr.o $(MODULE)-objs += @top_srcdir@/module/zfs/zrlock.o $(MODULE)-objs += @top_srcdir@/module/zfs/zvol.o diff --git a/module/zfs/zpl_file.c b/module/zfs/zpl_file.c new file mode 100644 index 000000000..41901bb6c --- /dev/null +++ b/module/zfs/zpl_file.c @@ -0,0 +1,173 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2011, Lawrence Livermore National Security, LLC. + */ + + +#include <sys/zfs_vfsops.h> +#include <sys/zfs_vnops.h> +#include <sys/zfs_znode.h> +#include <sys/zpl.h> + + +static int +zpl_readdir(struct file *filp, void *dirent, filldir_t filldir) +{ + struct dentry *dentry = filp->f_path.dentry; + cred_t *cr; + int error; + + cr = (cred_t *)get_current_cred(); + error = -zfs_readdir(dentry->d_inode, dirent, filldir, + &filp->f_pos, cr); + put_cred(cr); + ASSERT3S(error, <=, 0); + + return (error); +} + +static int +zpl_fsync(struct file *filp, struct dentry *dentry, int datasync) +{ + cred_t *cr; + int error; + + cr = (cred_t *)get_current_cred(); + error = -zfs_fsync(filp->f_path.dentry->d_inode, datasync, cr); + put_cred(cr); + ASSERT3S(error, <=, 0); + + return (error); +} + +ssize_t +zpl_read_common(struct inode *ip, const char *buf, size_t len, loff_t pos, + uio_seg_t segment, int flags, cred_t *cr) +{ + int error; + struct iovec iov; + uio_t uio; + + iov.iov_base = (void *)buf; + iov.iov_len = len; + + uio.uio_iov = &iov; + uio.uio_resid = len; + uio.uio_iovcnt = 1; + uio.uio_loffset = pos; + uio.uio_limit = MAXOFFSET_T; + uio.uio_segflg = segment; + + error = -zfs_read(ip, &uio, flags, cr); + if (error < 0) + return (error); + + return (len - uio.uio_resid); +} + +static ssize_t +zpl_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos) +{ + cred_t *cr; + ssize_t read; + + cr = (cred_t *)get_current_cred(); + read = zpl_read_common(filp->f_mapping->host, buf, len, *ppos, + UIO_USERSPACE, filp->f_flags, cr); + put_cred(cr); + + if (read < 0) + return (read); + + *ppos += read; + return (read); +} + +ssize_t +zpl_write_common(struct inode *ip, const char *buf, size_t len, loff_t pos, + uio_seg_t segment, int flags, cred_t *cr) +{ + int error; + struct iovec iov; + uio_t uio; + + iov.iov_base = (void *)buf; + iov.iov_len = len; + + uio.uio_iov = &iov; + uio.uio_resid = len, + uio.uio_iovcnt = 1; + uio.uio_loffset = pos; + uio.uio_limit = MAXOFFSET_T; + uio.uio_segflg = segment; + + error = -zfs_write(ip, &uio, flags, cr); + if (error < 0) + return (error); + + return (len - uio.uio_resid); +} + +static ssize_t +zpl_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) +{ + cred_t *cr; + ssize_t wrote; + + cr = (cred_t *)get_current_cred(); + wrote = zpl_write_common(filp->f_mapping->host, buf, len, *ppos, + UIO_USERSPACE, filp->f_flags, cr); + put_cred(cr); + + if (wrote < 0) + return (wrote); + + *ppos += wrote; + return (wrote); +} + +const struct address_space_operations zpl_address_space_operations = { +#if 0 + .readpage = zpl_readpage, + .writepage = zpl_writepage, + .direct_IO = zpl_direct_IO, +#endif +}; + +const struct file_operations zpl_file_operations = { + .open = generic_file_open, + .llseek = generic_file_llseek, + .read = zpl_read, /* do_sync_read */ + .write = zpl_write, /* do_sync_write */ + .readdir = zpl_readdir, + .mmap = generic_file_mmap, + .fsync = zpl_fsync, + .aio_read = NULL, /* generic_file_aio_read */ + .aio_write = NULL, /* generic_file_aio_write */ +}; + +const struct file_operations zpl_dir_file_operations = { + .llseek = generic_file_llseek, + .read = generic_read_dir, + .readdir = zpl_readdir, + .fsync = zpl_fsync, +}; |