X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=utils.c;h=d81d49800f4cdf01c15baae2008d7e0e4d33bf71;hb=335b7011352bfe27d59094d622abe111177021d4;hp=20cddd9db3dafddab3f14aa774a3a748bc060bb8;hpb=11c83cefb8b4a03b1835efaf603ddc95430a0c9e;p=platform%2Fupstream%2Fbtrfs-progs.git diff --git a/utils.c b/utils.c index 20cddd9..d81d498 100644 --- a/utils.c +++ b/utils.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -39,6 +40,8 @@ #include #include +#include + #include "kerncompat.h" #include "radix-tree.h" #include "ctree.h" @@ -179,7 +182,8 @@ int btrfs_add_to_fsid(struct btrfs_trans_handle *trans, u32 sectorsize) { struct btrfs_super_block *disk_super; - struct btrfs_super_block *super = root->fs_info->super_copy; + struct btrfs_fs_info *fs_info = root->fs_info; + struct btrfs_super_block *super = fs_info->super_copy; struct btrfs_device *device; struct btrfs_dev_item *dev_item; char *buf = NULL; @@ -214,7 +218,7 @@ int btrfs_add_to_fsid(struct btrfs_trans_handle *trans, device->total_bytes = device_total_bytes; device->bytes_used = 0; device->total_ios = 0; - device->dev_root = root->fs_info->dev_root; + device->dev_root = fs_info->dev_root; device->name = strdup(path); if (!device->name) { ret = -ENOMEM; @@ -222,7 +226,7 @@ int btrfs_add_to_fsid(struct btrfs_trans_handle *trans, } INIT_LIST_HEAD(&device->dev_list); - ret = btrfs_add_device(trans, root, device); + ret = btrfs_add_device(trans, fs_info, device); if (ret) goto out; @@ -248,8 +252,8 @@ int btrfs_add_to_fsid(struct btrfs_trans_handle *trans, BUG_ON(ret != sectorsize); free(buf); - list_add(&device->dev_list, &root->fs_info->fs_devices->devices); - device->fs_devices = root->fs_info->fs_devices; + list_add(&device->dev_list, &fs_info->fs_devices->devices); + device->fs_devices = fs_info->fs_devices; return 0; out: @@ -296,7 +300,7 @@ static int btrfs_wipe_existing_sb(int fd) memset(buf, 0, len); ret = pwrite(fd, buf, len, offset); if (ret < 0) { - error("cannot wipe existing superblock: %s", strerror(errno)); + error("cannot wipe existing superblock: %m"); ret = -1; } else if (ret != len) { error("cannot wipe existing superblock: wrote %d of %zd", ret, len); @@ -318,7 +322,7 @@ int btrfs_prepare_device(int fd, const char *file, u64 *block_count_ret, ret = fstat(fd, &st); if (ret < 0) { - error("unable to stat %s: %s", file, strerror(errno)); + error("unable to stat %s: %m", file); return 1; } @@ -378,7 +382,7 @@ int btrfs_make_root_dir(struct btrfs_trans_handle *trans, btrfs_set_stack_inode_generation(&inode_item, trans->transid); btrfs_set_stack_inode_size(&inode_item, 0); btrfs_set_stack_inode_nlink(&inode_item, 1); - btrfs_set_stack_inode_nbytes(&inode_item, root->nodesize); + btrfs_set_stack_inode_nbytes(&inode_item, root->fs_info->nodesize); btrfs_set_stack_inode_mode(&inode_item, S_IFDIR | 0755); btrfs_set_stack_timespec_sec(&inode_item.atime, now); btrfs_set_stack_timespec_nsec(&inode_item.atime, 0); @@ -445,7 +449,7 @@ int is_mount_point(const char *path) return ret; } -static int is_reg_file(const char *path) +int is_reg_file(const char *path) { struct stat statbuf; @@ -454,6 +458,21 @@ static int is_reg_file(const char *path) return S_ISREG(statbuf.st_mode); } +int is_path_exist(const char *path) +{ + struct stat statbuf; + int ret; + + ret = stat(path, &statbuf); + if (ret < 0) { + if (errno == ENOENT) + return 0; + else + return -errno; + } + return 1; +} + /* * This function checks if the given input parameter is * an uuid or a path @@ -517,7 +536,7 @@ int get_btrfs_mount(const char *dev, char *mp, size_t mp_size) fd = open(dev, O_RDONLY); if (fd < 0) { ret = -errno; - error("cannot open %s: %s", dev, strerror(errno)); + error("cannot open %s: %m", dev); goto out; } @@ -555,8 +574,8 @@ int open_path_or_dev_mnt(const char *path, DIR **dirstream, int verbose) return -1; } ret = open_file_or_dir(mp, dirstream); - error_on(verbose && ret < 0, "can't access '%s': %s", - path, strerror(errno)); + error_on(verbose && ret < 0, "can't access '%s': %m", + path); } else { ret = btrfs_open_dir(path, dirstream, 1); } @@ -567,17 +586,16 @@ int open_path_or_dev_mnt(const char *path, DIR **dirstream, int verbose) /* * Do the following checks before calling open_file_or_dir(): * 1: path is in a btrfs filesystem - * 2: path is a directory + * 2: path is a directory if dir_only is 1 */ -int btrfs_open_dir(const char *path, DIR **dirstream, int verbose) +int btrfs_open(const char *path, DIR **dirstream, int verbose, int dir_only) { struct statfs stfs; struct stat st; int ret; if (statfs(path, &stfs) != 0) { - error_on(verbose, "cannot access '%s': %s", path, - strerror(errno)); + error_on(verbose, "cannot access '%s': %m", path); return -1; } @@ -587,25 +605,33 @@ int btrfs_open_dir(const char *path, DIR **dirstream, int verbose) } if (stat(path, &st) != 0) { - error_on(verbose, "cannot access '%s': %s", path, - strerror(errno)); + error_on(verbose, "cannot access '%s': %m", path); return -1; } - if (!S_ISDIR(st.st_mode)) { + if (dir_only && !S_ISDIR(st.st_mode)) { error_on(verbose, "not a directory: %s", path); return -3; } ret = open_file_or_dir(path, dirstream); if (ret < 0) { - error_on(verbose, "cannot access '%s': %s", path, - strerror(errno)); + error_on(verbose, "cannot access '%s': %m", path); } return ret; } +int btrfs_open_dir(const char *path, DIR **dirstream, int verbose) +{ + return btrfs_open(path, dirstream, verbose, 1); +} + +int btrfs_open_file_or_dir(const char *path, DIR **dirstream, int verbose) +{ + return btrfs_open(path, dirstream, verbose, 0); +} + /* checks if a device is a loop device */ static int is_loop_device (const char* device) { struct stat statbuf; @@ -792,14 +818,9 @@ static int blk_file_in_dev_list(struct btrfs_fs_devices* fs_devices, const char* file) { int ret; - struct list_head *head; - struct list_head *cur; struct btrfs_device *device; - head = &fs_devices->devices; - list_for_each(cur, head) { - device = list_entry(cur, struct btrfs_device, dev_list); - + list_for_each_entry(device, &fs_devices->devices, dev_list) { if((ret = is_same_loop_file(device->name, file))) return ret; } @@ -876,8 +897,7 @@ int check_mounted(const char* file) fd = open(file, O_RDONLY); if (fd < 0) { - error("mount check: cannot open %s: %s", file, - strerror(errno)); + error("mount check: cannot open %s: %m", file); return -errno; } @@ -966,16 +986,14 @@ int btrfs_register_one_device(const char *fname) fd = open("/dev/btrfs-control", O_RDWR); if (fd < 0) { warning( - "failed to open /dev/btrfs-control, skipping device registration: %s", - strerror(errno)); + "failed to open /dev/btrfs-control, skipping device registration: %m"); return -errno; } memset(&args, 0, sizeof(args)); strncpy_null(args.name, fname); ret = ioctl(fd, BTRFS_IOC_SCAN_DEV, &args); if (ret < 0) { - error("device scan failed on '%s': %s", fname, - strerror(errno)); + error("device scan failed on '%s': %m", fname); ret = -errno; } close(fd); @@ -1032,7 +1050,7 @@ int btrfs_device_already_in_root(struct btrfs_root *root, int fd, * structures. */ if (btrfs_super_magic(disk_super) != BTRFS_MAGIC && - btrfs_super_magic(disk_super) != BTRFS_MAGIC_PARTIAL) + btrfs_super_magic(disk_super) != BTRFS_MAGIC_TEMPORARY) goto brelse; if (!memcmp(disk_super->fsid, root->fs_info->super_copy->fsid, @@ -1228,6 +1246,7 @@ static int set_label_unmounted(const char *dev, const char *label) return -1; trans = btrfs_start_transaction(root, 1); + BUG_ON(IS_ERR(trans)); __strncpy_null(root->fs_info->super_copy->label, label, BTRFS_LABEL_SIZE - 1); btrfs_commit_transaction(trans, root); @@ -1244,15 +1263,14 @@ static int set_label_mounted(const char *mount_path, const char *labelp) fd = open(mount_path, O_RDONLY | O_NOATIME); if (fd < 0) { - error("unable to access %s: %s", mount_path, strerror(errno)); + error("unable to access %s: %m", mount_path); return -1; } memset(label, 0, sizeof(label)); __strncpy_null(label, labelp, BTRFS_LABEL_SIZE - 1); if (ioctl(fd, BTRFS_IOC_SET_FSLABEL, label) < 0) { - error("unable to set label of %s: %s", mount_path, - strerror(errno)); + error("unable to set label of %s: %m", mount_path); close(fd); return -1; } @@ -1300,7 +1318,7 @@ int get_label_mounted(const char *mount_path, char *labelp) fd = open(mount_path, O_RDONLY | O_NOATIME); if (fd < 0) { - error("unable to access %s: %s", mount_path, strerror(errno)); + error("unable to access %s: %m", mount_path); return -1; } @@ -1308,8 +1326,7 @@ int get_label_mounted(const char *mount_path, char *labelp) ret = ioctl(fd, BTRFS_IOC_GET_FSLABEL, label); if (ret < 0) { if (errno != ENOTTY) - error("unable to get label of %s: %s", mount_path, - strerror(errno)); + error("unable to get label of %s: %m", mount_path); ret = -errno; close(fd); return ret; @@ -1438,6 +1455,7 @@ u64 parse_qgroupid(const char *p) char *s = strchr(p, '/'); const char *ptr_src_end = p + strlen(p); char *ptr_parse_end = NULL; + enum btrfs_util_error err; u64 level; u64 id; int fd; @@ -1465,8 +1483,8 @@ u64 parse_qgroupid(const char *p) path: /* Path format like subv at 'my_subvol' is the fallback case */ - ret = test_issubvolume(p); - if (ret < 0 || !ret) + err = btrfs_util_is_subvolume(p); + if (err) goto err; fd = open(p, O_RDONLY); if (fd < 0) @@ -1526,10 +1544,16 @@ int open_file_or_dir(const char *fname, DIR **dirstream) void close_file_or_dir(int fd, DIR *dirstream) { - if (dirstream) + int old_errno; + + old_errno = errno; + if (dirstream) { closedir(dirstream); - else if (fd >= 0) + } else if (fd >= 0) { close(fd); + } + + errno = old_errno; } int get_device_info(int fd, u64 devid, @@ -1647,7 +1671,7 @@ int get_fs_info(const char *path, struct btrfs_ioctl_fs_info_args *fi_args, fd = open(path, O_RDONLY); if (fd < 0) { ret = -errno; - error("cannot open %s: %s", path, strerror(errno)); + error("cannot open %s: %m", path); goto out; } ret = check_mounted_where(fd, path, mp, sizeof(mp), @@ -1746,157 +1770,107 @@ out: return ret; } -#define isoctal(c) (((c) & ~7) == '0') - -static inline void translate(char *f, char *t) +int get_fsid(const char *path, u8 *fsid, int silent) { - while (*f != '\0') { - if (*f == '\\' && - isoctal(f[1]) && isoctal(f[2]) && isoctal(f[3])) { - *t++ = 64*(f[1] & 7) + 8*(f[2] & 7) + (f[3] & 7); - f += 4; - } else - *t++ = *f++; - } - *t = '\0'; - return; -} - -/* - * Checks if the swap device. - * Returns 1 if swap device, < 0 on error or 0 if not swap device. - */ -static int is_swap_device(const char *file) -{ - FILE *f; - struct stat st_buf; - dev_t dev; - ino_t ino = 0; - char tmp[PATH_MAX]; - char buf[PATH_MAX]; - char *cp; - int ret = 0; - - if (stat(file, &st_buf) < 0) - return -errno; - if (S_ISBLK(st_buf.st_mode)) - dev = st_buf.st_rdev; - else if (S_ISREG(st_buf.st_mode)) { - dev = st_buf.st_dev; - ino = st_buf.st_ino; - } else - return 0; - - if ((f = fopen("/proc/swaps", "r")) == NULL) - return 0; + int ret; + int fd; + struct btrfs_ioctl_fs_info_args args; - /* skip the first line */ - if (fgets(tmp, sizeof(tmp), f) == NULL) + fd = open(path, O_RDONLY); + if (fd < 0) { + ret = -errno; + if (!silent) + error("failed to open %s: %s", path, + strerror(-ret)); goto out; + } - while (fgets(tmp, sizeof(tmp), f) != NULL) { - if ((cp = strchr(tmp, ' ')) != NULL) - *cp = '\0'; - if ((cp = strchr(tmp, '\t')) != NULL) - *cp = '\0'; - translate(tmp, buf); - if (stat(buf, &st_buf) != 0) - continue; - if (S_ISBLK(st_buf.st_mode)) { - if (dev == st_buf.st_rdev) { - ret = 1; - break; - } - } else if (S_ISREG(st_buf.st_mode)) { - if (dev == st_buf.st_dev && ino == st_buf.st_ino) { - ret = 1; - break; - } - } + ret = ioctl(fd, BTRFS_IOC_FS_INFO, &args); + if (ret < 0) { + ret = -errno; + goto out; } -out: - fclose(f); + memcpy(fsid, args.fsid, BTRFS_FSID_SIZE); + ret = 0; +out: + if (fd != -1) + close(fd); return ret; } -/* - * Check for existing filesystem or partition table on device. - * Returns: - * 1 for existing fs or partition - * 0 for nothing found - * -1 for internal error - */ -static int check_overwrite(const char *device) +int is_seen_fsid(u8 *fsid, struct seen_fsid *seen_fsid_hash[]) { - const char *type; - blkid_probe pr = NULL; - int ret; - blkid_loff_t size; + u8 hash = fsid[0]; + int slot = hash % SEEN_FSID_HASH_SIZE; + struct seen_fsid *seen = seen_fsid_hash[slot]; - if (!device || !*device) - return 0; + while (seen) { + if (memcmp(seen->fsid, fsid, BTRFS_FSID_SIZE) == 0) + return 1; - ret = -1; /* will reset on success of all setup calls */ + seen = seen->next; + } - pr = blkid_new_probe_from_filename(device); - if (!pr) - goto out; + return 0; +} - size = blkid_probe_get_size(pr); - if (size < 0) - goto out; +int add_seen_fsid(u8 *fsid, struct seen_fsid *seen_fsid_hash[], + int fd, DIR *dirstream) +{ + u8 hash = fsid[0]; + int slot = hash % SEEN_FSID_HASH_SIZE; + struct seen_fsid *seen = seen_fsid_hash[slot]; + struct seen_fsid *alloc; - /* nothing to overwrite on a 0-length device */ - if (size == 0) { - ret = 0; - goto out; - } + if (!seen) + goto insert; - ret = blkid_probe_enable_partitions(pr, 1); - if (ret < 0) - goto out; + while (1) { + if (memcmp(seen->fsid, fsid, BTRFS_FSID_SIZE) == 0) + return -EEXIST; - ret = blkid_do_fullprobe(pr); - if (ret < 0) - goto out; + if (!seen->next) + break; - /* - * Blkid returns 1 for nothing found and 0 when it finds a signature, - * but we want the exact opposite, so reverse the return value here. - * - * In addition print some useful diagnostics about what actually is - * on the device. - */ - if (ret) { - ret = 0; - goto out; + seen = seen->next; } - if (!blkid_probe_lookup_value(pr, "TYPE", &type, NULL)) { - fprintf(stderr, - "%s appears to contain an existing " - "filesystem (%s).\n", device, type); - } else if (!blkid_probe_lookup_value(pr, "PTTYPE", &type, NULL)) { - fprintf(stderr, - "%s appears to contain a partition " - "table (%s).\n", device, type); - } else { - fprintf(stderr, - "%s appears to contain something weird " - "according to blkid\n", device); - } - ret = 1; +insert: + alloc = malloc(sizeof(*alloc)); + if (!alloc) + return -ENOMEM; -out: - if (pr) - blkid_free_probe(pr); - if (ret == -1) - fprintf(stderr, - "probe of %s failed, cannot detect " - "existing filesystem.\n", device); - return ret; + alloc->next = NULL; + memcpy(alloc->fsid, fsid, BTRFS_FSID_SIZE); + alloc->fd = fd; + alloc->dirstream = dirstream; + + if (seen) + seen->next = alloc; + else + seen_fsid_hash[slot] = alloc; + + return 0; +} + +void free_seen_fsid(struct seen_fsid *seen_fsid_hash[]) +{ + int slot; + struct seen_fsid *seen; + struct seen_fsid *next; + + for (slot = 0; slot < SEEN_FSID_HASH_SIZE; slot++) { + seen = seen_fsid_hash[slot]; + while (seen) { + next = seen->next; + close_file_or_dir(seen->fd, seen->dirstream); + free(seen); + seen = next; + } + seen_fsid_hash[slot] = NULL; + } } static int group_profile_devs_min(u64 flag) @@ -1987,84 +1961,6 @@ int group_profile_max_safe_loss(u64 flags) } } -u64 btrfs_min_dev_size(u32 nodesize) -{ - return 2 * (BTRFS_MKFS_SYSTEM_GROUP_SIZE + - btrfs_min_global_blk_rsv_size(nodesize)); -} - -/* - * Btrfs minimum size calculation is complicated, it should include at least: - * 1. system group size - * 2. minimum global block reserve - * 3. metadata used at mkfs - * 4. space reservation to create uuid for first mount. - * Also, raid factor should also be taken into consideration. - * To avoid the overkill calculation, (system group + global block rsv) * 2 - * for *EACH* device should be good enough. - */ -u64 btrfs_min_global_blk_rsv_size(u32 nodesize) -{ - return (u64)nodesize << 10; -} - -/* - * Check if a device is suitable for btrfs - * returns: - * 1: something is wrong, an error is printed - * 0: all is fine - */ -int test_dev_for_mkfs(const char *file, int force_overwrite) -{ - int ret, fd; - struct stat st; - - ret = is_swap_device(file); - if (ret < 0) { - error("checking status of %s: %s", file, strerror(-ret)); - return 1; - } - if (ret == 1) { - error("%s is a swap device", file); - return 1; - } - if (!force_overwrite) { - if (check_overwrite(file)) { - error("use the -f option to force overwrite of %s", - file); - return 1; - } - } - ret = check_mounted(file); - if (ret < 0) { - error("cannot check mount status of %s: %s", file, - strerror(-ret)); - return 1; - } - if (ret == 1) { - error("%s is mounted", file); - return 1; - } - /* check if the device is busy */ - fd = open(file, O_RDWR|O_EXCL); - if (fd < 0) { - error("unable to open %s: %s", file, strerror(errno)); - return 1; - } - if (fstat(fd, &st)) { - error("unable to stat %s: %s", file, strerror(errno)); - close(fd); - return 1; - } - if (!S_ISBLK(st.st_mode)) { - error("%s is not a block device", file); - close(fd); - return 1; - } - close(fd); - return 0; -} - int btrfs_scan_devices(void) { int fd = -1; @@ -2095,7 +1991,7 @@ int btrfs_scan_devices(void) fd = open(path, O_RDONLY); if (fd < 0) { - error("cannot open %s: %s", path, strerror(errno)); + error("cannot open %s: %m", path); continue; } ret = btrfs_scan_one_device(fd, path, &tmp_devices, @@ -2117,35 +2013,6 @@ int btrfs_scan_devices(void) return 0; } -int is_vol_small(const char *file) -{ - int fd = -1; - int e; - struct stat st; - u64 size; - - fd = open(file, O_RDONLY); - if (fd < 0) - return -errno; - if (fstat(fd, &st) < 0) { - e = -errno; - close(fd); - return e; - } - size = btrfs_device_size(fd, &st); - if (size == 0) { - close(fd); - return -1; - } - if (size < BTRFS_MKFS_SMALL_VOLUME_SIZE) { - close(fd); - return 1; - } else { - close(fd); - return 0; - } -} - /* * This reads a line from the stdin and only returns non-zero if the * first whitespace delimited token is a case insensitive match with yes @@ -2219,27 +2086,6 @@ int find_mount_root(const char *path, char **mount_root) return ret; } -int test_minimum_size(const char *file, u32 nodesize) -{ - int fd; - struct stat statbuf; - - fd = open(file, O_RDONLY); - if (fd < 0) - return -errno; - if (stat(file, &statbuf) < 0) { - close(fd); - return -errno; - } - if (btrfs_device_size(fd, &statbuf) < btrfs_min_dev_size(nodesize)) { - close(fd); - return 1; - } - close(fd); - return 0; -} - - /* * Test if path is a directory * Returns: @@ -2547,6 +2393,32 @@ unsigned int get_unit_mode_from_arg(int *argc, char *argv[], int df_mode) return unit_mode; } +u64 div_factor(u64 num, int factor) +{ + if (factor == 10) + return num; + num *= factor; + num /= 10; + return num; +} +/* + * Get the length of the string converted from a u64 number. + * + * Result is equal to log10(num) + 1, but without the use of math library. + */ +int count_digits(u64 num) +{ + int ret = 0; + + if (num == 0) + return 1; + while (num > 0) { + ret++; + num /= 10; + } + return ret; +} + int string_is_numerical(const char *str) { if (!str) @@ -2560,6 +2432,15 @@ int string_is_numerical(const char *str) return 1; } +int prefixcmp(const char *str, const char *prefix) +{ + for (; ; str++, prefix++) + if (!*prefix) + return 0; + else if (*str != *prefix) + return (unsigned char)*prefix - (unsigned char)*str; +} + /* Subvolume helper functions */ /* * test if name is a correct subvolume name @@ -2573,111 +2454,24 @@ int test_issubvolname(const char *name) strcmp(name, ".") && strcmp(name, ".."); } -/* - * Test if path is a subvolume - * Returns: - * 0 - path exists but it is not a subvolume - * 1 - path exists and it is a subvolume - * < 0 - error - */ -int test_issubvolume(const char *path) -{ - struct stat st; - struct statfs stfs; - int res; - - res = stat(path, &st); - if (res < 0) - return -errno; - - if (st.st_ino != BTRFS_FIRST_FREE_OBJECTID || !S_ISDIR(st.st_mode)) - return 0; - - res = statfs(path, &stfs); - if (res < 0) - return -errno; - - return (int)stfs.f_type == BTRFS_SUPER_MAGIC; -} - const char *subvol_strip_mountpoint(const char *mnt, const char *full_path) { int len = strlen(mnt); if (!len) return full_path; + if ((strncmp(mnt, full_path, len) != 0) || (full_path[len] != '/')) { + error("not on mount point: %s", mnt); + exit(1); + } + if (mnt[len - 1] != '/') len += 1; return full_path + len; } -/* - * Returns - * <0: Std error - * 0: All fine - * 1: Error; and error info printed to the terminal. Fixme. - * 2: If the fullpath is root tree instead of subvol tree - */ -int get_subvol_info(const char *fullpath, struct root_info *get_ri) -{ - u64 sv_id; - int ret = 1; - int fd = -1; - int mntfd = -1; - char *mnt = NULL; - const char *svpath = NULL; - DIR *dirstream1 = NULL; - DIR *dirstream2 = NULL; - - ret = test_issubvolume(fullpath); - if (ret < 0) - return ret; - if (!ret) { - error("not a subvolume: %s", fullpath); - return 1; - } - - ret = find_mount_root(fullpath, &mnt); - if (ret < 0) - return ret; - if (ret > 0) { - error("%s doesn't belong to btrfs mount point", fullpath); - return 1; - } - ret = 1; - svpath = subvol_strip_mountpoint(mnt, fullpath); - - fd = btrfs_open_dir(fullpath, &dirstream1, 1); - if (fd < 0) - goto out; - - ret = btrfs_list_get_path_rootid(fd, &sv_id); - if (ret) - goto out; - - mntfd = btrfs_open_dir(mnt, &dirstream2, 1); - if (mntfd < 0) - goto out; - - memset(get_ri, 0, sizeof(*get_ri)); - get_ri->root_id = sv_id; - - if (sv_id == BTRFS_FS_TREE_OBJECTID) - ret = btrfs_get_toplevel_subvol(mntfd, get_ri); - else - ret = btrfs_get_subvol(mntfd, get_ri); - if (ret) - error("can't find '%s': %d", svpath, ret); - -out: - close_file_or_dir(mntfd, dirstream2); - close_file_or_dir(fd, dirstream1); - free(mnt); - - return ret; -} - +/* Set the seed manually */ void init_rand_seed(u64 seed) { int i; @@ -2727,6 +2521,7 @@ u32 rand_u32(void) return (u32)jrand48(rand_seed); } +/* Return random number in range [0, upper) */ unsigned int rand_range(unsigned int upper) { __init_seed(); @@ -2737,6 +2532,61 @@ unsigned int rand_range(unsigned int upper) return (unsigned int)(jrand48(rand_seed) % upper); } +int rand_int(void) +{ + return (int)(rand_u32()); +} + +u64 rand_u64(void) +{ + u64 ret = 0; + + ret += rand_u32(); + ret <<= 32; + ret += rand_u32(); + return ret; +} + +u16 rand_u16(void) +{ + return (u16)(rand_u32()); +} + +u8 rand_u8(void) +{ + return (u8)(rand_u32()); +} + void btrfs_config_init(void) { } + +/* Returns total size of main memory in bytes, -1UL if error. */ +unsigned long total_memory(void) +{ + struct sysinfo si; + + if (sysinfo(&si) < 0) { + error("can't determine memory size"); + return -1UL; + } + return si.totalram * si.mem_unit; /* bytes */ +} + +void print_device_info(struct btrfs_device *device, char *prefix) +{ + if (prefix) + printf("%s", prefix); + printf("Device: id = %llu, name = %s\n", + device->devid, device->name); +} + +void print_all_devices(struct list_head *devices) +{ + struct btrfs_device *dev; + + printf("All Devices:\n"); + list_for_each_entry(dev, devices, dev_list) + print_device_info(dev, "\t"); + printf("\n"); +}