From c6aea6ef2d97982263b1652b7c186df269bf0de6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 19 Oct 2005 20:02:12 +0000 Subject: r11190: Fix enhancement request #3192. This does 2 things. 1). Makes dfree command a per-share parameter (it should be anyway IMHO). 2). Adds a "dfree cache time" parameter in seconds that specifies how long a dfree command output should be cached for. Default is zero (no caching). Jeremy. (This used to be commit 49ef8b88a3e12883148eb28d8e86fb07dbc3d12d) --- source3/smbd/dfree.c | 63 +++++++++++++++++++++++++++++++++++++++++-------- source3/smbd/vfs-wrap.c | 2 +- 2 files changed, 54 insertions(+), 11 deletions(-) (limited to 'source3/smbd') diff --git a/source3/smbd/dfree.c b/source3/smbd/dfree.c index 81a48b94fc..dad7d917e8 100644 --- a/source3/smbd/dfree.c +++ b/source3/smbd/dfree.c @@ -21,8 +21,9 @@ #include "includes.h" /**************************************************************************** -normalise for DOS usage + Normalise for DOS usage. ****************************************************************************/ + static void disk_norm(BOOL small_query, SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize) { /* check if the disk is beyond the max disk size */ @@ -59,17 +60,17 @@ static void disk_norm(BOOL small_query, SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree, /**************************************************************************** - return number of 1K blocks available on a path and total number + Return number of 1K blocks available on a path and total number. ****************************************************************************/ -static SMB_BIG_UINT disk_free(const char *path, BOOL small_query, +SMB_BIG_UINT sys_disk_free(connection_struct *conn, const char *path, BOOL small_query, SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize) { int dfree_retval; SMB_BIG_UINT dfree_q = 0; SMB_BIG_UINT bsize_q = 0; SMB_BIG_UINT dsize_q = 0; - char *dfree_command; + const char *dfree_command; (*dfree) = (*dsize) = 0; (*bsize) = 512; @@ -78,7 +79,7 @@ static SMB_BIG_UINT disk_free(const char *path, BOOL small_query, * If external disk calculation specified, use it. */ - dfree_command = lp_dfree_command(); + dfree_command = lp_dfree_command(SNUM(conn)); if (dfree_command && *dfree_command) { const char *p; char **lines; @@ -162,12 +163,54 @@ static SMB_BIG_UINT disk_free(const char *path, BOOL small_query, return(dfree_retval); } - /**************************************************************************** -wrap it to get filenames right + Potentially returned cached dfree info. ****************************************************************************/ -SMB_BIG_UINT sys_disk_free(const char *path, BOOL small_query, - SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize) + +SMB_BIG_UINT get_dfree_info(connection_struct *conn, + const char *path, + BOOL small_query, + SMB_BIG_UINT *bsize, + SMB_BIG_UINT *dfree, + SMB_BIG_UINT *dsize) { - return disk_free(path,small_query, bsize,dfree,dsize); + int dfree_cache_time = lp_dfree_cache_time(SNUM(conn)); + struct dfree_cached_info *dfc = conn->dfree_info; + SMB_BIG_UINT dfree_ret; + + if (!dfree_cache_time) { + return SMB_VFS_DISK_FREE(conn,path,small_query,bsize,dfree,dsize); + } + + if (dfc && (conn->lastused - dfc->last_dfree_time < dfree_cache_time)) { + /* Return cached info. */ + *bsize = dfc->bsize; + *dfree = dfc->dfree; + *dsize = dfc->dsize; + return dfc->dfree_ret; + } + + dfree_ret = SMB_VFS_DISK_FREE(conn,path,small_query,bsize,dfree,dsize); + + if (dfree_ret == (SMB_BIG_UINT)-1) { + /* Don't cache bad data. */ + return dfree_ret; + } + + /* No cached info or time to refresh. */ + if (!dfc) { + dfc = TALLOC_P(conn->mem_ctx, struct dfree_cached_info); + if (!dfc) { + return dfree_ret; + } + conn->dfree_info = dfc; + } + + dfc->bsize = *bsize; + dfc->dfree = *dfree; + dfc->dsize = *dsize; + dfc->dfree_ret = dfree_ret; + dfc->last_dfree_time = conn->lastused; + + return dfree_ret; } diff --git a/source3/smbd/vfs-wrap.c b/source3/smbd/vfs-wrap.c index 9ae1592a8e..c203af0c55 100644 --- a/source3/smbd/vfs-wrap.c +++ b/source3/smbd/vfs-wrap.c @@ -46,7 +46,7 @@ SMB_BIG_UINT vfswrap_disk_free(vfs_handle_struct *handle, connection_struct *con { SMB_BIG_UINT result; - result = sys_disk_free(path, small_query, bsize, dfree, dsize); + result = sys_disk_free(conn, path, small_query, bsize, dfree, dsize); return result; } -- cgit