forked from Minki/linux
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse
Pull fuse updates from Miklos Szeredi. * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse: fuse: verify all ioctl retry iov elements fuse: add missing INIT flag descriptions fuse: add missing INIT flags fuse: update attributes on aio_read fuse: invalidate inode mapping if mtime changes fuse: add FUSE_AUTO_INVAL_DATA init flag
This commit is contained in:
commit
2eac9eb8a2
@ -703,13 +703,16 @@ static ssize_t fuse_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
|
||||
unsigned long nr_segs, loff_t pos)
|
||||
{
|
||||
struct inode *inode = iocb->ki_filp->f_mapping->host;
|
||||
struct fuse_conn *fc = get_fuse_conn(inode);
|
||||
|
||||
if (pos + iov_length(iov, nr_segs) > i_size_read(inode)) {
|
||||
/*
|
||||
* In auto invalidate mode, always update attributes on read.
|
||||
* Otherwise, only update if we attempt to read past EOF (to ensure
|
||||
* i_size is up to date).
|
||||
*/
|
||||
if (fc->auto_inval_data ||
|
||||
(pos + iov_length(iov, nr_segs) > i_size_read(inode))) {
|
||||
int err;
|
||||
/*
|
||||
* If trying to read past EOF, make sure the i_size
|
||||
* attribute is up-to-date.
|
||||
*/
|
||||
err = fuse_update_attributes(inode, NULL, iocb->ki_filp, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
@ -1700,7 +1703,7 @@ static int fuse_verify_ioctl_iov(struct iovec *iov, size_t count)
|
||||
size_t n;
|
||||
u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT;
|
||||
|
||||
for (n = 0; n < count; n++) {
|
||||
for (n = 0; n < count; n++, iov++) {
|
||||
if (iov->iov_len > (size_t) max)
|
||||
return -ENOMEM;
|
||||
max -= iov->iov_len;
|
||||
|
@ -484,6 +484,9 @@ struct fuse_conn {
|
||||
/** Is fallocate not implemented by fs? */
|
||||
unsigned no_fallocate:1;
|
||||
|
||||
/** Use enhanced/automatic page cache invalidation. */
|
||||
unsigned auto_inval_data:1;
|
||||
|
||||
/** The number of requests waiting for completion */
|
||||
atomic_t num_waiting;
|
||||
|
||||
|
@ -197,6 +197,7 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
|
||||
struct fuse_conn *fc = get_fuse_conn(inode);
|
||||
struct fuse_inode *fi = get_fuse_inode(inode);
|
||||
loff_t oldsize;
|
||||
struct timespec old_mtime;
|
||||
|
||||
spin_lock(&fc->lock);
|
||||
if (attr_version != 0 && fi->attr_version > attr_version) {
|
||||
@ -204,15 +205,35 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
|
||||
return;
|
||||
}
|
||||
|
||||
old_mtime = inode->i_mtime;
|
||||
fuse_change_attributes_common(inode, attr, attr_valid);
|
||||
|
||||
oldsize = inode->i_size;
|
||||
i_size_write(inode, attr->size);
|
||||
spin_unlock(&fc->lock);
|
||||
|
||||
if (S_ISREG(inode->i_mode) && oldsize != attr->size) {
|
||||
truncate_pagecache(inode, oldsize, attr->size);
|
||||
invalidate_inode_pages2(inode->i_mapping);
|
||||
if (S_ISREG(inode->i_mode)) {
|
||||
bool inval = false;
|
||||
|
||||
if (oldsize != attr->size) {
|
||||
truncate_pagecache(inode, oldsize, attr->size);
|
||||
inval = true;
|
||||
} else if (fc->auto_inval_data) {
|
||||
struct timespec new_mtime = {
|
||||
.tv_sec = attr->mtime,
|
||||
.tv_nsec = attr->mtimensec,
|
||||
};
|
||||
|
||||
/*
|
||||
* Auto inval mode also checks and invalidates if mtime
|
||||
* has changed.
|
||||
*/
|
||||
if (!timespec_equal(&old_mtime, &new_mtime))
|
||||
inval = true;
|
||||
}
|
||||
|
||||
if (inval)
|
||||
invalidate_inode_pages2(inode->i_mapping);
|
||||
}
|
||||
}
|
||||
|
||||
@ -834,6 +855,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
|
||||
fc->big_writes = 1;
|
||||
if (arg->flags & FUSE_DONT_MASK)
|
||||
fc->dont_mask = 1;
|
||||
if (arg->flags & FUSE_AUTO_INVAL_DATA)
|
||||
fc->auto_inval_data = 1;
|
||||
} else {
|
||||
ra_pages = fc->max_read / PAGE_CACHE_SIZE;
|
||||
fc->no_lock = 1;
|
||||
@ -859,7 +882,8 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
|
||||
arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE;
|
||||
arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC |
|
||||
FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK |
|
||||
FUSE_FLOCK_LOCKS;
|
||||
FUSE_SPLICE_WRITE | FUSE_SPLICE_MOVE | FUSE_SPLICE_READ |
|
||||
FUSE_FLOCK_LOCKS | FUSE_IOCTL_DIR | FUSE_AUTO_INVAL_DATA;
|
||||
req->in.h.opcode = FUSE_INIT;
|
||||
req->in.numargs = 1;
|
||||
req->in.args[0].size = sizeof(*arg);
|
||||
|
@ -57,6 +57,9 @@
|
||||
*
|
||||
* 7.19
|
||||
* - add FUSE_FALLOCATE
|
||||
*
|
||||
* 7.20
|
||||
* - add FUSE_AUTO_INVAL_DATA
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_FUSE_H
|
||||
@ -88,7 +91,7 @@
|
||||
#define FUSE_KERNEL_VERSION 7
|
||||
|
||||
/** Minor version number of this interface */
|
||||
#define FUSE_KERNEL_MINOR_VERSION 19
|
||||
#define FUSE_KERNEL_MINOR_VERSION 20
|
||||
|
||||
/** The node ID of the root inode */
|
||||
#define FUSE_ROOT_ID 1
|
||||
@ -163,10 +166,19 @@ struct fuse_file_lock {
|
||||
/**
|
||||
* INIT request/reply flags
|
||||
*
|
||||
* FUSE_ASYNC_READ: asynchronous read requests
|
||||
* FUSE_POSIX_LOCKS: remote locking for POSIX file locks
|
||||
* FUSE_FILE_OPS: kernel sends file handle for fstat, etc... (not yet supported)
|
||||
* FUSE_ATOMIC_O_TRUNC: handles the O_TRUNC open flag in the filesystem
|
||||
* FUSE_EXPORT_SUPPORT: filesystem handles lookups of "." and ".."
|
||||
* FUSE_BIG_WRITES: filesystem can handle write size larger than 4kB
|
||||
* FUSE_DONT_MASK: don't apply umask to file mode on create operations
|
||||
* FUSE_SPLICE_WRITE: kernel supports splice write on the device
|
||||
* FUSE_SPLICE_MOVE: kernel supports splice move on the device
|
||||
* FUSE_SPLICE_READ: kernel supports splice read on the device
|
||||
* FUSE_FLOCK_LOCKS: remote locking for BSD style file locks
|
||||
* FUSE_HAS_IOCTL_DIR: kernel supports ioctl on directories
|
||||
* FUSE_AUTO_INVAL_DATA: automatically invalidate cached pages
|
||||
*/
|
||||
#define FUSE_ASYNC_READ (1 << 0)
|
||||
#define FUSE_POSIX_LOCKS (1 << 1)
|
||||
@ -175,7 +187,12 @@ struct fuse_file_lock {
|
||||
#define FUSE_EXPORT_SUPPORT (1 << 4)
|
||||
#define FUSE_BIG_WRITES (1 << 5)
|
||||
#define FUSE_DONT_MASK (1 << 6)
|
||||
#define FUSE_SPLICE_WRITE (1 << 7)
|
||||
#define FUSE_SPLICE_MOVE (1 << 8)
|
||||
#define FUSE_SPLICE_READ (1 << 9)
|
||||
#define FUSE_FLOCK_LOCKS (1 << 10)
|
||||
#define FUSE_HAS_IOCTL_DIR (1 << 11)
|
||||
#define FUSE_AUTO_INVAL_DATA (1 << 12)
|
||||
|
||||
/**
|
||||
* CUSE INIT request/reply flags
|
||||
|
Loading…
Reference in New Issue
Block a user