fs: kernfs: add poll file operation
[linux-2.6-block.git] / fs / kernfs / file.c
index f8d5021a652ead80f898ea5d4c421821ab8bae3b..ae948aaa4c5352ef57cc507262464dc9514e1e10 100644 (file)
@@ -832,26 +832,35 @@ void kernfs_drain_open_files(struct kernfs_node *kn)
  * to see if it supports poll (Neither 'poll' nor 'select' return
  * an appropriate error code).  When in doubt, set a suitable timeout value.
  */
+__poll_t kernfs_generic_poll(struct kernfs_open_file *of, poll_table *wait)
+{
+       struct kernfs_node *kn = kernfs_dentry_node(of->file->f_path.dentry);
+       struct kernfs_open_node *on = kn->attr.open;
+
+       poll_wait(of->file, &on->poll, wait);
+
+       if (of->event != atomic_read(&on->event))
+               return DEFAULT_POLLMASK|EPOLLERR|EPOLLPRI;
+
+       return DEFAULT_POLLMASK;
+}
+
 static __poll_t kernfs_fop_poll(struct file *filp, poll_table *wait)
 {
        struct kernfs_open_file *of = kernfs_of(filp);
        struct kernfs_node *kn = kernfs_dentry_node(filp->f_path.dentry);
-       struct kernfs_open_node *on = kn->attr.open;
+       __poll_t ret;
 
        if (!kernfs_get_active(kn))
-               goto trigger;
+               return DEFAULT_POLLMASK|EPOLLERR|EPOLLPRI;
 
-       poll_wait(filp, &on->poll, wait);
+       if (kn->attr.ops->poll)
+               ret = kn->attr.ops->poll(of, wait);
+       else
+               ret = kernfs_generic_poll(of, wait);
 
        kernfs_put_active(kn);
-
-       if (of->event != atomic_read(&on->event))
-               goto trigger;
-
-       return DEFAULT_POLLMASK;
-
- trigger:
-       return DEFAULT_POLLMASK|EPOLLERR|EPOLLPRI;
+       return ret;
 }
 
 static void kernfs_notify_workfn(struct work_struct *work)