/**************************************************************************** * apps/fsutils/mksmartfs/mksmartfs.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. The * ASF licenses this file to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. * ****************************************************************************/ /**************************************************************************** * Included Files ****************************************************************************/ #include #include #include #include #include #if !defined(CONFIG_DISABLE_MOUNTPOINT) # ifdef CONFIG_FS_SMARTFS # include "fsutils/mksmartfs.h" # include # include # endif #endif #include /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ /**************************************************************************** * Private Types ****************************************************************************/ /**************************************************************************** * Private Data ****************************************************************************/ /**************************************************************************** * Private Functions ****************************************************************************/ /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** * Name: issmartfs * * Description: * Check a SMART (Sector Mapped Allocation for Really Tiny) Flash file * system image on the specified block device (must be a SMART device). * * Inputs: * pathname - the full path to a registered block driver * * Return: * Zero (OK) on success; -1 (ERROR) on failure with errno set: * * EINVAL - NULL block driver string * ENOENT - 'pathname' does not refer to anything in the filesystem. * ENOTBLK - 'pathname' does not refer to a block driver * EFTYPE - the block driver hasn't been formatted yet * ****************************************************************************/ int issmartfs(FAR const char *pathname) { struct smart_format_s fmt; int fd; int ret; /* Find the inode of the block driver identified by 'source' */ fd = open(pathname, O_RDONLY); if (fd < 0) { return ERROR; } /* Get the format information so we know the block have been formatted */ ret = ioctl(fd, BIOC_GETFORMAT, (unsigned long)&fmt); if (ret < 0) { goto out; } if (!(fmt.flags & SMART_FMT_ISFORMATTED)) { errno = EFTYPE; ret = ERROR; goto out; } out: /* Close the driver */ close(fd); return ret; } /**************************************************************************** * Name: mksmartfs * * Description: * Make a SMART Flash file system image on the specified block device * * Inputs: * pathname - the full path to a registered block driver * sectorsize - the size of logical sectors on the device from 256-16384. * Setting this to zero will cause the device to be formatted * using the default CONFIG_MTD_SMART_SECTOR_SIZE value. * nrootdirs - Number of root directory entries to create. * * Return: * Zero (OK) on success; -1 (ERROR) on failure with errno set: * * EINVAL - NULL block driver string, bad number of FATS in 'fmt', bad FAT * size in 'fmt', bad cluster size in 'fmt' * ENOENT - 'pathname' does not refer to anything in the filesystem. * ENOTBLK - 'pathname' does not refer to a block driver * EACCES - block driver does not support wrie or geometry methods * * Assumptions: * - The caller must assure that the block driver is not mounted and not in * use when this function is called. The result of formatting a mounted * device is indeterminate (but likely not good). * ****************************************************************************/ #ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS int mksmartfs(FAR const char *pathname, uint16_t sectorsize, uint8_t nrootdirs) #else int mksmartfs(FAR const char *pathname, uint16_t sectorsize) #endif { struct smart_format_s fmt; struct smart_read_write_s request; uint8_t type; int fd; int x; int ret; /* Find the inode of the block driver identified by 'source' */ fd = open(pathname, O_RDWR); if (fd < 0) { ret = -ENOENT; goto errout; } /* Perform a low-level SMART format */ #ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS ret = ioctl(fd, BIOC_LLFORMAT, (sectorsize << 16) | nrootdirs); #else ret = ioctl(fd, BIOC_LLFORMAT, sectorsize << 16); #endif if (ret != OK) { goto errout_with_driver; } /* Get the format information so we know how big the sectors are */ ret = ioctl(fd, BIOC_GETFORMAT, (unsigned long) &fmt); /* Now Write the filesystem to media. Loop for each root dir entry and * allocate the reserved Root Dir Entry, then write a blank root dir for * it. */ type = SMARTFS_SECTOR_TYPE_DIR; request.offset = 0; request.count = 1; request.buffer = &type; x = 0; #ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS for (; x < nrootdirs; x++) #endif { ret = ioctl(fd, BIOC_ALLOCSECT, SMARTFS_ROOT_DIR_SECTOR + x); if (ret != SMARTFS_ROOT_DIR_SECTOR + x) { ret = -EIO; goto errout_with_driver; } /* Mark this block as a directory entry */ request.logsector = SMARTFS_ROOT_DIR_SECTOR + x; /* Issue a write to the sector, single byte */ ret = ioctl(fd, BIOC_WRITESECT, (unsigned long) &request); if (ret != 0) { ret = -EIO; goto errout_with_driver; } } errout_with_driver: /* Close the driver */ close(fd); errout: /* Release all allocated memory */ /* Return any reported errors */ if (ret < 0) { errno = -ret; return ERROR; } return OK; }