]> Pileus Git - ~andy/linux/blobdiff - fs/file.c
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
[~andy/linux] / fs / file.c
index 4ed58a32575e22e1bd4ad7359f4f5867b7bf1efd..db25c2bdfe464035be537cee3fc09acad77e8cdb 100644 (file)
--- a/fs/file.c
+++ b/fs/file.c
@@ -34,7 +34,7 @@ static void *alloc_fdmem(size_t size)
         * vmalloc() if the allocation size will be considered "large" by the VM.
         */
        if (size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER)) {
-               void *data = kmalloc(size, GFP_KERNEL|__GFP_NOWARN);
+               void *data = kmalloc(size, GFP_KERNEL|__GFP_NOWARN|__GFP_NORETRY);
                if (data != NULL)
                        return data;
        }
@@ -683,56 +683,33 @@ EXPORT_SYMBOL(fget_raw);
  * The fput_needed flag returned by fget_light should be passed to the
  * corresponding fput_light.
  */
-struct file *fget_light(unsigned int fd, int *fput_needed)
+struct file *__fget_light(unsigned int fd, fmode_t mask, int *fput_needed)
 {
-       struct file *file;
        struct files_struct *files = current->files;
+       struct file *file;
 
        *fput_needed = 0;
        if (atomic_read(&files->count) == 1) {
                file = __fcheck_files(files, fd);
-               if (file && (file->f_mode & FMODE_PATH))
+               if (file && (file->f_mode & mask))
                        file = NULL;
        } else {
-               rcu_read_lock();
-               file = fcheck_files(files, fd);
-               if (file) {
-                       if (!(file->f_mode & FMODE_PATH) &&
-                           atomic_long_inc_not_zero(&file->f_count))
-                               *fput_needed = 1;
-                       else
-                               /* Didn't get the reference, someone's freed */
-                               file = NULL;
-               }
-               rcu_read_unlock();
+               file = __fget(fd, mask);
+               if (file)
+                       *fput_needed = 1;
        }
 
        return file;
 }
+struct file *fget_light(unsigned int fd, int *fput_needed)
+{
+       return __fget_light(fd, FMODE_PATH, fput_needed);
+}
 EXPORT_SYMBOL(fget_light);
 
 struct file *fget_raw_light(unsigned int fd, int *fput_needed)
 {
-       struct file *file;
-       struct files_struct *files = current->files;
-
-       *fput_needed = 0;
-       if (atomic_read(&files->count) == 1) {
-               file = __fcheck_files(files, fd);
-       } else {
-               rcu_read_lock();
-               file = fcheck_files(files, fd);
-               if (file) {
-                       if (atomic_long_inc_not_zero(&file->f_count))
-                               *fput_needed = 1;
-                       else
-                               /* Didn't get the reference, someone's freed */
-                               file = NULL;
-               }
-               rcu_read_unlock();
-       }
-
-       return file;
+       return __fget_light(fd, 0, fput_needed);
 }
 
 void set_close_on_exec(unsigned int fd, int flag)