^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/ceph/ceph_debug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/highmem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/pagemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #ifdef CONFIG_BLOCK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/bio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/ceph/ceph_features.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/ceph/libceph.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/ceph/osd_client.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/ceph/messenger.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/ceph/decode.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/ceph/auth.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/ceph/pagelist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/ceph/striper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define OSD_OPREPLY_FRONT_LEN 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static struct kmem_cache *ceph_osd_request_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static const struct ceph_connection_operations osd_con_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * Implement client access to distributed object storage cluster.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * All data objects are stored within a cluster/cloud of OSDs, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * "object storage devices." (Note that Ceph OSDs have _nothing_ to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * do with the T10 OSD extensions to SCSI.) Ceph OSDs are simply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * remote daemons serving up and coordinating consistent and safe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * access to storage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * Cluster membership and the mapping of data objects onto storage devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * are described by the osd map.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * We keep track of pending OSD requests (read, write), resubmit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * requests to different OSDs when the cluster topology/data layout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * change, or retry the affected requests when the communications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * channel with an OSD is reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static void link_request(struct ceph_osd *osd, struct ceph_osd_request *req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static void unlink_request(struct ceph_osd *osd, struct ceph_osd_request *req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static void link_linger(struct ceph_osd *osd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct ceph_osd_linger_request *lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static void unlink_linger(struct ceph_osd *osd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct ceph_osd_linger_request *lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static void clear_backoffs(struct ceph_osd *osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #if 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static inline bool rwsem_is_wrlocked(struct rw_semaphore *sem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) bool wrlocked = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (unlikely(down_read_trylock(sem))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) wrlocked = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) up_read(sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return wrlocked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static inline void verify_osdc_locked(struct ceph_osd_client *osdc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) WARN_ON(!rwsem_is_locked(&osdc->lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static inline void verify_osdc_wrlocked(struct ceph_osd_client *osdc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) WARN_ON(!rwsem_is_wrlocked(&osdc->lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static inline void verify_osd_locked(struct ceph_osd *osd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct ceph_osd_client *osdc = osd->o_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) WARN_ON(!(mutex_is_locked(&osd->lock) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) rwsem_is_locked(&osdc->lock)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) !rwsem_is_wrlocked(&osdc->lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static inline void verify_lreq_locked(struct ceph_osd_linger_request *lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) WARN_ON(!mutex_is_locked(&lreq->lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static inline void verify_osdc_locked(struct ceph_osd_client *osdc) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static inline void verify_osdc_wrlocked(struct ceph_osd_client *osdc) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static inline void verify_osd_locked(struct ceph_osd *osd) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static inline void verify_lreq_locked(struct ceph_osd_linger_request *lreq) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * calculate the mapping of a file extent onto an object, and fill out the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * request accordingly. shorten extent as necessary if it crosses an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * object boundary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * fill osd op in request message.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static int calc_layout(struct ceph_file_layout *layout, u64 off, u64 *plen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) u64 *objnum, u64 *objoff, u64 *objlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) u64 orig_len = *plen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) u32 xlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /* object extent? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) ceph_calc_file_object_mapping(layout, off, orig_len, objnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) objoff, &xlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) *objlen = xlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (*objlen < orig_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) *plen = *objlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) dout(" skipping last %llu, final file extent %llu~%llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) orig_len - *plen, off, *plen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) dout("calc_layout objnum=%llx %llu~%llu\n", *objnum, *objoff, *objlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static void ceph_osd_data_init(struct ceph_osd_data *osd_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) memset(osd_data, 0, sizeof (*osd_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) osd_data->type = CEPH_OSD_DATA_TYPE_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * Consumes @pages if @own_pages is true.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static void ceph_osd_data_pages_init(struct ceph_osd_data *osd_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct page **pages, u64 length, u32 alignment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) bool pages_from_pool, bool own_pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) osd_data->type = CEPH_OSD_DATA_TYPE_PAGES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) osd_data->pages = pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) osd_data->length = length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) osd_data->alignment = alignment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) osd_data->pages_from_pool = pages_from_pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) osd_data->own_pages = own_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * Consumes a ref on @pagelist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static void ceph_osd_data_pagelist_init(struct ceph_osd_data *osd_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) struct ceph_pagelist *pagelist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) osd_data->type = CEPH_OSD_DATA_TYPE_PAGELIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) osd_data->pagelist = pagelist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #ifdef CONFIG_BLOCK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static void ceph_osd_data_bio_init(struct ceph_osd_data *osd_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct ceph_bio_iter *bio_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) u32 bio_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) osd_data->type = CEPH_OSD_DATA_TYPE_BIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) osd_data->bio_pos = *bio_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) osd_data->bio_length = bio_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #endif /* CONFIG_BLOCK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static void ceph_osd_data_bvecs_init(struct ceph_osd_data *osd_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct ceph_bvec_iter *bvec_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) u32 num_bvecs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) osd_data->type = CEPH_OSD_DATA_TYPE_BVECS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) osd_data->bvec_pos = *bvec_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) osd_data->num_bvecs = num_bvecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static struct ceph_osd_data *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) osd_req_op_raw_data_in(struct ceph_osd_request *osd_req, unsigned int which)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) BUG_ON(which >= osd_req->r_num_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return &osd_req->r_ops[which].raw_data_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct ceph_osd_data *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) osd_req_op_extent_osd_data(struct ceph_osd_request *osd_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) unsigned int which)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return osd_req_op_data(osd_req, which, extent, osd_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) EXPORT_SYMBOL(osd_req_op_extent_osd_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) void osd_req_op_raw_data_in_pages(struct ceph_osd_request *osd_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) unsigned int which, struct page **pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) u64 length, u32 alignment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) bool pages_from_pool, bool own_pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct ceph_osd_data *osd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) osd_data = osd_req_op_raw_data_in(osd_req, which);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) ceph_osd_data_pages_init(osd_data, pages, length, alignment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) pages_from_pool, own_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) EXPORT_SYMBOL(osd_req_op_raw_data_in_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) void osd_req_op_extent_osd_data_pages(struct ceph_osd_request *osd_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) unsigned int which, struct page **pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) u64 length, u32 alignment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) bool pages_from_pool, bool own_pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) struct ceph_osd_data *osd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) osd_data = osd_req_op_data(osd_req, which, extent, osd_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) ceph_osd_data_pages_init(osd_data, pages, length, alignment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) pages_from_pool, own_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) EXPORT_SYMBOL(osd_req_op_extent_osd_data_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) void osd_req_op_extent_osd_data_pagelist(struct ceph_osd_request *osd_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) unsigned int which, struct ceph_pagelist *pagelist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) struct ceph_osd_data *osd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) osd_data = osd_req_op_data(osd_req, which, extent, osd_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) ceph_osd_data_pagelist_init(osd_data, pagelist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) EXPORT_SYMBOL(osd_req_op_extent_osd_data_pagelist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) #ifdef CONFIG_BLOCK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) void osd_req_op_extent_osd_data_bio(struct ceph_osd_request *osd_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) unsigned int which,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) struct ceph_bio_iter *bio_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) u32 bio_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct ceph_osd_data *osd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) osd_data = osd_req_op_data(osd_req, which, extent, osd_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) ceph_osd_data_bio_init(osd_data, bio_pos, bio_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) EXPORT_SYMBOL(osd_req_op_extent_osd_data_bio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) #endif /* CONFIG_BLOCK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) void osd_req_op_extent_osd_data_bvecs(struct ceph_osd_request *osd_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) unsigned int which,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct bio_vec *bvecs, u32 num_bvecs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) u32 bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct ceph_osd_data *osd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct ceph_bvec_iter it = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) .bvecs = bvecs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) .iter = { .bi_size = bytes },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) osd_data = osd_req_op_data(osd_req, which, extent, osd_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) ceph_osd_data_bvecs_init(osd_data, &it, num_bvecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) EXPORT_SYMBOL(osd_req_op_extent_osd_data_bvecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) void osd_req_op_extent_osd_data_bvec_pos(struct ceph_osd_request *osd_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) unsigned int which,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct ceph_bvec_iter *bvec_pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) struct ceph_osd_data *osd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) osd_data = osd_req_op_data(osd_req, which, extent, osd_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) ceph_osd_data_bvecs_init(osd_data, bvec_pos, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) EXPORT_SYMBOL(osd_req_op_extent_osd_data_bvec_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static void osd_req_op_cls_request_info_pagelist(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct ceph_osd_request *osd_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) unsigned int which, struct ceph_pagelist *pagelist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct ceph_osd_data *osd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) osd_data = osd_req_op_data(osd_req, which, cls, request_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) ceph_osd_data_pagelist_init(osd_data, pagelist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) void osd_req_op_cls_request_data_pagelist(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) struct ceph_osd_request *osd_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) unsigned int which, struct ceph_pagelist *pagelist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct ceph_osd_data *osd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) osd_data = osd_req_op_data(osd_req, which, cls, request_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) ceph_osd_data_pagelist_init(osd_data, pagelist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) osd_req->r_ops[which].cls.indata_len += pagelist->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) osd_req->r_ops[which].indata_len += pagelist->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) EXPORT_SYMBOL(osd_req_op_cls_request_data_pagelist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) void osd_req_op_cls_request_data_pages(struct ceph_osd_request *osd_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) unsigned int which, struct page **pages, u64 length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) u32 alignment, bool pages_from_pool, bool own_pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct ceph_osd_data *osd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) osd_data = osd_req_op_data(osd_req, which, cls, request_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) ceph_osd_data_pages_init(osd_data, pages, length, alignment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) pages_from_pool, own_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) osd_req->r_ops[which].cls.indata_len += length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) osd_req->r_ops[which].indata_len += length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) EXPORT_SYMBOL(osd_req_op_cls_request_data_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) void osd_req_op_cls_request_data_bvecs(struct ceph_osd_request *osd_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) unsigned int which,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) struct bio_vec *bvecs, u32 num_bvecs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) u32 bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) struct ceph_osd_data *osd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct ceph_bvec_iter it = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) .bvecs = bvecs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) .iter = { .bi_size = bytes },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) osd_data = osd_req_op_data(osd_req, which, cls, request_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) ceph_osd_data_bvecs_init(osd_data, &it, num_bvecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) osd_req->r_ops[which].cls.indata_len += bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) osd_req->r_ops[which].indata_len += bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) EXPORT_SYMBOL(osd_req_op_cls_request_data_bvecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) void osd_req_op_cls_response_data_pages(struct ceph_osd_request *osd_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) unsigned int which, struct page **pages, u64 length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) u32 alignment, bool pages_from_pool, bool own_pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) struct ceph_osd_data *osd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) osd_data = osd_req_op_data(osd_req, which, cls, response_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) ceph_osd_data_pages_init(osd_data, pages, length, alignment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) pages_from_pool, own_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) EXPORT_SYMBOL(osd_req_op_cls_response_data_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static u64 ceph_osd_data_length(struct ceph_osd_data *osd_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) switch (osd_data->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) case CEPH_OSD_DATA_TYPE_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) case CEPH_OSD_DATA_TYPE_PAGES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return osd_data->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) case CEPH_OSD_DATA_TYPE_PAGELIST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return (u64)osd_data->pagelist->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) #ifdef CONFIG_BLOCK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) case CEPH_OSD_DATA_TYPE_BIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return (u64)osd_data->bio_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) #endif /* CONFIG_BLOCK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) case CEPH_OSD_DATA_TYPE_BVECS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return osd_data->bvec_pos.iter.bi_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) WARN(true, "unrecognized data type %d\n", (int)osd_data->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) static void ceph_osd_data_release(struct ceph_osd_data *osd_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (osd_data->type == CEPH_OSD_DATA_TYPE_PAGES && osd_data->own_pages) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) int num_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) num_pages = calc_pages_for((u64)osd_data->alignment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) (u64)osd_data->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) ceph_release_page_vector(osd_data->pages, num_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) } else if (osd_data->type == CEPH_OSD_DATA_TYPE_PAGELIST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) ceph_pagelist_release(osd_data->pagelist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) ceph_osd_data_init(osd_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) static void osd_req_op_data_release(struct ceph_osd_request *osd_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) unsigned int which)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) struct ceph_osd_req_op *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) BUG_ON(which >= osd_req->r_num_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) op = &osd_req->r_ops[which];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) switch (op->op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) case CEPH_OSD_OP_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) case CEPH_OSD_OP_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) case CEPH_OSD_OP_WRITEFULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) ceph_osd_data_release(&op->extent.osd_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) case CEPH_OSD_OP_CALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) ceph_osd_data_release(&op->cls.request_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) ceph_osd_data_release(&op->cls.request_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) ceph_osd_data_release(&op->cls.response_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) case CEPH_OSD_OP_SETXATTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) case CEPH_OSD_OP_CMPXATTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) ceph_osd_data_release(&op->xattr.osd_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) case CEPH_OSD_OP_STAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) ceph_osd_data_release(&op->raw_data_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) case CEPH_OSD_OP_NOTIFY_ACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) ceph_osd_data_release(&op->notify_ack.request_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) case CEPH_OSD_OP_NOTIFY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) ceph_osd_data_release(&op->notify.request_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) ceph_osd_data_release(&op->notify.response_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) case CEPH_OSD_OP_LIST_WATCHERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) ceph_osd_data_release(&op->list_watchers.response_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) case CEPH_OSD_OP_COPY_FROM2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) ceph_osd_data_release(&op->copy_from.osd_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * Assumes @t is zero-initialized.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) static void target_init(struct ceph_osd_request_target *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) ceph_oid_init(&t->base_oid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) ceph_oloc_init(&t->base_oloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) ceph_oid_init(&t->target_oid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) ceph_oloc_init(&t->target_oloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) ceph_osds_init(&t->acting);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) ceph_osds_init(&t->up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) t->size = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) t->min_size = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) t->osd = CEPH_HOMELESS_OSD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) static void target_copy(struct ceph_osd_request_target *dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) const struct ceph_osd_request_target *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) ceph_oid_copy(&dest->base_oid, &src->base_oid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) ceph_oloc_copy(&dest->base_oloc, &src->base_oloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) ceph_oid_copy(&dest->target_oid, &src->target_oid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) ceph_oloc_copy(&dest->target_oloc, &src->target_oloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) dest->pgid = src->pgid; /* struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) dest->spgid = src->spgid; /* struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) dest->pg_num = src->pg_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) dest->pg_num_mask = src->pg_num_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) ceph_osds_copy(&dest->acting, &src->acting);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) ceph_osds_copy(&dest->up, &src->up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) dest->size = src->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) dest->min_size = src->min_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) dest->sort_bitwise = src->sort_bitwise;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) dest->recovery_deletes = src->recovery_deletes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) dest->flags = src->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) dest->used_replica = src->used_replica;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) dest->paused = src->paused;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) dest->epoch = src->epoch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) dest->last_force_resend = src->last_force_resend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) dest->osd = src->osd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) static void target_destroy(struct ceph_osd_request_target *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) ceph_oid_destroy(&t->base_oid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) ceph_oloc_destroy(&t->base_oloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) ceph_oid_destroy(&t->target_oid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) ceph_oloc_destroy(&t->target_oloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) * requests
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) static void request_release_checks(struct ceph_osd_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) WARN_ON(!RB_EMPTY_NODE(&req->r_node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) WARN_ON(!RB_EMPTY_NODE(&req->r_mc_node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) WARN_ON(!list_empty(&req->r_private_item));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) WARN_ON(req->r_osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) static void ceph_osdc_release_request(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) struct ceph_osd_request *req = container_of(kref,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) struct ceph_osd_request, r_kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) unsigned int which;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) dout("%s %p (r_request %p r_reply %p)\n", __func__, req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) req->r_request, req->r_reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) request_release_checks(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (req->r_request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) ceph_msg_put(req->r_request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (req->r_reply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ceph_msg_put(req->r_reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) for (which = 0; which < req->r_num_ops; which++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) osd_req_op_data_release(req, which);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) target_destroy(&req->r_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) ceph_put_snap_context(req->r_snapc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (req->r_mempool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) mempool_free(req, req->r_osdc->req_mempool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) else if (req->r_num_ops <= CEPH_OSD_SLAB_OPS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) kmem_cache_free(ceph_osd_request_cache, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) kfree(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) void ceph_osdc_get_request(struct ceph_osd_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) dout("%s %p (was %d)\n", __func__, req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) kref_read(&req->r_kref));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) kref_get(&req->r_kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) EXPORT_SYMBOL(ceph_osdc_get_request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) void ceph_osdc_put_request(struct ceph_osd_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) dout("%s %p (was %d)\n", __func__, req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) kref_read(&req->r_kref));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) kref_put(&req->r_kref, ceph_osdc_release_request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) EXPORT_SYMBOL(ceph_osdc_put_request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static void request_init(struct ceph_osd_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) /* req only, each op is zeroed in osd_req_op_init() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) memset(req, 0, sizeof(*req));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) kref_init(&req->r_kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) init_completion(&req->r_completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) RB_CLEAR_NODE(&req->r_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) RB_CLEAR_NODE(&req->r_mc_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) INIT_LIST_HEAD(&req->r_private_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) target_init(&req->r_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * This is ugly, but it allows us to reuse linger registration and ping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * requests, keeping the structure of the code around send_linger{_ping}()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) * reasonable. Setting up a min_nr=2 mempool for each linger request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) * and dealing with copying ops (this blasts req only, watch op remains
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) * intact) isn't any better.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) static void request_reinit(struct ceph_osd_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) struct ceph_osd_client *osdc = req->r_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) bool mempool = req->r_mempool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) unsigned int num_ops = req->r_num_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) u64 snapid = req->r_snapid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) struct ceph_snap_context *snapc = req->r_snapc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) bool linger = req->r_linger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) struct ceph_msg *request_msg = req->r_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) struct ceph_msg *reply_msg = req->r_reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) dout("%s req %p\n", __func__, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) WARN_ON(kref_read(&req->r_kref) != 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) request_release_checks(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) WARN_ON(kref_read(&request_msg->kref) != 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) WARN_ON(kref_read(&reply_msg->kref) != 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) target_destroy(&req->r_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) request_init(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) req->r_osdc = osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) req->r_mempool = mempool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) req->r_num_ops = num_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) req->r_snapid = snapid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) req->r_snapc = snapc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) req->r_linger = linger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) req->r_request = request_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) req->r_reply = reply_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) struct ceph_snap_context *snapc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) unsigned int num_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) bool use_mempool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) gfp_t gfp_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) struct ceph_osd_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (use_mempool) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) BUG_ON(num_ops > CEPH_OSD_SLAB_OPS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) req = mempool_alloc(osdc->req_mempool, gfp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) } else if (num_ops <= CEPH_OSD_SLAB_OPS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) req = kmem_cache_alloc(ceph_osd_request_cache, gfp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) BUG_ON(num_ops > CEPH_OSD_MAX_OPS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) req = kmalloc(struct_size(req, r_ops, num_ops), gfp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (unlikely(!req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) request_init(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) req->r_osdc = osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) req->r_mempool = use_mempool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) req->r_num_ops = num_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) req->r_snapid = CEPH_NOSNAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) req->r_snapc = ceph_get_snap_context(snapc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) dout("%s req %p\n", __func__, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) EXPORT_SYMBOL(ceph_osdc_alloc_request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) static int ceph_oloc_encoding_size(const struct ceph_object_locator *oloc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) return 8 + 4 + 4 + 4 + (oloc->pool_ns ? oloc->pool_ns->len : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) static int __ceph_osdc_alloc_messages(struct ceph_osd_request *req, gfp_t gfp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) int num_request_data_items,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) int num_reply_data_items)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) struct ceph_osd_client *osdc = req->r_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) struct ceph_msg *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) int msg_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) WARN_ON(req->r_request || req->r_reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) WARN_ON(ceph_oid_empty(&req->r_base_oid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) WARN_ON(ceph_oloc_empty(&req->r_base_oloc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) /* create request message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) msg_size = CEPH_ENCODING_START_BLK_LEN +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) CEPH_PGID_ENCODING_LEN + 1; /* spgid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) msg_size += 4 + 4 + 4; /* hash, osdmap_epoch, flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) msg_size += CEPH_ENCODING_START_BLK_LEN +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) sizeof(struct ceph_osd_reqid); /* reqid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) msg_size += sizeof(struct ceph_blkin_trace_info); /* trace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) msg_size += 4 + sizeof(struct ceph_timespec); /* client_inc, mtime */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) msg_size += CEPH_ENCODING_START_BLK_LEN +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) ceph_oloc_encoding_size(&req->r_base_oloc); /* oloc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) msg_size += 4 + req->r_base_oid.name_len; /* oid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) msg_size += 2 + req->r_num_ops * sizeof(struct ceph_osd_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) msg_size += 8; /* snapid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) msg_size += 8; /* snap_seq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) msg_size += 4 + 8 * (req->r_snapc ? req->r_snapc->num_snaps : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) msg_size += 4 + 8; /* retry_attempt, features */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (req->r_mempool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) msg = ceph_msgpool_get(&osdc->msgpool_op, msg_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) num_request_data_items);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) msg = ceph_msg_new2(CEPH_MSG_OSD_OP, msg_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) num_request_data_items, gfp, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) memset(msg->front.iov_base, 0, msg->front.iov_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) req->r_request = msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) /* create reply message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) msg_size = OSD_OPREPLY_FRONT_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) msg_size += req->r_base_oid.name_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) msg_size += req->r_num_ops * sizeof(struct ceph_osd_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) if (req->r_mempool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) msg = ceph_msgpool_get(&osdc->msgpool_op_reply, msg_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) num_reply_data_items);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) msg = ceph_msg_new2(CEPH_MSG_OSD_OPREPLY, msg_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) num_reply_data_items, gfp, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) req->r_reply = msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) static bool osd_req_opcode_valid(u16 opcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) switch (opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) #define GENERATE_CASE(op, opcode, str) case CEPH_OSD_OP_##op: return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) __CEPH_FORALL_OSD_OPS(GENERATE_CASE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) #undef GENERATE_CASE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) static void get_num_data_items(struct ceph_osd_request *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) int *num_request_data_items,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) int *num_reply_data_items)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) struct ceph_osd_req_op *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) *num_request_data_items = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) *num_reply_data_items = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) for (op = req->r_ops; op != &req->r_ops[req->r_num_ops]; op++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) switch (op->op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) /* request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) case CEPH_OSD_OP_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) case CEPH_OSD_OP_WRITEFULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) case CEPH_OSD_OP_SETXATTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) case CEPH_OSD_OP_CMPXATTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) case CEPH_OSD_OP_NOTIFY_ACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) case CEPH_OSD_OP_COPY_FROM2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) *num_request_data_items += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) /* reply */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) case CEPH_OSD_OP_STAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) case CEPH_OSD_OP_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) case CEPH_OSD_OP_LIST_WATCHERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) *num_reply_data_items += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) /* both */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) case CEPH_OSD_OP_NOTIFY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) *num_request_data_items += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) *num_reply_data_items += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) case CEPH_OSD_OP_CALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) *num_request_data_items += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) *num_reply_data_items += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) WARN_ON(!osd_req_opcode_valid(op->op));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) * oid, oloc and OSD op opcode(s) must be filled in before this function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) * is called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) int ceph_osdc_alloc_messages(struct ceph_osd_request *req, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) int num_request_data_items, num_reply_data_items;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) get_num_data_items(req, &num_request_data_items, &num_reply_data_items);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) return __ceph_osdc_alloc_messages(req, gfp, num_request_data_items,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) num_reply_data_items);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) EXPORT_SYMBOL(ceph_osdc_alloc_messages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) * This is an osd op init function for opcodes that have no data or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) * other information associated with them. It also serves as a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * common init routine for all the other init functions, below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) struct ceph_osd_req_op *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) osd_req_op_init(struct ceph_osd_request *osd_req, unsigned int which,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) u16 opcode, u32 flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) struct ceph_osd_req_op *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) BUG_ON(which >= osd_req->r_num_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) BUG_ON(!osd_req_opcode_valid(opcode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) op = &osd_req->r_ops[which];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) memset(op, 0, sizeof (*op));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) op->op = opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) op->flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) return op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) EXPORT_SYMBOL(osd_req_op_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) void osd_req_op_extent_init(struct ceph_osd_request *osd_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) unsigned int which, u16 opcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) u64 offset, u64 length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) u64 truncate_size, u32 truncate_seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) struct ceph_osd_req_op *op = osd_req_op_init(osd_req, which,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) opcode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) size_t payload_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) BUG_ON(opcode != CEPH_OSD_OP_READ && opcode != CEPH_OSD_OP_WRITE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) opcode != CEPH_OSD_OP_WRITEFULL && opcode != CEPH_OSD_OP_ZERO &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) opcode != CEPH_OSD_OP_TRUNCATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) op->extent.offset = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) op->extent.length = length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) op->extent.truncate_size = truncate_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) op->extent.truncate_seq = truncate_seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (opcode == CEPH_OSD_OP_WRITE || opcode == CEPH_OSD_OP_WRITEFULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) payload_len += length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) op->indata_len = payload_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) EXPORT_SYMBOL(osd_req_op_extent_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) void osd_req_op_extent_update(struct ceph_osd_request *osd_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) unsigned int which, u64 length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) struct ceph_osd_req_op *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) u64 previous;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) BUG_ON(which >= osd_req->r_num_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) op = &osd_req->r_ops[which];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) previous = op->extent.length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (length == previous)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) return; /* Nothing to do */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) BUG_ON(length > previous);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) op->extent.length = length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (op->op == CEPH_OSD_OP_WRITE || op->op == CEPH_OSD_OP_WRITEFULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) op->indata_len -= previous - length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) EXPORT_SYMBOL(osd_req_op_extent_update);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) void osd_req_op_extent_dup_last(struct ceph_osd_request *osd_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) unsigned int which, u64 offset_inc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) struct ceph_osd_req_op *op, *prev_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) BUG_ON(which + 1 >= osd_req->r_num_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) prev_op = &osd_req->r_ops[which];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) op = osd_req_op_init(osd_req, which + 1, prev_op->op, prev_op->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) /* dup previous one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) op->indata_len = prev_op->indata_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) op->outdata_len = prev_op->outdata_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) op->extent = prev_op->extent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) /* adjust offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) op->extent.offset += offset_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) op->extent.length -= offset_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (op->op == CEPH_OSD_OP_WRITE || op->op == CEPH_OSD_OP_WRITEFULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) op->indata_len -= offset_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) EXPORT_SYMBOL(osd_req_op_extent_dup_last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) int osd_req_op_cls_init(struct ceph_osd_request *osd_req, unsigned int which,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) const char *class, const char *method)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) struct ceph_osd_req_op *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) struct ceph_pagelist *pagelist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) size_t payload_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) size_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) op = osd_req_op_init(osd_req, which, CEPH_OSD_OP_CALL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) pagelist = ceph_pagelist_alloc(GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (!pagelist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) op->cls.class_name = class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) size = strlen(class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) BUG_ON(size > (size_t) U8_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) op->cls.class_len = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) ret = ceph_pagelist_append(pagelist, class, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) goto err_pagelist_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) payload_len += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) op->cls.method_name = method;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) size = strlen(method);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) BUG_ON(size > (size_t) U8_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) op->cls.method_len = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) ret = ceph_pagelist_append(pagelist, method, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) goto err_pagelist_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) payload_len += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) osd_req_op_cls_request_info_pagelist(osd_req, which, pagelist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) op->indata_len = payload_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) err_pagelist_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) ceph_pagelist_release(pagelist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) EXPORT_SYMBOL(osd_req_op_cls_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) int osd_req_op_xattr_init(struct ceph_osd_request *osd_req, unsigned int which,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) u16 opcode, const char *name, const void *value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) size_t size, u8 cmp_op, u8 cmp_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) struct ceph_osd_req_op *op = osd_req_op_init(osd_req, which,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) opcode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) struct ceph_pagelist *pagelist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) size_t payload_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) BUG_ON(opcode != CEPH_OSD_OP_SETXATTR && opcode != CEPH_OSD_OP_CMPXATTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) pagelist = ceph_pagelist_alloc(GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) if (!pagelist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) payload_len = strlen(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) op->xattr.name_len = payload_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) ret = ceph_pagelist_append(pagelist, name, payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) goto err_pagelist_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) op->xattr.value_len = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) ret = ceph_pagelist_append(pagelist, value, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) goto err_pagelist_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) payload_len += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) op->xattr.cmp_op = cmp_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) op->xattr.cmp_mode = cmp_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) ceph_osd_data_pagelist_init(&op->xattr.osd_data, pagelist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) op->indata_len = payload_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) err_pagelist_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) ceph_pagelist_release(pagelist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) EXPORT_SYMBOL(osd_req_op_xattr_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) * @watch_opcode: CEPH_OSD_WATCH_OP_*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) static void osd_req_op_watch_init(struct ceph_osd_request *req, int which,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) u64 cookie, u8 watch_opcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) struct ceph_osd_req_op *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) op = osd_req_op_init(req, which, CEPH_OSD_OP_WATCH, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) op->watch.cookie = cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) op->watch.op = watch_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) op->watch.gen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) * @flags: CEPH_OSD_OP_ALLOC_HINT_FLAG_*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) void osd_req_op_alloc_hint_init(struct ceph_osd_request *osd_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) unsigned int which,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) u64 expected_object_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) u64 expected_write_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) u32 flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) struct ceph_osd_req_op *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) op = osd_req_op_init(osd_req, which, CEPH_OSD_OP_SETALLOCHINT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) op->alloc_hint.expected_object_size = expected_object_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) op->alloc_hint.expected_write_size = expected_write_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) op->alloc_hint.flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) * CEPH_OSD_OP_SETALLOCHINT op is advisory and therefore deemed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) * not worth a feature bit. Set FAILOK per-op flag to make
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) * sure older osds don't trip over an unsupported opcode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) op->flags |= CEPH_OSD_OP_FLAG_FAILOK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) EXPORT_SYMBOL(osd_req_op_alloc_hint_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) static void ceph_osdc_msg_data_add(struct ceph_msg *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) struct ceph_osd_data *osd_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) u64 length = ceph_osd_data_length(osd_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) if (osd_data->type == CEPH_OSD_DATA_TYPE_PAGES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) BUG_ON(length > (u64) SIZE_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) if (length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) ceph_msg_data_add_pages(msg, osd_data->pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) length, osd_data->alignment, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) } else if (osd_data->type == CEPH_OSD_DATA_TYPE_PAGELIST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) BUG_ON(!length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) ceph_msg_data_add_pagelist(msg, osd_data->pagelist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) #ifdef CONFIG_BLOCK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) } else if (osd_data->type == CEPH_OSD_DATA_TYPE_BIO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) ceph_msg_data_add_bio(msg, &osd_data->bio_pos, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) } else if (osd_data->type == CEPH_OSD_DATA_TYPE_BVECS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) ceph_msg_data_add_bvecs(msg, &osd_data->bvec_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) BUG_ON(osd_data->type != CEPH_OSD_DATA_TYPE_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) static u32 osd_req_encode_op(struct ceph_osd_op *dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) const struct ceph_osd_req_op *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) switch (src->op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) case CEPH_OSD_OP_STAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) case CEPH_OSD_OP_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) case CEPH_OSD_OP_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) case CEPH_OSD_OP_WRITEFULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) case CEPH_OSD_OP_ZERO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) case CEPH_OSD_OP_TRUNCATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) dst->extent.offset = cpu_to_le64(src->extent.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) dst->extent.length = cpu_to_le64(src->extent.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) dst->extent.truncate_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) cpu_to_le64(src->extent.truncate_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) dst->extent.truncate_seq =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) cpu_to_le32(src->extent.truncate_seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) case CEPH_OSD_OP_CALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) dst->cls.class_len = src->cls.class_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) dst->cls.method_len = src->cls.method_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) dst->cls.indata_len = cpu_to_le32(src->cls.indata_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) case CEPH_OSD_OP_WATCH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) dst->watch.cookie = cpu_to_le64(src->watch.cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) dst->watch.ver = cpu_to_le64(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) dst->watch.op = src->watch.op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) dst->watch.gen = cpu_to_le32(src->watch.gen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) case CEPH_OSD_OP_NOTIFY_ACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) case CEPH_OSD_OP_NOTIFY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) dst->notify.cookie = cpu_to_le64(src->notify.cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) case CEPH_OSD_OP_LIST_WATCHERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) case CEPH_OSD_OP_SETALLOCHINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) dst->alloc_hint.expected_object_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) cpu_to_le64(src->alloc_hint.expected_object_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) dst->alloc_hint.expected_write_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) cpu_to_le64(src->alloc_hint.expected_write_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) dst->alloc_hint.flags = cpu_to_le32(src->alloc_hint.flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) case CEPH_OSD_OP_SETXATTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) case CEPH_OSD_OP_CMPXATTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) dst->xattr.name_len = cpu_to_le32(src->xattr.name_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) dst->xattr.value_len = cpu_to_le32(src->xattr.value_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) dst->xattr.cmp_op = src->xattr.cmp_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) dst->xattr.cmp_mode = src->xattr.cmp_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) case CEPH_OSD_OP_CREATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) case CEPH_OSD_OP_DELETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) case CEPH_OSD_OP_COPY_FROM2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) dst->copy_from.snapid = cpu_to_le64(src->copy_from.snapid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) dst->copy_from.src_version =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) cpu_to_le64(src->copy_from.src_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) dst->copy_from.flags = src->copy_from.flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) dst->copy_from.src_fadvise_flags =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) cpu_to_le32(src->copy_from.src_fadvise_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) pr_err("unsupported osd opcode %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) ceph_osd_op_name(src->op));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) dst->op = cpu_to_le16(src->op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) dst->flags = cpu_to_le32(src->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) dst->payload_len = cpu_to_le32(src->indata_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) return src->indata_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) * build new request AND message, calculate layout, and adjust file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) * extent as needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) * if the file was recently truncated, we include information about its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) * old and new size so that the object can be updated appropriately. (we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) * avoid synchronously deleting truncated objects because it's slow.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) struct ceph_file_layout *layout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) struct ceph_vino vino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) u64 off, u64 *plen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) unsigned int which, int num_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) int opcode, int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) struct ceph_snap_context *snapc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) u32 truncate_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) u64 truncate_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) bool use_mempool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) struct ceph_osd_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) u64 objnum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) u64 objoff = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) u64 objlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) BUG_ON(opcode != CEPH_OSD_OP_READ && opcode != CEPH_OSD_OP_WRITE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) opcode != CEPH_OSD_OP_ZERO && opcode != CEPH_OSD_OP_TRUNCATE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) opcode != CEPH_OSD_OP_CREATE && opcode != CEPH_OSD_OP_DELETE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) req = ceph_osdc_alloc_request(osdc, snapc, num_ops, use_mempool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) if (!req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) r = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) /* calculate max write size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) r = calc_layout(layout, off, plen, &objnum, &objoff, &objlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) if (opcode == CEPH_OSD_OP_CREATE || opcode == CEPH_OSD_OP_DELETE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) osd_req_op_init(req, which, opcode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) u32 object_size = layout->object_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) u32 object_base = off - objoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) if (!(truncate_seq == 1 && truncate_size == -1ULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) if (truncate_size <= object_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) truncate_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) truncate_size -= object_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) if (truncate_size > object_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) truncate_size = object_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) osd_req_op_extent_init(req, which, opcode, objoff, objlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) truncate_size, truncate_seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) req->r_base_oloc.pool = layout->pool_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) req->r_base_oloc.pool_ns = ceph_try_get_string(layout->pool_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) ceph_oid_printf(&req->r_base_oid, "%llx.%08llx", vino.ino, objnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) req->r_flags = flags | osdc->client->options->read_from_replica;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) req->r_snapid = vino.snap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) if (flags & CEPH_OSD_FLAG_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) req->r_data_offset = off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if (num_ops > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) * This is a special case for ceph_writepages_start(), but it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) * also covers ceph_uninline_data(). If more multi-op request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) * use cases emerge, we will need a separate helper.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) r = __ceph_osdc_alloc_messages(req, GFP_NOFS, num_ops, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) r = ceph_osdc_alloc_messages(req, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) return req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) ceph_osdc_put_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) return ERR_PTR(r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) EXPORT_SYMBOL(ceph_osdc_new_request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) * We keep osd requests in an rbtree, sorted by ->r_tid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) DEFINE_RB_FUNCS(request, struct ceph_osd_request, r_tid, r_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) DEFINE_RB_FUNCS(request_mc, struct ceph_osd_request, r_tid, r_mc_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) * Call @fn on each OSD request as long as @fn returns 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) static void for_each_request(struct ceph_osd_client *osdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) int (*fn)(struct ceph_osd_request *req, void *arg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) struct rb_node *n, *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) for (n = rb_first(&osdc->osds); n; n = rb_next(n)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) struct ceph_osd *osd = rb_entry(n, struct ceph_osd, o_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) for (p = rb_first(&osd->o_requests); p; ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) struct ceph_osd_request *req =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) rb_entry(p, struct ceph_osd_request, r_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) p = rb_next(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) if (fn(req, arg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) for (p = rb_first(&osdc->homeless_osd.o_requests); p; ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) struct ceph_osd_request *req =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) rb_entry(p, struct ceph_osd_request, r_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) p = rb_next(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) if (fn(req, arg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) static bool osd_homeless(struct ceph_osd *osd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) return osd->o_osd == CEPH_HOMELESS_OSD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) static bool osd_registered(struct ceph_osd *osd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) verify_osdc_locked(osd->o_osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) return !RB_EMPTY_NODE(&osd->o_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) * Assumes @osd is zero-initialized.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) static void osd_init(struct ceph_osd *osd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) refcount_set(&osd->o_ref, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) RB_CLEAR_NODE(&osd->o_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) osd->o_requests = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) osd->o_linger_requests = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) osd->o_backoff_mappings = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) osd->o_backoffs_by_id = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) INIT_LIST_HEAD(&osd->o_osd_lru);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) INIT_LIST_HEAD(&osd->o_keepalive_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) osd->o_incarnation = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) mutex_init(&osd->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) static void osd_cleanup(struct ceph_osd *osd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) WARN_ON(!RB_EMPTY_NODE(&osd->o_node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) WARN_ON(!RB_EMPTY_ROOT(&osd->o_requests));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) WARN_ON(!RB_EMPTY_ROOT(&osd->o_linger_requests));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) WARN_ON(!RB_EMPTY_ROOT(&osd->o_backoff_mappings));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) WARN_ON(!RB_EMPTY_ROOT(&osd->o_backoffs_by_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) WARN_ON(!list_empty(&osd->o_osd_lru));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) WARN_ON(!list_empty(&osd->o_keepalive_item));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) if (osd->o_auth.authorizer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) WARN_ON(osd_homeless(osd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) ceph_auth_destroy_authorizer(osd->o_auth.authorizer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) * Track open sessions with osds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) static struct ceph_osd *create_osd(struct ceph_osd_client *osdc, int onum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) struct ceph_osd *osd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) WARN_ON(onum == CEPH_HOMELESS_OSD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) osd = kzalloc(sizeof(*osd), GFP_NOIO | __GFP_NOFAIL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) osd_init(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) osd->o_osdc = osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) osd->o_osd = onum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) ceph_con_init(&osd->o_con, osd, &osd_con_ops, &osdc->client->msgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) return osd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) static struct ceph_osd *get_osd(struct ceph_osd *osd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) if (refcount_inc_not_zero(&osd->o_ref)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) dout("get_osd %p %d -> %d\n", osd, refcount_read(&osd->o_ref)-1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) refcount_read(&osd->o_ref));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) return osd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) dout("get_osd %p FAIL\n", osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) static void put_osd(struct ceph_osd *osd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) dout("put_osd %p %d -> %d\n", osd, refcount_read(&osd->o_ref),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) refcount_read(&osd->o_ref) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) if (refcount_dec_and_test(&osd->o_ref)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) osd_cleanup(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) kfree(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) DEFINE_RB_FUNCS(osd, struct ceph_osd, o_osd, o_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) static void __move_osd_to_lru(struct ceph_osd *osd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) struct ceph_osd_client *osdc = osd->o_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) dout("%s osd %p osd%d\n", __func__, osd, osd->o_osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) BUG_ON(!list_empty(&osd->o_osd_lru));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) spin_lock(&osdc->osd_lru_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) list_add_tail(&osd->o_osd_lru, &osdc->osd_lru);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) spin_unlock(&osdc->osd_lru_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) osd->lru_ttl = jiffies + osdc->client->options->osd_idle_ttl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) static void maybe_move_osd_to_lru(struct ceph_osd *osd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) if (RB_EMPTY_ROOT(&osd->o_requests) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) RB_EMPTY_ROOT(&osd->o_linger_requests))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) __move_osd_to_lru(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) static void __remove_osd_from_lru(struct ceph_osd *osd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) struct ceph_osd_client *osdc = osd->o_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) dout("%s osd %p osd%d\n", __func__, osd, osd->o_osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) spin_lock(&osdc->osd_lru_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) if (!list_empty(&osd->o_osd_lru))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) list_del_init(&osd->o_osd_lru);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) spin_unlock(&osdc->osd_lru_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) * Close the connection and assign any leftover requests to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) * homeless session.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) static void close_osd(struct ceph_osd *osd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) struct ceph_osd_client *osdc = osd->o_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) struct rb_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) verify_osdc_wrlocked(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) dout("%s osd %p osd%d\n", __func__, osd, osd->o_osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) ceph_con_close(&osd->o_con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) for (n = rb_first(&osd->o_requests); n; ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) struct ceph_osd_request *req =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) rb_entry(n, struct ceph_osd_request, r_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) n = rb_next(n); /* unlink_request() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) dout(" reassigning req %p tid %llu\n", req, req->r_tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) unlink_request(osd, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) link_request(&osdc->homeless_osd, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) for (n = rb_first(&osd->o_linger_requests); n; ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) struct ceph_osd_linger_request *lreq =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) rb_entry(n, struct ceph_osd_linger_request, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) n = rb_next(n); /* unlink_linger() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) dout(" reassigning lreq %p linger_id %llu\n", lreq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) lreq->linger_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) unlink_linger(osd, lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) link_linger(&osdc->homeless_osd, lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) clear_backoffs(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) __remove_osd_from_lru(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) erase_osd(&osdc->osds, osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) put_osd(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) * reset osd connect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) static int reopen_osd(struct ceph_osd *osd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) struct ceph_entity_addr *peer_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) dout("%s osd %p osd%d\n", __func__, osd, osd->o_osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) if (RB_EMPTY_ROOT(&osd->o_requests) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) RB_EMPTY_ROOT(&osd->o_linger_requests)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) close_osd(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) peer_addr = &osd->o_osdc->osdmap->osd_addr[osd->o_osd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) if (!memcmp(peer_addr, &osd->o_con.peer_addr, sizeof (*peer_addr)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) !ceph_con_opened(&osd->o_con)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) struct rb_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) dout("osd addr hasn't changed and connection never opened, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) "letting msgr retry\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) /* touch each r_stamp for handle_timeout()'s benfit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) for (n = rb_first(&osd->o_requests); n; n = rb_next(n)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) struct ceph_osd_request *req =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) rb_entry(n, struct ceph_osd_request, r_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) req->r_stamp = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) ceph_con_close(&osd->o_con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) ceph_con_open(&osd->o_con, CEPH_ENTITY_TYPE_OSD, osd->o_osd, peer_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) osd->o_incarnation++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) static struct ceph_osd *lookup_create_osd(struct ceph_osd_client *osdc, int o,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) bool wrlocked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) struct ceph_osd *osd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) if (wrlocked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) verify_osdc_wrlocked(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) verify_osdc_locked(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) if (o != CEPH_HOMELESS_OSD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) osd = lookup_osd(&osdc->osds, o);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) osd = &osdc->homeless_osd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) if (!osd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) if (!wrlocked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) return ERR_PTR(-EAGAIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) osd = create_osd(osdc, o);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) insert_osd(&osdc->osds, osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) ceph_con_open(&osd->o_con, CEPH_ENTITY_TYPE_OSD, osd->o_osd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) &osdc->osdmap->osd_addr[osd->o_osd]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) dout("%s osdc %p osd%d -> osd %p\n", __func__, osdc, o, osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) return osd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) * Create request <-> OSD session relation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) * @req has to be assigned a tid, @osd may be homeless.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) static void link_request(struct ceph_osd *osd, struct ceph_osd_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) verify_osd_locked(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) WARN_ON(!req->r_tid || req->r_osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) dout("%s osd %p osd%d req %p tid %llu\n", __func__, osd, osd->o_osd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) req, req->r_tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) if (!osd_homeless(osd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) __remove_osd_from_lru(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) atomic_inc(&osd->o_osdc->num_homeless);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) get_osd(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) insert_request(&osd->o_requests, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) req->r_osd = osd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) static void unlink_request(struct ceph_osd *osd, struct ceph_osd_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) verify_osd_locked(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) WARN_ON(req->r_osd != osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) dout("%s osd %p osd%d req %p tid %llu\n", __func__, osd, osd->o_osd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) req, req->r_tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) req->r_osd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) erase_request(&osd->o_requests, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) put_osd(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) if (!osd_homeless(osd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) maybe_move_osd_to_lru(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) atomic_dec(&osd->o_osdc->num_homeless);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) static bool __pool_full(struct ceph_pg_pool_info *pi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) return pi->flags & CEPH_POOL_FLAG_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) static bool have_pool_full(struct ceph_osd_client *osdc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) struct rb_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) for (n = rb_first(&osdc->osdmap->pg_pools); n; n = rb_next(n)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) struct ceph_pg_pool_info *pi =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) rb_entry(n, struct ceph_pg_pool_info, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) if (__pool_full(pi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) static bool pool_full(struct ceph_osd_client *osdc, s64 pool_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) struct ceph_pg_pool_info *pi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) pi = ceph_pg_pool_by_id(osdc->osdmap, pool_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) if (!pi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) return __pool_full(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) * Returns whether a request should be blocked from being sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) * based on the current osdmap and osd_client settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) static bool target_should_be_paused(struct ceph_osd_client *osdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) const struct ceph_osd_request_target *t,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) struct ceph_pg_pool_info *pi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) bool pauserd = ceph_osdmap_flag(osdc, CEPH_OSDMAP_PAUSERD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) bool pausewr = ceph_osdmap_flag(osdc, CEPH_OSDMAP_PAUSEWR) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) ceph_osdmap_flag(osdc, CEPH_OSDMAP_FULL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) __pool_full(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) WARN_ON(pi->id != t->target_oloc.pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) return ((t->flags & CEPH_OSD_FLAG_READ) && pauserd) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) ((t->flags & CEPH_OSD_FLAG_WRITE) && pausewr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) (osdc->osdmap->epoch < osdc->epoch_barrier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) static int pick_random_replica(const struct ceph_osds *acting)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) int i = prandom_u32() % acting->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) dout("%s picked osd%d, primary osd%d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) acting->osds[i], acting->primary);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) * Picks the closest replica based on client's location given by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) * crush_location option. Prefers the primary if the locality is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) * the same.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) static int pick_closest_replica(struct ceph_osd_client *osdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) const struct ceph_osds *acting)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) struct ceph_options *opt = osdc->client->options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) int best_i, best_locality;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) int i = 0, locality;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) locality = ceph_get_crush_locality(osdc->osdmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) acting->osds[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) &opt->crush_locs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) if (i == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) (locality >= 0 && best_locality < 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) (locality >= 0 && best_locality >= 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) locality < best_locality)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) best_i = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) best_locality = locality;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) } while (++i < acting->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) dout("%s picked osd%d with locality %d, primary osd%d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) acting->osds[best_i], best_locality, acting->primary);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) return best_i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) enum calc_target_result {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) CALC_TARGET_NO_ACTION = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) CALC_TARGET_NEED_RESEND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) CALC_TARGET_POOL_DNE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) static enum calc_target_result calc_target(struct ceph_osd_client *osdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) struct ceph_osd_request_target *t,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) bool any_change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) struct ceph_pg_pool_info *pi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) struct ceph_pg pgid, last_pgid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) struct ceph_osds up, acting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) bool is_read = t->flags & CEPH_OSD_FLAG_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) bool is_write = t->flags & CEPH_OSD_FLAG_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) bool force_resend = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) bool unpaused = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) bool legacy_change = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) bool split = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) bool sort_bitwise = ceph_osdmap_flag(osdc, CEPH_OSDMAP_SORTBITWISE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) bool recovery_deletes = ceph_osdmap_flag(osdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) CEPH_OSDMAP_RECOVERY_DELETES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) enum calc_target_result ct_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) t->epoch = osdc->osdmap->epoch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) pi = ceph_pg_pool_by_id(osdc->osdmap, t->base_oloc.pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) if (!pi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) t->osd = CEPH_HOMELESS_OSD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) ct_res = CALC_TARGET_POOL_DNE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) if (osdc->osdmap->epoch == pi->last_force_request_resend) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) if (t->last_force_resend < pi->last_force_request_resend) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) t->last_force_resend = pi->last_force_request_resend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) force_resend = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) } else if (t->last_force_resend == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) force_resend = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) /* apply tiering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) ceph_oid_copy(&t->target_oid, &t->base_oid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) ceph_oloc_copy(&t->target_oloc, &t->base_oloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) if ((t->flags & CEPH_OSD_FLAG_IGNORE_OVERLAY) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) if (is_read && pi->read_tier >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) t->target_oloc.pool = pi->read_tier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) if (is_write && pi->write_tier >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) t->target_oloc.pool = pi->write_tier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) pi = ceph_pg_pool_by_id(osdc->osdmap, t->target_oloc.pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) if (!pi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) t->osd = CEPH_HOMELESS_OSD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) ct_res = CALC_TARGET_POOL_DNE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) __ceph_object_locator_to_pg(pi, &t->target_oid, &t->target_oloc, &pgid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) last_pgid.pool = pgid.pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) last_pgid.seed = ceph_stable_mod(pgid.seed, t->pg_num, t->pg_num_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) ceph_pg_to_up_acting_osds(osdc->osdmap, pi, &pgid, &up, &acting);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) if (any_change &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) ceph_is_new_interval(&t->acting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) &acting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) &t->up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) &up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) t->size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) pi->size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) t->min_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) pi->min_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) t->pg_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) pi->pg_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) t->sort_bitwise,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) sort_bitwise,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) t->recovery_deletes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) recovery_deletes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) &last_pgid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) force_resend = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) if (t->paused && !target_should_be_paused(osdc, t, pi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) t->paused = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) unpaused = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) legacy_change = ceph_pg_compare(&t->pgid, &pgid) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) ceph_osds_changed(&t->acting, &acting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) t->used_replica || any_change);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) if (t->pg_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) split = ceph_pg_is_split(&last_pgid, t->pg_num, pi->pg_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) if (legacy_change || force_resend || split) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) t->pgid = pgid; /* struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) ceph_pg_to_primary_shard(osdc->osdmap, pi, &pgid, &t->spgid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) ceph_osds_copy(&t->acting, &acting);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) ceph_osds_copy(&t->up, &up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) t->size = pi->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) t->min_size = pi->min_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) t->pg_num = pi->pg_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) t->pg_num_mask = pi->pg_num_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) t->sort_bitwise = sort_bitwise;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) t->recovery_deletes = recovery_deletes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) if ((t->flags & (CEPH_OSD_FLAG_BALANCE_READS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) CEPH_OSD_FLAG_LOCALIZE_READS)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) !is_write && pi->type == CEPH_POOL_TYPE_REP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) acting.size > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) int pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) WARN_ON(!is_read || acting.osds[0] != acting.primary);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) if (t->flags & CEPH_OSD_FLAG_BALANCE_READS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) pos = pick_random_replica(&acting);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) pos = pick_closest_replica(osdc, &acting);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) t->osd = acting.osds[pos];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) t->used_replica = pos > 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) t->osd = acting.primary;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) t->used_replica = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) if (unpaused || legacy_change || force_resend || split)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) ct_res = CALC_TARGET_NEED_RESEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) ct_res = CALC_TARGET_NO_ACTION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) dout("%s t %p -> %d%d%d%d ct_res %d osd%d\n", __func__, t, unpaused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) legacy_change, force_resend, split, ct_res, t->osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) return ct_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) static struct ceph_spg_mapping *alloc_spg_mapping(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) struct ceph_spg_mapping *spg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) spg = kmalloc(sizeof(*spg), GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) if (!spg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) RB_CLEAR_NODE(&spg->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) spg->backoffs = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) return spg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) static void free_spg_mapping(struct ceph_spg_mapping *spg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) WARN_ON(!RB_EMPTY_NODE(&spg->node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) WARN_ON(!RB_EMPTY_ROOT(&spg->backoffs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) kfree(spg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) * rbtree of ceph_spg_mapping for handling map<spg_t, ...>, similar to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) * ceph_pg_mapping. Used to track OSD backoffs -- a backoff [range] is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) * defined only within a specific spgid; it does not pass anything to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) * children on split, or to another primary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) DEFINE_RB_FUNCS2(spg_mapping, struct ceph_spg_mapping, spgid, ceph_spg_compare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) RB_BYPTR, const struct ceph_spg *, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) static u64 hoid_get_bitwise_key(const struct ceph_hobject_id *hoid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) return hoid->is_max ? 0x100000000ull : hoid->hash_reverse_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) static void hoid_get_effective_key(const struct ceph_hobject_id *hoid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) void **pkey, size_t *pkey_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) if (hoid->key_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) *pkey = hoid->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) *pkey_len = hoid->key_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) *pkey = hoid->oid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) *pkey_len = hoid->oid_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) static int compare_names(const void *name1, size_t name1_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) const void *name2, size_t name2_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) ret = memcmp(name1, name2, min(name1_len, name2_len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) if (name1_len < name2_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) else if (name1_len > name2_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) static int hoid_compare(const struct ceph_hobject_id *lhs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) const struct ceph_hobject_id *rhs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) void *effective_key1, *effective_key2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) size_t effective_key1_len, effective_key2_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) if (lhs->is_max < rhs->is_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) if (lhs->is_max > rhs->is_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) if (lhs->pool < rhs->pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) if (lhs->pool > rhs->pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) if (hoid_get_bitwise_key(lhs) < hoid_get_bitwise_key(rhs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) if (hoid_get_bitwise_key(lhs) > hoid_get_bitwise_key(rhs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) ret = compare_names(lhs->nspace, lhs->nspace_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) rhs->nspace, rhs->nspace_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) hoid_get_effective_key(lhs, &effective_key1, &effective_key1_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) hoid_get_effective_key(rhs, &effective_key2, &effective_key2_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) ret = compare_names(effective_key1, effective_key1_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) effective_key2, effective_key2_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) ret = compare_names(lhs->oid, lhs->oid_len, rhs->oid, rhs->oid_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) if (lhs->snapid < rhs->snapid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) if (lhs->snapid > rhs->snapid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) * For decoding ->begin and ->end of MOSDBackoff only -- no MIN/MAX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) * compat stuff here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) * Assumes @hoid is zero-initialized.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) static int decode_hoid(void **p, void *end, struct ceph_hobject_id *hoid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) u8 struct_v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) u32 struct_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) ret = ceph_start_decoding(p, end, 4, "hobject_t", &struct_v,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) &struct_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) if (struct_v < 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) pr_err("got struct_v %d < 4 of hobject_t\n", struct_v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) goto e_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) hoid->key = ceph_extract_encoded_string(p, end, &hoid->key_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) if (IS_ERR(hoid->key)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) ret = PTR_ERR(hoid->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) hoid->key = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) hoid->oid = ceph_extract_encoded_string(p, end, &hoid->oid_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) if (IS_ERR(hoid->oid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) ret = PTR_ERR(hoid->oid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) hoid->oid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) ceph_decode_64_safe(p, end, hoid->snapid, e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) ceph_decode_32_safe(p, end, hoid->hash, e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) ceph_decode_8_safe(p, end, hoid->is_max, e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) hoid->nspace = ceph_extract_encoded_string(p, end, &hoid->nspace_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) if (IS_ERR(hoid->nspace)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) ret = PTR_ERR(hoid->nspace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) hoid->nspace = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) ceph_decode_64_safe(p, end, hoid->pool, e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) ceph_hoid_build_hash_cache(hoid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) e_inval:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) static int hoid_encoding_size(const struct ceph_hobject_id *hoid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) return 8 + 4 + 1 + 8 + /* snapid, hash, is_max, pool */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 4 + hoid->key_len + 4 + hoid->oid_len + 4 + hoid->nspace_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) static void encode_hoid(void **p, void *end, const struct ceph_hobject_id *hoid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) ceph_start_encoding(p, 4, 3, hoid_encoding_size(hoid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) ceph_encode_string(p, end, hoid->key, hoid->key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) ceph_encode_string(p, end, hoid->oid, hoid->oid_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) ceph_encode_64(p, hoid->snapid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) ceph_encode_32(p, hoid->hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) ceph_encode_8(p, hoid->is_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) ceph_encode_string(p, end, hoid->nspace, hoid->nspace_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) ceph_encode_64(p, hoid->pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) static void free_hoid(struct ceph_hobject_id *hoid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) if (hoid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) kfree(hoid->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) kfree(hoid->oid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) kfree(hoid->nspace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) kfree(hoid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) static struct ceph_osd_backoff *alloc_backoff(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) struct ceph_osd_backoff *backoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) backoff = kzalloc(sizeof(*backoff), GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) if (!backoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) RB_CLEAR_NODE(&backoff->spg_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) RB_CLEAR_NODE(&backoff->id_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) return backoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) static void free_backoff(struct ceph_osd_backoff *backoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) WARN_ON(!RB_EMPTY_NODE(&backoff->spg_node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) WARN_ON(!RB_EMPTY_NODE(&backoff->id_node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) free_hoid(backoff->begin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) free_hoid(backoff->end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) kfree(backoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) * Within a specific spgid, backoffs are managed by ->begin hoid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) DEFINE_RB_INSDEL_FUNCS2(backoff, struct ceph_osd_backoff, begin, hoid_compare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) RB_BYVAL, spg_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) static struct ceph_osd_backoff *lookup_containing_backoff(struct rb_root *root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) const struct ceph_hobject_id *hoid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) struct rb_node *n = root->rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) while (n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) struct ceph_osd_backoff *cur =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) rb_entry(n, struct ceph_osd_backoff, spg_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) int cmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) cmp = hoid_compare(hoid, cur->begin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) if (cmp < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) n = n->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) } else if (cmp > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) if (hoid_compare(hoid, cur->end) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) return cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) n = n->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) return cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) * Each backoff has a unique id within its OSD session.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) DEFINE_RB_FUNCS(backoff_by_id, struct ceph_osd_backoff, id, id_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) static void clear_backoffs(struct ceph_osd *osd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) while (!RB_EMPTY_ROOT(&osd->o_backoff_mappings)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) struct ceph_spg_mapping *spg =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) rb_entry(rb_first(&osd->o_backoff_mappings),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) struct ceph_spg_mapping, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) while (!RB_EMPTY_ROOT(&spg->backoffs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) struct ceph_osd_backoff *backoff =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) rb_entry(rb_first(&spg->backoffs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) struct ceph_osd_backoff, spg_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) erase_backoff(&spg->backoffs, backoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) erase_backoff_by_id(&osd->o_backoffs_by_id, backoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) free_backoff(backoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) erase_spg_mapping(&osd->o_backoff_mappings, spg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) free_spg_mapping(spg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) * Set up a temporary, non-owning view into @t.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) static void hoid_fill_from_target(struct ceph_hobject_id *hoid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) const struct ceph_osd_request_target *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) hoid->key = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) hoid->key_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) hoid->oid = t->target_oid.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) hoid->oid_len = t->target_oid.name_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) hoid->snapid = CEPH_NOSNAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) hoid->hash = t->pgid.seed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) hoid->is_max = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) if (t->target_oloc.pool_ns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) hoid->nspace = t->target_oloc.pool_ns->str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) hoid->nspace_len = t->target_oloc.pool_ns->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) hoid->nspace = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) hoid->nspace_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) hoid->pool = t->target_oloc.pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) ceph_hoid_build_hash_cache(hoid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) static bool should_plug_request(struct ceph_osd_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) struct ceph_osd *osd = req->r_osd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) struct ceph_spg_mapping *spg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) struct ceph_osd_backoff *backoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) struct ceph_hobject_id hoid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) spg = lookup_spg_mapping(&osd->o_backoff_mappings, &req->r_t.spgid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) if (!spg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) hoid_fill_from_target(&hoid, &req->r_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) backoff = lookup_containing_backoff(&spg->backoffs, &hoid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) if (!backoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) dout("%s req %p tid %llu backoff osd%d spgid %llu.%xs%d id %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) __func__, req, req->r_tid, osd->o_osd, backoff->spgid.pgid.pool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) backoff->spgid.pgid.seed, backoff->spgid.shard, backoff->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) * Keep get_num_data_items() in sync with this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) static void setup_request_data(struct ceph_osd_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) struct ceph_msg *request_msg = req->r_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) struct ceph_msg *reply_msg = req->r_reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) struct ceph_osd_req_op *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) if (req->r_request->num_data_items || req->r_reply->num_data_items)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) WARN_ON(request_msg->data_length || reply_msg->data_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) for (op = req->r_ops; op != &req->r_ops[req->r_num_ops]; op++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) switch (op->op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) /* request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) case CEPH_OSD_OP_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) case CEPH_OSD_OP_WRITEFULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) WARN_ON(op->indata_len != op->extent.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) ceph_osdc_msg_data_add(request_msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) &op->extent.osd_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) case CEPH_OSD_OP_SETXATTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) case CEPH_OSD_OP_CMPXATTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) WARN_ON(op->indata_len != op->xattr.name_len +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) op->xattr.value_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) ceph_osdc_msg_data_add(request_msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) &op->xattr.osd_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) case CEPH_OSD_OP_NOTIFY_ACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) ceph_osdc_msg_data_add(request_msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) &op->notify_ack.request_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) case CEPH_OSD_OP_COPY_FROM2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) ceph_osdc_msg_data_add(request_msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) &op->copy_from.osd_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) /* reply */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) case CEPH_OSD_OP_STAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) ceph_osdc_msg_data_add(reply_msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) &op->raw_data_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) case CEPH_OSD_OP_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) ceph_osdc_msg_data_add(reply_msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) &op->extent.osd_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) case CEPH_OSD_OP_LIST_WATCHERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) ceph_osdc_msg_data_add(reply_msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) &op->list_watchers.response_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) /* both */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) case CEPH_OSD_OP_CALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) WARN_ON(op->indata_len != op->cls.class_len +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) op->cls.method_len +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) op->cls.indata_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) ceph_osdc_msg_data_add(request_msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) &op->cls.request_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) /* optional, can be NONE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) ceph_osdc_msg_data_add(request_msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) &op->cls.request_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) /* optional, can be NONE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) ceph_osdc_msg_data_add(reply_msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) &op->cls.response_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) case CEPH_OSD_OP_NOTIFY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) ceph_osdc_msg_data_add(request_msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) &op->notify.request_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) ceph_osdc_msg_data_add(reply_msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) &op->notify.response_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) static void encode_pgid(void **p, const struct ceph_pg *pgid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) ceph_encode_8(p, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) ceph_encode_64(p, pgid->pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) ceph_encode_32(p, pgid->seed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) ceph_encode_32(p, -1); /* preferred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) static void encode_spgid(void **p, const struct ceph_spg *spgid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) ceph_start_encoding(p, 1, 1, CEPH_PGID_ENCODING_LEN + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) encode_pgid(p, &spgid->pgid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) ceph_encode_8(p, spgid->shard);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) static void encode_oloc(void **p, void *end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) const struct ceph_object_locator *oloc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) ceph_start_encoding(p, 5, 4, ceph_oloc_encoding_size(oloc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) ceph_encode_64(p, oloc->pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) ceph_encode_32(p, -1); /* preferred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) ceph_encode_32(p, 0); /* key len */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) if (oloc->pool_ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) ceph_encode_string(p, end, oloc->pool_ns->str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) oloc->pool_ns->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) ceph_encode_32(p, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) static void encode_request_partial(struct ceph_osd_request *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) struct ceph_msg *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) void *p = msg->front.iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) void *const end = p + msg->front_alloc_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) u32 data_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) if (req->r_flags & CEPH_OSD_FLAG_WRITE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) /* snapshots aren't writeable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) WARN_ON(req->r_snapid != CEPH_NOSNAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) WARN_ON(req->r_mtime.tv_sec || req->r_mtime.tv_nsec ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) req->r_data_offset || req->r_snapc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) setup_request_data(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) encode_spgid(&p, &req->r_t.spgid); /* actual spg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) ceph_encode_32(&p, req->r_t.pgid.seed); /* raw hash */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) ceph_encode_32(&p, req->r_osdc->osdmap->epoch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) ceph_encode_32(&p, req->r_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) /* reqid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) ceph_start_encoding(&p, 2, 2, sizeof(struct ceph_osd_reqid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) memset(p, 0, sizeof(struct ceph_osd_reqid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) p += sizeof(struct ceph_osd_reqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) /* trace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) memset(p, 0, sizeof(struct ceph_blkin_trace_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) p += sizeof(struct ceph_blkin_trace_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) ceph_encode_32(&p, 0); /* client_inc, always 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) ceph_encode_timespec64(p, &req->r_mtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) p += sizeof(struct ceph_timespec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) encode_oloc(&p, end, &req->r_t.target_oloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) ceph_encode_string(&p, end, req->r_t.target_oid.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) req->r_t.target_oid.name_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) /* ops, can imply data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) ceph_encode_16(&p, req->r_num_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) for (i = 0; i < req->r_num_ops; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) data_len += osd_req_encode_op(p, &req->r_ops[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) p += sizeof(struct ceph_osd_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) ceph_encode_64(&p, req->r_snapid); /* snapid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) if (req->r_snapc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) ceph_encode_64(&p, req->r_snapc->seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) ceph_encode_32(&p, req->r_snapc->num_snaps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) for (i = 0; i < req->r_snapc->num_snaps; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) ceph_encode_64(&p, req->r_snapc->snaps[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) ceph_encode_64(&p, 0); /* snap_seq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) ceph_encode_32(&p, 0); /* snaps len */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) ceph_encode_32(&p, req->r_attempts); /* retry_attempt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) BUG_ON(p > end - 8); /* space for features */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) msg->hdr.version = cpu_to_le16(8); /* MOSDOp v8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) /* front_len is finalized in encode_request_finish() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) msg->front.iov_len = p - msg->front.iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) msg->hdr.front_len = cpu_to_le32(msg->front.iov_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) msg->hdr.data_len = cpu_to_le32(data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) * The header "data_off" is a hint to the receiver allowing it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) * to align received data into its buffers such that there's no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) * need to re-copy it before writing it to disk (direct I/O).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) msg->hdr.data_off = cpu_to_le16(req->r_data_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) dout("%s req %p msg %p oid %s oid_len %d\n", __func__, req, msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) req->r_t.target_oid.name, req->r_t.target_oid.name_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) static void encode_request_finish(struct ceph_msg *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) void *p = msg->front.iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) void *const partial_end = p + msg->front.iov_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) void *const end = p + msg->front_alloc_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) if (CEPH_HAVE_FEATURE(msg->con->peer_features, RESEND_ON_SPLIT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) /* luminous OSD -- encode features and be done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) p = partial_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) ceph_encode_64(&p, msg->con->peer_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) char spgid[CEPH_ENCODING_START_BLK_LEN +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) CEPH_PGID_ENCODING_LEN + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) __le32 hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) __le32 epoch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) __le32 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) char reqid[CEPH_ENCODING_START_BLK_LEN +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) sizeof(struct ceph_osd_reqid)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) char trace[sizeof(struct ceph_blkin_trace_info)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) __le32 client_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) struct ceph_timespec mtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) } __packed head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) struct ceph_pg pgid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) void *oloc, *oid, *tail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) int oloc_len, oid_len, tail_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) * Pre-luminous OSD -- reencode v8 into v4 using @head
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) * as a temporary buffer. Encode the raw PG; the rest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) * is just a matter of moving oloc, oid and tail blobs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) * around.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) memcpy(&head, p, sizeof(head));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) p += sizeof(head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) oloc = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) p += CEPH_ENCODING_START_BLK_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) pgid.pool = ceph_decode_64(&p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) p += 4 + 4; /* preferred, key len */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) len = ceph_decode_32(&p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) p += len; /* nspace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) oloc_len = p - oloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) oid = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) len = ceph_decode_32(&p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) p += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) oid_len = p - oid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) tail = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) tail_len = partial_end - p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) p = msg->front.iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) ceph_encode_copy(&p, &head.client_inc, sizeof(head.client_inc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) ceph_encode_copy(&p, &head.epoch, sizeof(head.epoch));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) ceph_encode_copy(&p, &head.flags, sizeof(head.flags));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) ceph_encode_copy(&p, &head.mtime, sizeof(head.mtime));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) /* reassert_version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) memset(p, 0, sizeof(struct ceph_eversion));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) p += sizeof(struct ceph_eversion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) BUG_ON(p >= oloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) memmove(p, oloc, oloc_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) p += oloc_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) pgid.seed = le32_to_cpu(head.hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) encode_pgid(&p, &pgid); /* raw pg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) BUG_ON(p >= oid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) memmove(p, oid, oid_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) p += oid_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) /* tail -- ops, snapid, snapc, retry_attempt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) BUG_ON(p >= tail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) memmove(p, tail, tail_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) p += tail_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) msg->hdr.version = cpu_to_le16(4); /* MOSDOp v4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) BUG_ON(p > end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) msg->front.iov_len = p - msg->front.iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) msg->hdr.front_len = cpu_to_le32(msg->front.iov_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) dout("%s msg %p tid %llu %u+%u+%u v%d\n", __func__, msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) le64_to_cpu(msg->hdr.tid), le32_to_cpu(msg->hdr.front_len),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) le32_to_cpu(msg->hdr.middle_len), le32_to_cpu(msg->hdr.data_len),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) le16_to_cpu(msg->hdr.version));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) * @req has to be assigned a tid and registered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) static void send_request(struct ceph_osd_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) struct ceph_osd *osd = req->r_osd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) verify_osd_locked(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) WARN_ON(osd->o_osd != req->r_t.osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) /* backoff? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) if (should_plug_request(req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) * We may have a previously queued request message hanging
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) * around. Cancel it to avoid corrupting the msgr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) if (req->r_sent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) ceph_msg_revoke(req->r_request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) req->r_flags |= CEPH_OSD_FLAG_KNOWN_REDIR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) if (req->r_attempts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) req->r_flags |= CEPH_OSD_FLAG_RETRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) WARN_ON(req->r_flags & CEPH_OSD_FLAG_RETRY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) encode_request_partial(req, req->r_request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) dout("%s req %p tid %llu to pgid %llu.%x spgid %llu.%xs%d osd%d e%u flags 0x%x attempt %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) __func__, req, req->r_tid, req->r_t.pgid.pool, req->r_t.pgid.seed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) req->r_t.spgid.pgid.pool, req->r_t.spgid.pgid.seed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) req->r_t.spgid.shard, osd->o_osd, req->r_t.epoch, req->r_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) req->r_attempts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) req->r_t.paused = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) req->r_stamp = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) req->r_attempts++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) req->r_sent = osd->o_incarnation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) req->r_request->hdr.tid = cpu_to_le64(req->r_tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) ceph_con_send(&osd->o_con, ceph_msg_get(req->r_request));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) static void maybe_request_map(struct ceph_osd_client *osdc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) bool continuous = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) verify_osdc_locked(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) WARN_ON(!osdc->osdmap->epoch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) if (ceph_osdmap_flag(osdc, CEPH_OSDMAP_FULL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) ceph_osdmap_flag(osdc, CEPH_OSDMAP_PAUSERD) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) ceph_osdmap_flag(osdc, CEPH_OSDMAP_PAUSEWR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) dout("%s osdc %p continuous\n", __func__, osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) continuous = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) dout("%s osdc %p onetime\n", __func__, osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) if (ceph_monc_want_map(&osdc->client->monc, CEPH_SUB_OSDMAP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) osdc->osdmap->epoch + 1, continuous))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) ceph_monc_renew_subs(&osdc->client->monc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) static void complete_request(struct ceph_osd_request *req, int err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) static void send_map_check(struct ceph_osd_request *req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) static void __submit_request(struct ceph_osd_request *req, bool wrlocked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) struct ceph_osd_client *osdc = req->r_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) struct ceph_osd *osd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) enum calc_target_result ct_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) bool need_send = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) bool promoted = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) WARN_ON(req->r_tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) dout("%s req %p wrlocked %d\n", __func__, req, wrlocked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) ct_res = calc_target(osdc, &req->r_t, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) if (ct_res == CALC_TARGET_POOL_DNE && !wrlocked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) goto promote;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) osd = lookup_create_osd(osdc, req->r_t.osd, wrlocked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) if (IS_ERR(osd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) WARN_ON(PTR_ERR(osd) != -EAGAIN || wrlocked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) goto promote;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) if (osdc->abort_err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) dout("req %p abort_err %d\n", req, osdc->abort_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) err = osdc->abort_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) } else if (osdc->osdmap->epoch < osdc->epoch_barrier) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) dout("req %p epoch %u barrier %u\n", req, osdc->osdmap->epoch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) osdc->epoch_barrier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) req->r_t.paused = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) maybe_request_map(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) } else if ((req->r_flags & CEPH_OSD_FLAG_WRITE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) ceph_osdmap_flag(osdc, CEPH_OSDMAP_PAUSEWR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) dout("req %p pausewr\n", req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) req->r_t.paused = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) maybe_request_map(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) } else if ((req->r_flags & CEPH_OSD_FLAG_READ) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) ceph_osdmap_flag(osdc, CEPH_OSDMAP_PAUSERD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) dout("req %p pauserd\n", req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) req->r_t.paused = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) maybe_request_map(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) } else if ((req->r_flags & CEPH_OSD_FLAG_WRITE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) !(req->r_flags & (CEPH_OSD_FLAG_FULL_TRY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) CEPH_OSD_FLAG_FULL_FORCE)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) (ceph_osdmap_flag(osdc, CEPH_OSDMAP_FULL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) pool_full(osdc, req->r_t.base_oloc.pool))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) dout("req %p full/pool_full\n", req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) if (ceph_test_opt(osdc->client, ABORT_ON_FULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) err = -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) pr_warn_ratelimited("FULL or reached pool quota\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) req->r_t.paused = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) maybe_request_map(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) } else if (!osd_homeless(osd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) need_send = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) maybe_request_map(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) mutex_lock(&osd->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) * Assign the tid atomically with send_request() to protect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) * multiple writes to the same object from racing with each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) * other, resulting in out of order ops on the OSDs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) req->r_tid = atomic64_inc_return(&osdc->last_tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) link_request(osd, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) if (need_send)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) send_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) else if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) complete_request(req, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) mutex_unlock(&osd->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) if (!err && ct_res == CALC_TARGET_POOL_DNE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) send_map_check(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) if (promoted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) downgrade_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) promote:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) up_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) down_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) wrlocked = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) promoted = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) static void account_request(struct ceph_osd_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) WARN_ON(req->r_flags & (CEPH_OSD_FLAG_ACK | CEPH_OSD_FLAG_ONDISK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) WARN_ON(!(req->r_flags & (CEPH_OSD_FLAG_READ | CEPH_OSD_FLAG_WRITE)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) req->r_flags |= CEPH_OSD_FLAG_ONDISK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) atomic_inc(&req->r_osdc->num_requests);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) req->r_start_stamp = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) req->r_start_latency = ktime_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) static void submit_request(struct ceph_osd_request *req, bool wrlocked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) ceph_osdc_get_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) account_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) __submit_request(req, wrlocked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) static void finish_request(struct ceph_osd_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) struct ceph_osd_client *osdc = req->r_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) WARN_ON(lookup_request_mc(&osdc->map_checks, req->r_tid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) dout("%s req %p tid %llu\n", __func__, req, req->r_tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) req->r_end_latency = ktime_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) if (req->r_osd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) unlink_request(req->r_osd, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) atomic_dec(&osdc->num_requests);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) * If an OSD has failed or returned and a request has been sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) * twice, it's possible to get a reply and end up here while the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) * request message is queued for delivery. We will ignore the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) * reply, so not a big deal, but better to try and catch it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) ceph_msg_revoke(req->r_request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) ceph_msg_revoke_incoming(req->r_reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) static void __complete_request(struct ceph_osd_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) dout("%s req %p tid %llu cb %ps result %d\n", __func__, req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) req->r_tid, req->r_callback, req->r_result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) if (req->r_callback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) req->r_callback(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) complete_all(&req->r_completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) ceph_osdc_put_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) static void complete_request_workfn(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) struct ceph_osd_request *req =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) container_of(work, struct ceph_osd_request, r_complete_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) __complete_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) * This is open-coded in handle_reply().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) static void complete_request(struct ceph_osd_request *req, int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) dout("%s req %p tid %llu err %d\n", __func__, req, req->r_tid, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) req->r_result = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) finish_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) INIT_WORK(&req->r_complete_work, complete_request_workfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) queue_work(req->r_osdc->completion_wq, &req->r_complete_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) static void cancel_map_check(struct ceph_osd_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) struct ceph_osd_client *osdc = req->r_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) struct ceph_osd_request *lookup_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) verify_osdc_wrlocked(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) lookup_req = lookup_request_mc(&osdc->map_checks, req->r_tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) if (!lookup_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) WARN_ON(lookup_req != req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) erase_request_mc(&osdc->map_checks, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) ceph_osdc_put_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) static void cancel_request(struct ceph_osd_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) dout("%s req %p tid %llu\n", __func__, req, req->r_tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) cancel_map_check(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) finish_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) complete_all(&req->r_completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) ceph_osdc_put_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) static void abort_request(struct ceph_osd_request *req, int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) dout("%s req %p tid %llu err %d\n", __func__, req, req->r_tid, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) cancel_map_check(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) complete_request(req, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) static int abort_fn(struct ceph_osd_request *req, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) int err = *(int *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) abort_request(req, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) return 0; /* continue iteration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) * Abort all in-flight requests with @err and arrange for all future
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) * requests to be failed immediately.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) void ceph_osdc_abort_requests(struct ceph_osd_client *osdc, int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) dout("%s osdc %p err %d\n", __func__, osdc, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) down_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) for_each_request(osdc, abort_fn, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) osdc->abort_err = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) up_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) EXPORT_SYMBOL(ceph_osdc_abort_requests);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) void ceph_osdc_clear_abort_err(struct ceph_osd_client *osdc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) down_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) osdc->abort_err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) up_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) EXPORT_SYMBOL(ceph_osdc_clear_abort_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) static void update_epoch_barrier(struct ceph_osd_client *osdc, u32 eb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) if (likely(eb > osdc->epoch_barrier)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) dout("updating epoch_barrier from %u to %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) osdc->epoch_barrier, eb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) osdc->epoch_barrier = eb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) /* Request map if we're not to the barrier yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) if (eb > osdc->osdmap->epoch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) maybe_request_map(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) void ceph_osdc_update_epoch_barrier(struct ceph_osd_client *osdc, u32 eb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) down_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) if (unlikely(eb > osdc->epoch_barrier)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) up_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) down_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) update_epoch_barrier(osdc, eb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) up_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) up_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) EXPORT_SYMBOL(ceph_osdc_update_epoch_barrier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) * We can end up releasing caps as a result of abort_request().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) * In that case, we probably want to ensure that the cap release message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) * has an updated epoch barrier in it, so set the epoch barrier prior to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) * aborting the first request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) static int abort_on_full_fn(struct ceph_osd_request *req, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) struct ceph_osd_client *osdc = req->r_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) bool *victims = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) if ((req->r_flags & CEPH_OSD_FLAG_WRITE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) (ceph_osdmap_flag(osdc, CEPH_OSDMAP_FULL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) pool_full(osdc, req->r_t.base_oloc.pool))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) if (!*victims) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) update_epoch_barrier(osdc, osdc->osdmap->epoch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) *victims = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) abort_request(req, -ENOSPC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) return 0; /* continue iteration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) * Drop all pending requests that are stalled waiting on a full condition to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) * clear, and complete them with ENOSPC as the return code. Set the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) * osdc->epoch_barrier to the latest map epoch that we've seen if any were
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) * cancelled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) static void ceph_osdc_abort_on_full(struct ceph_osd_client *osdc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) bool victims = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) if (ceph_test_opt(osdc->client, ABORT_ON_FULL) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) (ceph_osdmap_flag(osdc, CEPH_OSDMAP_FULL) || have_pool_full(osdc)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) for_each_request(osdc, abort_on_full_fn, &victims);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) static void check_pool_dne(struct ceph_osd_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) struct ceph_osd_client *osdc = req->r_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) struct ceph_osdmap *map = osdc->osdmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) verify_osdc_wrlocked(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) WARN_ON(!map->epoch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) if (req->r_attempts) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) * We sent a request earlier, which means that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) * previously the pool existed, and now it does not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) * (i.e., it was deleted).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) req->r_map_dne_bound = map->epoch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) dout("%s req %p tid %llu pool disappeared\n", __func__, req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) req->r_tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) dout("%s req %p tid %llu map_dne_bound %u have %u\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) req, req->r_tid, req->r_map_dne_bound, map->epoch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) if (req->r_map_dne_bound) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) if (map->epoch >= req->r_map_dne_bound) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) /* we had a new enough map */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) pr_info_ratelimited("tid %llu pool does not exist\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) req->r_tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) complete_request(req, -ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) send_map_check(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) static void map_check_cb(struct ceph_mon_generic_request *greq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) struct ceph_osd_client *osdc = &greq->monc->client->osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) struct ceph_osd_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) u64 tid = greq->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) WARN_ON(greq->result || !greq->u.newest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) down_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) req = lookup_request_mc(&osdc->map_checks, tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) if (!req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) dout("%s tid %llu dne\n", __func__, tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) dout("%s req %p tid %llu map_dne_bound %u newest %llu\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) req, req->r_tid, req->r_map_dne_bound, greq->u.newest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) if (!req->r_map_dne_bound)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) req->r_map_dne_bound = greq->u.newest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) erase_request_mc(&osdc->map_checks, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) check_pool_dne(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) ceph_osdc_put_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) up_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) static void send_map_check(struct ceph_osd_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) struct ceph_osd_client *osdc = req->r_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) struct ceph_osd_request *lookup_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) verify_osdc_wrlocked(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) lookup_req = lookup_request_mc(&osdc->map_checks, req->r_tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) if (lookup_req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) WARN_ON(lookup_req != req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) ceph_osdc_get_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) insert_request_mc(&osdc->map_checks, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) ret = ceph_monc_get_version_async(&osdc->client->monc, "osdmap",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) map_check_cb, req->r_tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) WARN_ON(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) * lingering requests, watch/notify v2 infrastructure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) static void linger_release(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) struct ceph_osd_linger_request *lreq =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) container_of(kref, struct ceph_osd_linger_request, kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) dout("%s lreq %p reg_req %p ping_req %p\n", __func__, lreq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) lreq->reg_req, lreq->ping_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) WARN_ON(!RB_EMPTY_NODE(&lreq->node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) WARN_ON(!RB_EMPTY_NODE(&lreq->osdc_node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) WARN_ON(!RB_EMPTY_NODE(&lreq->mc_node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) WARN_ON(!list_empty(&lreq->scan_item));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) WARN_ON(!list_empty(&lreq->pending_lworks));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) WARN_ON(lreq->osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) if (lreq->reg_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) ceph_osdc_put_request(lreq->reg_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) if (lreq->ping_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) ceph_osdc_put_request(lreq->ping_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) target_destroy(&lreq->t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) kfree(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) static void linger_put(struct ceph_osd_linger_request *lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) if (lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) kref_put(&lreq->kref, linger_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) static struct ceph_osd_linger_request *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) linger_get(struct ceph_osd_linger_request *lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) kref_get(&lreq->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) return lreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) static struct ceph_osd_linger_request *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) linger_alloc(struct ceph_osd_client *osdc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) struct ceph_osd_linger_request *lreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) lreq = kzalloc(sizeof(*lreq), GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) if (!lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) kref_init(&lreq->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) mutex_init(&lreq->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) RB_CLEAR_NODE(&lreq->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) RB_CLEAR_NODE(&lreq->osdc_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) RB_CLEAR_NODE(&lreq->mc_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) INIT_LIST_HEAD(&lreq->scan_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) INIT_LIST_HEAD(&lreq->pending_lworks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) init_completion(&lreq->reg_commit_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) init_completion(&lreq->notify_finish_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) lreq->osdc = osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) target_init(&lreq->t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) dout("%s lreq %p\n", __func__, lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) return lreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) DEFINE_RB_INSDEL_FUNCS(linger, struct ceph_osd_linger_request, linger_id, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) DEFINE_RB_FUNCS(linger_osdc, struct ceph_osd_linger_request, linger_id, osdc_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) DEFINE_RB_FUNCS(linger_mc, struct ceph_osd_linger_request, linger_id, mc_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) * Create linger request <-> OSD session relation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) * @lreq has to be registered, @osd may be homeless.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) static void link_linger(struct ceph_osd *osd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) struct ceph_osd_linger_request *lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) verify_osd_locked(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) WARN_ON(!lreq->linger_id || lreq->osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) dout("%s osd %p osd%d lreq %p linger_id %llu\n", __func__, osd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) osd->o_osd, lreq, lreq->linger_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) if (!osd_homeless(osd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) __remove_osd_from_lru(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) atomic_inc(&osd->o_osdc->num_homeless);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) get_osd(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) insert_linger(&osd->o_linger_requests, lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) lreq->osd = osd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) static void unlink_linger(struct ceph_osd *osd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) struct ceph_osd_linger_request *lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) verify_osd_locked(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) WARN_ON(lreq->osd != osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) dout("%s osd %p osd%d lreq %p linger_id %llu\n", __func__, osd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) osd->o_osd, lreq, lreq->linger_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) lreq->osd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) erase_linger(&osd->o_linger_requests, lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) put_osd(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) if (!osd_homeless(osd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) maybe_move_osd_to_lru(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) atomic_dec(&osd->o_osdc->num_homeless);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) static bool __linger_registered(struct ceph_osd_linger_request *lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) verify_osdc_locked(lreq->osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) return !RB_EMPTY_NODE(&lreq->osdc_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) static bool linger_registered(struct ceph_osd_linger_request *lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) struct ceph_osd_client *osdc = lreq->osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) bool registered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) down_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) registered = __linger_registered(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) up_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) return registered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) static void linger_register(struct ceph_osd_linger_request *lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) struct ceph_osd_client *osdc = lreq->osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) verify_osdc_wrlocked(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) WARN_ON(lreq->linger_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) linger_get(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) lreq->linger_id = ++osdc->last_linger_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) insert_linger_osdc(&osdc->linger_requests, lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) static void linger_unregister(struct ceph_osd_linger_request *lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) struct ceph_osd_client *osdc = lreq->osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) verify_osdc_wrlocked(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) erase_linger_osdc(&osdc->linger_requests, lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) linger_put(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) static void cancel_linger_request(struct ceph_osd_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) struct ceph_osd_linger_request *lreq = req->r_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) WARN_ON(!req->r_linger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) cancel_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) linger_put(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) struct linger_work {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) struct work_struct work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) struct ceph_osd_linger_request *lreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) struct list_head pending_item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) unsigned long queued_stamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) u64 notify_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) u64 notifier_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) void *payload; /* points into @msg front */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) size_t payload_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) struct ceph_msg *msg; /* for ceph_msg_put() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) } notify;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) } error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) static struct linger_work *lwork_alloc(struct ceph_osd_linger_request *lreq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) work_func_t workfn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) struct linger_work *lwork;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) lwork = kzalloc(sizeof(*lwork), GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) if (!lwork)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) INIT_WORK(&lwork->work, workfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) INIT_LIST_HEAD(&lwork->pending_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) lwork->lreq = linger_get(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) return lwork;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) static void lwork_free(struct linger_work *lwork)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) struct ceph_osd_linger_request *lreq = lwork->lreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) mutex_lock(&lreq->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) list_del(&lwork->pending_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) mutex_unlock(&lreq->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) linger_put(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) kfree(lwork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) static void lwork_queue(struct linger_work *lwork)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) struct ceph_osd_linger_request *lreq = lwork->lreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) struct ceph_osd_client *osdc = lreq->osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) verify_lreq_locked(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) WARN_ON(!list_empty(&lwork->pending_item));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) lwork->queued_stamp = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) list_add_tail(&lwork->pending_item, &lreq->pending_lworks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) queue_work(osdc->notify_wq, &lwork->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) static void do_watch_notify(struct work_struct *w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) struct linger_work *lwork = container_of(w, struct linger_work, work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) struct ceph_osd_linger_request *lreq = lwork->lreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) if (!linger_registered(lreq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) dout("%s lreq %p not registered\n", __func__, lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) WARN_ON(!lreq->is_watch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) dout("%s lreq %p notify_id %llu notifier_id %llu payload_len %zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) __func__, lreq, lwork->notify.notify_id, lwork->notify.notifier_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) lwork->notify.payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) lreq->wcb(lreq->data, lwork->notify.notify_id, lreq->linger_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) lwork->notify.notifier_id, lwork->notify.payload,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) lwork->notify.payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) ceph_msg_put(lwork->notify.msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) lwork_free(lwork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) static void do_watch_error(struct work_struct *w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) struct linger_work *lwork = container_of(w, struct linger_work, work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) struct ceph_osd_linger_request *lreq = lwork->lreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) if (!linger_registered(lreq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) dout("%s lreq %p not registered\n", __func__, lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) dout("%s lreq %p err %d\n", __func__, lreq, lwork->error.err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) lreq->errcb(lreq->data, lreq->linger_id, lwork->error.err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) lwork_free(lwork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) static void queue_watch_error(struct ceph_osd_linger_request *lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) struct linger_work *lwork;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) lwork = lwork_alloc(lreq, do_watch_error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) if (!lwork) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) pr_err("failed to allocate error-lwork\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) lwork->error.err = lreq->last_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) lwork_queue(lwork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) static void linger_reg_commit_complete(struct ceph_osd_linger_request *lreq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) int result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) if (!completion_done(&lreq->reg_commit_wait)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) lreq->reg_commit_error = (result <= 0 ? result : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) complete_all(&lreq->reg_commit_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) static void linger_commit_cb(struct ceph_osd_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) struct ceph_osd_linger_request *lreq = req->r_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) mutex_lock(&lreq->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) dout("%s lreq %p linger_id %llu result %d\n", __func__, lreq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) lreq->linger_id, req->r_result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) linger_reg_commit_complete(lreq, req->r_result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) lreq->committed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) if (!lreq->is_watch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) struct ceph_osd_data *osd_data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) osd_req_op_data(req, 0, notify, response_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) void *p = page_address(osd_data->pages[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) WARN_ON(req->r_ops[0].op != CEPH_OSD_OP_NOTIFY ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) osd_data->type != CEPH_OSD_DATA_TYPE_PAGES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) /* make note of the notify_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) if (req->r_ops[0].outdata_len >= sizeof(u64)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) lreq->notify_id = ceph_decode_64(&p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) dout("lreq %p notify_id %llu\n", lreq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) lreq->notify_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) dout("lreq %p no notify_id\n", lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) mutex_unlock(&lreq->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) linger_put(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) static int normalize_watch_error(int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) * Translate ENOENT -> ENOTCONN so that a delete->disconnection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) * notification and a failure to reconnect because we raced with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) * the delete appear the same to the user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) if (err == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) err = -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) static void linger_reconnect_cb(struct ceph_osd_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) struct ceph_osd_linger_request *lreq = req->r_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) mutex_lock(&lreq->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) dout("%s lreq %p linger_id %llu result %d last_error %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) lreq, lreq->linger_id, req->r_result, lreq->last_error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) if (req->r_result < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) if (!lreq->last_error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) lreq->last_error = normalize_watch_error(req->r_result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) queue_watch_error(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) mutex_unlock(&lreq->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) linger_put(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) static void send_linger(struct ceph_osd_linger_request *lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) struct ceph_osd_request *req = lreq->reg_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) struct ceph_osd_req_op *op = &req->r_ops[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) verify_osdc_wrlocked(req->r_osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) dout("%s lreq %p linger_id %llu\n", __func__, lreq, lreq->linger_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) if (req->r_osd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) cancel_linger_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) request_reinit(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) target_copy(&req->r_t, &lreq->t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) req->r_mtime = lreq->mtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) mutex_lock(&lreq->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) if (lreq->is_watch && lreq->committed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) WARN_ON(op->op != CEPH_OSD_OP_WATCH ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) op->watch.cookie != lreq->linger_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) op->watch.op = CEPH_OSD_WATCH_OP_RECONNECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) op->watch.gen = ++lreq->register_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) dout("lreq %p reconnect register_gen %u\n", lreq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) op->watch.gen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) req->r_callback = linger_reconnect_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) if (!lreq->is_watch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) lreq->notify_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) WARN_ON(op->watch.op != CEPH_OSD_WATCH_OP_WATCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) dout("lreq %p register\n", lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) req->r_callback = linger_commit_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) mutex_unlock(&lreq->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) req->r_priv = linger_get(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) req->r_linger = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) submit_request(req, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) static void linger_ping_cb(struct ceph_osd_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) struct ceph_osd_linger_request *lreq = req->r_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) mutex_lock(&lreq->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) dout("%s lreq %p linger_id %llu result %d ping_sent %lu last_error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) __func__, lreq, lreq->linger_id, req->r_result, lreq->ping_sent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) lreq->last_error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) if (lreq->register_gen == req->r_ops[0].watch.gen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) if (!req->r_result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) lreq->watch_valid_thru = lreq->ping_sent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) } else if (!lreq->last_error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) lreq->last_error = normalize_watch_error(req->r_result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) queue_watch_error(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) dout("lreq %p register_gen %u ignoring old pong %u\n", lreq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) lreq->register_gen, req->r_ops[0].watch.gen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) mutex_unlock(&lreq->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) linger_put(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) static void send_linger_ping(struct ceph_osd_linger_request *lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) struct ceph_osd_client *osdc = lreq->osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) struct ceph_osd_request *req = lreq->ping_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) struct ceph_osd_req_op *op = &req->r_ops[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) if (ceph_osdmap_flag(osdc, CEPH_OSDMAP_PAUSERD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) dout("%s PAUSERD\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) lreq->ping_sent = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) dout("%s lreq %p linger_id %llu ping_sent %lu register_gen %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) __func__, lreq, lreq->linger_id, lreq->ping_sent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) lreq->register_gen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) if (req->r_osd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) cancel_linger_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) request_reinit(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) target_copy(&req->r_t, &lreq->t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) WARN_ON(op->op != CEPH_OSD_OP_WATCH ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) op->watch.cookie != lreq->linger_id ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) op->watch.op != CEPH_OSD_WATCH_OP_PING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) op->watch.gen = lreq->register_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) req->r_callback = linger_ping_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) req->r_priv = linger_get(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) req->r_linger = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) ceph_osdc_get_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) account_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) req->r_tid = atomic64_inc_return(&osdc->last_tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) link_request(lreq->osd, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) send_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) static void linger_submit(struct ceph_osd_linger_request *lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) struct ceph_osd_client *osdc = lreq->osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) struct ceph_osd *osd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) down_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) linger_register(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) if (lreq->is_watch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) lreq->reg_req->r_ops[0].watch.cookie = lreq->linger_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) lreq->ping_req->r_ops[0].watch.cookie = lreq->linger_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) lreq->reg_req->r_ops[0].notify.cookie = lreq->linger_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) calc_target(osdc, &lreq->t, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) osd = lookup_create_osd(osdc, lreq->t.osd, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) link_linger(osd, lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) send_linger(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) up_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) static void cancel_linger_map_check(struct ceph_osd_linger_request *lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) struct ceph_osd_client *osdc = lreq->osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) struct ceph_osd_linger_request *lookup_lreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) verify_osdc_wrlocked(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) lookup_lreq = lookup_linger_mc(&osdc->linger_map_checks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) lreq->linger_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) if (!lookup_lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) WARN_ON(lookup_lreq != lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) erase_linger_mc(&osdc->linger_map_checks, lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) linger_put(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) * @lreq has to be both registered and linked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) static void __linger_cancel(struct ceph_osd_linger_request *lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) if (lreq->is_watch && lreq->ping_req->r_osd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) cancel_linger_request(lreq->ping_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) if (lreq->reg_req->r_osd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) cancel_linger_request(lreq->reg_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) cancel_linger_map_check(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) unlink_linger(lreq->osd, lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) linger_unregister(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) static void linger_cancel(struct ceph_osd_linger_request *lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) struct ceph_osd_client *osdc = lreq->osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) down_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) if (__linger_registered(lreq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) __linger_cancel(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) up_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) static void send_linger_map_check(struct ceph_osd_linger_request *lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) static void check_linger_pool_dne(struct ceph_osd_linger_request *lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) struct ceph_osd_client *osdc = lreq->osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) struct ceph_osdmap *map = osdc->osdmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) verify_osdc_wrlocked(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) WARN_ON(!map->epoch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) if (lreq->register_gen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) lreq->map_dne_bound = map->epoch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) dout("%s lreq %p linger_id %llu pool disappeared\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) lreq, lreq->linger_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) dout("%s lreq %p linger_id %llu map_dne_bound %u have %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) __func__, lreq, lreq->linger_id, lreq->map_dne_bound,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) map->epoch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) if (lreq->map_dne_bound) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) if (map->epoch >= lreq->map_dne_bound) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) /* we had a new enough map */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) pr_info("linger_id %llu pool does not exist\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) lreq->linger_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) linger_reg_commit_complete(lreq, -ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) __linger_cancel(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) send_linger_map_check(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) static void linger_map_check_cb(struct ceph_mon_generic_request *greq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) struct ceph_osd_client *osdc = &greq->monc->client->osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) struct ceph_osd_linger_request *lreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) u64 linger_id = greq->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) WARN_ON(greq->result || !greq->u.newest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) down_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) lreq = lookup_linger_mc(&osdc->linger_map_checks, linger_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) if (!lreq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) dout("%s linger_id %llu dne\n", __func__, linger_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) dout("%s lreq %p linger_id %llu map_dne_bound %u newest %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) __func__, lreq, lreq->linger_id, lreq->map_dne_bound,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) greq->u.newest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) if (!lreq->map_dne_bound)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) lreq->map_dne_bound = greq->u.newest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) erase_linger_mc(&osdc->linger_map_checks, lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) check_linger_pool_dne(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) linger_put(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) up_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) static void send_linger_map_check(struct ceph_osd_linger_request *lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) struct ceph_osd_client *osdc = lreq->osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) struct ceph_osd_linger_request *lookup_lreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) verify_osdc_wrlocked(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) lookup_lreq = lookup_linger_mc(&osdc->linger_map_checks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) lreq->linger_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) if (lookup_lreq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) WARN_ON(lookup_lreq != lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) linger_get(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) insert_linger_mc(&osdc->linger_map_checks, lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) ret = ceph_monc_get_version_async(&osdc->client->monc, "osdmap",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) linger_map_check_cb, lreq->linger_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) WARN_ON(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) static int linger_reg_commit_wait(struct ceph_osd_linger_request *lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) dout("%s lreq %p linger_id %llu\n", __func__, lreq, lreq->linger_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) ret = wait_for_completion_interruptible(&lreq->reg_commit_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) return ret ?: lreq->reg_commit_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) static int linger_notify_finish_wait(struct ceph_osd_linger_request *lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) dout("%s lreq %p linger_id %llu\n", __func__, lreq, lreq->linger_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) ret = wait_for_completion_interruptible(&lreq->notify_finish_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) return ret ?: lreq->notify_finish_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) * Timeout callback, called every N seconds. When 1 or more OSD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) * requests has been active for more than N seconds, we send a keepalive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) * (tag + timestamp) to its OSD to ensure any communications channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) * reset is detected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) static void handle_timeout(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) struct ceph_osd_client *osdc =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) container_of(work, struct ceph_osd_client, timeout_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) struct ceph_options *opts = osdc->client->options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) unsigned long cutoff = jiffies - opts->osd_keepalive_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) unsigned long expiry_cutoff = jiffies - opts->osd_request_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) LIST_HEAD(slow_osds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) struct rb_node *n, *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) dout("%s osdc %p\n", __func__, osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) down_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) * ping osds that are a bit slow. this ensures that if there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) * is a break in the TCP connection we will notice, and reopen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) * a connection with that osd (from the fault callback).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) for (n = rb_first(&osdc->osds); n; n = rb_next(n)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) struct ceph_osd *osd = rb_entry(n, struct ceph_osd, o_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) for (p = rb_first(&osd->o_requests); p; ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) struct ceph_osd_request *req =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) rb_entry(p, struct ceph_osd_request, r_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) p = rb_next(p); /* abort_request() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) if (time_before(req->r_stamp, cutoff)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) dout(" req %p tid %llu on osd%d is laggy\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) req, req->r_tid, osd->o_osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) if (opts->osd_request_timeout &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) time_before(req->r_start_stamp, expiry_cutoff)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) pr_err_ratelimited("tid %llu on osd%d timeout\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) req->r_tid, osd->o_osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) abort_request(req, -ETIMEDOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) for (p = rb_first(&osd->o_linger_requests); p; p = rb_next(p)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) struct ceph_osd_linger_request *lreq =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) rb_entry(p, struct ceph_osd_linger_request, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) dout(" lreq %p linger_id %llu is served by osd%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) lreq, lreq->linger_id, osd->o_osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) mutex_lock(&lreq->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) if (lreq->is_watch && lreq->committed && !lreq->last_error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) send_linger_ping(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) mutex_unlock(&lreq->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) if (found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) list_move_tail(&osd->o_keepalive_item, &slow_osds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) if (opts->osd_request_timeout) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) for (p = rb_first(&osdc->homeless_osd.o_requests); p; ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) struct ceph_osd_request *req =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) rb_entry(p, struct ceph_osd_request, r_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) p = rb_next(p); /* abort_request() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) if (time_before(req->r_start_stamp, expiry_cutoff)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) pr_err_ratelimited("tid %llu on osd%d timeout\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) req->r_tid, osdc->homeless_osd.o_osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) abort_request(req, -ETIMEDOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) if (atomic_read(&osdc->num_homeless) || !list_empty(&slow_osds))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) maybe_request_map(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) while (!list_empty(&slow_osds)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) struct ceph_osd *osd = list_first_entry(&slow_osds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) struct ceph_osd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) o_keepalive_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) list_del_init(&osd->o_keepalive_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) ceph_con_keepalive(&osd->o_con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) up_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) schedule_delayed_work(&osdc->timeout_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) osdc->client->options->osd_keepalive_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) static void handle_osds_timeout(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) struct ceph_osd_client *osdc =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) container_of(work, struct ceph_osd_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) osds_timeout_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) unsigned long delay = osdc->client->options->osd_idle_ttl / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) struct ceph_osd *osd, *nosd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) dout("%s osdc %p\n", __func__, osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) down_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) list_for_each_entry_safe(osd, nosd, &osdc->osd_lru, o_osd_lru) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) if (time_before(jiffies, osd->lru_ttl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) WARN_ON(!RB_EMPTY_ROOT(&osd->o_requests));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) WARN_ON(!RB_EMPTY_ROOT(&osd->o_linger_requests));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) close_osd(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) up_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) schedule_delayed_work(&osdc->osds_timeout_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) round_jiffies_relative(delay));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) static int ceph_oloc_decode(void **p, void *end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) struct ceph_object_locator *oloc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) u8 struct_v, struct_cv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) u32 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) void *struct_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) ceph_decode_need(p, end, 1 + 1 + 4, e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) struct_v = ceph_decode_8(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) struct_cv = ceph_decode_8(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) if (struct_v < 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) pr_warn("got v %d < 3 cv %d of ceph_object_locator\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) struct_v, struct_cv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) goto e_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) if (struct_cv > 6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) pr_warn("got v %d cv %d > 6 of ceph_object_locator\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) struct_v, struct_cv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) goto e_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) len = ceph_decode_32(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) ceph_decode_need(p, end, len, e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) struct_end = *p + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) oloc->pool = ceph_decode_64(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) *p += 4; /* skip preferred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) len = ceph_decode_32(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) if (len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) pr_warn("ceph_object_locator::key is set\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) goto e_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) if (struct_v >= 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) bool changed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) len = ceph_decode_32(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) if (len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) ceph_decode_need(p, end, len, e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) if (!oloc->pool_ns ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) ceph_compare_string(oloc->pool_ns, *p, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) *p += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) if (oloc->pool_ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) if (changed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) /* redirect changes namespace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) pr_warn("ceph_object_locator::nspace is changed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) goto e_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) if (struct_v >= 6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) s64 hash = ceph_decode_64(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) if (hash != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) pr_warn("ceph_object_locator::hash is set\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) goto e_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) /* skip the rest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) *p = struct_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) e_inval:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) static int ceph_redirect_decode(void **p, void *end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) struct ceph_request_redirect *redir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) u8 struct_v, struct_cv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) u32 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) void *struct_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) ceph_decode_need(p, end, 1 + 1 + 4, e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) struct_v = ceph_decode_8(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) struct_cv = ceph_decode_8(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) if (struct_cv > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) pr_warn("got v %d cv %d > 1 of ceph_request_redirect\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) struct_v, struct_cv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) goto e_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) len = ceph_decode_32(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) ceph_decode_need(p, end, len, e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) struct_end = *p + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) ret = ceph_oloc_decode(p, end, &redir->oloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) len = ceph_decode_32(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) if (len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) pr_warn("ceph_request_redirect::object_name is set\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) goto e_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) /* skip the rest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) *p = struct_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) e_inval:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) struct MOSDOpReply {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) struct ceph_pg pgid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) u64 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) u32 epoch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) int num_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) u32 outdata_len[CEPH_OSD_MAX_OPS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) s32 rval[CEPH_OSD_MAX_OPS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) int retry_attempt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) struct ceph_eversion replay_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) u64 user_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) struct ceph_request_redirect redirect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) static int decode_MOSDOpReply(const struct ceph_msg *msg, struct MOSDOpReply *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) void *p = msg->front.iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) void *const end = p + msg->front.iov_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) u16 version = le16_to_cpu(msg->hdr.version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) struct ceph_eversion bad_replay_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) u8 decode_redir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) u32 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) ceph_decode_32_safe(&p, end, len, e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) ceph_decode_need(&p, end, len, e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) p += len; /* skip oid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) ret = ceph_decode_pgid(&p, end, &m->pgid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) ceph_decode_64_safe(&p, end, m->flags, e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) ceph_decode_32_safe(&p, end, m->result, e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) ceph_decode_need(&p, end, sizeof(bad_replay_version), e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) memcpy(&bad_replay_version, p, sizeof(bad_replay_version));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) p += sizeof(bad_replay_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) ceph_decode_32_safe(&p, end, m->epoch, e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) ceph_decode_32_safe(&p, end, m->num_ops, e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) if (m->num_ops > ARRAY_SIZE(m->outdata_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) goto e_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) ceph_decode_need(&p, end, m->num_ops * sizeof(struct ceph_osd_op),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) for (i = 0; i < m->num_ops; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) struct ceph_osd_op *op = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) m->outdata_len[i] = le32_to_cpu(op->payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) p += sizeof(*op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) ceph_decode_32_safe(&p, end, m->retry_attempt, e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) for (i = 0; i < m->num_ops; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) ceph_decode_32_safe(&p, end, m->rval[i], e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) if (version >= 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) ceph_decode_need(&p, end, sizeof(m->replay_version), e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) memcpy(&m->replay_version, p, sizeof(m->replay_version));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) p += sizeof(m->replay_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) ceph_decode_64_safe(&p, end, m->user_version, e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) m->replay_version = bad_replay_version; /* struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) m->user_version = le64_to_cpu(m->replay_version.version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) if (version >= 6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) if (version >= 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) ceph_decode_8_safe(&p, end, decode_redir, e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) decode_redir = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) decode_redir = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) if (decode_redir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) ret = ceph_redirect_decode(&p, end, &m->redirect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) ceph_oloc_init(&m->redirect.oloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) e_inval:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) * Handle MOSDOpReply. Set ->r_result and call the callback if it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) * specified.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) static void handle_reply(struct ceph_osd *osd, struct ceph_msg *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) struct ceph_osd_client *osdc = osd->o_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) struct ceph_osd_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) struct MOSDOpReply m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) u64 tid = le64_to_cpu(msg->hdr.tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) u32 data_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) dout("%s msg %p tid %llu\n", __func__, msg, tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) down_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) if (!osd_registered(osd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) dout("%s osd%d unknown\n", __func__, osd->o_osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) goto out_unlock_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) WARN_ON(osd->o_osd != le64_to_cpu(msg->hdr.src.num));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) mutex_lock(&osd->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) req = lookup_request(&osd->o_requests, tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) if (!req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) dout("%s osd%d tid %llu unknown\n", __func__, osd->o_osd, tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) goto out_unlock_session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) m.redirect.oloc.pool_ns = req->r_t.target_oloc.pool_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) ret = decode_MOSDOpReply(msg, &m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) m.redirect.oloc.pool_ns = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) pr_err("failed to decode MOSDOpReply for tid %llu: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) req->r_tid, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) ceph_msg_dump(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) goto fail_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) dout("%s req %p tid %llu flags 0x%llx pgid %llu.%x epoch %u attempt %d v %u'%llu uv %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) __func__, req, req->r_tid, m.flags, m.pgid.pool, m.pgid.seed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) m.epoch, m.retry_attempt, le32_to_cpu(m.replay_version.epoch),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) le64_to_cpu(m.replay_version.version), m.user_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) if (m.retry_attempt >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) if (m.retry_attempt != req->r_attempts - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) dout("req %p tid %llu retry_attempt %d != %d, ignoring\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) req, req->r_tid, m.retry_attempt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) req->r_attempts - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) goto out_unlock_session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) WARN_ON(1); /* MOSDOpReply v4 is assumed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) if (!ceph_oloc_empty(&m.redirect.oloc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) dout("req %p tid %llu redirect pool %lld\n", req, req->r_tid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) m.redirect.oloc.pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) unlink_request(osd, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) mutex_unlock(&osd->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) * Not ceph_oloc_copy() - changing pool_ns is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) * supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) req->r_t.target_oloc.pool = m.redirect.oloc.pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) req->r_flags |= CEPH_OSD_FLAG_REDIRECTED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) CEPH_OSD_FLAG_IGNORE_OVERLAY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) CEPH_OSD_FLAG_IGNORE_CACHE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) req->r_tid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) __submit_request(req, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) goto out_unlock_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) if (m.result == -EAGAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) dout("req %p tid %llu EAGAIN\n", req, req->r_tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) unlink_request(osd, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) mutex_unlock(&osd->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) * The object is missing on the replica or not (yet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) * readable. Clear pgid to force a resend to the primary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) * via legacy_change.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) req->r_t.pgid.pool = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) req->r_t.pgid.seed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) WARN_ON(!req->r_t.used_replica);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) req->r_flags &= ~(CEPH_OSD_FLAG_BALANCE_READS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) CEPH_OSD_FLAG_LOCALIZE_READS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) req->r_tid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) __submit_request(req, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) goto out_unlock_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) if (m.num_ops != req->r_num_ops) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) pr_err("num_ops %d != %d for tid %llu\n", m.num_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) req->r_num_ops, req->r_tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) goto fail_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) for (i = 0; i < req->r_num_ops; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) dout(" req %p tid %llu op %d rval %d len %u\n", req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) req->r_tid, i, m.rval[i], m.outdata_len[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) req->r_ops[i].rval = m.rval[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) req->r_ops[i].outdata_len = m.outdata_len[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) data_len += m.outdata_len[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) if (data_len != le32_to_cpu(msg->hdr.data_len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) pr_err("sum of lens %u != %u for tid %llu\n", data_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) le32_to_cpu(msg->hdr.data_len), req->r_tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) goto fail_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) dout("%s req %p tid %llu result %d data_len %u\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) req, req->r_tid, m.result, data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) * Since we only ever request ONDISK, we should only ever get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) * one (type of) reply back.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) WARN_ON(!(m.flags & CEPH_OSD_FLAG_ONDISK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) req->r_result = m.result ?: data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) finish_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) mutex_unlock(&osd->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) up_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) __complete_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) fail_request:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) complete_request(req, -EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) out_unlock_session:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) mutex_unlock(&osd->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) out_unlock_osdc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) up_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) static void set_pool_was_full(struct ceph_osd_client *osdc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) struct rb_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) for (n = rb_first(&osdc->osdmap->pg_pools); n; n = rb_next(n)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) struct ceph_pg_pool_info *pi =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) rb_entry(n, struct ceph_pg_pool_info, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) pi->was_full = __pool_full(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) static bool pool_cleared_full(struct ceph_osd_client *osdc, s64 pool_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) struct ceph_pg_pool_info *pi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) pi = ceph_pg_pool_by_id(osdc->osdmap, pool_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) if (!pi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) return pi->was_full && !__pool_full(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) static enum calc_target_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) recalc_linger_target(struct ceph_osd_linger_request *lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) struct ceph_osd_client *osdc = lreq->osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) enum calc_target_result ct_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) ct_res = calc_target(osdc, &lreq->t, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) if (ct_res == CALC_TARGET_NEED_RESEND) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) struct ceph_osd *osd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) osd = lookup_create_osd(osdc, lreq->t.osd, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) if (osd != lreq->osd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) unlink_linger(lreq->osd, lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) link_linger(osd, lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) return ct_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) * Requeue requests whose mapping to an OSD has changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) static void scan_requests(struct ceph_osd *osd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) bool force_resend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) bool cleared_full,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) bool check_pool_cleared_full,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) struct rb_root *need_resend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) struct list_head *need_resend_linger)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) struct ceph_osd_client *osdc = osd->o_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) struct rb_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) bool force_resend_writes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) for (n = rb_first(&osd->o_linger_requests); n; ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) struct ceph_osd_linger_request *lreq =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) rb_entry(n, struct ceph_osd_linger_request, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) enum calc_target_result ct_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) n = rb_next(n); /* recalc_linger_target() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) dout("%s lreq %p linger_id %llu\n", __func__, lreq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) lreq->linger_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) ct_res = recalc_linger_target(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) switch (ct_res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) case CALC_TARGET_NO_ACTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) force_resend_writes = cleared_full ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) (check_pool_cleared_full &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) pool_cleared_full(osdc, lreq->t.base_oloc.pool));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) if (!force_resend && !force_resend_writes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) case CALC_TARGET_NEED_RESEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) cancel_linger_map_check(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) * scan_requests() for the previous epoch(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) * may have already added it to the list, since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) * it's not unlinked here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) if (list_empty(&lreq->scan_item))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) list_add_tail(&lreq->scan_item, need_resend_linger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) case CALC_TARGET_POOL_DNE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) list_del_init(&lreq->scan_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) check_linger_pool_dne(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) for (n = rb_first(&osd->o_requests); n; ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) struct ceph_osd_request *req =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) rb_entry(n, struct ceph_osd_request, r_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) enum calc_target_result ct_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) n = rb_next(n); /* unlink_request(), check_pool_dne() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) dout("%s req %p tid %llu\n", __func__, req, req->r_tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) ct_res = calc_target(osdc, &req->r_t, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) switch (ct_res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) case CALC_TARGET_NO_ACTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) force_resend_writes = cleared_full ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) (check_pool_cleared_full &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) pool_cleared_full(osdc, req->r_t.base_oloc.pool));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) if (!force_resend &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) (!(req->r_flags & CEPH_OSD_FLAG_WRITE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) !force_resend_writes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) case CALC_TARGET_NEED_RESEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) cancel_map_check(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) unlink_request(osd, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) insert_request(need_resend, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) case CALC_TARGET_POOL_DNE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) check_pool_dne(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) static int handle_one_map(struct ceph_osd_client *osdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) void *p, void *end, bool incremental,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) struct rb_root *need_resend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) struct list_head *need_resend_linger)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) struct ceph_osdmap *newmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) struct rb_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) bool skipped_map = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) bool was_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) was_full = ceph_osdmap_flag(osdc, CEPH_OSDMAP_FULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) set_pool_was_full(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) if (incremental)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) newmap = osdmap_apply_incremental(&p, end, osdc->osdmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) newmap = ceph_osdmap_decode(&p, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) if (IS_ERR(newmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) return PTR_ERR(newmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) if (newmap != osdc->osdmap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) * Preserve ->was_full before destroying the old map.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) * For pools that weren't in the old map, ->was_full
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) * should be false.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) for (n = rb_first(&newmap->pg_pools); n; n = rb_next(n)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) struct ceph_pg_pool_info *pi =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) rb_entry(n, struct ceph_pg_pool_info, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) struct ceph_pg_pool_info *old_pi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) old_pi = ceph_pg_pool_by_id(osdc->osdmap, pi->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) if (old_pi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) pi->was_full = old_pi->was_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) WARN_ON(pi->was_full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) if (osdc->osdmap->epoch &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) osdc->osdmap->epoch + 1 < newmap->epoch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) WARN_ON(incremental);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) skipped_map = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) ceph_osdmap_destroy(osdc->osdmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) osdc->osdmap = newmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) was_full &= !ceph_osdmap_flag(osdc, CEPH_OSDMAP_FULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) scan_requests(&osdc->homeless_osd, skipped_map, was_full, true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) need_resend, need_resend_linger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) for (n = rb_first(&osdc->osds); n; ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) struct ceph_osd *osd = rb_entry(n, struct ceph_osd, o_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) n = rb_next(n); /* close_osd() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) scan_requests(osd, skipped_map, was_full, true, need_resend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) need_resend_linger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) if (!ceph_osd_is_up(osdc->osdmap, osd->o_osd) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) memcmp(&osd->o_con.peer_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) ceph_osd_addr(osdc->osdmap, osd->o_osd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) sizeof(struct ceph_entity_addr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) close_osd(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) static void kick_requests(struct ceph_osd_client *osdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) struct rb_root *need_resend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) struct list_head *need_resend_linger)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) struct ceph_osd_linger_request *lreq, *nlreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) enum calc_target_result ct_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) struct rb_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) /* make sure need_resend targets reflect latest map */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) for (n = rb_first(need_resend); n; ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) struct ceph_osd_request *req =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) rb_entry(n, struct ceph_osd_request, r_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) n = rb_next(n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) if (req->r_t.epoch < osdc->osdmap->epoch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) ct_res = calc_target(osdc, &req->r_t, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) if (ct_res == CALC_TARGET_POOL_DNE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) erase_request(need_resend, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) check_pool_dne(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) for (n = rb_first(need_resend); n; ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) struct ceph_osd_request *req =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) rb_entry(n, struct ceph_osd_request, r_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) struct ceph_osd *osd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) n = rb_next(n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) erase_request(need_resend, req); /* before link_request() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) osd = lookup_create_osd(osdc, req->r_t.osd, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) link_request(osd, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) if (!req->r_linger) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) if (!osd_homeless(osd) && !req->r_t.paused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) send_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) cancel_linger_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) list_for_each_entry_safe(lreq, nlreq, need_resend_linger, scan_item) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) if (!osd_homeless(lreq->osd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) send_linger(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) list_del_init(&lreq->scan_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) * Process updated osd map.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) * The message contains any number of incremental and full maps, normally
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) * indicating some sort of topology change in the cluster. Kick requests
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) * off to different OSDs as needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) void *p = msg->front.iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) void *const end = p + msg->front.iov_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) u32 nr_maps, maplen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) u32 epoch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) struct ceph_fsid fsid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) struct rb_root need_resend = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) LIST_HEAD(need_resend_linger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) bool handled_incremental = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) bool was_pauserd, was_pausewr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) bool pauserd, pausewr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) dout("%s have %u\n", __func__, osdc->osdmap->epoch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) down_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) /* verify fsid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) ceph_decode_need(&p, end, sizeof(fsid), bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) ceph_decode_copy(&p, &fsid, sizeof(fsid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) if (ceph_check_fsid(osdc->client, &fsid) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) was_pauserd = ceph_osdmap_flag(osdc, CEPH_OSDMAP_PAUSERD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) was_pausewr = ceph_osdmap_flag(osdc, CEPH_OSDMAP_PAUSEWR) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) ceph_osdmap_flag(osdc, CEPH_OSDMAP_FULL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) have_pool_full(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) /* incremental maps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) ceph_decode_32_safe(&p, end, nr_maps, bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) dout(" %d inc maps\n", nr_maps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) while (nr_maps > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) ceph_decode_need(&p, end, 2*sizeof(u32), bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) epoch = ceph_decode_32(&p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) maplen = ceph_decode_32(&p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) ceph_decode_need(&p, end, maplen, bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) if (osdc->osdmap->epoch &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) osdc->osdmap->epoch + 1 == epoch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) dout("applying incremental map %u len %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) epoch, maplen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) err = handle_one_map(osdc, p, p + maplen, true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) &need_resend, &need_resend_linger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) handled_incremental = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) dout("ignoring incremental map %u len %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) epoch, maplen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) p += maplen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) nr_maps--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) if (handled_incremental)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) /* full maps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) ceph_decode_32_safe(&p, end, nr_maps, bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) dout(" %d full maps\n", nr_maps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) while (nr_maps) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) ceph_decode_need(&p, end, 2*sizeof(u32), bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) epoch = ceph_decode_32(&p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) maplen = ceph_decode_32(&p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) ceph_decode_need(&p, end, maplen, bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) if (nr_maps > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) dout("skipping non-latest full map %u len %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) epoch, maplen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) } else if (osdc->osdmap->epoch >= epoch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) dout("skipping full map %u len %d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) "older than our %u\n", epoch, maplen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) osdc->osdmap->epoch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) dout("taking full map %u len %d\n", epoch, maplen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) err = handle_one_map(osdc, p, p + maplen, false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) &need_resend, &need_resend_linger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) p += maplen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) nr_maps--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) * subscribe to subsequent osdmap updates if full to ensure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) * we find out when we are no longer full and stop returning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) * ENOSPC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) pauserd = ceph_osdmap_flag(osdc, CEPH_OSDMAP_PAUSERD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) pausewr = ceph_osdmap_flag(osdc, CEPH_OSDMAP_PAUSEWR) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) ceph_osdmap_flag(osdc, CEPH_OSDMAP_FULL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) have_pool_full(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) if (was_pauserd || was_pausewr || pauserd || pausewr ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) osdc->osdmap->epoch < osdc->epoch_barrier)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) maybe_request_map(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) kick_requests(osdc, &need_resend, &need_resend_linger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) ceph_osdc_abort_on_full(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) ceph_monc_got_map(&osdc->client->monc, CEPH_SUB_OSDMAP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) osdc->osdmap->epoch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) up_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) wake_up_all(&osdc->client->auth_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) bad:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) pr_err("osdc handle_map corrupt msg\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) ceph_msg_dump(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) up_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) * Resubmit requests pending on the given osd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) static void kick_osd_requests(struct ceph_osd *osd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) struct rb_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) clear_backoffs(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) for (n = rb_first(&osd->o_requests); n; ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) struct ceph_osd_request *req =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) rb_entry(n, struct ceph_osd_request, r_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) n = rb_next(n); /* cancel_linger_request() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) if (!req->r_linger) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) if (!req->r_t.paused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) send_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) cancel_linger_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) for (n = rb_first(&osd->o_linger_requests); n; n = rb_next(n)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) struct ceph_osd_linger_request *lreq =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) rb_entry(n, struct ceph_osd_linger_request, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) send_linger(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) * If the osd connection drops, we need to resubmit all requests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) static void osd_fault(struct ceph_connection *con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) struct ceph_osd *osd = con->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) struct ceph_osd_client *osdc = osd->o_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) dout("%s osd %p osd%d\n", __func__, osd, osd->o_osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) down_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) if (!osd_registered(osd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) dout("%s osd%d unknown\n", __func__, osd->o_osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) if (!reopen_osd(osd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) kick_osd_requests(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) maybe_request_map(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) up_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) struct MOSDBackoff {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) struct ceph_spg spgid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) u32 map_epoch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) u8 op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) u64 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) struct ceph_hobject_id *begin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) struct ceph_hobject_id *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) static int decode_MOSDBackoff(const struct ceph_msg *msg, struct MOSDBackoff *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) void *p = msg->front.iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) void *const end = p + msg->front.iov_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) u8 struct_v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) u32 struct_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) ret = ceph_start_decoding(&p, end, 1, "spg_t", &struct_v, &struct_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) ret = ceph_decode_pgid(&p, end, &m->spgid.pgid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) ceph_decode_8_safe(&p, end, m->spgid.shard, e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) ceph_decode_32_safe(&p, end, m->map_epoch, e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) ceph_decode_8_safe(&p, end, m->op, e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) ceph_decode_64_safe(&p, end, m->id, e_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) m->begin = kzalloc(sizeof(*m->begin), GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) if (!m->begin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) ret = decode_hoid(&p, end, m->begin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) free_hoid(m->begin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) m->end = kzalloc(sizeof(*m->end), GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) if (!m->end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) free_hoid(m->begin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) ret = decode_hoid(&p, end, m->end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) free_hoid(m->begin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) free_hoid(m->end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) e_inval:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) static struct ceph_msg *create_backoff_message(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) const struct ceph_osd_backoff *backoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) u32 map_epoch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) struct ceph_msg *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) void *p, *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) int msg_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) msg_size = CEPH_ENCODING_START_BLK_LEN +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) CEPH_PGID_ENCODING_LEN + 1; /* spgid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) msg_size += 4 + 1 + 8; /* map_epoch, op, id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) msg_size += CEPH_ENCODING_START_BLK_LEN +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) hoid_encoding_size(backoff->begin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) msg_size += CEPH_ENCODING_START_BLK_LEN +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) hoid_encoding_size(backoff->end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) msg = ceph_msg_new(CEPH_MSG_OSD_BACKOFF, msg_size, GFP_NOIO, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) p = msg->front.iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) end = p + msg->front_alloc_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) encode_spgid(&p, &backoff->spgid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) ceph_encode_32(&p, map_epoch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) ceph_encode_8(&p, CEPH_OSD_BACKOFF_OP_ACK_BLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) ceph_encode_64(&p, backoff->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) encode_hoid(&p, end, backoff->begin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) encode_hoid(&p, end, backoff->end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) BUG_ON(p != end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) msg->front.iov_len = p - msg->front.iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) msg->hdr.version = cpu_to_le16(1); /* MOSDBackoff v1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) msg->hdr.front_len = cpu_to_le32(msg->front.iov_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) return msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) static void handle_backoff_block(struct ceph_osd *osd, struct MOSDBackoff *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) struct ceph_spg_mapping *spg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) struct ceph_osd_backoff *backoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) struct ceph_msg *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) dout("%s osd%d spgid %llu.%xs%d id %llu\n", __func__, osd->o_osd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) m->spgid.pgid.pool, m->spgid.pgid.seed, m->spgid.shard, m->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) spg = lookup_spg_mapping(&osd->o_backoff_mappings, &m->spgid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) if (!spg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) spg = alloc_spg_mapping();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) if (!spg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) pr_err("%s failed to allocate spg\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) spg->spgid = m->spgid; /* struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) insert_spg_mapping(&osd->o_backoff_mappings, spg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) backoff = alloc_backoff();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) if (!backoff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) pr_err("%s failed to allocate backoff\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) backoff->spgid = m->spgid; /* struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) backoff->id = m->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) backoff->begin = m->begin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) m->begin = NULL; /* backoff now owns this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) backoff->end = m->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) m->end = NULL; /* ditto */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) insert_backoff(&spg->backoffs, backoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) insert_backoff_by_id(&osd->o_backoffs_by_id, backoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330) * Ack with original backoff's epoch so that the OSD can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) * discard this if there was a PG split.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) msg = create_backoff_message(backoff, m->map_epoch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) if (!msg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) pr_err("%s failed to allocate msg\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) ceph_con_send(&osd->o_con, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) static bool target_contained_by(const struct ceph_osd_request_target *t,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342) const struct ceph_hobject_id *begin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) const struct ceph_hobject_id *end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345) struct ceph_hobject_id hoid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) int cmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) hoid_fill_from_target(&hoid, t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) cmp = hoid_compare(&hoid, begin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) return !cmp || (cmp > 0 && hoid_compare(&hoid, end) < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353) static void handle_backoff_unblock(struct ceph_osd *osd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) const struct MOSDBackoff *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) struct ceph_spg_mapping *spg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) struct ceph_osd_backoff *backoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) struct rb_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) dout("%s osd%d spgid %llu.%xs%d id %llu\n", __func__, osd->o_osd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) m->spgid.pgid.pool, m->spgid.pgid.seed, m->spgid.shard, m->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) backoff = lookup_backoff_by_id(&osd->o_backoffs_by_id, m->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) if (!backoff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) pr_err("%s osd%d spgid %llu.%xs%d id %llu backoff dne\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) __func__, osd->o_osd, m->spgid.pgid.pool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) m->spgid.pgid.seed, m->spgid.shard, m->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) if (hoid_compare(backoff->begin, m->begin) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) hoid_compare(backoff->end, m->end)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) pr_err("%s osd%d spgid %llu.%xs%d id %llu bad range?\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) __func__, osd->o_osd, m->spgid.pgid.pool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) m->spgid.pgid.seed, m->spgid.shard, m->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) /* unblock it anyway... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) spg = lookup_spg_mapping(&osd->o_backoff_mappings, &backoff->spgid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) BUG_ON(!spg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) erase_backoff(&spg->backoffs, backoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) erase_backoff_by_id(&osd->o_backoffs_by_id, backoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) free_backoff(backoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) if (RB_EMPTY_ROOT(&spg->backoffs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) erase_spg_mapping(&osd->o_backoff_mappings, spg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) free_spg_mapping(spg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) for (n = rb_first(&osd->o_requests); n; n = rb_next(n)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) struct ceph_osd_request *req =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) rb_entry(n, struct ceph_osd_request, r_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) if (!ceph_spg_compare(&req->r_t.spgid, &m->spgid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) * Match against @m, not @backoff -- the PG may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) * have split on the OSD.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) if (target_contained_by(&req->r_t, m->begin, m->end)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) * If no other installed backoff applies,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) * resend.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) send_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) static void handle_backoff(struct ceph_osd *osd, struct ceph_msg *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) struct ceph_osd_client *osdc = osd->o_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414) struct MOSDBackoff m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) down_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) if (!osd_registered(osd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) dout("%s osd%d unknown\n", __func__, osd->o_osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) up_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) WARN_ON(osd->o_osd != le64_to_cpu(msg->hdr.src.num));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) mutex_lock(&osd->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) ret = decode_MOSDBackoff(msg, &m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) pr_err("failed to decode MOSDBackoff: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) ceph_msg_dump(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) switch (m.op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) case CEPH_OSD_BACKOFF_OP_BLOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) handle_backoff_block(osd, &m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) case CEPH_OSD_BACKOFF_OP_UNBLOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) handle_backoff_unblock(osd, &m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) pr_err("%s osd%d unknown op %d\n", __func__, osd->o_osd, m.op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) free_hoid(m.begin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) free_hoid(m.end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) mutex_unlock(&osd->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) up_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) * Process osd watch notifications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) static void handle_watch_notify(struct ceph_osd_client *osdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456) struct ceph_msg *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) void *p = msg->front.iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) void *const end = p + msg->front.iov_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) struct ceph_osd_linger_request *lreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) struct linger_work *lwork;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) u8 proto_ver, opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) u64 cookie, notify_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) u64 notifier_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) s32 return_code = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) void *payload = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) u32 payload_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) ceph_decode_8_safe(&p, end, proto_ver, bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) ceph_decode_8_safe(&p, end, opcode, bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) ceph_decode_64_safe(&p, end, cookie, bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) p += 8; /* skip ver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) ceph_decode_64_safe(&p, end, notify_id, bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) if (proto_ver >= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) ceph_decode_32_safe(&p, end, payload_len, bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) ceph_decode_need(&p, end, payload_len, bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) payload = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) p += payload_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) if (le16_to_cpu(msg->hdr.version) >= 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483) ceph_decode_32_safe(&p, end, return_code, bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) if (le16_to_cpu(msg->hdr.version) >= 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) ceph_decode_64_safe(&p, end, notifier_id, bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) down_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) lreq = lookup_linger_osdc(&osdc->linger_requests, cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) if (!lreq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) dout("%s opcode %d cookie %llu dne\n", __func__, opcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) goto out_unlock_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) mutex_lock(&lreq->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) dout("%s opcode %d cookie %llu lreq %p is_watch %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) opcode, cookie, lreq, lreq->is_watch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) if (opcode == CEPH_WATCH_EVENT_DISCONNECT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) if (!lreq->last_error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) lreq->last_error = -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) queue_watch_error(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) } else if (!lreq->is_watch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505) /* CEPH_WATCH_EVENT_NOTIFY_COMPLETE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506) if (lreq->notify_id && lreq->notify_id != notify_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) dout("lreq %p notify_id %llu != %llu, ignoring\n", lreq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) lreq->notify_id, notify_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) } else if (!completion_done(&lreq->notify_finish_wait)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) struct ceph_msg_data *data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) msg->num_data_items ? &msg->data[0] : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) if (data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) if (lreq->preply_pages) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) WARN_ON(data->type !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) CEPH_MSG_DATA_PAGES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) *lreq->preply_pages = data->pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) *lreq->preply_len = data->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) data->own_pages = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) lreq->notify_finish_error = return_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) complete_all(&lreq->notify_finish_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) /* CEPH_WATCH_EVENT_NOTIFY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) lwork = lwork_alloc(lreq, do_watch_notify);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) if (!lwork) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) pr_err("failed to allocate notify-lwork\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) goto out_unlock_lreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) lwork->notify.notify_id = notify_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) lwork->notify.notifier_id = notifier_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) lwork->notify.payload = payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) lwork->notify.payload_len = payload_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) lwork->notify.msg = ceph_msg_get(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) lwork_queue(lwork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) out_unlock_lreq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) mutex_unlock(&lreq->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) out_unlock_osdc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) up_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) bad:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548) pr_err("osdc handle_watch_notify corrupt msg\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552) * Register request, send initial attempt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) int ceph_osdc_start_request(struct ceph_osd_client *osdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) struct ceph_osd_request *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) bool nofail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) down_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) submit_request(req, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560) up_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) EXPORT_SYMBOL(ceph_osdc_start_request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) * Unregister a registered request. The request is not completed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) * ->r_result isn't set and __complete_request() isn't called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) void ceph_osdc_cancel_request(struct ceph_osd_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) struct ceph_osd_client *osdc = req->r_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) down_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575) if (req->r_osd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) cancel_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577) up_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) EXPORT_SYMBOL(ceph_osdc_cancel_request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) * @timeout: in jiffies, 0 means "wait forever"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584) static int wait_request_timeout(struct ceph_osd_request *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) unsigned long timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) long left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) dout("%s req %p tid %llu\n", __func__, req, req->r_tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) left = wait_for_completion_killable_timeout(&req->r_completion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591) ceph_timeout_jiffies(timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) if (left <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) left = left ?: -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) ceph_osdc_cancel_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) left = req->r_result; /* completed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) return left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) * wait for a request to complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605) int ceph_osdc_wait_request(struct ceph_osd_client *osdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606) struct ceph_osd_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) return wait_request_timeout(req, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610) EXPORT_SYMBOL(ceph_osdc_wait_request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) * sync - wait for all in-flight requests to flush. avoid starvation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) void ceph_osdc_sync(struct ceph_osd_client *osdc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617) struct rb_node *n, *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618) u64 last_tid = atomic64_read(&osdc->last_tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621) down_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622) for (n = rb_first(&osdc->osds); n; n = rb_next(n)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623) struct ceph_osd *osd = rb_entry(n, struct ceph_osd, o_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) mutex_lock(&osd->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) for (p = rb_first(&osd->o_requests); p; p = rb_next(p)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627) struct ceph_osd_request *req =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628) rb_entry(p, struct ceph_osd_request, r_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) if (req->r_tid > last_tid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) if (!(req->r_flags & CEPH_OSD_FLAG_WRITE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636) ceph_osdc_get_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) mutex_unlock(&osd->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) up_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639) dout("%s waiting on req %p tid %llu last_tid %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640) __func__, req, req->r_tid, last_tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) wait_for_completion(&req->r_completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642) ceph_osdc_put_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646) mutex_unlock(&osd->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) up_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650) dout("%s done last_tid %llu\n", __func__, last_tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652) EXPORT_SYMBOL(ceph_osdc_sync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654) static struct ceph_osd_request *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655) alloc_linger_request(struct ceph_osd_linger_request *lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) struct ceph_osd_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659) req = ceph_osdc_alloc_request(lreq->osdc, NULL, 1, false, GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660) if (!req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663) ceph_oid_copy(&req->r_base_oid, &lreq->t.base_oid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664) ceph_oloc_copy(&req->r_base_oloc, &lreq->t.base_oloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665) return req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668) static struct ceph_osd_request *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669) alloc_watch_request(struct ceph_osd_linger_request *lreq, u8 watch_opcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671) struct ceph_osd_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673) req = alloc_linger_request(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674) if (!req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678) * Pass 0 for cookie because we don't know it yet, it will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679) * filled in by linger_submit().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681) osd_req_op_watch_init(req, 0, 0, watch_opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683) if (ceph_osdc_alloc_messages(req, GFP_NOIO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684) ceph_osdc_put_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688) return req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692) * Returns a handle, caller owns a ref.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694) struct ceph_osd_linger_request *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695) ceph_osdc_watch(struct ceph_osd_client *osdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696) struct ceph_object_id *oid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697) struct ceph_object_locator *oloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698) rados_watchcb2_t wcb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699) rados_watcherrcb_t errcb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702) struct ceph_osd_linger_request *lreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705) lreq = linger_alloc(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706) if (!lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709) lreq->is_watch = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710) lreq->wcb = wcb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711) lreq->errcb = errcb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712) lreq->data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713) lreq->watch_valid_thru = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) ceph_oid_copy(&lreq->t.base_oid, oid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) ceph_oloc_copy(&lreq->t.base_oloc, oloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717) lreq->t.flags = CEPH_OSD_FLAG_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718) ktime_get_real_ts64(&lreq->mtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720) lreq->reg_req = alloc_watch_request(lreq, CEPH_OSD_WATCH_OP_WATCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721) if (!lreq->reg_req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723) goto err_put_lreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726) lreq->ping_req = alloc_watch_request(lreq, CEPH_OSD_WATCH_OP_PING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727) if (!lreq->ping_req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729) goto err_put_lreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732) linger_submit(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) ret = linger_reg_commit_wait(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735) linger_cancel(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) goto err_put_lreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739) return lreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741) err_put_lreq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) linger_put(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745) EXPORT_SYMBOL(ceph_osdc_watch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748) * Releases a ref.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750) * Times out after mount_timeout to preserve rbd unmap behaviour
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751) * introduced in 2894e1d76974 ("rbd: timeout watch teardown on unmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752) * with mount_timeout").
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754) int ceph_osdc_unwatch(struct ceph_osd_client *osdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755) struct ceph_osd_linger_request *lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757) struct ceph_options *opts = osdc->client->options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758) struct ceph_osd_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761) req = ceph_osdc_alloc_request(osdc, NULL, 1, false, GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762) if (!req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765) ceph_oid_copy(&req->r_base_oid, &lreq->t.base_oid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766) ceph_oloc_copy(&req->r_base_oloc, &lreq->t.base_oloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767) req->r_flags = CEPH_OSD_FLAG_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768) ktime_get_real_ts64(&req->r_mtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) osd_req_op_watch_init(req, 0, lreq->linger_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770) CEPH_OSD_WATCH_OP_UNWATCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772) ret = ceph_osdc_alloc_messages(req, GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774) goto out_put_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776) ceph_osdc_start_request(osdc, req, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777) linger_cancel(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778) linger_put(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779) ret = wait_request_timeout(req, opts->mount_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) out_put_req:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782) ceph_osdc_put_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785) EXPORT_SYMBOL(ceph_osdc_unwatch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787) static int osd_req_op_notify_ack_init(struct ceph_osd_request *req, int which,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788) u64 notify_id, u64 cookie, void *payload,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789) u32 payload_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791) struct ceph_osd_req_op *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792) struct ceph_pagelist *pl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795) op = osd_req_op_init(req, which, CEPH_OSD_OP_NOTIFY_ACK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797) pl = ceph_pagelist_alloc(GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798) if (!pl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801) ret = ceph_pagelist_encode_64(pl, notify_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802) ret |= ceph_pagelist_encode_64(pl, cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803) if (payload) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804) ret |= ceph_pagelist_encode_32(pl, payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805) ret |= ceph_pagelist_append(pl, payload, payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807) ret |= ceph_pagelist_encode_32(pl, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810) ceph_pagelist_release(pl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814) ceph_osd_data_pagelist_init(&op->notify_ack.request_data, pl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815) op->indata_len = pl->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819) int ceph_osdc_notify_ack(struct ceph_osd_client *osdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820) struct ceph_object_id *oid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821) struct ceph_object_locator *oloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822) u64 notify_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823) u64 cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824) void *payload,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825) u32 payload_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827) struct ceph_osd_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830) req = ceph_osdc_alloc_request(osdc, NULL, 1, false, GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831) if (!req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834) ceph_oid_copy(&req->r_base_oid, oid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835) ceph_oloc_copy(&req->r_base_oloc, oloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836) req->r_flags = CEPH_OSD_FLAG_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838) ret = osd_req_op_notify_ack_init(req, 0, notify_id, cookie, payload,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839) payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841) goto out_put_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843) ret = ceph_osdc_alloc_messages(req, GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845) goto out_put_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) ceph_osdc_start_request(osdc, req, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848) ret = ceph_osdc_wait_request(osdc, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850) out_put_req:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851) ceph_osdc_put_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854) EXPORT_SYMBOL(ceph_osdc_notify_ack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856) static int osd_req_op_notify_init(struct ceph_osd_request *req, int which,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857) u64 cookie, u32 prot_ver, u32 timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) void *payload, u32 payload_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860) struct ceph_osd_req_op *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861) struct ceph_pagelist *pl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864) op = osd_req_op_init(req, which, CEPH_OSD_OP_NOTIFY, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865) op->notify.cookie = cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867) pl = ceph_pagelist_alloc(GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868) if (!pl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871) ret = ceph_pagelist_encode_32(pl, 1); /* prot_ver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872) ret |= ceph_pagelist_encode_32(pl, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873) ret |= ceph_pagelist_encode_32(pl, payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874) ret |= ceph_pagelist_append(pl, payload, payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876) ceph_pagelist_release(pl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) ceph_osd_data_pagelist_init(&op->notify.request_data, pl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881) op->indata_len = pl->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886) * @timeout: in seconds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888) * @preply_{pages,len} are initialized both on success and error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889) * The caller is responsible for:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891) * ceph_release_page_vector(reply_pages, calc_pages_for(0, reply_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893) int ceph_osdc_notify(struct ceph_osd_client *osdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894) struct ceph_object_id *oid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895) struct ceph_object_locator *oloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896) void *payload,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897) u32 payload_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898) u32 timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899) struct page ***preply_pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900) size_t *preply_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902) struct ceph_osd_linger_request *lreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903) struct page **pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906) WARN_ON(!timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907) if (preply_pages) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908) *preply_pages = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909) *preply_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912) lreq = linger_alloc(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913) if (!lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916) lreq->preply_pages = preply_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917) lreq->preply_len = preply_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919) ceph_oid_copy(&lreq->t.base_oid, oid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4920) ceph_oloc_copy(&lreq->t.base_oloc, oloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4921) lreq->t.flags = CEPH_OSD_FLAG_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4923) lreq->reg_req = alloc_linger_request(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4924) if (!lreq->reg_req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4925) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4926) goto out_put_lreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4929) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4930) * Pass 0 for cookie because we don't know it yet, it will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4931) * filled in by linger_submit().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4932) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4933) ret = osd_req_op_notify_init(lreq->reg_req, 0, 0, 1, timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4934) payload, payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4935) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4936) goto out_put_lreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4938) /* for notify_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4939) pages = ceph_alloc_page_vector(1, GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4940) if (IS_ERR(pages)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4941) ret = PTR_ERR(pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4942) goto out_put_lreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4944) ceph_osd_data_pages_init(osd_req_op_data(lreq->reg_req, 0, notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4945) response_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4946) pages, PAGE_SIZE, 0, false, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4948) ret = ceph_osdc_alloc_messages(lreq->reg_req, GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4949) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4950) goto out_put_lreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4952) linger_submit(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4953) ret = linger_reg_commit_wait(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4954) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4955) ret = linger_notify_finish_wait(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4956) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4957) dout("lreq %p failed to initiate notify %d\n", lreq, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4959) linger_cancel(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4960) out_put_lreq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4961) linger_put(lreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4962) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4964) EXPORT_SYMBOL(ceph_osdc_notify);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4966) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4967) * Return the number of milliseconds since the watch was last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4968) * confirmed, or an error. If there is an error, the watch is no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4969) * longer valid, and should be destroyed with ceph_osdc_unwatch().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4970) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4971) int ceph_osdc_watch_check(struct ceph_osd_client *osdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4972) struct ceph_osd_linger_request *lreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4973) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4974) unsigned long stamp, age;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4975) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4977) down_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4978) mutex_lock(&lreq->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4979) stamp = lreq->watch_valid_thru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4980) if (!list_empty(&lreq->pending_lworks)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4981) struct linger_work *lwork =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4982) list_first_entry(&lreq->pending_lworks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4983) struct linger_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4984) pending_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4986) if (time_before(lwork->queued_stamp, stamp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4987) stamp = lwork->queued_stamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4989) age = jiffies - stamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4990) dout("%s lreq %p linger_id %llu age %lu last_error %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4991) lreq, lreq->linger_id, age, lreq->last_error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4992) /* we are truncating to msecs, so return a safe upper bound */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4993) ret = lreq->last_error ?: 1 + jiffies_to_msecs(age);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4995) mutex_unlock(&lreq->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4996) up_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4997) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5000) static int decode_watcher(void **p, void *end, struct ceph_watch_item *item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5002) u8 struct_v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5003) u32 struct_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5004) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5006) ret = ceph_start_decoding(p, end, 2, "watch_item_t",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5007) &struct_v, &struct_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5008) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5009) goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5011) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5012) ceph_decode_copy_safe(p, end, &item->name, sizeof(item->name), bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5013) ceph_decode_64_safe(p, end, item->cookie, bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5014) ceph_decode_skip_32(p, end, bad); /* skip timeout seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5016) if (struct_v >= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5017) ret = ceph_decode_entity_addr(p, end, &item->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5018) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5019) goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5020) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5021) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5024) dout("%s %s%llu cookie %llu addr %s\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5025) ENTITY_NAME(item->name), item->cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5026) ceph_pr_addr(&item->addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5027) bad:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5028) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5031) static int decode_watchers(void **p, void *end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5032) struct ceph_watch_item **watchers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5033) u32 *num_watchers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5034) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5035) u8 struct_v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5036) u32 struct_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5037) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5038) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5040) ret = ceph_start_decoding(p, end, 1, "obj_list_watch_response_t",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5041) &struct_v, &struct_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5042) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5043) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5045) *num_watchers = ceph_decode_32(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5046) *watchers = kcalloc(*num_watchers, sizeof(**watchers), GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5047) if (!*watchers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5048) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5050) for (i = 0; i < *num_watchers; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5051) ret = decode_watcher(p, end, *watchers + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5052) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5053) kfree(*watchers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5054) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5058) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5061) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5062) * On success, the caller is responsible for:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5063) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5064) * kfree(watchers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5065) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5066) int ceph_osdc_list_watchers(struct ceph_osd_client *osdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5067) struct ceph_object_id *oid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5068) struct ceph_object_locator *oloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5069) struct ceph_watch_item **watchers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5070) u32 *num_watchers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5071) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5072) struct ceph_osd_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5073) struct page **pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5074) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5076) req = ceph_osdc_alloc_request(osdc, NULL, 1, false, GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5077) if (!req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5078) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5080) ceph_oid_copy(&req->r_base_oid, oid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5081) ceph_oloc_copy(&req->r_base_oloc, oloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5082) req->r_flags = CEPH_OSD_FLAG_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5084) pages = ceph_alloc_page_vector(1, GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5085) if (IS_ERR(pages)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5086) ret = PTR_ERR(pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5087) goto out_put_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5090) osd_req_op_init(req, 0, CEPH_OSD_OP_LIST_WATCHERS, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5091) ceph_osd_data_pages_init(osd_req_op_data(req, 0, list_watchers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5092) response_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5093) pages, PAGE_SIZE, 0, false, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5095) ret = ceph_osdc_alloc_messages(req, GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5096) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5097) goto out_put_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5099) ceph_osdc_start_request(osdc, req, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5100) ret = ceph_osdc_wait_request(osdc, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5101) if (ret >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5102) void *p = page_address(pages[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5103) void *const end = p + req->r_ops[0].outdata_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5105) ret = decode_watchers(&p, end, watchers, num_watchers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5108) out_put_req:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5109) ceph_osdc_put_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5110) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5112) EXPORT_SYMBOL(ceph_osdc_list_watchers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5114) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5115) * Call all pending notify callbacks - for use after a watch is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5116) * unregistered, to make sure no more callbacks for it will be invoked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5117) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5118) void ceph_osdc_flush_notifies(struct ceph_osd_client *osdc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5120) dout("%s osdc %p\n", __func__, osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5121) flush_workqueue(osdc->notify_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5123) EXPORT_SYMBOL(ceph_osdc_flush_notifies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5125) void ceph_osdc_maybe_request_map(struct ceph_osd_client *osdc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5127) down_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5128) maybe_request_map(osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5129) up_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5131) EXPORT_SYMBOL(ceph_osdc_maybe_request_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5133) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5134) * Execute an OSD class method on an object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5135) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5136) * @flags: CEPH_OSD_FLAG_*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5137) * @resp_len: in/out param for reply length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5139) int ceph_osdc_call(struct ceph_osd_client *osdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5140) struct ceph_object_id *oid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5141) struct ceph_object_locator *oloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5142) const char *class, const char *method,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5143) unsigned int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5144) struct page *req_page, size_t req_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5145) struct page **resp_pages, size_t *resp_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5147) struct ceph_osd_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5148) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5150) if (req_len > PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5151) return -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5153) req = ceph_osdc_alloc_request(osdc, NULL, 1, false, GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5154) if (!req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5155) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5157) ceph_oid_copy(&req->r_base_oid, oid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5158) ceph_oloc_copy(&req->r_base_oloc, oloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5159) req->r_flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5161) ret = osd_req_op_cls_init(req, 0, class, method);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5162) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5163) goto out_put_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5165) if (req_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5166) osd_req_op_cls_request_data_pages(req, 0, &req_page, req_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5167) 0, false, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5168) if (resp_pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5169) osd_req_op_cls_response_data_pages(req, 0, resp_pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5170) *resp_len, 0, false, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5172) ret = ceph_osdc_alloc_messages(req, GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5173) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5174) goto out_put_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5176) ceph_osdc_start_request(osdc, req, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5177) ret = ceph_osdc_wait_request(osdc, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5178) if (ret >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5179) ret = req->r_ops[0].rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5180) if (resp_pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5181) *resp_len = req->r_ops[0].outdata_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5184) out_put_req:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5185) ceph_osdc_put_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5186) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5188) EXPORT_SYMBOL(ceph_osdc_call);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5190) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5191) * reset all osd connections
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5192) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5193) void ceph_osdc_reopen_osds(struct ceph_osd_client *osdc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5195) struct rb_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5197) down_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5198) for (n = rb_first(&osdc->osds); n; ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5199) struct ceph_osd *osd = rb_entry(n, struct ceph_osd, o_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5201) n = rb_next(n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5202) if (!reopen_osd(osd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5203) kick_osd_requests(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5205) up_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5208) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5209) * init, shutdown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5210) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5211) int ceph_osdc_init(struct ceph_osd_client *osdc, struct ceph_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5213) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5215) dout("init\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5216) osdc->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5217) init_rwsem(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5218) osdc->osds = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5219) INIT_LIST_HEAD(&osdc->osd_lru);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5220) spin_lock_init(&osdc->osd_lru_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5221) osd_init(&osdc->homeless_osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5222) osdc->homeless_osd.o_osdc = osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5223) osdc->homeless_osd.o_osd = CEPH_HOMELESS_OSD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5224) osdc->last_linger_id = CEPH_LINGER_ID_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5225) osdc->linger_requests = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5226) osdc->map_checks = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5227) osdc->linger_map_checks = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5228) INIT_DELAYED_WORK(&osdc->timeout_work, handle_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5229) INIT_DELAYED_WORK(&osdc->osds_timeout_work, handle_osds_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5231) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5232) osdc->osdmap = ceph_osdmap_alloc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5233) if (!osdc->osdmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5234) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5236) osdc->req_mempool = mempool_create_slab_pool(10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5237) ceph_osd_request_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5238) if (!osdc->req_mempool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5239) goto out_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5241) err = ceph_msgpool_init(&osdc->msgpool_op, CEPH_MSG_OSD_OP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5242) PAGE_SIZE, CEPH_OSD_SLAB_OPS, 10, "osd_op");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5243) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5244) goto out_mempool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5245) err = ceph_msgpool_init(&osdc->msgpool_op_reply, CEPH_MSG_OSD_OPREPLY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5246) PAGE_SIZE, CEPH_OSD_SLAB_OPS, 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5247) "osd_op_reply");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5248) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5249) goto out_msgpool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5251) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5252) osdc->notify_wq = create_singlethread_workqueue("ceph-watch-notify");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5253) if (!osdc->notify_wq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5254) goto out_msgpool_reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5256) osdc->completion_wq = create_singlethread_workqueue("ceph-completion");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5257) if (!osdc->completion_wq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5258) goto out_notify_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5260) schedule_delayed_work(&osdc->timeout_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5261) osdc->client->options->osd_keepalive_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5262) schedule_delayed_work(&osdc->osds_timeout_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5263) round_jiffies_relative(osdc->client->options->osd_idle_ttl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5265) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5267) out_notify_wq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5268) destroy_workqueue(osdc->notify_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5269) out_msgpool_reply:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5270) ceph_msgpool_destroy(&osdc->msgpool_op_reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5271) out_msgpool:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5272) ceph_msgpool_destroy(&osdc->msgpool_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5273) out_mempool:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5274) mempool_destroy(osdc->req_mempool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5275) out_map:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5276) ceph_osdmap_destroy(osdc->osdmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5277) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5278) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5281) void ceph_osdc_stop(struct ceph_osd_client *osdc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5283) destroy_workqueue(osdc->completion_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5284) destroy_workqueue(osdc->notify_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5285) cancel_delayed_work_sync(&osdc->timeout_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5286) cancel_delayed_work_sync(&osdc->osds_timeout_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5288) down_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5289) while (!RB_EMPTY_ROOT(&osdc->osds)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5290) struct ceph_osd *osd = rb_entry(rb_first(&osdc->osds),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5291) struct ceph_osd, o_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5292) close_osd(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5294) up_write(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5295) WARN_ON(refcount_read(&osdc->homeless_osd.o_ref) != 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5296) osd_cleanup(&osdc->homeless_osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5298) WARN_ON(!list_empty(&osdc->osd_lru));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5299) WARN_ON(!RB_EMPTY_ROOT(&osdc->linger_requests));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5300) WARN_ON(!RB_EMPTY_ROOT(&osdc->map_checks));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5301) WARN_ON(!RB_EMPTY_ROOT(&osdc->linger_map_checks));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5302) WARN_ON(atomic_read(&osdc->num_requests));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5303) WARN_ON(atomic_read(&osdc->num_homeless));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5305) ceph_osdmap_destroy(osdc->osdmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5306) mempool_destroy(osdc->req_mempool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5307) ceph_msgpool_destroy(&osdc->msgpool_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5308) ceph_msgpool_destroy(&osdc->msgpool_op_reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5311) static int osd_req_op_copy_from_init(struct ceph_osd_request *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5312) u64 src_snapid, u64 src_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5313) struct ceph_object_id *src_oid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5314) struct ceph_object_locator *src_oloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5315) u32 src_fadvise_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5316) u32 dst_fadvise_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5317) u32 truncate_seq, u64 truncate_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5318) u8 copy_from_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5320) struct ceph_osd_req_op *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5321) struct page **pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5322) void *p, *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5324) pages = ceph_alloc_page_vector(1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5325) if (IS_ERR(pages))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5326) return PTR_ERR(pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5328) op = osd_req_op_init(req, 0, CEPH_OSD_OP_COPY_FROM2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5329) dst_fadvise_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5330) op->copy_from.snapid = src_snapid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5331) op->copy_from.src_version = src_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5332) op->copy_from.flags = copy_from_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5333) op->copy_from.src_fadvise_flags = src_fadvise_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5335) p = page_address(pages[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5336) end = p + PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5337) ceph_encode_string(&p, end, src_oid->name, src_oid->name_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5338) encode_oloc(&p, end, src_oloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5339) ceph_encode_32(&p, truncate_seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5340) ceph_encode_64(&p, truncate_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5341) op->indata_len = PAGE_SIZE - (end - p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5343) ceph_osd_data_pages_init(&op->copy_from.osd_data, pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5344) op->indata_len, 0, false, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5345) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5348) int ceph_osdc_copy_from(struct ceph_osd_client *osdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5349) u64 src_snapid, u64 src_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5350) struct ceph_object_id *src_oid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5351) struct ceph_object_locator *src_oloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5352) u32 src_fadvise_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5353) struct ceph_object_id *dst_oid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5354) struct ceph_object_locator *dst_oloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5355) u32 dst_fadvise_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5356) u32 truncate_seq, u64 truncate_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5357) u8 copy_from_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5359) struct ceph_osd_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5360) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5362) req = ceph_osdc_alloc_request(osdc, NULL, 1, false, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5363) if (!req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5364) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5366) req->r_flags = CEPH_OSD_FLAG_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5368) ceph_oloc_copy(&req->r_t.base_oloc, dst_oloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5369) ceph_oid_copy(&req->r_t.base_oid, dst_oid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5371) ret = osd_req_op_copy_from_init(req, src_snapid, src_version, src_oid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5372) src_oloc, src_fadvise_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5373) dst_fadvise_flags, truncate_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5374) truncate_size, copy_from_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5375) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5376) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5378) ret = ceph_osdc_alloc_messages(req, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5379) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5380) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5382) ceph_osdc_start_request(osdc, req, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5383) ret = ceph_osdc_wait_request(osdc, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5385) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5386) ceph_osdc_put_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5387) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5389) EXPORT_SYMBOL(ceph_osdc_copy_from);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5391) int __init ceph_osdc_setup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5393) size_t size = sizeof(struct ceph_osd_request) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5394) CEPH_OSD_SLAB_OPS * sizeof(struct ceph_osd_req_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5396) BUG_ON(ceph_osd_request_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5397) ceph_osd_request_cache = kmem_cache_create("ceph_osd_request", size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5398) 0, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5400) return ceph_osd_request_cache ? 0 : -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5403) void ceph_osdc_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5405) BUG_ON(!ceph_osd_request_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5406) kmem_cache_destroy(ceph_osd_request_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5407) ceph_osd_request_cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5410) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5411) * handle incoming message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5412) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5413) static void dispatch(struct ceph_connection *con, struct ceph_msg *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5415) struct ceph_osd *osd = con->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5416) struct ceph_osd_client *osdc = osd->o_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5417) int type = le16_to_cpu(msg->hdr.type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5419) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5420) case CEPH_MSG_OSD_MAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5421) ceph_osdc_handle_map(osdc, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5422) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5423) case CEPH_MSG_OSD_OPREPLY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5424) handle_reply(osd, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5425) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5426) case CEPH_MSG_OSD_BACKOFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5427) handle_backoff(osd, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5428) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5429) case CEPH_MSG_WATCH_NOTIFY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5430) handle_watch_notify(osdc, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5431) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5433) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5434) pr_err("received unknown message type %d %s\n", type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5435) ceph_msg_type_name(type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5438) ceph_msg_put(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5441) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5442) * Lookup and return message for incoming reply. Don't try to do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5443) * anything about a larger than preallocated data portion of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5444) * message at the moment - for now, just skip the message.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5445) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5446) static struct ceph_msg *get_reply(struct ceph_connection *con,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5447) struct ceph_msg_header *hdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5448) int *skip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5450) struct ceph_osd *osd = con->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5451) struct ceph_osd_client *osdc = osd->o_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5452) struct ceph_msg *m = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5453) struct ceph_osd_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5454) int front_len = le32_to_cpu(hdr->front_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5455) int data_len = le32_to_cpu(hdr->data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5456) u64 tid = le64_to_cpu(hdr->tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5458) down_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5459) if (!osd_registered(osd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5460) dout("%s osd%d unknown, skipping\n", __func__, osd->o_osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5461) *skip = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5462) goto out_unlock_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5464) WARN_ON(osd->o_osd != le64_to_cpu(hdr->src.num));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5466) mutex_lock(&osd->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5467) req = lookup_request(&osd->o_requests, tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5468) if (!req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5469) dout("%s osd%d tid %llu unknown, skipping\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5470) osd->o_osd, tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5471) *skip = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5472) goto out_unlock_session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5475) ceph_msg_revoke_incoming(req->r_reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5477) if (front_len > req->r_reply->front_alloc_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5478) pr_warn("%s osd%d tid %llu front %d > preallocated %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5479) __func__, osd->o_osd, req->r_tid, front_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5480) req->r_reply->front_alloc_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5481) m = ceph_msg_new(CEPH_MSG_OSD_OPREPLY, front_len, GFP_NOFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5482) false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5483) if (!m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5484) goto out_unlock_session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5485) ceph_msg_put(req->r_reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5486) req->r_reply = m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5489) if (data_len > req->r_reply->data_length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5490) pr_warn("%s osd%d tid %llu data %d > preallocated %zu, skipping\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5491) __func__, osd->o_osd, req->r_tid, data_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5492) req->r_reply->data_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5493) m = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5494) *skip = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5495) goto out_unlock_session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5498) m = ceph_msg_get(req->r_reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5499) dout("get_reply tid %lld %p\n", tid, m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5501) out_unlock_session:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5502) mutex_unlock(&osd->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5503) out_unlock_osdc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5504) up_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5505) return m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5508) static struct ceph_msg *alloc_msg_with_page_vector(struct ceph_msg_header *hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5510) struct ceph_msg *m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5511) int type = le16_to_cpu(hdr->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5512) u32 front_len = le32_to_cpu(hdr->front_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5513) u32 data_len = le32_to_cpu(hdr->data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5515) m = ceph_msg_new2(type, front_len, 1, GFP_NOIO, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5516) if (!m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5517) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5519) if (data_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5520) struct page **pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5522) pages = ceph_alloc_page_vector(calc_pages_for(0, data_len),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5523) GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5524) if (IS_ERR(pages)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5525) ceph_msg_put(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5526) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5529) ceph_msg_data_add_pages(m, pages, data_len, 0, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5532) return m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5535) static struct ceph_msg *alloc_msg(struct ceph_connection *con,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5536) struct ceph_msg_header *hdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5537) int *skip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5539) struct ceph_osd *osd = con->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5540) int type = le16_to_cpu(hdr->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5542) *skip = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5543) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5544) case CEPH_MSG_OSD_MAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5545) case CEPH_MSG_OSD_BACKOFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5546) case CEPH_MSG_WATCH_NOTIFY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5547) return alloc_msg_with_page_vector(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5548) case CEPH_MSG_OSD_OPREPLY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5549) return get_reply(con, hdr, skip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5550) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5551) pr_warn("%s osd%d unknown msg type %d, skipping\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5552) osd->o_osd, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5553) *skip = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5554) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5558) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5559) * Wrappers to refcount containing ceph_osd struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5560) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5561) static struct ceph_connection *get_osd_con(struct ceph_connection *con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5563) struct ceph_osd *osd = con->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5564) if (get_osd(osd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5565) return con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5566) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5569) static void put_osd_con(struct ceph_connection *con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5570) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5571) struct ceph_osd *osd = con->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5572) put_osd(osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5575) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5576) * authentication
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5577) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5578) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5579) * Note: returned pointer is the address of a structure that's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5580) * managed separately. Caller must *not* attempt to free it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5581) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5582) static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5583) int *proto, int force_new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5585) struct ceph_osd *o = con->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5586) struct ceph_osd_client *osdc = o->o_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5587) struct ceph_auth_client *ac = osdc->client->monc.auth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5588) struct ceph_auth_handshake *auth = &o->o_auth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5590) if (force_new && auth->authorizer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5591) ceph_auth_destroy_authorizer(auth->authorizer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5592) auth->authorizer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5594) if (!auth->authorizer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5595) int ret = ceph_auth_create_authorizer(ac, CEPH_ENTITY_TYPE_OSD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5596) auth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5597) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5598) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5599) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5600) int ret = ceph_auth_update_authorizer(ac, CEPH_ENTITY_TYPE_OSD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5601) auth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5602) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5603) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5605) *proto = ac->protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5607) return auth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5610) static int add_authorizer_challenge(struct ceph_connection *con,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5611) void *challenge_buf, int challenge_buf_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5613) struct ceph_osd *o = con->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5614) struct ceph_osd_client *osdc = o->o_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5615) struct ceph_auth_client *ac = osdc->client->monc.auth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5617) return ceph_auth_add_authorizer_challenge(ac, o->o_auth.authorizer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5618) challenge_buf, challenge_buf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5621) static int verify_authorizer_reply(struct ceph_connection *con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5623) struct ceph_osd *o = con->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5624) struct ceph_osd_client *osdc = o->o_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5625) struct ceph_auth_client *ac = osdc->client->monc.auth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5627) return ceph_auth_verify_authorizer_reply(ac, o->o_auth.authorizer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5630) static int invalidate_authorizer(struct ceph_connection *con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5632) struct ceph_osd *o = con->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5633) struct ceph_osd_client *osdc = o->o_osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5634) struct ceph_auth_client *ac = osdc->client->monc.auth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5636) ceph_auth_invalidate_authorizer(ac, CEPH_ENTITY_TYPE_OSD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5637) return ceph_monc_validate_auth(&osdc->client->monc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5640) static void osd_reencode_message(struct ceph_msg *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5641) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5642) int type = le16_to_cpu(msg->hdr.type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5644) if (type == CEPH_MSG_OSD_OP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5645) encode_request_finish(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5648) static int osd_sign_message(struct ceph_msg *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5649) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5650) struct ceph_osd *o = msg->con->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5651) struct ceph_auth_handshake *auth = &o->o_auth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5653) return ceph_auth_sign_message(auth, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5656) static int osd_check_message_signature(struct ceph_msg *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5658) struct ceph_osd *o = msg->con->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5659) struct ceph_auth_handshake *auth = &o->o_auth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5661) return ceph_auth_check_message_signature(auth, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5664) static const struct ceph_connection_operations osd_con_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5665) .get = get_osd_con,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5666) .put = put_osd_con,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5667) .dispatch = dispatch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5668) .get_authorizer = get_authorizer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5669) .add_authorizer_challenge = add_authorizer_challenge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5670) .verify_authorizer_reply = verify_authorizer_reply,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5671) .invalidate_authorizer = invalidate_authorizer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5672) .alloc_msg = alloc_msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5673) .reencode_message = osd_reencode_message,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5674) .sign_message = osd_sign_message,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5675) .check_message_signature = osd_check_message_signature,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5676) .fault = osd_fault,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5677) };