Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Jul 12th, 2011  |  syntax: None  |  size: 3.02 KB  |  views: 719  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. struct group_info init_groups = { .usage = ATOMIC_INIT(2) };
  2. struct group_info *groups_alloc(int gidsetsize){
  3.     struct group_info *group_info;
  4.     int nblocks;
  5.     int i;
  6.  
  7.     nblocks = (gidsetsize + NGROUPS_PER_BLOCK - 1) / NGROUPS_PER_BLOCK;
  8.     /* Make sure we always allocate at least one indirect block pointer */
  9.     nblocks = nblocks ? : 1;
  10.     group_info = kmalloc(sizeof(*group_info) + nblocks*sizeof(gid_t *), GFP_USER);
  11.     if (!group_info)
  12.         return NULL;
  13.     group_info->ngroups = gidsetsize;
  14.     group_info->nblocks = nblocks;
  15.     atomic_set(&group_info->usage, 1);
  16.  
  17.     if (gidsetsize <= NGROUPS_SMALL)
  18.         group_info->blocks[0] = group_info->small_block;
  19.     else {
  20.         for (i = 0; i < nblocks; i++) {
  21.             gid_t *b;
  22.             b = (void *)__get_free_page(GFP_USER);
  23.             if (!b)
  24.                 goto out_undo_partial_alloc;
  25.             group_info->blocks[i] = b;
  26.         }
  27.     }
  28.     return group_info;
  29.  
  30. out_undo_partial_alloc:
  31.     while (--i >= 0) {
  32.         free_page((unsigned long)group_info->blocks[i]);
  33.     }
  34.     kfree(group_info);
  35.     return NULL;
  36. }
  37.  
  38. EXPORT_SYMBOL(groups_alloc);
  39.  
  40. void groups_free(struct group_info *group_info)
  41. {
  42.     if (group_info->blocks[0] != group_info->small_block) {
  43.         int i;
  44.         for (i = 0; i < group_info->nblocks; i++)
  45.             free_page((unsigned long)group_info->blocks[i]);
  46.     }
  47.     kfree(group_info);
  48. }
  49.  
  50. EXPORT_SYMBOL(groups_free);
  51.  
  52. /* export the group_info to a user-space array */
  53. static int groups_to_user(gid_t __user *grouplist,
  54.               const struct group_info *group_info)
  55. {
  56.     int i;
  57.     unsigned int count = group_info->ngroups;
  58.  
  59.     for (i = 0; i < group_info->nblocks; i++) {
  60.         unsigned int cp_count = min(NGROUPS_PER_BLOCK, count);
  61.         unsigned int len = cp_count * sizeof(*grouplist);
  62.  
  63.         if (copy_to_user(grouplist, group_info->blocks[i], len))
  64.             return -EFAULT;
  65.  
  66.         grouplist += NGROUPS_PER_BLOCK;
  67.         count -= cp_count;
  68.     }
  69.     return 0;
  70. }
  71.  
  72. /* fill a group_info from a user-space array - it must be allocated already */
  73. static int groups_from_user(struct group_info *group_info,
  74.     gid_t __user *grouplist)
  75. {
  76.     int i;
  77.     unsigned int count = group_info->ngroups;
  78.  
  79.     for (i = 0; i < group_info->nblocks; i++) {
  80.         unsigned int cp_count = min(NGROUPS_PER_BLOCK, count);
  81.         unsigned int len = cp_count * sizeof(*grouplist);
  82.  
  83.         if (copy_from_user(group_info->blocks[i], grouplist, len))
  84.             return -EFAULT;
  85.  
  86.         grouplist += NGROUPS_PER_BLOCK;
  87.         count -= cp_count;
  88.     }
  89.     return 0;
  90. }
  91.  
  92. /* a simple Shell sort */
  93. static void groups_sort(struct group_info *group_info)
  94. {
  95.     int base, max, stride;
  96.     int gidsetsize = group_info->ngroups;
  97.  
  98.     for (stride = 1; stride < gidsetsize; stride = 3 * stride + 1)
  99.         ; /* nothing */
  100.     stride /= 3;
  101.  
  102.     while (stride) {
  103.         max = gidsetsize
clone this paste RAW Paste Data