The branch, v3-6-test has been updated via 50e84a8 s3:gpfs: Add support for the gpfs_ftruncate call via d5cf47e s3:vfs:gpfs convert sharemodes/leases parameter via 7d18985 s3:vfs:syncops add option to disable module per share via 739621d s3:vfs:syncops make it possible to specify syncops:onclose per share from 8fcfb11 Make the vfs_acl_xattr and other modules work with NULL SD's. Fix the "protected" inheritance problem (bleeding up from the POSIX layer).
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-6-test - Log ----------------------------------------------------------------- commit 50e84a8fa2cbb400415e57573f37b9012396d13d Author: Christian Ambach <christian.amb...@de.ibm.com> Date: Fri Oct 8 13:43:17 2010 +0200 s3:gpfs: Add support for the gpfs_ftruncate call ported from the v3-4-ctdb branch to master This used to be commit 1f138cc9f4a Autobuild-User: Volker Lendecke <vlen...@samba.org> Autobuild-Date: Wed Oct 13 13:34:25 UTC 2010 on sn-devel-104 commit d5cf47ee1be630d461c5d7285dd8ce0a7ef35059 Author: Christian Ambach <christian.amb...@de.ibm.com> Date: Fri Oct 8 13:15:57 2010 +0200 s3:vfs:gpfs convert sharemodes/leases parameter convert gpfs:sharemodes and gpfs:leases parameters from a global setting to a per share setting commit 7d189850b0bde9c001fd33c4646f938d755e91a5 Author: Christian Ambach <christian.amb...@de.ibm.com> Date: Thu Oct 7 16:56:19 2010 +0200 s3:vfs:syncops add option to disable module per share add an option to disable the syncops module completely for a share with syncops:disable = true commit 739621d1a269aa1eca4e71a85b8f1feea126ac5f Author: Christian Ambach <christian.amb...@de.ibm.com> Date: Thu Oct 7 16:09:52 2010 +0200 s3:vfs:syncops make it possible to specify syncops:onclose per share convert the onclose option of the vfs_syncops module from a global option to a service-specific one as preparation for further flags, use a struct to store in the VFS handle instead of just the onclose flag ----------------------------------------------------------------------- Summary of changes: source3/modules/gpfs.c | 28 ++++++------ source3/modules/vfs_gpfs.c | 85 ++++++++++++++++++++++++++++++++++---- source3/modules/vfs_gpfs.h | 1 + source3/modules/vfs_syncops.c | 91 +++++++++++++++++++++++++++++++++++------ 4 files changed, 170 insertions(+), 35 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/modules/gpfs.c b/source3/modules/gpfs.c index e059808..cad765e 100644 --- a/source3/modules/gpfs.c +++ b/source3/modules/gpfs.c @@ -24,10 +24,9 @@ #include "gpfs_gpl.h" #include "vfs_gpfs.h" -static bool gpfs_share_modes; -static bool gpfs_leases; static bool gpfs_getrealfilename; static bool gpfs_winattr; +static bool gpfs_do_ftruncate; 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); @@ -38,7 +37,7 @@ static int (*gpfs_get_realfilename_path_fn)(char *pathname, char *filenamep, static int (*gpfs_set_winattrs_path_fn)(char *pathname, int flags, struct gpfs_winattr *attrs); static int (*gpfs_get_winattrs_path_fn)(char *pathname, struct gpfs_winattr *attrs); static int (*gpfs_get_winattrs_fn)(int fd, struct gpfs_winattr *attrs); - +static int (*gpfs_ftruncate_fn)(int fd, gpfs_off64_t length); bool set_gpfs_sharemode(files_struct *fsp, uint32 access_mask, uint32 share_access) @@ -47,10 +46,6 @@ bool set_gpfs_sharemode(files_struct *fsp, uint32 access_mask, unsigned int deny = GPFS_DENY_NONE; int result; - if (!gpfs_share_modes) { - return True; - } - if (gpfs_set_share_fn == NULL) { return False; } @@ -96,10 +91,6 @@ int set_gpfs_lease(int fd, int leasetype) { int gpfs_type = GPFS_LEASE_NONE; - if (!gpfs_leases) { - return True; - } - if (gpfs_set_lease_fn == NULL) { errno = EINVAL; return -1; @@ -141,6 +132,16 @@ int smbd_gpfs_putacl(char *pathname, int flags, void *acl) return gpfs_putacl_fn(pathname, flags, acl); } +int smbd_gpfs_ftruncate(int fd, gpfs_off64_t length) +{ + if (!gpfs_do_ftruncate || (gpfs_ftruncate_fn == NULL)) { + errno = ENOSYS; + return -1; + } + + return gpfs_ftruncate_fn(fd, length); +} + int smbd_gpfs_get_realfilename_path(char *pathname, char *filenamep, int *buflen) { @@ -247,13 +248,12 @@ void init_gpfs(void) init_gpfs_function(&gpfs_get_winattrs_path_fn,"gpfs_get_winattrs_path"); init_gpfs_function(&gpfs_set_winattrs_path_fn,"gpfs_set_winattrs_path"); init_gpfs_function(&gpfs_get_winattrs_fn,"gpfs_get_winattrs"); + init_gpfs_function(&gpfs_ftruncate_fn, "gpfs_ftruncate"); - - gpfs_share_modes = lp_parm_bool(-1, "gpfs", "sharemodes", True); - gpfs_leases = lp_parm_bool(-1, "gpfs", "leases", True); gpfs_getrealfilename = lp_parm_bool(-1, "gpfs", "getrealfilename", True); gpfs_winattr = lp_parm_bool(-1, "gpfs", "winattr", False); + gpfs_do_ftruncate = lp_parm_bool(-1, "gpfs", "ftruncate", True); return; } diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 5fdcef9..8fbfbdf 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -30,18 +30,29 @@ #include "nfs4_acls.h" #include "vfs_gpfs.h" +struct gpfs_config_data { + bool sharemodes; + bool leases; +}; + + static int vfs_gpfs_kernel_flock(vfs_handle_struct *handle, files_struct *fsp, uint32 share_mode, uint32 access_mask) { + struct gpfs_config_data *config; + + SMB_VFS_HANDLE_GET_DATA(handle, config, + struct gpfs_config_data, + return -1); + START_PROFILE(syscall_kernel_flock); kernel_flock(fsp->fh->fd, share_mode, access_mask); - if (!set_gpfs_sharemode(fsp, access_mask, fsp->share_access)) { - + if (config->sharemodes + && !set_gpfs_sharemode(fsp, access_mask, fsp->share_access)) { return -1; - } END_PROFILE(syscall_kernel_flock); @@ -51,7 +62,14 @@ static int vfs_gpfs_kernel_flock(vfs_handle_struct *handle, files_struct *fsp, static int vfs_gpfs_close(vfs_handle_struct *handle, files_struct *fsp) { - if ((fsp->fh != NULL) && (fsp->fh->fd != -1)) { + + struct gpfs_config_data *config; + + SMB_VFS_HANDLE_GET_DATA(handle, config, + struct gpfs_config_data, + return -1); + + if (config->sharemodes && (fsp->fh != NULL) && (fsp->fh->fd != -1)) { set_gpfs_sharemode(fsp, 0, 0); } @@ -61,16 +79,23 @@ static int vfs_gpfs_close(vfs_handle_struct *handle, files_struct *fsp) static int vfs_gpfs_setlease(vfs_handle_struct *handle, files_struct *fsp, int leasetype) { - int ret; + struct gpfs_config_data *config; + int ret=0; + + SMB_VFS_HANDLE_GET_DATA(handle, config, + struct gpfs_config_data, + return -1); START_PROFILE(syscall_linux_setlease); - if ( linux_set_lease_sighandler(fsp->fh->fd) == -1) + if (linux_set_lease_sighandler(fsp->fh->fd) == -1) return -1; - ret = set_gpfs_lease(fsp->fh->fd,leasetype); + if (config->leases) { + ret = set_gpfs_lease(fsp->fh->fd,leasetype); + } - if ( ret < 0 ) { + if (ret < 0) { /* This must have come from GPFS not being available */ /* or some other error, hence call the default */ ret = linux_setlease(fsp->fh->fd, leasetype); @@ -1103,7 +1128,50 @@ static int vfs_gpfs_ntimes(struct vfs_handle_struct *handle, } +static int vfs_gpfs_ftruncate(vfs_handle_struct *handle, files_struct *fsp, + SMB_OFF_T len) +{ + int result; + + result = smbd_gpfs_ftruncate(fsp->fh->fd, len); + if ((result == -1) && (errno == ENOSYS)) { + return SMB_VFS_NEXT_FTRUNCATE(handle, fsp, len); + } + return result; +} + +int vfs_gpfs_connect(struct vfs_handle_struct *handle, const char *service, + const char *user) +{ + struct gpfs_config_data *config; + int ret = SMB_VFS_NEXT_CONNECT(handle, service, user); + + if (ret < 0) { + return ret; + } + + config = talloc_zero(handle->conn, struct gpfs_config_data); + if (!config) { + SMB_VFS_NEXT_DISCONNECT(handle); + DEBUG(0, ("talloc_zero() failed\n")); return -1; + } + + config->sharemodes = lp_parm_bool(SNUM(handle->conn), "gpfs", + "sharemodes", true); + + config->leases = lp_parm_bool(SNUM(handle->conn), "gpfs", + "leases", true); + + SMB_VFS_HANDLE_SET_DATA(handle, config, + NULL, struct syncops_config_data, + return -1); + + return 0; +} + + static struct vfs_fn_pointers vfs_gpfs_fns = { + .connect_fn = vfs_gpfs_connect, .kernel_flock = vfs_gpfs_kernel_flock, .linux_setlease = vfs_gpfs_setlease, .get_real_filename = vfs_gpfs_get_real_filename, @@ -1124,6 +1192,7 @@ static struct vfs_fn_pointers vfs_gpfs_fns = { .fstat = vfs_gpfs_fstat, .lstat = vfs_gpfs_lstat, .ntimes = vfs_gpfs_ntimes, + .ftruncate = vfs_gpfs_ftruncate }; NTSTATUS vfs_gpfs_init(void); diff --git a/source3/modules/vfs_gpfs.h b/source3/modules/vfs_gpfs.h index d2899b5..46cfdfe 100644 --- a/source3/modules/vfs_gpfs.h +++ b/source3/modules/vfs_gpfs.h @@ -34,4 +34,5 @@ int smbd_gpfs_get_realfilename_path(char *pathname, char *filenamep, int smbd_fget_gpfs_winattrs(int fd, struct gpfs_winattr *attrs); int get_gpfs_winattrs(char * pathname,struct gpfs_winattr *attrs); int set_gpfs_winattrs(char * pathname,int flags,struct gpfs_winattr *attrs); +int smbd_gpfs_ftruncate(int fd, gpfs_off64_t length); void init_gpfs(void); diff --git a/source3/modules/vfs_syncops.c b/source3/modules/vfs_syncops.c index c098159..2b7c2a3 100644 --- a/source3/modules/vfs_syncops.c +++ b/source3/modules/vfs_syncops.c @@ -31,13 +31,21 @@ On those filesystems this module provides a way to perform those operations safely. - */ -/* most of the performance loss with this module is in fsync on close(). - You can disable that with syncops:onclose = no + You can disable that with + syncops:onclose = no + that can be set either globally or per share. + + you can also disable the module completely for a service with + syncops:disable = true + */ -static bool sync_onclose; + +struct syncops_config_data { + bool onclose; + bool disable; +}; /* given a filename, find the parent directory @@ -125,8 +133,16 @@ static int syncops_rename(vfs_handle_struct *handle, const struct smb_filename *smb_fname_src, const struct smb_filename *smb_fname_dst) { - int ret = SMB_VFS_NEXT_RENAME(handle, smb_fname_src, smb_fname_dst); - if (ret == 0) { + + int ret; + struct syncops_config_data *config; + + SMB_VFS_HANDLE_GET_DATA(handle, config, + struct syncops_config_data, + return -1); + + ret = SMB_VFS_NEXT_RENAME(handle, smb_fname_src, smb_fname_dst); + if (ret == 0 && !config->disable) { syncops_two_names(smb_fname_src->base_name, smb_fname_dst->base_name); } @@ -135,14 +151,28 @@ static int syncops_rename(vfs_handle_struct *handle, /* handle the rest with a macro */ #define SYNCOPS_NEXT(op, fname, args) do { \ - int ret = SMB_VFS_NEXT_ ## op args; \ - if (ret == 0 && fname) syncops_name(fname); \ + int ret; \ + struct syncops_config_data *config; \ + SMB_VFS_HANDLE_GET_DATA(handle, config, \ + struct syncops_config_data, \ + return -1); \ + ret = SMB_VFS_NEXT_ ## op args; \ + if (ret == 0 \ + && !config->disable \ + && fname) syncops_name(fname); \ return ret; \ } while (0) #define SYNCOPS_NEXT_SMB_FNAME(op, fname, args) do { \ - int ret = SMB_VFS_NEXT_ ## op args; \ - if (ret == 0 && fname) syncops_smb_fname(fname); \ + int ret; \ + struct syncops_config_data *config; \ + SMB_VFS_HANDLE_GET_DATA(handle, config, \ + struct syncops_config_data, \ + return -1); \ + ret = SMB_VFS_NEXT_ ## op args; \ + if (ret == 0 \ + && !config->disable \ + && fname) syncops_smb_fname(fname); \ return ret; \ } while (0) @@ -191,7 +221,13 @@ static int syncops_rmdir(vfs_handle_struct *handle, const char *fname) /* close needs to be handled specially */ static int syncops_close(vfs_handle_struct *handle, files_struct *fsp) { - if (fsp->can_write && sync_onclose) { + struct syncops_config_data *config; + + SMB_VFS_HANDLE_GET_DATA(handle, config, + struct syncops_config_data, + return -1); + + if (fsp->can_write && config->onclose) { /* ideally we'd only do this if we have written some data, but there is no flag for that in fsp yet. */ fsync(fsp->fh->fd); @@ -199,8 +235,39 @@ static int syncops_close(vfs_handle_struct *handle, files_struct *fsp) return SMB_VFS_NEXT_CLOSE(handle, fsp); } +int syncops_connect(struct vfs_handle_struct *handle, const char *service, + const char *user) +{ + + struct syncops_config_data *config; + int ret = SMB_VFS_NEXT_CONNECT(handle, service, user); + if (ret < 0) { + return ret; + } + + config = talloc_zero(handle->conn, struct syncops_config_data); + if (!config) { + SMB_VFS_NEXT_DISCONNECT(handle); + DEBUG(0, ("talloc_zero() failed\n")); + return -1; + } + + config->onclose = lp_parm_bool(SNUM(handle->conn), "syncops", + "onclose", true); + + config->disable = lp_parm_bool(SNUM(handle->conn), "syncops", + "disable", false); + + SMB_VFS_HANDLE_SET_DATA(handle, config, + NULL, struct syncops_config_data, + return -1); + + return 0; + +} static struct vfs_fn_pointers vfs_syncops_fns = { + .connect_fn = syncops_connect, .mkdir = syncops_mkdir, .rmdir = syncops_rmdir, .open = syncops_open, @@ -222,7 +289,5 @@ NTSTATUS vfs_syncops_init(void) if (!NT_STATUS_IS_OK(ret)) return ret; - sync_onclose = lp_parm_bool(-1, "syncops", "onclose", true); - return ret; } -- Samba Shared Repository