diff options
author | Jeff Layton <jlayton@redhat.com> | 2009-09-21 06:47:50 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2009-09-24 14:33:18 -0400 |
commit | 3bc303c254335dbd7c7012cc1760b12f1d5514d3 (patch) | |
tree | 7da17fbfd697216d9ed0ccd64ea9c03aaf3d52c1 /fs/cifs/cifsproto.h | |
parent | 48541bd3dd4739b4d574b44ea47660c88d833677 (diff) |
cifs: convert oplock breaks to use slow_work facility (try #4)
This is the fourth respin of the patch to convert oplock breaks to
use the slow_work facility.
A customer of ours was testing a backport of one of the earlier
patchsets, and hit a "Busy inodes after umount..." problem. An oplock
break job had raced with a umount, and the superblock got torn down and
its memory reused. When the oplock break job tried to dereference the
inode->i_sb, the kernel oopsed.
This patchset has the oplock break job hold an inode and vfsmount
reference until the oplock break completes. With this, there should be
no need to take a tcon reference (the vfsmount implicitly holds one
already).
Currently, when an oplock break comes in there's a chance that the
oplock break job won't occur if the allocation of the oplock_q_entry
fails. There are also some rather nasty races in the allocation and
handling these structs.
Rather than allocating oplock queue entries when an oplock break comes
in, add a few extra fields to the cifsFileInfo struct. Get rid of the
dedicated cifs_oplock_thread as well and queue the oplock break job to
the slow_work thread pool.
This approach also has the advantage that the oplock break jobs can
potentially run in parallel rather than be serialized like they are
today.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/cifsproto.h')
-rw-r--r-- | fs/cifs/cifsproto.h | 6 |
1 files changed, 1 insertions, 5 deletions
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index bf3ae881b2d5..733e71b57c7a 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -86,17 +86,13 @@ extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
86 | const int stage, | 86 | const int stage, |
87 | const struct nls_table *nls_cp); | 87 | const struct nls_table *nls_cp); |
88 | extern __u16 GetNextMid(struct TCP_Server_Info *server); | 88 | extern __u16 GetNextMid(struct TCP_Server_Info *server); |
89 | extern struct oplock_q_entry *AllocOplockQEntry(struct inode *, u16, | ||
90 | struct cifsTconInfo *); | ||
91 | extern void DeleteOplockQEntry(struct oplock_q_entry *); | ||
92 | extern void DeleteTconOplockQEntries(struct cifsTconInfo *); | ||
93 | extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601); | 89 | extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601); |
94 | extern u64 cifs_UnixTimeToNT(struct timespec); | 90 | extern u64 cifs_UnixTimeToNT(struct timespec); |
95 | extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, | 91 | extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, |
96 | int offset); | 92 | int offset); |
97 | 93 | ||
98 | extern int cifs_posix_open(char *full_path, struct inode **pinode, | 94 | extern int cifs_posix_open(char *full_path, struct inode **pinode, |
99 | struct super_block *sb, int mode, int oflags, | 95 | struct vfsmount *mnt, int mode, int oflags, |
100 | __u32 *poplock, __u16 *pnetfid, int xid); | 96 | __u32 *poplock, __u16 *pnetfid, int xid); |
101 | extern void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, | 97 | extern void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, |
102 | FILE_UNIX_BASIC_INFO *info, | 98 | FILE_UNIX_BASIC_INFO *info, |