The branch, master has been updated via 41c4666 s3/vfs: remove unused SMB_VFS_DISK_FREE() small_query parameter via 4ab0e57 smbd/reply: convert free space to 16bit in dskattr handler from 2501afe vfs_ceph: fix disk_free_fn callback
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 41c4666a726d3fbe234bcb8b38bd24c62799598f Author: David Disseldorp <dd...@samba.org> Date: Mon Feb 16 19:26:24 2015 +0100 s3/vfs: remove unused SMB_VFS_DISK_FREE() small_query parameter The small_query parameter for SMB_VFS_DISK_FREE() was, prior to the previous commit, used to obtain 16-bit wide free-space information for the deprecated dskattr SMB_COM_QUERY_INFORMATION_DISK command. With the dskattr handler now performing the 16-bit collapse directly, the small_query parameter can be removed from the entire code path. Signed-off-by: David Disseldorp <dd...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Tue Feb 17 05:37:20 CET 2015 on sn-devel-104 commit 4ab0e57f1073e776b8832f5edc3dca04ef903fef Author: David Disseldorp <dd...@samba.org> Date: Mon Feb 16 19:26:23 2015 +0100 smbd/reply: convert free space to 16bit in dskattr handler The deprecated Core Protocol dskattr SMB_COM_QUERY_INFORMATION_DISK command provides free space information in the form of 16-bit words. Until now, this has been handled by passing the dskattr specific small_query boolean through to disk_norm() via the SMB_VFS_DISK_FREE VFS hook. disk_norm(small_query=true) then modifies the block size and free space values such that they fit in the 16-bit field. This change adds the command specific logic to the dskattr handler, so that it can be removed from the SMB_VFS_DISK_FREE()->disk_norm() code path. In doing so, it fixes dskattr request handling against opaque VFS backends that don't call disk_norm(), such as vfs_glusterfs. Signed-off-by: David Disseldorp <dd...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> ----------------------------------------------------------------------- Summary of changes: examples/VFS/skel_opaque.c | 2 +- examples/VFS/skel_transparent.c | 5 ++--- source3/include/vfs.h | 10 +++++----- source3/include/vfs_macros.h | 8 ++++---- source3/modules/vfs_cap.c | 6 ++---- source3/modules/vfs_ceph.c | 11 ++++++----- source3/modules/vfs_default.c | 11 ++++++----- source3/modules/vfs_full_audit.c | 6 ++---- source3/modules/vfs_glusterfs.c | 5 ++--- source3/modules/vfs_gpfs.c | 10 +++++----- source3/modules/vfs_shadow_copy2.c | 10 ++++------ source3/modules/vfs_snapper.c | 10 ++++------ source3/modules/vfs_time_audit.c | 6 ++---- source3/smbd/dfree.c | 40 ++++++++++++-------------------------- source3/smbd/proto.h | 5 ++--- source3/smbd/reply.c | 21 +++++++++++++++++++- source3/smbd/trans2.c | 13 ++++++++++--- source3/smbd/vfs.c | 10 ++++------ source3/torture/cmd_vfs.c | 2 +- 19 files changed, 94 insertions(+), 97 deletions(-) Changeset truncated at 500 lines: diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index b52c381..2a53c8a 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -45,7 +45,7 @@ static void skel_disconnect(vfs_handle_struct *handle) } static uint64_t skel_disk_free(vfs_handle_struct *handle, const char *path, - bool small_query, uint64_t *bsize, + uint64_t *bsize, uint64_t *dfree, uint64_t *dsize) { *bsize = 0; diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index 925e520..eb561db 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -49,11 +49,10 @@ static void skel_disconnect(vfs_handle_struct *handle) } static uint64_t skel_disk_free(vfs_handle_struct *handle, const char *path, - bool small_query, uint64_t *bsize, + uint64_t *bsize, uint64_t *dfree, uint64_t *dsize) { - return SMB_VFS_NEXT_DISK_FREE(handle, path, small_query, bsize, - dfree, dsize); + return SMB_VFS_NEXT_DISK_FREE(handle, path, bsize, dfree, dsize); } static int skel_get_quota(vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, diff --git a/source3/include/vfs.h b/source3/include/vfs.h index 1843ef4..3444f62 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -160,7 +160,8 @@ /* Version 32 - Add "lease" to CREATE_FILE operation */ /* Version 32 - Add "lease" to struct files_struct */ /* Version 32 - Add SMB_VFS_READDIR_ATTR() */ -/* Version 32 - Add in and our create context blobs to create_file */ +/* Version 32 - Add in and out create context blobs to create_file */ +/* Version 32 - Remove unnecessary SMB_VFS_DISK_FREE() small_query parameter */ #define SMB_VFS_INTERFACE_VERSION 32 @@ -503,7 +504,7 @@ struct vfs_fn_pointers { int (*connect_fn)(struct vfs_handle_struct *handle, const char *service, const char *user); void (*disconnect_fn)(struct vfs_handle_struct *handle); - uint64_t (*disk_free_fn)(struct vfs_handle_struct *handle, const char *path, bool small_query, uint64_t *bsize, + uint64_t (*disk_free_fn)(struct vfs_handle_struct *handle, const char *path, uint64_t *bsize, uint64_t *dfree, uint64_t *dsize); int (*get_quota_fn)(struct vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt); int (*set_quota_fn)(struct vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt); @@ -903,9 +904,8 @@ int smb_vfs_call_connect(struct vfs_handle_struct *handle, const char *service, const char *user); void smb_vfs_call_disconnect(struct vfs_handle_struct *handle); uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle, - const char *path, bool small_query, - uint64_t *bsize, uint64_t *dfree, - uint64_t *dsize); + const char *path, uint64_t *bsize, + uint64_t *dfree, uint64_t *dsize); int smb_vfs_call_get_quota(struct vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt); diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h index ef97b49..0cc442e 100644 --- a/source3/include/vfs_macros.h +++ b/source3/include/vfs_macros.h @@ -39,10 +39,10 @@ #define SMB_VFS_NEXT_DISCONNECT(handle) \ smb_vfs_call_disconnect((handle)->next) -#define SMB_VFS_DISK_FREE(conn, path, small_query, bsize, dfree ,dsize) \ - smb_vfs_call_disk_free((conn)->vfs_handles, (path), (small_query), (bsize), (dfree), (dsize)) -#define SMB_VFS_NEXT_DISK_FREE(handle, path, small_query, bsize, dfree ,dsize)\ - smb_vfs_call_disk_free((handle)->next, (path), (small_query), (bsize), (dfree), (dsize)) +#define SMB_VFS_DISK_FREE(conn, path, bsize, dfree ,dsize) \ + smb_vfs_call_disk_free((conn)->vfs_handles, (path), (bsize), (dfree), (dsize)) +#define SMB_VFS_NEXT_DISK_FREE(handle, path, bsize, dfree ,dsize)\ + smb_vfs_call_disk_free((handle)->next, (path), (bsize), (dfree), (dsize)) #define SMB_VFS_GET_QUOTA(conn, qtype, id, qt) \ smb_vfs_call_get_quota((conn)->vfs_handles, (qtype), (id), (qt)) diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c index c52e30c..980010b 100644 --- a/source3/modules/vfs_cap.c +++ b/source3/modules/vfs_cap.c @@ -30,8 +30,7 @@ static char *capencode(TALLOC_CTX *ctx, const char *from); static char *capdecode(TALLOC_CTX *ctx, const char *from); static uint64_t cap_disk_free(vfs_handle_struct *handle, const char *path, - bool small_query, uint64_t *bsize, - uint64_t *dfree, uint64_t *dsize) + uint64_t *bsize, uint64_t *dfree, uint64_t *dsize) { char *cappath = capencode(talloc_tos(), path); @@ -39,8 +38,7 @@ static uint64_t cap_disk_free(vfs_handle_struct *handle, const char *path, errno = ENOMEM; return (uint64_t)-1; } - return SMB_VFS_NEXT_DISK_FREE(handle, cappath, small_query, bsize, - dfree, dsize); + return SMB_VFS_NEXT_DISK_FREE(handle, cappath, bsize, dfree, dsize); } static DIR *cap_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr) diff --git a/source3/modules/vfs_ceph.c b/source3/modules/vfs_ceph.c index b074e2d..0967428 100644 --- a/source3/modules/vfs_ceph.c +++ b/source3/modules/vfs_ceph.c @@ -156,8 +156,9 @@ static void cephwrap_disconnect(struct vfs_handle_struct *handle) /* Disk operations */ -static uint64_t cephwrap_disk_free(struct vfs_handle_struct *handle, const char *path, bool small_query, uint64_t *bsize, - uint64_t *dfree, uint64_t *dsize) +static uint64_t cephwrap_disk_free(struct vfs_handle_struct *handle, + const char *path, uint64_t *bsize, + uint64_t *dfree, uint64_t *dsize) { struct statvfs statvfs_buf; int ret; @@ -169,7 +170,7 @@ static uint64_t cephwrap_disk_free(struct vfs_handle_struct *handle, const char *bsize = statvfs_buf.f_bsize; *dfree = statvfs_buf.f_bavail; *dsize = statvfs_buf.f_blocks; - disk_norm(small_query, bsize, dfree, dsize); + disk_norm(bsize, dfree, dsize); DEBUG(10, ("[CEPH] bsize: %llu, dfree: %llu, dsize: %llu\n", llu(*bsize), llu(*dfree), llu(*dsize))); return *dfree; @@ -808,8 +809,8 @@ static int strict_allocate_ftruncate(struct vfs_handle_struct *handle, files_str /* available disk space is enough or not? */ space_avail = get_dfree_info(fsp->conn, - fsp->fsp_name->base_name, false, - &bsize,&dfree,&dsize); + fsp->fsp_name->base_name, + &bsize, &dfree, &dsize); /* space_avail is 1k blocks */ if (space_avail == (uint64_t)-1 || ((uint64_t)space_to_write/1024 > space_avail) ) { diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 5a4a187..31648f6 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -54,12 +54,13 @@ static void vfswrap_disconnect(vfs_handle_struct *handle) /* Disk operations */ -static uint64_t vfswrap_disk_free(vfs_handle_struct *handle, const char *path, bool small_query, uint64_t *bsize, - uint64_t *dfree, uint64_t *dsize) +static uint64_t vfswrap_disk_free(vfs_handle_struct *handle, const char *path, + uint64_t *bsize, uint64_t *dfree, + uint64_t *dsize) { uint64_t result; - result = sys_disk_free(handle->conn, path, small_query, bsize, dfree, dsize); + result = sys_disk_free(handle->conn, path, bsize, dfree, dsize); return result; } @@ -1873,8 +1874,8 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs /* available disk space is enough or not? */ space_avail = get_dfree_info(fsp->conn, - fsp->fsp_name->base_name, false, - &bsize,&dfree,&dsize); + fsp->fsp_name->base_name, + &bsize, &dfree, &dsize); /* space_avail is 1k blocks */ if (space_avail == (uint64_t)-1 || ((uint64_t)space_to_write/1024 > space_avail) ) { diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index c5a9c0d..b7a4eee 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -647,14 +647,12 @@ static void smb_full_audit_disconnect(vfs_handle_struct *handle) } static uint64_t smb_full_audit_disk_free(vfs_handle_struct *handle, - const char *path, - bool small_query, uint64_t *bsize, + const char *path, uint64_t *bsize, uint64_t *dfree, uint64_t *dsize) { uint64_t result; - result = SMB_VFS_NEXT_DISK_FREE(handle, path, small_query, bsize, - dfree, dsize); + result = SMB_VFS_NEXT_DISK_FREE(handle, path, bsize, dfree, dsize); /* Don't have a reasonable notion of failure here */ diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c index e0cc85c..09c789c 100644 --- a/source3/modules/vfs_glusterfs.c +++ b/source3/modules/vfs_glusterfs.c @@ -271,9 +271,8 @@ static void vfs_gluster_disconnect(struct vfs_handle_struct *handle) } static uint64_t vfs_gluster_disk_free(struct vfs_handle_struct *handle, - const char *path, bool small_query, - uint64_t *bsize_p, uint64_t *dfree_p, - uint64_t *dsize_p) + const char *path, uint64_t *bsize_p, + uint64_t *dfree_p, uint64_t *dsize_p) { struct statvfs statvfs = { 0, }; int ret; diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 6ead65b..b71b57f 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -2030,7 +2030,7 @@ static void vfs_gpfs_disk_free_quota(struct gpfs_quotaInfo qi, time_t cur_time, } static uint64_t vfs_gpfs_disk_free(vfs_handle_struct *handle, const char *path, - bool small_query, uint64_t *bsize, + uint64_t *bsize, uint64_t *dfree, uint64_t *dsize) { struct security_unix_token *utok; @@ -2042,14 +2042,14 @@ static uint64_t vfs_gpfs_disk_free(vfs_handle_struct *handle, const char *path, SMB_VFS_HANDLE_GET_DATA(handle, config, struct gpfs_config_data, return (uint64_t)-1); if (!config->dfreequota) { - return SMB_VFS_NEXT_DISK_FREE(handle, path, small_query, + return SMB_VFS_NEXT_DISK_FREE(handle, path, bsize, dfree, dsize); } err = sys_fsusage(path, dfree, dsize); if (err) { DEBUG (0, ("Could not get fs usage, errno %d\n", errno)); - return SMB_VFS_NEXT_DISK_FREE(handle, path, small_query, + return SMB_VFS_NEXT_DISK_FREE(handle, path, bsize, dfree, dsize); } @@ -2063,7 +2063,7 @@ static uint64_t vfs_gpfs_disk_free(vfs_handle_struct *handle, const char *path, err = vfs_gpfs_get_quotas(path, utok->uid, utok->gid, &fset_id, &qi_user, &qi_group, &qi_fset); if (err) { - return SMB_VFS_NEXT_DISK_FREE(handle, path, small_query, + return SMB_VFS_NEXT_DISK_FREE(handle, path, bsize, dfree, dsize); } @@ -2078,7 +2078,7 @@ static uint64_t vfs_gpfs_disk_free(vfs_handle_struct *handle, const char *path, vfs_gpfs_disk_free_quota(qi_fset, cur_time, dfree, dsize); } - disk_norm(small_query, bsize, dfree, dsize); + disk_norm(bsize, dfree, dsize); return *dfree; } diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index 439df5d..2a7a3a9 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -1732,9 +1732,8 @@ static int shadow_copy2_get_real_filename(struct vfs_handle_struct *handle, } static uint64_t shadow_copy2_disk_free(vfs_handle_struct *handle, - const char *path, bool small_query, - uint64_t *bsize, uint64_t *dfree, - uint64_t *dsize) + const char *path, uint64_t *bsize, + uint64_t *dfree, uint64_t *dsize) { time_t timestamp; char *stripped; @@ -1747,7 +1746,7 @@ static uint64_t shadow_copy2_disk_free(vfs_handle_struct *handle, return -1; } if (timestamp == 0) { - return SMB_VFS_NEXT_DISK_FREE(handle, path, small_query, + return SMB_VFS_NEXT_DISK_FREE(handle, path, bsize, dfree, dsize); } @@ -1757,8 +1756,7 @@ static uint64_t shadow_copy2_disk_free(vfs_handle_struct *handle, return -1; } - ret = SMB_VFS_NEXT_DISK_FREE(handle, conv, small_query, bsize, dfree, - dsize); + ret = SMB_VFS_NEXT_DISK_FREE(handle, conv, bsize, dfree, dsize); saved_errno = errno; TALLOC_FREE(conv); diff --git a/source3/modules/vfs_snapper.c b/source3/modules/vfs_snapper.c index b5e7628..415514a 100644 --- a/source3/modules/vfs_snapper.c +++ b/source3/modules/vfs_snapper.c @@ -2151,9 +2151,8 @@ static int snapper_gmt_get_real_filename(struct vfs_handle_struct *handle, } static uint64_t snapper_gmt_disk_free(vfs_handle_struct *handle, - const char *path, bool small_query, - uint64_t *bsize, uint64_t *dfree, - uint64_t *dsize) + const char *path, uint64_t *bsize, + uint64_t *dfree, uint64_t *dsize) { time_t timestamp; char *stripped; @@ -2166,7 +2165,7 @@ static uint64_t snapper_gmt_disk_free(vfs_handle_struct *handle, return -1; } if (timestamp == 0) { - return SMB_VFS_NEXT_DISK_FREE(handle, path, small_query, + return SMB_VFS_NEXT_DISK_FREE(handle, path, bsize, dfree, dsize); } @@ -2176,8 +2175,7 @@ static uint64_t snapper_gmt_disk_free(vfs_handle_struct *handle, return -1; } - ret = SMB_VFS_NEXT_DISK_FREE(handle, conv, small_query, bsize, dfree, - dsize); + ret = SMB_VFS_NEXT_DISK_FREE(handle, conv, bsize, dfree, dsize); saved_errno = errno; TALLOC_FREE(conv); diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c index a1e825a..04552ec 100644 --- a/source3/modules/vfs_time_audit.c +++ b/source3/modules/vfs_time_audit.c @@ -157,8 +157,7 @@ static void smb_time_audit_disconnect(vfs_handle_struct *handle) } static uint64_t smb_time_audit_disk_free(vfs_handle_struct *handle, - const char *path, - bool small_query, uint64_t *bsize, + const char *path, uint64_t *bsize, uint64_t *dfree, uint64_t *dsize) { uint64_t result; @@ -166,8 +165,7 @@ static uint64_t smb_time_audit_disk_free(vfs_handle_struct *handle, double timediff; clock_gettime_mono(&ts1); - result = SMB_VFS_NEXT_DISK_FREE(handle, path, small_query, bsize, - dfree, dsize); + result = SMB_VFS_NEXT_DISK_FREE(handle, path, bsize, dfree, dsize); clock_gettime_mono(&ts2); timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9; diff --git a/source3/smbd/dfree.c b/source3/smbd/dfree.c index d02c1bd..bcefea5 100644 --- a/source3/smbd/dfree.c +++ b/source3/smbd/dfree.c @@ -25,36 +25,21 @@ Normalise for DOS usage. ****************************************************************************/ -void disk_norm(bool small_query, uint64_t *bsize,uint64_t *dfree,uint64_t *dsize) +void disk_norm(uint64_t *bsize, uint64_t *dfree, uint64_t *dsize) { /* check if the disk is beyond the max disk size */ uint64_t maxdisksize = lp_max_disk_size(); if (maxdisksize) { /* convert to blocks - and don't overflow */ maxdisksize = ((maxdisksize*1024)/(*bsize))*1024; - if (*dsize > maxdisksize) *dsize = maxdisksize; - if (*dfree > maxdisksize) *dfree = maxdisksize-1; + if (*dsize > maxdisksize) { + *dsize = maxdisksize; + } + if (*dfree > maxdisksize) { + *dfree = maxdisksize - 1; + } /* the -1 should stop applications getting div by 0 errors */ - } - - if(small_query) { - while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512) { - *dfree /= 2; - *dsize /= 2; - *bsize *= 2; - /* - * Force max to fit in 16 bit fields. - */ - if (*bsize > (WORDMAX*512)) { - *bsize = (WORDMAX*512); - if (*dsize > WORDMAX) - *dsize = WORDMAX; - if (*dfree > WORDMAX) - *dfree = WORDMAX; - break; - } - } } } @@ -64,8 +49,8 @@ void disk_norm(bool small_query, uint64_t *bsize,uint64_t *dfree,uint64_t *dsize Return number of 1K blocks available on a path and total number. ****************************************************************************/ -uint64_t sys_disk_free(connection_struct *conn, const char *path, bool small_query, - uint64_t *bsize,uint64_t *dfree,uint64_t *dsize) +uint64_t sys_disk_free(connection_struct *conn, const char *path, + uint64_t *bsize, uint64_t *dfree, uint64_t *dsize) { uint64_t dfree_retval; uint64_t dfree_q = 0; @@ -161,7 +146,7 @@ uint64_t sys_disk_free(connection_struct *conn, const char *path, bool small_que *dfree = MAX(1,*dfree); } - disk_norm(small_query,bsize,dfree,dsize); + disk_norm(bsize, dfree, dsize); if ((*bsize) < 1024) { dfree_retval = (*dfree)/(1024/(*bsize)); @@ -178,7 +163,6 @@ uint64_t sys_disk_free(connection_struct *conn, const char *path, bool small_que uint64_t get_dfree_info(connection_struct *conn, const char *path, - bool small_query, uint64_t *bsize, uint64_t *dfree, uint64_t *dsize) @@ -188,7 +172,7 @@ uint64_t get_dfree_info(connection_struct *conn, uint64_t dfree_ret; if (!dfree_cache_time) { - return SMB_VFS_DISK_FREE(conn,path,small_query,bsize,dfree,dsize); + return SMB_VFS_DISK_FREE(conn, path, bsize, dfree, dsize); } if (dfc && (conn->lastused - dfc->last_dfree_time < dfree_cache_time)) { @@ -199,7 +183,7 @@ uint64_t get_dfree_info(connection_struct *conn, return dfc->dfree_ret; } - dfree_ret = SMB_VFS_DISK_FREE(conn,path,small_query,bsize,dfree,dsize); + dfree_ret = SMB_VFS_DISK_FREE(conn, path, bsize, dfree, dsize); if (dfree_ret == (uint64_t)-1) { /* Don't cache bad data. */ diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index 26a199c..f01bbbd 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -168,12 +168,11 @@ bool connections_snum_used(struct smbd_server_connection *unused, int snum); /* The following definitions come from smbd/dfree.c */ -void disk_norm(bool small_query, uint64_t *bsize,uint64_t *dfree,uint64_t *dsize); -uint64_t sys_disk_free(connection_struct *conn, const char *path, bool small_query, +void disk_norm(uint64_t *bsize,uint64_t *dfree,uint64_t *dsize); +uint64_t sys_disk_free(connection_struct *conn, const char *path, uint64_t *bsize,uint64_t *dfree,uint64_t *dsize); uint64_t get_dfree_info(connection_struct *conn, const char *path, - bool small_query, uint64_t *bsize, uint64_t *dfree, uint64_t *dsize); diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 0b6c102..5761d42 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1456,15 +1456,34 @@ void reply_setatr(struct smb_request *req) void reply_dskattr(struct smb_request *req) { connection_struct *conn = req->conn; + uint64_t ret; uint64_t dfree,dsize,bsize; START_PROFILE(SMBdskattr); - if (get_dfree_info(conn,".",True,&bsize,&dfree,&dsize) == (uint64_t)-1) { + ret = get_dfree_info(conn, ".", &bsize, &dfree, &dsize); + if (ret == (uint64_t)-1) { reply_nterror(req, map_nt_error_from_unix(errno)); END_PROFILE(SMBdskattr); return; } + /* + * Force max to fit in 16 bit fields. + */ + while (dfree > WORDMAX || dsize > WORDMAX || bsize < 512) { + dfree /= 2; + dsize /= 2; + bsize *= 2; + if (bsize > (WORDMAX*512)) { + bsize = (WORDMAX*512); + if (dsize > WORDMAX) + dsize = WORDMAX; -- Samba Shared Repository