00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "includes.h"
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #define MODULE "commit"
00040
00041 static int module_debug;
00042
00043 struct commit_info
00044 {
00045 SMB_OFF_T dbytes;
00046 SMB_OFF_T dthresh;
00047 };
00048
00049 static void commit_all(
00050 struct vfs_handle_struct * handle,
00051 files_struct * fsp)
00052 {
00053 struct commit_info *c;
00054
00055 if ((c = VFS_FETCH_FSP_EXTENSION(handle, fsp))) {
00056 if (c->dbytes) {
00057 DEBUG(module_debug,
00058 ("%s: flushing %lu dirty bytes\n",
00059 MODULE, (unsigned long)c->dbytes));
00060
00061 fdatasync(fsp->fh->fd);
00062 c->dbytes = 0;
00063 }
00064 }
00065 }
00066
00067 static void commit(
00068 struct vfs_handle_struct * handle,
00069 files_struct * fsp,
00070 ssize_t last_write)
00071 {
00072 struct commit_info *c;
00073
00074 if ((c = VFS_FETCH_FSP_EXTENSION(handle, fsp))) {
00075
00076 if (last_write > 0) {
00077 c->dbytes += last_write;
00078 }
00079
00080 if (c->dbytes > c->dthresh) {
00081 DEBUG(module_debug,
00082 ("%s: flushing %lu dirty bytes\n",
00083 MODULE, (unsigned long)c->dbytes));
00084
00085 fdatasync(fsp->fh->fd);
00086 c->dbytes = 0;
00087 }
00088 }
00089 }
00090
00091 static int commit_connect(
00092 struct vfs_handle_struct * handle,
00093 const char * service,
00094 const char * user)
00095 {
00096 module_debug = lp_parm_int(SNUM(handle->conn), MODULE, "debug", 100);
00097 return SMB_VFS_NEXT_CONNECT(handle, service, user);
00098 }
00099
00100 static int commit_open(
00101 vfs_handle_struct * handle,
00102 const char * fname,
00103 files_struct * fsp,
00104 int flags,
00105 mode_t mode)
00106 {
00107 SMB_OFF_T dthresh;
00108
00109
00110 if ((flags & O_ACCMODE) == O_RDONLY) {
00111 return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
00112 }
00113
00114 dthresh = conv_str_size(lp_parm_const_string(SNUM(handle->conn),
00115 MODULE, "dthresh", NULL));
00116
00117 if (dthresh > 0) {
00118 struct commit_info * c;
00119 c = VFS_ADD_FSP_EXTENSION(handle, fsp, struct commit_info);
00120 if (c) {
00121 c->dthresh = dthresh;
00122 c->dbytes = 0;
00123 }
00124 }
00125
00126 return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
00127 }
00128
00129 static ssize_t commit_write(
00130 vfs_handle_struct * handle,
00131 files_struct * fsp,
00132 int fd,
00133 void * data,
00134 size_t count)
00135 {
00136 ssize_t ret;
00137
00138 ret = SMB_VFS_NEXT_WRITE(handle, fsp, fd, data, count);
00139 commit(handle, fsp, ret);
00140
00141 return ret;
00142 }
00143
00144 static ssize_t commit_pwrite(
00145 vfs_handle_struct * handle,
00146 files_struct * fsp,
00147 int fd,
00148 void * data,
00149 size_t count,
00150 SMB_OFF_T offset)
00151 {
00152 ssize_t ret;
00153
00154 ret = SMB_VFS_NEXT_PWRITE(handle, fsp, fd, data, count, offset);
00155 commit(handle, fsp, ret);
00156
00157 return ret;
00158 }
00159
00160 static ssize_t commit_close(
00161 vfs_handle_struct * handle,
00162 files_struct * fsp,
00163 int fd)
00164 {
00165 commit_all(handle, fsp);
00166 return SMB_VFS_NEXT_CLOSE(handle, fsp, fd);
00167 }
00168
00169 static vfs_op_tuple commit_ops [] =
00170 {
00171 {SMB_VFS_OP(commit_open),
00172 SMB_VFS_OP_OPEN, SMB_VFS_LAYER_TRANSPARENT},
00173 {SMB_VFS_OP(commit_close),
00174 SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_TRANSPARENT},
00175 {SMB_VFS_OP(commit_write),
00176 SMB_VFS_OP_WRITE, SMB_VFS_LAYER_TRANSPARENT},
00177 {SMB_VFS_OP(commit_pwrite),
00178 SMB_VFS_OP_PWRITE, SMB_VFS_LAYER_TRANSPARENT},
00179 {SMB_VFS_OP(commit_connect),
00180 SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT},
00181
00182 {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
00183 };
00184
00185 NTSTATUS vfs_commit_init(void);
00186 NTSTATUS vfs_commit_init(void)
00187 {
00188 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, MODULE, commit_ops);
00189 }
00190