mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* cleanup filesystem core
@ 2012-02-15  8:22 Sascha Hauer
  2012-02-15  8:22 ` [PATCH 01/12] add list_is_singular Sascha Hauer
                   ` (11 more replies)
  0 siblings, 12 replies; 13+ messages in thread
From: Sascha Hauer @ 2012-02-15  8:22 UTC (permalink / raw)
  To: barebox

This series cleans up the filesystem core. The great goal of this series is to
allow unmounting a fileystem by just unregistering the device.
unmount already goes down to unregister a device, but unmount also cleans up
the allocated ressources. We move the filesystem drivers/devices to their own
bus which allows us to clean up the resources in the busses remove function so
that a filesystem can be unmounted *and* cleaned up by unregistering the device.

With this series (and the preceding one) it's possible to call the 'usb' command
on a panda board multiple times without crashing barebox. I tested this with
the onboard USB network adapter and a USB flash drive with a FAT mounted.

Sascha

Sascha Hauer (12):
      add list_is_singular
      dos partitions: Do not register as fixed partitions
      fs: Store mtab entries in list
      fs: make locally used function get_mtab_entry_by_path static
      fs: Store mtab path in allocated string
      fs: remove unused function fsdev_get_mountpoint
      fs: simplify get_mtab_entry_by_path
      fs: remove only once used variable
      fs: remove fs devices list
      fs: put fs devices on its own bus
      fs: allow to mount on subdirectories
      devices: unregister children when unregistering a device

 commands/mount.c      |   17 ++--
 common/partitions.c   |    2 +-
 drivers/base/driver.c |   20 +++-
 fs/fs.c               |  233 ++++++++++++++++++++++--------------------------
 include/fs.h          |   19 ++---
 include/linux/list.h  |    9 ++
 6 files changed, 145 insertions(+), 155 deletions(-)

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 01/12] add list_is_singular
  2012-02-15  8:22 cleanup filesystem core Sascha Hauer
@ 2012-02-15  8:22 ` Sascha Hauer
  2012-02-15  8:22 ` [PATCH 02/12] dos partitions: Do not register as fixed partitions Sascha Hauer
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Sascha Hauer @ 2012-02-15  8:22 UTC (permalink / raw)
  To: barebox

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 include/linux/list.h |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/include/linux/list.h b/include/linux/list.h
index 15ed499..5ae90b4 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -210,6 +210,15 @@ static inline int list_empty_careful(const struct list_head *head)
 	return (next == head) && (next == head->prev);
 }
 
+/**
+ * list_is_singular - tests whether a list has just one entry.
+ * @head: the list to test.
+ */
+static inline int list_is_singular(const struct list_head *head)
+{
+	return !list_empty(head) && (head->next == head->prev);
+}
+
 static inline void __list_splice(struct list_head *list,
 				 struct list_head *head)
 {
-- 
1.7.9


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 02/12] dos partitions: Do not register as fixed partitions
  2012-02-15  8:22 cleanup filesystem core Sascha Hauer
  2012-02-15  8:22 ` [PATCH 01/12] add list_is_singular Sascha Hauer
@ 2012-02-15  8:22 ` Sascha Hauer
  2012-02-15  8:22 ` [PATCH 03/12] fs: Store mtab entries in list Sascha Hauer
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Sascha Hauer @ 2012-02-15  8:22 UTC (permalink / raw)
  To: barebox

A fixed partition means that we can't remove it. This is only suitable
for our vital /dev/self0 and /dev/env0 partitions, so remove the fixed
flag.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/partitions.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/common/partitions.c b/common/partitions.c
index e4f3ad6..74b4f12 100644
--- a/common/partitions.c
+++ b/common/partitions.c
@@ -163,7 +163,7 @@ static int register_one_partition(struct block_device *blk,
 	return devfs_add_partition(blk->cdev.name,
 				part->first_sec * SECTOR_SIZE,
 				part->size * SECTOR_SIZE,
-				DEVFS_PARTITION_FIXED, partition_name);
+				0, partition_name);
 }
 
 /**
-- 
1.7.9


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 03/12] fs: Store mtab entries in list
  2012-02-15  8:22 cleanup filesystem core Sascha Hauer
  2012-02-15  8:22 ` [PATCH 01/12] add list_is_singular Sascha Hauer
  2012-02-15  8:22 ` [PATCH 02/12] dos partitions: Do not register as fixed partitions Sascha Hauer
@ 2012-02-15  8:22 ` Sascha Hauer
  2012-02-15  8:22 ` [PATCH 04/12] fs: make locally used function get_mtab_entry_by_path static Sascha Hauer
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Sascha Hauer @ 2012-02-15  8:22 UTC (permalink / raw)
  To: barebox

To make the code a bit easier to read. Also, do not allow
to umount / when something else is mounted.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/mount.c |   17 +++++-------
 fs/fs.c          |   78 +++++++++++++++++++++++-------------------------------
 include/fs.h     |    6 +++-
 3 files changed, 44 insertions(+), 57 deletions(-)

diff --git a/commands/mount.c b/commands/mount.c
index 7cefdbe..926cd3f 100644
--- a/commands/mount.c
+++ b/commands/mount.c
@@ -33,18 +33,15 @@
 static int do_mount(struct command *cmdtp, int argc, char *argv[])
 {
 	int ret = 0;
-	struct mtab_entry *entry = NULL;
+	struct mtab_entry *entry;
 
 	if (argc == 1) {
-		do {
-			entry = mtab_next_entry(entry);
-			if (entry) {
-				printf("%s on %s type %s\n",
-					entry->parent_device ? dev_name(entry->parent_device) : "none",
-					entry->path,
-					entry->dev->name);
-			}
-		} while (entry);
+		for_each_mtab_entry(entry) {
+			printf("%s on %s type %s\n",
+				entry->parent_device ? dev_name(entry->parent_device) : "none",
+				entry->path,
+				entry->dev->name);
+		}
 		return 0;
 	}
 
diff --git a/fs/fs.c b/fs/fs.c
index 13df71c..3dfbaaa 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -167,11 +167,12 @@ char *normalise_path(const char *pathname)
 }
 EXPORT_SYMBOL(normalise_path);
 
-static struct mtab_entry *mtab;
+LIST_HEAD(mtab_list);
+static struct mtab_entry *mtab_root;
 
 struct mtab_entry *get_mtab_entry_by_path(const char *_path)
 {
-	struct mtab_entry *match = NULL, *e = mtab;
+	struct mtab_entry *e = NULL;
 	char *path, *tok;
 
 	if (*_path != '/')
@@ -183,24 +184,15 @@ struct mtab_entry *get_mtab_entry_by_path(const char *_path)
 	if (tok)
 		*tok = 0;
 
-	while (e) {
-		if (!strcmp(path, e->path)) {
-			match = e;
-			break;
-		}
-		e = e->next;
+	for_each_mtab_entry(e) {
+		if (!strcmp(path, e->path))
+			goto found;
 	}
-
+	e = mtab_root;
+found:
 	free(path);
 
-	return match ? match : mtab;
-}
-
-struct mtab_entry *mtab_next_entry(struct mtab_entry *e)
-{
-	if (!e)
-		return mtab;
-	return e->next;
+	return e;
 }
 
 const char *fsdev_get_mountpoint(struct fs_device_d *fsdev)
@@ -248,7 +240,7 @@ static struct device_d *get_fs_device_by_path(char **path)
 	e = get_mtab_entry_by_path(*path);
 	if (!e)
 		return NULL;
-	if (e != mtab)
+	if (e != mtab_root)
 		*path += strlen(e->path);
 
 	dev = e->dev;
@@ -751,11 +743,6 @@ int mount(const char *device, const char *fsname, const char *_path)
 
 	debug("mount: %s on %s type %s\n", device, path, fsname);
 
-	if (get_mtab_entry_by_path(path) != mtab) {
-		errno = -EBUSY;
-		goto out;
-	}
-
 	if (strchr(path + 1, '/')) {
 		printf("mounting allowed on first directory level only\n");
 		errno = -EBUSY;
@@ -774,7 +761,7 @@ int mount(const char *device, const char *fsname, const char *_path)
 		goto out;
 	}
 
-	if (mtab) {
+	if (mtab_root) {
 		if (path_check_prereq(path, S_IFDIR))
 			goto out;
 	} else {
@@ -825,16 +812,12 @@ int mount(const char *device, const char *fsname, const char *_path)
 	safe_strncpy(entry->path, path, PATH_MAX);
 	entry->dev = dev;
 	entry->parent_device = parent_device;
-	entry->next = NULL;
-
-	if (!mtab)
-		mtab = entry;
-	else {
-		struct mtab_entry *e = mtab;
-		while (e->next)
-			e = e->next;
-		e->next = entry;
-	}
+
+	list_add_tail(&entry->list, &mtab_list);
+
+	if (!mtab_root)
+		mtab_root = entry;
+
 	errno = 0;
 
 	free(path);
@@ -854,27 +837,32 @@ EXPORT_SYMBOL(mount);
 
 int umount(const char *pathname)
 {
-	struct mtab_entry *entry = mtab;
-	struct mtab_entry *last = mtab;
+	struct mtab_entry *entry = NULL, *e;
 	char *p = normalise_path(pathname);
 	struct fs_device_d *fsdev;
 
-	while(entry && strcmp(p, entry->path)) {
-		last = entry;
-		entry = entry->next;
+	for_each_mtab_entry(e) {
+		if (!strcmp(p, e->path)) {
+			entry = e;
+			break;
+		}
 	}
 
 	free(p);
 
+	if (e == mtab_root && !list_is_singular(&mtab_list)) {
+		errno = -EBUSY;
+		return errno;
+	}
+
 	if (!entry) {
 		errno = -EFAULT;
 		return errno;
 	}
 
-	if (entry == mtab)
-		mtab = mtab->next;
-	else
-		last->next = entry->next;
+	list_del(&entry->list);
+	if (entry == mtab_root)
+		mtab_root = NULL;
 
 	unregister_device(entry->dev);
 	fsdev = entry->dev->type_data;
@@ -951,11 +939,11 @@ int stat(const char *filename, struct stat *s)
 		goto out;
 	}
 
-	if (e != mtab && strcmp(f, e->path)) {
+	if (e != mtab_root && strcmp(f, e->path)) {
 		f += strlen(e->path);
 		dev = e->dev;
 	} else
-		dev = mtab->dev;
+		dev = mtab_root->dev;
 
 	fsdrv = (struct fs_driver_d *)dev->driver->type_data;
 
diff --git a/include/fs.h b/include/fs.h
index 97d5995..dd10677 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -78,11 +78,14 @@ struct fs_driver_d {
 
 struct mtab_entry {
 	char path[PATH_MAX];
-	struct mtab_entry *next;
 	struct device_d *dev;
 	struct device_d *parent_device;
+	struct list_head list;
 };
 
+extern struct list_head mtab_list;
+#define for_each_mtab_entry(e) list_for_each_entry(e, &mtab_list, list)
+
 struct fs_device_d {
 	char *backingstore; /* the device we are associated with */
 	struct device_d dev; /* our own device */
@@ -148,7 +151,6 @@ char *mkmodestr(unsigned long mode, char *str);
  * directly in / and of course the root directory itself
  */
 struct mtab_entry *get_mtab_entry_by_path(const char *path);
-struct mtab_entry *mtab_next_entry(struct mtab_entry *entry);
 const char *fsdev_get_mountpoint(struct fs_device_d *fsdev);
 
 /*
-- 
1.7.9


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 04/12] fs: make locally used function get_mtab_entry_by_path static
  2012-02-15  8:22 cleanup filesystem core Sascha Hauer
                   ` (2 preceding siblings ...)
  2012-02-15  8:22 ` [PATCH 03/12] fs: Store mtab entries in list Sascha Hauer
@ 2012-02-15  8:22 ` Sascha Hauer
  2012-02-15  8:22 ` [PATCH 05/12] fs: Store mtab path in allocated string Sascha Hauer
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Sascha Hauer @ 2012-02-15  8:22 UTC (permalink / raw)
  To: barebox

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 fs/fs.c      |    2 +-
 include/fs.h |    1 -
 2 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/fs/fs.c b/fs/fs.c
index 3dfbaaa..afa0198 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -170,7 +170,7 @@ EXPORT_SYMBOL(normalise_path);
 LIST_HEAD(mtab_list);
 static struct mtab_entry *mtab_root;
 
-struct mtab_entry *get_mtab_entry_by_path(const char *_path)
+static struct mtab_entry *get_mtab_entry_by_path(const char *_path)
 {
 	struct mtab_entry *e = NULL;
 	char *path, *tok;
diff --git a/include/fs.h b/include/fs.h
index dd10677..d31fb20 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -150,7 +150,6 @@ char *mkmodestr(unsigned long mode, char *str);
  * Note that we only support mounting on directories lying
  * directly in / and of course the root directory itself
  */
-struct mtab_entry *get_mtab_entry_by_path(const char *path);
 const char *fsdev_get_mountpoint(struct fs_device_d *fsdev);
 
 /*
-- 
1.7.9


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 05/12] fs: Store mtab path in allocated string
  2012-02-15  8:22 cleanup filesystem core Sascha Hauer
                   ` (3 preceding siblings ...)
  2012-02-15  8:22 ` [PATCH 04/12] fs: make locally used function get_mtab_entry_by_path static Sascha Hauer
@ 2012-02-15  8:22 ` Sascha Hauer
  2012-02-15  8:22 ` [PATCH 06/12] fs: remove unused function fsdev_get_mountpoint Sascha Hauer
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Sascha Hauer @ 2012-02-15  8:22 UTC (permalink / raw)
  To: barebox

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 fs/fs.c      |    5 +++--
 include/fs.h |    2 +-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/fs/fs.c b/fs/fs.c
index afa0198..d65a41f 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -808,8 +808,8 @@ int mount(const char *device, const char *fsname, const char *_path)
 	dev = &fsdev->dev;
 
 	/* add mtab entry */
-	entry = &fsdev->mtab; 
-	safe_strncpy(entry->path, path, PATH_MAX);
+	entry = &fsdev->mtab;
+	entry->path = xstrdup(path);
 	entry->dev = dev;
 	entry->parent_device = parent_device;
 
@@ -860,6 +860,7 @@ int umount(const char *pathname)
 		return errno;
 	}
 
+	free(entry->path);
 	list_del(&entry->list);
 	if (entry == mtab_root)
 		mtab_root = NULL;
diff --git a/include/fs.h b/include/fs.h
index d31fb20..f1a1931 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -77,7 +77,7 @@ struct fs_driver_d {
 };
 
 struct mtab_entry {
-	char path[PATH_MAX];
+	char *path;
 	struct device_d *dev;
 	struct device_d *parent_device;
 	struct list_head list;
-- 
1.7.9


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 06/12] fs: remove unused function fsdev_get_mountpoint
  2012-02-15  8:22 cleanup filesystem core Sascha Hauer
                   ` (4 preceding siblings ...)
  2012-02-15  8:22 ` [PATCH 05/12] fs: Store mtab path in allocated string Sascha Hauer
@ 2012-02-15  8:22 ` Sascha Hauer
  2012-02-15  8:22 ` [PATCH 07/12] fs: simplify get_mtab_entry_by_path Sascha Hauer
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Sascha Hauer @ 2012-02-15  8:22 UTC (permalink / raw)
  To: barebox

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 fs/fs.c      |    5 -----
 include/fs.h |    7 -------
 2 files changed, 0 insertions(+), 12 deletions(-)

diff --git a/fs/fs.c b/fs/fs.c
index d65a41f..7175e33 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -195,11 +195,6 @@ found:
 	return e;
 }
 
-const char *fsdev_get_mountpoint(struct fs_device_d *fsdev)
-{
-	return fsdev->mtab.path;
-}
-
 static FILE files[MAX_FILES];
 
 static FILE *get_file(void)
diff --git a/include/fs.h b/include/fs.h
index f1a1931..8daa1bc 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -146,13 +146,6 @@ int ls(const char *path, ulong flags);
 char *mkmodestr(unsigned long mode, char *str);
 
 /*
- * Information about mounted devices.
- * Note that we only support mounting on directories lying
- * directly in / and of course the root directory itself
- */
-const char *fsdev_get_mountpoint(struct fs_device_d *fsdev);
-
-/*
  * Read a file into memory. Memory is allocated with malloc and must
  * be freed with free() afterwards. This function allocates one
  * byte more than actually needed and sets this to zero, so that
-- 
1.7.9


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 07/12] fs: simplify get_mtab_entry_by_path
  2012-02-15  8:22 cleanup filesystem core Sascha Hauer
                   ` (5 preceding siblings ...)
  2012-02-15  8:22 ` [PATCH 06/12] fs: remove unused function fsdev_get_mountpoint Sascha Hauer
@ 2012-02-15  8:22 ` Sascha Hauer
  2012-02-15  8:22 ` [PATCH 08/12] fs: remove only once used variable Sascha Hauer
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Sascha Hauer @ 2012-02-15  8:22 UTC (permalink / raw)
  To: barebox

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 fs/fs.c |   23 ++++++-----------------
 1 files changed, 6 insertions(+), 17 deletions(-)

diff --git a/fs/fs.c b/fs/fs.c
index 7175e33..121bf6f 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -170,29 +170,18 @@ EXPORT_SYMBOL(normalise_path);
 LIST_HEAD(mtab_list);
 static struct mtab_entry *mtab_root;
 
-static struct mtab_entry *get_mtab_entry_by_path(const char *_path)
+static struct mtab_entry *get_mtab_entry_by_path(const char *path)
 {
 	struct mtab_entry *e = NULL;
-	char *path, *tok;
-
-	if (*_path != '/')
-		return NULL;
-
-	path = strdup(_path);
-
-	tok = strchr(path + 1, '/');
-	if (tok)
-		*tok = 0;
 
 	for_each_mtab_entry(e) {
-		if (!strcmp(path, e->path))
-			goto found;
+		int len = strlen(e->path);
+		if (!strncmp(path, e->path, len) &&
+				(path[len] == '/' || path[len] == 0))
+			return e;
 	}
-	e = mtab_root;
-found:
-	free(path);
 
-	return e;
+	return mtab_root;
 }
 
 static FILE files[MAX_FILES];
-- 
1.7.9


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 08/12] fs: remove only once used variable
  2012-02-15  8:22 cleanup filesystem core Sascha Hauer
                   ` (6 preceding siblings ...)
  2012-02-15  8:22 ` [PATCH 07/12] fs: simplify get_mtab_entry_by_path Sascha Hauer
@ 2012-02-15  8:22 ` Sascha Hauer
  2012-02-15  8:22 ` [PATCH 09/12] fs: remove fs devices list Sascha Hauer
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Sascha Hauer @ 2012-02-15  8:22 UTC (permalink / raw)
  To: barebox

dev is used only once, so make the code a tiny bit simpler by
not using an extra variable but dereference it when needed directly.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 fs/fs.c |    6 ++----
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/fs/fs.c b/fs/fs.c
index 121bf6f..7bb5d8e 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -718,7 +718,7 @@ int mount(const char *device, const char *fsname, const char *_path)
 	struct fs_driver_d *fs_drv = NULL, *f;
 	struct mtab_entry *entry;
 	struct fs_device_d *fsdev;
-	struct device_d *dev, *parent_device = NULL;
+	struct device_d *parent_device = NULL;
 	struct cdev *cdev = NULL;
 	int ret;
 	char *path = normalise_path(_path);
@@ -789,12 +789,10 @@ int mount(const char *device, const char *fsname, const char *_path)
 	if (parent_device)
 		dev_add_child(parent_device, &fsdev->dev);
 
-	dev = &fsdev->dev;
-
 	/* add mtab entry */
 	entry = &fsdev->mtab;
 	entry->path = xstrdup(path);
-	entry->dev = dev;
+	entry->dev = &fsdev->dev;
 	entry->parent_device = parent_device;
 
 	list_add_tail(&entry->list, &mtab_list);
-- 
1.7.9


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 09/12] fs: remove fs devices list
  2012-02-15  8:22 cleanup filesystem core Sascha Hauer
                   ` (7 preceding siblings ...)
  2012-02-15  8:22 ` [PATCH 08/12] fs: remove only once used variable Sascha Hauer
@ 2012-02-15  8:22 ` Sascha Hauer
  2012-02-15  8:22 ` [PATCH 10/12] fs: put fs devices on its own bus Sascha Hauer
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Sascha Hauer @ 2012-02-15  8:22 UTC (permalink / raw)
  To: barebox

We store the fs devices in a list only because we want to
check if the fs driver needs a backingstore or not. The
driver will bail out anyway if it needs a backingstore and
doesn't find one. So we can remove this check and thus remove
the list of fs devices.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 fs/fs.c      |   23 +----------------------
 include/fs.h |    2 --
 2 files changed, 1 insertions(+), 24 deletions(-)

diff --git a/fs/fs.c b/fs/fs.c
index 7bb5d8e..3e65c64 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -701,7 +701,6 @@ static LIST_HEAD(fs_driver_list);
 
 int register_fs_driver(struct fs_driver_d *fsdrv)
 {
-	list_add_tail(&fsdrv->list, &fs_driver_list);
 	register_driver(&fsdrv->drv);
 	return 0;
 }
@@ -715,7 +714,6 @@ EXPORT_SYMBOL(register_fs_driver);
  */
 int mount(const char *device, const char *fsname, const char *_path)
 {
-	struct fs_driver_d *fs_drv = NULL, *f;
 	struct mtab_entry *entry;
 	struct fs_device_d *fsdev;
 	struct device_d *parent_device = NULL;
@@ -733,18 +731,6 @@ int mount(const char *device, const char *fsname, const char *_path)
 		goto out;
 	}
 
-	list_for_each_entry(f, &fs_driver_list, list) {
-		if (!strcmp(f->drv.name, fsname)) {
-			fs_drv = f;
-			break;
-		}
-	}
-
-	if (!fs_drv) {
-		errno = -EINVAL;
-		goto out;
-	}
-
 	if (mtab_root) {
 		if (path_check_prereq(path, S_IFDIR))
 			goto out;
@@ -757,14 +743,7 @@ int mount(const char *device, const char *fsname, const char *_path)
 	}
 
 	fsdev = xzalloc(sizeof(struct fs_device_d));
-	if (!(fs_drv->flags & FS_DRIVER_NO_DEV)) {
-		fsdev->backingstore = strdup(device);
-		if (!device) {
-			printf("need a device for driver %s\n", fsname);
-			errno = -ENODEV;
-			goto out1;
-		}
-	}
+	fsdev->backingstore = xstrdup(device);
 	safe_strncpy(fsdev->dev.name, fsname, MAX_DRIVER_NAME);
 	fsdev->dev.type_data = fsdev;
 	fsdev->dev.id = get_free_deviceid(fsdev->dev.name);
diff --git a/include/fs.h b/include/fs.h
index 8daa1bc..fcaef32 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -72,8 +72,6 @@ struct fs_driver_d {
 	struct driver_d drv;
 
 	unsigned long flags;
-
-	struct list_head list;
 };
 
 struct mtab_entry {
-- 
1.7.9


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 10/12] fs: put fs devices on its own bus
  2012-02-15  8:22 cleanup filesystem core Sascha Hauer
                   ` (8 preceding siblings ...)
  2012-02-15  8:22 ` [PATCH 09/12] fs: remove fs devices list Sascha Hauer
@ 2012-02-15  8:22 ` Sascha Hauer
  2012-02-15  8:22 ` [PATCH 11/12] fs: allow to mount on subdirectories Sascha Hauer
  2012-02-15  8:22 ` [PATCH 12/12] devices: unregister children when unregistering a device Sascha Hauer
  11 siblings, 0 replies; 13+ messages in thread
From: Sascha Hauer @ 2012-02-15  8:22 UTC (permalink / raw)
  To: barebox

By putting the fs devices/drivers on a bus on its own we can hook
into the bus remove function to cleanup the fs device. This way
we can unmount a device by simply unregistering the device which
is useful for for example USB mass storage devices. These can now
unregister the assoiated filesystems by unregistering their child
devices.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 fs/fs.c      |  122 ++++++++++++++++++++++++++++++++++++----------------------
 include/fs.h |    1 +
 2 files changed, 77 insertions(+), 46 deletions(-)

diff --git a/fs/fs.c b/fs/fs.c
index 3e65c64..637a01f 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -697,11 +697,67 @@ int close(int fd)
 }
 EXPORT_SYMBOL(close);
 
-static LIST_HEAD(fs_driver_list);
+static int fs_match(struct device_d *dev, struct driver_d *drv)
+{
+	return strcmp(dev->name, drv->name) ? -1 : 0;
+}
+
+static int fs_probe(struct device_d *dev)
+{
+	struct fs_device_d *fsdev = container_of(dev, struct fs_device_d, dev);
+	struct mtab_entry *entry = &fsdev->mtab;
+	int ret;
+
+	ret = dev->driver->probe(dev);
+	if (ret)
+		return ret;
+
+	if (fsdev->cdev) {
+		dev_add_child(fsdev->cdev->dev, &fsdev->dev);
+		entry->parent_device = fsdev->cdev->dev;
+	}
+
+	entry->dev = &fsdev->dev;
+
+	list_add_tail(&entry->list, &mtab_list);
+
+	if (!mtab_root)
+		mtab_root = entry;
+
+	return 0;
+}
+
+static void fs_remove(struct device_d *dev)
+{
+	struct fs_device_d *fsdev = container_of(dev, struct fs_device_d, dev);
+	struct mtab_entry *entry = &fsdev->mtab;
+
+	if (fsdev->dev.driver) {
+		dev->driver->remove(dev);
+		list_del(&entry->list);
+	}
+
+	free(entry->path);
+
+	if (entry == mtab_root)
+		mtab_root = NULL;
+
+	free(fsdev->backingstore);
+	free(fsdev);
+}
+
+struct bus_type fs_bus = {
+	.name = "fs",
+	.match = fs_match,
+	.probe = fs_probe,
+	.remove = fs_remove,
+};
 
 int register_fs_driver(struct fs_driver_d *fsdrv)
 {
+	fsdrv->drv.bus = &fs_bus;
 	register_driver(&fsdrv->drv);
+
 	return 0;
 }
 EXPORT_SYMBOL(register_fs_driver);
@@ -714,10 +770,7 @@ EXPORT_SYMBOL(register_fs_driver);
  */
 int mount(const char *device, const char *fsname, const char *_path)
 {
-	struct mtab_entry *entry;
 	struct fs_device_d *fsdev;
-	struct device_d *parent_device = NULL;
-	struct cdev *cdev = NULL;
 	int ret;
 	char *path = normalise_path(_path);
 
@@ -728,17 +781,17 @@ int mount(const char *device, const char *fsname, const char *_path)
 	if (strchr(path + 1, '/')) {
 		printf("mounting allowed on first directory level only\n");
 		errno = -EBUSY;
-		goto out;
+		goto err_free_path;
 	}
 
 	if (mtab_root) {
 		if (path_check_prereq(path, S_IFDIR))
-			goto out;
+			goto err_free_path;
 	} else {
 		/* no mtab, so we only allow to mount on '/' */
 		if (*path != '/' || *(path + 1)) {
 			errno = -ENOTDIR;
-			goto out;
+			goto err_free_path;
 		}
 	}
 
@@ -747,51 +800,37 @@ int mount(const char *device, const char *fsname, const char *_path)
 	safe_strncpy(fsdev->dev.name, fsname, MAX_DRIVER_NAME);
 	fsdev->dev.type_data = fsdev;
 	fsdev->dev.id = get_free_deviceid(fsdev->dev.name);
+	fsdev->mtab.path = xstrdup(path);
+	fsdev->dev.bus = &fs_bus;
+
+	if (!strncmp(device, "/dev/", 5))
+		fsdev->cdev = cdev_by_name(device + 5);
 
 	if ((ret = register_device(&fsdev->dev))) {
 		errno = ret;
-		goto out1;
+		goto err_register;
 	}
 
 	if (!fsdev->dev.driver) {
-		/* driver didn't accept the device. Bail out */
+		/*
+		 * Driver didn't accept the device or no driver for this
+		 * device. Bail out
+		 */
 		errno = -EINVAL;
-		goto out2;
+		goto err_no_driver;
 	}
 
-	if (!strncmp(device, "/dev/", 5)) {
-		cdev = cdev_by_name(device + 5);
-		if(cdev)
-			parent_device = cdev->dev;
-	}
-
-	if (parent_device)
-		dev_add_child(parent_device, &fsdev->dev);
-
-	/* add mtab entry */
-	entry = &fsdev->mtab;
-	entry->path = xstrdup(path);
-	entry->dev = &fsdev->dev;
-	entry->parent_device = parent_device;
-
-	list_add_tail(&entry->list, &mtab_list);
-
-	if (!mtab_root)
-		mtab_root = entry;
-
 	errno = 0;
 
-	free(path);
 	return 0;
 
-out2:
+err_no_driver:
 	unregister_device(&fsdev->dev);
-out1:
-	if (fsdev->backingstore)
-		free(fsdev->backingstore);
-	free(fsdev);
-out:
+err_register:
+	fs_remove(&fsdev->dev);
+err_free_path:
 	free(path);
+
 	return errno;
 }
 EXPORT_SYMBOL(mount);
