On 08/04/2007, at 5:23 PM, Jeremy Allison wrote:

On Sun, Apr 08, 2007 at 05:09:36PM -0700, James Peach wrote:

You could add this to vfs_cacheprime, and just have an option that
determines whether it does a readahead (ie. I/O hint) or an actual
read(2).

I await your patch :-).

I knew you were going to say that!
Sure, but 2 modules that do *almost* the same thing is just confusing.

I don't think they do. readahead is built around
this one syscall on Linux. It's not the same as
cacheprime - cacheprime reads from the start of
the file, readahead triggers on every pread/sendfile
request that matches offset MOD readahead_offset.

They're not *exactly* the same, but they are mostly the same. The difference is quite subtle. This patch should resolve the differences:

Index: SAMBA_3_0/source/modules/vfs_cacheprime.c
===================================================================
--- SAMBA_3_0/source/modules/vfs_cacheprime.c   (revision 22132)
+++ SAMBA_3_0/source/modules/vfs_cacheprime.c   (working copy)
@@ -1,5 +1,6 @@
/*
- * Copyright (c) James Peach 2005-2006
+ * Copyright (c) James Peach 2005-2007
+ * Copyright (c) Jeremy Allison 2007
  *
* This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by
@@ -31,6 +32,14 @@
* cacheprime:rsize Amount of readahead in bytes. This should be a
  *                          multiple of the RAID stripe width.
  *      cacheprime:debug    Debug level at which to emit messages.
+ *      cacheprime:force alignment
+ * Force all I/O to be aligned to an rsize boundary. + * If this is false, we simply issue a readahead on
+ *                          each rsize boundary.
+ *
+ * To configure for Vista:
+ *      cacheprime:rsize = 0x80000
+ *      cacheprime:force alignment = no
  */
#define READAHEAD_MIN       (128 * 1024)        /* min is 128 KiB */
@@ -41,7 +50,38 @@
static int module_debug;
static ssize_t g_readsz = 0;
static void * g_readbuf = NULL;
+static BOOL g_forcealign = False;
+static void sys_readahead(int fd, SMB_OFF_T offset, SMB_OFF_T len)
+{
+        static BOOL didmsg = False;
+        int err;
+
+#if defined(HAVE_LINUX_READAHEAD)
+               err = readahead(fromfd, offset, (size_t)rhd->len);
+
+ DEBUG(10,("%s: readahead on fd %u, offset %llu, len %u returned %d \n",
+                MODULE,
+                       (unsigned int)fromfd,
+                       (unsigned long long)offset,
+                       (unsigned int)rhd->len,
+                       err ));
+#elif defined(HAVE_POSIX_FADVISE)
+ err = posix_fadvise(fromfd, offset, (off_t)rhd->len, POSIX_FADV_WILLNEED); + DEBUG(10,("%s: posix_fadvise on fd %u, offset %llu, len %u returned %d\n",
+            MODULE,
+                       (unsigned int)fromfd,
+                       (unsigned long long)offset,
+                       (unsigned int)rhd->len,
+                       err ));
+#else
+               if (!didmsg) {
+                       DEBUG(0,("%s: no readahead on this platform\n", 
MODULE));
+                       didmsg = True;
+               }
+#endif
+}
+
/* Prime the kernel buffer cache with data from the specified file. We use * per-fsp data to make sure we only ever do this once. If pread is being
  * emulated by seek/read/seek, when this will suck quite a lot.
@@ -71,15 +111,20 @@
             return False;
         }
-        DEBUG(module_debug,
-            ("%s: doing readahead of %lld bytes at %lld for %s\n",
-            MODULE, (long long)g_readsz, (long long)*last,
-            fsp->fsp_name));
+        if (g_forcealign) {
+                DEBUG(module_debug,
+ ("%s: doing readahead of %lld bytes at %lld for % s\n",
+                    MODULE, (long long)g_readsz, (long long)*last,
+                    fsp->fsp_name));
-        nread = sys_pread(fd, g_readbuf, g_readsz, *last);
-        if (nread < 0) {
-            *last = -1;
-            return False;
+                nread = sys_pread(fd, g_readbuf, g_readsz, *last);
+                if (nread < 0) {
+                    *last = -1;
+                    return False;
+                }
+        } else {
+                sys_readahead(fd, *last, g_readsz);
+                nread += g_readsz;
         }
         *last += nread;
@@ -103,6 +148,9 @@
g_readsz = conv_str_size(lp_parm_const_string(SNUM(handle- >conn),
                                         MODULE, "rsize", NULL));
+        g_forcealign = lp_parm_bool(SNUM(handle->conn), MODULE,
+                            "force alignment", False);
+
         if (g_readsz < READAHEAD_MIN) {
                 DEBUG(module_debug, ("%s: %ld bytes of readahead "
                             "requested, using minimum of %u\n",
@@ -115,9 +163,11 @@
                 g_readsz = READAHEAD_MAX;
         }
-        if ((g_readbuf = SMB_MALLOC(g_readsz)) == NULL) {
-                /* Turn off readahead if we can't get a buffer. */
-                g_readsz = 0;
+        if (g_forcealign == True) {
+                if ((g_readbuf = SMB_MALLOC(g_readsz)) == NULL) {
+ /* Turn off readahead if we can't get a buffer. */
+                        g_readsz = 0;
+                }
         }
         return SMB_VFS_NEXT_CONNECT(handle, service, user);



--
James Peach | [EMAIL PROTECTED]


Reply via email to