]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - libfrog/linux.c
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
10 #include <sys/sysinfo.h>
12 #include "libxfs_priv.h"
16 extern char *progname
;
17 static int max_block_alignment
;
20 # define BLKGETSIZE64 _IOR(0x12,114,size_t)
23 # define BLKBSZSET _IOW(0x12,113,size_t)
26 # define BLKSSZGET _IO(0x12,104)
30 #define RAMDISK_MAJOR 1 /* ramdisk major number */
33 #define PROC_MOUNTED "/proc/mounts"
36 * Check if the filesystem is mounted. Be verbose if asked, and
37 * optionally restrict check to /writable/ mounts (i.e. RO is OK)
39 #define CHECK_MOUNT_VERBOSE 0x1
40 #define CHECK_MOUNT_WRITABLE 0x2
43 platform_check_mount(char *name
, char *block
, struct stat
*s
, int flags
)
48 char mounts
[MAXPATHLEN
];
51 /* If either fails we are not mounted */
52 if (stat(block
, &st
) < 0)
54 if ((st
.st_mode
& S_IFMT
) != S_IFBLK
)
59 strcpy(mounts
, (!access(PROC_MOUNTED
, R_OK
)) ? PROC_MOUNTED
: MOUNTED
);
60 if ((f
= setmntent(mounts
, "r")) == NULL
) {
61 /* Unexpected failure, warn unconditionally */
63 _("%s: %s possibly contains a mounted filesystem\n"),
68 * This whole business is to work out if our block device is mounted
69 * after we lost ustat(2), see:
70 * 4e7a824 libxfs/linux.c: Replace use of ustat by stat
71 * We don't really want to stat every single mounted directory,
72 * as that may include tmpfs, cgroups, procfs or - worst - hung nfs
73 * servers. So first, a simple check: does the "dev" start with "/" ?
75 while ((mnt
= getmntent(f
)) != NULL
) {
76 if (mnt
->mnt_fsname
[0] != '/')
78 if (stat(mnt
->mnt_dir
, &mst
) < 0)
80 if (mst
.st_dev
!= s
->st_rdev
)
82 /* Found our device, is RO OK? */
83 if ((flags
& CHECK_MOUNT_WRITABLE
) && hasmntopt(mnt
, MNTOPT_RO
))
90 /* No mounts contained the condition we were looking for */
94 if (flags
& CHECK_MOUNT_VERBOSE
) {
95 if (flags
& CHECK_MOUNT_WRITABLE
) {
97 _("%s: %s contains a mounted and writable filesystem\n"),
101 _("%s: %s contains a mounted filesystem\n"),
109 platform_check_ismounted(char *name
, char *block
, struct stat
*s
, int verbose
)
113 flags
= verbose
? CHECK_MOUNT_VERBOSE
: 0;
114 return platform_check_mount(name
, block
, s
, flags
);
118 platform_check_iswritable(char *name
, char *block
, struct stat
*s
)
122 /* Writable checks are always verbose */
123 flags
= CHECK_MOUNT_WRITABLE
| CHECK_MOUNT_VERBOSE
;
124 return platform_check_mount(name
, block
, s
, flags
);
128 platform_set_blocksize(int fd
, char *path
, dev_t device
, int blocksize
, int fatal
)
132 if (major(device
) != RAMDISK_MAJOR
) {
133 if ((error
= ioctl(fd
, BLKBSZSET
, &blocksize
)) < 0) {
134 fprintf(stderr
, _("%s: %s - cannot set blocksize "
135 "%d on block device %s: %s\n"),
136 progname
, fatal
? "error": "warning",
137 blocksize
, path
, strerror(errno
));
144 platform_flush_device(int fd
, dev_t device
)
147 if (major(device
) == RAMDISK_MAJOR
)
150 if (fstat(fd
, &st
) < 0)
153 if (S_ISREG(st
.st_mode
))
156 ioctl(fd
, BLKFLSBUF
, 0);
160 platform_findsizes(char *path
, int fd
, long long *sz
, int *bsz
)
166 if (fstat(fd
, &st
) < 0) {
167 fprintf(stderr
, _("%s: "
168 "cannot stat the device file \"%s\": %s\n"),
169 progname
, path
, strerror(errno
));
173 if ((st
.st_mode
& S_IFMT
) == S_IFREG
) {
176 *sz
= (long long)(st
.st_size
>> 9);
178 if (ioctl(fd
, XFS_IOC_DIOINFO
, &da
) < 0) {
180 * fall back to BBSIZE; mkfs might fail if there's a
181 * size mismatch between the image & the host fs...
187 if (*bsz
> max_block_alignment
)
188 max_block_alignment
= *bsz
;
192 error
= ioctl(fd
, BLKGETSIZE64
, &size
);
194 /* BLKGETSIZE64 returns size in bytes not 512-byte blocks */
195 *sz
= (long long)(size
>> 9);
197 /* If BLKGETSIZE64 fails, try BLKGETSIZE */
198 unsigned long tmpsize
;
200 error
= ioctl(fd
, BLKGETSIZE
, &tmpsize
);
202 fprintf(stderr
, _("%s: can't determine device size\n"),
206 *sz
= (long long)tmpsize
;
209 if (ioctl(fd
, BLKSSZGET
, bsz
) < 0) {
210 fprintf(stderr
, _("%s: warning - cannot get sector size "
211 "from block device %s: %s\n"),
212 progname
, path
, strerror(errno
));
215 if (*bsz
> max_block_alignment
)
216 max_block_alignment
= *bsz
;
220 platform_findrawpath(char *path
)
226 platform_findblockpath(char *path
)
232 platform_direct_blockdev(void)
238 platform_align_blockdev(void)
240 if (!max_block_alignment
)
241 return getpagesize();
242 return max_block_alignment
;
248 return sysconf(_SC_NPROCESSORS_ONLN
);
252 platform_physmem(void)
256 if (sysinfo(&si
) < 0) {
257 fprintf(stderr
, _("%s: can't determine memory size\n"),
261 return (si
.totalram
>> 10) * si
.mem_unit
; /* kilobytes */