aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2011-07-12 14:48:39 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2011-07-20 20:47:50 -0400
commitf15146380d28b746df3c8b81b392812eb982382a (patch)
treebf43b38b60c21bd01b007c9636062783d406eb29
parent72c5052ddc3956d847f21c2b8d55c93664a51b2c (diff)
fs: seq_file - add event counter to simplify poll() support
Moving the event counter into the dynamically allocated 'struc seq_file' allows poll() support without the need to allocate its own tracking structure. All current users are switched over to use the new counter. Requested-by: Andrew Morton akpm@linux-foundation.org Acked-by: NeilBrown <neilb@suse.de> Tested-by: Lucas De Marchi lucas.demarchi@profusion.mobi Signed-off-by: Kay Sievers <kay.sievers@vrfy.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--drivers/md/md.c26
-rw-r--r--fs/namespace.c4
-rw-r--r--fs/proc/base.c2
-rw-r--r--include/linux/mnt_namespace.h1
-rw-r--r--include/linux/seq_file.h1
-rw-r--r--mm/swapfile.c29
6 files changed, 20 insertions, 43 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 91e31e260b4a..dfc9425db70b 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -6394,16 +6394,11 @@ static void md_seq_stop(struct seq_file *seq, void *v)
6394 mddev_put(mddev); 6394 mddev_put(mddev);
6395} 6395}
6396 6396
6397struct mdstat_info {
6398 int event;
6399};
6400
6401static int md_seq_show(struct seq_file *seq, void *v) 6397static int md_seq_show(struct seq_file *seq, void *v)
6402{ 6398{
6403 mddev_t *mddev = v; 6399 mddev_t *mddev = v;
6404 sector_t sectors; 6400 sector_t sectors;
6405 mdk_rdev_t *rdev; 6401 mdk_rdev_t *rdev;
6406 struct mdstat_info *mi = seq->private;
6407 struct bitmap *bitmap; 6402 struct bitmap *bitmap;
6408 6403
6409 if (v == (void*)1) { 6404 if (v == (void*)1) {
@@ -6415,7 +6410,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
6415 6410
6416 spin_unlock(&pers_lock); 6411 spin_unlock(&pers_lock);
6417 seq_printf(seq, "\n"); 6412 seq_printf(seq, "\n");
6418 mi->event = atomic_read(&md_event_count); 6413 seq->poll_event = atomic_read(&md_event_count);
6419 return 0; 6414 return 0;
6420 } 6415 }
6421 if (v == (void*)2) { 6416 if (v == (void*)2) {
@@ -6527,26 +6522,21 @@ static const struct seq_operations md_seq_ops = {
6527 6522
6528static int md_seq_open(struct inode *inode, struct file *file) 6523static int md_seq_open(struct inode *inode, struct file *file)
6529{ 6524{
6525 struct seq_file *seq;
6530 int error; 6526 int error;
6531 struct mdstat_info *mi = kmalloc(sizeof(*mi), GFP_KERNEL);
6532 if (mi == NULL)
6533 return -ENOMEM;
6534 6527
6535 error = seq_open(file, &md_seq_ops); 6528 error = seq_open(file, &md_seq_ops);
6536 if (error) 6529 if (error)
6537 kfree(mi); 6530 return error;
6538 else { 6531
6539 struct seq_file *p = file->private_data; 6532 seq = file->private_data;
6540 p->private = mi; 6533 seq->poll_event = atomic_read(&md_event_count);
6541 mi->event = atomic_read(&md_event_count);
6542 }
6543 return error; 6534 return error;
6544} 6535}
6545 6536
6546static unsigned int mdstat_poll(struct file *filp, poll_table *wait) 6537static unsigned int mdstat_poll(struct file *filp, poll_table *wait)
6547{ 6538{
6548 struct seq_file *m = filp->private_data; 6539 struct seq_file *seq = filp->private_data;
6549 struct mdstat_info *mi = m->private;
6550 int mask; 6540 int mask;
6551 6541
6552 poll_wait(filp, &md_event_waiters, wait); 6542 poll_wait(filp, &md_event_waiters, wait);
@@ -6554,7 +6544,7 @@ static unsigned int mdstat_poll(struct file *filp, poll_table *wait)
6554 /* always allow read */ 6544 /* always allow read */
6555 mask = POLLIN | POLLRDNORM; 6545 mask = POLLIN | POLLRDNORM;
6556 6546
6557 if (mi->event != atomic_read(&md_event_count)) 6547 if (seq->poll_event != atomic_read(&md_event_count))
6558 mask |= POLLERR | POLLPRI; 6548 mask |= POLLERR | POLLPRI;
6559 return mask; 6549 return mask;
6560} 6550}
diff --git a/fs/namespace.c b/fs/namespace.c
index fe59bd145d21..cda50fe9250a 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -934,8 +934,8 @@ int mnt_had_events(struct proc_mounts *p)
934 int res = 0; 934 int res = 0;
935 935
936 br_read_lock(vfsmount_lock); 936 br_read_lock(vfsmount_lock);
937 if (p->event != ns->event) { 937 if (p->m.poll_event != ns->event) {
938 p->event = ns->event; 938 p->m.poll_event = ns->event;
939 res = 1; 939 res = 1;
940 } 940 }
941 br_read_unlock(vfsmount_lock); 941 br_read_unlock(vfsmount_lock);
diff --git a/fs/proc/base.c b/fs/proc/base.c
index be1ff932033b..3dc5e2a5cc38 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -673,7 +673,7 @@ static int mounts_open_common(struct inode *inode, struct file *file,
673 p->m.private = p; 673 p->m.private = p;
674 p->ns = ns; 674 p->ns = ns;
675 p->root = root; 675 p->root = root;
676 p->event = ns->event; 676 p->m.poll_event = ns->event;
677 677
678 return 0; 678 return 0;
679 679
diff --git a/include/linux/mnt_namespace.h b/include/linux/mnt_namespace.h
index 0b89efc6f215..29304855652d 100644
--- a/include/linux/mnt_namespace.h
+++ b/include/linux/mnt_namespace.h
@@ -18,7 +18,6 @@ struct proc_mounts {
18 struct seq_file m; /* must be the first element */ 18 struct seq_file m; /* must be the first element */
19 struct mnt_namespace *ns; 19 struct mnt_namespace *ns;
20 struct path root; 20 struct path root;
21 int event;
22}; 21};
23 22
24struct fs_struct; 23struct fs_struct;
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index 03c0232b4169..be720cd2038d 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -23,6 +23,7 @@ struct seq_file {
23 u64 version; 23 u64 version;
24 struct mutex lock; 24 struct mutex lock;
25 const struct seq_operations *op; 25 const struct seq_operations *op;
26 int poll_event;
26 void *private; 27 void *private;
27}; 28};
28 29
diff --git a/mm/swapfile.c b/mm/swapfile.c
index ff8dc1a18cb4..1b8c33907242 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1681,19 +1681,14 @@ out:
1681} 1681}
1682 1682
1683#ifdef CONFIG_PROC_FS 1683#ifdef CONFIG_PROC_FS
1684struct proc_swaps {
1685 struct seq_file seq;
1686 int event;
1687};
1688
1689static unsigned swaps_poll(struct file *file, poll_table *wait) 1684static unsigned swaps_poll(struct file *file, poll_table *wait)
1690{ 1685{
1691 struct proc_swaps *s = file->private_data; 1686 struct seq_file *seq = file->private_data;
1692 1687
1693 poll_wait(file, &proc_poll_wait, wait); 1688 poll_wait(file, &proc_poll_wait, wait);
1694 1689
1695 if (s->event != atomic_read(&proc_poll_event)) { 1690 if (seq->poll_event != atomic_read(&proc_poll_event)) {
1696 s->event = atomic_read(&proc_poll_event); 1691 seq->poll_event = atomic_read(&proc_poll_event);
1697 return POLLIN | POLLRDNORM | POLLERR | POLLPRI; 1692 return POLLIN | POLLRDNORM | POLLERR | POLLPRI;
1698 } 1693 }
1699 1694
@@ -1783,24 +1778,16 @@ static const struct seq_operations swaps_op = {
1783 1778
1784static int swaps_open(struct inode *inode, struct file *file) 1779static int swaps_open(struct inode *inode, struct file *file)
1785{ 1780{
1786 struct proc_swaps *s; 1781 struct seq_file *seq;
1787 int ret; 1782 int ret;
1788 1783
1789 s = kmalloc(sizeof(struct proc_swaps), GFP_KERNEL);
1790 if (!s)
1791 return -ENOMEM;
1792
1793 file->private_data = s;
1794
1795 ret = seq_open(file, &swaps_op); 1784 ret = seq_open(file, &swaps_op);
1796 if (ret) { 1785 if (ret)
1797 kfree(s);
1798 return ret; 1786 return ret;
1799 }
1800 1787
1801 s->seq.private = s; 1788 seq = file->private_data;
1802 s->event = atomic_read(&proc_poll_event); 1789 seq->poll_event = atomic_read(&proc_poll_event);
1803 return ret; 1790 return 0;
1804} 1791}
1805 1792
1806static const struct file_operations proc_swaps_operations = { 1793static const struct file_operations proc_swaps_operations = {