ChangeSet 1.2191, 2005/03/21 20:09:44-06:00, [EMAIL PROTECTED](none)

        [CIFS] add new retry on failure to legacy servers such as NT4 of delete 
of readonly files.
        
        Signed-off-by: Steve French ([EMAIL PROTECTED])



 cifspdu.h   |   19 ++++++++++++++
 cifsproto.h |    7 ++---
 cifssmb.c   |   81 ++++++++++++++++++++----------------------------------------
 inode.c     |   30 ++++++++++++++++++++--
 misc.c      |   10 +++++--
 5 files changed, 85 insertions(+), 62 deletions(-)


diff -Nru a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
--- a/fs/cifs/cifspdu.h 2005-03-30 12:08:35 -08:00
+++ b/fs/cifs/cifspdu.h 2005-03-30 12:08:35 -08:00
@@ -36,6 +36,7 @@
 #define SMB_COM_CLOSE                 0x04 /* triv req/rsp, timestamp ignored 
*/
 #define SMB_COM_DELETE                0x06 /* trivial response */
 #define SMB_COM_RENAME                0x07 /* trivial response */
+#define SMB_COM_SETATTR               0x09 /* trivial response */
 #define SMB_COM_LOCKING_ANDX          0x24 /* trivial response */
 #define SMB_COM_COPY                  0x29 /* trivial rsp, fail filename 
ignrd*/
 #define SMB_COM_READ_ANDX             0x2E
@@ -864,6 +865,24 @@
        struct smb_hdr hdr;     /* wct = 0 */
        __u16 ByteCount;        /* bct = 0 */
 } CREATE_DIRECTORY_RSP;
+
+typedef struct smb_com_setattr_req {
+       struct smb_hdr hdr; /* wct = 8 */
+       __le16 attr;
+       __le16 time_low;
+       __le16 time_high;
+       __le16 reserved[5]; /* must be zero */
+       __u16  ByteCount;
+       __u8   BufferFormat; /* 4 = ASCII */
+       unsigned char fileName[1];
+} SETATTR_REQ;
+
+typedef struct smb_com_setattr_rsp {
+       struct smb_hdr hdr;     /* wct = 0 */
+       __u16 ByteCount;        /* bct = 0 */
+} SETATTR_RSP;
+
+/* empty wct response to setattr */
 
 /***************************************************/
 /* NT Transact structure defintions follow         */
diff -Nru a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
--- a/fs/cifs/cifsproto.h       2005-03-30 12:08:35 -08:00
+++ b/fs/cifs/cifsproto.h       2005-03-30 12:08:35 -08:00
@@ -137,10 +137,11 @@
                        const struct nls_table *nls_codepage);
 extern int CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon,
                        const FILE_BASIC_INFO * data, __u16 fid);
-extern int CIFSSMBSetTimesLegacy(int xid, struct cifsTconInfo *tcon, 
-                       char *fileName, FILE_BASIC_INFO * data,
+#if 0
+extern int CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon,
+                       char *fileName, __u16 dos_attributes,
                        const struct nls_table *nls_codepage);
-
+#endif /* possibly unneeded function */
 extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon,
                        const char *fileName, __u64 size,int 
setAllocationSizeFlag,
                        const struct nls_table *nls_codepage);
diff -Nru a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
--- a/fs/cifs/cifssmb.c 2005-03-30 12:08:35 -08:00
+++ b/fs/cifs/cifssmb.c 2005-03-30 12:08:35 -08:00
@@ -3526,85 +3526,58 @@
        return rc;
 }
 
+/* Can not be used to set time stamps yet (due to old DOS time format) */
+/* Can be used to set attributes */
+#if 0  /* Possibly not needed - since it turns out that strangely NT4 has a bug
+         handling it anyway and NT4 was what we thought it would be needed for
+         Do not delete it until we prove whether needed for Win9x though */
 int
-CIFSSMBSetTimesLegacy(int xid, struct cifsTconInfo *tcon, char *fileName,
-               FILE_BASIC_INFO * data, const struct nls_table *nls_codepage)
+CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon, char *fileName,
+               __u16 dos_attrs, const struct nls_table *nls_codepage)
 {
-       TRANSACTION2_SPI_REQ *pSMB = NULL;
-       TRANSACTION2_SPI_RSP *pSMBr = NULL;
-       FILE_INFO_STANDARD   *pfinfo;
-       int name_len;
+       SETATTR_REQ *pSMB = NULL;
+       SETATTR_RSP *pSMBr = NULL;
        int rc = 0;
-       int bytes_returned = 0;
-       char *data_offset;
-       __u16 params, param_offset, count, offset, byte_count;
+       int bytes_returned;
+       int name_len;
 
-       cFYI(1, ("In SetTimesLegacy"));
+       cFYI(1, ("In SetAttrLegacy"));
 
-SetTimesRetryLegacy:
-       rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
+SetAttrLgcyRetry:
+       rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
        if (rc)
                return rc;
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, PATH_MAX
-                                 /* find define for this maxpathcomponent */
-                                 , nls_codepage);
-               name_len++;     /* trailing null */
+                       cifs_strtoUCS((wchar_t *) pSMB->fileName, fileName, 
+                               PATH_MAX, nls_codepage);
+               name_len++;     /* trailing null */
                name_len *= 2;
-       } else {                /* BB improve the check for buffer overruns BB 
*/
+       } else {                /* BB improve the check for buffer overruns BB 
*/
                name_len = strnlen(fileName, PATH_MAX);
-               name_len++;     /* trailing null */
-               strncpy(pSMB->FileName, fileName, name_len);
+               name_len++;     /* trailing null */
+               strncpy(pSMB->fileName, fileName, name_len);
        }
