|
@@ -3215,6 +3215,92 @@ GetDFSRefExit:
|
|
return rc;
|
|
return rc;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/* Query File System Info such as free space to old servers such as Win 9x */
|
|
|
|
+int
|
|
|
|
+SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData)
|
|
|
|
+{
|
|
|
|
+/* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
|
|
|
|
+ TRANSACTION2_QFSI_REQ *pSMB = NULL;
|
|
|
|
+ TRANSACTION2_QFSI_RSP *pSMBr = NULL;
|
|
|
|
+ FILE_SYSTEM_ALLOC_INFO *response_data;
|
|
|
|
+ int rc = 0;
|
|
|
|
+ int bytes_returned = 0;
|
|
|
|
+ __u16 params, byte_count;
|
|
|
|
+
|
|
|
|
+ cFYI(1, ("OldQFSInfo"));
|
|
|
|
+oldQFSInfoRetry:
|
|
|
|
+ rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
|
|
|
|
+ (void **) &pSMBr);
|
|
|
|
+ if (rc)
|
|
|
|
+ return rc;
|
|
|
|
+ rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
|
|
|
|
+ (void **) &pSMBr);
|
|
|
|
+ if (rc)
|
|
|
|
+ return rc;
|
|
|
|
+
|
|
|
|
+ params = 2; /* level */
|
|
|
|
+ pSMB->TotalDataCount = 0;
|
|
|
|
+ pSMB->MaxParameterCount = cpu_to_le16(2);
|
|
|
|
+ pSMB->MaxDataCount = cpu_to_le16(1000);
|
|
|
|
+ pSMB->MaxSetupCount = 0;
|
|
|
|
+ pSMB->Reserved = 0;
|
|
|
|
+ pSMB->Flags = 0;
|
|
|
|
+ pSMB->Timeout = 0;
|
|
|
|
+ pSMB->Reserved2 = 0;
|
|
|
|
+ byte_count = params + 1 /* pad */ ;
|
|
|
|
+ pSMB->TotalParameterCount = cpu_to_le16(params);
|
|
|
|
+ pSMB->ParameterCount = pSMB->TotalParameterCount;
|
|
|
|
+ pSMB->ParameterOffset = cpu_to_le16(offsetof(
|
|
|
|
+ struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
|
|
|
|
+ pSMB->DataCount = 0;
|
|
|
|
+ pSMB->DataOffset = 0;
|
|
|
|
+ pSMB->SetupCount = 1;
|
|
|
|
+ pSMB->Reserved3 = 0;
|
|
|
|
+ pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
|
|
|
|
+ pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
|
|
|
|
+ pSMB->hdr.smb_buf_length += byte_count;
|
|
|
|
+ pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
|
|
+
|
|
|
|
+ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
|
|
+ (struct smb_hdr *) pSMBr, &bytes_returned, 0);
|
|
|
|
+ if (rc) {
|
|
|
|
+ cFYI(1, ("Send error in QFSInfo = %d", rc));
|
|
|
|
+ } else { /* decode response */
|
|
|
|
+ rc = validate_t2((struct smb_t2_rsp *)pSMBr);
|
|
|
|
+
|
|
|
|
+ if (rc || (pSMBr->ByteCount < 18))
|
|
|
|
+ rc = -EIO; /* bad smb */
|
|
|
|
+ else {
|
|
|
|
+ __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
|
|
|
|
+ cFYI(1,("qfsinf resp BCC: %d Offset %d",
|
|
|
|
+ pSMBr->ByteCount, data_offset));
|
|
|
|
+
|
|
|
|
+ response_data =
|
|
|
|
+ (FILE_SYSTEM_ALLOC_INFO *)
|
|
|
|
+ (((char *) &pSMBr->hdr.Protocol) + data_offset);
|
|
|
|
+ FSData->f_bsize =
|
|
|
|
+ le16_to_cpu(response_data->BytesPerSector) *
|
|
|
|
+ le32_to_cpu(response_data->
|
|
|
|
+ SectorsPerAllocationUnit);
|
|
|
|
+ FSData->f_blocks =
|
|
|
|
+ le32_to_cpu(response_data->TotalAllocationUnits);
|
|
|
|
+ FSData->f_bfree = FSData->f_bavail =
|
|
|
|
+ le32_to_cpu(response_data->FreeAllocationUnits);
|
|
|
|
+ cFYI(1,
|
|
|
|
+ ("Blocks: %lld Free: %lld Block size %ld",
|
|
|
|
+ (unsigned long long)FSData->f_blocks,
|
|
|
|
+ (unsigned long long)FSData->f_bfree,
|
|
|
|
+ FSData->f_bsize));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ cifs_buf_release(pSMB);
|
|
|
|
+
|
|
|
|
+ if (rc == -EAGAIN)
|
|
|
|
+ goto oldQFSInfoRetry;
|
|
|
|
+
|
|
|
|
+ return rc;
|
|
|
|
+}
|
|
|
|
+
|
|
int
|
|
int
|
|
CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData)
|
|
CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData)
|
|
{
|
|
{
|
|
@@ -3236,7 +3322,7 @@ QFSInfoRetry:
|
|
params = 2; /* level */
|
|
params = 2; /* level */
|
|
pSMB->TotalDataCount = 0;
|
|
pSMB->TotalDataCount = 0;
|
|
pSMB->MaxParameterCount = cpu_to_le16(2);
|
|
pSMB->MaxParameterCount = cpu_to_le16(2);
|
|
- pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
|
|
|
|
|
|
+ pSMB->MaxDataCount = cpu_to_le16(1000);
|
|
pSMB->MaxSetupCount = 0;
|
|
pSMB->MaxSetupCount = 0;
|
|
pSMB->Reserved = 0;
|
|
pSMB->Reserved = 0;
|
|
pSMB->Flags = 0;
|
|
pSMB->Flags = 0;
|
|
@@ -3259,17 +3345,14 @@ QFSInfoRetry:
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
|
|
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
|
|
if (rc) {
|
|
if (rc) {
|
|
- cERROR(1, ("Send error in QFSInfo = %d", rc));
|
|
|
|
|
|
+ cFYI(1, ("Send error in QFSInfo = %d", rc));
|
|
} else { /* decode response */
|
|
} else { /* decode response */
|
|
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
|
|
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
|
|
|
|
|
|
- if (rc || (pSMBr->ByteCount < 24)) /* BB alsO CHEck enough total bytes returned */
|
|
|
|
|
|
+ if (rc || (pSMBr->ByteCount < 24))
|
|
rc = -EIO; /* bad smb */
|
|
rc = -EIO; /* bad smb */
|
|
else {
|
|
else {
|
|
__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
|
|
__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
|
|
- cFYI(1,
|
|
|
|
- ("Decoding qfsinfo response. BCC: %d Offset %d",
|
|
|
|
- pSMBr->ByteCount, data_offset));
|
|
|
|
|
|
|
|
response_data =
|
|
response_data =
|
|
(FILE_SYSTEM_INFO
|
|
(FILE_SYSTEM_INFO
|