- glob_t glob_info;
- struct stat stat_buf;
- char *chk_major, *chk_minor;
- char *savept, *dev;
- char *ret_path;
- char buf[PATH_MAX] = {'\0'}, path[PATH_MAX] = {'\0'};
- char real_path[PATH_MAX] = {'\0'};
- int i, rc = 0;
- int major, minor;
-
- if (!source)
- return -EINVAL;
-
- ret_path = realpath(source, real_path);
- if (ret_path == NULL) {
- if (verbose)
- fprintf(stderr, "warning: %s: cannot resolve: %s\n",
- source, strerror(errno));
- return -EINVAL;
- }
-
- src_len = sizeof(real_path);
-
- if (strncmp(real_path, "/dev/loop", 9) == 0)
- return 0;
-
- if ((real_path[0] != '/') && (strpbrk(real_path, ",:") != NULL))
- return 0;
-
- dev = real_path + src_len - 1;
- while (dev > real_path && (*dev != '/')) {
- if (isdigit(*dev))
- *dev = 0;
- dev--;
- }
- snprintf(path, sizeof(path), "/sys/block%s/%s", dev,
- MAX_HW_SECTORS_KB_PATH);
- rc = read_file(path, buf, sizeof(buf));
- if (rc == 0 && (strlen(buf) - 1) > 0) {
- snprintf(path, sizeof(path), "/sys/block%s/%s", dev,
- MAX_SECTORS_KB_PATH);
- rc = write_file(path, buf);
- if (rc && verbose)
- fprintf(stderr, "warning: opening %s: %s\n",
- path, strerror(errno));
- return rc;
- }
-
- if (rc != ENOENT)
- return rc;
-
- /* The name of the device say 'X' specified in /dev/X may not
- * match any entry under /sys/block/. In that case we need to
- * match the major/minor number to find the entry under
- * sys/block corresponding to /dev/X */
- dev = real_path + src_len - 1;
- while (dev > real_path) {
- if (isdigit(*dev))
- *dev = 0;
- dev--;
- }
-
- rc = stat(dev, &stat_buf);
- if (rc) {
- if (verbose)
- fprintf(stderr, "warning: %s, device %s stat failed\n",
- strerror(errno), dev);
- return rc;
- }
-
- major = major(stat_buf.st_rdev);
- minor = minor(stat_buf.st_rdev);
- rc = glob("/sys/block/*", GLOB_NOSORT, NULL, &glob_info);
- if (rc) {
- if (verbose)
- fprintf(stderr, "warning: failed to read entries under "
- "/sys/block\n");
- return rc;
- }
-
- for (i = 0; i < glob_info.gl_pathc; i++){
- snprintf(path, sizeof(path), "%s/dev", glob_info.gl_pathv[i]);
-
- rc = read_file(path, buf, sizeof(buf));
- if (rc)
- continue;
-
- if (buf[strlen(buf) - 1] == '\n')
- buf[strlen(buf) - 1] = '\0';
-
- chk_major = strtok_r(buf, ":", &savept);
- chk_minor = savept;
- if (major == atoi(chk_major) &&minor == atoi(chk_minor))
- break;
- }
-
- if (i == glob_info.gl_pathc) {
- if (verbose)
- fprintf(stderr,"warning: device %s does not match any "
- "entry under /sys/block\n", real_path);
- rc = -EINVAL;
- goto out;
- }
-
- snprintf(path, sizeof(path), "%s/%s", glob_info.gl_pathv[i],
- MAX_HW_SECTORS_KB_PATH);
- rc = read_file(path, buf, sizeof(buf));
- if (rc) {
- if (verbose)
- fprintf(stderr, "warning: opening %s: %s\n",
- path, strerror(errno));
- goto out;
- }
-
- if (strlen(buf) - 1 > 0) {
- snprintf(path, sizeof(path), "%s/%s",
- glob_info.gl_pathv[i], MAX_SECTORS_KB_PATH);
- rc = write_file(path, buf);
- if (rc && verbose)
- fprintf(stderr, "warning: writing to %s: %s\n",
- path, strerror(errno));
- }