xref: /haiku/src/system/libroot/os/fs_info.cpp (revision 9a6a20d4689307142a7ed26a1437ba47e244e73f)
1 /*
2 ** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 ** Distributed under the terms of the MIT License.
4 */
5 
6 
7 #include <fs_info.h>
8 
9 #include <errno.h>
10 #include <fcntl.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 
14 #include <errno_private.h>
15 #include <syscalls.h>
16 #include <syscall_utils.h>
17 
18 
19 dev_t
20 dev_for_path(const char *path)
21 {
22 	struct stat stat;
23 	int status = _kern_read_stat(AT_FDCWD, path, true, &stat, sizeof(struct stat));
24 	if (status == B_OK)
25 		return stat.st_dev;
26 
27 	RETURN_AND_SET_ERRNO(status);
28 }
29 
30 
31 dev_t
32 next_dev(int32 *_cookie)
33 {
34 	return _kern_next_device(_cookie);
35 		// For some reason, this one returns its error code directly
36 }
37 
38 
39 int
40 fs_stat_dev(dev_t device, fs_info *info)
41 {
42 	status_t status = _kern_read_fs_info(device, info);
43 
44 	if (info != NULL) {
45 		if (info->volume_name[0] == 0) {
46 			// Give a default name to unnamed volumes
47 			off_t divisor = 1ULL << 40;
48 			off_t diskSize = info->total_blocks * info->block_size;
49 
50 			char unit = 'T';
51 			if (diskSize < divisor) {
52 				divisor = 1UL << 30;
53 				unit = 'G';
54 				if (diskSize < divisor) {
55 					divisor = 1UL << 20;
56 					unit = 'M';
57 				}
58 			}
59 
60 			double size = double((10 * diskSize + divisor - 1) / divisor);
61 
62 			sprintf(info->volume_name, "%g %ciB %s volume", size / 10, unit, info->fsh_name);
63 		}
64 	}
65 
66 	RETURN_AND_SET_ERRNO(status);
67 }
68