diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-02 23:25:04 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-02 23:25:04 -0400 |
commit | aab174f0df5d72d31caccf281af5f614fa254578 (patch) | |
tree | 2a172c5009c4ac8755e858593154c258ce7709a0 /fs/timerfd.c | |
parent | ca41cc96b2813221b05af57d0355157924de5a07 (diff) | |
parent | 2bd2c1941f141ad780135ccc1cd08ca71a24f10a (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs update from Al Viro:
- big one - consolidation of descriptor-related logics; almost all of
that is moved to fs/file.c
(BTW, I'm seriously tempted to rename the result to fd.c. As it is,
we have a situation when file_table.c is about handling of struct
file and file.c is about handling of descriptor tables; the reasons
are historical - file_table.c used to be about a static array of
struct file we used to have way back).
A lot of stray ends got cleaned up and converted to saner primitives,
disgusting mess in android/binder.c is still disgusting, but at least
doesn't poke so much in descriptor table guts anymore. A bunch of
relatively minor races got fixed in process, plus an ext4 struct file
leak.
- related thing - fget_light() partially unuglified; see fdget() in
there (and yes, it generates the code as good as we used to have).
- also related - bits of Cyrill's procfs stuff that got entangled into
that work; _not_ all of it, just the initial move to fs/proc/fd.c and
switch of fdinfo to seq_file.
- Alex's fs/coredump.c spiltoff - the same story, had been easier to
take that commit than mess with conflicts. The rest is a separate
pile, this was just a mechanical code movement.
- a few misc patches all over the place. Not all for this cycle,
there'll be more (and quite a few currently sit in akpm's tree)."
Fix up trivial conflicts in the android binder driver, and some fairly
simple conflicts due to two different changes to the sock_alloc_file()
interface ("take descriptor handling from sock_alloc_file() to callers"
vs "net: Providing protocol type via system.sockprotoname xattr of
/proc/PID/fd entries" adding a dentry name to the socket)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (72 commits)
MAX_LFS_FILESIZE should be a loff_t
compat: fs: Generic compat_sys_sendfile implementation
fs: push rcu_barrier() from deactivate_locked_super() to filesystems
btrfs: reada_extent doesn't need kref for refcount
coredump: move core dump functionality into its own file
coredump: prevent double-free on an error path in core dumper
usb/gadget: fix misannotations
fcntl: fix misannotations
ceph: don't abuse d_delete() on failure exits
hypfs: ->d_parent is never NULL or negative
vfs: delete surplus inode NULL check
switch simple cases of fget_light to fdget
new helpers: fdget()/fdput()
switch o2hb_region_dev_write() to fget_light()
proc_map_files_readdir(): don't bother with grabbing files
make get_file() return its argument
vhost_set_vring(): turn pollstart/pollstop into bool
switch prctl_set_mm_exe_file() to fget_light()
switch xfs_find_handle() to fget_light()
switch xfs_swapext() to fget_light()
...
Diffstat (limited to 'fs/timerfd.c')
-rw-r--r-- | fs/timerfd.c | 45 |
1 files changed, 21 insertions, 24 deletions
diff --git a/fs/timerfd.c b/fs/timerfd.c index dffeb3795af1..d03822bbf190 100644 --- a/fs/timerfd.c +++ b/fs/timerfd.c | |||
@@ -234,19 +234,17 @@ static const struct file_operations timerfd_fops = { | |||
234 | .llseek = noop_llseek, | 234 | .llseek = noop_llseek, |
235 | }; | 235 | }; |
236 | 236 | ||
237 | static struct file *timerfd_fget(int fd) | 237 | static int timerfd_fget(int fd, struct fd *p) |
238 | { | 238 | { |
239 | struct file *file; | 239 | struct fd f = fdget(fd); |
240 | 240 | if (!f.file) | |
241 | file = fget(fd); | 241 | return -EBADF; |
242 | if (!file) | 242 | if (f.file->f_op != &timerfd_fops) { |
243 | return ERR_PTR(-EBADF); | 243 | fdput(f); |
244 | if (file->f_op != &timerfd_fops) { | 244 | return -EINVAL; |
245 | fput(file); | ||
246 | return ERR_PTR(-EINVAL); | ||
247 | } | 245 | } |
248 | 246 | *p = f; | |
249 | return file; | 247 | return 0; |
250 | } | 248 | } |
251 | 249 | ||
252 | SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) | 250 | SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) |
@@ -284,7 +282,7 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | |||
284 | const struct itimerspec __user *, utmr, | 282 | const struct itimerspec __user *, utmr, |
285 | struct itimerspec __user *, otmr) | 283 | struct itimerspec __user *, otmr) |
286 | { | 284 | { |
287 | struct file *file; | 285 | struct fd f; |
288 | struct timerfd_ctx *ctx; | 286 | struct timerfd_ctx *ctx; |
289 | struct itimerspec ktmr, kotmr; | 287 | struct itimerspec ktmr, kotmr; |
290 | int ret; | 288 | int ret; |
@@ -297,10 +295,10 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | |||
297 | !timespec_valid(&ktmr.it_interval)) | 295 | !timespec_valid(&ktmr.it_interval)) |
298 | return -EINVAL; | 296 | return -EINVAL; |
299 | 297 | ||
300 | file = timerfd_fget(ufd); | 298 | ret = timerfd_fget(ufd, &f); |
301 | if (IS_ERR(file)) | 299 | if (ret) |
302 | return PTR_ERR(file); | 300 | return ret; |
303 | ctx = file->private_data; | 301 | ctx = f.file->private_data; |
304 | 302 | ||
305 | timerfd_setup_cancel(ctx, flags); | 303 | timerfd_setup_cancel(ctx, flags); |
306 | 304 | ||
@@ -334,7 +332,7 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | |||
334 | ret = timerfd_setup(ctx, flags, &ktmr); | 332 | ret = timerfd_setup(ctx, flags, &ktmr); |
335 | 333 | ||
336 | spin_unlock_irq(&ctx->wqh.lock); | 334 | spin_unlock_irq(&ctx->wqh.lock); |
337 | fput(file); | 335 | fdput(f); |
338 | if (otmr && copy_to_user(otmr, &kotmr, sizeof(kotmr))) | 336 | if (otmr && copy_to_user(otmr, &kotmr, sizeof(kotmr))) |
339 | return -EFAULT; | 337 | return -EFAULT; |
340 | 338 | ||
@@ -343,14 +341,13 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | |||
343 | 341 | ||
344 | SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr) | 342 | SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr) |
345 | { | 343 | { |
346 | struct file *file; | 344 | struct fd f; |
347 | struct timerfd_ctx *ctx; | 345 | struct timerfd_ctx *ctx; |
348 | struct itimerspec kotmr; | 346 | struct itimerspec kotmr; |
349 | 347 | int ret = timerfd_fget(ufd, &f); | |
350 | file = timerfd_fget(ufd); | 348 | if (ret) |
351 | if (IS_ERR(file)) | 349 | return ret; |
352 | return PTR_ERR(file); | 350 | ctx = f.file->private_data; |
353 | ctx = file->private_data; | ||
354 | 351 | ||
355 | spin_lock_irq(&ctx->wqh.lock); | 352 | spin_lock_irq(&ctx->wqh.lock); |
356 | if (ctx->expired && ctx->tintv.tv64) { | 353 | if (ctx->expired && ctx->tintv.tv64) { |
@@ -362,7 +359,7 @@ SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr) | |||
362 | kotmr.it_value = ktime_to_timespec(timerfd_get_remaining(ctx)); | 359 | kotmr.it_value = ktime_to_timespec(timerfd_get_remaining(ctx)); |
363 | kotmr.it_interval = ktime_to_timespec(ctx->tintv); | 360 | kotmr.it_interval = ktime_to_timespec(ctx->tintv); |
364 | spin_unlock_irq(&ctx->wqh.lock); | 361 | spin_unlock_irq(&ctx->wqh.lock); |
365 | fput(file); | 362 | fdput(f); |
366 | 363 | ||
367 | return copy_to_user(otmr, &kotmr, sizeof(kotmr)) ? -EFAULT: 0; | 364 | return copy_to_user(otmr, &kotmr, sizeof(kotmr)) ? -EFAULT: 0; |
368 | } | 365 | } |