Skip to content

Commit c0aeabf

Browse files
author
mcardenas
committed
fix: race condition for device error propagation
fix: NO_SENSE errortype when it should be backwards fix: unified simple problems
1 parent 1f1ee3c commit c0aeabf

6 files changed

Lines changed: 113 additions & 101 deletions

File tree

src/iosched/unified.c

Lines changed: 4 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
*/
5757

5858
#include "libltfs/ltfs.h"
59+
#include "libltfs/ltfs_locking_old.h"
5960
#include "libltfs/tape.h"
6061
#include "libltfs/ltfs_fsops_raw.h"
6162
#include "libltfs/index_criteria.h"
@@ -252,7 +253,6 @@ void _unified_unset_write_ip(struct dentry_priv *dpr, struct unified_data *priv)
252253
void _unified_handle_write_error(ssize_t write_ret, struct write_request *req,
253254
struct dentry_priv *dpr, struct unified_data *priv);
254255
int _unified_get_write_error(struct dentry_priv *dpr);
255-
int _unified_write_index_after_perm(int write_ret, struct unified_data *priv);
256256

257257
/**
258258
* Initialize an instance of the unified scheduler.
@@ -1189,9 +1189,6 @@ void _unified_process_index_queue(struct unified_data *priv)
11891189
if (ret < 0) {
11901190
/* Index partition writer: failed to write data to the tape (%d) */
11911191
ltfsmsg(LTFS_WARN, 13013W, (int)ret);
1192-
if (IS_WRITE_PERM(-ret)) {
1193-
ret = tape_set_cart_volume_lock_status(priv->vol, PWE_MAM_IP);
1194-
}
11951192
_unified_handle_write_error(ret, req, dentry_priv, priv);
11961193
break;
11971194
} else {
@@ -1283,7 +1280,6 @@ void _unified_process_data_queue(enum request_state queue, struct unified_data *
12831280
if (ret < 0) {
12841281
/* Data partition writer: failed to write data to the tape (%d) */
12851282
ltfsmsg(LTFS_WARN, 13014W, (int)ret);
1286-
(void)_unified_write_index_after_perm(ret, priv);
12871283
_unified_handle_write_error(ret, req, dentry_priv, priv);
12881284
break;
12891285
} else {
@@ -1314,7 +1310,9 @@ void _unified_process_data_queue(enum request_state queue, struct unified_data *
13141310
if (ret < 0) {
13151311
/* Data partition writer: failed to write data to the tape (%d) */
13161312
ltfsmsg(LTFS_WARN, 13014W, (int)ret);
1317-
(void)_unified_write_index_after_perm(ret, priv);
1313+
1314+
// Note: Do we need to handle these errors?
1315+
// _unified_handle_write_error(ret, req, dentry_priv, priv);
13181316
break;
13191317
} else {
13201318
TAILQ_REMOVE(&local_req_list, req, list);
@@ -1961,7 +1959,6 @@ int _unified_flush_unlocked(struct dentry *d, struct unified_data *priv)
19611959
ret = ltfs_fsraw_write(d, req_cache, req->count, req->offset, dp_id, false, priv->vol);
19621960
if (ret < 0) {
19631961
ltfsmsg(LTFS_ERR, 13019E, (int)ret);
1964-
(void)_unified_write_index_after_perm(ret, priv);
19651962
_unified_handle_write_error(ret, req, dpr, priv);
19661963
break;
19671964
} else if (dpr->write_ip) {
@@ -2246,56 +2243,6 @@ int _unified_get_write_error(struct dentry_priv *dpr)
22462243
return ret;
22472244
}
22482245

2249-
int _unified_write_index_after_perm(int write_ret, struct unified_data *priv)
2250-
{
2251-
int ret = 0;
2252-
struct tc_position err_pos;
2253-
uint64_t last_index_pos = UINT64_MAX;
2254-
unsigned long blocksize;
2255-
2256-
if (!IS_WRITE_PERM(-write_ret)) {
2257-
/* Nothing to do for non-medium error */
2258-
return ret;
2259-
}
2260-
2261-
ltfsmsg(LTFS_INFO, 13024I, write_ret);
2262-
ret = tape_set_cart_volume_lock_status(priv->vol, PWE_MAM_DP);
2263-
if (ret < 0)
2264-
ltfsmsg(LTFS_ERR, 13026E, "update MAM", ret);
2265-
2266-
blocksize = ltfs_get_blocksize(priv->vol);
2267-
2268-
ret = tape_get_first_untransfered_position(priv->vol->device, &err_pos);
2269-
if (ret < 0) {
2270-
ltfsmsg(LTFS_ERR, 13026E, "get error pos", ret);
2271-
return ret;
2272-
}
2273-
2274-
/* Check the err_pos is larger than the last index position of the partition */
2275-
if (err_pos.partition == ltfs_part_id2num(priv->vol->label->partid_ip, priv->vol)) {
2276-
last_index_pos = priv->vol->ip_coh.set_id;
2277-
} else {
2278-
last_index_pos = priv->vol->dp_coh.set_id;
2279-
}
2280-
2281-
if (last_index_pos > err_pos.block) {
2282-
ltfsmsg(LTFS_INFO, 13027I, (int)err_pos.partition,
2283-
(unsigned long long)err_pos.block, (unsigned long long)last_index_pos);
2284-
err_pos.block = last_index_pos + 1;
2285-
}
2286-
2287-
ltfsmsg(LTFS_INFO, 13025I, (int)err_pos.partition, (unsigned long long)err_pos.block, blocksize);
2288-
ret = ltfs_fsraw_cleanup_extent(priv->vol->index->root, err_pos, blocksize, priv->vol);
2289-
if (ret < 0) {
2290-
ltfsmsg(LTFS_ERR, 13026E, "extent cleanup", ret);
2291-
return ret;
2292-
}
2293-
2294-
ret = ltfs_write_index(ltfs_ip_id(priv->vol), SYNC_WRITE_PERM, priv->vol);
2295-
2296-
return ret;
2297-
}
2298-
22992246
/**
23002247
* Enable profiler function
23012248
* @param work_dir work directory to store profiler data

src/libltfs/iosched.c

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,11 @@
5050
**
5151
*************************************************************************************
5252
*/
53+
#include "ltfs_error.h"
5354
#include "ltfs_fuse.h"
55+
#include "ltfs_fsops_raw.h"
5456
#include "ltfs.h"
57+
#include "tape.h"
5558
#include "iosched.h"
5659

5760
struct iosched_priv {
@@ -61,6 +64,53 @@ struct iosched_priv {
6164
void *backend_handle; /**< Backend private data */
6265
};
6366

67+
int _iosched_write_index_after_perm(int write_ret, struct ltfs_volume *volume)
68+
{
69+
int ret = 0;
70+
struct tc_position err_pos;
71+
uint64_t last_index_pos = UINT64_MAX;
72+
unsigned long blocksize;
73+
74+
if (!IS_WRITE_PERM(-write_ret)) {
75+
/* Nothing to do for non-medium error */
76+
return ret;
77+
}
78+
79+
ltfsmsg(LTFS_INFO, 13024I, write_ret);
80+
blocksize = ltfs_get_blocksize(volume);
81+
82+
ret = tape_get_first_untransfered_position(volume->device, &err_pos);
83+
if (ret < 0) {
84+
ltfsmsg(LTFS_ERR, 13026E, "get error pos", ret);
85+
return ret;
86+
}
87+
88+
/* Check the err_pos is larger than the last index position of the partition */
89+
if (err_pos.partition == ltfs_part_id2num(volume->label->partid_ip, volume)) {
90+
last_index_pos = volume->ip_coh.set_id;
91+
} else {
92+
last_index_pos = volume->dp_coh.set_id;
93+
}
94+
95+
if (last_index_pos > err_pos.block) {
96+
ltfsmsg(LTFS_INFO, 13027I, (int)err_pos.partition,
97+
(unsigned long long)err_pos.block, (unsigned long long)last_index_pos);
98+
err_pos.block = last_index_pos + 1;
99+
}
100+
101+
ltfsmsg(LTFS_INFO, 13025I, (int)err_pos.partition, (unsigned long long)err_pos.block, blocksize);
102+
ret = ltfs_fsraw_cleanup_extent(volume->index->root, err_pos, blocksize, volume);
103+
if (ret < 0) {
104+
ltfsmsg(LTFS_ERR, 13026E, "extent cleanup", ret);
105+
return ret;
106+
}
107+
108+
ret = ltfs_write_index(ltfs_ip_id(volume), SYNC_WRITE_PERM, volume);
109+
110+
return ret;
111+
}
112+
113+
64114
/**
65115
* Initialize the I/O scheduler.
66116
* @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
230280
CHECK_ARG_NULL(d, -LTFS_NULL_ARG);
231281

232282
ret = priv->ops->write(d, buf, size, offset, isupdatetime, priv->backend_handle);
233-
if (ret > 0 && (size_t) ret > size)
234-
ret = size;
283+
// TODO: Add logs to this thing
284+
if (ret < 0) {
285+
if (IS_WRITE_PERM(-ret)) {
286+
mam_lockval vollock = d->matches_name_criteria ? PWE_MAM_IP : PWE_MAM_DP;
287+
int sync_ret = _iosched_write_index_after_perm(ret, vol);
288+
if (sync_ret < 0) {
289+
tape_set_cart_volume_lock_status(vol, PWE_MAM);
290+
return sync_ret;
291+
}
292+
tape_set_cart_volume_lock_status(vol, vollock);
293+
}
294+
return ret;
295+
}
235296

236-
return ret;
297+
return ret > (ssize_t)size? (ssize_t)size : ret;
237298
}
238299

239300
/**

src/libltfs/ltfs.c

Lines changed: 6 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959

6060
#include "fs.h"
6161
#include "ltfs.h"
62+
#include "ltfs_error.h"
6263
#include "ltfs_internal.h"
6364
#include "libltfs/ltfslogging.h"
6465
#include "ltfs_copyright.h"
@@ -2431,15 +2432,14 @@ size_t ltfs_max_cache_size(struct ltfs_volume *vol)
24312432
*/
24322433
int ltfs_write_index(char partition, char *reason, struct ltfs_volume *vol)
24332434
{
2434-
int ret, ret_mam;
2435+
int ret;
24352436
struct tape_offset old_selfptr, old_backptr;
24362437
struct ltfs_timespec modtime_old = { .tv_sec = 0, .tv_nsec = 0 };
24372438
bool generation_inc = false;
24382439
struct tc_position physical_selfptr, current_position;
24392440
char *cache_path_save = NULL;
24402441
bool write_perm = (strcmp(reason, SYNC_WRITE_PERM) == 0);
2441-
bool update_vollock = false;
2442-
int volstat = -1, new_volstat = 0;
2442+
int volstat = -1;
24432443
char *bc_print = NULL;
24442444
unsigned long long diff;
24452445

@@ -2567,13 +2567,13 @@ int ltfs_write_index(char partition, char *reason, struct ltfs_volume *vol)
25672567
return -1;
25682568
}
25692569

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

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

2597-
if (IS_WRITE_PERM(-ret))
2598-
update_vollock = true;
2599-
26002597
goto out_write_perm;
26012598
}
26022599
}
@@ -2614,9 +2611,6 @@ int ltfs_write_index(char partition, char *reason, struct ltfs_volume *vol)
26142611
vol->index->backptr = old_backptr;
26152612
vol->index->selfptr = old_selfptr;
26162613

2617-
if (IS_WRITE_PERM(-ret))
2618-
update_vollock = true;
2619-
26202614
goto out_write_perm;
26212615
}
26222616

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

2634-
if (IS_WRITE_PERM(-ret))
2635-
update_vollock = true;
2636-
26372628
goto out_write_perm;
26382629
}
26392630

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

2680-
if (update_vollock) {
2681-
if (volstat == PWE_MAM_DP && partition == ltfs_ip_id(vol))
2682-
new_volstat = PWE_MAM_BOTH;
2683-
else if (volstat == PWE_MAM_IP && partition == ltfs_dp_id(vol))
2684-
new_volstat = PWE_MAM_BOTH;
2685-
else if (volstat == UNLOCKED_MAM && partition == ltfs_ip_id(vol))
2686-
new_volstat = PWE_MAM_IP;
2687-
else if (volstat == UNLOCKED_MAM && partition == ltfs_dp_id(vol))
2688-
new_volstat = PWE_MAM_DP;
2689-
2690-
if (new_volstat) {
2691-
ret_mam = tape_set_cart_volume_lock_status(vol, new_volstat);
2692-
if (ret_mam)
2693-
ret = ret_mam;
2694-
}
2695-
}
2696-
26972671
return ret;
26982672
}
26992673

@@ -4443,7 +4417,7 @@ static int _ltfs_write_rao_file(char *file_path_org, unsigned char *buf, size_t
44434417
ltfsmsg(LTFS_ERR, 10001E, __FILE__);
44444418
return -LTFS_NO_MEMORY;
44454419
}
4446-
4420+
44474421
arch_open(&fd, path,
44484422
O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
44494423
SHARE_FLAG_DENYRW, PERMISSION_READWRITE);

src/libltfs/ltfs_error.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,7 @@
383383
#define EDEV_MEDIUM_MAX 20399 /* Maximum medium error value */
384384

385385
#define IS_MEDIUM_ERROR(e) ((e>=EDEV_MEDIUM_MIN)&&(e<=EDEV_MEDIUM_MAX))
386+
#define IS_RW_PERM(e) ((e==EDEV_RW_PERM)||(e==EDEV_READ_PERM)||(e==EDEV_WRITE_PERM))
386387
#define IS_READ_PERM(e) ((e==EDEV_RW_PERM)||(e==EDEV_READ_PERM)||(e==EDEV_MEDIUM_FORMAT_CORRUPTED))
387388
#define IS_WRITE_PERM(e) ((e==EDEV_RW_PERM)||(e==EDEV_WRITE_PERM)||(e==EDEV_MEDIUM_FORMAT_CORRUPTED))
388389

src/libltfs/ltfs_fsops.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
*/
5757

5858
#include "ltfs.h"
59+
#include "ltfs_error.h"
5960
#include "ltfs_internal.h"
6061
#include "ltfs_fsops.h"
6162
#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
17811782
}
17821783
}
17831784

1784-
if (ret < 0)
1785-
return ret;
1786-
else
1787-
return 0;
1785+
return ret < 0? ret : 0;
17881786
}
17891787

17901788
ssize_t ltfs_fsops_read(struct dentry *d, char *buf, size_t count, off_t offset,

src/tape_drivers/generic/file/filedebug_tc.c

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -875,9 +875,9 @@ int filedebug_write(void *device, const char *buf, size_t count, struct tc_posit
875875
if ( state->write_counter > state->force_writeperm ) {
876876
ltfsmsg(LTFS_ERR, 30007E, "write");
877877
if (state->force_errortype)
878-
return -EDEV_NO_SENSE;
878+
return -EDEV_WRITE_PERM;
879879
else
880-
return -EDEV_WRITE_PERM;
880+
return -EDEV_NO_SENSE;
881881
} else if ( state->write_counter > (state->force_writeperm - THRESHOLD_FORCE_WRITE_NO_WRITE) ) {
882882
ltfsmsg(LTFS_INFO, 30019I);
883883
++state->current_position.block;
@@ -1421,7 +1421,7 @@ static inline int _sanitize_tape(struct filedebug_data *state)
14211421
ret = -EDEV_MEDIUM_FORMAT_ERROR;
14221422
break;
14231423
}
1424-
}
1424+
}
14251425
else if (gen == DRIVE_GEN_JAG4) {
14261426
switch (state->conf.cart_type) {
14271427
case TC_MP_JB:
@@ -2798,8 +2798,39 @@ int filedebug_get_keyalias(void *device, unsigned char **keyalias)
27982798

27992799
int filedebug_takedump_drive(void *device, bool nonforced_dump)
28002800
{
2801-
/* Do nothing */
2802-
return DEVICE_GOOD;
2801+
char fname_base[1024];
2802+
char fname[1024];
2803+
time_t now;
2804+
struct tm *tm_now;
2805+
struct filedebug_data *priv = (struct filedebug_data*)device;
2806+
2807+
/* Make base filename */
2808+
time(&now);
2809+
tm_now = localtime(&now);
2810+
sprintf(fname_base, "/tmp/ltfs_%s_%d_%02d%02d_%02d%02d%02d"
2811+
, priv->serial_number
2812+
, tm_now->tm_year+1900
2813+
, tm_now->tm_mon+1
2814+
, tm_now->tm_mday
2815+
, tm_now->tm_hour
2816+
, tm_now->tm_min
2817+
, tm_now->tm_sec);
2818+
2819+
if (nonforced_dump) {
2820+
ltfsmsg(LTFS_INFO, 30261I);
2821+
strcpy(fname, fname_base);
2822+
strcat(fname, ".dmp");
2823+
} else {
2824+
ltfsmsg(LTFS_INFO, 30262I);
2825+
strcpy(fname, fname_base);
2826+
strcat(fname, "_f.dmp");
2827+
}
2828+
2829+
FILE *mockdmp = fopen(fname, "rw");
2830+
fprintf(mockdmp, "This is a mock drive dump");
2831+
fclose(mockdmp);
2832+
2833+
return 0;
28032834
}
28042835

28052836
int filedebug_is_mountable(void *device, const char *barcode, const unsigned char cart_type,

0 commit comments

Comments
 (0)