AC_DEFINE(HAVE_COMPARISON_FN_T,1,[Whether or not we have comparison_fn_t])
fi
-############################################
-# Check if we have extended attributes
-AC_CHECK_HEADERS(sys/attributes.h attr/xattr.h sys/xattr.h)
-AC_SEARCH_LIBS(getxattr, [attr])
-AC_CHECK_FUNCS(getxattr lgetxattr fgetxattr listxattr llistxattr)
-AC_CHECK_FUNCS(flistxattr removexattr lremovexattr fremovexattr)
-AC_CHECK_FUNCS(setxattr lsetxattr fsetxattr)
-AC_CHECK_FUNCS(attr_get attr_list attr_set attr_remove)
-AC_CHECK_FUNCS(attr_getf attr_listf attr_setf attr_removef)
-
#################################################
# check for ACL support
{ EPIPE, NT_STATUS_CONNECTION_DISCONNECTED },
{ ECONNREFUSED, NT_STATUS_CONNECTION_REFUSED },
{ EBUSY, NT_STATUS_SHARING_VIOLATION },
+ { ENOTSUP, NT_STATUS_NOT_SUPPORTED},
+#ifdef ENOATTR
+ { ENOATTR, NT_STATUS_NOT_FOUND },
+#endif
+#ifdef ENODATA
+ { ENODATA, NT_STATUS_NOT_FOUND },
+#endif
#ifdef EDQUOT
{ EDQUOT, NT_STATUS_QUOTA_EXCEEDED },
#endif
dnl # LIBRPC subsystem
-SMB_SUBSYSTEM_MK(LIBNDR_RAW,librpc/config.mk)
-
SMB_SUBSYSTEM_NOPROTO(LIBNDR_GEN)
-SMB_SUBSYSTEM(LIBNDR_GEN,[],
- [librpc/gen_ndr/tables.o
- librpc/gen_ndr/ndr_audiosrv.o
- librpc/gen_ndr/ndr_dcerpc.o
- librpc/gen_ndr/ndr_echo.o
- librpc/gen_ndr/ndr_exchange.o
- librpc/gen_ndr/ndr_dsbackup.o
- librpc/gen_ndr/ndr_efs.o
- librpc/gen_ndr/ndr_misc.o
- librpc/gen_ndr/ndr_lsa.o
- librpc/gen_ndr/ndr_lsads.o
- librpc/gen_ndr/ndr_dfs.o
- librpc/gen_ndr/ndr_drsuapi.o
- librpc/gen_ndr/ndr_policyagent.o
- librpc/gen_ndr/ndr_samr.o
- librpc/gen_ndr/ndr_spoolss.o
- librpc/gen_ndr/ndr_wkssvc.o
- librpc/gen_ndr/ndr_srvsvc.o
- librpc/gen_ndr/ndr_svcctl.o
- librpc/gen_ndr/ndr_atsvc.o
- librpc/gen_ndr/ndr_eventlog.o
- librpc/gen_ndr/ndr_epmapper.o
- librpc/gen_ndr/ndr_dbgidl.o
- librpc/gen_ndr/ndr_dssetup.o
- librpc/gen_ndr/ndr_msgsvc.o
- librpc/gen_ndr/ndr_wins.o
- librpc/gen_ndr/ndr_winreg.o
- librpc/gen_ndr/ndr_mgmt.o
- librpc/gen_ndr/ndr_protected_storage.o
- librpc/gen_ndr/ndr_dcom.o
- librpc/gen_ndr/ndr_oxidresolver.o
- librpc/gen_ndr/ndr_remact.o
- librpc/gen_ndr/ndr_wzcsvc.o
- librpc/gen_ndr/ndr_browser.o
- librpc/gen_ndr/ndr_w32time.o
- librpc/gen_ndr/ndr_scerpc.o
- librpc/gen_ndr/ndr_ntsvcs.o
- librpc/gen_ndr/ndr_netlogon.o
- librpc/gen_ndr/ndr_trkwks.o
- librpc/gen_ndr/ndr_keysvc.o
- librpc/gen_ndr/ndr_krb5pac.o
- librpc/gen_ndr/ndr_schannel.o])
+SMB_SUBSYSTEM_MK(LIBNDR_GEN,librpc/config.mk)
+SMB_SUBSYSTEM_MK(LIBNDR_RAW,librpc/config.mk)
SMB_SUBSYSTEM_MK(LIBRPC_RAW,librpc/config.mk)
SMB_SUBSYSTEM_MK(LIBRPC,librpc/config.mk)
# End SUBSYSTEM LIBRPC_RAW
################################################
+################################################
+# Start SUBSYSTEM LIBNDR_GEN
+[SUBSYSTEM::LIBNDR_GEN]
+INIT_OBJ_FILES = \
+ librpc/gen_ndr/tables.o
+ADD_OBJ_FILES = \
+ librpc/gen_ndr/ndr_audiosrv.o \
+ librpc/gen_ndr/ndr_dcerpc.o \
+ librpc/gen_ndr/ndr_echo.o \
+ librpc/gen_ndr/ndr_exchange.o \
+ librpc/gen_ndr/ndr_dsbackup.o \
+ librpc/gen_ndr/ndr_efs.o \
+ librpc/gen_ndr/ndr_misc.o \
+ librpc/gen_ndr/ndr_lsa.o \
+ librpc/gen_ndr/ndr_lsads.o \
+ librpc/gen_ndr/ndr_dfs.o \
+ librpc/gen_ndr/ndr_drsuapi.o \
+ librpc/gen_ndr/ndr_policyagent.o \
+ librpc/gen_ndr/ndr_samr.o \
+ librpc/gen_ndr/ndr_spoolss.o \
+ librpc/gen_ndr/ndr_wkssvc.o \
+ librpc/gen_ndr/ndr_srvsvc.o \
+ librpc/gen_ndr/ndr_svcctl.o \
+ librpc/gen_ndr/ndr_atsvc.o \
+ librpc/gen_ndr/ndr_eventlog.o \
+ librpc/gen_ndr/ndr_epmapper.o \
+ librpc/gen_ndr/ndr_dbgidl.o \
+ librpc/gen_ndr/ndr_dssetup.o \
+ librpc/gen_ndr/ndr_msgsvc.o \
+ librpc/gen_ndr/ndr_wins.o \
+ librpc/gen_ndr/ndr_winreg.o \
+ librpc/gen_ndr/ndr_mgmt.o \
+ librpc/gen_ndr/ndr_protected_storage.o \
+ librpc/gen_ndr/ndr_dcom.o \
+ librpc/gen_ndr/ndr_oxidresolver.o \
+ librpc/gen_ndr/ndr_remact.o \
+ librpc/gen_ndr/ndr_wzcsvc.o \
+ librpc/gen_ndr/ndr_browser.o \
+ librpc/gen_ndr/ndr_w32time.o \
+ librpc/gen_ndr/ndr_scerpc.o \
+ librpc/gen_ndr/ndr_ntsvcs.o \
+ librpc/gen_ndr/ndr_netlogon.o \
+ librpc/gen_ndr/ndr_trkwks.o \
+ librpc/gen_ndr/ndr_keysvc.o \
+ librpc/gen_ndr/ndr_krb5pac.o \
+ librpc/gen_ndr/ndr_xattr.o \
+ librpc/gen_ndr/ndr_schannel.o
+# End SUBSYSTEM LIBNDR_GEN
+################################################
+
################################################
# Start SUBSYSTEM LIBRPC
[SUBSYSTEM::LIBRPC]
--- /dev/null
+#include "idl_types.h"
+
+/*
+ IDL structures for xattr file attributes
+
+ this has nothing to do with RPC, we are just using our NDR/IDL
+ infrastructure as a convenient way to store linearised information
+ about a file in a architecture independent manner
+*/
+
+interface xattr
+{
+ const string XATTR_DOSATTRIB_NAME = "user.DosAttrib";
+ const string XATTR_DOSATTRIB_ESTIMATED_SIZE = 64;
+
+ /* by using a union we can cope with new version of
+ this structure more easily */
+ typedef struct {
+ uint32 attrib;
+ uint32 ea_size;
+ uint64 size;
+ uint64 alloc_size;
+ NTTIME create_time;
+ NTTIME change_time;
+ } xattr_DosInfo1;
+
+ typedef union {
+ [case(1)] xattr_DosInfo1 info1;
+ } xattr_DosInfo;
+
+ typedef [public] struct {
+ uint16 version;
+ [switch_is(version)] xattr_DosInfo info;
+ } xattr_DosAttrib;
+}
/*
a useful helper function for printing idl structures via DEBUG()
*/
-void ndr_print_debug(void (*fn)(struct ndr_print *, const char *, void *),
- const char *name,
- void *ptr)
+void ndr_print_debug(ndr_print_fn_t fn, const char *name, void *ptr)
{
struct ndr_print *ndr;
/*
a useful helper function for printing idl unions via DEBUG()
*/
-void ndr_print_union_debug(void (*fn)(struct ndr_print *, const char *, uint32_t, void *),
- const char *name,
- uint32_t level,
- void *ptr)
+void ndr_print_union_debug(ndr_print_union_fn_t fn, const char *name, uint32_t level, void *ptr)
{
struct ndr_print *ndr;
/*
a useful helper function for printing idl function calls via DEBUG()
*/
-void ndr_print_function_debug(void (*fn)(struct ndr_print *, const char *, int , void *),
- const char *name,
- int flags,
- void *ptr)
+void ndr_print_function_debug(ndr_print_function_t fn, const char *name, int flags, void *ptr)
{
struct ndr_print *ndr;
handle subcontext buffers, which in midl land are user-marshalled, but
we use magic in pidl to make them easier to cope with
*/
-NTSTATUS ndr_pull_subcontext_fn(struct ndr_pull *ndr,
- size_t sub_size,
- void *base,
- NTSTATUS (*fn)(struct ndr_pull *, void *))
+NTSTATUS ndr_pull_subcontext_fn(struct ndr_pull *ndr, size_t sub_size,
+ void *base, ndr_pull_fn_t fn)
{
struct ndr_pull *ndr2;
NDR_ALLOC(ndr, ndr2);
}
-NTSTATUS ndr_pull_subcontext_flags_fn(struct ndr_pull *ndr,
- size_t sub_size,
- void *base,
- NTSTATUS (*fn)(struct ndr_pull *, int , void *))
+NTSTATUS ndr_pull_subcontext_flags_fn(struct ndr_pull *ndr, size_t sub_size,
+ void *base, ndr_pull_flags_fn_t fn)
{
struct ndr_pull *ndr2;
NDR_ALLOC(ndr, ndr2);
return NT_STATUS_OK;
}
-NTSTATUS ndr_pull_subcontext_union_fn(struct ndr_pull *ndr,
- size_t sub_size,
- uint32_t level,
- void *base,
- NTSTATUS (*fn)(struct ndr_pull *, int , uint32_t , void *))
+NTSTATUS ndr_pull_subcontext_union_fn(struct ndr_pull *ndr, size_t sub_size,
+ uint32_t level, void *base, ndr_pull_union_fn_t fn)
{
struct ndr_pull *ndr2;
handle subcontext buffers, which in midl land are user-marshalled, but
we use magic in pidl to make them easier to cope with
*/
-NTSTATUS ndr_push_subcontext_fn(struct ndr_push *ndr,
- size_t sub_size,
- void *base,
- NTSTATUS (*fn)(struct ndr_push *, void *))
+NTSTATUS ndr_push_subcontext_fn(struct ndr_push *ndr, size_t sub_size,
+ void *base, ndr_push_fn_t fn)
{
struct ndr_push *ndr2;
/*
handle subcontext buffers for function that take a flags arg
*/
-NTSTATUS ndr_push_subcontext_flags_fn(struct ndr_push *ndr,
- size_t sub_size,
- void *base,
- NTSTATUS (*fn)(struct ndr_push *, int, void *))
+NTSTATUS ndr_push_subcontext_flags_fn(struct ndr_push *ndr, size_t sub_size,
+ void *base, ndr_push_flags_fn_t fn)
{
struct ndr_push *ndr2;
/*
handle subcontext buffers for function that take a union
*/
-NTSTATUS ndr_push_subcontext_union_fn(struct ndr_push *ndr,
- size_t sub_size,
- uint32_t level,
- void *base,
- NTSTATUS (*fn)(struct ndr_push *, int, uint32_t, void *))
+NTSTATUS ndr_push_subcontext_union_fn(struct ndr_push *ndr, size_t sub_size,
+ uint32_t level, void *base, ndr_push_union_fn_t fn)
{
struct ndr_push *ndr2;
pull a union from a blob using NDR
*/
NTSTATUS ndr_pull_union_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, uint32_t level, void *p,
- NTSTATUS (*fn)(struct ndr_pull *, int ndr_flags, uint32_t, void *))
+ ndr_pull_union_fn_t fn)
{
struct ndr_pull *ndr;
ndr = ndr_pull_init_blob(blob, mem_ctx);
pull a struct from a blob using NDR
*/
NTSTATUS ndr_pull_struct_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p,
- NTSTATUS (*fn)(struct ndr_pull *, int , void *))
+ ndr_pull_flags_fn_t fn)
{
struct ndr_pull *ndr;
ndr = ndr_pull_init_blob(blob, mem_ctx);
push a struct to a blob using NDR
*/
NTSTATUS ndr_push_struct_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p,
- NTSTATUS (*fn)(struct ndr_push *, int , void *))
+ ndr_push_flags_fn_t fn)
{
NTSTATUS status;
struct ndr_push *ndr;
-SMB_MODULE_MK(ntvfs_posix, NTVFS, STATIC, ntvfs/config.mk)
dnl #############################################
AC_DEFINE(HAVE_STAT_TV_NSEC,1,[Whether stat has tv_nsec nanosecond fields])
fi
+dnl ############################################
+dnl use flistxattr as the key function for having
+dnl sufficient xattr support for posix xattr backend
+AC_CHECK_HEADERS(sys/attributes.h attr/xattr.h sys/xattr.h)
+AC_SEARCH_LIBS(flistxattr, [attr])
+
+if test x"$ac_cv_func_flistxattr" = x"yes"; then
+ SMB_MODULE_DEFAULT(posix_xattr, STATIC)
+ AC_DEFINE(HAVE_XATTR_SUPPORT,1,[Whether we have xattr support])
+fi
+SMB_MODULE_MK(posix_xattr, NTVFS, NOT, ntvfs/posix/config.mk)
+SMB_MODULE_MK(ntvfs_posix, NTVFS, STATIC, ntvfs/config.mk)
+################################################
+# Start MODULE posix_xattr
+[MODULE::posix_xattr]
+INIT_OBJ_FILES = \
+ ntvfs/posix/pvfs_xattr.o
+# End MODULE posix_xattr
+################################################
+
+
################################################
# Start MODULE ntvfs_posix
[MODULE::ntvfs_posix]
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "include/includes.h"
+#include "includes.h"
#include "vfs_posix.h"
if ((st->st_mode & S_IWUSR) == 0)
result |= FILE_ATTRIBUTE_READONLY;
- if ((pvfs->flags & PVFS_FLAG_MAP_ARCHIVE) && ((st->st_mode & S_IXUSR) != 0))
- result |= FILE_ATTRIBUTE_ARCHIVE;
-
- if ((pvfs->flags & PVFS_FLAG_MAP_SYSTEM) && ((st->st_mode & S_IXGRP) != 0))
- result |= FILE_ATTRIBUTE_SYSTEM;
-
- if ((pvfs->flags & PVFS_FLAG_MAP_HIDDEN) && ((st->st_mode & S_IXOTH) != 0))
- result |= FILE_ATTRIBUTE_HIDDEN;
+ if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) {
+ if ((pvfs->flags & PVFS_FLAG_MAP_ARCHIVE) && ((st->st_mode & S_IXUSR) != 0))
+ result |= FILE_ATTRIBUTE_ARCHIVE;
+
+ if ((pvfs->flags & PVFS_FLAG_MAP_SYSTEM) && ((st->st_mode & S_IXGRP) != 0))
+ result |= FILE_ATTRIBUTE_SYSTEM;
+
+ if ((pvfs->flags & PVFS_FLAG_MAP_HIDDEN) && ((st->st_mode & S_IXOTH) != 0))
+ result |= FILE_ATTRIBUTE_HIDDEN;
+ }
if (S_ISDIR(st->st_mode))
result = FILE_ATTRIBUTE_DIRECTORY | (result & FILE_ATTRIBUTE_READONLY);
/*
fill in the dos file attributes for a file
*/
-NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name)
+NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd)
{
/* make directories appear as size 0 */
if (S_ISDIR(name->st.st_mode)) {
name->dos.ea_size = 0;
name->dos.file_id = (((uint64_t)name->st.st_dev)<<32) | name->st.st_ino;
+#if HAVE_XATTR_SUPPORT
+ if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) {
+ return pvfs_xattr_load(pvfs, name, fd);
+ }
+#endif
+
return NT_STATUS_OK;
}
mode |= S_IWUSR;
}
- if ((attrib & FILE_ATTRIBUTE_ARCHIVE) &&
- (pvfs->flags & PVFS_FLAG_MAP_ARCHIVE)) {
- mode |= S_IXUSR;
- }
-
- if ((attrib & FILE_ATTRIBUTE_SYSTEM) &&
- (pvfs->flags & PVFS_FLAG_MAP_SYSTEM)) {
- mode |= S_IXGRP;
- }
-
- if ((attrib & FILE_ATTRIBUTE_HIDDEN) &&
- (pvfs->flags & PVFS_FLAG_MAP_HIDDEN)) {
- mode |= S_IXOTH;
+ if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) {
+ if ((attrib & FILE_ATTRIBUTE_ARCHIVE) &&
+ (pvfs->flags & PVFS_FLAG_MAP_ARCHIVE)) {
+ mode |= S_IXUSR;
+ }
+
+ if ((attrib & FILE_ATTRIBUTE_SYSTEM) &&
+ (pvfs->flags & PVFS_FLAG_MAP_SYSTEM)) {
+ mode |= S_IXGRP;
+ }
+
+ if ((attrib & FILE_ATTRIBUTE_HIDDEN) &&
+ (pvfs->flags & PVFS_FLAG_MAP_HIDDEN)) {
+ mode |= S_IXOTH;
+ }
}
return mode;
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "include/includes.h"
+#include "includes.h"
#include "vfs_posix.h"
#include "system/time.h"
#include "system/filesys.h"
return status;
}
+
+#if HAVE_XATTR_SUPPORT
+ name->dos.attrib = io->ntcreatex.in.file_attr;
+ if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) {
+ status = pvfs_xattr_save(pvfs, name, fd);
+ }
+#endif
+
/* form the lock context used for byte range locking and
opendb locking */
status = pvfs_locking_key(name, f, &f->locking_key);
return;
}
+ /* re-mark it async, just in case someone up the chain does
+ paranoid checking */
+ req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC;
+
/* send the reply up the chain */
req->async_states->status = status;
req->async_states->send_fn(req);
*/
-#include "include/includes.h"
+#include "includes.h"
#include "vfs_posix.h"
#include "system/dir.h"
name->full_name = partial_name;
if (name->exists) {
- return pvfs_fill_dos_info(pvfs, name);
+ return pvfs_fill_dos_info(pvfs, name, -1);
}
return NT_STATUS_OK;
/* if we can stat() the full name now then we are done */
if (stat((*name)->full_name, &(*name)->st) == 0) {
(*name)->exists = True;
- return pvfs_fill_dos_info(pvfs, *name);
+ return pvfs_fill_dos_info(pvfs, *name, -1);
}
/* search for a matching filename */
(*name)->original_name = talloc_strdup(*name, fname);
(*name)->stream_name = NULL;
- status = pvfs_fill_dos_info(pvfs, *name);
+ status = pvfs_fill_dos_info(pvfs, *name, -1);
return status;
}
name->exists = True;
- return pvfs_fill_dos_info(pvfs, name);
+ return pvfs_fill_dos_info(pvfs, name, fd);
}
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "include/includes.h"
+#include "includes.h"
#include "vfs_posix.h"
#include "system/time.h"
}
}
+ *f->name = newstats;
+
+#if HAVE_XATTR_SUPPORT
+ if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) {
+ return pvfs_xattr_save(pvfs, f->name, f->fd);
+ }
+#endif
return NT_STATUS_OK;
}
}
}
+ *name = newstats;
+
+#if HAVE_XATTR_SUPPORT
+ if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) {
+ return pvfs_xattr_save(pvfs, name, -1);
+ }
+#endif
+
return NT_STATUS_OK;
}
--- /dev/null
+/*
+ Unix SMB/CIFS implementation.
+
+ POSIX NTVFS backend - xattr support
+
+ Copyright (C) Andrew Tridgell 2004
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "system/filesys.h"
+#include "vfs_posix.h"
+#include "librpc/gen_ndr/ndr_xattr.h"
+
+
+/*
+ pull a xattr as a blob, from either a file or a file descriptor
+*/
+static NTSTATUS pull_xattr_blob(TALLOC_CTX *mem_ctx,
+ const char *attr_name,
+ const char *fname,
+ int fd,
+ size_t estimated_size,
+ DATA_BLOB *blob)
+{
+ int ret;
+
+ *blob = data_blob_talloc(mem_ctx, NULL, estimated_size);
+ if (blob->data == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+again:
+ if (fd != -1) {
+ ret = fgetxattr(fd, attr_name, blob->data, estimated_size);
+ } else {
+ ret = getxattr(fname, attr_name, blob->data, estimated_size);
+ }
+ if (ret == -1 && errno == ERANGE) {
+ estimated_size *= 2;
+ blob->data = talloc_realloc(mem_ctx, blob->data, estimated_size);
+ if (blob->data == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ blob->length = estimated_size;
+ goto again;
+ }
+
+ if (ret == -1) {
+ data_blob_free(blob);
+ return map_nt_error_from_unix(errno);
+ }
+
+ blob->length = ret;
+
+ return NT_STATUS_OK;
+}
+
+/*
+ push a xattr as a blob, from either a file or a file descriptor
+*/
+static NTSTATUS push_xattr_blob(TALLOC_CTX *mem_ctx,
+ const char *attr_name,
+ const char *fname,
+ int fd,
+ const DATA_BLOB *blob)
+{
+ int ret;
+
+ if (fd != -1) {
+ ret = fsetxattr(fd, attr_name, blob->data, blob->length, 0);
+ } else {
+ ret = setxattr(fname, attr_name, blob->data, blob->length, 0);
+ }
+ if (ret == -1) {
+ return map_nt_error_from_unix(errno);
+ }
+
+ return NT_STATUS_OK;
+}
+
+
+/*
+ fill in file attributes from extended attributes
+*/
+NTSTATUS pvfs_xattr_load(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd)
+{
+ DATA_BLOB blob;
+ NTSTATUS status;
+ struct xattr_DosAttrib attrib;
+ TALLOC_CTX *mem_ctx = talloc(name, 0);
+ struct xattr_DosInfo1 *info1;
+
+ status = pull_xattr_blob(mem_ctx, XATTR_DOSATTRIB_NAME, name->full_name,
+ fd, XATTR_DOSATTRIB_ESTIMATED_SIZE, &blob);
+
+ /* if the filesystem doesn't support them, then tell pvfs not to try again */
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
+ DEBUG(5,("pvfs_xattr: xattr not supported in filesystem\n"));
+ pvfs->flags &= ~PVFS_FLAG_XATTR_ENABLE;
+ talloc_free(mem_ctx);
+ return NT_STATUS_OK;
+ }
+
+ /* not having a DosAttrib is not an error */
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
+ talloc_free(mem_ctx);
+ return NT_STATUS_OK;
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(mem_ctx);
+ return status;
+ }
+
+ /* pull the blob */
+ status = ndr_pull_struct_blob(&blob, mem_ctx, &attrib,
+ (ndr_pull_flags_fn_t)ndr_pull_xattr_DosAttrib);
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(mem_ctx);
+ return status;
+ }
+
+ switch (attrib.version) {
+ case 1:
+ info1 = &attrib.info.info1;
+ name->dos.attrib = info1->attrib;
+ name->dos.ea_size = info1->ea_size;
+ if (name->st.st_size == info1->size) {
+ name->dos.alloc_size = info1->alloc_size;
+ }
+ if (info1->create_time != 0) {
+ name->dos.create_time = info1->create_time;
+ }
+ if (info1->change_time != 0) {
+ name->dos.change_time = info1->change_time;
+ }
+ break;
+
+ default:
+ DEBUG(0,("ERROR: Unsupported xattr DosAttrib version %d on '%s'\n",
+ attrib.version, name->full_name));
+ talloc_free(mem_ctx);
+ return NT_STATUS_INVALID_LEVEL;
+ }
+
+ talloc_free(mem_ctx);
+ return NT_STATUS_OK;
+}
+
+
+/*
+ save the file attribute into into the xattr
+*/
+NTSTATUS pvfs_xattr_save(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd)
+{
+ struct xattr_DosAttrib attrib;
+ struct xattr_DosInfo1 *info1;
+ TALLOC_CTX *mem_ctx = talloc(name, 0);
+ DATA_BLOB blob;
+ NTSTATUS status;
+
+ attrib.version = 1;
+ info1 = &attrib.info.info1;
+
+ info1->attrib = name->dos.attrib;
+ info1->ea_size = name->dos.ea_size;
+ info1->size = name->st.st_size;
+ info1->alloc_size = name->dos.alloc_size;
+ info1->create_time = name->dos.create_time;
+ info1->change_time = name->dos.change_time;
+
+ status = ndr_push_struct_blob(&blob, mem_ctx, &attrib,
+ (ndr_push_flags_fn_t)ndr_push_xattr_DosAttrib);
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(mem_ctx);
+ return status;
+ }
+
+ status = push_xattr_blob(mem_ctx, XATTR_DOSATTRIB_NAME, name->full_name, fd, &blob);
+ talloc_free(mem_ctx);
+
+ return status;
+}
This is the default backend
*/
-#include "include/includes.h"
+#include "includes.h"
#include "vfs_posix.h"
if (lp_strict_locking(snum)) pvfs->flags |= PVFS_FLAG_STRICT_LOCKING;
if (lp_ci_filesystem(snum)) pvfs->flags |= PVFS_FLAG_CI_FILESYSTEM;
+#if HAVE_XATTR_SUPPORT
+ if (lp_parm_bool(snum, "posix", "xattr", True)) pvfs->flags |= PVFS_FLAG_XATTR_ENABLE;
+#endif
+
pvfs->sharing_violation_delay = 1000000;
delay = lp_parm_int(snum, "posix", "sharedelay");
if (delay != -1) {
#define PVFS_FLAG_READONLY (1<<4)
#define PVFS_FLAG_STRICT_SYNC (1<<5)
#define PVFS_FLAG_STRICT_LOCKING (1<<6)
+#define PVFS_FLAG_XATTR_ENABLE (1<<7)
/* forward declare some anonymous structures */
struct pvfs_dir;