Skip to content
Open
Show file tree
Hide file tree
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
61 changes: 4 additions & 57 deletions src/iosched/unified.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
*/

#include "libltfs/ltfs.h"
#include "libltfs/ltfs_locking_old.h"
#include "libltfs/tape.h"
#include "libltfs/ltfs_fsops_raw.h"
#include "libltfs/index_criteria.h"
Expand Down Expand Up @@ -252,7 +253,6 @@ void _unified_unset_write_ip(struct dentry_priv *dpr, struct unified_data *priv)
void _unified_handle_write_error(ssize_t write_ret, struct write_request *req,
struct dentry_priv *dpr, struct unified_data *priv);
int _unified_get_write_error(struct dentry_priv *dpr);
int _unified_write_index_after_perm(int write_ret, struct unified_data *priv);

/**
* Initialize an instance of the unified scheduler.
Expand Down Expand Up @@ -1189,9 +1189,6 @@ void _unified_process_index_queue(struct unified_data *priv)
if (ret < 0) {
/* Index partition writer: failed to write data to the tape (%d) */
ltfsmsg(LTFS_WARN, 13013W, (int)ret);
if (IS_WRITE_PERM(-ret)) {
ret = tape_set_cart_volume_lock_status(priv->vol, PWE_MAM_IP);
}
_unified_handle_write_error(ret, req, dentry_priv, priv);
break;
} else {
Expand Down Expand Up @@ -1283,7 +1280,6 @@ void _unified_process_data_queue(enum request_state queue, struct unified_data *
if (ret < 0) {
/* Data partition writer: failed to write data to the tape (%d) */
ltfsmsg(LTFS_WARN, 13014W, (int)ret);
(void)_unified_write_index_after_perm(ret, priv);
_unified_handle_write_error(ret, req, dentry_priv, priv);
break;
} else {
Expand Down Expand Up @@ -1314,7 +1310,9 @@ void _unified_process_data_queue(enum request_state queue, struct unified_data *
if (ret < 0) {
/* Data partition writer: failed to write data to the tape (%d) */
ltfsmsg(LTFS_WARN, 13014W, (int)ret);
(void)_unified_write_index_after_perm(ret, priv);

// Note: Do we need to handle these errors?
// _unified_handle_write_error(ret, req, dentry_priv, priv);
break;
} else {
TAILQ_REMOVE(&local_req_list, req, list);
Expand Down Expand Up @@ -1961,7 +1959,6 @@ int _unified_flush_unlocked(struct dentry *d, struct unified_data *priv)
ret = ltfs_fsraw_write(d, req_cache, req->count, req->offset, dp_id, false, priv->vol);
if (ret < 0) {
ltfsmsg(LTFS_ERR, 13019E, (int)ret);
(void)_unified_write_index_after_perm(ret, priv);
_unified_handle_write_error(ret, req, dpr, priv);
break;
} else if (dpr->write_ip) {
Expand Down Expand Up @@ -2246,56 +2243,6 @@ int _unified_get_write_error(struct dentry_priv *dpr)
return ret;
}

int _unified_write_index_after_perm(int write_ret, struct unified_data *priv)
{
int ret = 0;
struct tc_position err_pos;
uint64_t last_index_pos = UINT64_MAX;
unsigned long blocksize;

if (!IS_WRITE_PERM(-write_ret)) {
/* Nothing to do for non-medium error */
return ret;
}

ltfsmsg(LTFS_INFO, 13024I, write_ret);
ret = tape_set_cart_volume_lock_status(priv->vol, PWE_MAM_DP);
if (ret < 0)
ltfsmsg(LTFS_ERR, 13026E, "update MAM", ret);

blocksize = ltfs_get_blocksize(priv->vol);

ret = tape_get_first_untransfered_position(priv->vol->device, &err_pos);
if (ret < 0) {
ltfsmsg(LTFS_ERR, 13026E, "get error pos", ret);
return ret;
}

/* Check the err_pos is larger than the last index position of the partition */
if (err_pos.partition == ltfs_part_id2num(priv->vol->label->partid_ip, priv->vol)) {
last_index_pos = priv->vol->ip_coh.set_id;
} else {
last_index_pos = priv->vol->dp_coh.set_id;
}

if (last_index_pos > err_pos.block) {
ltfsmsg(LTFS_INFO, 13027I, (int)err_pos.partition,
(unsigned long long)err_pos.block, (unsigned long long)last_index_pos);
err_pos.block = last_index_pos + 1;
}

ltfsmsg(LTFS_INFO, 13025I, (int)err_pos.partition, (unsigned long long)err_pos.block, blocksize);
ret = ltfs_fsraw_cleanup_extent(priv->vol->index->root, err_pos, blocksize, priv->vol);
if (ret < 0) {
ltfsmsg(LTFS_ERR, 13026E, "extent cleanup", ret);
return ret;
}

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

return ret;
}

/**
* Enable profiler function
* @param work_dir work directory to store profiler data
Expand Down
67 changes: 64 additions & 3 deletions src/libltfs/iosched.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,11 @@
**
*************************************************************************************
*/
#include "ltfs_error.h"
#include "ltfs_fuse.h"
#include "ltfs_fsops_raw.h"
#include "ltfs.h"
#include "tape.h"
#include "iosched.h"

struct iosched_priv {
Expand All @@ -61,6 +64,53 @@ struct iosched_priv {
void *backend_handle; /**< Backend private data */
};

int _iosched_write_index_after_perm(int write_ret, struct ltfs_volume *volume)
{
int ret = 0;
struct tc_position err_pos;
uint64_t last_index_pos = UINT64_MAX;
unsigned long blocksize;

if (!IS_WRITE_PERM(-write_ret)) {
/* Nothing to do for non-medium error */
return ret;
}

ltfsmsg(LTFS_INFO, 13024I, write_ret);
blocksize = ltfs_get_blocksize(volume);

ret = tape_get_first_untransfered_position(volume->device, &err_pos);
if (ret < 0) {
ltfsmsg(LTFS_ERR, 13026E, "get error pos", ret);
return ret;
}

/* Check the err_pos is larger than the last index position of the partition */
if (err_pos.partition == ltfs_part_id2num(volume->label->partid_ip, volume)) {
last_index_pos = volume->ip_coh.set_id;
} else {
last_index_pos = volume->dp_coh.set_id;
}

if (last_index_pos > err_pos.block) {
ltfsmsg(LTFS_INFO, 13027I, (int)err_pos.partition,
(unsigned long long)err_pos.block, (unsigned long long)last_index_pos);
err_pos.block = last_index_pos + 1;
}

ltfsmsg(LTFS_INFO, 13025I, (int)err_pos.partition, (unsigned long long)err_pos.block, blocksize);
ret = ltfs_fsraw_cleanup_extent(volume->index->root, err_pos, blocksize, volume);
if (ret < 0) {
ltfsmsg(LTFS_ERR, 13026E, "extent cleanup", ret);
return ret;
}

ret = ltfs_write_index(ltfs_ip_id(volume), SYNC_WRITE_PERM, volume);

return ret;
}


/**
* Initialize the I/O scheduler.
* @param plugin The plugin to take scheduler operations from.
Expand Down Expand Up @@ -230,10 +280,21 @@ ssize_t iosched_write(struct dentry *d, const char *buf, size_t size, off_t offs
CHECK_ARG_NULL(d, -LTFS_NULL_ARG);

ret = priv->ops->write(d, buf, size, offset, isupdatetime, priv->backend_handle);
if (ret > 0 && (size_t) ret > size)
ret = size;
// TODO: Add logs to this thing
if (ret < 0) {
if (IS_WRITE_PERM(-ret)) {
mam_lockval vollock = d->matches_name_criteria ? PWE_MAM_IP : PWE_MAM_DP;
int sync_ret = _iosched_write_index_after_perm(ret, vol);
if (sync_ret < 0) {
tape_set_cart_volume_lock_status(vol, PWE_MAM);
return sync_ret;
}
tape_set_cart_volume_lock_status(vol, vollock);
}
return ret;
}

return ret;
return ret > (ssize_t)size? (ssize_t)size : ret;
}

/**
Expand Down
38 changes: 6 additions & 32 deletions src/libltfs/ltfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@

#include "fs.h"
#include "ltfs.h"
#include "ltfs_error.h"
#include "ltfs_internal.h"
#include "libltfs/ltfslogging.h"
#include "ltfs_copyright.h"
Expand Down Expand Up @@ -2431,15 +2432,14 @@ size_t ltfs_max_cache_size(struct ltfs_volume *vol)
*/
int ltfs_write_index(char partition, char *reason, struct ltfs_volume *vol)
{
int ret, ret_mam;
int ret;
struct tape_offset old_selfptr, old_backptr;
struct ltfs_timespec modtime_old = { .tv_sec = 0, .tv_nsec = 0 };
bool generation_inc = false;
struct tc_position physical_selfptr, current_position;
char *cache_path_save = NULL;
bool write_perm = (strcmp(reason, SYNC_WRITE_PERM) == 0);
bool update_vollock = false;
int volstat = -1, new_volstat = 0;
int volstat = -1;
char *bc_print = NULL;
unsigned long long diff;

Expand Down Expand Up @@ -2567,13 +2567,13 @@ int ltfs_write_index(char partition, char *reason, struct ltfs_volume *vol)
return -1;
}

/* Prior to writing the index, compare the current location of the head position to the head location
/* Prior to writing the index, compare the current location of the head position to the head location
that is kept in the cache of ltfs (physical_selfptr). If they are different return error (-1) */
diff = ((unsigned long long)physical_selfptr.block - (unsigned long long)current_position.block);
if (diff) {
/* Position mismatch, diff not equal zero */
ltfsmsg(LTFS_INFO, 17293E, (unsigned long long)physical_selfptr.block, (unsigned long long)current_position.block);
return -1;
return -LTFS_INDEX_INVALID;
}

old_selfptr = vol->index->selfptr;
Expand All @@ -2594,9 +2594,6 @@ int ltfs_write_index(char partition, char *reason, struct ltfs_volume *vol)
vol->index->backptr = old_backptr;
vol->index->selfptr = old_selfptr;

if (IS_WRITE_PERM(-ret))
update_vollock = true;

goto out_write_perm;
}
}
Expand All @@ -2614,9 +2611,6 @@ int ltfs_write_index(char partition, char *reason, struct ltfs_volume *vol)
vol->index->backptr = old_backptr;
vol->index->selfptr = old_selfptr;

if (IS_WRITE_PERM(-ret))
update_vollock = true;

goto out_write_perm;
}

Expand All @@ -2631,9 +2625,6 @@ int ltfs_write_index(char partition, char *reason, struct ltfs_volume *vol)
vol->index->backptr = old_backptr;
vol->index->selfptr = old_selfptr;

if (IS_WRITE_PERM(-ret))
update_vollock = true;

goto out_write_perm;
}

Expand Down Expand Up @@ -2677,23 +2668,6 @@ int ltfs_write_index(char partition, char *reason, struct ltfs_volume *vol)
ltfs_mutex_unlock(&vol->device->read_only_flag_mutex);
}

if (update_vollock) {
if (volstat == PWE_MAM_DP && partition == ltfs_ip_id(vol))
new_volstat = PWE_MAM_BOTH;
else if (volstat == PWE_MAM_IP && partition == ltfs_dp_id(vol))
new_volstat = PWE_MAM_BOTH;
else if (volstat == UNLOCKED_MAM && partition == ltfs_ip_id(vol))
new_volstat = PWE_MAM_IP;
else if (volstat == UNLOCKED_MAM && partition == ltfs_dp_id(vol))
new_volstat = PWE_MAM_DP;

if (new_volstat) {
ret_mam = tape_set_cart_volume_lock_status(vol, new_volstat);
if (ret_mam)
ret = ret_mam;
}
}

return ret;
}

