00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "includes.h"
00022
00023
00024
00025
00026
00027 static void disk_norm(BOOL small_query, SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
00028 {
00029
00030 SMB_BIG_UINT maxdisksize = lp_maxdisksize();
00031 if (maxdisksize) {
00032
00033 maxdisksize = ((maxdisksize*1024)/(*bsize))*1024;
00034 if (*dsize > maxdisksize) *dsize = maxdisksize;
00035 if (*dfree > maxdisksize) *dfree = maxdisksize-1;
00036
00037
00038 }
00039
00040 if(small_query) {
00041 while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512) {
00042 *dfree /= 2;
00043 *dsize /= 2;
00044 *bsize *= 2;
00045
00046
00047
00048 if (*bsize > (WORDMAX*512)) {
00049 *bsize = (WORDMAX*512);
00050 if (*dsize > WORDMAX)
00051 *dsize = WORDMAX;
00052 if (*dfree > WORDMAX)
00053 *dfree = WORDMAX;
00054 break;
00055 }
00056 }
00057 }
00058 }
00059
00060
00061
00062
00063
00064
00065
00066 SMB_BIG_UINT sys_disk_free(connection_struct *conn, const char *path, BOOL small_query,
00067 SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
00068 {
00069 SMB_BIG_UINT dfree_retval;
00070 SMB_BIG_UINT dfree_q = 0;
00071 SMB_BIG_UINT bsize_q = 0;
00072 SMB_BIG_UINT dsize_q = 0;
00073 const char *dfree_command;
00074
00075 (*dfree) = (*dsize) = 0;
00076 (*bsize) = 512;
00077
00078
00079
00080
00081
00082 dfree_command = lp_dfree_command(SNUM(conn));
00083 if (dfree_command && *dfree_command) {
00084 const char *p;
00085 char **lines;
00086 pstring syscmd;
00087
00088 slprintf(syscmd, sizeof(syscmd)-1, "%s %s", dfree_command, path);
00089 DEBUG (3, ("disk_free: Running command %s\n", syscmd));
00090
00091 lines = file_lines_pload(syscmd, NULL);
00092 if (lines) {
00093 char *line = lines[0];
00094
00095 DEBUG (3, ("Read input from dfree, \"%s\"\n", line));
00096
00097 *dsize = STR_TO_SMB_BIG_UINT(line, &p);
00098 while (p && *p && isspace(*p))
00099 p++;
00100 if (p && *p)
00101 *dfree = STR_TO_SMB_BIG_UINT(p, &p);
00102 while (p && *p && isspace(*p))
00103 p++;
00104 if (p && *p)
00105 *bsize = STR_TO_SMB_BIG_UINT(p, NULL);
00106 else
00107 *bsize = 1024;
00108 file_lines_free(lines);
00109 DEBUG (3, ("Parsed output of dfree, dsize=%u, dfree=%u, bsize=%u\n",
00110 (unsigned int)*dsize, (unsigned int)*dfree, (unsigned int)*bsize));
00111
00112 if (!*dsize)
00113 *dsize = 2048;
00114 if (!*dfree)
00115 *dfree = 1024;
00116 } else {
00117 DEBUG (0, ("disk_free: sys_popen() failed for command %s. Error was : %s\n",
00118 syscmd, strerror(errno) ));
00119 if (sys_fsusage(path, dfree, dsize) != 0) {
00120 DEBUG (0, ("disk_free: sys_fsusage() failed. Error was : %s\n",
00121 strerror(errno) ));
00122 return (SMB_BIG_UINT)-1;
00123 }
00124 }
00125 } else {
00126 if (sys_fsusage(path, dfree, dsize) != 0) {
00127 DEBUG (0, ("disk_free: sys_fsusage() failed. Error was : %s\n",
00128 strerror(errno) ));
00129 return (SMB_BIG_UINT)-1;
00130 }
00131 }
00132
00133 if (disk_quotas(path, &bsize_q, &dfree_q, &dsize_q)) {
00134 (*bsize) = bsize_q;
00135 (*dfree) = MIN(*dfree,dfree_q);
00136 (*dsize) = MIN(*dsize,dsize_q);
00137 }
00138
00139
00140 if (*bsize < 256) {
00141 DEBUG(5,("disk_free:Warning: bsize == %d < 256 . Changing to assumed correct bsize = 512\n",(int)*bsize));
00142 *bsize = 512;
00143 }
00144
00145 if ((*dsize)<1) {
00146 static int done;
00147 if (!done) {
00148 DEBUG(0,("WARNING: dfree is broken on this system\n"));
00149 done=1;
00150 }
00151 *dsize = 20*1024*1024/(*bsize);
00152 *dfree = MAX(1,*dfree);
00153 }
00154
00155 disk_norm(small_query,bsize,dfree,dsize);
00156
00157 if ((*bsize) < 1024) {
00158 dfree_retval = (*dfree)/(1024/(*bsize));
00159 } else {
00160 dfree_retval = ((*bsize)/1024)*(*dfree);
00161 }
00162
00163 return(dfree_retval);
00164 }
00165
00166
00167
00168
00169
00170 SMB_BIG_UINT get_dfree_info(connection_struct *conn,
00171 const char *path,
00172 BOOL small_query,
00173 SMB_BIG_UINT *bsize,
00174 SMB_BIG_UINT *dfree,
00175 SMB_BIG_UINT *dsize)
00176 {
00177 int dfree_cache_time = lp_dfree_cache_time(SNUM(conn));
00178 struct dfree_cached_info *dfc = conn->dfree_info;
00179 SMB_BIG_UINT dfree_ret;
00180
00181 if (!dfree_cache_time) {
00182 return SMB_VFS_DISK_FREE(conn,path,small_query,bsize,dfree,dsize);
00183 }
00184
00185 if (dfc && (conn->lastused - dfc->last_dfree_time < dfree_cache_time)) {
00186
00187 *bsize = dfc->bsize;
00188 *dfree = dfc->dfree;
00189 *dsize = dfc->dsize;
00190 return dfc->dfree_ret;
00191 }
00192
00193 dfree_ret = SMB_VFS_DISK_FREE(conn,path,small_query,bsize,dfree,dsize);
00194
00195 if (dfree_ret == (SMB_BIG_UINT)-1) {
00196
00197 return dfree_ret;
00198 }
00199
00200
00201 if (!dfc) {
00202 dfc = TALLOC_P(conn->mem_ctx, struct dfree_cached_info);
00203 if (!dfc) {
00204 return dfree_ret;
00205 }
00206 conn->dfree_info = dfc;
00207 }
00208
00209 dfc->bsize = *bsize;
00210 dfc->dfree = *dfree;
00211 dfc->dsize = *dsize;
00212 dfc->dfree_ret = dfree_ret;
00213 dfc->last_dfree_time = conn->lastused;
00214
00215 return dfree_ret;
00216 }