diff --git a/src/iosched/unified.c b/src/iosched/unified.c index f492e12f..f600f998 100644 --- a/src/iosched/unified.c +++ b/src/iosched/unified.c @@ -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" @@ -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. @@ -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 { @@ -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 { @@ -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); @@ -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) { @@ -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 diff --git a/src/libltfs/iosched.c b/src/libltfs/iosched.c index a2abcd30..bad1c2dc 100644 --- a/src/libltfs/iosched.c +++ b/src/libltfs/iosched.c @@ -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 { @@ -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. @@ -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; } /** diff --git a/src/libltfs/ltfs.c b/src/libltfs/ltfs.c index c0c624b3..27dc888f 100644 --- a/src/libltfs/ltfs.c +++ b/src/libltfs/ltfs.c @@ -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" @@ -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; @@ -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; @@ -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; } } @@ -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; } @@ -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; } @@ -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; } @@ -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); diff --git a/src/libltfs/ltfs_error.h b/src/libltfs/ltfs_error.h index c762520e..8283ffcd 100644 --- a/src/libltfs/ltfs_error.h +++ b/src/libltfs/ltfs_error.h @@ -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)) diff --git a/src/libltfs/ltfs_fsops.c b/src/libltfs/ltfs_fsops.c index 7b2aa4d4..ce56c5d7 100644 --- a/src/libltfs/ltfs_fsops.c +++ b/src/libltfs/ltfs_fsops.c @@ -56,6 +56,7 @@ */ #include "ltfs.h" +#include "ltfs_error.h" #include "ltfs_internal.h" #include "ltfs_fsops.h" #include "ltfs_fsops_raw.h" @@ -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, diff --git a/src/tape_drivers/generic/file/filedebug_tc.c b/src/tape_drivers/generic/file/filedebug_tc.c index 615517f0..9dfda747 100644 --- a/src/tape_drivers/generic/file/filedebug_tc.c +++ b/src/tape_drivers/generic/file/filedebug_tc.c @@ -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; @@ -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: @@ -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,