* [PATCH 1/3] fs: add set_flags wrapper
@ 2010-12-14 15:11 Dmitry Monakhov
2010-12-14 15:11 ` [PATCH 2/3] fs: add fadvise file_operation Dmitry Monakhov
2010-12-14 15:11 ` [PATCH 3/3] ecryptfs: add fadvise/set_flags calbacks Dmitry Monakhov
0 siblings, 2 replies; 4+ messages in thread
From: Dmitry Monakhov @ 2010-12-14 15:11 UTC (permalink / raw)
To: ecryptfs-devel, linux-fsdevel; +Cc: viro, Dmitry Monakhov
Direct f_flags manipulation may be not suitable for some filesytems.
Let's introduce new ->set_flags() callback for that purpose. This callback
is responsible for flags check, so ->check_flags() no longer needed.
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
fs/bad_inode.c | 4 ++--
fs/fcntl.c | 14 +++++++-------
fs/nfs/file.c | 12 ++++++++----
include/linux/fs.h | 2 +-
4 files changed, 18 insertions(+), 14 deletions(-)
diff --git a/fs/bad_inode.c b/fs/bad_inode.c
index f024d8a..97933cd 100644
--- a/fs/bad_inode.c
+++ b/fs/bad_inode.c
@@ -120,7 +120,7 @@ static unsigned long bad_file_get_unmapped_area(struct file *file,
return -EIO;
}
-static int bad_file_check_flags(int flags)
+static int bad_file_set_flags(struct file *file, int flags)
{
return -EIO;
}
@@ -165,7 +165,7 @@ static const struct file_operations bad_file_ops =
.lock = bad_file_lock,
.sendpage = bad_file_sendpage,
.get_unmapped_area = bad_file_get_unmapped_area,
- .check_flags = bad_file_check_flags,
+ .set_flags = bad_file_set_flags,
.flock = bad_file_flock,
.splice_write = bad_file_splice_write,
.splice_read = bad_file_splice_read,
diff --git a/fs/fcntl.c b/fs/fcntl.c
index f8cc34f..76b77ac 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -173,10 +173,6 @@ static int setfl(int fd, struct file * filp, unsigned long arg)
return -EINVAL;
}
- if (filp->f_op && filp->f_op->check_flags)
- error = filp->f_op->check_flags(arg);
- if (error)
- return error;
/*
* ->fasync() is responsible for setting the FASYNC bit.
@@ -189,10 +185,14 @@ static int setfl(int fd, struct file * filp, unsigned long arg)
if (error > 0)
error = 0;
}
- spin_lock(&filp->f_lock);
- filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK);
- spin_unlock(&filp->f_lock);
+ if (filp->f_op && filp->f_op->set_flags)
+ error = filp->f_op->set_flags(filp, arg);
+ else {
+ spin_lock(&filp->f_lock);
+ filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK);
+ spin_unlock(&filp->f_lock);
+ }
out:
return error;
}
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 05bf3c0..32ac63a 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -55,7 +55,7 @@ static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov,
unsigned long nr_segs, loff_t pos);
static int nfs_file_flush(struct file *, fl_owner_t id);
static int nfs_file_fsync(struct file *, int datasync);
-static int nfs_check_flags(int flags);
+static int nfs_set_flags(struct file *file, int flags);
static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl);
static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl);
static int nfs_setlease(struct file *file, long arg, struct file_lock **fl);
@@ -77,7 +77,7 @@ const struct file_operations nfs_file_operations = {
.flock = nfs_flock,
.splice_read = nfs_file_splice_read,
.splice_write = nfs_file_splice_write,
- .check_flags = nfs_check_flags,
+ .set_flags = nfs_set_flags,
.setlease = nfs_setlease,
};
@@ -104,11 +104,15 @@ const struct inode_operations nfs3_file_inode_operations = {
# define IS_SWAPFILE(inode) (0)
#endif
-static int nfs_check_flags(int flags)
+#define NFS_FL_MASK (O_NONBLOCK | O_NDELAY | O_NOATIME)
+static int nfs_set_flags(struct file * filp, int flags)
{
if ((flags & (O_APPEND | O_DIRECT)) == (O_APPEND | O_DIRECT))
return -EINVAL;
+ spin_lock(&filp->f_lock);
+ filp->f_flags = (flags & NFS_FL_MASK) | (filp->f_flags & ~NFS_FL_MASK);
+ spin_unlock(&filp->f_lock);
return 0;
}
@@ -125,7 +129,7 @@ nfs_file_open(struct inode *inode, struct file *filp)
filp->f_path.dentry->d_name.name);
nfs_inc_stats(inode, NFSIOS_VFSOPEN);
- res = nfs_check_flags(filp->f_flags);
+ res = nfs_set_flags(filp, filp->f_flags);
if (res)
return res;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 6708fef..b176d11 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1517,7 +1517,7 @@ struct file_operations {
int (*lock) (struct file *, int, struct file_lock *);
ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
- int (*check_flags)(int);
+ int (*set_flags)(struct file *, int);
int (*flock) (struct file *, int, struct file_lock *);
ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
--
1.7.2.3
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/3] fs: add fadvise file_operation
2010-12-14 15:11 [PATCH 1/3] fs: add set_flags wrapper Dmitry Monakhov
@ 2010-12-14 15:11 ` Dmitry Monakhov
2010-12-14 15:11 ` [PATCH 3/3] ecryptfs: add fadvise/set_flags calbacks Dmitry Monakhov
1 sibling, 0 replies; 4+ messages in thread
From: Dmitry Monakhov @ 2010-12-14 15:11 UTC (permalink / raw)
To: ecryptfs-devel, linux-fsdevel; +Cc: viro, Dmitry Monakhov
sys_fadvise result in direct f_mode modification, which may be not
suitable for some unusual filesytems where file mode invariant is more
complex. In order to support such filesystems we have to delegate fadvise
logic to filesystem layer.
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
include/linux/fadvise.h | 3 ++
include/linux/fs.h | 1 +
mm/fadvise.c | 56 +++++++++++++++++++++++++++++++---------------
3 files changed, 42 insertions(+), 18 deletions(-)
diff --git a/include/linux/fadvise.h b/include/linux/fadvise.h
index e8e7471..8389378 100644
--- a/include/linux/fadvise.h
+++ b/include/linux/fadvise.h
@@ -18,4 +18,7 @@
#define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
#endif
+#ifdef __KERNEL__
+extern int generic_fadvise(struct file *file, loff_t off, loff_t len, int adv);
+#endif
#endif /* FADVISE_H_INCLUDED */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index b176d11..63785d3 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1522,6 +1522,7 @@ struct file_operations {
ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
int (*setlease)(struct file *, long, struct file_lock **);
+ int (*fadvise)(struct file* file, loff_t offset, loff_t len, int advice);
};
struct inode_operations {
diff --git a/mm/fadvise.c b/mm/fadvise.c
index 8d723c9..e13ee29 100644
--- a/mm/fadvise.c
+++ b/mm/fadvise.c
@@ -7,6 +7,7 @@
* Initial version.
*/
+#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/file.h>
#include <linux/fs.h>
@@ -24,10 +25,9 @@
* POSIX_FADV_WILLNEED could set PG_Referenced, and POSIX_FADV_NOREUSE could
* deactivate the pages and clear PG_Referenced.
*/
-SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice)
+int generic_fadvise(struct file* file, loff_t offset, loff_t len, int advice)
{
- struct file *file = fget(fd);
- struct address_space *mapping;
+ struct address_space *mapping = file->f_mapping;
struct backing_dev_info *bdi;
loff_t endbyte; /* inclusive */
pgoff_t start_index;
@@ -35,20 +35,6 @@ SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice)
unsigned long nrpages;
int ret = 0;
- if (!file)
- return -EBADF;
-
- if (S_ISFIFO(file->f_path.dentry->d_inode->i_mode)) {
- ret = -ESPIPE;
- goto out;
- }
-
- mapping = file->f_mapping;
- if (!mapping || len < 0) {
- ret = -EINVAL;
- goto out;
- }
-
if (mapping->a_ops->get_xip_mem) {
switch (advice) {
case POSIX_FADV_NORMAL:
@@ -106,7 +92,7 @@ SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice)
nrpages = end_index - start_index + 1;
if (!nrpages)
nrpages = ~0UL;
-
+
ret = force_page_cache_readahead(mapping, file,
start_index,
nrpages);
@@ -131,9 +117,43 @@ SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice)
ret = -EINVAL;
}
out:
+ return ret;
+}
+EXPORT_SYMBOL(generic_fadvise);
+
+
+int do_fadvise(int fd, loff_t offset, loff_t len, int advice)
+
+{
+ struct file *file = fget(fd);
+ int (*fadvise)(struct file *,loff_t, loff_t, int) = generic_fadvise;
+ int ret = 0;
+ if (!file)
+ return -EBADF;
+
+ if (S_ISFIFO(file->f_path.dentry->d_inode->i_mode)) {
+ ret = -ESPIPE;
+ goto out;
+ }
+
+ if (!file->f_mapping || len < 0) {
+ ret = -EINVAL;
+ goto out;
+ }
+ if (file->f_op && file->f_op->fadvise)
+ fadvise = file->f_op->fadvise;
+
+ ret = fadvise(file, offset, len, advice);
+out:
fput(file);
return ret;
}
+
+SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice)
+{
+ return do_fadvise(fd, offset, len, advice);
+}
+
#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
asmlinkage long SyS_fadvise64_64(long fd, loff_t offset, loff_t len, long advice)
{
--
1.7.2.3
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3/3] ecryptfs: add fadvise/set_flags calbacks
2010-12-14 15:11 [PATCH 1/3] fs: add set_flags wrapper Dmitry Monakhov
2010-12-14 15:11 ` [PATCH 2/3] fs: add fadvise file_operation Dmitry Monakhov
@ 2010-12-14 15:11 ` Dmitry Monakhov
1 sibling, 0 replies; 4+ messages in thread
From: Dmitry Monakhov @ 2010-12-14 15:11 UTC (permalink / raw)
To: ecryptfs-devel, linux-fsdevel; +Cc: viro, Dmitry Monakhov
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
fs/ecryptfs/file.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 67 insertions(+), 0 deletions(-)
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index 91da029..24149ec 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -31,6 +31,7 @@
#include <linux/security.h>
#include <linux/compat.h>
#include <linux/fs_stack.h>
+#include <linux/fadvise.h>
#include "ecryptfs_kernel.h"
/**
@@ -317,6 +318,68 @@ ecryptfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
#endif
+static int
+ecryptfs_fadvise(struct file *file, loff_t offset, loff_t len, int advice)
+{
+ struct file *lower_file = NULL;
+ long rc = 0;
+
+ if (ecryptfs_file_to_private(file))
+ lower_file = ecryptfs_file_to_lower(file);
+
+ if (!lower_file || !lower_file->f_op)
+ return rc;
+
+ if (lower_file->f_op && lower_file->f_op->fadvise)
+ rc = lower_file->f_op->fadvise(lower_file, offset, len, advice);
+ else
+ rc = generic_fadvise(lower_file, offset, len, advice);
+ if (!rc)
+ generic_fadvise(file, offset, len, advice);
+
+ return rc;
+}
+
+#define ECRYPTFS_FL_MASK (O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
+static int ecryptfs_set_flags(struct file *file, int flags)
+{
+ struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
+ struct dentry *ecryptfs_dentry = file->f_path.dentry;
+ struct file *lower_file = NULL;
+ int rc = 0;
+ mount_crypt_stat = &ecryptfs_superblock_to_private(
+ ecryptfs_dentry->d_sb)->mount_crypt_stat;
+ if ((mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED)
+ && (flags & O_APPEND)) {
+ printk(KERN_WARNING "Mount has encrypted view enabled; "
+ "files may only be read\n");
+ rc = -EPERM;
+ goto out;
+ }
+ if (ecryptfs_file_to_private(file))
+ lower_file = ecryptfs_file_to_lower(file);
+ if (!lower_file)
+ goto out;
+
+ spin_lock(&file->f_lock);
+ if (lower_file->f_op && lower_file->f_op->set_flags)
+ rc = lower_file->f_op->set_flags(lower_file, flags);
+ else {
+ spin_lock(&lower_file->f_lock);
+ lower_file->f_flags = (flags & ECRYPTFS_FL_MASK) |
+ (lower_file->f_flags & ~ECRYPTFS_FL_MASK);
+ spin_unlock(&lower_file->f_lock);
+ }
+ if (!rc)
+ file->f_flags = (flags & ECRYPTFS_FL_MASK) |
+ (file->f_flags & ~ECRYPTFS_FL_MASK);
+ spin_unlock(&file->f_lock);
+
+out:
+ return rc;
+
+
+}
const struct file_operations ecryptfs_dir_fops = {
.readdir = ecryptfs_readdir,
.unlocked_ioctl = ecryptfs_unlocked_ioctl,
@@ -330,6 +393,8 @@ const struct file_operations ecryptfs_dir_fops = {
.fasync = ecryptfs_fasync,
.splice_read = generic_file_splice_read,
.llseek = default_llseek,
+ .set_flags = ecryptfs_set_flags,
+ .fadvise = ecryptfs_fadvise,
};
const struct file_operations ecryptfs_main_fops = {
@@ -350,4 +415,6 @@ const struct file_operations ecryptfs_main_fops = {
.fsync = ecryptfs_fsync,
.fasync = ecryptfs_fasync,
.splice_read = generic_file_splice_read,
+ .set_flags = ecryptfs_set_flags,
+ .fadvise = ecryptfs_fadvise,
};
--
1.7.2.3
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/3] fs: add fadvise file_operation
2014-10-10 16:29 [PATCH 1/3] fs: fcntl add set_flags wrapper Dmitry Monakhov
@ 2014-10-10 16:29 ` Dmitry Monakhov
0 siblings, 0 replies; 4+ messages in thread
From: Dmitry Monakhov @ 2014-10-10 16:29 UTC (permalink / raw)
To: linux-fsdevel; +Cc: viro, Dmitry Monakhov
sys_fadvise result in direct f_mode modification, which may be not
suitable for some unusual filesytems where file mode invariant is more
complex. In order to support such filesystems we have to delegate fadvise
logic to filesystem layer.
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
include/linux/fs.h | 4 ++
mm/fadvise.c | 81 ++++++++++++++++++++++++++++++++-------------------
2 files changed, 55 insertions(+), 30 deletions(-)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index bbf40a5..8c4c323 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1511,6 +1511,7 @@ struct file_operations {
long (*fallocate)(struct file *file, int mode, loff_t offset,
loff_t len);
int (*show_fdinfo)(struct seq_file *m, struct file *f);
+ int (*fadvise)(struct file *file, loff_t off, loff_t len, int advice);
};
struct inode_operations {
@@ -2073,6 +2074,9 @@ extern int finish_open(struct file *file, struct dentry *dentry,
int *opened);
extern int finish_no_open(struct file *file, struct dentry *dentry);
+/* fs/fadvise.c */
+extern int generic_fadvise(struct file *file, loff_t off, loff_t len, int adv);
+
/* fs/ioctl.c */
extern int ioctl_preallocate(struct file *filp, void __user *argp);
diff --git a/mm/fadvise.c b/mm/fadvise.c
index 3bcfd81..a568ba6 100644
--- a/mm/fadvise.c
+++ b/mm/fadvise.c
@@ -7,6 +7,7 @@
* Initial version.
*/
+#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/file.h>
#include <linux/fs.h>
@@ -25,10 +26,9 @@
* POSIX_FADV_WILLNEED could set PG_Referenced, and POSIX_FADV_NOREUSE could
* deactivate the pages and clear PG_Referenced.
*/
-SYSCALL_DEFINE4(fadvise64_64, int, fd, loff_t, offset, loff_t, len, int, advice)
+int generic_fadvise(struct file *file, loff_t offset, loff_t len, int advice)
{
- struct fd f = fdget(fd);
- struct address_space *mapping;
+ struct address_space *mapping = file->f_mapping;
struct backing_dev_info *bdi;
loff_t endbyte; /* inclusive */
pgoff_t start_index;
@@ -36,20 +36,6 @@ SYSCALL_DEFINE4(fadvise64_64, int, fd, loff_t, offset, loff_t, len, int, advice)
unsigned long nrpages;
int ret = 0;
- if (!f.file)
- return -EBADF;
-
- if (S_ISFIFO(file_inode(f.file)->i_mode)) {
- ret = -ESPIPE;
- goto out;
- }
-
- mapping = f.file->f_mapping;
- if (!mapping || len < 0) {
- ret = -EINVAL;
- goto out;
- }
-
if (mapping->a_ops->get_xip_mem) {
switch (advice) {
case POSIX_FADV_NORMAL:
@@ -77,21 +63,21 @@ SYSCALL_DEFINE4(fadvise64_64, int, fd, loff_t, offset, loff_t, len, int, advice)
switch (advice) {
case POSIX_FADV_NORMAL:
- f.file->f_ra.ra_pages = bdi->ra_pages;
- spin_lock(&f.file->f_lock);
- f.file->f_mode &= ~FMODE_RANDOM;
- spin_unlock(&f.file->f_lock);
+ file->f_ra.ra_pages = bdi->ra_pages;
+ spin_lock(&file->f_lock);
+ file->f_mode &= ~FMODE_RANDOM;
+ spin_unlock(&file->f_lock);
break;
case POSIX_FADV_RANDOM:
- spin_lock(&f.file->f_lock);
- f.file->f_mode |= FMODE_RANDOM;
- spin_unlock(&f.file->f_lock);
+ spin_lock(&file->f_lock);
+ file->f_mode |= FMODE_RANDOM;
+ spin_unlock(&file->f_lock);
break;
case POSIX_FADV_SEQUENTIAL:
- f.file->f_ra.ra_pages = bdi->ra_pages * 2;
- spin_lock(&f.file->f_lock);
- f.file->f_mode &= ~FMODE_RANDOM;
- spin_unlock(&f.file->f_lock);
+ file->f_ra.ra_pages = bdi->ra_pages * 2;
+ spin_lock(&file->f_lock);
+ file->f_mode &= ~FMODE_RANDOM;
+ spin_unlock(&file->f_lock);
break;
case POSIX_FADV_WILLNEED:
/* First and last PARTIAL page! */
@@ -107,7 +93,7 @@ SYSCALL_DEFINE4(fadvise64_64, int, fd, loff_t, offset, loff_t, len, int, advice)
* Ignore return value because fadvise() shall return
* success even if filesystem can't retrieve a hint,
*/
- force_page_cache_readahead(mapping, f.file, start_index,
+ force_page_cache_readahead(mapping, file, start_index,
nrpages);
break;
case POSIX_FADV_NOREUSE:
@@ -142,15 +128,50 @@ SYSCALL_DEFINE4(fadvise64_64, int, fd, loff_t, offset, loff_t, len, int, advice)
ret = -EINVAL;
}
out:
+ return ret;
+}
+EXPORT_SYMBOL(generic_fadvise);
+
+static int do_fadvise(int fd, loff_t offset, loff_t len, int advice)
+{
+ struct fd f = fdget(fd);
+ int (*fadvise)(struct file *, loff_t, loff_t, int) = generic_fadvise;
+ int ret = 0;
+
+ if (!f.file)
+ return -EBADF;
+
+ if (S_ISFIFO(file_inode(f.file)->i_mode)) {
+ ret = -ESPIPE;
+ goto out;
+ }
+ if (!f.file->f_mapping || len < 0) {
+ ret = -EINVAL;
+ goto out;
+ }
+ if (!f.file->f_mapping || len < 0) {
+ ret = -EINVAL;
+ goto out;
+ }
+ if (f.file->f_op && f.file->f_op->fadvise)
+ fadvise = f.file->f_op->fadvise;
+
+ ret = fadvise(f.file, offset, len, advice);
+out:
fdput(f);
return ret;
}
+SYSCALL_DEFINE4(fadvise64_64, int, fd, loff_t, offset, loff_t, len, int, advice)
+{
+ return do_fadvise(fd, offset, len, advice);
+}
+
#ifdef __ARCH_WANT_SYS_FADVISE64
SYSCALL_DEFINE4(fadvise64, int, fd, loff_t, offset, size_t, len, int, advice)
{
- return sys_fadvise64_64(fd, offset, len, advice);
+ return do_fadvise(fd, offset, len, advice);
}
#endif
--
1.7.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2014-10-10 16:29 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-12-14 15:11 [PATCH 1/3] fs: add set_flags wrapper Dmitry Monakhov
2010-12-14 15:11 ` [PATCH 2/3] fs: add fadvise file_operation Dmitry Monakhov
2010-12-14 15:11 ` [PATCH 3/3] ecryptfs: add fadvise/set_flags calbacks Dmitry Monakhov
-- strict thread matches above, loose matches on Subject: below --
2014-10-10 16:29 [PATCH 1/3] fs: fcntl add set_flags wrapper Dmitry Monakhov
2014-10-10 16:29 ` [PATCH 2/3] fs: add fadvise file_operation Dmitry Monakhov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).