[SCM] Samba Shared Repository - branch v3-3-test updated - release-3-2-0pre2-4929-geeeceea

Derrell Lipman derrell at samba.org
Tue Feb 10 20:04:13 GMT 2009


The branch, v3-3-test has been updated
       via  eeeceea8b92b8b814209f496a7ab953dcd0a8367 (commit)
      from  0acc962e3968253a3f64b5a92def177ced44994d (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-3-test


- Log -----------------------------------------------------------------
commit eeeceea8b92b8b814209f496a7ab953dcd0a8367
Author: Derrell Lipman <derrell.lipman at unwireduniverse.com>
Date:   Tue Feb 10 15:03:32 2009 -0500

    [Bug 6069] Add a fstatvfs function for libsmbclient
    
    - Fill in the remainder of the data (or at least as much as we can get) for
      the fstatvfs return value.
    
    Derrell

-----------------------------------------------------------------------

Summary of changes:
 examples/libsmbclient/testfstatvfs.c |   15 +++-
 source/include/includes.h            |    2 +
 source/include/proto.h               |   15 ++++
 source/libsmb/clifsinfo.c            |  145 ++++++++++++++++++++++++++++++++++
 source/libsmb/libsmb_stat.c          |   64 +++++++++++++++
 5 files changed, 240 insertions(+), 1 deletions(-)


Changeset truncated at 500 lines:

diff --git a/examples/libsmbclient/testfstatvfs.c b/examples/libsmbclient/testfstatvfs.c
index fbb51f1..f8a6870 100644
--- a/examples/libsmbclient/testfstatvfs.c
+++ b/examples/libsmbclient/testfstatvfs.c
@@ -72,7 +72,20 @@ int main(int argc, char * argv[])
         }
         else
         {
-            printf("Features: ");
+            printf("\n");
+            printf("Block Size: %lu\n", statvfsbuf.f_bsize);
+            printf("Fragment Size: %lu\n", statvfsbuf.f_frsize);
+            printf("Blocks: %llu\n", statvfsbuf.f_blocks);
+            printf("Free Blocks: %llu\n", statvfsbuf.f_bfree);
+            printf("Available Blocks: %llu\n", statvfsbuf.f_bavail);
+            printf("Files : %llu\n", statvfsbuf.f_files);
+            printf("Free Files: %llu\n", statvfsbuf.f_ffree);
+            printf("Available Files: %llu\n", statvfsbuf.f_favail);
+            printf("File System ID: %lu\n", statvfsbuf.f_fsid);
+            printf("\n");
+
+            printf("Flags: 0x%lx\n", statvfsbuf.f_flag);
+            printf("Extended Features: ");
 
             if (statvfsbuf.f_flag & SMBC_VFS_FEATURE_NO_UNIXCIFS)
             {
diff --git a/source/include/includes.h b/source/include/includes.h
index d130171..65b4242 100644
--- a/source/include/includes.h
+++ b/source/include/includes.h
@@ -470,10 +470,12 @@ typedef int VOLATILE SIG_ATOMIC_T;
 #define SMB_BIG_UINT unsigned long long
 #define SMB_BIG_INT long long
 #define SBIG_UINT(p, ofs, v) (SIVAL(p,ofs,(v)&0xFFFFFFFF), SIVAL(p,(ofs)+4,(v)>>32))
+#define BIG_UINT(p, ofs) ((((SMB_BIG_UINT) IVAL(p,(ofs)+4))<<32)|IVAL(p,ofs))
 #else
 #define SMB_BIG_UINT unsigned long
 #define SMB_BIG_INT long
 #define SBIG_UINT(p, ofs, v) (SIVAL(p,ofs,v),SIVAL(p,(ofs)+4,0))
+#define BIG_UINT(p, ofs) (IVAL(p,ofs))
 #endif
 
 #define SMB_BIG_UINT_BITS (sizeof(SMB_BIG_UINT)*8)
diff --git a/source/include/proto.h b/source/include/proto.h
index 226f7be..04ceb83 100644
--- a/source/include/proto.h
+++ b/source/include/proto.h
@@ -4333,6 +4333,21 @@ bool cli_set_unix_extensions_capabilities(struct cli_state *cli, uint16 major, u
 bool cli_get_fs_attr_info(struct cli_state *cli, uint32 *fs_attr);
 bool cli_get_fs_volume_info_old(struct cli_state *cli, fstring volume_name, uint32 *pserial_number);
 bool cli_get_fs_volume_info(struct cli_state *cli, fstring volume_name, uint32 *pserial_number, time_t *pdate);
+bool cli_get_fs_full_size_info(struct cli_state *cli,
+                               SMB_BIG_UINT *total_allocation_units,
+                               SMB_BIG_UINT *caller_allocation_units,
+                               SMB_BIG_UINT *actual_allocation_units,
+                               SMB_BIG_UINT *sectors_per_allocation_unit,
+                               SMB_BIG_UINT *bytes_per_sector);
+bool cli_get_posix_fs_info(struct cli_state *cli,
+                           uint32 *optimal_transfer_size,
+                           uint32 *block_size,
+                           SMB_BIG_UINT *total_blocks,
+                           SMB_BIG_UINT *blocks_available,
+                           SMB_BIG_UINT *user_blocks_available,
+                           SMB_BIG_UINT *total_file_nodes,
+                           SMB_BIG_UINT *free_file_nodes,
+                           SMB_BIG_UINT *fs_identifier);
 NTSTATUS cli_raw_ntlm_smb_encryption_start(struct cli_state *cli, 
 				const char *user,
 				const char *pass,
diff --git a/source/libsmb/clifsinfo.c b/source/libsmb/clifsinfo.c
index 5e73b61..dd56f30 100644
--- a/source/libsmb/clifsinfo.c
+++ b/source/libsmb/clifsinfo.c
@@ -303,6 +303,151 @@ cleanup:
 	return ret;
 }
 
+bool cli_get_fs_full_size_info(struct cli_state *cli,
+                               SMB_BIG_UINT *total_allocation_units,
+                               SMB_BIG_UINT *caller_allocation_units,
+                               SMB_BIG_UINT *actual_allocation_units,
+                               SMB_BIG_UINT *sectors_per_allocation_unit,
+                               SMB_BIG_UINT *bytes_per_sector)
+{
+	bool ret = False;
+	uint16 setup;
+	char param[2];
+	char *rparam=NULL, *rdata=NULL;
+	unsigned int rparam_count=0, rdata_count=0;
+
+	setup = TRANSACT2_QFSINFO;
+
+	SSVAL(param,0,SMB_FS_FULL_SIZE_INFORMATION);
+
+	if (!cli_send_trans(cli, SMBtrans2,
+		    NULL,
+		    0, 0,
+		    &setup, 1, 0,
+		    param, 2, 0,
+		    NULL, 0, 560)) {
+		goto cleanup;
+	}
+
+	if (!cli_receive_trans(cli, SMBtrans2,
+                              &rparam, &rparam_count,
+                              &rdata, &rdata_count)) {
+		goto cleanup;
+	}
+
+	if (cli_is_error(cli)) {
+		ret = False;
+		goto cleanup;
+	} else {
+		ret = True;
+	}
+
+	if (rdata_count != 32) {
+		goto cleanup;
+	}
+
+	if (total_allocation_units) {
+                *total_allocation_units = BIG_UINT(rdata, 0);
+	}
+	if (caller_allocation_units) {
+		*caller_allocation_units = BIG_UINT(rdata,8);
+	}
+	if (actual_allocation_units) {
+		*actual_allocation_units = BIG_UINT(rdata,16);
+	}
+	if (sectors_per_allocation_unit) {
+		*sectors_per_allocation_unit = IVAL(rdata,24);
+	}
+	if (bytes_per_sector) {
+		*bytes_per_sector = IVAL(rdata,28);
+	}
+
+cleanup:
+	SAFE_FREE(rparam);
+	SAFE_FREE(rdata);
+
+	return ret;
+}
+
+bool cli_get_posix_fs_info(struct cli_state *cli,
+                           uint32 *optimal_transfer_size,
+                           uint32 *block_size,
+                           SMB_BIG_UINT *total_blocks,
+                           SMB_BIG_UINT *blocks_available,
+                           SMB_BIG_UINT *user_blocks_available,
+                           SMB_BIG_UINT *total_file_nodes,
+                           SMB_BIG_UINT *free_file_nodes,
+                           SMB_BIG_UINT *fs_identifier)
+{
+	bool ret = False;
+	uint16 setup;
+	char param[2];
+	char *rparam=NULL, *rdata=NULL;
+	unsigned int rparam_count=0, rdata_count=0;
+
+	setup = TRANSACT2_QFSINFO;
+
+	SSVAL(param,0,SMB_QUERY_POSIX_FS_INFO);
+
+	if (!cli_send_trans(cli, SMBtrans2,
+		    NULL,
+		    0, 0,
+		    &setup, 1, 0,
+		    param, 2, 0,
+		    NULL, 0, 560)) {
+		goto cleanup;
+	}
+
+	if (!cli_receive_trans(cli, SMBtrans2,
+                              &rparam, &rparam_count,
+                              &rdata, &rdata_count)) {
+		goto cleanup;
+	}
+
+	if (cli_is_error(cli)) {
+		ret = False;
+		goto cleanup;
+	} else {
+		ret = True;
+	}
+
+	if (rdata_count != 56) {
+		goto cleanup;
+	}
+
+	if (optimal_transfer_size) {
+                *optimal_transfer_size = IVAL(rdata, 0);
+	}
+	if (block_size) {
+		*block_size = IVAL(rdata,4);
+	}
+	if (total_blocks) {
+		*total_blocks = BIG_UINT(rdata,8);
+	}
+	if (blocks_available) {
+		*blocks_available = BIG_UINT(rdata,16);
+	}
+	if (user_blocks_available) {
+		*user_blocks_available = BIG_UINT(rdata,24);
+	}
+	if (total_file_nodes) {
+		*total_file_nodes = BIG_UINT(rdata,32);
+	}
+	if (free_file_nodes) {
+		*free_file_nodes = BIG_UINT(rdata,40);
+	}
+	if (fs_identifier) {
+		*fs_identifier = BIG_UINT(rdata,48);
+	}
+
+cleanup:
+	SAFE_FREE(rparam);
+	SAFE_FREE(rdata);
+
+	return ret;
+}
+
+
 /******************************************************************************
  Send/receive the request encryption blob.
 ******************************************************************************/
diff --git a/source/libsmb/libsmb_stat.c b/source/libsmb/libsmb_stat.c
index e5eac59..02088c3 100644
--- a/source/libsmb/libsmb_stat.c
+++ b/source/libsmb/libsmb_stat.c
@@ -312,6 +312,7 @@ SMBC_fstatvfs_ctx(SMBCCTX *context,
 {
 	uint32 fs_attrs = 0;
 	struct cli_state *cli = file->srv->cli;
+                
 
         /* Initialize all fields (at least until we actually use them) */
         memset(st, 0, sizeof(*st));
@@ -327,7 +328,70 @@ SMBC_fstatvfs_ctx(SMBCCTX *context,
 
         /* See if the server has UNIX CIFS support */
         if (! SERVER_HAS_UNIX_CIFS(cli)) {
+                SMB_BIG_UINT total_allocation_units;
+                SMB_BIG_UINT caller_allocation_units;
+                SMB_BIG_UINT actual_allocation_units;
+                SMB_BIG_UINT sectors_per_allocation_unit;
+                SMB_BIG_UINT bytes_per_sector;
+                
+                /* Nope. If size data is available... */
+                if (cli_get_fs_full_size_info(cli,
+                                              &total_allocation_units,
+                                              &caller_allocation_units,
+                                              &actual_allocation_units,
+                                              &sectors_per_allocation_unit,
+                                              &bytes_per_sector)) {
+
+                        /* ... then provide it */
+                        st->f_bsize =
+                                (unsigned long) bytes_per_sector;
+                        st->f_frsize =
+                                (unsigned long) sectors_per_allocation_unit;
+                        st->f_blocks =
+                                (fsblkcnt_t) total_allocation_units;
+                        st->f_bfree =
+                                (fsblkcnt_t) actual_allocation_units;
+                }
+
                 st->f_flag |= SMBC_VFS_FEATURE_NO_UNIXCIFS;
+        } else {
+                uint32 optimal_transfer_size;
+                uint32 block_size;
+                SMB_BIG_UINT total_blocks;
+                SMB_BIG_UINT blocks_available;
+                SMB_BIG_UINT user_blocks_available;
+                SMB_BIG_UINT total_file_nodes;
+                SMB_BIG_UINT free_file_nodes;
+                SMB_BIG_UINT fs_identifier;
+
+                /* Has UNIXCIFS. If POSIX filesystem info is available... */
+                if (cli_get_posix_fs_info(cli,
+                                          &optimal_transfer_size,
+                                          &block_size,
+                                          &total_blocks,
+                                          &blocks_available,
+                                          &user_blocks_available,
+                                          &total_file_nodes,
+                                          &free_file_nodes,
+                                          &fs_identifier)) {
+
+                        /* ... then what's provided here takes precedence. */
+                        st->f_bsize =
+                                (unsigned long) block_size;
+                        st->f_blocks =
+                                (fsblkcnt_t) total_blocks;
+                        st->f_bfree =
+                                (fsblkcnt_t) blocks_available;
+                        st->f_bavail =
+                                (fsblkcnt_t) user_blocks_available;
+                        st->f_files =
+                                (fsfilcnt_t) total_file_nodes;
+                        st->f_ffree =
+                                (fsfilcnt_t) free_file_nodes;
+                        st->f_fsid =
+                                (unsigned long) fs_identifier;
+                        
+                }
         }
 
         /* See if the share is case sensitive */


-- 
Samba Shared Repository


More information about the samba-cvs mailing list