diff options
Diffstat (limited to 'fs/kernfs/file.c')
| -rw-r--r-- | fs/kernfs/file.c | 31 | 
1 files changed, 20 insertions, 11 deletions
diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index f8d5021a652e..ae948aaa4c53 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -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)  |