summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim McDonough <jmcd@samba.org>2006-11-09 20:29:31 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:15:43 -0500
commit4fe70bcee2ec8515f123d8c826631b54bbf793e7 (patch)
tree0fb5daec6104c03c3cd9f9d5521506564d2af6cd
parente513fb27d61d31cdc1a0e723c5345a659cc2caf2 (diff)
downloadsamba-4fe70bcee2ec8515f123d8c826631b54bbf793e7.tar.gz
samba-4fe70bcee2ec8515f123d8c826631b54bbf793e7.tar.bz2
samba-4fe70bcee2ec8515f123d8c826631b54bbf793e7.zip
r19647: Add some GPFS support in a vfs mod. Also adds the kernel flock op to
the vfs layer, since gpfs supports it. Thanks to Volker, Christian, Mathias, Chetan, and Peter. (This used to be commit 0620658890fa9c68a9848538728023192319c81a)
-rw-r--r--source3/Makefile.in6
-rw-r--r--source3/configure.in15
-rw-r--r--source3/include/smbprofile.h4
-rw-r--r--source3/include/vfs.h3
-rw-r--r--source3/include/vfs_macros.h3
-rw-r--r--source3/lib/system.c25
-rw-r--r--source3/modules/gpfs.c231
-rw-r--r--source3/modules/vfs_default.c11
-rw-r--r--source3/modules/vfs_gpfs.c68
-rw-r--r--source3/profile/profile.c1
-rw-r--r--source3/smbd/open.c37
11 files changed, 380 insertions, 24 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index ad2c507da9..d776de2b3f 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -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@
diff --git a/source3/configure.in b/source3/configure.in
index 059643f38e..cce21a29b2 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -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)
diff --git a/source3/include/smbprofile.h b/source3/include/smbprofile.h
index d29f066796..39f02ec9f5 100644
--- a/source3/include/smbprofile.h
+++ b/source3/include/smbprofile.h
@@ -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)
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 185ca01f6c..48cabe7d3c 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -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;
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index 2d6f8580f6..119b616e72 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -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)))
@@ -182,6 +183,7 @@
#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)))
@@ -295,6 +297,7 @@
#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)))
diff --git a/source3/lib/system.c b/source3/lib/system.c
index a440ece410..9ee3f7cc26 100644
--- a/source3/lib/system.c
+++ b/source3/lib/system.c
@@ -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/source3/modules/gpfs.c b/source3/modules/gpfs.c
new file mode 100644
index 0000000000..f63a85294b
--- /dev/null
+++ b/source3/modules/gpfs.c
@@ -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 */
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index ae565ae980..486a76ac88 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -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/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c
new file mode 100644
index 0000000000..c5658ceb51
--- /dev/null
+++ b/source3/modules/vfs_gpfs.c
@@ -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);
+}
diff --git a/source3/profile/profile.c b/source3/profile/profile.c
index 926cc508dd..187512333c 100644
--- a/source3/profile/profile.c
+++ b/source3/profile/profile.c
@@ -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 */
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 4e91cdfd2a..1899a6fce7 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -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