@@ -800,7 +839,6 @@ int umount(const char *pathname)
 {
 	struct mtab_entry *entry = NULL, *e;
 	char *p = normalise_path(pathname);
-	struct fs_device_d *fsdev;
 
 	for_each_mtab_entry(e) {
 		if (!strcmp(p, e->path)) {
@@ -821,15 +859,7 @@ int umount(const char *pathname)
 		return errno;
 	}
 
-	free(entry->path);
-	list_del(&entry->list);
-	if (entry == mtab_root)
-		mtab_root = NULL;
-
 	unregister_device(entry->dev);
-	fsdev = entry->dev->type_data;
-	free(fsdev->backingstore);
-	free(fsdev);
 
 	return 0;
 }
diff --git a/include/fs.h b/include/fs.h
index fcaef32..656160d 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -90,6 +90,7 @@ struct fs_device_d {
 
 	struct fs_driver_d *driver;
 
+	struct cdev *cdev;
 	struct mtab_entry mtab;
 };
 
-- 
1.7.9


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 11/12] fs: allow to mount on subdirectories
  2012-02-15  8:22 cleanup filesystem core Sascha Hauer
                   ` (9 preceding siblings ...)
  2012-02-15  8:22 ` [PATCH 10/12] fs: put fs devices on its own bus Sascha Hauer
