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
2 changes: 1 addition & 1 deletion src/libltfs/ltfs_fuse_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@
#ifndef __ltfs_fuse_version_h__
#define __ltfs_fuse_version_h__

#define FUSE_USE_VERSION 26
#define FUSE_USE_VERSION 30

#endif /* __ltfs_fuse_version_h__ */
19 changes: 12 additions & 7 deletions src/ltfs_fuse.c
Original file line number Diff line number Diff line change
Expand Up @@ -853,9 +853,9 @@ int _ltfs_fuse_filldir(void *buf, const char *name, void *priv)
return ret;
}

ret = filler(buf, new_name, NULL, 0);
ret = filler(buf, new_name, NULL, 0, 0);
#else
ret = filler(buf, name, NULL, 0);
ret = filler(buf, name, NULL, 0, 0);
#endif

free(new_name);
Expand All @@ -875,12 +875,12 @@ int ltfs_fuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler,

ltfsmsg(LTFS_DEBUG, 14047D, _dentry_name(path, file->file_info));

if (filler(buf, ".", NULL, 0)) {
if (filler(buf, ".", NULL, 0, 0)) {
/* No buffer space */
ltfsmsg(LTFS_DEBUG, 14026D);
return -ENOBUFS;
}
if (filler(buf, "..", NULL, 0)) {
if (filler(buf, "..", NULL, 0, 0)) {
/* No buffer space */
ltfsmsg(LTFS_DEBUG, 14026D);
return -ENOBUFS;
Expand Down Expand Up @@ -1068,6 +1068,14 @@ void * ltfs_fuse_mount(struct fuse_conn_info *conn)

ltfs_request_trace(FUSE_REQ_ENTER(REQ_MOUNT), 0, 0);

/* FUSE3: Disable async reads to prevent unnecessary tape repositioning.
* The -osync_read option was removed in FUSE3. Async read is now controlled
* via FUSE_CAP_ASYNC_READ in the init() callback (this function).
* See: https://github.com/libfuse/libfuse/blob/master/ChangeLog.rst
*/
if (conn->capable & FUSE_CAP_ASYNC_READ)
conn->want &= ~FUSE_CAP_ASYNC_READ;

if (priv->pid_orig != getpid()) {
/*
* Reopen device when LTFS was forked in fuse_main().
Expand Down Expand Up @@ -1206,7 +1214,6 @@ struct fuse_operations ltfs_ops = {
.init = ltfs_fuse_mount,
.destroy = ltfs_fuse_umount,
.getattr = ltfs_fuse_getattr,
.fgetattr = ltfs_fuse_fgetattr,
.access = ltfs_fuse_access,
.statfs = ltfs_fuse_statfs,
.open = ltfs_fuse_open,
Expand All @@ -1218,7 +1225,6 @@ struct fuse_operations ltfs_ops = {
.chown = ltfs_fuse_chown,
.create = ltfs_fuse_create,
.truncate = ltfs_fuse_truncate,
.ftruncate = ltfs_fuse_ftruncate,
.unlink = ltfs_fuse_unlink,
.rename = ltfs_fuse_rename,
.mkdir = ltfs_fuse_mkdir,
Expand All @@ -1236,6 +1242,5 @@ struct fuse_operations ltfs_ops = {
.symlink = ltfs_fuse_symlink,
.readlink = ltfs_fuse_readlink,
#if FUSE_VERSION >= 28
.flag_nullpath_ok = 1,
#endif
};
55 changes: 29 additions & 26 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#include <grp.h>

#include "ltfs_fuse.h"
#include <fuse3/fuse_lowlevel.h>
#include "libltfs/ltfs.h"
#include "ltfs_copyright.h"
#include "libltfs/pathname.h"
Expand Down Expand Up @@ -747,20 +748,17 @@ int main(int argc, char **argv)
}

/* Unlink objects from the file system instead of having them renamed to .fuse_hidden */
ret = fuse_opt_add_arg(&args, "-ohard_remove");
/* FUSE3: removed deprecated option: ret = fuse_opt_add_arg(&args, "-ohard_remove"); */
Comment on lines -750 to +751
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hard remove also does not seem deprecated but discouraged.
TBD if this is an issue

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for investigating this. I will wait for your findings on whether
hard_remove causes any issues. Please let me know and I will update accordingly.

if (ret < 0) {
/* Could not enable FUSE option */
ltfsmsg(LTFS_ERR, 14001E, "hard_remove", ret);
/* FUSE3: removed deprecated option: ltfsmsg(LTFS_ERR, 14001E, "hard_remove", ret); */
return 1;
}

/* perform reads synchronously */
ret = fuse_opt_add_arg(&args, "-osync_read");
if (ret < 0) {
/* Could not enable FUSE option */
ltfsmsg(LTFS_ERR, 14001E, "sync_read", ret);
return 1;
}
/* FUSE3: The -osync_read option was removed in FUSE3.
* Async read is now disabled via FUSE_CAP_ASYNC_READ in the
* init() callback (see ltfs_fuse_mount() in ltfs_fuse.c).
*/

#ifdef __APPLE__
/* Change MacFUSE timeout from 60 secs to 3100 secs (41mins) */
Expand Down Expand Up @@ -788,11 +786,11 @@ int main(int argc, char **argv)
#endif

#if FUSE_VERSION >= 28
/* For FUSE 2.8 or higher, automatically enable big_writes */
ret = fuse_opt_add_arg(&args, "-obig_writes");
/* FUSE3: removed deprecated option: For FUSE 2.8 or higher, automatically enable big_writes */
/* FUSE3: removed deprecated option: ret = fuse_opt_add_arg(&args, "-obig_writes"); */
if (ret < 0) {
/* Could not enable FUSE option */
ltfsmsg(LTFS_ERR, 14001E, "big_writes", ret);
/* FUSE3: removed deprecated option: ltfsmsg(LTFS_ERR, 14001E, "big_writes", ret); */
return 1;
}
#endif
Expand Down Expand Up @@ -974,14 +972,15 @@ int single_drive_main(struct fuse_args *args, struct ltfs_fuse_data *priv)
/* If the local inode space is big enough, have FUSE pass through our UIDs as inode
* numbers instead of generating its own. */
if (sizeof(ino_t) >= 8) {
ret = fuse_opt_add_arg(args, "-ouse_ino");
if (ret < 0) {
/* Could not enable FUSE option */
ltfsmsg(LTFS_ERR, 14001E, "use_ino", ret);
return 1;
}
}

/* FUSE3: use_ino option removed in FUSE3 */
/* ret = fuse_opt_add_arg(args, "-ouse_ino"); */
if (ret < 0) {
/* Could not enable FUSE option */
/* FUSE3: removed deprecated option: ltfsmsg(LTFS_ERR, 14001E, "use_ino", ret); */
return 1;
}
}

/* Set file system name to "ltfs:devname" in case FUSE doesn't pick it up */
snprintf(fsname, sizeof(fsname), "-ofsname=ltfs:%s", priv->devname);
ret = fuse_opt_add_arg(args, fsname);
Expand Down Expand Up @@ -1223,12 +1222,16 @@ int single_drive_main(struct fuse_args *args, struct ltfs_fuse_data *priv)
for ( i=0; i<args->argc; i++) {
fuse_opt_add_arg(&tmpa, args->argv[i]);
}
ret = fuse_parse_cmdline( &tmpa, &mountpoint, NULL, NULL);
fuse_opt_free_args(&tmpa);
if (ret < 0 || mountpoint == NULL) {
ltfsmsg(LTFS_ERR, 14094E, ret);
ltfs_volume_free(&priv->data);
return 1;
{
struct fuse_cmdline_opts fuse_opts;
ret = fuse_parse_cmdline(&tmpa, &fuse_opts);
fuse_opt_free_args(&tmpa);
if (ret < 0 || fuse_opts.mountpoint == NULL) {
ltfsmsg(LTFS_ERR, 14094E, ret);
ltfs_volume_free(&priv->data);
return 1;
}
mountpoint = fuse_opts.mountpoint;
}
priv->data->mountpoint = mountpoint;
priv->data->mountpoint_len = strlen(mountpoint);
Expand Down
1 change: 1 addition & 0 deletions src/tape_drivers/hp_tape.c
Copy link
Copy Markdown
Member

@Piloalucard Piloalucard May 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @mhorimoto ! Thank you for opening this PR! Seems good so far, I will continue reviewing, but I think we may need to also add from LTO-5 to LTO-9, within the same format you used.
https://ltoworld.com/ I used this page as a source to see which LTO drives exists for Tandberg, renamed to Overland. One constraint is that we do not have Tandberg/Overland hardware to test them.
What do you think?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @Piloalucard san.
Thank you for your review!
I will research the Tandberg/Overland LTO-5 to LTO-9 drive entries using ltoworld.com and add them in the same format.
However, I only have a Tandberg LTO-6 drive, so I can only verify the LTO-6 entry with actual hardware. The other entries (LTO-5, LTO-7 to LTO-9) will be based on research only, without real device testing.
I'll update this PR once the investigation is complete.

Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ struct supported_device *hp_supported_drives[] = {
TAPEDRIVE( HP_VENDOR_ID, "Ultrium 7-SCSI", DRIVE_LTO7, "[Ultrium 7-SCSI]" ), /* HP Ultrium Gen 7 */
TAPEDRIVE( HPE_VENDOR_ID, "Ultrium 8-SCSI", DRIVE_LTO8, "[Ultrium 8-SCSI]" ), /* HPE Ultrium Gen 8 */
TAPEDRIVE( HPE_VENDOR_ID, "Ultrium 9-SCSI", DRIVE_LTO9, "[Ultrium 9-SCSI]" ), /* HPE Ultrium Gen 9 */
TAPEDRIVE( TANDBERG_VENDOR_ID, "LTO-6 HH ", DRIVE_LTO6_HH, "[LTO-6 HH]" ), /* TANDBERG LTO-6 HH */
/* End of supported_devices */
NULL
};
Expand Down
1 change: 1 addition & 0 deletions src/tape_drivers/hp_tape.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ extern "C" {

#define HP_VENDOR_ID "HP"
#define HPE_VENDOR_ID "HPE"
#define TANDBERG_VENDOR_ID "TANDBERG"

extern struct error_table hp_tape_errors[];

Expand Down
2 changes: 1 addition & 1 deletion src/tape_drivers/linux/sg/sg_tape.c
Original file line number Diff line number Diff line change
Expand Up @@ -3031,7 +3031,7 @@ int sg_remaining_capacity(void *device, struct tc_remaining_cap *cap)

memset(buffer, 0, LOGSENSEPAGE);

if (IS_LTO(priv->drive_type) && (DRIVE_GEN(priv->drive_type) == 0x05)) {
if (IS_LTO(priv->drive_type) && (DRIVE_GEN(priv->drive_type) == 0x05 || priv->vendor == VENDOR_TANDBERG)) {
/* Use LogPage 0x31 */
ret = sg_logsense(device, (uint8_t)LOG_TAPECAPACITY, (uint8_t)0, (void *)buffer, LOGSENSEPAGE);
if(ret < 0)
Expand Down
1 change: 1 addition & 0 deletions src/tape_drivers/tape_drivers.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ enum {
VENDOR_IBM,
VENDOR_HP,
VENDOR_QUANTUM,
VENDOR_TANDBERG,
};

enum {
Expand Down
11 changes: 11 additions & 0 deletions src/tape_drivers/vendor_compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,8 @@ int get_vendor_id(char* vendor)
return VENDOR_HP;
else if (!strncmp(vendor, HPE_VENDOR_ID, strlen(HPE_VENDOR_ID)))
return VENDOR_HP;
else if (!strncmp(vendor, TANDBERG_VENDOR_ID, strlen(TANDBERG_VENDOR_ID)))
return VENDOR_TANDBERG;
else if (!strncmp(vendor, QUANTUM_VENDOR_ID, strlen(QUANTUM_VENDOR_ID)))
return VENDOR_QUANTUM;
else
Expand All @@ -309,6 +311,9 @@ struct supported_device **get_supported_devs(int vendor)
case VENDOR_QUANTUM:
cur = quantum_supported_drives;
break;
case VENDOR_TANDBERG:
cur = hp_supported_drives;
break;
}

return cur;
Expand Down Expand Up @@ -412,6 +417,9 @@ void init_error_table(int vendor,
case VENDOR_QUANTUM:
*vendor_table = quantum_tape_errors;
break;
case VENDOR_TANDBERG:
*vendor_table = hp_tape_errors;
break;
}
}

Expand All @@ -429,6 +437,9 @@ int init_timeout(int vendor, struct timeout_tape **table, int type)
case VENDOR_QUANTUM:
ret = quantum_tape_init_timeout(table, type);
break;
case VENDOR_TANDBERG:
ret = hp_tape_init_timeout(table, type);
break;
}

return ret;
Expand Down