mirror of
https://git.code.sf.net/p/ntfs-3g/ntfs-3g.git
synced 2024-11-23 01:53:45 +08:00
Enabled Recording the special files the same way as WSL
Optionally record the special files (symlinks, fifos, sockets, character and block devices) using reparse points instead of using Interix representation. Doing so, the special files are interoperable with Windows Subsystem for linux (WSL).
This commit is contained in:
parent
172da09947
commit
5d46b32b91
@ -26,6 +26,8 @@
|
||||
|
||||
int ntfs_ea_check_wsldev(ntfs_inode *ni, dev_t *rdevp);
|
||||
|
||||
int ntfs_ea_set_wsl_not_symlink(ntfs_inode *ni, mode_t mode, dev_t dev);
|
||||
|
||||
int ntfs_get_ntfs_ea(ntfs_inode *ni, char *value, size_t size);
|
||||
|
||||
int ntfs_set_ntfs_ea(ntfs_inode *ni, const char *value, size_t size, int flags);
|
||||
|
@ -37,6 +37,11 @@ REPARSE_POINT *ntfs_get_reparse_point(ntfs_inode *ni);
|
||||
|
||||
int ntfs_reparse_check_wsl(ntfs_inode *ni, const REPARSE_POINT *reparse);
|
||||
|
||||
int ntfs_reparse_set_wsl_symlink(ntfs_inode *ni,
|
||||
const ntfschar *target, int target_len);
|
||||
|
||||
int ntfs_reparse_set_wsl_not_symlink(ntfs_inode *ni, mode_t mode);
|
||||
|
||||
int ntfs_set_ntfs_reparse_data(ntfs_inode *ni, const char *value,
|
||||
size_t size, int flags);
|
||||
int ntfs_remove_ntfs_reparse_data(ntfs_inode *ni);
|
||||
|
@ -98,6 +98,11 @@ typedef enum {
|
||||
NTFS_VOLUME_INSECURE = 22
|
||||
} ntfs_volume_status;
|
||||
|
||||
typedef enum {
|
||||
NTFS_FILES_INTERIX,
|
||||
NTFS_FILES_WSL,
|
||||
} ntfs_volume_special_files;
|
||||
|
||||
/**
|
||||
* enum ntfs_volume_state_bits -
|
||||
*
|
||||
@ -256,6 +261,7 @@ struct _ntfs_volume {
|
||||
s64 free_mft_records; /* Same for free mft records (see above) */
|
||||
BOOL efs_raw; /* volume is mounted for raw access to
|
||||
efs-encrypted files */
|
||||
ntfs_volume_special_files special_files; /* Implementation of special files */
|
||||
const char *abs_mnt_point; /* Mount point */
|
||||
#ifdef XATTR_MAPPINGS
|
||||
struct XATTRMAPPING *xattr_mapping;
|
||||
|
127
libntfs-3g/dir.c
127
libntfs-3g/dir.c
@ -5,7 +5,7 @@
|
||||
* Copyright (c) 2004-2005 Richard Russon
|
||||
* Copyright (c) 2004-2008 Szabolcs Szakacsits
|
||||
* Copyright (c) 2005-2007 Yura Pakhuchiy
|
||||
* Copyright (c) 2008-2020 Jean-Pierre Andre
|
||||
* Copyright (c) 2008-2021 Jean-Pierre Andre
|
||||
*
|
||||
* 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
|
||||
@ -68,6 +68,7 @@
|
||||
#include "reparse.h"
|
||||
#include "object_id.h"
|
||||
#include "xattrs.h"
|
||||
#include "ea.h"
|
||||
|
||||
/*
|
||||
* The little endian Unicode strings "$I30", "$SII", "$SDH", "$O"
|
||||
@ -1496,9 +1497,11 @@ static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, le32 securid,
|
||||
{
|
||||
ntfs_inode *ni;
|
||||
int rollback_data = 0, rollback_sd = 0;
|
||||
int rollback_dir = 0;
|
||||
FILE_NAME_ATTR *fn = NULL;
|
||||
STANDARD_INFORMATION *si = NULL;
|
||||
int err, fn_len, si_len;
|
||||
ntfs_volume_special_files special_files;
|
||||
|
||||
ntfs_log_trace("Entering.\n");
|
||||
|
||||
@ -1515,6 +1518,7 @@ static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, le32 securid,
|
||||
#if CACHE_NIDATA_SIZE
|
||||
ntfs_inode_invalidate(dir_ni->vol, ni->mft_no);
|
||||
#endif
|
||||
special_files = dir_ni->vol->special_files;
|
||||
/*
|
||||
* Create STANDARD_INFORMATION attribute.
|
||||
* JPA Depending on available inherited security descriptor,
|
||||
@ -1542,8 +1546,19 @@ static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, le32 securid,
|
||||
} else
|
||||
clear_nino_flag(ni, v3_Extensions);
|
||||
if (!S_ISREG(type) && !S_ISDIR(type)) {
|
||||
si->file_attributes = FILE_ATTR_SYSTEM;
|
||||
ni->flags = FILE_ATTR_SYSTEM;
|
||||
switch (special_files) {
|
||||
case NTFS_FILES_WSL :
|
||||
if (!S_ISLNK(type)) {
|
||||
si->file_attributes
|
||||
= FILE_ATTRIBUTE_RECALL_ON_OPEN;
|
||||
ni->flags = FILE_ATTRIBUTE_RECALL_ON_OPEN;
|
||||
}
|
||||
break;
|
||||
default :
|
||||
si->file_attributes = FILE_ATTR_SYSTEM;
|
||||
ni->flags = FILE_ATTR_SYSTEM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ni->flags |= FILE_ATTR_ARCHIVE;
|
||||
if (NVolHideDotFiles(dir_ni->vol)
|
||||
@ -1576,8 +1591,8 @@ static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, le32 securid,
|
||||
err = errno;
|
||||
goto err_out;
|
||||
}
|
||||
rollback_sd = 1;
|
||||
}
|
||||
rollback_sd = 1;
|
||||
|
||||
if (S_ISDIR(type)) {
|
||||
INDEX_ROOT *ir = NULL;
|
||||
@ -1626,34 +1641,58 @@ static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, le32 securid,
|
||||
switch (type) {
|
||||
case S_IFBLK:
|
||||
case S_IFCHR:
|
||||
data_len = offsetof(INTX_FILE, device_end);
|
||||
data = ntfs_malloc(data_len);
|
||||
if (!data) {
|
||||
err = errno;
|
||||
goto err_out;
|
||||
switch (special_files) {
|
||||
case NTFS_FILES_WSL :
|
||||
data_len = 0;
|
||||
data = (INTX_FILE*)NULL;
|
||||
break;
|
||||
default :
|
||||
data_len = offsetof(INTX_FILE,
|
||||
device_end);
|
||||
data = (INTX_FILE*)ntfs_malloc(
|
||||
data_len);
|
||||
if (!data) {
|
||||
err = errno;
|
||||
goto err_out;
|
||||
}
|
||||
data->major = cpu_to_le64(major(dev));
|
||||
data->minor = cpu_to_le64(minor(dev));
|
||||
if (type == S_IFBLK)
|
||||
data->magic
|
||||
= INTX_BLOCK_DEVICE;
|
||||
if (type == S_IFCHR)
|
||||
data->magic
|
||||
= INTX_CHARACTER_DEVICE;
|
||||
break;
|
||||
}
|
||||
data->major = cpu_to_le64(major(dev));
|
||||
data->minor = cpu_to_le64(minor(dev));
|
||||
if (type == S_IFBLK)
|
||||
data->magic = INTX_BLOCK_DEVICE;
|
||||
if (type == S_IFCHR)
|
||||
data->magic = INTX_CHARACTER_DEVICE;
|
||||
break;
|
||||
case S_IFLNK:
|
||||
data_len = sizeof(INTX_FILE_TYPES) +
|
||||
switch (special_files) {
|
||||
case NTFS_FILES_WSL :
|
||||
data_len = 0;
|
||||
data = (INTX_FILE*)NULL;
|
||||
break;
|
||||
default :
|
||||
data_len = sizeof(INTX_FILE_TYPES) +
|
||||
target_len * sizeof(ntfschar);
|
||||
data = ntfs_malloc(data_len);
|
||||
if (!data) {
|
||||
err = errno;
|
||||
goto err_out;
|
||||
}
|
||||
data->magic = INTX_SYMBOLIC_LINK;
|
||||
memcpy(data->target, target,
|
||||
data = (INTX_FILE*)ntfs_malloc(
|
||||
data_len);
|
||||
if (!data) {
|
||||
err = errno;
|
||||
goto err_out;
|
||||
}
|
||||
data->magic = INTX_SYMBOLIC_LINK;
|
||||
memcpy(data->target, target,
|
||||
target_len * sizeof(ntfschar));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case S_IFSOCK:
|
||||
data = NULL;
|
||||
data_len = 1;
|
||||
if (special_files == NTFS_FILES_WSL)
|
||||
data_len = 0;
|
||||
else
|
||||
data_len = 1;
|
||||
break;
|
||||
default: /* FIFO or regular file. */
|
||||
data = NULL;
|
||||
@ -1684,9 +1723,10 @@ static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, le32 securid,
|
||||
fn->file_name_type = FILE_NAME_POSIX;
|
||||
if (S_ISDIR(type))
|
||||
fn->file_attributes = FILE_ATTR_I30_INDEX_PRESENT;
|
||||
if (!S_ISREG(type) && !S_ISDIR(type))
|
||||
fn->file_attributes = FILE_ATTR_SYSTEM;
|
||||
else
|
||||
if (!S_ISREG(type) && !S_ISDIR(type)) {
|
||||
if (special_files == NTFS_FILES_INTERIX)
|
||||
fn->file_attributes = FILE_ATTR_SYSTEM;
|
||||
} else
|
||||
fn->file_attributes |= ni->flags & FILE_ATTR_COMPRESSED;
|
||||
fn->file_attributes |= FILE_ATTR_ARCHIVE;
|
||||
fn->file_attributes |= ni->flags & FILE_ATTR_HIDDEN;
|
||||
@ -1714,10 +1754,40 @@ static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, le32 securid,
|
||||
ntfs_log_perror("Failed to add entry to the index");
|
||||
goto err_out;
|
||||
}
|
||||
rollback_dir = 1;
|
||||
/* Set hard links count and directory flag. */
|
||||
ni->mrec->link_count = const_cpu_to_le16(1);
|
||||
if (S_ISDIR(type))
|
||||
ni->mrec->flags |= MFT_RECORD_IS_DIRECTORY;
|
||||
/* Add reparse data */
|
||||
if (special_files == NTFS_FILES_WSL) {
|
||||
switch (type) {
|
||||
case S_IFLNK :
|
||||
err = ntfs_reparse_set_wsl_symlink(ni, target,
|
||||
target_len);
|
||||
break;
|
||||
case S_IFIFO :
|
||||
case S_IFSOCK :
|
||||
case S_IFCHR :
|
||||
case S_IFBLK :
|
||||
err = ntfs_reparse_set_wsl_not_symlink(ni,
|
||||
type);
|
||||
if (!err) {
|
||||
err = ntfs_ea_set_wsl_not_symlink(ni,
|
||||
type, dev);
|
||||
if (err)
|
||||
ntfs_remove_ntfs_reparse_data(ni);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
err = 0;
|
||||
break;
|
||||
}
|
||||
if (err) {
|
||||
err = errno;
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
ntfs_inode_mark_dirty(ni);
|
||||
/* Done! */
|
||||
free(fn);
|
||||
@ -1727,6 +1797,9 @@ static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, le32 securid,
|
||||
err_out:
|
||||
ntfs_log_trace("Failed.\n");
|
||||
|
||||
if (rollback_dir)
|
||||
ntfs_index_remove(dir_ni, ni, fn, fn_len);
|
||||
|
||||
if (rollback_sd)
|
||||
ntfs_attr_remove(ni, AT_SECURITY_DESCRIPTOR, AT_UNNAMED, 0);
|
||||
|
||||
|
@ -62,6 +62,7 @@
|
||||
#include "xattrs.h"
|
||||
|
||||
static const char lxdev[] = "$LXDEV";
|
||||
static const char lxmod[] = "$LXMOD";
|
||||
|
||||
|
||||
/*
|
||||
@ -466,3 +467,53 @@ int ntfs_ea_check_wsldev(ntfs_inode *ni, dev_t *rdevp)
|
||||
return (res);
|
||||
}
|
||||
|
||||
int ntfs_ea_set_wsl_not_symlink(ntfs_inode *ni, mode_t type, dev_t dev)
|
||||
{
|
||||
le32 mode;
|
||||
struct {
|
||||
le32 major;
|
||||
le32 minor;
|
||||
} device;
|
||||
struct EA_WSL {
|
||||
struct EA_LXMOD { /* always inserted */
|
||||
EA_ATTR base;
|
||||
char name[sizeof(lxmod)];
|
||||
char value[sizeof(mode)];
|
||||
char stuff[3 & -(sizeof(lxmod) + sizeof(mode))];
|
||||
} mod;
|
||||
struct EA_LXDEV { /* char or block devices only */
|
||||
EA_ATTR base;
|
||||
char name[sizeof(lxdev)];
|
||||
char value[sizeof(device)];
|
||||
char stuff[3 & -(sizeof(lxdev) + sizeof(device))];
|
||||
} dev;
|
||||
} attr;
|
||||
int len;
|
||||
int res;
|
||||
|
||||
memset(&attr, 0, sizeof(attr));
|
||||
mode = cpu_to_le32((u32)(type | 0644));
|
||||
attr.mod.base.next_entry_offset
|
||||
= const_cpu_to_le32(sizeof(attr.mod));
|
||||
attr.mod.base.flags = 0;
|
||||
attr.mod.base.name_length = sizeof(lxmod) - 1;
|
||||
attr.mod.base.value_length = const_cpu_to_le16(sizeof(mode));
|
||||
memcpy(attr.mod.name, lxmod, sizeof(lxmod));
|
||||
memcpy(attr.mod.value, &mode, sizeof(mode));
|
||||
len = sizeof(attr.mod);
|
||||
|
||||
if (S_ISCHR(type) || S_ISBLK(type)) {
|
||||
device.major = cpu_to_le32(major(dev));
|
||||
device.minor = cpu_to_le32(minor(dev));
|
||||
attr.dev.base.next_entry_offset
|
||||
= const_cpu_to_le32(sizeof(attr.dev));
|
||||
attr.dev.base.flags = 0;
|
||||
attr.dev.base.name_length = sizeof(lxdev) - 1;
|
||||
attr.dev.base.value_length = const_cpu_to_le16(sizeof(device));
|
||||
memcpy(attr.dev.name, lxdev, sizeof(lxdev));
|
||||
memcpy(attr.dev.value, &device, sizeof(device));
|
||||
len += sizeof(attr.dev);
|
||||
}
|
||||
res = ntfs_set_ntfs_ea(ni, (char*)&attr, len, 0);
|
||||
return (res);
|
||||
}
|
||||
|
@ -1331,6 +1331,92 @@ int ntfs_remove_ntfs_reparse_data(ntfs_inode *ni)
|
||||
return (res ? -1 : 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set reparse data for a WSL type symlink
|
||||
*/
|
||||
|
||||
int ntfs_reparse_set_wsl_symlink(ntfs_inode *ni,
|
||||
const ntfschar *target, int target_len)
|
||||
{
|
||||
int res;
|
||||
int len;
|
||||
int reparse_len;
|
||||
char *utarget;
|
||||
REPARSE_POINT *reparse;
|
||||
struct WSL_LINK_REPARSE_DATA *data;
|
||||
|
||||
res = -1;
|
||||
utarget = (char*)NULL;
|
||||
len = ntfs_ucstombs(target, target_len, &utarget, 0);
|
||||
if (len > 0) {
|
||||
reparse_len = sizeof(REPARSE_POINT) + sizeof(data->type) + len;
|
||||
reparse = (REPARSE_POINT*)malloc(reparse_len);
|
||||
if (reparse) {
|
||||
data = (struct WSL_LINK_REPARSE_DATA*)
|
||||
reparse->reparse_data;
|
||||
reparse->reparse_tag = IO_REPARSE_TAG_LX_SYMLINK;
|
||||
reparse->reparse_data_length
|
||||
= cpu_to_le16(sizeof(data->type) + len);
|
||||
reparse->reserved = const_cpu_to_le16(0);
|
||||
data->type = const_cpu_to_le32(2);
|
||||
memcpy(data->link, utarget, len);
|
||||
res = ntfs_set_ntfs_reparse_data(ni,
|
||||
(char*)reparse, reparse_len, 0);
|
||||
free(reparse);
|
||||
}
|
||||
}
|
||||
free(utarget);
|
||||
return (res);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set reparse data for a WSL special file other than a symlink
|
||||
* (socket, fifo, character or block device)
|
||||
*/
|
||||
|
||||
int ntfs_reparse_set_wsl_not_symlink(ntfs_inode *ni, mode_t mode)
|
||||
{
|
||||
int res;
|
||||
int len;
|
||||
int reparse_len;
|
||||
le32 reparse_tag;
|
||||
REPARSE_POINT *reparse;
|
||||
|
||||
res = -1;
|
||||
len = 0;
|
||||
switch (mode) {
|
||||
case S_IFSOCK :
|
||||
reparse_tag = IO_REPARSE_TAG_AF_UNIX;
|
||||
break;
|
||||
case S_IFIFO :
|
||||
reparse_tag = IO_REPARSE_TAG_LX_FIFO;
|
||||
break;
|
||||
case S_IFCHR :
|
||||
reparse_tag = IO_REPARSE_TAG_LX_CHR;
|
||||
break;
|
||||
case S_IFBLK :
|
||||
reparse_tag = IO_REPARSE_TAG_LX_BLK;
|
||||
break;
|
||||
default :
|
||||
len = -1;
|
||||
errno = EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
if (len >= 0) {
|
||||
reparse_len = sizeof(REPARSE_POINT) + len;
|
||||
reparse = (REPARSE_POINT*)malloc(reparse_len);
|
||||
if (reparse) {
|
||||
reparse->reparse_tag = reparse_tag;
|
||||
reparse->reparse_data_length = cpu_to_le16(len);
|
||||
reparse->reserved = const_cpu_to_le16(0);
|
||||
res = ntfs_set_ntfs_reparse_data(ni,
|
||||
(char*)reparse, reparse_len, 0);
|
||||
free(reparse);
|
||||
}
|
||||
}
|
||||
return (res);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the reparse data into a buffer
|
||||
|
@ -2385,7 +2385,11 @@ static int ntfs_fuse_create(fuse_req_t req, fuse_ino_t parent, const char *name,
|
||||
perm = (typemode & ~ctx->dmask & 0777)
|
||||
| (dsetgid & S_ISGID);
|
||||
else
|
||||
perm = typemode & ~ctx->fmask & 0777;
|
||||
if ((ctx->special_files == NTFS_FILES_WSL)
|
||||
&& S_ISLNK(type))
|
||||
perm = typemode | 0777;
|
||||
else
|
||||
perm = typemode & ~ctx->fmask & 0777;
|
||||
/*
|
||||
* Try to get a security id available for
|
||||
* file creation (from inheritance or argument).
|
||||
@ -4737,6 +4741,7 @@ int main(int argc, char *argv[])
|
||||
goto err_out;
|
||||
|
||||
ctx->vol->abs_mnt_point = ctx->abs_mnt_point;
|
||||
ctx->vol->special_files = ctx->special_files;
|
||||
ctx->security.vol = ctx->vol;
|
||||
ctx->vol->secure_flags = ctx->secure_flags;
|
||||
#ifdef HAVE_SETXATTR /* extended attributes interface required */
|
||||
|
@ -316,6 +316,14 @@ data streams are mapped to xattrs and user can manipulate them using
|
||||
.B user_xattr
|
||||
Same as \fBstreams_interface=\fP\fIxattr\fP.
|
||||
.TP
|
||||
.BI special_files= value
|
||||
This option selects a mode for representing a special file to be created
|
||||
(symbolic link, socket, fifo, character or block device). The mode can
|
||||
be \fBinterix\fR or \fBwsl\fR, and existing files in either mode are
|
||||
recognized irrespective of the selected mode. Interix is the traditional
|
||||
mode, used by default, and wsl is interoperable with Windows WSL, but
|
||||
it is not compatible with Windows versions earlier than Windows 10.
|
||||
.TP
|
||||
.B efs_raw
|
||||
This option should only be used in backup or restore situation.
|
||||
It changes the apparent size of files and the behavior of read and
|
||||
|
@ -2117,7 +2117,11 @@ static int ntfs_fuse_create(const char *org_path, mode_t typemode, dev_t dev,
|
||||
perm = (typemode & ~ctx->dmask & 0777)
|
||||
| (dsetgid & S_ISGID);
|
||||
else
|
||||
perm = typemode & ~ctx->fmask & 0777;
|
||||
if ((ctx->special_files == NTFS_FILES_WSL)
|
||||
&& S_ISLNK(type))
|
||||
perm = typemode | 0777;
|
||||
else
|
||||
perm = typemode & ~ctx->fmask & 0777;
|
||||
/*
|
||||
* Try to get a security id available for
|
||||
* file creation (from inheritance or argument).
|
||||
@ -4464,6 +4468,7 @@ int main(int argc, char *argv[])
|
||||
ctx->vol->abs_mnt_point = ctx->abs_mnt_point;
|
||||
ctx->security.vol = ctx->vol;
|
||||
ctx->vol->secure_flags = ctx->secure_flags;
|
||||
ctx->vol->special_files = ctx->special_files;
|
||||
#ifdef HAVE_SETXATTR /* extended attributes interface required */
|
||||
ctx->vol->efs_raw = ctx->efs_raw;
|
||||
#endif /* HAVE_SETXATTR */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* ntfs-3g_common.c - Common definitions for ntfs-3g and lowntfs-3g.
|
||||
*
|
||||
* Copyright (c) 2010-2020 Jean-Pierre Andre
|
||||
* Copyright (c) 2010-2021 Jean-Pierre Andre
|
||||
* Copyright (c) 2010 Erik Larsson
|
||||
*
|
||||
* This program/include file is free software; you can redistribute it and/or
|
||||
@ -127,6 +127,7 @@ const struct DEFOPTION optionlist[] = {
|
||||
{ "xattrmapping", OPT_XATTRMAPPING, FLGOPT_STRING },
|
||||
{ "efs_raw", OPT_EFS_RAW, FLGOPT_BOGUS },
|
||||
{ "posix_nlink", OPT_POSIX_NLINK, FLGOPT_BOGUS },
|
||||
{ "special_files", OPT_SPECIAL_FILES, FLGOPT_STRING },
|
||||
{ (const char*)NULL, 0, 0 } /* end marker */
|
||||
} ;
|
||||
|
||||
@ -503,6 +504,17 @@ char *parse_mount_options(ntfs_fuse_context_t *ctx,
|
||||
case OPT_POSIX_NLINK :
|
||||
ctx->posix_nlink = TRUE;
|
||||
break;
|
||||
case OPT_SPECIAL_FILES :
|
||||
if (!strcmp(val, "interix"))
|
||||
ctx->special_files = NTFS_FILES_INTERIX;
|
||||
else if (!strcmp(val, "wsl"))
|
||||
ctx->special_files = NTFS_FILES_WSL;
|
||||
else {
|
||||
ntfs_log_error("Invalid special_files"
|
||||
" mode.\n");
|
||||
goto err_exit;
|
||||
}
|
||||
break;
|
||||
case OPT_FSNAME : /* Filesystem name. */
|
||||
/*
|
||||
* We need this to be able to check whether filesystem
|
||||
|
@ -93,6 +93,7 @@ enum {
|
||||
OPT_XATTRMAPPING,
|
||||
OPT_EFS_RAW,
|
||||
OPT_POSIX_NLINK,
|
||||
OPT_SPECIAL_FILES,
|
||||
} ;
|
||||
|
||||
/* Option flags */
|
||||
@ -155,6 +156,7 @@ typedef struct {
|
||||
BOOL blkdev;
|
||||
BOOL mounted;
|
||||
BOOL posix_nlink;
|
||||
ntfs_volume_special_files special_files;
|
||||
#ifdef HAVE_SETXATTR /* extended attributes interface required */
|
||||
BOOL efs_raw;
|
||||
#ifdef XATTR_MAPPINGS
|
||||
|
Loading…
Reference in New Issue
Block a user