-/* BB fixme - we have to map to FILE_STANDARD_INFO (level 1 info
-       in parent function, from the better and ususal FILE_BASIC_INFO */
-       params = 6 + name_len;
-       pSMB->MaxParameterCount = cpu_to_le16(2);
-       pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU 
from sess structure BB */
-       pSMB->MaxSetupCount = 0;
-       pSMB->Reserved = 0;
-       pSMB->Flags = 0;
-       pSMB->Timeout = 0;
-       pSMB->Reserved2 = 0;
-       param_offset = offsetof(struct smb_com_transaction2_spi_req,
-                                     InformationLevel) - 4;
-       offset = param_offset + params;
-       data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
-       pfinfo = (FILE_INFO_STANDARD *)data_offset;
-       /* BB add conversion for FILE_BASIC_INFO data struct to
-                FILE_INFO_STANDARD finfo struct */
-       pSMB->ParameterOffset = cpu_to_le16(param_offset);
-       pSMB->DataOffset = cpu_to_le16(offset);
-       pSMB->SetupCount = 1;
-       pSMB->Reserved3 = 0;
-       pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
-       count = sizeof(FILE_INFO_STANDARD);
-       byte_count = 3 /* pad */  + params + count;
-
-       pSMB->DataCount = cpu_to_le16(count);
-       pSMB->ParameterCount = cpu_to_le16(params);
-       pSMB->TotalDataCount = pSMB->DataCount;
-       pSMB->TotalParameterCount = pSMB->ParameterCount;
-       pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
-       pSMB->Reserved4 = 0;
-       pSMB->hdr.smb_buf_length += byte_count;
-       pSMB->ByteCount = cpu_to_le16(byte_count);
+       pSMB->attr = cpu_to_le16(dos_attrs);
+       pSMB->BufferFormat = 0x04;
+       pSMB->hdr.smb_buf_length += name_len + 1;
+       pSMB->ByteCount = cpu_to_le16(name_len + 1);
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("SetPathInfo (times legacy) returned %d", rc));
+               cFYI(1, ("Error in LegacySetAttr = %d", rc));
        }
 
        cifs_buf_release(pSMB);
 
        if (rc == -EAGAIN)
-               goto SetTimesRetryLegacy;
+               goto SetAttrLgcyRetry;
 
        return rc;
 }
+#endif /* temporarily unneeded SetAttr legacy function */
 
 int
 CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon,
diff -Nru a/fs/cifs/inode.c b/fs/cifs/inode.c
--- a/fs/cifs/inode.c   2005-03-30 12:08:34 -08:00
+++ b/fs/cifs/inode.c   2005-03-30 12:08:34 -08:00
@@ -417,14 +417,40 @@
                }
        } else if (rc == -EACCES) {
                /* try only if r/o attribute set in local lookup data? */
-               pinfo_buf = (FILE_BASIC_INFO 
*)kmalloc(sizeof(FILE_BASIC_INFO),GFP_KERNEL);
+               pinfo_buf = (FILE_BASIC_INFO *)kmalloc(sizeof(FILE_BASIC_INFO),
+                       GFP_KERNEL);
                if(pinfo_buf) {
                        memset(pinfo_buf,0,sizeof(FILE_BASIC_INFO));        
                /* ATTRS set to normal clears r/o bit */
                        pinfo_buf->Attributes = cpu_to_le32(ATTR_NORMAL);
                        rc = CIFSSMBSetTimes(xid, pTcon, full_path, pinfo_buf,
                                cifs_sb->local_nls);
-                       kfree(pinfo_buf);
+                       if(rc == -EOPNOTSUPP) {
+                               int oplock = FALSE;
+                               __u16 netfid;
+                       /*      rc = CIFSSMBSetAttrLegacy(xid, pTcon, full_path,
+                                                         (__u16)ATTR_NORMAL,
+                                                         cifs_sb->local_nls); 
+                       For some strange reason it seems that NT4 eats the
+                       old setattr call without actually setting the attributes
+                       so on to the third attempted workaround ... */
+
+                       /* BB could scan to see if we already have it open */
+                       /* and pass in pid of opener to function */
+                               rc = CIFSSMBOpen(xid, pTcon, full_path,
+                                               FILE_OPEN,
+                                               FILE_WRITE_ATTRIBUTES,
+                                               CREATE_NOT_DIR, &netfid,
+                                               &oplock, NULL,
+                                               cifs_sb->local_nls);
+                               if(rc==0) {
+                                       rc = CIFSSMBSetFileTimes(xid, pTcon,
+                                                       pinfo_buf, netfid);
+                                       CIFSSMBClose(xid, pTcon, netfid);
+                               }
+                       }
+                       kfree(pinfo_buf); 
+                               
                }
                if(rc==0) {
                        rc = CIFSSMBDelFile(xid, pTcon, full_path, 
cifs_sb->local_nls);
diff -Nru a/fs/cifs/misc.c b/fs/cifs/misc.c
--- a/fs/cifs/misc.c    2005-03-30 12:08:35 -08:00
+++ b/fs/cifs/misc.c    2005-03-30 12:08:35 -08:00
@@ -353,10 +353,14 @@
        if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) ||
            (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) {
                if ((unsigned int)length < 2 + sizeof (struct smb_hdr)) {
-                       cERROR(1, ("Length less than 2 + sizeof smb_hdr "));
-                       if (((unsigned int)length >= sizeof (struct smb_hdr) - 
1)
-                           && (smb->Status.CifsError != 0))
+                       if (((unsigned int)length >= 
+                               sizeof (struct smb_hdr) - 1)
+                           && (smb->Status.CifsError != 0)) {
+                               smb->WordCount = 0;
                                return 0;       /* some error cases do not 
return wct and bcc */
+                       } else {
+                               cERROR(1, ("Length less than smb header size"));
+                       }
 
                }
                if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to