modules/vfs_commit.c

説明を見る。
00001 /*
00002  * Copyright (c) James Peach 2006
00003  *
00004  * This program is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017  */
00018 
00019 #include "includes.h"
00020 
00021 /* Commit data module.
00022  *
00023  * The purpose of this module is to flush data to disk at regular intervals,
00024  * just like the NFS commit operation. There's two rationales for this. First,
00025  * it minimises the data loss in case of a power outage without incurring
00026  * the poor performance of synchronous I/O. Second, a steady flush rate
00027  * can produce better throughput than suddenly dumping massive amounts of
00028  * writes onto a disk.
00029  *
00030  * Tunables:
00031  *
00032  *  commit: dthresh         Amount of dirty data that can accumulate
00033  *                                      before we commit (sync) it.
00034  *
00035  *  commit: debug           Debug level at which to emit messages.
00036  *
00037  */
00038 
00039 #define MODULE "commit"
00040 
00041 static int module_debug;
00042 
00043 struct commit_info
00044 {
00045         SMB_OFF_T dbytes;       /* Dirty (uncommitted) bytes */
00046         SMB_OFF_T dthresh;      /* Dirty data threshold */
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         /* Don't bother with read-only files. */
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 

Sambaに対してSat Aug 29 21:23:07 2009に生成されました。  doxygen 1.4.7