Skip to content

Commit 486ce60

Browse files
author
Atsushi Abe
authored
Improve error position detention at WRITE PERM (#357)
* Correct miscalculation of last block on tape * Consider the final index on the partition as error position even if very small number is returned * Never adjust the force_writeperm threshold for better debug * Stop checking the I/F of the ltfs-backends repository
1 parent 15aea0c commit 486ce60

File tree

17 files changed

+118
-62
lines changed

17 files changed

+118
-62
lines changed

.github/workflows/build-centos7.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ jobs:
1212
uses: actions/checkout@v1
1313
- name: Build LTFS
1414
id: build
15-
uses: LinearTapeFileSystem/CentOS7-Build@v1.3
15+
uses: LinearTapeFileSystem/CentOS7-Build@v1.4
1616
with:
1717
destination: '/tmp/ltfs'

.github/workflows/build-centos8.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ jobs:
1212
uses: actions/checkout@v1
1313
- name: Build LTFS
1414
id: build
15-
uses: LinearTapeFileSystem/CentOS8-Build@v1.5
15+
uses: LinearTapeFileSystem/CentOS8-Build@v1.6
1616
with:
1717
destination: '/tmp/ltfs'

messages/iosched_unified/root.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ root:table {
6262
13022W:string { "Freeing a dentry priv with outstanding write requests. This is a bug." }
6363
//unused 13023W:string { "Failed to copy a request: will stop writing file to the index partition." }
6464
13024I:string { "Clean up extents and append index at index partition (%d)." }
65-
13025I:string { "Get error position (%d, %d)." }
65+
13025I:string { "Truncate extents larger than position (%d, %lld), block size = %ld." }
6666
13026E:string { "Write perm handling error : %s (%d)." }
67+
13027I:string { "Error position is larger than last index position: (%d, %lld), last index = %lld." }
6768
}
6869
}

