mirror of
https://github.com/samba-team/samba.git
synced 2025-08-03 04:22:09 +03:00
Efficient xattr handling for VxFS Signed-off-by: Abhidnya Joshi <Abhidnya.Joshi@veritas.com>
Reviewed-by: Volker Lendecke <vl@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org> Autobuild-User(master): Jeremy Allison <jra@samba.org> Autobuild-Date(master): Fri Jun 3 07:26:34 CEST 2016 on sn-devel-144
This commit is contained in:
committed by
Jeremy Allison
parent
8814b25565
commit
469fdcd662
244
source3/modules/lib_vxfs.c
Normal file
244
source3/modules/lib_vxfs.c
Normal file
@ -0,0 +1,244 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Wrap VxFS xattr calls.
|
||||
|
||||
Copyright (C) Veritas Technologies LLC <www.veritas.com> 2016
|
||||
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "smbd/smbd.h"
|
||||
#include "system/filesys.h"
|
||||
#include "string.h"
|
||||
|
||||
/*
|
||||
* Available under GPL at
|
||||
* http://www.veritas.com/community/downloads/vxfsmisc-library
|
||||
*/
|
||||
#define LIBVXFS "/usr/lib64/vxfsmisc.so"
|
||||
|
||||
|
||||
static int (*vxfs_setxattr_fd_func) (int fd, const char *name,
|
||||
const void *value, size_t len, int flags);
|
||||
static int (*vxfs_getxattr_fd_func) (int fd, const char *name, void *value,
|
||||
size_t *len);
|
||||
static int (*vxfs_removexattr_fd_func) (int fd, const char *name);
|
||||
static int (*vxfs_listxattr_fd_func) (int fd, void *value, size_t *len);
|
||||
|
||||
int vxfs_setxattr_fd(int fd, const char *name, const void *value,
|
||||
size_t len, int flags)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (vxfs_setxattr_fd_func == NULL) {
|
||||
errno = ENOSYS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEBUG(10, ("Calling vxfs_setxattr_fd\n"));
|
||||
ret = vxfs_setxattr_fd_func(fd, name, value, len, flags);
|
||||
if (ret) {
|
||||
errno = ret;
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vxfs_setxattr_path(const char *path, const char *name, const void *value,
|
||||
size_t len, int flags, bool is_dir)
|
||||
{
|
||||
int ret, fd = -1;
|
||||
|
||||
if (is_dir) {
|
||||
fd = open(path, O_RDONLY|O_DIRECTORY);
|
||||
} else {
|
||||
fd = open(path, O_WRONLY);
|
||||
}
|
||||
|
||||
if (fd == -1) {
|
||||
DEBUG(10, ("error in vxfs_setxattr_path: %s\n",
|
||||
strerror(errno)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = vxfs_setxattr_fd(fd, name, value, len, flags);
|
||||
|
||||
close(fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vxfs_getxattr_fd(int fd, const char *name, void *value, size_t len)
|
||||
{
|
||||
int ret;
|
||||
size_t size = len;
|
||||
|
||||
if (vxfs_getxattr_fd_func == NULL) {
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
DEBUG(10, ("Calling vxfs_getxattr_fd with %s\n", name));
|
||||
ret = vxfs_getxattr_fd_func(fd, name, value, &size);
|
||||
if (ret) {
|
||||
errno = ret;
|
||||
if (ret == EFBIG) {
|
||||
errno = ERANGE;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int vxfs_getxattr_path(const char *path, const char *name, void *value,
|
||||
size_t len)
|
||||
{
|
||||
int ret, fd = -1;
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
DEBUG(10, ("file not opened: vxfs_getxattr_path for %s\n",
|
||||
path));
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = vxfs_getxattr_fd(fd, name, value, len);
|
||||
close(fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vxfs_removexattr_fd(int fd, const char *name)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (vxfs_removexattr_fd_func == NULL) {
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
DEBUG(10, ("Calling vxfs_removexattr_fd with %s\n", name));
|
||||
ret = vxfs_removexattr_fd_func(fd, name);
|
||||
if (ret) {
|
||||
errno = ret;
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vxfs_removexattr_path(const char *path, const char *name, bool is_dir)
|
||||
{
|
||||
int ret, fd = -1;
|
||||
|
||||
if (is_dir) {
|
||||
fd = open(path, O_RDONLY|O_DIRECTORY);
|
||||
} else {
|
||||
fd = open(path, O_WRONLY);
|
||||
}
|
||||
if (fd == -1) {
|
||||
DEBUG(10, ("file not opened: vxfs_removexattr_path for %s\n",
|
||||
path));
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = vxfs_removexattr_fd(fd, name);
|
||||
close(fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vxfs_listxattr_fd(int fd, char *list, size_t size)
|
||||
{
|
||||
int ret;
|
||||
size_t len = size;
|
||||
|
||||
if (vxfs_listxattr_fd_func == NULL) {
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = vxfs_listxattr_fd_func(fd, list, &len);
|
||||
DEBUG(10, ("vxfs_listxattr_fd: returned ret = %d\n", ret));
|
||||
if (ret) {
|
||||
errno = ret;
|
||||
if (ret == EFBIG) {
|
||||
errno = ERANGE;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int vxfs_listxattr_path(const char *path, char *list, size_t size)
|
||||
{
|
||||
int ret, fd = -1;
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
DEBUG(10, ("file not opened: vxfs_listxattr_path for %s\n",
|
||||
path));
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = vxfs_listxattr_fd(fd, list, size);
|
||||
close(fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool load_lib_vxfs_function(void *lib_handle, void *fn_ptr,
|
||||
const char *fnc_name)
|
||||
{
|
||||
void **vlib_handle = (void **)lib_handle;
|
||||
void **fn_pointer = (void **)fn_ptr;
|
||||
|
||||
*fn_pointer = dlsym(*vlib_handle, fnc_name);
|
||||
if (*fn_pointer == NULL) {
|
||||
DEBUG(10, ("Cannot find symbol for %s\n", fnc_name));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void vxfs_init()
|
||||
{
|
||||
static void *lib_handle = NULL;
|
||||
|
||||
if (lib_handle != NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
lib_handle = dlopen(LIBVXFS, RTLD_LAZY);
|
||||
if (lib_handle == NULL) {
|
||||
DEBUG(10, ("Cannot get lib handle\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG(10, ("Calling vxfs_init\n"));
|
||||
load_lib_vxfs_function(&lib_handle, &vxfs_setxattr_fd_func,
|
||||
"vxfs_nxattr_set");
|
||||
load_lib_vxfs_function(&lib_handle, &vxfs_getxattr_fd_func,
|
||||
"vxfs_nxattr_get");
|
||||
load_lib_vxfs_function(&lib_handle, &vxfs_removexattr_fd_func,
|
||||
"vxfs_nxattr_remove");
|
||||
load_lib_vxfs_function(&lib_handle, &vxfs_listxattr_fd_func,
|
||||
"vxfs_nxattr_list");
|
||||
|
||||
}
|
@ -1,9 +1,10 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Wrap VxFS calls in vfs functions.
|
||||
This module is for ACL handling.
|
||||
This module is for ACL and XATTR handling.
|
||||
|
||||
Copyright (C) Symantec Corporation <www.symantec.com> 2014
|
||||
Copyright (C) Veritas Technologies LLC <www.veritas.com> 2016
|
||||
|
||||
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
|
||||
@ -25,6 +26,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "../libcli/security/security.h"
|
||||
#include "../librpc/gen_ndr/ndr_security.h"
|
||||
#include "system/filesys.h"
|
||||
#include "vfs_vxfs.h"
|
||||
|
||||
#undef DBGC_CLASS
|
||||
#define DBGC_CLASS DBGC_VFS
|
||||
@ -509,9 +511,42 @@ static int vxfs_sys_acl_set_file(vfs_handle_struct *handle, const char *name,
|
||||
static int vxfs_set_xattr(struct vfs_handle_struct *handle, const char *path,
|
||||
const char *name, const void *value, size_t size,
|
||||
int flags){
|
||||
struct smb_filename *smb_fname;
|
||||
bool is_dir = false;
|
||||
int ret = 0;
|
||||
|
||||
DEBUG(10, ("In vxfs_set_xattr\n"));
|
||||
|
||||
smb_fname = synthetic_smb_fname(talloc_tos(), path, NULL, NULL, 0);
|
||||
if (smb_fname == NULL) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (SMB_VFS_NEXT_STAT(handle, smb_fname) != 0) {
|
||||
TALLOC_FREE(smb_fname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
is_dir = S_ISDIR(smb_fname->st.st_ex_mode);
|
||||
TALLOC_FREE(smb_fname);
|
||||
|
||||
ret = vxfs_setxattr_path(path, name, value, size, flags,
|
||||
is_dir);
|
||||
if ((ret == 0) ||
|
||||
((ret == -1) && (errno != ENOTSUP) && (errno != ENOSYS))) {
|
||||
/*
|
||||
* Now remve old style xattr if it exists
|
||||
*/
|
||||
SMB_VFS_NEXT_REMOVEXATTR(handle, path, name);
|
||||
/*
|
||||
* Do not bother about return value
|
||||
*/
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEBUG(10, ("Fallback to xattr\n"));
|
||||
if (strcmp(name, XATTR_NTACL_NAME) == 0) {
|
||||
return SMB_VFS_NEXT_SETXATTR(handle, path, XATTR_USER_NTACL,
|
||||
value, size, flags);
|
||||
@ -529,9 +564,18 @@ static int vxfs_set_xattr(struct vfs_handle_struct *handle, const char *path,
|
||||
static int vxfs_fset_xattr(struct vfs_handle_struct *handle,
|
||||
struct files_struct *fsp, const char *name,
|
||||
const void *value, size_t size, int flags){
|
||||
int ret = 0;
|
||||
|
||||
DEBUG(10, ("In vxfs_fset_xattr\n"));
|
||||
|
||||
ret = vxfs_setxattr_fd(fsp->fh->fd, name, value, size, flags);
|
||||
if ((ret == 0) ||
|
||||
((ret == -1) && (errno != ENOTSUP) && (errno != ENOSYS))) {
|
||||
SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEBUG(10, ("Fallback to xattr"));
|
||||
if (strcmp(name, XATTR_NTACL_NAME) == 0) {
|
||||
return SMB_VFS_NEXT_FSETXATTR(handle, fsp, XATTR_USER_NTACL,
|
||||
value, size, flags);
|
||||
@ -549,9 +593,16 @@ static int vxfs_fset_xattr(struct vfs_handle_struct *handle,
|
||||
static ssize_t vxfs_get_xattr(struct vfs_handle_struct *handle,
|
||||
const char *path, const char *name,
|
||||
void *value, size_t size){
|
||||
int ret;
|
||||
|
||||
DEBUG(10, ("In vxfs_get_xattr\n"));
|
||||
ret = vxfs_getxattr_path(path, name, value, size);
|
||||
if ((ret != -1) || ((errno != ENOTSUP) &&
|
||||
(errno != ENOSYS) && (errno != ENODATA))) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEBUG(10, ("Fallback to xattr\n"));
|
||||
if (strcmp(name, XATTR_NTACL_NAME) == 0) {
|
||||
return SMB_VFS_NEXT_GETXATTR(handle, path, XATTR_USER_NTACL,
|
||||
value, size);
|
||||
@ -569,9 +620,17 @@ static ssize_t vxfs_get_xattr(struct vfs_handle_struct *handle,
|
||||
static ssize_t vxfs_fget_xattr(struct vfs_handle_struct *handle,
|
||||
struct files_struct *fsp, const char *name,
|
||||
void *value, size_t size){
|
||||
int ret;
|
||||
|
||||
DEBUG(10, ("In vxfs_fget_xattr\n"));
|
||||
|
||||
ret = vxfs_getxattr_fd(fsp->fh->fd, name, value, size);
|
||||
if ((ret != -1) || ((errno != ENOTSUP) &&
|
||||
(errno != ENOSYS) && (errno != ENODATA))) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEBUG(10, ("Fallback to xattr\n"));
|
||||
if (strcmp(name, XATTR_NTACL_NAME) == 0) {
|
||||
return SMB_VFS_NEXT_FGETXATTR(handle, fsp, XATTR_USER_NTACL,
|
||||
value, size);
|
||||
@ -588,38 +647,86 @@ static ssize_t vxfs_fget_xattr(struct vfs_handle_struct *handle,
|
||||
|
||||
static int vxfs_remove_xattr(struct vfs_handle_struct *handle,
|
||||
const char *path, const char *name){
|
||||
struct smb_filename *smb_fname;
|
||||
bool is_dir = false;
|
||||
int ret = 0, ret_new = 0, old_errno;
|
||||
|
||||
DEBUG(10, ("In vxfs_remove_xattr\n"));
|
||||
|
||||
/* Remove with old way */
|
||||
if (strcmp(name, XATTR_NTACL_NAME) == 0) {
|
||||
return SMB_VFS_NEXT_REMOVEXATTR(handle, path, XATTR_USER_NTACL);
|
||||
ret = SMB_VFS_NEXT_REMOVEXATTR(handle, path,
|
||||
XATTR_USER_NTACL);
|
||||
} else {
|
||||
if (strcasecmp(name, XATTR_USER_NTACL) != 0) {
|
||||
ret = SMB_VFS_NEXT_REMOVEXATTR(handle, path,
|
||||
name);
|
||||
}
|
||||
}
|
||||
old_errno = errno;
|
||||
|
||||
/* Clients can't see XATTR_USER_NTACL directly. */
|
||||
if (strcasecmp(name, XATTR_USER_NTACL) == 0) {
|
||||
errno = ENOATTR;
|
||||
/* Remove with new way */
|
||||
smb_fname = synthetic_smb_fname(talloc_tos(), path, NULL, NULL, 0);
|
||||
if (smb_fname == NULL) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return SMB_VFS_NEXT_REMOVEXATTR(handle, path, name);
|
||||
if (SMB_VFS_NEXT_STAT(handle, smb_fname) != 0) {
|
||||
TALLOC_FREE(smb_fname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
is_dir = S_ISDIR(smb_fname->st.st_ex_mode);
|
||||
TALLOC_FREE(smb_fname);
|
||||
/*
|
||||
* If both fail, return failuer else return whichever succeeded
|
||||
*/
|
||||
ret_new = vxfs_removexattr_path(path, name, is_dir);
|
||||
if (errno == ENOTSUP || errno == ENOSYS) {
|
||||
errno = old_errno;
|
||||
}
|
||||
if ((ret_new != -1) && (ret == -1)) {
|
||||
ret = ret_new;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
static int vxfs_fremove_xattr(struct vfs_handle_struct *handle,
|
||||
struct files_struct *fsp, const char *name){
|
||||
int ret = 0, ret_new = 0, old_errno;
|
||||
|
||||
DEBUG(10, ("In vxfs_fremove_xattr\n"));
|
||||
|
||||
/* Remove with old way */
|
||||
if (strcmp(name, XATTR_NTACL_NAME) == 0) {
|
||||
return SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, XATTR_USER_NTACL);
|
||||
ret = SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp,
|
||||
XATTR_USER_NTACL);
|
||||
} else {
|
||||
/* Clients can't remove XATTR_USER_NTACL directly. */
|
||||
if (strcasecmp(name, XATTR_USER_NTACL) != 0) {
|
||||
ret = SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp,
|
||||
name);
|
||||
}
|
||||
}
|
||||
old_errno = errno;
|
||||
|
||||
/* Remove with new way */
|
||||
ret_new = vxfs_removexattr_fd(fsp->fh->fd, name);
|
||||
/*
|
||||
* If both fail, return failuer else return whichever succeeded
|
||||
*/
|
||||
if (errno == ENOTSUP || errno == ENOSYS) {
|
||||
errno = old_errno;
|
||||
}
|
||||
if ((ret_new != -1) && (ret == -1)) {
|
||||
ret = ret_new;
|
||||
}
|
||||
|
||||
/* Clients can't remove XATTR_USER_NTACL directly. */
|
||||
if (strcasecmp(name, XATTR_USER_NTACL) == 0) {
|
||||
errno = ENOATTR;
|
||||
return -1;
|
||||
}
|
||||
return ret;
|
||||
|
||||
return SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, name);
|
||||
}
|
||||
|
||||
static size_t vxfs_filter_list(char *list, size_t size)
|
||||
@ -645,6 +752,11 @@ static ssize_t vxfs_listxattr(vfs_handle_struct *handle, const char *path,
|
||||
{
|
||||
ssize_t result;
|
||||
|
||||
result = vxfs_listxattr_path(path, list, size);
|
||||
if (result >= 0 || ((errno != ENOTSUP) && (errno != ENOSYS))) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = SMB_VFS_NEXT_LISTXATTR(handle, path, list, size);
|
||||
|
||||
if (result <= 0) {
|
||||
@ -663,6 +775,11 @@ static ssize_t vxfs_flistxattr(struct vfs_handle_struct *handle,
|
||||
{
|
||||
ssize_t result;
|
||||
|
||||
result = vxfs_listxattr_fd(fsp->fh->fd, list, size);
|
||||
if (result >= 0 || ((errno != ENOTSUP) && (errno != ENOSYS))) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = SMB_VFS_NEXT_FLISTXATTR(handle, fsp, list, size);
|
||||
|
||||
if (result <= 0) {
|
||||
@ -679,19 +796,25 @@ static int vfs_vxfs_connect(struct vfs_handle_struct *handle,
|
||||
const char *service, const char *user)
|
||||
{
|
||||
|
||||
int ret = SMB_VFS_NEXT_CONNECT(handle, service, user);
|
||||
int ret;
|
||||
|
||||
ret = SMB_VFS_NEXT_CONNECT(handle, service, user);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
vxfs_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct vfs_fn_pointers vfs_vxfs_fns = {
|
||||
.connect_fn = vfs_vxfs_connect,
|
||||
|
||||
#ifdef VXFS_ACL_SHARE
|
||||
.sys_acl_set_file_fn = vxfs_sys_acl_set_file,
|
||||
.sys_acl_set_fd_fn = vxfs_sys_acl_set_fd,
|
||||
#endif
|
||||
|
||||
.getxattr_fn = vxfs_get_xattr,
|
||||
.fgetxattr_fn = vxfs_fget_xattr,
|
||||
|
34
source3/modules/vfs_vxfs.h
Normal file
34
source3/modules/vfs_vxfs.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Wrap VxFS xattr calls in vfs functions.
|
||||
|
||||
Copyright (C) Veritas Technologies LLC <www.veritas.com> 2016
|
||||
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
int vxfs_setxattr_path(const char *, const char *, const void *, size_t, int,
|
||||
bool);
|
||||
int vxfs_setxattr_fd(int, const char *, const void *, size_t, int);
|
||||
|
||||
int vxfs_getxattr_path(const char *, const char *, void *, size_t);
|
||||
int vxfs_getxattr_fd(int, const char *, void *, size_t);
|
||||
|
||||
int vxfs_removexattr_path(const char *, const char *, bool);
|
||||
int vxfs_removexattr_fd(int, const char *);
|
||||
|
||||
int vxfs_listxattr_path(const char *, char *, size_t);
|
||||
int vxfs_listxattr_fd(int, char *, size_t);
|
||||
|
||||
void vxfs_init(void);
|
@ -479,7 +479,7 @@ bld.SAMBA3_MODULE('vfs_snapper',
|
||||
|
||||
bld.SAMBA3_MODULE('vfs_vxfs',
|
||||
subsystem='vfs',
|
||||
source='vfs_vxfs.c',
|
||||
source='lib_vxfs.c vfs_vxfs.c',
|
||||
init_function='',
|
||||
internal_module=bld.SAMBA3_IS_STATIC_MODULE('vfs_vxfs'),
|
||||
enabled=bld.SAMBA3_IS_ENABLED_MODULE('vfs_vxfs'))
|
||||
|
Reference in New Issue
Block a user