summaryrefslogtreecommitdiff
path: root/net/9p/client.c
AgeCommit message (Collapse)Author
2023-10-279p/net: fix possible memory leak in p9_check_errors()Hangyu Hua
When p9pdu_readf() is called with "s?d" attribute, it allocates a pointer that will store a string. But when p9pdu_readf() fails while handling "d" then this pointer will not be freed in p9_check_errors(). Fixes: 51a87c552dfd ("9p: rework client code to use new protocol support functions") Reviewed-by: Christian Schoenebeck <linux_oss@crudebyte.com> Signed-off-by: Hangyu Hua <hbh25y@gmail.com> Message-ID: <20231027030302.11927-1-hbh25y@gmail.com> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
2023-10-269p: v9fs_listxattr: fix %s null argument warningDominique Martinet
W=1 warns about null argument to kprintf: In file included from fs/9p/xattr.c:12: In function ‘v9fs_xattr_get’, inlined from ‘v9fs_listxattr’ at fs/9p/xattr.c:142:9: include/net/9p/9p.h:55:2: error: ‘%s’ directive argument is null [-Werror=format-overflow=] 55 | _p9_debug(level, __func__, fmt, ##__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Use an empty string instead of : - this is ok 9p-wise because p9pdu_vwritef serializes a null string and an empty string the same way (one '0' word for length) - since this degrades the print statements, add new single quotes for xattr's name delimter (Old: "file = (null)", new: "file = ''") Link: https://lore.kernel.org/r/20231008060138.517057-1-suhui@nfschina.com Suggested-by: Su Hui <suhui@nfschina.com> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org> Acked-by: Christian Schoenebeck <linux_oss@crudebyte.com> Message-ID: <20231025103445.1248103-2-asmadeus@codewreck.org>
2023-07-209p: remove dead stores (variable set again without being read)Dominique Martinet
The 9p code for some reason used to initialize variables outside of the declaration, e.g. instead of just initializing the variable like this: int retval = 0 We would be doing this: int retval; retval = 0; This is perfectly fine and the compiler will just optimize dead stores anyway, but scan-build seems to think this is a problem and there are many of these warnings making the output of scan-build full of such warnings: fs/9p/vfs_inode.c:916:2: warning: Value stored to 'retval' is never read [deadcode.DeadStores] retval = 0; ^ ~ I have no strong opinion here, but if we want to regularly run scan-build we should fix these just to silence the messages. I've confirmed these all are indeed ok to remove. Reviewed-by: Simon Horman <simon.horman@corigine.com> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org> Signed-off-by: Eric Van Hensbergen <ericvh@kernel.org>
2023-03-279p: Add additional debug flags and open modesEric Van Hensbergen
Add some additional debug flags to assist with debugging cache changes. Also add some additional open modes so we can track cache state in fids more directly. Signed-off-by: Eric Van Hensbergen <ericvh@kernel.org>
2023-02-24net/9p: fix bug in client create for .LEric Van Hensbergen
We are supposed to set fid->mode to reflect the flags that were used to open the file. We were actually setting it to the creation mode which is the default perms of the file not the flags the file was opened with. Signed-off-by: Eric Van Hensbergen <ericvh@kernel.org> Reviewed-by: Dominique Martinet <asmadeus@codewreck.org>
2023-02-23net/9p: Adjust maximum MSIZE to account for p9 headerEric Van Hensbergen
Add maximum p9 header size to MSIZE to make sure we can have page aligned data. Signed-off-by: Eric Van Hensbergen <ericvh@kernel.org> Reviewed-by: Dominique Martinet <asmadeus@codewreck.org>
2022-12-23Merge tag '9p-for-6.2-rc1' of https://github.com/martinetd/linuxLinus Torvalds
Pull 9p updates from Dominique Martinet: - improve p9_check_errors to check buffer size instead of msize when possible (e.g. not zero-copy) - some more syzbot and KCSAN fixes - minor headers include cleanup * tag '9p-for-6.2-rc1' of https://github.com/martinetd/linux: 9p/client: fix data race on req->status net/9p: fix response size check in p9_check_errors() net/9p: distinguish zero-copy requests 9p/xen: do not memcpy header into req->rc 9p: set req refcount to zero to avoid uninitialized usage 9p/net: Remove unneeded idr.h #include 9p/fs: Remove unneeded idr.h #include
2022-12-139p/client: fix data race on req->statusDominique Martinet
KCSAN reported a race between writing req->status in p9_client_cb and accessing it in p9_client_rpc's wait_event. Accesses to req itself is protected by the data barrier (writing req fields, write barrier, writing status // reading status, read barrier, reading other req fields), but status accesses themselves apparently also must be annotated properly with WRITE_ONCE/READ_ONCE when we access it without locks. Follows: - error paths writing status in various threads all can notify p9_client_rpc, so these all also need WRITE_ONCE - there's a similar read loop in trans_virtio for zc case that also needs READ_ONCE - other reads in trans_fd should be protected by the trans_fd lock and lists state machine, as corresponding writers all are within trans_fd and should be under the same lock. If KCSAN complains on them we likely will have something else to fix as well, so it's better to leave them unmarked and look again if required. Link: https://lkml.kernel.org/r/20221205124756.426350-1-asmadeus@codewreck.org Reported-by: Naresh Kamboju <naresh.kamboju@linaro.org> Suggested-by: Marco Elver <elver@google.com> Acked-by: Marco Elver <elver@google.com> Reviewed-by: Christian Schoenebeck <linux_oss@crudebyte.com> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
2022-12-06net/9p: fix response size check in p9_check_errors()Christian Schoenebeck
Since commit 60ece0833b6c ("net/9p: allocate appropriate reduced message buffers") it is no longer appropriate to check server's response size against msize. Check against the previously allocated buffer capacity instead. - Omit this size check entirely for zero-copy messages, as those always allocate 4k (P9_ZC_HDR_SZ) linear buffers which are not used for actual payload and can be much bigger than 4k. - Replace p9_debug() by pr_err() to make sure this message is always printed in case this error is triggered. - Add 9p message type to error message to ease investigation. Link: https://lkml.kernel.org/r/e0edec84b1c80119ae937ce854b4f5f6dbe2d08c.1669144861.git.linux_oss@crudebyte.com Signed-off-by: Christian Schoenebeck <linux_oss@crudebyte.com> Tested-by: Stefano Stabellini <sstabellini@kernel.org> Reported-by: kernel test robot <lkp@intel.com> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
2022-12-06net/9p: distinguish zero-copy requestsChristian Schoenebeck
Add boolean `zc` member to struct p9_fcall to distinguish zero-copy messages (not using the linear `sdata` buffer for message payload) from regular messages (which do copy message payload to `sdata` before being further processed). This new member is appended to end of structure to avoid inserting huge padding in generated layout. Link: https://lkml.kernel.org/r/8f2a5c12a446c3b544da64e0b1550e1fb2d6f972.1669144861.git.linux_oss@crudebyte.com Signed-off-by: Christian Schoenebeck <linux_oss@crudebyte.com> Tested-by: Stefano Stabellini <sstabellini@kernel.org> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
2022-12-029p: set req refcount to zero to avoid uninitialized usageSchspa Shi
When a new request is allocated, the refcount will be zero if it is reused, but if the request is newly allocated from slab, it is not fully initialized before being added to idr. If the p9_read_work got a response before the refcount initiated. It will use a uninitialized req, which will result in a bad request data struct. Here is the logs from syzbot. Corrupted memory at 0xffff88807eade00b [ 0xff 0x07 0x00 0x00 0x00 0x00 0x00 0x00 . . . . . . . . ] (in kfence-#110): p9_fcall_fini net/9p/client.c:248 [inline] p9_req_put net/9p/client.c:396 [inline] p9_req_put+0x208/0x250 net/9p/client.c:390 p9_client_walk+0x247/0x540 net/9p/client.c:1165 clone_fid fs/9p/fid.h:21 [inline] v9fs_fid_xattr_set+0xe4/0x2b0 fs/9p/xattr.c:118 v9fs_xattr_set fs/9p/xattr.c:100 [inline] v9fs_xattr_handler_set+0x6f/0x120 fs/9p/xattr.c:159 __vfs_setxattr+0x119/0x180 fs/xattr.c:182 __vfs_setxattr_noperm+0x129/0x5f0 fs/xattr.c:216 __vfs_setxattr_locked+0x1d3/0x260 fs/xattr.c:277 vfs_setxattr+0x143/0x340 fs/xattr.c:309 setxattr+0x146/0x160 fs/xattr.c:617 path_setxattr+0x197/0x1c0 fs/xattr.c:636 __do_sys_setxattr fs/xattr.c:652 [inline] __se_sys_setxattr fs/xattr.c:648 [inline] __ia32_sys_setxattr+0xc0/0x160 fs/xattr.c:648 do_syscall_32_irqs_on arch/x86/entry/common.c:112 [inline] __do_fast_syscall_32+0x65/0xf0 arch/x86/entry/common.c:178 do_fast_syscall_32+0x33/0x70 arch/x86/entry/common.c:203 entry_SYSENTER_compat_after_hwframe+0x70/0x82 Below is a similar scenario, the scenario in the syzbot log looks more complicated than this one, but this patch can fix it. T21124 p9_read_work ======================== second trans ================================= p9_client_walk p9_client_rpc p9_client_prepare_req p9_tag_alloc req = kmem_cache_alloc(p9_req_cache, GFP_NOFS); tag = idr_alloc << preempted >> req->tc.tag = tag; /* req->[refcount/tag] == uninitialized */ m->rreq = p9_tag_lookup(m->client, m->rc.tag); /* increments uninitalized refcount */ refcount_set(&req->refcount, 2); /* cb drops one ref */ p9_client_cb(req) /* reader thread drops its ref: request is incorrectly freed */ p9_req_put(req) /* use after free and ref underflow */ p9_req_put(req) To fix it, we can initialize the refcount to zero before add to idr. Link: https://lkml.kernel.org/r/20221201033310.18589-1-schspa@gmail.com Cc: stable@vger.kernel.org # 6.0+ due to 6cda12864cb0 ("9p: Drop kref usage") Fixes: 728356dedeff ("9p: Add refcount to p9_req_t") Reported-by: syzbot+8f1060e2aaf8ca55220b@syzkaller.appspotmail.com Signed-off-by: Schspa Shi <schspa@gmail.com> Reviewed-by: Christian Schoenebeck <linux_oss@crudebyte.com> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
2022-11-25use less confusing names for iov_iter direction initializersAl Viro
READ/WRITE proved to be actively confusing - the meanings are "data destination, as used with read(2)" and "data source, as used with write(2)", but people keep interpreting those as "we read data from it" and "we write data to it", i.e. exactly the wrong way. Call them ITER_DEST and ITER_SOURCE - at least that is harder to misinterpret... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2022-10-05net/9p: allocate appropriate reduced message buffersChristian Schoenebeck
So far 'msize' was simply used for all 9p message types, which is far too much and slowed down performance tremendously with large values for user configurable 'msize' option. Let's stop this waste by using the new p9_msg_buf_size() function for allocating more appropriate, smaller buffers according to what is actually sent over the wire. Only exception: RDMA transport is currently excluded from this message size optimization - for its response buffers that is - as RDMA transport would not cope with it, due to its response buffers being pulled from a shared pool. [1] Link: https://lore.kernel.org/all/Ys3jjg52EIyITPua@codewreck.org/ [1] Link: https://lkml.kernel.org/r/3f51590535dc96ed0a165b8218c57639cfa5c36c.1657920926.git.linux_oss@crudebyte.com Signed-off-by: Christian Schoenebeck <linux_oss@crudebyte.com> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
2022-10-05net/9p: split message size argument into 't_size' and 'r_size' pairChristian Schoenebeck
Refactor 'max_size' argument of p9_tag_alloc() and 'req_size' argument of p9_client_prepare_req() both into a pair of arguments 't_size' and 'r_size' respectively to allow handling the buffer size for request and reply separately from each other. Link: https://lkml.kernel.org/r/9431a25fe4b37fd12cecbd715c13af71f701f220.1657920926.git.linux_oss@crudebyte.com Signed-off-by: Christian Schoenebeck <linux_oss@crudebyte.com> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
2022-08-08Merge tag 'pull-work.iov_iter-rebased' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs Pull more iov_iter updates from Al Viro: - more new_sync_{read,write}() speedups - ITER_UBUF introduction - ITER_PIPE cleanups - unification of iov_iter_get_pages/iov_iter_get_pages_alloc and switching them to advancing semantics - making ITER_PIPE take high-order pages without splitting them - handling copy_page_from_iter() for high-order pages properly * tag 'pull-work.iov_iter-rebased' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (32 commits) fix copy_page_from_iter() for compound destinations hugetlbfs: copy_page_to_iter() can deal with compound pages copy_page_to_iter(): don't split high-order page in case of ITER_PIPE expand those iov_iter_advance()... pipe_get_pages(): switch to append_pipe() get rid of non-advancing variants ceph: switch the last caller of iov_iter_get_pages_alloc() 9p: convert to advancing variant of iov_iter_get_pages_alloc() af_alg_make_sg(): switch to advancing variant of iov_iter_get_pages() iter_to_pipe(): switch to advancing variant of iov_iter_get_pages() block: convert to advancing variants of iov_iter_get_pages{,_alloc}() iov_iter: advancing variants of iov_iter_get_pages{,_alloc}() iov_iter: saner helper for page array allocation fold __pipe_get_pages() into pipe_get_pages() ITER_XARRAY: don't open-code DIV_ROUND_UP() unify the rest of iov_iter_get_pages()/iov_iter_get_pages_alloc() guts unify xarray_get_pages() and xarray_get_pages_alloc() unify pipe_get_pages() and pipe_get_pages_alloc() iov_iter_get_pages(): sanity-check arguments iov_iter_get_pages_alloc(): lift freeing pages array on failure exits into wrapper ...
2022-08-089p: convert to advancing variant of iov_iter_get_pages_alloc()Al Viro
that one is somewhat clumsier than usual and needs serious testing. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2022-08-06Merge tag '9p-for-5.20' of https://github.com/martinetd/linuxLinus Torvalds
Pull 9p updates from Dominique Martinet: - a couple of fixes - add a tracepoint for fid refcounting - some cleanup/followup on fid lookup - some cleanup around req refcounting * tag '9p-for-5.20' of https://github.com/martinetd/linux: net/9p: Initialize the iounit field during fid creation net: 9p: fix refcount leak in p9_read_work() error handling 9p: roll p9_tag_remove into p9_req_put 9p: Add client parameter to p9_req_put() 9p: Drop kref usage 9p: Fix some kernel-doc comments 9p fid refcount: cleanup p9_fid_put calls 9p fid refcount: add a 9p_fid_ref tracepoint 9p fid refcount: add p9_fid_get/put wrappers 9p: Fix minor typo in code comment 9p: Remove unnecessary variable for old fids while walking from d_parent 9p: Make the path walk logic more clear about when cloning is required 9p: Track the root fid with its own variable during lookups
2022-07-16net/9p: Initialize the iounit field during fid creationTyler Hicks
Ensure that the fid's iounit field is set to zero when a new fid is created. Certain 9P operations, such as OPEN and CREATE, allow the server to reply with an iounit size which the client code assigns to the p9_fid struct shortly after the fid is created by p9_fid_create(). On the other hand, an XATTRWALK operation doesn't allow for the server to specify an iounit value. The iounit field of the newly allocated p9_fid struct remained uninitialized in that case. Depending on allocation patterns, the iounit value could have been something reasonable that was carried over from previously freed fids or, in the worst case, could have been arbitrary values from non-fid related usages of the memory location. The bug was detected in the Windows Subsystem for Linux 2 (WSL2) kernel after the uninitialized iounit field resulted in the typical sequence of two getxattr(2) syscalls, one to get the size of an xattr and another after allocating a sufficiently sized buffer to fit the xattr value, to hit an unexpected ERANGE error in the second call to getxattr(2). An uninitialized iounit field would sometimes force rsize to be smaller than the xattr value size in p9_client_read_once() and the 9P server in WSL refused to chunk up the READ on the attr_fid and, instead, returned ERANGE to the client. The virtfs server in QEMU seems happy to chunk up the READ and this problem goes undetected there. Link: https://lkml.kernel.org/r/20220710141402.803295-1-tyhicks@linux.microsoft.com Fixes: ebf46264a004 ("fs/9p: Add support user. xattr") Cc: stable@vger.kernel.org Signed-off-by: Tyler Hicks <tyhicks@linux.microsoft.com> Reviewed-by: Christian Schoenebeck <linux_oss@crudebyte.com> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
2022-07-159p: roll p9_tag_remove into p9_req_putDominique Martinet
mempool prep commit removed the awkward kref usage which didn't allow passing client pointer easily with the ref, so we no longer need a separate function to remove the tag from idr. This has the side benefit that it should be more robust in detecting leaks: umount will now properly catch unfreed requests as they still will be in the idr until the last ref is dropped Link: https://lkml.kernel.org/r/20220712060801.2487140-1-asmadeus@codewreck.org Signed-off-by: Dominique Martinet <asmadeus@codewreck.org> Reviewed-by: Christian Schoenebeck <linux_oss@crudebyte.com>
2022-07-099p: Add client parameter to p9_req_put()Kent Overstreet
This is to aid in adding mempools, in the next patch. Link: https://lkml.kernel.org/r/20220704014243.153050-2-kent.overstreet@gmail.com Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> Cc: Eric Van Hensbergen <ericvh@gmail.com> Cc: Latchesar Ionkov <lucho@ionkov.net> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
2022-07-099p: Drop kref usageKent Overstreet
An upcoming patch is going to require passing the client through p9_req_put() -> p9_req_free(), but that's awkward with the kref indirection - so this patch switches to using refcount_t directly. Link: https://lkml.kernel.org/r/20220704014243.153050-1-kent.overstreet@gmail.com Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> Cc: Eric Van Hensbergen <ericvh@gmail.com> Cc: Latchesar Ionkov <lucho@ionkov.net> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
2022-07-029p fid refcount: add a 9p_fid_ref tracepointDominique Martinet
This adds a tracepoint event for 9p fid lifecycle tracing: when a fid is created, its reference count increased/decreased, and freed. The new 9p_fid_ref tracepoint should help anyone wishing to debug any fid problem such as missing clunk (destroy) or use-after-free. Link: https://lkml.kernel.org/r/20220612085330.1451496-6-asmadeus@codewreck.org Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
2022-07-029p fid refcount: add p9_fid_get/put wrappersDominique Martinet
I was recently reminded that it is not clear that p9_client_clunk() was actually just decrementing refcount and clunking only when that reaches zero: make it clear through a set of helpers. This will also allow instrumenting refcounting better for debugging next patch Link: https://lkml.kernel.org/r/20220612085330.1451496-5-asmadeus@codewreck.org Reviewed-by: Tyler Hicks <tyhicks@linux.microsoft.com> Reviewed-by: Christian Schoenebeck <linux_oss@crudebyte.com> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
2022-06-099p: handling Rerror without copy_from_iter_full()Al Viro
p9_client_zc_rpc()/p9_check_zc_errors() are playing fast and loose with copy_from_iter_full(). Reading from file is done by sending Tread request. Response consists of fixed-sized header (including the amount of data actually read) followed by the data itself. For zero-copy case we arrange the things so that the first 11 bytes of reply go into the fixed-sized buffer, with the rest going straight into the pages we want to read into. What makes the things inconvenient is that sglist describing what should go where has to be set *before* the reply arrives. As the result, if reply is an error, the things get interesting. On success we get size[4] Rread tag[2] count[4] data[count] For error layout varies depending upon the protocol variant - in original 9P and 9P2000 it's size[4] Rerror tag[2] len[2] error[len] in 9P2000.U size[4] Rerror tag[2] len[2] error[len] errno[4] in 9P2000.L size[4] Rlerror tag[2] errno[4] The last case is nice and simple - we have an 11-byte response that fits into the fixed-sized buffer we hoped to get an Rread into. In other two, though, we get a variable-length string spill into the pages we'd prepared for the data to be read. Had that been in fixed-sized buffer (which is actually 4K), we would've dealt with that the same way we handle non-zerocopy case. However, for zerocopy it doesn't end up there, so we need to copy it from those pages. The trouble is, by the time we get around to that, the references to pages in question are already dropped. As the result, p9_zc_check_errors() tries to get the data using copy_from_iter_full(). Unfortunately, the iov_iter it's trying to read from might *NOT* be capable of that. It is, after all, a data destination, not data source. In particular, if it's an ITER_PIPE one, copy_from_iter_full() will simply fail. In ->zc_request() itself we do have those pages and dealing with the problem in there would be a simple matter of memcpy_from_page() into the fixed-sized buffer. Moreover, it isn't hard to recognize the (rare) case when such copying is needed. That way we get rid of p9_zc_check_errors() entirely - p9_check_errors() can be used instead both for zero-copy and non-zero-copy cases. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2022-01-10net/9p: show error message if user 'msize' cannot be satisfiedChristian Schoenebeck
If user supplied a large value with the 'msize' option, then client would silently limit that 'msize' value to the maximum value supported by transport. That's a bit confusing for users of not having any indication why the preferred 'msize' value could not be satisfied. Link: https://lkml.kernel.org/r/783ba37c1566dd715b9a67d437efa3b77e3cd1a7.1640870037.git.linux_oss@crudebyte.com Reported-by: Vivek Goyal <vgoyal@redhat.com> Signed-off-by: Christian Schoenebeck <linux_oss@crudebyte.com> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
2021-11-049p: fix a bunch of checkpatch warningsDominique Martinet
Sohaib Mohamed started a serie of tiny and incomplete checkpatch fixes but seemingly stopped halfway -- take over and do most of it. This is still missing net/9p/trans* and net/9p/protocol.c for a later time... Link: http://lkml.kernel.org/r/20211102134608.1588018-3-dominique.martinet@atmark-techno.com Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
2021-11-039p: fix file headersDominique Martinet
- add missing SPDX-License-Identifier - remove (sometimes incorrect) file name from file header Link: http://lkml.kernel.org/r/20211102134608.1588018-2-dominique.martinet@atmark-techno.com Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
2021-11-039p/net: fix missing error check in p9_check_errorsDominique Martinet
Link: https://lkml.kernel.org/r/99338965-d36c-886e-cd0e-1d8fff2b4746@gmail.com Reported-by: syzbot+06472778c97ed94af66d@syzkaller.appspotmail.com Cc: stable@vger.kernel.org Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
2021-09-05net/9p: increase default msize to 128kChristian Schoenebeck
Let's raise the default msize value to 128k. The 'msize' option defines the maximum message size allowed for any message being transmitted (in both directions) between 9p server and 9p client during a 9p session. Currently the default 'msize' is just 8k, which is way too conservative. Such a small 'msize' value has quite a negative performance impact, because individual 9p messages have to be split up far too often into numerous smaller messages to fit into this message size limitation. A default value of just 8k also has a much higher probablity of hitting short-read issues like: https://gitlab.com/qemu-project/qemu/-/issues/409 Unfortunately user feedback showed that many 9p users are not aware that this option even exists, nor the negative impact it might have if it is too low. Link: http://lkml.kernel.org/r/61ea0f0faaaaf26dd3c762eabe4420306ced21b9.1630770829.git.linux_oss@crudebyte.com Link: https://lists.gnu.org/archive/html/qemu-devel/2021-03/msg01003.html Signed-off-by: Christian Schoenebeck <linux_oss@crudebyte.com> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
2021-09-05net/9p: use macro to define default msizeChristian Schoenebeck
Use a macro to define the default value for the 'msize' option at one place instead of using two separate integer literals. Link: http://lkml.kernel.org/r/28bb651ae0349a7d57e8ddc92c1bd5e62924a912.1630770829.git.linux_oss@crudebyte.com Signed-off-by: Christian Schoenebeck <linux_oss@crudebyte.com> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
2021-03-28net: 9p: Correct function names in the kerneldoc commentsXiongfeng Wang
Fix the following W=1 kernel build warning(s): net/9p/client.c:133: warning: expecting prototype for parse_options(). Prototype was for parse_opts() instead net/9p/client.c:269: warning: expecting prototype for p9_req_alloc(). Prototype was for p9_tag_alloc() instead Reported-by: Hulk Robot <hulkci@huawei.com> Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
2021-03-03net: 9p: advance iov on empty readJisheng Zhang
I met below warning when cating a small size(about 80bytes) txt file on 9pfs(msize=2097152 is passed to 9p mount option), the reason is we miss iov_iter_advance() if the read count is 0 for zerocopy case, so we didn't truncate the pipe, then iov_iter_pipe() thinks the pipe is full. Fix it by removing the exception for 0 to ensure to call iov_iter_advance() even on empty read for zerocopy case. [ 8.279568] WARNING: CPU: 0 PID: 39 at lib/iov_iter.c:1203 iov_iter_pipe+0x31/0x40 [ 8.280028] Modules linked in: [ 8.280561] CPU: 0 PID: 39 Comm: cat Not tainted 5.11.0+ #6 [ 8.281260] RIP: 0010:iov_iter_pipe+0x31/0x40 [ 8.281974] Code: 2b 42 54 39 42 5c 76 22 c7 07 20 00 00 00 48 89 57 18 8b 42 50 48 c7 47 08 b [ 8.283169] RSP: 0018:ffff888000cbbd80 EFLAGS: 00000246 [ 8.283512] RAX: 0000000000000010 RBX: ffff888000117d00 RCX: 0000000000000000 [ 8.283876] RDX: ffff88800031d600 RSI: 0000000000000000 RDI: ffff888000cbbd90 [ 8.284244] RBP: ffff888000cbbe38 R08: 0000000000000000 R09: ffff8880008d2058 [ 8.284605] R10: 0000000000000002 R11: ffff888000375510 R12: 0000000000000050 [ 8.284964] R13: ffff888000cbbe80 R14: 0000000000000050 R15: ffff88800031d600 [ 8.285439] FS: 00007f24fd8af600(0000) GS:ffff88803ec00000(0000) knlGS:0000000000000000 [ 8.285844] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 8.286150] CR2: 00007f24fd7d7b90 CR3: 0000000000c97000 CR4: 00000000000406b0 [ 8.286710] Call Trace: [ 8.288279] generic_file_splice_read+0x31/0x1a0 [ 8.289273] ? do_splice_to+0x2f/0x90 [ 8.289511] splice_direct_to_actor+0xcc/0x220 [ 8.289788] ? pipe_to_sendpage+0xa0/0xa0 [ 8.290052] do_splice_direct+0x8b/0xd0 [ 8.290314] do_sendfile+0x1ad/0x470 [ 8.290576] do_syscall_64+0x2d/0x40 [ 8.290818] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 8.291409] RIP: 0033:0x7f24fd7dca0a [ 8.292511] Code: c3 0f 1f 80 00 00 00 00 4c 89 d2 4c 89 c6 e9 bd fd ff ff 0f 1f 44 00 00 31 8 [ 8.293360] RSP: 002b:00007ffc20932818 EFLAGS: 00000206 ORIG_RAX: 0000000000000028 [ 8.293800] RAX: ffffffffffffffda RBX: 0000000001000000 RCX: 00007f24fd7dca0a [ 8.294153] RDX: 0000000000000000 RSI: 0000000000000003 RDI: 0000000000000001 [ 8.294504] RBP: 0000000000000003 R08: 0000000000000000 R09: 0000000000000000 [ 8.294867] R10: 0000000001000000 R11: 0000000000000206 R12: 0000000000000003 [ 8.295217] R13: 0000000000000001 R14: 0000000000000001 R15: 0000000000000000 [ 8.295782] ---[ end trace 63317af81b3ca24b ]--- Signed-off-by: Jisheng Zhang <Jisheng.Zhang@synaptics.com> Signed-off-by: David S. Miller <davem@davemloft.net>
2020-12-21Merge tag '9p-for-5.11-rc1' of git://github.com/martinetd/linuxLinus Torvalds
Pull 9p update from Dominique Martinet: - fix long-standing limitation on open-unlink-fop pattern - add refcount to p9_fid (fixes the above and will allow for more cleanups and simplifications in the future) * tag '9p-for-5.11-rc1' of git://github.com/martinetd/linux: 9p: Remove unnecessary IS_ERR() check 9p: Uninitialized variable in v9fs_writeback_fid() 9p: Fix writeback fid incorrectly being attached to dentry 9p: apply review requests for fid refcounting 9p: add refcount to p9_fid struct fs/9p: search open fids first fs/9p: track open fids fs/9p: fix create-unlink-getattr idiom
2020-11-199p: apply review requests for fid refcountingDominique Martinet
Fix style issues in parent commit ("apply review requests for fid refcounting"), no functional change. Link: http://lkml.kernel.org/r/1605802012-31133-2-git-send-email-asmadeus@codewreck.org Fixes: 6636b6dcc3db ("9p: add refcount to p9_fid struct") Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
2020-11-199p: add refcount to p9_fid structJianyong Wu
Fix race issue in fid contention. Eric's and Greg's patch offer a mechanism to fix open-unlink-f*syscall bug in 9p. But there is race issue in fid parallel accesses. As Greg's patch stores all of fids from opened files into according inode, so all the lookup fid ops can retrieve fid from inode preferentially. But there is no mechanism to handle the fid contention issue. For example, there are two threads get the same fid in the same time and one of them clunk the fid before the other thread ready to discard the fid. In this scenario, it will lead to some fatal problems, even kernel core dump. I introduce a mechanism to fix this race issue. A counter field introduced into p9_fid struct to store the reference counter to the fid. When a fid is allocated from the inode or dentry, the counter will increase, and will decrease at the end of its occupation. It is guaranteed that the fid won't be clunked before the reference counter go down to 0, then we can avoid the clunked fid to be used. tests: race issue test from the old test case: for file in {01..50}; do touch f.${file}; done seq 1 1000 | xargs -n 1 -P 50 -I{} cat f.* > /dev/null open-unlink-f*syscall test: I have tested for f*syscall include: ftruncate fstat fchown fchmod faccessat. Link: http://lkml.kernel.org/r/20200923141146.90046-5-jianyong.wu@arm.com Fixes: 478ba09edc1f ("fs/9p: search open fids first") Signed-off-by: Jianyong Wu <jianyong.wu@arm.com> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
2020-11-03fs/9p: fix create-unlink-getattr idiomEric Van Hensbergen
Fixes several outstanding bug reports of not being able to getattr from an open file after an unlink. This patch cleans up transient fids on an unlink and will search open fids on a client if it detects a dentry that appears to have been unlinked. This search is necessary because fstat does not pass fd information through the VFS API to the filesystem, only the dentry which for 9p has an imperfect match to fids. Inherent in this patch is also a fix for the qid handling on create/open which apparently wasn't being set correctly and was necessary for the search to succeed. A possible optimization over this fix is to include accounting of open fids with the inode in the private data (in a similar fashion to the way we track transient fids with dentries). This would allow a much quicker search for a matching open fid. (changed v9fs_fid_find_global to v9fs_fid_find_inode in comment) Link: http://lkml.kernel.org/r/20200923141146.90046-2-jianyong.wu@arm.com Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com> Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com> Signed-off-by: Jianyong Wu <jianyong.wu@arm.com> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
2020-11-02net: 9p: Fix kerneldoc warnings of missing parameters etcAndrew Lunn
net/9p/client.c:420: warning: Function parameter or member 'c' not described in 'p9_client_cb' net/9p/client.c:420: warning: Function parameter or member 'req' not described in 'p9_client_cb' net/9p/client.c:420: warning: Function parameter or member 'status' not described in 'p9_client_cb' net/9p/client.c:568: warning: Function parameter or member 'uidata' not described in 'p9_check_zc_errors' net/9p/trans_common.c:23: warning: Function parameter or member 'nr_pages' not described in 'p9_release_pages' net/9p/trans_common.c:23: warning: Function parameter or member 'pages' not described in 'p9_release_pages' net/9p/trans_fd.c:132: warning: Function parameter or member 'rreq' not described in 'p9_conn' net/9p/trans_fd.c:132: warning: Function parameter or member 'wreq' not described in 'p9_conn' net/9p/trans_fd.c:56: warning: Function parameter or member 'privport' not described in 'p9_fd_opts' net/9p/trans_rdma.c:113: warning: Function parameter or member 'cqe' not described in 'p9_rdma_context' net/9p/trans_rdma.c:129: warning: Function parameter or member 'privport' not described in 'p9_rdma_opts' net/9p/trans_virtio.c:215: warning: Function parameter or member 'limit' not described in 'pack_sg_list_p' net/9p/trans_virtio.c:83: warning: Function parameter or member 'chan_list' not described in 'virtio_chan' net/9p/trans_virtio.c:83: warning: Function parameter or member 'p9_max_pages' not described in 'virtio_chan' net/9p/trans_virtio.c:83: warning: Function parameter or member 'ring_bufs_avail' not described in 'virtio_chan' net/9p/trans_virtio.c:83: warning: Function parameter or member 'tag' not described in 'virtio_chan' net/9p/trans_virtio.c:83: warning: Function parameter or member 'vc_wq' not described in 'virtio_chan' Signed-off-by: Andrew Lunn <andrew@lunn.ch> Acked-by: Dominique Martinet <asmadeus@codewreck.org> Link: https://lore.kernel.org/r/20201031182655.1082065-1-andrew@lunn.ch Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2020-07-13net: 9p: kerneldoc fixesAndrew Lunn
Simple fixes which require no deep knowledge of the code. Cc: Eric Van Hensbergen <ericvh@gmail.com> Cc: Latchesar Ionkov <lucho@ionkov.net> Cc: Dominique Martinet <asmadeus@codewreck.org> Signed-off-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
2020-03-279pnet: allow making incomplete read requestsSergey Alirzaev
A user doesn't necessarily want to wait for all the requested data to be available, since the waiting time for each request is unbounded. The new method permits sending one read request at a time and getting the response ASAP, allowing to use 9pnet with synthetic file systems representing arbitrary data streams. Link: http://lkml.kernel.org/r/20200205204053.12751-1-l29ah@cock.li Signed-off-by: Sergey Alirzaev <l29ah@cock.li> Signed-off-by: Dominique Martinet <dominique.martinet@cea.fr>
2019-09-039p: Transport error uninitializedLu Shuaibing
The p9_tag_alloc() does not initialize the transport error t_err field. The struct p9_req_t *req is allocated and stored in a struct p9_client variable. The field t_err is never initialized before p9_conn_cancel() checks its value. KUMSAN(KernelUninitializedMemorySantizer, a new error detection tool) reports this bug. ================================================================== BUG: KUMSAN: use of uninitialized memory in p9_conn_cancel+0x2d9/0x3b0 Read of size 4 at addr ffff88805f9b600c by task kworker/1:2/1216 CPU: 1 PID: 1216 Comm: kworker/1:2 Not tainted 5.2.0-rc4+ #28 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014 Workqueue: events p9_write_work Call Trace: dump_stack+0x75/0xae __kumsan_report+0x17c/0x3e6 kumsan_report+0xe/0x20 p9_conn_cancel+0x2d9/0x3b0 p9_write_work+0x183/0x4a0 process_one_work+0x4d1/0x8c0 worker_thread+0x6e/0x780 kthread+0x1ca/0x1f0 ret_from_fork+0x35/0x40 Allocated by task 1979: save_stack+0x19/0x80 __kumsan_kmalloc.constprop.3+0xbc/0x120 kmem_cache_alloc+0xa7/0x170 p9_client_prepare_req.part.9+0x3b/0x380 p9_client_rpc+0x15e/0x880 p9_client_create+0x3d0/0xac0 v9fs_session_init+0x192/0xc80 v9fs_mount+0x67/0x470 legacy_get_tree+0x70/0xd0 vfs_get_tree+0x4a/0x1c0 do_mount+0xba9/0xf90 ksys_mount+0xa8/0x120 __x64_sys_mount+0x62/0x70 do_syscall_64+0x6d/0x1e0 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Freed by task 0: (stack is not available) The buggy address belongs to the object at ffff88805f9b6008 which belongs to the cache p9_req_t of size 144 The buggy address is located 4 bytes inside of 144-byte region [ffff88805f9b6008, ffff88805f9b6098) The buggy address belongs to the page: page:ffffea00017e6d80 refcount:1 mapcount:0 mapping:ffff888068b63740 index:0xffff88805f9b7d90 compound_mapcount: 0 flags: 0x100000000010200(slab|head) raw: 0100000000010200 ffff888068b66450 ffff888068b66450 ffff888068b63740 raw: ffff88805f9b7d90 0000000000100001 00000001ffffffff 0000000000000000 page dumped because: kumsan: bad access detected ================================================================== Link: http://lkml.kernel.org/r/20190613070854.10434-1-shuaibinglu@126.com Signed-off-by: Lu Shuaibing <shuaibinglu@126.com> [dominique.martinet@cea.fr: grouped the added init with the others] Signed-off-by: Dominique Martinet <dominique.martinet@cea.fr>
2019-05-30treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 188Thomas Gleixner
Based on 1 normalized pattern(s): this program is free software you can redistribute it and or modify it under the terms of the gnu general public license version 2 as published by the free software foundation this program is distributed in the hope that it will be useful but without any warranty without even the implied warranty of merchantability or fitness for a particular purpose see the gnu general public license for more details you should have received a copy of the gnu general public license along with this program if not write to free software foundation 51 franklin street fifth floor boston ma 02111 1301 usa extracted by the scancode license scanner the SPDX license identifier GPL-2.0-only has been chosen to replace the boilerplate/reference in 27 file(s). Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Richard Fontana <rfontana@redhat.com> Reviewed-by: Alexios Zavras <alexios.zavras@intel.com> Reviewed-by: Steve Winslow <swinslow@gmail.com> Reviewed-by: Allison Randal <allison@lohutok.net> Cc: linux-spdx@vger.kernel.org Link: https://lkml.kernel.org/r/20190528170026.981318839@linutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-03-139p/net: fix memory leak in p9_client_createzhengbin
If msize is less than 4096, we should close and put trans, destroy tagpool, not just free client. This patch fixes that. Link: http://lkml.kernel.org/m/1552464097-142659-1-git-send-email-zhengbin13@huawei.com Cc: stable@vger.kernel.org Fixes: 574d356b7a02 ("9p/net: put a lower bound on msize") Reported-by: Hulk Robot <hulkci@huawei.com> Signed-off-by: zhengbin <zhengbin13@huawei.com> Signed-off-by: Dominique Martinet <dominique.martinet@cea.fr>
2018-12-259p/net: put a lower bound on msizeDominique Martinet
If the requested msize is too small (either from command line argument or from the server version reply), we won't get any work done. If it's *really* too small, nothing will work, and this got caught by syzbot recently (on a new kmem_cache_create_usercopy() call) Just set a minimum msize to 4k in both code paths, until someone complains they have a use-case for a smaller msize. We need to check in both mount option and server reply individually because the msize for the first version request would be unchecked with just a global check on clnt->msize. Link: http://lkml.kernel.org/r/1541407968-31350-1-git-send-email-asmadeus@codewreck.org Reported-by: syzbot+0c1d61e4db7db94102ca@syzkaller.appspotmail.com Signed-off-by: Dominique Martinet <dominique.martinet@cea.fr> Cc: Eric Van Hensbergen <ericvh@gmail.com> Cc: Latchesar Ionkov <lucho@ionkov.net> Cc: stable@vger.kernel.org
2018-11-01Merge branch 'work.afs' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs Pull AFS updates from Al Viro: "AFS series, with some iov_iter bits included" * 'work.afs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (26 commits) missing bits of "iov_iter: Separate type from direction and use accessor functions" afs: Probe multiple fileservers simultaneously afs: Fix callback handling afs: Eliminate the address pointer from the address list cursor afs: Allow dumping of server cursor on operation failure afs: Implement YFS support in the fs client afs: Expand data structure fields to support YFS afs: Get the target vnode in afs_rmdir() and get a callback on it afs: Calc callback expiry in op reply delivery afs: Fix FS.FetchStatus delivery from updating wrong vnode afs: Implement the YFS cache manager service afs: Remove callback details from afs_callback_break struct afs: Commit the status on a new file/dir/symlink afs: Increase to 64-bit volume ID and 96-bit vnode ID for YFS afs: Don't invoke the server to read data beyond EOF afs: Add a couple of tracepoints to log I/O errors afs: Handle EIO from delivery function afs: Fix TTL on VL server and address lists afs: Implement VL server rotation afs: Improve FS server rotation error handling ...
2018-10-24iov_iter: Separate type from direction and use accessor functionsDavid Howells
In the iov_iter struct, separate the iterator type from the iterator direction and use accessor functions to access them in most places. Convert a bunch of places to use switch-statements to access them rather then chains of bitwise-AND statements. This makes it easier to add further iterator types. Also, this can be more efficient as to implement a switch of small contiguous integers, the compiler can use ~50% fewer compare instructions than it has to use bitwise-and instructions. Further, cease passing the iterator type into the iterator setup function. The iterator function can set that itself. Only the direction is required. Signed-off-by: David Howells <dhowells@redhat.com>
2018-10-109p: potential NULL dereferenceDan Carpenter
p9_tag_alloc() is supposed to return error pointers, but we accidentally return a NULL here. It would cause a NULL dereference in the caller. Link: http://lkml.kernel.org/m/20180926103934.GA14535@mwanda Fixes: 996d5b4db4b1 ("9p: Use a slab for allocating requests") Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Dominique Martinet <dominique.martinet@cea.fr>
2018-09-089p: Add refcount to p9_req_tTomas Bortoli
To avoid use-after-free(s), use a refcount to keep track of the usable references to any instantiated struct p9_req_t. This commit adds p9_req_put(), p9_req_get() and p9_req_try_get() as wrappers to kref_put(), kref_get() and kref_get_unless_zero(). These are used by the client and the transports to keep track of valid requests' references. p9_free_req() is added back and used as callback by kref_put(). Add SLAB_TYPESAFE_BY_RCU as it ensures that the memory freed by kmem_cache_free() will not be reused for another type until the rcu synchronisation period is over, so an address gotten under rcu read lock is safe to inc_ref() without corrupting random memory while the lock is held. Link: http://lkml.kernel.org/r/1535626341-20693-1-git-send-email-asmadeus@codewreck.org Co-developed-by: Dominique Martinet <dominique.martinet@cea.fr> Signed-off-by: Tomas Bortoli <tomasbortoli@gmail.com> Reported-by: syzbot+467050c1ce275af2a5b8@syzkaller.appspotmail.com Signed-off-by: Dominique Martinet <dominique.martinet@cea.fr>
2018-09-089p: rename p9_free_req() functionTomas Bortoli
In sight of the next patch to add a refcount in p9_req_t, rename the p9_free_req() function in p9_release_req(). In the next patch the actual kfree will be moved to another function. Link: http://lkml.kernel.org/r/20180811144254.23665-1-tomasbortoli@gmail.com Signed-off-by: Tomas Bortoli <tomasbortoli@gmail.com> Acked-by: Jun Piao <piaojun@huawei.com> Signed-off-by: Dominique Martinet <dominique.martinet@cea.fr>
2018-09-089p: add a per-client fcall kmem_cacheDominique Martinet
Having a specific cache for the fcall allocations helps speed up end-to-end latency. The caches will automatically be merged if there are multiple caches of items with the same size so we do not need to try to share a cache between different clients of the same size. Since the msize is negotiated with the server, only allocate the cache after that negotiation has happened - previous allocations or allocations of different sizes (e.g. zero-copy fcall) are made with kmalloc directly. Some figures on two beefy VMs with Connect-IB (sriov) / trans=rdma, with ior running 32 processes in parallel doing small 32 bytes IOs: - no alloc (4.18-rc7 request cache): 65.4k req/s - non-power of two alloc, no patch: 61.6k req/s - power of two alloc, no patch: 62.2k req/s - non-power of two alloc, with patch: 64.7k req/s - power of two alloc, with patch: 65.1k req/s Link: http://lkml.kernel.org/r/1532943263-24378-2-git-send-email-asmadeus@codewreck.org Signed-off-by: Dominique Martinet <dominique.martinet@cea.fr> Acked-by: Jun Piao <piaojun@huawei.com> Cc: Matthew Wilcox <willy@infradead.org> Cc: Greg Kurz <groug@kaod.org>
2018-09-089p: embed fcall in req to round down buffer allocsDominique Martinet
'msize' is often a power of two, or at least page-aligned, so avoiding an overhead of two dozen bytes for each allocation will help the allocator do its work and reduce memory fragmentation. Link: http://lkml.kernel.org/r/1533825236-22896-1-git-send-email-asmadeus@codewreck.org Suggested-by: Matthew Wilcox <willy@infradead.org> Signed-off-by: Dominique Martinet <dominique.martinet@cea.fr> Reviewed-by: Greg Kurz <groug@kaod.org> Acked-by: Jun Piao <piaojun@huawei.com> Cc: Matthew Wilcox <willy@infradead.org>