[PATCH] cifs: take reference to inode for oplock breaks
Jeff Layton
jlayton at redhat.com
Mon Aug 31 05:07:11 MDT 2009
When an oplock break comes in, cifs needs to do things like write out
dirty data for it. It doesn't hold a reference to that inode in this
case however. Get an active reference to the inode when an oplock break
comes in. If we don't get a reference, we still need to create an oplock
queue entry so that the oplock release call gets done, but we'll want to
skip writeback in that case.
Signed-off-by: Jeff Layton <jlayton at redhat.com>
---
fs/cifs/cifsfs.c | 26 ++++++++++----------------
fs/cifs/misc.c | 2 +-
2 files changed, 11 insertions(+), 17 deletions(-)
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 2fcc722..647c5bc 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -993,13 +993,8 @@ static int cifs_oplock_thread(void *dummyarg)
cFYI(1, ("found oplock item to write out"));
tcon = oplock->tcon;
inode = oplock->pinode;
- /* can not grab inode sem here since it would
- deadlock when oplock received on delete
- since vfs_unlink holds the i_mutex across
- the call */
- /* mutex_lock(&inode->i_mutex);*/
- cifsi = CIFS_I(inode);
- if (S_ISREG(inode->i_mode)) {
+ if (inode && S_ISREG(inode->i_mode)) {
+ cifsi = CIFS_I(inode);
#ifdef CONFIG_CIFS_EXPERIMENTAL
if (cifsi->clientCanCacheAll == 0)
break_lease(inode, FMODE_READ);
@@ -1010,17 +1005,16 @@ static int cifs_oplock_thread(void *dummyarg)
if (cifsi->clientCanCacheRead == 0) {
waitrc = filemap_fdatawait(
inode->i_mapping);
+ if (rc == 0)
+ rc = waitrc;
invalidate_remote_inode(inode);
}
- if (rc == 0)
- rc = waitrc;
- } else
- rc = 0;
- /* mutex_unlock(&inode->i_mutex);*/
- if (rc)
- cifsi->write_behind_rc = rc;
- cFYI(1, ("Oplock flush inode %p rc %d",
- inode, rc));
+ if (rc)
+ cifsi->write_behind_rc = rc;
+ cFYI(1, ("Oplock flush inode %p rc %d",
+ inode, rc));
+ }
+ iput(inode);
/*
* releasing stale oplock after recent reconnect
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index acdd9fa..ec98910 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -608,7 +608,7 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv,
}
oplock->tcon = tcon;
- oplock->pinode = netfile->pInode;
+ oplock->pinode = igrab(netfile->pInode);
oplock->netfid = netfile->netfid;
spin_lock(&cifs_oplock_lock);
list_add_tail(&oplock->qhead,
--
1.6.0.6
--MP_/29a/jeNjh3405h4FWKpo/NS--
More information about the linux-cifs-client
mailing list