*/
int btrfs_is_subvolume(const char *path)
{
- struct stat st;
- int ret;
+ struct stat st;
+ struct statfs sfs;
- ret = is_btrfs(path);
- if (ret <= 0)
- return ret;
+ if (statfs(path, &sfs) == -1)
+ return -1;
+ if (!is_btrfs(&sfs))
+ return 0;
if (stat(path, &st) == -1)
return -1;
}
-/* Adapted from btrfsprogs */
-int is_btrfs(const char *path)
+bool
+is_btrfs(const struct statfs *sfs)
{
- struct statfs sfs;
- int ret;
-
- ret = statfs(path, &sfs);
- if (ret == -1)
- return -1;
-
- return sfs.f_type == BTRFS_SUPER_MAGIC;
+ return sfs->f_type == BTRFS_SUPER_MAGIC;
}
-
#include <sys/socket.h>
#include <sys/stat.h>
+#include <sys/statfs.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
extern int btrfs_create_subvolume(const char *path);
extern int btrfs_remove_subvolume(const char *path);
extern int btrfs_is_subvolume(const char *path);
-extern int is_btrfs(const char *path);
+extern bool is_btrfs(const struct statfs *sfs);
#endif
/* basename() renamed to Basename() to avoid libc name space confusion */
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
+#include <sys/statfs.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#if WITH_BTRFS
if (subvolflg && (strlen(prefix_user_home) - (int)strlen(path)) <= 1) {
char *btrfs_check = strdup(path);
+ struct statfs sfs;
if (!btrfs_check) {
fprintf(stderr,
fail_exit(E_HOMEDIR, process_selinux);
}
stpcpy(&btrfs_check[strlen(path) - strlen(cp) - 1], "");
- if (is_btrfs(btrfs_check) <= 0) {
+ if (statfs(btrfs_check, &sfs) == -1) {
+ fprintf(stderr, "%s: statfs(\"%s\"): %s\n",
+ Prog, btrfs_check, strerrno());
+ fail_exit(E_HOMEDIR, process_selinux);
+ }
+ free(btrfs_check);
+ if (!is_btrfs(&sfs)) {
fprintf(stderr,
_("%s: home directory \"%s\" must be mounted on BTRFS\n"),
Prog, path);
fail_exit(E_HOMEDIR, process_selinux);
}
- free(btrfs_check);
// make subvolume to mount for user instead of directory
if (btrfs_create_subvolume(path)) {
fprintf(stderr,