summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-07-17 08:58:04 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2019-07-17 08:58:04 -0700
commit57a8ec387e1441ea5e1232bc0749fb99a8cba7e7 (patch)
treeb5fb03fc6bc5754de8b5b1f8b0e4f36d67c8315c /fs
parent0a8ad0ffa4d80a544f6cbff703bf6394339afcdf (diff)
parent43e11fa2d1d3b6e35629fa556eb7d571edba2010 (diff)
Merge branch 'akpm' (patches from Andrew)
Merge more updates from Andrew Morton: "VM: - z3fold fixes and enhancements by Henry Burns and Vitaly Wool - more accurate reclaimed slab caches calculations by Yafang Shao - fix MAP_UNINITIALIZED UAPI symbol to not depend on config, by Christoph Hellwig - !CONFIG_MMU fixes by Christoph Hellwig - new novmcoredd parameter to omit device dumps from vmcore, by Kairui Song - new test_meminit module for testing heap and pagealloc initialization, by Alexander Potapenko - ioremap improvements for huge mappings, by Anshuman Khandual - generalize kprobe page fault handling, by Anshuman Khandual - device-dax hotplug fixes and improvements, by Pavel Tatashin - enable synchronous DAX fault on powerpc, by Aneesh Kumar K.V - add pte_devmap() support for arm64, by Robin Murphy - unify locked_vm accounting with a helper, by Daniel Jordan - several misc fixes core/lib: - new typeof_member() macro including some users, by Alexey Dobriyan - make BIT() and GENMASK() available in asm, by Masahiro Yamada - changed LIST_POISON2 on x86_64 to 0xdead000000000122 for better code generation, by Alexey Dobriyan - rbtree code size optimizations, by Michel Lespinasse - convert struct pid count to refcount_t, by Joel Fernandes get_maintainer.pl: - add --no-moderated switch to skip moderated ML's, by Joe Perches misc: - ptrace PTRACE_GET_SYSCALL_INFO interface - coda updates - gdb scripts, various" [ Using merge message suggestion from Vlastimil Babka, with some editing - Linus ] * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (100 commits) fs/select.c: use struct_size() in kmalloc() mm: add account_locked_vm utility function arm64: mm: implement pte_devmap support mm: introduce ARCH_HAS_PTE_DEVMAP mm: clean up is_device_*_page() definitions mm/mmap: move common defines to mman-common.h mm: move MAP_SYNC to asm-generic/mman-common.h device-dax: "Hotremove" persistent memory that is used like normal RAM mm/hotplug: make remove_memory() interface usable device-dax: fix memory and resource leak if hotplug fails include/linux/lz4.h: fix spelling and copy-paste errors in documentation ipc/mqueue.c: only perform resource calculation if user valid include/asm-generic/bug.h: fix "cut here" for WARN_ON for __WARN_TAINT architectures scripts/gdb: add helpers to find and list devices scripts/gdb: add lx-genpd-summary command drivers/pps/pps.c: clear offset flags in PPS_SETPARAMS ioctl kernel/pid.c: convert struct pid count to refcount_t drivers/rapidio/devices/rio_mport_cdev.c: NUL terminate some strings select: shift restore_saved_sigmask_unless() into poll_select_copy_remaining() select: change do_poll() to return -ERESTARTNOHAND rather than -EINTR ...
Diffstat (limited to 'fs')
-rw-r--r--fs/aio.c20
-rw-r--r--fs/binfmt_elf.c1
-rw-r--r--fs/binfmt_flat.c2
-rw-r--r--fs/coda/Makefile3
-rw-r--r--fs/coda/cache.c2
-rw-r--r--fs/coda/cnode.c17
-rw-r--r--fs/coda/coda_fs_i.h4
-rw-r--r--fs/coda/coda_int.h10
-rw-r--r--fs/coda/coda_linux.c45
-rw-r--r--fs/coda/coda_linux.h16
-rw-r--r--fs/coda/coda_psdev.h95
-rw-r--r--fs/coda/dir.c12
-rw-r--r--fs/coda/file.c143
-rw-r--r--fs/coda/inode.c3
-rw-r--r--fs/coda/pioctl.c3
-rw-r--r--fs/coda/psdev.c36
-rw-r--r--fs/coda/symlink.c3
-rw-r--r--fs/coda/sysctl.c11
-rw-r--r--fs/coda/upcall.c146
-rw-r--r--fs/eventpoll.c12
-rw-r--r--fs/hfsplus/xattr.c2
-rw-r--r--fs/io_uring.c11
-rw-r--r--fs/proc/Kconfig3
-rw-r--r--fs/proc/inode.c27
-rw-r--r--fs/proc/proc_sysctl.c4
-rw-r--r--fs/proc/vmcore.c9
-rw-r--r--fs/reiserfs/journal.c6
-rw-r--r--fs/select.c96
-rw-r--r--fs/ufs/super.c2
29 files changed, 491 insertions, 253 deletions
diff --git a/fs/aio.c b/fs/aio.c
index 2d405733a8c6..8327db0c8e08 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -2094,7 +2094,6 @@ SYSCALL_DEFINE6(io_pgetevents,
const struct __aio_sigset __user *, usig)
{
struct __aio_sigset ksig = { NULL, };
- sigset_t ksigmask, sigsaved;
struct timespec64 ts;
bool interrupted;
int ret;
@@ -2105,14 +2104,14 @@ SYSCALL_DEFINE6(io_pgetevents,
if (usig && copy_from_user(&ksig, usig, sizeof(ksig)))
return -EFAULT;
- ret = set_user_sigmask(ksig.sigmask, &ksigmask, &sigsaved, ksig.sigsetsize);
+ ret = set_user_sigmask(ksig.sigmask, ksig.sigsetsize);
if (ret)
return ret;
ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL);
interrupted = signal_pending(current);
- restore_user_sigmask(ksig.sigmask, &sigsaved, interrupted);
+ restore_saved_sigmask_unless(interrupted);
if (interrupted && !ret)
ret = -ERESTARTNOHAND;
@@ -2130,7 +2129,6 @@ SYSCALL_DEFINE6(io_pgetevents_time32,
const struct __aio_sigset __user *, usig)
{
struct __aio_sigset ksig = { NULL, };
- sigset_t ksigmask, sigsaved;
struct timespec64 ts;
bool interrupted;
int ret;
@@ -2142,14 +2140,14 @@ SYSCALL_DEFINE6(io_pgetevents_time32,
return -EFAULT;
- ret = set_user_sigmask(ksig.sigmask, &ksigmask, &sigsaved, ksig.sigsetsize);
+ ret = set_user_sigmask(ksig.sigmask, ksig.sigsetsize);
if (ret)
return ret;
ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL);
interrupted = signal_pending(current);
- restore_user_sigmask(ksig.sigmask, &sigsaved, interrupted);
+ restore_saved_sigmask_unless(interrupted);
if (interrupted && !ret)
ret = -ERESTARTNOHAND;
@@ -2198,7 +2196,6 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents,
const struct __compat_aio_sigset __user *, usig)
{
struct __compat_aio_sigset ksig = { NULL, };
- sigset_t ksigmask, sigsaved;
struct timespec64 t;
bool interrupted;
int ret;
@@ -2209,14 +2206,14 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents,
if (usig && copy_from_user(&ksig, usig, sizeof(ksig)))
return -EFAULT;
- ret = set_compat_user_sigmask(ksig.sigmask, &ksigmask, &sigsaved, ksig.sigsetsize);
+ ret = set_compat_user_sigmask(ksig.sigmask, ksig.sigsetsize);
if (ret)
return ret;
ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL);
interrupted = signal_pending(current);
- restore_user_sigmask(ksig.sigmask, &sigsaved, interrupted);
+ restore_saved_sigmask_unless(interrupted);
if (interrupted && !ret)
ret = -ERESTARTNOHAND;
@@ -2234,7 +2231,6 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents_time64,
const struct __compat_aio_sigset __user *, usig)
{
struct __compat_aio_sigset ksig = { NULL, };
- sigset_t ksigmask, sigsaved;
struct timespec64 t;
bool interrupted;
int ret;
@@ -2245,14 +2241,14 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents_time64,
if (usig && copy_from_user(&ksig, usig, sizeof(ksig)))
return -EFAULT;
- ret = set_compat_user_sigmask(ksig.sigmask, &ksigmask, &sigsaved, ksig.sigsetsize);
+ ret = set_compat_user_sigmask(ksig.sigmask, ksig.sigsetsize);
if (ret)
return ret;
ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL);
interrupted = signal_pending(current);
- restore_user_sigmask(ksig.sigmask, &sigsaved, interrupted);
+ restore_saved_sigmask_unless(interrupted);
if (interrupted && !ret)
ret = -ERESTARTNOHAND;
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 8264b468f283..d4e11b2e04f6 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1127,7 +1127,6 @@ out_free_interp:
load_addr, interp_load_addr);
if (retval < 0)
goto out;
- /* N.B. passed_fileno might not be initialized? */
current->mm->end_code = end_code;
current->mm->start_code = start_code;
current->mm->start_data = start_data;
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index 8c6b50f34466..831a2b25ba79 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -431,7 +431,6 @@ static int load_flat_file(struct linux_binprm *bprm,
unsigned long len, memp, memp_size, extra, rlim;
__be32 __user *reloc;
u32 __user *rp;
- struct inode *inode;
int i, rev, relocs;
loff_t fpos;
unsigned long start_code, end_code;
@@ -439,7 +438,6 @@ static int load_flat_file(struct linux_binprm *bprm,
int ret;
hdr = ((struct flat_hdr *) bprm->buf); /* exec-header */
- inode = file_inode(bprm->file);
text_len = ntohl(hdr->data_start);
data_len = ntohl(hdr->data_end) - ntohl(hdr->data_start);
diff --git a/fs/coda/Makefile b/fs/coda/Makefile
index 1ce66819da2a..78befb8369c9 100644
--- a/fs/coda/Makefile
+++ b/fs/coda/Makefile
@@ -6,7 +6,8 @@
obj-$(CONFIG_CODA_FS) += coda.o
coda-objs := psdev.o cache.o cnode.o inode.o dir.o file.o upcall.o \
- coda_linux.o symlink.o pioctl.o sysctl.o
+ coda_linux.o symlink.o pioctl.o
+coda-$(CONFIG_SYSCTL) += sysctl.o
# If you want debugging output, please uncomment the following line.
diff --git a/fs/coda/cache.c b/fs/coda/cache.c
index 201fc08a8b4f..3b8c4513118f 100644
--- a/fs/coda/cache.c
+++ b/fs/coda/cache.c
@@ -21,7 +21,7 @@
#include <linux/spinlock.h>
#include <linux/coda.h>
-#include <linux/coda_psdev.h>
+#include "coda_psdev.h"
#include "coda_linux.h"
#include "coda_cache.h"
diff --git a/fs/coda/cnode.c b/fs/coda/cnode.c
index 845b5a66952a..06855f6c7902 100644
--- a/fs/coda/cnode.c
+++ b/fs/coda/cnode.c
@@ -8,8 +8,8 @@
#include <linux/time.h>
#include <linux/coda.h>
-#include <linux/coda_psdev.h>
#include <linux/pagemap.h>
+#include "coda_psdev.h"
#include "coda_linux.h"
static inline int coda_fideq(struct CodaFid *fid1, struct CodaFid *fid2)
@@ -137,11 +137,6 @@ struct inode *coda_fid_to_inode(struct CodaFid *fid, struct super_block *sb)
struct inode *inode;
unsigned long hash = coda_f2i(fid);
- if ( !sb ) {
- pr_warn("%s: no sb!\n", __func__);
- return NULL;
- }
-
inode = ilookup5(sb, hash, coda_test_inode, fid);
if ( !inode )
return NULL;
@@ -153,6 +148,16 @@ struct inode *coda_fid_to_inode(struct CodaFid *fid, struct super_block *sb)
return inode;
}
+struct coda_file_info *coda_ftoc(struct file *file)
+{
+ struct coda_file_info *cfi = file->private_data;
+
+ BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
+
+ return cfi;
+
+}
+
/* the CONTROL inode is made without asking attributes from Venus */
struct inode *coda_cnode_makectl(struct super_block *sb)
{
diff --git a/fs/coda/coda_fs_i.h b/fs/coda/coda_fs_i.h
index d702ba1a2bf9..1763ff95d865 100644
--- a/fs/coda/coda_fs_i.h
+++ b/fs/coda/coda_fs_i.h
@@ -40,10 +40,9 @@ struct coda_file_info {
int cfi_magic; /* magic number */
struct file *cfi_container; /* container file for this cnode */
unsigned int cfi_mapcount; /* nr of times this file is mapped */
+ bool cfi_access_intent; /* is access intent supported */
};
-#define CODA_FTOC(file) ((struct coda_file_info *)((file)->private_data))
-
/* flags */
#define C_VATTR 0x1 /* Validity of vattr in inode */
#define C_FLUSH 0x2 /* used after a flush */
@@ -54,6 +53,7 @@ struct inode *coda_cnode_make(struct CodaFid *, struct super_block *);
struct inode *coda_iget(struct super_block *sb, struct CodaFid *fid, struct coda_vattr *attr);
struct inode *coda_cnode_makectl(struct super_block *sb);
struct inode *coda_fid_to_inode(struct CodaFid *fid, struct super_block *sb);
+struct coda_file_info *coda_ftoc(struct file *file);
void coda_replace_fid(struct inode *, struct CodaFid *, struct CodaFid *);
#endif
diff --git a/fs/coda/coda_int.h b/fs/coda/coda_int.h
index bb0b3e0ed6c2..f82b59c9dd28 100644
--- a/fs/coda/coda_int.h
+++ b/fs/coda/coda_int.h
@@ -13,9 +13,19 @@ extern int coda_fake_statfs;
void coda_destroy_inodecache(void);
int __init coda_init_inodecache(void);
int coda_fsync(struct file *coda_file, loff_t start, loff_t end, int datasync);
+
+#ifdef CONFIG_SYSCTL
void coda_sysctl_init(void);
void coda_sysctl_clean(void);
+#else
+static inline void coda_sysctl_init(void)
+{
+}
+static inline void coda_sysctl_clean(void)
+{
+}
+#endif
#endif /* _CODA_INT_ */
diff --git a/fs/coda/coda_linux.c b/fs/coda/coda_linux.c
index f3d543dd9a98..2e1a5a192074 100644
--- a/fs/coda/coda_linux.c
+++ b/fs/coda/coda_linux.c
@@ -18,7 +18,7 @@
#include <linux/string.h>
#include <linux/coda.h>
-#include <linux/coda_psdev.h>
+#include "coda_psdev.h"
#include "coda_linux.h"
/* initialize the debugging variables */
@@ -66,6 +66,25 @@ unsigned short coda_flags_to_cflags(unsigned short flags)
return coda_flags;
}
+static struct timespec64 coda_to_timespec64(struct coda_timespec ts)
+{
+ struct timespec64 ts64 = {
+ .tv_sec = ts.tv_sec,
+ .tv_nsec = ts.tv_nsec,
+ };
+
+ return ts64;
+}
+
+static struct coda_timespec timespec64_to_coda(struct timespec64 ts64)
+{
+ struct coda_timespec ts = {
+ .tv_sec = ts64.tv_sec,
+ .tv_nsec = ts64.tv_nsec,
+ };
+
+ return ts;
+}
/* utility functions below */
void coda_vattr_to_iattr(struct inode *inode, struct coda_vattr *attr)
@@ -105,11 +124,11 @@ void coda_vattr_to_iattr(struct inode *inode, struct coda_vattr *attr)
if (attr->va_size != -1)
inode->i_blocks = (attr->va_size + 511) >> 9;
if (attr->va_atime.tv_sec != -1)
- inode->i_atime = timespec_to_timespec64(attr->va_atime);
+ inode->i_atime = coda_to_timespec64(attr->va_atime);
if (attr->va_mtime.tv_sec != -1)
- inode->i_mtime = timespec_to_timespec64(attr->va_mtime);
+ inode->i_mtime = coda_to_timespec64(attr->va_mtime);
if (attr->va_ctime.tv_sec != -1)
- inode->i_ctime = timespec_to_timespec64(attr->va_ctime);
+ inode->i_ctime = coda_to_timespec64(attr->va_ctime);
}
@@ -130,12 +149,12 @@ void coda_iattr_to_vattr(struct iattr *iattr, struct coda_vattr *vattr)
vattr->va_uid = (vuid_t) -1;
vattr->va_gid = (vgid_t) -1;
vattr->va_size = (off_t) -1;
- vattr->va_atime.tv_sec = (time_t) -1;
- vattr->va_atime.tv_nsec = (time_t) -1;
- vattr->va_mtime.tv_sec = (time_t) -1;
- vattr->va_mtime.tv_nsec = (time_t) -1;
- vattr->va_ctime.tv_sec = (time_t) -1;
- vattr->va_ctime.tv_nsec = (time_t) -1;
+ vattr->va_atime.tv_sec = (int64_t) -1;
+ vattr->va_atime.tv_nsec = (long) -1;
+ vattr->va_mtime.tv_sec = (int64_t) -1;
+ vattr->va_mtime.tv_nsec = (long) -1;
+ vattr->va_ctime.tv_sec = (int64_t) -1;
+ vattr->va_ctime.tv_nsec = (long) -1;
vattr->va_type = C_VNON;
vattr->va_fileid = -1;
vattr->va_gen = -1;
@@ -175,13 +194,13 @@ void coda_iattr_to_vattr(struct iattr *iattr, struct coda_vattr *vattr)
vattr->va_size = iattr->ia_size;
}
if ( valid & ATTR_ATIME ) {
- vattr->va_atime = timespec64_to_timespec(iattr->ia_atime);
+ vattr->va_atime = timespec64_to_coda(iattr->ia_atime);
}
if ( valid & ATTR_MTIME ) {
- vattr->va_mtime = timespec64_to_timespec(iattr->ia_mtime);
+ vattr->va_mtime = timespec64_to_coda(iattr->ia_mtime);
}
if ( valid & ATTR_CTIME ) {
- vattr->va_ctime = timespec64_to_timespec(iattr->ia_ctime);
+ vattr->va_ctime = timespec64_to_coda(iattr->ia_ctime);
}
}
diff --git a/fs/coda/coda_linux.h b/fs/coda/coda_linux.h
index 126155cadfa9..d5ebd36fb2cc 100644
--- a/fs/coda/coda_linux.h
+++ b/fs/coda/coda_linux.h
@@ -59,22 +59,6 @@ void coda_vattr_to_iattr(struct inode *, struct coda_vattr *);
void coda_iattr_to_vattr(struct iattr *, struct coda_vattr *);
unsigned short coda_flags_to_cflags(unsigned short);
-/* sysctl.h */
-void coda_sysctl_init(void);
-void coda_sysctl_clean(void);
-
-#define CODA_ALLOC(ptr, cast, size) do { \
- if (size < PAGE_SIZE) \
- ptr = kzalloc((unsigned long) size, GFP_KERNEL); \
- else \
- ptr = (cast)vzalloc((unsigned long) size); \
- if (!ptr) \
- pr_warn("kernel malloc returns 0 at %s:%d\n", __FILE__, __LINE__); \
-} while (0)
-
-
-#define CODA_FREE(ptr, size) kvfree((ptr))
-
/* inode to cnode access functions */
static inline struct coda_inode_info *ITOC(struct inode *inode)
diff --git a/fs/coda/coda_psdev.h b/fs/coda/coda_psdev.h
new file mode 100644
index 000000000000..52da08c770b0
--- /dev/null
+++ b/fs/coda/coda_psdev.h
@@ -0,0 +1,95 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __CODA_PSDEV_H
+#define __CODA_PSDEV_H
+
+#include <linux/backing-dev.h>
+#include <linux/magic.h>
+#include <linux/mutex.h>
+
+#define CODA_PSDEV_MAJOR 67
+#define MAX_CODADEVS 5 /* how many do we allow */
+
+struct kstatfs;
+
+/* messages between coda filesystem in kernel and Venus */
+struct upc_req {
+ struct list_head uc_chain;
+ caddr_t uc_data;
+ u_short uc_flags;
+ u_short uc_inSize; /* Size is at most 5000 bytes */
+ u_short uc_outSize;
+ u_short uc_opcode; /* copied from data to save lookup */
+ int uc_unique;
+ wait_queue_head_t uc_sleep; /* process' wait queue */
+};
+
+#define CODA_REQ_ASYNC 0x1
+#define CODA_REQ_READ 0x2
+#define CODA_REQ_WRITE 0x4
+#define CODA_REQ_ABORT 0x8
+
+/* communication pending/processing queues */
+struct venus_comm {
+ u_long vc_seq;
+ wait_queue_head_t vc_waitq; /* Venus wait queue */
+ struct list_head vc_pending;
+ struct list_head vc_processing;
+ int vc_inuse;
+ struct super_block *vc_sb;
+ struct mutex vc_mutex;
+};
+
+static inline struct venus_comm *coda_vcp(struct super_block *sb)
+{
+ return (struct venus_comm *)((sb)->s_fs_info);
+}
+
+/* upcalls */
+int venus_rootfid(struct super_block *sb, struct CodaFid *fidp);
+int venus_getattr(struct super_block *sb, struct CodaFid *fid,
+ struct coda_vattr *attr);
+int venus_setattr(struct super_block *, struct CodaFid *, struct coda_vattr *);
+int venus_lookup(struct super_block *sb, struct CodaFid *fid,
+ const char *name, int length, int *type,
+ struct CodaFid *resfid);
+int venus_close(struct super_block *sb, struct CodaFid *fid, int flags,
+ kuid_t uid);
+int venus_open(struct super_block *sb, struct CodaFid *fid, int flags,
+ struct file **f);
+int venus_mkdir(struct super_block *sb, struct CodaFid *dirfid,
+ const char *name, int length,
+ struct CodaFid *newfid, struct coda_vattr *attrs);
+int venus_create(struct super_block *sb, struct CodaFid *dirfid,
+ const char *name, int length, int excl, int mode,
+ struct CodaFid *newfid, struct coda_vattr *attrs);
+int venus_rmdir(struct super_block *sb, struct CodaFid *dirfid,
+ const char *name, int length);
+int venus_remove(struct super_block *sb, struct CodaFid *dirfid,
+ const char *name, int length);
+int venus_readlink(struct super_block *sb, struct CodaFid *fid,
+ char *buffer, int *length);
+int venus_rename(struct super_block *sb, struct CodaFid *new_fid,
+ struct CodaFid *old_fid, size_t old_length,
+ size_t new_length, const char *old_name,
+ const char *new_name);
+int venus_link(struct super_block *sb, struct CodaFid *fid,
+ struct CodaFid *dirfid, const char *name, int len );
+int venus_symlink(struct super_block *sb, struct CodaFid *fid,
+ const char *name, int len, const char *symname, int symlen);
+int venus_access(struct super_block *sb, struct CodaFid *fid, int mask);
+int venus_pioctl(struct super_block *sb, struct CodaFid *fid,
+ unsigned int cmd, struct PioctlData *data);
+int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out,
+ size_t nbytes);
+int venus_fsync(struct super_block *sb, struct CodaFid *fid);
+int venus_statfs(struct dentry *dentry, struct kstatfs *sfs);
+int venus_access_intent(struct super_block *sb, struct CodaFid *fid,
+ bool *access_intent_supported,
+ size_t count, loff_t ppos, int type);
+
+/*
+ * Statistics
+ */
+
+extern struct venus_comm coda_comms[];
+#endif
diff --git a/fs/coda/dir.c b/fs/coda/dir.c
index 00876ddadb43..ca40c2556ba6 100644
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -23,7 +23,7 @@
#include <linux/uaccess.h>
#include <linux/coda.h>
-#include <linux/coda_psdev.h>
+#include "coda_psdev.h"
#include "coda_linux.h"
#include "coda_cache.h"
@@ -47,8 +47,8 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, unsig
int type = 0;
if (length > CODA_MAXNAMLEN) {
- pr_err("name too long: lookup, %s (%*s)\n",
- coda_i2s(dir), (int)length, name);
+ pr_err("name too long: lookup, %s %zu\n",
+ coda_i2s(dir), length);
return ERR_PTR(-ENAMETOOLONG);
}
@@ -356,8 +356,7 @@ static int coda_venus_readdir(struct file *coda_file, struct dir_context *ctx)
ino_t ino;
int ret;
- cfi = CODA_FTOC(coda_file);
- BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
+ cfi = coda_ftoc(coda_file);
host_file = cfi->cfi_container;
cii = ITOC(file_inode(coda_file));
@@ -426,8 +425,7 @@ static int coda_readdir(struct file *coda_file, struct dir_context *ctx)
struct file *host_file;
int ret;
- cfi = CODA_FTOC(coda_file);
- BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
+ cfi = coda_ftoc(coda_file);
host_file = cfi->cfi_container;
if (host_file->f_op->iterate || host_file->f_op->iterate_shared) {
diff --git a/fs/coda/file.c b/fs/coda/file.c
index 1cbc1f2298ee..128d63df5bfb 100644
--- a/fs/coda/file.c
+++ b/fs/coda/file.c
@@ -20,22 +20,43 @@
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
+#include <linux/uio.h>
#include <linux/coda.h>
-#include <linux/coda_psdev.h>
-
+#include "coda_psdev.h"
#include "coda_linux.h"
#include "coda_int.h"
+struct coda_vm_ops {
+ atomic_t refcnt;
+ struct file *coda_file;
+ const struct vm_operations_struct *host_vm_ops;
+ struct vm_operations_struct vm_ops;
+};
+
static ssize_t
coda_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
{
struct file *coda_file = iocb->ki_filp;
- struct coda_file_info *cfi = CODA_FTOC(coda_file);
+ struct inode *coda_inode = file_inode(coda_file);
+ struct coda_file_info *cfi = coda_ftoc(coda_file);
+ loff_t ki_pos = iocb->ki_pos;
+ size_t count = iov_iter_count(to);
+ ssize_t ret;
- BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
+ ret = venus_access_intent(coda_inode->i_sb, coda_i2f(coda_inode),
+ &cfi->cfi_access_intent,
+ count, ki_pos, CODA_ACCESS_TYPE_READ);
+ if (ret)
+ goto finish_read;
- return vfs_iter_read(cfi->cfi_container, to, &iocb->ki_pos, 0);
+ ret = vfs_iter_read(cfi->cfi_container, to, &iocb->ki_pos, 0);
+
+finish_read:
+ venus_access_intent(coda_inode->i_sb, coda_i2f(coda_inode),
+ &cfi->cfi_access_intent,
+ count, ki_pos, CODA_ACCESS_TYPE_READ_FINISH);
+ return ret;
}
static ssize_t
@@ -43,13 +64,18 @@ coda_file_write_iter(struct kiocb *iocb, struct iov_iter *to)
{
struct file *coda_file = iocb->ki_filp;
struct inode *coda_inode = file_inode(coda_file);
- struct coda_file_info *cfi = CODA_FTOC(coda_file);
- struct file *host_file;
+ struct coda_file_info *cfi = coda_ftoc(coda_file);
+ struct file *host_file = cfi->cfi_container;
+ loff_t ki_pos = iocb->ki_pos;
+ size_t count = iov_iter_count(to);
ssize_t ret;
- BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
+ ret = venus_access_intent(coda_inode->i_sb, coda_i2f(coda_inode),
+ &cfi->cfi_access_intent,
+ count, ki_pos, CODA_ACCESS_TYPE_WRITE);
+ if (ret)
+ goto finish_write;
- host_file = cfi->cfi_container;
file_start_write(host_file);
inode_lock(coda_inode);
ret = vfs_iter_write(cfi->cfi_container, to, &iocb->ki_pos, 0);
@@ -58,26 +84,73 @@ coda_file_write_iter(struct kiocb *iocb, struct iov_iter *to)
coda_inode->i_mtime = coda_inode->i_ctime = current_time(coda_inode);
inode_unlock(coda_inode);
file_end_write(host_file);
+
+finish_write:
+ venus_access_intent(coda_inode->i_sb, coda_i2f(coda_inode),
+ &cfi->cfi_access_intent,
+ count, ki_pos, CODA_ACCESS_TYPE_WRITE_FINISH);
return ret;
}
+static void
+coda_vm_open(struct vm_area_struct *vma)
+{
+ struct coda_vm_ops *cvm_ops =
+ container_of(vma->vm_ops, struct coda_vm_ops, vm_ops);
+
+ atomic_inc(&cvm_ops->refcnt);
+
+ if (cvm_ops->host_vm_ops && cvm_ops->host_vm_ops->open)
+ cvm_ops->host_vm_ops->open(vma);
+}
+
+static void
+coda_vm_close(struct vm_area_struct *vma)
+{
+ struct coda_vm_ops *cvm_ops =
+ container_of(vma->vm_ops, struct coda_vm_ops, vm_ops);
+
+ if (cvm_ops->host_vm_ops && cvm_ops->host_vm_ops->close)
+ cvm_ops->host_vm_ops->close(vma);
+
+ if (atomic_dec_and_test(&cvm_ops->refcnt)) {
+ vma->vm_ops = cvm_ops->host_vm_ops;
+ fput(cvm_ops->coda_file);
+ kfree(cvm_ops);
+ }
+}
+
static int
coda_file_mmap(struct file *coda_file, struct vm_area_struct *vma)
{
- struct coda_file_info *cfi;
+ struct inode *coda_inode = file_inode(coda_file);
+ struct coda_file_info *cfi = coda_ftoc(coda_file);
+ struct file *host_file = cfi->cfi_container;
+ struct inode *host_inode = file_inode(host_file);
struct coda_inode_info *cii;
- struct file *host_file;
- struct inode *coda_inode, *host_inode;
-
- cfi = CODA_FTOC(coda_file);
- BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
- host_file = cfi->cfi_container;
+ struct coda_vm_ops *cvm_ops;
+ loff_t ppos;
+ size_t count;
+ int ret;
if (!host_file->f_op->mmap)
return -ENODEV;
- coda_inode = file_inode(coda_file);
- host_inode = file_inode(host_file);
+ if (WARN_ON(coda_file != vma->vm_file))
+ return -EIO;
+
+ count = vma->vm_end - vma->vm_start;
+ ppos = vma->vm_pgoff * PAGE_SIZE;
+
+ ret = venus_access_intent(coda_inode->i_sb, coda_i2f(coda_inode),
+ &cfi->cfi_access_intent,
+ count, ppos, CODA_ACCESS_TYPE_MMAP);
+ if (ret)
+ return ret;
+
+ cvm_ops = kmalloc(sizeof(struct coda_vm_ops), GFP_KERNEL);
+ if (!cvm_ops)
+ return -ENOMEM;
cii = ITOC(coda_inode);
spin_lock(&cii->c_lock);
@@ -89,6 +162,7 @@ coda_file_mmap(struct file *coda_file, struct vm_area_struct *vma)
* the container file on us! */
else if (coda_inode->i_mapping != host_inode->i_mapping) {
spin_unlock(&cii->c_lock);
+ kfree(cvm_ops);
return -EBUSY;
}
@@ -97,7 +171,29 @@ coda_file_mmap(struct file *coda_file, struct vm_area_struct *vma)
cfi->cfi_mapcount++;
spin_unlock(&cii->c_lock);
- return call_mmap(host_file, vma);
+ vma->vm_file = get_file(host_file);
+ ret = call_mmap(vma->vm_file, vma);
+
+ if (ret) {
+ /* if call_mmap fails, our caller will put coda_file so we
+ * should drop the reference to the host_file that we got.
+ */
+ fput(host_file);
+ kfree(cvm_ops);
+ } else {
+ /* here we add redirects for the open/close vm_operations */
+ cvm_ops->host_vm_ops = vma->vm_ops;
+ if (vma->vm_ops)
+ cvm_ops->vm_ops = *vma->vm_ops;
+
+ cvm_ops->vm_ops.open = coda_vm_open;
+ cvm_ops->vm_ops.close = coda_vm_close;
+ cvm_ops->coda_file = coda_file;
+ atomic_set(&cvm_ops->refcnt, 1);
+
+ vma->vm_ops = &cvm_ops->vm_ops;
+ }
+ return ret;
}
int coda_open(struct inode *coda_inode, struct file *coda_file)
@@ -127,6 +223,8 @@ int coda_open(struct inode *coda_inode, struct file *coda_file)
cfi->cfi_magic = CODA_MAGIC;
cfi->cfi_mapcount = 0;
cfi->cfi_container = host_file;
+ /* assume access intents are supported unless we hear otherwise */
+ cfi->cfi_access_intent = true;
BUG_ON(coda_file->private_data != NULL);
coda_file->private_data = cfi;
@@ -142,8 +240,7 @@ int coda_release(struct inode *coda_inode, struct file *coda_file)
struct inode *host_inode;
int err;
- cfi = CODA_FTOC(coda_file);
- BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
+ cfi = coda_ftoc(coda_file);
err = venus_close(coda_inode->i_sb, coda_i2f(coda_inode),
coda_flags, coda_file->f_cred->fsuid);
@@ -185,8 +282,7 @@ int coda_fsync(struct file *coda_file, loff_t start, loff_t end, int datasync)
return err;
inode_lock(coda_inode);
- cfi = CODA_FTOC(coda_file);
- BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
+ cfi = coda_ftoc(coda_file);
host_file = cfi->cfi_container;
err = vfs_fsync(host_file, datasync);
@@ -207,4 +303,3 @@ const struct file_operations coda_file_operations = {
.fsync = coda_fsync,
.splice_read = generic_file_splice_read,
};
-
diff --git a/fs/coda/inode.c b/fs/coda/inode.c
index 23f6ebd08e80..321f56e487cb 100644
--- a/fs/coda/inode.c
+++ b/fs/coda/inode.c
@@ -27,7 +27,7 @@
#include <linux/vmalloc.h>
#include <linux/coda.h>
-#include <linux/coda_psdev.h>
+#include "coda_psdev.h"
#include "coda_linux.h"
#include "coda_cache.h"
@@ -236,6 +236,7 @@ static void coda_put_super(struct super_block *sb)
vcp->vc_sb = NULL;
sb->s_fs_info = NULL;
mutex_unlock(&vcp->vc_mutex);
+ mutex_destroy(&vcp->vc_mutex);
pr_info("Bye bye.\n");
}
diff --git a/fs/coda/pioct