/** * ntfs_inode_sync_standard_information - update standard information attribute * @ni: ntfs inode to update standard information * * Return 0 on success or -1 on error with errno set to the error code. */ static int ntfs_inode_sync_standard_information(ntfs_inode *ni) { ntfs_attr_search_ctx *ctx; STANDARD_INFORMATION *std_info; u32 lth; le32 lthle; ntfs_log_trace("Entering for inode %lld\n", (long long)ni->mft_no); ctx = ntfs_attr_get_search_ctx(ni, NULL); if (!ctx) return -1; if (ntfs_attr_lookup(AT_STANDARD_INFORMATION, AT_UNNAMED, 0, CASE_SENSITIVE, 0, NULL, 0, ctx)) { ntfs_log_perror("Failed to sync standard info (inode %lld)", (long long)ni->mft_no); ntfs_attr_put_search_ctx(ctx); return -1; } std_info = (STANDARD_INFORMATION *)((u8 *)ctx->attr + le16_to_cpu(ctx->attr->value_offset)); std_info->file_attributes = ni->flags; if (test_nino_flag(ni, TimesDirty)) { std_info->creation_time = utc2ntfs(ni->creation_time); std_info->last_data_change_time = utc2ntfs(ni->last_data_change_time); std_info->last_mft_change_time = utc2ntfs(ni->last_mft_change_time); std_info->last_access_time = utc2ntfs(ni->last_access_time); } /* JPA update v3.x extensions, ensuring consistency */ lthle = ctx->attr->length; lth = le32_to_cpu(lthle); if (test_nino_flag(ni, v3_Extensions) && (lth <= sizeof(STANDARD_INFORMATION))) ntfs_log_error("bad sync of standard information\n"); if (lth > sizeof(STANDARD_INFORMATION)) { std_info->owner_id = ni->owner_id; std_info->security_id = ni->security_id; std_info->quota_charged = ni->quota_charged; std_info->usn = ni->usn; } ntfs_inode_mark_dirty(ctx->ntfs_ino); ntfs_attr_put_search_ctx(ctx); return 0; }
/** * get_current_ntfs_time - get the current time in little endian NTFS format * * Get the current time from the Linux kernel, convert it to its corresponding * NTFS time and return that in little endian format. */ inline s64 get_current_ntfs_time(void) { /* ignores leap second */ return utc2ntfs(get_seconds()) + xtime.tv_nsec/1000; }
/** * ntfs_inode_sync_file_name - update FILE_NAME attributes * @ni: ntfs inode to update FILE_NAME attributes * * Update all FILE_NAME attributes for inode @ni in the index. * * Return 0 on success or -1 on error with errno set to the error code. */ static int ntfs_inode_sync_file_name(ntfs_inode *ni) { ntfs_attr_search_ctx *ctx = NULL; ntfs_index_context *ictx; ntfs_inode *index_ni; FILE_NAME_ATTR *fn; int err = 0; ntfs_log_trace("Entering for inode %lld\n", (long long)ni->mft_no); ctx = ntfs_attr_get_search_ctx(ni, NULL); if (!ctx) { err = errno; goto err_out; } /* Walk through all FILE_NAME attributes and update them. */ while (!ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, 0, 0, NULL, 0, ctx)) { fn = (FILE_NAME_ATTR *)((u8 *)ctx->attr + le16_to_cpu(ctx->attr->value_offset)); if (MREF_LE(fn->parent_directory) == ni->mft_no) { /* * WARNING: We cheat here and obtain 2 attribute * search contexts for one inode (first we obtained * above, second will be obtained inside * ntfs_index_lookup), it's acceptable for library, * but will deadlock in the kernel. */ index_ni = ni; } else index_ni = ntfs_inode_open(ni->vol, le64_to_cpu(fn->parent_directory)); if (!index_ni) { if (!err) err = errno; ntfs_log_perror("Failed to open inode %lld with index", (long long)le64_to_cpu(fn->parent_directory)); continue; } ictx = ntfs_index_ctx_get(index_ni, NTFS_INDEX_I30, 4); if (!ictx) { if (!err) err = errno; ntfs_log_perror("Failed to get index ctx, inode %lld", (long long)index_ni->mft_no); if (ni != index_ni && ntfs_inode_close(index_ni) && !err) err = errno; continue; } if (ntfs_index_lookup(fn, sizeof(FILE_NAME_ATTR), ictx)) { if (!err) { if (errno == ENOENT) err = EIO; else err = errno; } ntfs_log_perror("Index lookup failed, inode %lld", (long long)index_ni->mft_no); ntfs_index_ctx_put(ictx); if (ni != index_ni && ntfs_inode_close(index_ni) && !err) err = errno; continue; } /* Update flags and file size. */ fn = (FILE_NAME_ATTR *)ictx->data; fn->file_attributes = (fn->file_attributes & ~FILE_ATTR_VALID_FLAGS) | (ni->flags & FILE_ATTR_VALID_FLAGS); fn->allocated_size = cpu_to_sle64(ni->allocated_size); fn->data_size = cpu_to_sle64(ni->data_size); if (test_nino_flag(ni, TimesDirty)) { fn->creation_time = utc2ntfs(ni->creation_time); fn->last_data_change_time = utc2ntfs(ni->last_data_change_time); fn->last_mft_change_time = utc2ntfs(ni->last_mft_change_time); fn->last_access_time = utc2ntfs(ni->last_access_time); } ntfs_index_entry_mark_dirty(ictx); ntfs_index_ctx_put(ictx); if ((ni != index_ni) && ntfs_inode_close(index_ni) && !err) err = errno; } /* Check for real error occurred. */ if (errno != ENOENT) { err = errno; ntfs_log_perror("Attribute lookup failed, inode %lld", (long long)ni->mft_no); goto err_out; } ntfs_attr_put_search_ctx(ctx); if (err) { errno = err; return -1; } return 0; err_out: if (ctx) ntfs_attr_put_search_ctx(ctx); errno = err; return -1; }