Expand Down Expand Up @@ -4443,7 +4417,7 @@ static int _ltfs_write_rao_file(char *file_path_org, unsigned char *buf, size_t
ltfsmsg(LTFS_ERR, 10001E, __FILE__);
return -LTFS_NO_MEMORY;
}

arch_open(&fd, path,
O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
SHARE_FLAG_DENYRW, PERMISSION_READWRITE);
Expand Down
1 change: 1 addition & 0 deletions src/libltfs/ltfs_error.h
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,7 @@
#define EDEV_MEDIUM_MAX 20399 /* Maximum medium error value */

#define IS_MEDIUM_ERROR(e) ((e>=EDEV_MEDIUM_MIN)&&(e<=EDEV_MEDIUM_MAX))
#define IS_RW_PERM(e) ((e==EDEV_RW_PERM)||(e==EDEV_READ_PERM)||(e==EDEV_WRITE_PERM))
#define IS_READ_PERM(e) ((e==EDEV_RW_PERM)||(e==EDEV_READ_PERM)||(e==EDEV_MEDIUM_FORMAT_CORRUPTED))
#define IS_WRITE_PERM(e) ((e==EDEV_RW_PERM)||(e==EDEV_WRITE_PERM)||(e==EDEV_MEDIUM_FORMAT_CORRUPTED))

