contents.c revision 8aef66d2125af8de7672a12895276802fcc1948f
179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn/* 279f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn * Copyright (C) 2010 The Android Open Source Project 379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn * 479f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 579f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn * you may not use this file except in compliance with the License. 679f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn * You may obtain a copy of the License at 779f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn * 879f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 979f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn * 1079f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 1179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 1279f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn * See the License for the specific language governing permissions and 1479f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn * limitations under the License. 1579f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn */ 1679f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 1779f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn#include <sys/stat.h> 1879f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn#include <string.h> 1979f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn#include <stdio.h> 2079f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 2179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn#include "ext4_utils.h" 2279f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn#include "ext4.h" 2379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn#include "make_ext4fs.h" 2479f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn#include "allocate.h" 2579f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn#include "contents.h" 2679f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn#include "extent.h" 2779f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn#include "indirect.h" 2879f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 2979f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackbornstatic u32 dentry_size(u32 entries, struct dentry *dentries) 3079f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn{ 3179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn u32 len = 24; 3279f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn unsigned int i; 3379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 3479f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn for (i = 0; i < entries; i++) { 3579f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn unsigned int dentry_len = 8 + 4 * 3679f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn DIV_ROUND_UP(strlen(dentries[i].filename), 4); 3779f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn if (len % info.block_size + dentry_len > info.block_size) 3879f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn len += info.block_size - (len % info.block_size); 3979f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn len += dentry_len; 4079f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn } 4179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 4279f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn return len; 4379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn} 4479f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 4579f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn#define PAD_TO(x, y) (x + (y - (x % y))) 4679f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 4779f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackbornstatic struct ext4_dir_entry_2 *add_dentry(u8 *data, u32 *offset, 4879f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn struct ext4_dir_entry_2 *prev, u32 inode, const char *name, 4979f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn u8 file_type) 5079f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn{ 5179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn u8 name_len = strlen(name); 5279f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn u16 rec_len = 8 + PAD_TO(name_len, 4); 5379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn struct ext4_dir_entry_2 *dentry; 5479f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 5579f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn u32 start_block = *offset / info.block_size; 5679f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn u32 end_block = (*offset + rec_len) / info.block_size; 5779f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn if (start_block != end_block) { 5879f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn /* Adding this dentry will cross a block boundary, so pad the previous 5979f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn dentry to the block boundary */ 6079f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn if (!prev) 6179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn critical_error("no prev"); 6279f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn prev->rec_len += end_block * info.block_size - *offset; 6379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn *offset = end_block * info.block_size; 6479f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn } 6579f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 6679f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn dentry = (struct ext4_dir_entry_2 *)(data + *offset); 6779f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn dentry->inode = inode; 6879f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn dentry->rec_len = rec_len; 6979f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn dentry->name_len = name_len; 7079f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn dentry->file_type = file_type; 7179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn memcpy(dentry->name, name, name_len); 7279f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 7379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn *offset += rec_len; 7479f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn return dentry; 7579f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn} 7679f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 7779f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn/* Creates a directory structure for an array of directory entries, dentries, 7879f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn and stores the location of the structure in an inode. The new inode's 7979f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn .. link is set to dir_inode_num. Stores the location of the inode number 8079f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn of each directory entry into dentries[i].inode, to be filled in later 8179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn when the inode for the entry is allocated. Returns the inode number of the 8279f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn new directory */ 8379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackbornu32 make_directory(u32 dir_inode_num, u32 entries, struct dentry *dentries, 8479f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn u32 dirs) 8579f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn{ 8679f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn struct ext4_inode *inode; 8779f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn u32 blocks = DIV_ROUND_UP(dentry_size(entries, dentries), info.block_size); 8879f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn u64 len = (u64)blocks * info.block_size; 8979f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn u32 offset = 0; 9079f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn u32 inode_num; 9179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn u8 *data; 9279f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn unsigned int i; 9379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn struct ext4_dir_entry_2 *dentry; 9479f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 9579f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn if (dir_inode_num) { 9679f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn inode_num = allocate_inode(info); 9779f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn } else { 9879f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn dir_inode_num = EXT4_ROOT_INO; 9979f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn inode_num = EXT4_ROOT_INO; 10079f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn } 10179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 10279f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn if (inode_num == EXT4_ALLOCATE_FAILED) { 10379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn error("failed to allocate inode\n"); 10479f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn return EXT4_ALLOCATE_FAILED; 10579f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn } 10679f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 10779f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn add_directory(inode_num); 10879f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 10979f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn inode = get_inode(inode_num); 11079f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn if (inode == NULL) { 11179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn error("failed to get inode %u", inode_num); 11279f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn return EXT4_ALLOCATE_FAILED; 11379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn } 11479f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 11579f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn data = inode_allocate_data_extents(inode, len, len); 11679f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn if (data == NULL) { 11779f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn error("failed to allocate %llu extents", len); 11879f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn return EXT4_ALLOCATE_FAILED; 11979f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn } 12079f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 12179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn inode->i_mode = S_IFDIR; 12279f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn inode->i_links_count = dirs + 2; 12379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn inode->i_flags |= aux_info.default_i_flags; 12479f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 12579f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn dentry = NULL; 12679f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 12779f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn dentry = add_dentry(data, &offset, NULL, inode_num, ".", EXT4_FT_DIR); 12879f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn if (!dentry) { 12979f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn error("failed to add . directory"); 13079f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn return EXT4_ALLOCATE_FAILED; 13179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn } 13279f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 13379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn dentry = add_dentry(data, &offset, dentry, dir_inode_num, "..", EXT4_FT_DIR); 13479f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn if (!dentry) { 13579f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn error("failed to add .. directory"); 13679f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn return EXT4_ALLOCATE_FAILED; 13779f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn } 13879f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 13979f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn for (i = 0; i < entries; i++) { 14079f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn dentry = add_dentry(data, &offset, dentry, 0, dentries[i].filename, 14179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn dentries[i].file_type); 14279f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn dentries[i].inode = &dentry->inode; 143f108cdd9ee5efe354d87edd02a07b323298c116cJean-Michel Trivi if (!dentry) { 144f108cdd9ee5efe354d87edd02a07b323298c116cJean-Michel Trivi error("failed to add directory"); 145f108cdd9ee5efe354d87edd02a07b323298c116cJean-Michel Trivi return EXT4_ALLOCATE_FAILED; 146f108cdd9ee5efe354d87edd02a07b323298c116cJean-Michel Trivi } 147f108cdd9ee5efe354d87edd02a07b323298c116cJean-Michel Trivi } 14879f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 14979f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn dentry = (struct ext4_dir_entry_2 *)(data + offset); 15079f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn dentry->inode = 0; 15179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn dentry->rec_len = len - offset; 15279f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn dentry->name_len = 0; 15379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn dentry->file_type = EXT4_FT_UNKNOWN; 15479f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 15579f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn return inode_num; 15679f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn} 15779f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 15879f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn/* Creates a file on disk. Returns the inode number of the new file */ 15979f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackbornu32 make_file(const char *filename, u64 len) 16079f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn{ 16179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn struct ext4_inode *inode; 16279f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn u32 inode_num; 16379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 16479f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn inode_num = allocate_inode(info); 16579f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn if (inode_num == EXT4_ALLOCATE_FAILED) { 16679f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn error("failed to allocate inode\n"); 16779f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn return EXT4_ALLOCATE_FAILED; 16879f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn } 16979f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 17079f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn inode = get_inode(inode_num); 17179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn if (inode == NULL) { 17279f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn error("failed to get inode %u", inode_num); 17379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn return EXT4_ALLOCATE_FAILED; 17479f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn } 17579f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 17679f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn inode_allocate_file_extents(inode, len, filename); 17779f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 17879f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn inode->i_mode = S_IFREG; 17979f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn inode->i_links_count = 1; 18079f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn inode->i_flags |= aux_info.default_i_flags; 18179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 18279f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn return inode_num; 18379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn} 18479f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 18579f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn/* Creates a file on disk. Returns the inode number of the new file */ 18679f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackbornu32 make_link(const char *filename, const char *link) 18779f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn{ 18879f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn struct ext4_inode *inode; 18979f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn u32 inode_num; 19079f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn u32 len = strlen(link); 19179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 19279f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn inode_num = allocate_inode(info); 19379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn if (inode_num == EXT4_ALLOCATE_FAILED) { 19479f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn error("failed to allocate inode\n"); 19579f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn return EXT4_ALLOCATE_FAILED; 19679f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn } 19779f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 19879f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn inode = get_inode(inode_num); 19979f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn if (inode == NULL) { 20079f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn error("failed to get inode %u", inode_num); 20179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn return EXT4_ALLOCATE_FAILED; 20279f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn } 20379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 20479f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn inode->i_mode = S_IFLNK; 20579f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn inode->i_links_count = 1; 20679f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn inode->i_flags |= aux_info.default_i_flags; 20779f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn inode->i_size_lo = len; 20879f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 20979f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn if (len + 1 <= sizeof(inode->i_block)) { 21079f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn /* Fast symlink */ 21179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn memcpy((char*)inode->i_block, link, len); 21279f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn } else { 21379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn u8 *data = inode_allocate_data_indirect(inode, info.block_size, info.block_size); 21479f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn memcpy(data, link, len); 21579f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn inode->i_blocks_lo = info.block_size / 512; 21679f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn } 21779f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 21879f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn return inode_num; 21979f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn} 22079f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 22179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackbornint inode_set_permissions(u32 inode_num, u16 mode, u16 uid, u16 gid) 22279f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn{ 22379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn struct ext4_inode *inode = get_inode(inode_num); 22479f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn 22579f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn if (!inode) 226 return -1; 227 228 inode->i_mode |= mode; 229 inode->i_uid = uid; 230 inode->i_gid = gid; 231 232 return 0; 233} 234