^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) * Copyright (c) 2014-2016 Christoph Hellwig.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "blocklayout.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #define NFSDBG_FACILITY NFSDBG_PNFS_LD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) static inline struct pnfs_block_extent *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) ext_node(struct rb_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) return rb_entry(node, struct pnfs_block_extent, be_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static struct pnfs_block_extent *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) ext_tree_first(struct rb_root *root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) struct rb_node *node = rb_first(root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) return node ? ext_node(node) : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static struct pnfs_block_extent *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) ext_tree_prev(struct pnfs_block_extent *be)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct rb_node *node = rb_prev(&be->be_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) return node ? ext_node(node) : NULL;
^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) static struct pnfs_block_extent *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) ext_tree_next(struct pnfs_block_extent *be)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct rb_node *node = rb_next(&be->be_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) return node ? ext_node(node) : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static inline sector_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) ext_f_end(struct pnfs_block_extent *be)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) return be->be_f_offset + be->be_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static struct pnfs_block_extent *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) __ext_tree_search(struct rb_root *root, sector_t start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct rb_node *node = root->rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct pnfs_block_extent *be = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) while (node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) be = ext_node(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (start < be->be_f_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) node = node->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) else if (start >= ext_f_end(be))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) node = node->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if (be) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (start < be->be_f_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (start >= ext_f_end(be))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) return ext_tree_next(be);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) ext_can_merge(struct pnfs_block_extent *be1, struct pnfs_block_extent *be2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (be1->be_state != be2->be_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (be1->be_device != be2->be_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (be1->be_f_offset + be1->be_length != be2->be_f_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (be1->be_state != PNFS_BLOCK_NONE_DATA &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) (be1->be_v_offset + be1->be_length != be2->be_v_offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (be1->be_state == PNFS_BLOCK_INVALID_DATA &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) be1->be_tag != be2->be_tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static struct pnfs_block_extent *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) ext_try_to_merge_left(struct rb_root *root, struct pnfs_block_extent *be)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct pnfs_block_extent *left = ext_tree_prev(be);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (left && ext_can_merge(left, be)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) left->be_length += be->be_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) rb_erase(&be->be_node, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) nfs4_put_deviceid_node(be->be_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) kfree(be);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static struct pnfs_block_extent *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) ext_try_to_merge_right(struct rb_root *root, struct pnfs_block_extent *be)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct pnfs_block_extent *right = ext_tree_next(be);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (right && ext_can_merge(be, right)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) be->be_length += right->be_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) rb_erase(&right->be_node, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) nfs4_put_deviceid_node(right->be_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) kfree(right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static void __ext_put_deviceids(struct list_head *head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct pnfs_block_extent *be, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) list_for_each_entry_safe(be, tmp, head, be_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) nfs4_put_deviceid_node(be->be_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) kfree(be);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) __ext_tree_insert(struct rb_root *root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct pnfs_block_extent *new, bool merge_ok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct rb_node **p = &root->rb_node, *parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct pnfs_block_extent *be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) while (*p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) parent = *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) be = ext_node(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (new->be_f_offset < be->be_f_offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (merge_ok && ext_can_merge(new, be)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) be->be_f_offset = new->be_f_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (be->be_state != PNFS_BLOCK_NONE_DATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) be->be_v_offset = new->be_v_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) be->be_length += new->be_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) be = ext_try_to_merge_left(root, be);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) goto free_new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) p = &(*p)->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) } else if (new->be_f_offset >= ext_f_end(be)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (merge_ok && ext_can_merge(be, new)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) be->be_length += new->be_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) be = ext_try_to_merge_right(root, be);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) goto free_new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) p = &(*p)->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) rb_link_node(&new->be_node, parent, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) rb_insert_color(&new->be_node, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) free_new:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) nfs4_put_deviceid_node(new->be_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) kfree(new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) __ext_tree_remove(struct rb_root *root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) sector_t start, sector_t end, struct list_head *tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct pnfs_block_extent *be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) sector_t len1 = 0, len2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) sector_t orig_v_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) sector_t orig_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) be = __ext_tree_search(root, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (!be)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (be->be_f_offset >= end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) orig_v_offset = be->be_v_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) orig_len = be->be_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (start > be->be_f_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) len1 = start - be->be_f_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (ext_f_end(be) > end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) len2 = ext_f_end(be) - end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (len2 > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (len1 > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct pnfs_block_extent *new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) new = kzalloc(sizeof(*new), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (!new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) be->be_length = len1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) new->be_f_offset = end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (be->be_state != PNFS_BLOCK_NONE_DATA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) new->be_v_offset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) orig_v_offset + orig_len - len2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) new->be_length = len2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) new->be_state = be->be_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) new->be_tag = be->be_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) new->be_device = nfs4_get_deviceid(be->be_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) __ext_tree_insert(root, new, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) be->be_f_offset = end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (be->be_state != PNFS_BLOCK_NONE_DATA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) be->be_v_offset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) orig_v_offset + orig_len - len2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) be->be_length = len2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (len1 > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) be->be_length = len1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) be = ext_tree_next(be);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) while (be && ext_f_end(be) <= end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) struct pnfs_block_extent *next = ext_tree_next(be);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) rb_erase(&be->be_node, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) list_add_tail(&be->be_list, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) be = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (be && be->be_f_offset < end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) len1 = ext_f_end(be) - end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) be->be_f_offset = end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (be->be_state != PNFS_BLOCK_NONE_DATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) be->be_v_offset += be->be_length - len1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) be->be_length = len1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^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) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) ext_tree_insert(struct pnfs_block_layout *bl, struct pnfs_block_extent *new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct pnfs_block_extent *be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct rb_root *root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) switch (new->be_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) case PNFS_BLOCK_READWRITE_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) case PNFS_BLOCK_INVALID_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) root = &bl->bl_ext_rw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) case PNFS_BLOCK_READ_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) case PNFS_BLOCK_NONE_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) root = &bl->bl_ext_ro;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) dprintk("invalid extent type\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) spin_lock(&bl->bl_ext_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) be = __ext_tree_search(root, new->be_f_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (!be || be->be_f_offset >= ext_f_end(new)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) __ext_tree_insert(root, new, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) } else if (new->be_f_offset >= be->be_f_offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (ext_f_end(new) <= ext_f_end(be)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) nfs4_put_deviceid_node(new->be_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) kfree(new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) sector_t new_len = ext_f_end(new) - ext_f_end(be);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) sector_t diff = new->be_length - new_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) new->be_f_offset += diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) new->be_v_offset += diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) new->be_length = new_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) } else if (ext_f_end(new) <= ext_f_end(be)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) new->be_length = be->be_f_offset - new->be_f_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) __ext_tree_insert(root, new, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) struct pnfs_block_extent *split;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) sector_t new_len = ext_f_end(new) - ext_f_end(be);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) sector_t diff = new->be_length - new_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) split = kmemdup(new, sizeof(*new), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (!split) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) goto out;
^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) split->be_length = be->be_f_offset - split->be_f_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) split->be_device = nfs4_get_deviceid(new->be_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) __ext_tree_insert(root, split, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) new->be_f_offset += diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) new->be_v_offset += diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) new->be_length = new_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) spin_unlock(&bl->bl_ext_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) __ext_tree_lookup(struct rb_root *root, sector_t isect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) struct pnfs_block_extent *ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) struct rb_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) struct pnfs_block_extent *be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) node = root->rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) while (node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) be = ext_node(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (isect < be->be_f_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) node = node->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) else if (isect >= ext_f_end(be))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) node = node->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) *ret = *be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) ext_tree_lookup(struct pnfs_block_layout *bl, sector_t isect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct pnfs_block_extent *ret, bool rw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) spin_lock(&bl->bl_ext_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (!rw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) found = __ext_tree_lookup(&bl->bl_ext_ro, isect, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (!found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) found = __ext_tree_lookup(&bl->bl_ext_rw, isect, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) spin_unlock(&bl->bl_ext_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) int ext_tree_remove(struct pnfs_block_layout *bl, bool rw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) sector_t start, sector_t end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) int err, err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) LIST_HEAD(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) spin_lock(&bl->bl_ext_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) err = __ext_tree_remove(&bl->bl_ext_ro, start, end, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (rw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) err2 = __ext_tree_remove(&bl->bl_ext_rw, start, end, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) err = err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) spin_unlock(&bl->bl_ext_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) __ext_put_deviceids(&tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) ext_tree_split(struct rb_root *root, struct pnfs_block_extent *be,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) sector_t split)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) struct pnfs_block_extent *new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) sector_t orig_len = be->be_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) new = kzalloc(sizeof(*new), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (!new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) be->be_length = split - be->be_f_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) new->be_f_offset = split;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (be->be_state != PNFS_BLOCK_NONE_DATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) new->be_v_offset = be->be_v_offset + be->be_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) new->be_length = orig_len - be->be_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) new->be_state = be->be_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) new->be_tag = be->be_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) new->be_device = nfs4_get_deviceid(be->be_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) __ext_tree_insert(root, new, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) ext_tree_mark_written(struct pnfs_block_layout *bl, sector_t start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) sector_t len, u64 lwb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) struct rb_root *root = &bl->bl_ext_rw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) sector_t end = start + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) struct pnfs_block_extent *be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) LIST_HEAD(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) spin_lock(&bl->bl_ext_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * First remove all COW extents or holes from written to range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) err = __ext_tree_remove(&bl->bl_ext_ro, start, end, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * Then mark all invalid extents in the range as written to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) for (be = __ext_tree_search(root, start); be; be = ext_tree_next(be)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (be->be_f_offset >= end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (be->be_state != PNFS_BLOCK_INVALID_DATA || be->be_tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (be->be_f_offset < start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct pnfs_block_extent *left = ext_tree_prev(be);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (left && ext_can_merge(left, be)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) sector_t diff = start - be->be_f_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) left->be_length += diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) be->be_f_offset += diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) be->be_v_offset += diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) be->be_length -= diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) err = ext_tree_split(root, be, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (ext_f_end(be) > end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) struct pnfs_block_extent *right = ext_tree_next(be);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (right && ext_can_merge(be, right)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) sector_t diff = end - be->be_f_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) be->be_length -= diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) right->be_f_offset -= diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) right->be_v_offset -= diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) right->be_length += diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) err = ext_tree_split(root, be, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^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) if (be->be_f_offset >= start && ext_f_end(be) <= end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) be->be_tag = EXTENT_WRITTEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) be = ext_try_to_merge_left(root, be);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) be = ext_try_to_merge_right(root, be);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (bl->bl_lwb < lwb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) bl->bl_lwb = lwb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) spin_unlock(&bl->bl_ext_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) __ext_put_deviceids(&tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) static size_t ext_tree_layoutupdate_size(struct pnfs_block_layout *bl, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (bl->bl_scsi_layout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) return sizeof(__be32) + PNFS_SCSI_RANGE_SIZE * count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) return sizeof(__be32) + PNFS_BLOCK_EXTENT_SIZE * count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) static void ext_tree_free_commitdata(struct nfs4_layoutcommit_args *arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) size_t buffer_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (arg->layoutupdate_pages != &arg->layoutupdate_page) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) int nr_pages = DIV_ROUND_UP(buffer_size, PAGE_SIZE), i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) for (i = 0; i < nr_pages; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) put_page(arg->layoutupdate_pages[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) vfree(arg->start_p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) kfree(arg->layoutupdate_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) put_page(arg->layoutupdate_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) static __be32 *encode_block_extent(struct pnfs_block_extent *be, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) p = xdr_encode_opaque_fixed(p, be->be_device->deviceid.data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) NFS4_DEVICEID4_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) p = xdr_encode_hyper(p, be->be_f_offset << SECTOR_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) p = xdr_encode_hyper(p, be->be_length << SECTOR_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) p = xdr_encode_hyper(p, 0LL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) *p++ = cpu_to_be32(PNFS_BLOCK_READWRITE_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) static __be32 *encode_scsi_range(struct pnfs_block_extent *be, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) p = xdr_encode_hyper(p, be->be_f_offset << SECTOR_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return xdr_encode_hyper(p, be->be_length << SECTOR_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) static int ext_tree_encode_commit(struct pnfs_block_layout *bl, __be32 *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) size_t buffer_size, size_t *count, __u64 *lastbyte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) struct pnfs_block_extent *be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) spin_lock(&bl->bl_ext_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) for (be = ext_tree_first(&bl->bl_ext_rw); be; be = ext_tree_next(be)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (be->be_state != PNFS_BLOCK_INVALID_DATA ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) be->be_tag != EXTENT_WRITTEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) (*count)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (ext_tree_layoutupdate_size(bl, *count) > buffer_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /* keep counting.. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) ret = -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) if (bl->bl_scsi_layout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) p = encode_scsi_range(be, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) p = encode_block_extent(be, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) be->be_tag = EXTENT_COMMITTING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) *lastbyte = bl->bl_lwb - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) bl->bl_lwb = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) spin_unlock(&bl->bl_ext_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) ext_tree_prepare_commit(struct nfs4_layoutcommit_args *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) struct pnfs_block_layout *bl = BLK_LO2EXT(NFS_I(arg->inode)->layout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) size_t count = 0, buffer_size = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) __be32 *start_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) dprintk("%s enter\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) arg->layoutupdate_page = alloc_page(GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (!arg->layoutupdate_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) start_p = page_address(arg->layoutupdate_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) arg->layoutupdate_pages = &arg->layoutupdate_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) ret = ext_tree_encode_commit(bl, start_p + 1, buffer_size, &count, &arg->lastbytewritten);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (unlikely(ret)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) ext_tree_free_commitdata(arg, buffer_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) buffer_size = ext_tree_layoutupdate_size(bl, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) arg->layoutupdate_pages =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) kcalloc(DIV_ROUND_UP(buffer_size, PAGE_SIZE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) sizeof(struct page *), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (!arg->layoutupdate_pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) start_p = __vmalloc(buffer_size, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (!start_p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) kfree(arg->layoutupdate_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) *start_p = cpu_to_be32(count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) arg->layoutupdate_len = ext_tree_layoutupdate_size(bl, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (unlikely(arg->layoutupdate_pages != &arg->layoutupdate_page)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) void *p = start_p, *end = p + arg->layoutupdate_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) struct page *page = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) arg->start_p = start_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) for ( ; p < end; p += PAGE_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) page = vmalloc_to_page(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) arg->layoutupdate_pages[i++] = page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) get_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) dprintk("%s found %zu ranges\n", __func__, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) return 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) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) ext_tree_mark_committed(struct nfs4_layoutcommit_args *arg, int status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) struct pnfs_block_layout *bl = BLK_LO2EXT(NFS_I(arg->inode)->layout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) struct rb_root *root = &bl->bl_ext_rw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) struct pnfs_block_extent *be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) dprintk("%s status %d\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) ext_tree_free_commitdata(arg, arg->layoutupdate_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) spin_lock(&bl->bl_ext_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) for (be = ext_tree_first(root); be; be = ext_tree_next(be)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if (be->be_state != PNFS_BLOCK_INVALID_DATA ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) be->be_tag != EXTENT_COMMITTING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) * Mark as written and try again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) * XXX: some real error handling here wouldn't hurt..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) be->be_tag = EXTENT_WRITTEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) be->be_state = PNFS_BLOCK_READWRITE_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) be->be_tag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) be = ext_try_to_merge_left(root, be);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) be = ext_try_to_merge_right(root, be);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) spin_unlock(&bl->bl_ext_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }