CIFS: Make cifs_push_locks send as many locks at once as possible
authorPavel Shilovsky <piastry@etersoft.ru>
Sat, 22 Oct 2011 11:33:32 +0000 (15:33 +0400)
committerSteve French <smfrench@gmail.com>
Mon, 24 Oct 2011 18:11:55 +0000 (13:11 -0500)
that reduces a traffic and increases a performance.

Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
Acked-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <smfrench@gmail.com>
fs/cifs/file.c

index 569184e6ee0191fec4ef51c504918f0223ab945f..ea096ce5d4f7e86b94df26ac319cca8769c38595 100644 (file)
@@ -829,6 +829,11 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
        struct cifsLockInfo *li, *tmp;
        struct cifs_tcon *tcon;
        struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
+       unsigned int num, max_num;
+       LOCKING_ANDX_RANGE *buf, *cur;
+       int types[] = {LOCKING_ANDX_LARGE_FILES,
+                      LOCKING_ANDX_SHARED_LOCK | LOCKING_ANDX_LARGE_FILES};
+       int i;
 
        xid = GetXid();
        tcon = tlink_tcon(cfile->tlink);
@@ -840,17 +845,49 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
                return rc;
        }
 
-       list_for_each_entry_safe(li, tmp, &cinode->llist, llist) {
-               stored_rc = CIFSSMBLock(xid, tcon, cfile->netfid,
-                                       li->pid, li->length, li->offset,
-                                       0, 1, li->type, 0, 0);
-               if (stored_rc)
-                       rc = stored_rc;
+       max_num = (tcon->ses->server->maxBuf - sizeof(struct smb_hdr)) /
+                 sizeof(LOCKING_ANDX_RANGE);
+       buf = kzalloc(max_num * sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL);
+       if (!buf) {
+               mutex_unlock(&cinode->lock_mutex);
+               FreeXid(xid);
+               return rc;
+       }
+
+       for (i = 0; i < 2; i++) {
+               cur = buf;
+               num = 0;
+               list_for_each_entry_safe(li, tmp, &cinode->llist, llist) {
+                       if (li->type != types[i])
+                               continue;
+                       cur->Pid = cpu_to_le16(li->pid);
+                       cur->LengthLow = cpu_to_le32((u32)li->length);
+                       cur->LengthHigh = cpu_to_le32((u32)(li->length>>32));
+                       cur->OffsetLow = cpu_to_le32((u32)li->offset);
+                       cur->OffsetHigh = cpu_to_le32((u32)(li->offset>>32));
+                       if (++num == max_num) {
+                               stored_rc = cifs_lockv(xid, tcon, cfile->netfid,
+                                                      li->type, 0, num, buf);
+                               if (stored_rc)
+                                       rc = stored_rc;
+                               cur = buf;
+                               num = 0;
+                       } else
+                               cur++;
+               }
+
+               if (num) {
+                       stored_rc = cifs_lockv(xid, tcon, cfile->netfid,
+                                              types[i], 0, num, buf);
+                       if (stored_rc)
+                               rc = stored_rc;
+               }
        }
 
        cinode->can_cache_brlcks = false;
        mutex_unlock(&cinode->lock_mutex);
 
+       kfree(buf);
        FreeXid(xid);
        return rc;
 }