From patchwork Fri Aug 31 09:41:26 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Shilovsky X-Patchwork-Id: 1392361 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 18BE63FDF6 for ; Fri, 31 Aug 2012 09:41:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752081Ab2HaJlt (ORCPT ); Fri, 31 Aug 2012 05:41:49 -0400 Received: from mail-lpp01m010-f46.google.com ([209.85.215.46]:47623 "EHLO mail-lpp01m010-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751780Ab2HaJlt (ORCPT ); Fri, 31 Aug 2012 05:41:49 -0400 Received: by mail-lpp01m010-f46.google.com with SMTP id y9so2146322lag.19 for ; Fri, 31 Aug 2012 02:41:48 -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=ZxmrMIkO4IhAVtgMBehTqTQuZon9s0vA93wwOgi8C+zgf7zHVbLpJPxzufImbmDJo1 K2UyooVigAPnrRHMzRTTxjOkWTgmPI/HO0krlD6xu8nD6kcLLZEv+aloPTL6jZUbbNIL h1g7nY9RHN8RJ731zQxqZbKk3bT6CUw32fVZRzG80CvLN9tu6lppgMsklu98h46ys4Xp 0NTIuLDQ55CvfC2zZgkkCG4dZQbtb3fV+gmRrGX/uzRwA2s+ekdylk8XmcVcB0pGCpvL OZRDdF5h86F9y9sM7o+O5cJCF8xRvCZwr9Lpz4X07OzT3uJD+R5EQFjD4YXRFRhvdyjL vJ4g== Received: by 10.152.123.140 with SMTP id ma12mr5984956lab.22.1346406108652; Fri, 31 Aug 2012 02:41:48 -0700 (PDT) Received: from localhost.localdomain ([95.84.16.136]) by mx.google.com with ESMTPS id lv13sm4283257lab.8.2012.08.31.02.41.46 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 31 Aug 2012 02:41:47 -0700 (PDT) From: Pavel Shilovsky To: linux-cifs@vger.kernel.org Subject: [PATCH v2 5/7] CIFS: Use brlock cache for SMB2 Date: Fri, 31 Aug 2012 13:41:26 +0400 Message-Id: <1346406088-4537-6-git-send-email-pshilovsky@etersoft.ru> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1346406088-4537-1-git-send-email-pshilovsky@etersoft.ru> References: <1346406088-4537-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