Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

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