mirror of
https://git.code.sf.net/p/ntfs-3g/ntfs-3g.git
synced 2024-11-23 10:04:00 +08:00
Adapted to ntfs-3g.1.2812
This commit is contained in:
parent
ca9e62559a
commit
499e106341
1
AUTHORS
1
AUTHORS
@ -5,6 +5,7 @@ Jean-Pierre Andre
|
||||
Alon Bar-Lev
|
||||
Dominique L Bouix
|
||||
Csaba Henk
|
||||
Bernhard Kaindl
|
||||
Erik Larsson
|
||||
Alejandro Pulver
|
||||
Szabolcs Szakacsits
|
||||
|
@ -186,7 +186,8 @@ struct _ntfs_attr {
|
||||
};
|
||||
|
||||
/**
|
||||
* enum ntfs_attr_state_bits - bits for the state field in the ntfs_attr structure
|
||||
* enum ntfs_attr_state_bits - bits for the state field in the ntfs_attr
|
||||
* structure
|
||||
*/
|
||||
typedef enum {
|
||||
NA_Initialized, /* 1: structure is initialized. */
|
||||
|
@ -27,13 +27,20 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWS
|
||||
|
||||
#ifndef HAVE_FFS
|
||||
#define HAVE_FFS
|
||||
extern int ffs(int i);
|
||||
#endif /* HAVE_FFS */
|
||||
|
||||
#ifndef HAVE_DAEMON
|
||||
extern int daemon(int nochdir, int noclose);
|
||||
#endif /* HAVE_DAEMON */
|
||||
|
||||
#ifndef HAVE_STRSEP
|
||||
extern char *strsep(char **stringp, const char *delim);
|
||||
#endif /* HAVE_STRSEP */
|
||||
|
||||
#ifdef WINDOWS
|
||||
|
||||
#define HAVE_STDIO_H /* mimic config.h */
|
||||
#define HAVE_STDARG_H
|
||||
|
||||
|
@ -128,12 +128,14 @@ struct _ntfs_inode {
|
||||
inode of the base mft record. */
|
||||
};
|
||||
|
||||
/* Temp: for directory handling */
|
||||
void *private_data; /* ntfs_dt containing this inode */
|
||||
int ref_count;
|
||||
|
||||
/* Below fields are valid only for base inode. */
|
||||
s64 data_size; /* Data size stored in the filename index. */
|
||||
|
||||
/*
|
||||
* These two fields are used to sync filename index and guaranteed to be
|
||||
* correct, however value in index itself maybe wrong (windows itself
|
||||
* do not update them properly).
|
||||
*/
|
||||
s64 data_size; /* Data size of unnamed DATA attribute. */
|
||||
s64 allocated_size; /* Allocated size stored in the filename
|
||||
index. (NOTE: Equal to allocated size of
|
||||
the unnamed data attribute for normal or
|
||||
@ -141,6 +143,11 @@ struct _ntfs_inode {
|
||||
of the unnamed data attribute for sparse or
|
||||
compressed files.) */
|
||||
|
||||
/*
|
||||
* These four fields are copy of relevant fields from
|
||||
* STANDARD_INFORMATION attribute and used to sync it and FILE_NAME
|
||||
* attribute in the index.
|
||||
*/
|
||||
time_t creation_time;
|
||||
time_t last_data_change_time;
|
||||
time_t last_mft_change_time;
|
||||
|
@ -239,10 +239,6 @@ struct _ntfs_volume {
|
||||
struct CACHE_HEADER *legacy_cache;
|
||||
#endif
|
||||
|
||||
/* Temp: for directory handling */
|
||||
void *private_data; /* ntfs_dir for . */
|
||||
void *private_bmp1; /* ntfs_bmp for $MFT/$BITMAP */
|
||||
void *private_bmp2; /* ntfs_bmp for $Bitmap */
|
||||
};
|
||||
|
||||
extern ntfs_volume *ntfs_volume_alloc(void);
|
||||
|
@ -506,7 +506,7 @@ void ntfs_attr_close(ntfs_attr *na)
|
||||
* @na: ntfs attribute for which to map (part of) a runlist
|
||||
* @vcn: map runlist part containing this vcn
|
||||
*
|
||||
* Map the part of a runlist containing the @vcn of an the ntfs attribute @na.
|
||||
* Map the part of a runlist containing the @vcn of the ntfs attribute @na.
|
||||
*
|
||||
* Return 0 on success and -1 on error with errno set to the error code.
|
||||
*/
|
||||
@ -549,8 +549,8 @@ int ntfs_attr_map_runlist(ntfs_attr *na, VCN vcn)
|
||||
* ntfs_attr_map_whole_runlist - map the whole runlist of an ntfs attribute
|
||||
* @na: ntfs attribute for which to map the runlist
|
||||
*
|
||||
* Map the whole runlist of an the ntfs attribute @na. For an attribute made
|
||||
* up of only one attribute extent this is the same as calling
|
||||
* Map the whole runlist of the ntfs attribute @na. For an attribute made up
|
||||
* of only one attribute extent this is the same as calling
|
||||
* ntfs_attr_map_runlist(na, 0) but for an attribute with multiple extents this
|
||||
* will map the runlist fragments from each of the extents thus giving access
|
||||
* to the entirety of the disk allocation of an attribute.
|
||||
@ -2998,7 +2998,7 @@ int ntfs_attr_record_rm(ntfs_attr_search_ctx *ctx)
|
||||
NInoAttrListClearDirty(base_ni);
|
||||
}
|
||||
|
||||
/* Free MFT record, if it isn't contain attributes. */
|
||||
/* Free MFT record, if it doesn't contain attributes. */
|
||||
if (le32_to_cpu(ctx->mrec->bytes_in_use) -
|
||||
le16_to_cpu(ctx->mrec->attrs_offset) == 8) {
|
||||
if (ntfs_mft_record_free(ni->vol, ni)) {
|
||||
@ -3260,9 +3260,9 @@ rm_attr_err_out:
|
||||
(ATTR_RECORD*)((u8*)attr_ni->mrec + offset), 0))
|
||||
ntfs_log_perror("Failed to remove just added attribute #2");
|
||||
free_err_out:
|
||||
/* Free MFT record, if it isn't contain attributes. */
|
||||
/* Free MFT record, if it doesn't contain attributes. */
|
||||
if (le32_to_cpu(attr_ni->mrec->bytes_in_use) -
|
||||
le32_to_cpu(attr_ni->mrec->attrs_offset) == 8)
|
||||
le16_to_cpu(attr_ni->mrec->attrs_offset) == 8)
|
||||
if (ntfs_mft_record_free(attr_ni->vol, attr_ni))
|
||||
ntfs_log_perror("Failed to free MFT record");
|
||||
err_out:
|
||||
@ -4325,7 +4325,7 @@ retry:
|
||||
*/
|
||||
first_lcn = ntfs_rl_vcn_to_lcn(na->rl, stop_vcn);
|
||||
if (first_lcn == LCN_EINVAL) {
|
||||
err = EIO;
|
||||
errno = EIO;
|
||||
ntfs_log_perror("Bad runlist");
|
||||
goto put_err_out;
|
||||
}
|
||||
@ -4349,8 +4349,7 @@ retry:
|
||||
continue;
|
||||
}
|
||||
|
||||
err = ntfs_attr_update_meta(a, na, m, ctx);
|
||||
switch (err) {
|
||||
switch (ntfs_attr_update_meta(a, na, m, ctx)) {
|
||||
case -1: return -1;
|
||||
case -2: goto retry;
|
||||
case -3: goto put_err_out;
|
||||
@ -4360,7 +4359,6 @@ retry:
|
||||
mp_size = ntfs_get_size_for_mapping_pairs(na->ni->vol, na->rl,
|
||||
stop_vcn);
|
||||
if (mp_size <= 0) {
|
||||
err = errno;
|
||||
ntfs_log_perror("%s: get MP size failed", __FUNCTION__);
|
||||
goto put_err_out;
|
||||
}
|
||||
@ -4419,8 +4417,8 @@ retry:
|
||||
if (ntfs_attr_record_resize(m, a,
|
||||
le16_to_cpu(a->mapping_pairs_offset) +
|
||||
mp_size)) {
|
||||
errno = EIO;
|
||||
ntfs_log_perror("Failed to resize attribute");
|
||||
err = EIO;
|
||||
goto put_err_out;
|
||||
}
|
||||
}
|
||||
@ -4444,7 +4442,6 @@ retry:
|
||||
stop_vcn, &stop_vcn))
|
||||
finished_build = TRUE;
|
||||
if (!finished_build && errno != ENOSPC) {
|
||||
err = errno;
|
||||
ntfs_log_perror("Failed to build mapping pairs");
|
||||
goto put_err_out;
|
||||
}
|
||||
@ -4452,7 +4449,6 @@ retry:
|
||||
}
|
||||
/* Check whether error occurred. */
|
||||
if (errno != ENOENT) {
|
||||
err = errno;
|
||||
ntfs_log_perror("%s: Attribute lookup failed", __FUNCTION__);
|
||||
goto put_err_out;
|
||||
}
|
||||
@ -4468,14 +4464,12 @@ retry:
|
||||
continue;
|
||||
/* Remove unused attribute record. */
|
||||
if (ntfs_attr_record_rm(ctx)) {
|
||||
err = errno;
|
||||
ntfs_log_perror("Could not remove unused attr");
|
||||
goto put_err_out;
|
||||
}
|
||||
ntfs_attr_reinit_search_ctx(ctx);
|
||||
}
|
||||
if (errno != ENOENT) {
|
||||
err = errno;
|
||||
ntfs_log_perror("%s: Attr lookup failed", __FUNCTION__);
|
||||
goto put_err_out;
|
||||
}
|
||||
@ -4492,14 +4486,12 @@ retry:
|
||||
mp_size = ntfs_get_size_for_mapping_pairs(na->ni->vol,
|
||||
na->rl, stop_vcn);
|
||||
if (mp_size <= 0) {
|
||||
err = errno;
|
||||
ntfs_log_perror("%s: get mp size failed", __FUNCTION__);
|
||||
goto put_err_out;
|
||||
}
|
||||
/* Allocate new mft record. */
|
||||
ni = ntfs_mft_record_alloc(na->ni->vol, base_ni);
|
||||
if (!ni) {
|
||||
err = errno;
|
||||
ntfs_log_perror("Could not allocate new MFT record");
|
||||
goto put_err_out;
|
||||
}
|
||||
@ -4524,6 +4516,7 @@ retry:
|
||||
ntfs_log_perror("Could not add attribute extent");
|
||||
if (ntfs_mft_record_free(na->ni->vol, ni))
|
||||
ntfs_log_perror("Could not free MFT record");
|
||||
errno = err;
|
||||
goto put_err_out;
|
||||
}
|
||||
a = (ATTR_RECORD*)((u8*)m + err);
|
||||
@ -4536,6 +4529,7 @@ retry:
|
||||
ntfs_log_perror("Failed to build MP");
|
||||
if (ntfs_mft_record_free(na->ni->vol, ni))
|
||||
ntfs_log_perror("Couldn't free MFT record");
|
||||
errno = err;
|
||||
goto put_err_out;
|
||||
}
|
||||
a->highest_vcn = cpu_to_sle64(stop_vcn - 1);
|
||||
@ -4551,7 +4545,6 @@ out:
|
||||
put_err_out:
|
||||
if (ctx)
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
errno = err;
|
||||
goto out;
|
||||
}
|
||||
#undef NTFS_VCN_DELETE_MARK
|
||||
@ -4916,7 +4909,7 @@ rollback:
|
||||
ntfs_log_perror("Couldn't truncate runlist. Rollback failed");
|
||||
} else {
|
||||
/* Prepare to mapping pairs update. */
|
||||
na->allocated_size = org_alloc_size << vol->cluster_size_bits;
|
||||
na->allocated_size = org_alloc_size;
|
||||
/* Restore mapping pairs. */
|
||||
if (ntfs_attr_update_mapping_pairs(na, 0 /*na->allocated_size >>
|
||||
vol->cluster_size_bits*/)) {
|
||||
|
@ -20,16 +20,12 @@
|
||||
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef WINDOWS
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
/* TODO: Add check for FFS in the configure script... (AIA) */
|
||||
|
||||
#ifndef HAVE_FFS
|
||||
/**
|
||||
* ffs - Find the first set bit in an int
|
||||
@ -69,5 +65,186 @@ int ffs(int x)
|
||||
}
|
||||
#endif /* HAVE_FFS */
|
||||
|
||||
#endif /* WINDOWS */
|
||||
#ifndef HAVE_DAEMON
|
||||
/* ************************************************************
|
||||
* From: src.opensolaris.org
|
||||
* src/lib/libresolv2/common/bsd/daemon.c
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1997-2000 by Sun Microsystems, Inc.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char sccsid[] = "@(#)daemon.c 8.1 (Berkeley) 6/4/93";
|
||||
static const char rcsid[] = "$Id: compat.c,v 1.1.1.1.2.1 2008-08-16 15:17:44 jpandre Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
int daemon(int nochdir, int noclose) {
|
||||
int fd;
|
||||
|
||||
switch (fork()) {
|
||||
case -1:
|
||||
return (-1);
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
if (setsid() == -1)
|
||||
return (-1);
|
||||
|
||||
if (!nochdir)
|
||||
(void)chdir("/");
|
||||
|
||||
if (!noclose && (fd = open("/dev/null", O_RDWR, 0)) != -1) {
|
||||
(void)dup2(fd, 0);
|
||||
(void)dup2(fd, 1);
|
||||
(void)dup2(fd, 2);
|
||||
if (fd > 2)
|
||||
(void)close (fd);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* End: src/lib/libresolv2/common/bsd/daemon.c
|
||||
*************************************************************/
|
||||
#endif /* HAVE_DAEMON */
|
||||
|
||||
#ifndef HAVE_STRSEP
|
||||
/* ************************************************************
|
||||
* From: src.opensolaris.org
|
||||
* src/lib/libresolv2/common/bsd/strsep.c
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1997, by Sun Microsystems, Inc.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char sccsid[] = "strsep.c 8.1 (Berkeley) 6/4/93";
|
||||
static const char rcsid[] = "$Id: compat.c,v 1.1.1.1.2.1 2008-08-16 15:17:44 jpandre Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDIO_H
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get next token from string *stringp, where tokens are possibly-empty
|
||||
* strings separated by characters from delim.
|
||||
*
|
||||
* Writes NULs into the string at *stringp to end tokens.
|
||||
* delim need not remain constant from call to call.
|
||||
* On return, *stringp points past the last NUL written (if there might
|
||||
* be further tokens), or is NULL (if there are definitely no more tokens).
|
||||
*
|
||||
* If *stringp is NULL, strsep returns NULL.
|
||||
*/
|
||||
char *strsep(char **stringp, const char *delim) {
|
||||
char *s;
|
||||
const char *spanp;
|
||||
int c, sc;
|
||||
char *tok;
|
||||
|
||||
if ((s = *stringp) == NULL)
|
||||
return (NULL);
|
||||
for (tok = s;;) {
|
||||
c = *s++;
|
||||
spanp = delim;
|
||||
do {
|
||||
if ((sc = *spanp++) == c) {
|
||||
if (c == 0)
|
||||
s = NULL;
|
||||
else
|
||||
s[-1] = 0;
|
||||
*stringp = s;
|
||||
return (tok);
|
||||
}
|
||||
} while (sc != 0);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* End: src/lib/libresolv2/common/bsd/strsep.c
|
||||
*************************************************************/
|
||||
#endif /* HAVE_STRSEP */
|
||||
|
||||
|
@ -1419,21 +1419,21 @@ static int ntfs_ib_split(ntfs_index_context *icx, INDEX_BLOCK *ib)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* JPA static */
|
||||
int ntfs_ie_add(ntfs_index_context *icx, INDEX_ENTRY *ie)
|
||||
{
|
||||
INDEX_HEADER *ih;
|
||||
int allocated_size, new_size;
|
||||
int ret = STATUS_ERROR;
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
/* removed by JPA to make function usable for security indexes
|
||||
char *fn;
|
||||
|
||||
fn = ntfs_ie_filename_get(ie);
|
||||
ntfs_log_trace("file: '%s'\n", fn);
|
||||
ntfs_attr_name_free(&fn);
|
||||
*/
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
|
||||
|
@ -275,6 +275,8 @@ err_out:
|
||||
* If it is an extent inode, we disconnect it from its base inode before we
|
||||
* destroy it.
|
||||
*
|
||||
* It is OK to pass NULL to this function, it is just noop in this case.
|
||||
*
|
||||
* Return 0 on success or -1 on error with errno set to the error code. On
|
||||
* error, @ni has not been freed. The user should attempt to handle the error
|
||||
* and call ntfs_inode_close() again. The following error codes are defined:
|
||||
|
@ -52,6 +52,10 @@ typedef struct ntfs_volume ntfs_volume;
|
||||
#include "types.h"
|
||||
#include "device.h"
|
||||
|
||||
#ifndef MAX_PATH
|
||||
#define MAX_PATH 1024
|
||||
#endif
|
||||
|
||||
#ifndef NTFS_BLOCK_SIZE
|
||||
#define NTFS_BLOCK_SIZE 512
|
||||
#define NTFS_BLOCK_SIZE_BITS 9
|
||||
|
116
src/ntfs-3g.c
116
src/ntfs-3g.c
@ -75,6 +75,14 @@
|
||||
#include <sys/xattr.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_MKDEV_H
|
||||
#include <sys/mkdev.h>
|
||||
#endif
|
||||
|
||||
#include "compat.h"
|
||||
#include "attrib.h"
|
||||
#include "inode.h"
|
||||
#include "volume.h"
|
||||
@ -376,18 +384,16 @@ static int ntfs_fuse_getattr(const char *org_path, struct stat *stbuf)
|
||||
int res = 0;
|
||||
ntfs_inode *ni;
|
||||
ntfs_attr *na;
|
||||
ntfs_volume *vol;
|
||||
char *path = NULL;
|
||||
ntfschar *stream_name;
|
||||
int stream_name_len;
|
||||
struct SECURITY_CONTEXT security;
|
||||
|
||||
vol = ctx->vol;
|
||||
stream_name_len = ntfs_fuse_parse_path(org_path, &path, &stream_name);
|
||||
if (stream_name_len < 0)
|
||||
return stream_name_len;
|
||||
memset(stbuf, 0, sizeof(struct stat));
|
||||
ni = ntfs_pathname_to_inode(vol, NULL, path);
|
||||
ni = ntfs_pathname_to_inode(ctx->vol, NULL, path);
|
||||
if (!ni) {
|
||||
res = -errno;
|
||||
goto exit;
|
||||
@ -630,15 +636,13 @@ static int ntfs_fuse_readdir(const char *path, void *buf,
|
||||
struct fuse_file_info *fi __attribute__((unused)))
|
||||
{
|
||||
ntfs_fuse_fill_context_t fill_ctx;
|
||||
ntfs_volume *vol;
|
||||
ntfs_inode *ni;
|
||||
s64 pos = 0;
|
||||
int err = 0;
|
||||
|
||||
vol = ctx->vol;
|
||||
fill_ctx.filler = filler;
|
||||
fill_ctx.buf = buf;
|
||||
ni = ntfs_pathname_to_inode(vol, NULL, path);
|
||||
ni = ntfs_pathname_to_inode(ctx->vol, NULL, path);
|
||||
if (!ni)
|
||||
return -errno;
|
||||
if (ntfs_readdir(ni, &pos, &fill_ctx,
|
||||
@ -653,7 +657,6 @@ static int ntfs_fuse_readdir(const char *path, void *buf,
|
||||
static int ntfs_fuse_open(const char *org_path,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
ntfs_volume *vol;
|
||||
ntfs_inode *ni;
|
||||
ntfs_attr *na;
|
||||
int res = 0;
|
||||
@ -666,8 +669,7 @@ static int ntfs_fuse_open(const char *org_path,
|
||||
stream_name_len = ntfs_fuse_parse_path(org_path, &path, &stream_name);
|
||||
if (stream_name_len < 0)
|
||||
return stream_name_len;
|
||||
vol = ctx->vol;
|
||||
ni = ntfs_pathname_to_inode(vol, NULL, path);
|
||||
ni = ntfs_pathname_to_inode(ctx->vol, NULL, path);
|
||||
if (ni) {
|
||||
na = ntfs_attr_open(ni, AT_DATA, stream_name, stream_name_len);
|
||||
if (na) {
|
||||
@ -765,7 +767,6 @@ exit:
|
||||
static int ntfs_fuse_write(const char *org_path, const char *buf, size_t size,
|
||||
off_t offset, struct fuse_file_info *fi __attribute__((unused)))
|
||||
{
|
||||
ntfs_volume *vol;
|
||||
ntfs_inode *ni = NULL;
|
||||
ntfs_attr *na = NULL;
|
||||
char *path = NULL;
|
||||
@ -777,8 +778,7 @@ static int ntfs_fuse_write(const char *org_path, const char *buf, size_t size,
|
||||
res = stream_name_len;
|
||||
goto out;
|
||||
}
|
||||
vol = ctx->vol;
|
||||
ni = ntfs_pathname_to_inode(vol, NULL, path);
|
||||
ni = ntfs_pathname_to_inode(ctx->vol, NULL, path);
|
||||
if (!ni) {
|
||||
res = -errno;
|
||||
goto exit;
|
||||
@ -789,17 +789,18 @@ static int ntfs_fuse_write(const char *org_path, const char *buf, size_t size,
|
||||
goto exit;
|
||||
}
|
||||
while (size) {
|
||||
res = ntfs_attr_pwrite(na, offset, size, buf);
|
||||
if (res < (s64)size)
|
||||
ntfs_log_perror("ntfs_attr_pwrite partial write (%lld: "
|
||||
"%lld <> %d)", (long long)offset, (long long)size, res);
|
||||
if (res <= 0) {
|
||||
s64 ret = ntfs_attr_pwrite(na, offset, size, buf);
|
||||
if (0 <= ret && ret < (s64)size)
|
||||
ntfs_log_perror("ntfs_attr_pwrite partial write to '%s'"
|
||||
" (%lld: %lld <> %lld)", path, (long long)offset,
|
||||
(long long)size, ret);
|
||||
if (ret <= 0) {
|
||||
res = -errno;
|
||||
goto exit;
|
||||
}
|
||||
size -= res;
|
||||
offset += res;
|
||||
total += res;
|
||||
size -= ret;
|
||||
offset += ret;
|
||||
total += ret;
|
||||
}
|
||||
res = total;
|
||||
if (res > 0)
|
||||
@ -822,7 +823,6 @@ out:
|
||||
|
||||
static int ntfs_fuse_trunc(const char *org_path, off_t size, BOOL chkwrite)
|
||||
{
|
||||
ntfs_volume *vol;
|
||||
ntfs_inode *ni = NULL;
|
||||
ntfs_attr *na = NULL;
|
||||
int res;
|
||||
@ -834,8 +834,7 @@ static int ntfs_fuse_trunc(const char *org_path, off_t size, BOOL chkwrite)
|
||||
stream_name_len = ntfs_fuse_parse_path(org_path, &path, &stream_name);
|
||||
if (stream_name_len < 0)
|
||||
return stream_name_len;
|
||||
vol = ctx->vol;
|
||||
ni = ntfs_pathname_to_inode(vol, NULL, path);
|
||||
ni = ntfs_pathname_to_inode(ctx->vol, NULL, path);
|
||||
if (!ni)
|
||||
goto exit;
|
||||
|
||||
@ -1166,29 +1165,7 @@ static int ntfs_fuse_create_stream(const char *path,
|
||||
return res;
|
||||
}
|
||||
|
||||
static int ntfs_fuse_create_file(const char *org_path, mode_t mode,
|
||||
struct fuse_file_info *fi __attribute__((unused)))
|
||||
{
|
||||
char *path = NULL;
|
||||
ntfschar *stream_name;
|
||||
int stream_name_len;
|
||||
int res;
|
||||
|
||||
stream_name_len = ntfs_fuse_parse_path(org_path, &path, &stream_name);
|
||||
if (stream_name_len < 0)
|
||||
return stream_name_len;
|
||||
if (!stream_name_len)
|
||||
res = ntfs_fuse_create(path, mode, 0, NULL);
|
||||
else
|
||||
res = ntfs_fuse_create_stream(path, stream_name,
|
||||
stream_name_len);
|
||||
free(path);
|
||||
if (stream_name_len)
|
||||
free(stream_name);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int ntfs_fuse_mknod(const char *org_path, mode_t mode, dev_t dev)
|
||||
static int ntfs_fuse_mknod_common(const char *org_path, mode_t mode, dev_t dev)
|
||||
{
|
||||
char *path = NULL;
|
||||
ntfschar *stream_name;
|
||||
@ -1214,6 +1191,17 @@ exit:
|
||||
return res;
|
||||
}
|
||||
|
||||
static int ntfs_fuse_mknod(const char *path, mode_t mode, dev_t dev)
|
||||
{
|
||||
return ntfs_fuse_mknod_common(path, mode, dev);
|
||||
}
|
||||
|
||||
static int ntfs_fuse_create_file(const char *path, mode_t mode,
|
||||
struct fuse_file_info *fi __attribute__((unused)))
|
||||
{
|
||||
return ntfs_fuse_mknod_common(path, mode, 0);
|
||||
}
|
||||
|
||||
static int ntfs_fuse_symlink(const char *to, const char *from)
|
||||
{
|
||||
if (ntfs_fuse_is_named_data_stream(from))
|
||||
@ -1616,17 +1604,13 @@ static const int nf_ns_xattr_preffix_len = 5;
|
||||
static int ntfs_fuse_listxattr(const char *path, char *list, size_t size)
|
||||
{
|
||||
ntfs_attr_search_ctx *actx = NULL;
|
||||
ntfs_volume *vol;
|
||||
ntfs_inode *ni;
|
||||
char *to = list;
|
||||
int ret = 0;
|
||||
|
||||
if (ctx->streams != NF_STREAMS_INTERFACE_XATTR)
|
||||
return -EOPNOTSUPP;
|
||||
vol = ctx->vol;
|
||||
if (!vol)
|
||||
return -ENODEV;
|
||||
ni = ntfs_pathname_to_inode(vol, NULL, path);
|
||||
ni = ntfs_pathname_to_inode(ctx->vol, NULL, path);
|
||||
if (!ni)
|
||||
return -errno;
|
||||
actx = ntfs_attr_get_search_ctx(ni, NULL);
|
||||
@ -1680,17 +1664,13 @@ static int ntfs_fuse_getxattr_windows(const char *path, const char *name,
|
||||
char *value, size_t size)
|
||||
{
|
||||
ntfs_attr_search_ctx *actx = NULL;
|
||||
ntfs_volume *vol;
|
||||
ntfs_inode *ni;
|
||||
char *to = value;
|
||||
int ret = 0;
|
||||
|
||||
if (strcmp(name, "ntfs.streams.list"))
|
||||
return -EOPNOTSUPP;
|
||||
vol = ctx->vol;
|
||||
if (!vol)
|
||||
return -ENODEV;
|
||||
ni = ntfs_pathname_to_inode(vol, NULL, path);
|
||||
ni = ntfs_pathname_to_inode(ctx->vol, NULL, path);
|
||||
if (!ni)
|
||||
return -errno;
|
||||
actx = ntfs_attr_get_search_ctx(ni, NULL);
|
||||
@ -1746,7 +1726,6 @@ exit:
|
||||
static int ntfs_fuse_getxattr(const char *path, const char *name,
|
||||
char *value, size_t size)
|
||||
{
|
||||
ntfs_volume *vol;
|
||||
ntfs_inode *ni;
|
||||
ntfs_attr *na = NULL;
|
||||
ntfschar *lename = NULL;
|
||||
@ -1759,10 +1738,7 @@ static int ntfs_fuse_getxattr(const char *path, const char *name,
|
||||
if (strncmp(name, nf_ns_xattr_preffix, nf_ns_xattr_preffix_len) ||
|
||||
strlen(name) == (size_t)nf_ns_xattr_preffix_len)
|
||||
return -ENODATA;
|
||||
vol = ctx->vol;
|
||||
if (!vol)
|
||||
return -ENODEV;
|
||||
ni = ntfs_pathname_to_inode(vol, NULL, path);
|
||||
ni = ntfs_pathname_to_inode(ctx->vol, NULL, path);
|
||||
if (!ni)
|
||||
return -errno;
|
||||
lename_len = ntfs_mbstoucs(name + nf_ns_xattr_preffix_len, &lename);
|
||||
@ -1796,7 +1772,6 @@ exit:
|
||||
static int ntfs_fuse_setxattr(const char *path, const char *name,
|
||||
const char *value, size_t size, int flags)
|
||||
{
|
||||
ntfs_volume *vol;
|
||||
ntfs_inode *ni;
|
||||
ntfs_attr *na = NULL;
|
||||
ntfschar *lename = NULL;
|
||||
@ -1807,10 +1782,7 @@ static int ntfs_fuse_setxattr(const char *path, const char *name,
|
||||
if (strncmp(name, nf_ns_xattr_preffix, nf_ns_xattr_preffix_len) ||
|
||||
strlen(name) == (size_t)nf_ns_xattr_preffix_len)
|
||||
return -EACCES;
|
||||
vol = ctx->vol;
|
||||
if (!vol)
|
||||
return -ENODEV;
|
||||
ni = ntfs_pathname_to_inode(vol, NULL, path);
|
||||
ni = ntfs_pathname_to_inode(ctx->vol, NULL, path);
|
||||
if (!ni)
|
||||
return -errno;
|
||||
lename_len = ntfs_mbstoucs(name + nf_ns_xattr_preffix_len, &lename);
|
||||
@ -1854,7 +1826,6 @@ exit:
|
||||
|
||||
static int ntfs_fuse_removexattr(const char *path, const char *name)
|
||||
{
|
||||
ntfs_volume *vol;
|
||||
ntfs_inode *ni;
|
||||
ntfschar *lename = NULL;
|
||||
int res = 0, lename_len;
|
||||
@ -1865,10 +1836,7 @@ static int ntfs_fuse_removexattr(const char *path, const char *name)
|
||||
if (strncmp(name, nf_ns_xattr_preffix, nf_ns_xattr_preffix_len) ||
|
||||
strlen(name) == (size_t)nf_ns_xattr_preffix_len)
|
||||
return -ENODATA;
|
||||
vol = ctx->vol;
|
||||
if (!vol)
|
||||
return -ENODEV;
|
||||
ni = ntfs_pathname_to_inode(vol, NULL, path);
|
||||
ni = ntfs_pathname_to_inode(ctx->vol, NULL, path);
|
||||
if (!ni)
|
||||
return -errno;
|
||||
lename_len = ntfs_mbstoucs(name + nf_ns_xattr_preffix_len, &lename);
|
||||
@ -2579,7 +2547,7 @@ static void setup_logging(char *parsed_options)
|
||||
opts.device, (ctx->ro) ? "Read-Only" : "Read-Write",
|
||||
ctx->vol->vol_name, ctx->vol->major_ver,
|
||||
ctx->vol->minor_ver);
|
||||
ntfs_log_info("Cmdline options: %s\n", opts.options);
|
||||
ntfs_log_info("Cmdline options: %s\n", opts.options ? opts.options : "");
|
||||
ntfs_log_info("Mount options: %s\n", parsed_options);
|
||||
}
|
||||
|
||||
@ -2645,15 +2613,17 @@ int main(int argc, char *argv[])
|
||||
if (drop_privs())
|
||||
goto err_out;
|
||||
#endif
|
||||
|
||||
if (stat(opts.device, &sbuf)) {
|
||||
ntfs_log_perror("Failed to access '%s'", opts.device);
|
||||
err = NTFS_VOLUME_NO_PRIVILEGE;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
#if !(defined(__sun) && defined (__SVR4))
|
||||
/* Always use fuseblk for block devices unless it's surely missing. */
|
||||
if (S_ISBLK(sbuf.st_mode) && (fstype != FSTYPE_FUSE))
|
||||
ctx->blkdev = TRUE;
|
||||
#endif
|
||||
|
||||
#ifndef FUSE_INTERNAL
|
||||
if (getuid() && ctx->blkdev) {
|
||||
|
Loading…
Reference in New Issue
Block a user