diff options
author | Jeff Layton <jlayton@redhat.com> | 2010-10-11 15:07:19 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2010-10-12 14:08:01 -0400 |
commit | d7c86ff8cd00abc730fe5d031f43dc9138b6324e (patch) | |
tree | a1f264ce2f33e3ac77a459291b9a5e45a63e3bff /fs/cifs/dir.c | |
parent | a5e18bc36e9e05ce0338d370a2ce4290910e43ea (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/dir.c')
-rw-r--r-- | fs/cifs/dir.c | 10 |
1 files changed, 3 insertions, 7 deletions
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 6887c412c61a..c205ec9293ea 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -132,8 +132,7 @@ cifs_bp_rename_retry: | |||
132 | 132 | ||
133 | struct cifsFileInfo * | 133 | struct cifsFileInfo * |
134 | cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, struct file *file, | 134 | cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, struct file *file, |
135 | struct vfsmount *mnt, struct tcon_link *tlink, | 135 | struct tcon_link *tlink, unsigned int oflags, __u32 oplock) |
136 | unsigned int oflags, __u32 oplock) | ||
137 | { | 136 | { |
138 | struct dentry *dentry = file->f_path.dentry; | 137 | struct dentry *dentry = file->f_path.dentry; |
139 | struct cifsFileInfo *pCifsFile; | 138 | struct cifsFileInfo *pCifsFile; |
@@ -147,7 +146,6 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, struct file *file, | |||
147 | pCifsFile->pid = current->tgid; | 146 | pCifsFile->pid = current->tgid; |
148 | pCifsFile->uid = current_fsuid(); | 147 | pCifsFile->uid = current_fsuid(); |
149 | pCifsFile->dentry = dget(dentry); | 148 | pCifsFile->dentry = dget(dentry); |
150 | pCifsFile->mnt = mnt; | ||
151 | pCifsFile->pfile = file; | 149 | pCifsFile->pfile = file; |
152 | pCifsFile->invalidHandle = false; | 150 | pCifsFile->invalidHandle = false; |
153 | pCifsFile->closePend = false; | 151 | pCifsFile->closePend = false; |
@@ -485,8 +483,7 @@ cifs_create_set_dentry: | |||
485 | } | 483 | } |
486 | 484 | ||
487 | pfile_info = cifs_new_fileinfo(newinode, fileHandle, filp, | 485 | pfile_info = cifs_new_fileinfo(newinode, fileHandle, filp, |
488 | nd->path.mnt, tlink, oflags, | 486 | tlink, oflags, oplock); |
489 | oplock); | ||
490 | if (pfile_info == NULL) { | 487 | if (pfile_info == NULL) { |
491 | fput(filp); | 488 | fput(filp); |
492 | CIFSSMBClose(xid, tcon, fileHandle); | 489 | CIFSSMBClose(xid, tcon, fileHandle); |
@@ -760,8 +757,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
760 | } | 757 | } |
761 | 758 | ||
762 | cfile = cifs_new_fileinfo(newInode, fileHandle, filp, | 759 | cfile = cifs_new_fileinfo(newInode, fileHandle, filp, |
763 | nd->path.mnt, tlink, | 760 | tlink, nd->intent.open.flags, |
764 | nd->intent.open.flags, | ||
765 | oplock); | 761 | oplock); |
766 | if (cfile == NULL) { | 762 | if (cfile == NULL) { |
767 | fput(filp); | 763 | fput(filp); |