📄 inodes.c
字号:
/* * Copyright (c) International Business Machines Corp., 2000-2002 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include "jfs_types.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stddef.h>#include <time.h>#include <errno.h>#include "jfs_endian.h"#include "jfs_filsys.h"#include "jfs_dinode.h"#include "initmap.h"#include "inode.h"#include "devices.h"#include "inodes.h"#include "debug.h"#include "message.h"/* endian routines */extern unsigned type_jfs;/* * NAME: init_aggr_inode_table * * FUNCTION: Initialize aggregate inodes to disk * * PARAMETERS: * aggr_block_size - block size for aggregate * dev_ptr - open port for device to write to * aggr_inodes - Array of initial aggregate inodes. They have been * initialized elsewhere. * num_aggr_inodes - Number of aggregate inodes initialized. * table_loc - Byte offset of table location * inode_map_loc - Block offset of inode map * inode_map_sz - Byte count of inode map * inostamp - Inode stamp to be used for aggregate inodes * * RETURNS: * success: 0 * failure: any other value */int init_aggr_inode_table(int aggr_block_size, HFILE dev_ptr, struct dinode *aggr_inodes, int num_aggr_inodes, int64_t table_loc, int64_t inode_map_loc, int inode_map_sz, unsigned inostamp){ void *buffer; int64_t first_block, last_block, index; int i, rc; struct dinode *buf_ai; /* * Allocate space for first inode extent, and clear */ buffer = calloc(INODE_EXTENT_SIZE, sizeof (char)); if (buffer == NULL) { message_user(MSG_OSO_INSUFF_MEMORY, NULL, 0, OSO_MSG); return (ENOMEM); } /* * Initialize inodes: 0, 1, 3, and 4 * Inode 2 has already been initialized; */ DBG_TRACE(("size of dinode = %d\n", sizeof (struct dinode))) aggr_inodes[AGGR_RESERVED_I].di_nlink = 1; /* * Initialize inode 1: "self" inode */ init_inode(&(aggr_inodes[AGGREGATE_I]), AGGREGATE_I, AGGREGATE_I, inode_map_sz / aggr_block_size, inode_map_sz, inode_map_loc, IFJOURNAL | IFREG, max_extent_data, table_loc / aggr_block_size, aggr_block_size, inostamp); aggr_inodes[AGGREGATE_I].di_gengen = 1; /* * Initialize inode 3: inline log inode */ init_inode(&(aggr_inodes[LOG_I]), AGGREGATE_I, LOG_I, 0, 0, 0, IFJOURNAL | IFREG, no_data, table_loc / aggr_block_size, aggr_block_size, inostamp); /* * Initialize inode 4: bad block inode */ init_inode(&(aggr_inodes[BADBLOCK_I]), AGGREGATE_I, BADBLOCK_I, 0, 0, 0, IFJOURNAL | IFREG | ISPARSE, no_data, table_loc / aggr_block_size, aggr_block_size, inostamp); /* * Copy initialized inodes to buffer */ memcpy(buffer, aggr_inodes, num_aggr_inodes * sizeof (struct dinode)); /* * Write Inode extent to disk */ /* swap if on big endian machine */ /* swap gengen from aggr_inodes[AGGREGATE_I] in buffer */ buf_ai = ((struct dinode *) buffer) + AGGREGATE_I; buf_ai->di_gengen = __le32_to_cpu(buf_ai->di_gengen); for (i = 0; i < num_aggr_inodes; i++) { ujfs_swap_dinode((struct dinode *) buffer, PUT, type_jfs); buffer = (char *) buffer + sizeof (struct dinode); } buffer = (char *) buffer - (num_aggr_inodes * sizeof (struct dinode)); rc = ujfs_rw_diskblocks(dev_ptr, table_loc, INODE_EXTENT_SIZE, buffer, PUT); free(buffer); if (rc != 0) return rc; /* * Mark blocks allocated in block allocation map */ first_block = table_loc / aggr_block_size; last_block = first_block + (INODE_EXTENT_SIZE / aggr_block_size); for (index = first_block; ((index < last_block) && (rc == 0)); index++) { rc = markit(index, ALLOC); } return (rc);}/* * NAME: init_fileset_inode_table * * FUNCTION: Initialize fileset inodes and write to disk * * PARAMETERS: * aggr_block_size - block size for aggregate * dev_ptr - open port for device to write to * inode_location - Filled in with byte offset of first extent of fileset * inode table * inode_size - Filled in with byte count of first extent of fileset * inode table * fileset_start - First block for fileset, will use this to determine * where to put the inodes on disk * fileset_inode_map_loc - First block of fileset inode map * inostamp - stamp for inode * * RETURNS: * success: 0 * failure: any other value */int init_fileset_inode_table(int aggr_block_size, HFILE dev_ptr, int64_t * inode_location, int *inode_size, int64_t fileset_start, int64_t fileset_inode_map_loc, unsigned inostamp){ void *buffer, *bp; struct dinode inode_buffer; int64_t first_block, last_block, index; int i, rc; int root_size; dtroot_t *root_header; /* * Find space for the inode extent * * Release 1 will not support multiple filesets per aggregate, so the * location of the inode extent can be fixed. However in future releases * this will have to be modified to find the space for this extent using * the block allocation map. */#ifdef ONE_FILESET_PER_AGGR /* * The first fileset inode extent is the first thing written for the * fileset, so its location is the start of the fileset */ *inode_location = fileset_start * aggr_block_size;#else *inode_location = get_space(*inode_size);#endif /* ONE_FILESET_PER_AGGR */ /* * Allocate space for first inode extent, and clear */ *inode_size = INODE_EXTENT_SIZE; bp = buffer = calloc(*inode_size, sizeof (char)); if (bp == NULL) { message_user(MSG_OSO_INSUFF_MEMORY, NULL, 0, OSO_MSG); return (ENOMEM); } /* * Inode 0 - Reserved Inode */ memset(&inode_buffer, 0, sizeof (inode_buffer)); init_inode(&inode_buffer, FILESYSTEM_I, FILESET_RSVD_I, 0, 0, 0, IFJOURNAL | IFREG, no_data, fileset_start, aggr_block_size, inostamp); memcpy(bp, &inode_buffer, sizeof (inode_buffer)); bp = (char *) bp + sizeof (inode_buffer); /* * Inode 1 - 2nd half of fileset superblock information * * When we add support for VFS this will be a special inode with * different information. For now we will just make it look like an * empty inode to reserve it. */ memset(&inode_buffer, 0, sizeof (inode_buffer)); init_inode(&inode_buffer, FILESYSTEM_I, FILESET_EXT_I, 0, 0, 0, IFJOURNAL | IFREG, no_data, fileset_start, aggr_block_size, inostamp); memcpy(bp, &inode_buffer, sizeof (inode_buffer)); bp = (char *) bp + sizeof (inode_buffer); /* * Inode 2 - Root directory */ memset(&inode_buffer, 0, sizeof (inode_buffer)); root_size = sizeof (struct dinode) - offsetof(struct dinode, di_inlinedata); init_inode(&inode_buffer, FILESYSTEM_I, ROOT_I, 0, root_size, 0, IFJOURNAL | IFDIR | 0755, no_data, fileset_start, aggr_block_size, inostamp); /* Set number of links for root to account for '.' entry */ inode_buffer.di_nlink = 2; /* * Initialize the directory B+-tree header for the root inode * Since the root directory has no entries the nextindex is 0; nextindex
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -