[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Fri Jun 3 05:27:03 UTC 2016


The branch, master has been updated
       via  469fdcd Efficient xattr handling for VxFS Signed-off-by: Abhidnya Joshi <Abhidnya.Joshi at veritas.com>
      from  8814b25 lib: replace: snprintf - Fix length calculation for hex/octal 64-bit values.

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 469fdcd66269f340a05e6a9e4a9de51a1f5d99b2
Author: Abhidnya Joshi <Abhidnya.Joshi at veritas.com>
Date:   Wed Jun 1 23:38:31 2016 -0700

    Efficient xattr handling for VxFS Signed-off-by: Abhidnya Joshi <Abhidnya.Joshi at veritas.com>
    
    Reviewed-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Fri Jun  3 07:26:34 CEST 2016 on sn-devel-144

-----------------------------------------------------------------------

Summary of changes:
 source3/modules/lib_vxfs.c    | 244 ++++++++++++++++++++++++++++++++++++++++++
 source3/modules/vfs_vxfs.c    | 149 +++++++++++++++++++++++---
 source3/modules/vfs_vxfs.h    |  34 ++++++
 source3/modules/wscript_build |   2 +-
 4 files changed, 415 insertions(+), 14 deletions(-)
 create mode 100644 source3/modules/lib_vxfs.c
 create mode 100644 source3/modules/vfs_vxfs.h


Changeset truncated at 500 lines:

diff --git a/source3/modules/lib_vxfs.c b/source3/modules/lib_vxfs.c
new file mode 100644
index 0000000..0d5ea60
--- /dev/null
+++ b/source3/modules/lib_vxfs.c
@@ -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");
+
+}
diff --git a/source3/modules/vfs_vxfs.c b/source3/modules/vfs_vxfs.c
index bcd7ae3..feb3d49 100644
--- a/source3/modules/vfs_vxfs.c
+++ b/source3/modules/vfs_vxfs.c
@@ -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;
+	}
+
+	if (SMB_VFS_NEXT_STAT(handle, smb_fname) != 0) {
+		TALLOC_FREE(smb_fname);
 		return -1;
 	}
 
-	return SMB_VFS_NEXT_REMOVEXATTR(handle, path, name);
+	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;
 
-	/* Clients can't remove XATTR_USER_NTACL directly. */
-	if (strcasecmp(name, XATTR_USER_NTACL) == 0) {
-		errno = ENOATTR;
-		return -1;
+	/* 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;
 	}
 
-	return SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, name);
+	return ret;
+
 }
 
 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;
 


-- 
Samba Shared Repository



More information about the samba-cvs mailing list