Motr  M0
dir.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 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_CONF
24 #include "lib/trace.h"
25 
26 #include "conf/objs/common.h"
27 
28 static bool dir_check(const void *bob)
29 {
30  const struct m0_conf_dir *self = bob;
31  const struct m0_conf_obj *self_obj = &self->cd_obj;
32 
33  M0_PRE(m0_conf_obj_type(&self->cd_obj) == &M0_CONF_DIR_TYPE);
34 
35  return m0_conf_obj_is_stub(self_obj) ||
36  _0C(self_obj->co_parent != NULL);
37 }
38 
41 
42 static int dir_decode(struct m0_conf_obj *dest M0_UNUSED,
43  const struct m0_confx_obj *src M0_UNUSED)
44 {
45  M0_IMPOSSIBLE("m0_conf_dir is not supposed to be decoded");
46  return -1;
47 }
48 
50  const struct m0_conf_obj *src M0_UNUSED)
51 {
52  M0_IMPOSSIBLE("m0_conf_dir is not supposed to be encoded");
53  return -1;
54 }
55 
56 static bool dir_match(const struct m0_conf_obj *cached M0_UNUSED,
57  const struct m0_confx_obj *flat M0_UNUSED)
58 {
59  M0_IMPOSSIBLE("m0_conf_dir should not be compared with m0_confx_obj");
60  return false;
61 }
62 
63 static bool
64 belongs(const struct m0_conf_obj *entry, const struct m0_conf_dir *dir)
65 {
66  return m0_conf_obj_type(entry) == dir->cd_item_type &&
67  entry->co_parent == &dir->cd_obj;
68 }
69 
79 static bool
80 readdir_pre(const struct m0_conf_dir *dir, const struct m0_conf_obj *entry)
81 {
82  return _0C(dir->cd_obj.co_status == M0_CS_READY) &&
83  _0C(dir->cd_obj.co_nrefs > 0) &&
84  _0C(ergo(entry != NULL, m0_conf_obj_invariant(entry))) &&
85  _0C(ergo(entry != NULL, belongs(entry, dir))) &&
86  _0C(ergo(entry != NULL, entry->co_nrefs > 0));
87 }
88 
99 static bool readdir_post(int retval, const struct m0_conf_dir *dir,
100  const struct m0_conf_obj *entry)
101 {
102  return _0C(M0_IN(retval, (M0_CONF_DIREND, M0_CONF_DIRNEXT,
103  M0_CONF_DIRMISS))) &&
104  _0C((retval == M0_CONF_DIREND) == (entry == NULL)) &&
105  _0C(ergo(entry != NULL, m0_conf_obj_invariant(entry))) &&
106  _0C(ergo(entry != NULL, belongs(entry, dir))) &&
107  _0C(ergo(entry != NULL,
108  (retval == M0_CONF_DIRNEXT) == (entry->co_nrefs > 0)));
109 }
110 
111 static int dir_readdir(const struct m0_conf_obj *dir, struct m0_conf_obj **pptr)
112 {
113  struct m0_conf_obj *next;
114  int ret;
115  struct m0_conf_dir *d = M0_CONF_CAST(dir, m0_conf_dir);
116  struct m0_conf_obj *prev = *pptr;
117 
118  M0_ENTRY();
119  M0_PRE(readdir_pre(d, prev));
120 
121  if (prev == NULL) {
122  next = m0_conf_dir_tlist_head(&d->cd_items);
123  } else {
124  next = m0_conf_dir_tlist_next(&d->cd_items, prev);
125  m0_conf_obj_put(prev);
126  *pptr = NULL;
127  }
128 
129  if (next == NULL) {
130  ret = M0_CONF_DIREND;
131  } else if (next->co_status == M0_CS_READY) {
133  *pptr = next;
134  ret = M0_CONF_DIRNEXT;
135  } else {
136  *pptr = next; /* let the caller know which object is missing */
137  ret = M0_CONF_DIRMISS;
138  }
139 
140  M0_POST(readdir_post(ret, d, *pptr));
141  M0_LEAVE("retval=%d", ret);
142  return ret;
143 }
144 
145 static int dir_lookup(const struct m0_conf_obj *parent,
146  const struct m0_fid *name, struct m0_conf_obj **out)
147 {
148  struct m0_conf_dir *x = M0_CONF_CAST(parent, m0_conf_dir);
149  struct m0_conf_obj *obj;
150 
151  M0_PRE(parent->co_status == M0_CS_READY);
152 
153  obj = m0_tl_find(m0_conf_dir, item, &x->cd_items,
154  m0_fid_eq(&item->co_id, name));
155  if (obj == NULL)
156  return M0_ERR_INFO(-ENOENT, FID_F": No elem="FID_F" in dir="
157  FID_F, FID_P(&parent->co_parent->co_id),
158  FID_P(name), FID_P(&parent->co_id));
159  *out = obj;
161  return 0;
162 }
163 
164 static void dir_delete(struct m0_conf_obj *obj)
165 {
166  struct m0_conf_obj *item;
168 
169  m0_tl_teardown(m0_conf_dir, &x->cd_items, item) {
170  /* `item' is deleted by m0_conf_cache_fini(). */
171  }
172  m0_conf_dir_tlist_fini(&x->cd_items);
173  m0_conf_dir_bob_fini(x);
174  m0_free(x);
175 }
176 
177 static const struct m0_conf_obj_ops dir_ops = {
178  .coo_invariant = dir_invariant,
179  .coo_decode = dir_decode,
180  .coo_encode = dir_encode,
181  .coo_match = dir_match,
182  .coo_lookup = dir_lookup,
183  .coo_readdir = dir_readdir,
184  .coo_downlinks = NULL,
185  .coo_delete = dir_delete
186 };
187 
188 static struct m0_conf_obj *dir_create(void)
189 {
190  struct m0_conf_dir *x;
191  struct m0_conf_obj *ret;
192 
193  M0_ALLOC_PTR(x);
194  if (x == NULL)
195  return NULL;
196  m0_conf_dir_bob_init(x);
197 
198  /* Initialise concrete fields. */
199  m0_conf_dir_tlist_init(&x->cd_items);
200 
201  ret = &x->cd_obj;
202  ret->co_ops = &dir_ops;
203  return ret;
204 }
205 
207  .cot_ftype = {
208  .ft_id = M0_CONF__DIR_FT_ID,
209  .ft_name = "conf_dir"
210  },
211  .cot_create = &dir_create,
212  .cot_magic = M0_CONF_DIR_MAGIC
213 };
214 
216  .ft_id = '/',
217  .ft_name = "conf relation"
218 };
219 
220 #undef M0_TRACE_SUBSYSTEM
221 
222 /*
223  * Local variables:
224  * c-indentation-style: "K&R"
225  * c-basic-offset: 8
226  * tab-width: 8
227  * fill-column: 80
228  * scroll-step: 1
229  * End:
230  */
231 /*
232  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
233  */
const struct m0_conf_obj_type * m0_conf_obj_type(const struct m0_conf_obj *obj)
Definition: obj.c:363
static const struct m0_conf_obj_ops dir_ops
Definition: dir.c:177
struct m0_fid co_id
Definition: obj.h:208
#define M0_PRE(cond)
int const char * name
Definition: dir.c:325
#define NULL
Definition: misc.h:38
#define ergo(a, b)
Definition: misc.h:293
static bool x
Definition: sm.c:168
const struct m0_fid_type M0_CONF_RELFID_TYPE
Definition: dir.c:215
M0_LEAVE()
uint8_t ft_id
Definition: fid.h:101
bool(* coo_invariant)(const struct m0_conf_obj *obj)
Definition: obj_ops.h:79
M0_INTERNAL void m0_conf_obj_put(struct m0_conf_obj *obj)
Definition: obj_ops.c:205
static bool belongs(const struct m0_conf_obj *entry, const struct m0_conf_dir *dir)
Definition: dir.c:64
static int dir_decode(struct m0_conf_obj *dest M0_UNUSED, const struct m0_confx_obj *src M0_UNUSED)
Definition: dir.c:42
struct m0_conf_obj * co_parent
Definition: obj.h:223
static struct m0_rpc_item * item
Definition: item.c:56
M0_INTERNAL bool m0_conf_obj_is_stub(const struct m0_conf_obj *obj)
Definition: obj.c:302
static struct foo * obj
Definition: tlist.c:302
struct m0_tl cd_items
Definition: obj.h:360
M0_INTERNAL void m0_conf_obj_get(struct m0_conf_obj *obj)
Definition: obj_ops.c:186
uint64_t co_nrefs
Definition: obj.h:231
#define M0_ERR_INFO(rc, fmt,...)
Definition: trace.h:215
#define m0_tl_teardown(name, head, obj)
Definition: tlist.h:708
M0_CONF__BOB_DEFINE(m0_conf_dir, M0_CONF_DIR_MAGIC, dir_check)
const struct m0_fid_type cot_ftype
Definition: obj.h:314
M0_CONF__INVARIANT_DEFINE(dir_invariant, m0_conf_dir)
static int next[]
Definition: cp.c:248
#define M0_POST(cond)
static void dir_delete(struct m0_conf_obj *obj)
Definition: dir.c:164
static bool dir_check(const void *bob)
Definition: dir.c:28
#define M0_CONF_CAST(ptr, type)
Definition: obj.h:780
#define FID_P(f)
Definition: fid.h:77
static struct m0_conf_obj * dir_create(void)
Definition: dir.c:188
M0_INTERNAL bool m0_fid_eq(const struct m0_fid *fid0, const struct m0_fid *fid1)
Definition: fid.c:164
Definition: fid.h:38
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
static bool readdir_pre(const struct m0_conf_dir *dir, const struct m0_conf_obj *entry)
Definition: dir.c:80
static int dir_lookup(const struct m0_conf_obj *parent, const struct m0_fid *name, struct m0_conf_obj **out)
Definition: dir.c:145
M0_ENTRY("Setting %.*s's xattr %s=%.*s", dentry->d_name.len,(char *) dentry->d_name.name, name,(int) size,(char *) value)
#define _0C(exp)
Definition: assert.h:311
static int dir_readdir(const struct m0_conf_obj *dir, struct m0_conf_obj **pptr)
Definition: dir.c:111
enum m0_conf_status co_status
Definition: obj.h:210
static bool dir_match(const struct m0_conf_obj *cached M0_UNUSED, const struct m0_confx_obj *flat M0_UNUSED)
Definition: dir.c:56
struct inode * dir
Definition: dir.c:1028
#define out(...)
Definition: gen.c:41
static int dir_encode(struct m0_confx_obj *dest M0_UNUSED, const struct m0_conf_obj *src M0_UNUSED)
Definition: dir.c:49
#define m0_tl_find(name, var, head,...)
Definition: tlist.h:757
const struct m0_conf_obj_type M0_CONF_DIR_TYPE
Definition: dir.c:206
void m0_free(void *data)
Definition: memory.c:146
struct m0_pdclust_src_addr src
Definition: fd.c:108
M0_INTERNAL bool m0_conf_obj_invariant(const struct m0_conf_obj *obj)
Definition: obj_ops.c:52
static bool readdir_post(int retval, const struct m0_conf_dir *dir, const struct m0_conf_obj *entry)
Definition: dir.c:99
#define FID_F
Definition: fid.h:75
const struct m0_conf_obj_ops * co_ops
Definition: obj.h:212
#define M0_IMPOSSIBLE(fmt,...)
#define M0_UNUSED
Definition: misc.h:380