Adapted to ntfs-3g-2009.2.1

N2009_11_14_FIXES
jpandre 2009-02-12 20:32:21 +00:00
parent 8191533495
commit 93b695f1cc
9 changed files with 104 additions and 83 deletions

View File

@ -23,8 +23,8 @@
# Autoconf
AC_PREREQ(2.59)
AC_INIT([ntfs-3g],[2009.1.1],[ntfs-3g-devel@lists.sf.net])
LIBNTFS_3G_VERSION="48"
AC_INIT([ntfs-3g],[2009.2.1],[ntfs-3g-devel@lists.sf.net])
LIBNTFS_3G_VERSION="49"
AC_CONFIG_SRCDIR([src/ntfs-3g.c])
# Environment

View File

@ -4,7 +4,7 @@
* Copyright (c) 2000-2004 Anton Altaparmakov
* Copyright (c) 2004-2005 Richard Russon
* Copyright (c) 2005-2006 Yura Pakhuchiy
* Copyright (c) 2005-2008 Szabolcs Szakacsits
* Copyright (c) 2005-2009 Szabolcs Szakacsits
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
@ -56,8 +56,8 @@
#define MS_EXCLUSIVE 0x08000000
#ifndef MS_FORCE
#define MS_FORCE 0x10000000
#ifndef MS_RECOVER
#define MS_RECOVER 0x10000000
#endif
#define MS_IGNORE_HIBERFILE 0x20000000

View File

@ -392,7 +392,7 @@ ntfs_attr *ntfs_attr_open(ntfs_inode *ni, const ATTR_TYPES type,
errno = EINVAL;
goto out;
}
na = calloc(sizeof(ntfs_attr), 1);
na = ntfs_calloc(sizeof(ntfs_attr));
if (!na)
goto out;
if (name && name != AT_UNNAMED && name != NTFS_INDEX_I30) {
@ -1704,6 +1704,7 @@ static int ntfs_attr_find(const ATTR_TYPES type, const ntfschar *name,
} else {
if (name && name != AT_UNNAMED) {
errno = EINVAL;
ntfs_log_perror("%s", __FUNCTION__);
return -1;
}
vol = NULL;
@ -1815,8 +1816,9 @@ static int ntfs_attr_find(const ATTR_TYPES type, const ntfschar *name,
}
}
}
ntfs_log_debug("ntfs_attr_find(): File is corrupt. Run chkdsk.\n");
errno = EIO;
ntfs_log_perror("%s: Corrupt inode (%lld)", __FUNCTION__,
ctx->ntfs_ino ? (long long)ctx->ntfs_ino->mft_no : -1);
return -1;
}
@ -1984,6 +1986,7 @@ find_attr_list_attr:
/* Check for bogus calls. */
if (name || name_len || val || val_len || lowest_vcn) {
errno = EINVAL;
ntfs_log_perror("%s", __FUNCTION__);
return -1;
}
@ -2014,9 +2017,9 @@ find_attr_list_attr:
if (errno != ENOENT)
return rc;
/* Not found?!? Absurd! Must be a bug... )-: */
ntfs_log_error("Extant attribute list wasn't found\n");
errno = EINVAL;
/* Not found?!? Absurd! */
errno = EIO;
ntfs_log_error("Attribute list wasn't found");
return -1;
}
}
@ -2131,10 +2134,8 @@ is_enumeration:
/* We want an extent record. */
ni = ntfs_extent_inode_open(base_ni,
al_entry->mft_reference);
if (!ni) {
ntfs_log_perror("Failed to map extent inode");
if (!ni)
break;
}
ctx->ntfs_ino = ni;
ctx->mrec = ni->mrec;
}
@ -2204,7 +2205,7 @@ do_next_attr:
ctx->attr = ctx->base_attr;
}
errno = EIO;
ntfs_log_perror("Inode is corrupt (%lld)", (unsigned long long)ni->mft_no);
ntfs_log_perror("Inode is corrupt (%lld)", (long long)base_ni->mft_no);
return -1;
not_found:
/*
@ -2338,6 +2339,7 @@ int ntfs_attr_lookup(const ATTR_TYPES type, const ntfschar *name,
(!ctx->ntfs_ino || !(vol = ctx->ntfs_ino->vol) ||
!vol->upcase || !vol->upcase_len))) {
errno = EINVAL;
ntfs_log_perror("%s", __FUNCTION__);
goto out;
}
@ -4281,6 +4283,7 @@ static int ntfs_attr_update_mapping_pairs_i(ntfs_attr *na, VCN from_vcn)
const runlist_element *stop_rl;
int err, mp_size, cur_max_mp_size, exp_max_mp_size, ret = -1;
BOOL finished_build;
retry:
if (!na || !na->rl || from_vcn) {
errno = EINVAL;
@ -4376,12 +4379,19 @@ retry:
exp_max_mp_size = le32_to_cpu(m->bytes_allocated) -
le32_to_cpu(m->bytes_in_use) + cur_max_mp_size;
/* Get the size for the rest of mapping pairs array. */
/* old code equivalent
mp_size = ntfs_get_size_for_mapping_pairs(na->ni->vol, na->rl,
stop_vcn, INT_MAX);
*/
mp_size = ntfs_get_size_for_mapping_pairs(na->ni->vol, stop_rl,
stop_vcn, exp_max_mp_size);
{ /* temporary compare against old computation */
int old;
old = ntfs_get_size_for_mapping_pairs(na->ni->vol, na->rl,
stop_vcn, INT_MAX);
if (((mp_size <= exp_max_mp_size) || (old <= exp_max_mp_size))
&& (mp_size != old)) {
ntfs_log_error("Bad runlist size, old %d new %d\n",old,mp_size);
goto put_err_out;
}
}
if (mp_size <= 0) {
ntfs_log_perror("%s: get MP size failed", __FUNCTION__);
goto put_err_out;

View File

@ -87,7 +87,7 @@ static ntfs_inode *__ntfs_inode_allocate(ntfs_volume *vol)
{
ntfs_inode *ni;
ni = (ntfs_inode*)calloc(1, sizeof(ntfs_inode));
ni = (ntfs_inode*)ntfs_calloc(sizeof(ntfs_inode));
if (ni)
ni->vol = vol;
return ni;
@ -444,11 +444,8 @@ ntfs_inode *ntfs_extent_inode_open(ntfs_inode *base_ni, const MFT_REF mref)
ni = __ntfs_inode_allocate(base_ni->vol);
if (!ni)
goto out;
if (ntfs_file_record_read(base_ni->vol, le64_to_cpu(mref), &ni->mrec,
NULL)) {
ntfs_log_perror("ntfs_file_record_read failed #2");
if (ntfs_file_record_read(base_ni->vol, le64_to_cpu(mref), &ni->mrec, NULL))
goto err_out;
}
ni->mft_no = mft_no;
ni->nr_extents = -1;
ni->base_ni = base_ni;

View File

@ -3,7 +3,7 @@
*
* Copyright (c) 2002-2005 Anton Altaparmakov
* Copyright (c) 2005 Yura Pakhuchiy
* Copyright (c) 2005-2006 Szabolcs Szakacsits
* Copyright (c) 2005-2009 Szabolcs Szakacsits
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
@ -676,8 +676,8 @@ BOOL ntfs_is_logfile_clean(ntfs_attr *log_na, RESTART_PAGE_HEADER *rp)
*/
if (ra->client_in_use_list != LOGFILE_NO_CLIENT &&
!(ra->flags & RESTART_VOLUME_IS_CLEAN)) {
ntfs_log_error("$LogFile indicates unclean shutdown (%d, %d)\n",
le16_to_cpu(ra->client_in_use_list),
ntfs_log_error("The disk contains an unclean file system (%d, "
"%d).\n", le16_to_cpu(ra->client_in_use_list),
le16_to_cpu(ra->flags));
return FALSE;
}

View File

@ -105,11 +105,9 @@ int ntfs_mft_records_read(const ntfs_volume *vol, const MFT_REF mref,
if (br != count) {
if (br != -1)
errno = EIO;
if (br >= 0)
ntfs_log_debug("Error: partition is smaller than it should "
"be!\n");
else
ntfs_log_perror("Error reading $Mft record(s)");
ntfs_log_perror("Failed to read of MFT, mft=%llu count=%lld "
"br=%lld", (long long)m, (long long)count,
(long long)br);
return -1;
}
return 0;
@ -290,10 +288,9 @@ int ntfs_file_record_read(const ntfs_volume *vol, const MFT_REF mref,
if (!m)
return -1;
}
if (ntfs_mft_record_read(vol, mref, m)) {
ntfs_log_perror("ntfs_mft_record_read failed");
if (ntfs_mft_record_read(vol, mref, m))
goto err_out;
}
if (ntfs_mft_record_check(vol, mref, m))
goto err_out;
@ -1404,7 +1401,6 @@ found_free_rec:
goto undo_mftbmp_alloc;
if (ntfs_mft_record_read(vol, bit, m)) {
ntfs_log_perror("Error reading mft %lld #2", (long long)bit);
free(m);
goto undo_mftbmp_alloc;
}
@ -1707,7 +1703,6 @@ found_free_rec:
goto undo_mftbmp_alloc;
if (ntfs_mft_record_read(vol, bit, m)) {
ntfs_log_perror("Error reading mft %lld", (long long)bit);
free(m);
goto undo_mftbmp_alloc;
}

View File

@ -2,7 +2,7 @@
* mst.c - Multi sector fixup handling code. Originated from the Linux-NTFS project.
*
* Copyright (c) 2000-2004 Anton Altaparmakov
* Copyright (c) 2006 Szabolcs Szakacsits
* Copyright (c) 2006-2009 Szabolcs Szakacsits
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
@ -63,6 +63,7 @@ int ntfs_mst_post_read_fixup(NTFS_RECORD *b, const u32 size)
(u32)(usa_ofs + (usa_count * 2)) > size ||
(size >> NTFS_BLOCK_SIZE_BITS) != usa_count) {
errno = EINVAL;
ntfs_log_perror("%s", __FUNCTION__);
return -1;
}
/* Position of usn in update sequence array. */
@ -91,6 +92,7 @@ int ntfs_mst_post_read_fixup(NTFS_RECORD *b, const u32 size)
*/
b->magic = magic_BAAD;
errno = EIO;
ntfs_log_perror("Incomplete multi-sector transfer");
return -1;
}
data_pos += NTFS_BLOCK_SIZE/sizeof(u16);
@ -142,6 +144,7 @@ int ntfs_mst_pre_write_fixup(NTFS_RECORD *b, const u32 size)
if (!b || ntfs_is_baad_record(b->magic) ||
ntfs_is_hole_record(b->magic)) {
errno = EINVAL;
ntfs_log_perror("%s: bad argument", __FUNCTION__);
return -1;
}
/* Setup the variables. */
@ -153,6 +156,7 @@ int ntfs_mst_pre_write_fixup(NTFS_RECORD *b, const u32 size)
(u32)(usa_ofs + (usa_count * 2)) > size ||
(size >> NTFS_BLOCK_SIZE_BITS) != usa_count) {
errno = EINVAL;
ntfs_log_perror("%s", __FUNCTION__);
return -1;
}
/* Position of usn in update sequence array. */

View File

@ -94,14 +94,8 @@ static const char *hibernated_volume_msg =
"\n";
static const char *unclean_journal_msg =
"Mount is denied because NTFS is marked to be in use. Choose one action:\n"
"\n"
"Choice 1: If you have Windows then disconnect the external devices by\n"
" clicking on the 'Safely Remove Hardware' icon in the Windows\n"
" taskbar then shutdown Windows cleanly.\n"
"\n"
"Choice 2: If you don't have Windows then you can use the 'force' option for\n"
" your own responsibility. For example type on the command line:\n";
"Write access is denied because the disk wasn't safely powered\n"
"off and the 'norecover' mount option was specified.\n";
static const char *opened_volume_msg =
"Mount is denied because the NTFS volume is already exclusively opened.\n"
@ -119,14 +113,6 @@ static const char *access_denied_msg =
"and the mounting user ID. More explanation is provided at\n"
"http://ntfs-3g.org/support.html#unprivileged\n";
static const char *forced_mount_msg =
"\n"
" mount -t ntfs-3g -o force %s %s\n"
"\n"
" Or add the option to the relevant row in the /etc/fstab file:\n"
"\n"
" %s %s ntfs-3g force 0 0\n";
/**
* ntfs_volume_alloc - Create an NTFS volume object and initialise it
*
@ -1116,9 +1102,10 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags)
ntfs_volume_check_hiberfile(vol, 1) < 0)
goto error_exit;
if (ntfs_volume_check_logfile(vol) < 0) {
if (!(flags & MS_FORCE))
if (!(flags & MS_RECOVER))
goto error_exit;
ntfs_log_info("WARNING: Forced mount, reset $LogFile.\n");
ntfs_log_info("The file system wasn't safely "
"closed on Windows. Fixing.\n");
if (ntfs_logfile_reset(vol))
goto error_exit;
}
@ -1550,8 +1537,6 @@ void ntfs_mount_error(const char *volume, const char *mntpoint, int err)
break;
case NTFS_VOLUME_UNCLEAN_UNMOUNT:
ntfs_log_error("%s", unclean_journal_msg);
ntfs_log_error(forced_mount_msg, volume, mntpoint,
volume, mntpoint);
break;
case NTFS_VOLUME_LOCKED:
ntfs_log_error("%s", opened_volume_msg);

View File

@ -133,7 +133,7 @@ typedef struct {
BOOL ro;
BOOL show_sys_files;
BOOL silent;
BOOL force;
BOOL recover;
BOOL hiberfile;
BOOL debug;
BOOL no_detach;
@ -162,18 +162,18 @@ static const char *usage_msg =
"\n"
"%s %s %s %d - Third Generation NTFS Driver\n"
"\n"
"Copyright (C) 2006-2009 Szabolcs Szakacsits\n"
"Copyright (C) 2005-2007 Yura Pakhuchiy\n"
"Copyright (C) 2006-2009 Szabolcs Szakacsits\n"
"Copyright (C) 2007-2009 Jean-Pierre Andre\n"
"Copyright (C) 2009 Erik Larsson\n"
"\n"
"Usage: %s [-o option[,...]] <device|image_file> <mount_point>\n"
"\n"
"Options: ro (read-only mount), force, remove_hiberfile, uid=,\n"
" gid=, umask=, fmask=, dmask=, streams_interface=.\n"
" Please see the details in the manual.\n"
"Options: ro (read-only mount), remove_hiberfile, uid=, gid=,\n"
" umask=, fmask=, dmask=, streams_interface=.\n"
" Please see the details in the manual (type: man ntfs-3g).\n"
"\n"
"Examples: ntfs-3g -o force /dev/sda1 /mnt/windows\n"
"Example: ntfs-3g /dev/sda1 /mnt/windows\n"
"\n"
"%s";
@ -380,11 +380,11 @@ static void set_fuse_error(int *err)
#if defined(__APPLE__) || defined(__DARWIN__)
static void *ntfs_macfuse_init(struct fuse_conn_info *conn)
{
FUSE_ENABLE_XTIMES(conn);
return NULL;
FUSE_ENABLE_XTIMES(conn);
return NULL;
}
static int ntfs_macfuse_getxtimes(const char *org_path,
static int ntfs_macfuse_getxtimes(const char *org_path,
struct timespec *bkuptime, struct timespec *crtime)
{
int res = 0;
@ -429,12 +429,33 @@ int ntfs_macfuse_setcrtime(const char *path, const struct timespec *tv)
if (tv) {
ni->creation_time = tv->tv_sec;
ntfs_fuse_update_times(ni, NTFS_UPDATE_CTIME);
}
}
if (ntfs_inode_close(ni))
set_fuse_error(&res);
return res;
}
int ntfs_macfuse_setbkuptime(const char *path, const struct timespec *tv)
{
ntfs_inode *ni;
int res = 0;
if (ntfs_fuse_is_named_data_stream(path))
return -EINVAL; /* n/a for named data streams. */
ni = ntfs_pathname_to_inode(ctx->vol, NULL, path);
if (!ni)
return -errno;
/*
* Doing nothing while pretending to do something. NTFS has no backup
* time. If this function is not implemented then some apps break.
*/
if (ntfs_inode_close(ni))
set_fuse_error(&res);
return res;
}
#endif /* defined(__APPLE__) || defined(__DARWIN__) */
static int ntfs_fuse_getattr(const char *org_path, struct stat *stbuf)
@ -2279,7 +2300,7 @@ static int ntfs_fuse_getxattr(const char *path, const char *name,
return -EOPNOTSUPP;
namespace = xattr_namespace(name);
if (namespace == XATTRNS_NONE)
return -ENODATA;
return -EOPNOTSUPP;
#if POSIXACLS
/* parent directory must be executable */
if (ntfs_fuse_fill_security_context(&security)
@ -2437,7 +2458,7 @@ static int ntfs_fuse_setxattr(const char *path, const char *name,
return -EOPNOTSUPP;
namespace = xattr_namespace(name);
if (namespace == XATTRNS_NONE)
return -ENODATA;
return -EOPNOTSUPP;
#if POSIXACLS
/* parent directory must be executable */
if (ntfs_fuse_fill_security_context(&security)
@ -2626,7 +2647,7 @@ static int ntfs_fuse_removexattr(const char *path, const char *name)
return -EOPNOTSUPP;
namespace = xattr_namespace(name);
if (namespace == XATTRNS_NONE)
return -ENODATA;
return -EOPNOTSUPP;
#if POSIXACLS
/* parent directory must be executable */
if (ntfs_fuse_fill_security_context(&security)
@ -2762,10 +2783,11 @@ static struct fuse_operations ntfs_3g_ops = {
.listxattr = ntfs_fuse_listxattr,
#endif /* HAVE_SETXATTR */
#if defined(__APPLE__) || defined(__DARWIN__)
.init = ntfs_macfuse_init,
.init = ntfs_macfuse_init,
/* MacFUSE extensions. */
.getxtimes = ntfs_macfuse_getxtimes,
.setcrtime = ntfs_macfuse_setcrtime,
.getxtimes = ntfs_macfuse_getxtimes,
.setcrtime = ntfs_macfuse_setcrtime,
.setbkuptime = ntfs_macfuse_setbkuptime
#endif /* defined(__APPLE__) || defined(__DARWIN__) */
};
@ -2776,9 +2798,16 @@ static int ntfs_fuse_init(void)
return -1;
*ctx = (ntfs_fuse_context_t) {
.uid = getuid(),
.gid = getgid(),
.uid = getuid(),
.gid = getgid(),
#if defined(linux)
.streams = NF_STREAMS_INTERFACE_XATTR,
#else
.streams = NF_STREAMS_INTERFACE_NONE,
#endif
.atime = ATIME_RELATIVE,
.silent = TRUE,
.recover = TRUE
};
return 0;
}
@ -2791,8 +2820,8 @@ static int ntfs_open(const char *device)
flags |= MS_EXCLUSIVE;
if (ctx->ro)
flags |= MS_RDONLY;
if (ctx->force)
flags |= MS_FORCE;
if (ctx->recover)
flags |= MS_RECOVER;
if (ctx->hiberfile)
flags |= MS_IGNORE_HIBERFILE;
@ -2893,9 +2922,6 @@ static char *parse_mount_options(const char *orig_opts)
return NULL;
}
ctx->silent = TRUE;
ctx->atime = ATIME_RELATIVE;
s = options;
while (s && *s && (val = strsep(&s, ","))) {
opt = strsep(&val, "=");
@ -2976,10 +3002,14 @@ static char *parse_mount_options(const char *orig_opts)
if (bogus_option_value(val, "silent"))
goto err_exit;
ctx->silent = TRUE;
} else if (!strcmp(opt, "force")) {
if (bogus_option_value(val, "force"))
} else if (!strcmp(opt, "recover")) {
if (bogus_option_value(val, "recover"))
goto err_exit;
ctx->force = TRUE;
ctx->recover = TRUE;
} else if (!strcmp(opt, "norecover")) {
if (bogus_option_value(val, "norecover"))
goto err_exit;
ctx->recover = FALSE;
} else if (!strcmp(opt, "remove_hiberfile")) {
if (bogus_option_value(val, "remove_hiberfile"))
goto err_exit;