aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2014-07-07 01:16:04 -0400
committerIngo Molnar <mingo@kernel.org>2014-07-16 09:10:39 -0400
commit743162013d40ca612b4cb53d3a200dff2d9ab26e (patch)
treeb688e8afdbb96d18c7466b088b2dc21156a0bedd /fs/cifs
parentd26fad5b38e1c4667d4f2604936e59c837caa54d (diff)
sched: Remove proliferation of wait_on_bit() action functions
The current "wait_on_bit" interface requires an 'action' function to be provided which does the actual waiting. There are over 20 such functions, many of them identical. Most cases can be satisfied by one of just two functions, one which uses io_schedule() and one which just uses schedule(). So: Rename wait_on_bit and wait_on_bit_lock to wait_on_bit_action and wait_on_bit_lock_action to make it explicit that they need an action function. Introduce new wait_on_bit{,_lock} and wait_on_bit{,_lock}_io which are *not* given an action function but implicitly use a standard one. The decision to error-out if a signal is pending is now made based on the 'mode' argument rather than being encoded in the action function. All instances of the old wait_on_bit and wait_on_bit_lock which can use the new version have been changed accordingly and their action functions have been discarded. wait_on_bit{_lock} does not return any specific error code in the event of a signal so the caller must check for non-zero and interpolate their own error code as appropriate. The wait_on_bit() call in __fscache_wait_on_invalidate() was ambiguous as it specified TASK_UNINTERRUPTIBLE but used fscache_wait_bit_interruptible as an action function. David Howells confirms this should be uniformly "uninterruptible" The main remaining user of wait_on_bit{,_lock}_action is NFS which needs to use a freezer-aware schedule() call. A comment in fs/gfs2/glock.c notes that having multiple 'action' functions is useful as they display differently in the 'wchan' field of 'ps'. (and /proc/$PID/wchan). As the new bit_wait{,_io} functions are tagged "__sched", they will not show up at all, but something higher in the stack. So the distinction will still be visible, only with different function names (gds2_glock_wait versus gfs2_glock_dq_wait in the gfs2/glock.c case). Since first version of this patch (against 3.15) two new action functions appeared, on in NFS and one in CIFS. CIFS also now uses an action function that makes the same freezer aware schedule call as NFS. Signed-off-by: NeilBrown <neilb@suse.de> Acked-by: David Howells <dhowells@redhat.com> (fscache, keys) Acked-by: Steven Whitehouse <swhiteho@redhat.com> (gfs2) Acked-by: Peter Zijlstra <peterz@infradead.org> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Steve French <sfrench@samba.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Link: http://lkml.kernel.org/r/20140707051603.28027.72349.stgit@notabene.brown Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/connect.c10
-rw-r--r--fs/cifs/file.c9
-rw-r--r--fs/cifs/inode.c4
-rw-r--r--fs/cifs/misc.c2
4 files changed, 5 insertions, 20 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 20d75b8ddb26..b98366f21f9e 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -3934,13 +3934,6 @@ cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb)
3934 return tlink_tcon(cifs_sb_master_tlink(cifs_sb)); 3934 return tlink_tcon(cifs_sb_master_tlink(cifs_sb));
3935} 3935}
3936 3936
3937static int
3938cifs_sb_tcon_pending_wait(void *unused)
3939{
3940 schedule();
3941 return signal_pending(current) ? -ERESTARTSYS : 0;
3942}
3943
3944/* find and return a tlink with given uid */ 3937/* find and return a tlink with given uid */
3945static struct tcon_link * 3938static struct tcon_link *
3946tlink_rb_search(struct rb_root *root, kuid_t uid) 3939tlink_rb_search(struct rb_root *root, kuid_t uid)
@@ -4039,11 +4032,10 @@ cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
4039 } else { 4032 } else {
4040wait_for_construction: 4033wait_for_construction:
4041 ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING, 4034 ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING,
4042 cifs_sb_tcon_pending_wait,
4043 TASK_INTERRUPTIBLE); 4035 TASK_INTERRUPTIBLE);
4044 if (ret) { 4036 if (ret) {
4045 cifs_put_tlink(tlink); 4037 cifs_put_tlink(tlink);
4046 return ERR_PTR(ret); 4038 return ERR_PTR(-ERESTARTSYS);
4047 } 4039 }
4048 4040
4049 /* if it's good, return it */ 4041 /* if it's good, return it */
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index e90a1e9aa627..b88b1ade4d3d 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -3618,13 +3618,6 @@ static int cifs_launder_page(struct page *page)
3618 return rc; 3618 return rc;
3619} 3619}
3620 3620
3621static int
3622cifs_pending_writers_wait(void *unused)
3623{
3624 schedule();
3625 return 0;
3626}
3627
3628void cifs_oplock_break(struct work_struct *work) 3621void cifs_oplock_break(struct work_struct *work)
3629{ 3622{
3630 struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo, 3623 struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo,
@@ -3636,7 +3629,7 @@ void cifs_oplock_break(struct work_struct *work)
3636 int rc = 0; 3629 int rc = 0;
3637 3630
3638 wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS, 3631 wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS,
3639 cifs_pending_writers_wait, TASK_UNINTERRUPTIBLE); 3632 TASK_UNINTERRUPTIBLE);
3640 3633
3641 server->ops->downgrade_oplock(server, cinode, 3634 server->ops->downgrade_oplock(server, cinode,
3642 test_bit(CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, &cinode->flags)); 3635 test_bit(CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, &cinode->flags));
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index a174605f6afa..213c4580b4e3 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1794,8 +1794,8 @@ cifs_revalidate_mapping(struct inode *inode)
1794 int rc; 1794 int rc;
1795 unsigned long *flags = &CIFS_I(inode)->flags; 1795 unsigned long *flags = &CIFS_I(inode)->flags;
1796 1796
1797 rc = wait_on_bit_lock(flags, CIFS_INO_LOCK, cifs_wait_bit_killable, 1797 rc = wait_on_bit_lock_action(flags, CIFS_INO_LOCK, cifs_wait_bit_killable,
1798 TASK_KILLABLE); 1798 TASK_KILLABLE);
1799 if (rc) 1799 if (rc)
1800 return rc; 1800 return rc;
1801 1801
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 3b0c62e622da..6bf55d0ed494 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -582,7 +582,7 @@ int cifs_get_writer(struct cifsInodeInfo *cinode)
582 582
583start: 583start:
584 rc = wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_OPLOCK_BREAK, 584 rc = wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_OPLOCK_BREAK,
585 cifs_oplock_break_wait, TASK_KILLABLE); 585 TASK_KILLABLE);
586 if (rc) 586 if (rc)
587 return rc; 587 return rc;
588 588