?? device.c
字號:
int err; err = ntfs_mst_pre_write_fixup((NTFS_RECORD*) ((u8*)b + i * bksize), bksize); if (err < 0) { /* Abort write at this position. */ if (!i) return err; count = i; break; } } /* Write the prepared data. */ written = ntfs_pwrite(dev, pos, count * bksize, b); /* Quickly deprotect the data again. */ for (i = 0; i < count; ++i) ntfs_mst_post_write_fixup((NTFS_RECORD*)((u8*)b + i * bksize)); if (written <= 0) return written; /* Finally, return the number of complete blocks written. */ return written / bksize;}/** * ntfs_cluster_read - read ntfs clusters * @vol: volume to read from * @lcn: starting logical cluster number * @count: number of clusters to read * @b: output data buffer * * Read @count ntfs clusters starting at logical cluster number @lcn from * volume @vol into buffer @b. Return number of clusters read or -1 on error, * with errno set to the error code. */s64 ntfs_cluster_read(const ntfs_volume *vol, const s64 lcn, const s64 count, void *b){ s64 br; if (!vol || lcn < 0 || count < 0) { errno = EINVAL; return -1; } if (vol->nr_clusters < lcn + count) { errno = ESPIPE; ntfs_log_perror("Trying to read outside of volume " "(%lld < %lld)", (long long)vol->nr_clusters, (long long)lcn + count); return -1; } br = ntfs_pread(vol->dev, lcn << vol->cluster_size_bits, count << vol->cluster_size_bits, b); if (br < 0) { ntfs_log_perror("Error reading cluster(s)"); return br; } return br >> vol->cluster_size_bits;}/** * ntfs_cluster_write - write ntfs clusters * @vol: volume to write to * @lcn: starting logical cluster number * @count: number of clusters to write * @b: data buffer to write to disk * * Write @count ntfs clusters starting at logical cluster number @lcn from * buffer @b to volume @vol. Return the number of clusters written or -1 on * error, with errno set to the error code. */s64 ntfs_cluster_write(const ntfs_volume *vol, const s64 lcn, const s64 count, const void *b){ s64 bw; if (!vol || lcn < 0 || count < 0) { errno = EINVAL; return -1; } if (vol->nr_clusters < lcn + count) { errno = ESPIPE; ntfs_log_perror("Trying to write outside of volume " "(%lld < %lld)", (long long)vol->nr_clusters, (long long)lcn + count); return -1; } if (!NVolReadOnly(vol)) bw = ntfs_pwrite(vol->dev, lcn << vol->cluster_size_bits, count << vol->cluster_size_bits, b); else bw = count << vol->cluster_size_bits; if (bw < 0) { ntfs_log_perror("Error writing cluster(s)"); return bw; } return bw >> vol->cluster_size_bits;}/** * ntfs_device_offset_valid - test if a device offset is valid * @dev: open device * @ofs: offset to test for validity * * Test if the offset @ofs is an existing location on the device described * by the open device structure @dev. * * Return 0 if it is valid and -1 if it is not valid. */static int ntfs_device_offset_valid(struct ntfs_device *dev, s64 ofs){ char ch; if (dev->d_ops->seek(dev, ofs, SEEK_SET) >= 0 && dev->d_ops->read(dev, &ch, 1) == 1) return 0; return -1;}/** * ntfs_device_size_get - return the size of a device in blocks * @dev: open device * @block_size: block size in bytes in which to return the result * * Return the number of @block_size sized blocks in the device described by the * open device @dev. * * Adapted from e2fsutils-1.19, Copyright (C) 1995 Theodore Ts'o. * * On error return -1 with errno set to the error code. */s64 ntfs_device_size_get(struct ntfs_device *dev, int block_size){ s64 high, low; if (!dev || block_size <= 0 || (block_size - 1) & block_size) { errno = EINVAL; return -1; }#ifdef BLKGETSIZE64 { u64 size; if (dev->d_ops->ioctl(dev, BLKGETSIZE64, &size) >= 0) { ntfs_log_debug("BLKGETSIZE64 nr bytes = %llu (0x%llx)\n", (unsigned long long)size, (unsigned long long)size); return (s64)size / block_size; } }#endif#ifdef BLKGETSIZE { unsigned long size; if (dev->d_ops->ioctl(dev, BLKGETSIZE, &size) >= 0) { ntfs_log_debug("BLKGETSIZE nr 512 byte blocks = %lu (0x%lx)\n", size, size); return (s64)size * 512 / block_size; } }#endif#ifdef FDGETPRM { struct floppy_struct this_floppy; if (dev->d_ops->ioctl(dev, FDGETPRM, &this_floppy) >= 0) { ntfs_log_debug("FDGETPRM nr 512 byte blocks = %lu (0x%lx)\n", (unsigned long)this_floppy.size, (unsigned long)this_floppy.size); return (s64)this_floppy.size * 512 / block_size; } }#endif /* * We couldn't figure it out by using a specialized ioctl, * so do binary search to find the size of the device. */ low = 0LL; for (high = 1024LL; !ntfs_device_offset_valid(dev, high); high <<= 1) low = high; while (low < high - 1LL) { const s64 mid = (low + high) / 2; if (!ntfs_device_offset_valid(dev, mid)) low = mid; else high = mid; } dev->d_ops->seek(dev, 0LL, SEEK_SET); return (low + 1LL) / block_size;}/** * ntfs_device_partition_start_sector_get - get starting sector of a partition * @dev: open device * * On success, return the starting sector of the partition @dev in the parent * block device of @dev. On error return -1 with errno set to the error code. * * The following error codes are defined: * EINVAL Input parameter error * EOPNOTSUPP System does not support HDIO_GETGEO ioctl * ENOTTY @dev is a file or a device not supporting HDIO_GETGEO */s64 ntfs_device_partition_start_sector_get(struct ntfs_device *dev){ if (!dev) { errno = EINVAL; return -1; }#ifdef HDIO_GETGEO { struct hd_geometry geo; if (!dev->d_ops->ioctl(dev, HDIO_GETGEO, &geo)) { ntfs_log_debug("HDIO_GETGEO start_sect = %lu (0x%lx)\n", geo.start, geo.start); return geo.start; } }#else errno = EOPNOTSUPP;#endif return -1;}/** * ntfs_device_heads_get - get number of heads of device * @dev: open device * * On success, return the number of heads on the device @dev. On error return * -1 with errno set to the error code. * * The following error codes are defined: * EINVAL Input parameter error * EOPNOTSUPP System does not support HDIO_GETGEO ioctl * ENOTTY @dev is a file or a device not supporting HDIO_GETGEO */int ntfs_device_heads_get(struct ntfs_device *dev){ if (!dev) { errno = EINVAL; return -1; }#ifdef HDIO_GETGEO { struct hd_geometry geo; if (!dev->d_ops->ioctl(dev, HDIO_GETGEO, &geo)) { ntfs_log_debug("HDIO_GETGEO heads = %u (0x%x)\n", (unsigned)geo.heads, (unsigned)geo.heads); return geo.heads; } }#else errno = EOPNOTSUPP;#endif return -1;}/** * ntfs_device_sectors_per_track_get - get number of sectors per track of device * @dev: open device * * On success, return the number of sectors per track on the device @dev. On * error return -1 with errno set to the error code. * * The following error codes are defined: * EINVAL Input parameter error * EOPNOTSUPP System does not support HDIO_GETGEO ioctl * ENOTTY @dev is a file or a device not supporting HDIO_GETGEO */int ntfs_device_sectors_per_track_get(struct ntfs_device *dev){ if (!dev) { errno = EINVAL; return -1; }#ifdef HDIO_GETGEO { struct hd_geometry geo; if (!dev->d_ops->ioctl(dev, HDIO_GETGEO, &geo)) { ntfs_log_debug("HDIO_GETGEO sectors_per_track = %u (0x%x)\n", (unsigned)geo.sectors, (unsigned)geo.sectors); return geo.sectors; } }#else errno = EOPNOTSUPP;#endif return -1;}/** * ntfs_device_sector_size_get - get sector size of a device * @dev: open device * * On success, return the sector size in bytes of the device @dev. * On error return -1 with errno set to the error code. * * The following error codes are defined: * EINVAL Input parameter error * EOPNOTSUPP System does not support BLKSSZGET ioctl * ENOTTY @dev is a file or a device not supporting BLKSSZGET */int ntfs_device_sector_size_get(struct ntfs_device *dev){ if (!dev) { errno = EINVAL; return -1; }#ifdef BLKSSZGET { int sect_size = 0; if (!dev->d_ops->ioctl(dev, BLKSSZGET, §_size)) { ntfs_log_debug("BLKSSZGET sector size = %d bytes\n", sect_size); return sect_size; } }#else errno = EOPNOTSUPP;#endif return -1;}/** * ntfs_device_block_size_set - set block size of a device * @dev: open device * @block_size: block size to set @dev to * * On success, return 0. * On error return -1 with errno set to the error code. * * The following error codes are defined: * EINVAL Input parameter error * EOPNOTSUPP System does not support BLKBSZSET ioctl * ENOTTY @dev is a file or a device not supporting BLKBSZSET */int ntfs_device_block_size_set(struct ntfs_device *dev, int block_size __attribute__((unused))){ if (!dev) { errno = EINVAL; return -1; }#ifdef BLKBSZSET { size_t s_block_size = block_size; if (!dev->d_ops->ioctl(dev, BLKBSZSET, &s_block_size)) { ntfs_log_debug("Used BLKBSZSET to set block size to " "%d bytes.\n", block_size); return 0; } /* If not a block device, pretend it was successful. */ if (!NDevBlock(dev)) return 0; }#else /* If not a block device, pretend it was successful. */ if (!NDevBlock(dev)) return 0; errno = EOPNOTSUPP;#endif return -1;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -