diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2013-08-30 12:47:21 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-09-03 23:04:44 -0400 |
commit | 7e3fb5842e2294a09fb67c41d8e3f32db5134c43 (patch) | |
tree | 6c5ef4f0789970cf9b8b0719cd988f5a3ad6078d | |
parent | a2e0578be3652406b2ffd2eeb31cdbdffa325d64 (diff) |
switch epoll_ctl() to fdget
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/eventpoll.c | 31 |
1 files changed, 15 insertions, 16 deletions
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 9ad17b15b454..293f86741ddb 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -1792,7 +1792,7 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd, | |||
1792 | { | 1792 | { |
1793 | int error; | 1793 | int error; |
1794 | int did_lock_epmutex = 0; | 1794 | int did_lock_epmutex = 0; |
1795 | struct file *file, *tfile; | 1795 | struct fd f, tf; |
1796 | struct eventpoll *ep; | 1796 | struct eventpoll *ep; |
1797 | struct epitem *epi; | 1797 | struct epitem *epi; |
1798 | struct epoll_event epds; | 1798 | struct epoll_event epds; |
@@ -1802,20 +1802,19 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd, | |||
1802 | copy_from_user(&epds, event, sizeof(struct epoll_event))) | 1802 | copy_from_user(&epds, event, sizeof(struct epoll_event))) |
1803 | goto error_return; | 1803 | goto error_return; |
1804 | 1804 | ||
1805 | /* Get the "struct file *" for the eventpoll file */ | ||
1806 | error = -EBADF; | 1805 | error = -EBADF; |
1807 | file = fget(epfd); | 1806 | f = fdget(epfd); |
1808 | if (!file) | 1807 | if (!f.file) |
1809 | goto error_return; | 1808 | goto error_return; |
1810 | 1809 | ||
1811 | /* Get the "struct file *" for the target file */ | 1810 | /* Get the "struct file *" for the target file */ |
1812 | tfile = fget(fd); | 1811 | tf = fdget(fd); |
1813 | if (!tfile) | 1812 | if (!tf.file) |
1814 | goto error_fput; | 1813 | goto error_fput; |
1815 | 1814 | ||
1816 | /* The target file descriptor must support poll */ | 1815 | /* The target file descriptor must support poll */ |
1817 | error = -EPERM; | 1816 | error = -EPERM; |
1818 | if (!tfile->f_op || !tfile->f_op->poll) | 1817 | if (!tf.file->f_op || !tf.file->f_op->poll) |
1819 | goto error_tgt_fput; | 1818 | goto error_tgt_fput; |
1820 | 1819 | ||
1821 | /* Check if EPOLLWAKEUP is allowed */ | 1820 | /* Check if EPOLLWAKEUP is allowed */ |
@@ -1828,14 +1827,14 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd, | |||
1828 | * adding an epoll file descriptor inside itself. | 1827 | * adding an epoll file descriptor inside itself. |
1829 | */ | 1828 | */ |
1830 | error = -EINVAL; | 1829 | error = -EINVAL; |
1831 | if (file == tfile || !is_file_epoll(file)) | 1830 | if (f.file == tf.file || !is_file_epoll(f.file)) |
1832 | goto error_tgt_fput; | 1831 | goto error_tgt_fput; |
1833 | 1832 | ||
1834 | /* | 1833 | /* |
1835 | * At this point it is safe to assume that the "private_data" contains | 1834 | * At this point it is safe to assume that the "private_data" contains |
1836 | * our own data structure. | 1835 | * our own data structure. |
1837 | */ | 1836 | */ |
1838 | ep = file->private_data; | 1837 | ep = f.file->private_data; |
1839 | 1838 | ||
1840 | /* | 1839 | /* |
1841 | * When we insert an epoll file descriptor, inside another epoll file | 1840 | * When we insert an epoll file descriptor, inside another epoll file |
@@ -1854,14 +1853,14 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd, | |||
1854 | did_lock_epmutex = 1; | 1853 | did_lock_epmutex = 1; |
1855 | } | 1854 | } |
1856 | if (op == EPOLL_CTL_ADD) { | 1855 | if (op == EPOLL_CTL_ADD) { |
1857 | if (is_file_epoll(tfile)) { | 1856 | if (is_file_epoll(tf.file)) { |
1858 | error = -ELOOP; | 1857 | error = -ELOOP; |
1859 | if (ep_loop_check(ep, tfile) != 0) { | 1858 | if (ep_loop_check(ep, tf.file) != 0) { |
1860 | clear_tfile_check_list(); | 1859 | clear_tfile_check_list(); |
1861 | goto error_tgt_fput; | 1860 | goto error_tgt_fput; |
1862 | } | 1861 | } |
1863 | } else | 1862 | } else |
1864 | list_add(&tfile->f_tfile_llink, &tfile_check_list); | 1863 | list_add(&tf.file->f_tfile_llink, &tfile_check_list); |
1865 | } | 1864 | } |
1866 | 1865 | ||
1867 | mutex_lock_nested(&ep->mtx, 0); | 1866 | mutex_lock_nested(&ep->mtx, 0); |
@@ -1871,14 +1870,14 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd, | |||
1871 | * above, we can be sure to be able to use the item looked up by | 1870 | * above, we can be sure to be able to use the item looked up by |
1872 | * ep_find() till we release the mutex. | 1871 | * ep_find() till we release the mutex. |
1873 | */ | 1872 | */ |
1874 | epi = ep_find(ep, tfile, fd); | 1873 | epi = ep_find(ep, tf.file, fd); |
1875 | 1874 | ||
1876 | error = -EINVAL; | 1875 | error = -EINVAL; |
1877 | switch (op) { | 1876 | switch (op) { |
1878 | case EPOLL_CTL_ADD: | 1877 | case EPOLL_CTL_ADD: |
1879 | if (!epi) { | 1878 | if (!epi) { |
1880 | epds.events |= POLLERR | POLLHUP; | 1879 | epds.events |= POLLERR | POLLHUP; |
1881 | error = ep_insert(ep, &epds, tfile, fd); | 1880 | error = ep_insert(ep, &epds, tf.file, fd); |
1882 | } else | 1881 | } else |
1883 | error = -EEXIST; | 1882 | error = -EEXIST; |
1884 | clear_tfile_check_list(); | 1883 | clear_tfile_check_list(); |
@@ -1903,9 +1902,9 @@ error_tgt_fput: | |||
1903 | if (did_lock_epmutex) | 1902 | if (did_lock_epmutex) |
1904 | mutex_unlock(&epmutex); | 1903 | mutex_unlock(&epmutex); |
1905 | 1904 | ||
1906 | fput(tfile); | 1905 | fdput(tf); |
1907 | error_fput: | 1906 | error_fput: |
1908 | fput(file); | 1907 | fdput(f); |
1909 | error_return: | 1908 | error_return: |
1910 | 1909 | ||
1911 | return error; | 1910 | return error; |