^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) #include <linux/ceph/ceph_debug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/ceph/cls_lock_client.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/ceph/decode.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/ceph/libceph.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * ceph_cls_lock - grab rados lock for object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * @oid, @oloc: object to lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * @lock_name: the name of the lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * @type: lock type (CEPH_CLS_LOCK_EXCLUSIVE or CEPH_CLS_LOCK_SHARED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * @cookie: user-defined identifier for this instance of the lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * @tag: user-defined tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * @desc: user-defined lock description
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * @flags: lock flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * All operations on the same lock should use the same tag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) int ceph_cls_lock(struct ceph_osd_client *osdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct ceph_object_id *oid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct ceph_object_locator *oloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) char *lock_name, u8 type, char *cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) char *tag, char *desc, u8 flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) int lock_op_buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) int name_len = strlen(lock_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) int cookie_len = strlen(cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) int tag_len = strlen(tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) int desc_len = strlen(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) void *p, *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct page *lock_op_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct timespec64 mtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) lock_op_buf_size = name_len + sizeof(__le32) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) cookie_len + sizeof(__le32) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) tag_len + sizeof(__le32) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) desc_len + sizeof(__le32) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) sizeof(struct ceph_timespec) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* flag and type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) sizeof(u8) + sizeof(u8) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) CEPH_ENCODING_START_BLK_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if (lock_op_buf_size > PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) return -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) lock_op_page = alloc_page(GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (!lock_op_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) p = page_address(lock_op_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) end = p + lock_op_buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* encode cls_lock_lock_op struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) ceph_start_encoding(&p, 1, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) lock_op_buf_size - CEPH_ENCODING_START_BLK_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) ceph_encode_string(&p, end, lock_name, name_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) ceph_encode_8(&p, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) ceph_encode_string(&p, end, cookie, cookie_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) ceph_encode_string(&p, end, tag, tag_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) ceph_encode_string(&p, end, desc, desc_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* only support infinite duration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) memset(&mtime, 0, sizeof(mtime));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) ceph_encode_timespec64(p, &mtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) p += sizeof(struct ceph_timespec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) ceph_encode_8(&p, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) dout("%s lock_name %s type %d cookie %s tag %s desc %s flags 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) __func__, lock_name, type, cookie, tag, desc, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) ret = ceph_osdc_call(osdc, oid, oloc, "lock", "lock",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) CEPH_OSD_FLAG_WRITE, lock_op_page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) lock_op_buf_size, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) dout("%s: status %d\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) __free_page(lock_op_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) EXPORT_SYMBOL(ceph_cls_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * ceph_cls_unlock - release rados lock for object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * @oid, @oloc: object to lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * @lock_name: the name of the lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * @cookie: user-defined identifier for this instance of the lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) int ceph_cls_unlock(struct ceph_osd_client *osdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct ceph_object_id *oid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct ceph_object_locator *oloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) char *lock_name, char *cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) int unlock_op_buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) int name_len = strlen(lock_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) int cookie_len = strlen(cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) void *p, *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct page *unlock_op_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) unlock_op_buf_size = name_len + sizeof(__le32) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) cookie_len + sizeof(__le32) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) CEPH_ENCODING_START_BLK_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (unlock_op_buf_size > PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) unlock_op_page = alloc_page(GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (!unlock_op_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) p = page_address(unlock_op_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) end = p + unlock_op_buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* encode cls_lock_unlock_op struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) ceph_start_encoding(&p, 1, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) unlock_op_buf_size - CEPH_ENCODING_START_BLK_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) ceph_encode_string(&p, end, lock_name, name_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) ceph_encode_string(&p, end, cookie, cookie_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) dout("%s lock_name %s cookie %s\n", __func__, lock_name, cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) ret = ceph_osdc_call(osdc, oid, oloc, "lock", "unlock",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) CEPH_OSD_FLAG_WRITE, unlock_op_page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) unlock_op_buf_size, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) dout("%s: status %d\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) __free_page(unlock_op_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) EXPORT_SYMBOL(ceph_cls_unlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * ceph_cls_break_lock - release rados lock for object for specified client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * @oid, @oloc: object to lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * @lock_name: the name of the lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * @cookie: user-defined identifier for this instance of the lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * @locker: current lock owner
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) int ceph_cls_break_lock(struct ceph_osd_client *osdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct ceph_object_id *oid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct ceph_object_locator *oloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) char *lock_name, char *cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct ceph_entity_name *locker)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) int break_op_buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) int name_len = strlen(lock_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) int cookie_len = strlen(cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct page *break_op_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) void *p, *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) break_op_buf_size = name_len + sizeof(__le32) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) cookie_len + sizeof(__le32) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) sizeof(u8) + sizeof(__le64) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) CEPH_ENCODING_START_BLK_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (break_op_buf_size > PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) break_op_page = alloc_page(GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (!break_op_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) p = page_address(break_op_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) end = p + break_op_buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /* encode cls_lock_break_op struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) ceph_start_encoding(&p, 1, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) break_op_buf_size - CEPH_ENCODING_START_BLK_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ceph_encode_string(&p, end, lock_name, name_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) ceph_encode_copy(&p, locker, sizeof(*locker));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) ceph_encode_string(&p, end, cookie, cookie_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) dout("%s lock_name %s cookie %s locker %s%llu\n", __func__, lock_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) cookie, ENTITY_NAME(*locker));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) ret = ceph_osdc_call(osdc, oid, oloc, "lock", "break_lock",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) CEPH_OSD_FLAG_WRITE, break_op_page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) break_op_buf_size, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) dout("%s: status %d\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) __free_page(break_op_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) EXPORT_SYMBOL(ceph_cls_break_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) int ceph_cls_set_cookie(struct ceph_osd_client *osdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct ceph_object_id *oid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) struct ceph_object_locator *oloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) char *lock_name, u8 type, char *old_cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) char *tag, char *new_cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) int cookie_op_buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) int name_len = strlen(lock_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) int old_cookie_len = strlen(old_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) int tag_len = strlen(tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) int new_cookie_len = strlen(new_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) void *p, *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct page *cookie_op_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) cookie_op_buf_size = name_len + sizeof(__le32) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) old_cookie_len + sizeof(__le32) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) tag_len + sizeof(__le32) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) new_cookie_len + sizeof(__le32) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) sizeof(u8) + CEPH_ENCODING_START_BLK_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (cookie_op_buf_size > PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) cookie_op_page = alloc_page(GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (!cookie_op_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) p = page_address(cookie_op_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) end = p + cookie_op_buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /* encode cls_lock_set_cookie_op struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ceph_start_encoding(&p, 1, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) cookie_op_buf_size - CEPH_ENCODING_START_BLK_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) ceph_encode_string(&p, end, lock_name, name_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) ceph_encode_8(&p, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ceph_encode_string(&p, end, old_cookie, old_cookie_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) ceph_encode_string(&p, end, tag, tag_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) ceph_encode_string(&p, end, new_cookie, new_cookie_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) dout("%s lock_name %s type %d old_cookie %s tag %s new_cookie %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) __func__, lock_name, type, old_cookie, tag, new_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ret = ceph_osdc_call(osdc, oid, oloc, "lock", "set_cookie",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) CEPH_OSD_FLAG_WRITE, cookie_op_page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) cookie_op_buf_size, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) dout("%s: status %d\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) __free_page(cookie_op_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) EXPORT_SYMBOL(ceph_cls_set_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) void ceph_free_lockers(struct ceph_locker *lockers, u32 num_lockers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) for (i = 0; i < num_lockers; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) kfree(lockers[i].id.cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) kfree(lockers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) EXPORT_SYMBOL(ceph_free_lockers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) static int decode_locker(void **p, void *end, struct ceph_locker *locker)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) u8 struct_v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) u32 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) char *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) ret = ceph_start_decoding(p, end, 1, "locker_id_t", &struct_v, &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) ceph_decode_copy(p, &locker->id.name, sizeof(locker->id.name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) s = ceph_extract_encoded_string(p, end, NULL, GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (IS_ERR(s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return PTR_ERR(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) locker->id.cookie = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) ret = ceph_start_decoding(p, end, 1, "locker_info_t", &struct_v, &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) *p += sizeof(struct ceph_timespec); /* skip expiration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) ret = ceph_decode_entity_addr(p, end, &locker->info.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) len = ceph_decode_32(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) *p += len; /* skip description */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) dout("%s %s%llu cookie %s addr %s\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) ENTITY_NAME(locker->id.name), locker->id.cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) ceph_pr_addr(&locker->info.addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static int decode_lockers(void **p, void *end, u8 *type, char **tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct ceph_locker **lockers, u32 *num_lockers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) u8 struct_v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) u32 struct_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) char *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) ret = ceph_start_decoding(p, end, 1, "cls_lock_get_info_reply",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) &struct_v, &struct_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) *num_lockers = ceph_decode_32(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) *lockers = kcalloc(*num_lockers, sizeof(**lockers), GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (!*lockers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) for (i = 0; i < *num_lockers; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) ret = decode_locker(p, end, *lockers + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) goto err_free_lockers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) *type = ceph_decode_8(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) s = ceph_extract_encoded_string(p, end, NULL, GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (IS_ERR(s)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) ret = PTR_ERR(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) goto err_free_lockers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) *tag = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) err_free_lockers:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) ceph_free_lockers(*lockers, *num_lockers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * On success, the caller is responsible for:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * kfree(tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * ceph_free_lockers(lockers, num_lockers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) int ceph_cls_lock_info(struct ceph_osd_client *osdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct ceph_object_id *oid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct ceph_object_locator *oloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) char *lock_name, u8 *type, char **tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct ceph_locker **lockers, u32 *num_lockers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) int get_info_op_buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) int name_len = strlen(lock_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) struct page *get_info_op_page, *reply_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) size_t reply_len = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) void *p, *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) get_info_op_buf_size = name_len + sizeof(__le32) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) CEPH_ENCODING_START_BLK_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (get_info_op_buf_size > PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) get_info_op_page = alloc_page(GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (!get_info_op_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) reply_page = alloc_page(GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (!reply_page) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) __free_page(get_info_op_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) p = page_address(get_info_op_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) end = p + get_info_op_buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) /* encode cls_lock_get_info_op struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) ceph_start_encoding(&p, 1, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) get_info_op_buf_size - CEPH_ENCODING_START_BLK_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) ceph_encode_string(&p, end, lock_name, name_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) dout("%s lock_name %s\n", __func__, lock_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) ret = ceph_osdc_call(osdc, oid, oloc, "lock", "get_info",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) CEPH_OSD_FLAG_READ, get_info_op_page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) get_info_op_buf_size, &reply_page, &reply_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) dout("%s: status %d\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (ret >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) p = page_address(reply_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) end = p + reply_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) ret = decode_lockers(&p, end, type, tag, lockers, num_lockers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) __free_page(get_info_op_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) __free_page(reply_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) EXPORT_SYMBOL(ceph_cls_lock_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) int ceph_cls_assert_locked(struct ceph_osd_request *req, int which,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) char *lock_name, u8 type, char *cookie, char *tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) int assert_op_buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) int name_len = strlen(lock_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) int cookie_len = strlen(cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) int tag_len = strlen(tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) struct page **pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) void *p, *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) assert_op_buf_size = name_len + sizeof(__le32) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) cookie_len + sizeof(__le32) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) tag_len + sizeof(__le32) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) sizeof(u8) + CEPH_ENCODING_START_BLK_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (assert_op_buf_size > PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) ret = osd_req_op_cls_init(req, which, "lock", "assert_locked");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) pages = ceph_alloc_page_vector(1, GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (IS_ERR(pages))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) return PTR_ERR(pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) p = page_address(pages[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) end = p + assert_op_buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) /* encode cls_lock_assert_op struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) ceph_start_encoding(&p, 1, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) assert_op_buf_size - CEPH_ENCODING_START_BLK_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) ceph_encode_string(&p, end, lock_name, name_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) ceph_encode_8(&p, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) ceph_encode_string(&p, end, cookie, cookie_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) ceph_encode_string(&p, end, tag, tag_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) WARN_ON(p != end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) osd_req_op_cls_request_data_pages(req, which, pages, assert_op_buf_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 0, false, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) EXPORT_SYMBOL(ceph_cls_assert_locked);