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 tag 'fuse-update-5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse

Pull fuse updates from Miklos Szeredi:

- Fix a page locking bug in write (introduced in 2.6.26)

- Allow sgid bit to be killed in setacl()

- Miscellaneous fixes and cleanups

* tag 'fuse-update-5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse:
cuse: simplify refcount
cuse: prevent clone
virtiofs: fix userns
virtiofs: remove useless function
virtiofs: split requests that exceed virtqueue size
virtiofs: fix memory leak in virtio_fs_probe()
fuse: invalidate attrs when page writeback completes
fuse: add a flag FUSE_SETXATTR_ACL_KILL_SGID to kill SGID
fuse: extend FUSE_SETXATTR request
fuse: fix matching of FUSE_DEV_IOC_CLONE command
fuse: fix a typo
fuse: don't zero pages twice
fuse: fix typo for fuse_conn.max_pages comment
fuse: fix write deadlock

+111 -57
+6 -1
fs/fuse/acl.c
··· 71 71 return -EINVAL; 72 72 73 73 if (acl) { 74 + unsigned int extra_flags = 0; 74 75 /* 75 76 * Fuse userspace is responsible for updating access 76 77 * permissions in the inode, if needed. fuse_setxattr ··· 95 94 return ret; 96 95 } 97 96 98 - ret = fuse_setxattr(inode, name, value, size, 0); 97 + if (!in_group_p(i_gid_into_mnt(&init_user_ns, inode)) && 98 + !capable_wrt_inode_uidgid(&init_user_ns, inode, CAP_FSETID)) 99 + extra_flags |= FUSE_SETXATTR_ACL_KILL_SGID; 100 + 101 + ret = fuse_setxattr(inode, name, value, size, 0, extra_flags); 99 102 kfree(value); 100 103 } else { 101 104 ret = fuse_removexattr(inode, name);
+5 -7
fs/fuse/cuse.c
··· 511 511 fuse_conn_init(&cc->fc, &cc->fm, file->f_cred->user_ns, 512 512 &fuse_dev_fiq_ops, NULL); 513 513 514 + cc->fc.release = cuse_fc_release; 514 515 fud = fuse_dev_alloc_install(&cc->fc); 515 - if (!fud) { 516 - kfree(cc); 516 + fuse_conn_put(&cc->fc); 517 + if (!fud) 517 518 return -ENOMEM; 518 - } 519 519 520 520 INIT_LIST_HEAD(&cc->list); 521 - cc->fc.release = cuse_fc_release; 522 521 523 522 cc->fc.initialized = 1; 524 523 rc = cuse_send_init(cc); 525 524 if (rc) { 526 525 fuse_dev_free(fud); 527 - fuse_conn_put(&cc->fc); 528 526 return rc; 529 527 } 530 528 file->private_data = fud; ··· 559 561 unregister_chrdev_region(cc->cdev->dev, 1); 560 562 cdev_del(cc->cdev); 561 563 } 562 - /* Base reference is now owned by "fud" */ 563 - fuse_conn_put(&cc->fc); 564 564 565 565 rc = fuse_dev_release(inode, file); /* puts the base reference */ 566 566 ··· 623 627 cuse_channel_fops.owner = THIS_MODULE; 624 628 cuse_channel_fops.open = cuse_channel_open; 625 629 cuse_channel_fops.release = cuse_channel_release; 630 + /* CUSE is not prepared for FUSE_DEV_IOC_CLONE */ 631 + cuse_channel_fops.unlocked_ioctl = NULL; 626 632 627 633 cuse_class = class_create(THIS_MODULE, "cuse"); 628 634 if (IS_ERR(cuse_class))
+2 -5
fs/fuse/dev.c
··· 2233 2233 int oldfd; 2234 2234 struct fuse_dev *fud = NULL; 2235 2235 2236 - if (_IOC_TYPE(cmd) != FUSE_DEV_IOC_MAGIC) 2237 - return -ENOTTY; 2238 - 2239 - switch (_IOC_NR(cmd)) { 2240 - case _IOC_NR(FUSE_DEV_IOC_CLONE): 2236 + switch (cmd) { 2237 + case FUSE_DEV_IOC_CLONE: 2241 2238 res = -EFAULT; 2242 2239 if (!get_user(oldfd, (__u32 __user *)arg)) { 2243 2240 struct file *old = fget(oldfd);
+44 -27
fs/fuse/file.c
··· 802 802 { 803 803 struct fuse_conn *fc = get_fuse_conn(inode); 804 804 805 - if (fc->writeback_cache) { 806 - /* 807 - * A hole in a file. Some data after the hole are in page cache, 808 - * but have not reached the client fs yet. So, the hole is not 809 - * present there. 810 - */ 811 - int i; 812 - int start_idx = num_read >> PAGE_SHIFT; 813 - size_t off = num_read & (PAGE_SIZE - 1); 814 - 815 - for (i = start_idx; i < ap->num_pages; i++) { 816 - zero_user_segment(ap->pages[i], off, PAGE_SIZE); 817 - off = 0; 818 - } 819 - } else { 805 + /* 806 + * If writeback_cache is enabled, a short read means there's a hole in 807 + * the file. Some data after the hole is in page cache, but has not 808 + * reached the client fs yet. So the hole is not present there. 809 + */ 810 + if (!fc->writeback_cache) { 820 811 loff_t pos = page_offset(ap->pages[0]) + num_read; 821 812 fuse_read_update_size(inode, pos, attr_ver); 822 813 } ··· 1094 1103 struct fuse_file *ff = file->private_data; 1095 1104 struct fuse_mount *fm = ff->fm; 1096 1105 unsigned int offset, i; 1106 + bool short_write; 1097 1107 int err; 1098 1108 1099 1109 for (i = 0; i < ap->num_pages; i++) ··· 1109 1117 if (!err && ia->write.out.size > count) 1110 1118 err = -EIO; 1111 1119 1120 + short_write = ia->write.out.size < count; 1112 1121 offset = ap->descs[0].offset; 1113 1122 count = ia->write.out.size; 1114 1123 for (i = 0; i < ap->num_pages; i++) { 1115 1124 struct page *page = ap->pages[i]; 1116 1125 1117 - if (!err && !offset && count >= PAGE_SIZE) 1118 - SetPageUptodate(page); 1119 - 1120 - if (count > PAGE_SIZE - offset) 1121 - count -= PAGE_SIZE - offset; 1122 - else 1123 - count = 0; 1124 - offset = 0; 1125 - 1126 - unlock_page(page); 1126 + if (err) { 1127 + ClearPageUptodate(page); 1128 + } else { 1129 + if (count >= PAGE_SIZE - offset) 1130 + count -= PAGE_SIZE - offset; 1131 + else { 1132 + if (short_write) 1133 + ClearPageUptodate(page); 1134 + count = 0; 1135 + } 1136 + offset = 0; 1137 + } 1138 + if (ia->write.page_locked && (i == ap->num_pages - 1)) 1139 + unlock_page(page); 1127 1140 put_page(page); 1128 1141 } 1129 1142 1130 1143 return err; 1131 1144 } 1132 1145 1133 - static ssize_t fuse_fill_write_pages(struct fuse_args_pages *ap, 1146 + static ssize_t fuse_fill_write_pages(struct fuse_io_args *ia, 1134 1147 struct address_space *mapping, 1135 1148 struct iov_iter *ii, loff_t pos, 1136 1149 unsigned int max_pages) 1137 1150 { 1151 + struct fuse_args_pages *ap = &ia->ap; 1138 1152 struct fuse_conn *fc = get_fuse_conn(mapping->host); 1139 1153 unsigned offset = pos & (PAGE_SIZE - 1); 1140 1154 size_t count = 0; ··· 1193 1195 if (offset == PAGE_SIZE) 1194 1196 offset = 0; 1195 1197 1198 + /* If we copied full page, mark it uptodate */ 1199 + if (tmp == PAGE_SIZE) 1200 + SetPageUptodate(page); 1201 + 1202 + if (PageUptodate(page)) { 1203 + unlock_page(page); 1204 + } else { 1205 + ia->write.page_locked = true; 1206 + break; 1207 + } 1196 1208 if (!fc->big_writes) 1197 1209 break; 1198 1210 } while (iov_iter_count(ii) && count < fc->max_write && ··· 1246 1238 break; 1247 1239 } 1248 1240 1249 - count = fuse_fill_write_pages(ap, mapping, ii, pos, nr_pages); 1241 + count = fuse_fill_write_pages(&ia, mapping, ii, pos, nr_pages); 1250 1242 if (count <= 0) { 1251 1243 err = count; 1252 1244 } else { ··· 1761 1753 container_of(args, typeof(*wpa), ia.ap.args); 1762 1754 struct inode *inode = wpa->inode; 1763 1755 struct fuse_inode *fi = get_fuse_inode(inode); 1756 + struct fuse_conn *fc = get_fuse_conn(inode); 1764 1757 1765 1758 mapping_set_error(inode->i_mapping, error); 1759 + /* 1760 + * A writeback finished and this might have updated mtime/ctime on 1761 + * server making local mtime/ctime stale. Hence invalidate attrs. 1762 + * Do this only if writeback_cache is not enabled. If writeback_cache 1763 + * is enabled, we trust local ctime/mtime. 1764 + */ 1765 + if (!fc->writeback_cache) 1766 + fuse_invalidate_attr(inode); 1766 1767 spin_lock(&fi->lock); 1767 1768 rb_erase(&wpa->writepages_entry, &fi->writepages); 1768 1769 while (wpa->next) {
+10 -3
fs/fuse/fuse_i.h
··· 552 552 /** Maximum write size */ 553 553 unsigned max_write; 554 554 555 - /** Maxmum number of pages that can be used in a single request */ 555 + /** Maximum number of pages that can be used in a single request */ 556 556 unsigned int max_pages; 557 + 558 + /** Constrain ->max_pages to this value during feature negotiation */ 559 + unsigned int max_pages_limit; 557 560 558 561 /** Input queue */ 559 562 struct fuse_iqueue iq; ··· 671 668 /** Is setxattr not implemented by fs? */ 672 669 unsigned no_setxattr:1; 673 670 671 + /** Does file server support extended setxattr */ 672 + unsigned setxattr_ext:1; 673 + 674 674 /** Is getxattr not implemented by fs? */ 675 675 unsigned no_getxattr:1; 676 676 ··· 719 713 /** Use enhanced/automatic page cache invalidation. */ 720 714 unsigned auto_inval_data:1; 721 715 722 - /** Filesystem is fully reponsible for page cache invalidation. */ 716 + /** Filesystem is fully responsible for page cache invalidation. */ 723 717 unsigned explicit_inval_data:1; 724 718 725 719 /** Does the filesystem support readdirplus? */ ··· 940 934 struct { 941 935 struct fuse_write_in in; 942 936 struct fuse_write_out out; 937 + bool page_locked; 943 938 } write; 944 939 }; 945 940 struct fuse_args_pages ap; ··· 1200 1193 bool fuse_lock_inode(struct inode *inode); 1201 1194 1202 1195 int fuse_setxattr(struct inode *inode, const char *name, const void *value, 1203 - size_t size, int flags); 1196 + size_t size, int flags, unsigned int extra_flags); 1204 1197 ssize_t fuse_getxattr(struct inode *inode, const char *name, void *value, 1205 1198 size_t size); 1206 1199 ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size);
+5 -2
fs/fuse/inode.c
··· 712 712 fc->pid_ns = get_pid_ns(task_active_pid_ns(current)); 713 713 fc->user_ns = get_user_ns(user_ns); 714 714 fc->max_pages = FUSE_DEFAULT_MAX_PAGES_PER_REQ; 715 + fc->max_pages_limit = FUSE_MAX_MAX_PAGES; 715 716 716 717 INIT_LIST_HEAD(&fc->mounts); 717 718 list_add(&fm->fc_entry, &fc->mounts); ··· 1041 1040 fc->abort_err = 1; 1042 1041 if (arg->flags & FUSE_MAX_PAGES) { 1043 1042 fc->max_pages = 1044 - min_t(unsigned int, FUSE_MAX_MAX_PAGES, 1043 + min_t(unsigned int, fc->max_pages_limit, 1045 1044 max_t(unsigned int, arg->max_pages, 1)); 1046 1045 } 1047 1046 if (IS_ENABLED(CONFIG_FUSE_DAX) && ··· 1053 1052 fc->handle_killpriv_v2 = 1; 1054 1053 fm->sb->s_flags |= SB_NOSEC; 1055 1054 } 1055 + if (arg->flags & FUSE_SETXATTR_EXT) 1056 + fc->setxattr_ext = 1; 1056 1057 } else { 1057 1058 ra_pages = fc->max_read / PAGE_SIZE; 1058 1059 fc->no_lock = 1; ··· 1098 1095 FUSE_PARALLEL_DIROPS | FUSE_HANDLE_KILLPRIV | FUSE_POSIX_ACL | 1099 1096 FUSE_ABORT_ERROR | FUSE_MAX_PAGES | FUSE_CACHE_SYMLINKS | 1100 1097 FUSE_NO_OPENDIR_SUPPORT | FUSE_EXPLICIT_INVAL_DATA | 1101 - FUSE_HANDLE_KILLPRIV_V2; 1098 + FUSE_HANDLE_KILLPRIV_V2 | FUSE_SETXATTR_EXT; 1102 1099 #ifdef CONFIG_FUSE_DAX 1103 1100 if (fm->fc->dax) 1104 1101 ia->in.flags |= FUSE_MAP_ALIGNMENT;
+19 -9
fs/fuse/virtio_fs.c
··· 18 18 #include <linux/uio.h> 19 19 #include "fuse_i.h" 20 20 21 + /* Used to help calculate the FUSE connection's max_pages limit for a request's 22 + * size. Parts of the struct fuse_req are sliced into scattergather lists in 23 + * addition to the pages used, so this can help account for that overhead. 24 + */ 25 + #define FUSE_HEADER_OVERHEAD 4 26 + 21 27 /* List of virtio-fs device instances and a lock for the list. Also provides 22 28 * mutual exclusion in device removal and mounting path 23 29 */ ··· 131 125 struct virtio_fs *fs = vq->vdev->priv; 132 126 133 127 return &fs->vqs[vq->index]; 134 - } 135 - 136 - static inline struct fuse_pqueue *vq_to_fpq(struct virtqueue *vq) 137 - { 138 - return &vq_to_fsvq(vq)->fud->pq; 139 128 } 140 129 141 130 /* Should be called with fsvq->lock held. */ ··· 897 896 out_vqs: 898 897 vdev->config->reset(vdev); 899 898 virtio_fs_cleanup_vqs(vdev, fs); 899 + kfree(fs->vqs); 900 900 901 901 out: 902 902 vdev->priv = NULL; ··· 1415 1413 { 1416 1414 struct virtio_fs *fs; 1417 1415 struct super_block *sb; 1418 - struct fuse_conn *fc; 1416 + struct fuse_conn *fc = NULL; 1419 1417 struct fuse_mount *fm; 1420 - int err; 1418 + unsigned int virtqueue_size; 1419 + int err = -EIO; 1421 1420 1422 1421 /* This gets a reference on virtio_fs object. This ptr gets installed 1423 1422 * in fc->iq->priv. Once fuse_conn is going away, it calls ->put() ··· 1430 1427 return -EINVAL; 1431 1428 } 1432 1429 1430 + virtqueue_size = virtqueue_get_vring_size(fs->vqs[VQ_REQUEST].vq); 1431 + if (WARN_ON(virtqueue_size <= FUSE_HEADER_OVERHEAD)) 1432 + goto out_err; 1433 + 1433 1434 err = -ENOMEM; 1434 1435 fc = kzalloc(sizeof(struct fuse_conn), GFP_KERNEL); 1435 1436 if (!fc) ··· 1443 1436 if (!fm) 1444 1437 goto out_err; 1445 1438 1446 - fuse_conn_init(fc, fm, get_user_ns(current_user_ns()), 1447 - &virtio_fs_fiq_ops, fs); 1439 + fuse_conn_init(fc, fm, fsc->user_ns, &virtio_fs_fiq_ops, fs); 1448 1440 fc->release = fuse_free_conn; 1449 1441 fc->delete_stale = true; 1450 1442 fc->auto_submounts = true; 1443 + 1444 + /* Tell FUSE to split requests that exceed the virtqueue's size */ 1445 + fc->max_pages_limit = min_t(unsigned int, fc->max_pages_limit, 1446 + virtqueue_size - FUSE_HEADER_OVERHEAD); 1451 1447 1452 1448 fsc->s_fs_info = fm; 1453 1449 sb = sget_fc(fsc, virtio_fs_test_super, set_anon_super_fc);
+6 -3
fs/fuse/xattr.c
··· 12 12 #include <linux/posix_acl_xattr.h> 13 13 14 14 int fuse_setxattr(struct inode *inode, const char *name, const void *value, 15 - size_t size, int flags) 15 + size_t size, int flags, unsigned int extra_flags) 16 16 { 17 17 struct fuse_mount *fm = get_fuse_mount(inode); 18 18 FUSE_ARGS(args); ··· 25 25 memset(&inarg, 0, sizeof(inarg)); 26 26 inarg.size = size; 27 27 inarg.flags = flags; 28 + inarg.setxattr_flags = extra_flags; 29 + 28 30 args.opcode = FUSE_SETXATTR; 29 31 args.nodeid = get_node_id(inode); 30 32 args.in_numargs = 3; 31 - args.in_args[0].size = sizeof(inarg); 33 + args.in_args[0].size = fm->fc->setxattr_ext ? 34 + sizeof(inarg) : FUSE_COMPAT_SETXATTR_IN_SIZE; 32 35 args.in_args[0].value = &inarg; 33 36 args.in_args[1].size = strlen(name) + 1; 34 37 args.in_args[1].value = name; ··· 202 199 if (!value) 203 200 return fuse_removexattr(inode, name); 204 201 205 - return fuse_setxattr(inode, name, value, size, flags); 202 + return fuse_setxattr(inode, name, value, size, flags, 0); 206 203 } 207 204 208 205 static bool no_xattr_list(struct dentry *dentry)
+14
include/uapi/linux/fuse.h
··· 179 179 * 7.33 180 180 * - add FUSE_HANDLE_KILLPRIV_V2, FUSE_WRITE_KILL_SUIDGID, FATTR_KILL_SUIDGID 181 181 * - add FUSE_OPEN_KILL_SUIDGID 182 + * - extend fuse_setxattr_in, add FUSE_SETXATTR_EXT 183 + * - add FUSE_SETXATTR_ACL_KILL_SGID 182 184 */ 183 185 184 186 #ifndef _LINUX_FUSE_H ··· 332 330 * does not have CAP_FSETID. Additionally upon 333 331 * write/truncate sgid is killed only if file has group 334 332 * execute permission. (Same as Linux VFS behavior). 333 + * FUSE_SETXATTR_EXT: Server supports extended struct fuse_setxattr_in 335 334 */ 336 335 #define FUSE_ASYNC_READ (1 << 0) 337 336 #define FUSE_POSIX_LOCKS (1 << 1) ··· 363 360 #define FUSE_MAP_ALIGNMENT (1 << 26) 364 361 #define FUSE_SUBMOUNTS (1 << 27) 365 362 #define FUSE_HANDLE_KILLPRIV_V2 (1 << 28) 363 + #define FUSE_SETXATTR_EXT (1 << 29) 366 364 367 365 /** 368 366 * CUSE INIT request/reply flags ··· 454 450 * FUSE_OPEN_KILL_SUIDGID: Kill suid and sgid if executable 455 451 */ 456 452 #define FUSE_OPEN_KILL_SUIDGID (1 << 0) 453 + 454 + /** 455 + * setxattr flags 456 + * FUSE_SETXATTR_ACL_KILL_SGID: Clear SGID when system.posix_acl_access is set 457 + */ 458 + #define FUSE_SETXATTR_ACL_KILL_SGID (1 << 0) 457 459 458 460 enum fuse_opcode { 459 461 FUSE_LOOKUP = 1, ··· 691 681 uint32_t padding; 692 682 }; 693 683 684 + #define FUSE_COMPAT_SETXATTR_IN_SIZE 8 685 + 694 686 struct fuse_setxattr_in { 695 687 uint32_t size; 696 688 uint32_t flags; 689 + uint32_t setxattr_flags; 690 + uint32_t padding; 697 691 }; 698 692 699 693 struct fuse_getxattr_in {