static int copy_metadata(struct btrfs_root *root, int fd, struct btrfs_key *key) { struct btrfs_path *path; struct btrfs_inode_item *inode_item; int ret; path = btrfs_alloc_path(); if (!path) { fprintf(stderr, "ERROR: Ran out of memory\n"); return -ENOMEM; } ret = btrfs_lookup_inode(NULL, root, path, key, 0); if (ret == 0) { struct btrfs_timespec *bts; struct timespec times[2]; inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0], struct btrfs_inode_item); ret = fchown(fd, btrfs_inode_uid(path->nodes[0], inode_item), btrfs_inode_gid(path->nodes[0], inode_item)); if (ret) { fprintf(stderr, "ERROR: Failed to change owner: %s\n", strerror(errno)); goto out; } ret = fchmod(fd, btrfs_inode_mode(path->nodes[0], inode_item)); if (ret) { fprintf(stderr, "ERROR: Failed to change mode: %s\n", strerror(errno)); goto out; } bts = btrfs_inode_atime(inode_item); times[0].tv_sec = btrfs_timespec_sec(path->nodes[0], bts); times[0].tv_nsec = btrfs_timespec_nsec(path->nodes[0], bts); bts = btrfs_inode_mtime(inode_item); times[1].tv_sec = btrfs_timespec_sec(path->nodes[0], bts); times[1].tv_nsec = btrfs_timespec_nsec(path->nodes[0], bts); ret = futimens(fd, times); if (ret) { fprintf(stderr, "ERROR: Failed to set times: %s\n", strerror(errno)); goto out; } } out: btrfs_free_path(path); return ret; }
static int copy_file(struct btrfs_root *root, int fd, struct btrfs_key *key, const char *file) { struct extent_buffer *leaf; struct btrfs_path *path; struct btrfs_file_extent_item *fi; struct btrfs_inode_item *inode_item; struct btrfs_timespec *bts; struct btrfs_key found_key; int ret; int extent_type; int compression; int loops = 0; u64 found_size = 0; struct timespec times[2]; int times_ok = 0; path = btrfs_alloc_path(); if (!path) { fprintf(stderr, "Ran out of memory\n"); return -ENOMEM; } ret = btrfs_lookup_inode(NULL, root, path, key, 0); if (ret == 0) { inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0], struct btrfs_inode_item); found_size = btrfs_inode_size(path->nodes[0], inode_item); if (restore_metadata) { /* * Change the ownership and mode now, set times when * copyout is finished. */ ret = fchown(fd, btrfs_inode_uid(path->nodes[0], inode_item), btrfs_inode_gid(path->nodes[0], inode_item)); if (ret && !ignore_errors) goto out; ret = fchmod(fd, btrfs_inode_mode(path->nodes[0], inode_item)); if (ret && !ignore_errors) goto out; bts = btrfs_inode_atime(inode_item); times[0].tv_sec = btrfs_timespec_sec(path->nodes[0], bts); times[0].tv_nsec = btrfs_timespec_nsec(path->nodes[0], bts); bts = btrfs_inode_mtime(inode_item); times[1].tv_sec = btrfs_timespec_sec(path->nodes[0], bts); times[1].tv_nsec = btrfs_timespec_nsec(path->nodes[0], bts); times_ok = 1; } }
static int copy_metadata(struct btrfs_root *root, int fd, struct btrfs_key *key) { struct btrfs_path path; struct btrfs_inode_item *inode_item; int ret; btrfs_init_path(&path); ret = btrfs_lookup_inode(NULL, root, &path, key, 0); if (ret == 0) { struct btrfs_timespec *bts; struct timespec times[2]; inode_item = btrfs_item_ptr(path.nodes[0], path.slots[0], struct btrfs_inode_item); ret = fchown(fd, btrfs_inode_uid(path.nodes[0], inode_item), btrfs_inode_gid(path.nodes[0], inode_item)); if (ret) { error("failed to change owner: %m"); goto out; } ret = fchmod(fd, btrfs_inode_mode(path.nodes[0], inode_item)); if (ret) { error("failed to change mode: %m"); goto out; } bts = btrfs_inode_atime(inode_item); times[0].tv_sec = btrfs_timespec_sec(path.nodes[0], bts); times[0].tv_nsec = btrfs_timespec_nsec(path.nodes[0], bts); bts = btrfs_inode_mtime(inode_item); times[1].tv_sec = btrfs_timespec_sec(path.nodes[0], bts); times[1].tv_nsec = btrfs_timespec_nsec(path.nodes[0], bts); ret = futimens(fd, times); if (ret) { error("failed to set times: %m"); goto out; } } out: btrfs_release_path(&path); return ret; }
static void print_timespec(struct extent_buffer *eb, struct btrfs_timespec *timespec, const char *prefix, const char *suffix) { struct tm tm; u64 tmp_u64; u32 tmp_u32; time_t tmp_time; char timestamp[256]; tmp_u64 = btrfs_timespec_sec(eb, timespec); tmp_u32 = btrfs_timespec_nsec(eb, timespec); tmp_time = tmp_u64; localtime_r(&tmp_time, &tm); strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", &tm); printf("%s%llu.%u (%s)%s", prefix, (unsigned long long)tmp_u64, tmp_u32, timestamp, suffix); }