]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
cifs: don't use vfsmount to pin superblock for oplock breaks
authorJeff Layton <jlayton@redhat.com>
Mon, 11 Oct 2010 19:07:19 +0000 (15:07 -0400)
committerSteve French <sfrench@us.ibm.com>
Tue, 12 Oct 2010 18:08:01 +0000 (18:08 +0000)
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>
fs/cifs/cifs_fs_sb.h
fs/cifs/cifsfs.c
fs/cifs/cifsfs.h
fs/cifs/cifsglob.h
fs/cifs/cifsproto.h
fs/cifs/dir.c
fs/cifs/file.c

index 586ee3d527d207ff176720075f4c8b9329cba102..525ba59a41058a6d13f4311fb841eb2604a00140 100644 (file)
@@ -48,6 +48,7 @@ struct cifs_sb_info {
        struct nls_table *local_nls;
        unsigned int rsize;
        unsigned int wsize;
+       atomic_t active;
        uid_t   mnt_uid;
        gid_t   mnt_gid;
        mode_t  mnt_file_mode;
index 3258c822328b97a28344406fa1625973b95ffcbe..cbd468c880c4e36e5377bb307e3d9f603cae8ed9 100644 (file)
@@ -83,6 +83,24 @@ extern mempool_t *cifs_sm_req_poolp;
 extern mempool_t *cifs_req_poolp;
 extern mempool_t *cifs_mid_poolp;
 
+void
+cifs_sb_active(struct super_block *sb)
+{
+       struct cifs_sb_info *server = CIFS_SB(sb);
+
+       if (atomic_inc_return(&server->active) == 1)
+               atomic_inc(&sb->s_active);
+}
+
+void
+cifs_sb_deactive(struct super_block *sb)
+{
+       struct cifs_sb_info *server = CIFS_SB(sb);
+
+       if (atomic_dec_and_test(&server->active))
+               deactivate_super(sb);
+}
+
 static int
 cifs_read_super(struct super_block *sb, void *data,
                const char *devname, int silent)
index 786bdf36aebfbd7df0d7f53633e28a3eea4ded56..85544bcab517f475aefe105f24f91450ade9ba69 100644 (file)
@@ -42,10 +42,8 @@ extern const struct address_space_operations cifs_addr_ops;
 extern const struct address_space_operations cifs_addr_ops_smallbuf;
 
 /* Functions related to super block operations */
-/* extern const struct super_operations cifs_super_ops;*/
-extern void cifs_read_inode(struct inode *);
-/*extern void cifs_delete_inode(struct inode *);*/  /* BB not needed yet */
-/* extern void cifs_write_inode(struct inode *); */ /* BB not needed yet */
+extern void cifs_sb_active(struct super_block *sb);
+extern void cifs_sb_deactive(struct super_block *sb);
 
 /* Functions related to inodes */
 extern const struct inode_operations cifs_dir_inode_ops;
index 8289e61937a2cffd27c3fa5b1c122ddb44fc11fd..e2b760ef22fffbf9dd802be19c9b000e0866d649 100644 (file)
@@ -388,7 +388,6 @@ struct cifsFileInfo {
        /* lock scope id (0 if none) */
        struct file *pfile; /* needed for writepage */
        struct dentry *dentry;
-       struct vfsmount *mnt;
        struct tcon_link *tlink;
        struct mutex lock_mutex;
        struct list_head llist; /* list of byte range locks we have. */
index 29a2ee8ae51f0d3c39780d8fe8f835e4310473a5..7f416abd34cf34328904d913a3b4deb20e514712 100644 (file)
@@ -107,7 +107,7 @@ extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
 
 extern struct cifsFileInfo *cifs_new_fileinfo(struct inode *newinode,
                                __u16 fileHandle, struct file *file,
-                               struct vfsmount *mnt, struct tcon_link *tlink,
+                               struct tcon_link *tlink,
                                unsigned int oflags, __u32 oplock);
 extern int cifs_posix_open(char *full_path, struct inode **pinode,
                                struct super_block *sb,
index 6887c412c61a635ee6b214629cdab2f4b44f136b..c205ec9293eaae3e00c23f6cd815f869988cc16e 100644 (file)
@@ -132,8 +132,7 @@ cifs_bp_rename_retry:
 
 struct cifsFileInfo *
 cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, struct file *file,
-                 struct vfsmount *mnt, struct tcon_link *tlink,
-                 unsigned int oflags, __u32 oplock)
+                 struct tcon_link *tlink, unsigned int oflags, __u32 oplock)
 {
        struct dentry *dentry = file->f_path.dentry;
        struct cifsFileInfo *pCifsFile;
@@ -147,7 +146,6 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, struct file *file,
        pCifsFile->pid = current->tgid;
        pCifsFile->uid = current_fsuid();
        pCifsFile->dentry = dget(dentry);
-       pCifsFile->mnt = mnt;
        pCifsFile->pfile = file;
        pCifsFile->invalidHandle = false;
        pCifsFile->closePend = false;
@@ -485,8 +483,7 @@ cifs_create_set_dentry:
                }
 
                pfile_info = cifs_new_fileinfo(newinode, fileHandle, filp,
-                                               nd->path.mnt, tlink, oflags,
-                                               oplock);
+                                               tlink, oflags, oplock);
                if (pfile_info == NULL) {
                        fput(filp);
                        CIFSSMBClose(xid, tcon, fileHandle);
@@ -760,8 +757,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
                        }
 
                        cfile = cifs_new_fileinfo(newInode, fileHandle, filp,
-                                                 nd->path.mnt, tlink,
-                                                 nd->intent.open.flags,
+                                                 tlink, nd->intent.open.flags,
                                                  oplock);
                        if (cfile == NULL) {
                                fput(filp);
index c302b9c5264488f598c53095f2fc2fd16bb32dab..fd78a355f634d921e62a197778158b8ada7f9fba 100644 (file)
@@ -282,7 +282,6 @@ int cifs_open(struct inode *inode, struct file *file)
                        }
 
                        pCifsFile = cifs_new_fileinfo(inode, netfid, file,
-                                                       file->f_path.mnt,
                                                        tlink, oflags, oplock);
                        if (pCifsFile == NULL) {
                                CIFSSMBClose(xid, tcon, netfid);
@@ -375,8 +374,8 @@ int cifs_open(struct inode *inode, struct file *file)
        if (rc != 0)
                goto out;
 
-       pCifsFile = cifs_new_fileinfo(inode, netfid, file, file->f_path.mnt,
-                                       tlink, file->f_flags, oplock);
+       pCifsFile = cifs_new_fileinfo(inode, netfid, file, tlink,
+                                       file->f_flags, oplock);
        if (pCifsFile == NULL) {
                rc = -ENOMEM;
                goto out;
@@ -2381,14 +2380,14 @@ void cifs_oplock_break(struct work_struct *work)
 
 void cifs_oplock_break_get(struct cifsFileInfo *cfile)
 {
-       mntget(cfile->mnt);
+       cifs_sb_active(cfile->dentry->d_sb);
        cifsFileInfo_get(cfile);
 }
 
 void cifs_oplock_break_put(struct cifsFileInfo *cfile)
 {
-       mntput(cfile->mnt);
        cifsFileInfo_put(cfile);
+       cifs_sb_deactive(cfile->dentry->d_sb);
 }
 
 const struct address_space_operations cifs_addr_ops = {