From patchwork Thu Nov 11 07:07:02 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Shilovsky X-Patchwork-Id: 316492 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oAB77NaU027379 for ; Thu, 11 Nov 2010 07:07:23 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750742Ab0KKHHW (ORCPT ); Thu, 11 Nov 2010 02:07:22 -0500 Received: from mail-qy0-f174.google.com ([209.85.216.174]:56791 "EHLO mail-qy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757356Ab0KKHHW (ORCPT ); Thu, 11 Nov 2010 02:07:22 -0500 Received: by qyk12 with SMTP id 12so3995221qyk.19 for ; Wed, 10 Nov 2010 23:07:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:subject:date :message-id:x-mailer; bh=dU0F390X6BAjKP4KQBLa1MqGJEDbfpAN0Rfe5PlNkjM=; b=bp6cuD8YGkj1GZ7VnmKixAkiBlqOQ0ncT4YcKYeefEbN5C7RtLlrr81u6Tw+l2WAmO FgrV9BOhCJOut+L5nMcUUqzhdTUCeX/BKY//4iansL9XPzGBjo/qZ+tq02k5Dl6PotM7 qQRfU4ZsrNaMhSy6AuaQEZPspEGIvpZ+xC2RI= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:subject:date:message-id:x-mailer; b=fLfKvP7GLP7m7OrgJlFnADEC0DYdEegSiyfru6r6Z8ACo9GG5/cpFuGaFEVIWE0OlL oKPKAx0xV0iZqaZdrOjC3G3aYcg8srIIkvZDLUi31OmEV9CcQdji7ubungH4koFvQkHT gDQkuqPdek1yY/RcPfmFR3mDll1/rWwRLUwwA= Received: by 10.229.110.8 with SMTP id l8mr478070qcp.144.1289459241361; Wed, 10 Nov 2010 23:07:21 -0800 (PST) Received: from localhost.localdomain ([213.87.194.146]) by mx.google.com with ESMTPS id x9sm1596993qco.46.2010.11.10.23.07.17 (version=TLSv1/SSLv3 cipher=RC4-MD5); Wed, 10 Nov 2010 23:07:20 -0800 (PST) From: Pavel Shilovsky To: linux-cifs@vger.kernel.org Subject: [PATCH 1/6] CIFS: Make cifsFileInfo_put work with strict cache mode Date: Thu, 11 Nov 2010 10:07:02 +0300 Message-Id: <1289459222-8210-1-git-send-email-piastryyy@gmail.com> X-Mailer: git-send-email 1.7.2.3 Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Thu, 11 Nov 2010 07:07:23 +0000 (UTC) diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index e9a393c..be7b159 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h @@ -40,6 +40,7 @@ #define CIFS_MOUNT_FSCACHE 0x8000 /* local caching enabled */ #define CIFS_MOUNT_MF_SYMLINKS 0x10000 /* Minshall+French Symlinks enabled */ #define CIFS_MOUNT_MULTIUSER 0x20000 /* multiuser mount */ +#define CIFS_MOUNT_STRICT_IO 0x40000 /* strict cache mode */ struct cifs_sb_info { struct rb_root tlink_tree; diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 897b2b2..b8d783c 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -61,6 +61,7 @@ extern int cifs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); extern int cifs_revalidate_file(struct file *filp); extern int cifs_revalidate_dentry(struct dentry *); +extern void cifs_invalidate_mapping(struct inode *inode); extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *); extern int cifs_setattr(struct dentry *, struct iattr *); diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 06c3e83..d604e09 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -124,19 +124,11 @@ static inline int cifs_open_inode_helper(struct inode *inode, temp = cifs_NTtimeToUnix(buf->LastWriteTime); if (timespec_equal(&inode->i_mtime, &temp) && (inode->i_size == - (loff_t)le64_to_cpu(buf->EndOfFile))) { + (loff_t)le64_to_cpu(buf->EndOfFile)) && + !pCifsInode->invalid_mapping) { cFYI(1, "inode unchanged on server"); - } else { - if (inode->i_mapping) { - /* BB no need to lock inode until after invalidate - since namei code should already have it locked? */ - rc = filemap_write_and_wait(inode->i_mapping); - mapping_set_error(inode->i_mapping, rc); - } - cFYI(1, "invalidating remote inode since open detected it " - "changed"); - invalidate_remote_inode(inode); - } + } else + cifs_invalidate_mapping(inode); client_can_cache: if (pTcon->unix_ext) @@ -250,6 +242,9 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file, cifs_set_oplock_level(pCifsInode, oplock); + if (pCifsInode->invalid_mapping) + cifs_invalidate_mapping(inode); + file->private_data = pCifsFile; return pCifsFile; } @@ -264,6 +259,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) struct inode *inode = cifs_file->dentry->d_inode; struct cifsTconInfo *tcon = tlink_tcon(cifs_file->tlink); struct cifsInodeInfo *cifsi = CIFS_I(inode); + struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifsLockInfo *li, *tmp; spin_lock(&cifs_file_list_lock); @@ -279,6 +275,13 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) if (list_empty(&cifsi->openFileList)) { cFYI(1, "closing last open instance for inode %p", cifs_file->dentry->d_inode); + + /* in strict cache mode we need invalidate mapping on the last + close because it may cause a error when we open this file + again and get at least level II oplock */ + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) + CIFS_I(inode)->invalid_mapping = true; + cifs_set_oplock_level(cifsi, 0); } spin_unlock(&cifs_file_list_lock); diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index ef3a55b..518514e 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -1671,8 +1671,7 @@ cifs_inode_needs_reval(struct inode *inode) } /* check invalid_mapping flag and zap the cache if it's set */ -static void -cifs_invalidate_mapping(struct inode *inode) +void cifs_invalidate_mapping(struct inode *inode) { int rc; struct cifsInodeInfo *cifs_i = CIFS_I(inode);