diff options
author | Jeremy Allison <jra@samba.org> | 2005-10-19 20:02:12 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 11:05:06 -0500 |
commit | c6aea6ef2d97982263b1652b7c186df269bf0de6 (patch) | |
tree | 3b56fedaf2c5107945724005d9d16cb03438ff7e /source3/smbd | |
parent | ad93243f2399c2f349434dbbb33ed3766a817a8d (diff) | |
download | samba-c6aea6ef2d97982263b1652b7c186df269bf0de6.tar.gz samba-c6aea6ef2d97982263b1652b7c186df269bf0de6.tar.bz2 samba-c6aea6ef2d97982263b1652b7c186df269bf0de6.zip |
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)
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/dfree.c | 63 | ||||
-rw-r--r-- | source3/smbd/vfs-wrap.c | 2 |
2 files changed, 54 insertions, 11 deletions
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; } |