From: hooanon05@yahoo.co.jp
To: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Junjiro Okajima <hooanon05@yahoo.co.jp>
Subject: [PATCH 40/67] aufs file and vm operations
Date: Fri, 16 May 2008 23:32:54 +0900 [thread overview]
Message-ID: <12109484023224-git-send-email-hooanon05@yahoo.co.jp> (raw)
In-Reply-To: <12109484022745-git-send-email-hooanon05@yahoo.co.jp>
From: Junjiro Okajima <hooanon05@yahoo.co.jp>
initial commit
aufs file and vm operations
Signed-off-by: Junjiro Okajima <hooanon05@yahoo.co.jp>
---
fs/aufs/f_op.c | 665 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 665 insertions(+), 0 deletions(-)
diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c
new file mode 100644
index 0000000..ee8a849
--- /dev/null
+++ b/fs/aufs/f_op.c
@@ -0,0 +1,665 @@
+/*
+ * Copyright (C) 2005-2008 Junjiro Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * file and vm operations
+ *
+ * $Id: f_op.c,v 1.4 2008/05/12 00:28:10 sfjro Exp $
+ */
+
+//#include <linux/fsnotify.h>
+#include <linux/fs_stack.h>
+//#include <linux/pagemap.h>
+#include <linux/poll.h>
+//#include <linux/security.h>
+#include "aufs.h"
+
+/* common function to regular file and dir */
+int aufs_flush(struct file *file, fl_owner_t id)
+{
+ int err;
+ struct dentry *dentry;
+ aufs_bindex_t bindex, bend;
+
+ dentry = file->f_dentry;
+ LKTRTrace("%.*s\n", AuDLNPair(dentry));
+
+ // aufs_read_lock_file()
+ si_noflush_read_lock(dentry->d_sb);
+ fi_read_lock(file);
+ di_read_lock_child(dentry, AuLock_IW);
+
+ err = 0;
+ bend = au_fbend(file);
+ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
+ struct file *h_file;
+ h_file = au_h_fptr(file, bindex);
+ if (h_file && h_file->f_op && h_file->f_op->flush) {
+ err = h_file->f_op->flush(h_file, id);
+ if (!err)
+ au_update_fuse_h_inode
+ (h_file->f_vfsmnt, h_file->f_dentry);
+ /*ignore*/
+ }
+ }
+ au_cpup_attr_timesizes(dentry->d_inode);
+
+ di_read_unlock(dentry, AuLock_IW);
+ fi_read_unlock(file);
+ si_read_unlock(dentry->d_sb);
+ AuTraceErr(err);
+ return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int do_open_nondir(struct file *file, int flags)
+{
+ int err;
+ aufs_bindex_t bindex;
+ struct super_block *sb;
+ struct file *h_file;
+ struct dentry *dentry;
+ struct inode *inode;
+ struct au_finfo *finfo;
+
+ dentry = file->f_dentry;
+ LKTRTrace("%.*s, flags 0%o\n", AuDLNPair(dentry), flags);
+ FiMustWriteLock(file);
+ inode = dentry->d_inode;
+ AuDebugOn(!inode || S_ISDIR(inode->i_mode));
+
+ err = 0;
+ finfo = au_fi(file);
+ finfo->fi_h_vm_ops = NULL;
+ sb = dentry->d_sb;
+ bindex = au_dbstart(dentry);
+ AuDebugOn(!au_h_dptr(dentry, bindex)->d_inode);
+ /* O_TRUNC is processed already */
+ BUG_ON(au_test_ro(sb, bindex, inode) && (flags & O_TRUNC));
+
+ h_file = au_h_open(dentry, bindex, flags, file);
+ //if (LktrCond) {fput(h_file); au_br_put(au_sbr(dentry->d_sb, bindex));
+ //h_file = ERR_PTR(-1);}
+ if (!IS_ERR(h_file)) {
+ au_set_fbstart(file, bindex);
+ au_set_fbend(file, bindex);
+ au_set_h_fptr(file, bindex, h_file);
+ au_update_figen(file);
+ //file->f_ra = h_file->f_ra; //??
+ //AuDbgFile(file);
+ return 0; /* success */
+ }
+ err = PTR_ERR(h_file);
+ AuTraceErr(err);
+ return err;
+}
+
+static int aufs_open_nondir(struct inode *inode, struct file *file)
+{
+ return au_do_open(inode, file, do_open_nondir);
+}
+
+static int aufs_release_nondir(struct inode *inode, struct file *file)
+{
+ struct super_block *sb = file->f_dentry->d_sb;
+
+ LKTRTrace("i%lu, %.*s\n", inode->i_ino, AuDLNPair(file->f_dentry));
+
+ si_noflush_read_lock(sb);
+ au_finfo_fin(file);
+ si_read_unlock(sb);
+ return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static ssize_t aufs_read(struct file *file, char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ ssize_t err;
+ struct dentry *dentry;
+ struct file *h_file;
+ struct super_block *sb;
+ struct inode *h_inode;
+
+ dentry = file->f_dentry;
+ LKTRTrace("%.*s, cnt %lu, pos %Ld\n",
+ AuDLNPair(dentry), (unsigned long)count, *ppos);
+ //AuDbgDentry(dentry);
+
+ sb = dentry->d_sb;
+ si_read_lock(sb, AuLock_FLUSH);
+ err = au_reval_and_lock_finfo(file, au_reopen_nondir, /*wlock*/0,
+ /*locked*/0);
+ //if (LktrCond) {fi_read_unlock(file); err = -1;}
+ if (unlikely(err))
+ goto out;
+
+ /* support LSM and notify */
+ h_file = au_h_fptr(file, au_fbstart(file));
+ h_inode = h_file->f_dentry->d_inode;
+ err = vfsub_read_u(h_file, buf, count, ppos,
+ au_opt_test_dlgt(au_mntflags(sb)));
+ //file->f_ra = h_file->f_ra; //??
+ fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode);
+
+ fi_read_unlock(file);
+ out:
+ si_read_unlock(sb);
+ AuTraceErr(err);
+ return err;
+}
+
+static ssize_t aufs_write(struct file *file, const char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ ssize_t err;
+ struct dentry *dentry, *parent;
+ struct inode *inode, *dir;
+ struct super_block *sb;
+ unsigned int mnt_flags;
+ struct file *h_file;
+ char __user *buf = (char __user *)ubuf;
+ struct au_hin_ignore ign;
+ struct vfsub_args vargs;
+
+ dentry = file->f_dentry;
+ LKTRTrace("%.*s, cnt %lu, pos %Ld\n",
+ AuDLNPair(dentry), (unsigned long)count, *ppos);
+
+ inode = dentry->d_inode;
+ mutex_lock(&inode->i_mutex);
+ sb = dentry->d_sb;
+ si_read_lock(sb, AuLock_FLUSH);
+ err = au_reval_and_lock_finfo(file, au_reopen_nondir, /*wlock*/1,
+ /*locked*/1);
+ //if (LktrCond) {fi_write_unlock(file); err = -1;}
+ if (unlikely(err))
+ goto out;
+ err = au_ready_to_write(file, -1);
+ //if (LktrCond) err = -1;
+ if (unlikely(err))
+ goto out_unlock;
+
+ /* support LSM and notify */
+ mnt_flags = au_mntflags(sb);
+ vfsub_args_init(&vargs, &ign, au_opt_test_dlgt(mnt_flags), 0);
+ h_file = au_h_fptr(file, au_fbstart(file));
+ if (!au_opt_test(mnt_flags, UDBA_INOTIFY))
+ err = vfsub_write_u(h_file, buf, count, ppos, &vargs);
+ else {
+ parent = dget_parent(dentry);
+ dir = parent->d_inode;
+ ii_read_lock_parent(dir);
+ vfsub_ign_hinode(&vargs, IN_MODIFY,
+ au_hi(dir, au_fbstart(file)));
+ err = vfsub_write_u(h_file, buf, count, ppos, &vargs);
+ ii_read_unlock(dir);
+ dput(parent);
+ }
+ ii_write_lock_child(inode);
+ au_cpup_attr_timesizes(inode);
+ ii_write_unlock(inode);
+
+ out_unlock:
+ fi_write_unlock(file);
+ out:
+ si_read_unlock(sb);
+ mutex_unlock(&inode->i_mutex);
+ AuTraceErr(err);
+ return err;
+}
+
+#ifdef CONFIG_AUFS_SPLICE_PATCH
+static int au_test_loopback(void)
+{
+ const char c = current->comm[4];
+ /* true if a kernel thread named 'loop[0-9].*' accesses a file */
+ const int loopback = (current->mm == NULL
+ && '0' <= c && c <= '9'
+ && strncmp(current->comm, "loop", 4) == 0);
+ return loopback;
+}
+
+static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
+ struct pipe_inode_info *pipe, size_t len,
+ unsigned int flags)
+{
+ ssize_t err;
+ struct file *h_file;
+ struct dentry *dentry;
+ struct super_block *sb;
+
+ dentry = file->f_dentry;
+ LKTRTrace("%.*s, pos %Ld, len %lu\n",
+ AuDLNPair(dentry), *ppos, (unsigned long)len);
+
+ sb = dentry->d_sb;
+ si_read_lock(sb, AuLock_FLUSH);
+ err = au_reval_and_lock_finfo(file, au_reopen_nondir, /*wlock*/0,
+ /*locked*/0);
+ if (unlikely(err))
+ goto out;
+
+ err = -EINVAL;
+ /* support LSM and notify */
+ h_file = au_h_fptr(file, au_fbstart(file));
+ if (/* unlikely */(au_test_loopback())) {
+ file->f_mapping = h_file->f_mapping;
+ smp_mb(); /* unnecessary? */
+ }
+ err = vfsub_splice_to(h_file, ppos, pipe, len, flags,
+ au_opt_test_dlgt(au_mntflags(sb)));
+ //file->f_ra = h_file->f_ra; //??
+ fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode);
+ fi_read_unlock(file);
+
+ out:
+ si_read_unlock(sb);
+ AuTraceErr(err);
+ return err;
+}
+
+static ssize_t
+aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos,
+ size_t len, unsigned int flags)
+{
+ ssize_t err;
+ struct dentry *dentry;
+ struct inode *inode, *h_inode;
+ struct super_block *sb;
+ struct file *h_file;
+ struct au_hin_ignore ign;
+ struct vfsub_args vargs;
+ unsigned int mnt_flags;
+
+ dentry = file->f_dentry;
+ LKTRTrace("%.*s, len %lu, pos %Ld\n",
+ AuDLNPair(dentry), (unsigned long)len, *ppos);
+
+ inode = dentry->d_inode;
+ mutex_lock(&inode->i_mutex);
+ sb = dentry->d_sb;
+ si_read_lock(sb, AuLock_FLUSH);
+ err = au_reval_and_lock_finfo(file, au_reopen_nondir, /*wlock*/1,
+ /*locked*/1);
+ //if (LktrCond) {fi_write_unlock(file); err = -1;}
+ if (unlikely(err))
+ goto out;
+ err = au_ready_to_write(file, -1);
+ //if (LktrCond) err = -1;
+ if (unlikely(err))
+ goto out_unlock;
+
+ /* support LSM and notify */
+ mnt_flags = au_mntflags(sb);
+ vfsub_args_init(&vargs, &ign, au_opt_test_dlgt(mnt_flags), 0);
+ h_file = au_h_fptr(file, au_fbstart(file));
+ h_inode = h_file->f_dentry->d_inode;
+ /* current do_splice_from() doesn't fire up the inotify event */
+ if (1 || !au_opt_test(mnt_flags, UDBA_INOTIFY))
+ err = vfsub_splice_from(pipe, h_file, ppos, len, flags, &vargs);
+ else {
+ //struct dentry *parent = dget_parent(dentry);
+ //vfsub_ign_hinode(&vargs, IN_MODIFY,
+ //au_hi(parent->d_inode, au_fbstart(file));
+ err = vfsub_splice_from(pipe, h_file, ppos, len, flags, &vargs);
+ //dput(parent);
+ }
+ ii_write_lock_child(inode);
+ au_cpup_attr_timesizes(inode);
+ ii_write_unlock(inode);
+
+ out_unlock:
+ fi_write_unlock(file);
+ out:
+ si_read_unlock(sb);
+ mutex_unlock(&inode->i_mutex);
+ AuTraceErr(err);
+ return err;
+}
+#endif /* CONFIG_AUFS_SPLICE_PATCH */
+
+/* ---------------------------------------------------------------------- */
+
+static int aufs_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+ int err;
+ struct dentry *dentry;
+ struct file *file, *h_file;
+ struct inode *inode;
+ static DECLARE_WAIT_QUEUE_HEAD(wq);
+ struct au_finfo *finfo;
+ //struct page *page;
+
+ AuTraceEnter();
+ AuDebugOn(!vma || !vma->vm_file);
+ //todo: non-robr mode, user vm_file as it is.
+ wait_event(wq, (file = au_robr_safe_file(vma)));
+ AuDebugOn(!au_test_aufs(file->f_dentry->d_sb));
+ dentry = file->f_dentry;
+ LKTRTrace("%.*s\n", AuDLNPair(dentry));
+ inode = dentry->d_inode;
+ AuDebugOn(!S_ISREG(inode->i_mode));
+
+ /* do not revalidate, no si lock */
+ finfo = au_fi(file);
+ h_file = finfo->fi_hfile[0 + finfo->fi_bstart].hf_file;
+ AuDebugOn(!h_file || !au_test_mmapped(file));
+ fi_write_lock(file);
+ vma->vm_file = h_file;
+ err = finfo->fi_h_vm_ops->fault(vma, vmf);
+ //file->f_ra = h_file->f_ra; //??
+ au_robr_reset_file(vma, file);
+ fi_write_unlock(file);
+#if 0 //def CONFIG_SMP
+ //wake_up_nr(&wq, online_cpu - 1);
+ wake_up_all(&wq);
+#else
+ wake_up(&wq);
+#endif
+
+ if (!(err & VM_FAULT_ERROR)) {
+#if 0
+ page = vmf->page;
+ AuDbg("%p, %d\n", page, page_mapcount(page));
+#endif
+ //page->mapping = file->f_mapping;
+ //get_page(page);
+ //file->f_mapping = h_file->f_mapping;
+ //touch_atime(NULL, dentry);
+ //inode->i_atime = h_file->f_dentry->d_inode->i_atime;
+ }
+ AuTraceErr(err);
+ //AuDbg("err %d\n", err);
+ return err;
+}
+
+static struct vm_operations_struct aufs_vm_ops = {
+ //.open = aufs_vmaopen,
+ //.close = aufs_vmaclose,
+ .fault = aufs_fault,
+#if 0 // rfu
+ unsigned long (*nopfn)(struct vm_area_struct *area,
+ unsigned long address);
+ //page_mkwrite(struct vm_area_struct *vma, struct page *page)
+#endif
+};
+
+/* ---------------------------------------------------------------------- */
+
+static struct vm_operations_struct *au_vm_ops(struct file *h_file,
+ struct vm_area_struct *vma)
+{
+ struct vm_operations_struct *vm_ops;
+ int err;
+
+ AuTraceEnter();
+
+ if (!au_test_nfs(h_file->f_vfsmnt->mnt_sb))
+ err = h_file->f_op->mmap(h_file, vma);
+ else {
+ lockdep_off();
+ err = h_file->f_op->mmap(h_file, vma);
+ lockdep_on();
+ }
+ vm_ops = ERR_PTR(err);
+ if (unlikely(err))
+ goto out;
+ vm_ops = vma->vm_ops;
+ err = do_munmap(current->mm, vma->vm_start,
+ vma->vm_end - vma->vm_start);
+ if (unlikely(err)) {
+ AuIOErr("failed internal unmapping %.*s, %d\n",
+ AuDLNPair(h_file->f_dentry), err);
+ vm_ops = ERR_PTR(-EIO);
+ }
+
+ out:
+ AuTraceErrPtr(vm_ops);
+ return vm_ops;
+}
+
+static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ int err, wlock, mmapped;
+ struct dentry *dentry;
+ struct super_block *sb;
+ struct file *h_file;
+ struct vm_operations_struct *vm_ops;
+
+ dentry = file->f_dentry;
+ LKTRTrace("%.*s, %lx, len %lu\n",
+ AuDLNPair(dentry), vma->vm_start,
+ vma->vm_end - vma->vm_start);
+ AuDebugOn(!S_ISREG(dentry->d_inode->i_mode));
+ AuDebugOn(down_write_trylock(&vma->vm_mm->mmap_sem));
+
+ mmapped = au_test_mmapped(file); /* can be harmless race condition */
+ wlock = !!(file->f_mode & FMODE_WRITE);
+ sb = dentry->d_sb;
+ si_read_lock(sb, AuLock_FLUSH);
+ err = au_reval_and_lock_finfo(file, au_reopen_nondir,
+ wlock | !mmapped, /*locked*/0);
+ //err = -1;
+ if (unlikely(err))
+ goto out;
+
+ if (wlock) {
+ err = au_ready_to_write(file, -1);
+ //err = -1;
+ if (unlikely(err))
+ goto out_unlock;
+ }
+
+ h_file = au_h_fptr(file, au_fbstart(file));
+ if (unlikely(au_test_fuse(h_file->f_dentry->d_sb))) {
+ /*
+ * by this assignment, f_mapping will differs from aufs inode
+ * i_mapping.
+ * if someone else mixes the use of f_dentry->d_inode and
+ * f_mapping->host, then a problem may arise.
+ */
+ file->f_mapping = h_file->f_mapping;
+ }
+
+ if (0 && h_file->f_op->mmap == generic_file_mmap) {
+ err = generic_file_mmap(file, vma); /* instead of h_file */
+ if (unlikely(err))
+ goto out_unlock;
+ au_fi(file)->fi_h_vm_ops = vma->vm_ops;
+ } else {
+ vm_ops = NULL;
+ if (!mmapped) {
+ vm_ops = au_vm_ops(h_file, vma);
+ err = PTR_ERR(vm_ops);
+ if (IS_ERR(vm_ops))
+ goto out_unlock;
+ }
+
+ err = generic_file_mmap(file, vma);
+ if (unlikely(err))
+ goto out_unlock;
+ vma->vm_ops = &aufs_vm_ops;
+ /* test again */
+ if (!au_test_mmapped(file)) {
+ FiMustWriteLock(file);
+ au_fi(file)->fi_h_vm_ops = vm_ops;
+ }
+ }
+
+ file_accessed(h_file);
+ au_update_fuse_h_inode(h_file->f_vfsmnt, h_file->f_dentry); /*ignore*/
+ fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode);
+
+ out_unlock:
+ if (!wlock && mmapped)
+ fi_read_unlock(file);
+ else
+ fi_write_unlock(file);
+ out:
+ si_read_unlock(sb);
+ AuTraceErr(err);
+ return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static unsigned int aufs_poll(struct file *file, poll_table *wait)
+{
+ unsigned int mask;
+ struct file *h_file;
+ int err;
+ struct dentry *dentry;
+ struct super_block *sb;
+
+ dentry = file->f_dentry;
+ LKTRTrace("%.*s, wait %p\n", AuDLNPair(dentry), wait);
+ AuDebugOn(S_ISDIR(dentry->d_inode->i_mode));
+
+ /* We should pretend an error happened. */
+ mask = POLLERR /* | POLLIN | POLLOUT */;
+ sb = dentry->d_sb;
+ si_read_lock(sb, AuLock_FLUSH);
+ err = au_reval_and_lock_finfo(file, au_reopen_nondir, /*wlock*/0,
+ /*locked*/0);
+ //err = -1;
+ if (unlikely(err))
+ goto out;
+
+ /* it is not an error of hidden_file has no operation */
+ mask = DEFAULT_POLLMASK;
+ h_file = au_h_fptr(file, au_fbstart(file));
+ if (h_file->f_op && h_file->f_op->poll)
+ mask = h_file->f_op->poll(h_file, wait);
+ fi_read_unlock(file);
+
+ out:
+ si_read_unlock(sb);
+ AuTraceErr((int)mask);
+ return mask;
+}
+
+static int aufs_fsync_nondir(struct file *file, struct dentry *dentry,
+ int datasync)
+{
+ int err;
+ struct inode *inode;
+ struct file *h_file;
+ struct super_block *sb;
+
+ LKTRTrace("%.*s, %d\n", AuDLNPair(dentry), datasync);
+ inode = dentry->d_inode;
+
+ IMustLock(file->f_mapping->host);
+ if (unlikely(inode != file->f_mapping->host)) {
+ mutex_unlock(&file->f_mapping->host->i_mutex);
+ mutex_lock(&inode->i_mutex);
+ }
+ IMustLock(inode);
+
+ sb = dentry->d_sb;
+ si_read_lock(sb, AuLock_FLUSH);
+ err = 0; //-EBADF; // posix?
+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
+ goto out;
+ err = au_reval_and_lock_finfo(file, au_reopen_nondir, /*wlock*/1,
+ /*locked*/1);
+ //err = -1;
+ if (unlikely(err))
+ goto out;
+ err = au_ready_to_write(file, -1);
+ //err = -1;
+ if (unlikely(err))
+ goto out_unlock;
+
+ err = -EINVAL;
+ h_file = au_h_fptr(file, au_fbstart(file));
+ if (h_file->f_op && h_file->f_op->fsync) {
+ ii_write_lock_child(inode);
+ mutex_lock_nested(&h_file->f_dentry->d_inode->i_mutex,
+ AuLsc_I_CHILD);
+ err = h_file->f_op->fsync(h_file, h_file->f_dentry, datasync);
+ //err = -1;
+ if (!err)
+ au_update_fuse_h_inode(h_file->f_vfsmnt,
+ h_file->f_dentry);
+ au_cpup_attr_timesizes(inode);
+ mutex_unlock(&h_file->f_dentry->d_inode->i_mutex);
+ ii_write_unlock(inode);
+ }
+
+ out_unlock:
+ fi_write_unlock(file);
+ out:
+ si_read_unlock(sb);
+ if (unlikely(inode != file->f_mapping->host)) {
+ mutex_unlock(&inode->i_mutex);
+ mutex_lock(&file->f_mapping->host->i_mutex);
+ }
+ AuTraceErr(err);
+ return err;
+}
+
+static int aufs_fasync(int fd, struct file *file, int flag)
+{
+ int err;
+ struct file *h_file;
+ struct dentry *dentry;
+ struct super_block *sb;
+
+ dentry = file->f_dentry;
+ LKTRTrace("%.*s, %d\n", AuDLNPair(dentry), flag);
+
+ sb = dentry->d_sb;
+ si_read_lock(sb, AuLock_FLUSH);
+ err = au_reval_and_lock_finfo(file, au_reopen_nondir, /*wlock*/0,
+ /*locked*/0);
+ //err = -1;
+ if (unlikely(err))
+ goto out;
+
+ h_file = au_h_fptr(file, au_fbstart(file));
+ if (h_file->f_op && h_file->f_op->fasync)
+ err = h_file->f_op->fasync(fd, h_file, flag);
+ fi_read_unlock(file);
+
+ out:
+ si_read_unlock(sb);
+ AuTraceErr(err);
+ return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
+struct file_operations aufs_file_fop = {
+ .read = aufs_read,
+ .write = aufs_write,
+ .poll = aufs_poll,
+ .mmap = aufs_mmap,
+ .open = aufs_open_nondir,
+ .flush = aufs_flush,
+ .release = aufs_release_nondir,
+ .fsync = aufs_fsync_nondir,
+ .fasync = aufs_fasync,
+#ifdef CONFIG_AUFS_SPLICE_PATCH
+ .splice_write = aufs_splice_write,
+ .splice_read = aufs_splice_read,
+#endif
+};
--
1.4.4.4
next prev parent reply other threads:[~2008-05-16 14:50 UTC|newest]
Thread overview: 80+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-05-16 14:32 [PATCH 1/67] aufs document hooanon05
2008-05-16 14:32 ` [PATCH 2/67] aufs manual hooanon05
2008-05-16 14:32 ` [PATCH 3/67] aufs global header file hooanon05
2008-05-16 14:32 ` [PATCH 4/67] aufs configuration hooanon05
2008-05-16 14:32 ` [PATCH 5/67] aufs Makefile hooanon05
2008-05-16 14:32 ` [PATCH 6/67] aufs main header file hooanon05
2008-05-16 14:32 ` [PATCH 7/67] aufs module initialization and module-global hooanon05
2008-05-16 14:32 ` [PATCH 8/67] aufs module global variables and operations hooanon05
2008-05-16 14:32 ` [PATCH 9/67] aufs super_block operations hooanon05
2008-05-16 14:32 ` [PATCH 10/67] aufs mount and " hooanon05
2008-05-16 14:32 ` [PATCH 11/67] aufs superblock private data hooanon05
2008-05-16 14:32 ` [PATCH 12/67] aufs branch filesystems and xino for them hooanon05
2008-05-16 14:32 ` [PATCH 13/67] aufs branch management hooanon05
2008-05-16 14:32 ` [PATCH 14/67] aufs external inode number translation table and bitmap hooanon05
2008-05-16 14:32 ` [PATCH 15/67] aufs special handling for inode attributes on FUSE branch hooanon05
2008-05-16 14:32 ` [PATCH 16/67] aufs lookup functions for NFS branch in linux-2.6.19 and later hooanon05
2008-05-16 14:32 ` [PATCH 17/67] aufs special handling inode attributes on XFS branch in linux-2.6.24 " hooanon05
2008-05-16 14:32 ` [PATCH 18/67] aufs sysfs interface and lifetime management, header hooanon05
2008-05-16 14:32 ` [PATCH 19/67] aufs sysfs interface and lifetime management, source hooanon05
2008-05-16 14:32 ` [PATCH 20/67] aufs mount options/flags, header hooanon05
2008-05-16 14:32 ` [PATCH 21/67] aufs mount options/flags, source hooanon05
2008-05-16 14:32 ` [PATCH 22/67] aufs workqueue for asynchronous/super-io/delegated operations, header hooanon05
2008-05-16 14:32 ` [PATCH 23/67] aufs workqueue for asynchronous/super-io/delegated operations, source hooanon05
2008-05-16 14:32 ` [PATCH 24/67] aufs sub-VFS, header hooanon05
2008-05-16 14:32 ` [PATCH 25/67] aufs sub-VFS, source hooanon05
2008-05-16 14:32 ` [PATCH 26/67] aufs sub-dcache, header hooanon05
2008-05-16 14:32 ` [PATCH 27/67] aufs sub-dcache, source hooanon05
2008-05-16 14:32 ` [PATCH 28/67] aufs copy-up/down functions hooanon05
2008-05-16 14:32 ` [PATCH 29/67] aufs copy-up functions, see wbr_policy.c for copy-down hooanon05
2008-05-16 14:32 ` [PATCH 30/67] aufs whiteout for logical deletion and opaque directory, header hooanon05
2008-05-16 14:32 ` [PATCH 31/67] aufs whiteout for logical deletion and opaque directory, source hooanon05
2008-05-16 14:32 ` [PATCH 32/67] aufs pseudo-link hooanon05
2008-05-16 14:32 ` [PATCH 33/67] aufs policies for selecting one among multiple writable branches hooanon05
2008-05-16 14:32 ` [PATCH 34/67] aufs lookup and dentry operations, header hooanon05
2008-05-16 14:32 ` [PATCH 35/67] aufs lookup and dentry operations, source hooanon05
2008-05-16 14:32 ` [PATCH 36/67] aufs dentry private data hooanon05
2008-05-16 14:32 ` [PATCH 37/67] aufs file operations hooanon05
2008-05-16 14:32 ` [PATCH 38/67] aufs handling file/dir, and address_space operation hooanon05
2008-05-16 14:32 ` [PATCH 39/67] aufs file private data hooanon05
2008-05-16 14:32 ` hooanon05 [this message]
2008-05-16 14:32 ` [PATCH 41/67] aufs directory operations, header hooanon05
2008-05-16 14:32 ` [PATCH 42/67] aufs directory operations, source hooanon05
2008-05-16 14:32 ` [PATCH 43/67] aufs virtual or vertical directory hooanon05
2008-05-16 14:32 ` [PATCH 44/67] aufs inode operations hooanon05
2008-05-16 14:32 ` [PATCH 45/67] aufs inode functions hooanon05
2008-05-16 14:33 ` [PATCH 46/67] aufs inode private data hooanon05
2008-05-16 14:33 ` [PATCH 47/67] aufs inode operations (except add/del/rename) hooanon05
2008-05-16 14:33 ` [PATCH 48/67] aufs inode operations (add entry) hooanon05
2008-05-16 14:33 ` [PATCH 49/67] aufs inode operations (del entry) hooanon05
2008-05-16 14:33 ` [PATCH 50/67] aufs inode operation (rename entry) hooanon05
2008-05-16 14:33 ` [PATCH 51/67] aufs lower (branch filesystem) inode and setting inotify hooanon05
2008-05-16 14:33 ` [PATCH 52/67] aufs inotify handler hooanon05
2008-05-16 14:33 ` [PATCH 53/67] aufs sub-routines for vfs in hinotify or dlgt mode hooanon05
2008-05-16 14:33 ` [PATCH 54/67] aufs lookup functions in 'delegate' mode hooanon05
2008-05-16 14:33 ` [PATCH 55/67] aufs export via nfs hooanon05
2008-05-16 14:33 ` [PATCH 56/67] aufs 'robr', aufs as readonly branch of another aufs hooanon05
2008-05-16 14:33 ` [PATCH 57/67] aufs sysfs interface hooanon05
2008-05-16 14:33 ` [PATCH 58/67] aufs misc functions, header hooanon05
2008-05-16 14:33 ` [PATCH 59/67] aufs misc functions, source hooanon05
2008-05-16 14:33 ` [PATCH 60/67] aufs debug print functions, header hooanon05
2008-05-16 14:33 ` [PATCH 61/67] aufs debug print functions, source hooanon05
2008-05-16 14:33 ` [PATCH 62/67] aufs magic sysrq handler hooanon05
2008-05-16 14:33 ` [PATCH 63/67] aufs mount helper hooanon05
2008-05-16 14:33 ` [PATCH 64/67] aufs pseudo-link helper hooanon05
2008-05-16 14:33 ` [PATCH 65/67] aufs pseudo-link helper for symlink hooanon05
2008-05-16 14:33 ` [PATCH 66/67] aufs umount helper hooanon05
2008-05-16 14:33 ` [PATCH 67/67] merge aufs hooanon05
2008-05-16 15:36 ` [PATCH 8/67] aufs module global variables and operations Jan Engelhardt
2008-05-16 15:33 ` [PATCH 6/67] aufs main header file Jan Engelhardt
2008-05-16 17:25 ` [PATCH 5/67] aufs Makefile Sam Ravnborg
2008-05-19 2:27 ` hooanon05
2008-05-16 15:28 ` [PATCH 4/67] aufs configuration Jan Engelhardt
2008-05-19 2:23 ` hooanon05
2008-05-16 14:59 ` [PATCH 1/67] aufs document Dave Quigley
2008-05-16 15:32 ` Jan Engelhardt
2008-05-16 21:07 ` Josef 'Jeff' Sipek
2008-05-19 2:25 ` hooanon05
2008-05-16 15:45 ` hooanon05
2008-05-16 16:09 ` Dave Quigley
2008-05-17 2:06 ` hooanon05
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=12109484023224-git-send-email-hooanon05@yahoo.co.jp \
--to=hooanon05@yahoo.co.jp \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®