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

Merge tag '9p-for-6.7-rc1' of https://github.com/martinetd/linux

Pull 9p updates from Dominique Martinet:
A bunch of small fixes:

- three W=1 warning fixes: the NULL -> "" replacement isn't trivial
but is serialized identically by the protocol layer and has been
tested

- one syzbot/KCSAN datarace annotation where we don't care about
users messing with the fd they passed to mount -t 9p

- removing a declaration without implementation

- yet another race fix for trans_fd around connection close: the
'err' field is also used in potentially racy calls and this isn't
complete, but it's better than what we had

- and finally a theorical memory leak fix on serialization failure"

* tag '9p-for-6.7-rc1' of https://github.com/martinetd/linux:
9p/net: fix possible memory leak in p9_check_errors()
9p/fs: add MODULE_DESCRIPTION
9p/net: xen: fix false positive printf format overflow warning
9p: v9fs_listxattr: fix %s null argument warning
9p/trans_fd: Annotate data-racy writes to file::f_flags
fs/9p: Remove unused function declaration v9fs_inode2stat()
9p/trans_fd: avoid sending req to a cancelled conn

+32 -19
+1
fs/9p/v9fs.c
··· 732 732 MODULE_AUTHOR("Latchesar Ionkov <lucho@ionkov.net>"); 733 733 MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>"); 734 734 MODULE_AUTHOR("Ron Minnich <rminnich@lanl.gov>"); 735 + MODULE_DESCRIPTION("9P Client File System"); 735 736 MODULE_LICENSE("GPL");
-1
fs/9p/v9fs_vfs.h
··· 52 52 unsigned int flags); 53 53 int v9fs_dir_release(struct inode *inode, struct file *filp); 54 54 int v9fs_file_open(struct inode *inode, struct file *file); 55 - void v9fs_inode2stat(struct inode *inode, struct p9_wstat *stat); 56 55 int v9fs_uflags2omode(int uflags, int extended); 57 56 58 57 void v9fs_blank_wstat(struct p9_wstat *wstat);
+3 -2
fs/9p/xattr.c
··· 68 68 struct p9_fid *fid; 69 69 int ret; 70 70 71 - p9_debug(P9_DEBUG_VFS, "name = %s value_len = %zu\n", 71 + p9_debug(P9_DEBUG_VFS, "name = '%s' value_len = %zu\n", 72 72 name, buffer_size); 73 73 fid = v9fs_fid_lookup(dentry); 74 74 if (IS_ERR(fid)) ··· 139 139 140 140 ssize_t v9fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) 141 141 { 142 - return v9fs_xattr_get(dentry, NULL, buffer, buffer_size); 142 + /* Txattrwalk with an empty string lists xattrs instead */ 143 + return v9fs_xattr_get(dentry, "", buffer, buffer_size); 143 144 } 144 145 145 146 static int v9fs_xattr_handler_get(const struct xattr_handler *handler,
+5 -3
net/9p/client.c
··· 540 540 return 0; 541 541 542 542 if (!p9_is_proto_dotl(c)) { 543 - char *ename; 543 + char *ename = NULL; 544 544 545 545 err = p9pdu_readf(&req->rc, c->proto_version, "s?d", 546 546 &ename, &ecode); 547 - if (err) 547 + if (err) { 548 + kfree(ename); 548 549 goto out_err; 550 + } 549 551 550 552 if (p9_is_proto_dotu(c) && ecode < 512) 551 553 err = -ecode; ··· 1981 1979 goto error; 1982 1980 } 1983 1981 p9_debug(P9_DEBUG_9P, 1984 - ">>> TXATTRWALK file_fid %d, attr_fid %d name %s\n", 1982 + ">>> TXATTRWALK file_fid %d, attr_fid %d name '%s'\n", 1985 1983 file_fid->fid, attr_fid->fid, attr_name); 1986 1984 1987 1985 req = p9_client_rpc(clnt, P9_TXATTRWALK, "dds",
+16 -5
net/9p/trans_fd.c
··· 671 671 672 672 p9_debug(P9_DEBUG_TRANS, "mux %p task %p tcall %p id %d\n", 673 673 m, current, &req->tc, req->tc.id); 674 - if (m->err < 0) 675 - return m->err; 676 674 677 675 spin_lock(&m->req_lock); 676 + 677 + if (m->err < 0) { 678 + spin_unlock(&m->req_lock); 679 + return m->err; 680 + } 681 + 678 682 WRITE_ONCE(req->status, REQ_STATUS_UNSENT); 679 683 list_add_tail(&req->req_list, &m->unsent_req_list); 680 684 spin_unlock(&m->req_lock); ··· 836 832 goto out_free_ts; 837 833 if (!(ts->rd->f_mode & FMODE_READ)) 838 834 goto out_put_rd; 839 - /* prevent workers from hanging on IO when fd is a pipe */ 840 - ts->rd->f_flags |= O_NONBLOCK; 835 + /* Prevent workers from hanging on IO when fd is a pipe. 836 + * It's technically possible for userspace or concurrent mounts to 837 + * modify this flag concurrently, which will likely result in a 838 + * broken filesystem. However, just having bad flags here should 839 + * not crash the kernel or cause any other sort of bug, so mark this 840 + * particular data race as intentional so that tooling (like KCSAN) 841 + * can allow it and detect further problems. 842 + */ 843 + data_race(ts->rd->f_flags |= O_NONBLOCK); 841 844 ts->wr = fget(wfd); 842 845 if (!ts->wr) 843 846 goto out_put_rd; 844 847 if (!(ts->wr->f_mode & FMODE_WRITE)) 845 848 goto out_put_wr; 846 - ts->wr->f_flags |= O_NONBLOCK; 849 + data_race(ts->wr->f_flags |= O_NONBLOCK); 847 850 848 851 client->trans = ts; 849 852 client->status = Connected;
+7 -8
net/9p/trans_xen.c
··· 54 54 char *tag; 55 55 struct p9_client *client; 56 56 57 - int num_rings; 58 57 struct xen_9pfs_dataring *rings; 59 58 }; 60 59 ··· 130 131 if (list_entry_is_head(priv, &xen_9pfs_devs, list)) 131 132 return -EINVAL; 132 133 133 - num = p9_req->tc.tag % priv->num_rings; 134 + num = p9_req->tc.tag % XEN_9PFS_NUM_RINGS; 134 135 ring = &priv->rings[num]; 135 136 136 137 again: ··· 278 279 list_del(&priv->list); 279 280 write_unlock(&xen_9pfs_lock); 280 281 281 - for (i = 0; i < priv->num_rings; i++) { 282 + for (i = 0; i < XEN_9PFS_NUM_RINGS; i++) { 282 283 struct xen_9pfs_dataring *ring = &priv->rings[i]; 283 284 284 285 cancel_work_sync(&ring->work); ··· 407 408 if (p9_xen_trans.maxsize > XEN_FLEX_RING_SIZE(max_ring_order)) 408 409 p9_xen_trans.maxsize = XEN_FLEX_RING_SIZE(max_ring_order) / 2; 409 410 410 - priv->num_rings = XEN_9PFS_NUM_RINGS; 411 - priv->rings = kcalloc(priv->num_rings, sizeof(*priv->rings), 411 + priv->rings = kcalloc(XEN_9PFS_NUM_RINGS, sizeof(*priv->rings), 412 412 GFP_KERNEL); 413 413 if (!priv->rings) { 414 414 kfree(priv); 415 415 return -ENOMEM; 416 416 } 417 417 418 - for (i = 0; i < priv->num_rings; i++) { 418 + for (i = 0; i < XEN_9PFS_NUM_RINGS; i++) { 419 419 priv->rings[i].priv = priv; 420 420 ret = xen_9pfs_front_alloc_dataring(dev, &priv->rings[i], 421 421 max_ring_order); ··· 432 434 if (ret) 433 435 goto error_xenbus; 434 436 ret = xenbus_printf(xbt, dev->nodename, "num-rings", "%u", 435 - priv->num_rings); 437 + XEN_9PFS_NUM_RINGS); 436 438 if (ret) 437 439 goto error_xenbus; 438 - for (i = 0; i < priv->num_rings; i++) { 440 + 441 + for (i = 0; i < XEN_9PFS_NUM_RINGS; i++) { 439 442 char str[16]; 440 443 441 444 BUILD_BUG_ON(XEN_9PFS_NUM_RINGS > 9);