summaryrefslogtreecommitdiffstats
path: root/drivers/block/rbd.c (follow)
Commit message (Collapse)AuthorAgeFilesLines
* rbd: don't mess with a page vector in rbd_notify_op_lock()Ilya Dryomov2020-04-131-5/+1
| | | | | | | | | rbd_notify_op_lock() isn't interested in a notify reply. Instead of accepting that page vector just to free it, have watch-notify code take care of it. Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Jason Dillaman <dillaman@redhat.com>
* rbd: don't test rbd_dev->opts in rbd_dev_image_release()Ilya Dryomov2020-04-131-1/+1
| | | | | | | | | | | | | rbd_dev->opts is used to distinguish between the image that is being mapped and a parent. However, because we no longer establish watch for read-only mappings, this test is imprecise and results in unnecessary rbd_unregister_watch() calls. Make it consistent with need_watch in rbd_dev_image_probe(). Fixes: b9ef2b8858a0 ("rbd: don't establish watch for read-only mappings") Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Jason Dillaman <dillaman@redhat.com>
* rbd: call rbd_dev_unprobe() after unwatching and flushing notifiesIlya Dryomov2020-04-131-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | rbd_dev_unprobe() is supposed to undo most of rbd_dev_image_probe(), including rbd_dev_header_info(), which means that rbd_dev_header_info() isn't supposed to be called after rbd_dev_unprobe(). However, rbd_dev_image_release() calls rbd_dev_unprobe() before rbd_unregister_watch(). This is racy because a header update notify can sneak in: "rbd unmap" thread ceph-watch-notify worker rbd_dev_image_release() rbd_dev_unprobe() free and zero out header rbd_watch_cb() rbd_dev_refresh() rbd_dev_header_info() read in header The same goes for "rbd map" because rbd_dev_image_probe() calls rbd_dev_unprobe() on errors. In both cases this results in a memory leak. Fixes: fd22aef8b47c ("rbd: move rbd_unregister_watch() call into rbd_dev_image_release()") Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Jason Dillaman <dillaman@redhat.com>
* rbd: avoid a deadlock on header_rwsem when flushing notifiesIlya Dryomov2020-04-131-4/+13
| | | | | | | | | | | | | | | | rbd_unregister_watch() flushes notifies and therefore cannot be called under header_rwsem because a header update notify takes header_rwsem to synchronize with "rbd map". If mapping an image fails after the watch is established and a header update notify sneaks in, we deadlock when erroring out from rbd_dev_image_probe(). Move watch registration and unregistration out of the critical section. The only reason they were put there was to make header_rwsem management slightly more obvious. Fixes: 811c66887746 ("rbd: fix rbd map vs notify races") Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Jason Dillaman <dillaman@redhat.com>
* rbd: enable multiple blk-mq queuesHannes Reinecke2020-03-301-1/+1
| | | | | | | | | Allocate one queue per CPU and get a performance boost from higher parallelism. Signed-off-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Ilya Dryomov <idryomov@gmail.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
* rbd: embed image request in blk-mq pduIlya Dryomov2020-03-301-87/+51
| | | | | | | | | | | Avoid making allocations for !IMG_REQ_CHILD image requests. Only IMG_REQ_CHILD image requests need to be freed now. Move the initial request checks to rbd_queue_rq(). Unfortunately we can't fill the image request and kick the state machine directly from rbd_queue_rq() because ->queue_rq() isn't allowed to block. Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
* rbd: acquire header_rwsem just once in rbd_queue_workfn()Ilya Dryomov2020-03-301-28/+31
| | | | | | | | | | Currently header_rwsem is acquired twice: once in rbd_dev_parent_get() when the image request is being created and then in rbd_queue_workfn() to capture mapping_size and snapc. Introduce rbd_img_capture_header() and move image request allocation so that header_rwsem can be acquired just once. Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
* rbd: get rid of img_request_layered_clear()Ilya Dryomov2020-03-301-8/+1
| | | | | | No need to clear IMG_REQ_LAYERED before destroying the request. Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
* rbd: kill img_request krefHannes Reinecke2020-03-301-19/+5
| | | | | | | | | The reference counter is never increased, so we can as well call rbd_img_request_destroy() directly and drop the kref. Signed-off-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Ilya Dryomov <idryomov@gmail.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
* rbd: remove barriers from img_request_layered_{set,clear,test}()Ilya Dryomov2020-03-301-3/+0
| | | | | | | | IMG_REQ_LAYERED is set in rbd_img_request_create(), and tested and cleared in rbd_img_request_destroy() when the image request is about to be destroyed. The barriers are unnecessary. Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
* Merge branch 'merge.nfs-fs_parse.1' of ↵Linus Torvalds2020-02-081-20/+11
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs Pull vfs file system parameter updates from Al Viro: "Saner fs_parser.c guts and data structures. The system-wide registry of syntax types (string/enum/int32/oct32/.../etc.) is gone and so is the horror switch() in fs_parse() that would have to grow another case every time something got added to that system-wide registry. New syntax types can be added by filesystems easily now, and their namespace is that of functions - not of system-wide enum members. IOW, they can be shared or kept private and if some turn out to be widely useful, we can make them common library helpers, etc., without having to do anything whatsoever to fs_parse() itself. And we already get that kind of requests - the thing that finally pushed me into doing that was "oh, and let's add one for timeouts - things like 15s or 2h". If some filesystem really wants that, let them do it. Without somebody having to play gatekeeper for the variants blessed by direct support in fs_parse(), TYVM. Quite a bit of boilerplate is gone. And IMO the data structures make a lot more sense now. -200LoC, while we are at it" * 'merge.nfs-fs_parse.1' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (25 commits) tmpfs: switch to use of invalfc() cgroup1: switch to use of errorfc() et.al. procfs: switch to use of invalfc() hugetlbfs: switch to use of invalfc() cramfs: switch to use of errofc() et.al. gfs2: switch to use of errorfc() et.al. fuse: switch to use errorfc() et.al. ceph: use errorfc() and friends instead of spelling the prefix out prefix-handling analogues of errorf() and friends turn fs_param_is_... into functions fs_parse: handle optional arguments sanely fs_parse: fold fs_parameter_desc/fs_parameter_spec fs_parser: remove fs_parameter_description name field add prefix to fs_context->log ceph_parse_param(), ceph_parse_mon_ips(): switch to passing fc_log new primitive: __fs_parse() switch rbd and libceph to p_log-based primitives struct p_log, variants of warnf() et.al. taking that one instead teach logfc() to handle prefices, give it saner calling conventions get rid of cg_invalf() ...
| * fs_parse: fold fs_parameter_desc/fs_parameter_specAl Viro2020-02-071-6/+2
| | | | | | | | | | | | The former contains nothing but a pointer to an array of the latter... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
| * fs_parser: remove fs_parameter_description name fieldEric Sandeen2020-02-071-1/+0
| | | | | | | | | | | | | | | | Unused now. Signed-off-by: Eric Sandeen <sandeen@redhat.com> Acked-by: David Howells <dhowells@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
| * new primitive: __fs_parse()Al Viro2020-02-071-1/+1
| | | | | | | | | | | | | | | | | | | | | | fs_parse() analogue taking p_log instead of fs_context. fs_parse() turned into a wrapper, callers in ceph_common and rbd switched to __fs_parse(). As the result, fs_parse() never gets NULL fs_context and neither do fs_context-based logging primitives Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
| * switch rbd and libceph to p_log-based primitivesAl Viro2020-02-071-8/+6
| | | | | | | | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
| * struct p_log, variants of warnf() et.al. taking that one insteadAl Viro2020-02-071-0/+1
| | | | | | | | | | | | primitives for prefixed logging Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
| * Pass consistent param->type to fs_parse()Al Viro2020-02-071-5/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | As it is, vfs_parse_fs_string() makes "foo" and "foo=" indistinguishable; both get fs_value_is_string for ->type and NULL for ->string. To make it even more unpleasant, that combination is impossible to produce with fsconfig(). Much saner rules would be "foo" => fs_value_is_flag, NULL "foo=" => fs_value_is_string, "" "foo=bar" => fs_value_is_string, "bar" All cases are distinguishable, all results are expressable by fsconfig(), ->has_value checks are much simpler that way (to the point of the field being useless) and quite a few regressions go away (gfs2 has no business accepting -o nodebug=, for example). Partially based upon patches from Miklos. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* | rbd: set the 'device' link in sysfsHannes Reinecke2020-01-271-1/+1
| | | | | | | | | | | | | | | | | | | | The rbd driver already provides additional information in sysfs under /sys/bus/rbd, so we should set the 'device' link in the block device to reference this information. Signed-off-by: Hannes Reinecke <hare@suse.com> Reviewed-by: Ilya Dryomov <idryomov@gmail.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
* | rbd: work around -Wuninitialized warningArnd Bergmann2020-01-271-1/+1
|/ | | | | | | | | | | | | | | | | gcc -O3 warns about a dummy variable that is passed down into rbd_img_fill_nodata without being initialized: drivers/block/rbd.c: In function 'rbd_img_fill_nodata': drivers/block/rbd.c:2573:13: error: 'dummy' is used uninitialized in this function [-Werror=uninitialized] fctx->iter = *fctx->pos; Since this is a dummy, I assume the warning is harmless, but it's better to initialize it anyway and avoid the warning. Fixes: mmtom ("init/Kconfig: enable -O3 for all arches") Signed-off-by: Arnd Bergmann <arnd@arndb.de> Reviewed-by: Ilya Dryomov <idryomov@gmail.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
* libceph, rbd, ceph: convert to use the new mount APIDavid Howells2019-11-271-109/+153
| | | | | | | | | | | | | | | | Convert the ceph filesystem to the new internal mount API as the old one will be obsoleted and removed. This allows greater flexibility in communication of mount parameters between userspace, the VFS and the filesystem. See Documentation/filesystems/mount_api.txt for more information. [ Numerous string handling, leak and regression fixes; rbd conversion was particularly broken and had to be redone almost from scratch. ] Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
* rbd: ask for a weaker incompat mask for read-only mappingsIlya Dryomov2019-11-251-4/+11
| | | | | | | | | | | | | | | For a read-only mapping, ask for a set of features that make the image only unwritable rather than both unreadable and unwritable by a client that doesn't understand them. As of today, the difference between them for krbd is journaling (JOURNALING) and live migration (MIGRATING). get_features method supports read_only parameter since hammer, ceph.git commit 6176ec5fde2a ("librbd: differentiate between R/O vs R/W RBD features"). Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Jason Dillaman <dillaman@redhat.com> Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
* rbd: don't query snapshot featuresIlya Dryomov2019-11-251-37/+1
| | | | | | | | | | | | Since infernalis, ceph.git commit 281f87f9ee52 ("cls_rbd: get_features on snapshots returns HEAD image features"), querying and checking that is pointless. Userspace support for manipulating image features after image creation came also in infernalis, so a snapshot with a different set of features wasn't ever possible. Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Jason Dillaman <dillaman@redhat.com> Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
* rbd: remove snapshot existence validation codeIlya Dryomov2019-11-251-39/+3
| | | | | | | | | | | | | | | | | | RBD_DEV_FLAG_EXISTS check in rbd_queue_workfn() is racy and leads to inconsistent behaviour. If the object (or its snapshot) isn't there, the OSD returns ENOENT. A read submitted before the snapshot removal notification is processed would be zero-filled and ended with status OK, while future reads would be failed with IOERR. It also doesn't handle a case when an image that is mapped read-only is removed. On top of this, because watch is no longer established for read-only mappings, we no longer get notifications, so rbd_exists_validate() is effectively dead code. While failing requests rather than returning zeros is a good thing, RBD_DEV_FLAG_EXISTS is not it. Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Jason Dillaman <dillaman@redhat.com> Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
* rbd: don't establish watch for read-only mappingsIlya Dryomov2019-11-251-14/+27
| | | | | | | | | With exclusive lock out of the way, watch is the only thing left that prevents a read-only mapping from being used with read-only OSD caps. Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Jason Dillaman <dillaman@redhat.com> Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
* rbd: don't acquire exclusive lock for read-only mappingsIlya Dryomov2019-11-251-2/+13
| | | | | | | | | | | | | | | A read-only mapping should be usable with read-only OSD caps, so neither the header lock nor the object map lock can be acquired. Unfortunately, this means that images mapped read-only lose the advantage of the object map. Snapshots, however, can take advantage of the object map without any exclusionary locks, so if the object map is desired, snapshot the image and map the snapshot instead of the image. Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Jason Dillaman <dillaman@redhat.com> Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
* rbd: disallow read-write partitions on images mapped read-onlyIlya Dryomov2019-11-251-3/+10
| | | | | | | | | | | | | | | If an image is mapped read-only, don't allow setting its partition(s) to read-write via BLKROSET: with the previous patch all writes to such images are failed anyway. If an image is mapped read-write, its partition(s) can be set to read-only (and back to read-write) as before. Note that at the rbd level the image will remain writeable: anything sent down by the block layer will be executed, including any write from internal kernel users. Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Jason Dillaman <dillaman@redhat.com> Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
* rbd: treat images mapped read-only seriouslyIlya Dryomov2019-11-251-5/+8
| | | | | | | | | | | | | | | Even though -o ro/-o read_only/--read-only options are very old, we have never really treated them seriously (on par with snapshots). As a first step, fail writes to images mapped read-only just like we do for snapshots. We need this check in rbd because the block layer basically ignores read-only setting, see commit a32e236eb93e ("Partially revert "block: fail op_is_write() requests to read-only partitions""). Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Jason Dillaman <dillaman@redhat.com> Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
* rbd: introduce RBD_DEV_FLAG_READONLYIlya Dryomov2019-11-251-5/+14
| | | | | | | | | | | | | | | rbd_dev->opts is not available for parent images, making checking rbd_dev->opts->read_only in various places (rbd_dev_image_probe(), need_exclusive_lock(), use_object_map() in the following patches) harder than it needs to be. Keeping rbd_dev_image_probe() in mind, move the initialization in do_rbd_add() up. snap_id isn't filled in at that point, so replace rbd_is_snap() with a snap_name comparison. Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Jason Dillaman <dillaman@redhat.com> Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
* rbd: introduce rbd_is_snap()Ilya Dryomov2019-11-251-8/+13
| | | | | | Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Jason Dillaman <dillaman@redhat.com> Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
* rbd: fix spelling mistake "requeueing" -> "requeuing"Colin Ian King2019-11-251-1/+1
| | | | | | | There is a spelling mistake in a debug message. Fix it. Signed-off-by: Colin Ian King <colin.king@canonical.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
* rbd: silence bogus uninitialized warning in rbd_object_map_update_finish()Ilya Dryomov2019-11-141-1/+1
| | | | | | | | | | | | | | | | | | Some versions of gcc (so far 6.3 and 7.4) throw a warning: drivers/block/rbd.c: In function 'rbd_object_map_callback': drivers/block/rbd.c:2124:21: warning: 'current_state' may be used uninitialized in this function [-Wmaybe-uninitialized] (current_state == OBJECT_EXISTS && state == OBJECT_EXISTS_CLEAN)) drivers/block/rbd.c:2092:23: note: 'current_state' was declared here u8 state, new_state, current_state; ^~~~~~~~~~~~~ It's bogus because all current_state accesses are guarded by has_current_state. Reported-by: kbuild test robot <lkp@intel.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
* rbd: cancel lock_dwork if the wait is interruptedDongsheng Yang2019-10-151-3/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There is a warning message in my test with below steps: # rbd bench --io-type write --io-size 4K --io-threads 1 --io-pattern rand test & # sleep 5 # pkill -9 rbd # rbd map test & # sleep 5 # pkill rbd The reason is that the rbd_add_acquire_lock() is interruptable, that means, when we kill the waiting on ->acquire_wait, the lock_dwork could be still running. 1. do_rbd_add() 2. lock_dwork rbd_add_acquire_lock() - queue_delayed_work() lock_dwork queued - wait_for_completion_killable_timeout() <-- kill happen rbd_dev_image_unlock() <-- UNLOCKED now, nothing to do. rbd_dev_device_release() rbd_dev_image_release() - ... lock successed here - cancel_delayed_work_sync(&rbd_dev->lock_dwork) Then when we reach the rbd_dev_free(), WARN_ON is triggered because lock_state is not RBD_LOCK_STATE_UNLOCKED. To fix it, this commit make sure the lock_dwork was finished before calling rbd_dev_image_unlock(). On the other hand, this would not happend in do_rbd_remove(), because after rbd mapped, lock_dwork will only be queued for IO request, and request will continue unless lock_dwork finished. when we call rbd_dev_image_unlock() in do_rbd_remove(), all requests are done. That means, lock_state should not be locked again after rbd_dev_image_unlock(). [ Cancel lock_dwork in rbd_add_acquire_lock(), only if the wait is interrupted. ] Fixes: 637cd060537d ("rbd: new exclusive lock wait/wake code") Signed-off-by: Dongsheng Yang <dongsheng.yang@easystack.cn> Reviewed-by: Ilya Dryomov <idryomov@gmail.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
* rbd: pull rbd_img_request_create() dout out into the callersIlya Dryomov2019-09-161-2/+6
| | | | | | | Make it more informative: log op_type, offset and length for block layer requests and initiating obj_req for child requests. Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
* rbd: fix response length parameter for encoded stringsDongsheng Yang2019-09-161-4/+6
| | | | | | | | | | rbd_dev_image_id() allocates space for length but passes a smaller value to rbd_obj_method_sync(). rbd_dev_v2_object_prefix() doesn't allocate space for length. Fix both to be consistent. Signed-off-by: Dongsheng Yang <dongsheng.yang@easystack.cn> Reviewed-by: Ilya Dryomov <idryomov@gmail.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
* rbd: restore zeroing past the overlap when reading from parentIlya Dryomov2019-08-281-0/+11
| | | | | | | | | | | The parent image is read only up to the overlap point, the rest of the buffer should be zeroed. This snuck in because as it turns out the overlap test case has not been triggering this code path for a while now. Fixes: a9b67e69949d ("rbd: replace obj_req->tried_parent with obj_req->read_state") Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Jason Dillaman <dillaman@redhat.com>
* Merge tag 'ceph-for-5.3-rc1' of git://github.com/ceph/ceph-clientLinus Torvalds2019-07-181-588/+1600
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Pull ceph updates from Ilya Dryomov: "Lots of exciting things this time! - support for rbd object-map and fast-diff features (myself). This will speed up reads, discards and things like snap diffs on sparse images. - ceph.snap.btime vxattr to expose snapshot creation time (David Disseldorp). This will be used to integrate with "Restore Previous Versions" feature added in Windows 7 for folks who reexport ceph through SMB. - security xattrs for ceph (Zheng Yan). Only selinux is supported for now due to the limitations of ->dentry_init_security(). - support for MSG_ADDR2, FS_BTIME and FS_CHANGE_ATTR features (Jeff Layton). This is actually a single feature bit which was missing because of the filesystem pieces. With this in, the kernel client will finally be reported as "luminous" by "ceph features" -- it is still being reported as "jewel" even though all required Luminous features were implemented in 4.13. - stop NULL-terminating ceph vxattrs (Jeff Layton). The convention with xattrs is to not terminate and this was causing inconsistencies with ceph-fuse. - change filesystem time granularity from 1 us to 1 ns, again fixing an inconsistency with ceph-fuse (Luis Henriques). On top of this there are some additional dentry name handling and cap flushing fixes from Zheng. Finally, Jeff is formally taking over for Zheng as the filesystem maintainer" * tag 'ceph-for-5.3-rc1' of git://github.com/ceph/ceph-client: (71 commits) ceph: fix end offset in truncate_inode_pages_range call ceph: use generic_delete_inode() for ->drop_inode ceph: use ceph_evict_inode to cleanup inode's resource ceph: initialize superblock s_time_gran to 1 MAINTAINERS: take over for Zheng as CephFS kernel client maintainer rbd: setallochint only if object doesn't exist rbd: support for object-map and fast-diff rbd: call rbd_dev_mapping_set() from rbd_dev_image_probe() libceph: export osd_req_op_data() macro libceph: change ceph_osdc_call() to take page vector for response libceph: bump CEPH_MSG_MAX_DATA_LEN (again) rbd: new exclusive lock wait/wake code rbd: quiescing lock should wait for image requests rbd: lock should be quiesced on reacquire rbd: introduce copyup state machine rbd: rename rbd_obj_setup_*() to rbd_obj_init_*() rbd: move OSD request allocation into object request state machines rbd: factor out __rbd_osd_setup_discard_ops() rbd: factor out rbd_osd_setup_copyup() rbd: introduce obj_req->osd_reqs list ...
| * rbd: setallochint only if object doesn't existIlya Dryomov2019-07-081-5/+14
| | | | | | | | | | | | | | | | setallochint is really only useful on object creation. Continue hinting unconditionally if object map cannot be used. Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
| * rbd: support for object-map and fast-diffIlya Dryomov2019-07-081-3/+717
| | | | | | | | | | | | | | | | | | | | | | | | Speed up reads, discards and zeroouts through RBD_OBJ_FLAG_MAY_EXIST and RBD_OBJ_FLAG_NOOP_FOR_NONEXISTENT based on object map. Invalid object maps are not trusted, but still updated. Note that we never iterate, resize or invalidate object maps. If object-map feature is enabled but object map fails to load, we just fail the requester (either "rbd map" or I/O, by way of post-acquire action). Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
| * rbd: call rbd_dev_mapping_set() from rbd_dev_image_probe()Ilya Dryomov2019-07-081-8/+6
| | | | | | | | | | | | | | | | Snapshot object map will be loaded in rbd_dev_image_probe(), so we need to know snapshot's size (as opposed to HEAD's size) sooner. Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
| * libceph: change ceph_osdc_call() to take page vector for responseIlya Dryomov2019-07-081-4/+4
| | | | | | | | | | | | | | | | | | This will be used for loading object map. rbd_obj_read_sync() isn't suitable because object map must be accessed through class methods. Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn> Reviewed-by: Jeff Layton <jlayton@kernel.org>
| * rbd: new exclusive lock wait/wake codeIlya Dryomov2019-07-081-143/+186
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | rbd_wait_state_locked() is built around rbd_dev->lock_waitq and blocks rbd worker threads while waiting for the lock, potentially impacting other rbd devices. There is no good way to pass an error code into image request state machines when acquisition fails, hence the use of RBD_DEV_FLAG_BLACKLISTED for everything and various other issues. Introduce rbd_dev->acquiring_list and move acquisition into image request state machine. Use rbd_img_schedule() for kicking and passing error codes. No blocking occurs while waiting for the lock, but rbd_dev->lock_rwsem is still held across lock, unlock and set_cookie calls. Always acquire the lock on "rbd map" to avoid associating the latency of acquiring the lock with the first I/O request. A slight regression is that lock_timeout is now respected only if lock acquisition is triggered by "rbd map" and not by I/O. This is somewhat compensated by the fact that we no longer block if the peer refuses to release lock -- I/O is failed with EROFS right away. Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
| * rbd: quiescing lock should wait for image requestsIlya Dryomov2019-07-081-14/+90
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Syncing OSD requests doesn't really work. A single image request may be comprised of multiple object requests, each of which can go through a series of OSD requests (original, copyups, etc). On top of that, the OSD cliest may be shared with other rbd devices. What we want is to ensure that all in-flight image requests complete. Introduce rbd_dev->running_list and block in RBD_LOCK_STATE_RELEASING until that happens. New OSD requests may be started during this time. Note that __rbd_img_handle_request() acquires rbd_dev->lock_rwsem only if need_exclusive_lock() returns true. This avoids a deadlock similar to the one outlined in the previous commit between unlock and I/O that doesn't require lock, such as a read with object-map feature disabled. Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
| * rbd: lock should be quiesced on reacquireIlya Dryomov2019-07-081-14/+21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Quiesce exclusive lock at the top of rbd_reacquire_lock() instead of only when ceph_cls_set_cookie() fails. This avoids a deadlock on rbd_dev->lock_rwsem. If rbd_dev->lock_rwsem is needed for I/O completion, set_cookie can hang ceph-msgr worker thread if set_cookie reply ends up behind an I/O reply, because, like lock and unlock requests, set_cookie is sent and waited upon with rbd_dev->lock_rwsem held for write. Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
| * rbd: introduce copyup state machineIlya Dryomov2019-07-081-64/+123
| | | | | | | | | | | | | | | | | | | | | | Both write and copyup paths will get more complex with object map. Factor copyup code out into a separate state machine. While at it, take advantage of obj_req->osd_reqs list and issue empty and current snapc OSD requests together, one after another. Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
| * rbd: rename rbd_obj_setup_*() to rbd_obj_init_*()Ilya Dryomov2019-07-081-13/+13
| | | | | | | | | | | | | | These functions don't allocate and set up OSD requests anymore. Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
| * rbd: move OSD request allocation into object request state machinesIlya Dryomov2019-07-081-118/+96
| | | | | | | | | | | | | | | | | | | | Following submission, move initial OSD request allocation into object request state machines. Everything that has to do with OSD requests is now handled inside the state machine, all __rbd_img_fill_request() has left is initialization. Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
| * rbd: factor out __rbd_osd_setup_discard_ops()Ilya Dryomov2019-07-081-16/+27
| | | | | | | | | | | | | | | | | | With obj_req->xferred removed, obj_req->ex.oe_off and obj_req->ex.oe_len can be updated if required for alignment. Previously the new offset and length weren't stored anywhere beyond rbd_obj_setup_discard(). Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
| * rbd: factor out rbd_osd_setup_copyup()Ilya Dryomov2019-07-081-12/+17
| | | | | | | | | | Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
| * rbd: introduce obj_req->osd_reqs listIlya Dryomov2019-07-081-91/+100
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Since the dawn of time it had been assumed that a single object request spawns a single OSD request. This is already impacting copyup: instead of sending empty and current snapc copyups together, we wait for empty snapc OSD request to complete in order to reassign obj_req->osd_req with current snapc OSD request. Looking further, updating potentially hundreds of snapshot object maps serially is a non-starter. Replace obj_req->osd_req pointer with obj_req->osd_reqs list. Use osd_req->r_private_item for linkage. Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
| * rbd: introduce image request state machineIlya Dryomov2019-07-081-57/+137
| | | | | | | | | | | | | | | | | | | | | | | | Make it possible to schedule image requests on a workqueue. This fixes parent chain recursion added in the previous commit and lays the ground for exclusive lock wait/wake improvements. The "wait for pending subrequests and report first nonzero result" code is generalized to be used by object request state machine. Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>