arm64: dts: rockchip: rk3399: add aclk/hclk_vop init freq
[firefly-linux-kernel-4.4.55.git] / fs / sdcardfs / packagelist.c
1 /*
2  * fs/sdcardfs/packagelist.c
3  *
4  * Copyright (c) 2013 Samsung Electronics Co. Ltd
5  *   Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun,
6  *               Sunghwan Yun, Sungjong Seo
7  *
8  * This program has been developed as a stackable file system based on
9  * the WrapFS which written by
10  *
11  * Copyright (c) 1998-2011 Erez Zadok
12  * Copyright (c) 2009     Shrikar Archak
13  * Copyright (c) 2003-2011 Stony Brook University
14  * Copyright (c) 2003-2011 The Research Foundation of SUNY
15  *
16  * This file is dual licensed.  It may be redistributed and/or modified
17  * under the terms of the Apache 2.0 License OR version 2 of the GNU
18  * General Public License.
19  */
20
21 #include "sdcardfs.h"
22 #include <linux/hashtable.h>
23 #include <linux/delay.h>
24 #include <linux/radix-tree.h>
25 #include <linux/dcache.h>
26
27 #include <linux/init.h>
28 #include <linux/module.h>
29 #include <linux/slab.h>
30
31 #include <linux/configfs.h>
32
33 struct hashtable_entry {
34         struct hlist_node hlist;
35         struct hlist_node dlist; /* for deletion cleanup */
36         struct qstr key;
37         atomic_t value;
38 };
39
40 static DEFINE_HASHTABLE(package_to_appid, 8);
41 static DEFINE_HASHTABLE(package_to_userid, 8);
42 static DEFINE_HASHTABLE(ext_to_groupid, 8);
43
44
45 static struct kmem_cache *hashtable_entry_cachep;
46
47 static void inline qstr_init(struct qstr *q, const char *name) {
48         q->name = name;
49         q->len = strlen(q->name);
50         q->hash = full_name_hash(q->name, q->len);
51 }
52
53 static inline int qstr_copy(const struct qstr *src, struct qstr *dest) {
54         dest->name = kstrdup(src->name, GFP_KERNEL);
55         dest->hash_len = src->hash_len;
56         return !!dest->name;
57 }
58
59
60 static appid_t __get_appid(const struct qstr *key)
61 {
62         struct hashtable_entry *hash_cur;
63         unsigned int hash = key->hash;
64         appid_t ret_id;
65
66         rcu_read_lock();
67         hash_for_each_possible_rcu(package_to_appid, hash_cur, hlist, hash) {
68                 if (qstr_case_eq(key, &hash_cur->key)) {
69                         ret_id = atomic_read(&hash_cur->value);
70                         rcu_read_unlock();
71                         return ret_id;
72                 }
73         }
74         rcu_read_unlock();
75         return 0;
76 }
77
78 appid_t get_appid(const char *key)
79 {
80         struct qstr q;
81         qstr_init(&q, key);
82         return __get_appid(&q);
83 }
84
85 static appid_t __get_ext_gid(const struct qstr *key)
86 {
87         struct hashtable_entry *hash_cur;
88         unsigned int hash = key->hash;
89         appid_t ret_id;
90
91         rcu_read_lock();
92         hash_for_each_possible_rcu(ext_to_groupid, hash_cur, hlist, hash) {
93                 if (qstr_case_eq(key, &hash_cur->key)) {
94                         ret_id = atomic_read(&hash_cur->value);
95                         rcu_read_unlock();
96                         return ret_id;
97                 }
98         }
99         rcu_read_unlock();
100         return 0;
101 }
102
103 appid_t get_ext_gid(const char *key)
104 {
105         struct qstr q;
106         qstr_init(&q, key);
107         return __get_ext_gid(&q);
108 }
109
110 static appid_t __is_excluded(const struct qstr *app_name, userid_t user)
111 {
112         struct hashtable_entry *hash_cur;
113         unsigned int hash = app_name->hash;
114
115         rcu_read_lock();
116         hash_for_each_possible_rcu(package_to_userid, hash_cur, hlist, hash) {
117                 if (atomic_read(&hash_cur->value) == user &&
118                                 qstr_case_eq(app_name, &hash_cur->key)) {
119                         rcu_read_unlock();
120                         return 1;
121                 }
122         }
123         rcu_read_unlock();
124         return 0;
125 }
126
127 appid_t is_excluded(const char *key, userid_t user)
128 {
129         struct qstr q;
130         qstr_init(&q, key);
131         return __is_excluded(&q, user);
132 }
133
134 /* Kernel has already enforced everything we returned through
135  * derive_permissions_locked(), so this is used to lock down access
136  * even further, such as enforcing that apps hold sdcard_rw. */
137 int check_caller_access_to_name(struct inode *parent_node, const struct qstr *name) {
138         struct qstr q_autorun = QSTR_LITERAL("autorun.inf");
139         struct qstr q__android_secure = QSTR_LITERAL(".android_secure");
140         struct qstr q_android_secure = QSTR_LITERAL("android_secure");
141
142         /* Always block security-sensitive files at root */
143         if (parent_node && SDCARDFS_I(parent_node)->perm == PERM_ROOT) {
144                 if (qstr_case_eq(name, &q_autorun)
145                         || qstr_case_eq(name, &q__android_secure)
146                         || qstr_case_eq(name, &q_android_secure)) {
147                         return 0;
148                 }
149         }
150
151         /* Root always has access; access for any other UIDs should always
152          * be controlled through packages.list. */
153         if (from_kuid(&init_user_ns, current_fsuid()) == 0) {
154                 return 1;
155         }
156
157         /* No extra permissions to enforce */
158         return 1;
159 }
160
161 /* This function is used when file opening. The open flags must be
162  * checked before calling check_caller_access_to_name() */
163 int open_flags_to_access_mode(int open_flags) {
164         if((open_flags & O_ACCMODE) == O_RDONLY) {
165                 return 0; /* R_OK */
166         } else if ((open_flags & O_ACCMODE) == O_WRONLY) {
167                 return 1; /* W_OK */
168         } else {
169                 /* Probably O_RDRW, but treat as default to be safe */
170                 return 1; /* R_OK | W_OK */
171         }
172 }
173
174 static struct hashtable_entry *alloc_hashtable_entry(const struct qstr *key,
175                 appid_t value)
176 {
177         struct hashtable_entry *ret = kmem_cache_alloc(hashtable_entry_cachep,
178                         GFP_KERNEL);
179         if (!ret)
180                 return NULL;
181
182         if (!qstr_copy(key, &ret->key)) {
183                 kmem_cache_free(hashtable_entry_cachep, ret);
184                 return NULL;
185         }
186
187         atomic_set(&ret->value, value);
188         return ret;
189 }
190
191 static int insert_packagelist_appid_entry_locked(const struct qstr *key, appid_t value)
192 {
193         struct hashtable_entry *hash_cur;
194         struct hashtable_entry *new_entry;
195         unsigned int hash = key->hash;
196
197         hash_for_each_possible_rcu(package_to_appid, hash_cur, hlist, hash) {
198                 if (qstr_case_eq(key, &hash_cur->key)) {
199                         atomic_set(&hash_cur->value, value);
200                         return 0;
201                 }
202         }
203         new_entry = alloc_hashtable_entry(key, value);
204         if (!new_entry)
205                 return -ENOMEM;
206         hash_add_rcu(package_to_appid, &new_entry->hlist, hash);
207         return 0;
208 }
209
210 static int insert_ext_gid_entry_locked(const struct qstr *key, appid_t value)
211 {
212         struct hashtable_entry *hash_cur;
213         struct hashtable_entry *new_entry;
214         unsigned int hash = key->hash;
215
216         /* An extension can only belong to one gid */
217         hash_for_each_possible_rcu(ext_to_groupid, hash_cur, hlist, hash) {
218                 if (qstr_case_eq(key, &hash_cur->key))
219                         return -EINVAL;
220         }
221         new_entry = alloc_hashtable_entry(key, value);
222         if (!new_entry)
223                 return -ENOMEM;
224         hash_add_rcu(ext_to_groupid, &new_entry->hlist, hash);
225         return 0;
226 }
227
228 static int insert_userid_exclude_entry_locked(const struct qstr *key, userid_t value)
229 {
230         struct hashtable_entry *hash_cur;
231         struct hashtable_entry *new_entry;
232         unsigned int hash = key->hash;
233
234         /* Only insert if not already present */
235         hash_for_each_possible_rcu(package_to_userid, hash_cur, hlist, hash) {
236                 if (atomic_read(&hash_cur->value) == value &&
237                                 qstr_case_eq(key, &hash_cur->key))
238                         return 0;
239         }
240         new_entry = alloc_hashtable_entry(key, value);
241         if (!new_entry)
242                 return -ENOMEM;
243         hash_add_rcu(package_to_userid, &new_entry->hlist, hash);
244         return 0;
245 }
246
247 static void fixup_all_perms_name(const struct qstr *key)
248 {
249         struct sdcardfs_sb_info *sbinfo;
250         struct limit_search limit = {
251                 .flags = BY_NAME,
252                 .name = key->name,
253                 .length = key->len,
254         };
255         list_for_each_entry(sbinfo, &sdcardfs_super_list, list) {
256                 if (sbinfo_has_sdcard_magic(sbinfo))
257                         fixup_perms_recursive(sbinfo->sb->s_root, &limit);
258         }
259 }
260
261 static void fixup_all_perms_name_userid(const struct qstr *key, userid_t userid)
262 {
263         struct sdcardfs_sb_info *sbinfo;
264         struct limit_search limit = {
265                 .flags = BY_NAME | BY_USERID,
266                 .name = key->name,
267                 .length = key->len,
268                 .userid = userid,
269         };
270         list_for_each_entry(sbinfo, &sdcardfs_super_list, list) {
271                 if (sbinfo_has_sdcard_magic(sbinfo))
272                         fixup_perms_recursive(sbinfo->sb->s_root, &limit);
273         }
274 }
275
276 static void fixup_all_perms_userid(userid_t userid)
277 {
278         struct sdcardfs_sb_info *sbinfo;
279         struct limit_search limit = {
280                 .flags = BY_USERID,
281                 .userid = userid,
282         };
283         list_for_each_entry(sbinfo, &sdcardfs_super_list, list) {
284                 if (sbinfo_has_sdcard_magic(sbinfo))
285                         fixup_perms_recursive(sbinfo->sb->s_root, &limit);
286         }
287 }
288
289 static int insert_packagelist_entry(const struct qstr *key, appid_t value)
290 {
291         int err;
292
293         mutex_lock(&sdcardfs_super_list_lock);
294         err = insert_packagelist_appid_entry_locked(key, value);
295         if (!err)
296                 fixup_all_perms_name(key);
297         mutex_unlock(&sdcardfs_super_list_lock);
298
299         return err;
300 }
301
302 static int insert_ext_gid_entry(const struct qstr *key, appid_t value)
303 {
304         int err;
305
306         mutex_lock(&sdcardfs_super_list_lock);
307         err = insert_ext_gid_entry_locked(key, value);
308         mutex_unlock(&sdcardfs_super_list_lock);
309
310         return err;
311 }
312
313 static int insert_userid_exclude_entry(const struct qstr *key, userid_t value)
314 {
315         int err;
316
317         mutex_lock(&sdcardfs_super_list_lock);
318         err = insert_userid_exclude_entry_locked(key, value);
319         if (!err)
320                 fixup_all_perms_name_userid(key, value);
321         mutex_unlock(&sdcardfs_super_list_lock);
322
323         return err;
324 }
325
326 static void free_hashtable_entry(struct hashtable_entry *entry)
327 {
328         kfree(entry->key.name);
329         hash_del_rcu(&entry->dlist);
330         kmem_cache_free(hashtable_entry_cachep, entry);
331 }
332
333 static void remove_packagelist_entry_locked(const struct qstr *key)
334 {
335         struct hashtable_entry *hash_cur;
336         unsigned int hash = key->hash;
337         struct hlist_node *h_t;
338         HLIST_HEAD(free_list);
339
340         hash_for_each_possible_rcu(package_to_userid, hash_cur, hlist, hash) {
341                 if (qstr_case_eq(key, &hash_cur->key)) {
342                         hash_del_rcu(&hash_cur->hlist);
343                         hlist_add_head(&hash_cur->dlist, &free_list);
344                 }
345         }
346         hash_for_each_possible_rcu(package_to_appid, hash_cur, hlist, hash) {
347                 if (qstr_case_eq(key, &hash_cur->key)) {
348                         hash_del_rcu(&hash_cur->hlist);
349                         hlist_add_head(&hash_cur->dlist, &free_list);
350                         break;
351                 }
352         }
353         synchronize_rcu();
354         hlist_for_each_entry_safe(hash_cur, h_t, &free_list, dlist)
355                 free_hashtable_entry(hash_cur);
356 }
357
358 static void remove_packagelist_entry(const struct qstr *key)
359 {
360         mutex_lock(&sdcardfs_super_list_lock);
361         remove_packagelist_entry_locked(key);
362         fixup_all_perms_name(key);
363         mutex_unlock(&sdcardfs_super_list_lock);
364         return;
365 }
366
367 static void remove_ext_gid_entry_locked(const struct qstr *key, gid_t group)
368 {
369         struct hashtable_entry *hash_cur;
370         unsigned int hash = key->hash;
371
372         hash_for_each_possible_rcu(ext_to_groupid, hash_cur, hlist, hash) {
373                 if (qstr_case_eq(key, &hash_cur->key) && atomic_read(&hash_cur->value) == group) {
374                         hash_del_rcu(&hash_cur->hlist);
375                         synchronize_rcu();
376                         free_hashtable_entry(hash_cur);
377                         break;
378                 }
379         }
380 }
381
382 static void remove_ext_gid_entry(const struct qstr *key, gid_t group)
383 {
384         mutex_lock(&sdcardfs_super_list_lock);
385         remove_ext_gid_entry_locked(key, group);
386         mutex_unlock(&sdcardfs_super_list_lock);
387         return;
388 }
389
390 static void remove_userid_all_entry_locked(userid_t userid)
391 {
392         struct hashtable_entry *hash_cur;
393         struct hlist_node *h_t;
394         HLIST_HEAD(free_list);
395         int i;
396
397         hash_for_each_rcu(package_to_userid, i, hash_cur, hlist) {
398                 if (atomic_read(&hash_cur->value) == userid) {
399                         hash_del_rcu(&hash_cur->hlist);
400                         hlist_add_head(&hash_cur->dlist, &free_list);
401                 }
402         }
403         synchronize_rcu();
404         hlist_for_each_entry_safe(hash_cur, h_t, &free_list, dlist) {
405                 free_hashtable_entry(hash_cur);
406         }
407 }
408
409 static void remove_userid_all_entry(userid_t userid)
410 {
411         mutex_lock(&sdcardfs_super_list_lock);
412         remove_userid_all_entry_locked(userid);
413         fixup_all_perms_userid(userid);
414         mutex_unlock(&sdcardfs_super_list_lock);
415         return;
416 }
417
418 static void remove_userid_exclude_entry_locked(const struct qstr *key, userid_t userid)
419 {
420         struct hashtable_entry *hash_cur;
421         unsigned int hash = key->hash;
422
423         hash_for_each_possible_rcu(package_to_userid, hash_cur, hlist, hash) {
424                 if (qstr_case_eq(key, &hash_cur->key) &&
425                                 atomic_read(&hash_cur->value) == userid) {
426                         hash_del_rcu(&hash_cur->hlist);
427                         synchronize_rcu();
428                         free_hashtable_entry(hash_cur);
429                         break;
430                 }
431         }
432 }
433
434 static void remove_userid_exclude_entry(const struct qstr *key, userid_t userid)
435 {
436         mutex_lock(&sdcardfs_super_list_lock);
437         remove_userid_exclude_entry_locked(key, userid);
438         fixup_all_perms_name_userid(key, userid);
439         mutex_unlock(&sdcardfs_super_list_lock);
440         return;
441 }
442
443 static void packagelist_destroy(void)
444 {
445         struct hashtable_entry *hash_cur;
446         struct hlist_node *h_t;
447         HLIST_HEAD(free_list);
448         int i;
449         mutex_lock(&sdcardfs_super_list_lock);
450         hash_for_each_rcu(package_to_appid, i, hash_cur, hlist) {
451                 hash_del_rcu(&hash_cur->hlist);
452                 hlist_add_head(&hash_cur->dlist, &free_list);
453         }
454         hash_for_each_rcu(package_to_userid, i, hash_cur, hlist) {
455                 hash_del_rcu(&hash_cur->hlist);
456                 hlist_add_head(&hash_cur->dlist, &free_list);
457         }
458         synchronize_rcu();
459         hlist_for_each_entry_safe(hash_cur, h_t, &free_list, dlist)
460                 free_hashtable_entry(hash_cur);
461         mutex_unlock(&sdcardfs_super_list_lock);
462         printk(KERN_INFO "sdcardfs: destroyed packagelist pkgld\n");
463 }
464
465 #define SDCARDFS_CONFIGFS_ATTR(_pfx, _name)                     \
466 static struct configfs_attribute _pfx##attr_##_name = { \
467         .ca_name        = __stringify(_name),           \
468         .ca_mode        = S_IRUGO | S_IWUGO,            \
469         .ca_owner       = THIS_MODULE,                  \
470         .show           = _pfx##_name##_show,           \
471         .store          = _pfx##_name##_store,          \
472 }
473
474 #define SDCARDFS_CONFIGFS_ATTR_RO(_pfx, _name)                  \
475 static struct configfs_attribute _pfx##attr_##_name = { \
476         .ca_name        = __stringify(_name),           \
477         .ca_mode        = S_IRUGO,                      \
478         .ca_owner       = THIS_MODULE,                  \
479         .show           = _pfx##_name##_show,           \
480 }
481
482 #define SDCARDFS_CONFIGFS_ATTR_WO(_pfx, _name)                  \
483 static struct configfs_attribute _pfx##attr_##_name = { \
484         .ca_name        = __stringify(_name),           \
485         .ca_mode        = S_IWUGO,                      \
486         .ca_owner       = THIS_MODULE,                  \
487         .store          = _pfx##_name##_store,          \
488 }
489
490 struct package_details {
491         struct config_item item;
492         struct qstr name;
493 };
494
495 static inline struct package_details *to_package_details(struct config_item *item)
496 {
497         return item ? container_of(item, struct package_details, item) : NULL;
498 }
499
500 static ssize_t package_details_appid_show(struct config_item *item, char *page)
501 {
502         return scnprintf(page, PAGE_SIZE, "%u\n", __get_appid(&to_package_details(item)->name));
503 }
504
505 static ssize_t package_details_appid_store(struct config_item *item,
506                                        const char *page, size_t count)
507 {
508         unsigned int tmp;
509         int ret;
510
511         ret = kstrtouint(page, 10, &tmp);
512         if (ret)
513                 return ret;
514
515         ret = insert_packagelist_entry(&to_package_details(item)->name, tmp);
516
517         if (ret)
518                 return ret;
519
520         return count;
521 }
522
523 static ssize_t package_details_excluded_userids_show(struct config_item *item,
524                                       char *page)
525 {
526         struct package_details *package_details = to_package_details(item);
527         struct hashtable_entry *hash_cur;
528         unsigned int hash = package_details->name.hash;
529         int count = 0;
530
531         rcu_read_lock();
532         hash_for_each_possible_rcu(package_to_userid, hash_cur, hlist, hash) {
533                 if (qstr_case_eq(&package_details->name, &hash_cur->key))
534                         count += scnprintf(page + count, PAGE_SIZE - count,
535                                         "%d ", atomic_read(&hash_cur->value));
536         }
537         rcu_read_unlock();
538         if (count)
539                 count--;
540         count += scnprintf(page + count, PAGE_SIZE - count, "\n");
541         return count;
542 }
543
544 static ssize_t package_details_excluded_userids_store(struct config_item *item,
545                                        const char *page, size_t count)
546 {
547         unsigned int tmp;
548         int ret;
549
550         ret = kstrtouint(page, 10, &tmp);
551         if (ret)
552                 return ret;
553
554         ret = insert_userid_exclude_entry(&to_package_details(item)->name, tmp);
555
556         if (ret)
557                 return ret;
558
559         return count;
560 }
561
562 static ssize_t package_details_clear_userid_store(struct config_item *item,
563                                        const char *page, size_t count)
564 {
565         unsigned int tmp;
566         int ret;
567
568         ret = kstrtouint(page, 10, &tmp);
569         if (ret)
570                 return ret;
571         remove_userid_exclude_entry(&to_package_details(item)->name, tmp);
572         return count;
573 }
574
575 static void package_details_release(struct config_item *item)
576 {
577         struct package_details *package_details = to_package_details(item);
578         printk(KERN_INFO "sdcardfs: removing %s\n", package_details->name.name);
579         remove_packagelist_entry(&package_details->name);
580         kfree(package_details->name.name);
581         kfree(package_details);
582 }
583
584 SDCARDFS_CONFIGFS_ATTR(package_details_, appid);
585 SDCARDFS_CONFIGFS_ATTR(package_details_, excluded_userids);
586 SDCARDFS_CONFIGFS_ATTR_WO(package_details_, clear_userid);
587
588 static struct configfs_attribute *package_details_attrs[] = {
589         &package_details_attr_appid,
590         &package_details_attr_excluded_userids,
591         &package_details_attr_clear_userid,
592         NULL,
593 };
594
595 static struct configfs_item_operations package_details_item_ops = {
596       .release = package_details_release,
597 };
598
599 static struct config_item_type package_appid_type = {
600         .ct_item_ops    = &package_details_item_ops,
601         .ct_attrs       = package_details_attrs,
602         .ct_owner       = THIS_MODULE,
603 };
604
605 struct extensions_value {
606         struct config_group group;
607         unsigned int num;
608 };
609
610 struct extension_details {
611         struct config_item item;
612         struct qstr name;
613         unsigned int num;
614 };
615
616 static inline struct extensions_value *to_extensions_value(struct config_item *item)
617 {
618         return item ? container_of(to_config_group(item), struct extensions_value, group) : NULL;
619 }
620
621 static inline struct extension_details *to_extension_details(struct config_item *item)
622 {
623         return item ? container_of(item, struct extension_details, item) : NULL;
624 }
625
626 static void extension_details_release(struct config_item *item)
627 {
628         struct extension_details *extension_details = to_extension_details(item);
629
630         printk(KERN_INFO "sdcardfs: No longer mapping %s files to gid %d\n",
631                         extension_details->name.name, extension_details->num);
632         remove_ext_gid_entry(&extension_details->name, extension_details->num);
633         kfree(extension_details->name.name);
634         kfree(extension_details);
635 }
636
637 static struct configfs_item_operations extension_details_item_ops = {
638         .release = extension_details_release,
639 };
640
641 static struct config_item_type extension_details_type = {
642         .ct_item_ops = &extension_details_item_ops,
643         .ct_owner = THIS_MODULE,
644 };
645
646 static struct config_item *extension_details_make_item(struct config_group *group, const char *name)
647 {
648         struct extensions_value *extensions_value = to_extensions_value(&group->cg_item);
649         struct extension_details *extension_details = kzalloc(sizeof(struct extension_details), GFP_KERNEL);
650         const char *tmp;
651         int ret;
652         if (!extension_details)
653                 return ERR_PTR(-ENOMEM);
654
655         tmp = kstrdup(name, GFP_KERNEL);
656         if (!tmp) {
657                 kfree(extension_details);
658                 return ERR_PTR(-ENOMEM);
659         }
660         qstr_init(&extension_details->name, tmp);
661         ret = insert_ext_gid_entry(&extension_details->name, extensions_value->num);
662
663         if (ret) {
664                 kfree(extension_details->name.name);
665                 kfree(extension_details);
666                 return ERR_PTR(ret);
667         }
668         config_item_init_type_name(&extension_details->item, name, &extension_details_type);
669
670         return &extension_details->item;
671 }
672
673 static struct configfs_group_operations extensions_value_group_ops = {
674         .make_item = extension_details_make_item,
675 };
676
677 static struct config_item_type extensions_name_type = {
678         .ct_group_ops   = &extensions_value_group_ops,
679         .ct_owner       = THIS_MODULE,
680 };
681
682 static struct config_group *extensions_make_group(struct config_group *group, const char *name)
683 {
684         struct extensions_value *extensions_value;
685         unsigned int tmp;
686         int ret;
687
688         extensions_value = kzalloc(sizeof(struct extensions_value), GFP_KERNEL);
689         if (!extensions_value)
690                 return ERR_PTR(-ENOMEM);
691         ret = kstrtouint(name, 10, &tmp);
692         if (ret) {
693                 kfree(extensions_value);
694                 return ERR_PTR(ret);
695         }
696
697         extensions_value->num = tmp;
698         config_group_init_type_name(&extensions_value->group, name,
699                                                 &extensions_name_type);
700         return &extensions_value->group;
701 }
702
703 static void extensions_drop_group(struct config_group *group, struct config_item *item)
704 {
705         struct extensions_value *value = to_extensions_value(item);
706         printk(KERN_INFO "sdcardfs: No longer mapping any files to gid %d\n", value->num);
707         kfree(value);
708 }
709
710 static struct configfs_group_operations extensions_group_ops = {
711         .make_group     = extensions_make_group,
712         .drop_item      = extensions_drop_group,
713 };
714
715 static struct config_item_type extensions_type = {
716         .ct_group_ops   = &extensions_group_ops,
717         .ct_owner       = THIS_MODULE,
718 };
719
720 struct config_group extension_group = {
721         .cg_item = {
722                 .ci_namebuf = "extensions",
723                 .ci_type = &extensions_type,
724         },
725 };
726
727 static struct config_item *packages_make_item(struct config_group *group, const char *name)
728 {
729         struct package_details *package_details;
730         const char *tmp;
731
732         package_details = kzalloc(sizeof(struct package_details), GFP_KERNEL);
733         if (!package_details)
734                 return ERR_PTR(-ENOMEM);
735         tmp = kstrdup(name, GFP_KERNEL);
736         if (!tmp) {
737                 kfree(package_details);
738                 return ERR_PTR(-ENOMEM);
739         }
740         qstr_init(&package_details->name, tmp);
741         config_item_init_type_name(&package_details->item, name,
742                                                 &package_appid_type);
743
744         return &package_details->item;
745 }
746
747 static ssize_t packages_list_show(struct config_item *item, char *page)
748 {
749         struct hashtable_entry *hash_cur_app;
750         struct hashtable_entry *hash_cur_user;
751         int i;
752         int count = 0, written = 0;
753         const char errormsg[] = "<truncated>\n";
754         unsigned int hash;
755
756         rcu_read_lock();
757         hash_for_each_rcu(package_to_appid, i, hash_cur_app, hlist) {
758                 written = scnprintf(page + count, PAGE_SIZE - sizeof(errormsg) - count, "%s %d\n",
759                                         hash_cur_app->key.name, atomic_read(&hash_cur_app->value));
760                 hash = hash_cur_app->key.hash;
761                 hash_for_each_possible_rcu(package_to_userid, hash_cur_user, hlist, hash) {
762                         if (qstr_case_eq(&hash_cur_app->key, &hash_cur_user->key)) {
763                                 written += scnprintf(page + count + written - 1,
764                                         PAGE_SIZE - sizeof(errormsg) - count - written + 1,
765                                         " %d\n", atomic_read(&hash_cur_user->value)) - 1;
766                         }
767                 }
768                 if (count + written == PAGE_SIZE - sizeof(errormsg) - 1) {
769                         count += scnprintf(page + count, PAGE_SIZE - count, errormsg);
770                         break;
771                 }
772                 count += written;
773         }
774         rcu_read_unlock();
775
776         return count;
777 }
778
779 static ssize_t packages_remove_userid_store(struct config_item *item,
780                                        const char *page, size_t count)
781 {
782         unsigned int tmp;
783         int ret;
784
785         ret = kstrtouint(page, 10, &tmp);
786         if (ret)
787                 return ret;
788         remove_userid_all_entry(tmp);
789         return count;
790 }
791
792 static struct configfs_attribute packages_attr_packages_gid_list = {
793         .ca_name        = "packages_gid.list",
794         .ca_mode        = S_IRUGO,
795         .ca_owner       = THIS_MODULE,
796         .show           = packages_list_show,
797 };
798
799 SDCARDFS_CONFIGFS_ATTR_WO(packages_, remove_userid);
800
801 static struct configfs_attribute *packages_attrs[] = {
802         &packages_attr_packages_gid_list,
803         &packages_attr_remove_userid,
804         NULL,
805 };
806
807 /*
808  * Note that, since no extra work is required on ->drop_item(),
809  * no ->drop_item() is provided.
810  */
811 static struct configfs_group_operations packages_group_ops = {
812         .make_item      = packages_make_item,
813 };
814
815 static struct config_item_type packages_type = {
816         .ct_group_ops   = &packages_group_ops,
817         .ct_attrs       = packages_attrs,
818         .ct_owner       = THIS_MODULE,
819 };
820
821 struct config_group *sd_default_groups[] = {
822         &extension_group,
823         NULL,
824 };
825
826 static struct configfs_subsystem sdcardfs_packages = {
827         .su_group = {
828                 .cg_item = {
829                         .ci_namebuf = "sdcardfs",
830                         .ci_type = &packages_type,
831                 },
832                 .default_groups = sd_default_groups,
833         },
834 };
835
836 static int configfs_sdcardfs_init(void)
837 {
838         int ret, i;
839         struct configfs_subsystem *subsys = &sdcardfs_packages;
840         for (i = 0; sd_default_groups[i]; i++) {
841                 config_group_init(sd_default_groups[i]);
842         }
843         config_group_init(&subsys->su_group);
844         mutex_init(&subsys->su_mutex);
845         ret = configfs_register_subsystem(subsys);
846         if (ret) {
847                 printk(KERN_ERR "Error %d while registering subsystem %s\n",
848                        ret,
849                        subsys->su_group.cg_item.ci_namebuf);
850         }
851         return ret;
852 }
853
854 static void configfs_sdcardfs_exit(void)
855 {
856         configfs_unregister_subsystem(&sdcardfs_packages);
857 }
858
859 int packagelist_init(void)
860 {
861         hashtable_entry_cachep =
862                 kmem_cache_create("packagelist_hashtable_entry",
863                                         sizeof(struct hashtable_entry), 0, 0, NULL);
864         if (!hashtable_entry_cachep) {
865                 printk(KERN_ERR "sdcardfs: failed creating pkgl_hashtable entry slab cache\n");
866                 return -ENOMEM;
867         }
868
869         configfs_sdcardfs_init();
870         return 0;
871 }
872
873 void packagelist_exit(void)
874 {
875         configfs_sdcardfs_exit();
876         packagelist_destroy();
877         if (hashtable_entry_cachep)
878                 kmem_cache_destroy(hashtable_entry_cachep);
879 }