@@ -31,6 +31,149 @@ static struct btrfs_device *btrfs_device_by_devid(struct btrfs_fs_devices *fs_de
3131 return NULL ;
3232}
3333
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+
34177/*
35178 * Test a 64K RST write on a 2 disk RAID1 at a logical address of 1M and then
36179 * delete the 1st 32K, making the new start address 1M+32K.
@@ -468,6 +611,7 @@ static const test_func_t tests[] = {
468611 test_create_update_delete ,
469612 test_tail_delete ,
470613 test_front_delete ,
614+ test_front_delete_prev_item ,
471615};
472616
473617static int run_test (test_func_t test , u32 sectorsize , u32 nodesize )
0 commit comments