@@ -31,6 +31,149 @@ static struct btrfs_device *btrfs_device_by_devid(struct btrfs_fs_devices *fs_de
31
31
return NULL ;
32
32
}
33
33
34
+ /*
35
+ * Test a 1M RST write that spans two adjacent RST items on disk and then
36
+ * delete a portion starting in the first item and spanning into the second
37
+ * item. This is similar to test_front_delete(), but spanning multiple items.
38
+ */
39
+ static int test_front_delete_prev_item (struct btrfs_trans_handle * trans )
40
+ {
41
+ struct btrfs_fs_info * fs_info = trans -> fs_info ;
42
+ struct btrfs_io_context * bioc ;
43
+ struct btrfs_io_stripe io_stripe = { 0 };
44
+ u64 map_type = RST_TEST_RAID1_TYPE ;
45
+ u64 logical1 = SZ_1M ;
46
+ u64 logical2 = SZ_2M ;
47
+ u64 len = SZ_1M ;
48
+ int ret ;
49
+
50
+ bioc = alloc_btrfs_io_context (fs_info , logical1 , RST_TEST_NUM_DEVICES );
51
+ if (!bioc ) {
52
+ test_std_err (TEST_ALLOC_IO_CONTEXT );
53
+ ret = - ENOMEM ;
54
+ goto out ;
55
+ }
56
+
57
+ io_stripe .dev = btrfs_device_by_devid (fs_info -> fs_devices , 0 );
58
+ bioc -> map_type = map_type ;
59
+ bioc -> size = len ;
60
+
61
+ /* Insert RAID extent 1. */
62
+ for (int i = 0 ; i < RST_TEST_NUM_DEVICES ; i ++ ) {
63
+ struct btrfs_io_stripe * stripe = & bioc -> stripes [i ];
64
+
65
+ stripe -> dev = btrfs_device_by_devid (fs_info -> fs_devices , i );
66
+ if (!stripe -> dev ) {
67
+ test_err ("cannot find device with devid %d" , i );
68
+ ret = - EINVAL ;
69
+ goto out ;
70
+ }
71
+
72
+ stripe -> physical = logical1 + i * SZ_1G ;
73
+ }
74
+
75
+ ret = btrfs_insert_one_raid_extent (trans , bioc );
76
+ if (ret ) {
77
+ test_err ("inserting RAID extent failed: %d" , ret );
78
+ goto out ;
79
+ }
80
+
81
+ bioc -> logical = logical2 ;
82
+ /* Insert RAID extent 2, directly adjacent to it. */
83
+ for (int i = 0 ; i < RST_TEST_NUM_DEVICES ; i ++ ) {
84
+ struct btrfs_io_stripe * stripe = & bioc -> stripes [i ];
85
+
86
+ stripe -> dev = btrfs_device_by_devid (fs_info -> fs_devices , i );
87
+ if (!stripe -> dev ) {
88
+ test_err ("cannot find device with devid %d" , i );
89
+ ret = - EINVAL ;
90
+ goto out ;
91
+ }
92
+
93
+ stripe -> physical = logical2 + i * SZ_1G ;
94
+ }
95
+
96
+ ret = btrfs_insert_one_raid_extent (trans , bioc );
97
+ if (ret ) {
98
+ test_err ("inserting RAID extent failed: %d" , ret );
99
+ goto out ;
100
+ }
101
+
102
+ ret = btrfs_delete_raid_extent (trans , logical1 + SZ_512K , SZ_1M );
103
+ if (ret ) {
104
+ test_err ("deleting RAID extent [%llu, %llu] failed" ,
105
+ logical1 + SZ_512K , (u64 )SZ_1M );
106
+ goto out ;
107
+ }
108
+
109
+ /* Verify item 1 is truncated to 512K. */
110
+ ret = btrfs_get_raid_extent_offset (fs_info , logical1 , & len , map_type , 0 ,
111
+ & io_stripe );
112
+ if (ret ) {
113
+ test_err ("lookup of RAID extent [%llu, %llu] failed" , logical1 ,
114
+ logical1 + len );
115
+ goto out ;
116
+ }
117
+
118
+ if (io_stripe .physical != logical1 ) {
119
+ test_err ("invalid physical address, expected %llu got %llu" ,
120
+ logical1 , io_stripe .physical );
121
+ ret = - EINVAL ;
122
+ goto out ;
123
+ }
124
+
125
+ if (len != SZ_512K ) {
126
+ test_err ("invalid stripe length, expected %llu got %llu" ,
127
+ (u64 )SZ_512K , len );
128
+ ret = - EINVAL ;
129
+ goto out ;
130
+ }
131
+
132
+ /* Verify item 2's start is moved by 512K. */
133
+ ret = btrfs_get_raid_extent_offset (fs_info , logical2 + SZ_512K , & len ,
134
+ map_type , 0 , & io_stripe );
135
+ if (ret ) {
136
+ test_err ("lookup of RAID extent [%llu, %llu] failed" ,
137
+ logical2 + SZ_512K , logical2 + len );
138
+ goto out ;
139
+ }
140
+
141
+ if (io_stripe .physical != logical2 + SZ_512K ) {
142
+ test_err ("invalid physical address, expected %llu got %llu" ,
143
+ logical2 + SZ_512K , io_stripe .physical );
144
+ ret = - EINVAL ;
145
+ goto out ;
146
+ }
147
+
148
+ if (len != SZ_512K ) {
149
+ test_err ("invalid stripe length, expected %llu got %llu" ,
150
+ (u64 )SZ_512K , len );
151
+ ret = - EINVAL ;
152
+ goto out ;
153
+ }
154
+
155
+ /* Verify there's a hole at [1M+512K, 2M+512K] . */
156
+ len = SZ_1M ;
157
+ ret = btrfs_get_raid_extent_offset (fs_info , logical1 + SZ_512K , & len ,
158
+ map_type , 0 , & io_stripe );
159
+ if (ret != - ENODATA ) {
160
+ test_err ("lookup of RAID [%llu, %llu] succeeded, should fail" ,
161
+ logical1 + SZ_512K , logical1 + SZ_512K + len );
162
+ goto out ;
163
+ }
164
+
165
+ /* Clean up after us. */
166
+ ret = btrfs_delete_raid_extent (trans , logical1 , SZ_512K );
167
+ if (ret )
168
+ goto out ;
169
+
170
+ ret = btrfs_delete_raid_extent (trans , logical2 + SZ_512K , SZ_512K );
171
+
172
+ out :
173
+ btrfs_put_bioc (bioc );
174
+ return ret ;
175
+ }
176
+
34
177
/*
35
178
* Test a 64K RST write on a 2 disk RAID1 at a logical address of 1M and then
36
179
* delete the 1st 32K, making the new start address 1M+32K.
@@ -468,6 +611,7 @@ static const test_func_t tests[] = {
468
611
test_create_update_delete ,
469
612
test_tail_delete ,
470
613
test_front_delete ,
614
+ test_front_delete_prev_item ,
471
615
};
472
616
473
617
static int run_test (test_func_t test , u32 sectorsize , u32 nodesize )
0 commit comments