Merge c75dc0697c
into 75dcdc2cf3
commit
3a7a8266ac
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue