FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Redhat > Device-mapper Development

 
 
LinkBack Thread Tools
 
Old 05-25-2011, 12:40 PM
Hannes Reinecke
 
Default Use refcounting for sysfs devices

As we're caching sysfs devices we need to introduce some sort
of refcounting here. Otherwise the device might be removed from
other threads while we're still accessing it.

References: bnc#642846

Signed-off-by: Hannes Reinecke <hare@suse.de>

diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c
index fc64881..ff63a1b 100644
--- a/libmultipath/sysfs.c
+++ b/libmultipath/sysfs.c
@@ -44,6 +44,7 @@ static LIST_HEAD(sysfs_dev_list);
struct sysfs_dev {
struct list_head node;
struct sysfs_device dev;
+ int refcount;
};

int sysfs_init(char *path, size_t len)
@@ -152,6 +153,7 @@ struct sysfs_device *sysfs_device_get(const char *devpath)
if (strcmp(sysdev_loop->dev.devpath, devpath_real) == 0) {
dbg("found vanished dev in cache '%s'",
sysdev_loop->dev.devpath);
+ sysdev_loop->refcount++;
return &sysdev_loop->dev;
}
}
@@ -167,6 +169,7 @@ struct sysfs_device *sysfs_device_get(const char *devpath)
if (strcmp(sysdev_loop->dev.devpath, devpath_real) == 0) {
dbg("found dev in cache '%s'", sysdev_loop->dev.devpath);
dev = &sysdev_loop->dev;
+ sysdev_loop->refcount++;
}
}

@@ -177,6 +180,7 @@ struct sysfs_device *sysfs_device_get(const char *devpath)
if (sysdev == NULL)
return NULL;
memset(sysdev, 0x00, sizeof(struct sysfs_dev));
+ sysdev->refcount = 1;
list_add(&sysdev->node, &sysfs_dev_list);
dev = &sysdev->dev;
}
@@ -243,6 +247,8 @@ struct sysfs_device *sysfs_device_verify(struct sysfs_device *dev)
char path[PATH_SIZE];
struct stat statbuf;

+ if (!dev->devpath)
+ return NULL;
strlcpy(path, sysfs_path, sizeof(path));
strlcat(path, dev->devpath, sizeof(path));
if (stat(dev->devpath, &statbuf) == 0 &&
@@ -258,15 +264,21 @@ void sysfs_device_put(struct sysfs_device *dev)

list_for_each_entry(sysdev_loop, &sysfs_dev_list, node) {
if (&sysdev_loop->dev == dev) {
- dbg("removed dev '%s' from cache",
- sysdev_loop->dev.devpath);
- list_del(&sysdev_loop->node);
- free(sysdev_loop);
+ sysdev_loop->refcount--;
+ if (!sysdev_loop->refcount) {
+ dbg("removed dev '%s' from cache",
+ sysdev_loop->dev.devpath);
+ list_del(&sysdev_loop->node);
+ free(sysdev_loop);
+ } else {
+ dbg("dev '%s' still in cache, refcount %d",
+ sysdev_loop->dev.devpath,
+ sysdev_loop->refcount);
+ }
return;
}
}
- dbg("dev '%s' not found in cache",
- sysdev_loop->dev.devpath);
+ dbg("dev '%s' not found in cache", dev->devpath);

return;
}

--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
 

Thread Tools




All times are GMT. The time now is 06:29 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org