r22132: I hate inefficiency. Don't call conv_str_size()
authorJeremy Allison <jra@samba.org>
Sun, 8 Apr 2007 19:41:47 +0000 (19:41 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:19:15 +0000 (12:19 -0500)
on every pread/sendfile call, initialize these
variables in an allocated struct at connection
time and just refer to them directly.
Jeremy.
(This used to be commit 85df3fca681a44c882f596ef042ad9956c3a63c0)

source3/modules/vfs_readahead.c
source3/smbd/vfs.c

index 2663326c994f209e73b8a75d19cc529bf78e7319..550562d03d08d15c40ab6539baea0fd7ea940204 100644 (file)
 static BOOL didmsg;
 #endif
 
+struct readahead_data {
+       SMB_OFF_T off_bound;
+       SMB_OFF_T len;
+       BOOL didmsg;
+};
+
 /* 
  * This module copes with Vista AIO read requests on Linux
  * by detecting the initial 0x80000 boundary reads and causing
  * the buffer cache to be filled in advance.
  */
 
-static unsigned long get_offset_boundary(struct vfs_handle_struct *handle)
-{
-       SMB_OFF_T off_bound = conv_str_size(lp_parm_const_string(SNUM(handle->conn),
-                                               "readahead",
-                                               "offset",
-                                               NULL));
-       if (off_bound == 0) {
-               off_bound = 0x80000;
-       }
-       return (unsigned long)off_bound;
-}
-
-static unsigned long get_offset_length(struct vfs_handle_struct *handle, unsigned long def_val)
-{
-       SMB_OFF_T len = conv_str_size(lp_parm_const_string(SNUM(handle->conn),
-                                               "readahead",
-                                               "length",
-                                               NULL));
-       if (len == 0) {
-               len = def_val;
-       }
-       return (unsigned long)len;
-}
+/*******************************************************************
+ sendfile wrapper that does readahead/posix_fadvise.
+*******************************************************************/
 
 static ssize_t readahead_sendfile(struct vfs_handle_struct *handle,
                                        int tofd,
@@ -60,27 +46,27 @@ static ssize_t readahead_sendfile(struct vfs_handle_struct *handle,
                                        SMB_OFF_T offset,
                                        size_t count)
 {
-       unsigned long off_bound = get_offset_boundary(handle);
-       if ( offset % off_bound == 0) {
-               unsigned long len = get_offset_length(handle, off_bound);
+       struct readahead_data *rhd = (struct readahead_data *)handle->data;
+
+       if ( offset % rhd->off_bound == 0) {
 #if defined(HAVE_LINUX_READAHEAD)
-               int err = readahead(fromfd, offset, (size_t)len);
+               int err = readahead(fromfd, offset, (size_t)rhd->len);
                DEBUG(10,("readahead_sendfile: readahead on fd %u, offset %llu, len %u returned %d\n",
                        (unsigned int)fromfd,
                        (unsigned long long)offset,
-                       (unsigned int)len,
+                       (unsigned int)rhd->len,
                        err ));
 #elif defined(HAVE_POSIX_FADVISE)
-               int err = posix_fadvise(fromfd, offset, (off_t)len, POSIX_FADV_WILLNEED);
+               int err = posix_fadvise(fromfd, offset, (off_t)rhd->len, POSIX_FADV_WILLNEED);
                DEBUG(10,("readahead_sendfile: posix_fadvise on fd %u, offset %llu, len %u returned %d\n",
                        (unsigned int)fromfd,
                        (unsigned long long)offset,
-                       (unsigned int)len,
+                       (unsigned int)rhd->len,
                        err ));
 #else
-               if (!didmsg) {
+               if (!rhd->didmsg) {
                        DEBUG(0,("readahead_sendfile: no readahead on this platform\n"));
-                       didmsg = True;
+                       rhd->didmsg = True;
                }
 #endif
        }
@@ -93,6 +79,10 @@ static ssize_t readahead_sendfile(struct vfs_handle_struct *handle,
                                        count);
 }
 
+/*******************************************************************
+ pread wrapper that does readahead/posix_fadvise.
+*******************************************************************/
+
 static ssize_t readahead_pread(vfs_handle_struct *handle,
                                files_struct *fsp,
                                int fd,
@@ -100,40 +90,97 @@ static ssize_t readahead_pread(vfs_handle_struct *handle,
                                size_t count,
                                SMB_OFF_T offset)
 {
-       unsigned long off_bound = get_offset_boundary(handle);
-       if ( offset % off_bound == 0) {
-               unsigned long len = get_offset_length(handle, off_bound);
+       struct readahead_data *rhd = (struct readahead_data *)handle->data;
+
+       if ( offset % rhd->off_bound == 0) {
 #if defined(HAVE_LINUX_READAHEAD)
-               int err = readahead(fd, offset, (size_t)len);
+               int err = readahead(fd, offset, (size_t)rhd->len);
                DEBUG(10,("readahead_pread: readahead on fd %u, offset %llu, len %u returned %d\n",
                        (unsigned int)fd,
                        (unsigned long long)offset,
-                       (unsigned int)len,
+                       (unsigned int)rhd->len,
                        err ));
 #elif defined(HAVE_POSIX_FADVISE)
-               int err = posix_fadvise(fromfd, offset, (off_t)len, POSIX_FADV_WILLNEED);
+               int err = posix_fadvise(fromfd, offset, (off_t)rhd->len, POSIX_FADV_WILLNEED);
                DEBUG(10,("readahead_pread: posix_fadvise on fd %u, offset %llu, len %u returned %d\n",
                        (unsigned int)fd,
                        (unsigned long long)offset,
-                       (unsigned int)len,
+                       (unsigned int)rhd->len,
                        (err ));
 #else
-               if (!didmsg) {
+               if (!rhd->didmsg) {
                        DEBUG(0,("readahead_pread: no readahead on this platform\n"));
-                       didmsg = True;
+                       rhd->didmsg = True;
                }
 #endif
         }
         return SMB_VFS_NEXT_PREAD(handle, fsp, fd, data, count, offset);
 }
 
+/*******************************************************************
+ Directly called from main smbd when freeing handle.
+*******************************************************************/
+
+static void free_readahead_data(void **pptr)
+{
+       SAFE_FREE(*pptr);
+}
+
+/*******************************************************************
+ Allocate the handle specific data so we don't call the expensive
+ conv_str_size function for each sendfile/pread.
+*******************************************************************/
+
+static int readahead_connect(struct vfs_handle_struct *handle,
+                               const char *service,
+                               const char *user)
+{
+       struct readahead_data *rhd = SMB_MALLOC_P(struct readahead_data);
+       if (!rhd) {
+               DEBUG(0,("readahead_connect: out of memory\n"));
+               return -1;
+       }
+       ZERO_STRUCTP(rhd);
+
+       rhd->didmsg = False;
+       rhd->off_bound = conv_str_size(lp_parm_const_string(SNUM(handle->conn),
+                                               "readahead",
+                                               "offset",
+                                               NULL));
+       if (rhd->off_bound == 0) {
+               rhd->off_bound = 0x80000;
+       }
+       rhd->len = conv_str_size(lp_parm_const_string(SNUM(handle->conn),
+                                               "readahead",
+                                               "length",
+                                               NULL));
+       if (rhd->len == 0) {
+               rhd->len = rhd->off_bound;
+       }
+
+       handle->data = (void *)rhd;
+       handle->free_data = free_readahead_data;
+       return 0;
+}
+
+/*******************************************************************
+ Functions we're replacing.
+ We don't replace read as it isn't used from smbd to read file
+ data.
+*******************************************************************/
+
 static vfs_op_tuple readahead_ops [] =
 {
        {SMB_VFS_OP(readahead_sendfile), SMB_VFS_OP_SENDFILE, SMB_VFS_LAYER_TRANSPARENT},
        {SMB_VFS_OP(readahead_pread), SMB_VFS_OP_PREAD, SMB_VFS_LAYER_TRANSPARENT},
+        {SMB_VFS_OP(readahead_connect), SMB_VFS_OP_CONNECT,  SMB_VFS_LAYER_TRANSPARENT},
        {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
 };
 
+/*******************************************************************
+ Module initialization boilerplate.
+*******************************************************************/
+
 NTSTATUS vfs_readahead_init(void);
 NTSTATUS vfs_readahead_init(void)
 {
index 82ea602187c0eb95241db46d944863f526a2424b..0803ffb7e7017a210e187b507bab8e77555c8c13 100644 (file)
@@ -174,7 +174,7 @@ BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object)
                DEBUG(5, ("Checking operation #%d (type %d, layer %d)\n", i, ops[i].type, ops[i].layer));
                if(ops[i].layer == SMB_VFS_LAYER_OPAQUE) {
                        /* If this operation was already made opaque by different module, it
-                        * will be overridded here.
+                        * will be overridden here.
                         */
                        DEBUGADD(5, ("Making operation type %d opaque [module %s]\n", ops[i].type, vfs_object));
                        vfs_set_operation(&conn->vfs_opaque, ops[i].type, handle, ops[i].op);