cifs: use existing handle for compound_op(OP_SET_INFO) when possible
authorRonnie Sahlberg <lsahlber@redhat.com>
Thu, 29 Aug 2019 23:53:56 +0000 (09:53 +1000)
committerSteve French <stfrench@microsoft.com>
Mon, 16 Sep 2019 16:43:37 +0000 (11:43 -0500)
If we already have a writable handle for a path we want to set the
attributes for then use that instead of a create/set-info/close compound.

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/cifs/smb2inode.c

index 939fc7b..9bb0a5b 100644 (file)
@@ -192,14 +192,27 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
                size[0] = sizeof(FILE_BASIC_INFO);
                data[0] = ptr;
 
-               rc = SMB2_set_info_init(tcon, &rqst[num_rqst], COMPOUND_FID,
-                                       COMPOUND_FID, current->tgid,
-                                       FILE_BASIC_INFORMATION,
-                                       SMB2_O_INFO_FILE, 0, data, size);
+               if (cfile)
+                       rc = SMB2_set_info_init(tcon, &rqst[num_rqst],
+                               cfile->fid.persistent_fid,
+                               cfile->fid.volatile_fid, current->tgid,
+                               FILE_BASIC_INFORMATION,
+                               SMB2_O_INFO_FILE, 0, data, size);
+               else {
+                       rc = SMB2_set_info_init(tcon, &rqst[num_rqst],
+                               COMPOUND_FID,
+                               COMPOUND_FID, current->tgid,
+                               FILE_BASIC_INFORMATION,
+                               SMB2_O_INFO_FILE, 0, data, size);
+                       if (!rc) {
+                               smb2_set_next_command(tcon, &rqst[num_rqst]);
+                               smb2_set_related(&rqst[num_rqst]);
+                       }
+               }
+
                if (rc)
                        goto finished;
-               smb2_set_next_command(tcon, &rqst[num_rqst]);
-               smb2_set_related(&rqst[num_rqst++]);
+               num_rqst++;
                trace_smb3_set_info_compound_enter(xid, ses->Suid, tcon->tid,
                                                   full_path);
                break;
@@ -231,8 +244,10 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
                                        COMPOUND_FID, COMPOUND_FID,
                                        current->tgid, FILE_RENAME_INFORMATION,
                                        SMB2_O_INFO_FILE, 0, data, size);
-                       smb2_set_next_command(tcon, &rqst[num_rqst]);
-                       smb2_set_related(&rqst[num_rqst]);
+                       if (!rc) {
+                               smb2_set_next_command(tcon, &rqst[num_rqst]);
+                               smb2_set_related(&rqst[num_rqst]);
+                       }
                }
                if (rc)
                        goto finished;
@@ -475,6 +490,7 @@ smb2_mkdir_setinfo(struct inode *inode, const char *name,
 {
        FILE_BASIC_INFO data;
        struct cifsInodeInfo *cifs_i;
+       struct cifsFileInfo *cfile;
        u32 dosattrs;
        int tmprc;
 
@@ -482,10 +498,11 @@ smb2_mkdir_setinfo(struct inode *inode, const char *name,
        cifs_i = CIFS_I(inode);
        dosattrs = cifs_i->cifsAttrs | ATTR_READONLY;
        data.Attributes = cpu_to_le32(dosattrs);
+       cifs_get_writable_path(tcon, name, &cfile);
        tmprc = smb2_compound_op(xid, tcon, cifs_sb, name,
                                 FILE_WRITE_ATTRIBUTES, FILE_CREATE,
                                 CREATE_NOT_FILE, &data, SMB2_OP_SET_INFO,
-                                NULL);
+                                cfile);
        if (tmprc == 0)
                cifs_i->cifsAttrs = dosattrs;
 }