source: branches/samba-3.3.x/source/modules/vfs_cacheprime.c@ 206

Last change on this file since 206 was 206, checked in by Herwig Bauernfeind, 17 years ago

Import Samba 3.3 branch at 3.0.0 level (psmedley's port)

File size: 6.5 KB
Line 
1/*
2 * Copyright (c) James Peach 2005-2006
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "includes.h"
19
20/* Cache priming module.
21 *
22 * The purpose of this module is to do RAID stripe width reads to prime the
23 * buffer cache to do zero-copy I/O for subsequent sendfile calls. The idea is
24 * to do a single large read at the start of the file to make sure that most or
25 * all of the file is pulled into the buffer cache. Subsequent I/Os have
26 * reduced latency.
27 *
28 * Tunables.
29 *
30 * cacheprime:rsize Amount of readahead in bytes. This should be a
31 * multiple of the RAID stripe width.
32 * cacheprime:debug Debug level at which to emit messages.
33 */
34
35#define READAHEAD_MIN (128 * 1024) /* min is 128 KiB */
36#define READAHEAD_MAX (100 * 1024 * 1024) /* max is 100 MiB */
37
38#define MODULE "cacheprime"
39
40static int module_debug;
41static ssize_t g_readsz = 0;
42static void * g_readbuf = NULL;
43
44/* Prime the kernel buffer cache with data from the specified file. We use
45 * per-fsp data to make sure we only ever do this once. If pread is being
46 * emulated by seek/read/seek, when this will suck quite a lot.
47 */
48static bool prime_cache(
49 struct vfs_handle_struct * handle,
50 files_struct * fsp,
51 SMB_OFF_T offset,
52 size_t count)
53{
54 SMB_OFF_T * last;
55 ssize_t nread;
56
57 last = (SMB_OFF_T *)VFS_ADD_FSP_EXTENSION(handle, fsp, SMB_OFF_T);
58 if (!last) {
59 return False;
60 }
61
62 if (*last == -1) {
63 /* Readahead disabled. */
64 return False;
65 }
66
67 if ((*last + g_readsz) > (offset + count)) {
68 /* Skip readahead ... we've already been here. */
69 return False;
70 }
71
72 DEBUG(module_debug,
73 ("%s: doing readahead of %lld bytes at %lld for %s\n",
74 MODULE, (long long)g_readsz, (long long)*last,
75 fsp->fsp_name));
76
77 nread = sys_pread(fsp->fh->fd, g_readbuf, g_readsz, *last);
78 if (nread < 0) {
79 *last = -1;