@ 2012-02-15  8:22 ` Sascha Hauer
  2012-02-15  8:22 ` [PATCH 12/12] devices: unregister children when unregistering a device Sascha Hauer
  11 siblings, 0 replies; 13+ messages in thread
From: Sascha Hauer @ 2012-02-15  8:22 UTC (permalink / raw)
  To: barebox

Since get_mtab_entry_by_path() is a bit more flexible now
we no longer have to force the user to mount on the root
directory only. Instead, we can allow to mount on subdirectories
aswell. Nested mounts are still not possible though.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 fs/fs.c |   13 +++++++------
 1 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/fs/fs.c b/fs/fs.c
index 637a01f..3923ec6 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -778,13 +778,14 @@ int mount(const char *device, const char *fsname, const char *_path)
 
 	debug("mount: %s on %s type %s\n", device, path, fsname);
 
-	if (strchr(path + 1, '/')) {
-		printf("mounting allowed on first directory level only\n");
-		errno = -EBUSY;
-		goto err_free_path;
-	}
-
 	if (mtab_root) {
+		struct mtab_entry *entry;
+		entry = get_mtab_entry_by_path(path);
+		if (entry != mtab_root) {
+			printf("sorry, no nested mounts\n");
+			errno = -EBUSY;
+			goto err_free_path;
+		}
 		if (path_check_prereq(path, S_IFDIR))
 			goto err_free_path;
 	} else {
-- 
1.7.9


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 12/12] devices: unregister children when unregistering a device
  2012-02-15  8:22 cleanup filesystem core Sascha Hauer
                   ` (10 preceding siblings ...)
  2012-02-15  8:22 ` [PATCH 11/12] fs: allow to mount on subdirectories Sascha Hauer
