Skip to content

Commit

Permalink
Change the sync behavior to fit the LTFS format Spec 2.5 (#461)
Browse files Browse the repository at this point in the history
  • Loading branch information
Atsushi Abe authored May 24, 2024
1 parent d19dfcf commit 06367df
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 41 deletions.
1 change: 1 addition & 0 deletions src/iosched/unified.c
Original file line number Diff line number Diff line change
Expand Up @@ -2291,6 +2291,7 @@ int _unified_write_index_after_perm(int write_ret, struct unified_data *priv)
return ret;
}

ltfs_set_commit_message_reason(SYNC_WRITE_PERM, priv->vol);
ret = ltfs_write_index(ltfs_ip_id(priv->vol), SYNC_WRITE_PERM, priv->vol);

return ret;
Expand Down
69 changes: 62 additions & 7 deletions src/libltfs/ltfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1779,6 +1779,7 @@ int ltfs_mount(bool force_full, bool deep_recovery, bool recover_extra, bool rec
}
INTERRUPTED_GOTO(ret, out_unlock);
ltfsmsg(LTFS_INFO, 11022I);
ltfs_set_commit_message_reason(SYNC_RECOVERY, vol);
ret = ltfs_write_index(vol->label->partid_ip, SYNC_RECOVERY, vol);
if (ret < 0)
goto out_unlock;
Expand Down Expand Up @@ -1864,13 +1865,6 @@ int ltfs_mount(bool force_full, bool deep_recovery, bool recover_extra, bool rec
if (vol->index->uid_number == 0)
ltfsmsg(LTFS_WARN, 11307W, vol->label->vol_uuid);

/* Clear the commit message so it doesn't carry over from the previous session */
/* TODO: is this the right place to clear the commit message? */
if (vol->index->commit_message) {
free(vol->index->commit_message);
vol->index->commit_message = NULL;
}

/* If we reach this point, both partitions end in an index file. */
vol->ip_index_file_end = true;
vol->dp_index_file_end = true;
Expand Down Expand Up @@ -2535,6 +2529,7 @@ int ltfs_write_index(char partition, char *reason, struct ltfs_volume *vol)

write_perm = true;
reason = SYNC_WRITE_PERM;
ltfs_set_commit_message_reason(SYNC_WRITE_PERM, vol);
}
/* ignore return value: we want to keep trying even if, e.g., the DP fills up */
}
Expand Down Expand Up @@ -3137,6 +3132,7 @@ int ltfs_format_tape(struct ltfs_volume *vol, int density_code, bool destructive
if (ret < 0)
return ret;
ltfsmsg(LTFS_INFO, 11278I, vol->label->partid_dp); /* "Writing Index to ..." */
ltfs_set_commit_message_reason(SYNC_FORMAT, vol);
ret = ltfs_write_index(vol->label->partid_dp, SYNC_FORMAT, vol);
if (ret < 0) {
ltfsmsg(LTFS_ERR, 11279E, vol->label->partid_dp, ret);
Expand Down Expand Up @@ -3633,6 +3629,7 @@ int ltfs_sync_index(char *reason, bool index_locking, struct ltfs_volume *vol)
* For now, write the same index on IP and return an error against a sync
* request.
*/
ltfs_set_commit_message_reason(SYNC_WRITE_PERM, vol);
ret_r = ltfs_write_index(ltfs_ip_id(vol), SYNC_WRITE_PERM, vol);
if (!ret_r) {
ltfsmsg(LTFS_INFO, 11344I, bc_print);
Expand Down Expand Up @@ -4634,3 +4631,61 @@ int ltfs_build_fullpath(char **dest, struct dentry *d)

return ret;
}

/**
* Update commit message of index to the prefixed message based on sync reason.
* @param reason sync reason defined in ltfs.h
* @param vol LTFS colume
*/
void ltfs_set_commit_message_reason(char *reason, struct ltfs_volume *vol)
{
ltfs_mutex_lock(&vol->index->dirty_lock);
ltfs_set_commit_message_reason_unlocked(reason, vol);
ltfs_mutex_unlock(&vol->index->dirty_lock);

return;
}

/**
* Update commit message of index to the prefixed message based on sync reason. Caller need to
* take index->dirty_lock before calling this function.
* @param reason sync reason defined in ltfs.h
* @param vol LTFS volume
*/
void ltfs_set_commit_message_reason_unlocked(char *reason, struct ltfs_volume *vol)
{
bool dirty = false;
int ret = 0;
char *str_now = NULL, *msg = NULL;
struct ltfs_timespec now;

if (!vol->index->dirty) {
/* Do nothing because no update was made */
goto out;
}

if (vol->index->commit_message) {
free(vol->index->commit_message);
dirty = true;
}

ret = get_current_timespec(&now);
if (ret)
goto out;

ret = xml_format_time(now, &str_now);
if (ret)
goto out;

ret = asprintf(&msg, "%s - %s", reason, str_now);
if (ret) {
vol->index->commit_message = msg;
dirty = true;
}

out:
if (dirty)
ltfs_set_index_dirty(false, false, vol->index);

return;
}
3 changes: 3 additions & 0 deletions src/libltfs/ltfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,9 @@ int ltfs_profiler_set(uint64_t source, struct ltfs_volume *vol);
int ltfs_get_rao_list(char *path, struct ltfs_volume *vol);
int ltfs_build_fullpath(char **dest, struct dentry *d);

void ltfs_set_commit_message_reason(char *reason, struct ltfs_volume *vol);
void ltfs_set_commit_message_reason_unlocked(char *reason, struct ltfs_volume *vol);

#ifdef __cplusplus
}
#endif
Expand Down
4 changes: 4 additions & 0 deletions src/libltfs/ltfs_fsops.c
Original file line number Diff line number Diff line change
Expand Up @@ -2106,6 +2106,10 @@ int ltfs_fsops_volume_sync(char *reason, struct ltfs_volume *vol)
if (ret < 0)
return ret;

ltfs_mutex_lock(&vol->index->dirty_lock);
ltfs_set_commit_message_reason_unlocked(reason, vol);
ltfs_mutex_unlock(&vol->index->dirty_lock);

ret = ltfs_sync_index(reason, true, vol);

return ret;
Expand Down
10 changes: 7 additions & 3 deletions src/libltfs/ltfs_internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -1323,6 +1323,7 @@ int ltfs_check_medium(bool fix, bool deep, bool recover_extra, bool recover_syml
}
}
/* write to data partition if it doesn't end in an index file */
ltfs_set_commit_message_reason(SYNC_RECOVERY, vol);
if (! dp_have_index || dp_blocks_after) {
ltfsmsg(LTFS_INFO, 17259I, "DP", vol->index->selfptr.partition, (unsigned long long)vol->index->selfptr.block);
ret = ltfs_write_index(vol->label->partid_dp, SYNC_RECOVERY, vol);
Expand Down Expand Up @@ -1407,12 +1408,15 @@ int ltfs_write_index_conditional(char partition, struct ltfs_volume *vol)

CHECK_ARG_NULL(vol, -LTFS_NULL_ARG);

if (partition == ltfs_ip_id(vol) && ! vol->ip_index_file_end)
if (partition == ltfs_ip_id(vol) && ! vol->ip_index_file_end) {
ltfs_set_commit_message_reason(SYNC_CASCHE_PRESSURE, vol);
ret = ltfs_write_index(partition, SYNC_CASCHE_PRESSURE, vol);
else if (partition == ltfs_dp_id(vol) &&
} else if (partition == ltfs_dp_id(vol) &&
(! vol->dp_index_file_end ||
(vol->ip_index_file_end && vol->index->selfptr.partition == ltfs_ip_id(vol))))
(vol->ip_index_file_end && vol->index->selfptr.partition == ltfs_ip_id(vol)))) {
ltfs_set_commit_message_reason(SYNC_CASCHE_PRESSURE, vol);
ret = ltfs_write_index(partition, SYNC_CASCHE_PRESSURE, vol);
}

return ret;
}
Expand Down
1 change: 1 addition & 0 deletions src/libltfs/periodic_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ ltfs_thread_return periodic_sync_thread(void* data)
ltfsmsg(LTFS_WARN, 17063W, __FUNCTION__);
}

ltfs_set_commit_message_reason(SYNC_PERIODIC, priv->vol);
ret = ltfs_sync_index(SYNC_PERIODIC, true, priv->vol);
if (ret < 0) {
ltfsmsg(LTFS_INFO, 11030I, ret);
Expand Down
74 changes: 44 additions & 30 deletions src/libltfs/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,7 @@ static int _xattr_get_virtual(struct dentry *d, char *buf, size_t buf_size, cons
ret = _xattr_get_vendorunique_xattr(&val, name, vol);
}
} else if (! strcmp(name, "ltfs.sync")) {
ltfs_set_commit_message_reason(SYNC_EA, vol);
ret = ltfs_sync_index(SYNC_EA, false, vol);
}
}
Expand Down Expand Up @@ -915,9 +916,8 @@ static int _xattr_set_virtual(struct dentry *d, const char *name, const char *va
{
int ret = 0;

if (! strcmp(name, "ltfs.sync") && d == vol->index->root)
ret = ltfs_sync_index(SYNC_EA, false, vol);
else if (! strcmp(name, "ltfs.commitMessage") && d == vol->index->root) {
if ((! strcmp(name, "ltfs.commitMessage") || ! strcmp(name, "ltfs.sync"))
&& d == vol->index->root) {
char *value_null_terminated, *new_value;

if (size > INDEX_MAX_COMMENT_LEN) {
Expand All @@ -926,38 +926,49 @@ static int _xattr_set_virtual(struct dentry *d, const char *name, const char *va
}

ltfs_mutex_lock(&vol->index->dirty_lock);
if (! value || ! size) {
/* Clear the current comment field */
if (vol->index->commit_message) {
free(vol->index->commit_message);
vol->index->commit_message = NULL;
}
if (! vol->index->dirty) {
/* Do nothing because index is clean */
ret = 0;
} else {
value_null_terminated = malloc(size + 1);
if (! value_null_terminated) {
ltfsmsg(LTFS_ERR, 10001E, "_xattr_set_virtual: commit_message");
ltfs_mutex_unlock(&vol->index->dirty_lock);
return -LTFS_NO_MEMORY;
}
memcpy(value_null_terminated, value, size);
value_null_terminated[size] = '\0';
if (! value || ! size) {
/* Clear the current comment field */
if (vol->index->commit_message) {
free(vol->index->commit_message);
vol->index->commit_message = NULL;
}
} else {
value_null_terminated = malloc(size + 1);
if (! value_null_terminated) {
ltfsmsg(LTFS_ERR, 10001E, "_xattr_set_virtual: commit_message");
ltfs_mutex_unlock(&vol->index->dirty_lock);
return -LTFS_NO_MEMORY;
}
memcpy(value_null_terminated, value, size);
value_null_terminated[size] = '\0';

ret = pathname_format(value_null_terminated, &new_value, false, true);
free(value_null_terminated);
if (ret < 0) {
ltfs_mutex_unlock(&vol->index->dirty_lock);
return ret;
ret = pathname_format(value_null_terminated, &new_value, false, true);
free(value_null_terminated);
if (ret < 0) {
/* Try to sync index even if the value is not valid */
ltfs_set_commit_message_reason_unlocked(SYNC_EA, vol);
ltfs_mutex_unlock(&vol->index->dirty_lock);

ret = ltfs_sync_index(SYNC_EA, false, vol);
return ret;
}
ret = 0;

/* Update THE commit message in the index */
if (vol->index->commit_message)
free(vol->index->commit_message);
vol->index->commit_message = new_value;
}
ret = 0;

/* Update the commit message in the index */
if (vol->index->commit_message)
free(vol->index->commit_message);
vol->index->commit_message = new_value;
ltfs_set_index_dirty(false, false, vol->index);
}

ltfs_set_index_dirty(false, false, vol->index);
ltfs_mutex_unlock(&vol->index->dirty_lock);
ret = ltfs_sync_index(SYNC_EA, false, vol);

} else if (! strcmp(name, "ltfs.volumeName") && d == vol->index->root) {
char *value_null_terminated, *new_value;
Expand Down Expand Up @@ -1228,6 +1239,8 @@ static int _xattr_set_virtual(struct dentry *d, const char *name, const char *va
vol->lock_status = new;

ltfs_set_index_dirty(false, false, vol->index);
ltfs_set_commit_message_reason_unlocked(SYNC_ADV_LOCK, vol);

ret = ltfs_sync_index(SYNC_ADV_LOCK, false, vol);
ret = tape_device_lock(vol->device);
if (ret < 0) {
Expand Down Expand Up @@ -1486,9 +1499,10 @@ int xattr_set(struct dentry *d, const char *name, const char *value, size_t size

releasewrite_mrsw(&d->meta_lock);

if (write_idx)
if (write_idx) {
ltfs_set_commit_message_reason(SYNC_EA, vol);
ret = ltfs_sync_index(SYNC_EA, false, vol);
else
} else
ret = 0;

out_unlock:
Expand Down
5 changes: 4 additions & 1 deletion src/ltfs_fuse.c
Original file line number Diff line number Diff line change
Expand Up @@ -450,8 +450,10 @@ int ltfs_fuse_release(const char *path, struct fuse_file_info *fi)

open_write = (((fi->flags & O_WRONLY) == O_WRONLY) || ((fi->flags & O_RDWR) == O_RDWR));
ret = ltfs_fsops_close(file->file_info->dentry_handle, dirty, open_write, true, priv->data);
if (write_index)
if (write_index) {
ltfs_set_commit_message_reason(SYNC_CLOSE, priv->data);
ltfs_sync_index(SYNC_CLOSE, true, priv->data);
}

_file_close(file->file_info, priv);
_free_ltfs_file_handle(file);
Expand Down Expand Up @@ -1167,6 +1169,7 @@ void ltfs_fuse_umount(void *userdata)
if (kmi_initialized(priv->data))
kmi_destroy(priv->data);

ltfs_set_commit_message_reason(SYNC_UNMOUNT, priv->data);
ltfs_unmount(SYNC_UNMOUNT, priv->data);

ltfs_request_trace(FUSE_REQ_EXIT(REQ_UNMOUNT), 0, 0);
Expand Down
3 changes: 3 additions & 0 deletions src/utils/ltfsck.c
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,7 @@ int check_ltfs_volume(struct ltfs_volume *vol, struct other_check_opts *opt)
return LTFSCK_UNCORRECTED;
} else {
print_criteria_info(vol);
ltfs_set_commit_message_reason(SYNC_CHECK, vol);
ltfs_unmount(SYNC_CHECK, vol);
ltfsmsg(LTFS_INFO, 16022I);
return LTFSCK_CORRECTED;
Expand Down Expand Up @@ -1174,6 +1175,7 @@ int _rollback_dp(struct ltfs_volume *vol, struct other_check_opts *opt, struct t
if (ret != LTFSCK_NO_ERRORS)
ltfsmsg(LTFS_ERR, 16055E, ret);
} else {
ltfs_set_commit_message_reason(SYNC_ROLLBACK, vol);
ret = ltfs_write_index(ltfs_dp_id(vol), SYNC_ROLLBACK, vol);
if (ret < 0) {
ltfsmsg(LTFS_ERR, 16056E, ret);
Expand Down Expand Up @@ -1288,6 +1290,7 @@ int rollback(struct ltfs_volume *vol, struct other_check_opts *opt)
r.current_pos = ltfs_get_index_selfpointer(vol);
ltfsmsg(LTFS_DEBUG, 16081D, ltfs_get_index_generation(vol),
(int)r.current_pos.partition, (unsigned long long)r.current_pos.block);
ltfs_set_commit_message_reason(SYNC_ROLLBACK, vol);
ltfs_unmount(SYNC_ROLLBACK, vol);
vol->index = NULL;
}
Expand Down

0 comments on commit 06367df

Please sign in to comment.