aboutsummaryrefslogtreecommitdiffstats
path: root/fs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/file.c')
-rw-r--r--fs/file.c128
1 files changed, 59 insertions, 69 deletions
diff --git a/fs/file.c b/fs/file.c
index 4a78f981557a..60a45e9f5323 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -34,7 +34,7 @@ static void *alloc_fdmem(size_t size)
34 * vmalloc() if the allocation size will be considered "large" by the VM. 34 * vmalloc() if the allocation size will be considered "large" by the VM.
35 */ 35 */
36 if (size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER)) { 36 if (size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER)) {
37 void *data = kmalloc(size, GFP_KERNEL|__GFP_NOWARN); 37 void *data = kmalloc(size, GFP_KERNEL|__GFP_NOWARN|__GFP_NORETRY);
38 if (data != NULL) 38 if (data != NULL)
39 return data; 39 return data;
40 } 40 }
@@ -348,21 +348,16 @@ out:
348 return NULL; 348 return NULL;
349} 349}
350 350
351static void close_files(struct files_struct * files) 351static struct fdtable *close_files(struct files_struct * files)
352{ 352{
353 int i, j;
354 struct fdtable *fdt;
355
356 j = 0;
357
358 /* 353 /*
359 * It is safe to dereference the fd table without RCU or 354 * It is safe to dereference the fd table without RCU or
360 * ->file_lock because this is the last reference to the 355 * ->file_lock because this is the last reference to the
361 * files structure. But use RCU to shut RCU-lockdep up. 356 * files structure.
362 */ 357 */
363 rcu_read_lock(); 358 struct fdtable *fdt = rcu_dereference_raw(files->fdt);
364 fdt = files_fdtable(files); 359 int i, j = 0;
365 rcu_read_unlock(); 360
366 for (;;) { 361 for (;;) {
367 unsigned long set; 362 unsigned long set;
368 i = j * BITS_PER_LONG; 363 i = j * BITS_PER_LONG;
@@ -381,6 +376,8 @@ static void close_files(struct files_struct * files)
381 set >>= 1; 376 set >>= 1;
382 } 377 }
383 } 378 }
379
380 return fdt;
384} 381}
385 382
386struct files_struct *get_files_struct(struct task_struct *task) 383struct files_struct *get_files_struct(struct task_struct *task)
@@ -398,14 +395,9 @@ struct files_struct *get_files_struct(struct task_struct *task)
398 395
399void put_files_struct(struct files_struct *files) 396void put_files_struct(struct files_struct *files)
400{ 397{
401 struct fdtable *fdt;
402
403 if (atomic_dec_and_test(&files->count)) { 398 if (atomic_dec_and_test(&files->count)) {
404 close_files(files); 399 struct fdtable *fdt = close_files(files);
405 /* not really needed, since nobody can see us */ 400
406 rcu_read_lock();
407 fdt = files_fdtable(files);
408 rcu_read_unlock();
409 /* free the arrays if they are not embedded */ 401 /* free the arrays if they are not embedded */
410 if (fdt != &files->fdtab) 402 if (fdt != &files->fdtab)
411 __free_fdtable(fdt); 403 __free_fdtable(fdt);
@@ -645,16 +637,16 @@ void do_close_on_exec(struct files_struct *files)
645 spin_unlock(&files->file_lock); 637 spin_unlock(&files->file_lock);
646} 638}
647 639
648struct file *fget(unsigned int fd) 640static struct file *__fget(unsigned int fd, fmode_t mask)
649{ 641{
650 struct file *file;
651 struct files_struct *files = current->files; 642 struct files_struct *files = current->files;
643 struct file *file;
652 644
653 rcu_read_lock(); 645 rcu_read_lock();
654 file = fcheck_files(files, fd); 646 file = fcheck_files(files, fd);
655 if (file) { 647 if (file) {
656 /* File object ref couldn't be taken */ 648 /* File object ref couldn't be taken */
657 if (file->f_mode & FMODE_PATH || 649 if ((file->f_mode & mask) ||
658 !atomic_long_inc_not_zero(&file->f_count)) 650 !atomic_long_inc_not_zero(&file->f_count))
659 file = NULL; 651 file = NULL;
660 } 652 }
@@ -663,25 +655,16 @@ struct file *fget(unsigned int fd)
663 return file; 655 return file;
664} 656}
665 657
658struct file *fget(unsigned int fd)
659{
660 return __fget(fd, FMODE_PATH);
661}
666EXPORT_SYMBOL(fget); 662EXPORT_SYMBOL(fget);
667 663
668struct file *fget_raw(unsigned int fd) 664struct file *fget_raw(unsigned int fd)
669{ 665{
670 struct file *file; 666 return __fget(fd, 0);
671 struct files_struct *files = current->files;
672
673 rcu_read_lock();
674 file = fcheck_files(files, fd);
675 if (file) {
676 /* File object ref couldn't be taken */
677 if (!atomic_long_inc_not_zero(&file->f_count))
678 file = NULL;
679 }
680 rcu_read_unlock();
681
682 return file;
683} 667}
684
685EXPORT_SYMBOL(fget_raw); 668EXPORT_SYMBOL(fget_raw);
686 669
687/* 670/*
@@ -700,58 +683,65 @@ EXPORT_SYMBOL(fget_raw);
700 * The fput_needed flag returned by fget_light should be passed to the 683 * The fput_needed flag returned by fget_light should be passed to the
701 * corresponding fput_light. 684 * corresponding fput_light.
702 */ 685 */
703struct file *fget_light(unsigned int fd, int *fput_needed) 686static unsigned long __fget_light(unsigned int fd, fmode_t mask)
704{ 687{
705 struct file *file;
706 struct files_struct *files = current->files; 688 struct files_struct *files = current->files;
689 struct file *file;
707 690
708 *fput_needed = 0;
709 if (atomic_read(&files->count) == 1) { 691 if (atomic_read(&files->count) == 1) {
710 file = fcheck_files(files, fd); 692 file = __fcheck_files(files, fd);
711 if (file && (file->f_mode & FMODE_PATH)) 693 if (!file || unlikely(file->f_mode & mask))
712 file = NULL; 694 return 0;
695 return (unsigned long)file;
713 } else { 696 } else {
714 rcu_read_lock(); 697 file = __fget(fd, mask);
715 file = fcheck_files(files, fd); 698 if (!file)
716 if (file) { 699 return 0;
717 if (!(file->f_mode & FMODE_PATH) && 700 return FDPUT_FPUT | (unsigned long)file;
718 atomic_long_inc_not_zero(&file->f_count))
719 *fput_needed = 1;
720 else
721 /* Didn't get the reference, someone's freed */
722 file = NULL;
723 }
724 rcu_read_unlock();
725 } 701 }
702}
703unsigned long __fdget(unsigned int fd)
704{
705 return __fget_light(fd, FMODE_PATH);
706}
707EXPORT_SYMBOL(__fdget);
726 708
727 return file; 709unsigned long __fdget_raw(unsigned int fd)
710{
711 return __fget_light(fd, 0);
728} 712}
729EXPORT_SYMBOL(fget_light);
730 713
731struct file *fget_raw_light(unsigned int fd, int *fput_needed) 714unsigned long __fdget_pos(unsigned int fd)
732{ 715{
733 struct file *file;
734 struct files_struct *files = current->files; 716 struct files_struct *files = current->files;
717 struct file *file;
718 unsigned long v;
735 719
736 *fput_needed = 0;
737 if (atomic_read(&files->count) == 1) { 720 if (atomic_read(&files->count) == 1) {
738 file = fcheck_files(files, fd); 721 file = __fcheck_files(files, fd);
722 v = 0;
739 } else { 723 } else {
740 rcu_read_lock(); 724 file = __fget(fd, 0);
741 file = fcheck_files(files, fd); 725 v = FDPUT_FPUT;
742 if (file) {
743 if (atomic_long_inc_not_zero(&file->f_count))
744 *fput_needed = 1;
745 else
746 /* Didn't get the reference, someone's freed */
747 file = NULL;
748 }
749 rcu_read_unlock();
750 } 726 }
727 if (!file)
728 return 0;
751 729
752 return file; 730 if (file->f_mode & FMODE_ATOMIC_POS) {
731 if (file_count(file) > 1) {
732 v |= FDPUT_POS_UNLOCK;
733 mutex_lock(&file->f_pos_lock);
734 }
735 }
736 return v | (unsigned long)file;
753} 737}
754 738
739/*
740 * We only lock f_pos if we have threads or if the file might be
741 * shared with another process. In both cases we'll have an elevated
742 * file count (done either by fdget() or by fork()).
743 */
744
755void set_close_on_exec(unsigned int fd, int flag) 745void set_close_on_exec(unsigned int fd, int flag)
756{ 746{
757 struct files_struct *files = current->files; 747 struct files_struct *files = current->files;