revoked_file_ops is a set of file operations designed to be used when a files backing store has been removed. revoked_file_ops return 0 from reads (aka EOF). Tell poll the file is always ready for I/O and return -EIO from all other operations. This is designed to allow userspace to gracefully file descriptors that enter this unusable state. Signed-off-by: Eric W. Biederman <ebiederm@xxxxxxxxxxxx> --- fs/Makefile | 2 +- fs/revoked_file.c | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/fs.h | 2 + 3 files changed, 184 insertions(+), 1 deletions(-) create mode 100644 fs/revoked_file.c diff --git a/fs/Makefile b/fs/Makefile index af6d047..7787ddd 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -11,7 +11,7 @@ obj-y := open.o read_write.o file_table.o super.o \ attr.o bad_inode.o file.o filesystems.o namespace.o \ seq_file.o xattr.o libfs.o fs-writeback.o \ pnode.o drop_caches.o splice.o sync.o utimes.o \ - stack.o fs_struct.o + stack.o fs_struct.o revoked_file.o ifeq ($(CONFIG_BLOCK),y) obj-y += buffer.o bio.o block_dev.o direct-io.o mpage.o ioprio.o diff --git a/fs/revoked_file.c b/fs/revoked_file.c new file mode 100644 index 0000000..9936693 --- /dev/null +++ b/fs/revoked_file.c @@ -0,0 +1,181 @@ +/* + * linux/fs/revoked_file.c + * + * Copyright (C) 1997, Stephen Tweedie + * + * Provide stub functions for unreadable inodes + * + * Fabian Frederick : August 2003 - All file operations assigned to EIO + * + * Eric Biederman : 8 April 2008 - Derivied from bad_inode.c + */ + +#include <linux/fs.h> +#include <linux/module.h> +#include <linux/stat.h> +#include <linux/time.h> +#include <linux/namei.h> +#include <linux/poll.h> + +static loff_t revoked_file_llseek(struct file *file, loff_t offset, int origin) +{ + return -EIO; +} + +static ssize_t revoked_file_read(struct file *filp, char __user *buf, + size_t size, loff_t *ppos) +{ + return 0; +} + +static ssize_t revoked_file_write(struct file *filp, const char __user *buf, + size_t siz, loff_t *ppos) +{ + return -EIO; +} + +static ssize_t revoked_file_aio_read(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) +{ + return 0; +} + +static ssize_t revoked_file_aio_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) +{ + return -EIO; +} + +static int revoked_file_readdir(struct file *filp, void *dirent, filldir_t filldir) +{ + return -EIO; +} + +static unsigned int revoked_file_poll(struct file *filp, poll_table *wait) +{ + return POLLIN | POLLOUT | POLLERR | POLLRDNORM | POLLWRNORM; +} + +static int revoked_file_ioctl (struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + return -EIO; +} + +static long revoked_file_unlocked_ioctl(struct file *file, unsigned cmd, + unsigned long arg) +{ + return -EIO; +} + +static long revoked_file_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + return -EIO; +} + +static int revoked_file_mmap(struct file *file, struct vm_area_struct *vma) +{ + return -EIO; +} + +static int revoked_file_open(struct inode *inode, struct file *filp) +{ + return -EIO; +} + +static int revoked_file_flush(struct file *file, fl_owner_t id) +{ + return 0; +} + +static int revoked_file_release(struct inode *inode, struct file *filp) +{ + return 0; +} + +static int revoked_file_fsync(struct file *file, struct dentry *dentry, + int datasync) +{ + return -EIO; +} + +static int revoked_file_aio_fsync(struct kiocb *iocb, int datasync) +{ + return -EIO; +} + +static int revoked_file_fasync(int fd, struct file *filp, int on) +{ + return -EIO; +} + +static int revoked_file_lock(struct file *file, int cmd, struct file_lock *fl) +{ + return -EIO; +} + +static ssize_t revoked_file_sendpage(struct file *file, struct page *page, + int off, size_t len, loff_t *pos, int more) +{ + return -EIO; +} + +static unsigned long revoked_file_get_unmapped_area(struct file *file, + unsigned long addr, unsigned long len, + unsigned long pgoff, unsigned long flags) +{ + return -EIO; +} + +static int revoked_file_check_flags(int flags) +{ + return -EIO; +} + +static int revoked_file_flock(struct file *filp, int cmd, struct file_lock *fl) +{ + return -EIO; +} + +static ssize_t revoked_file_splice_write(struct pipe_inode_info *pipe, + struct file *out, loff_t *ppos, size_t len, + unsigned int flags) +{ + return -EIO; +} + +static ssize_t revoked_file_splice_read(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags) +{ + return -EIO; +} + +const struct file_operations revoked_file_ops = +{ + .llseek = revoked_file_llseek, + .read = revoked_file_read, + .write = revoked_file_write, + .aio_read = revoked_file_aio_read, + .aio_write = revoked_file_aio_write, + .readdir = revoked_file_readdir, + .poll = revoked_file_poll, + .ioctl = revoked_file_ioctl, + .unlocked_ioctl = revoked_file_unlocked_ioctl, + .compat_ioctl = revoked_file_compat_ioctl, + .mmap = revoked_file_mmap, + .open = revoked_file_open, + .flush = revoked_file_flush, + .release = revoked_file_release, + .fsync = revoked_file_fsync, + .aio_fsync = revoked_file_aio_fsync, + .fasync = revoked_file_fasync, + .lock = revoked_file_lock, + .sendpage = revoked_file_sendpage, + .get_unmapped_area = revoked_file_get_unmapped_area, + .check_flags = revoked_file_check_flags, + .flock = revoked_file_flock, + .splice_write = revoked_file_splice_write, + .splice_read = revoked_file_splice_read, +}; diff --git a/include/linux/fs.h b/include/linux/fs.h index a82a2ea..2fb0871 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -896,6 +896,8 @@ extern int fops_substitute(struct file *file, const struct file_operations *f_op extern void inode_fops_substitute(struct inode *inode, const struct file_operations *f_op, struct vm_operations_struct *vm_ops); +extern const struct file_operations revoked_file_ops; + extern struct mutex files_lock; #define file_list_lock() mutex_lock(&files_lock); #define file_list_unlock() mutex_unlock(&files_lock); -- 1.6.1.2.350.g88cc -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html