@ 2012-02-15  8:22 ` Sascha Hauer
  11 siblings, 0 replies; 13+ messages in thread
From: Sascha Hauer @ 2012-02-15  8:22 UTC (permalink / raw)
  To: barebox

We currently do not allow to unregister a device when it
has children. However, the return value is seldomly checked.
Also this breaks for hot pluggable devices like USB which we have
to unregister when they disappear. The best way to fix this is to
unregister our children and also the partitions on the unregistered
device.
We unregister the device first and then afterwards the children.
We do this because for example network devices have a miidev as
child which they unregister themselves. So we only have to
unregister the children which are not cleaned up by the drivers,
namely fs devices.
Also, unregister all partitions on a disappearing device.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/base/driver.c |   20 +++++++++++++++-----
 1 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 0132e7d..3777f82 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -137,16 +137,26 @@ EXPORT_SYMBOL(register_device);
 
 int unregister_device(struct device_d *old_dev)
 {
-	debug("unregister_device: %s\n", dev_name(old_dev));
+	struct cdev *cdev, *ct;
+	struct device_d *child, *dt;
 
-	if (!list_empty(&old_dev->children)) {
-		errno = -EBUSY;
-		return errno;
-	}
+	dev_dbg(old_dev, "unregister\n");
 
 	if (old_dev->driver)
 		old_dev->bus->remove(old_dev);
 
+	list_for_each_entry_safe(child, dt, &old_dev->children, sibling) {
+		dev_dbg(old_dev, "unregister child %s\n", dev_name(child));
+		unregister_device(child);
+	}
+
+	list_for_each_entry_safe(cdev, ct, &old_dev->cdevs, devices_list) {
+		if (cdev->flags & DEVFS_IS_PARTITION) {
+			dev_dbg(old_dev, "unregister part %s\n", cdev->name);
+			devfs_del_partition(cdev->name);
+		}
+	}
+
 	list_del(&old_dev->list);
 	list_del(&old_dev->active);
 
-- 
1.7.9


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2012-02-15  8:23 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-15  8:22 cleanup filesystem core Sascha Hauer
2012-02-15  8:22 ` [PATCH 01/12] add list_is_singular Sascha Hauer
2012-02-15  8:22 ` [PATCH 02/12] dos partitions: Do not register as fixed partitions Sascha Hauer
2012-02-15  8:22 ` [PATCH 03/12] fs: Store mtab entries in list Sascha Hauer
2012-02-15  8:22 ` [PATCH 04/12] fs: make locally used function get_mtab_entry_by_path static Sascha Hauer
2012-02-15  8:22 ` [PATCH 05/12] fs: Store mtab path in allocated string Sascha Hauer
2012-02-15  8:22 ` [PATCH 06/12] fs: remove unused function fsdev_get_mountpoint Sascha Hauer
2012-02-15  8:22 ` [PATCH 07/12] fs: simplify get_mtab_entry_by_path Sascha Hauer
2012-02-15  8:22 ` [PATCH 08/12] fs: remove only once used variable Sascha Hauer
2012-02-15  8:22 ` [PATCH 09/12] fs: remove fs devices list Sascha Hauer
2012-02-15  8:22 ` [PATCH 10/12] fs: put fs devices on its own bus Sascha Hauer
2012-02-15  8:22 ` [PATCH 11/12] fs: allow to mount on subdirectories Sascha Hauer
2012-02-15  8:22 ` [PATCH 12/12] devices: unregister children when unregistering a device Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox