http://linux-ntfs.sourceforge.net/snapshots/ntfsprogs-200307311516.tar.bz2
[ntfsprogs.git] / libntfs / disk_io.c
1 /*
2  * disk_io.c - Disk io functions. Part of the Linux-NTFS project.
3  *
4  * Copyright (c) 2000-2003 Anton Altaparmakov
5  *
6  * This program/include file is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as published
8  * by the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program/include file is distributed in the hope that it will be
12  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program (in the main directory of the Linux-NTFS
18  * distribution in the file COPYING); if not, write to the Free Software
19  * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include "config.h"
23
24 #include <unistd.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <errno.h>
28 #include <stdio.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <fcntl.h>
32 #include <sys/ioctl.h>
33 #ifdef HAVE_LINUX_FD_H
34 #       include <linux/fd.h>
35 #endif
36
37 #include "types.h"
38 #include "disk_io.h"
39 #include "mst.h"
40 #include "debug.h"
41 #include "device.h"
42
43 #if defined(linux) && defined(_IO) && !defined(BLKGETSIZE)
44 #       define BLKGETSIZE _IO(0x12,96) /* Get device size in 512byte blocks. */
45 #endif
46
47 /**
48  * ntfs_pread - positioned read from disk
49  * @dev:        device to read from
50  * @pos:        position in device to read from
51  * @count:      number of bytes to read
52  * @b:          output data buffer
53  *
54  * This function will read @count bytes from device @dev at position @pos into
55  * the data buffer @b.
56  *
57  * On success, return the number of successfully read bytes. If this number is
58  * lower than @count this means that we have either reached end of file or
59  * encountered an error during the read so that the read is partial. 0 means
60  * end of file or nothing to read (@count is 0).
61  *
62  * On error and nothing has been read, return -1 with errno set appropriately
63  * to the return code of either seek, read, or set to EINVAL in case of
64  * invalid arguments.
65  */
66 s64 ntfs_pread(struct ntfs_device *dev, const s64 pos, s64 count, void *b)
67 {
68         s64 br, total;
69         struct ntfs_device_operations *dops;
70
71         Dprintf("%s(): Entering for pos 0x%Lx, count 0x%Lx.\n", __FUNCTION__,
72                         pos, count);
73         if (!b || count < 0 || pos < 0) {
74                 errno = EINVAL;
75                 return -1;
76         }
77         if (!count)
78                 return 0;
79         dops = dev->d_ops;
80         /* Locate to position. */
81         if (dops->seek(dev, pos, SEEK_SET) == (off_t)-1) {
82                 Dprintf("ntfs_pread: device seek to 0x%Lx returned error: "
83                                 "%s\n", pos, strerror(errno));
84                 return -1;
85         }
86         /* Read the data. */
87         for (total = 0; count; count -= br, total += br) {
88                 br = dops->read(dev, (char*)b + total, count);
89                 /* If everything ok, continue. */
90                 if (br > 0)
91                         continue;
92                 /* If EOF or error return number of bytes read. */
93                 if (!br || total)
94                         return total;
95                 /* Nothing read and error, return error status. */
96                 return br;
97         }
98         /* Finally, return the number of bytes read. */
99         return total;
100 }
101
102 /**
103  * ntfs_pwrite - positioned write to disk
104  * @dev:        device to write to
105  * @pos:        position in file descriptor to write to
106  * @count:      number of bytes to write
107  * @b:          data buffer to write to disk
108  *
109  * This function will write @count bytes from data buffer @b to the device @dev
110  * at position @pos.
111  *
112  * On success, return the number of successfully written bytes. If this number
113  * is lower than @count this means that the write has been interrupted in
114  * flight or that an error was encountered during the write so that the write
115  * is partial. 0 means nothing was written (also return 0 when @count is 0).
116  *
117  * On error and nothing has been written, return -1 with errno set
118  * appropriately to the return code of either seek, write, or set
119  * to EINVAL in case of invalid arguments.
120  */
121 s64 ntfs_pwrite(struct ntfs_device *dev, const s64 pos, s64 count,
122                 const void *b)
123 {
124         s64 written, total;
125         struct ntfs_device_operations *dops;
126
127         Dprintf("%s(): Entering for pos 0x%Lx, count 0x%Lx.\n", __FUNCTION__,
128                         pos, count);
129         if (!b || count < 0 || pos < 0) {
130                 errno = EINVAL;
131                 return -1;
132         }
133         if (!count)
134                 return 0;
135         if (NDevReadOnly(dev)) {
136                 errno = EROFS;
137                 return -1;
138         }
139         dops = dev->d_ops;
140         /* Locate to position. */
141         if (dops->seek(dev, pos, SEEK_SET) == (off_t)-1) {
142                 Dprintf("ntfs_pwrite: seek to 0x%Lx returned error: %s\n",
143                                 pos, strerror(errno));
144                 return -1;
145         }
146         NDevSetDirty(dev);
147         /* Write the data. */
148         for (total = 0; count; count -= written, total += written) {
149                 written = dops->write(dev, (char*)b + total, count);
150                 /* If everything ok, continue. */
151                 if (written > 0)
152                         continue;
153                 /*
154                  * If nothing written or error return number of bytes written.
155                  */
156                 if (!written || total)
157                         break;
158                 /* Nothing written and error, return error status. */
159                 return written;
160         }
161         /* Finally, return the number of bytes written. */
162         return total;
163 }
164
165 static int ntfs_device_disk_io_open(struct ntfs_device *dev, int flags)
166 {
167         struct flock flk;
168
169         if (NDevOpen(dev)) {
170                 errno = EBUSY;
171                 return -1;
172         }
173         /* Open the device/file obtaining the file descriptor. */
174         if (((int)dev->d_private = open(dev->d_name, flags)) == -1)
175                 return -1;
176         /* Setup our read-only flag. */
177         if ((flags & O_RDWR) != O_RDWR)
178                 NDevSetReadOnly(dev);
179         /* Acquire exlusive (mandatory) lock on the whole device. */
180         memset(&flk, 0, sizeof(flk));
181         if (NDevReadOnly(dev))
182                 flk.l_type = F_RDLCK;
183         else
184                 flk.l_type = F_WRLCK;
185         flk.l_whence = SEEK_SET;
186         flk.l_start = flk.l_len = 0LL;
187         if (fcntl((int)dev->d_private, F_SETLK, &flk)) {
188                 int eo = errno;
189                 Dprintf("ntfs_device_disk_io_open: Could not lock %s for %s: "
190                                 "%s\n", dev->d_name, NDevReadOnly(dev) ?
191                                 "reading" : "writing", strerror(errno));
192                 if (close((int)dev->d_private))
193                         Dprintf("ntfs_device_disk_io_open: Warning: Could not "
194                                         "close %s: %s\n", dev->d_name,
195                                         strerror(errno));
196                 errno = eo;
197                 return -1;
198         }
199         /* Set our open flag. */
200         NDevSetOpen(dev);
201         return 0;
202 }
203
204 static int ntfs_device_disk_io_close(struct ntfs_device *dev)
205 {
206         struct flock flk;
207
208         if (!NDevOpen(dev)) {
209                 errno = EBADF;
210                 return -1;
211         }
212         if (NDevDirty(dev))
213                 fsync((int)dev->d_private);
214         /* Release exlusive (mandatory) lock on the whole device. */
215         memset(&flk, 0, sizeof(flk));
216         flk.l_type = F_UNLCK;
217         flk.l_whence = SEEK_SET;
218         flk.l_start = flk.l_len = 0LL;
219         if (fcntl((int)dev->d_private, F_SETLK, &flk))
220                 Dprintf("ntfs_device_disk_io_close: Warning: Could not unlock "
221                                 "%s: %s\n", dev->d_name, strerror(errno));
222         /* Close the file descriptor and clear our open flag. */
223         if (close((int)dev->d_private))
224                 return -1;
225         NDevClearOpen(dev);
226         return 0;
227 }
228
229 static s64 ntfs_device_disk_io_seek(struct ntfs_device *dev, s64 offset,
230                 int whence)
231 {
232         return lseek((int)dev->d_private, offset, whence);
233 }
234
235 static s64 ntfs_device_disk_io_read(struct ntfs_device *dev, void *buf,
236                 s64 count)
237 {
238         return read((int)dev->d_private, buf, count);
239 }
240
241 static s64 ntfs_device_disk_io_write(struct ntfs_device *dev, const void *buf,
242                 s64 count)
243 {
244         if (NDevReadOnly(dev)) {
245                 errno = EROFS;
246                 return -1;
247         }
248         NDevSetDirty(dev);
249         return write((int)dev->d_private, buf, count);
250 }
251
252 static s64 ntfs_device_disk_io_pread(struct ntfs_device *dev, void *buf,
253                 s64 count, s64 offset)
254 {
255         return ntfs_pread(dev, offset, count, buf);
256 }
257
258 static s64 ntfs_device_disk_io_pwrite(struct ntfs_device *dev, const void *buf,
259                 s64 count, s64 offset)
260 {
261         if (NDevReadOnly(dev)) {
262                 errno = EROFS;
263                 return -1;
264         }
265         NDevSetDirty(dev);
266         return ntfs_pwrite(dev, offset, count, buf);
267 }
268
269 static int ntfs_device_disk_io_sync(struct ntfs_device *dev)
270 {
271         if (!NDevReadOnly(dev) && NDevDirty(dev)) {
272                 int res = fsync((int)dev->d_private);
273                 if (!res)
274                         NDevClearDirty(dev);
275                 return res;
276         }
277         return 0;
278 }
279
280 static int ntfs_device_disk_io_stat(struct ntfs_device *dev, struct stat *buf)
281 {
282         return fstat((int)dev->d_private, buf);
283 }
284
285 static int ntfs_device_disk_io_ioctl(struct ntfs_device *dev, int request,
286                 void *argp)
287 {
288         return ioctl((int)dev->d_private, request, argp);
289 }
290
291 /**
292  * Default device operations for working with unix style devices and files.
293  */
294 struct ntfs_device_operations ntfs_device_disk_io_ops = {
295         .open           = ntfs_device_disk_io_open,
296         .close          = ntfs_device_disk_io_close,
297         .seek           = ntfs_device_disk_io_seek,
298         .read           = ntfs_device_disk_io_read,
299         .write          = ntfs_device_disk_io_write,
300         .pread          = ntfs_device_disk_io_pread,
301         .pwrite         = ntfs_device_disk_io_pwrite,
302         .sync           = ntfs_device_disk_io_sync,
303         .stat           = ntfs_device_disk_io_stat,
304         .ioctl          = ntfs_device_disk_io_ioctl,
305 };
306
307 /**
308  * ntfs_mst_pread - multi sector transfer (mst) positioned read
309  * @dev:        device to read from
310  * @pos:        position in file descriptor to read from
311  * @count:      number of blocks to read
312  * @bksize:     size of each block that needs mst deprotecting
313  * @b:          output data buffer
314  *
315  * Multi sector transfer (mst) positioned read. This function will read @count
316  * blocks of size @bksize bytes each from device @dev at position @pos into the
317  * the data buffer @b.
318  *
319  * On success, return the number of successfully read blocks. If this number is
320  * lower than @count this means that we have reached end of file, that the read
321  * was interrupted, or that an error was encountered during the read so that
322  * the read is partial. 0 means end of file or nothing was read (also return 0
323  * when @count or @bksize are 0).
324  *
325  * On error and nothing was read, return -1 with errno set appropriately to the
326  * return code of either seek, read, or set to EINVAL in case of invalid
327  * arguments.
328  *
329  * NOTE: If an incomplete multi sector transfer has been detected the magic
330  * will have been changed to magic_BAAD but no error will be returned. Thus it
331  * is possible that we return count blocks as being read but that any number
332  * (between zero and count!) of these blocks is actually subject to a multi
333  * sector transfer error. This should be detected by the caller by checking for
334  * the magic being "BAAD".
335  */
336 s64 ntfs_mst_pread(struct ntfs_device *dev, const s64 pos, s64 count,
337                 const u32 bksize, void *b)
338 {
339         s64 br, i;
340
341         if (bksize & (bksize - 1) || bksize % NTFS_SECTOR_SIZE) {
342                 errno = EINVAL;
343                 return -1;
344         }
345         /* Do the read. */
346         br = ntfs_pread(dev, pos, count * bksize, b);
347         if (br < 0)
348                 return br;
349         /*
350          * Apply fixups to successfully read data, disregarding any errors
351          * returned from the MST fixup function. This is because we want to
352          * fixup everything possible and we rely on the fact that the "BAAD"
353          * magic will be detected later on.
354          */
355         count = br / bksize;
356         for (i = 0; i < count; ++i)
357                 ntfs_mst_post_read_fixup((NTFS_RECORD*)
358                                 ((u8*)b + i * bksize), bksize);
359         /* Finally, return the number of complete blocks read. */
360         return count;
361 }
362
363 /**
364  * ntfs_mst_pwrite - multi sector transfer (mst) positioned write
365  * @dev:        device to write to
366  * @pos:        position in file descriptor to write to
367  * @count:      number of blocks to write
368  * @bksize:     size of each block that needs mst protecting
369  * @b:          data buffer to write to disk
370  *
371  * Multi sector transfer (mst) positioned write. This function will write
372  * @count blocks of size @bksize bytes each from data buffer @b to the device
373  * @dev at position @pos.
374  *
375  * On success, return the number of successfully written blocks. If this number
376  * is lower than @count this means that the write has been interrutped or that
377  * an error was encountered during the write so that the write is partial. 0
378  * means nothing was written (also return 0 when @count or @bksize are 0).
379  *
380  * On error and nothing has been written, return -1 with errno set
381  * appropriately to the return code of either seek, write, or set
382  * to EINVAL in case of invalid arguments.
383  *
384  * NOTE: We mst protect the data, write it, then mst deprotect it using a quick
385  * deprotect algorithm (no checking). This saves us from making a copy before
386  * the write and at the same time causes the usn to be incremented in the
387  * buffer. This conceptually fits in better with the idea that cached data is
388  * always deprotected and protection is performed when the data is actually
389  * going to hit the disk and the cache is immediately deprotected again
390  * simulating an mst read on the written data. This way cache coherency is
391  * achieved.
392  */
393 s64 ntfs_mst_pwrite(struct ntfs_device *dev, const s64 pos, s64 count,
394                 const u32 bksize, const void *b)
395 {
396         s64 written, i;
397
398         if (count < 0 || bksize % NTFS_SECTOR_SIZE) {
399                 errno = EINVAL;
400                 return -1;
401         }
402         if (!count)
403                 return 0;
404         /* Prepare data for writing. */
405         for (i = 0; i < count; ++i) {
406                 int err;
407
408                 err = ntfs_mst_pre_write_fixup((NTFS_RECORD*)
409                                 ((u8*)b + i * bksize), bksize);
410                 if (err < 0) {
411                         /* Abort write at this position. */
412                         if (!i)
413                                 return err;
414                         count = i;
415                         break;
416                 }
417         }
418         /* Write the prepared data. */
419         written = ntfs_pwrite(dev, pos, count * bksize, b);
420         /* Quickly deprotect the data again. */
421         for (i = 0; i < count; ++i)
422                 ntfs_mst_post_write_fixup((NTFS_RECORD*)((u8*)b + i * bksize));
423         if (written <= 0)
424                 return written;
425         /* Finally, return the number of complete blocks written. */
426         return written / bksize;
427 }
428
429 /**
430  * ntfs_cluster_read - read ntfs clusters
431  * @vol:        volume to read from
432  * @lcn:        starting logical cluster number
433  * @count:      number of clusters to read
434  * @b:          output data buffer
435  *
436  * Read @count ntfs clusters starting at logical cluster number @lcn from
437  * volume @vol into buffer @b. Return number of clusters read or -1 on error,
438  * with errno set to the error code.
439  */
440 s64 ntfs_cluster_read(const ntfs_volume *vol, const s64 lcn, const s64 count,
441                 void *b)
442 {
443         s64 br;
444
445         if (!vol || lcn < 0 || count < 0) {
446                 errno = EINVAL;
447                 return -1;
448         }
449         if (vol->nr_clusters < lcn + count) {
450                 errno = ESPIPE;
451                 return -1;
452         }
453         br = ntfs_pread(vol->dev, lcn << vol->cluster_size_bits,
454                         count << vol->cluster_size_bits, b);
455         if (br < 0) {
456                 Dperror("Error reading cluster(s)");
457                 return br;
458         }
459         return br >> vol->cluster_size_bits;
460 }
461
462 /**
463  * ntfs_cluster_write - write ntfs clusters
464  * @vol:        volume to write to
465  * @lcn:        starting logical cluster number
466  * @count:      number of clusters to write
467  * @b:          data buffer to write to disk
468  *
469  * Write @count ntfs clusters starting at logical cluster number @lcn from
470  * buffer @b to volume @vol. Return the number of clusters written or -1 on
471  * error, with errno set to the error code.
472  */
473 s64 ntfs_cluster_write(const ntfs_volume *vol, const s64 lcn,
474                 const s64 count, const void *b)
475 {
476         s64 bw;
477
478         if (!vol || lcn < 0 || count < 0) {
479                 errno = EINVAL;
480                 return -1;
481         }
482         if (vol->nr_clusters < lcn + count) {
483                 errno = ESPIPE;
484                 return -1;
485         }
486         if (!NVolReadOnly(vol))
487                 bw = ntfs_pwrite(vol->dev, lcn << vol->cluster_size_bits,
488                                 count << vol->cluster_size_bits, b);
489         else
490                 bw = count << vol->cluster_size_bits;
491         if (bw < 0) {
492                 Dperror("Error writing cluster(s)");
493                 return bw;
494         }
495         return bw >> vol->cluster_size_bits;
496 }
497
498 /**
499  * ntfs_device_offset_valid - test if a device offset is valid
500  * @dev:        open device
501  * @ofs:        offset to test for validity
502  *
503  * Test if the offset @ofs is an existing location on the device described
504  * by the open device structure @dev.
505  *
506  * Return 0 if it is valid and -1 if it is not valid.
507  */
508 static inline int ntfs_device_offset_valid(struct ntfs_device *dev, s64 ofs)
509 {
510         char ch;
511
512         if (dev->d_ops->seek(dev, ofs, SEEK_SET) >= 0 &&
513                         dev->d_ops->read(dev, &ch, 1) == 1)
514                 return 0;
515         return -1;
516 }
517
518 /**
519  * ntfs_device_size_get - return the size of a device in blocks
520  * @dev:        open device
521  * @block_size: block size in bytes in which to return the result
522  *
523  * Return the number of @block_size sized blocks in the device described by the
524  * open device @dev.
525  *
526  * Adapted from e2fsutils-1.19, Copyright (C) 1995 Theodore Ts'o.
527  */
528 s64 ntfs_device_size_get(struct ntfs_device *dev, int block_size)
529 {
530         s64 high, low;
531 #ifdef BLKGETSIZE
532         long size;
533
534         if (dev->d_ops->ioctl(dev, BLKGETSIZE, &size) >= 0) {
535                 Dprintf("BLKGETSIZE nr 512 byte blocks = %ld (0x%ld)\n", size,
536                                 size);
537                 return (s64)size * 512 / block_size;
538         }
539 #endif
540 #ifdef FDGETPRM
541         {       struct floppy_struct this_floppy;
542
543                 if (dev->d_ops->ioctl(dev, FDGETPRM, &this_floppy) >= 0) {
544                         Dprintf("FDGETPRM nr 512 byte blocks = %ld (0x%ld)\n",
545                                         this_floppy.size, this_floppy.size);
546                         return (s64)this_floppy.size * 512 / block_size;
547                 }
548         }
549 #endif
550         /*
551          * We couldn't figure it out by using a specialized ioctl,
552          * so do binary search to find the size of the device.
553          */
554         low = 0LL;
555         for (high = 1024LL; !ntfs_device_offset_valid(dev, high); high <<= 1)
556                 low = high;
557         while (low < high - 1LL) {
558                 const s64 mid = (low + high) / 2;
559
560                 if (!ntfs_device_offset_valid(dev, mid))
561                         low = mid;
562                 else
563                         high = mid;
564         }
565         dev->d_ops->seek(dev, 0LL, SEEK_SET);
566         return (low + 1LL) / block_size;
567 }
568