Skip to content

Commit

Permalink
DAOS-14476 dfs: update root stbuf on lookup of root
Browse files Browse the repository at this point in the history
- In order to avoid stale root stat data, update the root stbuf on lookup.
- add mtime/ctime proper querying for dfs_lookup()

Features: dfs
Required-githooks: true

Signed-off-by: Mohamad Chaarawi <mohamad.chaarawi@intel.com>
  • Loading branch information
mchaarawi committed Jan 12, 2024
1 parent 365a503 commit 6271472
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 20 deletions.
89 changes: 70 additions & 19 deletions src/client/dfs/dfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -3416,13 +3416,10 @@ lookup_rel_path(dfs_t *dfs, dfs_obj_t *root, const char *path, int flags,
lookup_rel_path_loop:

/*
* Open the directory object one level up.
* Since fetch_entry does not support ".",
* we can't support ".." as the last entry,
* nor can we support "../.." because we don't
* have parent.parent_oid and parent.mode.
* For now, represent this partial state with
* parent_fully_valid.
* Open the directory object one level up. Since fetch_entry does not support ".",
* we can't support ".." as the last entry, nor can we support "../.." because we
* don't have parent.parent_oid and parent.mode. For now, represent this partial
* state with parent_fully_valid.
*/
parent_fully_valid = true;
if (strcmp(token, "..") == 0) {
Expand Down Expand Up @@ -3508,15 +3505,23 @@ lookup_rel_path(dfs_t *dfs, dfs_obj_t *root, const char *path, int flags,
}

if (stbuf) {
daos_size_t size;
daos_array_stbuf_t array_stbuf = {0};

rc = daos_array_get_size(obj->oh, DAOS_TX_NONE, &size, NULL);
rc = daos_array_stat(obj->oh, DAOS_TX_NONE, &array_stbuf, NULL);
if (rc) {
daos_array_close(obj->oh, NULL);
D_GOTO(err_obj, rc = daos_der2errno(rc));
}
stbuf->st_size = size;

stbuf->st_size = array_stbuf.st_size;
stbuf->st_blocks = (stbuf->st_size + (1 << 9) - 1) >> 9;

rc = update_stbuf_times(entry, array_stbuf.st_max_epoch, stbuf,
NULL);
if (rc) {
daos_array_close(obj->oh, NULL);
D_GOTO(err_obj, rc);
}
}
break;
}
Expand Down Expand Up @@ -3617,31 +3622,77 @@ lookup_rel_path(dfs_t *dfs, dfs_obj_t *root, const char *path, int flags,
}

obj->d.chunk_size = entry.chunk_size;
obj->d.oclass = entry.oclass;
if (stbuf)
stbuf->st_size = sizeof(entry);

obj->d.oclass = entry.oclass;
oid_cp(&parent.oid, obj->oid);
oid_cp(&parent.parent_oid, obj->parent_oid);
parent.oh = obj->oh;
parent.mode = entry.mode;

if (stbuf) {
daos_epoch_t ep;

rc = daos_obj_query_max_epoch(obj->oh, DAOS_TX_NONE, &ep, NULL);
if (rc) {
daos_obj_close(obj->oh, NULL);
D_GOTO(err_obj, rc = daos_der2errno(rc));
}

rc = update_stbuf_times(entry, ep, stbuf, NULL);
if (rc) {
daos_obj_close(obj->oh, NULL);
D_GOTO(err_obj, rc = daos_der2errno(rc));
}
stbuf->st_size = sizeof(entry);
}
}

if (mode)
*mode = obj->mode;

if (stbuf) {
if (is_root) {
daos_epoch_t ep;

/** refresh possibly stale root stbuf */
rc = fetch_entry(dfs->layout_v, dfs->super_oh, DAOS_TX_NONE, "/", 1, false,
&exists, &entry, 0, NULL, NULL, NULL);
if (rc) {
D_DEBUG(DB_TRACE, "fetch root entry failed: %d", rc);
return rc;
}
if (!exists || !S_ISDIR(entry.mode)) {
/** something really bad happended! */

Check failure on line 3664 in src/client/dfs/dfs.c

View workflow job for this annotation

GitHub Actions / Codespell

happended ==> happened
D_ERROR("Root object corrupted!");
D_GOTO(err_obj, rc = EIO);
}

if (mode)
*mode = entry.mode;
dfs->root_stbuf.st_mode = entry.mode;
dfs->root_stbuf.st_uid = entry.uid;
dfs->root_stbuf.st_gid = entry.gid;

rc = daos_obj_query_max_epoch(dfs->root.oh, DAOS_TX_NONE, &ep, NULL);
if (rc)
D_GOTO(err_obj, rc = daos_der2errno(rc));

/** object was updated since creation */
rc = update_stbuf_times(entry, ep, &dfs->root_stbuf, NULL);
if (rc)
D_GOTO(err_obj, rc);
if (tspec_gt(dfs->root_stbuf.st_ctim, dfs->root_stbuf.st_mtim)) {
dfs->root_stbuf.st_atim.tv_sec = entry.ctime;
dfs->root_stbuf.st_atim.tv_nsec = entry.ctime_nano;
} else {
dfs->root_stbuf.st_atim.tv_sec = entry.mtime;
dfs->root_stbuf.st_atim.tv_nsec = entry.mtime_nano;
}
memcpy(stbuf, &dfs->root_stbuf, sizeof(struct stat));
} else {
stbuf->st_nlink = 1;
stbuf->st_mode = obj->mode;
stbuf->st_uid = entry.uid;
stbuf->st_gid = entry.gid;
stbuf->st_mtim.tv_sec = entry.mtime;
stbuf->st_mtim.tv_nsec = entry.mtime_nano;
stbuf->st_ctim.tv_sec = entry.ctime;
stbuf->st_ctim.tv_nsec = entry.ctime_nano;
stbuf->st_gid = entry.gid;
if (tspec_gt(stbuf->st_ctim, stbuf->st_mtim)) {
stbuf->st_atim.tv_sec = entry.ctime;
stbuf->st_atim.tv_nsec = entry.ctime_nano;
Expand Down
32 changes: 31 additions & 1 deletion src/tests/suite/dfs_unit_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -1415,15 +1415,45 @@ dfs_test_chown(void **state)
char *filename_file2 = "open_stat2";
mode_t create_mode = S_IWUSR | S_IRUSR;
int create_flags = O_RDWR | O_CREAT | O_EXCL;
struct timespec ctime_orig, mtime_orig;
mode_t orig_mode;
int rc;

if (arg->myrank != 0)
return;

rc = dfs_lookup(dfs_mt, "/", O_RDWR, &dir, NULL, &stbuf);
rc = dfs_lookup(dfs_mt, "/", O_RDWR, &dir, &orig_mode, &stbuf);
assert_int_equal(rc, 0);
assert_int_equal(stbuf.st_uid, geteuid());
assert_int_equal(stbuf.st_gid, getegid());
mtime_orig.tv_sec = stbuf.st_mtim.tv_sec;
mtime_orig.tv_nsec = stbuf.st_mtim.tv_nsec;
ctime_orig.tv_sec = stbuf.st_ctim.tv_sec;
ctime_orig.tv_nsec = stbuf.st_ctim.tv_nsec;

/** chown of root and see if visible */
print_message("Running chown tests on root object...\n");
memset(&stbuf, 0, sizeof(stbuf));
stbuf.st_uid = 3;
stbuf.st_gid = 4;
stbuf.st_mtim.tv_sec = mtime_orig.tv_sec + 10;
stbuf.st_mtim.tv_nsec = mtime_orig.tv_nsec;
stbuf.st_mode = orig_mode | S_IROTH | S_IWOTH | S_IXOTH;
rc = dfs_osetattr(dfs_mt, dir, &stbuf,
DFS_SET_ATTR_UID | DFS_SET_ATTR_GID | DFS_SET_ATTR_MTIME |
DFS_SET_ATTR_MODE);
assert_int_equal(rc, 0);
rc = dfs_release(dir);
assert_int_equal(rc, 0);

memset(&stbuf, 0, sizeof(stbuf));
rc = dfs_lookup(dfs_mt, "/", O_RDWR, &dir, NULL, &stbuf);
assert_int_equal(rc, 0);
assert_int_equal(stbuf.st_mode, orig_mode | S_IROTH | S_IWOTH | S_IXOTH);
assert_int_equal(stbuf.st_uid, 3);
assert_int_equal(stbuf.st_gid, 4);
assert_true(check_ts(ctime_orig, stbuf.st_ctim));
assert_int_equal(mtime_orig.tv_sec + 10, stbuf.st_mtim.tv_sec);
rc = dfs_release(dir);
assert_int_equal(rc, 0);

Expand Down

0 comments on commit 6271472

Please sign in to comment.