Push to branch refs/heads/master:
1540ae90783ec8097ab7df1a42607af02851591d -->
675f7660ffb0e1880011f6b3c4f9ac241491e3cd
diff --git a/Documentation/filesystems/00-INDEX
b/Documentation/filesystems/00-INDEX
index 61cd1c5..4303614 100644
--- a/Documentation/filesystems/00-INDEX
+++ b/Documentation/filesystems/00-INDEX
@@ -116,8 +116,6 @@ vfat.txt
- info on using the VFAT filesystem used in Windows NT and Windows 95
vfs.txt
- overview of the Virtual File System
-wrapfs.txt
- - info and mount options for the stackable wrapper file system
xfs.txt
- info and mount options for the XFS filesystem.
xip.txt
diff --git a/Documentation/filesystems/wrapfs.txt
b/Documentation/filesystems/wrapfs.txt
deleted file mode 100644
index daa313b..0000000
--- a/Documentation/filesystems/wrapfs.txt
+++ /dev/null
@@ -1,172 +0,0 @@
-Wrapfs: a null-layer (aka wrapper) stackable file system
-
-Maintainer: Erez Zadok <ezk AT cs DOT stonybrook DOT edu>
-Web Site: <http://wrapfs.filesystems.org/>
-
-------------------------------------------------------------------------------
-MOTIVATION:
-
-Wrapfs is a small null-layer stackable file system, similar to BSD's Nullfs.
-Wrapfs is small, under 1,800 lines of code. Compare that to, say, eCryptfs
-(in mainline since 2.6.19) and Unionfs, each of which are over 10,000 LoC.
-As such, Wrapfs is simple, easy to read and understand, and very easy to
-code-review. Wrapfs is useful for several reasons:
-
-1. Many people like to experiment with in-kernel file system ideas. Wrapfs
- is an ideal small template that one can modify to incrementally create
- new file system functionalities.
-
-2. As a platform to test and debug generic stacking problems in other Linux
- stackable file systems (e.g., eCryptfs) more easily.
-
-3. As a way to test VFS enhancements to better support stacking in Linux.
-
-4. Wrapfs is also a very useful instructional tool, often used as a starting
- point for course assignments, for people who want a small example of how
- the Linux VFS works, or for those who want to learn how to write new
- Linux file systems.
-
-5. As an alternative to bind mounts. Wrapfs acts similarly to BSD's
- loopback mount file system (lofs).
-
-Various versions of Wrapfs appeared as part of the "fistgen" package since
-1994, and have been used by numerous users world-wide. This latest version
-was rewritten entirely from scratch in 2010 and had supported every kernel
-as of 2.6.32. All versions of wrapfs have been thoroughly tested using LTP,
-FSX, racer, and other test-suites. Wrapfs code uses the latest VFS API
-changes of the corresponding kernel. For a more detailed history of Wrapfs,
-and list of most of its known users, see the section marked "HISTORY" below.
-
-------------------------------------------------------------------------------
-OPERATION:
-
-This is a brief description of how Wrapfs operates. For more information,
-see the full paper published in Linux Expo 1999, titled "A Stackable File
-System Interface For Linux":
-
- <http://www.fsl.cs.sunysb.edu/docs/linux-stacking/linux.pdf>
-
-The basic function of a stackable file system is to pass an operation and
-its arguments to the lower-level file system. For every VFS object (inode,
-dentry, file, superblock, etc.), Wrapfs keeps a one-to-one mapping of a
-Wrapfs-level object to the lower one. We call the Wrapfs object the "upper"
-one, and the one below we call the "lower" one. Wrapfs stores these
-mappings as simple pointers inside the private field of the existing VFS
-objects (e.g., dentry->d_fsdata, sb->s_fs_info, and a container for inodes).
-
-There are two kinds of stackable operations: those that create new VFS
-objects and those that don't.
-
-The following distilled code snippet shows a method which doesn't create a
-new object. The method just has to pass it to the lower layer and propagate
-any errors back up the VFS:
-
-int wrapfs_unlink(struct inode *dir, struct dentry *dentry)
-{
- int err;
- struct inode *lower_dir;
- struct dentry *lower_dentry;
- lower_dir = get_lower_inode(dir);
- lower_dentry = get_lower_dentry(dentry);
- err = lower_dir->i_op->unlink(lower_dir, lower_dentry);
- return err;
-}
-
-The following code snippet shows a method which creates a new object. After
-a lower object gets created, Wrapfs has to also create its own object, and
-make the pointer connections between the upper and lower objects (the latter
-is done via a helper routine called "interpose"):
-
-int wrapfs_create(struct inode *dir, struct dentry *dentry, int mode)
-{
- int err;
- struct dentry *lower_dentry;
- struct inode *lower_dir;
- lower_dir = wrapfs_lower_inode(dir);
- lower_dentry = wrapfs_lower_dentry(dentry);
- err = vfs_create(lower_dir, lower_dentry, mode);
- if (!err)
- err = wrapfs_interpose(dentry, dir->i_sb);
- return err;
-}
-
-The wrapfs_unlink code snippet above can be easily modified to change the
-behavior of unlink(2). For example, if an ->unlink operation is changed to
-->rename, this could become the basis for an "undo" file system; or if the
-lower_dentry's name gets encrypted before calling the lower ->unlink, this
-could be part of an encryption file system.
-
-------------------------------------------------------------------------------
-USAGE:
-
-First, you have to have some pre-existing directory already mounted from any
-other file system, say /some/lower/path. Then, to mount wrapfs in
-/mnt/wrapfs, on that lower directory, issue this command:
-
-# mount -t wrapfs /some/lower/path /mnt/wrapfs
-
-To access the files via Wrapfs, use the mount point /mnt/wrapfs.
-
-------------------------------------------------------------------------------
-CAVEATS:
-
-Stacking on NFS. Wrapfs has been tested with LTP, racer, fsx, parallel
-compile, and more. It's been tested on top of ext2, ext3, xfs, reiserfs,
-and tmpfs -- and passed all tests. However, on top of nfs3, wrapfs has to
-treat silly-deleted files as if they don't exist: in ->unlink, if we try to
-vfs_unlink an NFS silly-deleted file, NFS returns EBUSY; so we simply ignore
-it and return 0 (success) to the VFS. NFS will delete this file later on
-anyway. As the VFS also has special handling for silly-deleted files, this
-isn't unusual. A cleaner way to handle this in the future is if the VFS
-were to handle silly-deleted (aka "delayed-delete") files entirely at the
-VFS.
-
-------------------------------------------------------------------------------
-HISTORY:
-
-Wrapfs was developed initially in 1994 for Linux 2.1, as part of Erez
-Zadok's graduate work at Columbia University. It was designed to be a
-flexible null-layer, pass-through, stackable file system, from which other
-file systems would be developed and even instantiated automatically using a
-high-level language. One of the first file systems developed from Wrapfs
-was a simple encryption file system called Cryptfs (eCryptfs is based on
-Cryptfs). Other examples include Gzipfs, a stackable compression file
-system, and Unionfs, a stackable unification file system. Wrapfs was
-integrated into a larger package called fistgen (see www.filesystems.org),
-and ported to FreeBSD and Solaris. Wrapfs and fistgen continued to be
-maintained for newer versions of kernels, but remained largely standalone
-until recently: this release of Wrapfs for Linux represents a clean version
-written from scratch.
-
-Over the past 15+ years, versions of Wrapfs had been used by many users and
-companies. At one point or another, the following groups have used stacking
-code based on Wrapfs.
-
-1. PROJECTS: eCryptfs, Unionfs, mini_fo, Aufs, FindFS, StoreCompress,
- TestFS, ToPAS, and MFS.
-
-2. COMPANIES AND RESEARCH LABS: Bell Labs's Plan 9 group, EMC,
- Hewlett-Packard, IBM Research Almaden, IBM Research Austin, Red Hat,
- SuSE, Sun Microsystems, Veritas, Booyaka, CalSoft (India), Computer Farm,
- Deutsche Bank (Germany), DreamWorks LLC, Eli Lilly and Company, FAME
- Information Services, GMX AG (Germany), IBM global services (India), IDA
- Center for Communications Research, Indra Networks, Inc., Kavi
- Corporation, Mendepie, Mitsubishi Electric (Japan), Mobile-Mind, Monster
- Labs, Morning Network (Russia), NeST Technologies, Packet General
- Networks, Inc., Outstep Technologies, Reflective Systems Group, River
- Styx Internet, SARAI Net, Saint-Petersburg Official Web Site (Russia),
- Shadow Island Games, TISCover (Germany), Trymedia Systems, Uber Admin,
- Videsh Sanchar Nigam Limited (India), Wanadoo (France), and iNsu
- Innovations.
-
-3. UNIVERSITIES: Georgia Institute of Technology, Stanford University, UC
- Berkeley, UCLA, University of Maryland, College Park, University of
- Michigan, Ben Gurion University (Israel), Clarkson University, Clemson
- University, Deutsches Elektronen Synchrotron (Germany), Electronics and
- Telecommunications Research Institute (South Korea), Indian Institute of
- Technology (India), National Taiwan University, Pune University (India),
- The College of William \& Mary, Trinity College (Ireland), Universitaet
- Frankfurt am Main (Germany), University Hospital Olomouc (Czech
- Republic), and University of Salermo (Italy).
-
-------------------------------------------------------------------------------
diff --git a/MAINTAINERS b/MAINTAINERS
index e5a5621..d0cdb2f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6349,13 +6349,6 @@ F: include/linux/mfd/wm8400*
F: sound/soc/codecs/wm8350.*
F: sound/soc/codecs/wm8400.*
-WRAPFS
-M: Erez Zadok <[email protected]>
-L: [email protected]
-W: http://wrapfs.filesystems.org/
-T: git git.kernel.org/pub/scm/linux/kernel/git/ezk/wrapfs.git
-S: Maintained
-
X.25 NETWORK LAYER
M: Andrew Hendry <[email protected]>
L: [email protected]
diff --git a/fs/Kconfig b/fs/Kconfig
index 4aefd66..5f85b59 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -169,7 +169,6 @@ if MISC_FILESYSTEMS
source "fs/adfs/Kconfig"
source "fs/affs/Kconfig"
source "fs/ecryptfs/Kconfig"
-source "fs/wrapfs/Kconfig"
source "fs/hfs/Kconfig"
source "fs/hfsplus/Kconfig"
source "fs/befs/Kconfig"
diff --git a/fs/Makefile b/fs/Makefile
index 08a6645..e6ec1d3 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -84,7 +84,6 @@ obj-$(CONFIG_ISO9660_FS) += isofs/
obj-$(CONFIG_HFSPLUS_FS) += hfsplus/ # Before hfs to find wrapped HFS+
obj-$(CONFIG_HFS_FS) += hfs/
obj-$(CONFIG_ECRYPT_FS) += ecryptfs/
-obj-$(CONFIG_WRAP_FS) += wrapfs/
obj-$(CONFIG_VXFS_FS) += freevxfs/
obj-$(CONFIG_NFS_FS) += nfs/
obj-$(CONFIG_EXPORTFS) += exportfs/
diff --git a/fs/wrapfs/Kconfig b/fs/wrapfs/Kconfig
deleted file mode 100644
index d790ccd..0000000
--- a/fs/wrapfs/Kconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-config WRAP_FS
- tristate "Wrapfs stackable file system (EXPERIMENTAL)"
- depends on EXPERIMENTAL
- help
- Wrapfs is a stackable file system which simply passes its
- operations to the lower layer. It is designed as a useful
- template for developing or debugging other stackable file systems,
- and more (see Documentation/filesystems/wrapfs.txt). See
- <http://wrapfs.filesystems.org/> for details.
diff --git a/fs/wrapfs/Makefile b/fs/wrapfs/Makefile
deleted file mode 100644
index f318d11..0000000
--- a/fs/wrapfs/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-WRAPFS_VERSION="0.1"
-
-EXTRA_CFLAGS += -DWRAPFS_VERSION=\"$(WRAPFS_VERSION)\"
-
-obj-$(CONFIG_WRAP_FS) += wrapfs.o
-
-wrapfs-y := dentry.o file.o inode.o main.o super.o lookup.o mmap.o
diff --git a/fs/wrapfs/dentry.c b/fs/wrapfs/dentry.c
deleted file mode 100644
index 3ecab8e..0000000
--- a/fs/wrapfs/dentry.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 1998-2017 Erez Zadok
- * Copyright (c) 2009 Shrikar Archak
- * Copyright (c) 2003-2017 Stony Brook University
- * Copyright (c) 2003-2017 The Research Foundation of SUNY
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include "wrapfs.h"
-
-/*
- * returns: -ERRNO if error (returned to user)
- * 0: tell VFS to invalidate dentry
- * 1: dentry is valid
- */
-static int wrapfs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
-{
- struct path lower_path, saved_path;
- struct dentry *lower_dentry;
- int err = 1;
-
- wrapfs_get_lower_path(dentry, &lower_path);
- lower_dentry = lower_path.dentry;
- if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate)
- goto out;
- pathcpy(&saved_path, &nd->path);
- pathcpy(&nd->path, &lower_path);
- err = lower_dentry->d_op->d_revalidate(lower_dentry, nd);
- pathcpy(&nd->path, &saved_path);
-out:
- wrapfs_put_lower_path(dentry, &lower_path);
- return err;
-}
-
-static void wrapfs_d_release(struct dentry *dentry)
-{
- /* release and reset the lower paths */
- wrapfs_put_reset_lower_path(dentry);
- free_dentry_private_data(dentry);
- return;
-}
-
-const struct dentry_operations wrapfs_dops = {
- .d_revalidate = wrapfs_d_revalidate,
- .d_release = wrapfs_d_release,
-};
diff --git a/fs/wrapfs/file.c b/fs/wrapfs/file.c
deleted file mode 100644
index cfaf536..0000000
--- a/fs/wrapfs/file.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright (c) 1998-2017 Erez Zadok
- * Copyright (c) 2009 Shrikar Archak
- * Copyright (c) 2003-2017 Stony Brook University
- * Copyright (c) 2003-2017 The Research Foundation of SUNY
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include "wrapfs.h"
-
-static ssize_t wrapfs_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
- int err;
- struct file *lower_file;
- struct dentry *dentry = file->f_path.dentry;
-
- lower_file = wrapfs_lower_file(file);
- err = vfs_read(lower_file, buf, count, ppos);
- /* update our inode atime upon a successful lower read */
- if (err >= 0)
- fsstack_copy_attr_atime(dentry->d_inode,
- lower_file->f_path.dentry->d_inode);
-
- return err;
-}
-
-static ssize_t wrapfs_write(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- int err = 0;
- struct file *lower_file;
- struct dentry *dentry = file->f_path.dentry;
-
- lower_file = wrapfs_lower_file(file);
- err = vfs_write(lower_file, buf, count, ppos);
- /* update our inode times+sizes upon a successful lower write */
- if (err >= 0) {
- fsstack_copy_inode_size(dentry->d_inode,
- lower_file->f_path.dentry->d_inode);
- fsstack_copy_attr_times(dentry->d_inode,
- lower_file->f_path.dentry->d_inode);
- }
-
- return err;
-}
-
-static int wrapfs_readdir(struct file *file, void *dirent, filldir_t filldir)
-{
- int err = 0;
- struct file *lower_file = NULL;
- struct dentry *dentry = file->f_path.dentry;
-
- lower_file = wrapfs_lower_file(file);
- err = vfs_readdir(lower_file, filldir, dirent);
- file->f_pos = lower_file->f_pos;
- if (err >= 0) /* copy the atime */
- fsstack_copy_attr_atime(dentry->d_inode,
- lower_file->f_path.dentry->d_inode);
- return err;
-}
-
-static long wrapfs_ioctl(struct file *file, unsigned int cmd, unsigned long
arg)
-{
- long err = -ENOTTY;
- struct file *lower_file;
-
- lower_file = wrapfs_lower_file(file);
-
- /* XXX: use vfs_ioctl if/when VFS exports it */
- if (!lower_file || !lower_file->f_op)
- goto out;
- if (lower_file->f_op->unlocked_ioctl) {
- err = lower_file->f_op->unlocked_ioctl(lower_file, cmd, arg);
- } else if (lower_file->f_op->ioctl) {
- lock_kernel();
- err = lower_file->f_op->ioctl(
- lower_file->f_path.dentry->d_inode,
- lower_file, cmd, arg);
- unlock_kernel();
- }
-
- /* some ioctls can change inode attributes (EXT2_IOC_SETFLAGS) */
- if (!err)
- fsstack_copy_attr_all(file->f_path.dentry->d_inode,
- lower_file->f_path.dentry->d_inode);
-out:
- return err;
-}
-
-static int wrapfs_mmap(struct file *file, struct vm_area_struct *vma)
-{
- int err = 0;
- bool willwrite;
- struct file *lower_file;
- const struct vm_operations_struct *saved_vm_ops = NULL;
-
- /* this might be deferred to mmap's writepage */
- willwrite = ((vma->vm_flags | VM_SHARED | VM_WRITE) == vma->vm_flags);
-
- /*
- * File systems which do not implement ->writepage may use
- * generic_file_readonly_mmap as their ->mmap op. If you call
- * generic_file_readonly_mmap with VM_WRITE, you'd get an -EINVAL.
- * But we cannot call the lower ->mmap op, so we can't tell that
- * writeable mappings won't work. Therefore, our only choice is to
- * check if the lower file system supports the ->writepage, and if
- * not, return EINVAL (the same error that
- * generic_file_readonly_mmap returns in that case).
- */
- lower_file = wrapfs_lower_file(file);
- if (willwrite && !lower_file->f_mapping->a_ops->writepage) {
- err = -EINVAL;
- printk(KERN_ERR "wrapfs: lower file system does not "
- "support writeable mmap\n");
- goto out;
- }
-
- /*
- * find and save lower vm_ops.
- *
- * XXX: the VFS should have a cleaner way of finding the lower vm_ops
- */
- if (!WRAPFS_F(file)->lower_vm_ops) {
- err = lower_file->f_op->mmap(lower_file, vma);
- if (err) {
- printk(KERN_ERR "wrapfs: lower mmap failed %d\n", err);
- goto out;
- }
- saved_vm_ops = vma->vm_ops; /* save: came from lower ->mmap */
- }
-
- /*
- * Next 3 lines are all I need from generic_file_mmap. I definitely
- * don't want its test for ->readpage which returns -ENOEXEC.
- */
- file_accessed(file);
- vma->vm_ops = &wrapfs_vm_ops;
- vma->vm_flags |= VM_CAN_NONLINEAR;
-
- file->f_mapping->a_ops = &wrapfs_aops; /* set our aops */
- if (!WRAPFS_F(file)->lower_vm_ops) /* save for our ->fault */
- WRAPFS_F(file)->lower_vm_ops = saved_vm_ops;
-
-out:
- return err;
-}
-
-static int wrapfs_open(struct inode *inode, struct file *file)
-{
- int err = 0;
- struct file *lower_file = NULL;
- struct path lower_path;
-
- /* don't open unhashed/deleted files */
- if (d_unhashed(file->f_path.dentry)) {
- err = -ENOENT;
- goto out_err;
- }
-
- file->private_data =
- kzalloc(sizeof(struct wrapfs_file_info), GFP_KERNEL);
- if (!WRAPFS_F(file)) {
- err = -ENOMEM;
- goto out_err;
- }
-
- /* open lower object and link wrapfs's file struct to lower's */
- wrapfs_get_lower_path(file->f_path.dentry, &lower_path);
- lower_file = dentry_open(lower_path.dentry, lower_path.mnt,
- file->f_flags, current_cred());
- if (IS_ERR(lower_file)) {
- err = PTR_ERR(lower_file);
- lower_file = wrapfs_lower_file(file);
- if (lower_file) {
- wrapfs_set_lower_file(file, NULL);
- fput(lower_file); /* fput calls dput for lower_dentry */
- }
- } else {
- wrapfs_set_lower_file(file, lower_file);
- }
-
- if (err)
- kfree(WRAPFS_F(file));
- else
- fsstack_copy_attr_all(inode, wrapfs_lower_inode(inode));
-out_err:
- return err;
-}
-
-static int wrapfs_flush(struct file *file, fl_owner_t id)
-{
- int err = 0;
- struct file *lower_file = NULL;
-
- lower_file = wrapfs_lower_file(file);
- if (lower_file && lower_file->f_op && lower_file->f_op->flush)
- err = lower_file->f_op->flush(lower_file, id);
-
- return err;
-}
-
-/* release all lower object references & free the file info structure */
-static int wrapfs_file_release(struct inode *inode, struct file *file)
-{
- struct file *lower_file;
-
- lower_file = wrapfs_lower_file(file);
- if (lower_file) {
- wrapfs_set_lower_file(file, NULL);
- fput(lower_file);
- }
-
- kfree(WRAPFS_F(file));
- return 0;
-}
-
-static int wrapfs_fsync(struct file *file, int datasync)
-{
- int err;
- struct file *lower_file;
- struct path lower_path;
- struct dentry *dentry = file->f_path.dentry;
-
- lower_file = wrapfs_lower_file(file);
- wrapfs_get_lower_path(dentry, &lower_path);
- err = vfs_fsync(lower_file, datasync);
- wrapfs_put_lower_path(dentry, &lower_path);
-
- return err;
-}
-
-static int wrapfs_fasync(int fd, struct file *file, int flag)
-{
- int err = 0;
- struct file *lower_file = NULL;
-
- lock_kernel();
- lower_file = wrapfs_lower_file(file);
- if (lower_file->f_op && lower_file->f_op->fasync)
- err = lower_file->f_op->fasync(fd, lower_file, flag);
- unlock_kernel();
-
- return err;
-}
-
-static ssize_t wrapfs_aio_read(struct kiocb *iocb, const struct iovec *iov,
- unsigned long nr_segs, loff_t pos)
-{
- int err = -EINVAL;
- struct file *file, *lower_file;
-
- file = iocb->ki_filp;
- lower_file = wrapfs_lower_file(file);
- if (!lower_file->f_op->aio_read)
- goto out;
- /*
- * It appears safe to rewrite this iocb, because in
- * do_io_submit@fs/aio.c, iocb is a just copy from user.
- */
- get_file(lower_file); /* prevent lower_file from being released */
- iocb->ki_filp = lower_file;
- err = lower_file->f_op->aio_read(iocb, iov, nr_segs, pos);
- iocb->ki_filp = file;
- fput(lower_file);
- /* update upper inode atime as needed */
- if (err >= 0 || err == -EIOCBQUEUED)
- fsstack_copy_attr_atime(file->f_path.dentry->d_inode,
- lower_file->f_path.dentry->d_inode);
-out:
- return err;
-}
-
-static ssize_t wrapfs_aio_write(struct kiocb *iocb, const struct iovec *iov,
- unsigned long nr_segs, loff_t pos)
-{
- int err = -EINVAL;
- struct file *file, *lower_file;
-
- file = iocb->ki_filp;
- lower_file = wrapfs_lower_file(file);
- if (!lower_file->f_op->aio_write)
- goto out;
- /*
- * It appears safe to rewrite this iocb, because in
- * do_io_submit@fs/aio.c, iocb is a just copy from user.
- */
- get_file(lower_file); /* prevent lower_file from being released */
- iocb->ki_filp = lower_file;
- err = lower_file->f_op->aio_write(iocb, iov, nr_segs, pos);
- iocb->ki_filp = file;
- fput(lower_file);
- /* update upper inode times/sizes as needed */
- if (err >= 0 || err == -EIOCBQUEUED) {
- fsstack_copy_inode_size(file->f_path.dentry->d_inode,
- lower_file->f_path.dentry->d_inode);
- fsstack_copy_attr_times(file->f_path.dentry->d_inode,
- lower_file->f_path.dentry->d_inode);
- }
-out:
- return err;
-}
-
-/*
- * Wrapfs cannot use generic_file_llseek as ->llseek, because it would
- * only set the offset of the upper file. So we have to implement our
- * own method to set both the upper and lower file offsets
- * consistently.
- */
-static loff_t wrapfs_file_llseek(struct file *file, loff_t offset, int whence)
-{
- int err;
- struct file *lower_file;
-
- err = generic_file_llseek(file, offset, whence);
- if (err < 0)
- goto out;
-
- lower_file = wrapfs_lower_file(file);
- err = generic_file_llseek(lower_file, offset, whence);
-
-out:
- return err;
-}
-
-const struct file_operations wrapfs_main_fops = {
- .llseek = generic_file_llseek,
- .read = wrapfs_read,
- .write = wrapfs_write,
- .unlocked_ioctl = wrapfs_ioctl,
- .mmap = wrapfs_mmap,
- .open = wrapfs_open,
- .flush = wrapfs_flush,
- .release = wrapfs_file_release,
- .fsync = wrapfs_fsync,
- .fasync = wrapfs_fasync,
- .aio_read = wrapfs_aio_read,
- .aio_write = wrapfs_aio_write,
-};
-
-/* trimmed directory options */
-const struct file_operations wrapfs_dir_fops = {
- .llseek = wrapfs_file_llseek,
- .read = generic_read_dir,
- .readdir = wrapfs_readdir,
- .unlocked_ioctl = wrapfs_ioctl,
- .open = wrapfs_open,
- .release = wrapfs_file_release,
- .flush = wrapfs_flush,
- .fsync = wrapfs_fsync,
- .fasync = wrapfs_fasync,
-};
diff --git a/fs/wrapfs/inode.c b/fs/wrapfs/inode.c
deleted file mode 100644
index 6631772..0000000
--- a/fs/wrapfs/inode.c
+++ /dev/null
@@ -1,628 +0,0 @@
-/*
- * Copyright (c) 1998-2017 Erez Zadok
- * Copyright (c) 2009 Shrikar Archak
- * Copyright (c) 2003-2017 Stony Brook University
- * Copyright (c) 2003-2017 The Research Foundation of SUNY
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include "wrapfs.h"
-
-static int wrapfs_create(struct inode *dir, struct dentry *dentry,
- int mode, struct nameidata *nd)
-{
- int err = 0;
- struct dentry *lower_dentry;
- struct dentry *lower_parent_dentry = NULL;
- struct path lower_path, saved_path;
-
- wrapfs_get_lower_path(dentry, &lower_path);
- lower_dentry = lower_path.dentry;
- lower_parent_dentry = lock_parent(lower_dentry);
-
- err = mnt_want_write(lower_path.mnt);
- if (err)
- goto out_unlock;
-
- pathcpy(&saved_path, &nd->path);
- pathcpy(&nd->path, &lower_path);
- err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode, nd);
- pathcpy(&nd->path, &saved_path);
- if (err)
- goto out;
-
- err = wrapfs_interpose(dentry, dir->i_sb, &lower_path);
- if (err)
- goto out;
- fsstack_copy_attr_times(dir, wrapfs_lower_inode(dir));
- fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode);
-
-out:
- mnt_drop_write(lower_path.mnt);
-out_unlock:
- unlock_dir(lower_parent_dentry);
- wrapfs_put_lower_path(dentry, &lower_path);
- return err;
-}
-
-static int wrapfs_link(struct dentry *old_dentry, struct inode *dir,
- struct dentry *new_dentry)
-{
- struct dentry *lower_old_dentry;
- struct dentry *lower_new_dentry;
- struct dentry *lower_dir_dentry;
- u64 file_size_save;
- int err;
- struct path lower_old_path, lower_new_path;
-
- file_size_save = i_size_read(old_dentry->d_inode);
- wrapfs_get_lower_path(old_dentry, &lower_old_path);
- wrapfs_get_lower_path(new_dentry, &lower_new_path);
- lower_old_dentry = lower_old_path.dentry;
- lower_new_dentry = lower_new_path.dentry;
- lower_dir_dentry = lock_parent(lower_new_dentry);
-
- err = mnt_want_write(lower_new_path.mnt);
- if (err)
- goto out_unlock;
-
- err = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode,
- lower_new_dentry);
- if (err || !lower_new_dentry->d_inode)
- goto out;
-
- err = wrapfs_interpose(new_dentry, dir->i_sb, &lower_new_path);
- if (err)
- goto out;
- fsstack_copy_attr_times(dir, lower_new_dentry->d_inode);
- fsstack_copy_inode_size(dir, lower_new_dentry->d_inode);
- old_dentry->d_inode->i_nlink =
- wrapfs_lower_inode(old_dentry->d_inode)->i_nlink;
- i_size_write(new_dentry->d_inode, file_size_save);
-out:
- mnt_drop_write(lower_new_path.mnt);
-out_unlock:
- unlock_dir(lower_dir_dentry);
- wrapfs_put_lower_path(old_dentry, &lower_old_path);
- wrapfs_put_lower_path(new_dentry, &lower_new_path);
- return err;
-}
-
-static int wrapfs_unlink(struct inode *dir, struct dentry *dentry)
-{
- int err;
- struct dentry *lower_dentry;
- struct inode *lower_dir_inode = wrapfs_lower_inode(dir);
- struct dentry *lower_dir_dentry;
- struct path lower_path;
-
- wrapfs_get_lower_path(dentry, &lower_path);
- lower_dentry = lower_path.dentry;
- dget(lower_dentry);
- lower_dir_dentry = lock_parent(lower_dentry);
-
- err = mnt_want_write(lower_path.mnt);
- if (err)
- goto out_unlock;
- err = vfs_unlink(lower_dir_inode, lower_dentry);
-
- /*
- * Note: unlinking on top of NFS can cause silly-renamed files.
- * Trying to delete such files results in EBUSY from NFS
- * below. Silly-renamed files will get deleted by NFS later on, so
- * we just need to detect them here and treat such EBUSY errors as
- * if the upper file was successfully deleted.
- */
- if (err == -EBUSY && lower_dentry->d_flags & DCACHE_NFSFS_RENAMED)
- err = 0;
- if (err)
- goto out;
- fsstack_copy_attr_times(dir, lower_dir_inode);
- fsstack_copy_inode_size(dir, lower_dir_inode);
- dentry->d_inode->i_nlink =
- wrapfs_lower_inode(dentry->d_inode)->i_nlink;
- dentry->d_inode->i_ctime = dir->i_ctime;
- d_drop(dentry); /* this is needed, else LTP fails (VFS won't do it) */
-out:
- mnt_drop_write(lower_path.mnt);
-out_unlock:
- unlock_dir(lower_dir_dentry);
- dput(lower_dentry);
- wrapfs_put_lower_path(dentry, &lower_path);
- return err;
-}
-
-static int wrapfs_symlink(struct inode *dir, struct dentry *dentry,
- const char *symname)
-{
- int err = 0;
- struct dentry *lower_dentry;
- struct dentry *lower_parent_dentry = NULL;
- struct path lower_path;
-
- wrapfs_get_lower_path(dentry, &lower_path);
- lower_dentry = lower_path.dentry;
- lower_parent_dentry = lock_parent(lower_dentry);
-
- err = mnt_want_write(lower_path.mnt);
- if (err)
- goto out_unlock;
- err = vfs_symlink(lower_parent_dentry->d_inode, lower_dentry, symname);
- if (err)
- goto out;
- err = wrapfs_interpose(dentry, dir->i_sb, &lower_path);
- if (err)
- goto out;
- fsstack_copy_attr_times(dir, wrapfs_lower_inode(dir));
- fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode);
-
-out:
- mnt_drop_write(lower_path.mnt);
-out_unlock:
- unlock_dir(lower_parent_dentry);
- wrapfs_put_lower_path(dentry, &lower_path);
- return err;
-}
-
-static int wrapfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
-{
- int err = 0;
- struct dentry *lower_dentry;
- struct dentry *lower_parent_dentry = NULL;
- struct path lower_path;
-
- wrapfs_get_lower_path(dentry, &lower_path);
- lower_dentry = lower_path.dentry;
- lower_parent_dentry = lock_parent(lower_dentry);
-
- err = mnt_want_write(lower_path.mnt);
- if (err)
- goto out_unlock;
- err = vfs_mkdir(lower_parent_dentry->d_inode, lower_dentry, mode);
- if (err)
- goto out;
-
- err = wrapfs_interpose(dentry, dir->i_sb, &lower_path);
- if (err)
- goto out;
-
- fsstack_copy_attr_times(dir, wrapfs_lower_inode(dir));
- fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode);
- /* update number of links on parent directory */
- dir->i_nlink = wrapfs_lower_inode(dir)->i_nlink;
-
-out:
- mnt_drop_write(lower_path.mnt);
-out_unlock:
- unlock_dir(lower_parent_dentry);
- wrapfs_put_lower_path(dentry, &lower_path);
- return err;
-}
-
-static int wrapfs_rmdir(struct inode *dir, struct dentry *dentry)
-{
- struct dentry *lower_dentry;
- struct dentry *lower_dir_dentry;
- int err;
- struct path lower_path;
-
- wrapfs_get_lower_path(dentry, &lower_path);
- lower_dentry = lower_path.dentry;
- lower_dir_dentry = lock_parent(lower_dentry);
-
- err = mnt_want_write(lower_path.mnt);
- if (err)
- goto out_unlock;
- err = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry);
- if (err)
- goto out;
-
- d_drop(dentry); /* drop our dentry on success (why not VFS's job?) */
- if (dentry->d_inode)
- clear_nlink(dentry->d_inode);
- fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
- fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode);
- dir->i_nlink = lower_dir_dentry->d_inode->i_nlink;
-
-out:
- mnt_drop_write(lower_path.mnt);
-out_unlock:
- unlock_dir(lower_dir_dentry);
- wrapfs_put_lower_path(dentry, &lower_path);
- return err;
-}
-
-static int wrapfs_mknod(struct inode *dir, struct dentry *dentry, int mode,
- dev_t dev)
-{
- int err = 0;
- struct dentry *lower_dentry;
- struct dentry *lower_parent_dentry = NULL;
- struct path lower_path;
-
- wrapfs_get_lower_path(dentry, &lower_path);
- lower_dentry = lower_path.dentry;
- lower_parent_dentry = lock_parent(lower_dentry);
-
- err = mnt_want_write(lower_path.mnt);
- if (err)
- goto out_unlock;
- err = vfs_mknod(lower_parent_dentry->d_inode, lower_dentry, mode, dev);
- if (err)
- goto out;
-
- err = wrapfs_interpose(dentry, dir->i_sb, &lower_path);
- if (err)
- goto out;
- fsstack_copy_attr_times(dir, wrapfs_lower_inode(dir));
- fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode);
-
-out:
- mnt_drop_write(lower_path.mnt);
-out_unlock:
- unlock_dir(lower_parent_dentry);
- wrapfs_put_lower_path(dentry, &lower_path);
- return err;
-}
-
-/*
- * The locking rules in wrapfs_rename are complex. We could use a simpler
- * superblock-level name-space lock for renames and copy-ups.
- */
-static int wrapfs_rename(struct inode *old_dir, struct dentry *old_dentry,
- struct inode *new_dir, struct dentry *new_dentry)
-{
- int err = 0;
- struct dentry *lower_old_dentry = NULL;
- struct dentry *lower_new_dentry = NULL;
- struct dentry *lower_old_dir_dentry = NULL;
- struct dentry *lower_new_dir_dentry = NULL;
- struct dentry *trap = NULL;
- struct path lower_old_path, lower_new_path;
-
- wrapfs_get_lower_path(old_dentry, &lower_old_path);
- wrapfs_get_lower_path(new_dentry, &lower_new_path);
- lower_old_dentry = lower_old_path.dentry;
- lower_new_dentry = lower_new_path.dentry;
- lower_old_dir_dentry = dget_parent(lower_old_dentry);
- lower_new_dir_dentry = dget_parent(lower_new_dentry);
-
- trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
- /* source should not be ancestor of target */
- if (trap == lower_old_dentry) {
- err = -EINVAL;
- goto out;
- }
- /* target should not be ancestor of source */
- if (trap == lower_new_dentry) {
- err = -ENOTEMPTY;
- goto out;
- }
-
- err = mnt_want_write(lower_old_path.mnt);
- if (err)
- goto out;
- err = mnt_want_write(lower_new_path.mnt);
- if (err)
- goto out_drop_old_write;
-
- err = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry,
- lower_new_dir_dentry->d_inode, lower_new_dentry);
- if (err)
- goto out_err;
-
- fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode);
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs