1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

o code sync for dev-cache.c

o made copyright headers the same

o added __attribute ((format ... to print_log so we'll get better compile errors

o added iterator to the hash table
This commit is contained in:
Joe Thornber 2001-10-03 11:06:31 +00:00
parent 9e300c8427
commit b8e4e502d3
15 changed files with 265 additions and 262 deletions

View File

@ -1,31 +1,7 @@
/* /*
* tools/lib/lvm_config.c * Copyright (C) 2001 Sistina Software (UK) Limited.
*
* Copyright (C) 2001 Sistina Software
*
*
* This LVM library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This LVM library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this LVM library; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA
*
*/
/*
* Changelog
*
* 17/04/2001 - First version [Joe Thornber]
* *
* This file is released under the GPL.
*/ */
#include <sys/types.h> #include <sys/types.h>

View File

@ -1,20 +1,7 @@
/* /*
* Copyright (C) 2001 Sistina Software * Copyright (C) 2001 Sistina Software (UK) Limited.
* *
* This LVM library is free software; you can redistribute it and/or * This file is released under the GPL.
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This LVM library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this LVM library; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA
*/ */
#ifndef _LVM_CONFIG_H #ifndef _LVM_CONFIG_H

View File

@ -181,4 +181,29 @@ void hash_iterate(struct hash_table *t, iterate_fn f)
f(c->data); f(c->data);
} }
void *hash_get_data(struct hash_table *t, struct hash_node *n)
{
return n->data;
}
static struct hash_node *_next_slot(struct hash_table *t, unsigned int s)
{
struct hash_node *c = 0;
int i;
for (i = s; i < t->num_slots && !c; i++)
c = t->slots[i];
return c;
}
struct hash_node *hash_get_first(struct hash_table *t)
{
return _next_slot(t, 0);
}
struct hash_node *hash_get_next(struct hash_table *t, struct hash_node *n)
{
return n->next ? n->next : _next_slot(t, _hash(n->key) + 1);
}

View File

@ -8,10 +8,12 @@
#define _LVM_HASH_H #define _LVM_HASH_H
struct hash_table; struct hash_table;
struct hash_node;
typedef void (*iterate_fn)(void *data); typedef void (*iterate_fn)(void *data);
struct hash_table *create_hash_table(unsigned size_hint); struct hash_table *hash_create(unsigned size_hint);
void destroy_hash_table(struct hash_table *t); void hash_destroy(struct hash_table *t);
char *hash_lookup(struct hash_table *t, const char *key); char *hash_lookup(struct hash_table *t, const char *key);
void hash_insert(struct hash_table *t, const char *key, void *data); void hash_insert(struct hash_table *t, const char *key, void *data);
@ -20,5 +22,9 @@ void hash_remove(struct hash_table *t, const char *key);
unsigned hash_get_num_entries(struct hash_table *t); unsigned hash_get_num_entries(struct hash_table *t);
void hash_iterate(struct hash_table *t, iterate_fn f); void hash_iterate(struct hash_table *t, iterate_fn f);
void *hash_get_data(struct hash_table *t, struct hash_node *n);
struct hash_node *hash_get_first(struct hash_table *t);
struct hash_node *hash_get_next(struct hash_table *t, struct hash_node *n);
#endif #endif

View File

@ -32,9 +32,9 @@ struct list_head {
* This is only for internal list manipulation where we know * This is only for internal list manipulation where we know
* the prev/next entries already! * the prev/next entries already!
*/ */
static __inline__ void __list_add(struct list_head * new, static __inline__ void __list_add(struct list_head *new,
struct list_head * prev, struct list_head *prev,
struct list_head * next) struct list_head *next)
{ {
next->prev = new; next->prev = new;
new->next = next; new->next = next;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2001 Sistina Software * Copyright (C) 2001 Sistina Software (UK) Limited.
* *
* This file is released under the GPL. * This file is released under the GPL.
*/ */
@ -11,83 +11,163 @@
#include <stdlib.h> #include <stdlib.h>
#define DEV_PATH_LEN 256 /*
* FIXME: really need to seperate names from the devices since
* multiple names can point to the same device.
*/
struct d_internal { struct dev_iter {
struct device dev; struct hash_node *current;
struct dev_filter *filter;
int count;
int rw;
FILE *fp;
}; };
struct { struct dir_list {
static pool *mem; struct list_head dir_list;
char *dir[0];
};
static struct {
struct pool *mem;
struct hash_table *devices; struct hash_table *devices;
int has_scanned;
struct list_head dirs;
} _cache; } _cache;
static inline struct d_internal *_alloc_dev()
#define _alloc(x) pool_alloc(_cache.mem, (x))
#define _free(x) pool_free(_cache.mem, (x))
/*
* return a new path for the destination of the path.
*/
static char * _follow_link(const char *path, struct stat *info)
{ {
return pool_alloc(_cache.mem, sizeof(struct d_internal)); char buffer[PATH_MAX + 1], *r;
int n;
n = readlink(path, buffer);
if (n <= 0)
return NULL;
buffer[n] = '\0';
if (stat(buffer, info) < 0) {
log_sys_err("stat");
return NULL;
}
return pool_strdup(_cache.mem, buffer);
} }
static struct d_internal *_create_dev(const char *path) /*
* Get rid of extra slashes in the path string.
*/
static void _collapse_slashes(char *str)
{
char *ptr;
int was_slash = 0;
for (ptr = str; *ptr; ptr++) {
if (*ptr == '/') {
if (was_slash)
continue;
was_slash = 1;
} else
was_slash = 0;
*str++ = *ptr;
}
*str = *ptr;
}
static struct device *_create_dev(const char *path)
{ {
/* FIXME: follow sym links */
struct stat info; struct stat info;
char norm[DEV_PATH_LEN]; struct device *dev;
_normalise_path(norm, path); char *normed = _collapse_slashes(path);
if (stat(path, &info) < 0) { if (!normed) {
stack;
return NULL;
}
if (stat(normed, &info) < 0) {
log_sys_error("stat"); log_sys_error("stat");
return 0; return NULL;
} }
/* FIXME: lost the will to program */ if (S_ISLNK(info.st_mode)) {
if () { char *new_path;
log_debug("%s is a symbolic link, following\n", normed);
normed = _follow_link(normed, &info);
if (!normed)
return NULL;
} }
if (!S_ISBLK(info.st_mode)) {
log_debug("%s is not a block device\n", normed);
return NULL;
}
if (!(dev = _alloc(sizeof(*dev)))) {
stack;
return NULL;
}
dev->name = normed;
dev->dev = info.st_rdev;
return dev;
} }
static struct device *_add(const char *dir, const char *path)
#define DEV_READ 0
#define DEV_WRITE 1
static inline struct FILE *_open_read(const char *path)
{ {
return fopen(path, "r"); struct device *d;
int len = strlen(dir) + strlen(path) + 2;
char *buffer = _alloc(len);
snprintf(buffer, len, "%s/%s", path);
d = dev_cache_get(path);
if (!d)
_free(buffer); /* pool_free is safe in this case */
return d;
} }
static inline struct FILE *_open_write(const char *path) static int _dir_scan(const char *dir)
{ {
return fopen(path, "rw"); int n, dirent_count;
} struct dirent **dirent;
static int _check_open(struct d_internal *di, int rw) dirent_count = scandir(dir, &dirent, NULL, alphasort);
{ if (dirent_count > 0) {
/* is it already open ? */ for (n = 0; n < dirent_count; n++) {
if (dev->fp) _add(dir, dirent[n]->d_name);
return 0; free(dirent[n]);
if (di->fp) {
/* do we need to upgrade a read ? */
if (di->rw == DEV_READ && rw == DEV_WRITE) {
struct FILE *fp = _open_write(di->dev.path);
if (!fp)
return 0;
fclose(di->fp);
di->fp = fp;
} }
} else if (rw == DEV_READ) free(dirent);
di->fp = _open_read(di->dev.path); }
else
di->fp = _open_write(di->dev.path);
return di->fp ? 1 : 0; return 1;
} }
int init_dev_cache() static void _full_scan(void)
{
struct dir_list *dl;
if (_cache.has_scanned)
return;
for (dl = _cache.dirs.next; dl != &_cache.dirs; dl = dl->next)
_dir_scan(dl.dir);
_cache.has_scanned = 1;
}
int dev_cache_init(void)
{ {
if (!(_cache.mem = pool_create(10 * 1024))) { if (!(_cache.mem = pool_create(10 * 1024))) {
stack; stack;
@ -104,68 +184,70 @@ int init_dev_cache()
return 1; return 1;
} }
static void _close_device(void *d) void dev_cache_exit(void)
{
struct d_internal *di = (struct d_internal *) d;
if (di->fp)
fclose(di->fp);
}
void exit_dev_cache()
{ {
pool_destroy(_cache.mem); pool_destroy(_cache.mem);
hash_iterate(_cache.devices, _close_devices);
hash_destroy(_cache.devices); hash_destroy(_cache.devices);
} }
struct device *get_device(const char *name) int dev_cache_add_dir(const char *path)
{ {
struct d_internal *di = hash_lookup(_cache.devices, name); struct dir_list *dl;
if (di)
di->count++;
else {
di = _create_device(name);
if (di) if (!(dl = _alloc(sizeof(*dl) + strlen(path) + 1)))
hash_insert(t, name, di); return 0;
strcpy(dl->dir, path);
list_add(dl, _cache.directories);
return 1;
}
struct device *dev_cache_get(const char *name)
{
struct device *d = hash_lookup(_cache.devices, name);
if (!d && (d = _create_device(name)))
hash_insert(t, name, d);
return d;
}
struct dev_iter *dev_iter_create(struct dev_filter *f)
{
struct dev_iter *di = dbg_malloc(sizeof(*di));
if (!di)
return NULL;
_full_scan();
di->current = hash_get_first();
di->filter = f;
return di;
}
void dev_iter_destroy(struct dev_iter *iter)
{
dbg_free(iter);
}
static inline struct device *_iter_next(struct dev_iter *iter)
{
struct device *d = hash_get_data(_cache.devices, iter->current);
iter->current = hash_next(_cache.devices, iter->current);
return d;
}
struct device *dev_iter_get(struct dev_iter *iter)
{
while (iter->current) {
struct device *d = _iter_next(iter);
if (!iter->filter ||
iter->filter->pass_filter(iter->filter, d))
return d;
} }
return di ? &di->d : 0; return NULL;
} }
void put_device(struct device *d)
{
struct d_internal *di = (struct d_internal *) d;
if (--di->count < 0)
log_error("device reference count < 0");
else if (di->count == 0)
_close_device(di);
}
ssize_t dev_read(struct device *dev, size_t offset, size_t len, void *buffer)
{
struct d_internal *di = (struct d_internal *) dev;
if (!_check_open(di, DEV_READ)) {
stack;
return -EPERM;
}
fseek(dev->fp, offset, SEEK_SET);
return fread(buffer, 1, len, dev->fp);
}
ssize_t dev_write(struct device *dev, size_t offset, size_t len, void *buffer)
{
struct d_internal *di = (struct d_internal *) dev;
if (!_check_open(di, DEV_WRITE)) {
stack;
return -EPERM;
}
fseek(dev->fp, offset, SEEK_SET);
return fwrite(buffer, 1, len, dev->fp);
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2001 Sistina Software * Copyright (C) 2001 Sistina Software (UK) Limited.
* *
* This file is released under the GPL. * This file is released under the GPL.
*/ */
@ -31,7 +31,7 @@ int dev_cache_init(void);
void dev_cache_exit(void); void dev_cache_exit(void);
int dev_cache_add_dir(const char *path); int dev_cache_add_dir(const char *path);
struct device *dev_cache_get(const char *name); struct device *dev_cache_get(const char *name, struct dev_filter *f);
/* /*
@ -45,10 +45,13 @@ struct device *dev_iter_get(struct dev_iter *iter);
/* /*
* All io should use these routines, rather than opening the devices * All io should use these routines, rather than opening the devices
* by hand. You do not have to call an open routine. * by hand. You do not have to call an open routine. ATM all io is
* immediately flushed.
*/ */
__uint64_t dev_get_size(struct device *dev); /* in 512 byte sectors */ int dev_get_size(struct device *dev, uint64_t *size); /* in k */
ssize_t dev_read(struct device *dev, size_t offset, size_t len, void *buffer); int64_t dev_read(struct device *dev, uint64_t offset,
ssize_t dev_write(struct device *dev, size_t offset, size_t len, void *buffer); int64_t len, void *buffer);
int64_t dev_write(struct device *dev, uint64_t offset,
int64_t len, void *buffer);
#endif #endif

View File

@ -20,22 +20,19 @@
#ifndef _LVM_DEV_MANAGER_H #ifndef _LVM_DEV_MANAGER_H
#define _LVM_DEV_MANAGER_H #define _LVM_DEV_MANAGER_H
#include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#include "config.h" #include "config.h"
struct device { struct dev_manager;
char *name; struct dev_iter;
dev_t dev;
};
struct dev_mgr; struct dev_manager *create_dev_manager();
typedef struct _dummy_counter *dev_counter_t;
struct dev_mgr *init_dev_manager(struct config_node *cfg_node);
void fin_dev_manager(struct dev_mgr *dm); void fin_dev_manager(struct dev_mgr *dm);
struct device *dev_by_name(struct dev_mgr *dm, const char *name); struct device *get_dev_by_name(struct dev_mgr *dm, const char *name);
struct device *dev_by_dev(struct dev_mgr *dm, dev_t d); struct device *get_dev_by_dev(struct dev_mgr *dm, dev_t d);
void put_dev(struct dev_mgr *dm, const char *name);
/* either of these trigger a full scan, the first time they're run */ /* either of these trigger a full scan, the first time they're run */
dev_counter_t init_dev_scan(struct dev_mgr *dm); dev_counter_t init_dev_scan(struct dev_mgr *dm);

View File

@ -1,22 +1,7 @@
/* /*
* Copyright (C) 2001 Sistina Software * Copyright (C) 2001 Sistina Software (UK) Limited.
*
*
* This LVM library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This LVM library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this LVM library; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA
* *
* This file is released under the GPL.
*/ */
#include "log.h" #include "log.h"

View File

@ -1,21 +1,7 @@
/* /*
* Copyright (C) 2001 Sistina Software * Copyright (C) 2001 Sistina Software (UK) Limited.
*
* This LVM library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This LVM library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this LVM library; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA
* *
* This file is released under the GPL.
*/ */
#ifndef _LVM_LOG_H #ifndef _LVM_LOG_H
@ -31,7 +17,7 @@
#define _LOG_FATAL 2 #define _LOG_FATAL 2
void init_log(FILE *fp); void init_log(FILE *fp);
void fin_log(); void fin_log(void);
void init_syslog(int facility); void init_syslog(int facility);
void fin_syslog(void); void fin_syslog(void);
@ -43,7 +29,8 @@ void init_debug(int level);
int test_mode(void); int test_mode(void);
int debug_level(void); int debug_level(void);
void print_log(int level, const char *file, int line, const char *format, ...); void print_log(int level, const char *file, int line, const char *format, ...)
__attribute__ (( format (printf, 4, 5) ));
#define plog(l, x...) print_log(l, __FILE__, __LINE__ , ## x) #define plog(l, x...) print_log(l, __FILE__, __LINE__ , ## x)
@ -69,7 +56,6 @@ void print_log(int level, const char *file, int line, const char *format, ...);
* *
* In addition, messages will be logged to file or syslog if they * In addition, messages will be logged to file or syslog if they
* are more serious than the log level specified with -d. * are more serious than the log level specified with -d.
*
*/ */
#define log_error(fmt, args...) log_err(fmt , ## args) #define log_error(fmt, args...) log_err(fmt , ## args)

View File

@ -1,24 +1,7 @@
/* /*
* Copyright (C) 2000, 2001 Sistina Software * Copyright (C) 2001 Sistina Software (UK) Limited.
* *
* lvm is free software; you can redistribute it and/or modify * This file is released under the GPL.
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* lvm is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* TODO:
*
* Thread safety seems to have fallen out, put lock back in.
*/ */
#include <assert.h> #include <assert.h>

View File

@ -1,21 +1,7 @@
/* /*
* Copyright (C) 2001 Sistina Software * Copyright (C) 2001 Sistina Software (UK) Limited.
*
* lvm is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* lvm is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* *
* This file is released under the GPL.
*/ */
#ifndef _LVM_DBG_MALLOC_H #ifndef _LVM_DBG_MALLOC_H

View File

@ -1,22 +1,9 @@
/* /*
* Copyright (C) 2001 Sistina Software * Copyright (C) 2001 Sistina Software (UK) Limited.
*
* LVM is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* LVM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LVM; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* *
* This file is released under the GPL.
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>

View File

@ -32,9 +32,9 @@ struct list_head {
* This is only for internal list manipulation where we know * This is only for internal list manipulation where we know
* the prev/next entries already! * the prev/next entries already!
*/ */
static __inline__ void __list_add(struct list_head * new, static __inline__ void __list_add(struct list_head *new,
struct list_head * prev, struct list_head *prev,
struct list_head * next) struct list_head *next)
{ {
next->prev = new; next->prev = new;
new->next = next; new->next = next;