--- Begin Message ---
Package: ntfs-3g
Version: 1:2009.4.4-1ubuntu4
Severity: normal
Tags: patch
Here is a patch from LinuxDeepin, which can provide extended attributes
supported in ntfs-3g, the author is Jiahua Huang <jhuangjiahua (AT)
gmail (DOT) com> and licensed as the same as ntfs-3g package in Debian.
I don't know if this patch can be accepted to provide such a function in
Debian.
LinuxDeepin has tried to make it possible to install Linux on an ntfs
partition with ntfs-3g, I think it is a good feature at least for the
newer comers of Linux.
Regards,
Aron Xu
--- System information. ---
Architecture: i386
Kernel: Linux 2.6.31-16-generic
Debian Release: squeeze/sid
500 karmic-updates debian.nctu.edu.tw
500 karmic-security debian.nctu.edu.tw
500 karmic ppa.launchpad.net
500 karmic packages.medibuntu.org
500 karmic debian.nctu.edu.tw
500 karmic archive.canonical.com
--- Package information. ---
Depends (Version) | Installed
==============================-+-===========
libc6 (>= 2.4) | 2.10.1-0ubuntu15
libfuse2 (>= 2.6) | 2.7.4-1.1ubuntu4.3
libntfs-3g54 | 1:2009.4.4-1ubuntu4
initramfs-tools | 0.92bubuntu53
Package's Recommends field is empty.
Package's Suggests field is empty.
diff --git a/ntfs-3g-2009.1.1/src/ntfs-3g.c b/ntfs-3g-2009.1.1/src/ntfs-3g.c
index a7b2e57..047ebaf 100644
--- a/ntfs-3g-2009.1.1/src/ntfs-3g.c
+++ b/ntfs-3g-2009.1.1/src/ntfs-3g.c
@@ -400,6 +400,89 @@ int ntfs_macfuse_setcrtime(const char *path, const struct
timespec *tv)
}
#endif /* defined(__APPLE__) || defined(__DARWIN__) */
+/* for linux ownership, permissions */
+static const char nf_ns_attr_linux_uid[] = "user.linux.uid";
+static const char nf_ns_attr_linux_gid[] = "user.linux.gid";
+static const char nf_ns_attr_linux_mode[] = "user.linux.mode";
+
+static int ntfs_fuse_in_getattr(ntfs_inode *ni, const char *name,
+ char *value, size_t size)
+{
+ ntfs_attr *na = NULL;
+ ntfschar *lename = NULL;
+ int res, lename_len;
+
+ if (!ni)
+ return -errno;
+ lename_len = ntfs_mbstoucs(name, &lename);
+ if (lename_len == -1) {
+ res = -errno;
+ goto exit;
+ }
+ na = ntfs_attr_open(ni, AT_DATA, lename, lename_len);
+ if (!na) {
+ res = -ENODATA;
+ goto exit;
+ }
+ if (size) {
+ if (size >= na->data_size) {
+ res = ntfs_attr_pread(na, 0, na->data_size, value);
+ if (res != na->data_size)
+ res = -errno;
+ } else
+ res = -ERANGE;
+ } else
+ res = na->data_size;
+exit:
+ if (na)
+ ntfs_attr_close(na);
+ free(lename);
+ return res;
+}
+
+static int ntfs_fuse_in_setattr(ntfs_inode *ni, const char *name,
+ const char *value, size_t size)
+{
+ ntfs_attr *na = NULL;
+ ntfschar *lename = NULL;
+ int res, lename_len;
+
+ if (!ni)
+ return -errno;
+ lename_len = ntfs_mbstoucs(name, &lename);
+ if (lename_len == -1) {
+ res = -errno;
+ goto exit;
+ }
+ na = ntfs_attr_open(ni, AT_DATA, lename, lename_len);
+ if (!na) {
+ if (ntfs_attr_add(ni, AT_DATA, lename, lename_len, NULL, 0)) {
+ res = -errno;
+ goto exit;
+ }
+ na = ntfs_attr_open(ni, AT_DATA, lename, lename_len);
+ if (!na) {
+ res = -errno;
+ goto exit;
+ }
+ } else {
+ if (ntfs_attr_truncate(na, (s64)size)) {
+ res = -errno;
+ goto exit;
+ }
+ }
+ res = ntfs_attr_pwrite(na, 0, size, value);
+ if (res != (s64) size)
+ res = -errno;
+ else
+ res = 0;
+exit:
+ if (na)
+ ntfs_attr_close(na);
+ free(lename);
+ return res;
+}
+
static int ntfs_fuse_getattr(const char *org_path, struct stat *stbuf)
{
int res = 0;
@@ -409,6 +492,18 @@ static int ntfs_fuse_getattr(const char *org_path, struct
stat *stbuf)
ntfschar *stream_name;
int stream_name_len;
+ char modec[10]=" ";
+ char uidc[10]=" ";
+ char gidc[10]=" ";
+
+ unsigned int modei;
+ unsigned int uid;
+ unsigned int gid;
+
+ modei |= (0777 & ~ctx->fmask);
+ uid = ctx->uid;
+ gid = ctx->gid;
+
stream_name_len = ntfs_fuse_parse_path(org_path, &path, &stream_name);
if (stream_name_len < 0)
return stream_name_len;
@@ -510,8 +605,24 @@ static int ntfs_fuse_getattr(const char *org_path, struct
stat *stbuf)
}
stbuf->st_mode |= (0777 & ~ctx->fmask);
}
- stbuf->st_uid = ctx->uid;
- stbuf->st_gid = ctx->gid;
+ if (ntfs_fuse_in_getattr(ni, nf_ns_attr_linux_mode, modec, 65536) > 0){
+ sscanf(modec, "%o", &modei);
+ stbuf->st_mode = modei;
+ }
+
+ if (ntfs_fuse_in_getattr(ni, nf_ns_attr_linux_uid, uidc, 65536) > 0){
+ sscanf(uidc, "%u", &uid);
+ stbuf->st_uid = uid;
+ } else {
+ stbuf->st_uid = ctx->uid;
+ }
+ if (ntfs_fuse_in_getattr(ni, nf_ns_attr_linux_gid, gidc, 65536) > 0){
+ sscanf(gidc, "%u", &gid);
+ stbuf->st_gid = gid;
+ } else {
+ stbuf->st_gid = ctx->gid;
+ }
+
stbuf->st_ino = ni->mft_no;
stbuf->st_atime = ni->last_access_time;
stbuf->st_ctime = ni->last_mft_change_time;
@@ -848,8 +959,18 @@ exit:
static int ntfs_fuse_chmod(const char *path,
mode_t mode __attribute__((unused)))
{
+ ntfs_inode *ni;
+ char modec[10]=" ";
+
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;
+ sprintf(modec, "%o", mode);
+ ntfs_fuse_in_setattr(ni, nf_ns_attr_linux_mode, modec, strlen(modec));
+ ntfs_inode_close(ni);
+
if (ctx->silent)
return 0;
return -EOPNOTSUPP;
@@ -857,8 +978,22 @@ static int ntfs_fuse_chmod(const char *path,
static int ntfs_fuse_chown(const char *path, uid_t uid, gid_t gid)
{
+ ntfs_inode *ni;
+ char uidc[10]=" 0";
+ char gidc[10]=" 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;
+ sprintf(uidc, "%d", uid);
+ sprintf(gidc, "%d", gid);
+ ntfs_fuse_in_setattr(ni, nf_ns_attr_linux_gid, gidc, strlen(gidc));
+ ntfs_fuse_in_setattr(ni, nf_ns_attr_linux_uid, uidc, strlen(uidc));
+ ntfs_inode_close(ni);
+
if (ctx->silent)
return 0;
if (uid == ctx->uid && gid == ctx->gid)
@@ -875,6 +1010,17 @@ static int ntfs_fuse_create(const char *org_path, dev_t
type, dev_t dev,
char *path;
int res = 0, uname_len, utarget_len;
+ char modec[10]=" ";
+ char uidc[10]=" 0";
+ char gidc[10]=" 0";
+
+ int mode, uid, gid;
+ struct fuse_context *mycontext = fuse_get_context();
+ uid = mycontext->uid;
+ gid = mycontext->gid;
+ mode = (type & 0777) ? type : ( type | 0777);
+ type = type & 0177000;
+
path = strdup(org_path);
if (!path)
return -errno;
@@ -914,6 +1060,13 @@ static int ntfs_fuse_create(const char *org_path, dev_t
type, dev_t dev,
break;
}
if (ni) {
+ sprintf(uidc, "%d", uid);
+ sprintf(gidc, "%d", gid);
+ ntfs_fuse_in_setattr(ni, nf_ns_attr_linux_gid, gidc,
strlen(gidc));
+ ntfs_fuse_in_setattr(ni, nf_ns_attr_linux_uid, uidc,
strlen(uidc));
+ sprintf(modec, "%o", mode);
+ ntfs_fuse_in_setattr(ni, nf_ns_attr_linux_mode, modec,
strlen(modec));
+
if (ntfs_inode_close(ni))
set_fuse_error(&res);
ntfs_fuse_update_times(dir_ni, NTFS_UPDATE_MCTIME);
@@ -974,7 +1127,7 @@ static int ntfs_fuse_mknod_common(const char *org_path,
mode_t mode, dev_t dev)
goto exit;
}
if (!stream_name_len)
- res = ntfs_fuse_create(path, mode & S_IFMT, dev, NULL);
+ res = ntfs_fuse_create(path, mode, dev, NULL);
else
res = ntfs_fuse_create_stream(path, stream_name,
stream_name_len);
@@ -1264,7 +1417,7 @@ static int ntfs_fuse_mkdir(const char *path,
{
if (ntfs_fuse_is_named_data_stream(path))
return -EINVAL; /* n/a for named data streams. */
- return ntfs_fuse_create(path, S_IFDIR, 0, NULL);
+ return ntfs_fuse_create(path, mode | S_IFDIR, 0, NULL);
}
static int ntfs_fuse_rmdir(const char *path)
signature.asc
Description: OpenPGP digital signature
--- End Message ---