PATCH samba cache and read-ahead

Amin Azez azez at ufomechanic.net
Mon Nov 12 14:24:20 GMT 2007


Attached is proof-of-concept caching and read-ahead for Samba to
optimize WAN scenarios.
It applies to Friday's SVN.
They are distributed here under GPL3

The proof of concept provides extra functionality to the cifs proxy.

Read-ahead
========

It supports configurable read-ahead.

In a simple scenario where only one proxy is used on the client side of
the WAN, if the read-ahead window is a little more than the WAN
bandwidth multiplied by the round-trip time, then the WAN link should be
fully utilized. On a 100ms RTT WAN link, this can reduce the time to
load a large file by 25%; and even better when there is higher latency.

Caching
=====

It supports simple caching when an op-lock is obtained, intended to
manage better caching than the client might, but the caching is
currently a bit simple, supporting only a linear extent from offset zero.

Compression
========

Where there is a proxy on both sides of the WAN it can also negotiate
compression, which combined with read-ahead can reduce time to load a
big file to 25% of normal, if the file compresses at around 25%.

Cache-revalidation
============

There is also basic cache-revalidation if there is an existing cache
file, where the client proxy can provide a md5 checksum of what is in
the cache as part of a read-request, and the server proxy just confirms
this. Currently re-validation is done as compressible read-ahead, which
means the client cannot gauge downstream bandwidth usage better than it
can guess cache-hits, so I think I must introduce a streaming
revalidation where the server sends unsolicited updates based on the
compressed response size.


A pre-cached 10MB file 25% compressible took:

Normal: 470 seconds
read-ahead: 367 seconds
zlib + read-ahead: 97 seconds
zlib + read-ahead+cache-validation: 9 seconds

or down to around 2% of the transfer time.

The code is ugly; I'm still working out which layers of Samba I should
be tainting.

Mapping generic operations
===================

I had some trouble with cvfs; CIFS_MAP_GENERIC_DEFAULT was set to false
yet all the handler functions were written assuming it was true, but
also, having a union to hold the different smb_read structs turned out
to be less helpful than it first seemed.

I tried adding some extra accessor macros in interfaces.h but I find the
whole thing unsatisfactory. I've been toying with generics of various
kinds, including multiple invocations of the C pre-processor on
vfs_cifs.c so we can write the function once but implement it for all
the various smb_read structs involved. Anybody think it might be nicer
to consider converting to vala? Me neither but I don't like managing
this hard work be hand. Passing round a union* in this fashion is as bad
as passing round a void* except we don't get the compiler warnings. I
think the void* would make me feel happier as we could cast it with a
protective macro that checked the level, what we have now is plain
dangerous.

New operations
==========

I defined a SAMBA wire-protocol operation SMBreadMagic but it's
currently really just SMBreadx with compression support added. I'm
agreed that a new operation needed adding here, but I'm not totally
certain that I needed a new samba-level operation SMB_READ_CACHE. It's
so similar to SMB_READ_READX that the code that handles it is nearly the
same, only can't quite be because they use different members of the
smb_read union (bah!) and I don't think much of my accessor macros.

Advertising capabilities
================

I also took the liberty of:
#define CAP_CACHE              0x00100000

so client and server could tell if they supported the caching and
compression stuff. I'm not sure about this being the best way, I don't
feel good stealing one of these bits, maybe we need an
extra_capabilities field to use when talking to samba servers?

smb.conf
======

The smb.conf file has to look something like this:

[myshare-8]
        ntvfs handler = cifs
        cifs:server = 10.0.0.5
        cifs:share = myshare
        cifs:cache-enabled = FALSE
        cifs:cache-readahead = 8192
        # I think these next two are not used, now we have MAGIC_CA
        cifs:server-compression = FALSE
        cifs:client-compression = TRUE

        cifs:user = USERNAME
        cifs:password = PASSWORD
        cifs:domain = DOMAIN


I'm now trying to find out how to get the cifs-proxy to proxy the
connecting users credentials. Any help would be appreciated.

Sam
-------------- next part --------------
A non-text attachment was scrubbed...
Name: samba_cache.patch
Type: text/x-patch
Size: 80112 bytes
Desc: not available
Url : http://lists.samba.org/archive/samba-technical/attachments/20071112/aed2d772/samba_cache.bin


More information about the samba-technical mailing list