vfs_samfs.c.patch revision 7065
7065N/ASource: Oracle Solaris (based on VFS module written by dirk.nitschke@oracle.com)
7065N/AShared with community as Samba.org bug #5780 :
7065N/Ahttps://bugzilla.samba.org/show_bug.cgi?id=5780
7065N/A
7065N/Adiff --git a/source3/modules/vfs_samfs.c b/source3/modules/vfs_samfs.c
7065N/Anew file mode 100644
7065N/Aindex 0000000..9370768
7065N/A--- /dev/null 2012-07-16 09:13:54.000000000 -0700
7065N/A+++ b/source3/modules/vfs_samfs.c 2012-07-16 09:21:00.168046000 -0700
7065N/A@@ -0,0 +1,179 @@
7065N/A+/*
7065N/A+ * Support for offline files with Sun SAM-QFS
7065N/A+ *
7065N/A+ * Copyright (C) Dirk Nitschke, 2009
7065N/A+ *
7065N/A+ * Modified by Jiri Sasek, 2010
7065N/A+ * To conform the samba-vfs api
7065N/A+ *
7065N/A+ * This program is free software; you can redistribute it and/or modify
7065N/A+ * it under the terms of the GNU General Public License as published by
7065N/A+ * the Free Software Foundation; either version 3 of the License, or
7065N/A+ * (at your option) any later version.
7065N/A+ *
7065N/A+ * This program is distributed in the hope that it will be useful,
7065N/A+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7065N/A+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7065N/A+ * GNU General Public License for more details.
7065N/A+ *
7065N/A+ * You should have received a copy of the GNU General Public License
7065N/A+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
7065N/A+ *
7065N/A+ */
7065N/A+
7065N/A+#include "includes.h"
7065N/A+#include "smbd/smbd.h"
7065N/A+/*
7065N/A+ * Include files for Sun SAM-QFS
7065N/A+ *
7065N/A+ */
7065N/A+#include <samfs/stat.h>
7065N/A+#include <samfs/lib.h>
7065N/A+
7065N/A+#undef DBGC_CLASS
7065N/A+#define DBGC_CLASS DBGC_VFS
7065N/A+
7065N/A+#define SAMFS_MODULE_NAME "samfs"
7065N/A+
7065N/A+NTSTATUS vfs_samfs_init(void);
7065N/A+
7065N/A+/*
7065N/A+ * samfs_is_offline()
7065N/A+ * check if the local file is offline in the sense of SAM-QFS
7065N/A+ *
7065N/A+ * A segmented file is offline if the file's index inode is
7065N/A+ * offline or at least one of it's segments is offline.
7065N/A+ *
7065N/A+ * See sam_stat(3) and sam_segment_stat(3) for details.
7065N/A+ *
7065N/A+ * If something goes wrong we assume that the file is offline.
7065N/A+ */
7065N/A+static bool samfs_is_offline(struct vfs_handle_struct *handle, const struct smb_filename *fname, SMB_STRUCT_STAT *sbuf)
7065N/A+{
7065N/A+ struct sam_stat file_info;
7065N/A+ struct sam_stat *seg_info_ptr;
7065N/A+ int number_of_segments, number_of_segments_offline = 0;
7065N/A+ int result;
7065N/A+ int i;
7065N/A+ NTSTATUS status;
7065N/A+ char *path;
7065N/A+
7065N/A+ status = get_full_smb_filename(talloc_tos(), fname, &path);
7065N/A+ if (!NT_STATUS_IS_OK(status)) {
7065N/A+ errno = map_errno_from_nt_status(status);
7065N/A+ return false;
7065N/A+ }
7065N/A+
7065N/A+ if (ISDOT(path) || ISDOTDOT(path)) {
7065N/A+ return false;
7065N/A+ }
7065N/A+
7065N/A+ /*
7065N/A+ * Initialize file_info to be all zero bits
7065N/A+ */
7065N/A+ memset((void *)&file_info, 0, sizeof(struct sam_stat));
7065N/A+
7065N/A+ /*
7065N/A+ * Stat the file using the regular sam_stat function
7065N/A+ */
7065N/A+ result = sam_stat(path, &file_info, sizeof(struct sam_stat));
7065N/A+
7065N/A+ if (result != 0) {
7065N/A+ DEBUG(10,("samfs_is_offline: cannot sam_stat %s, %s\nAssuming file is offline.\n", \
7065N/A+ path, strerror(errno)));
7065N/A+ return true;
7065N/A+ }
7065N/A+
7065N/A+ /*
7065N/A+ * Check if file is offline
7065N/A+ */
7065N/A+ if (SS_ISOFFLINE(file_info.attr)) {
7065N/A+ DEBUG(10,("samfs_is_offline: file %s is offline.\n", path));
7065N/A+ return true;
7065N/A+ }
7065N/A+
7065N/A+ /*
7065N/A+ * Check for segmented file
7065N/A+ */
7065N/A+ if (SS_ISSEGMENT_F(file_info.attr)) {
7065N/A+ number_of_segments = NUM_SEGS(&file_info);
7065N/A+ seg_info_ptr = (struct sam_stat *)talloc_zero_array(talloc_tos(),
7065N/A+ struct sam_stat, number_of_segments);
7065N/A+ if (seg_info_ptr == NULL) {
7065N/A+ DEBUG(10,("samfs_is_offline: cannot talloc for "
7065N/A+ "segment stat info %s\nAssuming file is offline.\n",
7065N/A+ path));
7065N/A+ return true;
7065N/A+ }
7065N/A+
7065N/A+ /*
7065N/A+ * Stat all segments
7065N/A+ */
7065N/A+ result = sam_segment_stat(path, seg_info_ptr,
7065N/A+ number_of_segments * sizeof(struct sam_stat));
7065N/A+ if (result != 0) {
7065N/A+ DEBUG(10,("samfs_is_offline: cannot sam_segment_stat %s, "
7065N/A+ "%s\nAssuming file is offline.\n",
7065N/A+ path, strerror(errno)));
7065N/A+ TALLOC_FREE(seg_info_ptr);
7065N/A+ return true;
7065N/A+ }
7065N/A+ /*
7065N/A+ * Loop over segments until we have checked all segments
7065N/A+ * or found one which is offline.
7065N/A+ */
7065N/A+ for (i = 0; i < number_of_segments; i++) {
7065N/A+ if (SS_ISOFFLINE(seg_info_ptr[i].attr)) {
7065N/A+ number_of_segments_offline++;
7065N/A+ }
7065N/A+ }
7065N/A+ DEBUG(10,("samfs_is_offline: file %s has %d offline segments\n"
7065N/A+ , path, number_of_segments_offline));
7065N/A+ TALLOC_FREE(seg_info_ptr);
7065N/A+ }
7065N/A+ return (number_of_segments_offline) ? true : false ;
7065N/A+}
7065N/A+
7065N/A+/*
7065N/A+ * samfs_set_offline()
7065N/A+ *
7065N/A+ * Release the local file in the sense of SAM-QFS.
7065N/A+ * See sam_release(3) for details.
7065N/A+ *
7065N/A+ */
7065N/A+static int samfs_set_offline(struct vfs_handle_struct *handle, const struct smb_filename *fname)
7065N/A+{
7065N/A+ int result;
7065N/A+ NTSTATUS status;
7065N/A+ char *path;
7065N/A+
7065N/A+ status = get_full_smb_filename(talloc_tos(), fname, &path);
7065N/A+ if (!NT_STATUS_IS_OK(status)) {
7065N/A+ errno = map_errno_from_nt_status(status);
7065N/A+ return false;
7065N/A+ }
7065N/A+
7065N/A+ /*
7065N/A+ * release a file-command to SAM-stager
7065N/A+ */
7065N/A+ result = sam_release(path, "i");
7065N/A+ if (result != 0) {
7065N/A+ DEBUG(10,("samfs_set_offline: sam_release %s returned %s\n",
7065N/A+ path, strerror(errno)));
7065N/A+ return -1;
7065N/A+ }
7065N/A+ return 0;
7065N/A+}
7065N/A+
7065N/A+/* VFS operations structure */
7065N/A+
7065N/A+static struct vfs_fn_pointers samfs_fns = {
7065N/A+ .is_offline_fn = samfs_is_offline,
7065N/A+ .set_offline_fn = samfs_set_offline
7065N/A+};
7065N/A+
7065N/A+NTSTATUS vfs_samfs_init(void)
7065N/A+{
7065N/A+ return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, SAMFS_MODULE_NAME,
7065N/A+ &samfs_fns);
7065N/A+}