pull/48/merge
kgermanov 2023-07-10 17:51:43 +04:00 committed by GitHub
commit 3a7a8266ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 118 additions and 35 deletions

View File

@ -90,6 +90,8 @@ struct ntfs_device {
heads or -1. */
int d_sectors_per_track; /* Disk geometry: number of
sectors per track or -1. */
s64 dev_offset; /* Offset from the start of the device
where the ntfs filesystem begins.*/
};
struct stat;
@ -117,6 +119,9 @@ struct ntfs_device_operations {
extern struct ntfs_device *ntfs_device_alloc(const char *name, const long state,
struct ntfs_device_operations *dops, void *priv_data);
extern struct ntfs_device *ntfs_device_alloc_ext(const char *name, const long state,
struct ntfs_device_operations *dops, void *priv_data, s64 dev_offset);
extern int ntfs_device_free(struct ntfs_device *dev);
extern int ntfs_device_sync(struct ntfs_device *dev);

View File

@ -299,6 +299,7 @@ extern ntfs_volume *ntfs_device_mount(struct ntfs_device *dev,
ntfs_mount_flags flags);
extern ntfs_volume *ntfs_mount(const char *name, ntfs_mount_flags flags);
extern ntfs_volume *ntfs_mount_ext(const char *name, ntfs_mount_flags flags, const s64 dev_offset);
extern int ntfs_umount(ntfs_volume *vol, const BOOL force);
extern int ntfs_version_is_supported(ntfs_volume *vol);

View File

@ -114,6 +114,30 @@
struct ntfs_device *ntfs_device_alloc(const char *name, const long state,
struct ntfs_device_operations *dops, void *priv_data)
{
return ntfs_device_alloc_ext(name, state, dops, priv_data, 0);
}
/**
* ntfs_device_alloc_ext - allocate an ntfs device structure and pre-initialize it
* @name: name of the device (must be present)
* @state: initial device state (usually zero)
* @dops: ntfs device operations to use with the device (must be present)
* @priv_data: pointer to private data (optional)
* @dev_offset: offset from beginning of device where the ntfs filesystem begins
*
* Allocate an ntfs device structure and pre-initialize it with the user-
* specified device operations @dops, device state @state, device name @name,
* and optional private data @priv_data.
*
* Note, @name is copied and can hence be freed after this functions returns.
*
* On success return a pointer to the allocated ntfs device structure and on
* error return NULL with errno set to the error code returned by ntfs_malloc().
*/
struct ntfs_device *ntfs_device_alloc_ext(const char *name, const long state,
struct ntfs_device_operations *dops, void *priv_data, const s64 dev_offset)
{
struct ntfs_device *dev;
if (!name) {
@ -134,6 +158,7 @@ struct ntfs_device *ntfs_device_alloc(const char *name, const long state,
dev->d_private = priv_data;
dev->d_heads = -1;
dev->d_sectors_per_track = -1;
dev->dev_offset = dev_offset;
}
return dev;
}
@ -541,7 +566,7 @@ s64 ntfs_device_size_get(struct ntfs_device *dev, int block_size)
ntfs_log_debug("BLKGETSIZE64 nr bytes = %llu (0x%llx)\n",
(unsigned long long)size,
(unsigned long long)size);
return (s64)size / block_size;
return (s64)(size - dev->dev_offset) / block_size;
}
}
#endif
@ -551,7 +576,7 @@ s64 ntfs_device_size_get(struct ntfs_device *dev, int block_size)
if (dev->d_ops->ioctl(dev, BLKGETSIZE, &size) >= 0) {
ntfs_log_debug("BLKGETSIZE nr 512 byte blocks = %lu (0x%lx)\n",
size, size);
return (s64)size * 512 / block_size;
return (s64)(size * 512 - dev->dev_offset) / block_size;
}
}
#endif
@ -562,7 +587,7 @@ s64 ntfs_device_size_get(struct ntfs_device *dev, int block_size)
ntfs_log_debug("FDGETPRM nr 512 byte blocks = %lu (0x%lx)\n",
(unsigned long)this_floppy.size,
(unsigned long)this_floppy.size);
return (s64)this_floppy.size * 512 / block_size;
return (s64)(this_floppy.size * 512 - dev->dev_offset) / block_size;
}
}
#endif
@ -575,7 +600,7 @@ s64 ntfs_device_size_get(struct ntfs_device *dev, int block_size)
ntfs_log_debug("DIOCGMEDIASIZE nr bytes = %llu (0x%llx)\n",
(unsigned long long)size,
(unsigned long long)size);
return (s64)size / block_size;
return (s64)(size - dev->dev_offset) / block_size;
}
}
#endif
@ -592,7 +617,7 @@ s64 ntfs_device_size_get(struct ntfs_device *dev, int block_size)
ntfs_log_debug("DKIOCGETBLOCKCOUNT nr blocks = %llu (0x%llx)\n",
(unsigned long long) blocks,
(unsigned long long) blocks);
return blocks * sector_size / block_size;
return (blocks * sector_size - dev->dev_offset) / block_size;
}
}
#endif

View File

@ -244,7 +244,7 @@ static int ntfs_device_unix_io_close(struct ntfs_device *dev)
static s64 ntfs_device_unix_io_seek(struct ntfs_device *dev, s64 offset,
int whence)
{
return lseek(DEV_FD(dev), offset, whence);
return lseek(DEV_FD(dev), offset + dev->dev_offset, whence);
}
/**
@ -298,7 +298,7 @@ static s64 ntfs_device_unix_io_write(struct ntfs_device *dev, const void *buf,
static s64 ntfs_device_unix_io_pread(struct ntfs_device *dev, void *buf,
s64 count, s64 offset)
{
return pread(DEV_FD(dev), buf, count, offset);
return pread(DEV_FD(dev), buf, count, offset + dev->dev_offset);
}
/**
@ -320,7 +320,7 @@ static s64 ntfs_device_unix_io_pwrite(struct ntfs_device *dev, const void *buf,
return -1;
}
NDevSetDirty(dev);
return pwrite(DEV_FD(dev), buf, count, offset);
return pwrite(DEV_FD(dev), buf, count, offset + dev->dev_offset);
}
/**
@ -356,7 +356,15 @@ static int ntfs_device_unix_io_sync(struct ntfs_device *dev)
*/
static int ntfs_device_unix_io_stat(struct ntfs_device *dev, struct stat *buf)
{
return fstat(DEV_FD(dev), buf);
int res = fstat(DEV_FD(dev), buf);
if (res == 0) {
buf->st_size -= dev->dev_offset;
buf->st_blocks = ((buf->st_blksize == 0) ?
0 : buf->st_size / buf->st_blksize);
}
return res;
}
/**

View File

@ -1413,13 +1413,46 @@ int ntfs_set_ignore_case(ntfs_volume *vol)
*/
ntfs_volume *ntfs_mount(const char *name __attribute__((unused)),
ntfs_mount_flags flags __attribute__((unused)))
{
return ntfs_mount_ext(name, flags, 0);
}
/**
* ntfs_mount_ext - open ntfs volume with dev_offset
* @name: name of device/file to open
* @flags: optional mount flags
* @dev_offset: offset from beginning of device where the ntfs filesystem begins
*
* This function mounts an ntfs volume. @name should contain the name of the
* device/file to mount as the ntfs volume.
*
* @flags is an optional second parameter. The same flags are used as for
* the mount system call (man 2 mount). Currently only the following flags
* is implemented:
* NTFS_MNT_RDONLY - mount volume read-only
*
* The function opens the device or file @name and verifies that it contains a
* valid bootsector. Then, it allocates an ntfs_volume structure and initializes
* some of the values inside the structure from the information stored in the
* bootsector. It proceeds to load the necessary system files and completes
* setting up the structure.
*
* Return the allocated volume structure on success and NULL on error with
* errno set to the error code.
*
* Note, that a copy is made of @name, and hence it can be discarded as
* soon as the function returns.
*/
ntfs_volume *ntfs_mount_ext(const char *name __attribute__((unused)),
ntfs_mount_flags flags __attribute__((unused)), const s64 dev_offset)
{
#ifndef NO_NTFS_DEVICE_DEFAULT_IO_OPS
struct ntfs_device *dev;
ntfs_volume *vol;
/* Allocate an ntfs_device structure. */
dev = ntfs_device_alloc(name, 0, &ntfs_device_default_io_ops, NULL);
dev = ntfs_device_alloc_ext(name, 0, &ntfs_device_default_io_ops, NULL, dev_offset);
if (!dev)
return NULL;
/* Call ntfs_device_mount() to do the actual mount. */

View File

@ -1285,13 +1285,13 @@ static s64 ntfs_device_win32_seek(struct ntfs_device *dev, s64 offset,
s64 abs_ofs;
win32_fd *fd = (win32_fd *)dev->d_private;
ntfs_log_trace("seek offset = 0x%llx, whence = %d.\n", offset, whence);
ntfs_log_trace("seek offset = 0x%llx, whence = %d.\n", offset + dev->dev_offset, whence);
switch (whence) {
case SEEK_SET:
abs_ofs = offset;
abs_ofs = offset + dev->dev_offset;
break;
case SEEK_CUR:
abs_ofs = fd->pos + offset;
abs_ofs = fd->pos + offset + dev->dev_offset;
break;
case SEEK_END:
/* End of partition != end of disk. */
@ -1301,7 +1301,7 @@ static s64 ntfs_device_win32_seek(struct ntfs_device *dev, s64 offset,
errno = EOPNOTSUPP;
return -1;
}
abs_ofs = fd->part_length + offset;
abs_ofs = fd->part_length + offset + dev->dev_offset;
break;
default:
ntfs_log_trace("Wrong mode %d.\n", whence);
@ -1788,7 +1788,7 @@ static int ntfs_device_win32_stat(struct ntfs_device *dev, struct stat *buf)
}
memset(buf, 0, sizeof(struct stat));
buf->st_mode = st_mode;
buf->st_size = fd->part_length;
buf->st_size = fd->part_length - dev->dev_offset;
if (buf->st_size != -1)
buf->st_blocks = buf->st_size >> 9;
else
@ -1911,10 +1911,10 @@ static s64 ntfs_device_win32_pread(struct ntfs_device *dev, void *b,
/* read the fast way if sector aligned */
fd = (win32_fd*)dev->d_private;
if (!((count | offset) & (fd->geo_sector_size - 1))) {
got = ntfs_device_win32_pio(fd, offset, count, b, (void*)NULL);
if (!((count | (offset + dev->dev_offset)) & (fd->geo_sector_size - 1))) {
got = ntfs_device_win32_pio(fd, offset + dev->dev_offset, count, b, (void*)NULL);
} else {
if (ntfs_device_win32_seek(dev, offset, 0) == -1)
if (ntfs_device_win32_seek(dev, offset + dev->dev_offset, 0) == -1)
got = 0;
else
got = ntfs_device_win32_read(dev, b, count);
@ -1931,10 +1931,10 @@ static s64 ntfs_device_win32_pwrite(struct ntfs_device *dev, const void *b,
/* write the fast way if sector aligned */
fd = (win32_fd*)dev->d_private;
if (!((count | offset) & (fd->geo_sector_size - 1))) {
put = ntfs_device_win32_pio(fd, offset, count, (void*)NULL, b);
if (!((count | (offset + dev->dev_offset)) & (fd->geo_sector_size - 1))) {
put = ntfs_device_win32_pio(fd, offset + dev->dev_offset, count, (void*)NULL, b);
} else {
if (ntfs_device_win32_seek(dev, offset, 0) == -1)
if (ntfs_device_win32_seek(dev, offset + dev->dev_offset, 0) == -1)
put = 0;
else
put = ntfs_device_win32_write(dev, b, count);

View File

@ -267,7 +267,7 @@ static const char *usage_msg =
"\n"
"Usage: %s [-o option[,...]] <device|image_file> <mount_point>\n"
"\n"
"Options: ro (read-only mount), windows_names, uid=, gid=,\n"
"Options: ro (read-only mount), dev_offset=, windows_names, uid=, gid=,\n"
" umask=, fmask=, dmask=, streams_interface=.\n"
" Please see the details in the manual (type: man ntfs-3g).\n"
"\n"
@ -4307,11 +4307,11 @@ static int ntfs_fuse_init(void)
return 0;
}
static int ntfs_open(const char *device)
static int ntfs_open(const char *device, const s64 dev_offset)
{
unsigned long flags = 0;
ntfs_volume *vol;
if (!ctx->blkdev)
flags |= NTFS_MNT_EXCLUSIVE;
if (ctx->ro)
@ -4324,7 +4324,7 @@ static int ntfs_open(const char *device)
if (ctx->hiberfile)
flags |= NTFS_MNT_IGNORE_HIBERFILE;
ctx->vol = vol = ntfs_mount(device, flags);
ctx->vol = vol = ntfs_mount_ext(device, flags, dev_offset);
if (!vol) {
ntfs_log_perror("Failed to mount '%s'", device);
goto err_out;
@ -4724,7 +4724,7 @@ int main(int argc, char *argv[])
goto err2;
}
#endif
err = ntfs_open(opts.device);
err = ntfs_open(opts.device, ctx->dev_offset);
if (err)
goto err_out;

View File

@ -202,7 +202,7 @@ static const char *usage_msg =
"\n"
"Usage: %s [-o option[,...]] <device|image_file> <mount_point>\n"
"\n"
"Options: ro (read-only mount), windows_names, uid=, gid=,\n"
"Options: ro (read-only mount), windows_names, dev_offset=, uid=, gid=,\n"
" umask=, fmask=, dmask=, streams_interface=.\n"
" Please see the details in the manual (type: man ntfs-3g).\n"
"\n"
@ -4020,7 +4020,7 @@ static int ntfs_fuse_init(void)
return 0;
}
static int ntfs_open(const char *device)
static int ntfs_open(const char *device, const s64 dev_offset)
{
unsigned long flags = 0;
@ -4036,7 +4036,7 @@ static int ntfs_open(const char *device)
if (ctx->hiberfile)
flags |= NTFS_MNT_IGNORE_HIBERFILE;
ctx->vol = ntfs_mount(device, flags);
ctx->vol = ntfs_mount_ext(device, flags, dev_offset);
if (!ctx->vol) {
ntfs_log_perror("Failed to mount '%s'", device);
goto err_out;
@ -4452,7 +4452,7 @@ int main(int argc, char *argv[])
goto err2;
}
#endif
err = ntfs_open(opts.device);
err = ntfs_open(opts.device, ctx->dev_offset);
if (err)
goto err_out;

View File

@ -45,6 +45,7 @@ typedef enum {
static struct options {
probe_t probetype;
char *device;
s64 dev_offset;
} opts;
static const char *EXEC_NAME = "ntfs-3g.probe";
@ -55,13 +56,13 @@ static const char *usage_msg =
"\n"
"Copyright (C) 2007 Szabolcs Szakacsits\n"
"\n"
"Usage: %s <--readonly|--readwrite> <device|image_file>\n"
"Usage: %s <--readonly|--readwrite> <--dev_offset n> <device|image_file>\n"
"\n"
"Example: ntfs-3g.probe --readwrite /dev/sda1\n"
"\n"
"%s";
static int ntfs_open(const char *device)
static int ntfs_open(const char *device, const s64 dev_offset)
{
ntfs_volume *vol;
unsigned long flags = 0;
@ -70,7 +71,7 @@ static int ntfs_open(const char *device)
if (opts.probetype == PROBE_READONLY)
flags |= NTFS_MNT_RDONLY;
vol = ntfs_mount(device, flags);
vol = ntfs_mount_ext(device, flags, dev_offset);
if (!vol)
ret = ntfs_volume_error(errno);
@ -89,11 +90,12 @@ static int parse_options(int argc, char *argv[])
{
int c;
static const char *sopt = "-hrw";
static const char *sopt = "-hrwo:";
static const struct option lopt[] = {
{ "readonly", no_argument, NULL, 'r' },
{ "readwrite", no_argument, NULL, 'w' },
{ "help", no_argument, NULL, 'h' },
{ "dev_offset", required_argument, NULL, 'o' },
{ NULL, 0, NULL, 0 }
};
@ -125,6 +127,9 @@ static int parse_options(int argc, char *argv[])
case 'w':
opts.probetype = PROBE_READWRITE;
break;
case 'o':
opts.dev_offset = optarg ? strtoull(optarg, 0, 0) : 0;
break;
default:
ntfs_log_error("%s: Unknown option '%s'.\n", EXEC_NAME,
argv[optind - 1]);
@ -156,7 +161,7 @@ int main(int argc, char *argv[])
exit(NTFS_VOLUME_SYNTAX_ERROR);
}
err = ntfs_open(opts.device);
err = ntfs_open(opts.device, opts.dev_offset);
free(opts.device);
if (err)

View File

@ -132,6 +132,7 @@ const struct DEFOPTION optionlist[] = {
{ "-h", OPT_HELP, FLGOPT_BOGUS },
{ "--version", OPT_VERSION, FLGOPT_BOGUS },
{ "-V", OPT_VERSION, FLGOPT_BOGUS },
{ "dev_offset", OPT_DEV_OFFSET, FLGOPT_DECIMAL },
{ (const char*)NULL, 0, 0 } /* end marker */
} ;
@ -519,6 +520,9 @@ char *parse_mount_options(ntfs_fuse_context_t *ctx,
goto err_exit;
}
break;
case OPT_DEV_OFFSET :
ctx->dev_offset = strtoull(val, 0, 0);
break;
case OPT_FSNAME : /* Filesystem name. */
/*
* We need this to be able to check whether filesystem

View File

@ -96,6 +96,7 @@ enum {
OPT_SPECIAL_FILES,
OPT_HELP,
OPT_VERSION,
OPT_DEV_OFFSET,
} ;
/* Option flags */
@ -178,6 +179,7 @@ typedef struct {
struct SECURITY_CONTEXT security;
struct open_file *open_files; /* only defined in lowntfs-3g */
u64 latest_ghost;
s64 dev_offset;
} ntfs_fuse_context_t;
extern const char *EXEC_NAME;