You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by pk...@apache.org on 2022/04/18 16:21:29 UTC
[incubator-nuttx] 01/02: libc/blockstream: add block out stream backend
This is an automated email from the ASF dual-hosted git repository.
pkarashchenko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 889a3bf7fc060376151f46595d0ac81d172f8009
Author: chao.an <an...@xiaomi.com>
AuthorDate: Mon Jan 10 22:56:39 2022 +0800
libc/blockstream: add block out stream backend
Signed-off-by: chao.an <an...@xiaomi.com>
---
include/nuttx/streams.h | 53 +++++++++
libs/libc/stream/Make.defs | 4 +
libs/libc/stream/lib_blkoutstream.c | 225 ++++++++++++++++++++++++++++++++++++
3 files changed, 282 insertions(+)
diff --git a/include/nuttx/streams.h b/include/nuttx/streams.h
index 4d53114211..98348019f3 100644
--- a/include/nuttx/streams.h
+++ b/include/nuttx/streams.h
@@ -29,6 +29,9 @@
#include <lzf.h>
#include <stdio.h>
+#ifndef CONFIG_DISABLE_MOUNTPOINT
+#include <nuttx/fs/fs.h>
+#endif
/****************************************************************************
* Pre-processor Definitions
@@ -197,6 +200,16 @@ struct lib_lzfoutstream_s
};
#endif
+#ifndef CONFIG_DISABLE_MOUNTPOINT
+struct lib_blkoutstream_s
+{
+ struct lib_outstream_s public;
+ FAR struct inode *inode;
+ struct geometry geo;
+ FAR unsigned char *cache;
+};
+#endif
+
/****************************************************************************
* Public Data
****************************************************************************/
@@ -374,6 +387,46 @@ void lib_lzfoutstream(FAR struct lib_lzfoutstream_s *stream,
FAR struct lib_outstream_s *backend);
#endif
+/****************************************************************************
+ * Name: lib_blkoutstream_open
+ *
+ * Description:
+ * open block driver stream backend
+ *
+ * Input Parameters:
+ * stream - User allocated, uninitialized instance of struct
+ * lib_blkoutstream_s to be initialized.
+ * name - The full path to the block driver to be opened.
+ *
+ * Returned Value:
+ * Returns zero on success or a negated errno on failure
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_DISABLE_MOUNTPOINT
+int lib_blkoutstream_open(FAR struct lib_blkoutstream_s *stream,
+ FAR const char *name);
+#endif
+
+/****************************************************************************
+ * Name: lib_blkoutstream_close
+ *
+ * Description:
+ * close block driver stream backend
+ *
+ * Input Parameters:
+ * stream - User allocated, uninitialized instance of struct
+ * lib_blkoutstream_s to be initialized.
+ *
+ * Returned Value:
+ * None (User allocated instance initialized).
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_DISABLE_MOUNTPOINT
+void lib_blkoutstream_close(FAR struct lib_blkoutstream_s *stream);
+#endif
+
/****************************************************************************
* Name: lib_noflush
*
diff --git a/libs/libc/stream/Make.defs b/libs/libc/stream/Make.defs
index 7af465dc09..622b3f1f67 100644
--- a/libs/libc/stream/Make.defs
+++ b/libs/libc/stream/Make.defs
@@ -38,6 +38,10 @@ ifeq ($(CONFIG_LIBC_LZF),y)
CSRCS += lib_lzfcompress.c
endif
+ifeq ($(CONFIG_DISABLE_MOUNTPOINT),)
+CSRCS += lib_blkoutstream.c
+endif
+
# Add the stdio directory to the build
DEPPATH += --dep-path stream
diff --git a/libs/libc/stream/lib_blkoutstream.c b/libs/libc/stream/lib_blkoutstream.c
new file mode 100644
index 0000000000..929cb1997e
--- /dev/null
+++ b/libs/libc/stream/lib_blkoutstream.c
@@ -0,0 +1,225 @@
+/****************************************************************************
+ * libs/libc/stream/lib_blkoutstream.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 <nuttx/config.h>
+
+#include <unistd.h>
+#include <nuttx/streams.h>
+
+#include "libc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifndef CONFIG_DISABLE_MOUNTPOINT
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: blkoutstream_flush
+ ****************************************************************************/
+
+static int blkoutstream_flush(FAR struct lib_outstream_s *this)
+{
+ FAR struct lib_blkoutstream_s *stream =
+ (FAR struct lib_blkoutstream_s *)this;
+ size_t sectorsize = stream->geo.geo_sectorsize;
+ int ret = OK;
+
+ if (this->nput % sectorsize > 0)
+ {
+ ret = stream->inode->u.i_bops->write(stream->inode, stream->cache,
+ this->nput / sectorsize, 1);
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: blkoutstream_puts
+ ****************************************************************************/
+
+static int blkoutstream_puts(FAR struct lib_outstream_s *this,
+ FAR const void *buf, int len)
+{
+ FAR struct lib_blkoutstream_s *stream =
+ (FAR struct lib_blkoutstream_s *)this;
+ size_t sectorsize = stream->geo.geo_sectorsize;
+ FAR struct inode *inode = stream->inode;
+ FAR const unsigned char *ptr = buf;
+ size_t remain = len;
+ int ret;
+
+ while (remain > 0)
+ {
+ size_t sblock = this->nput / sectorsize;
+ size_t offset = this->nput % sectorsize;
+
+ if (offset > 0)
+ {
+ size_t copyin = offset + remain > sectorsize ?
+ sectorsize - offset : remain;
+
+ memcpy(stream->cache + offset, ptr, copyin);
+
+ ptr += copyin;
+ offset += copyin;
+ this->nput += copyin;
+ remain -= copyin;
+
+ if (offset == stream->geo.geo_sectorsize)
+ {
+ ret = inode->u.i_bops->write(inode, stream->cache, sblock, 1);
+ if (ret < 0)
+ {
+ return ret;
+ }
+ }
+ }
+ else if (remain < stream->geo.geo_sectorsize)
+ {
+ memcpy(stream->cache, ptr, remain);
+ this->nput += remain;
+ remain = 0;
+ }
+ else if (remain >= stream->geo.geo_sectorsize)
+ {
+ size_t copyin = (remain / stream->geo.geo_sectorsize) *
+ stream->geo.geo_sectorsize;
+
+ ret = inode->u.i_bops->write(inode, ptr, sblock,
+ remain / stream->geo.geo_sectorsize);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ ptr += copyin;
+ this->nput += copyin;
+ remain -= copyin;
+ }
+ }
+
+ return len;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lib_blkoutstream_close
+ *
+ * Description:
+ * close block driver stream backend
+ *
+ * Input Parameters:
+ * stream - User allocated, uninitialized instance of struct
+ * lib_blkoutstream_s to be initialized.
+ *
+ * Returned Value:
+ * None (User allocated instance initialized).
+ *
+ ****************************************************************************/
+
+void lib_blkoutstream_close(FAR struct lib_blkoutstream_s *stream)
+{
+ if (stream)
+ {
+ if (stream->inode)
+ {
+ close_blockdriver(stream->inode);
+ stream->inode = NULL;
+ }
+
+ if (stream->cache)
+ {
+ lib_free(stream->cache);
+ stream->cache = NULL;
+ }
+ }
+}
+
+/****************************************************************************
+ * Name: lib_blkoutstream_open
+ *
+ * Description:
+ * block driver stream backend
+ *
+ * Input Parameters:
+ * stream - User allocated, uninitialized instance of struct
+ * lib_blkoutstream_s to be initialized.
+ * name - The full path to the block driver to be opened.
+ *
+ * Returned Value:
+ * Returns zero on success or a negated errno on failure
+ *
+ ****************************************************************************/
+
+int lib_blkoutstream_open(FAR struct lib_blkoutstream_s *stream,
+ FAR const char *name)
+{
+ FAR struct inode *inode = NULL;
+ int ret;
+
+ if (stream == NULL || name == NULL)
+ {
+ return -EINVAL;
+ }
+
+ ret = open_blockdriver(name, 0, &inode);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ memset(stream, 0, sizeof(*stream));
+
+ if (inode->u.i_bops->geometry == NULL ||
+ inode->u.i_bops->write == NULL ||
+ inode->u.i_bops->geometry(inode, &stream->geo) < 0 ||
+ stream->geo.geo_sectorsize <= 0 ||
+ stream->geo.geo_nsectors <= 0)
+ {
+ close_blockdriver(inode);
+ return -EINVAL;
+ }
+
+ stream->cache = lib_malloc(stream->geo.geo_sectorsize);
+ if (stream->cache == NULL)
+ {
+ close_blockdriver(inode);
+ return -ENOMEM;
+ }
+
+ stream->inode = inode;
+ stream->public.puts = blkoutstream_puts;
+ stream->public.flush = blkoutstream_flush;
+
+ return OK;
+}
+#endif