From patchwork Mon Sep 10 12:19:33 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Shilovsky X-Patchwork-Id: 1432011 Return-Path: X-Original-To: patchwork-cifs-client@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 8440140220 for ; Mon, 10 Sep 2012 12:19:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757691Ab2IJMTx (ORCPT ); Mon, 10 Sep 2012 08:19:53 -0400 Received: from mail-lb0-f174.google.com ([209.85.217.174]:39807 "EHLO mail-lb0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757687Ab2IJMTw (ORCPT ); Mon, 10 Sep 2012 08:19:52 -0400 Received: by mail-lb0-f174.google.com with SMTP id gj3so1125411lbb.19 for ; Mon, 10 Sep 2012 05:19:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:subject:date:message-id:x-mailer:in-reply-to:references; bh=12d5fndCQZ78/yyHgcJaUlvzqT0dHBOyThryhQ9Ava0=; b=IpBn0vyekwrhU47JYf17hIBmXSStNQMYUT6p627JokkR34cGYzfxr2VosXtJOXo4Q+ J89zwbYoesBWfbLY8l1YK8QYcH6CKGzSc54vXmUuTZxF0gAqJ7hTX8VZ6HrwT4S2buPT 2i0naT84hflLTBiY4TduHXGL5KVDejeSIoRpx0or3qtSpSB/vzbkyjdpybeN7lyvXtw8 hXnRxg+Zh+W0/KYn/pLtqoYFRsQnehPkBtiOpB62ty+5Mb650dIlBifw+PtbEF09fr56 PMZcg1+11gDpTwtqdXvZjwPTYwpqbm2E7wi9Qv7QqV/yY3HuV6o+b/elSbQDO0c6rYjg /Wsg== Received: by 10.152.113.68 with SMTP id iw4mr12549143lab.50.1347279591899; Mon, 10 Sep 2012 05:19:51 -0700 (PDT) Received: from localhost.localdomain ([178.45.128.11]) by mx.google.com with ESMTPS id r8sm3514851lba.15.2012.09.10.05.19.49 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 10 Sep 2012 05:19:50 -0700 (PDT) From: Pavel Shilovsky To: linux-cifs@vger.kernel.org Subject: [PATCH v3 5/7] CIFS: Use brlock cache for SMB2 Date: Mon, 10 Sep 2012 16:19:33 +0400 Message-Id: <1347279575-6071-6-git-send-email-pshilovsky@etersoft.ru> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1347279575-6071-1-git-send-email-pshilovsky@etersoft.ru> References: <1347279575-6071-1-git-send-email-pshilovsky@etersoft.ru> Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Signed-off-by: Pavel Shilovsky --- fs/cifs/smb2file.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++ fs/cifs/smb2ops.c | 3 +- fs/cifs/smb2proto.h | 1 + 3 files changed, 94 insertions(+), 1 deletions(-) diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c index a25ea02..181e13d 100644 --- a/fs/cifs/smb2file.c +++ b/fs/cifs/smb2file.c @@ -201,3 +201,94 @@ smb2_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock, kfree(buf); return rc; } + +static int +smb2_push_mand_fdlocks(struct cifs_fid_locks *fdlocks, const unsigned int xid, + struct smb2_lock_element *buf, unsigned int max_num) +{ + int rc = 0, stored_rc; + struct cifsFileInfo *cfile = fdlocks->cfile; + struct cifsLockInfo *li; + unsigned int num = 0; + struct smb2_lock_element *cur = buf; + struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); + + list_for_each_entry(li, &fdlocks->locks, llist) { + cur->Length = cpu_to_le64(li->length); + cur->Offset = cpu_to_le64(li->offset); + cur->Flags = cpu_to_le32(li->type | + SMB2_LOCKFLAG_FAIL_IMMEDIATELY); + if (++num == max_num) { + stored_rc = smb2_lockv(xid, tcon, + cfile->fid.persistent_fid, + cfile->fid.volatile_fid, + current->tgid, num, buf); + if (stored_rc) + rc = stored_rc; + cur = buf; + num = 0; + } else + cur++; + } + if (num) { + stored_rc = smb2_lockv(xid, tcon, + cfile->fid.persistent_fid, + cfile->fid.volatile_fid, + current->tgid, num, buf); + if (stored_rc) + rc = stored_rc; + } + + return rc; +} + +int +smb2_push_mandatory_locks(struct cifsFileInfo *cfile) +{ + int rc = 0, stored_rc; + unsigned int xid; + unsigned int max_num, max_buf; + struct smb2_lock_element *buf; + struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode); + struct cifs_fid_locks *fdlocks; + + xid = get_xid(); + mutex_lock(&cinode->lock_mutex); + if (!cinode->can_cache_brlcks) { + mutex_unlock(&cinode->lock_mutex); + free_xid(xid); + return rc; + } + + /* + * Accessing maxBuf is racy with cifs_reconnect - need to store value + * and check it for zero before using. + */ + max_buf = tlink_tcon(cfile->tlink)->ses->server->maxBuf; + if (!max_buf) { + mutex_unlock(&cinode->lock_mutex); + free_xid(xid); + return -EINVAL; + } + + max_num = max_buf / sizeof(struct smb2_lock_element); + buf = kzalloc(max_num * sizeof(struct smb2_lock_element), GFP_KERNEL); + if (!buf) { + mutex_unlock(&cinode->lock_mutex); + free_xid(xid); + return -ENOMEM; + } + + list_for_each_entry(fdlocks, &cinode->llist, llist) { + stored_rc = smb2_push_mand_fdlocks(fdlocks, xid, buf, max_num); + if (stored_rc) + rc = stored_rc; + } + + cinode->can_cache_brlcks = false; + kfree(buf); + + mutex_unlock(&cinode->lock_mutex); + free_xid(xid); + return rc; +} diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index caed2c5..0808b23 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -371,7 +371,7 @@ smb2_set_fid(struct cifsFileInfo *cfile, struct cifs_fid *fid, __u32 oplock) cfile->fid.persistent_fid = fid->persistent_fid; cfile->fid.volatile_fid = fid->volatile_fid; smb2_set_oplock_level(cinode, oplock); - /* cinode->can_cache_brlcks = cinode->clientCanCacheAll; */ + cinode->can_cache_brlcks = cinode->clientCanCacheAll; } static int @@ -615,6 +615,7 @@ struct smb_version_operations smb21_operations = { .queryfs = smb2_queryfs, .mand_lock = smb2_mand_lock, .mand_unlock_range = smb2_unlock_range, + .push_mand_locks = smb2_push_mandatory_locks, }; struct smb_version_values smb21_values = { diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index ab19152..8b4d371 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h @@ -86,6 +86,7 @@ extern int smb2_open_file(const unsigned int xid, struct cifs_tcon *tcon, extern void smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock); extern int smb2_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock, const unsigned int xid); +extern int smb2_push_mandatory_locks(struct cifsFileInfo *cfile); /* * SMB2 Worker functions - most of protocol specific implementation details