components/samba/samba/patches/vfs_samfs.c.patch
author Jiri Sasek <Jiri.Sasek@Sun.COM>
Wed, 20 Mar 2013 08:56:48 -0700
branchs11-update
changeset 2525 5e4049097207
parent 923 79e84368f624
child 4109 b8f324d4e07c
permissions -rw-r--r--
16103575 Update Samba to 3.6.12 release. 15813281 SUNBT7195246 After Samba patch 119757-25/119758-25: Files not deleted, smbs 16299853 problem in UTILITY/SAMBA 16443813 Build noise in vfs_samfs caused by a missing prototype 16294231 "smbd" is frequently dumping core in AIO with SAM-FS involved. 16395062 "smbd" is not closing stale Samba connections with SAM-FS involved.

bug #5780

diff --git a/source3/Makefile.in b/source3/Makefile.in
index 425aa2b..db1d809 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -715,6 +715,7 @@ VFS_AIXACL_OBJ = modules/vfs_aixacl.o modules/vfs_aixacl_util.o
 VFS_AIXACL2_OBJ = modules/vfs_aixacl2.o modules/vfs_aixacl_util.o modules/nfs4_acls.o
 VFS_SOLARISACL_OBJ = modules/vfs_solarisacl.o
 VFS_ZFSACL_OBJ = modules/vfs_zfsacl.o modules/nfs4_acls.o
+VFS_SAMFS_OBJ = modules/vfs_samfs.o
 VFS_HPUXACL_OBJ = modules/vfs_hpuxacl.o
 VFS_IRIXACL_OBJ = modules/vfs_irixacl.o
 VFS_TRU64ACL_OBJ = modules/vfs_tru64acl.o
@@ -2741,6 +2742,10 @@ bin/zfsacl.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_ZFSACL_OBJ)
 	@echo "Building plugin $@"
 	@$(SHLD_MODULE) $(VFS_ZFSACL_OBJ)
 
+bin/samfs.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_SAMFS_OBJ)
+	@echo "Building plugin $@"
+	@$(SHLD_MODULE) $(VFS_SAMFS_OBJ) @SAMFS_LIBS@
+
 bin/irixacl.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_IRIXACL_OBJ)
 	@echo "Building plugin $@"
 	@$(SHLD_MODULE) $(VFS_IRIXACL_OBJ)
