Motr  M0
file.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2013-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 #undef M0_TRACE_SUBSYSTEM
24 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_FILE
25 
26 #include "lib/trace.h"
27 #include "lib/arith.h"
28 #include "fid/fid_xc.h"
29 #include "xcode/xcode.h"
30 #include "rm/rm.h"
31 #include "file/file.h"
32 
149 /* Forward Declarations */
150 static bool file_lock_equal(const struct m0_rm_resource *resource0,
151  const struct m0_rm_resource *resource1);
152 static m0_bcount_t file_lock_len(const struct m0_rm_resource *resource);
153 static int file_lock_encode(struct m0_bufvec_cursor *cur,
154  const struct m0_rm_resource *resource);
155 static int file_lock_decode(struct m0_bufvec_cursor *cur,
156  struct m0_rm_resource **resource);
157 static void file_lock_credit_init(struct m0_rm_resource *resource,
158  struct m0_rm_credit *credit);
159 static void file_lock_resource_free(struct m0_rm_resource *resource);
160 
161 static void file_lock_incoming_complete(struct m0_rm_incoming *in, int32_t rc);
162 static void file_lock_incoming_conflict(struct m0_rm_incoming *in);
163 
164 static bool file_lock_cr_intersects(const struct m0_rm_credit *self,
165  const struct m0_rm_credit *c1);
166 static m0_bcount_t file_lock_cr_len(const struct m0_rm_credit *c0);
167 
168 static int file_lock_cr_join(struct m0_rm_credit *self,
169  const struct m0_rm_credit *c1);
170 static int file_lock_cr_disjoin(struct m0_rm_credit *self,
171  const struct m0_rm_credit *c1,
172  struct m0_rm_credit *intersection);
173 static int file_lock_cr_copy(struct m0_rm_credit *dest,
174  const struct m0_rm_credit *self);
175 static int file_lock_cr_diff(struct m0_rm_credit *self,
176  const struct m0_rm_credit *c1);
177 static bool file_lock_cr_conflicts(const struct m0_rm_credit *self,
178  const struct m0_rm_credit *c1);
179 static bool file_lock_cr_is_subset(const struct m0_rm_credit *self,
180  const struct m0_rm_credit *c1);
181 static int file_lock_cr_encode(struct m0_rm_credit *self,
182  struct m0_bufvec_cursor *cur);
183 static int file_lock_cr_decode(struct m0_rm_credit *self,
184  struct m0_bufvec_cursor *cur);
185 static void file_lock_cr_free(struct m0_rm_credit *self);
186 static void file_lock_cr_initial_capital(struct m0_rm_credit *self);
187 
190  .rto_len = file_lock_len,
191  .rto_decode = file_lock_decode,
192  .rto_encode = file_lock_encode,
193 };
194 
197  .rop_resource_free = file_lock_resource_free,
198 };
199 
202  .cro_join = file_lock_cr_join,
203  .cro_copy = file_lock_cr_copy,
204  .cro_diff = file_lock_cr_diff,
205  .cro_free = file_lock_cr_free,
206  .cro_encode = file_lock_cr_encode,
207  .cro_decode = file_lock_cr_decode,
208  .cro_len = file_lock_cr_len,
209  .cro_is_subset = file_lock_cr_is_subset,
210  .cro_disjoin = file_lock_cr_disjoin,
211  .cro_conflicts = file_lock_cr_conflicts,
212  .cro_initial_capital = file_lock_cr_initial_capital,
213 };
214 
217  .rio_conflict = file_lock_incoming_conflict
218 };
219 
220 #define R_F(resource) container_of(resource, struct m0_file, fi_res)
221 
223 static bool file_lock_equal(const struct m0_rm_resource *resource0,
224  const struct m0_rm_resource *resource1)
225 {
226  struct m0_file *file0;
227  struct m0_file *file1;
228 
229  M0_PRE(resource0 != NULL && resource1 != NULL);
230 
231  file0 = R_F(resource0);
232  file1 = R_F(resource1);
233 
234  return m0_fid_eq(file0->fi_fid, file1->fi_fid);
235 }
236 
237 static m0_bcount_t file_lock_len(const struct m0_rm_resource *resource)
238 {
239  struct m0_file *fl;
240  struct m0_xcode_obj fidobj;
241  struct m0_xcode_ctx ctx;
242  static m0_bcount_t flock_len;
243 
244  M0_ASSERT(resource != NULL);
245 
246  if (flock_len == 0) {
247  fl = R_F(resource);
248  fidobj.xo_type = m0_fid_xc;
249  fidobj.xo_ptr = (void *)fl->fi_fid;
250  m0_xcode_ctx_init(&ctx, &fidobj);
251  flock_len = m0_xcode_length(&ctx);
252  M0_ASSERT(flock_len > 0);
253  }
254 
255  return flock_len;
256 }
257 
258 static int file_lock_encdec(struct m0_file *file,
259  struct m0_bufvec_cursor *cur,
260  enum m0_xcode_what what)
261 {
262  int rc;
263  struct m0_xcode_obj xo = M0_XCODE_OBJ(m0_fid_xc, (void *)file->fi_fid);
264 
265  M0_ENTRY();
266  M0_ASSERT(cur != NULL);
267 
268  rc = m0_xcode_encdec(&xo, cur, what);
269  if (rc == 0 && file->fi_fid == NULL)
270  file->fi_fid = xo.xo_ptr;
276  return M0_RC(rc);
277 }
278 
281  const struct m0_rm_resource *resource)
282 {
283  struct m0_file *fl;
284  int rc;
285 
286  M0_ENTRY();
287  M0_PRE(resource != NULL);
288 
289  fl = R_F(resource);
291  return M0_RC(rc);
292 }
293 
296  struct m0_rm_resource **resource)
297 {
298  struct m0_file *fl;
299  int rc;
300 
301  M0_ENTRY();
302  M0_PRE(resource != NULL);
303 
304  M0_ALLOC_PTR(fl);
305  if (fl == NULL)
306  return M0_ERR(-ENOMEM);
308  if (rc == 0) {
309  fl->fi_res.r_ops = &file_lock_ops;
310  /*
311  * Other resource parameters are initialised by
312  * m0_rm_resource_add()
313  */
314  *resource = &fl->fi_res;
315  } else
316  m0_free(fl);
317  return M0_RC(rc);
318 }
319 
321 static void file_lock_credit_init(struct m0_rm_resource *resource,
322  struct m0_rm_credit *credit)
323 {
324  M0_ASSERT(credit != NULL);
325  credit->cr_datum = 0;
326  credit->cr_ops = &file_lock_credit_ops;
327 }
328 
329 static void file_lock_resource_free(struct m0_rm_resource *resource)
330 {
331  struct m0_file *fl;
332 
333  fl = R_F(resource);
334  m0_xcode_free_obj(&M0_XCODE_OBJ(m0_fid_xc, (void *)fl->fi_fid));
335  m0_free(fl);
336 }
337 
339 static void file_lock_incoming_complete(struct m0_rm_incoming *in, int32_t rc)
340 {
341  /* Do nothing */
342  return;
343 }
344 
347 {
348  /* Do nothing */
349  return;
350 }
351 
352 static bool file_lock_credit_invariant(const struct m0_rm_credit *file_cr)
353 {
354  return M0_IN(file_cr->cr_datum, (0, RM_FILE_LOCK));
355 }
356 
357 static bool file_lock_cr_intersects(const struct m0_rm_credit *self,
358  const struct m0_rm_credit *c1)
359 {
360  M0_ASSERT(c1 != NULL);
363  return self->cr_datum == c1->cr_datum;
364 }
365 
366 static m0_bcount_t file_lock_cr_len(const struct m0_rm_credit *c0)
367 {
368  struct m0_xcode_obj datumobj;
369  struct m0_xcode_ctx ctx;
370 
371  M0_ASSERT(c0 != NULL);
373 
374  datumobj.xo_type = &M0_XT_U64;
375  datumobj.xo_ptr = (void *)&c0->cr_datum;
376  m0_xcode_ctx_init(&ctx, &datumobj);
377  return m0_xcode_length(&ctx);
378 }
379 
380 static int file_lock_cr_join(struct m0_rm_credit *self,
381  const struct m0_rm_credit *c1)
382 {
383  return 0;
384 }
385 
386 static int file_lock_cr_disjoin(struct m0_rm_credit *self,
387  const struct m0_rm_credit *c1,
388  struct m0_rm_credit *intersection)
389 {
390  return M0_ERR(-EPERM);
391 }
392 
394  const struct m0_rm_credit *self)
395 {
396  M0_ASSERT(dest != NULL);
398 
399  dest->cr_datum = self->cr_datum;
400  dest->cr_owner = self->cr_owner;
401  dest->cr_ops = self->cr_ops;
403  return 0;
404 }
405 
406 static int file_lock_cr_diff(struct m0_rm_credit *self,
407  const struct m0_rm_credit *c1)
408 {
409  M0_ASSERT(c1 != NULL);
412 
413  self->cr_datum = max64((int64_t)(self->cr_datum - c1->cr_datum), 0);
415  return 0;
416 }
417 
418 static bool file_lock_cr_conflicts(const struct m0_rm_credit *self,
419  const struct m0_rm_credit *c1)
420 {
421  M0_ASSERT(c1 != NULL);
424 
425  return self->cr_datum & c1->cr_datum;
426 }
427 
428 static bool file_lock_cr_is_subset(const struct m0_rm_credit *self,
429  const struct m0_rm_credit *c1)
430 {
433  return self->cr_datum <= c1->cr_datum;
434 }
435 
436 static int file_lock_cr_encdec(struct m0_rm_credit *self,
437  struct m0_bufvec_cursor *cur,
438  enum m0_xcode_what what)
439 {
440  M0_ENTRY();
441  M0_ASSERT(cur != NULL);
442 
444  &self->cr_datum),
445  cur, what));
446 }
447 
448 static int file_lock_cr_encode(struct m0_rm_credit *self,
449  struct m0_bufvec_cursor *cur)
450 {
452  return file_lock_cr_encdec(self, cur, M0_XCODE_ENCODE);
453 }
454 
455 static int file_lock_cr_decode(struct m0_rm_credit *self,
456  struct m0_bufvec_cursor *cur)
457 {
458  return file_lock_cr_encdec(self, cur, M0_XCODE_DECODE);
459 }
460 
461 static void file_lock_cr_free(struct m0_rm_credit *self)
462 {
463  self->cr_datum = 0;
464 }
465 
467 {
468  self->cr_datum = RM_FILE_LOCK;
469 }
470  /* end internal FileLockInternal */
472 
477 M0_INTERNAL void m0_file_init(struct m0_file *file,
478  const struct m0_fid *fid,
479  struct m0_rm_domain *dom,
480  enum m0_di_types di_type)
481 {
482  M0_PRE(file != NULL);
483  M0_PRE(fid != NULL);
484 
487  file->fi_fid = fid;
488  if (dom != NULL)
490  &file->fi_res);
491  if (M0_FI_ENABLED("skip_di_for_ut"))
493  else
494  file->fi_di_ops = m0_di_ops_get(di_type);
495 }
496 M0_EXPORTED(m0_file_init);
497 
498 M0_INTERNAL void m0_file_fini(struct m0_file *file)
499 {
501  file->fi_res.r_ops = NULL;
502  file->fi_di_ops = NULL;
503  file->fi_fid = NULL;
504 }
505 M0_EXPORTED(m0_file_fini);
506 
507 M0_INTERNAL void m0_file_owner_init(struct m0_rm_owner *owner,
508  const struct m0_uint128 *grp_id,
509  struct m0_file *file,
510  struct m0_rm_remote *creditor)
511 {
512  m0_rm_owner_init_rfid(owner, grp_id, &file->fi_res, creditor);
513 }
514 M0_EXPORTED(m0_file_owner_init);
515 
516 M0_INTERNAL void m0_file_owner_fini(struct m0_rm_owner *owner)
517 {
518  m0_rm_owner_fini(owner);
519 }
520 M0_EXPORTED(m0_file_owner_fini);
521 
522 M0_INTERNAL void m0_file_lock(struct m0_rm_owner *owner,
523  struct m0_rm_incoming *req)
524 {
525  M0_ENTRY();
526 /*
527  * @todo This API should be called before m0_file_lock is invoked to ensure that
528  * the rm incoming chan is initialised. The calling fom will listen on this chan
529  * for the file lock events.
530  */
533  req->rin_want.cr_datum = RM_FILE_LOCK;
534  req->rin_ops = &file_lock_incoming_ops;
536  M0_LEAVE();
537 }
538 M0_EXPORTED(m0_file_lock);
539 
540 M0_INTERNAL void m0_file_unlock(struct m0_rm_incoming *req)
541 {
542  M0_ENTRY();
545  M0_LEAVE();
546 }
547 M0_EXPORTED(m0_file_unlock);
548 
550  struct m0_rm_resource_type *flock_rt)
551 {
552  M0_ENTRY();
553 
554  flock_rt->rt_id = M0_RM_FLOCK_RT;
555  flock_rt->rt_ops = &file_lock_type_ops;
556  return M0_RC(m0_rm_type_register(dom, flock_rt));
557 }
558 M0_EXPORTED(m0_file_lock_type_register);
559 
560 M0_INTERNAL
562 {
563  M0_ENTRY();
564  m0_rm_type_deregister(flock_rt);
565  M0_LEAVE();
566 }
567 M0_EXPORTED(m0_file_lock_type_deregister);
568 
570  .ft_id = 'G',
571  .ft_name = "file fid"
572 };
573 
574 M0_INTERNAL int m0_file_mod_init(void)
575 {
577  return 0;
578 }
579 
580 M0_INTERNAL void m0_file_mod_fini(void)
581 {
583 }
584 
587 #undef M0_TRACE_SUBSYSTEM
588 
589 /*
590  * Local variables:
591  * c-indentation-style: "K&R"
592  * c-basic-offset: 8
593  * tab-width: 8
594  * fill-column: 79
595  * scroll-step: 1
596  * End:
597  */
const struct m0_rm_credit_ops * cr_ops
Definition: rm.h:502
static void file_lock_cr_free(struct m0_rm_credit *self)
Definition: file.c:461
static int file_lock_cr_copy(struct m0_rm_credit *dest, const struct m0_rm_credit *self)
Definition: file.c:393
M0_INTERNAL int m0_xcode_encdec(struct m0_xcode_obj *obj, struct m0_bufvec_cursor *cur, enum m0_xcode_what what)
Definition: xcode.c:416
static int file_lock_cr_join(struct m0_rm_credit *self, const struct m0_rm_credit *c1)
Definition: file.c:380
static m0_bcount_t file_lock_cr_len(const struct m0_rm_credit *c0)
Definition: file.c:366
static int file_lock_encode(struct m0_bufvec_cursor *cur, const struct m0_rm_resource *resource)
Definition: file.c:280
#define M0_PRE(cond)
const struct m0_xcode_type * xo_type
Definition: xcode.h:351
const struct m0_rm_credit_ops file_lock_credit_ops
Definition: file.c:200
uint64_t cr_datum
Definition: rm.h:514
#define NULL
Definition: misc.h:38
bool(* cro_intersects)(const struct m0_rm_credit *self, const struct m0_rm_credit *c1)
Definition: rm.h:579
static struct m0_rm_remote creditor
Definition: file.c:95
static struct buffer * cur(struct m0_addb2_mach *mach, m0_bcount_t space)
Definition: addb2.c:791
void(* rio_complete)(struct m0_rm_incoming *in, int32_t rc)
Definition: rm.h:1493
static struct io_request req
Definition: file.c:100
struct m0_file file
Definition: di.c:36
const struct m0_rm_resource_ops file_lock_ops
Definition: file.c:195
#define M0_LOG(level,...)
Definition: trace.h:167
M0_LEAVE()
static void file_lock_credit_init(struct m0_rm_resource *resource, struct m0_rm_credit *credit)
Definition: file.c:321
uint8_t ft_id
Definition: fid.h:101
const struct m0_fid * fi_fid
Definition: file.h:88
static bool file_lock_cr_intersects(const struct m0_rm_credit *self, const struct m0_rm_credit *c1)
Definition: file.c:357
static void file_lock_resource_free(struct m0_rm_resource *resource)
Definition: file.c:329
bool(* rto_eq)(const struct m0_rm_resource *resource0, const struct m0_rm_resource *resource1)
Definition: rm.h:454
static int file_lock_cr_decode(struct m0_rm_credit *self, struct m0_bufvec_cursor *cur)
Definition: file.c:455
const struct m0_fid_type m0_file_fid_type
Definition: file.c:569
M0_INTERNAL void m0_file_lock(struct m0_rm_owner *owner, struct m0_rm_incoming *req)
Definition: file.c:522
M0_INTERNAL void m0_xcode_free_obj(struct m0_xcode_obj *obj)
Definition: xcode.c:248
uint64_t m0_bcount_t
Definition: types.h:77
m0_xcode_what
Definition: xcode.h:647
M0_INTERNAL void m0_file_mod_fini(void)
Definition: file.c:580
#define R_F(resource)
Definition: file.c:220
struct m0_fid fid
Definition: di.c:46
M0_INTERNAL void m0_file_lock_type_deregister(struct m0_rm_resource_type *flock_rt)
Definition: file.c:561
return M0_RC(rc)
M0_INTERNAL int m0_xcode_length(struct m0_xcode_ctx *ctx)
Definition: xcode.c:390
const struct m0_rm_resource_ops * r_ops
Definition: rm.h:305
#define M0_ENTRY(...)
Definition: trace.h:170
M0_INTERNAL int m0_file_lock_type_register(struct m0_rm_domain *dom, struct m0_rm_resource_type *flock_rt)
Definition: file.c:549
m0_di_types
Definition: di.h:72
static int file_lock_encdec(struct m0_file *file, struct m0_bufvec_cursor *cur, enum m0_xcode_what what)
Definition: file.c:258
static int64_t max64(int64_t a, int64_t b)
Definition: arith.h:51
return M0_ERR(-EOPNOTSUPP)
M0_INTERNAL void m0_fid_type_register(const struct m0_fid_type *fidt)
Definition: fid.c:46
M0_INTERNAL void m0_rm_incoming_init(struct m0_rm_incoming *in, struct m0_rm_owner *owner, enum m0_rm_incoming_type type, enum m0_rm_incoming_policy policy, uint64_t flags)
Definition: rm.c:1060
#define M0_ASSERT(cond)
M0_INTERNAL void m0_rm_owner_fini(struct m0_rm_owner *owner)
Definition: rm.c:943
M0_INTERNAL void m0_rm_owner_init_rfid(struct m0_rm_owner *owner, const struct m0_uint128 *group, struct m0_rm_resource *res, struct m0_rm_remote *creditor)
Definition: rm.c:649
static int file_lock_cr_diff(struct m0_rm_credit *self, const struct m0_rm_credit *c1)
Definition: file.c:406
static struct m0_stob_domain * dom
Definition: storage.c:38
static void file_lock_incoming_complete(struct m0_rm_incoming *in, int32_t rc)
Definition: file.c:339
static int file_lock_cr_disjoin(struct m0_rm_credit *self, const struct m0_rm_credit *c1, struct m0_rm_credit *intersection)
Definition: file.c:386
M0_INTERNAL void m0_file_owner_init(struct m0_rm_owner *owner, const struct m0_uint128 *grp_id, struct m0_file *file, struct m0_rm_remote *creditor)
Definition: file.c:507
void(* rop_credit_init)(struct m0_rm_resource *resource, struct m0_rm_credit *credit)
Definition: rm.h:365
#define M0_POST(cond)
const struct m0_rm_incoming_ops file_lock_incoming_ops
Definition: file.c:215
static bool file_lock_credit_invariant(const struct m0_rm_credit *file_cr)
Definition: file.c:352
M0_INTERNAL void m0_fid_type_unregister(const struct m0_fid_type *fidt)
Definition: fid.c:55
M0_INTERNAL int m0_file_mod_init(void)
Definition: file.c:574
#define FID_P(f)
Definition: fid.h:77
static int file_lock_cr_encdec(struct m0_rm_credit *self, struct m0_bufvec_cursor *cur, enum m0_xcode_what what)
Definition: file.c:436
M0_INTERNAL bool m0_fid_eq(const struct m0_fid *fid0, const struct m0_fid *fid1)
Definition: fid.c:164
M0_INTERNAL void m0_rm_credit_put(struct m0_rm_incoming *in)
Definition: rm.c:1797
M0_INTERNAL void m0_rm_resource_add(struct m0_rm_resource_type *rtype, struct m0_rm_resource *res)
Definition: rm.c:337
M0_INTERNAL void m0_file_unlock(struct m0_rm_incoming *req)
Definition: file.c:540
#define M0_FI_ENABLED(tag)
Definition: finject.h:231
Definition: fid.h:38
M0_INTERNAL const struct m0_di_ops * m0_di_ops_get(enum m0_di_types di_type)
Definition: di.c:365
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
struct m0_rm_resource fi_res
Definition: file.h:90
static bool file_lock_cr_conflicts(const struct m0_rm_credit *self, const struct m0_rm_credit *c1)
Definition: file.c:418
M0_INTERNAL void m0_rm_incoming_fini(struct m0_rm_incoming *in)
Definition: rm.c:1099
const struct m0_rm_resource_type_ops * rt_ops
Definition: rm.h:388
M0_INTERNAL int m0_rm_type_register(struct m0_rm_domain *dom, struct m0_rm_resource_type *rt)
Definition: rm.c:252
void * xo_ptr
Definition: xcode.h:353
M0_INTERNAL void m0_file_fini(struct m0_file *file)
Definition: file.c:498
#define M0_XCODE_OBJ(type, ptr)
Definition: xcode.h:962
static int file_lock_decode(struct m0_bufvec_cursor *cur, struct m0_rm_resource **resource)
Definition: file.c:295
static m0_bcount_t file_lock_len(const struct m0_rm_resource *resource)
Definition: file.c:237
Definition: nucleus.c:42
M0_INTERNAL void m0_xcode_ctx_init(struct m0_xcode_ctx *ctx, const struct m0_xcode_obj *obj)
Definition: xcode.c:373
Definition: file.h:81
Definition: di.h:73
M0_INTERNAL void m0_file_owner_fini(struct m0_rm_owner *owner)
Definition: file.c:516
M0_INTERNAL void m0_rm_type_deregister(struct m0_rm_resource_type *rt)
Definition: rm.c:288
static void file_lock_cr_initial_capital(struct m0_rm_credit *self)
Definition: file.c:466
static bool file_lock_cr_is_subset(const struct m0_rm_credit *self, const struct m0_rm_credit *c1)
Definition: file.c:428
void m0_free(void *data)
Definition: memory.c:146
static bool file_lock_equal(const struct m0_rm_resource *resource0, const struct m0_rm_resource *resource1)
Definition: file.c:223
static int file_lock_cr_encode(struct m0_rm_credit *self, struct m0_bufvec_cursor *cur)
Definition: file.c:448
const struct m0_xcode_type M0_XT_U64
Definition: xcode.c:940
const struct m0_rm_resource_type_ops file_lock_type_ops
Definition: file.c:188
int32_t rc
Definition: trigger_fop.h:47
uint64_t rt_id
Definition: rm.h:403
M0_INTERNAL void m0_rm_resource_del(struct m0_rm_resource *res)
Definition: rm.c:361
M0_INTERNAL void m0_rm_credit_get(struct m0_rm_incoming *in)
Definition: rm.c:1758
const struct m0_di_ops * fi_di_ops
Definition: file.h:92
#define FID_F
Definition: fid.h:75
M0_INTERNAL void m0_file_init(struct m0_file *file, const struct m0_fid *fid, struct m0_rm_domain *dom, enum m0_di_types di_type)
Definition: file.c:477
Definition: rm.h:1156
static void file_lock_incoming_conflict(struct m0_rm_incoming *in)
Definition: file.c:346