⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mdb.c

📁 《嵌入式系统设计与实例开发实验教材二源码》Linux内核移植与编译实验
💻 C
字号:
/* * linux/fs/hfs/mdb.c * * Copyright (C) 1995-1997  Paul H. Hargrove * This file may be distributed under the terms of the GNU General Public License. * * This file contains functions for reading/writing the MDB. * * "XXX" in a comment is a note to myself to consider changing something. * * In function preconditions the term "valid" applied to a pointer to * a structure means that the pointer is non-NULL and the structure it * points to has all fields initialized to consistent values. * * The code in this file initializes some structures which contain * pointers by calling memset(&foo, 0, sizeof(foo)). * This produces the desired behavior only due to the non-ANSI * assumption that the machine representation of NULL is all zeros. */#include "hfs.h"/*================ File-local data types ================*//*  * The HFS Master Directory Block (MDB). * * Also known as the Volume Information Block (VIB), this structure is * the HFS equivalent of a superblock. * * Reference: _Inside Macintosh: Files_ pages 2-59 through 2-62 * * modified for HFS Extended */struct raw_mdb {	hfs_word_t	drSigWord;	/* Signature word indicating fs type */	hfs_lword_t	drCrDate;	/* fs creation date/time */	hfs_lword_t	drLsMod;	/* fs modification date/time */	hfs_word_t	drAtrb;		/* fs attributes */	hfs_word_t	drNmFls;	/* number of files in root directory */	hfs_word_t	drVBMSt;	/* location (in 512-byte blocks)					   of the volume bitmap */	hfs_word_t	drAllocPtr;	/* location (in allocation blocks)					   to begin next allocation search */	hfs_word_t	drNmAlBlks;	/* number of allocation blocks */	hfs_lword_t	drAlBlkSiz;	/* bytes in an allocation block */	hfs_lword_t	drClpSiz;	/* clumpsize, the number of bytes to					   allocate when extending a file */	hfs_word_t	drAlBlSt;	/* location (in 512-byte blocks)					   of the first allocation block */	hfs_lword_t	drNxtCNID;	/* CNID to assign to the next					   file or directory created */	hfs_word_t	drFreeBks;	/* number of free allocation blocks */	hfs_byte_t	drVN[28];	/* the volume label */	hfs_lword_t	drVolBkUp;	/* fs backup date/time */	hfs_word_t	drVSeqNum;	/* backup sequence number */	hfs_lword_t	drWrCnt;	/* fs write count */	hfs_lword_t	drXTClpSiz;	/* clumpsize for the extents B-tree */	hfs_lword_t	drCTClpSiz;	/* clumpsize for the catalog B-tree */	hfs_word_t	drNmRtDirs;	/* number of directories in					   the root directory */	hfs_lword_t	drFilCnt;	/* number of files in the fs */	hfs_lword_t	drDirCnt;	/* number of directories in the fs */	hfs_byte_t	drFndrInfo[32];	/* data used by the Finder */	hfs_word_t	drEmbedSigWord;	/* embedded volume signature */	hfs_lword_t     drEmbedExtent;  /* starting block number (xdrStABN) 					   and number of allocation blocks 					   (xdrNumABlks) occupied by embedded					   volume */	hfs_lword_t	drXTFlSize;	/* bytes in the extents B-tree */	hfs_byte_t	drXTExtRec[12];	/* extents B-tree's first 3 extents */	hfs_lword_t	drCTFlSize;	/* bytes in the catalog B-tree */	hfs_byte_t	drCTExtRec[12];	/* catalog B-tree's first 3 extents */} __attribute__((packed));/*================ Global functions ================*//* * hfs_mdb_get() * * Build the in-core MDB for a filesystem, including * the B-trees and the volume bitmap. */struct hfs_mdb *hfs_mdb_get(hfs_sysmdb sys_mdb, int readonly,			    hfs_s32 part_start){	struct hfs_mdb *mdb;	hfs_buffer buf;	struct raw_mdb *raw;	unsigned int bs, block;	int lcv, limit;	hfs_buffer *bmbuf;	if (!HFS_NEW(mdb)) {		hfs_warn("hfs_fs: out of memory\n");		return NULL;	}	memset(mdb, 0, sizeof(*mdb));	mdb->magic = HFS_MDB_MAGIC;	mdb->sys_mdb = sys_mdb;	INIT_LIST_HEAD(&mdb->entry_dirty);	hfs_init_waitqueue(&mdb->rename_wait);	hfs_init_waitqueue(&mdb->bitmap_wait);	/* See if this is an HFS filesystem */	buf = hfs_buffer_get(sys_mdb, part_start + HFS_MDB_BLK, 1);	if (!hfs_buffer_ok(buf)) {		hfs_warn("hfs_fs: Unable to read superblock\n");		HFS_DELETE(mdb);		goto bail2;	}	raw = (struct raw_mdb *)hfs_buffer_data(buf);	if (hfs_get_ns(raw->drSigWord) != htons(HFS_SUPER_MAGIC)) {		hfs_buffer_put(buf);		HFS_DELETE(mdb);		goto bail2;	}	mdb->buf = buf;		bs = hfs_get_hl(raw->drAlBlkSiz);	if (!bs || (bs & (HFS_SECTOR_SIZE-1))) {		hfs_warn("hfs_fs: bad allocation block size %d != 512\n", bs);		hfs_buffer_put(buf);		HFS_DELETE(mdb);		goto bail2;	}	mdb->alloc_blksz = bs >> HFS_SECTOR_SIZE_BITS;	/* These parameters are read from the MDB, and never written */	mdb->create_date = hfs_get_hl(raw->drCrDate);	mdb->fs_ablocks  = hfs_get_hs(raw->drNmAlBlks);	mdb->fs_start    = hfs_get_hs(raw->drAlBlSt) + part_start;	mdb->backup_date = hfs_get_hl(raw->drVolBkUp);	mdb->clumpablks  = (hfs_get_hl(raw->drClpSiz) / mdb->alloc_blksz)						 >> HFS_SECTOR_SIZE_BITS;	memcpy(mdb->vname, raw->drVN, sizeof(raw->drVN));	/* These parameters are read from and written to the MDB */	mdb->modify_date  = hfs_get_nl(raw->drLsMod);	mdb->attrib       = hfs_get_ns(raw->drAtrb);	mdb->free_ablocks = hfs_get_hs(raw->drFreeBks);	mdb->next_id      = hfs_get_hl(raw->drNxtCNID);	mdb->write_count  = hfs_get_hl(raw->drWrCnt);	mdb->root_files   = hfs_get_hs(raw->drNmFls);	mdb->root_dirs    = hfs_get_hs(raw->drNmRtDirs);	mdb->file_count   = hfs_get_hl(raw->drFilCnt);	mdb->dir_count    = hfs_get_hl(raw->drDirCnt);	/* TRY to get the alternate (backup) MDB. */	lcv = mdb->fs_start + mdb->fs_ablocks * mdb->alloc_blksz;	limit = lcv + mdb->alloc_blksz;	for (; lcv < limit; ++lcv) {		buf = hfs_buffer_get(sys_mdb, lcv, 1);		if (hfs_buffer_ok(buf)) {			struct raw_mdb *tmp =				(struct raw_mdb *)hfs_buffer_data(buf);						if (hfs_get_ns(tmp->drSigWord) ==			    htons(HFS_SUPER_MAGIC)) {				mdb->alt_buf = buf;				break;			}		}		hfs_buffer_put(buf);	}		if (mdb->alt_buf == NULL) {		hfs_warn("hfs_fs: unable to locate alternate MDB\n");		hfs_warn("hfs_fs: continuing without an alternate MDB\n");	}		/* read in the bitmap */	block = hfs_get_hs(raw->drVBMSt) + part_start;	bmbuf = mdb->bitmap;	lcv = (mdb->fs_ablocks + 4095) / 4096;	for ( ; lcv; --lcv, ++bmbuf, ++block) {		if (!hfs_buffer_ok(*bmbuf =				   hfs_buffer_get(sys_mdb, block, 1))) {			hfs_warn("hfs_fs: unable to read volume bitmap\n");			goto bail1;		}	}	if (!(mdb->ext_tree = hfs_btree_init(mdb, htonl(HFS_EXT_CNID),					     raw->drXTExtRec,					     hfs_get_hl(raw->drXTFlSize),					     hfs_get_hl(raw->drXTClpSiz))) ||	    !(mdb->cat_tree = hfs_btree_init(mdb, htonl(HFS_CAT_CNID),					     raw->drCTExtRec,					     hfs_get_hl(raw->drCTFlSize),					     hfs_get_hl(raw->drCTClpSiz)))) {		hfs_warn("hfs_fs: unable to initialize data structures\n");		goto bail1;	}	if (!(mdb->attrib & htons(HFS_SB_ATTRIB_CLEAN))) {		hfs_warn("hfs_fs: WARNING: mounting unclean filesystem.\n");	} else if (!readonly) {		/* Mark the volume uncleanly unmounted in case we crash */		hfs_put_ns(mdb->attrib & htons(~HFS_SB_ATTRIB_CLEAN),			   raw->drAtrb);		hfs_buffer_dirty(mdb->buf);		hfs_buffer_sync(mdb->buf);	}	return mdb;bail1:	hfs_mdb_put(mdb, readonly);bail2:	return NULL;}/* * hfs_mdb_commit() * * Description: *   This updates the MDB on disk (look also at hfs_write_super()). *   It does not check, if the superblock has been modified, or *   if the filesystem has been mounted read-only. It is mainly *   called by hfs_write_super() and hfs_btree_extend(). * Input Variable(s): *   struct hfs_mdb *mdb: Pointer to the hfs MDB *   int backup; * Output Variable(s): *   NONE * Returns: *   void * Preconditions: *   'mdb' points to a "valid" (struct hfs_mdb). * Postconditions: *   The HFS MDB and on disk will be updated, by copying the possibly *   modified fields from the in memory MDB (in native byte order) to *   the disk block buffer. *   If 'backup' is non-zero then the alternate MDB is also written *   and the function doesn't return until it is actually on disk. */void hfs_mdb_commit(struct hfs_mdb *mdb, int backup){	struct raw_mdb *raw = (struct raw_mdb *)hfs_buffer_data(mdb->buf);	/* Commit catalog entries to buffers */	hfs_cat_commit(mdb);	/* Commit B-tree data to buffers */	hfs_btree_commit(mdb->cat_tree, raw->drCTExtRec, raw->drCTFlSize);	hfs_btree_commit(mdb->ext_tree, raw->drXTExtRec, raw->drXTFlSize);	/* Update write_count and modify_date */	++mdb->write_count;	mdb->modify_date = hfs_time();	/* These parameters may have been modified, so write them back */	hfs_put_nl(mdb->modify_date,   raw->drLsMod);	hfs_put_hs(mdb->free_ablocks,  raw->drFreeBks);	hfs_put_hl(mdb->next_id,       raw->drNxtCNID);	hfs_put_hl(mdb->write_count,   raw->drWrCnt);	hfs_put_hs(mdb->root_files,    raw->drNmFls);	hfs_put_hs(mdb->root_dirs,     raw->drNmRtDirs);	hfs_put_hl(mdb->file_count,    raw->drFilCnt);	hfs_put_hl(mdb->dir_count,     raw->drDirCnt);	/* write MDB to disk */	hfs_buffer_dirty(mdb->buf);       	/* write the backup MDB, not returning until it is written.          * we only do this when either the catalog or extents overflow         * files grow. */        if (backup && hfs_buffer_ok(mdb->alt_buf)) {		struct raw_mdb *tmp = (struct raw_mdb *)			hfs_buffer_data(mdb->alt_buf);				if ((hfs_get_hl(tmp->drCTFlSize) < 		     hfs_get_hl(raw->drCTFlSize)) ||		    (hfs_get_hl(tmp->drXTFlSize) <		     hfs_get_hl(raw->drXTFlSize))) {			memcpy(hfs_buffer_data(mdb->alt_buf), 			       hfs_buffer_data(mdb->buf), HFS_SECTOR_SIZE); 			hfs_buffer_dirty(mdb->alt_buf);			hfs_buffer_sync(mdb->alt_buf);		}        }}/* * hfs_mdb_put() * * Release the resources associated with the in-core MDB.  */void hfs_mdb_put(struct hfs_mdb *mdb, int readonly) {	int lcv;	/* invalidate cached catalog entries */	hfs_cat_invalidate(mdb);	/* free the B-trees */	hfs_btree_free(mdb->ext_tree);	hfs_btree_free(mdb->cat_tree);	/* free the volume bitmap */	for (lcv = 0; lcv < HFS_BM_MAXBLOCKS; ++lcv) {		hfs_buffer_put(mdb->bitmap[lcv]);	}	/* update volume attributes */	if (!readonly) {		struct raw_mdb *raw = 				(struct raw_mdb *)hfs_buffer_data(mdb->buf);		hfs_put_ns(mdb->attrib, raw->drAtrb);		hfs_buffer_dirty(mdb->buf);	}	/* free the buffers holding the primary and alternate MDBs */	hfs_buffer_put(mdb->buf);	hfs_buffer_put(mdb->alt_buf);	/* free the MDB */	HFS_DELETE(mdb);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -