fs: Add fs_mkfs operation to fs api

Adds fs_mkfs function to fs api. It will allow to perform mkfs operation
in file systems added to Zephyr.

Signed-off-by: Franciszek Zdobylak <fzdobylak@internships.antmicro.com>
diff --git a/include/zephyr/fs/fs.h b/include/zephyr/fs/fs.h
index 6dac93a..4aa0159 100644
--- a/include/zephyr/fs/fs.h
+++ b/include/zephyr/fs/fs.h
@@ -605,6 +605,23 @@
  */
 int fs_statvfs(const char *path, struct fs_statvfs *stat);
 
+#if defined(CONFIG_FILE_SYSTEM_MKFS)
+
+/**
+ * @brief Create fresh file system
+ *
+ * @param fs_type Type of file system to create.
+ * @param dev_id Id of storage device.
+ * @param cfg Backend dependent init object. If NULL then default configuration is used.
+ * @param flags Additional flags for file system implementation.
+ *
+ * @retval 0 on success;
+ * @retval <0 negative errno code on error.
+ */
+int fs_mkfs(int fs_type, uintptr_t dev_id, void *cfg, int flags);
+
+#endif /* CONFIG_FILE_SYSTEM_MKFS */
+
 /**
  * @brief Register a file system
  *
diff --git a/include/zephyr/fs/fs_sys.h b/include/zephyr/fs/fs_sys.h
index d19e195..806162b 100644
--- a/include/zephyr/fs/fs_sys.h
+++ b/include/zephyr/fs/fs_sys.h
@@ -38,6 +38,8 @@
  * @param stat Checks the status of a file or directory specified by the path
  * @param statvfs Returns the total and available space on the file system
  *        volume
+ * @param mkfs Formats a device to specified file system type. Note that this
+ *        operation destroys existing data on a target device.
  */
 struct fs_file_system_t {
 	/* File operations */
@@ -66,6 +68,9 @@
 					struct fs_dirent *entry);
 	int (*statvfs)(struct fs_mount_t *mountp, const char *path,
 					struct fs_statvfs *stat);
+#if defined(CONFIG_FILE_SYSTEM_MKFS)
+	int (*mkfs)(uintptr_t dev_id, void *cfg, int flags);
+#endif
 };
 
 /**
diff --git a/subsys/fs/Kconfig b/subsys/fs/Kconfig
index daf7b9c..43e6d02 100644
--- a/subsys/fs/Kconfig
+++ b/subsys/fs/Kconfig
@@ -51,6 +51,12 @@
 	  This shell provides basic browsing of the contents of the
 	  file system.
 
+config FILE_SYSTEM_MKFS
+	bool "Allow to format file system"
+	help
+		Enables function fs_mkfs that can be used to format a storage
+		device.
+
 config FUSE_FS_ACCESS
 	bool "FUSE based access to file system partitions"
 	depends on ARCH_POSIX
diff --git a/subsys/fs/fs.c b/subsys/fs/fs.c
index edd3922..f8460dc 100644
--- a/subsys/fs/fs.c
+++ b/subsys/fs/fs.c
@@ -721,6 +721,42 @@
 	return rc;
 }
 
+#if defined(CONFIG_FILE_SYSTEM_MKFS)
+
+int fs_mkfs(int fs_type, uintptr_t dev_id, void *cfg, int flags)
+{
+	int rc = -EINVAL;
+	const struct fs_file_system_t *fs;
+
+	k_mutex_lock(&mutex, K_FOREVER);
+
+	/* Get file system information */
+	fs = fs_type_get(fs_type);
+	if (fs == NULL) {
+		LOG_ERR("fs type %d not registered!!",
+				fs_type);
+		rc = -ENOENT;
+		goto mount_err;
+	}
+
+	CHECKIF(fs->mkfs == NULL) {
+		LOG_ERR("fs type %d does not support mkfs", fs_type);
+		rc = -ENOTSUP;
+		goto mount_err;
+	}
+
+	rc = fs->mkfs(dev_id, cfg, flags);
+	if (rc < 0) {
+		LOG_ERR("mkfs error (%d)", rc);
+		goto mount_err;
+	}
+
+mount_err:
+	k_mutex_unlock(&mutex);
+	return rc;
+}
+
+#endif /* CONFIG_FILE_SYSTEM_MKFS */
 
 int fs_unmount(struct fs_mount_t *mp)
 {