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>
Esse commit está contido em:
@@ -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)
|
||||
|
Referência em uma nova issue
Block a user