mirror of
git://sourceware.org/git/lvm2.git
synced 2025-10-08 19:33:19 +03:00
o dev_cache_t program works
This commit is contained in:
@@ -46,6 +46,8 @@ static struct {
|
||||
#define _alloc(x) pool_alloc(_cache.mem, (x))
|
||||
#define _free(x) pool_free(_cache.mem, (x))
|
||||
|
||||
static int _dir_scan(const char *dir);
|
||||
|
||||
/*
|
||||
* return a new path for the destination of the path.
|
||||
*/
|
||||
@@ -90,9 +92,8 @@ static void _collapse_slashes(char *str)
|
||||
*str = *ptr;
|
||||
}
|
||||
|
||||
static struct device *_create_dev(const char *path)
|
||||
static struct device *_create_dev(const char *path, struct stat *info)
|
||||
{
|
||||
struct stat info;
|
||||
struct device *dev;
|
||||
char *name = pool_strdup(_cache.mem, path);
|
||||
|
||||
@@ -103,31 +104,13 @@ static struct device *_create_dev(const char *path)
|
||||
|
||||
_collapse_slashes(name);
|
||||
|
||||
if (stat(name, &info) < 0) {
|
||||
log_sys_err("stat");
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (S_ISLNK(info.st_mode)) {
|
||||
log_debug("%s is a symbolic link, following\n", name);
|
||||
if (!(name = _follow_link(name, &info))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
|
||||
if (!S_ISBLK(info.st_mode)) {
|
||||
log_debug("%s is not a block device\n", name);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!(dev = _alloc(sizeof(*dev)))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
dev->name = name;
|
||||
dev->dev = info.st_rdev;
|
||||
dev->dev = info->st_rdev;
|
||||
return dev;
|
||||
|
||||
bad:
|
||||
@@ -135,28 +118,75 @@ static struct device *_create_dev(const char *path)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct device *_add(const char *dir, const char *path)
|
||||
static int _insert(const char *path, int recurse)
|
||||
{
|
||||
struct device *d;
|
||||
int len = strlen(dir) + strlen(path) + 2;
|
||||
char *buffer = dbg_malloc(len);
|
||||
struct stat info;
|
||||
struct device *dev;
|
||||
|
||||
snprintf(buffer, len, "%s/%s", dir, path);
|
||||
d = dev_cache_get(buffer, NULL);
|
||||
dbg_free(buffer);
|
||||
log_debug("dev-cache adding %s", path);
|
||||
|
||||
return d;
|
||||
if (stat(path, &info) < 0) {
|
||||
log_sys_err("stat");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (S_ISDIR(info.st_mode)) {
|
||||
if (recurse)
|
||||
return _dir_scan(path);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (S_ISLNK(info.st_mode)) {
|
||||
log_debug("%s is a symbolic link, following", path);
|
||||
if (!(path = _follow_link(path, &info))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!S_ISBLK(info.st_mode)) {
|
||||
log_debug("%s is not a block device", path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(dev = _create_dev(path, &info))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
hash_insert(_cache.devices, path, dev);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char *_join(const char *dir, const char *name)
|
||||
{
|
||||
int len = strlen(dir) + strlen(name) + 2;
|
||||
char *r = dbg_malloc(len);
|
||||
if (r)
|
||||
snprintf(r, len, "%s/%s", dir, name);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _dir_scan(const char *dir)
|
||||
{
|
||||
int n, dirent_count;
|
||||
struct dirent **dirent;
|
||||
char *path;
|
||||
|
||||
dirent_count = scandir(dir, &dirent, NULL, alphasort);
|
||||
if (dirent_count > 0) {
|
||||
for (n = 0; n < dirent_count; n++) {
|
||||
_add(dir, dirent[n]->d_name);
|
||||
if (dirent[n]->d_name[0] == '.') {
|
||||
free(dirent[n]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((path = _join(dir, dirent[n]->d_name)))
|
||||
_insert(path, 1);
|
||||
|
||||
dbg_free(path);
|
||||
free(dirent[n]);
|
||||
}
|
||||
free(dirent);
|
||||
@@ -217,21 +247,14 @@ int dev_cache_add_dir(const char *path)
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct device *_insert_new(const char *name)
|
||||
{
|
||||
struct device *d = _create_dev(name);
|
||||
if (!d || !hash_insert(_cache.devices, name, d))
|
||||
return NULL;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
struct device *dev_cache_get(const char *name, struct dev_filter *f)
|
||||
{
|
||||
struct device *d = (struct device *) hash_lookup(_cache.devices, name);
|
||||
|
||||
if (!d && (d = _create_dev(name)))
|
||||
hash_insert(_cache.devices, name, d);
|
||||
if (!d) {
|
||||
_insert(name, 0);
|
||||
d = (struct device *) hash_lookup(_cache.devices, name);
|
||||
}
|
||||
|
||||
return (d && (!f || f->passes_filter(f, d))) ? d : NULL;
|
||||
}
|
||||
|
Reference in New Issue
Block a user