X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=fs%2Ffile_table.c;h=43e9e1737de2cb365c954afeddfb64ae0433779b;hb=8191151d0933d65fb6b659ffbd765479f0f200e1;hp=03d83cb686b12598191d97edd55779315d74dc8a;hpb=1da177e4c3f41524e886b7f1b8a0c1fc7321cac2;p=linux-2.6 diff --git a/fs/file_table.c b/fs/file_table.c index 03d83cb686..43e9e1737d 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -16,6 +16,7 @@ #include #include #include +#include /* sysctl tunables... */ struct files_stat_struct files_stat = { @@ -63,42 +64,44 @@ static inline void file_free(struct file *f) */ struct file *get_empty_filp(void) { -static int old_max; + static int old_max; struct file * f; /* * Privileged users can go above max_files */ - if (files_stat.nr_files < files_stat.max_files || - capable(CAP_SYS_ADMIN)) { - f = kmem_cache_alloc(filp_cachep, GFP_KERNEL); - if (f) { - memset(f, 0, sizeof(*f)); - if (security_file_alloc(f)) { - file_free(f); - goto fail; - } - eventpoll_init_file(f); - atomic_set(&f->f_count, 1); - f->f_uid = current->fsuid; - f->f_gid = current->fsgid; - rwlock_init(&f->f_owner.lock); - /* f->f_version: 0 */ - INIT_LIST_HEAD(&f->f_list); - f->f_maxcount = INT_MAX; - return f; - } - } - + if (files_stat.nr_files >= files_stat.max_files && + !capable(CAP_SYS_ADMIN)) + goto over; + + f = kmem_cache_alloc(filp_cachep, GFP_KERNEL); + if (f == NULL) + goto fail; + + memset(f, 0, sizeof(*f)); + if (security_file_alloc(f)) + goto fail_sec; + + eventpoll_init_file(f); + atomic_set(&f->f_count, 1); + f->f_uid = current->fsuid; + f->f_gid = current->fsgid; + rwlock_init(&f->f_owner.lock); + /* f->f_version: 0 */ + INIT_LIST_HEAD(&f->f_list); + return f; + +over: /* Ran out of filps - report that */ - if (files_stat.max_files >= old_max) { + if (files_stat.nr_files > old_max) { printk(KERN_INFO "VFS: file-max limit %d reached\n", files_stat.max_files); - old_max = files_stat.max_files; - } else { - /* Big problems... */ - printk(KERN_WARNING "VFS: filp allocation failed\n"); + old_max = files_stat.nr_files; } + goto fail; + +fail_sec: + file_free(f); fail: return NULL; } @@ -123,6 +126,8 @@ void fastcall __fput(struct file *file) struct inode *inode = dentry->d_inode; might_sleep(); + + fsnotify_close(file); /* * The function eventpoll_release() should be the first called * in the file cleanup chain.