aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/file.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2010-10-11 15:07:19 -0400
committerSteve French <sfrench@us.ibm.com>2010-10-12 14:08:01 -0400
commitd7c86ff8cd00abc730fe5d031f43dc9138b6324e (patch)
treea1f264ce2f33e3ac77a459291b9a5e45a63e3bff /fs/cifs/file.c
parenta5e18bc36e9e05ce0338d370a2ce4290910e43ea (diff)
cifs: don't use vfsmount to pin superblock for oplock breaks
Filesystems aren't really supposed to do anything with a vfsmount. It's considered a layering violation since vfsmounts are entirely managed at the VFS layer. CIFS currently keeps an active reference to a vfsmount in order to prevent the superblock vanishing before an oplock break has completed. What we really want to do instead is to keep sb->s_active high until the oplock break has completed. This patch borrows the scheme that NFS uses for handling sillyrenames. An atomic_t is added to the cifs_sb_info. When it transitions from 0 to 1, an extra reference to the superblock is taken (by bumping the s_active value). When it transitions from 1 to 0, that reference is dropped and a the superblock teardown may proceed if there are no more references to it. Also, the vfsmount pointer is removed from cifsFileInfo and from cifs_new_fileinfo, and some bogus forward declarations are removed from cifsfs.h. Signed-off-by: Jeff Layton <jlayton@redhat.com> Reviewed-by: Suresh Jayaraman <sjayaraman@suse.de> Acked-by: Dave Kleikamp <shaggy@linux.vnet.ibm.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r--fs/cifs/file.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index c302b9c52644..fd78a355f634 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -282,7 +282,6 @@ int cifs_open(struct inode *inode, struct file *file)
282 } 282 }
283 283
284 pCifsFile = cifs_new_fileinfo(inode, netfid, file, 284 pCifsFile = cifs_new_fileinfo(inode, netfid, file,
285 file->f_path.mnt,
286 tlink, oflags, oplock); 285 tlink, oflags, oplock);
287 if (pCifsFile == NULL) { 286 if (pCifsFile == NULL) {
288 CIFSSMBClose(xid, tcon, netfid); 287 CIFSSMBClose(xid, tcon, netfid);
@@ -375,8 +374,8 @@ int cifs_open(struct inode *inode, struct file *file)
375 if (rc != 0) 374 if (rc != 0)
376 goto out; 375 goto out;
377 376
378 pCifsFile = cifs_new_fileinfo(inode, netfid, file, file->f_path.mnt, 377 pCifsFile = cifs_new_fileinfo(inode, netfid, file, tlink,
379 tlink, file->f_flags, oplock); 378 file->f_flags, oplock);
380 if (pCifsFile == NULL) { 379 if (pCifsFile == NULL) {
381 rc = -ENOMEM; 380 rc = -ENOMEM;
382 goto out; 381 goto out;
@@ -2381,14 +2380,14 @@ void cifs_oplock_break(struct work_struct *work)
2381 2380
2382void cifs_oplock_break_get(struct cifsFileInfo *cfile) 2381void cifs_oplock_break_get(struct cifsFileInfo *cfile)
2383{ 2382{
2384 mntget(cfile->mnt); 2383 cifs_sb_active(cfile->dentry->d_sb);
2385 cifsFileInfo_get(cfile); 2384 cifsFileInfo_get(cfile);
2386} 2385}
2387 2386
2388void cifs_oplock_break_put(struct cifsFileInfo *cfile) 2387void cifs_oplock_break_put(struct cifsFileInfo *cfile)
2389{ 2388{
2390 mntput(cfile->mnt);
2391 cifsFileInfo_put(cfile); 2389 cifsFileInfo_put(cfile);
2390 cifs_sb_deactive(cfile->dentry->d_sb);
2392} 2391}
2393 2392
2394const struct address_space_operations cifs_addr_ops = { 2393const struct address_space_operations cifs_addr_ops = {