- mkntfs: Generate a random DCE compliant UUID for the created volume

and include --with-uuid[=PFX] and --without-uuid options.  (Anton)
- configure.ac: Set language to C.  (Anton)
- mkntfs: Always set default cluster size to 4096 bytes regardless of
  volume size.  This is what Windows Vista does and it makes perfect
  sense from a performance point of view.  (Anton)
edge.strict_endians
aia21 2006-12-13 00:11:50 +00:00
parent 914cf8f2be
commit 1a4fb3431c
10 changed files with 194 additions and 55 deletions

View File

@ -106,6 +106,12 @@ xx/xx/2006 - x.xx.x - .
Adapt unix_io pread()/pwrite() device operations to use pread()/
pwrite() system call and adapt win32_io device operations to not
supply pread()/pwrite(). (Csaba Henk, Anton)
- mkntfs: Generate a random DCE compliant UUID for the created volume
and include --with-uuid[=PFX] and --without-uuid options. (Anton)
- configure.ac: Set language to C. (Anton)
- mkntfs: Always set default cluster size to 4096 bytes regardless of
volume size. This is what Windows Vista does and it makes perfect
sense from a performance point of view. (Anton)
21/06/2006 - 1.13.1 - Various fixes.

View File

@ -53,6 +53,7 @@ AC_INIT([ntfsprogs],[1.13.2-WIP],[linux-ntfs-dev@lists.sourceforge.net])
LTVERSION_LIBNTFS="10:0:0"
AC_SUBST(LTVERSION_LIBNTFS)
AC_LANG([C])
AC_CANONICAL_HOST([])
AC_CANONICAL_TARGET([])
AC_CONFIG_SRCDIR([config.h.in])
@ -241,6 +242,42 @@ all_includes="$all_includes $USER_INCLUDES"
AC_SUBST(all_includes)
AC_SUBST(all_libraries)
# Specify support for generating DCE compliant UUIDs (aka GUIDs). We check if
# uuid/uuid.h header is present and the uuid library is present that goes with
# it and then check if uuid_generate() is present and usable.
#
# DCE UUIDs are enabled by default and can be disabled with the --disable-uuid
# option to the configure script.
AC_ARG_WITH(uuid, [
--with-uuid@<:@=PFX@:>@ generate DCE compliant UUIDs, with optional prefix
to uuid library and headers @<:@default=detect@:>@
--without-uuid do not generate DCE compliant UUIDs],
if test "$with_uuid" = "yes"; then
extrapath=default
elif test "$with_uuid" = "no"; then
extrapath=
else
extrapath=$with_uuid
fi,
extrapath=default
)
if test "x$extrapath" != "x"; then
if test "x$extrapath" != "xdefault"; then
MKNTFS_CPPFLAGS="$MKNTFS_CPPFLAGS -I$extrapath/include"
MKNTFS_LIBS="$MKNTFS_LIBS -L$extrapath/lib"
fi
AC_CHECK_HEADER([uuid/uuid.h],
AC_CHECK_LIB([uuid], [uuid_generate],
AC_DEFINE([ENABLE_UUID], 1,
[Define this to 1 if you want to enable generation of
DCE compliant UUIDs.])
MKNTFS_LIBS="$MKNTFS_LIBS -luuid",
AC_MSG_WARN([Linux-NTFS DCE compliant UUID generation code requires the uuid library.]),
),
AC_MSG_WARN([Linux-NTFS DCE compliant UUID generation code requires the uuid library.]),
)
fi
# Get compiler name
if test ! -z "$CC"; then
_cc="$CC"
@ -292,6 +329,9 @@ AC_SUBST(LIBNTFS_CFLAGS)
AC_SUBST(LIBNTFS_GNOMEVFS_CFLAGS)
AC_SUBST(LIBNTFS_GNOMEVFS_LIBS)
AC_SUBST(MKNTFS_CPPFLAGS)
AC_SUBST(MKNTFS_LIBS)
AC_SUBST(AUTODIRS)
# Checks for libraries.

View File

@ -152,6 +152,8 @@ struct _ntfs_volume {
u8 major_ver; /* Ntfs major version of volume. */
u8 minor_ver; /* Ntfs minor version of volume. */
u16 flags; /* Bit array of VOLUME_* flags. */
GUID guid; /* The volume guid if present (otherwise it is
a NULL guid). */
u16 sector_size; /* Byte size of a sector. */
u8 sector_size_bits; /* Log(2) of the byte size of a sector. */

View File

@ -596,7 +596,6 @@ static const ntfschar dotdot[3] = { const_cpu_to_le16('.'),
/**
* ntfs_filldir - ntfs specific filldir method
* @dir_ni: ntfs inode of current directory
* @pos: current position in directory
* @ie: current index entry
* @dirent: context for filldir callback supplied by the caller
@ -605,7 +604,7 @@ static const ntfschar dotdot[3] = { const_cpu_to_le16('.'),
* Pass information specifying the current directory entry @ie to the @filldir
* callback.
*/
static int ntfs_filldir(ntfs_inode *dir_ni, s64 *pos, INDEX_ENTRY *ie,
static int ntfs_filldir(s64 *pos, INDEX_ENTRY *ie,
void *dirent, ntfs_filldir_t filldir)
{
FILE_NAME_ATTR *fn = &ie->key.file_name;
@ -857,7 +856,7 @@ int ntfs_readdir(ntfs_inode *dir_ni, s64 *pos,
* Submit the directory entry to ntfs_filldir(), which will
* invoke the filldir() callback as appropriate.
*/
rc = ntfs_filldir(dir_ni, pos, ie, dirent, filldir);
rc = ntfs_filldir(pos, ie, dirent, filldir);
if (rc) {
ntfs_attr_put_search_ctx(ctx);
ctx = NULL;
@ -1018,7 +1017,7 @@ find_next_index_buffer:
* Submit the directory entry to ntfs_filldir(), which will
* invoke the filldir() callback as appropriate.
*/
rc = ntfs_filldir(dir_ni, pos, ie, dirent, filldir);
rc = ntfs_filldir(pos, ie, dirent, filldir);
if (rc)
goto done;
}

View File

@ -71,18 +71,20 @@ struct ntfs_logging {
/**
* ntfs_log - This struct controls all the logging in the library and tools.
*/
static struct ntfs_logging ntfs_log = {
static struct ntfs_logging ntfs_log = (struct ntfs_logging) {
.levels = NTFS_LOG_LEVEL_INFO | NTFS_LOG_LEVEL_QUIET |
NTFS_LOG_LEVEL_WARNING | NTFS_LOG_LEVEL_ERROR |
NTFS_LOG_LEVEL_PERROR | NTFS_LOG_LEVEL_CRITICAL |
NTFS_LOG_LEVEL_PROGRESS |
#ifdef DEBUG
NTFS_LOG_LEVEL_DEBUG | NTFS_LOG_LEVEL_TRACE |
NTFS_LOG_LEVEL_DEBUG | NTFS_LOG_LEVEL_TRACE |
#endif
NTFS_LOG_LEVEL_INFO | NTFS_LOG_LEVEL_QUIET | NTFS_LOG_LEVEL_WARNING |
NTFS_LOG_LEVEL_ERROR | NTFS_LOG_LEVEL_PERROR | NTFS_LOG_LEVEL_CRITICAL |
NTFS_LOG_LEVEL_PROGRESS,
NTFS_LOG_FLAG_ONLYNAME,
0,
.flags = NTFS_LOG_FLAG_ONLYNAME,
#ifdef DEBUG
ntfs_log_handler_outerr
.handler = ntfs_log_handler_outerr,
#else
ntfs_log_handler_null
.handler = ntfs_log_handler_null,
#endif
};
@ -343,8 +345,10 @@ int ntfs_log_redirect(const char *function, const char *file,
#ifdef HAVE_SYSLOG_H
int ntfs_log_handler_syslog(const char *function __attribute__((unused)),
const char *file, __attribute__((unused)) int line, u32 level,
void *data __attribute__((unused)), const char *format, va_list args)
const char *file, int line __attribute__((unused)),
u32 level __attribute__((unused)),
void *data __attribute__((unused)), const char *format,
va_list args)
{
int ret = 0;
int olderr = errno;

View File

@ -4,6 +4,7 @@ Makefile
Makefile.in
mkntfs
ntfscat
ntfsck
ntfsclone
ntfscluster
ntfscmp

View File

@ -44,8 +44,9 @@ ntfsfix_SOURCES = ntfsfix.c utils.c utils.h
ntfsfix_LDADD = $(AM_LIBS)
ntfsfix_LDFLAGS = $(AM_LFLAGS)
mkntfs_CPPFLAGS = $(AM_CPPFLAGS) $(MKNTFS_CPPFLAGS)
mkntfs_SOURCES = attrdef.c attrdef.h upcase.c upcase.h boot.c boot.h sd.c sd.h mkntfs.c utils.c utils.h
mkntfs_LDADD = $(AM_LIBS)
mkntfs_LDADD = $(AM_LIBS) $(MKNTFS_LIBS)
mkntfs_LDFLAGS = $(AM_LFLAGS)
ntfslabel_SOURCES = ntfslabel.c utils.c utils.h

View File

@ -127,20 +127,7 @@ Enable compression on the volume.
Specify the size of clusters in bytes. Valid cluster size values are powers of
two, with at least 256, and at most 65536 bytes per cluster. If omitted,
.B mkntfs
determines the
.I cluster\-size
from the volume size. The value is determined as follows:
.TS
box;
lB lB lB
l l r.
Volume size Default cluster size
0 \- 512MB 512 bytes
512MB \- 1GB 1024 bytes
1GB \- 2GB 2048 bytes
2GB + 4096 bytes
.TE
.sp
uses 4096 bytes as the default cluster size.
.sp
Note that the default cluster size is set to be at least equal to the sector
size as a cluster cannot be smaller than a sector. Also, note that values
@ -150,7 +137,7 @@ by Windows).
.TP
\fB\-N\fR, \fB\-\-ntfs\-version\fR STRING
Select the version of NTFS you wish to create. This can be "1.2"
(Windows NT 4.0) or "3.1" (Windows XP, Server 2003 and Vista).
(Windows NT 4.0) or "3.1" (Windows XP, Server 2003, and Vista).
Versions are upwards compatible and Windows 2000, which uses version "3.0",
can read/write both.

View File

@ -81,6 +81,10 @@
#ifdef HAVE_LIBGEN_H
#include <libgen.h>
#endif
#ifdef ENABLE_UUID
#include <uuid/uuid.h>
#endif
#ifdef HAVE_GETOPT_H
#include <getopt.h>
@ -2083,6 +2087,34 @@ static int add_attr_file_name(MFT_RECORD *m, const MFT_REF parent_dir,
return i;
}
#ifdef ENABLE_UUID
/**
* add_attr_object_id -
*
* Note we insert only a basic object id which only has the GUID and none of
* the extended fields. This is because we currently only use this function
* when creating the object id for the volume.
*
* Return 0 on success or -errno on error.
*/
static int add_attr_object_id(MFT_RECORD *m, const GUID *object_id)
{
OBJECT_ID_ATTR oi;
int err;
oi = (OBJECT_ID_ATTR) {
.object_id = *object_id,
};
err = insert_resident_attr_in_mft_record(m, AT_OBJECT_ID, NULL,
0, 0, 0, 0, (u8*)&oi, sizeof(oi.object_id));
if (err < 0)
ntfs_log_error("add_attr_vol_info failed: %s\n", strerror(-err));
return err;
}
#endif
/**
* add_attr_sd
*
@ -2754,9 +2786,8 @@ do_next:
idx_entry = (INDEX_ENTRY*)((u8*)idx_entry +
le16_to_cpu(idx_entry->length));
}
} else {
} else
return -EINVAL;
}
memmove((u8*)idx_entry + idx_size, (u8*)idx_entry,
le32_to_cpu(m->bytes_in_use) -
((u8*)idx_entry - (u8*)m));
@ -3300,6 +3331,56 @@ static int create_hardlink(INDEX_BLOCK *idx, const MFT_REF ref_parent,
return 0;
}
#ifdef ENABLE_UUID
/**
* index_obj_id_insert
*
* Insert an index entry with the key @guid and data pointing to the mft record
* @ref in the $O index root of the mft record @m (which must be the mft record
* for $ObjId).
*
* Return 0 on success or -errno on error.
*/
static int index_obj_id_insert(MFT_RECORD *m, const GUID *guid,
const MFT_REF ref)
{
INDEX_ENTRY *idx_entry_new;
int data_ofs, idx_size, err;
OBJ_ID_INDEX_DATA *oi;
/*
* Insert the index entry for the object id in the index.
*
* First determine the size of the index entry to be inserted. This
* consists of the index entry header, followed by the index key, i.e.
* the GUID, followed by the index data, i.e. OBJ_ID_INDEX_DATA.
*/
data_ofs = (sizeof(INDEX_ENTRY_HEADER) + sizeof(GUID) + 7) & ~7;
idx_size = (data_ofs + sizeof(OBJ_ID_INDEX_DATA) + 7) & ~7;
idx_entry_new = ntfs_calloc(idx_size);
if (!idx_entry_new)
return -errno;
idx_entry_new->data_offset = cpu_to_le16(data_ofs);
idx_entry_new->data_length = cpu_to_le16(sizeof(OBJ_ID_INDEX_DATA));
idx_entry_new->length = cpu_to_le16(idx_size);
idx_entry_new->key_length = cpu_to_le16(sizeof(GUID));
idx_entry_new->key.object_id = *guid;
oi = (OBJ_ID_INDEX_DATA*)((u8*)idx_entry_new + data_ofs);
oi->mft_reference = ref;
err = insert_index_entry_in_res_dir_index(idx_entry_new, idx_size, m,
NTFS_INDEX_O, 2, AT_UNUSED);
free(idx_entry_new);
if (err < 0) {
ntfs_log_error("index_obj_id_insert failed inserting index "
"entry: %s\n", strerror(-err));
return err;
}
return 0;
}
#endif
/**
* mkntfs_cleanup
*/
@ -3593,14 +3674,11 @@ static BOOL mkntfs_override_vol_params(ntfs_volume *vol)
ntfs_log_debug("volume size = %llikiB\n", volume_size / 1024);
/* If user didn't specify the cluster size, determine it now. */
if (!vol->cluster_size) {
if (volume_size <= 512LL << 20) /* <= 512MB */
vol->cluster_size = 512;
else if (volume_size <= 1LL << 30) /* ]512MB-1GB] */
vol->cluster_size = 1024;
else if (volume_size <= 2LL << 30) /* ]1GB-2GB] */
vol->cluster_size = 2048;
else
vol->cluster_size = 4096;
/*
* Windows Vista always uses 4096 bytes as the default cluster
* size regardless of the volume size so we do it, too.
*/
vol->cluster_size = 4096;
/* For small volumes on devices with large sector sizes. */
if (vol->cluster_size < (u32)opts.sector_size)
vol->cluster_size = opts.sector_size;
@ -4192,11 +4270,16 @@ static BOOL mkntfs_sync_index_record(INDEX_ALLOCATION* idx, MFT_RECORD* m,
return TRUE;
}
/**
* create_file_volume -
*/
static BOOL create_file_volume(MFT_RECORD *m, MFT_REF root_ref, VOLUME_FLAGS fl)
static BOOL create_file_volume(MFT_RECORD *m, MFT_REF root_ref,
VOLUME_FLAGS fl
, const GUID *volume_guid
#ifndef ENABLE_UUID
__attribute__((unused))
#endif
)
{
int i, err;
u8 *sd;
@ -4216,14 +4299,21 @@ static BOOL create_file_volume(MFT_RECORD *m, MFT_REF root_ref, VOLUME_FLAGS fl)
if (!err)
err = add_attr_vol_name(m, g_vol->vol_name, g_vol->vol_name ?
strlen(g_vol->vol_name) : 0);
#ifdef ENABLE_UUID
if (!err)
err = add_attr_object_id(m, volume_guid);
#endif
if (!err) {
if (fl & VOLUME_IS_DIRTY)
ntfs_log_quiet("Setting the volume dirty so check disk runs "
"on next reboot into Windows.\n");
err = add_attr_vol_info(m, fl, g_vol->major_ver, g_vol->minor_ver);
ntfs_log_quiet("Setting the volume dirty so check "
"disk runs on next reboot into "
"Windows.\n");
err = add_attr_vol_info(m, fl, g_vol->major_ver,
g_vol->minor_ver);
}
if (err < 0) {
ntfs_log_error("Couldn't create $Volume: %s\n", strerror(-err));
ntfs_log_error("Couldn't create $Volume: %s\n",
strerror(-err));
return FALSE;
}
return TRUE;
@ -4672,7 +4762,11 @@ static BOOL mkntfs_create_root_structures(void)
volume_flags |= VOLUME_IS_DIRTY;
}
free(bs);
if (!create_file_volume(m, root_ref, volume_flags))
#ifdef ENABLE_UUID
/* Generate a GUID for the volume. */
uuid_generate((void*)&g_vol->guid);
#endif
if (!create_file_volume(m, root_ref, volume_flags, &g_vol->guid))
return FALSE;
ntfs_log_verbose("Creating $BadClus (mft record 8)\n");
m = (MFT_RECORD*)(g_buf + 8 * g_vol->mft_record_size);
@ -4768,7 +4862,7 @@ static BOOL mkntfs_create_root_structures(void)
if (!err)
err = initialize_secure(buf_sds_init, buf_sds_first_size, m);
free (buf_sds_init);
free(buf_sds_init);
buf_sds_init = NULL;
if (err < 0) {
ntfs_log_error("Couldn't create $Secure: %s\n",
@ -4882,7 +4976,6 @@ static BOOL mkntfs_create_root_structures(void)
ntfs_log_error("Couldn't create $Quota: %s\n", strerror(-err));
return FALSE;
}
ntfs_log_verbose("Creating $ObjId (mft record 25)\n");
m = (MFT_RECORD*)(g_buf + 25 * g_vol->mft_record_size);
m->flags |= MFT_RECORD_IS_4;
@ -4897,12 +4990,18 @@ static BOOL mkntfs_create_root_structures(void)
/* FIXME: This should be IGNORE_CASE */
if (!err)
err = add_attr_index_root(m, "$O", 2, 0, AT_UNUSED,
COLLATION_NTOFS_ULONGS, g_vol->indx_record_size);
COLLATION_NTOFS_ULONGS,
g_vol->indx_record_size);
#ifdef ENABLE_UUID
if (!err)
err = index_obj_id_insert(m, &g_vol->guid,
MK_LE_MREF(FILE_Volume, FILE_Volume));
#endif
if (err < 0) {
ntfs_log_error("Couldn't create $ObjId: %s\n", strerror(-err));
ntfs_log_error("Couldn't create $ObjId: %s\n",
strerror(-err));
return FALSE;
}
ntfs_log_verbose("Creating $Reparse (mft record 26)\n");
m = (MFT_RECORD*)(g_buf + 26 * g_vol->mft_record_size);
m->flags |= MFT_RECORD_IS_4;

View File

@ -1717,7 +1717,7 @@ static void check_dest_free_space(u64 src_bytes)
{
u64 dest_bytes;
struct statvfs stvfs;
struct stat stat;
struct stat st;
if (opt.metadata || opt.blkdev_out || opt.std_out)
return;
@ -1732,8 +1732,8 @@ static void check_dest_free_space(u64 src_bytes)
}
/* If file is a FIFO then there is no point in checking the size. */
if (!fstat(fd_out, &stat)) {
if (S_ISFIFO(stat.st_mode))
if (!fstat(fd_out, &st)) {
if (S_ISFIFO(st.st_mode))
return;
} else
Printf("WARNING: fstat failed: %s\n", strerror(errno));