diff options
author | Gurjant Kalsi <me@gurjantkalsi.com> | 2015-11-10 11:28:02 -0800 |
---|---|---|
committer | Gurjant Kalsi <me@gurjantkalsi.com> | 2015-11-10 11:28:02 -0800 |
commit | ccbde6a385823481bdd049b9de0e674ae97f65c4 (patch) | |
tree | c90997e7a84636e6c8bad6ba009dbac7fd52f5e5 /lib | |
parent | f619de0efd4981fab6e0da9d8106d57c664452df (diff) | |
download | common-ccbde6a385823481bdd049b9de0e674ae97f65c4.tar.gz |
[spifs][fs] Create and enable an FS format hook.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/fs/debug.c | 19 | ||||
-rw-r--r-- | lib/fs/fs.c | 20 | ||||
-rw-r--r-- | lib/fs/include/lib/fs.h | 4 | ||||
-rw-r--r-- | lib/fs/include/lib/fs/spifs.h | 33 | ||||
-rw-r--r-- | lib/fs/spifs/spifs.c | 38 |
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, |