r19647: Add some GPFS support in a vfs mod. Also adds the kernel flock op to
authorJim McDonough <jmcd@samba.org>
Thu, 9 Nov 2006 20:29:31 +0000 (20:29 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:15:43 +0000 (12:15 -0500)
the vfs layer, since gpfs supports it.  Thanks to Volker, Christian,
Mathias, Chetan, and Peter.

source/Makefile.in
source/configure.in
source/include/smbprofile.h
source/include/vfs.h
source/include/vfs_macros.h
source/lib/system.c
source/modules/gpfs.c [new file with mode: 0644]
source/modules/vfs_default.c
source/modules/vfs_gpfs.c [new file with mode: 0644]
source/profile/profile.c
source/smbd/open.c

index ad2c507da979f75287a26f6f74979163c26fb179..d776de2b3fcbf91c835bd3a0228b60b63a43df05 100644 (file)
@@ -427,6 +427,7 @@ VFS_CATIA_OBJ = modules/vfs_catia.o
 VFS_CACHEPRIME_OBJ = modules/vfs_cacheprime.o
 VFS_PREALLOC_OBJ = modules/vfs_prealloc.o
 VFS_COMMIT_OBJ = modules/vfs_commit.o
+VFS_GPFS_OBJ = modules/vfs_gpfs.o modules/gpfs.o
 
 PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o
 
@@ -1532,6 +1533,11 @@ bin/commit.@SHLIBEXT@: $(VFS_COMMIT_OBJ)
        @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_COMMIT_OBJ) \
                @SONAMEFLAG@`basename $@`
 
+bin/gpfs.@SHLIBEXT@: $(VFS_GPFS_OBJ)
+       @echo "Building plugin $@"
+       @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_GPFS_OBJ) \
+               @SONAMEFLAG@`basename $@`
+
 bin/wbinfo@EXEEXT@: $(WBINFO_OBJ) @BUILD_POPT@ bin/.dummy
        @echo Linking $@
        @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(WBINFO_OBJ) $(DYNEXP) $(LIBS) $(LDAP_LIBS) @POPTLIBS@
index 059643f38e55472b13755c6f050109700ae79f7a..cce21a29b216cb6d855a15d46c2fdc7395fa43ab 100644 (file)
@@ -1249,6 +1249,20 @@ AC_CHECK_HEADERS(execinfo.h libexc.h libunwind.h)
 AC_CHECK_FUNCS(backtrace_symbols)
 AC_CHECK_LIB(exc, trace_back_stack)
 
