]>
git.proxmox.com Git - mirror_spl.git/blob - modules/spl/spl-file.c
1 #include <sys/sysmacros.h>
7 static spinlock_t file_lock
= SPIN_LOCK_UNLOCKED
;
8 static LIST_HEAD(file_list
);
9 static kmem_cache_t
*file_cache
;
11 /* Function must be called while holding the file_lock */
17 BUG_ON(!spin_is_locked(&file_lock
));
19 list_for_each_entry(fp
, &file_list
, f_list
) {
21 BUG_ON(atomic_read(&fp
->f_ref
) == 0);
34 /* Already open just take an extra reference */
35 spin_lock(&file_lock
);
39 atomic_inc(&fp
->f_ref
);
40 spin_unlock(&file_lock
);
44 spin_unlock(&file_lock
);
46 /* File was not yet opened via the SPL layer create needed bits */
47 fp
= kmem_cache_alloc(file_cache
, 0);
51 mutex_enter(&fp
->f_lock
);
53 fp
->f_vnode
= vn_alloc(KM_SLEEP
);
54 if (fp
->f_vnode
== NULL
)
57 /* XXX: Setup needed vnode stop, open file etc */
59 fp
->f_file
= fget(fd
);
60 if (fp
->f_file
== NULL
)
64 atomic_inc(&fp
->f_ref
);
66 spin_lock(&file_lock
);
67 list_add(&fp
->f_list
, &file_list
);
68 spin_unlock(&file_lock
);
70 mutex_exit(&fp
->f_lock
);
76 mutex_exit(&fp
->f_lock
);
77 kmem_cache_free(file_cache
, fp
);
83 static void releasef_locked(file_t
*fp
)
85 BUG_ON(fp
->f_file
== NULL
);
86 BUG_ON(fp
->f_vnode
== NULL
);
88 /* Unlinked from list, no refs, safe to free outside mutex */
92 kmem_cache_free(file_cache
, fp
);
100 spin_lock(&file_lock
);
104 atomic_dec(&fp
->f_ref
);
106 if (atomic_read(&fp
->f_ref
) > 0) {
107 spin_unlock(&file_lock
);
111 list_del(&fp
->f_list
);
112 spin_unlock(&file_lock
);
118 EXPORT_SYMBOL(releasef
);
121 file_cache_constructor(void *buf
, void *cdrarg
, int kmflags
)
125 atomic_set(&fp
->f_ref
, 0);
126 mutex_init(&fp
->f_lock
, NULL
, MUTEX_DEFAULT
, NULL
);
129 } /* file_cache_constructor() */
132 file_cache_destructor(void *buf
, void *cdrarg
)
136 mutex_destroy(&fp
->f_lock
);
137 } /* file_cache_destructor() */
142 file_cache
= kmem_cache_create("spl_file_cache", sizeof(file_t
), 64,
143 file_cache_constructor
,
144 file_cache_destructor
,
145 NULL
, NULL
, NULL
, 0);
151 file_t
*fp
, *next_fp
;
154 spin_lock(&file_lock
);
156 list_for_each_entry_safe(fp
, next_fp
, &file_list
, f_list
) {
157 list_del(&fp
->f_list
);
162 kmem_cache_destroy(file_cache
);
164 spin_unlock(&file_lock
);
167 printk("Warning: %d files leaked\n", leaked
);