summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorIra Cooper <ira@samba.org>2013-02-06 13:35:25 +0000
committerJeremy Allison <jra@samba.org>2013-02-08 21:44:37 +0100
commit233b32b771188a6b9ee730a2a202023370e80746 (patch)
tree557443a4d082cb0e30b56451bf4b0958710e3043 /source3/smbd
parentbeb6c13e9a8c317bca240e875d9e3bcd940a02fb (diff)
downloadsamba-233b32b771188a6b9ee730a2a202023370e80746.tar.gz
samba-233b32b771188a6b9ee730a2a202023370e80746.tar.bz2
samba-233b32b771188a6b9ee730a2a202023370e80746.zip
s3: Make SMB2_GETINFO multi-volume aware.
Not all shares are a single volume. Some actually expose multiple volumes under a single share. In these cases showing the amount of space free as the space free at the base of the directory heirarchy is wrong. Reviewed-by: Jeremy Allison <jra@samba.org> Autobuild-User(master): Jeremy Allison <jra@samba.org> Autobuild-Date(master): Fri Feb 8 21:44:37 CET 2013 on sn-devel-104
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/globals.h1
-rw-r--r--source3/smbd/smb2_getinfo.c1
-rw-r--r--source3/smbd/trans2.c27
3 files changed, 20 insertions, 9 deletions
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 4a86697d48..6ead9626a5 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -155,6 +155,7 @@ NTSTATUS smbd_do_qfsinfo(connection_struct *conn,
uint16_t info_level,
uint16_t flags2,
unsigned int max_data_bytes,
+ struct smb_filename *smb_fname,
char **ppdata,
int *ret_data_len);
diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c
index 33cee9910c..5616c849ad 100644
--- a/source3/smbd/smb2_getinfo.c
+++ b/source3/smbd/smb2_getinfo.c
@@ -413,6 +413,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
file_info_level,
STR_UNICODE,
in_output_buffer_length,
+ fsp->fsp_name,
&data,
&data_size);
if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 92d047ae5d..8cffc15dec 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -3021,6 +3021,7 @@ NTSTATUS smbd_do_qfsinfo(connection_struct *conn,
uint16_t info_level,
uint16_t flags2,
unsigned int max_data_bytes,
+ struct smb_filename *fname,
char **ppdata,
int *ret_data_len)
{
@@ -3029,10 +3030,17 @@ NTSTATUS smbd_do_qfsinfo(connection_struct *conn,
const char *vname = volume_label(talloc_tos(), SNUM(conn));
int snum = SNUM(conn);
char *fstype = lp_fstype(talloc_tos(), SNUM(conn));
+ char *filename = NULL;
uint32 additional_flags = 0;
- struct smb_filename smb_fname_dot;
+ struct smb_filename smb_fname;
SMB_STRUCT_STAT st;
+ if (fname == NULL || fname->base_name == NULL) {
+ filename = ".";
+ } else {
+ filename = fname->base_name;
+ }
+
if (IS_IPC(conn)) {
if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
DEBUG(0,("smbd_do_qfsinfo: not an allowed "
@@ -3044,15 +3052,15 @@ NTSTATUS smbd_do_qfsinfo(connection_struct *conn,
DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level));
- ZERO_STRUCT(smb_fname_dot);
- smb_fname_dot.base_name = discard_const_p(char, ".");
+ ZERO_STRUCT(smb_fname);
+ smb_fname.base_name = discard_const_p(char, filename);
- if(SMB_VFS_STAT(conn, &smb_fname_dot) != 0) {
+ if(SMB_VFS_STAT(conn, &smb_fname) != 0) {
DEBUG(2,("stat of . failed (%s)\n", strerror(errno)));
return map_nt_error_from_unix(errno);
}
- st = smb_fname_dot.st;
+ st = smb_fname.st;
*ppdata = (char *)SMB_REALLOC(
*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
@@ -3069,7 +3077,7 @@ NTSTATUS smbd_do_qfsinfo(connection_struct *conn,
{
uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
data_len = 18;
- if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
+ if (get_dfree_info(conn,filename,False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
return map_nt_error_from_unix(errno);
}
@@ -3193,7 +3201,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u
{
uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
data_len = 24;
- if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
+ if (get_dfree_info(conn,filename,False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
return map_nt_error_from_unix(errno);
}
block_size = lp_block_size(snum);
@@ -3225,7 +3233,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
{
uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
data_len = 32;
- if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
+ if (get_dfree_info(conn,filename,False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
return map_nt_error_from_unix(errno);
}
block_size = lp_block_size(snum);
@@ -3418,7 +3426,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
return NT_STATUS_INVALID_LEVEL;
}
- rc = SMB_VFS_STATVFS(conn, ".", &svfs);
+ rc = SMB_VFS_STATVFS(conn, filename, &svfs);
if (!rc) {
data_len = 56;
@@ -3598,6 +3606,7 @@ static void call_trans2qfsinfo(connection_struct *conn,
info_level,
req->flags2,
max_data_bytes,
+ NULL,
ppdata, &data_len);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);