mirror of
https://git.code.sf.net/p/ntfs-3g/ntfs-3g.git
synced 2024-12-04 15:34:28 +08:00
* Fix ntfs_attr_p{read,write}. (see Changelog)
* Minor fixes and some stubs for uncommitted code. * Update README about ./autogen.sh.
This commit is contained in:
parent
03556cdd8b
commit
f7e5e1cc26
@ -20,6 +20,8 @@ xx/xx/xxxx - 1.12.0-WIP
|
|||||||
failed. (Yura)
|
failed. (Yura)
|
||||||
- Fix random errno returned by ntfs_inode_open() if the MFT record
|
- Fix random errno returned by ntfs_inode_open() if the MFT record
|
||||||
wasn't in use. (Szaka)
|
wasn't in use. (Szaka)
|
||||||
|
- Fix ntfs_attr_p{read,write} to not return less bytes if trapped on
|
||||||
|
unmapped runlist region. (Yura)
|
||||||
|
|
||||||
20/07/2005 - 1.11.1 - Fix several ntfsmount bugs.
|
20/07/2005 - 1.11.1 - Fix several ntfsmount bugs.
|
||||||
|
|
||||||
|
1
README
1
README
@ -47,6 +47,7 @@ Quick Installation
|
|||||||
|
|
||||||
In most cases it should be sufficient to do:
|
In most cases it should be sufficient to do:
|
||||||
|
|
||||||
|
./autogen.sh <-- Only in case you received source from CVS.
|
||||||
./configure
|
./configure
|
||||||
make
|
make
|
||||||
make install <-- You usually need to be root for this one.
|
make install <-- You usually need to be root for this one.
|
||||||
|
@ -810,6 +810,14 @@ res_err_out:
|
|||||||
*/
|
*/
|
||||||
ofs = pos - (rl->vcn << vol->cluster_size_bits);
|
ofs = pos - (rl->vcn << vol->cluster_size_bits);
|
||||||
for (; count; rl++, ofs = 0) {
|
for (; count; rl++, ofs = 0) {
|
||||||
|
if (rl->lcn == LCN_RL_NOT_MAPPED) {
|
||||||
|
rl = ntfs_attr_find_vcn(na, rl->vcn);
|
||||||
|
if (!rl) {
|
||||||
|
if (errno == ENOENT)
|
||||||
|
errno = EIO;
|
||||||
|
goto rl_err_out;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!rl->length)
|
if (!rl->length)
|
||||||
goto rl_err_out;
|
goto rl_err_out;
|
||||||
if (rl->lcn < (LCN)0) {
|
if (rl->lcn < (LCN)0) {
|
||||||
@ -829,9 +837,9 @@ res_err_out:
|
|||||||
to_read = min(count, (rl->length << vol->cluster_size_bits) -
|
to_read = min(count, (rl->length << vol->cluster_size_bits) -
|
||||||
ofs);
|
ofs);
|
||||||
retry:
|
retry:
|
||||||
Dprintf("%s(): Reading 0x%llx bytes from vcn 0x%llx, lcn 0x%llx, "
|
Dprintf("%s(): Reading 0x%llx bytes from vcn 0x%llx, "
|
||||||
"ofs 0x%llx.\n", __FUNCTION__, to_read,
|
"lcn 0x%llx, ofs 0x%llx.\n", __FUNCTION__,
|
||||||
rl->vcn, rl->lcn, ofs);
|
to_read, rl->vcn, rl->lcn, ofs);
|
||||||
br = ntfs_pread(vol->dev, (rl->lcn << vol->cluster_size_bits) +
|
br = ntfs_pread(vol->dev, (rl->lcn << vol->cluster_size_bits) +
|
||||||
ofs, to_read, b);
|
ofs, to_read, b);
|
||||||
/* If everything ok, update progress counters and continue. */
|
/* If everything ok, update progress counters and continue. */
|
||||||
@ -1049,6 +1057,14 @@ s64 ntfs_attr_pwrite(ntfs_attr *na, const s64 pos, s64 count, const void *b)
|
|||||||
*/
|
*/
|
||||||
ofs = pos - (rl->vcn << vol->cluster_size_bits);
|
ofs = pos - (rl->vcn << vol->cluster_size_bits);
|
||||||
for (; count; rl++, ofs = 0) {
|
for (; count; rl++, ofs = 0) {
|
||||||
|
if (rl->lcn == LCN_RL_NOT_MAPPED) {
|
||||||
|
rl = ntfs_attr_find_vcn(na, rl->vcn);
|
||||||
|
if (!rl) {
|
||||||
|
if (errno == ENOENT)
|
||||||
|
errno = EIO;
|
||||||
|
goto rl_err_out;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!rl->length) {
|
if (!rl->length) {
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
goto rl_err_out;
|
goto rl_err_out;
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
#include "dir.h"
|
#include "dir.h"
|
||||||
#include "unistr.h"
|
#include "unistr.h"
|
||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
|
#include "index.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -253,7 +254,7 @@ static int ntfs_fuse_getattr(const char *org_path, struct stat *stbuf)
|
|||||||
if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY &&
|
if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY &&
|
||||||
!stream_name_len) {
|
!stream_name_len) {
|
||||||
stbuf->st_mode = S_IFDIR | (0777 & ~ctx->dmask);
|
stbuf->st_mode = S_IFDIR | (0777 & ~ctx->dmask);
|
||||||
na = ntfs_attr_open(ni, AT_INDEX_ALLOCATION, I30, 0);
|
na = ntfs_attr_open(ni, AT_INDEX_ALLOCATION, I30, 4);
|
||||||
if (na) {
|
if (na) {
|
||||||
stbuf->st_size = na->data_size;
|
stbuf->st_size = na->data_size;
|
||||||
stbuf->st_blocks = na->allocated_size >>
|
stbuf->st_blocks = na->allocated_size >>
|
||||||
@ -355,14 +356,13 @@ static int ntfs_fuse_open(const char *org_path,
|
|||||||
vol = ctx->vol;
|
vol = ctx->vol;
|
||||||
ni = ntfs_pathname_to_inode(vol, NULL, path);
|
ni = ntfs_pathname_to_inode(vol, NULL, path);
|
||||||
if (ni) {
|
if (ni) {
|
||||||
if (stream_name_len) {
|
na = ntfs_attr_open(ni, AT_DATA, stream_name, stream_name_len);
|
||||||
na = ntfs_attr_open(ni, AT_DATA, stream_name,
|
if (na) {
|
||||||
stream_name_len);
|
if (NAttrEncrypted(na))
|
||||||
if (na)
|
res = -EACCES;
|
||||||
ntfs_attr_close(na);
|
ntfs_attr_close(na);
|
||||||
else
|
} else
|
||||||
res = -errno;
|
res = -errno;
|
||||||
}
|
|
||||||
ntfs_inode_close(ni);
|
ntfs_inode_close(ni);
|
||||||
} else
|
} else
|
||||||
res = -errno;
|
res = -errno;
|
||||||
@ -398,6 +398,8 @@ static int ntfs_fuse_read(const char *org_path, char *buf, size_t size,
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
res = ntfs_attr_pread(na, offset, size, buf);
|
res = ntfs_attr_pread(na, offset, size, buf);
|
||||||
|
if (res == -1)
|
||||||
|
res = -errno;
|
||||||
ntfs_attr_close(na);
|
ntfs_attr_close(na);
|
||||||
exit:
|
exit:
|
||||||
if (ni && ntfs_inode_close(ni))
|
if (ni && ntfs_inode_close(ni))
|
||||||
@ -434,6 +436,10 @@ static int ntfs_fuse_write(const char *org_path, const char *buf, size_t size,
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
res = ntfs_attr_pwrite(na, offset, size, buf);
|
res = ntfs_attr_pwrite(na, offset, size, buf);
|
||||||
|
if (res == -1)
|
||||||
|
res = -errno;
|
||||||
|
if (res < size)
|
||||||
|
perror("ntfs_attr_pwrite returned less than requested.");
|
||||||
ctx->state |= (NF_FreeClustersOutdate | NF_FreeMFTOutdate);
|
ctx->state |= (NF_FreeClustersOutdate | NF_FreeMFTOutdate);
|
||||||
ntfs_attr_close(na);
|
ntfs_attr_close(na);
|
||||||
exit:
|
exit:
|
||||||
@ -529,6 +535,11 @@ exit:
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ntfs_fuse_rm_file(char *file)
|
||||||
|
{
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
static int ntfs_fuse_unlink(const char *org_path)
|
static int ntfs_fuse_unlink(const char *org_path)
|
||||||
{
|
{
|
||||||
ntfs_inode *ni = NULL;
|
ntfs_inode *ni = NULL;
|
||||||
@ -541,15 +552,11 @@ static int ntfs_fuse_unlink(const char *org_path)
|
|||||||
stream_name_len = ntfs_fuse_parse_path(org_path, &path, &stream_name);
|
stream_name_len = ntfs_fuse_parse_path(org_path, &path, &stream_name);
|
||||||
if (stream_name_len < 0)
|
if (stream_name_len < 0)
|
||||||
return stream_name_len;
|
return stream_name_len;
|
||||||
if (!stream_name_len) {
|
if (!stream_name_len)
|
||||||
res = -EOPNOTSUPP;
|
return ntfs_fuse_rm_file(path);
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
ni = ntfs_pathname_to_inode(ctx->vol, NULL, path);
|
ni = ntfs_pathname_to_inode(ctx->vol, NULL, path);
|
||||||
if (!ni) {
|
if (!ni) {
|
||||||
res = -errno;
|
res = -errno;
|
||||||
if (res == -ENOENT)
|
|
||||||
res = -EOPNOTSUPP;
|
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
na = ntfs_attr_open(ni, AT_DATA, stream_name, stream_name_len);
|
na = ntfs_attr_open(ni, AT_DATA, stream_name, stream_name_len);
|
||||||
@ -935,7 +942,7 @@ static char *parse_options(char *options, char **device)
|
|||||||
opt = strsep(&val, "=");
|
opt = strsep(&val, "=");
|
||||||
if (!strcmp(opt, "dev")) { /* Device to mount. */
|
if (!strcmp(opt, "dev")) { /* Device to mount. */
|
||||||
if (!val) {
|
if (!val) {
|
||||||
Eprintf("dev option should have value.\n");
|
Eprintf("'dev' option should have value.\n");
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
*device = malloc(PATH_MAX + 1);
|
*device = malloc(PATH_MAX + 1);
|
||||||
@ -953,7 +960,7 @@ static char *parse_options(char *options, char **device)
|
|||||||
strcpy(*device, val);
|
strcpy(*device, val);
|
||||||
} else if (!strcmp(opt, "ro")) { /* Read-only mount. */
|
} else if (!strcmp(opt, "ro")) { /* Read-only mount. */
|
||||||
if (val) {
|
if (val) {
|
||||||
Eprintf("ro option should not have value.\n");
|
Eprintf("'ro' option should not have value.\n");
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
ctx->ro =TRUE;
|
ctx->ro =TRUE;
|
||||||
@ -961,7 +968,7 @@ static char *parse_options(char *options, char **device)
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
} else if (!strcmp(opt, "fake_ro")) {
|
} else if (!strcmp(opt, "fake_ro")) {
|
||||||
if (val) {
|
if (val) {
|
||||||
Eprintf("fake_ro option should not have "
|
Eprintf("'fake_ro' option should not have "
|
||||||
"value.\n");
|
"value.\n");
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
@ -972,63 +979,63 @@ static char *parse_options(char *options, char **device)
|
|||||||
* We need this to be able to check whether filesystem
|
* We need this to be able to check whether filesystem
|
||||||
* mounted or not.
|
* mounted or not.
|
||||||
*/
|
*/
|
||||||
Eprintf("fsname is unsupported option.\n");
|
Eprintf("'fsname' is unsupported option.\n");
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
} else if (!strcmp(opt, "no_def_opts")) {
|
} else if (!strcmp(opt, "no_def_opts")) {
|
||||||
if (val) {
|
if (val) {
|
||||||
Eprintf("no_def_opts option should not have "
|
Eprintf("'no_def_opts' option should not have "
|
||||||
"value.\n");
|
"value.\n");
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
no_def_opts = TRUE; /* Don't add default options. */
|
no_def_opts = TRUE; /* Don't add default options. */
|
||||||
} else if (!strcmp(opt, "umask")) {
|
} else if (!strcmp(opt, "umask")) {
|
||||||
if (!val) {
|
if (!val) {
|
||||||
Eprintf("umask option should have value.\n");
|
Eprintf("'umask' option should have value.\n");
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
sscanf(val, "%i", &ctx->fmask);
|
sscanf(val, "%i", &ctx->fmask);
|
||||||
ctx->dmask = ctx->fmask;
|
ctx->dmask = ctx->fmask;
|
||||||
} else if (!strcmp(opt, "fmask")) {
|
} else if (!strcmp(opt, "fmask")) {
|
||||||
if (!val) {
|
if (!val) {
|
||||||
Eprintf("fmask option should have value.\n");
|
Eprintf("'fmask' option should have value.\n");
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
sscanf(val, "%i", &ctx->fmask);
|
sscanf(val, "%i", &ctx->fmask);
|
||||||
} else if (!strcmp(opt, "dmask")) {
|
} else if (!strcmp(opt, "dmask")) {
|
||||||
if (!val) {
|
if (!val) {
|
||||||
Eprintf("dmask option should have value.\n");
|
Eprintf("'dmask' option should have value.\n");
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
sscanf(val, "%i", &ctx->dmask);
|
sscanf(val, "%i", &ctx->dmask);
|
||||||
} else if (!strcmp(opt, "uid")) {
|
} else if (!strcmp(opt, "uid")) {
|
||||||
if (!val) {
|
if (!val) {
|
||||||
Eprintf("uid option should have value.\n");
|
Eprintf("'uid' option should have value.\n");
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
sscanf(val, "%i", &ctx->uid);
|
sscanf(val, "%i", &ctx->uid);
|
||||||
} else if (!strcmp(opt, "gid")) {
|
} else if (!strcmp(opt, "gid")) {
|
||||||
if (!val) {
|
if (!val) {
|
||||||
Eprintf("gid option should have value.\n");
|
Eprintf("'gid' option should have value.\n");
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
sscanf(val, "%i", &ctx->gid);
|
sscanf(val, "%i", &ctx->gid);
|
||||||
} else if (!strcmp(opt, "show_sys_files")) {
|
} else if (!strcmp(opt, "show_sys_files")) {
|
||||||
if (val) {
|
if (val) {
|
||||||
Eprintf("show_sys_files option should not "
|
Eprintf("'show_sys_files' option should not "
|
||||||
"have value.\n");
|
"have value.\n");
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
ctx->show_sys_files = TRUE;
|
ctx->show_sys_files = TRUE;
|
||||||
} else if (!strcmp(opt, "succeed_chmod")) {
|
} else if (!strcmp(opt, "succeed_chmod")) {
|
||||||
if (val) {
|
if (val) {
|
||||||
Eprintf("succeed_chmod option should not "
|
Eprintf("'succeed_chmod' option should not "
|
||||||
"have value.\n");
|
"have value.\n");
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
ctx->succeed_chmod = TRUE;
|
ctx->succeed_chmod = TRUE;
|
||||||
} else if (!strcmp(opt, "force")) {
|
} else if (!strcmp(opt, "force")) {
|
||||||
if (val) {
|
if (val) {
|
||||||
Eprintf("force option should not "
|
Eprintf("'force' option should not "
|
||||||
"have value.\n");
|
"have value.\n");
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
@ -1100,7 +1107,7 @@ int main(int argc, char *argv[])
|
|||||||
/* Parse options. */
|
/* Parse options. */
|
||||||
parsed_options = parse_options(options, &device);
|
parsed_options = parse_options(options, &device);
|
||||||
if (!device) {
|
if (!device) {
|
||||||
Eprintf("dev option is mandatory.\n");
|
Eprintf("'dev' option is mandatory.\n");
|
||||||
ntfs_fuse_destroy();
|
ntfs_fuse_destroy();
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user