+echo -n "checking for GPFS GPL libs... "
+save_LIBS="$LIBS"
+LIBS="$LIBS -lgpfs_gpl"
+AC_TRY_LINK([#include <gpfs_gpl.h>],
+          [gpfs_set_share(0,GPFS_SHARE_READ,GPFS_DENY_NONE)],
+          samba_cv_HAVE_GPFS=yes,
+          samba_cv_HAVE_GPFS=no)
+echo $samba_cv_HAVE_GPFS
+if test x"$samba_cv_HAVE_GPFS" = x"yes"; then
+    AC_DEFINE(HAVE_GPFS,1,[Whether GPFS GPL libs are available])
+    default_shared_modules="$default_shared_modules vfs_gpfs"
+fi
+LIBS="$save_LIBS"
+
 # Note that all the libunwind symbols in the API are defined to internal
 # platform-specific version, so we must include libunwind.h before checking
 # any of them.
@@ -5910,6 +5924,7 @@ SMB_MODULE(vfs_catia, \$(VFS_CATIA_OBJ), "bin/catia.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_cacheprime, \$(VFS_CACHEPRIME_OBJ), "bin/cacheprime.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_prealloc, \$(VFS_PREALLOC_OBJ), "bin/prealloc.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_commit, \$(VFS_COMMIT_OBJ), "bin/commit.$SHLIBEXT", VFS)
+SMB_MODULE(vfs_gpfs, \$(VFS_GPFS_OBJ), "bin/gpfs.$SHLIBEXT", VFS)
 
 SMB_SUBSYSTEM(VFS,smbd/vfs.o)
 
index d29f066796bc68a80393917e9fbfff587e34920c..39f02ec9f538d04ba845957401f1408a3d0c2ff1 100644 (file)
@@ -164,6 +164,10 @@ enum profile_stats_values
 #define syscall_fcntl_lock_count __profile_stats_value(PR_VALUE_SYSCALL_FCNTL_LOCK, count)
 #define syscall_fcntl_lock_time __profile_stats_value(PR_VALUE_SYSCALL_FCNTL_LOCK, time)
 
+       PR_VALUE_SYSCALL_KERNEL_FLOCK,
+#define syscall_kernel_flock_count __profile_stats_value(PR_VALUE_SYSCALL_KERNEL_FLOCK, count)
+#define syscall_kernel_flock_time __profile_stats_value(PR_VALUE_SYSCALL_KERNEL_FLOCK, time)
+
        PR_VALUE_SYSCALL_FCNTL_GETLOCK,
 #define syscall_fcntl_getlock_count __profile_stats_value(PR_VALUE_SYSCALL_FCNTL_GETLOCK, count)
 #define syscall_fcntl_getlock_time __profile_stats_value(PR_VALUE_SYSCALL_FCNTL_GETLOCK, time)
index 185ca01f6c155fb16cd993ad7b6491e8d09037d1..48cabe7d3c14eb35e0b48a891c2a397643ad01fa 100644 (file)
@@ -144,6 +144,7 @@ typedef enum _vfs_op_type {
        SMB_VFS_OP_UTIME,
        SMB_VFS_OP_FTRUNCATE,
        SMB_VFS_OP_LOCK,
+       SMB_VFS_OP_KERNEL_FLOCK,
        SMB_VFS_OP_GETLOCK,
        SMB_VFS_OP_SYMLINK,
        SMB_VFS_OP_READLINK,
@@ -266,6 +267,7 @@ struct vfs_ops {
                int (*utime)(struct vfs_handle_struct *handle, const char *path, struct utimbuf *times);
                int (*ftruncate)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_OFF_T offset);
                BOOL (*lock)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
+               int (*kernel_flock)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, uint32 share_mode);
                BOOL (*getlock)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid);
                int (*symlink)(struct vfs_handle_struct *handle, const char *oldpath, const char *newpath);
                int (*readlink)(struct vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz);
@@ -380,6 +382,7 @@ struct vfs_ops {
                struct vfs_handle_struct *utime;
                struct vfs_handle_struct *ftruncate;
                struct vfs_handle_struct *lock;
+               struct vfs_handle_struct *kernel_flock;
                struct vfs_handle_struct *getlock;
                struct vfs_handle_struct *symlink;
                struct vfs_handle_struct *readlink;
index 2d6f8580f682df718e696166c87768a09b1ea07d..119b616e72e69efc9abba3e5769be476b7bb44fa 100644 (file)
@@ -70,6 +70,7 @@
 #define SMB_VFS_UTIME(conn, path, times) ((conn)->vfs.ops.utime((conn)->vfs.handles.utime, (path), (times)))
 #define SMB_VFS_FTRUNCATE(fsp, fd, offset) ((fsp)->conn->vfs.ops.ftruncate((fsp)->conn->vfs.handles.ftruncate, (fsp), (fd), (offset)))
 #define SMB_VFS_LOCK(fsp, fd, op, offset, count, type) ((fsp)->conn->vfs.ops.lock((fsp)->conn->vfs.handles.lock, (fsp), (fd) ,(op), (offset), (count), (type)))
+#define SMB_VFS_KERNEL_FLOCK(fsp, fd, share_mode) ((fsp)->conn->vfs.ops.kernel_flock((fsp)->conn->vfs.handles.kernel_flock, (fsp), (fd), (share_mode)))
 #define SMB_VFS_GETLOCK(fsp, fd, poffset, pcount, ptype, ppid) ((fsp)->conn->vfs.ops.getlock((fsp)->conn->vfs.handles.getlock, (fsp), (fd) ,(poffset), (pcount), (ptype), (ppid)))
 #define SMB_VFS_SYMLINK(conn, oldpath, newpath) ((conn)->vfs.ops.symlink((conn)->vfs.handles.symlink, (oldpath), (newpath)))
 #define SMB_VFS_READLINK(conn, path, buf, bufsiz) ((conn)->vfs.ops.readlink((conn)->vfs.handles.readlink, (path), (buf), (bufsiz)))
 #define SMB_VFS_OPAQUE_UTIME(conn, path, times) ((conn)->vfs_opaque.ops.utime((conn)->vfs_opaque.handles.utime, (path), (times)))
 #define SMB_VFS_OPAQUE_FTRUNCATE(fsp, fd, offset) ((fsp)->conn->vfs_opaque.ops.ftruncate((fsp)->conn->vfs_opaque.handles.ftruncate, (fsp), (fd), (offset)))
 #define SMB_VFS_OPAQUE_LOCK(fsp, fd, op, offset, count, type) ((fsp)->conn->vfs_opaque.ops.lock((fsp)->conn->vfs_opaque.handles.lock, (fsp), (fd) ,(op), (offset), (count), (type)))
+#define SMB_VFS_OPAQUE_FLOCK(fsp, fd, share_mode) ((fsp)->conn->vfs_opaque.ops.lock((fsp)->conn->vfs_opaque.handles.kernel_flock, (fsp), (fd), (share_mode)))
 #define SMB_VFS_OPAQUE_GETLOCK(fsp, fd, poffset, pcount, ptype, ppid) ((fsp)->conn->vfs_opaque.ops.getlock((fsp)->conn->vfs_opaque.handles.getlock, (fsp), (fd), (poffset), (pcount), (ptype), (ppid)))
 #define SMB_VFS_OPAQUE_SYMLINK(conn, oldpath, newpath) ((conn)->vfs_opaque.ops.symlink((conn)->vfs_opaque.handles.symlink, (oldpath), (newpath)))
 #define SMB_VFS_OPAQUE_READLINK(conn, path, buf, bufsiz) ((conn)->vfs_opaque.ops.readlink((conn)->vfs_opaque.handles.readlink, (path), (buf), (bufsiz)))
 #define SMB_VFS_NEXT_UTIME(handle, path, times) ((handle)->vfs_next.ops.utime((handle)->vfs_next.handles.utime, (path), (times)))
 #define SMB_VFS_NEXT_FTRUNCATE(handle, fsp, fd, offset) ((handle)->vfs_next.ops.ftruncate((handle)->vfs_next.handles.ftruncate, (fsp), (fd), (offset)))
 #define SMB_VFS_NEXT_LOCK(handle, fsp, fd, op, offset, count, type) ((handle)->vfs_next.ops.lock((handle)->vfs_next.handles.lock, (fsp), (fd) ,(op), (offset), (count), (type)))
+#define SMB_VFS_NEXT_KERNEL_FLOCK(handle, fsp, fd, share_mode)((handle)->vfs_next.ops.lock((handle)->vfs_next.handles.kernel_flock, (fsp), (fd), (share_mode)))
 #define SMB_VFS_NEXT_GETLOCK(handle, fsp, fd, poffset, pcount, ptype, ppid) ((handle)->vfs_next.ops.getlock((handle)->vfs_next.handles.getlock, (fsp), (fd), (poffset), (pcount), (ptype), (ppid)))
 #define SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath) ((handle)->vfs_next.ops.symlink((handle)->vfs_next.handles.symlink, (oldpath), (newpath)))
 #define SMB_VFS_NEXT_READLINK(handle, path, buf, bufsiz) ((handle)->vfs_next.ops.readlink((handle)->vfs_next.handles.readlink, (path), (buf), (bufsiz)))
index a440ece410a26e2a7997c02e12474eee4e22299a..9ee3f7cc26afc782548dad80c1e7780c8ce417c8 100644 (file)
@@ -379,6 +379,31 @@ FILE *sys_fopen(const char *path, const char *type)
 #endif
 }
 
+
+/*******************************************************************
+ A flock() wrapper that will perform the kernel flock.
+********************************************************************/
+
+void kernel_flock(int fd, uint32 share_mode)
+{
+#if HAVE_KERNEL_SHARE_MODES
+       int kernel_mode = 0;
+       if (share_mode == FILE_SHARE_WRITE) {
+               kernel_mode = LOCK_MAND|LOCK_WRITE;
+       } else if (share_mode == FILE_SHARE_READ) {
+               kernel_mode = LOCK_MAND|LOCK_READ;
+       } else if (share_mode == FILE_SHARE_NONE) {
+               kernel_mode = LOCK_MAND;
+       }
+       if (kernel_mode) {
+               flock(fd, kernel_mode);
+       }
+#endif
+       ;
+}
+
+
+
 /*******************************************************************
  An opendir wrapper that will deal with 64 bit filesizes.
 ********************************************************************/
diff --git a/source/modules/gpfs.c b/source/modules/gpfs.c
new file mode 100644 (file)
index 0000000..f63a852
--- /dev/null
@@ -0,0 +1,231 @@
+/* 
+ *  Unix SMB/CIFS implementation.
+ *  Provide a connection to GPFS specific features
+ *  Copyright (C) Volker Lendecke 2005
+ *
+ *  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"
+
+#ifdef HAVE_GPFS
+
+#include "gpfs_gpl.h"
+
+static void *libgpfs_handle = NULL;
+
+static int (*gpfs_set_share_fn)(int fd, unsigned int allow, unsigned int deny);
+static int (*gpfs_set_lease_fn)(int fd, unsigned int leaseType);
+static int (*gpfs_getacl_fn)(char *pathname, int flags, void *acl);
+static int (*gpfs_putacl_fn)(char *pathname, int flags, void *acl);
+
+
+BOOL set_gpfs_sharemode(files_struct *fsp, uint32 access_mask,
+                       uint32 share_access)
+{
+       unsigned int allow = GPFS_SHARE_NONE;
+       unsigned int deny = GPFS_DENY_NONE;
+       int result;
+
+       if (gpfs_set_share_fn == NULL) {
+               return False;
+       }
+
+       if ((fsp == NULL) || (fsp->fh == NULL) || (fsp->fh->fd < 0)) {
+               /* No real file, don't disturb */
+               return True;
+       }
+
+       allow |= (access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA|
+                                DELETE_ACCESS)) ? GPFS_SHARE_WRITE : 0;
+       allow |= (access_mask & (FILE_READ_DATA|FILE_EXECUTE)) ?
+               GPFS_SHARE_READ : 0;
+       deny |= (share_access & (FILE_SHARE_WRITE|FILE_SHARE_DELETE)) ?
+               0 : GPFS_DENY_WRITE;
+       deny |= (share_access & (FILE_SHARE_READ)) ?
+               0 : GPFS_DENY_READ;
+
+       DEBUG(10, ("am=%x, allow=%d, sa=%x, deny=%d\n",
+                  access_mask, allow, share_access, deny));
+
+       result = gpfs_set_share_fn(fsp->fh->fd, allow, deny);
+       if (result != 0) {
+               if (errno == ENOSYS) {
+                       DEBUG(5, ("VFS module vfs_gpfs loaded, but no gpfs "
+                                 "support has been compiled into Samba. Allowing access\n"));
+                       return True;
+               } else {
+                       DEBUG(10, ("gpfs_set_share failed: %s\n",
+                                  strerror(errno)));
+               }
+       }
+
+       return (result == 0);
+}
+
+int set_gpfs_lease(int fd, int leasetype)
+{
+       int gpfs_type = GPFS_LEASE_NONE;
+
+       if (gpfs_set_lease_fn == NULL) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       if (leasetype == F_RDLCK) {
+               gpfs_type = GPFS_LEASE_READ;
+       }
+       if (leasetype == F_WRLCK) {
+               gpfs_type = GPFS_LEASE_WRITE;
+       }
+       return gpfs_set_lease_fn(fd, gpfs_type);
+}
+
+int smbd_gpfs_getacl(char *pathname, int flags, void *acl)
+{
+       if (gpfs_getacl_fn == NULL) {
+               errno = ENOSYS;
+               return -1;
+       }
+
+       return gpfs_getacl_fn(pathname, flags, acl);
+}
+
+int smbd_gpfs_putacl(char *pathname, int flags, void *acl)
+{
+       if (gpfs_putacl_fn == NULL) {
+               errno = ENOSYS;
+               return -1;
+       }
+
+       return gpfs_putacl_fn(pathname, flags, acl);
+}
+
+void init_gpfs(void)
+{
+       if (libgpfs_handle != NULL) {
+               return;
+       }
+
+       libgpfs_handle = sys_dlopen("libgpfs_gpl.so", RTLD_LAZY);
+
+       if (libgpfs_handle == NULL) {
+               DEBUG(10, ("sys_dlopen for libgpfs_gpl failed: %s\n",
+                          strerror(errno)));
+               return;
+       }
+
+       DEBUG(10, ("libgpfs_gpl.so loaded\n"));
+
+       gpfs_set_share_fn = sys_dlsym(libgpfs_handle, "gpfs_set_share");
+       if (gpfs_set_share_fn == NULL) {
+               DEBUG(3, ("libgpfs_gpl.so does not contain the symbol "
+                         "'gpfs_set_share'\n"));
+               sys_dlclose(libgpfs_handle);
+
+               /* leave libgpfs_handle != NULL around, no point
+                  in trying twice */
+               gpfs_set_share_fn = NULL;
+               gpfs_set_lease_fn = NULL;
+               gpfs_getacl_fn = NULL;
+               gpfs_putacl_fn = NULL;
+               return;
+       }
+
+       gpfs_set_lease_fn = sys_dlsym(libgpfs_handle, "gpfs_set_lease");
+       if (gpfs_set_lease_fn == NULL) {
+               DEBUG(3, ("libgpfs_gpl.so does not contain the symbol "
+                         "'gpfs_set_lease'\n"));
+               sys_dlclose(libgpfs_handle);
+
+               /* leave libgpfs_handle != NULL around, no point
+                  in trying twice */
+               gpfs_set_share_fn = NULL;
+               gpfs_set_lease_fn = NULL;
+               gpfs_getacl_fn = NULL;
+               gpfs_putacl_fn = NULL;
+               return;
+       }
+
+       gpfs_getacl_fn = sys_dlsym(libgpfs_handle, "gpfs_getacl");
+       if (gpfs_getacl_fn == NULL) {
+               DEBUG(3, ("libgpfs_gpl.so does not contain the symbol "
+                         "'gpfs_getacl'\n"));
+               sys_dlclose(libgpfs_handle);
+
+               /* leave libgpfs_handle != NULL around, no point
+                  in trying twice */
+               gpfs_set_share_fn = NULL;
+               gpfs_set_lease_fn = NULL;
+               gpfs_getacl_fn = NULL;
+               gpfs_putacl_fn = NULL;
+               return;
+       }
+
+       gpfs_putacl_fn = sys_dlsym(libgpfs_handle, "gpfs_putacl");
+       if (gpfs_putacl_fn == NULL) {
+               DEBUG(3, ("libgpfs_gpl.so does not contain the symbol "
+                         "'gpfs_putacl'\n"));
+               sys_dlclose(libgpfs_handle);
+
+               /* leave libgpfs_handle != NULL around, no point
+                  in trying twice */
+               gpfs_set_share_fn = NULL;
+               gpfs_set_lease_fn = NULL;
+               gpfs_getacl_fn = NULL;
+               gpfs_putacl_fn = NULL;
+               return;
+       }
+
+}
+
+#else
+
+int set_gpfs_lease(int snum, int leasetype)
+{
+       DEBUG(0, ("'VFS module smbgpfs loaded, without gpfs support compiled\n"));
+
+       /* We need to indicate that no GPFS is around by returning ENOSYS, so
+        * that the normal linux kernel oplock code is called. */
+       errno = ENOSYS;
+       return -1;
+}
+
+BOOL set_gpfs_sharemode(files_struct *fsp, uint32 access_mask,
+                       uint32 share_access)
+{
+       DEBUG(0, ("VFS module - smbgpfs.so loaded, without gpfs support compiled\n"));
+       /* Don't disturb but complain */
+       return True;
+}
+
+int smbd_gpfs_getacl(char *pathname, int flags, void *acl)
+{
+       errno = ENOSYS;
+       return -1;
+}
+
+int smbd_gpfs_putacl(char *pathname, int flags, void *acl)
+{
+       errno = ENOSYS;
+       return -1;
+}
+
+void init_gpfs(void)
+{
+       return;
+}
+
+#endif /* HAVE_GPFS */
index ae565ae98075e66620042d8992c29f75955aba96..486a76ac88ad94ccb1ec1a1781da191f9bde6366 100644 (file)
@@ -764,6 +764,15 @@ static BOOL vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int fd, i
        return result;
 }
 
