static int freeze_fs(struct ploop_copy_handle *h) { int ret; if (h->mntfd != -1) { /* Sync fs */ ploop_dbg(4, "SYNCFS"); if (sys_syncfs(h->mntfd)) { ploop_err(errno, "syncfs() failed"); ret = SYSEXIT_FSYNC; goto err; } /* Flush journal and freeze fs (this also clears the fs dirty bit) */ ploop_dbg(4, "FIFREEZE"); ret = ioctl_device(h->mntfd, FIFREEZE, 0); if (ret) goto err; h->fs_frozen = 1; } ploop_dbg(4, "IOC_SYNC"); ret = ioctl_device(h->devfd, PLOOP_IOC_SYNC, 0); if (ret) goto err; return 0; err: ploop_copy_release(h); return ret; }
void ploop_copy_release(struct ploop_copy_handle *h) { if (h == NULL) return; if (h->fs_frozen) { (void)ioctl_device(h->mntfd, FITHAW, 0); h->fs_frozen = 0; } if (h->tracker_on) { (void)ioctl_device(h->devfd, PLOOP_IOC_TRACK_ABORT, 0); h->tracker_on = 0; } if (h->mntfd != -1) { close(h->mntfd); h->mntfd = -1; } if (h->devfd != -1) { close(h->devfd); h->devfd = -1; } if (h->idelta.fd != -1) close_delta(&h->idelta); }
int ploop_copy_start(struct ploop_copy_handle *h, struct ploop_copy_stat *stat) { int ret; struct ploop_track_extent e; ssize_t n; __u64 pos; ret = pthread_create(&h->send_th, NULL, sender_thread, h); if (ret) { ploop_err(ret, "Can't create send thread"); ret = SYSEXIT_SYS; goto err; } pthread_barrier_wait(&h->sd.barrier); ploop_dbg(3, "pcopy track init"); ret = ioctl_device(h->devfd, PLOOP_IOC_TRACK_INIT, &e); if (ret) goto err; h->tracker_on = 1; h->trackend = e.end; ploop_log(3, "pcopy start %s e.end=%" PRIu64, h->async ? "async" : "", (uint64_t)e.end); for (pos = 0; pos <= h->trackend; ) { h->trackpos = pos + h->cluster; ret = ioctl_device(h->devfd, PLOOP_IOC_TRACK_SETPOS, &h->trackpos); if (ret) goto err; ret = send_image_block(h, h->cluster, pos, &n); if (ret) goto err; if (n == 0) /* EOF */ break; pos += n; if (pos > h->eof_offset) h->eof_offset = pos; } wait_sender(h); stat->xferred_total = stat->xferred = pos; send_cmd(h, PCOPY_CMD_SYNC); ploop_dbg(3, "pcopy start finished"); return 0; err: ploop_copy_release(h); return ret; }
int ploop_complete_running_operation(const char *device) { struct ploop_balloon_ctl b_ctl; int fd, ret; fd = open_device(device); if (fd == -1) return SYSEXIT_OPEN; bzero(&b_ctl, sizeof(b_ctl)); b_ctl.keep_intact = 1; ret = ioctl(fd, PLOOP_IOC_BALLOON, &b_ctl); if (ret) { ploop_err(errno, "Unable to get in-kernel maintenance state"); ret = SYSEXIT_DEVIOC; goto err; } if (b_ctl.mntn_type == PLOOP_MNTN_OFF) goto err; ploop_log(0, "Completing an on-going operation %s for device %s", mntn2str(b_ctl.mntn_type), device); switch (b_ctl.mntn_type) { case PLOOP_MNTN_MERGE: ret = ioctl_device(fd, PLOOP_IOC_MERGE, 0); break; case PLOOP_MNTN_GROW: ret = ioctl_device(fd, PLOOP_IOC_GROW, 0); break; case PLOOP_MNTN_RELOC: case PLOOP_MNTN_FBLOADED: ret = ploop_balloon_complete(device); break; case PLOOP_MNTN_TRACK: ret = ioctl_device(fd, PLOOP_IOC_TRACK_ABORT, 0); break; case PLOOP_MNTN_DISCARD: ret = ploop_balloon_complete(device); break; case PLOOP_MNTN_BALLOON: /* FIXME : ploop_balloon_check_and_repair(device, mount_point, 1; */ ret = 0; break; } err: close(fd); return ret; }
static int freeze(struct ploop_copy_handle *h) { int ret; ret = ioctl(h->partfd, PLOOP_IOC_FREEZE); if (ret) { if (errno == EINVAL) ret = freeze_fs(h); else ploop_err(errno, "Failed to freeze device"); if (ret) goto err; } else { ploop_log(0, "Freezing device..."); h->dev_frozen = 1; } ploop_dbg(3, "IOC_SYNC"); ret = ioctl_device(h->devfd, PLOOP_IOC_SYNC, 0); if (ret) goto err; return 0; err: ploop_copy_release(h); return ret; }
/*remove device, when success, it return the device's serialno, when failure, return TDSP_SERIAL_NOCARD 0X10000*/ int tdsp_remove_device(unsigned long serialno) { int fd; BUSENUM_UNPLUG_HARDWARE unplug; int bytes; debug("call the function: tdsp_remove_device( %ld)\n", serialno); fd = open_device(TDSP_BUS_DEVICE_NAME); if (fd == -1) { perror("open error"); return TDSP_SERIAL_NO_NOCARD; } unplug.Size = bytes = sizeof(unplug); unplug.SerialNo = serialno; if (ioctl_device(fd, TDSP_UNPLUG, &unplug) == -1) { close_device(fd); perror("tdsp_remove_device: ioctl error"); return TDSP_SERIAL_NO_NOCARD; } close_device(fd); debug("tdsp_remove_device( %ld ): success\n", serialno); return serialno; }
int tdsp_query_power_state() { int fd; int ret; debug("call the function: tdsp_query_power_state()\n"); g_buspowerstate = PowerOff; fd = open_device(TDSP_BUS_DEVICE_NAME); if (fd == -1) { debug(":open file error, fail!\n"); perror("open error"); return TDSP_SERIAL_NO_NOCARD; } if (ioctl_device(fd, TDSP_QUERY_BUS_POWER_STATE, &ret) != 0) { close_device(fd); debug(": ioctl error, fail!\n"); perror("ioctl error"); return TDSP_SERIAL_NO_NOCARD; } close_device(fd); debug(": ret = 0x%x\n", ret); g_buspowerstate = ret; return ret; }
int tdsp_query_device() { debug("call the function: tdsp_query_device \n"); int fd; int ret; g_iscardin = FALSE; g_currentserialno = TDSP_SERIAL_NO_NOCARD; fd = open_device(TDSP_BUS_DEVICE_NAME); if (fd == -1) { perror("open error"); return TDSP_SERIAL_NO_NOCARD; } if (ioctl_device(fd, TDSP_DISPLAY_IN_USE, &ret) == -1) { close_device(fd); perror("ioctl error"); return TDSP_SERIAL_NO_NOCARD; } // debug ("tdsp_query_device: ret = 0x%x\n",ret); close_device(fd); g_currentserialno = ret; g_iscardin = TRUE; debug("\ttdsp_query_device: g_iscardin = %d and g_currentserialno = 0x%x\n", g_iscardin, g_currentserialno); return ret; }
static int blk_discard(int fd, __u32 cluster, __u64 start, __u64 len) { __u64 max_discard_len = S2B(B2S(UINT_MAX) / cluster * cluster); while (len > 0) { __u64 range[2]; int ret; range[0] = start; range[1] = MIN(len, max_discard_len); if (start % S2B(cluster) && len > range[1]) range[1] -= start % S2B(cluster); ploop_log(1, "Call BLKDISCARD start=%" PRIu64 " length=%" PRIu64, (uint64_t)range[0], (uint64_t)range[1]); ret = ioctl_device(fd, BLKDISCARD, range); if (ret) return ret; start += range[1]; len -= range[1]; } return 0; }
int tdsp_query_reset_flag() { int fd; int ret; g_busresetflag = 0; debug("call the function: tdsp_query_reset_flag()\n"); fd = open_device(TDSP_BUS_DEVICE_NAME); if (fd == -1) { perror("open error"); return -1; } if (ioctl_device(fd, TDSP_QUERY_RESET_FLAG, &ret) == -1) { close_device(fd); perror("ioctl error"); return -1; } close_device(fd); debug ("the function: tdsp_query_reset_flag: ret = %d (0 is right, 1 is no right)\n", ret); g_busresetflag = ret; return ret; }
int ploop_balloon_complete(const char *device) { int fd, err; struct ploop_balloon_ctl b_ctl; fd = open_device(device); if (fd == -1) return SYSEXIT_OPEN; err = ioctl(fd, PLOOP_IOC_DISCARD_FINI); if (err && errno != EBUSY) { ploop_err(errno, "Can't finalize discard mode"); err = SYSEXIT_DEVIOC; goto out; } memset(&b_ctl, 0, sizeof(b_ctl)); b_ctl.keep_intact = 1; err = ioctl_device(fd, PLOOP_IOC_BALLOON, &b_ctl); if (err) goto out; switch (b_ctl.mntn_type) { case PLOOP_MNTN_BALLOON: case PLOOP_MNTN_MERGE: case PLOOP_MNTN_GROW: case PLOOP_MNTN_TRACK: case PLOOP_MNTN_OFF: ploop_log(0, "Nothing to complete: kernel is in \"%s\" state", mntn2str(b_ctl.mntn_type)); goto out; case PLOOP_MNTN_RELOC: case PLOOP_MNTN_FBLOADED: break; default: ploop_err(0, "Error: unknown mntn_type (%u)", b_ctl.mntn_type); err = SYSEXIT_PROTOCOL; goto out; } err = ploop_balloon_relocation(fd, &b_ctl, device); out: close(fd); return err; }
int tdsp_read_register(unsigned long uloffset, unsigned long ullength, char *chbuf) { debug("call the function: tdsp_read_register( offset=%ld,length=%ld)\n", uloffset, ullength); int fd; int bytes; PRW_REGISTER_STRUC pregister; fd = open_device(TDSP_BUS_DEVICE_NAME); if (fd == -1) { perror("open error"); return FALSE; } pregister = (PRW_REGISTER_STRUC) malloc(bytes = (sizeof(RW_REGISTER_STRUC) + ullength + 1)); if (pregister == NULL) { debug("tdsp_read_register: malloc pregister error\n"); close_device(fd); return FALSE; } pregister->offset = uloffset; pregister->length = ullength; debug("the pregister: pregister->offse=%d,pregister->length=%ld\n", pregister->offset, pregister->length); if (ioctl_device(fd, TDSP_READ_REGISTER, pregister) == -1) { free(pregister); close_device(fd); printf("tdsp_read_register: ioctl error"); return FALSE; } close_device(fd); pregister->buf[ullength + 1] = '\0'; if (chbuf != NULL) memcpy(chbuf, pregister->buf, ullength); BtPrintBuffer(pregister->buf, ullength); free(pregister); return TRUE; }
static int blkpg_resize_partition(int fd, struct GptEntry *pe) { struct blkpg_ioctl_arg ioctl_arg; struct blkpg_partition part; bzero(&part, sizeof(part)); part.pno = 1; part.start = S2B(pe->starting_lba); part.length = S2B(pe->ending_lba - pe->starting_lba + 1); ploop_log(3, "update partition table start=%llu length=%llu", part.start, part.length); ioctl_arg.op = BLKPG_RESIZE_PARTITION; ioctl_arg.flags = 0; ioctl_arg.datalen = sizeof(struct blkpg_partition); ioctl_arg.data = ∂ return ioctl_device(fd, BLKPG, &ioctl_arg); }
int tdsp_download_dsp_code(unsigned long serialno) { debug("call the function: tdsp_download_dsp_code(%ld)\n ", serialno); // return TRUE; int fd; fd = open_device(TDSP_BUS_DEVICE_NAME); if (fd == -1) { printf("open error"); return FALSE; } unsigned long dwioctlcode; if (serialno == TDSP_SERIAL_NO_BT) { dwioctlcode = TDSP_RELOAD_BT_CODE; } else if (serialno == TDSP_SERIAL_NO_WLAN) { dwioctlcode = TDSP_RELOAD_WLAN_CODE; } else if (serialno == TDSP_SERIAL_NO_COEXIST) { dwioctlcode = TDSP_RELOAD_COMBO_CODE; } else { debug("the serialno is incorrect !"); close_device(fd); return FALSE; } if (ioctl_device(fd, dwioctlcode, NULL) == -1) { debug("DOWNLOAD DSP CODE Failed"); close_device(fd); return FALSE; } usleep(200000); debug("Download DSP code success! \n"); close_device(fd); return TRUE; }
int set_hotkey_flag(unsigned long mode) { debug("call the function: set_hotkey_flag(%d)!\n", mode); int fd; fd = open_device(TDSP_BUS_DEVICE_NAME); if (fd == -1) { perror("open error"); return -1; } if (ioctl_device(fd, TDSP_SET_HOT_FLAG, &mode) == -1) { close_device(fd); perror("set_hotkey_flag: ioctl error"); return -1; } debug("set_hotkey_flag: success!\n"); close_device(fd); return 0; }
int write_enum_mode(unsigned long mode) { debug("call the function: tdsp_write_enum_mode(%d)!\n", mode); int fd; fd = open_device(TDSP_BUS_DEVICE_NAME); if (fd == -1) { perror("open error"); return -1; } if (ioctl_device(fd, TDSP_WRITE_ENUM_MODE, &mode) == -1) { close_device(fd); perror("tdsp_write_enum_mode: ioctl error"); return -1; } debug("tdsp_ write_enum_mode: success\n"); close_device(fd); return 0; }
void tdsp_power_off() { int fd; fd = open_device(TDSP_BUS_DEVICE_NAME); if (fd == -1) { perror("open error"); return; } debug("tdsp_bus_power_off ... wait ...\n"); if (ioctl_device(fd, TDSP_POWER_OFF, NULL) == -1) { close_device(fd); perror("tdsp_power_off: ioctl error "); return; } debug("tdsp_power_off: success\n"); close_device(fd); return; }
int tdsp_write_eeprom(unsigned long uloffset, unsigned long ullength, char *chbuf) { debug ("call the function: tdsp_write_eeprom( offset=%ld,length=%ld,buf=\"%s\")\n", uloffset, ullength, chbuf); int fd; int bytes; PLOAD_EEPROM_STRUC peeprom; fd = open_device(TDSP_BUS_DEVICE_NAME); if (fd == -1) { perror("open error"); return FALSE; } peeprom = (PLOAD_EEPROM_STRUC) malloc(bytes = (sizeof(LOAD_EEPROM_STRUC) + ullength)); if (peeprom == NULL) { debug("tdsp_write_eeprom: malloc peeprom error\n"); close_device(fd); return FALSE; } peeprom->offset = uloffset; peeprom->length = ullength; memcpy(peeprom->buf, chbuf, ullength); debug("the peeprom: peeprom->offse=%d,tpeeprom->length=%ld,peeprom->buf=%s\n", peeprom->offset, peeprom->length, peeprom->buf); if (ioctl_device(fd, TDSP_WRITE_EEPROM, peeprom) == -1) { free(peeprom); close_device(fd); perror("tdsp_write_eeprom: ioctl error"); return FALSE; } free(peeprom); close_device(fd); return TRUE; }
int tdsp_set_init_flag(unsigned long mode) { debug("call the function:tdsp_set_init_flag( %ld)\n", mode); int fd; int ret = mode; fd = open_device(TDSP_BUS_DEVICE_NAME); if (fd == -1) { perror("openerror"); return FALSE; } if (ioctl_device(fd, TDSP_SET_INIT_FLAG, &ret) == -1) { close_device(fd); perror("ioctlerror"); return FALSE; } close_device(fd); debug("\ttdsp_set_init_flag success\n"); return TRUE; }
int read_enum_mode() { int fd; unsigned long ret; debug("call the function: read_enum_mode \n"); fd = open_device(TDSP_BUS_DEVICE_NAME); if (fd == -1) { perror("open error"); return -1; } if (ioctl_device(fd, TDSP_READ_ENUM_MODE, &ret) != 0) { close_device(fd); perror("ioctl error"); return -1; } debug("get read_enum_mode is: ret = 0x%x\n", ret); close_device(fd); g_rawenummode = ret; return ret; }
/*plugin device, when success, it return the device's serialno, when failure, return TDSP_SERIAL_NOCARD 0X10000*/ int tdsp_add_device(char *devicename, unsigned long namelen, unsigned long serialno) { int fd; int bytes; PBUSENUM_PLUGIN_HARDWARE hardware; debug("call the function: tdsp_add_device(%s, %ld, %ld)!\n", devicename, namelen, serialno); fd = open_device(TDSP_BUS_DEVICE_NAME); if (fd == -1) { perror("open error"); return TDSP_SERIAL_NO_NOCARD; } hardware = (PBUSENUM_PLUGIN_HARDWARE) malloc(bytes = (sizeof(BUSENUM_PLUGIN_HARDWARE) + namelen)); if (hardware == NULL) { debug("tdsp_add_device: malloc hardware error\n"); close_device(fd); return TDSP_SERIAL_NO_NOCARD; } hardware->Size = sizeof(BUSENUM_PLUGIN_HARDWARE); hardware->SerialNo = serialno; memcpy(hardware->HardwareIDs, devicename, namelen); // debug ("tdsp_add_device: namelen = %d, total len = %d, the serialno is:%d\n", namelen, bytes,serialno); if (ioctl_device(fd, TDSP_PLUGIN, hardware) == -1) { free(hardware); close_device(fd); perror("tdsp_add_device: ioctl error"); return TDSP_SERIAL_NO_NOCARD; } debug("tdsp_add_device: success!the serialno is %d\n", serialno); free(hardware); close_device(fd); return serialno; }
static int freeze_fs(struct ploop_copy_handle *h) { int ret; if (h->mntfd != -1) { /* Sync fs */ ploop_log(0, "Freezing fs..."); if (sys_syncfs(h->mntfd)) { ploop_err(errno, "syncfs() failed"); return SYSEXIT_FSYNC; } /* Flush journal and freeze fs (this also clears the fs dirty bit) */ ploop_dbg(3, "FIFREEZE"); ret = ioctl_device(h->mntfd, FIFREEZE, 0); if (ret) return ret; h->fs_frozen = 1; } return 0; }
int tdsp_download_dsp_code_from_file(unsigned long serialno) { debug("call the function: tdsp_download_dsp_code_from_file(%ld)\n ", serialno); // return TRUE; int fd; fd = open_device(TDSP_BUS_DEVICE_NAME); if (fd == -1) { printf("open error"); close_device(fd); return FALSE; } if (ioctl_device(fd, TDSP_RELOAD_CODE_FROM_FILE, &serialno) == -1) { debug("DOWNLOAD DSP CODE FROM FILE Failed\n"); close_device(fd); return FALSE; } usleep(200000); debug("Download DSP code from file success! \n"); close_device(fd); return TRUE; }
int tdsp_query_pnp_state(unsigned long mode) { debug("call the function: tdsp_query_pnp_state(%ld) \n", mode); int fd; int ret = mode; g_dsppnpstate = UnKnown; fd = open_device(TDSP_BUS_DEVICE_NAME); if (fd == -1) { perror("openerror"); return 4; } if (ioctl_device(fd, TDSP_QUERY_DEVICE_STATE, &ret) == -1) { close_device(fd); perror("ioctlerror"); return 4; } close_device(fd); g_dsppnpstate = (DEVICE_PNP_STATE) ret; debug("tdsp_query_pnp_state success: g_dsppnpstate = 0x%x\n", ret); return ret; }
int ploop_balloon_clear_state(const char *device) { int fd, ret; struct ploop_balloon_ctl b_ctl; fd = open_device(device); if (fd == -1) return SYSEXIT_OPEN; bzero(&b_ctl, sizeof(b_ctl)); ret = ioctl_device(fd, PLOOP_IOC_BALLOON, &b_ctl); if (ret) goto err; if (b_ctl.mntn_type != PLOOP_MNTN_OFF) { ploop_err(0, "Can't clear stale in-kernel \"BALLOON\" " "maintenance state because kernel is in \"%s\" " "state now", mntn2str(b_ctl.mntn_type)); ret = SYSEXIT_EBUSY; } err: close(fd); return ret; }
int ploop_balloon_check_and_repair(const char *device, const char *mount_point, int repair) { int ret, fd = -1; int balloonfd = -1; __u32 n_free_blocks; __u32 freezed_a_h; __u32 dev_start; /* /sys/block/ploop0/ploop0p1/start */ struct ploop_balloon_ctl b_ctl; struct stat st; struct pfiemap *pfiemap = NULL; struct freemap *freemap = NULL; struct freemap *rangemap = NULL; struct relocmap *relocmap = NULL; struct ploop_freeblks_ctl *freeblks = NULL; struct ploop_relocblks_ctl *relocblks= NULL; char *msg = repair ? "repair" : "check"; __u32 *reverse_map = NULL; __u32 reverse_map_len; int top_level; int entries_used; struct delta delta = {}; int drop_state = 0; ret = get_balloon(mount_point, &st, &balloonfd); if (ret) return ret; if (st.st_size == 0) { ploop_log(0, "Nothing to do: hidden balloon is empty"); close(balloonfd); return 0; } pfiemap = fiemap_alloc(128); freemap = freemap_alloc(128); rangemap = freemap_alloc(128); relocmap = relocmap_alloc(128); if (!pfiemap || !freemap || !rangemap || !relocmap) { ret = SYSEXIT_MALLOC; goto err; } fd = open_device(device); if (fd == -1) { ret = SYSEXIT_OPEN; goto err; } memset(&b_ctl, 0, sizeof(b_ctl)); /* block other maintenance ops even if we only check balloon */ b_ctl.inflate = 1; ret = ioctl_device(fd, PLOOP_IOC_BALLOON, &b_ctl); if (ret) goto err; switch (b_ctl.mntn_type) { case PLOOP_MNTN_BALLOON: drop_state = 1; ret = open_top_delta(device, &delta, &top_level); if (ret) goto err; reverse_map_len = delta.l2_size + delta.l2_size; reverse_map = alloc_reverse_map(reverse_map_len); if (reverse_map == NULL) { ret = SYSEXIT_MALLOC; goto err; } break; case PLOOP_MNTN_MERGE: case PLOOP_MNTN_GROW: case PLOOP_MNTN_TRACK: ploop_err(0, "Can't %s hidden balloon while another " "maintenance operation is in progress (%s)", msg, mntn2str(b_ctl.mntn_type)); ret = SYSEXIT_EBUSY; goto err; case PLOOP_MNTN_FBLOADED: case PLOOP_MNTN_RELOC: ploop_err(0, "Can't %s hidden balloon before previous " "balloon operation (%s) is completed. Use " "\"ploop-balloon complete\".", msg, mntn2str(b_ctl.mntn_type)); ret = SYSEXIT_EBUSY; goto err; case PLOOP_MNTN_OFF: ploop_err(0, "Error: mntn_type is PLOOP_MNTN_OFF after " "IOC_BALLOON"); ret = SYSEXIT_PROTOCOL; goto err; default: ploop_err(0, "Error: unknown mntn_type (%u)", b_ctl.mntn_type); ret = SYSEXIT_PROTOCOL; goto err; } if (dev_num2dev_start(device, st.st_dev, &dev_start)) { ploop_err(0, "Can't find out offset from start of ploop " "device (%s) to start of partition where fs (%s) " "resides", device, mount_point); ret = SYSEXIT_SYSFS; goto err; } ret = fiemap_get(balloonfd, S2B(dev_start), 0, st.st_size, &pfiemap); if (ret) goto err; fiemap_adjust(pfiemap, delta.blocksize); ret = fiemap_build_rmap(pfiemap, reverse_map, reverse_map_len, &delta); if (ret) goto err; ret = rmap2freemap(reverse_map, 0, reverse_map_len, &freemap, &entries_used); if (ret) goto err; if (entries_used == 0) { ploop_log(0, "No free blocks found"); goto err; } ret = freemap2freeblks(freemap, top_level, &freeblks, &n_free_blocks); if (ret) goto err; if (!repair) { ploop_log(0, "Found %u free blocks. Consider using " "\"ploop-balloon repair\"", n_free_blocks); ret = 0; goto err; } else { ploop_log(0, "Found %u free blocks", n_free_blocks); } ret = ioctl_device(fd, PLOOP_IOC_FREEBLKS, freeblks); if (ret) goto err; drop_state = 0; freezed_a_h = freeblks->alloc_head; if (freezed_a_h > reverse_map_len) { ploop_err(0, "Image corrupted: a_h=%u > rlen=%u", freezed_a_h, reverse_map_len); ret = SYSEXIT_PLOOPFMT; goto err; } ret = range_build(freezed_a_h, n_free_blocks, reverse_map, reverse_map_len, &delta, freemap, &rangemap, &relocmap); if (ret) goto err; ret = relocmap2relocblks(relocmap, top_level, freezed_a_h, n_free_blocks, &relocblks); if (ret) goto err; ret = ioctl_device(fd, PLOOP_IOC_RELOCBLKS, relocblks); if (ret) goto err; ploop_log(0, "TRUNCATED: %u cluster-blocks (%llu bytes)", relocblks->alloc_head, (unsigned long long)(relocblks->alloc_head * S2B(delta.blocksize))); err: if (drop_state) { memset(&b_ctl, 0, sizeof(b_ctl)); (void)ioctl_device(fd, PLOOP_IOC_BALLOON, &b_ctl); } // FIXME: close_delta() if (balloonfd >= 0) close(balloonfd); if (fd >= 0) close(fd); free(pfiemap); free(freemap); free(rangemap); free(relocmap); free(reverse_map); free(freeblks); free(relocblks); return ret; }
static int __ploop_discard(struct ploop_disk_images_data *di, int fd, const char *device, const char *mount_point, __u64 minlen_b, __u32 cluster, __u32 to_free, __u64 blk_discard_range[2], const int *stop) { pid_t tpid; int err = 0, ret, status; __u32 size = 0; struct ploop_cleanup_hook *h; if (blk_discard_range != NULL) ploop_log(0, "Discard %s start=%" PRIu64 " length=%" PRIu64, device, (uint64_t)blk_discard_range[0], (uint64_t)blk_discard_range[1]); else ploop_log(3, "Trying to find free extents bigger than %" PRIu64 " bytes", (uint64_t)minlen_b); if (ploop_lock_di(di)) return SYSEXIT_LOCK; ret = ioctl_device(fd, PLOOP_IOC_DISCARD_INIT, NULL); ploop_unlock_di(di); if (ret) { ploop_err(errno, "Can't initialize discard mode"); return ret; } tpid = fork(); if (tpid < 0) { ploop_err(errno, "Can't fork"); ret = ioctl_device(fd, PLOOP_IOC_DISCARD_FINI, NULL); if (ret) { ploop_err(errno, "Can't finalize discard mode"); return ret; } } h = register_cleanup_hook(cancel_discard, (void *) device); if (tpid == 0) { if (blk_discard_range != NULL) ret = blk_discard(fd, cluster, blk_discard_range[0], blk_discard_range[1]); else ret = ploop_trim(mount_point, minlen_b, cluster); if (ioctl_device(fd, PLOOP_IOC_DISCARD_FINI, NULL)) ploop_err(errno, "Can't finalize discard mode"); exit(ret != 0); } while (1) { struct ploop_balloon_ctl b_ctl; ploop_log(3, "Waiting"); ret = ioctl(fd, PLOOP_IOC_DISCARD_WAIT, NULL); if (ret < 0) { ploop_err(errno, "Waiting for a discard request failed"); break; } else if (ret == 0) break; /* FIXME PLOOP_IOC_DISCARD_WAIT should return size */ ret = ioctl(fd, PLOOP_IOC_FBFILTER, 0); if (ret < 0) { ploop_err(errno, "Can't filter free blocks"); break; } else if (ret == 0) { /* Nothing to do */ ret = ioctl_device(fd, PLOOP_IOC_FBDROP, 0); if (ret) break; continue; } else size += ret; /* serialize ploop operations vs ploop_complete_running_operation() * NB: PLOOP_IOC_BALLOON may change mntn from PLOOP_MNTN_DISCARD: * to PLOOP_MNTN_FBLOADED */ if (ploop_lock_di(di)) { ret = SYSEXIT_LOCK; break; } memset(&b_ctl, 0, sizeof(b_ctl)); b_ctl.keep_intact = 1; ret = ioctl_device(fd, PLOOP_IOC_BALLOON, &b_ctl); if (ret) { ploop_unlock_di(di); break; } if (b_ctl.mntn_type == PLOOP_MNTN_OFF) { ploop_log(0, "Unexpected maintenance type 0x%x", b_ctl.mntn_type); ret = -1; ploop_unlock_di(di); break; } if (size >= to_free || (stop && *stop)) { ploop_log(3, "Killing the trim process %d", tpid); kill(tpid, SIGUSR1); ret = ioctl(fd, PLOOP_IOC_DISCARD_FINI); if (ret < 0 && errno != EBUSY) ploop_err(errno, "Can't finalize a discard mode"); } ploop_log(0, "Starting relocation"); ret = ploop_balloon_relocation(fd, &b_ctl, device); ploop_unlock_di(di); if (ret) break; } if (ret) { err = -1; ret = ioctl(fd, PLOOP_IOC_DISCARD_FINI); if (ret < 0) { if (errno == EBUSY) ploop_log(-1, "Discard finalized, but " "relocation is still not completed"); else ploop_err(errno, "Can't finalize discard mode"); } kill(tpid, SIGKILL); } else { ploop_log(0, "%d clusters have been relocated", size); } unregister_cleanup_hook(h); while ((ret = waitpid(tpid, &status, 0))) if (errno != EINTR) break; if (ret == -1) { if (errno != ECHILD) ploop_err(errno, "wait() failed"); err = -1; } else if (WIFEXITED(status)) { ret = WEXITSTATUS(status); if (ret) { ploop_err(0, "The trim process failed with code %d", ret); err = -1; } } else if (WIFSIGNALED(status)) { ploop_err(0, "The trim process killed by signal %d", WTERMSIG(status)); err = -1; } else { ploop_err(0, "The trim process died abnormally"); err = -1; } return err; }
int get_tdsp_version(PTDSPVERSION ver) { int fd; unsigned char verinfo[64]; debug("call the function: get_tdsp_version ()\n"); fd = open_device(TDSP_BUS_DEVICE_NAME); if (fd == -1) { perror("open error"); return -1; } int bsuccess; bsuccess = FALSE; if (ver->pos[0] == 1) { long serial = 1; memset(verinfo, '\0', 64); memcpy(verinfo, &serial, sizeof(serial)); if (ioctl_device(fd, TDSP_QUERY_DEVICE_VERSION, &verinfo) == -1) { close_device(fd); ver->pos[0] = 0; perror("ioctl error"); return -1; } else { strcpy((char *) ver->btver, (char *) verinfo); } } if (ver->pos[1] == 1) { long serial = 2; memset(verinfo, '\0', 64); memcpy(verinfo, &serial, sizeof(serial)); if (ioctl_device(fd, TDSP_QUERY_DEVICE_VERSION, &verinfo) == -1) { close_device(fd); ver->pos[1] = 0; perror("ioctl error"); return -1; } else { strcpy((char *) ver->wlanver, (char *) verinfo); } } if (ver->pos[2] == 1) { memset(verinfo, '\0', 64); if (ioctl_device(fd, TDSP_QUERY_BUS_VERSION, &verinfo) == -1) { close_device(fd); ver->pos[2] = 0; perror("ioctl error"); return -1; } else { strcpy((char *) ver->busver, (char *) verinfo); } } if (ver->pos[3] == 1) { unsigned long verinfo1; if (ioctl_device(fd, TDSP_QUERY_FIRMWARE_VERSION, &verinfo1) == -1) { close_device(fd); ver->pos[3] = 0; perror("ioctl error"); return -1; } else { ver->firmwarever = verinfo1; } } if (ver->pos[4] == 1) { unsigned long verinfo2; if (ioctl_device(fd, TDSP_QUERY_8051_VERSION, &verinfo2) == -1) { close_device(fd); ver->pos[4] = 0; perror("ioctl error"); return -1; } else { ver->ver8051= verinfo2; } } close_device(fd); return TRUE; }
int ploop_balloon_change_size(const char *device, int balloonfd, off_t new_size) { int fd = -1; int ret; off_t old_size; __u32 dev_start; /* /sys/block/ploop0/ploop0p1/start */ __u32 n_free_blocks; __u32 freezed_a_h; struct ploop_balloon_ctl b_ctl; struct stat st; struct pfiemap *pfiemap = NULL; struct freemap *freemap = NULL; struct freemap *rangemap = NULL; struct relocmap *relocmap = NULL; struct ploop_freeblks_ctl *freeblks = NULL; struct ploop_relocblks_ctl *relocblks = NULL; __u32 *reverse_map = NULL; __u32 reverse_map_len; int top_level; struct delta delta = { .fd = -1 }; int entries_used; int drop_state = 0; if (fstat(balloonfd, &st)) { ploop_err(errno, "Can't get balloon file size"); return SYSEXIT_FSTAT; } old_size = st.st_size; new_size = (S2B(new_size) + st.st_blksize - 1) & ~(st.st_blksize - 1); ploop_log(0, "Changing balloon size old_size=%ld new_size=%ld", (long)old_size, (long)new_size); pfiemap = fiemap_alloc(128); freemap = freemap_alloc(128); rangemap = freemap_alloc(128); relocmap = relocmap_alloc(128); if (!pfiemap || !freemap || !rangemap || !relocmap) { ret = SYSEXIT_MALLOC; goto err; } fd = open_device(device); if (fd == -1) { ret = SYSEXIT_OPEN; goto err; } memset(&b_ctl, 0, sizeof(b_ctl)); if (old_size < new_size) b_ctl.inflate = 1; ret = ioctl_device(fd, PLOOP_IOC_BALLOON, &b_ctl); if (ret) goto err; drop_state = 1; if (old_size >= new_size) { ret = do_truncate(balloonfd, b_ctl.mntn_type, old_size, new_size); goto err; } if (dev_num2dev_start(device, st.st_dev, &dev_start)) { ploop_err(0, "Can't find out offset from start of ploop " "device (%s) to start of partition", device); ret = SYSEXIT_SYSFS; goto err; } ret = open_top_delta(device, &delta, &top_level); if (ret) goto err; ret = do_inflate(balloonfd, b_ctl.mntn_type, old_size, &new_size, &drop_state); if (ret) goto err; reverse_map_len = delta.l2_size + delta.l2_size; reverse_map = alloc_reverse_map(reverse_map_len); if (reverse_map == NULL) { ret = SYSEXIT_MALLOC; goto err; } ret = fiemap_get(balloonfd, S2B(dev_start), old_size, new_size, &pfiemap); if (ret) goto err; fiemap_adjust(pfiemap, delta.blocksize); ret = fiemap_build_rmap(pfiemap, reverse_map, reverse_map_len, &delta); if (ret) goto err; ret = rmap2freemap(reverse_map, 0, reverse_map_len, &freemap, &entries_used); if (ret) goto err; if (entries_used == 0) { drop_state = 1; ploop_log(0, "No unused cluster blocks found"); goto out; } ret = freemap2freeblks(freemap, top_level, &freeblks, &n_free_blocks); if (ret) goto err; ret = ioctl_device(fd, PLOOP_IOC_FREEBLKS, freeblks); if (ret) goto err; freezed_a_h = freeblks->alloc_head; if (freezed_a_h > reverse_map_len) { ploop_err(0, "Image corrupted: a_h=%u > rlen=%u", freezed_a_h, reverse_map_len); ret = SYSEXIT_PLOOPFMT; goto err; } ret = range_build(freezed_a_h, n_free_blocks, reverse_map, reverse_map_len, &delta, freemap, &rangemap, &relocmap); if (ret) goto err; ret = relocmap2relocblks(relocmap, top_level, freezed_a_h, n_free_blocks, &relocblks); if (ret) goto err; ret = ioctl_device(fd, PLOOP_IOC_RELOCBLKS, relocblks); if (ret) goto err; ploop_log(0, "TRUNCATED: %u cluster-blocks (%llu bytes)", relocblks->alloc_head, (unsigned long long)(relocblks->alloc_head * S2B(delta.blocksize))); out: ret = 0; err: if (drop_state) { memset(&b_ctl, 0, sizeof(b_ctl)); (void)ioctl_device(fd, PLOOP_IOC_BALLOON, &b_ctl); } if (fd != -1) close(fd); free(pfiemap); free(freemap); free(rangemap); free(relocmap); free(reverse_map); free(freeblks); free(relocblks); if (delta.fd != -1) close_delta(&delta); return ret; } int ploop_balloon_get_state(const char *device, __u32 *state) { int fd, ret; struct ploop_balloon_ctl b_ctl; fd = open_device(device); if (fd == -1) return SYSEXIT_OPEN; bzero(&b_ctl, sizeof(b_ctl)); b_ctl.keep_intact = 1; ret = ioctl_device(fd, PLOOP_IOC_BALLOON, &b_ctl); if (ret) goto err; *state = b_ctl.mntn_type; err: close(fd); return ret; }
static int ploop_balloon_relocation(int fd, struct ploop_balloon_ctl *b_ctl, const char *device) { int ret = -1; __u32 n_free_blocks = 0; __u32 freezed_a_h; struct freemap *freemap = NULL; struct freemap *rangemap = NULL; struct relocmap *relocmap = NULL; struct ploop_freeblks_ctl *freeblks = NULL; struct ploop_relocblks_ctl *relocblks = NULL;; __u32 *reverse_map = NULL; __u32 reverse_map_len; int top_level; struct delta delta = {}; freemap = freemap_alloc(128); rangemap = freemap_alloc(128); relocmap = relocmap_alloc(128); if (freemap == NULL || rangemap == NULL || relocmap == NULL) { ret = SYSEXIT_MALLOC; goto err; } top_level = b_ctl->level; freezed_a_h = b_ctl->alloc_head; if (b_ctl->mntn_type == PLOOP_MNTN_RELOC) goto reloc; if (b_ctl->mntn_type != PLOOP_MNTN_FBLOADED) { ploop_err(0, "Error: non-suitable mntn_type (%u)", b_ctl->mntn_type); ret = SYSEXIT_PROTOCOL; goto err; } ret = freeblks_alloc(&freeblks, 0); if (ret) goto err; ret = ioctl_device(fd, PLOOP_IOC_FBGET, freeblks); if (ret) goto err; if (freeblks->n_extents == 0) goto reloc; ret = freeblks_alloc(&freeblks, freeblks->n_extents); if (ret) goto err; ret = ioctl_device(fd, PLOOP_IOC_FBGET, freeblks); if (ret) goto err; ret = freeblks2freemap(freeblks, &freemap, &n_free_blocks); if (ret) goto err; ret = open_top_delta(device, &delta, &top_level); if (ret) goto err; reverse_map_len = delta.l2_size + delta.l2_size; reverse_map = alloc_reverse_map(reverse_map_len); if (reverse_map == NULL) { close_delta(&delta); ret = SYSEXIT_MALLOC; goto err; } ret = range_build(freezed_a_h, n_free_blocks, reverse_map, reverse_map_len, &delta, freemap, &rangemap, &relocmap); close_delta(&delta); if (ret) goto err; reloc: ret = relocmap2relocblks(relocmap, top_level, freezed_a_h, n_free_blocks, &relocblks); if (ret) goto err; ret = ioctl_device(fd, PLOOP_IOC_RELOCBLKS, relocblks); if (ret) goto err; ploop_log(0, "TRUNCATED: %u cluster-blocks (%llu bytes)", relocblks->alloc_head, (unsigned long long)(relocblks->alloc_head * S2B(delta.blocksize))); err: free(freemap); free(rangemap); free(relocmap); free(reverse_map); free(freeblks); free(relocblks); return ret; }