diff --git a/source3/configure.in b/source3/configure.in
index 2494593..8daa53f 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -6653,6 +6653,8 @@ SMB_MODULE(vfs_aio_fork, \$(VFS_AIO_FORK_OBJ), "bin/aio_fork.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_preopen, \$(VFS_PREOPEN_OBJ), "bin/preopen.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_syncops, \$(VFS_SYNCOPS_OBJ), "bin/syncops.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_zfsacl, \$(VFS_ZFSACL_OBJ), "bin/zfsacl.$SHLIBEXT", VFS)
+AC_SUBST(SAMFS_LIBS)
+SMB_MODULE(vfs_samfs, \$(VFS_SAMFS_OBJ), "bin/samfs.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_notify_fam, \$(VFS_NOTIFY_FAM_OBJ), "bin/notify_fam.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_acl_xattr, \$(VFS_ACL_XATTR_OBJ), "bin/acl_xattr.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_acl_tdb, \$(VFS_ACL_TDB_OBJ), "bin/acl_tdb.$SHLIBEXT", VFS)
diff --git a/source3/modules/vfs_samfs.c b/source3/modules/vfs_samfs.c
new file mode 100644
index 0000000..9370768
--- /dev/null	2012-07-16 09:13:54.000000000 -0700
+++ b/source3/modules/vfs_samfs.c	2012-07-16 09:21:00.168046000 -0700
@@ -0,0 +1,181 @@
+/*
+ * Support for offline files with Sun SAM-QFS
+ *
+ * Copyright (C) Dirk Nitschke, 2009
+ *
+ * Modified by Jiri Sasek, 2010
+ * To conform the samba-vfs api
+ *
+ * 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 files for Sun SAM-QFS
+ *
+ */
+#include <pub/stat.h>
+#include <pub/lib.h>
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_VFS
+
+#define SAMFS_MODULE_NAME "samfs"
+
+NTSTATUS vfs_samfs_init(void);
+
+/*
+ * samfs_is_offline()
+ * check if the local file is offline in the sense of SAM-QFS
+ *
+ * A segmented file is offline if the file's index inode is
+ * offline or at least one of it's segments is offline.
+ *
+ * See sam_stat(3) and sam_segment_stat(3) for details.
+ *
+ * If something goes wrong we assume that the file is offline.
+ */
+static bool samfs_is_offline(struct vfs_handle_struct *handle, const struct smb_filename *fname, SMB_STRUCT_STAT *sbuf)
+{
+	struct sam_stat file_info;
+	struct sam_stat *seg_info_ptr;
+	int number_of_segments, number_of_segments_offline = 0;
+	int result;
+	int i;
+	NTSTATUS status;
+	char *path;
+
+        status = get_full_smb_filename(talloc_tos(), fname, &path);
+        if (!NT_STATUS_IS_OK(status)) {
+                errno = map_errno_from_nt_status(status);
+                return false;
+        }
+
+	if (ISDOT(path) || ISDOTDOT(path)) {
+		return false;
+	}
+
+	/*
+	 * Initialize file_info to be all zero bits
+	 */
+	memset((void *)&file_info, 0, sizeof(struct sam_stat));
+
+	/*
+	 * Stat the file using the regular sam_stat function
+	 */
+	result = sam_stat(path, &file_info, sizeof(struct sam_stat));
+
+	if (result != 0) {
+		DEBUG(10,("samfs_is_offline: cannot sam_stat %s, %s\nAssuming file is offline.\n", \
+			path, strerror(errno)));
+		return true;
+	}
+
+	/*
+	 * Check if file is offline
+	 */
+	if (SS_ISOFFLINE(file_info.attr)) {
+		DEBUG(10,("samfs_is_offline: file %s is offline.\n", path));
+		return true;
+	}
+
+	/*
+	 * Check for segmented file
+	 */
+	if (SS_ISSEGMENT_F(file_info.attr)) {
+		number_of_segments = NUM_SEGS(&file_info);
+		seg_info_ptr = (struct sam_stat *)TALLOC_ZERO_ARRAY(talloc_tos(),
+						struct sam_stat, number_of_segments);
+		if (seg_info_ptr != NULL) {
+			DEBUG(10,("samfs_is_offline: cannot talloc for "
+				"segment stat info %s\nAssuming file is offline.\n",
+				path));
+			return true;
+		}
+
+		/*
+		 * Stat all segments
+		 */
+		result = sam_segment_stat(path, seg_info_ptr,
+			number_of_segments * sizeof(struct sam_stat));
+		if (result != 0) {
+			DEBUG(10,("samfs_is_offline: cannot sam_segment_stat %s, "
+				"%s\nAssuming file is offline.\n",
+				path, strerror(errno)));
+			TALLOC_FREE(seg_info_ptr);
+			return true;
+		}
+		/*
+		 * Loop over segments until we have checked all segments
+		 * or found one which is offline.
+		 */
+		for (i = 0; i < number_of_segments; i++) {
+			if (SS_ISOFFLINE(seg_info_ptr[i].attr)) {
+				number_of_segments_offline++;
+			}
+		}
+		DEBUG(10,("samfs_is_offline: file %s has %d offline segments\n"
+			, path, number_of_segments_offline));
+		TALLOC_FREE(seg_info_ptr);
+	}
+	return (number_of_segments_offline) ? true : false ;
+}
+
+/*
+ * release a file-command to SAM-stagger
+ */
+extern int sam_release(const char *path, const char *command);
+
+/*
+ * samfs_set_offline()
+ *
+ * Release the local file in the sense of SAM-QFS.
+ * See sam_release(3) for details.
+ *
+ */
+static int samfs_set_offline(struct vfs_handle_struct *handle, const struct smb_filename *fname)
+{
+	int result;
+	NTSTATUS status;
+	char *path;
+
+        status = get_full_smb_filename(talloc_tos(), fname, &path);
+        if (!NT_STATUS_IS_OK(status)) {
+                errno = map_errno_from_nt_status(status);
+                return false;
+        }
+
+	result = sam_release(path, "i");
+	if (result != 0) {
+		DEBUG(10,("samfs_set_offline: sam_release %s returned %s\n",
+			path, strerror(errno)));
+		return -1;
+	}
+	return 0;
+}
+
+/* VFS operations structure */
+
+static struct vfs_fn_pointers samfs_fns = {
+	.is_offline = samfs_is_offline,
+	.set_offline = samfs_set_offline
+};
+
+NTSTATUS vfs_samfs_init(void)
+{
+	return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, SAMFS_MODULE_NAME,
+		&samfs_fns);
+}