static int bc_ioacct_notify(struct vnotifier_block *self, unsigned long event, void *arg, int old_ret) { struct user_beancounter *ub; unsigned long *vm_events; unsigned long long bin, bout; int i; if (event != VIRTINFO_VMSTAT) return old_ret; ub = top_beancounter(get_exec_ub()); if (ub == get_ub0()) return old_ret; /* Think over: do we need to account here bytes_dirty_missed? */ bout = ub->bytes_wrote; bin = 0; for_each_online_cpu(i) { bout += per_cpu_ptr(ub->ub_percpu, i)->bytes_wrote; bin += per_cpu_ptr(ub->ub_percpu, i)->bytes_read; } /* convert to Kbytes */ bout >>= 10; bin >>= 10; vm_events = ((unsigned long *)arg) + NR_VM_ZONE_STAT_ITEMS; vm_events[PGPGOUT] = (unsigned long)bout; vm_events[PGPGIN] = (unsigned long)bin; return NOTIFY_OK; }
/* Find an unused file structure and return a pointer to it. * Returns NULL, if there are no more free file structures or * we run out of memory. * * Be very careful using this. You are responsible for * getting write access to any mount that you might assign * to this filp, if it is opened for write. If this is not * done, you will imbalance int the mount's writer count * and a warning at __fput() time. */ struct file *get_empty_filp(void) { const struct cred *cred = current_cred(); static long old_max; struct file * f; int acct; acct = (get_exec_ub() == get_ub0()); /* * Privileged users can go above max_files */ if (acct && get_nr_files() >= files_stat.max_files && !capable(CAP_SYS_ADMIN)) { /* * percpu_counters are inaccurate. Do an expensive check before * we go and fail. */ if (percpu_counter_sum_positive(&nr_files) >= files_stat.max_files) goto over; } f = kmem_cache_zalloc(filp_cachep, GFP_KERNEL); if (f == NULL) goto fail; if (ub_file_charge(f)) goto fail_ch; if (acct) percpu_counter_inc(&nr_files); if (security_file_alloc(f)) goto fail_sec; INIT_LIST_HEAD(&f->f_u.fu_list); atomic_long_set(&f->f_count, 1); rwlock_init(&f->f_owner.lock); f->f_cred = get_cred(cred); spin_lock_init(&f->f_lock); eventpoll_init_file(f); /* f->f_version: 0 */ return f; over: /* Ran out of filps - report that */ if (get_nr_files() > old_max) { pr_info("VFS: file-max limit %lu reached\n", get_max_files()); old_max = get_nr_files(); } goto fail; fail_sec: file_free(f); fail: return NULL; fail_ch: kmem_cache_free(filp_cachep, f); return NULL; }
static inline void file_free(struct file *f) { file_check_state(f); if (f->f_ub == get_ub0()) percpu_counter_dec(&nr_files); ub_file_uncharge(f); call_rcu(&f->f_u.fu_rcuhead, file_free_rcu); }