Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) }