+static int vfswrap_kernel_flock(vfs_handle_struct *handle, files_struct *fsp, int fd,
+                               uint32 share_mode)
+{
+       START_PROFILE(syscall_kernel_flock);
+       kernel_flock(fd, share_mode);
+       END_PROFILE(syscall_kernel_flock);
+       return 0;
+}
+
 static BOOL vfswrap_getlock(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
 {
        BOOL result;
@@ -1189,6 +1198,8 @@ static vfs_op_tuple vfs_default_ops[] = {
         SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(vfswrap_lock),      SMB_VFS_OP_LOCK,
         SMB_VFS_LAYER_OPAQUE},
+       {SMB_VFS_OP(vfswrap_kernel_flock),      SMB_VFS_OP_KERNEL_FLOCK,
+        SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(vfswrap_getlock),   SMB_VFS_OP_GETLOCK,
         SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(vfswrap_symlink),   SMB_VFS_OP_SYMLINK,
diff --git a/source/modules/vfs_gpfs.c b/source/modules/vfs_gpfs.c
new file mode 100644 (file)
index 0000000..c5658ce
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+   Unix SMB/CIFS implementation.
+   Wrap gpfs calls in vfs functions.
+   Copyright (C) Christian Ambach <cambach1@de.ibm.com> 2006
+   
+   Major code contributions by Chetan Shringarpure <chetan.sh@in.ibm.com>
+   
+   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"
+
+
+static int vfs_gpfs_kernel_flock(vfs_handle_struct *handle, files_struct *fsp, 
+                                int fd, uint32 share_mode)
+{
+
+       START_PROFILE(syscall_kernel_flock);
+
+       kernel_flock(fsp->fh->fd, share_mode);
+
+       if (!set_gpfs_sharemode(fsp, fsp->access_mask, fsp->share_access)) {
+
+               return -1;
+
+       }
+
+       END_PROFILE(syscall_kernel_flock);
+
+       return 0;
+}
+
+
+static vfs_op_tuple gpfs_op_tuples[] = {
+
+       {SMB_VFS_OP(vfs_gpfs_kernel_flock),
+        SMB_VFS_OP_KERNEL_FLOCK,
+        SMB_VFS_LAYER_OPAQUE},
+
+       {SMB_VFS_OP(NULL),
+        SMB_VFS_OP_NOOP,
+        SMB_VFS_LAYER_NOOP}
+
+};
+
+
+NTSTATUS vfs_gpfs_init(void)
+{
+       init_gpfs();
+       
+       return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "gpfs",
+                               gpfs_op_tuples);
+}
index 926cc508dd2c46c97b8406cdcb08b75456f7c88d..187512333ccc83f9ca5df256a605265bd74db4a4 100644 (file)
@@ -287,6 +287,7 @@ BOOL profile_setup(BOOL rdonly)
            "syscall_utime",            /* PR_VALUE_SYSCALL_UTIME */
            "syscall_ftruncate",        /* PR_VALUE_SYSCALL_FTRUNCATE */
            "syscall_fcntl_lock",       /* PR_VALUE_SYSCALL_FCNTL_LOCK */
+           "syscall_kernel_flock",     /* PR_VALUE_SYSCALL_KERNEL_FLOCK */
            "syscall_fcntl_getlock",    /* PR_VALUE_SYSCALL_FCNTL_GETLOCK */
            "syscall_readlink",         /* PR_VALUE_SYSCALL_READLINK */
            "syscall_symlink",          /* PR_VALUE_SYSCALL_SYMLINK */
index 4e91cdfd2a1b406ca8cfc7da6a4038ce68b13cf9..1899a6fce7c51ba7d7ef49872ddcf4674bd4b7d0 100644 (file)
@@ -783,28 +783,6 @@ static void defer_open(struct share_mode_lock *lck,
        srv_defer_sign_response(mid);
 }
 
-/****************************************************************************
- Set a kernel flock on a file for NFS interoperability.
- This requires a patch to Linux.
-****************************************************************************/
-
-static void kernel_flock(files_struct *fsp, uint32 share_mode)
-{
-#if HAVE_KERNEL_SHARE_MODES
-       int kernel_mode = 0;
-       if (share_mode == FILE_SHARE_WRITE) {
-               kernel_mode = LOCK_MAND|LOCK_WRITE;
-       } else if (share_mode == FILE_SHARE_READ) {
-               kernel_mode = LOCK_MAND|LOCK_READ;
-       } else if (share_mode == FILE_SHARE_NONE) {
-               kernel_mode = LOCK_MAND;
-       }
-       if (kernel_mode) {
-               flock(fsp->fh->fd, kernel_mode);
-       }
-#endif
-       ;
-}
 
 /****************************************************************************
  On overwrite open ensure that the attributes match.
@@ -1126,6 +1104,8 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
        struct share_mode_lock *lck = NULL;
        uint32 open_access_mask = access_mask;
        NTSTATUS status;
+       int ret_flock;
+       
 
        if (conn->printer) {
                /* 
@@ -1644,9 +1624,18 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
            these only read them. Nobody but Samba can ever set a deny
            mode and we have already checked our more authoritative
            locking database for permission to set this deny mode. If
-           the kernel refuses the operations then the kernel is wrong */
+           the kernel refuses the operations then the kernel is wrong.
+          note that GPFS supports it as well - jmcd */
+
+       ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, fsp->fh->fd, share_access);
+       if(ret_flock == -1 ){
 
-       kernel_flock(fsp, share_access);
+               talloc_free(lck);
+               fd_close(conn, fsp);
+               file_free(fsp);
+               
+               return NT_STATUS_SHARING_VIOLATION;
+       }
 
        /*
         * At this point onwards, we can guarentee that the share entry