Skip to content

Commit 009d763

Browse files
authored
DAOS-18604 dfs: EC should not be used for directories (#17573)
- if dir-oclass is set to EC on container create, use default instead. - daos fs set-attr of an EC oclass on directory should apply only to files. directories will be create with the default in that case. - fix daos fs get-attr to show such changes Signed-off-by: Mohamad Chaarawi <mohamad.chaarawi@hpe.com>
1 parent 042b2c7 commit 009d763

6 files changed

Lines changed: 97 additions & 9 deletions

File tree

src/client/dfs/README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,14 @@ Object testdir
134134
By default, all directories are created with an object class with 1 shard. This means, that if the
135135
container redundancy factor (RF) is 0, OC_S1 oclass will be used; if RF=1 OC_RP_2G1 is used, and so
136136
on. The user can of course change that when creating the directory and set the desired object class
137-
manually, or set the default object class when creating the container.
137+
manually, or set the default object class when creating the container. Using an EC object class
138+
class for directories is not recommended since directory entries are small and EC overhead will be
139+
large anyway. Thus when setting the directory object class on container creation to an EC object
140+
class, DAOS will ignore the user setting and use the default replication object class depending on
141+
the redundancy factory of the container as explained earlier. If one uses the DAOS tool to change
142+
the object class of new files and directories to be created under an existing directory (daos fs
143+
set-attr), and that object class is EC, that setting will apply only to files. New directories will
144+
use the container default in that case.
138145
139146
Note that with this mapping, the inode information is stored with the entry that it corresponds to
140147
in the parent directory object. Thus, hard links won't be supported, since it won't be possible to

src/client/dfs/common.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/**
22
* (C) Copyright 2018-2024 Intel Corporation.
3+
* (C) Copyright 2026 Hewlett Packard Enterprise Development LP
34
*
45
* SPDX-License-Identifier: BSD-2-Clause-Patent
56
*/
@@ -643,8 +644,15 @@ create_dir(dfs_t *dfs, dfs_obj_t *parent, daos_oclass_id_t cid, dfs_obj_t *dir)
643644
if (cid == 0) {
644645
if (parent->d.oclass == 0)
645646
cid = dfs->attr.da_dir_oclass_id;
646-
else
647+
else {
647648
cid = parent->d.oclass;
649+
/*
650+
* If the parent oclass is EC, do not use that for a directory and use the
651+
* container default instead.
652+
*/
653+
if (daos_cid_is_ec(cid))
654+
cid = dfs->attr.da_dir_oclass_id;
655+
}
648656
}
649657

650658
/** Allocate an OID for the dir - local operation */

src/client/dfs/cont.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* (C) Copyright 2018-2024 Intel Corporation.
3-
* (C) Copyright 2025 Hewlett Packard Enterprise Development LP
3+
* (C) Copyright 2025-2026 Hewlett Packard Enterprise Development LP
44
*
55
* SPDX-License-Identifier: BSD-2-Clause-Patent
66
*/
@@ -189,8 +189,14 @@ dfs_cont_create(daos_handle_t poh, uuid_t *cuuid, dfs_attr_t *attr, daos_handle_
189189
}
190190
if (attr->da_file_oclass_id)
191191
dattr.da_file_oclass_id = attr->da_file_oclass_id;
192-
if (attr->da_dir_oclass_id)
192+
if (attr->da_dir_oclass_id) {
193193
dattr.da_dir_oclass_id = attr->da_dir_oclass_id;
194+
if (daos_cid_is_ec(dattr.da_dir_oclass_id)) {
195+
D_WARN("EC object class for directories is not supported,"
196+
" reverting to use default");
197+
dattr.da_dir_oclass_id = 0;
198+
}
199+
}
194200

195201
/** check non default mode */
196202
if ((attr->da_mode & MODE_MASK) == DFS_RELAXED ||

src/client/dfs/obj.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* (C) Copyright 2018-2024 Intel Corporation.
3-
* (C) Copyright 2025 Hewlett Packard Enterprise Development LP
3+
* (C) Copyright 2025-2026 Hewlett Packard Enterprise Development LP
44
*
55
* SPDX-License-Identifier: BSD-2-Clause-Patent
66
*/
@@ -81,7 +81,16 @@ dfs_obj_get_info(dfs_t *dfs, dfs_obj_t *obj, dfs_obj_info_t *info)
8181

8282
/** what is the default oclass files and dirs will be created with in this dir */
8383
if (obj->d.oclass) {
84-
info->doi_dir_oclass_id = obj->d.oclass;
84+
/** if parent oclass is EC, dir would be chosen as container default */
85+
if (!daos_cid_is_ec(obj->d.oclass)) {
86+
info->doi_dir_oclass_id = obj->d.oclass;
87+
} else {
88+
if (dfs->attr.da_dir_oclass_id)
89+
info->doi_dir_oclass_id = dfs->attr.da_dir_oclass_id;
90+
else
91+
rc = daos_obj_get_oclass(dfs->coh, DAOS_OT_MULTI_HASHED, 0,
92+
0, &info->doi_dir_oclass_id);
93+
}
8594
info->doi_file_oclass_id = obj->d.oclass;
8695
} else {
8796
if (dfs->attr.da_dir_oclass_id)

src/include/daos/object.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* (C) Copyright 2016-2023 Intel Corporation.
3-
* (C) Copyright 2025 Hewlett Packard Enterprise Development LP
3+
* (C) Copyright 2025-2026 Hewlett Packard Enterprise Development LP
44
*
55
* SPDX-License-Identifier: BSD-2-Clause-Patent
66
*/
@@ -404,6 +404,17 @@ daos_oclass_is_ec(struct daos_oclass_attr *oca)
404404
return oca->ca_resil == DAOS_RES_EC;
405405
}
406406

407+
static inline bool
408+
daos_cid_is_ec(daos_oclass_id_t cid)
409+
{
410+
struct daos_oclass_attr *oca;
411+
412+
oca = daos_oclass_id2attr(cid, NULL);
413+
if (oca == NULL)
414+
return false;
415+
return daos_oclass_is_ec(oca);
416+
}
417+
407418
static inline void
408419
daos_obj_set_oid(daos_obj_id_t *oid, enum daos_otype_t type,
409420
enum daos_obj_redun ord, uint32_t nr_grps,

src/tests/suite/dfs_unit_test.c

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* (C) Copyright 2019-2024 Intel Corporation.
3-
* (C) Copyright 2025 Hewlett Packard Enterprise Development LP
3+
* (C) Copyright 2025-2026 Hewlett Packard Enterprise Development LP
44
*
55
* SPDX-License-Identifier: BSD-2-Clause-Patent
66
*/
@@ -2256,11 +2256,12 @@ dfs_test_oclass_hints(void **state)
22562256
daos_oclass_id_t cid;
22572257
daos_handle_t coh;
22582258
dfs_t *dfs_l;
2259-
dfs_obj_t *obj;
2259+
dfs_obj_t *obj, *dir;
22602260
daos_obj_id_t oid;
22612261
daos_oclass_id_t ecidx;
22622262
daos_prop_t *prop = NULL;
22632263
dfs_attr_t dattr = {0};
2264+
dfs_obj_info_t oinfo = {0};
22642265
struct pl_map_attr attr = {0};
22652266
int rc;
22662267

@@ -2416,6 +2417,21 @@ dfs_test_oclass_hints(void **state)
24162417
rc = compare_oclass(coh, cid, OC_RP_2GX);
24172418
assert_rc_equal(rc, 0);
24182419

2420+
/** create a directory and set EC to be used on the directory */
2421+
rc = dfs_open(dfs_l, NULL, "d1", S_IFDIR | S_IWUSR | S_IRUSR, O_RDWR | O_CREAT, 0, 0, NULL,
2422+
&dir);
2423+
assert_int_equal(rc, 0);
2424+
rc = dfs_obj_set_oclass(dfs_l, dir, 0, ecidx);
2425+
assert_int_equal(rc, 0);
2426+
/** get the dir info to query what oclass will be used */
2427+
rc = dfs_obj_get_info(dfs_l, dir, &oinfo);
2428+
assert_int_equal(rc, 0);
2429+
rc = compare_oclass(coh, oinfo.doi_dir_oclass_id, OC_RP_2G1);
2430+
assert_int_equal(rc, 0);
2431+
rc = compare_oclass(coh, oinfo.doi_file_oclass_id, ecidx);
2432+
assert_int_equal(rc, 0);
2433+
dfs_release(dir);
2434+
24192435
rc = dfs_umount(dfs_l);
24202436
assert_int_equal(rc, 0);
24212437
rc = daos_cont_close(coh, NULL);
@@ -2468,6 +2484,21 @@ dfs_test_oclass_hints(void **state)
24682484
rc = compare_oclass(coh, cid, OC_RP_3GX);
24692485
assert_rc_equal(rc, 0);
24702486

2487+
/** create a directory and set EC to be used on the directory */
2488+
rc = dfs_open(dfs_l, NULL, "d1", S_IFDIR | S_IWUSR | S_IRUSR, O_RDWR | O_CREAT, 0, 0, NULL,
2489+
&dir);
2490+
assert_int_equal(rc, 0);
2491+
rc = dfs_obj_set_oclass(dfs_l, dir, 0, ecidx);
2492+
assert_int_equal(rc, 0);
2493+
/** get the dir info to query what oclass will be used */
2494+
rc = dfs_obj_get_info(dfs_l, dir, &oinfo);
2495+
assert_int_equal(rc, 0);
2496+
rc = compare_oclass(coh, oinfo.doi_dir_oclass_id, OC_RP_3G1);
2497+
assert_int_equal(rc, 0);
2498+
rc = compare_oclass(coh, oinfo.doi_file_oclass_id, ecidx);
2499+
assert_int_equal(rc, 0);
2500+
dfs_release(dir);
2501+
24712502
rc = dfs_umount(dfs_l);
24722503
assert_int_equal(rc, 0);
24732504
rc = daos_cont_close(coh, NULL);
@@ -2520,6 +2551,22 @@ dfs_test_oclass_hints(void **state)
25202551
rc = compare_oclass(coh, cid, OC_RP_4GX);
25212552
assert_rc_equal(rc, 0);
25222553

2554+
/** create a directory and set EC to be used on the directory */
2555+
rc = dfs_open(dfs_l, NULL, "d1", S_IFDIR | S_IWUSR | S_IRUSR, O_RDWR | O_CREAT, 0, 0, NULL,
2556+
&dir);
2557+
assert_int_equal(rc, 0);
2558+
rc = dfs_obj_set_oclass(dfs_l, dir, 0, ecidx);
2559+
assert_int_equal(rc, 0);
2560+
/** get the dir info to query what oclass will be used */
2561+
rc = dfs_obj_get_info(dfs_l, dir, &oinfo);
2562+
assert_int_equal(rc, 0);
2563+
rc = compare_oclass(coh, oinfo.doi_dir_oclass_id, OC_RP_4G1);
2564+
assert_int_equal(rc, 0);
2565+
rc = compare_oclass(coh, oinfo.doi_file_oclass_id, ecidx);
2566+
assert_int_equal(rc, 0);
2567+
dfs_release(dir);
2568+
2569+
assert_int_equal(rc, 0);
25232570
rc = dfs_umount(dfs_l);
25242571
assert_int_equal(rc, 0);
25252572
rc = daos_cont_close(coh, NULL);

0 commit comments

Comments
 (0)