aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifsglob.h
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2009-09-21 06:47:50 -0400
committerSteve French <sfrench@us.ibm.com>2009-09-24 14:33:18 -0400
commit3bc303c254335dbd7c7012cc1760b12f1d5514d3 (patch)
tree7da17fbfd697216d9ed0ccd64ea9c03aaf3d52c1 /fs/cifs/cifsglob.h
parent48541bd3dd4739b4d574b44ea47660c88d833677 (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/cifsglob.h')
-rw-r--r--fs/cifs/cifsglob.h12
1 files changed, 5 insertions, 7 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index c19419a38f62..5d0fde18039c 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -18,6 +18,7 @@
18 */ 18 */
19#include <linux/in.h> 19#include <linux/in.h>
20#include <linux/in6.h> 20#include <linux/in6.h>
21#include <linux/slow-work.h>
21#include "cifs_fs_sb.h" 22#include "cifs_fs_sb.h"
22#include "cifsacl.h" 23#include "cifsacl.h"
23/* 24/*
@@ -346,14 +347,16 @@ struct cifsFileInfo {
346 /* lock scope id (0 if none) */ 347 /* lock scope id (0 if none) */
347 struct file *pfile; /* needed for writepage */ 348 struct file *pfile; /* needed for writepage */
348 struct inode *pInode; /* needed for oplock break */ 349 struct inode *pInode; /* needed for oplock break */
350 struct vfsmount *mnt;
349 struct mutex lock_mutex; 351 struct mutex lock_mutex;
350 struct list_head llist; /* list of byte range locks we have. */ 352 struct list_head llist; /* list of byte range locks we have. */
351 bool closePend:1; /* file is marked to close */ 353 bool closePend:1; /* file is marked to close */
352 bool invalidHandle:1; /* file closed via session abend */ 354 bool invalidHandle:1; /* file closed via session abend */
353 bool messageMode:1; /* for pipes: message vs byte mode */ 355 bool oplock_break_cancelled:1;
354 atomic_t count; /* reference count */ 356 atomic_t count; /* reference count */
355 struct mutex fh_mutex; /* prevents reopen race after dead ses*/ 357 struct mutex fh_mutex; /* prevents reopen race after dead ses*/
356 struct cifs_search_info srch_inf; 358 struct cifs_search_info srch_inf;
359 struct slow_work oplock_break; /* slow_work job for oplock breaks */
357}; 360};
358 361
359/* Take a reference on the file private data */ 362/* Take a reference on the file private data */
@@ -670,12 +673,6 @@ GLOBAL_EXTERN rwlock_t cifs_tcp_ses_lock;
670 */ 673 */
671GLOBAL_EXTERN rwlock_t GlobalSMBSeslock; 674GLOBAL_EXTERN rwlock_t GlobalSMBSeslock;
672 675
673/* Global list of oplocks */
674GLOBAL_EXTERN struct list_head cifs_oplock_list;
675
676/* Protects the cifs_oplock_list */
677GLOBAL_EXTERN spinlock_t cifs_oplock_lock;
678
679/* Outstanding dir notify requests */ 676/* Outstanding dir notify requests */
680GLOBAL_EXTERN struct list_head GlobalDnotifyReqList; 677GLOBAL_EXTERN struct list_head GlobalDnotifyReqList;
681/* DirNotify response queue */ 678/* DirNotify response queue */
@@ -726,3 +723,4 @@ GLOBAL_EXTERN unsigned int cifs_min_rcv; /* min size of big ntwrk buf pool */
726GLOBAL_EXTERN unsigned int cifs_min_small; /* min size of small buf pool */ 723GLOBAL_EXTERN unsigned int cifs_min_small; /* min size of small buf pool */
727GLOBAL_EXTERN unsigned int cifs_max_pending; /* MAX requests at once to server*/ 724GLOBAL_EXTERN unsigned int cifs_max_pending; /* MAX requests at once to server*/
728 725
726extern const struct slow_work_ops cifs_oplock_break_ops;