mirror of https://github.com/trapexit/mergerfs.git
Browse Source
rewrite gid cache system
rewrite gid cache system
Uses fixed storage so as to not require C++11 local thread storage or memory allocation.pull/155/head
Antonio SJ Musumeci
9 years ago
4 changed files with 237 additions and 67 deletions
-
7README.md
-
143src/gidcache.cpp
-
66src/gidcache.hpp
-
48src/ugid.cpp
@ -0,0 +1,143 @@ |
|||||
|
/*
|
||||
|
The MIT License (MIT) |
||||
|
|
||||
|
Copyright (c) 2015 Antonio SJ Musumeci <trapexit@spawn.link> |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is |
||||
|
furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in |
||||
|
all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
|
THE SOFTWARE. |
||||
|
*/ |
||||
|
|
||||
|
#include <stdlib.h>
|
||||
|
#include <sys/types.h>
|
||||
|
#include <pwd.h>
|
||||
|
#include <grp.h>
|
||||
|
#include <unistd.h>
|
||||
|
|
||||
|
#include <cstdlib>
|
||||
|
#include <algorithm>
|
||||
|
|
||||
|
#include "gidcache.hpp"
|
||||
|
|
||||
|
bool |
||||
|
gid_t_rec::operator<(const struct gid_t_rec &b) const |
||||
|
{ |
||||
|
return uid < b.uid; |
||||
|
} |
||||
|
|
||||
|
inline |
||||
|
gid_t_rec * |
||||
|
gid_t_cache::begin(void) |
||||
|
{ |
||||
|
return recs; |
||||
|
} |
||||
|
|
||||
|
inline |
||||
|
gid_t_rec * |
||||
|
gid_t_cache::end(void) |
||||
|
{ |
||||
|
return recs + size; |
||||
|
} |
||||
|
|
||||
|
inline |
||||
|
gid_t_rec * |
||||
|
gid_t_cache::allocrec(void) |
||||
|
{ |
||||
|
if(size == MAXRECS) |
||||
|
return &recs[rand() % MAXRECS]; |
||||
|
else |
||||
|
return &recs[size++]; |
||||
|
} |
||||
|
|
||||
|
inline |
||||
|
gid_t_rec * |
||||
|
gid_t_cache::lower_bound(gid_t_rec *begin, |
||||
|
gid_t_rec *end, |
||||
|
const uid_t uid) |
||||
|
{ |
||||
|
int step; |
||||
|
int count; |
||||
|
gid_t_rec *iter; |
||||
|
|
||||
|
count = std::distance(begin,end); |
||||
|
while(count > 0) |
||||
|
{ |
||||
|
iter = begin; |
||||
|
step = count / 2; |
||||
|
std::advance(iter,step); |
||||
|
if(iter->uid < uid) |
||||
|
{ |
||||
|
begin = ++iter; |
||||
|
count -= step + 1; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
count = step; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return begin; |
||||
|
} |
||||
|
|
||||
|
gid_t_rec * |
||||
|
gid_t_cache::cache(const uid_t uid, |
||||
|
const gid_t gid) |
||||
|
{ |
||||
|
int rv; |
||||
|
char buf[4096]; |
||||
|
struct passwd pwd; |
||||
|
struct passwd *pwdrv; |
||||
|
gid_t_rec *rec; |
||||
|
|
||||
|
rec = allocrec(); |
||||
|
|
||||
|
rec->uid = uid; |
||||
|
rv = ::getpwuid_r(uid,&pwd,buf,sizeof(buf),&pwdrv); |
||||
|
if(pwdrv != NULL && rv == 0) |
||||
|
{ |
||||
|
rec->size = 0; |
||||
|
rv = ::getgrouplist(pwd.pw_name,gid,NULL,&rec->size); |
||||
|
rec->size = std::min(MAXGIDS,rec->size); |
||||
|
rv = ::getgrouplist(pwd.pw_name,gid,rec->gids,&rec->size); |
||||
|
if(rv == -1) |
||||
|
{ |
||||
|
rec->gids[0] = gid; |
||||
|
rec->size = 1; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return rec; |
||||
|
} |
||||
|
|
||||
|
void |
||||
|
gid_t_cache::initgroups(const uid_t uid, |
||||
|
const gid_t gid) |
||||
|
{ |
||||
|
gid_t_rec *rec; |
||||
|
|
||||
|
rec = lower_bound(begin(),end(),uid); |
||||
|
if(rec == end() || rec->uid != uid) |
||||
|
{ |
||||
|
rec = cache(uid,gid); |
||||
|
::setgroups(rec->size,rec->gids); |
||||
|
std::sort(begin(),end()); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
::setgroups(rec->size,rec->gids); |
||||
|
} |
||||
|
} |
@ -0,0 +1,66 @@ |
|||||
|
/*
|
||||
|
The MIT License (MIT) |
||||
|
|
||||
|
Copyright (c) 2015 Antonio SJ Musumeci <trapexit@spawn.link> |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is |
||||
|
furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in |
||||
|
all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
|
THE SOFTWARE. |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __GIDCACHE_HPP__
|
||||
|
#define __GIDCACHE_HPP__
|
||||
|
|
||||
|
#include <sys/types.h>
|
||||
|
#include <unistd.h>
|
||||
|
|
||||
|
#define MAXGIDS 32
|
||||
|
#define MAXRECS 256
|
||||
|
|
||||
|
struct gid_t_rec |
||||
|
{ |
||||
|
uid_t uid; |
||||
|
int size; |
||||
|
gid_t gids[MAXGIDS]; |
||||
|
|
||||
|
bool |
||||
|
operator<(const struct gid_t_rec &b) const; |
||||
|
}; |
||||
|
|
||||
|
struct gid_t_cache |
||||
|
{ |
||||
|
public: |
||||
|
size_t size; |
||||
|
gid_t_rec recs[MAXRECS]; |
||||
|
|
||||
|
private: |
||||
|
gid_t_rec * begin(void); |
||||
|
gid_t_rec * end(void); |
||||
|
gid_t_rec * allocrec(void); |
||||
|
gid_t_rec * lower_bound(gid_t_rec *begin, |
||||
|
gid_t_rec *end, |
||||
|
const uid_t uid); |
||||
|
gid_t_rec * cache(const uid_t uid, |
||||
|
const gid_t gid); |
||||
|
|
||||
|
public: |
||||
|
void |
||||
|
initgroups(const uid_t uid, |
||||
|
const gid_t gid); |
||||
|
}; |
||||
|
|
||||
|
#endif
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue