Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 62 additions & 17 deletions src/client/dfs/obj.c
Original file line number Diff line number Diff line change
Expand Up @@ -2102,26 +2102,26 @@ dfs_osetattr(dfs_t *dfs, dfs_obj_t *obj, struct stat *stbuf, int flags)
* shrinks the head and empties the tail, otherwise only the tail extent changes.
*/
static int
dfs_pl_truncate(dfs_obj_t *obj, daos_off_t offset)
dfs_pl_truncate(dfs_obj_t *obj, daos_handle_t th, daos_off_t offset)
{
daos_size_t split = obj->f.split_off;
int rc;

if (offset <= split) {
rc = daos_array_set_size(obj->oh, DAOS_TX_NONE, offset, NULL);
rc = daos_array_set_size(obj->oh, th, offset, NULL);
if (rc)
return rc;
return daos_array_set_size(obj->f.tail_oh, DAOS_TX_NONE, 0, NULL);
return daos_array_set_size(obj->f.tail_oh, th, 0, NULL);
}

/* head retains all of [0, split_off); only the tail extent changes */
return daos_array_set_size(obj->f.tail_oh, DAOS_TX_NONE, offset - split, NULL);
return daos_array_set_size(obj->f.tail_oh, th, offset - split, NULL);
}

/* Punch the logical hole [offset, offset + len) of a progressive-layout file across head and tail.
*/
static int
dfs_pl_punch_hole(dfs_obj_t *obj, daos_off_t offset, daos_size_t len)
dfs_pl_punch_hole(dfs_obj_t *obj, daos_handle_t th, daos_off_t offset, daos_size_t len)
{
daos_size_t split = obj->f.split_off;
daos_off_t end = offset + len;
Expand All @@ -2135,7 +2135,7 @@ dfs_pl_punch_hole(dfs_obj_t *obj, daos_off_t offset, daos_size_t len)
if (offset < split) {
rg.rg_idx = offset;
rg.rg_len = (end < split ? end : split) - offset;
rc = daos_array_punch(obj->oh, DAOS_TX_NONE, &iod, NULL);
rc = daos_array_punch(obj->oh, th, &iod, NULL);
if (rc)
return rc;
}
Expand All @@ -2144,13 +2144,62 @@ dfs_pl_punch_hole(dfs_obj_t *obj, daos_off_t offset, daos_size_t len)

rg.rg_idx = tstart - split;
rg.rg_len = end - tstart;
rc = daos_array_punch(obj->f.tail_oh, DAOS_TX_NONE, &iod, NULL);
rc = daos_array_punch(obj->f.tail_oh, th, &iod, NULL);
if (rc)
return rc;
}
return 0;
}

/*
* Apply the chosen PL truncate/punch. In balanced mode the head and tail updates are wrapped in a
* DTX only when the operation touches both arrays; a single-array update is already atomic.
*/
static int
dfs_pl_punch_op(dfs_t *dfs, dfs_obj_t *obj, bool truncate, daos_off_t offset, daos_size_t len)
{
daos_handle_t th = DAOS_TX_NONE;
bool span_both;
int rc;

if (truncate)
span_both = offset <= obj->f.split_off;
else
span_both = offset < obj->f.split_off && (offset + len) > obj->f.split_off;

if (dfs->use_dtx && span_both) {
rc = daos_tx_open(dfs->coh, &th, 0, NULL);
if (rc) {
D_ERROR("daos_tx_open() failed (%d)\n", rc);
return daos_der2errno(rc);
}
}

restart:
if (truncate)
rc = dfs_pl_truncate(obj, th, offset);
else
rc = dfs_pl_punch_hole(obj, th, offset, len);
rc = daos_der2errno(rc);
if (rc)
D_GOTO(out, rc);

if (daos_handle_is_valid(th)) {
rc = daos_tx_commit(th, NULL);
if (rc) {
if (rc != -DER_TX_RESTART)
D_ERROR("daos_tx_commit() failed (%d)\n", rc);
D_GOTO(out, rc = daos_der2errno(rc));
}
}

out:
rc = check_tx(th, rc);
if (rc == ERESTART)
goto restart;
return rc;
}

int
dfs_punch(dfs_t *dfs, dfs_obj_t *obj, daos_off_t offset, daos_size_t len)
{
Expand All @@ -2175,10 +2224,8 @@ dfs_punch(dfs_t *dfs, dfs_obj_t *obj, daos_off_t offset, daos_size_t len)
daos_size_t tsize = 0;

/** simple truncate */
if (len == DFS_MAX_FSIZE) {
rc = dfs_pl_truncate(obj, offset);
return daos_der2errno(rc);
}
if (len == DFS_MAX_FSIZE)
return dfs_pl_punch_op(dfs, obj, true, offset, len);

/** logical size = split + tail extent when the tail has data, else the head extent
*/
Expand All @@ -2200,17 +2247,15 @@ dfs_punch(dfs_t *dfs, dfs_obj_t *obj, daos_off_t offset, daos_size_t len)
hi = offset + len;

/** if fsize is between the range to punch, just truncate to offset */
if (offset < size && size <= hi) {
rc = dfs_pl_truncate(obj, offset);
return daos_der2errno(rc);
}
if (offset < size && size <= hi)
return dfs_pl_punch_op(dfs, obj, true, offset, len);

D_ASSERT(size > hi);

rc = dfs_pl_punch_hole(obj, offset, len);
rc = dfs_pl_punch_op(dfs, obj, false, offset, len);
if (rc) {
D_ERROR("dfs_pl_punch_hole() failed (%d)\n", rc);
return daos_der2errno(rc);
return rc;
}

DFS_OP_STAT_INCR(dfs, DOS_TRUNCATE);
Expand Down
Loading