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
703703 unsigned long nr_segs, loff_t pos)
704704 {
705705 struct inode *inode = iocb->ki_filp->f_mapping->host;
706+ struct fuse_conn *fc = get_fuse_conn(inode);
706707
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))) {
708715 int err;
709− /*
710− * If trying to read past EOF, make sure the i_size
711− * attribute is up-to-date.
712− */
713716 err = fuse_update_attributes(inode, NULL, iocb->ki_filp, NULL);
714717 if (err)
715718 return err;
@@ -1700,7 +1703,7 @@ static int fuse_verify_ioctl_iov(struct iovec *iov, size_t count) · 984 unmodified lines
17001703 size_t n;
17011704 u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT;
17021705
1703− for (n = 0; n < count; n++) {
1706+ for (n = 0; n < count; n++, iov++) {
17041707 if (iov->iov_len > (size_t) max)
17051708 return -ENOMEM;
17061709 max -= iov->iov_len;
fs/fuse/fuse_i.h+3−0
@@ -484,6 +484,9 @@ struct fuse_conn { · 483 unmodified lines
484484 /** Is fallocate not implemented by fs? */
485485 unsigned no_fallocate:1;
486486
487+ /** Use enhanced/automatic page cache invalidation. */
488+ unsigned auto_inval_data:1;
489+
487490 /** The number of requests waiting for completion */
488491 atomic_t num_waiting;
489492
fs/fuse/inode.c+28−4
@@ -197,6 +197,7 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, · 196 unmodified lines
197197 struct fuse_conn *fc = get_fuse_conn(inode);
198198 struct fuse_inode *fi = get_fuse_inode(inode);
199199 loff_t oldsize;
200+ struct timespec old_mtime;
200201
201202 spin_lock(&fc->lock);
202203 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
204205 return;
205206 }
206207
208+ old_mtime = inode->i_mtime;
207209 fuse_change_attributes_common(inode, attr, attr_valid);
208210
209211 oldsize = inode->i_size;
210212 i_size_write(inode, attr->size);
211213 spin_unlock(&fc->lock);
212214
213− if (S_ISREG(inode->i_mode) && oldsize != attr->size) {
214− truncate_pagecache(inode, oldsize, attr->size);
215− invalidate_inode_pages2(inode->i_mapping);
215+ if (S_ISREG(inode->i_mode)) {
216+ bool inval = false;
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);
216237 }
217238 }
218239
@@ -834,6 +855,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) · 615 unmodified lines
834855 fc->big_writes = 1;
835856 if (arg->flags & FUSE_DONT_MASK)
836857 fc->dont_mask = 1;
858+ if (arg->flags & FUSE_AUTO_INVAL_DATA)
859+ fc->auto_inval_data = 1;
837860 } else {
838861 ra_pages = fc->max_read / PAGE_CACHE_SIZE;
839862 fc->no_lock = 1;
@@ -859,7 +882,8 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req) · 19 unmodified lines
859882 arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE;
860883 arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC |
861884 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;
863887 req->in.h.opcode = FUSE_INIT;
864888 req->in.numargs = 1;
865889 req->in.args[0].size = sizeof(*arg);
include/linux/fuse.h+18−1
@@ -57,6 +57,9 @@ · 56 unmodified lines
5757 *
5858 * 7.19
5959 * - add FUSE_FALLOCATE
60+ *
61+ * 7.20
62+ * - add FUSE_AUTO_INVAL_DATA
6063 */
6164
6265 #ifndef _LINUX_FUSE_H
@@ -88,7 +91,7 @@ · 25 unmodified lines
8891 #define FUSE_KERNEL_VERSION 7
8992
9093 /** Minor version number of this interface */
91−#define FUSE_KERNEL_MINOR_VERSION 19
94+#define FUSE_KERNEL_MINOR_VERSION 20
9295
9396 /** The node ID of the root inode */
9497 #define FUSE_ROOT_ID 1
@@ -163,10 +166,19 @@ struct fuse_file_lock { · 68 unmodified lines
163166 /**
164167 * INIT request/reply flags
165168 *
169+ * FUSE_ASYNC_READ: asynchronous read requests
166170 * 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
167173 * FUSE_EXPORT_SUPPORT: filesystem handles lookups of "." and ".."
174+ * FUSE_BIG_WRITES: filesystem can handle write size larger than 4kB
168175 * 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
169179 * 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
170182 */
171183 #define FUSE_ASYNC_READ (1 << 0)
172184 #define FUSE_POSIX_LOCKS (1 << 1)
@@ -175,7 +187,12 @@ struct fuse_file_lock { · 2 unmodified lines
175187 #define FUSE_EXPORT_SUPPORT (1 << 4)
176188 #define FUSE_BIG_WRITES (1 << 5)
177189 #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)
178193 #define FUSE_FLOCK_LOCKS (1 << 10)
194+#define FUSE_HAS_IOCTL_DIR (1 << 11)
195+#define FUSE_AUTO_INVAL_DATA (1 << 12)
179196
180197 /**
181198 * 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