1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148From 696dfa6ce29cb44d22e48bf66032e217383d8a2f Mon Sep 17 00:00:00 2001
From: zhouliang3 <zhouliang3@xiaomi.com>
Date: Tue, 24 Aug 2021 12:48:22 +0800
Subject: [PATCH] fs/littlefs: Add the function of obtaining absolute path
Signed-off-by: zhouliang3 <zhouliang3@xiaomi.com>
---
lfs.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
lfs.h | 8 ++++++
2 files changed, 87 insertions(+)
--- ./littlefs/littlefs/lfs.c
+++ ./littlefs/littlefs/lfs.c
@@ -542,6 +542,8 @@ static uint16_t lfs_fs_disk_version_minor(lfs_t *lfs) {
/// Internal operations predeclared here ///
+static lfs_ssize_t lfs_dir_rawpath(lfs_t *lfs,
+ lfs_mdir_t *dir, uint16_t id, char *path, lfs_size_t size);
#ifndef LFS_READONLY
static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir,
const struct lfs_mattr *attrs, int attrcount);
@@ -3790,6 +3792,53 @@ static lfs_soff_t lfs_file_rawsize(lfs_t *lfs, lfs_file_t *file) {
return file->ctz.size;
}
+static lfs_ssize_t lfs_dir_rawpath(lfs_t *lfs,
+ lfs_mdir_t *dir, uint16_t id, char *path, lfs_size_t size) {
+ struct lfs_info info;
+ char *next = path;
+ lfs_mdir_t parent;
+ lfs_ssize_t len;
+ lfs_stag_t tag;
+ int err;
+
+ if (lfs_pair_cmp(lfs->root, dir->pair) != 0) {
+ tag = lfs_fs_parent(lfs, dir->pair, &parent);
+ if (tag < 0) {
+ return tag;
+ }
+
+ len = lfs_dir_rawpath(lfs, &parent, lfs_tag_id(tag), next, size);
+ if (len < 0) {
+ return len;
+ }
+
+ next += len;
+ size -= len;
+ }
+
+ err = lfs_dir_getinfo(lfs, dir, id, &info);
+ if (err < 0) {
+ return err;
+ }
+
+ len = strlen(info.name);
+ if (len >= size) {
+ return LFS_ERR_INVAL;
+ }
+
+ memcpy(next, info.name, len + 1);
+ next += len;
+
+ if (info.type == LFS_TYPE_DIR) {
+ *next++ = '/';
+ if (++len >= size) {
+ return LFS_ERR_INVAL;
+ }
+ *next = '\0';
+ }
+
+ return next - path;
+}
/// General fs operations ///
static int lfs_rawstat(lfs_t *lfs, const char *path, struct lfs_info *info) {
@@ -6042,6 +6091,22 @@ lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file) {
return res;
}
+int lfs_file_path(lfs_t *lfs, lfs_file_t *file, char *path, lfs_size_t size) {
+ int err = LFS_LOCK(lfs->cfg);
+ if (err) {
+ return err;
+ }
+
+ LFS_TRACE("lfs_file_path(%p, %p)", (void*)lfs, (void*)file);
+ LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file));
+
+ err = lfs_dir_rawpath(lfs, &file->m, file->id, path, size);
+
+ LFS_TRACE("lfs_file_path -> %d", err);
+ LFS_UNLOCK(lfs->cfg);
+ return err < 0 ? err : 0;
+}
+
#ifndef LFS_READONLY
int lfs_mkdir(lfs_t *lfs, const char *path) {
int err = LFS_LOCK(lfs->cfg);
@@ -6173,6 +6238,20 @@ lfs_ssize_t lfs_fs_size(lfs_t *lfs) {
return res;
}
+int lfs_dir_path(lfs_t *lfs, lfs_dir_t *dir, char *path, lfs_size_t size) {
+ int err = LFS_LOCK(lfs->cfg);
+ if (err) {
+ return err;
+ }
+
+ LFS_TRACE("lfs_dir_path(%p, %p)", (void*)lfs, (void*)dir);
+ err = lfs_dir_rawpath(lfs, &dir->m, dir->id, path, size);
+
+ LFS_TRACE("lfs_dir_path -> %d", err);
+ LFS_UNLOCK(lfs->cfg);
+ return err < 0 ? err : 0;
+}
+
int lfs_fs_traverse(lfs_t *lfs, int (*cb)(void *, lfs_block_t), void *data) {
int err = LFS_LOCK(lfs->cfg);
if (err) {
--- ./littlefs/littlefs/lfs.h
+++ ./littlefs/littlefs/lfs.h
@@ -629,6 +629,10 @@ int lfs_file_rewind(lfs_t *lfs, lfs_file_t *file);
// Returns the size of the file, or a negative error code on failure.
lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file);
+// Get the absolute path of the open file.
+//
+// Returns a negative error code on failure.
+int lfs_file_path(lfs_t *lfs, lfs_file_t *file, char *path, lfs_size_t size);
/// Directory operations ///
@@ -679,6 +683,10 @@ lfs_soff_t lfs_dir_tell(lfs_t *lfs, lfs_dir_t *dir);
// Returns a negative error code on failure.
int lfs_dir_rewind(lfs_t *lfs, lfs_dir_t *dir);
+// Get the absolute path of the directory
+//
+// Returns a negative error code on failure.
+int lfs_dir_path(lfs_t *lfs, lfs_dir_t *dir, char *path, lfs_size_t size);
/// Filesystem-level filesystem operations
--
2.25.1