History

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

Linus Torvalds committed 14 years ago

Commit 2eac9eb2 parents ad54e46 fb6ccff4 files · +58 −11Browse files

Unified · Split

4 files
  1. fs/fuse/file.c +9 −6
  2. fs/fuse/fuse_i.h +3 −0
  3. fs/fuse/inode.c +28 −4
  4. include/linux/fuse.h +18 −1
fs/fuse/file.c+9−6
@@ -703,13 +703,16 @@ static ssize_t fuse_file_aio_read(struct kiocb *iocb, const struct iovec *iov, · 702 unmodified lines
703 unsigned long nr_segs, loff_t pos)703 unsigned long nr_segs, loff_t pos)
704{704{
705 struct inode *inode = iocb->ki_filp->f_mapping->host;705 struct inode *inode = iocb->ki_filp->f_mapping->host;
706 struct fuse_conn *fc = get_fuse_conn(inode);
706 707
707 if (pos + iov_length(iov, nr_segs) > i_size_read(inode)) {708 /*
709 * In auto invalidate mode, always update attributes on read.
710 * Otherwise, only update if we attempt to read past EOF (to ensure
711 * i_size is up to date).
712 */
713 if (fc->auto_inval_data ||
714 (pos + iov_length(iov, nr_segs) > i_size_read(inode))) {
708 int err;715 int err;
709 /*
710 * If trying to read past EOF, make sure the i_size
711 * attribute is up-to-date.
712 */
713 err = fuse_update_attributes(inode, NULL, iocb->ki_filp, NULL);716 err = fuse_update_attributes(inode, NULL, iocb->ki_filp, NULL);
714 if (err)717 if (err)
715 return err;718 return err;
@@ -1700,7 +1703,7 @@ static int fuse_verify_ioctl_iov(struct iovec *iov, size_t count) · 984 unmodified lines
1700 size_t n;1703 size_t n;
1701 u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT;1704 u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT;
1702 1705
1703 for (n = 0; n < count; n++) {1706 for (n = 0; n < count; n++, iov++) {
1704 if (iov->iov_len > (size_t) max)1707 if (iov->iov_len > (size_t) max)
1705 return -ENOMEM;1708 return -ENOMEM;
1706 max -= iov->iov_len;1709 max -= iov->iov_len;
fs/fuse/fuse_i.h+3−0
@@ -484,6 +484,9 @@ struct fuse_conn { · 483 unmodified lines
484 /** Is fallocate not implemented by fs? */484 /** Is fallocate not implemented by fs? */
485 unsigned no_fallocate:1;485 unsigned no_fallocate:1;
486 486
487 /** Use enhanced/automatic page cache invalidation. */
488 unsigned auto_inval_data:1;
489
487 /** The number of requests waiting for completion */490 /** The number of requests waiting for completion */
488 atomic_t num_waiting;491 atomic_t num_waiting;
489 492
fs/fuse/inode.c+28−4
@@ -197,6 +197,7 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, · 196 unmodified lines
197 struct fuse_conn *fc = get_fuse_conn(inode);197 struct fuse_conn *fc = get_fuse_conn(inode);
198 struct fuse_inode *fi = get_fuse_inode(inode);198 struct fuse_inode *fi = get_fuse_inode(inode);
199 loff_t oldsize;199 loff_t oldsize;
200 struct timespec old_mtime;
200 201
201 spin_lock(&fc->lock);202 spin_lock(&fc->lock);
202 if (attr_version != 0 && fi->attr_version > attr_version) {203 if (attr_version != 0 && fi->attr_version > attr_version) {
@@ -204,15 +205,35 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, · 1 unmodified line
204 return;205 return;
205 }206 }
206 207
208 old_mtime = inode->i_mtime;
207 fuse_change_attributes_common(inode, attr, attr_valid);209 fuse_change_attributes_common(inode, attr, attr_valid);
208 210
209 oldsize = inode->i_size;211 oldsize = inode->i_size;
210 i_size_write(inode, attr->size);212 i_size_write(inode, attr->size);
211 spin_unlock(&fc->lock);213 spin_unlock(&fc->lock);
212 214
213 if (S_ISREG(inode->i_mode) && oldsize != attr->size) {215 if (S_ISREG(inode->i_mode)) {
214 truncate_pagecache(inode, oldsize, attr->size);216 bool inval = false;
215 invalidate_inode_pages2(inode->i_mapping);217
218 if (oldsize != attr->size) {
219 truncate_pagecache(inode, oldsize, attr->size);
220 inval = true;
221 } else if (fc->auto_inval_data) {
222 struct timespec new_mtime = {
223 .tv_sec = attr->mtime,
224 .tv_nsec = attr->mtimensec,
225 };
226
227 /*
228 * Auto inval mode also checks and invalidates if mtime
229 * has changed.
230 */
231 if (!timespec_equal(&old_mtime, &new_mtime))
232 inval = true;
233 }
234
235 if (inval)
236 invalidate_inode_pages2(inode->i_mapping);
216 }237 }
217}238}
218 239
@@ -834,6 +855,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) · 615 unmodified lines
834 fc->big_writes = 1;855 fc->big_writes = 1;
835 if (arg->flags & FUSE_DONT_MASK)856 if (arg->flags & FUSE_DONT_MASK)
836 fc->dont_mask = 1;857 fc->dont_mask = 1;
858 if (arg->flags & FUSE_AUTO_INVAL_DATA)
859 fc->auto_inval_data = 1;
837 } else {860 } else {
838 ra_pages = fc->max_read / PAGE_CACHE_SIZE;861 ra_pages = fc->max_read / PAGE_CACHE_SIZE;
839 fc->no_lock = 1;862 fc->no_lock = 1;
@@ -859,7 +882,8 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req) · 19 unmodified lines
859 arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE;882 arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE;
860 arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC |883 arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC |
861 FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK |884 FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK |
862 FUSE_FLOCK_LOCKS;885 FUSE_SPLICE_WRITE | FUSE_SPLICE_MOVE | FUSE_SPLICE_READ |
886 FUSE_FLOCK_LOCKS | FUSE_IOCTL_DIR | FUSE_AUTO_INVAL_DATA;
863 req->in.h.opcode = FUSE_INIT;887 req->in.h.opcode = FUSE_INIT;
864 req->in.numargs = 1;888 req->in.numargs = 1;
865 req->in.args[0].size = sizeof(*arg);889 req->in.args[0].size = sizeof(*arg);
include/linux/fuse.h+18−1
@@ -57,6 +57,9 @@ · 56 unmodified lines
57 *57 *
58 * 7.1958 * 7.19
59 * - add FUSE_FALLOCATE59 * - add FUSE_FALLOCATE
60 *
61 * 7.20
62 * - add FUSE_AUTO_INVAL_DATA
60 */63 */
61 64
62#ifndef _LINUX_FUSE_H65#ifndef _LINUX_FUSE_H
@@ -88,7 +91,7 @@ · 25 unmodified lines
88#define FUSE_KERNEL_VERSION 791#define FUSE_KERNEL_VERSION 7
89 92
90/** Minor version number of this interface */93/** Minor version number of this interface */
91#define FUSE_KERNEL_MINOR_VERSION 1994#define FUSE_KERNEL_MINOR_VERSION 20
92 95
93/** The node ID of the root inode */96/** The node ID of the root inode */
94#define FUSE_ROOT_ID 197#define FUSE_ROOT_ID 1
@@ -163,10 +166,19 @@ struct fuse_file_lock { · 68 unmodified lines
163/**166/**
164 * INIT request/reply flags167 * INIT request/reply flags
165 *168 *
169 * FUSE_ASYNC_READ: asynchronous read requests
166 * FUSE_POSIX_LOCKS: remote locking for POSIX file locks170 * FUSE_POSIX_LOCKS: remote locking for POSIX file locks
171 * FUSE_FILE_OPS: kernel sends file handle for fstat, etc... (not yet supported)
172 * FUSE_ATOMIC_O_TRUNC: handles the O_TRUNC open flag in the filesystem
167 * FUSE_EXPORT_SUPPORT: filesystem handles lookups of "." and ".."173 * FUSE_EXPORT_SUPPORT: filesystem handles lookups of "." and ".."
174 * FUSE_BIG_WRITES: filesystem can handle write size larger than 4kB
168 * FUSE_DONT_MASK: don't apply umask to file mode on create operations175 * FUSE_DONT_MASK: don't apply umask to file mode on create operations
176 * FUSE_SPLICE_WRITE: kernel supports splice write on the device
177 * FUSE_SPLICE_MOVE: kernel supports splice move on the device
178 * FUSE_SPLICE_READ: kernel supports splice read on the device
169 * FUSE_FLOCK_LOCKS: remote locking for BSD style file locks179 * FUSE_FLOCK_LOCKS: remote locking for BSD style file locks
180 * FUSE_HAS_IOCTL_DIR: kernel supports ioctl on directories
181 * FUSE_AUTO_INVAL_DATA: automatically invalidate cached pages
170 */182 */
171#define FUSE_ASYNC_READ (1 << 0)183#define FUSE_ASYNC_READ (1 << 0)
172#define FUSE_POSIX_LOCKS (1 << 1)184#define FUSE_POSIX_LOCKS (1 << 1)
@@ -175,7 +187,12 @@ struct fuse_file_lock { · 2 unmodified lines
175#define FUSE_EXPORT_SUPPORT (1 << 4)187#define FUSE_EXPORT_SUPPORT (1 << 4)
176#define FUSE_BIG_WRITES (1 << 5)188#define FUSE_BIG_WRITES (1 << 5)
177#define FUSE_DONT_MASK (1 << 6)189#define FUSE_DONT_MASK (1 << 6)
190#define FUSE_SPLICE_WRITE (1 << 7)
191#define FUSE_SPLICE_MOVE (1 << 8)
192#define FUSE_SPLICE_READ (1 << 9)
178#define FUSE_FLOCK_LOCKS (1 << 10)193#define FUSE_FLOCK_LOCKS (1 << 10)
194#define FUSE_HAS_IOCTL_DIR (1 << 11)
195#define FUSE_AUTO_INVAL_DATA (1 << 12)
179 196
180/**197/**
181 * CUSE INIT request/reply flags198 * CUSE INIT request/reply flags

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t