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

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse

Pull fuse update from Miklos Szeredi:
"This contains a fix for a potential use-after-module-unload bug
noticed by Al and caching improvements for read-only fuse filesystems
by Andrew Gallagher"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse:
fuse: support clients that don't implement 'open'
fuse: don't invalidate attrs when not using atime
fuse: fix SetPageUptodate() condition in STORE
fuse: fix pipe_buf_operations

+74 -63
+7 -18
fs/fuse/dev.c
··· 1296 1296 return fuse_dev_do_read(fc, file, &cs, iov_length(iov, nr_segs)); 1297 1297 } 1298 1298 1299 - static int fuse_dev_pipe_buf_steal(struct pipe_inode_info *pipe, 1300 - struct pipe_buffer *buf) 1301 - { 1302 - return 1; 1303 - } 1304 - 1305 - static const struct pipe_buf_operations fuse_dev_pipe_buf_ops = { 1306 - .can_merge = 0, 1307 - .map = generic_pipe_buf_map, 1308 - .unmap = generic_pipe_buf_unmap, 1309 - .confirm = generic_pipe_buf_confirm, 1310 - .release = generic_pipe_buf_release, 1311 - .steal = fuse_dev_pipe_buf_steal, 1312 - .get = generic_pipe_buf_get, 1313 - }; 1314 - 1315 1299 static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos, 1316 1300 struct pipe_inode_info *pipe, 1317 1301 size_t len, unsigned int flags) ··· 1342 1358 buf->page = bufs[page_nr].page; 1343 1359 buf->offset = bufs[page_nr].offset; 1344 1360 buf->len = bufs[page_nr].len; 1345 - buf->ops = &fuse_dev_pipe_buf_ops; 1361 + /* 1362 + * Need to be careful about this. Having buf->ops in module 1363 + * code can Oops if the buffer persists after module unload. 1364 + */ 1365 + buf->ops = &nosteal_pipe_buf_ops; 1346 1366 1347 1367 pipe->nrbufs++; 1348 1368 page_nr++; ··· 1587 1599 1588 1600 this_num = min_t(unsigned, num, PAGE_CACHE_SIZE - offset); 1589 1601 err = fuse_copy_page(cs, &page, offset, this_num, 0); 1590 - if (!err && offset == 0 && (num != 0 || file_size == end)) 1602 + if (!err && offset == 0 && 1603 + (this_num == PAGE_CACHE_SIZE || file_size == end)) 1591 1604 SetPageUptodate(page); 1592 1605 unlock_page(page); 1593 1606 page_cache_release(page);
+12 -2
fs/fuse/dir.c
··· 112 112 get_fuse_inode(inode)->i_time = 0; 113 113 } 114 114 115 + /** 116 + * Mark the attributes as stale due to an atime change. Avoid the invalidate if 117 + * atime is not used. 118 + */ 119 + void fuse_invalidate_atime(struct inode *inode) 120 + { 121 + if (!IS_RDONLY(inode)) 122 + fuse_invalidate_attr(inode); 123 + } 124 + 115 125 /* 116 126 * Just mark the entry as stale, so that a next attempt to look it up 117 127 * will result in a new lookup call to userspace ··· 1381 1371 } 1382 1372 1383 1373 __free_page(page); 1384 - fuse_invalidate_attr(inode); /* atime changed */ 1374 + fuse_invalidate_atime(inode); 1385 1375 return err; 1386 1376 } 1387 1377 ··· 1414 1404 link[req->out.args[0].size] = '\0'; 1415 1405 out: 1416 1406 fuse_put_request(fc, req); 1417 - fuse_invalidate_attr(inode); /* atime changed */ 1407 + fuse_invalidate_atime(inode); 1418 1408 return link; 1419 1409 } 1420 1410
+29 -12
fs/fuse/file.c
··· 127 127 if (atomic_dec_and_test(&ff->count)) { 128 128 struct fuse_req *req = ff->reserved_req; 129 129 130 - if (sync) { 130 + if (ff->fc->no_open) { 131 + /* 132 + * Drop the release request when client does not 133 + * implement 'open' 134 + */ 135 + req->background = 0; 136 + path_put(&req->misc.release.path); 137 + fuse_put_request(ff->fc, req); 138 + } else if (sync) { 131 139 req->background = 0; 132 140 fuse_request_send(ff->fc, req); 133 141 path_put(&req->misc.release.path); ··· 152 144 int fuse_do_open(struct fuse_conn *fc, u64 nodeid, struct file *file, 153 145 bool isdir) 154 146 { 155 - struct fuse_open_out outarg; 156 147 struct fuse_file *ff; 157 - int err; 158 148 int opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN; 159 149 160 150 ff = fuse_file_alloc(fc); 161 151 if (!ff) 162 152 return -ENOMEM; 163 153 164 - err = fuse_send_open(fc, nodeid, file, opcode, &outarg); 165 - if (err) { 166 - fuse_file_free(ff); 167 - return err; 154 + ff->fh = 0; 155 + ff->open_flags = FOPEN_KEEP_CACHE; /* Default for no-open */ 156 + if (!fc->no_open || isdir) { 157 + struct fuse_open_out outarg; 158 + int err; 159 + 160 + err = fuse_send_open(fc, nodeid, file, opcode, &outarg); 161 + if (!err) { 162 + ff->fh = outarg.fh; 163 + ff->open_flags = outarg.open_flags; 164 + 165 + } else if (err != -ENOSYS || isdir) { 166 + fuse_file_free(ff); 167 + return err; 168 + } else { 169 + fc->no_open = 1; 170 + } 168 171 } 169 172 170 173 if (isdir) 171 - outarg.open_flags &= ~FOPEN_DIRECT_IO; 174 + ff->open_flags &= ~FOPEN_DIRECT_IO; 172 175 173 - ff->fh = outarg.fh; 174 176 ff->nodeid = nodeid; 175 - ff->open_flags = outarg.open_flags; 176 177 file->private_data = fuse_file_get(ff); 177 178 178 179 return 0; ··· 704 687 SetPageUptodate(page); 705 688 } 706 689 707 - fuse_invalidate_attr(inode); /* atime changed */ 690 + fuse_invalidate_atime(inode); 708 691 out: 709 692 unlock_page(page); 710 693 return err; ··· 733 716 fuse_read_update_size(inode, pos, 734 717 req->misc.read.attr_ver); 735 718 } 736 - fuse_invalidate_attr(inode); /* atime changed */ 719 + fuse_invalidate_atime(inode); 737 720 } 738 721 739 722 for (i = 0; i < req->num_pages; i++) {
+5
fs/fuse/fuse_i.h
··· 485 485 * and hence races in setting them will not cause malfunction 486 486 */ 487 487 488 + /** Is open/release not implemented by fs? */ 489 + unsigned no_open:1; 490 + 488 491 /** Is fsync not implemented by fs? */ 489 492 unsigned no_fsync:1; 490 493 ··· 790 787 void fuse_invalidate_attr(struct inode *inode); 791 788 792 789 void fuse_invalidate_entry_cache(struct dentry *entry); 790 + 791 + void fuse_invalidate_atime(struct inode *inode); 793 792 794 793 /** 795 794 * Acquire reference to fuse_conn
+18
fs/splice.c
··· 555 555 .get = generic_pipe_buf_get, 556 556 }; 557 557 558 + static int generic_pipe_buf_nosteal(struct pipe_inode_info *pipe, 559 + struct pipe_buffer *buf) 560 + { 561 + return 1; 562 + } 563 + 564 + /* Pipe buffer operations for a socket and similar. */ 565 + const struct pipe_buf_operations nosteal_pipe_buf_ops = { 566 + .can_merge = 0, 567 + .map = generic_pipe_buf_map, 568 + .unmap = generic_pipe_buf_unmap, 569 + .confirm = generic_pipe_buf_confirm, 570 + .release = generic_pipe_buf_release, 571 + .steal = generic_pipe_buf_nosteal, 572 + .get = generic_pipe_buf_get, 573 + }; 574 + EXPORT_SYMBOL(nosteal_pipe_buf_ops); 575 + 558 576 static ssize_t kernel_readv(struct file *file, const struct iovec *vec, 559 577 unsigned long vlen, loff_t offset) 560 578 {
+2
include/linux/pipe_fs_i.h
··· 157 157 int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *); 158 158 void generic_pipe_buf_release(struct pipe_inode_info *, struct pipe_buffer *); 159 159 160 + extern const struct pipe_buf_operations nosteal_pipe_buf_ops; 161 + 160 162 /* for F_SETPIPE_SZ and F_GETPIPE_SZ */ 161 163 long pipe_fcntl(struct file *, unsigned int, unsigned long arg); 162 164 struct pipe_inode_info *get_pipe_info(struct file *file);
+1 -31
net/core/skbuff.c
··· 74 74 struct kmem_cache *skbuff_head_cache __read_mostly; 75 75 static struct kmem_cache *skbuff_fclone_cache __read_mostly; 76 76 77 - static void sock_pipe_buf_release(struct pipe_inode_info *pipe, 78 - struct pipe_buffer *buf) 79 - { 80 - put_page(buf->page); 81 - } 82 - 83 - static void sock_pipe_buf_get(struct pipe_inode_info *pipe, 84 - struct pipe_buffer *buf) 85 - { 86 - get_page(buf->page); 87 - } 88 - 89 - static int sock_pipe_buf_steal(struct pipe_inode_info *pipe, 90 - struct pipe_buffer *buf) 91 - { 92 - return 1; 93 - } 94 - 95 - 96 - /* Pipe buffer operations for a socket. */ 97 - static const struct pipe_buf_operations sock_pipe_buf_ops = { 98 - .can_merge = 0, 99 - .map = generic_pipe_buf_map, 100 - .unmap = generic_pipe_buf_unmap, 101 - .confirm = generic_pipe_buf_confirm, 102 - .release = sock_pipe_buf_release, 103 - .steal = sock_pipe_buf_steal, 104 - .get = sock_pipe_buf_get, 105 - }; 106 - 107 77 /** 108 78 * skb_panic - private function for out-of-line support 109 79 * @skb: buffer ··· 1800 1830 .partial = partial, 1801 1831 .nr_pages_max = MAX_SKB_FRAGS, 1802 1832 .flags = flags, 1803 - .ops = &sock_pipe_buf_ops, 1833 + .ops = &nosteal_pipe_buf_ops, 1804 1834 .spd_release = sock_spd_release, 1805 1835 }; 1806 1836 struct sk_buff *frag_iter;