Expand Down
6 changes: 2 additions & 4 deletions src/libltfs/ltfs_fsops.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
*/

#include "ltfs.h"
#include "ltfs_error.h"
#include "ltfs_internal.h"
#include "ltfs_fsops.h"
#include "ltfs_fsops_raw.h"
Expand Down Expand Up @@ -1781,10 +1782,7 @@ int ltfs_fsops_write(struct dentry *d, const char *buf, size_t count, off_t offs
}
}

if (ret < 0)
return ret;
else
return 0;
return ret < 0? ret : 0;
}

ssize_t ltfs_fsops_read(struct dentry *d, char *buf, size_t count, off_t offset,
Expand Down
41 changes: 36 additions & 5 deletions src/tape_drivers/generic/file/filedebug_tc.c
Original file line number Diff line number Diff line change
Expand Up @@ -875,9 +875,9 @@ int filedebug_write(void *device, const char *buf, size_t count, struct tc_posit
if ( state->write_counter > state->force_writeperm ) {
ltfsmsg(LTFS_ERR, 30007E, "write");
if (state->force_errortype)
return -EDEV_NO_SENSE;
return -EDEV_WRITE_PERM;
else
return -EDEV_WRITE_PERM;
return -EDEV_NO_SENSE;
} else if ( state->write_counter > (state->force_writeperm - THRESHOLD_FORCE_WRITE_NO_WRITE) ) {
ltfsmsg(LTFS_INFO, 30019I);
++state->current_position.block;
Expand Down Expand Up @@ -1421,7 +1421,7 @@ static inline int _sanitize_tape(struct filedebug_data *state)
ret = -EDEV_MEDIUM_FORMAT_ERROR;
break;
}
}
}
else if (gen == DRIVE_GEN_JAG4) {
switch (state->conf.cart_type) {
case TC_MP_JB:
Expand Down Expand Up @@ -2798,8 +2798,39 @@ int filedebug_get_keyalias(void *device, unsigned char **keyalias)

int filedebug_takedump_drive(void *device, bool nonforced_dump)
{
/* Do nothing */
return DEVICE_GOOD;
char fname_base[1024];
char fname[1024];
time_t now;
struct tm *tm_now;
struct filedebug_data *priv = (struct filedebug_data*)device;

/* Make base filename */
time(&now);
tm_now = localtime(&now);
sprintf(fname_base, "/tmp/ltfs_%s_%d_%02d%02d_%02d%02d%02d"
, priv->serial_number
, tm_now->tm_year+1900
, tm_now->tm_mon+1
, tm_now->tm_mday
, tm_now->tm_hour
, tm_now->tm_min
, tm_now->tm_sec);

if (nonforced_dump) {
ltfsmsg(LTFS_INFO, 30261I);
strcpy(fname, fname_base);
strcat(fname, ".dmp");
} else {
ltfsmsg(LTFS_INFO, 30262I);
strcpy(fname, fname_base);
strcat(fname, "_f.dmp");
}

FILE *mockdmp = fopen(fname, "rw");
fprintf(mockdmp, "This is a mock drive dump");
fclose(mockdmp);

return 0;
}

int filedebug_is_mountable(void *device, const char *barcode, const unsigned char cart_type,
Expand Down
Loading