Motr  M0
dir.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016-2020 Seagate Technology LLC and/or its Affiliates
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * For any questions about this software or licensing,
17  * please email opensource@seagate.com or cortx-questions@seagate.com.
18  *
19  */
20 
21 
28 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_CONF
29 #include "lib/trace.h"
30 
31 #include "conf/obj.h"
32 #include "conf/obj_ops.h" /* m0_conf_obj_invariant */
33 #include "conf/cache.h" /* m0_conf_cache_lookup */
34 #include "motr/magic.h" /* M0_CONF_OBJ_MAGIC, M0_CONF_DIR_MAGIC */
35 #include "lib/errno.h" /* ENOMEM */
36 
37 M0_TL_DESCR_DEFINE(m0_conf_dir, "m0_conf_dir::cd_items", M0_INTERNAL,
38  struct m0_conf_obj, co_dir_link, co_gen_magic,
40 M0_TL_DEFINE(m0_conf_dir, M0_INTERNAL, struct m0_conf_obj);
41 
42 M0_INTERNAL void
44 {
46  M0_PRE(m0_conf_obj_type(obj) == dir->cd_item_type);
47 
48  m0_conf_child_adopt(&dir->cd_obj, obj);
49  m0_conf_dir_tlist_add_tail(&dir->cd_items, obj);
50 }
51 
52 M0_INTERNAL void
54 {
56  M0_PRE(m0_conf_obj_type(obj) == dir->cd_item_type);
57  M0_PRE(_0C(obj->co_cache == dir->cd_obj.co_cache) &&
58  _0C(obj->co_parent == &dir->cd_obj));
59 
60  m0_conf_dir_tlist_del(obj);
61 }
62 
63 M0_INTERNAL bool m0_conf_dir_elems_match(const struct m0_conf_dir *dir,
64  const struct m0_fid_arr *fids)
65 {
66  int i = 0;
67 
68  return m0_conf_dir_tlist_length(&dir->cd_items) == fids->af_count &&
69  m0_tl_forall(m0_conf_dir, obj, &dir->cd_items,
70  m0_fid_eq(&fids->af_elems[i++], &obj->co_id));
71 }
72 
80 static void conf_dir_id_build(struct m0_fid *out, const struct m0_fid *parent,
81  const struct m0_conf_obj_type *children_type)
82 {
83  *out = *parent;
85  /* clear the next 16 bits after fid type... */
86  out->f_container &= ~0x00ffff0000000000ULL;
87  /* ... place parent type there... */
88  out->f_container |= ((uint64_t)m0_fid_type_getfid(parent)->ft_id) << 48;
89  /* ... and place children type there. */
90  out->f_container |= ((uint64_t)children_type->cot_ftype.ft_id) << 40;
91 }
92 
93 static int conf_dir_new(struct m0_conf_cache *cache,
94  const struct m0_fid *parent,
95  const struct m0_fid *relfid,
96  const struct m0_conf_obj_type *children_type,
97  const struct m0_fid_arr *children_ids,
98  struct m0_conf_dir **out)
99 {
100  struct m0_fid dir_id;
101  struct m0_conf_obj *dir_obj;
102  struct m0_conf_dir *dir;
103  struct m0_conf_obj *child;
104  uint32_t i;
105  int rc;
106 
108  M0_PRE(children_ids == NULL ||
109  m0_forall(i, children_ids->af_count,
110  m0_conf_fid_type(&children_ids->af_elems[i]) ==
111  children_type));
112  M0_PRE(*out == NULL);
113 
114  conf_dir_id_build(&dir_id, parent, children_type);
116 
117  dir_obj = m0_conf_obj_create(&dir_id, cache);
118  if (dir_obj == NULL)
119  return M0_ERR(-ENOMEM);
120  dir = M0_CONF_CAST(dir_obj, m0_conf_dir);
121 
122  dir->cd_item_type = children_type;
123  dir->cd_relfid = *relfid;
124 
125  if (children_ids != NULL) {
126  for (i = 0; i < children_ids->af_count; ++i) {
127  rc = m0_conf_obj_find(cache, &children_ids->af_elems[i],
128  &child);
129  if (rc != 0)
130  goto err;
131  if (m0_conf_dir_tlist_contains(&dir->cd_items, child)) {
132  rc = M0_ERR_INFO(
133  -EEXIST, FID_F": Directory element "
134  FID_F" is not unique", FID_P(parent),
135  FID_P(&child->co_id));
136  goto err;
137  }
138  /* Link the directory and its element together. */
139  m0_conf_dir_add(dir, child);
140  }
141  }
142  rc = m0_conf_cache_add(cache, dir_obj);
143  if (rc == 0) {
144  dir_obj->co_status = M0_CS_READY;
145  *out = dir;
146  return M0_RC(0);
147  }
148 err:
149  if (children_ids != NULL) {
150  /* Restore consistency. */
151  m0_tl_teardown(m0_conf_dir, &dir->cd_items, child) {
152  m0_conf_cache_del(cache, child);
153  }
154  }
155  m0_conf_obj_delete(dir_obj);
156  return M0_ERR(rc);
157 }
158 
159 M0_INTERNAL int m0_conf_dir_new(struct m0_conf_obj *parent,
160  const struct m0_fid *relfid,
161  const struct m0_conf_obj_type *children_type,
162  const struct m0_fid_arr *children_ids,
163  struct m0_conf_dir **out)
164 {
165  int rc;
166 
167  rc = conf_dir_new(parent->co_cache, &parent->co_id, relfid,
168  children_type, children_ids, out);
169  if (rc == 0)
170  m0_conf_child_adopt(parent, &(*out)->cd_obj);
171  return M0_RC(rc);
172 }
173 
174 #undef M0_TRACE_SUBSYSTEM
175 
const struct m0_conf_obj_type * m0_conf_obj_type(const struct m0_conf_obj *obj)
Definition: obj.c:363
struct m0_fid co_id
Definition: obj.h:208
Definition: beck.c:235
#define M0_PRE(cond)
M0_TL_DEFINE(m0_conf_dir, M0_INTERNAL, struct m0_conf_obj)
#define NULL
Definition: misc.h:38
const struct m0_fid_type M0_CONF_RELFID_TYPE
Definition: dir.c:215
M0_INTERNAL struct m0_conf_obj * m0_conf_cache_lookup(const struct m0_conf_cache *cache, const struct m0_fid *id)
Definition: cache.c:106
M0_INTERNAL void m0_conf_dir_add(struct m0_conf_dir *dir, struct m0_conf_obj *obj)
Definition: dir.c:43
const struct m0_conf_obj_type * m0_conf_fid_type(const struct m0_fid *fid)
Definition: obj.c:368
uint8_t ft_id
Definition: fid.h:101
static int conf_dir_new(struct m0_conf_cache *cache, const struct m0_fid *parent, const struct m0_fid *relfid, const struct m0_conf_obj_type *children_type, const struct m0_fid_arr *children_ids, struct m0_conf_dir **out)
Definition: dir.c:93
struct m0_fid * af_elems
Definition: fid.h:45
struct m0_conf_cache * co_cache
Definition: obj.h:251
M0_TL_DESCR_DEFINE(m0_conf_dir, "m0_conf_dir::cd_items", M0_INTERNAL, struct m0_conf_obj, co_dir_link, co_gen_magic, M0_CONF_OBJ_MAGIC, M0_CONF_DIR_MAGIC)
static struct foo * obj
Definition: tlist.c:302
return M0_RC(rc)
M0_INTERNAL int m0_conf_dir_new(struct m0_conf_obj *parent, const struct m0_fid *relfid, const struct m0_conf_obj_type *children_type, const struct m0_fid_arr *children_ids, struct m0_conf_dir **out)
Definition: dir.c:159
int i
Definition: dir.c:1033
#define M0_ERR_INFO(rc, fmt,...)
Definition: trace.h:215
return M0_ERR(-EOPNOTSUPP)
M0_INTERNAL void m0_conf_child_adopt(struct m0_conf_obj *parent, struct m0_conf_obj *child)
Definition: obj.c:425
#define m0_tl_teardown(name, head, obj)
Definition: tlist.h:708
int rc
Definition: dir.c:333
const struct m0_fid_type cot_ftype
Definition: obj.h:314
#define M0_ASSERT(cond)
M0_INTERNAL const struct m0_fid_type * m0_fid_type_getfid(const struct m0_fid *fid)
Definition: fid.c:76
Definition: fid.h:43
M0_INTERNAL int m0_conf_obj_find(struct m0_conf_cache *cache, const struct m0_fid *id, struct m0_conf_obj **out)
Definition: obj_ops.c:136
static const struct m0_fid fids[]
Definition: diter.c:76
#define M0_CONF_CAST(ptr, type)
Definition: obj.h:780
M0_INTERNAL int m0_conf_cache_add(struct m0_conf_cache *cache, struct m0_conf_obj *obj)
Definition: cache.c:79
#define FID_P(f)
Definition: fid.h:77
static void conf_dir_id_build(struct m0_fid *out, const struct m0_fid *parent, const struct m0_conf_obj_type *children_type)
Definition: dir.c:80
M0_INTERNAL bool m0_fid_eq(const struct m0_fid *fid0, const struct m0_fid *fid1)
Definition: fid.c:164
#define m0_forall(var, nr,...)
Definition: misc.h:112
M0_INTERNAL struct m0_conf_obj * m0_conf_obj_create(const struct m0_fid *id, struct m0_conf_cache *cache)
Definition: obj_ops.c:80
Definition: fid.h:38
M0_INTERNAL void m0_conf_cache_del(const struct m0_conf_cache *cache, struct m0_conf_obj *obj)
Definition: cache.c:124
M0_INTERNAL void m0_conf_obj_delete(struct m0_conf_obj *obj)
Definition: obj_ops.c:167
#define _0C(exp)
Definition: assert.h:311
enum m0_conf_status co_status
Definition: obj.h:210
struct inode * dir
Definition: dir.c:1028
M0_INTERNAL void m0_conf_dir_del(struct m0_conf_dir *dir, struct m0_conf_obj *obj)
Definition: dir.c:53
#define out(...)
Definition: gen.c:41
const struct m0_conf_obj_type M0_CONF_DIR_TYPE
Definition: dir.c:206
M0_INTERNAL bool m0_conf_dir_elems_match(const struct m0_conf_dir *dir, const struct m0_fid_arr *fids)
Definition: dir.c:63
M0_INTERNAL bool m0_conf_obj_invariant(const struct m0_conf_obj *obj)
Definition: obj_ops.c:52
uint32_t af_count
Definition: fid.h:44
#define FID_F
Definition: fid.h:75
#define m0_tl_forall(name, var, head,...)
Definition: tlist.h:735
M0_INTERNAL void m0_fid_tassume(struct m0_fid *fid, const struct m0_fid_type *ft)
Definition: fid.c:146