On partial read/write, keep reading.
This avoids rsync errors and avoids data loss with cp, due to failing to copy the last byte of 0.1953125% of files. Unless direct_io is set, fuse expects a full read/write. As a workaround for a device hanging bug, if the length of a file on a Samsung device is 500 bytes modulo 512 bytes, libmtp returns a partial read omitting the last byte which must be requested separately. Fixes #85.
This commit is contained in:
parent
19e7bb9b60
commit
2c44f913e8
|
@ -85,13 +85,41 @@ int wrap_open(const char *path, struct fuse_file_info *file_info)
|
||||||
int wrap_read(const char *path, char *buf, size_t size, off_t offset,
|
int wrap_read(const char *path, char *buf, size_t size, off_t offset,
|
||||||
struct fuse_file_info *file_info)
|
struct fuse_file_info *file_info)
|
||||||
{
|
{
|
||||||
return SMTPFileSystem::instance()->read(path, buf, size, offset, file_info);
|
if (file_info->direct_io) {
|
||||||
|
return SMTPFileSystem::instance()->read(path, buf, size, offset, file_info);
|
||||||
|
} else {
|
||||||
|
int bytes_read = 0;
|
||||||
|
while (bytes_read < size) {
|
||||||
|
int rval = SMTPFileSystem::instance()->read(path, buf + bytes_read, size - bytes_read, offset + bytes_read, file_info);
|
||||||
|
if (rval < 0) {
|
||||||
|
return rval;
|
||||||
|
} else if (rval == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bytes_read += rval;
|
||||||
|
}
|
||||||
|
return bytes_read;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int wrap_write(const char *path, const char *buf, size_t size, off_t offset,
|
int wrap_write(const char *path, const char *buf, size_t size, off_t offset,
|
||||||
struct fuse_file_info *file_info)
|
struct fuse_file_info *file_info)
|
||||||
{
|
{
|
||||||
return SMTPFileSystem::instance()->write(path, buf, size, offset, file_info);
|
if (file_info->direct_io) {
|
||||||
|
return SMTPFileSystem::instance()->write(path, buf, size, offset, file_info);
|
||||||
|
} else {
|
||||||
|
int bytes_written = 0;
|
||||||
|
while (bytes_written < size) {
|
||||||
|
int rval = SMTPFileSystem::instance()->write(path, buf + bytes_written, size - bytes_written, offset + bytes_written, file_info);
|
||||||
|
if (rval < 0) {
|
||||||
|
return rval;
|
||||||
|
} else if (rval == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bytes_written += rval;
|
||||||
|
}
|
||||||
|
return bytes_written;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int wrap_statfs(const char *path, struct statvfs *stat_info)
|
int wrap_statfs(const char *path, struct statvfs *stat_info)
|
||||||
|
|
|
@ -720,6 +720,7 @@ bool MTPDevice::listDevices(bool verbose, const std::string &dev_file)
|
||||||
continue;
|
continue;
|
||||||
std::cout << i + 1 << ": "
|
std::cout << i + 1 << ": "
|
||||||
<< (raw_devices[i].device_entry.vendor ? raw_devices[i].device_entry.vendor : "Unknown vendor ")
|
<< (raw_devices[i].device_entry.vendor ? raw_devices[i].device_entry.vendor : "Unknown vendor ")
|
||||||
|
<< ", "
|
||||||
<< (raw_devices[i].device_entry.product ? raw_devices[i].device_entry.product : "Unknown product")
|
<< (raw_devices[i].device_entry.product ? raw_devices[i].device_entry.product : "Unknown product")
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
#ifdef HAVE_LIBMTP_CHECK_CAPABILITY
|
#ifdef HAVE_LIBMTP_CHECK_CAPABILITY
|
||||||
|
|
Loading…
Reference in New Issue