|
|
c401cc |
From 71beabf07ea569c41b4b2ce9a8d91e82a85b29c3 Mon Sep 17 00:00:00 2001
|
|
|
c401cc |
Message-Id: <71beabf07ea569c41b4b2ce9a8d91e82a85b29c3@dist-git>
|
|
|
c401cc |
From: Eric Blake <eblake@redhat.com>
|
|
|
c401cc |
Date: Wed, 26 Feb 2014 14:54:32 +0100
|
|
|
c401cc |
Subject: [PATCH] storage: reduce number of stat calls
|
|
|
c401cc |
|
|
|
c401cc |
https://bugzilla.redhat.com/show_bug.cgi?id=1032370
|
|
|
c401cc |
|
|
|
c401cc |
We are calling fstat() at least twice per storage volume in
|
|
|
c401cc |
a directory storage pool; this is rather wasteful. Refactoring
|
|
|
c401cc |
this is also a step towards making code reusable for gluster,
|
|
|
c401cc |
where gluster can provide struct stat but cannot use fstat().
|
|
|
c401cc |
|
|
|
c401cc |
* src/storage/storage_backend.h
|
|
|
c401cc |
(virStorageBackendVolOpenCheckMode)
|
|
|
c401cc |
(virStorageBackendUpdateVolTargetInfoFD): Update signature.
|
|
|
c401cc |
* src/storage/storage_backend.c
|
|
|
c401cc |
(virStorageBackendVolOpenCheckMode): Pass stat results back.
|
|
|
c401cc |
(virStorageBackendUpdateVolTargetInfoFD): Use existing stats.
|
|
|
c401cc |
(virStorageBackendVolOpen, virStorageBackendUpdateVolTargetInfo):
|
|
|
c401cc |
Update callers.
|
|
|
c401cc |
* src/storage/storage_backend_fs.c (virStorageBackendProbeTarget):
|
|
|
c401cc |
Likewise.
|
|
|
c401cc |
* src/storage/storage_backend_scsi.c
|
|
|
c401cc |
(virStorageBackendSCSIUpdateVolTargetInfo): Likewise.
|
|
|
c401cc |
* src/storage/storage_backend_mpath.c
|
|
|
c401cc |
(virStorageBackendMpathUpdateVolTargetInfo): Likewise.
|
|
|
c401cc |
|
|
|
c401cc |
Signed-off-by: Eric Blake <eblake@redhat.com>
|
|
|
c401cc |
(cherry picked from commit 9cac863965aa318667619727c387ec8ee3965557)
|
|
|
c401cc |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
c401cc |
---
|
|
|
c401cc |
src/storage/storage_backend.c | 62 +++++++++++++++++--------------------
|
|
|
c401cc |
src/storage/storage_backend.h | 10 ++++--
|
|
|
c401cc |
src/storage/storage_backend_fs.c | 5 +--
|
|
|
c401cc |
src/storage/storage_backend_mpath.c | 7 +++--
|
|
|
c401cc |
src/storage/storage_backend_scsi.c | 7 +++--
|
|
|
c401cc |
5 files changed, 49 insertions(+), 42 deletions(-)
|
|
|
c401cc |
|
|
|
c401cc |
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
|
|
|
c401cc |
index 086642c..f8c0004 100644
|
|
|
c401cc |
--- a/src/storage/storage_backend.c
|
|
|
c401cc |
+++ b/src/storage/storage_backend.c
|
|
|
c401cc |
@@ -1129,30 +1129,30 @@ virStorageBackendForType(int type)
|
|
|
c401cc |
* volume is a dangling symbolic link.
|
|
|
c401cc |
*/
|
|
|
c401cc |
int
|
|
|
c401cc |
-virStorageBackendVolOpenCheckMode(const char *path, unsigned int flags)
|
|
|
c401cc |
+virStorageBackendVolOpenCheckMode(const char *path, struct stat *sb,
|
|
|
c401cc |
+ unsigned int flags)
|
|
|
c401cc |
{
|
|
|
c401cc |
int fd, mode = 0;
|
|
|
c401cc |
- struct stat sb;
|
|
|
c401cc |
char *base = last_component(path);
|
|
|
c401cc |
|
|
|
c401cc |
- if (lstat(path, &sb) < 0) {
|
|
|
c401cc |
+ if (lstat(path, sb) < 0) {
|
|
|
c401cc |
virReportSystemError(errno,
|
|
|
c401cc |
_("cannot stat file '%s'"),
|
|
|
c401cc |
path);
|
|
|
c401cc |
return -1;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
- if (S_ISFIFO(sb.st_mode)) {
|
|
|
c401cc |
+ if (S_ISFIFO(sb->st_mode)) {
|
|
|
c401cc |
VIR_WARN("ignoring FIFO '%s'", path);
|
|
|
c401cc |
return -2;
|
|
|
c401cc |
- } else if (S_ISSOCK(sb.st_mode)) {
|
|
|
c401cc |
+ } else if (S_ISSOCK(sb->st_mode)) {
|
|
|
c401cc |
VIR_WARN("ignoring socket '%s'", path);
|
|
|
c401cc |
return -2;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
if ((fd = open(path, O_RDONLY|O_NONBLOCK|O_NOCTTY)) < 0) {
|
|
|
c401cc |
if ((errno == ENOENT || errno == ELOOP) &&
|
|
|
c401cc |
- S_ISLNK(sb.st_mode)) {
|
|
|
c401cc |
+ S_ISLNK(sb->st_mode)) {
|
|
|
c401cc |
VIR_WARN("ignoring dangling symlink '%s'", path);
|
|
|
c401cc |
return -2;
|
|
|
c401cc |
}
|
|
|
c401cc |
@@ -1163,7 +1163,7 @@ virStorageBackendVolOpenCheckMode(const char *path, unsigned int flags)
|
|
|
c401cc |
return -1;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
- if (fstat(fd, &sb) < 0) {
|
|
|
c401cc |
+ if (fstat(fd, sb) < 0) {
|
|
|
c401cc |
virReportSystemError(errno,
|
|
|
c401cc |
_("cannot stat file '%s'"),
|
|
|
c401cc |
path);
|
|
|
c401cc |
@@ -1171,13 +1171,13 @@ virStorageBackendVolOpenCheckMode(const char *path, unsigned int flags)
|
|
|
c401cc |
return -1;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
- if (S_ISREG(sb.st_mode))
|
|
|
c401cc |
+ if (S_ISREG(sb->st_mode))
|
|
|
c401cc |
mode = VIR_STORAGE_VOL_OPEN_REG;
|
|
|
c401cc |
- else if (S_ISCHR(sb.st_mode))
|
|
|
c401cc |
+ else if (S_ISCHR(sb->st_mode))
|
|
|
c401cc |
mode = VIR_STORAGE_VOL_OPEN_CHAR;
|
|
|
c401cc |
- else if (S_ISBLK(sb.st_mode))
|
|
|
c401cc |
+ else if (S_ISBLK(sb->st_mode))
|
|
|
c401cc |
mode = VIR_STORAGE_VOL_OPEN_BLOCK;
|
|
|
c401cc |
- else if (S_ISDIR(sb.st_mode)) {
|
|
|
c401cc |
+ else if (S_ISDIR(sb->st_mode)) {
|
|
|
c401cc |
mode = VIR_STORAGE_VOL_OPEN_DIR;
|
|
|
c401cc |
|
|
|
c401cc |
if (STREQ(base, ".") ||
|
|
|
c401cc |
@@ -1206,7 +1206,8 @@ virStorageBackendVolOpenCheckMode(const char *path, unsigned int flags)
|
|
|
c401cc |
|
|
|
c401cc |
int virStorageBackendVolOpen(const char *path)
|
|
|
c401cc |
{
|
|
|
c401cc |
- return virStorageBackendVolOpenCheckMode(path,
|
|
|
c401cc |
+ struct stat sb;
|
|
|
c401cc |
+ return virStorageBackendVolOpenCheckMode(path, &sb,
|
|
|
c401cc |
VIR_STORAGE_VOL_OPEN_DEFAULT);
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
@@ -1217,14 +1218,16 @@ virStorageBackendUpdateVolTargetInfo(virStorageVolTargetPtr target,
|
|
|
c401cc |
unsigned int openflags)
|
|
|
c401cc |
{
|
|
|
c401cc |
int ret, fd;
|
|
|
c401cc |
+ struct stat sb;
|
|
|
c401cc |
|
|
|
c401cc |
- if ((ret = virStorageBackendVolOpenCheckMode(target->path,
|
|
|
c401cc |
+ if ((ret = virStorageBackendVolOpenCheckMode(target->path, &sb,
|
|
|
c401cc |
openflags)) < 0)
|
|
|
c401cc |
return ret;
|
|
|
c401cc |
|
|
|
c401cc |
fd = ret;
|
|
|
c401cc |
ret = virStorageBackendUpdateVolTargetInfoFD(target,
|
|
|
c401cc |
fd,
|
|
|
c401cc |
+ &sb,
|
|
|
c401cc |
allocation,
|
|
|
c401cc |
capacity);
|
|
|
c401cc |
|
|
|
c401cc |
@@ -1275,35 +1278,28 @@ int virStorageBackendUpdateVolInfo(virStorageVolDefPtr vol,
|
|
|
c401cc |
int
|
|
|
c401cc |
virStorageBackendUpdateVolTargetInfoFD(virStorageVolTargetPtr target,
|
|
|
c401cc |
int fd,
|
|
|
c401cc |
+ struct stat *sb,
|
|
|
c401cc |
unsigned long long *allocation,
|
|
|
c401cc |
unsigned long long *capacity)
|
|
|
c401cc |
{
|
|
|
c401cc |
- struct stat sb;
|
|
|
c401cc |
#if WITH_SELINUX
|
|
|
c401cc |
security_context_t filecon = NULL;
|
|
|
c401cc |
#endif
|
|
|
c401cc |
|
|
|
c401cc |
- if (fstat(fd, &sb) < 0) {
|
|
|
c401cc |
- virReportSystemError(errno,
|
|
|
c401cc |
- _("cannot stat file '%s'"),
|
|
|
c401cc |
- target->path);
|
|
|
c401cc |
- return -1;
|
|
|
c401cc |
- }
|
|
|
c401cc |
-
|
|
|
c401cc |
if (allocation) {
|
|
|
c401cc |
- if (S_ISREG(sb.st_mode)) {
|
|
|
c401cc |
+ if (S_ISREG(sb->st_mode)) {
|
|
|
c401cc |
#ifndef WIN32
|
|
|
c401cc |
- *allocation = (unsigned long long)sb.st_blocks *
|
|
|
c401cc |
+ *allocation = (unsigned long long)sb->st_blocks *
|
|
|
c401cc |
(unsigned long long)DEV_BSIZE;
|
|
|
c401cc |
#else
|
|
|
c401cc |
- *allocation = sb.st_size;
|
|
|
c401cc |
+ *allocation = sb->st_size;
|
|
|
c401cc |
#endif
|
|
|
c401cc |
/* Regular files may be sparse, so logical size (capacity) is not same
|
|
|
c401cc |
* as actual allocation above
|
|
|
c401cc |
*/
|
|
|
c401cc |
if (capacity)
|
|
|
c401cc |
- *capacity = sb.st_size;
|
|
|
c401cc |
- } else if (S_ISDIR(sb.st_mode)) {
|
|
|
c401cc |
+ *capacity = sb->st_size;
|
|
|
c401cc |
+ } else if (S_ISDIR(sb->st_mode)) {
|
|
|
c401cc |
*allocation = 0;
|
|
|
c401cc |
if (capacity)
|
|
|
c401cc |
*capacity = 0;
|
|
|
c401cc |
@@ -1328,16 +1324,16 @@ virStorageBackendUpdateVolTargetInfoFD(virStorageVolTargetPtr target,
|
|
|
c401cc |
}
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
- target->perms.mode = sb.st_mode & S_IRWXUGO;
|
|
|
c401cc |
- target->perms.uid = sb.st_uid;
|
|
|
c401cc |
- target->perms.gid = sb.st_gid;
|
|
|
c401cc |
+ target->perms.mode = sb->st_mode & S_IRWXUGO;
|
|
|
c401cc |
+ target->perms.uid = sb->st_uid;
|
|
|
c401cc |
+ target->perms.gid = sb->st_gid;
|
|
|
c401cc |
|
|
|
c401cc |
if (!target->timestamps && VIR_ALLOC(target->timestamps) < 0)
|
|
|
c401cc |
return -1;
|
|
|
c401cc |
- target->timestamps->atime = get_stat_atime(&sb);
|
|
|
c401cc |
- target->timestamps->btime = get_stat_birthtime(&sb);
|
|
|
c401cc |
- target->timestamps->ctime = get_stat_ctime(&sb);
|
|
|
c401cc |
- target->timestamps->mtime = get_stat_mtime(&sb);
|
|
|
c401cc |
+ target->timestamps->atime = get_stat_atime(sb);
|
|
|
c401cc |
+ target->timestamps->btime = get_stat_birthtime(sb);
|
|
|
c401cc |
+ target->timestamps->ctime = get_stat_ctime(sb);
|
|
|
c401cc |
+ target->timestamps->mtime = get_stat_mtime(sb);
|
|
|
c401cc |
|
|
|
c401cc |
VIR_FREE(target->perms.label);
|
|
|
c401cc |
|
|
|
c401cc |
diff --git a/src/storage/storage_backend.h b/src/storage/storage_backend.h
|
|
|
c401cc |
index 55e0fee..9e07dd8 100644
|
|
|
c401cc |
--- a/src/storage/storage_backend.h
|
|
|
c401cc |
+++ b/src/storage/storage_backend.h
|
|
|
c401cc |
@@ -24,6 +24,8 @@
|
|
|
c401cc |
#ifndef __VIR_STORAGE_BACKEND_H__
|
|
|
c401cc |
# define __VIR_STORAGE_BACKEND_H__
|
|
|
c401cc |
|
|
|
c401cc |
+# include <sys/stat.h>
|
|
|
c401cc |
+
|
|
|
c401cc |
# include "internal.h"
|
|
|
c401cc |
# include "storage_conf.h"
|
|
|
c401cc |
# include "vircommand.h"
|
|
|
c401cc |
@@ -110,9 +112,10 @@ enum {
|
|
|
c401cc |
VIR_STORAGE_VOL_OPEN_CHAR |\
|
|
|
c401cc |
VIR_STORAGE_VOL_OPEN_BLOCK)
|
|
|
c401cc |
|
|
|
c401cc |
-int virStorageBackendVolOpenCheckMode(const char *path, unsigned int flags)
|
|
|
c401cc |
-ATTRIBUTE_RETURN_CHECK
|
|
|
c401cc |
-ATTRIBUTE_NONNULL(1);
|
|
|
c401cc |
+int virStorageBackendVolOpenCheckMode(const char *path, struct stat *sb,
|
|
|
c401cc |
+ unsigned int flags)
|
|
|
c401cc |
+ ATTRIBUTE_RETURN_CHECK
|
|
|
c401cc |
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
|
|
c401cc |
|
|
|
c401cc |
int virStorageBackendUpdateVolInfo(virStorageVolDefPtr vol,
|
|
|
c401cc |
int withCapacity);
|
|
|
c401cc |
@@ -126,6 +129,7 @@ int virStorageBackendUpdateVolTargetInfo(virStorageVolTargetPtr target,
|
|
|
c401cc |
unsigned int openflags);
|
|
|
c401cc |
int virStorageBackendUpdateVolTargetInfoFD(virStorageVolTargetPtr target,
|
|
|
c401cc |
int fd,
|
|
|
c401cc |
+ struct stat *sb,
|
|
|
c401cc |
unsigned long long *allocation,
|
|
|
c401cc |
unsigned long long *capacity);
|
|
|
c401cc |
int
|
|
|
c401cc |
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
|
|
|
c401cc |
index 0374ea1..5d68232 100644
|
|
|
c401cc |
--- a/src/storage/storage_backend_fs.c
|
|
|
c401cc |
+++ b/src/storage/storage_backend_fs.c
|
|
|
c401cc |
@@ -70,18 +70,19 @@ virStorageBackendProbeTarget(virStorageVolTargetPtr target,
|
|
|
c401cc |
int fd = -1;
|
|
|
c401cc |
int ret = -1;
|
|
|
c401cc |
virStorageFileMetadata *meta = NULL;
|
|
|
c401cc |
+ struct stat sb;
|
|
|
c401cc |
|
|
|
c401cc |
*backingStore = NULL;
|
|
|
c401cc |
*backingStoreFormat = VIR_STORAGE_FILE_AUTO;
|
|
|
c401cc |
if (encryption)
|
|
|
c401cc |
*encryption = NULL;
|
|
|
c401cc |
|
|
|
c401cc |
- if ((ret = virStorageBackendVolOpenCheckMode(target->path,
|
|
|
c401cc |
+ if ((ret = virStorageBackendVolOpenCheckMode(target->path, &sb,
|
|
|
c401cc |
VIR_STORAGE_VOL_FS_REFRESH_FLAGS)) < 0)
|
|
|
c401cc |
goto error; /* Take care to propagate ret, it is not always -1 */
|
|
|
c401cc |
fd = ret;
|
|
|
c401cc |
|
|
|
c401cc |
- if ((ret = virStorageBackendUpdateVolTargetInfoFD(target, fd,
|
|
|
c401cc |
+ if ((ret = virStorageBackendUpdateVolTargetInfoFD(target, fd, &sb,
|
|
|
c401cc |
allocation,
|
|
|
c401cc |
capacity)) < 0) {
|
|
|
c401cc |
goto error;
|
|
|
c401cc |
diff --git a/src/storage/storage_backend_mpath.c b/src/storage/storage_backend_mpath.c
|
|
|
c401cc |
index 8333f18..4191b7b 100644
|
|
|
c401cc |
--- a/src/storage/storage_backend_mpath.c
|
|
|
c401cc |
+++ b/src/storage/storage_backend_mpath.c
|
|
|
c401cc |
@@ -1,7 +1,7 @@
|
|
|
c401cc |
/*
|
|
|
c401cc |
* storage_backend_mpath.c: storage backend for multipath handling
|
|
|
c401cc |
*
|
|
|
c401cc |
- * Copyright (C) 2009-2011 Red Hat, Inc.
|
|
|
c401cc |
+ * Copyright (C) 2009-2011, 2013 Red Hat, Inc.
|
|
|
c401cc |
* Copyright (C) 2009-2008 Dave Allan
|
|
|
c401cc |
*
|
|
|
c401cc |
* This library is free software; you can redistribute it and/or
|
|
|
c401cc |
@@ -46,13 +46,16 @@ virStorageBackendMpathUpdateVolTargetInfo(virStorageVolTargetPtr target,
|
|
|
c401cc |
{
|
|
|
c401cc |
int ret = -1;
|
|
|
c401cc |
int fdret, fd = -1;
|
|
|
c401cc |
+ struct stat sb;
|
|
|
c401cc |
|
|
|
c401cc |
- if ((fdret = virStorageBackendVolOpen(target->path)) < 0)
|
|
|
c401cc |
+ if ((fdret = virStorageBackendVolOpenCheckMode(target->path, &sb,
|
|
|
c401cc |
+ VIR_STORAGE_VOL_OPEN_DEFAULT)) < 0)
|
|
|
c401cc |
goto out;
|
|
|
c401cc |
fd = fdret;
|
|
|
c401cc |
|
|
|
c401cc |
if (virStorageBackendUpdateVolTargetInfoFD(target,
|
|
|
c401cc |
fd,
|
|
|
c401cc |
+ &sb,
|
|
|
c401cc |
allocation,
|
|
|
c401cc |
capacity) < 0)
|
|
|
c401cc |
goto out;
|
|
|
c401cc |
diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c
|
|
|
c401cc |
index 26baf4a..9a2b423 100644
|
|
|
c401cc |
--- a/src/storage/storage_backend_scsi.c
|
|
|
c401cc |
+++ b/src/storage/storage_backend_scsi.c
|
|
|
c401cc |
@@ -1,7 +1,7 @@
|
|
|
c401cc |
/*
|
|
|
c401cc |
* storage_backend_scsi.c: storage backend for SCSI handling
|
|
|
c401cc |
*
|
|
|
c401cc |
- * Copyright (C) 2007-2008 Red Hat, Inc.
|
|
|
c401cc |
+ * Copyright (C) 2007-2008, 2013 Red Hat, Inc.
|
|
|
c401cc |
* Copyright (C) 2007-2008 Daniel P. Berrange
|
|
|
c401cc |
*
|
|
|
c401cc |
* This library is free software; you can redistribute it and/or
|
|
|
c401cc |
@@ -138,13 +138,16 @@ virStorageBackendSCSIUpdateVolTargetInfo(virStorageVolTargetPtr target,
|
|
|
c401cc |
{
|
|
|
c401cc |
int fdret, fd = -1;
|
|
|
c401cc |
int ret = -1;
|
|
|
c401cc |
+ struct stat sb;
|
|
|
c401cc |
|
|
|
c401cc |
- if ((fdret = virStorageBackendVolOpen(target->path)) < 0)
|
|
|
c401cc |
+ if ((fdret = virStorageBackendVolOpenCheckMode(target->path, &sb,
|
|
|
c401cc |
+ VIR_STORAGE_VOL_OPEN_DEFAULT)) < 0)
|
|
|
c401cc |
goto cleanup;
|
|
|
c401cc |
fd = fdret;
|
|
|
c401cc |
|
|
|
c401cc |
if (virStorageBackendUpdateVolTargetInfoFD(target,
|
|
|
c401cc |
fd,
|
|
|
c401cc |
+ &sb,
|
|
|
c401cc |
allocation,
|
|
|
c401cc |
capacity) < 0)
|
|
|
c401cc |
goto cleanup;
|
|
|
c401cc |
--
|
|
|
c401cc |
1.9.0
|
|
|
c401cc |
|