diff --git a/ChangeLog b/ChangeLog index 1a46320c..81bfe438 100644 --- a/ChangeLog +++ b/ChangeLog @@ -32,8 +32,8 @@ xx/xx/2006 - 1.13.1-WIP - ntfsinfo: dump either a minimal (default) or the entire attribute header (--verbose) for all attributes types. Also removed a lot of redundant code and made some formatting corrections. (Szaka) - - libntfs: add ntfs_str2ucs and ntfs_freeucs function, and convert - copy-pastes to use them. (Szaka) + - libntfs: add ntfs_str2ucs(), ntfs_freeucs() and ntfs_mft_usn_dec() + functions, and convert all copy-pastes to use them. (Szaka) 27/02/2006 - 1.13.0 - Lots and lots and lots of fixes and enhancements. diff --git a/include/ntfs/mft.h b/include/ntfs/mft.h index 4d811e79..ce481c21 100644 --- a/include/ntfs/mft.h +++ b/include/ntfs/mft.h @@ -111,6 +111,8 @@ extern ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, ntfs_inode *base_ni); extern int ntfs_mft_record_free(ntfs_volume *vol, ntfs_inode *ni); +extern int ntfs_mft_usn_dec(MFT_RECORD *mrec); + #ifdef NTFS_RICH #include "bitmap.h" diff --git a/libntfs/mft.c b/libntfs/mft.c index afe9a1be..302784bc 100644 --- a/libntfs/mft.c +++ b/libntfs/mft.c @@ -1935,3 +1935,26 @@ int ntfs_mft_add_index(struct ntfs_dir *dir) #endif /* NTFS_RICH */ +/** + * ntfs_mft_usn_dec - Decrement USN by one + * @mrec: pointer to an mft record + * + * On success return 0 and on error return -1 with errno set. + */ +int ntfs_mft_usn_dec(MFT_RECORD *mrec) +{ + u16 usn, *usnp; + + if (!mrec) { + errno = EINVAL; + return -1; + } + usnp = (u16 *)((char *)mrec + le16_to_cpu(mrec->usa_ofs)); + usn = le16_to_cpup(usnp); + if (usn-- <= 1) + usn = 0xfffe; + *usnp = cpu_to_le16(usn); + + return 0; +} + diff --git a/ntfsprogs/mkntfs.c b/ntfsprogs/mkntfs.c index b090a095..2bb882e4 100644 --- a/ntfsprogs/mkntfs.c +++ b/ntfsprogs/mkntfs.c @@ -5101,7 +5101,6 @@ static int mkntfs_redirect(struct mkntfs_options *opts2) pos = g_mftmirr_lcn * g_vol->cluster_size; lw = 1; for (i = 0; i < g_rl_mftmirr[0].length * g_vol->cluster_size / g_vol->mft_record_size; i++) { - u16 usn, *usnp; m = (MFT_RECORD*)(g_buf + i * g_vol->mft_record_size); /* * Decrement the usn by one, so it becomes the same as the one @@ -5109,11 +5108,10 @@ static int mkntfs_redirect(struct mkntfs_options *opts2) * $MFTMirr to have the exact same byte by byte content as * $MFT, rather than just equivalent meaning content. */ - usnp = (u16*)((char*)m + le16_to_cpu(m->usa_ofs)); - usn = le16_to_cpup(usnp); - if (usn-- <= 1) - usn = 0xfffe; - *usnp = cpu_to_le16(usn); + if (ntfs_mft_usn_dec(m)) { + ntfs_log_error("ntfs_mft_usn_dec"); + goto done; + } if (!opts.no_action) lw = ntfs_mst_pwrite(g_vol->dev, pos, 1, g_vol->mft_record_size, g_buf + i * g_vol->mft_record_size); if (lw != 1) { diff --git a/ntfsprogs/ntfsclone.c b/ntfsprogs/ntfsclone.c index 8aa18281..20997b50 100644 --- a/ntfsprogs/ntfsclone.c +++ b/ntfsprogs/ntfsclone.c @@ -1125,13 +1125,8 @@ static void wipe_unused_mft(ntfs_inode *ni) static void mft_record_write_with_same_usn(ntfs_volume *volume, ntfs_inode *ni) { - u16 usn, *usnp; - - usnp = (u16 *)((char *)ni->mrec + le16_to_cpu(ni->mrec->usa_ofs)); - usn = le16_to_cpup(usnp); - if (usn-- <= 1) - usn = 0xfffe; - *usnp = cpu_to_le16(usn); + if (ntfs_mft_usn_dec(ni->mrec)) + perr_exit("ntfs_mft_usn_dec"); if (ntfs_mft_record_write(volume, ni->mft_no, ni->mrec)) perr_exit("ntfs_mft_record_write");