s3:vfs:syncops make it possible to specify syncops:onclose per share
authorChristian Ambach <christian.ambach@de.ibm.com>
Thu, 7 Oct 2010 14:09:52 +0000 (16:09 +0200)
committerVolker Lendecke <vlendec@samba.org>
Wed, 13 Oct 2010 12:53:16 +0000 (12:53 +0000)
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

source3/modules/vfs_syncops.c

index c098159ff66a6f024f880067b5ead29897759f0e..3f52741009f917a3b7ca6773652281848db2c5e1 100644 (file)
 
   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.
+
  */
-static bool sync_onclose;
+
+struct syncops_config_data {
+       bool onclose;
+};
 
 /*
   given a filename, find the parent directory
@@ -191,7 +195,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 +209,36 @@ 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);
+
+       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 +260,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;
 }