> Actually, thinking about this again, I guess there's actually no > reason why you'd need a constructor function; if you just avoid > memset()ing the refcount field on allocation, that'd be good enough. Thanks for catching this. So what I did is: diff --git a/fs/file_table.c b/fs/file_table.c index 5b8b18259eca..c81a47aea47f 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -148,10 +148,14 @@ static int __init init_fs_stat_sysctls(void) fs_initcall(init_fs_stat_sysctls); #endif +static_assert(offsetof(struct file, f_ref) == 0); + static int init_file(struct file *f, int flags, const struct cred *cred) { int error; + memset(f + sizeof(file_ref_t), 0, sizeof(*f) - sizeof(file_ref_t)); + f->f_cred = get_cred(cred); error = security_file_alloc(f); if (unlikely(error)) { @@ -209,7 +213,7 @@ struct file *alloc_empty_file(int flags, const struct cred *cred) goto over; } - f = kmem_cache_zalloc(filp_cachep, GFP_KERNEL); + f = kmem_cache_alloc(filp_cachep, GFP_KERNEL); if (unlikely(!f)) return ERR_PTR(-ENOMEM); @@ -243,7 +247,7 @@ struct file *alloc_empty_file_noaccount(int flags, const struct cred *cred) struct file *f; int error; - f = kmem_cache_zalloc(filp_cachep, GFP_KERNEL); + f = kmem_cache_alloc(filp_cachep, GFP_KERNEL); if (unlikely(!f)) return ERR_PTR(-ENOMEM); @@ -270,7 +274,7 @@ struct file *alloc_empty_backing_file(int flags, const struct cred *cred) struct backing_file *ff; int error; - ff = kmem_cache_zalloc(bfilp_cachep, GFP_KERNEL); + ff = kmem_cache_alloc(bfilp_cachep, GFP_KERNEL); if (unlikely(!ff)) return ERR_PTR(-ENOMEM);