aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGurjant Kalsi <me@gurjantkalsi.com>2015-11-10 11:28:02 -0800
committerGurjant Kalsi <me@gurjantkalsi.com>2015-11-10 11:28:02 -0800
commitccbde6a385823481bdd049b9de0e674ae97f65c4 (patch)
treec90997e7a84636e6c8bad6ba009dbac7fd52f5e5 /lib
parentf619de0efd4981fab6e0da9d8106d57c664452df (diff)
downloadcommon-ccbde6a385823481bdd049b9de0e674ae97f65c4.tar.gz
[spifs][fs] Create and enable an FS format hook.
Diffstat (limited to 'lib')
-rw-r--r--lib/fs/debug.c19
-rw-r--r--lib/fs/fs.c20
-rw-r--r--lib/fs/include/lib/fs.h4
-rw-r--r--lib/fs/include/lib/fs/spifs.h33
-rw-r--r--lib/fs/spifs/spifs.c38
5 files changed, 103 insertions, 11 deletions
diff --git a/lib/fs/debug.c b/lib/fs/debug.c
index 85990fee..b89eee83 100644
--- a/lib/fs/debug.c
+++ b/lib/fs/debug.c
@@ -27,6 +27,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <platform.h>
+#include <err.h>
static void test_normalize(const char *in)
{
@@ -88,6 +89,7 @@ usage:
printf("%s mount <path> <type> [device]\n", argv[0].str);
printf("%s unmount <path>\n", argv[0].str);
printf("%s write <path> <string> [<offset>]\n", argv[0].str);
+ printf("%s format <type> [device]\n", argv[0].str);
return -1;
}
@@ -115,6 +117,23 @@ usage:
printf("error %d unmounting device\n", err);
return err;
}
+ } else if (!strcmp(argv[1].str, "format")) {
+ int err;
+
+ if (argc < 3)
+ goto notenoughargs;
+
+ err = fs_format_device(
+ argv[2].str,
+ (argc >= 4) ? argv[3].str : NULL,
+ NULL
+ );
+
+ if (err != NO_ERROR) {
+ printf("error %d formatting device\n", err);
+ return err;
+ }
+
} else if (!strcmp(argv[1].str, "write")) {
int err;
off_t off;
diff --git a/lib/fs/fs.c b/lib/fs/fs.c
index 0bd21e86..13458661 100644
--- a/lib/fs/fs.c
+++ b/lib/fs/fs.c
@@ -165,6 +165,26 @@ static status_t mount(const char *path, const char *device, const struct fs_api
}
+status_t fs_format_device(const char *fsname, const char *device, const void *args)
+{
+ const struct fs_impl *fs = find_fs(fsname);
+ if (!fs)
+ return ERR_NOT_FOUND;
+
+ if (fs->api->format == NULL) {
+ return ERR_NOT_SUPPORTED;
+ }
+
+ bdev_t *dev = NULL;
+ if (device && device[0] != '\0') {
+ dev = bio_open(device);
+ if (!dev)
+ return ERR_NOT_FOUND;
+ }
+
+ return fs->api->format(dev, args);
+}
+
status_t fs_mount(const char *path, const char *fsname, const char *device)
{
const struct fs_impl *fs = find_fs(fsname);
diff --git a/lib/fs/include/lib/fs.h b/lib/fs/include/lib/fs.h
index 52ba3afb..9ddb5048 100644
--- a/lib/fs/include/lib/fs.h
+++ b/lib/fs/include/lib/fs.h
@@ -41,6 +41,8 @@ struct dirent {
typedef struct filehandle filehandle;
typedef struct dirhandle dirhandle;
+
+status_t fs_format_device(const char *fsname, const char *device, const void *args);
status_t fs_mount(const char *path, const char *fs, const char *device) __NONNULL((1)) __NONNULL((2));
status_t fs_unmount(const char *path) __NONNULL();
@@ -75,6 +77,8 @@ typedef struct dircookie dircookie;
struct bdev;
struct fs_api {
+ status_t (*format)(struct bdev *, const void*);
+
status_t (*mount)(struct bdev *, fscookie **);
status_t (*unmount)(fscookie *);
status_t (*open)(fscookie *, const char *, filecookie **);
diff --git a/lib/fs/include/lib/fs/spifs.h b/lib/fs/include/lib/fs/spifs.h
new file mode 100644
index 00000000..8edb8ab3
--- /dev/null
+++ b/lib/fs/include/lib/fs/spifs.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2015 Gurjant Kalsi <me@gurjantkalsi.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef LIB_SPIFS_SPIFS_H_
+#define LIB_SPIFS_SPIFS_H_
+
+#include <lib/fs.h>
+
+typedef struct {
+ uint32_t toc_pages;
+} spifs_format_args_t;
+
+#endif // LIB_SPIFS_SPIFS_H_ \ No newline at end of file
diff --git a/lib/fs/spifs/spifs.c b/lib/fs/spifs/spifs.c
index 55f69cad..c2d4556c 100644
--- a/lib/fs/spifs/spifs.c
+++ b/lib/fs/spifs/spifs.c
@@ -28,6 +28,7 @@
#include <lib/cksum.h>
#include <lib/console.h>
#include <lib/fs.h>
+#include <lib/fs/spifs.h>
#include <list.h>
#include <lk/init.h>
#include <pow2.h>
@@ -439,7 +440,7 @@ static status_t get_device_page_info(bdev_t* dev, uint32_t* page_size, uint32_t
}
case 1: {
// Device has erase geometry.
- size_t erase_size = dev->geometry->erase_size;
+ size_t erase_size = valpow2(dev->geometry->erase_size);
size_t block_size = dev->block_size;
if (erase_size % block_size != 0) {
@@ -458,14 +459,25 @@ static status_t get_device_page_info(bdev_t* dev, uint32_t* page_size, uint32_t
}
}
-status_t spifs_format(bdev_t* dev, uint32_t num_pages)
+status_t spifs_format(bdev_t* dev, const void* args)
{
status_t err = NO_ERROR;
- LTRACEF("dev %p, num_pages %u\n", dev, num_pages);
+ LTRACEF("dev %p, args %p\n", dev, args);
DEBUG_ASSERT(dev);
+ spifs_format_args_t *spifs_args;
+ spifs_format_args_t default_args = {
+ .toc_pages = 1,
+ };
+
+ if (!args) {
+ spifs_args = &default_args;
+ } else {
+ spifs_args = (spifs_format_args_t*)args;
+ }
+
// Make sure that each of the three data structures are the same size.
STATIC_ASSERT(sizeof(toc_header_t) == SPIFS_ENTRY_LENGTH);
STATIC_ASSERT(sizeof(toc_file_t) == SPIFS_ENTRY_LENGTH);
@@ -478,19 +490,21 @@ status_t spifs_format(bdev_t* dev, uint32_t num_pages)
return err;
// Make sure entries can be exactly packed into pages.
- if (page_size % SPIFS_ENTRY_LENGTH != 0)
+ if (page_size % SPIFS_ENTRY_LENGTH != 0) {
return ERR_NOT_SUPPORTED;
+ }
// Make sure the device size is some multiple of the page size;
// we don't want a partial page at the end of the device.
- if (dev->total_size % page_size != 0)
+ if (dev->total_size % page_size != 0) {
return ERR_NOT_SUPPORTED;
+ }
uint32_t entires_per_page = page_size / SPIFS_ENTRY_LENGTH;
// Number of ToC entrries is the total number of entries less 2 for the
// header/footer
- uint32_t num_entries = num_pages * entires_per_page;
+ uint32_t num_entries = spifs_args->toc_pages * entires_per_page;
uint32_t num_toc_entries = num_entries - 2;
// Four entries will be consumed by metadata: Header, Front ToC entry,
@@ -516,16 +530,16 @@ status_t spifs_format(bdev_t* dev, uint32_t num_pages)
spifs_file_t f_toc;
f_toc.metadata.page_idx = 0;
- f_toc.metadata.length = num_pages * page_size;
- f_toc.metadata.capacity = num_pages * page_size;
+ f_toc.metadata.length = spifs_args->toc_pages * page_size;
+ f_toc.metadata.capacity = spifs_args->toc_pages * page_size;
f_toc.fs_handle = &spifs;
memset(f_toc.metadata.filename, 0, MAX_FILENAME_LENGTH);
strlcpy(f_toc.metadata.filename, FRONT_TOC_LABEL, MAX_FILENAME_LENGTH);
spifs_file_t b_toc;
- b_toc.metadata.page_idx = page_count - num_pages ;
- b_toc.metadata.length = num_pages * page_size;
- b_toc.metadata.capacity = num_pages * page_size;
+ b_toc.metadata.page_idx = page_count - spifs_args->toc_pages;
+ b_toc.metadata.length = spifs_args->toc_pages * page_size;
+ b_toc.metadata.capacity = spifs_args->toc_pages * page_size;
b_toc.fs_handle = &spifs;
memset(b_toc.metadata.filename, 0, MAX_FILENAME_LENGTH);
strlcpy(b_toc.metadata.filename, BACK_TOC_LABEL, MAX_FILENAME_LENGTH);
@@ -1042,6 +1056,8 @@ static status_t spifs_closedir(dircookie *dcookie)
}
static const struct fs_api spifs_api = {
+ .format = spifs_format,
+
.mount = spifs_mount,
.unmount = spifs_unmount,