Motr  M0
file.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2012-2020 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
23 /*
24  * Production code : m0t1fs/linux_kernel/file.c
25  * UT code : m0t1fs/linux_kernel/ut/file.c
26  *
27  * The production code is added this way to build motr kernel module.
28  * Both production code and UT code are part of Motr kernel module
29  * but production code file is not directly added to Makefile as a file
30  * that needs to be compiled.
31  * Instead, UT code is added in Makefile for motr kernel module build
32  * which subsequently adds production code file to motr kernel module.
33  */
34 #include <linux/version.h>
36 #include "ut/ut.h" /* m0_ut_suite */
37 #include "lib/chan.h" /* m0_chan */
38 #include "lib/vec.h" /* m0_indexvec_varr */
39 #include "fid/fid.h" /* m0_fid */
40 #include "lib/misc.h" /* m0_rnd */
41 #include "lib/time.h" /* m0_time_nanoseconds */
42 #include "lib/finject.h"
43 #include "layout/layout.h" /* m0_layout_domain_init */
44 #include "layout/linear_enum.h" /* m0_layout_linear_enum */
45 #include "fd/fd.h" /* m0_fd_fwd_map */
46 #include <linux/dcache.h> /* struct dentry */
47 #include "m0t1fs/linux_kernel/file_internal.h" /* io_request */
48 #include "m0t1fs/linux_kernel/m0t1fs.h" /* m0t1fs_sb */
49 #include "conf/helpers.h"
50 #include "reqh/reqh.h"
51 
52 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_M0T1FS
53 #include "lib/trace.h"
54 
55 /* fsync_test declared in m0t1fs/linux_kernel/ut/fsync.c */
56 void fsync_test(void);
57 
58 enum {
59  IOVEC_NR = 4,
60  IOVEC_BUF_LEN = 1024,
62 
63  /* Number of data units. */
64  LAY_N = 3,
65 
66  /* Number of parity units. */
67  LAY_K = 1,
68 
69  /* Number of members in pool. */
70  LAY_P = LAY_N + 2 * LAY_K,
71 
72  /* Unit Size = 12K. */
74  INDEXPG = 2000,
75  INDEXPG_STEP = 5000,
76 
77  /* Data size for parity group = 12K * 3 = 36K. */
79  FID_KEY = 3,
83 };
84 
85 static struct super_block sb;
86 static struct m0t1fs_sb csb;
87 static struct m0_pdclust_attr pdattr;
88 static struct m0_pdclust_layout *pdlay;
91 static struct m0t1fs_inode ci;
92 static struct m0_layout_linear_attr llattr;
93 static struct file lfile;
94 static struct m0_confc *confc = &csb.csb_reqh.rh_rconfc.rc_confc;
95 static struct m0_rm_remote creditor;
96 static bool runast = false;
97 static struct m0_rpc_conn conn;
98 
99 static struct pargrp_iomap map;
100 static struct io_request req;
101 
102 M0_TL_DESCR_DECLARE(rpcbulk, M0_EXTERN);
103 M0_TL_DECLARE(rpcbulk, M0_INTERNAL, struct m0_rpc_bulk_buf);
104 
105 int m0t1fs_rpc_init(struct m0t1fs_sb *csb, const char *ep);
106 int m0t1fs_net_init(struct m0t1fs_sb *csb, const char *ep);
107 int m0t1fs_rm_service_start(struct m0t1fs_sb *csb);
108 int m0t1fs_ha_init(struct m0t1fs_sb *csb, const char *ha_addr);
109 void m0t1fs_rpc_fini(struct m0t1fs_sb *csb);
110 void m0t1fs_net_fini(struct m0t1fs_sb *csb);
111 void m0t1fs_ha_fini(struct m0t1fs_sb *csb);
112 
113 #define LOCAL_EP "0@lo:12345:45:1"
114 
115 static char local_conf[] = "[44:\
116  {0x74| ((^t|1:0), 1, (11, 22), ^o|2:24, (0, 0), 41212,\
117  [3: \"param-0\", \"param-1\", \"param-2\"],\
118  [1: ^n|1:2], [1: ^S|2:15], [2: ^o|1:23, ^o|2:24],\
119  [1: ^p|1:0], [0])},\
120  {0x70| ((^p|1:0), [2: ^o|1:23, ^o|2:24])},\
121  {0x6e| ((^n|1:2), 16000, 2, 3, 2, [2: ^r|1:3, ^r|2:3])},\
122  {0x72| ((^r|1:3), [1:3], 0, 0, 0, 0, \""LOCAL_EP"\", [6: ^s|1:4,\
123  ^s|1:5,\
124  ^s|1:6,\
125  ^s|1:7,\
126  ^s|1:8,\
127  ^s|1:9])},\
128  {0x72| ((^r|2:3), [1:3], 0, 0, 0, 0, \""LOCAL_EP"\", [1: ^s|2:7])},\
129  {0x73| ((^s|1:4), @M0_CST_MDS, [1: \""LOCAL_EP"\"],\
130  [0], [0])},\
131  {0x73| ((^s|1:5), @M0_CST_IOS, [1: \""LOCAL_EP"\"],\
132  [0], [5: ^d|1:10, ^d|1:11, ^d|1:12, ^d|1:13, ^d|1:14])},\
133  {0x73| ((^s|1:6), @M0_CST_CONFD, [1: \""LOCAL_EP"\"],\
134  [0], [0])},\
135  {0x73| ((^s|1:7), @M0_CST_RMS, [1: \""LOCAL_EP"\"],\
136  [0], [0])},\
137  {0x73| ((^s|2:7), @M0_CST_RMS, [1: \""LOCAL_EP"\"],\
138  [0], [0])},\
139  {0x73| ((^s|1:8), @M0_CST_HA, [1: \""LOCAL_EP"\"],\
140  [0], [0])},\
141  {0x73| ((^s|1:9), @M0_CST_IOS, [1: \"addr-3\"], [0], [0])},\
142  {0x64| ((^d|1:10), 1, 4, 1, 4096, 596000000000, 3, 4, \"/dev/sdev0\")},\
143  {0x64| ((^d|1:11), 2, 4, 1, 4096, 596000000000, 3, 4, \"/dev/sdev1\")},\
144  {0x64| ((^d|1:12), 3, 7, 2, 8192, 320000000000, 2, 4, \"/dev/sdev2\")},\
145  {0x64| ((^d|1:13), 4, 7, 2, 8192, 320000000000, 2, 4, \"/dev/sdev3\")},\
146  {0x64| ((^d|1:14), 0, 7, 2, 8192, 320000000000, 2, 4, \"/dev/sdev4\")},\
147  {0x53| ((^S|2:15), [1: ^a|1:15], [1: ^v|1:24])},\
148  {0x61| ((^a|1:15), [1: ^e|1:16], [1: ^v|1:24])},\
149  {0x65| ((^e|1:16), ^n|1:2, [1: ^c|1:17], [1: ^v|1:24])},\
150  {0x63| ((^c|1:17),\
151  [5: ^k|1:18, ^k|1:19, ^k|1:20,\
152  ^k|1:21, ^k|1:22], [1: ^v|1:24])},\
153  {0x6b| ((^k|1:18), ^d|1:10, [1: ^v|1:24])},\
154  {0x6b| ((^k|1:19), ^d|1:11, [1: ^v|1:24])},\
155  {0x6b| ((^k|1:20), ^d|1:12, [1: ^v|1:24])},\
156  {0x6b| ((^k|1:21), ^d|1:13, [1: ^v|1:24])},\
157  {0x6b| ((^k|1:22), ^d|1:14, [1: ^v|1:24])},\
158  {0x6f| ((^o|1:23), 0, [1: ^v|1:24])},\
159  {0x76| ((^v|1:24), {0| (3, 1, 1, 5, [5: 0, 0, 0, 0, 1], [1: ^j|3:25])})},\
160  {0x6a| ((^j|3:25), ^S|2:15, [1: ^j|1:25])},\
161  {0x6a| ((^j|1:25), ^a|1:15, [1: ^j|1:26])},\
162  {0x6a| ((^j|1:26), ^e|1:16, [1: ^j|1:27])},\
163  {0x6a| ((^j|1:27), ^c|1:17, [5: ^j|1:28, ^j|1:29, ^j|1:30,\
164  ^j|1:31, ^j|1:32])},\
165  {0x6a| ((^j|1:28), ^k|1:18, [0])},\
166  {0x6a| ((^j|1:29), ^k|1:19, [0])},\
167  {0x6a| ((^j|1:30), ^k|1:20, [0])},\
168  {0x6a| ((^j|1:31), ^k|1:21, [0])},\
169  {0x6a| ((^j|1:32), ^k|1:22, [0])},\
170  {0x6f| ((^o|2:24), 0, [1: ^v|1:33])},\
171  {0x76| ((^v|1:33), {0| (1, 0, 0, 1, [5: 0, 0, 0, 0, 1], [1: ^j|3:34])})},\
172  {0x6a| ((^j|3:34), ^S|2:15, [1: ^j|1:34])},\
173  {0x6a| ((^j|1:34), ^a|1:15, [1: ^j|1:35])},\
174  {0x6a| ((^j|1:35), ^e|1:16, [1: ^j|1:36])},\
175  {0x6a| ((^j|1:36), ^c|1:17, [1: ^j|1:37])},\
176  {0x6a| ((^j|1:37), ^k|1:22, [0])}]";
177 
178 static void ast_thread(struct m0t1fs_sb *csb)
179 {
180  while (runast) {
181  m0_chan_wait(&csb->csb_iogroup.s_clink);
182  m0_sm_group_lock(&csb->csb_iogroup);
183  m0_sm_asts_run(&csb->csb_iogroup);
184  m0_sm_group_unlock(&csb->csb_iogroup);
185  }
186 }
187 
188 static void ast_thread_stop(struct m0t1fs_sb *csb)
189 {
190  runast = false;
191  m0_chan_signal_lock(&csb->csb_iogroup.s_chan);
192  m0_thread_join(&csb->csb_astthread);
193 }
194 
195 static int file_io_ut_init(void)
196 {
197  struct m0_conf_root *root;
198  struct m0_pool_version *pver;
199  struct m0_layout *lay;
200  int rc;
201  struct m0_fid fid;
202  struct m0_confc_args *confc_args;
203  struct m0_reqh *reqh = &csb.csb_reqh;
204 
205  M0_SET0(&sb);
206  M0_SET0(&creditor);
207  M0_SET0(confc);
209  csb.csb_confc_state.cus_state = M0_CC_READY;
210  runast = true;
211  rc = M0_THREAD_INIT(&csb.csb_astthread, struct m0t1fs_sb *, NULL,
212  &ast_thread, &csb, "m0_ast_thread");
213  M0_UT_ASSERT(rc == 0);
214 
215  rc = m0t1fs_net_init(&csb, NULL);
216  M0_ASSERT(rc == 0);
217 
218  csb.csb_process_fid = M0_FID_INIT(0x7200000000000002, 3);
219  rc = m0t1fs_rpc_init(&csb, NULL);
220  M0_ASSERT(rc == 0);
221 
222  confc_args = &(struct m0_confc_args){
223  .ca_profile = "<0x7000000000000001:0>",
224  .ca_confstr = (char *)local_conf,
225  .ca_rmach = &csb.csb_rpc_machine,
226  .ca_group = &csb.csb_iogroup,
227  };
228 
229  rc = m0t1fs_ha_init(&csb, csb.csb_laddr);
230  M0_UT_ASSERT(rc == 0);
231 
232  rc = m0_reqh_conf_setup(reqh, confc_args);
233  M0_UT_ASSERT(rc == 0);
235  M0_UT_ASSERT(rc == 0);
237  M0_UT_ASSERT(rc == 0);
238 
239  rc = m0__pools_common_init(&csb.csb_pools_common, NULL, root);
240  M0_UT_ASSERT(rc == 0);
241 
242  rc = m0_pools_setup(&csb.csb_pools_common, m0_reqh2profile(reqh),
243  NULL, NULL);
244  M0_UT_ASSERT(rc == 0);
245 
246  rc = m0_pools_service_ctx_create(&csb.csb_pools_common);
247  M0_UT_ASSERT(rc == 0);
248 
249  m0_fi_enable("m0_ha_failvec_fetch", "kernel-ut-no-ha");
250  rc = m0_pool_versions_setup(&csb.csb_pools_common);
251  M0_UT_ASSERT(rc == 0);
252  m0_fi_disable("m0_ha_failvec_fetch", "kernel-ut-no-ha");
253 
254  rc = m0_pool_version_get(&csb.csb_pools_common,
255  &M0_FID_TINIT('o', 33, 77), &pver);
256  M0_UT_ASSERT(rc == -ENOENT);
257 
258  rc = m0_pool_version_get(&csb.csb_pools_common,
259  &M0_FID_TINIT('o', 1, 23), &pver);
260  M0_UT_ASSERT(rc == 0);
261 
262  rc = m0_pool_version_get(&csb.csb_pools_common, NULL, &pver);
263  M0_UT_ASSERT(rc == 0);
264 
265  sb.s_fs_info = &csb;
266  csb.csb_next_key = FID_KEY;
267  m0_chan_init(&csb.csb_iowait, &csb.csb_iogroup.s_lock);
268  m0_atomic64_set(&csb.csb_pending_io_nr, 0);
270 
272 
274  M0_ASSERT(rc == 0);
275 
276  /* Tries to build a layout. */
277  llattr = (struct m0_layout_linear_attr) {
278  .lla_nr = pver->pv_attr.pa_P,
279  .lla_A = ATTR_A_CONST,
280  .lla_B = ATTR_B_CONST,
281  };
282  llenum = NULL;
283  rc = m0_linear_enum_build(&csb.csb_reqh.rh_ldom, &llattr, &llenum);
284  M0_ASSERT(rc == 0);
285 
286  pdattr = (struct m0_pdclust_attr) {
287  .pa_N = pver->pv_attr.pa_N,
288  .pa_K = pver->pv_attr.pa_K,
289  .pa_S = pver->pv_attr.pa_S,
290  .pa_P = pver->pv_attr.pa_P,
291  .pa_unit_size = UNIT_SIZE,
292 
293  };
294  m0_uint128_init(&pdattr.pa_seed, "upjumpandpumpim,");
295  rc = m0_pdclust_build(&csb.csb_reqh.rh_ldom, M0_DEFAULT_LAYOUT_ID,
296  &pdattr, &llenum->lle_base, &pdlay);
297  M0_ASSERT(rc == 0);
298  M0_ASSERT(pdlay != NULL);
299 
300  /* Initializes the m0t1fs inode and build layout instance. */
301  M0_SET0(&ci);
302  ci.ci_layout_id = M0_DEFAULT_LAYOUT_ID;
306 
307  lay = m0_pdl_to_layout(pdlay);
308  M0_ASSERT(lay != NULL);
309 
310  lay->l_pver = pver;
312  &ci.ci_layout_instance);
313  M0_ASSERT(rc == 0);
314  M0_ASSERT(ci.ci_layout_instance != NULL);
315 
316 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,19,0)
317  M0_ALLOC_PTR(lfile.f_path.dentry);
318  M0_ASSERT(lfile.f_path.dentry != NULL);
319  lfile.f_path.dentry->d_inode = &ci.ci_inode;
320  lfile.f_path.dentry->d_inode->i_sb = &sb;
321 #else
322  M0_ALLOC_PTR(lfile.f_dentry);
323  M0_ASSERT(lfile.f_dentry != NULL);
324  lfile.f_dentry->d_inode = &ci.ci_inode;
325  lfile.f_dentry->d_inode->i_sb = &sb;
326 #endif
327  /* Sets the file size in inode. */
328  ci.ci_inode.i_size = DATA_SIZE;
329  ci.ci_pver = pver->pv_id;
331 
332  return 0;
333 }
334 
335 static int file_io_ut_fini(void)
336 {
339 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,19,0)
340  m0_free(lfile.f_path.dentry);
341 #else
342  m0_free(lfile.f_dentry);
343 #endif
344  m0_layout_instance_fini(ci.ci_layout_instance);
345  /* Finalizes the m0_pdclust_layout type. */
347  m0_reqh_layouts_cleanup(&csb.csb_reqh);
348  m0_pool_versions_destroy(&csb.csb_pools_common);
349  m0_pools_service_ctx_destroy(&csb.csb_pools_common);
350  m0_pools_destroy(&csb.csb_pools_common);
351  m0_pools_common_fini(&csb.csb_pools_common);
352  m0_rconfc_stop_sync(&csb.csb_reqh.rh_rconfc);
353  m0_rconfc_fini(&csb.csb_reqh.rh_rconfc);
355  m0_reqh_services_terminate(&csb.csb_reqh);
358 
361 
362  return 0;
363 }
364 
365 static void ds_test(void)
366 {
367  int rc;
368  int cnt;
369  struct m0_fid cfid;
370  struct data_buf *dbuf;
371  struct iovec iovec_arr[IOVEC_NR];
372  struct m0_indexvec_varr *ivv;
373  struct pargrp_iomap *map;
374  struct m0_pdclust_instance *play_instance;
375  struct m0_pdclust_src_addr src;
376  struct m0_pdclust_tgt_addr tgt;
377  struct target_ioreq *ti;
378  struct io_req_fop *irfop;
379  struct m0_rpc_session session;
380 
381  M0_ALLOC_PTR(ivv);
382  M0_UT_ASSERT(ivv != NULL);
383 
384  M0_SET0(&req);
385  rc = m0_indexvec_varr_alloc(ivv, ARRAY_SIZE(iovec_arr));
386  M0_UT_ASSERT(rc == 0);
387 
388  M0_ALLOC_PTR(ti);
389  M0_UT_ASSERT(ti != NULL);
390  for (cnt = 0; cnt < IOVEC_NR; ++cnt) {
391  iovec_arr[cnt].iov_base = &rc;
392  iovec_arr[cnt].iov_len = IOVEC_BUF_LEN;
393 
395  V_COUNT(ivv, cnt) = IOVEC_BUF_LEN;
396  }
397 
398  /* io_request attributes test. */
399  rc = io_request_init(&req, &lfile, iovec_arr, ivv, IRT_WRITE);
400  M0_UT_ASSERT(rc == 0);
401  M0_UT_ASSERT(req.ir_rc == 0);
403  M0_UT_ASSERT(req.ir_type == IRT_WRITE);
404  M0_UT_ASSERT(req.ir_iovec == iovec_arr);
408 
409  /* Index array should be sorted in increasing order of file offset. */
410  for (cnt = 0; cnt < IOVEC_NR - 1; ++cnt) {
412  V_INDEX(&req.ir_ivv, cnt + 1));
413  }
414 
415  /* nw_xfer_request attributes test. */
421 
422  /* pargrp_iomap attributes test. */
424  M0_UT_ASSERT(rc == 0);
425 
427  map = req.ir_iomaps[0];
428  M0_UT_ASSERT(map->pi_magic == M0_T1FS_PGROUP_MAGIC);
429  M0_UT_ASSERT(map->pi_grpid == 0);
430 
431  /*
432  * Input index vector :
433  * {{21340, 1024}, {20316, 1024}, {19292, 1024}, {18268, 1024}}
434  */
435  M0_UT_ASSERT(indexvec_varr_count(&map->pi_ivv) == PAGE_SIZE * 2);
436 
437  /*
438  * Given input index vector results into 2 pages.
439  * {{16384, 4096}, {20480, 4096}}
440  * The data matrix in this case is 3 x 3.
441  * Since these indices map to page id
442  * 5(maps to element [1][1]) and 6(maps to element [2][1])
443  * in the data matrix.
444  * Rest all pages in data matrix will be NULL.
445  */
446  M0_UT_ASSERT(V_INDEX(&map->pi_ivv, 0) == PAGE_SIZE * 4);
447  M0_UT_ASSERT(V_COUNT(&map->pi_ivv, 0) == 2 * PAGE_SIZE);
448  M0_UT_ASSERT(map->pi_databufs != NULL);
449  M0_UT_ASSERT(map->pi_paritybufs != NULL);
450  M0_UT_ASSERT(map->pi_ops != NULL);
451  M0_UT_ASSERT(map->pi_ioreq == &req);
452  M0_UT_ASSERT(map->pi_databufs[0][0] == NULL);
453  M0_UT_ASSERT(map->pi_databufs[1][0] == NULL);
454  M0_UT_ASSERT(map->pi_databufs[2][0] == NULL);
455  M0_UT_ASSERT(map->pi_databufs[0][1] == NULL);
456  M0_UT_ASSERT(map->pi_databufs[1][1] != NULL);
457  M0_UT_ASSERT(map->pi_databufs[2][1] != NULL);
458  M0_UT_ASSERT(map->pi_databufs[0][2] == NULL);
459  M0_UT_ASSERT(map->pi_databufs[1][2] == NULL);
460  M0_UT_ASSERT(map->pi_databufs[2][2] == NULL);
461  M0_UT_ASSERT(map->pi_paritybufs[0][0] != NULL);
462  M0_UT_ASSERT(map->pi_paritybufs[1][0] != NULL);
463  M0_UT_ASSERT(map->pi_paritybufs[2][0] != NULL);
464 
465  src.sa_group = 0;
466  src.sa_unit = 0;
467  play_instance = pdlayout_instance(layout_instance(&req));
468  m0_fd_fwd_map(play_instance, &src, &tgt);
469  cfid = target_fid(&req, &tgt);
470 
471  /* target_ioreq attributes test. */
473  UNIT_SIZE);
474  M0_UT_ASSERT(rc == 0);
475  M0_UT_ASSERT(ti->ti_rc == 0);
476  M0_UT_ASSERT(m0_fid_eq(&ti->ti_fid, &cfid));
477  M0_UT_ASSERT(ti->ti_obj == tgt.ta_obj);
478  M0_UT_ASSERT(ti->ti_parbytes == 0);
479  M0_UT_ASSERT(ti->ti_databytes == 0);
483  M0_UT_ASSERT(iofops_tlist_is_empty(&ti->ti_iofops));
484  M0_UT_ASSERT(ti->ti_ops != NULL);
485 
486  /* io_req_fop attributes test. */
487  M0_ALLOC_PTR(irfop);
488  M0_UT_ASSERT(irfop != NULL);
490  rc = io_req_fop_init(irfop, ti, PA_DATA);
491  M0_UT_ASSERT(rc == 0);
493  M0_UT_ASSERT(irfop->irf_tioreq == ti);
496  M0_UT_ASSERT(irfop->irf_ast.sa_mach == &req.ir_sm);
497 
498  /* data_buf attributes test. */
499  dbuf = data_buf_alloc_init(0);
500  M0_UT_ASSERT(dbuf != NULL);
501  M0_UT_ASSERT(dbuf->db_flags == 0);
503  M0_UT_ASSERT(dbuf->db_buf.b_addr != NULL);
505  M0_UT_ASSERT(dbuf->db_auxbuf.b_addr == NULL);
506  M0_UT_ASSERT(dbuf->db_auxbuf.b_nob == 0);
507 
508  data_buf_dealloc_fini(dbuf);
509  dbuf = NULL;
510 
511  io_req_fop_fini(irfop);
512  M0_UT_ASSERT(irfop->irf_tioreq == NULL);
513  M0_UT_ASSERT(irfop->irf_ast.sa_cb == NULL);
514  M0_UT_ASSERT(irfop->irf_ast.sa_mach == NULL);
515  m0_free0(&irfop);
516 
517  V_SEG_NR(&ti->ti_ivv) = page_nr(UNIT_SIZE);
518  target_ioreq_fini(ti);
519  M0_UT_ASSERT(ti->ti_magic == 0);
520  M0_UT_ASSERT(ti->ti_ops == NULL);
521  M0_UT_ASSERT(ti->ti_session == NULL);
522  M0_UT_ASSERT(ti->ti_nwxfer == NULL);
523 
525  M0_UT_ASSERT(map->pi_ops == NULL);
526  M0_UT_ASSERT(map->pi_rtype == PIR_NONE);
527  M0_UT_ASSERT(map->pi_magic == 0);
528  M0_UT_ASSERT(map->pi_databufs == NULL);
529  M0_UT_ASSERT(map->pi_paritybufs == NULL);
530  M0_UT_ASSERT(map->pi_ioreq == NULL);
531 
532  m0_free0(&map);
533  req.ir_iomaps[0] = NULL;
534  req.ir_iomap_nr = 0;
535 
539  req.ir_nwxfer.nxr_bytes = 1;
540  M0_UT_ASSERT(tioreqht_htable_is_empty(&req.ir_nwxfer.nxr_tioreqs_hash));
546 
549  m0_free(ti);
551  m0_free(ivv);
552 }
553 
554 static int dummy_readrest(struct pargrp_iomap *map)
555 {
556  return 0;
557 }
558 
559 static void pargrp_iomap_test(void)
560 {
561  int rc;
562  int cnt;
563  uint32_t row;
564  uint32_t col;
565  uint64_t nr;
567  struct iovec iovec_arr[LAY_N * UNIT_SIZE / PAGE_SIZE];
568  struct m0_indexvec_varr *ivv;
569  struct m0_ivec_varr_cursor cur;
570  struct pargrp_iomap_ops piops;
571 
572  M0_ALLOC_PTR(ivv);
573  M0_UT_ASSERT(ivv != NULL);
574 
575  rc = m0_indexvec_varr_alloc(ivv, ARRAY_SIZE(iovec_arr));
576  M0_UT_ASSERT(rc == 0);
577 
578  for (cnt = 0; cnt < ARRAY_SIZE(iovec_arr); ++cnt) {
579  iovec_arr[cnt].iov_base = &rc;
580  iovec_arr[cnt].iov_len = PAGE_SIZE;
581 
582  V_INDEX(ivv, cnt) = (m0_bindex_t)(cnt * PAGE_SIZE);
583  V_COUNT(ivv, cnt) = PAGE_SIZE;
584  }
585 
586  M0_SET0(&req);
587  rc = io_request_init(&req, &lfile, iovec_arr, ivv, IRT_WRITE);
588  M0_UT_ASSERT(rc == 0);
589 
590  M0_SET0(&map);
591  rc = pargrp_iomap_init(&map, &req, 0);
592  M0_UT_ASSERT(rc == 0);
593 
595  M0_UT_ASSERT(rc == 0);
596  M0_UT_ASSERT(map.pi_databufs[0][0] != NULL);
597  M0_UT_ASSERT(map.pi_databufs[0][0]->db_buf.b_addr != NULL);
598  M0_UT_ASSERT(map.pi_databufs[0][0]->db_buf.b_nob == PAGE_SIZE);
599  M0_UT_ASSERT(map.pi_databufs[0][0]->db_flags == 0);
600  data_buf_dealloc_fini(map.pi_databufs[0][0]);
601  map.pi_databufs[0][0] = NULL;
602 
603  for (cnt = 0; cnt < ARRAY_SIZE(iovec_arr); ++cnt) {
604  V_INDEX(&map.pi_ivv, cnt) = (m0_bindex_t)(cnt * PAGE_SIZE);
605  V_COUNT(&map.pi_ivv, cnt) = PAGE_SIZE;
606  ++ V_SEG_NR(&map.pi_ivv);
607 
608  rc = pargrp_iomap_seg_process(&map, cnt, true);
609  M0_UT_ASSERT(rc == 0);
610 
611  page_pos_get(&map, V_INDEX(&map.pi_ivv, cnt), &row, &col);
612  M0_UT_ASSERT(map.pi_databufs[row][col] != NULL);
613  M0_UT_ASSERT(map.pi_databufs[row][col]->db_flags & PA_WRITE);
614  M0_UT_ASSERT(map.pi_databufs[row][col]->db_flags &
616  M0_UT_ASSERT(map.pi_databufs[row][col]->db_flags & ~PA_READ);
617  }
618 
619  /* Checks if given segment falls in pargrp_iomap::pi_ivv. */
623 
624  /*
625  * Checks if number of pages completely spanned by index vector
626  * is correct.
627  */
630 
631  /* Checks if all parity buffers are allocated properly. */
632  map.pi_rtype = PIR_READOLD;
634  M0_UT_ASSERT(rc == 0);
635 
636  for (row = 0; row < rows_nr(pdlay); ++row) {
637  for (col = 0; col < layout_k(pdlay); ++col) {
638  M0_UT_ASSERT(map.pi_paritybufs[row][col] != NULL);
639  M0_UT_ASSERT(map.pi_paritybufs[row][col]->db_flags &
640  PA_WRITE);
641  M0_UT_ASSERT(map.pi_paritybufs[row][col]->db_flags &
642  PA_READ);
643  }
644  }
645 
646  /*
647  * Checks if any auxiliary buffers are allocated.
648  * There should be no auxiliary buffers at all.
649  */
651  M0_UT_ASSERT(rc == 0);
652 
653  for (row = 0; row < rows_nr(pdlay); ++row) {
654  for (col = 0; col < layout_n(pdlay); ++col) {
655  M0_UT_ASSERT(map.pi_databufs[row][col]->db_flags &
657  }
658  }
659 
660  /* pargrp_iomap_fini() deallocates all data_buf structures in it. */
665  req.ir_nwxfer.nxr_bytes = 1;
667 
669  M0_UT_ASSERT(rc == 0);
670 
671  index = INDEXPG;
672  /*
673  * Segments {2000, 7000}, {9000, 14000}, {16000, 21000}, {23000, 28000}}
674  */
675  for (cnt = 0; cnt < IOVEC_NR; ++cnt) {
676 
677  iovec_arr[cnt].iov_base = &rc;
678  iovec_arr[cnt].iov_len = INDEXPG_STEP;
679 
680  V_INDEX(ivv, cnt) = index;
681  V_COUNT(ivv, cnt) = INDEXPG_STEP;
682  index += V_COUNT(ivv, cnt) + INDEXPG;
683  }
684 
685  M0_SET0(&req);
686  rc = io_request_init(&req, &lfile, iovec_arr, ivv, IRT_WRITE);
687  M0_UT_ASSERT(rc == 0);
688 
689  M0_SET0(&map);
690  rc = pargrp_iomap_init(&map, &req, 0);
691  M0_UT_ASSERT(rc == 0);
692 
693  piops = (struct pargrp_iomap_ops) {
695  .pi_spans_seg = pargrp_iomap_spans_seg,
696  /* Dummy UT function. */
697  .pi_readrest = dummy_readrest,
698  .pi_fullpages_find = pargrp_iomap_fullpages_count,
699  .pi_seg_process = pargrp_iomap_seg_process,
700  .pi_readold_auxbuf_alloc = pargrp_iomap_readold_auxbuf_alloc,
701  .pi_parity_recalc = pargrp_iomap_parity_recalc,
702  .pi_paritybufs_alloc = pargrp_iomap_paritybufs_alloc,
703  };
705  map.pi_ops = &piops;
707  M0_UT_ASSERT(rc == 0);
708  M0_UT_ASSERT(map.pi_databufs != NULL);
709  M0_UT_ASSERT(indexvec_varr_count(&map.pi_ivv) > 0);
710  M0_UT_ASSERT(map.pi_grpid == 0);
711  M0_UT_ASSERT(V_SEG_NR(&map.pi_ivv) == 4);
712 
713  M0_UT_ASSERT(V_INDEX(&map.pi_ivv, 0) == 0);
714  M0_UT_ASSERT(V_COUNT(&map.pi_ivv, 0) == 2 * PAGE_SIZE);
715  M0_UT_ASSERT(map.pi_databufs[0][0] != NULL);
716  M0_UT_ASSERT(map.pi_databufs[1][0] != NULL);
717 
718  M0_UT_ASSERT(V_INDEX(&map.pi_ivv, 1) == 2 * PAGE_SIZE);
719  M0_UT_ASSERT(V_COUNT(&map.pi_ivv, 1) == 2 * PAGE_SIZE);
720  M0_UT_ASSERT(map.pi_databufs[2][0] != NULL);
721  M0_UT_ASSERT(map.pi_databufs[0][1] != NULL);
722 
723  M0_UT_ASSERT(V_INDEX(&map.pi_ivv, 2) == 4 * PAGE_SIZE);
724  M0_UT_ASSERT(V_COUNT(&map.pi_ivv, 2) == 2 * PAGE_SIZE);
725  M0_UT_ASSERT(map.pi_databufs[1][1] != NULL);
726  M0_UT_ASSERT(map.pi_databufs[2][1] != NULL);
727 
728  M0_UT_ASSERT(V_INDEX(&map.pi_ivv, 3) == 6 * PAGE_SIZE);
729  M0_UT_ASSERT(V_COUNT(&map.pi_ivv, 3) == PAGE_SIZE);
730  M0_UT_ASSERT(map.pi_databufs[0][2] != NULL);
731 
733  M0_UT_ASSERT(rc == 0);
734  M0_UT_ASSERT(v_seg_endpos(&map.pi_ivv, 3) ==
735  data_size(pdlay));
736  M0_UT_ASSERT(map.pi_databufs[1][2] != NULL);
737  M0_UT_ASSERT(map.pi_databufs[1][2]->db_flags & PA_READ);
738  M0_UT_ASSERT(map.pi_databufs[2][2] != NULL);
739  M0_UT_ASSERT(map.pi_databufs[2][2]->db_flags & PA_READ);
740 
743  req.ir_nwxfer.nxr_bytes = 1;
745  m0_free(ivv);
746 }
747 
748 static void helpers_test(void)
749 {
750  uint32_t i;
751  uint32_t j;
752  uint32_t row;
753  uint32_t col;
754  m0_bindex_t start = 0;
755 
757  (UNIT_SIZE >> PAGE_SHIFT) * LAY_K);
758 
759  M0_UT_ASSERT(rows_nr(pdlay) == UNIT_SIZE >> PAGE_SHIFT);
762 
763  M0_UT_ASSERT(round_down(1000, 1024) == 0);
764  M0_UT_ASSERT(round_up(2000, 1024) == 2048);
765  M0_UT_ASSERT(round_up(0, 2) == 0);
766  M0_UT_ASSERT(round_down(1023, 1024) == 0);
767  M0_UT_ASSERT(round_up(1025, 1024) == 2048);
768  M0_UT_ASSERT(round_down(1024, 1024) == round_up(1024, 1024));
769 
770  M0_SET0(&req);
771  req.ir_file = &lfile;
772  map = (struct pargrp_iomap) {
773  .pi_ioreq = &req,
774  .pi_grpid = 0,
775  };
776 
777  for (i = 0; i < UNIT_SIZE / PAGE_SIZE; ++i) {
778  for (j = 0; j < LAY_N; ++j) {
779  page_pos_get(&map, start, &row, &col);
780  M0_UT_ASSERT(row == j && col == i);
781  start += PAGE_SIZE;
782  }
783  }
784 }
785 
786 static void nw_xfer_ops_test(void)
787 {
788  int cnt;
789  int rc;
791  struct iovec iovec_arr[LAY_N * UNIT_SIZE >>
792  PAGE_SHIFT];
793  struct m0_indexvec_varr *ivv;
794  struct target_ioreq *ti;
795  struct target_ioreq *ti1;
796  struct m0_pdclust_src_addr src;
797  struct m0_pdclust_tgt_addr tgt;
798 
799  M0_ALLOC_PTR(ivv);
800  M0_UT_ASSERT(ivv != NULL);
801 
802  M0_SET0(&req);
803  M0_SET0(&src);
804  M0_SET0(&tgt);
805  rc = m0_indexvec_varr_alloc(ivv, ARRAY_SIZE(iovec_arr));
806  M0_UT_ASSERT(rc == 0);
807 
808  index = 0;
809  for (cnt = 0; cnt < LAY_N * UNIT_SIZE >> PAGE_SHIFT; ++cnt) {
810  iovec_arr[cnt].iov_base = &rc;
811  iovec_arr[cnt].iov_len = PAGE_SIZE;
812 
813  V_INDEX(ivv, cnt) = index;
814  V_COUNT(ivv, cnt) = PAGE_SIZE;
815  index += PAGE_SIZE;
816  }
817 
818  M0_SET0(&req);
819  rc = io_request_init(&req, &lfile, iovec_arr, ivv, IRT_WRITE);
820  M0_UT_ASSERT(rc == 0);
821 
823  M0_UT_ASSERT(rc == 0);
826 
827  src.sa_unit = 0;
828 
829  /* Test for nw_xfer_tioreq_map. */
830  rc = nw_xfer_tioreq_map(&req.ir_nwxfer, &src, &tgt, &ti);
831  M0_UT_ASSERT(rc == 0);
832  M0_UT_ASSERT(!tioreqht_htable_is_empty(&req.ir_nwxfer.
833  nxr_tioreqs_hash));
834 
835  /* Test for nw_xfer_io_distribute. */
837  M0_UT_ASSERT(rc == 0);
838  M0_UT_ASSERT(tioreqht_htable_size(&req.ir_nwxfer.nxr_tioreqs_hash) ==
839  LAY_P - LAY_K);
840  m0_htable_for(tioreqht, ti, &req.ir_nwxfer.nxr_tioreqs_hash) {
842  M0_UT_ASSERT(ti->ti_ops != NULL);
843 
844  for (cnt = 0; cnt < V_SEG_NR(&ti->ti_ivv); ++cnt) {
845  M0_UT_ASSERT((V_INDEX(&ti->ti_ivv, cnt) &
846  (PAGE_SIZE - 1)) == 0);
848  }
850 
851  m0_htable_for(tioreqht, ti1, &req.ir_nwxfer.nxr_tioreqs_hash) {
852  tioreqht_htable_del(&req.ir_nwxfer.nxr_tioreqs_hash, ti1);
854 
858  req.ir_nwxfer.nxr_bytes = 1;
861  m0_free(ivv);
862 }
863 
864 static void target_ioreq_test(void)
865 {
866  struct target_ioreq *ti;
867  uint64_t size;
868  struct m0_fid cfid;
869  struct m0_rpc_session session = { .s_cancelled = false };
870  struct io_req_fop *irfop;
871  int cnt;
872  int rc;
873  void *aligned_buf;
874  struct iovec iovec_arr[IOVEC_NR];
875  struct m0_indexvec_varr *ivv;
876  struct pargrp_iomap *map;
877  uint32_t row;
878  uint32_t col;
879  struct data_buf *buf;
880  struct m0_pdclust_instance *play_instance;
881  struct m0_pdclust_src_addr src;
882  struct m0_pdclust_tgt_addr tgt;
883 
884  /* Checks working of target_ioreq_iofops_prepare() */
885 
886  M0_ALLOC_PTR(ti);
887  M0_UT_ASSERT(ti != NULL);
888  size = IOVEC_NR * PAGE_SIZE;
889  M0_SET0(&req);
891 
892  conn = (struct m0_rpc_conn) { .c_rpc_machine = &csb.csb_rpc_machine };
893  session.s_conn = &conn;
895 
896  aligned_buf = m0_alloc_aligned(M0_0VEC_ALIGN, M0_0VEC_SHIFT);
897 
898  io_request_bob_init(&req);
899  req.ir_file = &lfile;
901 
902  src.sa_group = 0;
903  src.sa_unit = 0;
904  play_instance = pdlayout_instance(layout_instance(&req));
905  m0_fd_fwd_map(play_instance, &src, &tgt);
906  cfid = target_fid(&req, &tgt);
908  size);
909  M0_UT_ASSERT(rc == 0);
910 
911  for (cnt = 0; cnt < IOVEC_NR; ++cnt) {
912  iovec_arr[cnt].iov_base = aligned_buf;
913  iovec_arr[cnt].iov_len = PAGE_SIZE;
914  V_ADDR (&ti->ti_bufvec, cnt) = aligned_buf;
915  V_COUNT(&ti->ti_ivv, cnt) = PAGE_SIZE;
916  V_INDEX(&ti->ti_ivv, cnt) = cnt * PAGE_SIZE;
917  PA(&ti->ti_pageattrs, cnt) = PA_READ | PA_DATA;
918  }
919  V_SEG_NR(&ti->ti_ivv) = IOVEC_NR;
920 
922  /*
923  * Even in normal case, we may experience m0_alloc() failure.
924  * So, we should handle the -ENOMEM too.
925  */
926  M0_UT_ASSERT(rc == 0 || rc == -ENOMEM);
927  if (rc != 0)
928  goto skip;
930  m0_tl_for(iofops, &ti->ti_iofops, irfop) {
931  struct m0_rpc_bulk *rbulk = &irfop->irf_iofop.if_rbulk;
935  } m0_tl_endfor;
936 
937  m0_tl_teardown(iofops, &ti->ti_iofops, irfop) {
938  struct m0_io_fop *iofop = &irfop->irf_iofop;
939 
942  irfop_fini(irfop);
943  /* @todo: fix me: m0_io_fop_fini(iofop); */
945  }
946 
947 skip:
948  /* Checks allocation failure. */
949  m0_fi_enable_off_n_on_m("m0_alloc", "fail_allocation", 1, 1);
951  M0_UT_ASSERT(rc == -ENOMEM);
952 
953  /* Checks allocation failure in m0_rpc_bulk_buf_add(). */
954 
955  m0_fi_enable_off_n_on_m("m0_alloc", "fail_allocation", 2, 1);
957  M0_UT_ASSERT(rc == -ENOMEM);
958  m0_fi_disable("m0_alloc", "fail_allocation");
959 
960  /* Finalisation */
962  req.ir_nwxfer.nxr_bytes = 1;
964  io_request_bob_fini(&req);
965 
966  /* Checks working of target_ioreq_seg_add() */
967  ivv = &ti->ti_ivv;
968  M0_SET0(&req);
969  rc = io_request_init(&req, &lfile, iovec_arr, ivv, IRT_WRITE);
970  M0_UT_ASSERT(rc == 0);
971 
972  m0_fi_enable_random("m0_alloc", "fail_allocation", 5);
974  m0_fi_disable("m0_alloc", "fail_allocation");
975  if (rc == -ENOMEM)
977  M0_UT_ASSERT(rc == 0);
978  map = req.ir_iomaps[0];
979 
980  /* Addition of data buffer */
981  page_pos_get(map, 0, &row, &col);
982  buf = map->pi_databufs[row][col];
983  M0_UT_ASSERT(row == 0);
984  M0_UT_ASSERT(col == 0);
985  V_SEG_NR(&ti->ti_ivv) = 0;
986 
987  for (cnt = 0; cnt < IOVEC_NR; ++cnt)
988  PA(&ti->ti_pageattrs, cnt) &= ~(PA_DATA | PA_PARITY);
989 
990  src.sa_group = 0;
991  src.sa_unit = 0;
992  tgt.ta_frame = 0;
993  tgt.ta_obj = 0;
994 
996  M0_UT_ASSERT(1 == V_SEG_NR(&ti->ti_ivv));
997  M0_UT_ASSERT(V_ADDR(&ti->ti_bufvec, 0) == buf->db_buf.b_addr);
998  M0_UT_ASSERT(PA(&ti->ti_pageattrs, 0) & PA_DATA);
999 
1000  /* Set gob_offset to COUNT(&ti->ti_ivec, 0) */
1001  page_pos_get(map, V_COUNT(&ti->ti_ivv, 0), &row, &col);
1002  buf = map->pi_databufs[row][col];
1003 
1004  target_ioreq_seg_add(ti, &src, &tgt, V_COUNT(&ti->ti_ivv, 0),
1005  PAGE_SIZE, map);
1006  M0_UT_ASSERT(2 == V_SEG_NR(&ti->ti_ivv));
1007  M0_UT_ASSERT(V_ADDR(&ti->ti_bufvec, 1) == buf->db_buf.b_addr);
1008  M0_UT_ASSERT(PA(&ti->ti_pageattrs, 1) & PA_DATA);
1009 
1010  /* Addition of parity buffer */
1011  buf = map->pi_paritybufs[page_id(0)][LAY_N % layout_n(pdlay)];
1012 
1013  src.sa_unit = LAY_N;
1014  target_ioreq_seg_add(ti, &src, &tgt, 0, PAGE_SIZE, map);
1015  M0_UT_ASSERT(3 == V_SEG_NR(&ti->ti_ivv));
1016  M0_UT_ASSERT(V_ADDR(&ti->ti_bufvec, 2) == buf->db_buf.b_addr);
1017  M0_UT_ASSERT(PA(&ti->ti_pageattrs, 2) & PA_PARITY);
1018 
1019  target_ioreq_fini(ti);
1021  m0_free0(&map);
1022  req.ir_iomaps[0] = NULL;
1023  req.ir_iomap_nr = 0;
1024 
1027  req.ir_nwxfer.nxr_bytes = 1;
1028  io_request_fini(&req);
1029 
1030  m0_free_aligned(aligned_buf, M0_0VEC_ALIGN, M0_0VEC_SHIFT);
1031  m0_free(ti);
1032 }
1033 
1034 static struct dgmode_rwvec dgvec_tmp;
1035 static void dgmode_readio_test(void)
1036 {
1037  int rc;
1038  uint64_t i;
1039  char content[LAY_P - 1] = {'b', 'c', 'd', 'e'};
1040  char *cont;
1041  uint32_t row;
1042  uint32_t col;
1043  uint64_t pgcur = 0;
1044  struct iovec *iovec_arr;
1045  struct m0_fop *reply;
1046  struct io_request *req;
1047  struct io_req_fop *irfop;
1048  struct m0_indexvec_varr *ivv;
1049  struct m0_rpc_bulk *rbulk;
1050  struct pargrp_iomap *iomap;
1051  struct target_ioreq *ti;
1052  struct m0_rpc_session *session;
1053  struct m0_layout_enum *le;
1054  struct m0_rpc_bulk_buf *rbuf;
1055  struct m0_pdclust_layout *play;
1056  struct m0_pdclust_src_addr src;
1057  struct m0_pdclust_tgt_addr tgt;
1058  struct m0_fop_cob_rw_reply *rw_rep;
1059  struct m0_fid cfid;
1060 
1061  M0_ALLOC_PTR(ivv);
1062  M0_UT_ASSERT(ivv != NULL);
1063 
1064  M0_ALLOC_ARR(iovec_arr, DGMODE_IOVEC_NR);
1065  M0_UT_ASSERT(iovec_arr != NULL);
1066 
1067  M0_ALLOC_PTR(req);
1068  M0_UT_ASSERT(req != NULL);
1069 
1071  M0_UT_ASSERT(rc == 0);
1072 
1073  /* 8 segments covering a parity group each. */
1074  for (i = 0; i < DGMODE_IOVEC_NR; ++i) {
1075  iovec_arr[i].iov_base = &rc;
1076  iovec_arr[i].iov_len = PAGE_SIZE;
1077 
1078  V_INDEX(ivv, i) = i * UNIT_SIZE * LAY_N;
1079  V_COUNT(ivv, i) = iovec_arr[i].iov_len;
1080  }
1081 
1082  ci.ci_inode.i_size = 2 * DATA_SIZE * DGMODE_IOVEC_NR;
1083  rc = io_request_init(req, &lfile, iovec_arr, ivv, IRT_READ);
1084  M0_UT_ASSERT(rc == 0);
1085 
1086  /* Creates all pargrp_iomap structures. */
1088  M0_UT_ASSERT(rc == 0);
1090 
1091  /* Spawns and initialises all target_ioreq objects. */
1093  M0_UT_ASSERT(rc == 0);
1094 
1096  m0_fid_convert_gob2cob(&ci.ci_fid, &cfid, 1);
1097  ti = tioreqht_htable_lookup(&req->ir_nwxfer.nxr_tioreqs_hash,
1098  &cfid.f_container);
1099  M0_UT_ASSERT(ti != NULL);
1100  /*
1101  * Fake data structure members so that UT passes through
1102  * PRE checks unhurt.
1103  */
1104  ti->ti_dgvec = &dgvec_tmp;
1108  session->s_conn = &conn;
1109  conn = (struct m0_rpc_conn) { .c_rpc_machine = &csb.csb_rpc_machine };
1110  conn.c_rpc_machine->rm_tm.ntm_dom = &csb.csb_ndom;
1111  ti->ti_session = session;
1112 
1113  /* Creates IO fops from pages. */
1115  M0_UT_ASSERT(rc == 0);
1116 
1117  /* Retrieves an IO fop that will be treated as a failed fop. */
1118  irfop = iofops_tlist_head(&ti->ti_iofops);
1120  &csb.csb_rpc_machine);
1122  &csb.csb_rpc_machine);
1123  reply->f_item.ri_rmachine = conn.c_rpc_machine;
1124  irfop->irf_iofop.if_fop.f_item.ri_reply = &reply->f_item;
1125 
1126  /* Increments refcount so that ref release can be verified. */
1127  reply = m0_fop_get(reply);
1128 
1129  rbulk = &irfop->irf_iofop.if_rbulk;
1130  M0_UT_ASSERT(m0_rpc_bulk_buf_length(rbulk) == 1);
1131  rbuf = m0_tlist_head(&rpcbulk_tl, &rbulk->rb_buflist);
1132 
1133  /*
1134  * Starts degraded mode processing for parity groups whose pages
1135  * are found in the failed IO fop.
1136  */
1139  rw_rep = io_rw_rep_get(reply);
1140  rw_rep->rwr_rc = 0;
1141  io_req_fop_dgmode_read(irfop);
1142 
1143  play = pdlayout_get(req);
1145  ci_layout_instance);
1146  M0_UT_ASSERT(le != NULL);
1147 
1148  for (i = 0; i < req->ir_iomap_nr; ++i) {
1149  iomap = req->ir_iomaps[i];
1150  if (iomap->pi_state != PI_DEGRADED)
1151  continue;
1152 
1153  rc = iomap->pi_ops->pi_dgmode_postprocess(iomap);
1154  M0_UT_ASSERT(rc == 0);
1155  }
1156 
1157  for (i = 0; i < rbuf->bb_zerovec.z_bvec.ov_vec.v_nr; ++i) {
1158  m0_bindex_t z_index = rbuf->bb_zerovec.z_index[i];
1159  ioreq_pgiomap_find(req, pargrp_id_find(z_index, req, irfop),
1160  &pgcur, &iomap);
1161  M0_UT_ASSERT(iomap != NULL);
1162  M0_UT_ASSERT(iomap->pi_state == PI_DEGRADED);
1163  pargrp_src_addr(z_index, req, ti, &src);
1164 
1165  tgt.ta_frame = z_index / layout_unit_size(play);
1167  file_to_fid(req->ir_file), &ti->ti_fid);
1168 
1170  &src);
1171  M0_UT_ASSERT(src.sa_unit < layout_n(play));
1172 
1173  /*
1174  * Checks if all pages from given unit_id are marked
1175  * as failed.
1176  */
1177  for (row = 0; row < rows_nr(play); ++row)
1178  M0_UT_ASSERT(iomap->pi_databufs[row][src.sa_unit]->
1179  db_flags & PA_READ_FAILED);
1180 
1181  }
1182 
1183  for (i = 0; i < req->ir_iomap_nr; ++i) {
1184  iomap = req->ir_iomaps[i];
1185  if (iomap->pi_state != PI_DEGRADED)
1186  continue;
1187 
1188  /* Traversing unit by unit. */
1189  for (col = 0; col < layout_n(play); ++col) {
1190  for (row = 0; row < rows_nr(play); ++row) {
1191  if (col == src.sa_unit)
1192  M0_UT_ASSERT(iomap->pi_databufs
1193  [row][col]->db_flags &
1194  PA_READ_FAILED);
1195  else {
1196  M0_UT_ASSERT(iomap->pi_databufs
1197  [row][col]->db_flags &
1198  PA_DGMODE_READ);
1199  memset(iomap->pi_databufs[row][col]->
1200  db_buf.b_addr, content[col],
1201  PAGE_SIZE);
1202  cont = (char *)iomap->pi_databufs
1203  [row][col]->db_buf.b_addr;
1204  }
1205  }
1206  }
1207 
1208  /* Parity units are needed for recovery. */
1209  for (col = 0; col < layout_k(play); ++col) {
1210  for (row = 0; row < rows_nr(play); ++row) {
1211  M0_UT_ASSERT(iomap->pi_paritybufs[row][col]->
1212  db_flags & PA_DGMODE_READ);
1213  memset(iomap->pi_paritybufs[row][col]->db_buf.
1214  b_addr, content[LAY_P - 2], PAGE_SIZE);
1215  cont = (char *)iomap->pi_paritybufs[row][col]->
1216  db_buf.b_addr;
1217  }
1218  }
1219 
1220  /* Recovers lost data unit/s. */
1222  M0_UT_ASSERT(rc == 0);
1223 
1224  /* Validate the recovered data. */
1225  for (row = 0; row < rows_nr(play); ++row) {
1226  cont = (char *)iomap->pi_databufs[row][src.sa_unit]->
1227  db_buf.b_addr;
1228  for (col = 0; col < PAGE_SIZE; ++col, ++cont)
1229  M0_UT_ASSERT(*cont == content[0]);
1230  }
1231  }
1232 
1233  ti->ti_dgvec = NULL;
1235  M0_UT_ASSERT(rc == 0);
1236  M0_UT_ASSERT(ti->ti_dgvec->dr_tioreq == ti);
1237 
1239  layout_k(play));
1241 
1242  /* Cleanup */
1248  ti->ti_dgvec = NULL;
1249 
1253  m0_indexvec_varr_free(ivv);
1254  m0_free(req);
1255  m0_free(iovec_arr);
1256  m0_free(ivv);
1257 }
1258 
1260  .ts_name = "file-io-ut",
1261  .ts_init = file_io_ut_init,
1262  .ts_fini = file_io_ut_fini,
1263  .ts_tests = {
1264  {"basic_data_structures_test", ds_test},
1265  {"helper_routines_test", helpers_test},
1266  {"parity_group_ops_test", pargrp_iomap_test},
1267  {"nw_xfer_ops_test", nw_xfer_ops_test},
1268  {"target_ioreq_ops_test", target_ioreq_test},
1269  {"dgmode_readio_test", dgmode_readio_test},
1270  {"fsync_test", fsync_test},
1271  {NULL, NULL},
1272  },
1273 };
1274 M0_EXPORTED(file_io_ut);
1275 #undef M0_TRACE_SUBSYSTEM
static struct m0t1fs_sb csb
Definition: file.c:86
Definition: file.c:67
struct m0_fop_type m0_fop_cob_readv_rep_fopt
Definition: io_fops.c:73
static int io_request_init(struct io_request *req, struct file *file, const struct iovec *iov, struct m0_indexvec_varr *ivv, enum io_req_type rw)
Definition: file.c:4299
static size_t nr
Definition: dump.c:1505
M0_INTERNAL void m0_chan_wait(struct m0_clink *link)
Definition: chan.c:336
M0_INTERNAL void m0_pools_common_fini(struct m0_pools_common *pc)
Definition: pool.c:1549
uint64_t ir_iomap_nr
Definition: file.c:79
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
M0_TL_DECLARE(rpcbulk, M0_INTERNAL, struct m0_rpc_bulk_buf)
#define V_INDEX(ivec, i)
Definition: file.c:395
static struct m0_fid target_fid(const struct io_request *req, struct m0_pdclust_tgt_addr *tgt)
Definition: file.c:668
M0_INTERNAL void m0_reqh_services_terminate(struct m0_reqh *reqh)
Definition: reqh.c:675
Definition: file.c:59
M0_INTERNAL void m0_fid_gob_make(struct m0_fid *gob_fid, uint32_t container, uint64_t key)
Definition: fid_convert.c:46
#define m0_htable_for(name, var, htable)
Definition: hash.h:483
uint64_t sa_group
Definition: pdclust.h:241
void * m0_tlist_head(const struct m0_tl_descr *d, const struct m0_tl *list)
Definition: tlist.c:187
#define NULL
Definition: misc.h:38
map
Definition: processor.c:112
static int dgmode_rwvec_alloc_init(struct target_ioreq *ti)
Definition: file.c:3275
struct m0_atomic64 nxr_rdbulk_nr
static struct m0_rm_remote creditor
Definition: file.c:95
struct m0_pool_version * l_pver
Definition: layout.h:261
static void io_req_fop_fini(struct io_req_fop *fop)
Definition: file.c:5019
static void pargrp_iomap_fini(struct pargrp_iomap *map)
Definition: file.c:1881
static struct buffer * cur(struct m0_addb2_mach *mach, m0_bcount_t space)
Definition: addb2.c:791
m0_bindex_t * z_index
Definition: vec.h:516
struct m0_buf db_auxbuf
static int ioreq_iomaps_prepare(struct io_request *req)
Definition: file.c:3187
int m0_thread_join(struct m0_thread *q)
Definition: kthread.c:169
void(* sa_cb)(struct m0_sm_group *grp, struct m0_sm_ast *)
Definition: sm.h:506
void * b_addr
Definition: buf.h:39
static struct io_request req
Definition: file.c:100
struct m0_file file
Definition: di.c:36
uint32_t pa_N
Definition: pdclust.h:104
static int file_io_ut_init(void)
Definition: file.c:195
struct m0_conf_obj rt_obj
Definition: obj.h:372
static void dgmode_readio_test(void)
Definition: file.c:1035
struct data_buf *** pi_paritybufs
static int nw_xfer_tioreq_map(struct nw_xfer_request *xfer, const struct m0_pdclust_src_addr *src, struct m0_pdclust_tgt_addr *tgt, struct target_ioreq **tio)
Definition: file.c:4520
int m0t1fs_net_init(struct m0t1fs_sb *csb, const char *ep)
Definition: super.c:573
M0_INTERNAL void m0_reqh_layouts_cleanup(struct m0_reqh *reqh)
Definition: reqh.c:169
static void nw_xfer_req_complete(struct nw_xfer_request *xfer, bool rmw)
Definition: file.c:6266
static uint32_t layout_k(const struct m0_pdclust_layout *play)
Definition: file.c:520
static void m0_atomic64_sub(struct m0_atomic64 *a, int64_t num)
static struct dgmode_rwvec dgvec_tmp
Definition: file.c:1034
uint64_t ir_magic
#define M0_FID_INIT(container, key)
Definition: fid.h:84
M0_INTERNAL const struct m0_fid * m0t1fs_inode_fid(const struct m0t1fs_inode *ci)
Definition: inode.c:61
M0_INTERNAL void m0_uint128_init(struct m0_uint128 *u128, const char *magic)
Definition: misc.c:150
struct m0_vec ov_vec
Definition: vec.h:147
static m0_bcount_t v_seg_endpos(struct m0_indexvec_varr *ivec, uint32_t i)
Definition: file.c:428
M0_INTERNAL int m0_linear_enum_build(struct m0_layout_domain *dom, const struct m0_layout_linear_attr *attr, struct m0_layout_linear_enum **out)
Definition: linear_enum.c:138
struct m0_rpc_bulk if_rbulk
Definition: io_fops.h:177
#define LOCAL_EP
Definition: file.c:113
#define V_ADDR(bv, i)
Definition: file.c:396
uint64_t ta_obj
Definition: pdclust.h:256
static void ds_test(void)
Definition: file.c:365
struct m0_indexvec_varr ti_bufvec
M0_INTERNAL void m0_rconfc_stop_sync(struct m0_rconfc *rconfc)
Definition: rconfc.c:2995
#define PA(pa, i)
Definition: file.c:400
struct m0_net_domain * ntm_dom
Definition: net.h:853
Definition: file.c:74
static void nw_xfer_ops_test(void)
Definition: file.c:786
M0_INTERNAL void m0_free_aligned(void *data, size_t size, unsigned shift)
Definition: memory.c:192
M0_INTERNAL void m0t1fs_file_lock_fini(struct m0t1fs_inode *ci)
Definition: inode.c:162
static struct file lfile
Definition: file.c:93
uint64_t m0_bindex_t
Definition: types.h:80
uint64_t ti_obj
struct m0_varr ti_pageattrs
#define M0_THREAD_INIT(thread, TYPE, init, func, arg, namefmt,...)
Definition: thread.h:139
static char * ha_addr
Definition: m0hsm.c:43
#define PAGE_SIZE
Definition: lnet_ut.c:277
struct m0_sm * sa_mach
Definition: sm.h:510
static int void * buf
Definition: dir.c:1019
static uint64_t round_up(uint64_t val, uint64_t size)
Definition: file.c:711
void m0t1fs_net_fini(struct m0t1fs_sb *csb)
Definition: super.c:618
static void m0_fi_enable_random(const char *func, const char *tag, uint32_t p)
Definition: finject.h:321
static struct m0_rpc_session session
Definition: formation2.c:38
#define M0_SET0(obj)
Definition: misc.h:64
static void ioreq_sm_state_set(struct io_request *req, int state)
Definition: file.c:1039
M0_INTERNAL void m0t1fs_sb_init(struct m0t1fs_sb *csb)
Definition: super.c:423
Definition: ut.h:77
M0_INTERNAL int m0_pools_setup(struct m0_pools_common *pc, const struct m0_fid *profile, struct m0_sm_group *sm_grp, struct m0_dtm *dtm)
Definition: pool.c:1810
static int io_req_fop_init(struct io_req_fop *fop, struct target_ioreq *ti, enum page_attr pattr)
Definition: file.c:4971
static struct m0_rpc_conn conn
Definition: file.c:97
struct m0_sm_ast irf_ast
static int io_req_fop_dgmode_read(struct io_req_fop *irfop)
Definition: file.c:6374
struct target_ioreq * irf_tioreq
Definition: sock.c:887
uint64_t ti_magic
M0_INTERNAL int m0_layout_instance_build(struct m0_layout *l, const struct m0_fid *fid, struct m0_layout_instance **out)
Definition: layout.c:1113
M0_INTERNAL void m0_rpc_bulk_buflist_empty(struct m0_rpc_bulk *rbulk)
Definition: bulk.c:279
bool s_cancelled
Definition: session.h:360
Definition: file.c:70
struct target_ioreq * dr_tioreq
static bool runast
Definition: file.c:96
#define m0_tl_endfor
Definition: tlist.h:700
struct m0_fid fid
Definition: di.c:46
static int pargrp_iomap_dgmode_recover(struct pargrp_iomap *map)
Definition: file.c:3040
M0_INTERNAL int m0_confc_root_open(struct m0_confc *confc, struct m0_conf_root **root)
Definition: helpers.c:219
Definition: sock.c:754
M0_INTERNAL void m0_sm_group_unlock(struct m0_sm_group *grp)
Definition: sm.c:96
M0_INTERNAL struct m0_fid * m0_reqh2profile(struct m0_reqh *reqh)
Definition: reqh.c:758
uint64_t irf_magic
M0_INTERNAL void m0t1fs_sb_fini(struct m0t1fs_sb *csb)
Definition: super.c:445
int i
Definition: dir.c:1033
void m0_fop_rpc_machine_set(struct m0_fop *fop, struct m0_rpc_machine *mach)
Definition: fop.c:352
M0_INTERNAL m0_bcount_t m0_rpc_session_get_max_item_payload_size(const struct m0_rpc_session *session)
Definition: session.c:775
enum page_attr db_flags
M0_INTERNAL int m0_indexvec_varr_alloc(struct m0_indexvec_varr *ivec, uint32_t len)
Definition: vec.c:1136
void m0t1fs_ha_fini(struct m0t1fs_sb *csb)
Definition: super.c:507
struct m0_rpc_machine * c_rpc_machine
Definition: conn.h:278
M0_INTERNAL uint32_t m0_layout_enum_find(const struct m0_layout_enum *e, const struct m0_fid *gfid, const struct m0_fid *target)
Definition: layout.c:1142
static void helpers_test(void)
Definition: file.c:748
static uint32_t rows_nr(struct m0_pdclust_layout *play)
Definition: file.c:691
M0_INTERNAL void m0t1fs_fs_unlock(struct m0t1fs_sb *csb)
Definition: super.c:112
int(* nxo_distribute)(struct nw_xfer_request *xfer)
uint64_t ti_parbytes
struct m0_conf_root * root
Definition: note.c:50
struct m0_layout_enum lle_base
Definition: linear_enum.h:69
M0_INTERNAL struct m0_fop_cob_rw_reply * io_rw_rep_get(struct m0_fop *fop)
Definition: io_fops.c:1056
struct m0_fop if_fop
Definition: io_fops.h:174
void * b_addr
Definition: buf.h:231
M0_INTERNAL int m0__pools_common_init(struct m0_pools_common *pc, struct m0_rpc_machine *rmach, struct m0_conf_root *root)
Definition: pool.c:1437
Definition: cnt.h:36
int(* pi_populate)(struct pargrp_iomap *iomap, struct m0_ivec_varr_cursor *cursor)
M0_INTERNAL int m0_pool_version_get(struct m0_pools_common *pc, const struct m0_fid *pool, struct m0_pool_version **pv)
Definition: pool.c:662
M0_INTERNAL struct m0_confc * m0_reqh2confc(struct m0_reqh *reqh)
Definition: reqh.c:753
#define M0_FID_TINIT(type, container, key)
Definition: fid.h:90
#define m0_tl_teardown(name, head, obj)
Definition: tlist.h:708
M0_INTERNAL void m0_fi_disable(const char *fp_func, const char *fp_tag)
Definition: finject.c:485
struct m0_striped_layout pl_base
Definition: pdclust.h:148
enum pargrp_iomap_state pi_state
static void m0_fi_enable(const char *func, const char *tag)
Definition: finject.h:276
M0_INTERNAL int m0_reqh_conf_setup(struct m0_reqh *reqh, struct m0_confc_args *args)
Definition: reqh.c:729
#define m0_free0(pptr)
Definition: memory.h:77
static uint64_t page_nr(m0_bcount_t size)
Definition: file.c:492
M0_INTERNAL size_t m0_io_fop_size_get(struct m0_fop *fop)
Definition: io_fops.c:1589
struct m0_net_transfer_mc rm_tm
Definition: rpc_machine.h:88
m0_bcount_t b_nob
Definition: buf.h:38
M0_INTERNAL void m0_chan_init(struct m0_chan *chan, struct m0_mutex *ch_guard)
Definition: chan.c:96
struct m0_ut_suite file_io_ut
Definition: file.c:1259
static uint64_t page_id(m0_bindex_t offset)
Definition: file.c:686
#define M0_ASSERT(cond)
struct m0_buf db_buf
static struct m0_confc * confc
Definition: file.c:94
struct nw_xfer_request ir_nwxfer
static void target_ioreq_test(void)
Definition: file.c:864
static struct m0_pdclust_layout * pdlay
Definition: file.c:88
struct m0_fid pver
Definition: idx_dix.c:74
M0_INTERNAL struct m0t1fs_inode * m0t1fs_file_to_m0inode(const struct file *file)
Definition: file.c:444
static void data_buf_dealloc_fini(struct data_buf *buf)
Definition: file.c:4838
static struct m0_pdclust_instance * pdlayout_instance(const struct m0_layout_instance *li)
Definition: file.c:504
const struct nw_xfer_ops * nxr_ops
uint64_t ta_frame
Definition: pdclust.h:254
struct m0_sm ir_sm
static void m0_atomic64_dec(struct m0_atomic64 *a)
static void dgmode_rwvec_dealloc_fini(struct dgmode_rwvec *dg)
Definition: file.c:3335
void(* iro_iomaps_destroy)(struct io_request *req)
static char local_conf[]
Definition: file.c:115
M0_INTERNAL void m0_pools_service_ctx_destroy(struct m0_pools_common *pc)
Definition: pool.c:1617
struct m0_fop * m0_fop_get(struct m0_fop *fop)
Definition: fop.c:162
static uint64_t layout_unit_size(const struct m0_pdclust_layout *play)
Definition: file.c:525
struct m0_rpc_item * ri_reply
Definition: item.h:163
Definition: file.c:78
int m0t1fs_ha_init(struct m0t1fs_sb *csb, const char *ha_addr)
Definition: super.c:478
static int m0_rconfc_start_sync(struct m0_rconfc *rconfc)
Definition: rconfc.h:502
uint64_t f_container
Definition: fid.h:39
struct m0_0vec bb_zerovec
Definition: bulk.h:179
int(* pi_dgmode_postprocess)(struct pargrp_iomap *map)
static struct m0t1fs_inode ci
Definition: file.c:91
static void ast_thread_stop(struct m0t1fs_sb *csb)
Definition: file.c:188
Definition: reqh.h:94
Definition: file.c:64
uint32_t v_nr
Definition: vec.h:51
static struct super_block super_block
Definition: fsync.c:84
static bool pargrp_iomap_spans_seg(struct pargrp_iomap *map, m0_bindex_t index, m0_bcount_t count)
Definition: file.c:1931
static void pargrp_src_addr(m0_bindex_t index, const struct io_request *req, const struct target_ioreq *tio_req, struct m0_pdclust_src_addr *src)
Definition: file.c:621
M0_INTERNAL void m0_fd_bwd_map(struct m0_pdclust_instance *pi, const struct m0_pdclust_tgt_addr *tgt, struct m0_pdclust_src_addr *src)
Definition: fd.c:959
static int pargrp_iomap_paritybufs_alloc(struct pargrp_iomap *map)
Definition: file.c:2275
struct m0_htable nxr_tioreqs_hash
static void target_ioreq_fini(struct target_ioreq *ti)
Definition: file.c:4708
struct m0_rpc_session * ti_session
struct m0_indexvec_varr ir_ivv
struct m0_tl ti_iofops
static void ast_thread(struct m0t1fs_sb *csb)
Definition: file.c:178
M0_INTERNAL void m0t1fs_fs_lock(struct m0t1fs_sb *csb)
Definition: super.c:105
struct m0_indexvec_varr dr_ivec_varr
static void page_pos_get(struct pargrp_iomap *map, m0_bindex_t index, uint32_t *row, uint32_t *col)
Definition: file.c:725
M0_INTERNAL void m0_indexvec_varr_free(struct m0_indexvec_varr *ivec)
Definition: vec.c:1160
int m0t1fs_rpc_init(struct m0t1fs_sb *csb, const char *ep)
Definition: super.c:631
static uint64_t data_size(const struct m0_pdclust_layout *play)
Definition: file.c:550
static const struct m0_rpc_item_ops io_item_ops
Definition: file.c:810
struct m0_sm s_sm
Definition: session.h:325
M0_INTERNAL void m0_chan_signal_lock(struct m0_chan *chan)
Definition: chan.c:165
M0_TL_DESCR_DECLARE(rpcbulk, M0_EXTERN)
const struct target_ioreq_ops * ti_ops
static struct pargrp_iomap map
Definition: file.c:99
static void irfop_fini(struct io_req_fop *irfop)
Definition: file.c:5044
struct m0_rpc_machine * ca_rmach
Definition: helpers.h:40
struct m0_uint128 pa_seed
Definition: pdclust.h:121
static uint64_t round_down(uint64_t val, uint64_t size)
Definition: file.c:697
static int nw_xfer_io_distribute(struct nw_xfer_request *xfer)
Definition: file.c:3394
M0_INTERNAL void m0_rconfc_fini(struct m0_rconfc *rconfc)
Definition: rconfc.c:3009
struct m0_bufvec z_bvec
Definition: vec.h:514
static uint32_t layout_n(const struct m0_pdclust_layout *play)
Definition: file.c:515
M0_INTERNAL struct m0_layout * m0_pdl_to_layout(struct m0_pdclust_layout *pl)
Definition: pdclust.c:393
const struct iovec * ir_iovec
static void m0_fi_enable_off_n_on_m(const char *func, const char *tag, uint32_t n, uint32_t m)
Definition: finject.h:346
static struct m0_pdclust_layout * pdlayout_get(const struct io_request *req)
Definition: file.c:510
static int64_t m0_atomic64_get(const struct m0_atomic64 *a)
static int pargrp_iomap_parity_recalc(struct pargrp_iomap *map)
Definition: file.c:1502
M0_INTERNAL bool m0_fid_eq(const struct m0_fid *fid0, const struct m0_fid *fid1)
Definition: fid.c:164
uint64_t sa_unit
Definition: pdclust.h:243
int m0t1fs_rm_service_start(struct m0t1fs_sb *csb)
Definition: super.c:542
m0t1fs_file_lock_init(ci, csb)
M0_INTERNAL void m0_ivec_varr_cursor_init(struct m0_ivec_varr_cursor *cur, struct m0_indexvec_varr *ivec)
Definition: vec.c:1183
M0_INTERNAL size_t m0_rpc_bulk_buf_length(struct m0_rpc_bulk *rbulk)
Definition: bulk.c:550
const char * ts_name
Definition: ut.h:99
uint64_t ti_databytes
static int pargrp_iomap_readold_auxbuf_alloc(struct pargrp_iomap *map)
Definition: file.c:2099
struct m0_pdclust_tgt_addr tgt
Definition: fd.c:110
static struct super_block sb
Definition: file.c:85
struct m0_reqh reqh
Definition: rm_foms.c:48
static void io_bottom_half(struct m0_sm_group *grp, struct m0_sm_ast *ast)
Definition: file.c:6025
static int pargrp_iomap_seg_process(struct pargrp_iomap *map, uint64_t seg, bool rmw)
Definition: file.c:1965
static void nw_xfer_request_fini(struct nw_xfer_request *xfer)
Definition: file.c:1234
Definition: fid.h:38
uint64_t f_key
Definition: fid.h:40
struct m0_fid ti_fid
static uint64_t indexvec_varr_count(struct m0_indexvec_varr *varr)
Definition: file.c:535
static struct m0_layout_instance * layout_instance(const struct io_request *req)
Definition: file.c:498
static int pargrp_iomap_init(struct pargrp_iomap *map, struct io_request *req, uint64_t grpid)
Definition: file.c:1795
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
const struct m0_rpc_item_ops * ri_ops
Definition: item.h:149
static int file_io_ut_fini(void)
Definition: file.c:335
M0_INTERNAL struct m0_layout_enum * m0_layout_instance_to_enum(const struct m0_layout_instance *li)
Definition: layout.c:1132
M0_INTERNAL int m0_pools_service_ctx_create(struct m0_pools_common *pc)
Definition: pool.c:1535
enum nw_xfer_state nxr_state
struct m0_indexvec_varr ti_ivv
static int target_ioreq_init(struct target_ioreq *ti, struct nw_xfer_request *xfer, const struct m0_fid *cobfid, uint64_t ta_obj, struct m0_rpc_session *session, uint64_t size)
Definition: file.c:4631
void m0t1fs_fid_alloc(struct m0t1fs_sb *csb, struct m0_fid *out)
Definition: dir.c:252
static void target_ioreq_seg_add(struct target_ioreq *ti, const struct m0_pdclust_src_addr *src, const struct m0_pdclust_tgt_addr *tgt, m0_bindex_t gob_offset, m0_bcount_t count, struct pargrp_iomap *map)
Definition: file.c:4857
static int pargrp_iomap_populate(struct pargrp_iomap *map, struct m0_ivec_varr_cursor *cursor)
Definition: file.c:2506
static void nw_xfer_request_init(struct nw_xfer_request *xfer)
Definition: file.c:1207
m0_bcount_t size
Definition: di.c:39
static uint64_t parity_units_page_nr(const struct m0_pdclust_layout *play)
Definition: file.c:530
static int start(struct m0_fom *fom)
Definition: trigger_fom.c:321
#define V_COUNT(ivec, i)
Definition: file.c:397
struct data_buf *** pi_databufs
struct m0_layout sl_base
Definition: layout.h:574
void m0_fop_put_lock(struct m0_fop *fop)
Definition: fop.c:199
static struct m0_layout_linear_attr llattr
Definition: file.c:90
M0_INTERNAL bool m0_rpc_bulk_is_empty(struct m0_rpc_bulk *rbulk)
Definition: bulk.c:539
static void ioreq_pgiomap_find(struct io_request *req, uint64_t grpid, uint64_t *cursor, struct pargrp_iomap **out)
Definition: file.c:1675
const struct io_request_ops * ir_ops
struct m0_atomic64 nxr_iofop_nr
void fsync_test(void)
Definition: fsync.c:630
M0_INTERNAL int m0_pdclust_build(struct m0_layout_domain *dom, uint64_t lid, const struct m0_pdclust_attr *attr, struct m0_layout_enum *le, struct m0_pdclust_layout **out)
Definition: pdclust.c:305
struct m0_io_fop irf_iofop
M0_INTERNAL void m0_sm_group_lock(struct m0_sm_group *grp)
Definition: sm.c:83
struct pargrp_iomap ** ir_iomaps
static int target_ioreq_iofops_prepare(struct target_ioreq *ti, enum page_attr filter)
Definition: file.c:6566
M0_INTERNAL void m0_confc_close(struct m0_conf_obj *obj)
Definition: confc.c:921
static void skip(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:465
struct m0_rconfc rh_rconfc
Definition: reqh.h:166
M0_INTERNAL void m0_layout_instance_fini(struct m0_layout_instance *li)
Definition: layout.c:1123
struct m0_tl rb_buflist
Definition: bulk.h:256
#define V_SEG_NR(ivec)
Definition: file.c:398
struct nw_xfer_request * ti_nwxfer
static int dummy_readrest(struct pargrp_iomap *map)
Definition: file.c:554
M0_INTERNAL void m0_layout_put(struct m0_layout *l)
Definition: layout.c:893
M0_INTERNAL void m0_fid_convert_gob2cob(const struct m0_fid *gob_fid, struct m0_fid *cob_fid, uint32_t device_id)
Definition: fid_convert.c:55
M0_INTERNAL int m0_pool_versions_setup(struct m0_pools_common *pc)
Definition: pool.c:1640
static uint64_t pargrp_id_find(m0_bindex_t index, const struct io_request *req, const struct io_req_fop *ir_fop)
Definition: file.c:638
M0_INTERNAL void * m0_alloc_aligned(size_t size, unsigned shift)
Definition: memory.c:168
M0_INTERNAL void m0_pool_versions_destroy(struct m0_pools_common *pc)
Definition: pool.c:1876
static void pargrp_iomap_test(void)
Definition: file.c:559
M0_INTERNAL void m0_fd_fwd_map(struct m0_pdclust_instance *pi, const struct m0_pdclust_src_addr *src, struct m0_pdclust_tgt_addr *tgt)
Definition: fd.c:838
static void ioreq_iomaps_destroy(struct io_request *req)
Definition: file.c:3255
M0_INTERNAL void m0_sm_asts_run(struct m0_sm_group *grp)
Definition: sm.c:150
static struct m0_dtm_oper_descr reply
Definition: transmit.c:94
void m0t1fs_rpc_fini(struct m0t1fs_sb *csb)
Definition: super.c:703
const char * ca_profile
Definition: helpers.h:34
#define m0_tl_for(name, head, obj)
Definition: tlist.h:695
void m0_free(void *data)
Definition: memory.c:146
Definition: file.c:73
static struct m0_pdclust_attr pdattr
Definition: file.c:87
#define m0_htable_endfor
Definition: hash.h:491
struct m0_rpc_item f_item
Definition: fop.h:83
uint32_t sm_state
Definition: sm.h:307
struct m0_pdclust_src_addr src
Definition: fd.c:108
struct dgmode_rwvec * ti_dgvec
struct file * ir_file
int32_t rc
Definition: trigger_fop.h:47
#define ARRAY_SIZE(a)
Definition: misc.h:45
const struct pargrp_iomap_ops * pi_ops
struct m0_rpc_conn * s_conn
Definition: session.h:312
#define M0_UT_ASSERT(a)
Definition: ut.h:46
static void io_request_fini(struct io_request *req)
Definition: file.c:4404
Definition: fop.h:79
static const struct m0_fid * file_to_fid(const struct file *file)
Definition: file.c:477
static int pargrp_iomap_readrest(struct pargrp_iomap *map)
Definition: file.c:2203
enum io_req_type ir_type
static void m0_atomic64_set(struct m0_atomic64 *a, int64_t num)
static uint64_t pargrp_iomap_fullpages_count(struct pargrp_iomap *map)
Definition: file.c:2051
uint64_t db_magic
static struct data_buf * data_buf_alloc_init(enum page_attr pattr)
Definition: file.c:4801
struct m0_fop * m0_fop_alloc(struct m0_fop_type *fopt, void *data, struct m0_rpc_machine *mach)
Definition: fop.c:96
static int pargrp_iomap_databuf_alloc(struct pargrp_iomap *map, uint32_t row, uint32_t col)
Definition: file.c:1951
static struct m0_layout_linear_enum * llenum
Definition: file.c:89
M0_INTERNAL void io_bob_tlists_init(void)
Definition: file.c:790
M0_INTERNAL void m0_pools_destroy(struct m0_pools_common *pc)
Definition: pool.c:1887