1/* 2 * ntfs_usnjrnl.c - NTFS kernel transaction log ($UsnJrnl) handling. 3 * 4 * Copyright (c) 2006-2011 Anton Altaparmakov. All Rights Reserved. 5 * Portions Copyright (c) 2006-2011 Apple Inc. All Rights Reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright notice, 11 * this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its 16 * contributors may be used to endorse or promote products derived from this 17 * software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * ALTERNATIVELY, provided that this notice and licensing terms are retained in 31 * full, this file may be redistributed and/or modified under the terms of the 32 * GNU General Public License (GPL) Version 2, in which case the provisions of 33 * that version of the GPL will apply to you instead of the license terms 34 * above. You can obtain a copy of the GPL Version 2 at 35 * http://developer.apple.com/opensource/licenses/gpl-2.txt. 36 */ 37 38#include <sys/errno.h> 39 40#include <kern/locks.h> 41 42#include "ntfs_debug.h" 43#include "ntfs_endian.h" 44#include "ntfs_page.h" 45#include "ntfs_time.h" 46#include "ntfs_types.h" 47#include "ntfs_usnjrnl.h" 48#include "ntfs_volume.h" 49 50/** 51 * ntfs_usnjrnl_stamp - stamp the transaction log ($UsnJrnl) on an ntfs volume 52 * @vol: ntfs volume on which to stamp the transaction log 53 * 54 * Stamp the transaction log ($UsnJrnl) on the ntfs volume @vol and return 0 55 * on success and errno on error. 56 * 57 * This function assumes that the transaction log has already been loaded and 58 * consistency checked by a call to ntfs_vfsops.c::ntfs_usnjrnl_load(). 59 */ 60errno_t ntfs_usnjrnl_stamp(ntfs_volume *vol) 61{ 62 ntfs_debug("Entering."); 63 if (!NVolUsnJrnlStamped(vol)) { 64 sle64 j_size, stamp; 65 upl_t upl; 66 upl_page_info_array_t pl; 67 USN_HEADER *uh; 68 ntfs_inode *max_ni; 69 errno_t err; 70 71 lck_spin_lock(&vol->usnjrnl_j_ni->size_lock); 72 j_size = vol->usnjrnl_j_ni->data_size; 73 lck_spin_unlock(&vol->usnjrnl_j_ni->size_lock); 74 max_ni = vol->usnjrnl_max_ni; 75 err = vnode_get(max_ni->vn); 76 if (err) { 77 ntfs_error(vol->mp, "Failed to get vnode for " 78 "$UsnJrnl/$DATA/$Max."); 79 return err; 80 } 81 lck_rw_lock_shared(&max_ni->lock); 82 err = ntfs_page_map(max_ni, 0, &upl, &pl, (u8**)&uh, TRUE); 83 if (err) { 84 ntfs_error(vol->mp, "Failed to read from " 85 "$UsnJrnl/$DATA/$Max attribute."); 86 (void)vnode_put(max_ni->vn); 87 return err; 88 } 89 stamp = ntfs_current_time(); 90 ntfs_debug("Stamping transaction log ($UsnJrnl): old " 91 "journal_id 0x%llx, old lowest_valid_usn " 92 "0x%llx, new journal_id 0x%llx, new " 93 "lowest_valid_usn 0x%llx.", 94 (unsigned long long) 95 sle64_to_cpu(uh->journal_id), 96 (unsigned long long) 97 sle64_to_cpu(uh->lowest_valid_usn), 98 (unsigned long long)sle64_to_cpu(stamp), 99 (unsigned long long)j_size); 100 uh->lowest_valid_usn = cpu_to_sle64(j_size); 101 uh->journal_id = stamp; 102 ntfs_page_unmap(max_ni, upl, pl, TRUE); 103 lck_rw_unlock_shared(&max_ni->lock); 104 (void)vnode_put(max_ni->vn); 105 /* Set the flag so we do not have to do it again on remount. */ 106 NVolSetUsnJrnlStamped(vol); 107 // TODO: Should we mark any times on the base inode $UsnJrnl 108 // for update here? 109 } 110 ntfs_debug("Done."); 111 return 0; 112} 113