diff --git a/source3/modules/vfs_ceph.c b/source3/modules/vfs_ceph.c index 8e11dab852e..59e9b9cf9b3 100644 --- a/source3/modules/vfs_ceph.c +++ b/source3/modules/vfs_ceph.c @@ -847,9 +847,8 @@ static int strict_allocate_ftruncate(struct vfs_handle_struct *handle, files_str "error %d. Falling back to slow manual allocation\n", errno)); /* available disk space is enough or not? */ - space_avail = get_dfree_info(fsp->conn, - fsp->fsp_name->base_name, - &bsize, &dfree, &dsize); + space_avail = + get_dfree_info(fsp->conn, fsp->fsp_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 de5a4a3dd55..5227e95e302 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -1978,9 +1978,8 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs "error %d. Falling back to slow manual allocation\n", errno)); /* available disk space is enough or not? */ - space_avail = get_dfree_info(fsp->conn, - fsp->fsp_name->base_name, - &bsize, &dfree, &dsize); + space_avail = + get_dfree_info(fsp->conn, fsp->fsp_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/smbd/dfree.c b/source3/smbd/dfree.c index fc52e518a48..7e58daa45cf 100644 --- a/source3/smbd/dfree.c +++ b/source3/smbd/dfree.c @@ -50,7 +50,7 @@ static void disk_norm(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, +uint64_t sys_disk_free(connection_struct *conn, struct smb_filename *fname, uint64_t *bsize, uint64_t *dfree, uint64_t *dsize) { uint64_t dfree_retval; @@ -59,6 +59,7 @@ uint64_t sys_disk_free(connection_struct *conn, const char *path, uint64_t dsize_q = 0; const char *dfree_command; static bool dfree_broken = false; + const char *path = fname->base_name; (*dfree) = (*dsize) = 0; (*bsize) = 512; @@ -124,7 +125,7 @@ uint64_t sys_disk_free(connection_struct *conn, const char *path, return (uint64_t)-1; } - if (disk_quotas(conn, path, &bsize_q, &dfree_q, &dsize_q)) { + if (disk_quotas(conn, fname, &bsize_q, &dfree_q, &dsize_q)) { uint64_t min_bsize = MIN(*bsize, bsize_q); (*dfree) = (*dfree) * (*bsize) / min_bsize; @@ -168,18 +169,15 @@ dfree_done: Potentially returned cached dfree info. ****************************************************************************/ -uint64_t get_dfree_info(connection_struct *conn, - const char *path, - uint64_t *bsize, - uint64_t *dfree, - uint64_t *dsize) +uint64_t get_dfree_info(connection_struct *conn, struct smb_filename *fname, + uint64_t *bsize, uint64_t *dfree, uint64_t *dsize) { int dfree_cache_time = lp_dfree_cache_time(SNUM(conn)); struct dfree_cached_info *dfc = conn->dfree_info; uint64_t dfree_ret; if (!dfree_cache_time) { - return sys_disk_free(conn, path, bsize, dfree, dsize); + return sys_disk_free(conn, fname, bsize, dfree, dsize); } if (dfc && (conn->lastused - dfc->last_dfree_time < dfree_cache_time)) { @@ -190,7 +188,7 @@ uint64_t get_dfree_info(connection_struct *conn, return dfc->dfree_ret; } - dfree_ret = sys_disk_free(conn, path, bsize, dfree, dsize); + dfree_ret = sys_disk_free(conn, fname, 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 7ca546005be..fb30a9e0eaa 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -172,13 +172,10 @@ bool connections_snum_used(struct smbd_server_connection *unused, int snum); /* The following definitions come from smbd/dfree.c */ -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, - uint64_t *bsize, - uint64_t *dfree, - uint64_t *dsize); +uint64_t sys_disk_free(connection_struct *conn, struct smb_filename *fname, + uint64_t *bsize, uint64_t *dfree, uint64_t *dsize); +uint64_t get_dfree_info(connection_struct *conn, struct smb_filename *fname, + uint64_t *bsize, uint64_t *dfree, uint64_t *dsize); /* The following definitions come from smbd/dir.c */ @@ -855,8 +852,8 @@ bool fork_echo_handler(struct smbXsrv_connection *xconn); /* The following definitions come from smbd/quotas.c */ -bool disk_quotas(connection_struct *conn, const char *path, uint64_t *bsize, - uint64_t *dfree, uint64_t *dsize); +bool disk_quotas(connection_struct *conn, struct smb_filename *fname, + uint64_t *bsize, uint64_t *dfree, uint64_t *dsize); /* The following definitions come from smbd/reply.c */ diff --git a/source3/smbd/quotas.c b/source3/smbd/quotas.c index 9d3b9061e9b..f3a727c0ed1 100644 --- a/source3/smbd/quotas.c +++ b/source3/smbd/quotas.c @@ -216,8 +216,8 @@ try to get the disk space from disk quotas (SunOS & Solaris2 version) Quota code by Peter Urbanec (amiga@cse.unsw.edu.au). ****************************************************************************/ -bool disk_quotas(connection_struct *conn, const char *path, uint64_t *bsize, - uint64_t *dfree, uint64_t *dsize) +bool disk_quotas(connection_struct *conn, struct smb_filename *fname, + uint64_t *bsize, uint64_t *dfree, uint64_t *dsize) { uid_t euser_id; int ret; @@ -230,14 +230,11 @@ bool disk_quotas(connection_struct *conn, const char *path, uint64_t *bsize, SMB_STRUCT_STAT sbuf; SMB_DEV_T devno; bool found = false; + const char *path = fname->base_name; euser_id = geteuid(); - if (sys_stat(path, &sbuf, false) == -1) { - return false; - } - - devno = sbuf.st_ex_dev ; + devno = fname->st.st_ex_dev; DEBUG(5,("disk_quotas: looking for path \"%s\" devno=%x\n", path, (unsigned int)devno)); if ((fd = fopen(MNTTAB, "r")) == NULL) { @@ -362,15 +359,16 @@ bool disk_quotas(connection_struct *conn, const char *path, uint64_t *bsize, try to get the disk space from disk quotas - default version ****************************************************************************/ -bool disk_quotas(connection_struct *conn, const char *path, uint64_t *bsize, - uint64_t *dfree, uint64_t *dsize) +bool disk_quotas(connection_struct *conn, struct smb_filename *fname, + uint64_t *bsize, uint64_t *dfree, uint64_t *dsize) { int r; struct dqblk D; uid_t euser_id; + const char *path = fname->base_name; #if !defined(AIX) char dev_disk[256]; - SMB_STRUCT_STAT S; + SMB_STRUCT_STAT S = fname->st; /* find the block device file */ @@ -463,8 +461,8 @@ bool disk_quotas(connection_struct *conn, const char *path, uint64_t *bsize, #else /* WITH_QUOTAS */ -bool disk_quotas(connection_struct *conn, const char *path, uint64_t *bsize, - uint64_t *dfree, uint64_t *dsize) +bool disk_quotas(connection_struct *conn, struct smb_filename *fname, + uint64_t *bsize, uint64_t *dfree, uint64_t *dsize) { (*bsize) = 512; /* This value should be ignored */ @@ -482,8 +480,8 @@ bool disk_quotas(connection_struct *conn, const char *path, uint64_t *bsize, /* wrapper to the new sys_quota interface this file should be removed later */ -bool disk_quotas(connection_struct *conn, const char *path, uint64_t *bsize, - uint64_t *dfree, uint64_t *dsize) +bool disk_quotas(connection_struct *conn, struct smb_filename *fname, + uint64_t *bsize, uint64_t *dfree, uint64_t *dsize) { int r; SMB_DISK_QUOTA D; @@ -496,7 +494,8 @@ bool disk_quotas(connection_struct *conn, const char *path, uint64_t *bsize, */ ZERO_STRUCT(D); id.uid = -1; - r = SMB_VFS_GET_QUOTA(conn, path, SMB_USER_FS_QUOTA_TYPE, id, &D); + r = SMB_VFS_GET_QUOTA(conn, fname->base_name, SMB_USER_FS_QUOTA_TYPE, + id, &D); if (r == -1 && errno != ENOSYS) { goto try_group_quota; } @@ -507,7 +506,8 @@ bool disk_quotas(connection_struct *conn, const char *path, uint64_t *bsize, ZERO_STRUCT(D); id.uid = geteuid(); - r = SMB_VFS_GET_QUOTA(conn, path, SMB_USER_QUOTA_TYPE, id, &D); + r = SMB_VFS_GET_QUOTA(conn, fname->base_name, SMB_USER_QUOTA_TYPE, id, + &D); if (r == -1) { goto try_group_quota; @@ -543,7 +543,8 @@ try_group_quota: */ ZERO_STRUCT(D); id.gid = -1; - r = SMB_VFS_GET_QUOTA(conn, path, SMB_GROUP_FS_QUOTA_TYPE, id, &D); + r = SMB_VFS_GET_QUOTA(conn, fname->base_name, SMB_GROUP_FS_QUOTA_TYPE, + id, &D); if (r == -1 && errno != ENOSYS) { return false; } @@ -554,7 +555,8 @@ try_group_quota: id.gid = getegid(); ZERO_STRUCT(D); - r = SMB_VFS_GET_QUOTA(conn, path, SMB_GROUP_QUOTA_TYPE, id, &D); + r = SMB_VFS_GET_QUOTA(conn, fname->base_name, SMB_GROUP_QUOTA_TYPE, id, + &D); if (r == -1) { return False; diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 0b7a4fbd329..4f1ecb1ae83 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1573,9 +1573,20 @@ void reply_dskattr(struct smb_request *req) connection_struct *conn = req->conn; uint64_t ret; uint64_t dfree,dsize,bsize; + struct smb_filename smb_fname; START_PROFILE(SMBdskattr); - ret = get_dfree_info(conn, ".", &bsize, &dfree, &dsize); + ZERO_STRUCT(smb_fname); + smb_fname.base_name = discard_const_p(char, "."); + + if (SMB_VFS_STAT(conn, &smb_fname) != 0) { + reply_nterror(req, map_nt_error_from_unix(errno)); + DBG_WARNING("stat of . failed (%s)\n", strerror(errno)); + END_PROFILE(SMBdskattr); + return; + } + + ret = get_dfree_info(conn, &smb_fname, &bsize, &dfree, &dsize); if (ret == (uint64_t)-1) { reply_nterror(req, map_nt_error_from_unix(errno)); END_PROFILE(SMBdskattr); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 9c0660b3674..1775316330e 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3438,8 +3438,8 @@ NTSTATUS smbd_do_qfsinfo(struct smbXsrv_connection *xconn, { uint64_t dfree,dsize,bsize,block_size,sectors_per_unit; data_len = 18; - df_ret = get_dfree_info(conn, filename, &bsize, &dfree, - &dsize); + df_ret = get_dfree_info(conn, &smb_fname, &bsize, + &dfree, &dsize); if (df_ret == (uint64_t)-1) { return map_nt_error_from_unix(errno); } @@ -3589,8 +3589,8 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u { uint64_t dfree,dsize,bsize,block_size,sectors_per_unit; data_len = 24; - df_ret = get_dfree_info(conn, filename, &bsize, &dfree, - &dsize); + df_ret = get_dfree_info(conn, &smb_fname, &bsize, + &dfree, &dsize); if (df_ret == (uint64_t)-1) { return map_nt_error_from_unix(errno); } @@ -3623,8 +3623,8 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned { uint64_t dfree,dsize,bsize,block_size,sectors_per_unit; data_len = 32; - df_ret = get_dfree_info(conn, filename, &bsize, &dfree, - &dsize); + df_ret = get_dfree_info(conn, &smb_fname, &bsize, + &dfree, &dsize); if (df_ret == (uint64_t)-1) { return map_nt_error_from_unix(errno); } diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 605f9ade703..45562eedebe 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -623,8 +623,8 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len) len -= fsp->fsp_name->st.st_ex_size; len /= 1024; /* Len is now number of 1k blocks needed. */ - space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, - &bsize, &dfree, &dsize); + space_avail = + get_dfree_info(conn, fsp->fsp_name, &bsize, &dfree, &dsize); if (space_avail == (uint64_t)-1) { return -1; }