2 * volume.c - NTFS volume handling code. Originated from the Linux-NTFS project.
4 * Copyright (c) 2000-2006 Anton Altaparmakov
5 * Copyright (c) 2002-2009 Szabolcs Szakacsits
6 * Copyright (c) 2004-2005 Richard Russon
7 * Copyright (c) 2010 Jean-Pierre Andre
9 * This program/include file is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as published
11 * by the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program/include file is distributed in the hope that it will be
15 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
16 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program (in the main directory of the NTFS-3G
21 * distribution in the file COPYING); if not, write to the Free Software
22 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
47 #ifdef HAVE_SYS_STAT_H
57 #if defined(__sun) && defined (__SVR4)
58 #include <sys/mnttab.h>
78 const char *ntfs_home
=
79 "News, support and information: http://tuxera.com\n";
81 static const char *invalid_ntfs_msg
=
82 "The device '%s' doesn't seem to have a valid NTFS.\n"
83 "Maybe the wrong device is used? Or the whole disk instead of a\n"
84 "partition (e.g. /dev/sda, not /dev/sda1)? Or the other way around?\n";
86 static const char *corrupt_volume_msg
=
87 "NTFS is either inconsistent, or there is a hardware fault, or it's a\n"
88 "SoftRAID/FakeRAID hardware. In the first case run chkdsk /f on Windows\n"
89 "then reboot into Windows twice. The usage of the /f parameter is very\n"
90 "important! If the device is a SoftRAID/FakeRAID then first activate\n"
91 "it and mount a different device under the /dev/mapper/ directory, (e.g.\n"
92 "/dev/mapper/nvidia_eahaabcc1). Please see the 'dmraid' documentation\n"
93 "for more details.\n";
95 static const char *hibernated_volume_msg
=
96 "The NTFS partition is in an unsafe state. Please resume and shutdown\n"
97 "Windows fully (no hibernation or fast restarting), or mount the volume\n"
98 "read-only with the 'ro' mount option.\n";
100 static const char *unclean_journal_msg
=
101 "Write access is denied because the disk wasn't safely powered\n"
102 "off and the 'norecover' mount option was specified.\n";
104 static const char *opened_volume_msg
=
105 "Mount is denied because the NTFS volume is already exclusively opened.\n"
106 "The volume may be already mounted, or another software may use it which\n"
107 "could be identified for example by the help of the 'fuser' command.\n";
109 static const char *fakeraid_msg
=
110 "Either the device is missing or it's powered down, or you have\n"
111 "SoftRAID hardware and must use an activated, different device under\n"
112 "/dev/mapper/, (e.g. /dev/mapper/nvidia_eahaabcc1) to mount NTFS.\n"
113 "Please see the 'dmraid' documentation for help.\n";
115 static const char *access_denied_msg
=
116 "Please check '%s' and the ntfs-3g binary permissions,\n"
117 "and the mounting user ID. More explanation is provided at\n"
118 "http://tuxera.com/community/ntfs-3g-faq/#unprivileged\n";
121 * ntfs_volume_alloc - Create an NTFS volume object and initialise it
127 ntfs_volume
*ntfs_volume_alloc(void)
129 return ntfs_calloc(sizeof(ntfs_volume
));
132 static void ntfs_attr_free(ntfs_attr
**na
)
135 ntfs_attr_close(*na
);
140 static int ntfs_inode_free(ntfs_inode
**ni
)
145 ret
= ntfs_inode_close(*ni
);
152 static void ntfs_error_set(int *err
)
159 * __ntfs_volume_release - Destroy an NTFS volume object
166 static int __ntfs_volume_release(ntfs_volume
*v
)
170 if (ntfs_inode_free(&v
->vol_ni
))
171 ntfs_error_set(&err
);
173 * FIXME: Inodes must be synced before closing
174 * attributes, otherwise unmount could fail.
176 if (v
->lcnbmp_ni
&& NInoDirty(v
->lcnbmp_ni
))
177 ntfs_inode_sync(v
->lcnbmp_ni
);
178 ntfs_attr_free(&v
->lcnbmp_na
);
179 if (ntfs_inode_free(&v
->lcnbmp_ni
))
180 ntfs_error_set(&err
);
182 if (v
->mft_ni
&& NInoDirty(v
->mft_ni
))
183 ntfs_inode_sync(v
->mft_ni
);
184 ntfs_attr_free(&v
->mftbmp_na
);
185 ntfs_attr_free(&v
->mft_na
);
186 if (ntfs_inode_free(&v
->mft_ni
))
187 ntfs_error_set(&err
);
189 if (v
->mftmirr_ni
&& NInoDirty(v
->mftmirr_ni
))
190 ntfs_inode_sync(v
->mftmirr_ni
);
191 ntfs_attr_free(&v
->mftmirr_na
);
192 if (ntfs_inode_free(&v
->mftmirr_ni
))
193 ntfs_error_set(&err
);
196 struct ntfs_device
*dev
= v
->dev
;
198 if (dev
->d_ops
->sync(dev
))
199 ntfs_error_set(&err
);
200 if (dev
->d_ops
->close(dev
))
201 ntfs_error_set(&err
);
204 ntfs_free_lru_caches(v
);
207 if (v
->locase
) free(v
->locase
);
212 return errno
? -1 : 0;
215 static void ntfs_attr_setup_flag(ntfs_inode
*ni
)
217 STANDARD_INFORMATION
*si
;
219 si
= ntfs_attr_readall(ni
, AT_STANDARD_INFORMATION
, AT_UNNAMED
, 0, NULL
);
221 ni
->flags
= si
->file_attributes
;
227 * ntfs_mft_load - load the $MFT and setup the ntfs volume with it
228 * @vol: ntfs volume whose $MFT to load
230 * Load $MFT from @vol and setup @vol with it. After calling this function the
231 * volume @vol is ready for use by all read access functions provided by the
234 * Return 0 on success and -1 on error with errno set to the error code.
236 static int ntfs_mft_load(ntfs_volume
*vol
)
238 VCN next_vcn
, last_vcn
, highest_vcn
;
240 MFT_RECORD
*mb
= NULL
;
241 ntfs_attr_search_ctx
*ctx
= NULL
;
245 /* Manually setup an ntfs_inode. */
246 vol
->mft_ni
= ntfs_inode_allocate(vol
);
247 mb
= ntfs_malloc(vol
->mft_record_size
);
248 if (!vol
->mft_ni
|| !mb
) {
249 ntfs_log_perror("Error allocating memory for $MFT");
252 vol
->mft_ni
->mft_no
= 0;
253 vol
->mft_ni
->mrec
= mb
;
254 /* Can't use any of the higher level functions yet! */
255 l
= ntfs_mst_pread(vol
->dev
, vol
->mft_lcn
<< vol
->cluster_size_bits
, 1,
256 vol
->mft_record_size
, mb
);
260 ntfs_log_perror("Error reading $MFT");
264 if (ntfs_mft_record_check(vol
, 0, mb
))
267 ctx
= ntfs_attr_get_search_ctx(vol
->mft_ni
, NULL
);
271 /* Find the $ATTRIBUTE_LIST attribute in $MFT if present. */
272 if (ntfs_attr_lookup(AT_ATTRIBUTE_LIST
, AT_UNNAMED
, 0, 0, 0, NULL
, 0,
274 if (errno
!= ENOENT
) {
275 ntfs_log_error("$MFT has corrupt attribute list.\n");
278 goto mft_has_no_attr_list
;
280 NInoSetAttrList(vol
->mft_ni
);
281 l
= ntfs_get_attribute_value_length(ctx
->attr
);
282 if (l
<= 0 || l
> 0x40000) {
283 ntfs_log_error("$MFT/$ATTR_LIST invalid length (%lld).\n",
287 vol
->mft_ni
->attr_list_size
= l
;
288 vol
->mft_ni
->attr_list
= ntfs_malloc(l
);
289 if (!vol
->mft_ni
->attr_list
)
292 l
= ntfs_get_attribute_value(vol
, ctx
->attr
, vol
->mft_ni
->attr_list
);
294 ntfs_log_error("Failed to get value of $MFT/$ATTR_LIST.\n");
297 if (l
!= vol
->mft_ni
->attr_list_size
) {
298 ntfs_log_error("Partial read of $MFT/$ATTR_LIST (%lld != "
299 "%u).\n", (long long)l
,
300 vol
->mft_ni
->attr_list_size
);
304 mft_has_no_attr_list
:
306 ntfs_attr_setup_flag(vol
->mft_ni
);
308 /* We now have a fully setup ntfs inode for $MFT in vol->mft_ni. */
310 /* Get an ntfs attribute for $MFT/$DATA and set it up, too. */
311 vol
->mft_na
= ntfs_attr_open(vol
->mft_ni
, AT_DATA
, AT_UNNAMED
, 0);
313 ntfs_log_perror("Failed to open ntfs attribute");
316 /* Read all extents from the $DATA attribute in $MFT. */
317 ntfs_attr_reinit_search_ctx(ctx
);
318 last_vcn
= vol
->mft_na
->allocated_size
>> vol
->cluster_size_bits
;
319 highest_vcn
= next_vcn
= 0;
321 while (!ntfs_attr_lookup(AT_DATA
, AT_UNNAMED
, 0, 0, next_vcn
, NULL
, 0,
323 runlist_element
*nrl
;
326 /* $MFT must be non-resident. */
327 if (!a
->non_resident
) {
328 ntfs_log_error("$MFT must be non-resident.\n");
331 /* $MFT must be uncompressed and unencrypted. */
332 if (a
->flags
& ATTR_COMPRESSION_MASK
||
333 a
->flags
& ATTR_IS_ENCRYPTED
) {
334 ntfs_log_error("$MFT must be uncompressed and "
339 * Decompress the mapping pairs array of this extent and merge
340 * the result into the existing runlist. No need for locking
341 * as we have exclusive access to the inode at this time and we
342 * are a mount in progress task, too.
344 nrl
= ntfs_mapping_pairs_decompress(vol
, a
, vol
->mft_na
->rl
);
346 ntfs_log_perror("ntfs_mapping_pairs_decompress() failed");
349 vol
->mft_na
->rl
= nrl
;
351 /* Get the lowest vcn for the next extent. */
352 highest_vcn
= sle64_to_cpu(a
->highest_vcn
);
353 next_vcn
= highest_vcn
+ 1;
355 /* Only one extent or error, which we catch below. */
359 /* Avoid endless loops due to corruption. */
360 if (next_vcn
< sle64_to_cpu(a
->lowest_vcn
)) {
361 ntfs_log_error("$MFT has corrupt attribute list.\n");
366 ntfs_log_error("$MFT/$DATA attribute not found.\n");
369 if (highest_vcn
&& highest_vcn
!= last_vcn
- 1) {
370 ntfs_log_error("Failed to load runlist for $MFT/$DATA.\n");
371 ntfs_log_error("highest_vcn = 0x%llx, last_vcn - 1 = 0x%llx\n",
372 (long long)highest_vcn
, (long long)last_vcn
- 1);
375 /* Done with the $Mft mft record. */
376 ntfs_attr_put_search_ctx(ctx
);
379 /* Update the size fields in the inode. */
380 vol
->mft_ni
->data_size
= vol
->mft_na
->data_size
;
381 vol
->mft_ni
->allocated_size
= vol
->mft_na
->allocated_size
;
382 set_nino_flag(vol
->mft_ni
, KnownSize
);
385 * The volume is now setup so we can use all read access functions.
387 vol
->mftbmp_na
= ntfs_attr_open(vol
->mft_ni
, AT_BITMAP
, AT_UNNAMED
, 0);
388 if (!vol
->mftbmp_na
) {
389 ntfs_log_perror("Failed to open $MFT/$BITMAP");
398 ntfs_attr_put_search_ctx(ctx
);
400 ntfs_attr_close(vol
->mft_na
);
404 ntfs_inode_close(vol
->mft_ni
);
412 * ntfs_mftmirr_load - load the $MFTMirr and setup the ntfs volume with it
413 * @vol: ntfs volume whose $MFTMirr to load
415 * Load $MFTMirr from @vol and setup @vol with it. After calling this function
416 * the volume @vol is ready for use by all write access functions provided by
417 * the ntfs library (assuming ntfs_mft_load() has been called successfully
420 * Return 0 on success and -1 on error with errno set to the error code.
422 static int ntfs_mftmirr_load(ntfs_volume
*vol
)
426 vol
->mftmirr_ni
= ntfs_inode_open(vol
, FILE_MFTMirr
);
427 if (!vol
->mftmirr_ni
) {
428 ntfs_log_perror("Failed to open inode $MFTMirr");
432 vol
->mftmirr_na
= ntfs_attr_open(vol
->mftmirr_ni
, AT_DATA
, AT_UNNAMED
, 0);
433 if (!vol
->mftmirr_na
) {
434 ntfs_log_perror("Failed to open $MFTMirr/$DATA");
438 if (ntfs_attr_map_runlist(vol
->mftmirr_na
, 0) < 0) {
439 ntfs_log_perror("Failed to map runlist of $MFTMirr/$DATA");
447 if (vol
->mftmirr_na
) {
448 ntfs_attr_close(vol
->mftmirr_na
);
449 vol
->mftmirr_na
= NULL
;
451 ntfs_inode_close(vol
->mftmirr_ni
);
452 vol
->mftmirr_ni
= NULL
;
458 * ntfs_volume_startup - allocate and setup an ntfs volume
459 * @dev: device to open
460 * @flags: optional mount flags
462 * Load, verify, and parse bootsector; load and setup $MFT and $MFTMirr. After
463 * calling this function, the volume is setup sufficiently to call all read
464 * and write access functions provided by the library.
466 * Return the allocated volume structure on success and NULL on error with
467 * errno set to the error code.
469 ntfs_volume
*ntfs_volume_startup(struct ntfs_device
*dev
,
470 ntfs_mount_flags flags
)
472 LCN mft_zone_size
, mft_lcn
;
475 NTFS_BOOT_SECTOR
*bs
;
478 if (!dev
|| !dev
->d_ops
|| !dev
->d_name
) {
480 ntfs_log_perror("%s: dev = %p", __FUNCTION__
, dev
);
484 bs
= ntfs_malloc(sizeof(NTFS_BOOT_SECTOR
));
488 /* Allocate the volume structure. */
489 vol
= ntfs_volume_alloc();
493 /* Create the default upcase table. */
494 vol
->upcase_len
= ntfs_upcase_build_default(&vol
->upcase
);
495 if (!vol
->upcase_len
|| !vol
->upcase
)
498 /* Default with no locase table and case sensitive file names */
499 vol
->locase
= (ntfschar
*)NULL
;
500 NVolSetCaseSensitive(vol
);
502 /* by default, all files are shown and not marked hidden */
503 NVolSetShowSysFiles(vol
);
504 NVolSetShowHidFiles(vol
);
505 NVolClearHideDotFiles(vol
);
506 /* set default compression */
507 #if DEFAULT_COMPRESSION
508 NVolSetCompression(vol
);
510 NVolClearCompression(vol
);
512 if (flags
& NTFS_MNT_RDONLY
)
513 NVolSetReadOnly(vol
);
515 /* ...->open needs bracketing to compile with glibc 2.7 */
516 if ((dev
->d_ops
->open
)(dev
, NVolReadOnly(vol
) ? O_RDONLY
: O_RDWR
)) {
517 if (!NVolReadOnly(vol
) && (errno
== EROFS
)) {
518 if ((dev
->d_ops
->open
)(dev
, O_RDONLY
)) {
519 ntfs_log_perror("Error opening read-only '%s'",
523 ntfs_log_info("Can only open '%s' as read-only\n",
525 NVolSetReadOnly(vol
);
528 ntfs_log_perror("Error opening '%s'", dev
->d_name
);
532 /* Attach the device to the volume. */
535 /* Now read the bootsector. */
536 br
= ntfs_pread(dev
, 0, sizeof(NTFS_BOOT_SECTOR
), bs
);
537 if (br
!= sizeof(NTFS_BOOT_SECTOR
)) {
541 ntfs_log_error("Failed to read bootsector (size=0)\n");
543 ntfs_log_perror("Error reading bootsector");
546 if (!ntfs_boot_sector_is_ntfs(bs
)) {
550 if (ntfs_boot_sector_parse(vol
, bs
) < 0)
555 /* Now set the device block size to the sector size. */
556 if (ntfs_device_block_size_set(vol
->dev
, vol
->sector_size
))
557 ntfs_log_debug("Failed to set the device block size to the "
558 "sector size. This may affect performance "
559 "but should be harmless otherwise. Error: "
560 "%s\n", strerror(errno
));
562 /* We now initialize the cluster allocator. */
564 mft_zone_size
= vol
->nr_clusters
>> 3; /* 12.5% */
566 /* Setup the mft zone. */
567 vol
->mft_zone_start
= vol
->mft_zone_pos
= vol
->mft_lcn
;
568 ntfs_log_debug("mft_zone_pos = 0x%llx\n", (long long)vol
->mft_zone_pos
);
571 * Calculate the mft_lcn for an unmodified NTFS volume (see mkntfs
572 * source) and if the actual mft_lcn is in the expected place or even
573 * further to the front of the volume, extend the mft_zone to cover the
574 * beginning of the volume as well. This is in order to protect the
575 * area reserved for the mft bitmap as well within the mft_zone itself.
576 * On non-standard volumes we don't protect it as the overhead would be
577 * higher than the speed increase we would get by doing it.
579 mft_lcn
= (8192 + 2 * vol
->cluster_size
- 1) / vol
->cluster_size
;
580 if (mft_lcn
* vol
->cluster_size
< 16 * 1024)
581 mft_lcn
= (16 * 1024 + vol
->cluster_size
- 1) /
583 if (vol
->mft_zone_start
<= mft_lcn
)
584 vol
->mft_zone_start
= 0;
585 ntfs_log_debug("mft_zone_start = 0x%llx\n", (long long)vol
->mft_zone_start
);
588 * Need to cap the mft zone on non-standard volumes so that it does
589 * not point outside the boundaries of the volume. We do this by
590 * halving the zone size until we are inside the volume.
592 vol
->mft_zone_end
= vol
->mft_lcn
+ mft_zone_size
;
593 while (vol
->mft_zone_end
>= vol
->nr_clusters
) {
595 vol
->mft_zone_end
= vol
->mft_lcn
+ mft_zone_size
;
597 ntfs_log_debug("mft_zone_end = 0x%llx\n", (long long)vol
->mft_zone_end
);
600 * Set the current position within each data zone to the start of the
603 vol
->data1_zone_pos
= vol
->mft_zone_end
;
604 ntfs_log_debug("data1_zone_pos = %lld\n", (long long)vol
->data1_zone_pos
);
605 vol
->data2_zone_pos
= 0;
606 ntfs_log_debug("data2_zone_pos = %lld\n", (long long)vol
->data2_zone_pos
);
608 /* Set the mft data allocation position to mft record 24. */
609 vol
->mft_data_pos
= 24;
612 * The cluster allocator is now fully operational.
615 /* Need to setup $MFT so we can use the library read functions. */
616 if (ntfs_mft_load(vol
) < 0) {
617 ntfs_log_perror("Failed to load $MFT");
621 /* Need to setup $MFTMirr so we can use the write functions, too. */
622 if (ntfs_mftmirr_load(vol
) < 0) {
623 ntfs_log_perror("Failed to load $MFTMirr");
631 __ntfs_volume_release(vol
);
637 * ntfs_volume_check_logfile - check logfile on target volume
638 * @vol: volume on which to check logfile
640 * Return 0 on success and -1 on error with errno set error code.
642 static int ntfs_volume_check_logfile(ntfs_volume
*vol
)
645 ntfs_attr
*na
= NULL
;
646 RESTART_PAGE_HEADER
*rp
= NULL
;
649 ni
= ntfs_inode_open(vol
, FILE_LogFile
);
651 ntfs_log_perror("Failed to open inode FILE_LogFile");
656 na
= ntfs_attr_open(ni
, AT_DATA
, AT_UNNAMED
, 0);
658 ntfs_log_perror("Failed to open $FILE_LogFile/$DATA");
663 if (!ntfs_check_logfile(na
, &rp
) || !ntfs_is_logfile_clean(na
, rp
))
666 * If the latest restart page was identified as version
667 * 2.0, then Windows may have kept a cached copy of
668 * metadata for fast restarting, and we should not mount.
669 * Hibernation will be seen the same way on a non
670 * Windows-system partition, so we have to use the same
671 * error code (EPERM).
672 * The restart page may also be identified as version 2.0
673 * when access to the file system is terminated abruptly
674 * by unplugging or power cut, so mounting is also rejected
675 * after such an event.
678 && (rp
->major_ver
== const_cpu_to_le16(2))
679 && (rp
->minor_ver
== const_cpu_to_le16(0))) {
680 ntfs_log_error("Metadata kept in Windows cache, refused to mount.\n");
686 if (ntfs_inode_close(ni
))
687 ntfs_error_set(&err
);
696 * ntfs_hiberfile_open - Find and open '/hiberfil.sys'
697 * @vol: An ntfs volume obtained from ntfs_mount
699 * Return: inode Success, hiberfil.sys is valid
700 * NULL hiberfil.sys doesn't exist or some other error occurred
702 static ntfs_inode
*ntfs_hiberfile_open(ntfs_volume
*vol
)
706 ntfs_inode
*ni_hibr
= NULL
;
707 ntfschar
*unicode
= NULL
;
709 const char *hiberfile
= "hiberfil.sys";
716 ni_root
= ntfs_inode_open(vol
, FILE_root
);
718 ntfs_log_debug("Couldn't open the root directory.\n");
722 unicode_len
= ntfs_mbstoucs(hiberfile
, &unicode
);
723 if (unicode_len
< 0) {
724 ntfs_log_perror("Couldn't convert 'hiberfil.sys' to Unicode");
728 inode
= ntfs_inode_lookup_by_name(ni_root
, unicode
, unicode_len
);
729 if (inode
== (u64
)-1) {
730 ntfs_log_debug("Couldn't find file '%s'.\n", hiberfile
);
735 ni_hibr
= ntfs_inode_open(vol
, inode
);
737 ntfs_log_debug("Couldn't open inode %lld.\n", (long long)inode
);
741 if (ntfs_inode_close(ni_root
)) {
742 ntfs_inode_close(ni_hibr
);
750 #define NTFS_HIBERFILE_HEADER_SIZE 4096
753 * ntfs_volume_check_hiberfile - check hiberfil.sys whether Windows is
754 * hibernated on the target volume
755 * @vol: volume on which to check hiberfil.sys
757 * Return: 0 if Windows isn't hibernated for sure
758 * -1 otherwise and errno is set to the appropriate value
760 int ntfs_volume_check_hiberfile(ntfs_volume
*vol
, int verbose
)
763 ntfs_attr
*na
= NULL
;
767 ni
= ntfs_hiberfile_open(vol
);
774 buf
= ntfs_malloc(NTFS_HIBERFILE_HEADER_SIZE
);
778 na
= ntfs_attr_open(ni
, AT_DATA
, AT_UNNAMED
, 0);
780 ntfs_log_perror("Failed to open hiberfil.sys data attribute");
784 bytes_read
= ntfs_attr_pread(na
, 0, NTFS_HIBERFILE_HEADER_SIZE
, buf
);
785 if (bytes_read
== -1) {
786 ntfs_log_perror("Failed to read hiberfil.sys");
789 if (bytes_read
< NTFS_HIBERFILE_HEADER_SIZE
) {
791 ntfs_log_error("Hibernated non-system partition, "
792 "refused to mount.\n");
796 if ((memcmp(buf
, "hibr", 4) == 0)
797 || (memcmp(buf
, "HIBR", 4) == 0)) {
799 ntfs_log_error("Windows is hibernated, refused to mount.\n");
803 /* All right, all header bytes are zero */
810 if (ntfs_inode_close(ni
))
811 ntfs_error_set(&err
);
813 return errno
? -1 : 0;
817 * Make sure a LOGGED_UTILITY_STREAM attribute named "$TXF_DATA"
818 * on the root directory is resident.
819 * When it is non-resident, the partition cannot be mounted on Vista
820 * (see http://support.microsoft.com/kb/974729)
822 * We take care to avoid this situation, however this can be a
823 * consequence of having used an older version (including older
824 * Windows version), so we had better fix it.
826 * Returns 0 if unneeded or successful
827 * -1 if there was an error, explained by errno
830 static int fix_txf_data(ntfs_volume
*vol
)
839 ntfs_log_debug("Loading root directory\n");
840 ni
= ntfs_inode_open(vol
, FILE_root
);
842 ntfs_log_perror("Failed to open root directory");
845 /* Get the $TXF_DATA attribute */
846 na
= ntfs_attr_open(ni
, AT_LOGGED_UTILITY_STREAM
, TXF_DATA
, 9);
848 if (NAttrNonResident(na
)) {
850 * Fix the attribute by truncating, then
853 ntfs_log_debug("Making $TXF_DATA resident\n");
854 txf_data
= ntfs_attr_readall(ni
,
855 AT_LOGGED_UTILITY_STREAM
,
856 TXF_DATA
, 9, &txf_data_size
);
858 if (ntfs_attr_truncate(na
, 0)
859 || (ntfs_attr_pwrite(na
, 0,
860 txf_data_size
, txf_data
)
866 ntfs_log_error("Failed to make $TXF_DATA resident\n");
868 ntfs_log_error("$TXF_DATA made resident\n");
872 if (ntfs_inode_close(ni
)) {
873 ntfs_log_perror("Failed to close root");
881 * ntfs_device_mount - open ntfs volume
882 * @dev: device to open
883 * @flags: optional mount flags
885 * This function mounts an ntfs volume. @dev should describe the device which
886 * to mount as the ntfs volume.
888 * @flags is an optional second parameter. The same flags are used as for
889 * the mount system call (man 2 mount). Currently only the following flag
891 * NTFS_MNT_RDONLY - mount volume read-only
893 * The function opens the device @dev and verifies that it contains a valid
894 * bootsector. Then, it allocates an ntfs_volume structure and initializes
895 * some of the values inside the structure from the information stored in the
896 * bootsector. It proceeds to load the necessary system files and completes
897 * setting up the structure.
899 * Return the allocated volume structure on success and NULL on error with
900 * errno set to the error code.
902 ntfs_volume
*ntfs_device_mount(struct ntfs_device
*dev
, ntfs_mount_flags flags
)
906 u8
*m
= NULL
, *m2
= NULL
;
907 ntfs_attr_search_ctx
*ctx
= NULL
;
911 VOLUME_INFORMATION
*vinf
;
917 vol
= ntfs_volume_startup(dev
, flags
);
921 /* Load data from $MFT and $MFTMirr and compare the contents. */
922 m
= ntfs_malloc(vol
->mftmirr_size
<< vol
->mft_record_size_bits
);
923 m2
= ntfs_malloc(vol
->mftmirr_size
<< vol
->mft_record_size_bits
);
927 l
= ntfs_attr_mst_pread(vol
->mft_na
, 0, vol
->mftmirr_size
,
928 vol
->mft_record_size
, m
);
929 if (l
!= vol
->mftmirr_size
) {
931 ntfs_log_perror("Failed to read $MFT");
933 ntfs_log_error("Failed to read $MFT, unexpected length "
934 "(%lld != %d).\n", (long long)l
,
940 l
= ntfs_attr_mst_pread(vol
->mftmirr_na
, 0, vol
->mftmirr_size
,
941 vol
->mft_record_size
, m2
);
942 if (l
!= vol
->mftmirr_size
) {
944 ntfs_log_perror("Failed to read $MFTMirr");
947 vol
->mftmirr_size
= l
;
949 ntfs_log_debug("Comparing $MFTMirr to $MFT...\n");
950 for (i
= 0; i
< vol
->mftmirr_size
; ++i
) {
951 MFT_RECORD
*mrec
, *mrec2
;
952 const char *ESTR
[12] = { "$MFT", "$MFTMirr", "$LogFile",
953 "$Volume", "$AttrDef", "root directory", "$Bitmap",
954 "$Boot", "$BadClus", "$Secure", "$UpCase", "$Extend" };
964 mrec
= (MFT_RECORD
*)(m
+ i
* vol
->mft_record_size
);
965 if (mrec
->flags
& MFT_RECORD_IN_USE
) {
966 if (ntfs_is_baad_recordp(mrec
)) {
967 ntfs_log_error("$MFT error: Incomplete multi "
968 "sector transfer detected in "
972 if (!ntfs_is_mft_recordp(mrec
)) {
973 ntfs_log_error("$MFT error: Invalid mft "
974 "record for '%s'.\n", s
);
978 mrec2
= (MFT_RECORD
*)(m2
+ i
* vol
->mft_record_size
);
979 if (mrec2
->flags
& MFT_RECORD_IN_USE
) {
980 if (ntfs_is_baad_recordp(mrec2
)) {
981 ntfs_log_error("$MFTMirr error: Incomplete "
982 "multi sector transfer "
983 "detected in '%s'.\n", s
);
986 if (!ntfs_is_mft_recordp(mrec2
)) {
987 ntfs_log_error("$MFTMirr error: Invalid mft "
988 "record for '%s'.\n", s
);
992 if (memcmp(mrec
, mrec2
, ntfs_mft_record_get_data_size(mrec
))) {
993 ntfs_log_error("$MFTMirr does not match $MFT (record "
1003 /* Now load the bitmap from $Bitmap. */
1004 ntfs_log_debug("Loading $Bitmap...\n");
1005 vol
->lcnbmp_ni
= ntfs_inode_open(vol
, FILE_Bitmap
);
1006 if (!vol
->lcnbmp_ni
) {
1007 ntfs_log_perror("Failed to open inode FILE_Bitmap");
1011 vol
->lcnbmp_na
= ntfs_attr_open(vol
->lcnbmp_ni
, AT_DATA
, AT_UNNAMED
, 0);
1012 if (!vol
->lcnbmp_na
) {
1013 ntfs_log_perror("Failed to open ntfs attribute");
1017 if (vol
->lcnbmp_na
->data_size
> vol
->lcnbmp_na
->allocated_size
) {
1018 ntfs_log_error("Corrupt cluster map size (%lld > %lld)\n",
1019 (long long)vol
->lcnbmp_na
->data_size
,
1020 (long long)vol
->lcnbmp_na
->allocated_size
);
1024 /* Now load the upcase table from $UpCase. */
1025 ntfs_log_debug("Loading $UpCase...\n");
1026 ni
= ntfs_inode_open(vol
, FILE_UpCase
);
1028 ntfs_log_perror("Failed to open inode FILE_UpCase");
1031 /* Get an ntfs attribute for $UpCase/$DATA. */
1032 na
= ntfs_attr_open(ni
, AT_DATA
, AT_UNNAMED
, 0);
1034 ntfs_log_perror("Failed to open ntfs attribute");
1038 * Note: Normally, the upcase table has a length equal to 65536
1039 * 2-byte Unicode characters but allow for different cases, so no
1040 * checks done. Just check we don't overflow 32-bits worth of Unicode
1043 if (na
->data_size
& ~0x1ffffffffULL
) {
1044 ntfs_log_error("Error: Upcase table is too big (max 32-bit "
1049 if (vol
->upcase_len
!= na
->data_size
>> 1) {
1050 vol
->upcase_len
= na
->data_size
>> 1;
1051 /* Throw away default table. */
1053 vol
->upcase
= ntfs_malloc(na
->data_size
);
1057 /* Read in the $DATA attribute value into the buffer. */
1058 l
= ntfs_attr_pread(na
, 0, na
->data_size
, vol
->upcase
);
1059 if (l
!= na
->data_size
) {
1060 ntfs_log_error("Failed to read $UpCase, unexpected length "
1061 "(%lld != %lld).\n", (long long)l
,
1062 (long long)na
->data_size
);
1066 /* Done with the $UpCase mft record. */
1067 ntfs_attr_close(na
);
1068 if (ntfs_inode_close(ni
)) {
1069 ntfs_log_perror("Failed to close $UpCase");
1072 /* Consistency check of $UpCase, restricted to plain ASCII chars */
1074 while ((k
< vol
->upcase_len
)
1076 && (le16_to_cpu(vol
->upcase
[k
])
1077 == ((k
< 'a') || (k
> 'z') ? k
: k
+ 'A' - 'a')))
1080 ntfs_log_error("Corrupted file $UpCase\n");
1085 * Now load $Volume and set the version information and flags in the
1086 * vol structure accordingly.
1088 ntfs_log_debug("Loading $Volume...\n");
1089 vol
->vol_ni
= ntfs_inode_open(vol
, FILE_Volume
);
1091 ntfs_log_perror("Failed to open inode FILE_Volume");
1094 /* Get a search context for the $Volume/$VOLUME_INFORMATION lookup. */
1095 ctx
= ntfs_attr_get_search_ctx(vol
->vol_ni
, NULL
);
1099 /* Find the $VOLUME_INFORMATION attribute. */
1100 if (ntfs_attr_lookup(AT_VOLUME_INFORMATION
, AT_UNNAMED
, 0, 0, 0, NULL
,
1102 ntfs_log_perror("$VOLUME_INFORMATION attribute not found in "
1107 /* Has to be resident. */
1108 if (a
->non_resident
) {
1109 ntfs_log_error("Attribute $VOLUME_INFORMATION must be "
1110 "resident but it isn't.\n");
1114 /* Get a pointer to the value of the attribute. */
1115 vinf
= (VOLUME_INFORMATION
*)(le16_to_cpu(a
->value_offset
) + (char*)a
);
1116 /* Sanity checks. */
1117 if ((char*)vinf
+ le32_to_cpu(a
->value_length
) > (char*)ctx
->mrec
+
1118 le32_to_cpu(ctx
->mrec
->bytes_in_use
) ||
1119 le16_to_cpu(a
->value_offset
) + le32_to_cpu(
1120 a
->value_length
) > le32_to_cpu(a
->length
)) {
1121 ntfs_log_error("$VOLUME_INFORMATION in $Volume is corrupt.\n");
1125 /* Setup vol from the volume information attribute value. */
1126 vol
->major_ver
= vinf
->major_ver
;
1127 vol
->minor_ver
= vinf
->minor_ver
;
1128 /* Do not use le16_to_cpu() macro here as our VOLUME_FLAGS are
1129 defined using cpu_to_le16() macro and hence are consistent. */
1130 vol
->flags
= vinf
->flags
;
1132 * Reinitialize the search context for the $Volume/$VOLUME_NAME lookup.
1134 ntfs_attr_reinit_search_ctx(ctx
);
1135 if (ntfs_attr_lookup(AT_VOLUME_NAME
, AT_UNNAMED
, 0, 0, 0, NULL
, 0,
1137 if (errno
!= ENOENT
) {
1138 ntfs_log_perror("Failed to lookup of $VOLUME_NAME in "
1143 * Attribute not present. This has been seen in the field.
1144 * Treat this the same way as if the attribute was present but
1147 vol
->vol_name
= ntfs_malloc(1);
1150 vol
->vol_name
[0] = '\0';
1153 /* Has to be resident. */
1154 if (a
->non_resident
) {
1155 ntfs_log_error("$VOLUME_NAME must be resident.\n");
1159 /* Get a pointer to the value of the attribute. */
1160 vname
= (ntfschar
*)(le16_to_cpu(a
->value_offset
) + (char*)a
);
1161 u
= le32_to_cpu(a
->value_length
) / 2;
1163 * Convert Unicode volume name to current locale multibyte
1166 vol
->vol_name
= NULL
;
1167 if (ntfs_ucstombs(vname
, u
, &vol
->vol_name
, 0) == -1) {
1168 ntfs_log_perror("Volume name could not be converted "
1169 "to current locale");
1170 ntfs_log_debug("Forcing name into ASCII by replacing "
1171 "non-ASCII characters with underscores.\n");
1172 vol
->vol_name
= ntfs_malloc(u
+ 1);
1176 for (j
= 0; j
< (s32
)u
; j
++) {
1177 u16 uc
= le16_to_cpu(vname
[j
]);
1180 vol
->vol_name
[j
] = (char)uc
;
1182 vol
->vol_name
[u
] = '\0';
1185 ntfs_attr_put_search_ctx(ctx
);
1187 /* Now load the attribute definitions from $AttrDef. */
1188 ntfs_log_debug("Loading $AttrDef...\n");
1189 ni
= ntfs_inode_open(vol
, FILE_AttrDef
);
1191 ntfs_log_perror("Failed to open $AttrDef");
1194 /* Get an ntfs attribute for $AttrDef/$DATA. */
1195 na
= ntfs_attr_open(ni
, AT_DATA
, AT_UNNAMED
, 0);
1197 ntfs_log_perror("Failed to open ntfs attribute");
1200 /* Check we don't overflow 32-bits. */
1201 if (na
->data_size
> 0xffffffffLL
) {
1202 ntfs_log_error("Attribute definition table is too big (max "
1203 "32-bit allowed).\n");
1207 vol
->attrdef_len
= na
->data_size
;
1208 vol
->attrdef
= ntfs_malloc(na
->data_size
);
1211 /* Read in the $DATA attribute value into the buffer. */
1212 l
= ntfs_attr_pread(na
, 0, na
->data_size
, vol
->attrdef
);
1213 if (l
!= na
->data_size
) {
1214 ntfs_log_error("Failed to read $AttrDef, unexpected length "
1215 "(%lld != %lld).\n", (long long)l
,
1216 (long long)na
->data_size
);
1220 /* Done with the $AttrDef mft record. */
1221 ntfs_attr_close(na
);
1222 if (ntfs_inode_close(ni
)) {
1223 ntfs_log_perror("Failed to close $AttrDef");
1227 * Check for dirty logfile and hibernated Windows.
1228 * We care only about read-write mounts.
1230 if (!(flags
& (NTFS_MNT_RDONLY
| NTFS_MNT_FORENSIC
))) {
1231 if (!(flags
& NTFS_MNT_IGNORE_HIBERFILE
) &&
1232 ntfs_volume_check_hiberfile(vol
, 1) < 0)
1234 if (ntfs_volume_check_logfile(vol
) < 0) {
1235 /* Always reject cached metadata for now */
1236 if (!(flags
& NTFS_MNT_RECOVER
) || (errno
== EPERM
))
1238 ntfs_log_info("The file system wasn't safely "
1239 "closed on Windows. Fixing.\n");
1240 if (ntfs_logfile_reset(vol
))
1243 /* make $TXF_DATA resident if present on the root directory */
1244 if (fix_txf_data(vol
))
1254 ntfs_attr_put_search_ctx(ctx
);
1257 __ntfs_volume_release(vol
);
1263 * Set appropriate flags for showing NTFS metafiles
1264 * or files marked as hidden.
1265 * Not set in ntfs_mount() to avoid breaking existing tools.
1268 int ntfs_set_shown_files(ntfs_volume
*vol
,
1269 BOOL show_sys_files
, BOOL show_hid_files
,
1270 BOOL hide_dot_files
)
1276 NVolClearShowSysFiles(vol
);
1277 NVolClearShowHidFiles(vol
);
1278 NVolClearHideDotFiles(vol
);
1280 NVolSetShowSysFiles(vol
);
1282 NVolSetShowHidFiles(vol
);
1284 NVolSetHideDotFiles(vol
);
1288 ntfs_log_error("Failed to set file visibility\n");
1293 * Set ignore case mode
1296 int ntfs_set_ignore_case(ntfs_volume
*vol
)
1301 if (vol
&& vol
->upcase
) {
1302 vol
->locase
= ntfs_locase_table_build(vol
->upcase
,
1305 NVolClearCaseSensitive(vol
);
1310 ntfs_log_error("Failed to set ignore_case mode\n");
1315 * ntfs_mount - open ntfs volume
1316 * @name: name of device/file to open
1317 * @flags: optional mount flags
1319 * This function mounts an ntfs volume. @name should contain the name of the
1320 * device/file to mount as the ntfs volume.
1322 * @flags is an optional second parameter. The same flags are used as for
1323 * the mount system call (man 2 mount). Currently only the following flags
1325 * NTFS_MNT_RDONLY - mount volume read-only
1327 * The function opens the device or file @name and verifies that it contains a
1328 * valid bootsector. Then, it allocates an ntfs_volume structure and initializes
1329 * some of the values inside the structure from the information stored in the
1330 * bootsector. It proceeds to load the necessary system files and completes
1331 * setting up the structure.
1333 * Return the allocated volume structure on success and NULL on error with
1334 * errno set to the error code.
1336 * Note, that a copy is made of @name, and hence it can be discarded as
1337 * soon as the function returns.
1339 ntfs_volume
*ntfs_mount(const char *name
__attribute__((unused
)),
1340 ntfs_mount_flags flags
__attribute__((unused
)))
1342 #ifndef NO_NTFS_DEVICE_DEFAULT_IO_OPS
1343 struct ntfs_device
*dev
;
1346 /* Allocate an ntfs_device structure. */
1347 dev
= ntfs_device_alloc(name
, 0, &ntfs_device_default_io_ops
, NULL
);
1350 /* Call ntfs_device_mount() to do the actual mount. */
1351 vol
= ntfs_device_mount(dev
, flags
);
1354 ntfs_device_free(dev
);
1357 ntfs_create_lru_caches(vol
);
1361 * ntfs_mount() makes no sense if NO_NTFS_DEVICE_DEFAULT_IO_OPS is
1362 * defined as there are no device operations available in libntfs in
1371 * ntfs_umount - close ntfs volume
1372 * @vol: address of ntfs_volume structure of volume to close
1373 * @force: if true force close the volume even if it is busy
1375 * Deallocate all structures (including @vol itself) associated with the ntfs
1378 * Return 0 on success. On error return -1 with errno set appropriately
1379 * (most likely to one of EAGAIN, EBUSY or EINVAL). The EAGAIN error means that
1380 * an operation is in progress and if you try the close later the operation
1381 * might be completed and the close succeed.
1383 * If @force is true (i.e. not zero) this function will close the volume even
1384 * if this means that data might be lost.
1386 * @vol must have previously been returned by a call to ntfs_mount().
1388 * @vol itself is deallocated and should no longer be dereferenced after this
1389 * function returns success. If it returns an error then nothing has been done
1390 * so it is safe to continue using @vol.
1392 int ntfs_umount(ntfs_volume
*vol
, const BOOL force
__attribute__((unused
)))
1394 struct ntfs_device
*dev
;
1402 ret
= __ntfs_volume_release(vol
);
1403 ntfs_device_free(dev
);
1407 #ifdef HAVE_MNTENT_H
1410 * ntfs_mntent_check - desc
1412 * If you are wanting to use this, you actually wanted to use
1413 * ntfs_check_if_mounted(), you just didn't realize. (-:
1415 * See description of ntfs_check_if_mounted(), below.
1417 static int ntfs_mntent_check(const char *file
, unsigned long *mnt_flags
)
1420 char *real_file
= NULL
, *real_fsname
= NULL
;
1424 real_file
= ntfs_malloc(PATH_MAX
+ 1);
1427 real_fsname
= ntfs_malloc(PATH_MAX
+ 1);
1432 if (!ntfs_realpath_canonicalize(file
, real_file
)) {
1436 if (!(f
= setmntent(MOUNTED
, "r"))) {
1440 while ((mnt
= getmntent(f
))) {
1441 if (!ntfs_realpath_canonicalize(mnt
->mnt_fsname
, real_fsname
))
1443 if (!strcmp(real_file
, real_fsname
))
1449 *mnt_flags
= NTFS_MF_MOUNTED
;
1450 if (!strcmp(mnt
->mnt_dir
, "/"))
1451 *mnt_flags
|= NTFS_MF_ISROOT
;
1452 #ifdef HAVE_HASMNTOPT
1453 if (hasmntopt(mnt
, "ro") && !hasmntopt(mnt
, "rw"))
1454 *mnt_flags
|= NTFS_MF_READONLY
;
1466 #else /* HAVE_MNTENT_H */
1468 #if defined(__sun) && defined (__SVR4)
1470 static int ntfs_mntent_check(const char *file
, unsigned long *mnt_flags
)
1472 struct mnttab
*mnt
= NULL
;
1473 char *real_file
= NULL
, *real_fsname
= NULL
;
1477 real_file
= (char*)ntfs_malloc(PATH_MAX
+ 1);
1480 real_fsname
= (char*)ntfs_malloc(PATH_MAX
+ 1);
1481 mnt
= (struct mnttab
*)ntfs_malloc(MNT_LINE_MAX
+ 1);
1482 if (!real_fsname
|| !mnt
) {
1486 if (!ntfs_realpath_canonicalize(file
, real_file
)) {
1490 if (!(f
= fopen(MNTTAB
, "r"))) {
1494 while (!getmntent(f
, mnt
)) {
1495 if (!ntfs_realpath_canonicalize(mnt
->mnt_special
, real_fsname
))
1497 if (!strcmp(real_file
, real_fsname
)) {
1498 *mnt_flags
= NTFS_MF_MOUNTED
;
1499 if (!strcmp(mnt
->mnt_mountp
, "/"))
1500 *mnt_flags
|= NTFS_MF_ISROOT
;
1501 if (hasmntopt(mnt
, "ro") && !hasmntopt(mnt
, "rw"))
1502 *mnt_flags
|= NTFS_MF_READONLY
;
1518 #endif /* defined(__sun) && defined (__SVR4) */
1519 #endif /* HAVE_MNTENT_H */
1522 * ntfs_check_if_mounted - check if an ntfs volume is currently mounted
1523 * @file: device file to check
1524 * @mnt_flags: pointer into which to return the ntfs mount flags (see volume.h)
1526 * If the running system does not support the {set,get,end}mntent() calls,
1527 * just return 0 and set *@mnt_flags to zero.
1529 * When the system does support the calls, ntfs_check_if_mounted() first tries
1530 * to find the device @file in /etc/mtab (or wherever this is kept on the
1531 * running system). If it is not found, assume the device is not mounted and
1532 * return 0 and set *@mnt_flags to zero.
1534 * If the device @file is found, set the NTFS_MF_MOUNTED flags in *@mnt_flags.
1536 * Further if @file is mounted as the file system root ("/"), set the flag
1537 * NTFS_MF_ISROOT in *@mnt_flags.
1539 * Finally, check if the file system is mounted read-only, and if so set the
1540 * NTFS_MF_READONLY flag in *@mnt_flags.
1542 * On success return 0 with *@mnt_flags set to the ntfs mount flags.
1544 * On error return -1 with errno set to the error code.
1546 int ntfs_check_if_mounted(const char *file
__attribute__((unused
)),
1547 unsigned long *mnt_flags
)
1550 #if defined(HAVE_MNTENT_H) || (defined(__sun) && defined (__SVR4))
1551 return ntfs_mntent_check(file
, mnt_flags
);
1558 * ntfs_version_is_supported - check if NTFS version is supported.
1559 * @vol: ntfs volume whose version we're interested in.
1561 * The function checks if the NTFS volume version is known or not.
1562 * Version 1.1 and 1.2 are used by Windows NT3.x and NT4.
1563 * Version 2.x is used by Windows 2000 Betas.
1564 * Version 3.0 is used by Windows 2000.
1565 * Version 3.1 is used by Windows XP, Windows Server 2003 and Longhorn.
1567 * Return 0 if NTFS version is supported otherwise -1 with errno set.
1569 * The following error codes are defined:
1570 * EOPNOTSUPP - Unknown NTFS version
1571 * EINVAL - Invalid argument
1573 int ntfs_version_is_supported(ntfs_volume
*vol
)
1582 major
= vol
->major_ver
;
1583 minor
= vol
->minor_ver
;
1585 if (NTFS_V1_1(major
, minor
) || NTFS_V1_2(major
, minor
))
1588 if (NTFS_V2_X(major
, minor
))
1591 if (NTFS_V3_0(major
, minor
) || NTFS_V3_1(major
, minor
))
1599 * ntfs_logfile_reset - "empty" $LogFile data attribute value
1600 * @vol: ntfs volume whose $LogFile we intend to reset.
1602 * Fill the value of the $LogFile data attribute, i.e. the contents of
1603 * the file, with 0xff's, thus marking the journal as empty.
1605 * FIXME(?): We might need to zero the LSN field of every single mft
1606 * record as well. (But, first try without doing that and see what
1607 * happens, since chkdsk might pickup the pieces and do it for us...)
1609 * On success return 0.
1611 * On error return -1 with errno set to the error code.
1613 int ntfs_logfile_reset(ntfs_volume
*vol
)
1624 ni
= ntfs_inode_open(vol
, FILE_LogFile
);
1626 ntfs_log_perror("Failed to open inode FILE_LogFile");
1630 na
= ntfs_attr_open(ni
, AT_DATA
, AT_UNNAMED
, 0);
1633 ntfs_log_perror("Failed to open $FILE_LogFile/$DATA");
1637 if (ntfs_empty_logfile(na
)) {
1639 ntfs_attr_close(na
);
1643 ntfs_attr_close(na
);
1644 return ntfs_inode_close(ni
);
1647 ntfs_inode_close(ni
);
1653 * ntfs_volume_write_flags - set the flags of an ntfs volume
1654 * @vol: ntfs volume where we set the volume flags
1657 * Set the on-disk volume flags in the mft record of $Volume and
1658 * on volume @vol to @flags.
1660 * Return 0 if successful and -1 if not with errno set to the error code.
1662 int ntfs_volume_write_flags(ntfs_volume
*vol
, const le16 flags
)
1665 VOLUME_INFORMATION
*c
;
1666 ntfs_attr_search_ctx
*ctx
;
1667 int ret
= -1; /* failure */
1669 if (!vol
|| !vol
->vol_ni
) {
1673 /* Get a pointer to the volume information attribute. */
1674 ctx
= ntfs_attr_get_search_ctx(vol
->vol_ni
, NULL
);
1678 if (ntfs_attr_lookup(AT_VOLUME_INFORMATION
, AT_UNNAMED
, 0, 0, 0, NULL
,
1680 ntfs_log_error("Attribute $VOLUME_INFORMATION was not found "
1686 if (a
->non_resident
) {
1687 ntfs_log_error("Attribute $VOLUME_INFORMATION must be resident "
1692 /* Get a pointer to the value of the attribute. */
1693 c
= (VOLUME_INFORMATION
*)(le16_to_cpu(a
->value_offset
) + (char*)a
);
1694 /* Sanity checks. */
1695 if ((char*)c
+ le32_to_cpu(a
->value_length
) > (char*)ctx
->mrec
+
1696 le32_to_cpu(ctx
->mrec
->bytes_in_use
) ||
1697 le16_to_cpu(a
->value_offset
) +
1698 le32_to_cpu(a
->value_length
) > le32_to_cpu(a
->length
)) {
1699 ntfs_log_error("Attribute $VOLUME_INFORMATION in $Volume is "
1704 /* Set the volume flags. */
1705 vol
->flags
= c
->flags
= flags
& VOLUME_FLAGS_MASK
;
1706 /* Write them to disk. */
1707 ntfs_inode_mark_dirty(vol
->vol_ni
);
1708 if (ntfs_inode_sync(vol
->vol_ni
))
1711 ret
= 0; /* success */
1713 ntfs_attr_put_search_ctx(ctx
);
1717 int ntfs_volume_error(int err
)
1723 ret
= NTFS_VOLUME_OK
;
1726 ret
= NTFS_VOLUME_NOT_NTFS
;
1729 ret
= NTFS_VOLUME_CORRUPT
;
1733 * Hibernation and fast restarting are seen the
1734 * same way on a non Windows-system partition.
1736 ret
= NTFS_VOLUME_HIBERNATED
;
1739 ret
= NTFS_VOLUME_UNCLEAN_UNMOUNT
;
1742 ret
= NTFS_VOLUME_LOCKED
;
1745 ret
= NTFS_VOLUME_RAID
;
1748 ret
= NTFS_VOLUME_NO_PRIVILEGE
;
1751 ret
= NTFS_VOLUME_UNKNOWN_REASON
;
1758 void ntfs_mount_error(const char *volume
, const char *mntpoint
, int err
)
1761 case NTFS_VOLUME_NOT_NTFS
:
1762 ntfs_log_error(invalid_ntfs_msg
, volume
);
1764 case NTFS_VOLUME_CORRUPT
:
1765 ntfs_log_error("%s", corrupt_volume_msg
);
1767 case NTFS_VOLUME_HIBERNATED
:
1768 ntfs_log_error(hibernated_volume_msg
, volume
, mntpoint
);
1770 case NTFS_VOLUME_UNCLEAN_UNMOUNT
:
1771 ntfs_log_error("%s", unclean_journal_msg
);
1773 case NTFS_VOLUME_LOCKED
:
1774 ntfs_log_error("%s", opened_volume_msg
);
1776 case NTFS_VOLUME_RAID
:
1777 ntfs_log_error("%s", fakeraid_msg
);
1779 case NTFS_VOLUME_NO_PRIVILEGE
:
1780 ntfs_log_error(access_denied_msg
, volume
);
1785 int ntfs_set_locale(void)
1789 locale
= setlocale(LC_ALL
, "");
1791 locale
= setlocale(LC_ALL
, NULL
);
1792 ntfs_log_error("Couldn't set local environment, using default "
1800 * Feed the counts of free clusters and free mft records
1803 int ntfs_volume_get_free_space(ntfs_volume
*vol
)
1808 ret
= -1; /* default return */
1809 vol
->free_clusters
= ntfs_attr_get_free_bits(vol
->lcnbmp_na
);
1810 if (vol
->free_clusters
< 0) {
1811 ntfs_log_perror("Failed to read NTFS $Bitmap");
1813 na
= vol
->mftbmp_na
;
1814 vol
->free_mft_records
= ntfs_attr_get_free_bits(na
);
1816 if (vol
->free_mft_records
>= 0)
1817 vol
->free_mft_records
+= (na
->allocated_size
- na
->data_size
) << 3;
1819 if (vol
->free_mft_records
< 0)
1820 ntfs_log_perror("Failed to calculate free MFT records");
1828 * ntfs_volume_rename - change the current label on a volume
1829 * @vol: volume to change the label on
1830 * @label: the new label
1831 * @label_len: the length of @label in ntfschars including the terminating NULL
1832 * character, which is mandatory (the value can not exceed 128)
1834 * Change the label on the volume @vol to @label.
1836 int ntfs_volume_rename(ntfs_volume
*vol
, const ntfschar
*label
, int label_len
)
1840 char *new_vol_name
= NULL
;
1841 int new_vol_name_len
;
1844 if (NVolReadOnly(vol
)) {
1845 ntfs_log_error("Refusing to change label on read-only mounted "
1851 label_len
*= sizeof(ntfschar
);
1852 if (label_len
> 0x100) {
1853 ntfs_log_error("New label is too long. Maximum %u characters "
1855 (unsigned)(0x100 / sizeof(ntfschar
)));
1860 na
= ntfs_attr_open(vol
->vol_ni
, AT_VOLUME_NAME
, AT_UNNAMED
, 0);
1862 if (errno
!= ENOENT
) {
1864 ntfs_log_perror("Lookup of $VOLUME_NAME attribute "
1869 /* The volume name attribute does not exist. Need to add it. */
1870 if (ntfs_attr_add(vol
->vol_ni
, AT_VOLUME_NAME
, AT_UNNAMED
, 0,
1871 (const u8
*) label
, label_len
))
1874 ntfs_log_perror("Encountered error while adding "
1875 "$VOLUME_NAME attribute");
1882 if (NAttrNonResident(na
)) {
1884 ntfs_log_error("Error: Attribute $VOLUME_NAME must be "
1889 if (na
->data_size
!= label_len
) {
1890 if (ntfs_attr_truncate(na
, label_len
)) {
1892 ntfs_log_perror("Error resizing resident "
1899 written
= ntfs_attr_pwrite(na
, 0, label_len
, label
);
1900 if (written
== -1) {
1902 ntfs_log_perror("Error when writing "
1903 "$VOLUME_NAME data");
1906 else if (written
!= label_len
) {
1908 ntfs_log_error("Partial write when writing "
1909 "$VOLUME_NAME data.");
1917 ntfs_ucstombs(label
, label_len
, &new_vol_name
, 0);
1918 if (new_vol_name_len
== -1) {
1920 ntfs_log_perror("Error while decoding new volume name");
1924 old_vol_name
= vol
->vol_name
;
1925 vol
->vol_name
= new_vol_name
;
1931 ntfs_attr_close(na
);
1934 return err
? -1 : 0;