diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-02-16 01:07:24 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-02-16 01:07:24 +0000 |
commit | 95db6b748fc86297827fbd9c9ef174d491c9ad89 (patch) | |
tree | 27a92a942821cde1edda9a1b088718d436b3efe4 /fs/hfs | |
parent | 45b27b0a0652331d104c953a5b192d843fff88f8 (diff) |
Merge with Linux 2.3.40.
Diffstat (limited to 'fs/hfs')
-rw-r--r-- | fs/hfs/ChangeLog | 4 | ||||
-rw-r--r-- | fs/hfs/extent.c | 21 | ||||
-rw-r--r-- | fs/hfs/file.c | 35 | ||||
-rw-r--r-- | fs/hfs/hfs_btree.h | 24 | ||||
-rw-r--r-- | fs/hfs/inode.c | 6 |
5 files changed, 67 insertions, 23 deletions
diff --git a/fs/hfs/ChangeLog b/fs/hfs/ChangeLog index 11c7d8506..723f2232d 100644 --- a/fs/hfs/ChangeLog +++ b/fs/hfs/ChangeLog @@ -1,3 +1,7 @@ +2000-01-02 a sun <asun@asun.cobalt.com> + + * file.c (hfs_get_block): added hfs_get_block for regular files. + 1999-04-12 a sun <asun@hecate.darksunrising.blah> * file_hdr.c (hdr_read): added rootinfo behaviour for DID header. diff --git a/fs/hfs/extent.c b/fs/hfs/extent.c index 3c92e7def..eca17bc63 100644 --- a/fs/hfs/extent.c +++ b/fs/hfs/extent.c @@ -523,7 +523,7 @@ static void shrink_fork(struct hfs_fork *fork, int ablocks) * Try to add enough allocation blocks to 'fork' * so that it is 'ablock' allocation blocks long. */ -static void grow_fork(struct hfs_fork *fork, int ablocks) +static int grow_fork(struct hfs_fork *fork, int ablocks) { struct hfs_cat_entry *entry = fork->entry; struct hfs_mdb *mdb = entry->mdb; @@ -535,8 +535,8 @@ static void grow_fork(struct hfs_fork *fork, int ablocks) blocks = fork->psize; need = ablocks - blocks/ablksz; - if (need < 1) { - return; + if (need < 1) { /* no need to grow the fork */ + return 0; } /* round up to clumpsize */ @@ -550,7 +550,7 @@ static void grow_fork(struct hfs_fork *fork, int ablocks) /* find last extent record and try to extend it */ if (!(ext = find_ext(fork, blocks/ablksz - 1))) { /* somehow we couldn't find the end of the file! */ - return; + return -1; } /* determine which is the last used extent in the record */ @@ -574,7 +574,7 @@ static void grow_fork(struct hfs_fork *fork, int ablocks) unlock_bitmap(mdb); if (err) { relse_ext(ext); - return; + return -1; } zero_blocks(mdb, start, len); @@ -600,7 +600,7 @@ more_extents: unlock_bitmap(mdb); if (!len || err) { relse_ext(ext); - return; + return -1; } zero_blocks(mdb, start, len); @@ -617,7 +617,7 @@ more_extents: lock_bitmap(mdb); hfs_clear_vbm_bits(mdb, start, len); unlock_bitmap(mdb); - return; + return -1; } } blocks = (fork->psize += len * ablksz); @@ -625,7 +625,7 @@ more_extents: } set_cache(fork, ext); relse_ext(ext); - return; + return 0; } /*================ Global functions ================*/ @@ -738,11 +738,8 @@ int hfs_extent_map(struct hfs_fork *fork, int block, int create) ablock = block / ablksz; if (block >= fork->psize) { - if (create) { - grow_fork(fork, ablock + 1); - } else { + if (!create || (grow_fork(fork, ablock + 1) < 0)) return 0; - } } #if defined(DEBUG_EXTENTS) || defined(DEBUG_ALL) diff --git a/fs/hfs/file.c b/fs/hfs/file.c index 943249478..d5edeac45 100644 --- a/fs/hfs/file.c +++ b/fs/hfs/file.c @@ -28,7 +28,7 @@ static hfs_rwret_t hfs_file_read(struct file *, char *, hfs_rwarg_t, static hfs_rwret_t hfs_file_write(struct file *, const char *, hfs_rwarg_t, loff_t *); static void hfs_file_truncate(struct inode *); -static int hfs_bmap(struct inode *, int); +static int hfs_get_block(struct inode *, long, struct buffer_head *, int); /*================ Global variables ================*/ @@ -61,7 +61,7 @@ struct inode_operations hfs_file_inode_operations = { NULL, /* rename */ NULL, /* readlink */ NULL, /* follow_link */ - hfs_bmap, /* get_block */ + hfs_get_block, /* get_block */ block_read_full_page, /* readpage */ NULL, /* writepage */ hfs_file_truncate, /* truncate */ @@ -124,19 +124,37 @@ struct buffer_head *hfs_getblk(struct hfs_fork *fork, int block, int create) } /* - * hfs_bmap() + * hfs_get_block * - * This is the bmap() field in the inode_operations structure for + * This is the hfs_get_block() field in the inode_operations structure for * "regular" (non-header) files. The purpose is to translate an inode * and a block number within the corresponding file into a physical * block number. This function just calls hfs_extent_map() to do the - * real work. + * real work and then stuffs the appropriate info into the buffer_head. */ -static int hfs_bmap(struct inode * inode, int block) +int hfs_get_block(struct inode *inode, long iblock, struct buffer_head *bh_result, int create) { - return hfs_extent_map(HFS_I(inode)->fork, block, 0); + unsigned long phys; + + phys = hfs_extent_map(HFS_I(inode)->fork, iblock, create); + if (phys) { + bh_result->b_dev = inode->i_dev; + bh_result->b_blocknr = phys; + bh_result->b_state |= (1UL << BH_Mapped); + if (create) + bh_result->b_state |= (1UL << BH_New); + return 0; + } + + if (!create) + return 0; + + /* we tried to add stuff, but we couldn't. send back an out-of-space + * error. */ + return -ENOSPC; } + /* * hfs_file_read() * @@ -146,8 +164,7 @@ static int hfs_bmap(struct inode * inode, int block) * 'filp->offset' bytes into the file. The data is transfered to * user-space at the address 'buf'. Returns the number of bytes * successfully transfered. This function checks the arguments, does - * some setup and then calls hfs_do_read() to do the actual transfer. - */ + * some setup and then calls hfs_do_read() to do the actual transfer. */ static hfs_rwret_t hfs_file_read(struct file * filp, char * buf, hfs_rwarg_t count, loff_t *ppos) { diff --git a/fs/hfs/hfs_btree.h b/fs/hfs/hfs_btree.h index 7f7aea600..97423b350 100644 --- a/fs/hfs/hfs_btree.h +++ b/fs/hfs/hfs_btree.h @@ -34,6 +34,20 @@ #define ndMapNode 0x02 /* Holds part of the bitmap of used nodes */ #define ndLeafNode 0xFF /* A leaf (ndNHeight==1) node */ +/* + * Legal values for the bthAtrb field of a (struct BTHdrRec) + * + * Reference: TN 1150 + */ +#define bthBadClose 0x00000001 /* b-tree not closed properly. not + used by hfsplus. */ +#define bthBigKeys 0x00000002 /* key length is u16 instead of u8. + used by hfsplus. */ +#define bthVarIndxKeys 0x00000004 /* variable key length instead of + max key length. use din catalog + b-tree but not in extents + b-tree (hfsplus). */ + /*================ Function-like macros ================*/ /* Access the cache slot which should contain the desired node */ @@ -70,7 +84,12 @@ struct BTHdrRec { hfs_word_t bthKeyLen; /* (F) The length of a key in an index node */ hfs_lword_t bthNNodes; /* (V) The total number of nodes */ hfs_lword_t bthFree; /* (V) The number of unused nodes */ - hfs_byte_t bthResv[76]; /* Reserved */ + hfs_word_t bthResv1; /* reserved */ + hfs_lword_t bthClpSiz; /* (F) clump size. not usually used. */ + hfs_byte_t bthType; /* (F) BTree type */ + hfs_byte_t bthResv2; /* reserved */ + hfs_lword_t bthAtrb; /* (F) attributes */ + hfs_lword_t bthResv3[16]; /* Reserved */ }; /* @@ -129,6 +148,8 @@ struct hfs_bnode { this node in-core (set for root and head) */ hfs_u32 node; /* Node number */ + hfs_u16 nodeSize; /* node size */ + hfs_u16 keyLen; /* key length */ /* locking related fields: */ hfs_wait_queue wqueue; /* Wait queue for write access */ hfs_wait_queue rqueue; /* Wait queue for read or reserve @@ -176,6 +197,7 @@ struct hfs_btree { int lock; hfs_wait_queue wait; int dirt; + int keySize; /* Fields from the BTHdrRec in native byte-order: */ hfs_u32 bthRoot; hfs_u32 bthNRecs; diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index 8fde9117d..af09655a0 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c @@ -44,14 +44,18 @@ static void init_file_inode(struct inode *inode, hfs_u8 fork) } if (fork == HFS_FK_DATA) { +#if 0 /* XXX: disable crlf translations for now */ hfs_u32 type = hfs_get_nl(entry->info.file.finfo.fdType); - fk = &entry->u.file.data_fork; HFS_I(inode)->convert = ((HFS_SB(inode->i_sb)->s_conv == 't') || ((HFS_SB(inode->i_sb)->s_conv == 'a') && ((type == htonl(0x54455854)) || /* "TEXT" */ (type == htonl(0x7474726f))))); /* "ttro" */ +#else + HFS_I(inode)->convert = 0; +#endif + fk = &entry->u.file.data_fork; } else { fk = &entry->u.file.rsrc_fork; HFS_I(inode)->convert = 0; |