Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d7c86ff8 authored by Jeff Layton's avatar Jeff Layton Committed by Steve French
Browse files

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: default avatarJeff Layton <jlayton@redhat.com>
Reviewed-by: default avatarSuresh Jayaraman <sjayaraman@suse.de>
Acked-by: default avatarDave Kleikamp <shaggy@linux.vnet.ibm.com>
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent a5e18bc3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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;
+18 −0
Original line number Diff line number Diff line
@@ -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)
+2 −4
Original line number Diff line number Diff line
@@ -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;
+0 −1
Original line number Diff line number Diff line
@@ -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. */
+1 −1
Original line number Diff line number Diff line
@@ -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,
Loading