@@ -31,6 +31,145 @@ static struct btrfs_device *btrfs_device_by_devid(struct btrfs_fs_devices *fs_de
31
31
return NULL ;
32
32
}
33
33
34
+ /* Test punching a hole into a single RAID stripe-extent. */
35
+ static int test_punch_hole (struct btrfs_trans_handle * trans )
36
+ {
37
+ struct btrfs_fs_info * fs_info = trans -> fs_info ;
38
+ struct btrfs_io_context * bioc ;
39
+ struct btrfs_io_stripe io_stripe = { 0 };
40
+ u64 map_type = RST_TEST_RAID1_TYPE ;
41
+ u64 logical1 = SZ_1M ;
42
+ u64 hole_start = logical1 + SZ_32K ;
43
+ u64 hole_len = SZ_64K ;
44
+ u64 logical2 = hole_start + hole_len ;
45
+ u64 len = SZ_1M ;
46
+ u64 len1 = SZ_32K ;
47
+ u64 len2 = len - len1 - hole_len ;
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
+ for (int i = 0 ; i < RST_TEST_NUM_DEVICES ; i ++ ) {
62
+ struct btrfs_io_stripe * stripe = & bioc -> stripes [i ];
63
+
64
+ stripe -> dev = btrfs_device_by_devid (fs_info -> fs_devices , i );
65
+ if (!stripe -> dev ) {
66
+ test_err ("cannot find device with devid %d" , i );
67
+ ret = - EINVAL ;
68
+ goto out ;
69
+ }
70
+
71
+ stripe -> physical = logical1 + i * SZ_1G ;
72
+ }
73
+
74
+ ret = btrfs_insert_one_raid_extent (trans , bioc );
75
+ if (ret ) {
76
+ test_err ("inserting RAID extent failed: %d" , ret );
77
+ goto out ;
78
+ }
79
+
80
+ ret = btrfs_get_raid_extent_offset (fs_info , logical1 , & len , map_type , 0 ,
81
+ & io_stripe );
82
+ if (ret ) {
83
+ test_err ("lookup of RAID extent [%llu, %llu] failed" , logical1 ,
84
+ logical1 + len );
85
+ goto out ;
86
+ }
87
+
88
+ if (io_stripe .physical != logical1 ) {
89
+ test_err ("invalid physical address, expected %llu got %llu" ,
90
+ logical1 , io_stripe .physical );
91
+ ret = - EINVAL ;
92
+ goto out ;
93
+ }
94
+
95
+ if (len != SZ_1M ) {
96
+ test_err ("invalid stripe length, expected %llu got %llu" ,
97
+ (u64 )SZ_1M , len );
98
+ ret = - EINVAL ;
99
+ goto out ;
100
+ }
101
+
102
+ ret = btrfs_delete_raid_extent (trans , hole_start , hole_len );
103
+ if (ret ) {
104
+ test_err ("deleting RAID extent [%llu, %llu] failed" ,
105
+ hole_start , hole_start + hole_len );
106
+ goto out ;
107
+ }
108
+
109
+ ret = btrfs_get_raid_extent_offset (fs_info , logical1 , & len1 , map_type ,
110
+ 0 , & io_stripe );
111
+ if (ret ) {
112
+ test_err ("lookup of RAID extent [%llu, %llu] failed" ,
113
+ logical1 , logical1 + len1 );
114
+ goto out ;
115
+ }
116
+
117
+ if (io_stripe .physical != logical1 ) {
118
+ test_err ("invalid physical address, expected %llu, got %llu" ,
119
+ logical1 , io_stripe .physical );
120
+ ret = - EINVAL ;
121
+ goto out ;
122
+ }
123
+
124
+ if (len1 != SZ_32K ) {
125
+ test_err ("invalid stripe length, expected %llu, got %llu" ,
126
+ (u64 )SZ_32K , len1 );
127
+ ret = - EINVAL ;
128
+ goto out ;
129
+ }
130
+
131
+ ret = btrfs_get_raid_extent_offset (fs_info , logical2 , & len2 , map_type ,
132
+ 0 , & io_stripe );
133
+ if (ret ) {
134
+ test_err ("lookup of RAID extent [%llu, %llu] failed" , logical2 ,
135
+ logical2 + len2 );
136
+ goto out ;
137
+ }
138
+
139
+ if (io_stripe .physical != logical2 ) {
140
+ test_err ("invalid physical address, expected %llu, got %llu" ,
141
+ logical2 , io_stripe .physical );
142
+ ret = - EINVAL ;
143
+ goto out ;
144
+ }
145
+
146
+ if (len2 != len - len1 - hole_len ) {
147
+ test_err ("invalid length, expected %llu, got %llu" ,
148
+ len - len1 - hole_len , len2 );
149
+ ret = - EINVAL ;
150
+ goto out ;
151
+ }
152
+
153
+ /* Check for the absence of the hole. */
154
+ ret = btrfs_get_raid_extent_offset (fs_info , hole_start , & hole_len ,
155
+ map_type , 0 , & io_stripe );
156
+ if (ret != - ENODATA ) {
157
+ ret = - EINVAL ;
158
+ test_err ("lookup of RAID extent [%llu, %llu] succeeded, should fail" ,
159
+ hole_start , hole_start + SZ_64K );
160
+ goto out ;
161
+ }
162
+
163
+ ret = btrfs_delete_raid_extent (trans , logical1 , len1 );
164
+ if (ret )
165
+ goto out ;
166
+
167
+ ret = btrfs_delete_raid_extent (trans , logical2 , len2 );
168
+ out :
169
+ btrfs_put_bioc (bioc );
170
+ return ret ;
171
+ }
172
+
34
173
/*
35
174
* Test a 1M RST write that spans two adjacent RST items on disk and then
36
175
* delete a portion starting in the first item and spanning into the second
@@ -612,6 +751,7 @@ static const test_func_t tests[] = {
612
751
test_tail_delete ,
613
752
test_front_delete ,
614
753
test_front_delete_prev_item ,
754
+ test_punch_hole ,
615
755
};
616
756
617
757
static int run_test (test_func_t test , u32 sectorsize , u32 nodesize )
0 commit comments