To save more space (equivalent to the size of one erase sector of MTD device) and to achieve faster read and write speeds, a method for direct writing was introduced at the FTL layer. This can be accomplished simply by using the following oflags during the open operation: 1. O_DIRECT. when this flag is passed in, ftl internally uses the direct write strategy and no read cache is used in ftl; otherwise, each write will be executed with the minimum granularity of flash erase sector size which means a "sector read back - erase sector - write sector" operation is performed by using a read cache buffer in heap. 2. O_SYNC. When this flag is passed in, we assume that the flash has been erased in advance and no erasure operation will be performed internally within ftl. O_SYNC will take effect only when both O_DIRECT and O_SYNC are passed in simultaneously. 3. For uniformity, we remapped the mount flag in mount.h and unified it with the open flag in fcntl.h. The repetitive parts of their definitions were reused, and the remaining part of the mount flag redefine to the unused bit of open flags. Signed-off-by: jingfei <jingfei@xiaomi.com>
122 lines
3.4 KiB
C
122 lines
3.4 KiB
C
/****************************************************************************
|
|
* drivers/bch/bchlib_setup.c
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* 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 <nuttx/config.h>
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/mount.h>
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <stdlib.h>
|
|
#include <errno.h>
|
|
#include <assert.h>
|
|
#include <debug.h>
|
|
|
|
#include <nuttx/kmalloc.h>
|
|
#include <nuttx/fs/fs.h>
|
|
#include <nuttx/drivers/drivers.h>
|
|
|
|
#include "bch.h"
|
|
|
|
/****************************************************************************
|
|
* Public Functions
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: bchlib_setup
|
|
*
|
|
* Description:
|
|
* Setup so that the block driver referenced by 'blkdev' can be accessed
|
|
* similar to a character device.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int bchlib_setup(FAR const char *blkdev, int oflags, FAR void **handle)
|
|
{
|
|
FAR struct bchlib_s *bch;
|
|
struct geometry geo;
|
|
bool readonly = (oflags & O_WROK) == 0;
|
|
int ret;
|
|
|
|
DEBUGASSERT(blkdev);
|
|
|
|
/* Allocate the BCH state structure */
|
|
|
|
bch = kmm_zalloc(sizeof(struct bchlib_s));
|
|
if (!bch)
|
|
{
|
|
ferr("ERROR: Failed to allocate BCH structure\n");
|
|
return -ENOMEM;
|
|
}
|
|
|
|
/* Open the block driver */
|
|
|
|
ret = open_blockdriver(blkdev, oflags, &bch->inode);
|
|
if (ret < 0)
|
|
{
|
|
ferr("ERROR: Failed to open driver %s: %d\n", blkdev, -ret);
|
|
goto errout_with_bch;
|
|
}
|
|
|
|
DEBUGASSERT(bch->inode && bch->inode->u.i_bops &&
|
|
bch->inode->u.i_bops->geometry);
|
|
|
|
ret = bch->inode->u.i_bops->geometry(bch->inode, &geo);
|
|
if (ret < 0)
|
|
{
|
|
ferr("ERROR: geometry failed: %d\n", -ret);
|
|
goto errout_with_bch;
|
|
}
|
|
|
|
if (!geo.geo_available)
|
|
{
|
|
ferr("ERROR: geometry failed: %d\n", -ret);
|
|
ret = -ENODEV;
|
|
goto errout_with_bch;
|
|
}
|
|
|
|
if (!readonly && (!bch->inode->u.i_bops->write || !geo.geo_writeenabled))
|
|
{
|
|
ferr("ERROR: write access not supported\n");
|
|
ret = -EACCES;
|
|
goto errout_with_bch;
|
|
}
|
|
|
|
/* Save the geometry info and complete initialization of the structure */
|
|
|
|
nxmutex_init(&bch->lock);
|
|
bch->nsectors = geo.geo_nsectors;
|
|
bch->sectsize = geo.geo_sectorsize;
|
|
bch->sector = (size_t)-1;
|
|
bch->readonly = readonly;
|
|
*handle = bch;
|
|
return OK;
|
|
|
|
errout_with_bch:
|
|
kmm_free(bch);
|
|
return ret;
|
|
}
|