]> Git Repo - J-u-boot.git/blame - fs/btrfs/btrfs.c
fs: btrfs: Crossport open_ctree_fs_info() from btrfs-progs
[J-u-boot.git] / fs / btrfs / btrfs.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
0c936ee3
MB
2/*
3 * BTRFS filesystem implementation for U-Boot
4 *
5 * 2017 Marek Behun, CZ.NIC, [email protected]
0c936ee3
MB
6 */
7
0c936ee3
MB
8#include <config.h>
9#include <malloc.h>
ba06b3c5 10#include <uuid.h>
0c936ee3 11#include <linux/time.h>
565a4147
QW
12#include "btrfs.h"
13#include "crypto/hash.h"
4aebb994 14#include "disk-io.h"
0c936ee3
MB
15
16struct btrfs_info btrfs_info;
f06bfcf5 17struct btrfs_fs_info *current_fs_info;
0c936ee3 18
207011b8 19static int readdir_callback(const struct __btrfs_root *root,
0c936ee3
MB
20 struct btrfs_dir_item *item)
21{
22 static const char typestr[BTRFS_FT_MAX][4] = {
23 [BTRFS_FT_UNKNOWN] = " ? ",
24 [BTRFS_FT_REG_FILE] = " ",
25 [BTRFS_FT_DIR] = "DIR",
26 [BTRFS_FT_CHRDEV] = "CHR",
27 [BTRFS_FT_BLKDEV] = "BLK",
28 [BTRFS_FT_FIFO] = "FIF",
29 [BTRFS_FT_SOCK] = "SCK",
30 [BTRFS_FT_SYMLINK] = "SYM",
31 [BTRFS_FT_XATTR] = " ? ",
32 };
33 struct btrfs_inode_item inode;
34 const char *name = (const char *) (item + 1);
35 char filetime[32], *target = NULL;
36 time_t mtime;
37
3b4b40c0
QW
38 if (btrfs_lookup_inode(root, (struct btrfs_key *)&item->location,
39 &inode, NULL)) {
0c936ee3
MB
40 printf("%s: Cannot find inode item for directory entry %.*s!\n",
41 __func__, item->name_len, name);
42 return 0;
43 }
44
45 mtime = inode.mtime.sec;
46 ctime_r(&mtime, filetime);
47
48 if (item->type == BTRFS_FT_SYMLINK) {
49 target = malloc(min(inode.size + 1,
50 (u64) btrfs_info.sb.sectorsize));
51
52 if (target && btrfs_readlink(root, item->location.objectid,
53 target)) {
54 free(target);
55 target = NULL;
56 }
57
58 if (!target)
59 printf("%s: Cannot read symlink target!\n", __func__);
60 }
61
62 printf("<%s> ", typestr[item->type]);
63 if (item->type == BTRFS_FT_CHRDEV || item->type == BTRFS_FT_BLKDEV)
64 printf("%4u,%5u ", (unsigned int) (inode.rdev >> 20),
65 (unsigned int) (inode.rdev & 0xfffff));
66 else
67 printf("%10llu ", inode.size);
68
69 printf("%24.24s %.*s", filetime, item->name_len, name);
70
71 if (item->type == BTRFS_FT_SYMLINK) {
72 printf(" -> %s", target ? target : "?");
73 if (target)
74 free(target);
75 }
76
77 printf("\n");
78
79 return 0;
80}
81
0528979f
SG
82int btrfs_probe(struct blk_desc *fs_dev_desc,
83 struct disk_partition *fs_partition)
0c936ee3 84{
f06bfcf5
QW
85 struct btrfs_fs_info *fs_info;
86 int ret = -1;
87
0c936ee3
MB
88 btrfs_blk_desc = fs_dev_desc;
89 btrfs_part_info = fs_partition;
90
91 memset(&btrfs_info, 0, sizeof(btrfs_info));
92
93 btrfs_hash_init();
94 if (btrfs_read_superblock())
95 return -1;
96
97 if (btrfs_chunk_map_init()) {
98 printf("%s: failed to init chunk map\n", __func__);
99 return -1;
100 }
101
102 btrfs_info.tree_root.objectid = 0;
103 btrfs_info.tree_root.bytenr = btrfs_info.sb.root;
104 btrfs_info.chunk_root.objectid = 0;
105 btrfs_info.chunk_root.bytenr = btrfs_info.sb.chunk_root;
106
57f24f10 107 if (__btrfs_read_chunk_tree()) {
0c936ee3
MB
108 printf("%s: failed to read chunk tree\n", __func__);
109 return -1;
110 }
111
112 if (btrfs_find_root(btrfs_get_default_subvol_objectid(),
113 &btrfs_info.fs_root, NULL)) {
114 printf("%s: failed to find default subvolume\n", __func__);
115 return -1;
116 }
117
f06bfcf5
QW
118 fs_info = open_ctree_fs_info(fs_dev_desc, fs_partition);
119 if (fs_info) {
120 current_fs_info = fs_info;
121 ret = 0;
122 }
123 return ret;
0c936ee3
MB
124}
125
126int btrfs_ls(const char *path)
127{
207011b8 128 struct __btrfs_root root = btrfs_info.fs_root;
0c936ee3
MB
129 u64 inr;
130 u8 type;
131
132 inr = btrfs_lookup_path(&root, root.root_dirid, path, &type, NULL, 40);
133
134 if (inr == -1ULL) {
135 printf("Cannot lookup path %s\n", path);
cd22e34c 136 return -1;
0c936ee3
MB
137 }
138
139 if (type != BTRFS_FT_DIR) {
140 printf("Not a directory: %s\n", path);
cd22e34c 141 return -1;
0c936ee3
MB
142 }
143
144 if (btrfs_readdir(&root, inr, readdir_callback)) {
145 printf("An error occured while listing directory %s\n", path);
cd22e34c 146 return -1;
0c936ee3
MB
147 }
148
149 return 0;
150}
151
152int btrfs_exists(const char *file)
153{
207011b8 154 struct __btrfs_root root = btrfs_info.fs_root;
0c936ee3
MB
155 u64 inr;
156 u8 type;
157
158 inr = btrfs_lookup_path(&root, root.root_dirid, file, &type, NULL, 40);
159
160 return (inr != -1ULL && type == BTRFS_FT_REG_FILE);
161}
162
163int btrfs_size(const char *file, loff_t *size)
164{
207011b8 165 struct __btrfs_root root = btrfs_info.fs_root;
0c936ee3
MB
166 struct btrfs_inode_item inode;
167 u64 inr;
168 u8 type;
169
170 inr = btrfs_lookup_path(&root, root.root_dirid, file, &type, &inode,
171 40);
172
173 if (inr == -1ULL) {
174 printf("Cannot lookup file %s\n", file);
cd22e34c 175 return -1;
0c936ee3
MB
176 }
177
178 if (type != BTRFS_FT_REG_FILE) {
179 printf("Not a regular file: %s\n", file);
cd22e34c 180 return -1;
0c936ee3
MB
181 }
182
183 *size = inode.size;
184 return 0;
185}
186
187int btrfs_read(const char *file, void *buf, loff_t offset, loff_t len,
188 loff_t *actread)
189{
207011b8 190 struct __btrfs_root root = btrfs_info.fs_root;
0c936ee3
MB
191 struct btrfs_inode_item inode;
192 u64 inr, rd;
193 u8 type;
194
195 inr = btrfs_lookup_path(&root, root.root_dirid, file, &type, &inode,
196 40);
197
198 if (inr == -1ULL) {
199 printf("Cannot lookup file %s\n", file);
cd22e34c 200 return -1;
0c936ee3
MB
201 }
202
203 if (type != BTRFS_FT_REG_FILE) {
204 printf("Not a regular file: %s\n", file);
cd22e34c 205 return -1;
0c936ee3
MB
206 }
207
208 if (!len)
209 len = inode.size;
210
211 if (len > inode.size - offset)
212 len = inode.size - offset;
213
214 rd = btrfs_file_read(&root, inr, offset, len, buf);
215 if (rd == -1ULL) {
216 printf("An error occured while reading file %s\n", file);
cd22e34c 217 return -1;
0c936ee3
MB
218 }
219
220 *actread = rd;
221 return 0;
222}
223
224void btrfs_close(void)
225{
226 btrfs_chunk_map_exit();
f06bfcf5
QW
227 if (current_fs_info) {
228 close_ctree_fs_info(current_fs_info);
229 current_fs_info = NULL;
230 }
0c936ee3
MB
231}
232
233int btrfs_uuid(char *uuid_str)
234{
235#ifdef CONFIG_LIB_UUID
236 uuid_bin_to_str(btrfs_info.sb.fsid, uuid_str, UUID_STR_FORMAT_STD);
237 return 0;
238#endif
239 return -ENOSYS;
240}
This page took 0.130877 seconds and 4 git commands to generate.