messages/libltfs/root.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ root:table {
429429
11332I:string { "Load successful." }
430430
11333I:string { "A cartridge with write-perm error is detected on %s. Seek the newest index (IP: Gen = %llu, VCR = %llu) (DP: Gen = %llu, VCR = %llu) (VCR = %llu)." }
431431
11334I:string { "Remove extent : %s (%llu, %llu)." }
432-
11335D:string { "Get physical block position (%d - %d)." }
432+
//unused 11335D:string { "Get physical block position (%d - %d)." }
433433
11336I:string { "The attribute does not exist. Ignore the expected error." }
434434
11337I:string { "Update index-dirty flag (%d) - %s (0x%p)." }
435435
11338I:string { "Syncing index of %s %s." }
@@ -833,6 +833,7 @@ v
833833
17289I:string { "Skip parsing the final index on IP." }
834834
17290I:string { "Partitioning the medium with the destructive method." }
835835
17291I:string { "Unpartitioning the medium with the destructive method." }
836+
17292I:string { "Current position is (%llu, %llu), Error position is (%llu, %llu)." }
836837

837838
// For Debug 19999I:string { "%s %s %d." }
838839

src/iosched/unified.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2250,6 +2250,7 @@ int _unified_write_index_after_perm(int write_ret, struct unified_data *priv)
22502250
{
22512251
int ret = 0;
22522252
struct tc_position err_pos;
2253+
uint64_t last_index_pos = UINT64_MAX;
22532254
unsigned long blocksize;
22542255

22552256
if (!IS_WRITE_PERM(-write_ret)) {
@@ -2263,14 +2264,27 @@ int _unified_write_index_after_perm(int write_ret, struct unified_data *priv)
22632264
ltfsmsg(LTFS_ERR, 13026E, "update MAM", ret);
22642265

22652266
blocksize = ltfs_get_blocksize(priv->vol);
2266-
ret = tape_get_physical_block_position(priv->vol->device, &err_pos);
2267+
2268+
ret = tape_get_first_untransfered_position(priv->vol->device, &err_pos);
22672269
if (ret < 0) {
22682270
ltfsmsg(LTFS_ERR, 13026E, "get error pos", ret);
22692271
return ret;
22702272
}
22712273

2272-
ltfsmsg(LTFS_INFO, 13025I, (int)err_pos.block, (int)blocksize);
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+
}
22732286

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

src/libltfs/ltfs_fsops_raw.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -443,8 +443,9 @@ int ltfs_fsraw_add_extent(struct dentry *d, struct extent_info *ext, bool update
443443
int ltfs_fsraw_cleanup_extent(struct dentry *d, struct tc_position err_pos, unsigned long blocksize, struct ltfs_volume *vol)
444444
{
445445
int ret = 0;
446-
struct name_list *entry, *tmp;
446+
struct name_list *entry, *tmp;
447447
struct extent_info *ext, *preventry;
448+
struct tc_position extent_last = {0, 0, UINT32_MAX, false, false};
448449

449450
if (HASH_COUNT(d->child_list) != 0) {
450451
HASH_ITER(hh, d->child_list, entry, tmp) {
@@ -453,7 +454,24 @@ int ltfs_fsraw_cleanup_extent(struct dentry *d, struct tc_position err_pos, unsi
453454
}
454455
else {
455456
TAILQ_FOREACH_REVERSE_SAFE(ext, &entry->d->extentlist, extent_struct, list, preventry) {
456-
if (err_pos.block <= (ext->start.block + ext->bytecount/blocksize)) {
457+
if (ext->start.block && ext->bytecount) {
458+
extent_last.partition = ltfs_part_id2num(ext->start.partition, vol);
459+
/* Calculate the last block of this extent */
460+
extent_last.block = ext->start.block + (ext->bytecount / blocksize);
461+
if ( (ext->bytecount % blocksize) == 0 )
462+
extent_last.block--;
463+
} else {
464+
extent_last.partition = UINT32_MAX;
465+
extent_last.block = 0;
466+
}
467+
468+
/*
469+
* err_pos has the first block number that tape drive has it on buffer
470+
* but not transferred to the medium.
471+
* It means position (err_pos-1) is the last block on the medium.
472+
*/
473+
if ( extent_last.partition == err_pos.partition && err_pos.block <= extent_last.block ) {
474+
457475
ltfsmsg(LTFS_INFO, 11334I, entry->name, (unsigned long long)ext->start.block, (unsigned long long)ext->bytecount);
458476

459477
ret = ltfs_get_volume_lock(false, vol);

src/libltfs/tape.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,30 +1122,32 @@ int tape_update_position(struct device_data *dev, struct tc_position *pos)
11221122
return 0;
11231123
}
11241124

1125-
int tape_get_physical_block_position(struct device_data *dev, struct tc_position *pos)
1125+
int tape_get_first_untransfered_position(struct device_data *dev, struct tc_position *pos)
11261126
{
11271127
int ret;
1128-
unsigned int block;
11291128

11301129
CHECK_ARG_NULL(dev, -LTFS_NULL_ARG);
11311130
CHECK_ARG_NULL(pos, -LTFS_NULL_ARG);
11321131

1132+
/* Update current position, just in case. Because no penalty here */
11331133
ret = dev->backend->readpos(dev->backend_data, &dev->position);
11341134
if (ret < 0) {
11351135
ltfsmsg(LTFS_ERR, 17132E);
11361136
return ret;
11371137
}
11381138

1139-
ret = dev->backend->get_block_in_buffer(dev->backend_data, &block);
1139+
/* Capture first untransferred position */
1140+
ret = dev->backend->get_next_block_to_xfer(dev->backend_data, pos);
11401141
if (ret < 0) {
11411142
ltfsmsg(LTFS_ERR, 17132E);
11421143
return ret;
11431144
}
11441145

1145-
memcpy(pos, &dev->position, sizeof(struct tc_position));
1146-
1147-
ltfsmsg(LTFS_DEBUG, 11335D, (int)pos->block, block);
1148-
pos->block -= block;
1146+
ltfsmsg(LTFS_INFO, 17292I,
1147+
(unsigned long long)dev->position.partition,
1148+
(unsigned long long)dev->position.block,
1149+
(unsigned long long)pos->partition,
1150+
(unsigned long long)pos->block);
11491151

11501152
return 0;
11511153
}

src/libltfs/tape.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ int tape_update_position(struct device_data *dev, struct tc_position *pos);
165165
int tape_seek(struct device_data *dev, struct tc_position *pos);
166166
int tape_seek_eod(struct device_data *dev, tape_partition_t partition);
167167
int tape_seek_append_position(struct device_data *dev, tape_partition_t prt, bool unlock_write);
168-
int tape_get_physical_block_position(struct device_data *dev, struct tc_position *pos);
168+
int tape_get_first_untransfered_position(struct device_data *dev, struct tc_position *pos);
169169

170170
int tape_spacefm(struct device_data *dev, int count);
171171
ssize_t tape_read(struct device_data *dev, char *buf, size_t count, const bool unusual_size,

src/libltfs/tape_ops.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -915,12 +915,12 @@ struct tape_ops {
915915
int (*set_profiler)(void *device, char *work_dir, bool enable);
916916

917917
/**
918-
* Get block number stored in the drive buffer
918+
* Get first block number which is not transferred to the medium yet in the buffer
919919
* @param device A pointer to the tape device
920-
* @param block Number of blocks stored in the drive buffer
920+
* @param pos Position of the record that is not transferred yet in the buffer
921921
* @return 0 on success or a negative value on error
922922
*/
923-
int (*get_block_in_buffer)(void *device, unsigned int *block);
923+
int (*get_next_block_to_xfer)(void *device, struct tc_position *pos);
924924

925925
/**
926926
* Check if the generation of tape drive and the current loaded cartridge is read-only combination

src/tape_drivers/freebsd/cam/cam_tc.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,10 +1193,10 @@ int camtape_unload(void *device, struct tc_position *pos)
11931193
}
11941194

11951195
/*
1196-
* Get the number of blocks in the buffer on the tape drive after a write. Eventually it would
1196+
* Get the first block position that is not transferred to the medium. Eventually it would
11971197
* be nice to include this in status information returned from the sa(4) driver.
11981198
*/
1199-
static int camtape_get_block_in_buffer(void *device, uint32_t *block)
1199+
static int camtape_get_next_block_to_xfer(void *device, struct tc_position *pos)
12001200
{
12011201
int rc;
12021202
union ccb *ccb = NULL;
@@ -1240,9 +1240,10 @@ static int camtape_get_block_in_buffer(void *device, uint32_t *block)
12401240
if (rc != DEVICE_GOOD)
12411241
camtape_process_errors(softc, rc, msg, "READPOS", true);
12421242
else {
1243-
*block = scsi_3btoul(ext_data.num_objects);
1244-
ltfsmsg(LTFS_DEBUG, 30398D, "blocks-in-buffer",
1245-
(unsigned long long) *block, 0, 0, softc->drive_serial);
1243+
pos->partition = ext_data.partition;
1244+
pos->block = scsi_8btou64(ext_data.last_object)
1245+
ltfsmsg(LTFS_DEBUG, 30398D, "next-block-to-xfer",
1246+
(unsigned long long) pos->block, 0, 0, softc->drive_serial);
12461247
}
12471248

12481249
bailout:
@@ -4170,7 +4171,7 @@ struct tape_ops camtape_drive_handler = {
41704171
.get_serialnumber = camtape_get_serialnumber,
41714172
.get_info = camtape_get_info,
41724173
.set_profiler = camtape_set_profiler,
4173-
.get_block_in_buffer = camtape_get_block_in_buffer,
4174+
.get_next_block_to_xfer = camtape_get_next_block_to_xfer,
41744175
.is_readonly = camtape_is_readonly
41754176
};
41764177

0 commit comments

Comments
 (0)