Advertisement
Guest User

Untitled

a guest
Mar 26th, 2017
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.55 KB | None | 0 0
  1.  
  2.  
  3.  
  4. struct group_info init_groups = { .usage = ATOMIC_INIT(2) };
  5.  
  6. struct group_info *groups_alloc(int gidsetsize){
  7.  
  8.     struct group_info *group_info;
  9.  
  10.     int nblocks;
  11.  
  12.     int i;
  13.  
  14.  
  15.  
  16.     nblocks = (gidsetsize + NGROUPS_PER_BLOCK - 1) / NGROUPS_PER_BLOCK;
  17.  
  18.     /* Make sure we always allocate at least one indirect block pointer */
  19.  
  20.     nblocks = nblocks ? : 1;
  21.  
  22.     group_info = kmalloc(sizeof(*group_info) + nblocks*sizeof(gid_t *), GFP_USER);
  23.  
  24.     if (!group_info)
  25.  
  26.         return NULL;
  27.  
  28.     group_info->ngroups = gidsetsize;
  29.  
  30.     group_info->nblocks = nblocks;
  31.  
  32.     atomic_set(&group_info->usage, 1);
  33.  
  34.  
  35.  
  36.     if (gidsetsize <= NGROUPS_SMALL)
  37.  
  38.         group_info->blocks[0] = group_info->small_block;
  39.  
  40.     else {
  41.  
  42.         for (i = 0; i < nblocks; i++) {
  43.  
  44.             gid_t *b;
  45.  
  46.             b = (void *)__get_free_page(GFP_USER);
  47.  
  48.             if (!b)
  49.  
  50.                 goto out_undo_partial_alloc;
  51.  
  52.             group_info->blocks[i] = b;
  53.  
  54.         }
  55.  
  56.     }
  57.  
  58.     return group_info;
  59.  
  60.  
  61.  
  62. out_undo_partial_alloc:
  63.  
  64.     while (--i >= 0) {
  65.  
  66.         free_page((unsigned long)group_info->blocks[i]);
  67.  
  68.     }
  69.  
  70.     kfree(group_info);
  71.  
  72.     return NULL;
  73.  
  74. }
  75.  
  76.  
  77.  
  78. EXPORT_SYMBOL(groups_alloc);
  79.  
  80.  
  81.  
  82. void groups_free(struct group_info *group_info)
  83.  
  84. {
  85.  
  86.     if (group_info->blocks[0] != group_info->small_block) {
  87.  
  88.         int i;
  89.  
  90.         for (i = 0; i < group_info->nblocks; i++)
  91.  
  92.             free_page((unsigned long)group_info->blocks[i]);
  93.  
  94.     }
  95.  
  96.     kfree(group_info);
  97.  
  98. }
  99.  
  100.  
  101.  
  102. EXPORT_SYMBOL(groups_free);
  103.  
  104.  
  105.  
  106. /* export the group_info to a user-space array */
  107.  
  108. static int groups_to_user(gid_t __user *grouplist,
  109.  
  110.               const struct group_info *group_info)
  111.  
  112. {
  113.  
  114.     int i;
  115.  
  116.     unsigned int count = group_info->ngroups;
  117.  
  118.  
  119.  
  120.     for (i = 0; i < group_info->nblocks; i++) {
  121.  
  122.         unsigned int cp_count = min(NGROUPS_PER_BLOCK, count);
  123.  
  124.         unsigned int len = cp_count * sizeof(*grouplist);
  125.  
  126.  
  127.  
  128.         if (copy_to_user(grouplist, group_info->blocks[i], len))
  129.  
  130.             return -EFAULT;
  131.  
  132.  
  133.  
  134.         grouplist += NGROUPS_PER_BLOCK;
  135.  
  136.         count -= cp_count;
  137.  
  138.     }
  139.  
  140.     return 0;
  141.  
  142. }
  143.  
  144.  
  145.  
  146. /* fill a group_info from a user-space array - it must be allocated already */
  147.  
  148. static int groups_from_user(struct group_info *group_info,
  149.  
  150.     gid_t __user *grouplist)
  151.  
  152. {
  153.  
  154.     int i;
  155.  
  156.     unsigned int count = group_info->ngroups;
  157.  
  158.  
  159.  
  160.     for (i = 0; i < group_info->nblocks; i++) {
  161.  
  162.         unsigned int cp_count = min(NGROUPS_PER_BLOCK, count);
  163.  
  164.         unsigned int len
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement