mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
dev-cache: skip double stat() call on each _insert
When the device is inserted in dev_name_confirmed() stat() is called twice as _insert() has it's own stat() call. Extend _insert() parameter with struct stat* - which could be used if it has been just obtained. When NULL is passed code is doing its own stat() call as before.
This commit is contained in:
parent
7c5feaed3b
commit
6c0e44d5a2
@ -1,5 +1,6 @@
|
|||||||
Version 2.02.105 -
|
Version 2.02.105 -
|
||||||
=====================================
|
=====================================
|
||||||
|
Optimize double call of stat() for cached devices.
|
||||||
Enable support for thin provisioning for default configuration.
|
Enable support for thin provisioning for default configuration.
|
||||||
Improve process_each_lv_in_vg() tag processing.
|
Improve process_each_lv_in_vg() tag processing.
|
||||||
Reodered and simplified logging code.
|
Reodered and simplified logging code.
|
||||||
|
@ -50,7 +50,8 @@ static struct {
|
|||||||
#define _free(x) dm_pool_free(_cache.mem, (x))
|
#define _free(x) dm_pool_free(_cache.mem, (x))
|
||||||
#define _strdup(x) dm_pool_strdup(_cache.mem, (x))
|
#define _strdup(x) dm_pool_strdup(_cache.mem, (x))
|
||||||
|
|
||||||
static int _insert(const char *path, int rec, int check_with_udev_db);
|
static int _insert(const char *path, const struct stat *info,
|
||||||
|
int rec, int check_with_udev_db);
|
||||||
|
|
||||||
/* Setup non-zero members of passed zeroed 'struct device' */
|
/* Setup non-zero members of passed zeroed 'struct device' */
|
||||||
static void _dev_init(struct device *dev, int max_error_count)
|
static void _dev_init(struct device *dev, int max_error_count)
|
||||||
@ -442,7 +443,7 @@ static int _insert_dir(const char *dir)
|
|||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
_collapse_slashes(path);
|
_collapse_slashes(path);
|
||||||
r &= _insert(path, 1, 0);
|
r &= _insert(path, NULL, 1, 0);
|
||||||
dm_free(path);
|
dm_free(path);
|
||||||
|
|
||||||
free(dirent[n]);
|
free(dirent[n]);
|
||||||
@ -528,14 +529,14 @@ static int _insert_udev_dir(struct udev *udev, const char *dir)
|
|||||||
log_very_verbose("udev failed to return a device node for entry %s.",
|
log_very_verbose("udev failed to return a device node for entry %s.",
|
||||||
entry_name);
|
entry_name);
|
||||||
else
|
else
|
||||||
r &= _insert(node_name, 0, 0);
|
r &= _insert(node_name, NULL, 0, 0);
|
||||||
|
|
||||||
udev_list_entry_foreach(symlink_entry, udev_device_get_devlinks_list_entry(device)) {
|
udev_list_entry_foreach(symlink_entry, udev_device_get_devlinks_list_entry(device)) {
|
||||||
if (!(symlink_name = udev_list_entry_get_name(symlink_entry)))
|
if (!(symlink_name = udev_list_entry_get_name(symlink_entry)))
|
||||||
log_very_verbose("udev failed to return a symlink name for entry %s.",
|
log_very_verbose("udev failed to return a symlink name for entry %s.",
|
||||||
entry_name);
|
entry_name);
|
||||||
else
|
else
|
||||||
r &= _insert(symlink_name, 0, 0);
|
r &= _insert(symlink_name, NULL, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
udev_device_unref(device);
|
udev_device_unref(device);
|
||||||
@ -589,28 +590,33 @@ static void _insert_dirs(struct dm_list *dirs)
|
|||||||
|
|
||||||
#endif /* UDEV_SYNC_SUPPORT */
|
#endif /* UDEV_SYNC_SUPPORT */
|
||||||
|
|
||||||
static int _insert(const char *path, int rec, int check_with_udev_db)
|
static int _insert(const char *path, const struct stat *info,
|
||||||
|
int rec, int check_with_udev_db)
|
||||||
{
|
{
|
||||||
struct stat info;
|
struct stat tinfo;
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
if (stat(path, &info) < 0) {
|
if (!info) {
|
||||||
|
if (stat(path, &tinfo) < 0) {
|
||||||
log_sys_very_verbose("stat", path);
|
log_sys_very_verbose("stat", path);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
info = &tinfo;
|
||||||
|
}
|
||||||
|
|
||||||
if (check_with_udev_db && !_device_in_udev_db(info.st_rdev)) {
|
if (check_with_udev_db && !_device_in_udev_db(info->st_rdev)) {
|
||||||
log_very_verbose("%s: Not in udev db", path);
|
log_very_verbose("%s: Not in udev db", path);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (S_ISDIR(info.st_mode)) { /* add a directory */
|
if (S_ISDIR(info->st_mode)) { /* add a directory */
|
||||||
/* check it's not a symbolic link */
|
/* check it's not a symbolic link */
|
||||||
if (lstat(path, &info) < 0) {
|
if (lstat(path, &tinfo) < 0) {
|
||||||
log_sys_very_verbose("lstat", path);
|
log_sys_very_verbose("lstat", path);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (S_ISLNK(info.st_mode)) {
|
if (S_ISLNK(tinfo.st_mode)) {
|
||||||
log_debug_devs("%s: Symbolic link to directory", path);
|
log_debug_devs("%s: Symbolic link to directory", path);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -618,12 +624,12 @@ static int _insert(const char *path, int rec, int check_with_udev_db)
|
|||||||
if (rec && !_insert_dir(path))
|
if (rec && !_insert_dir(path))
|
||||||
return_0;
|
return_0;
|
||||||
} else { /* add a device */
|
} else { /* add a device */
|
||||||
if (!S_ISBLK(info.st_mode)) {
|
if (!S_ISBLK(info->st_mode)) {
|
||||||
log_debug_devs("%s: Not a block device", path);
|
log_debug_devs("%s: Not a block device", path);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_insert_dev(path, info.st_rdev))
|
if (!_insert_dev(path, info->st_rdev))
|
||||||
return_0;
|
return_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -881,7 +887,7 @@ const char *dev_name_confirmed(struct device *dev, int quiet)
|
|||||||
if (dm_list_size(&dev->aliases) > 1) {
|
if (dm_list_size(&dev->aliases) > 1) {
|
||||||
dm_list_del(dev->aliases.n);
|
dm_list_del(dev->aliases.n);
|
||||||
if (!r)
|
if (!r)
|
||||||
_insert(name, 0, obtain_device_list_from_udev());
|
_insert(name, &buf, 0, obtain_device_list_from_udev());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -903,13 +909,20 @@ struct device *dev_cache_get(const char *name, struct dev_filter *f)
|
|||||||
return d;
|
return d;
|
||||||
|
|
||||||
/* If the entry's wrong, remove it */
|
/* If the entry's wrong, remove it */
|
||||||
if (d && (stat(name, &buf) || (buf.st_rdev != d->dev))) {
|
if (stat(name, &buf) < 0) {
|
||||||
|
if (d)
|
||||||
|
dm_hash_remove(_cache.names, name);
|
||||||
|
log_sys_very_verbose("stat", name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d && (buf.st_rdev != d->dev)) {
|
||||||
dm_hash_remove(_cache.names, name);
|
dm_hash_remove(_cache.names, name);
|
||||||
d = NULL;
|
d = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!d) {
|
if (!d) {
|
||||||
_insert(name, 0, obtain_device_list_from_udev());
|
_insert(name, &buf, 0, obtain_device_list_from_udev());
|
||||||
d = (struct device *) dm_hash_lookup(_cache.names, name);
|
d = (struct device *) dm_hash_lookup(_cache.names, name);
|
||||||
if (!d) {
|
if (!d) {
|
||||||
_full_scan(0);
|
_full_scan(0);
|
||||||
|
Loading…
Reference in New Issue
Block a user