summaryrefslogtreecommitdiffstats
path: root/fs/hfs
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-02-16 01:07:24 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-02-16 01:07:24 +0000
commit95db6b748fc86297827fbd9c9ef174d491c9ad89 (patch)
tree27a92a942821cde1edda9a1b088718d436b3efe4 /fs/hfs
parent45b27b0a0652331d104c953a5b192d843fff88f8 (diff)
Merge with Linux 2.3.40.
Diffstat (limited to 'fs/hfs')
-rw-r--r--fs/hfs/ChangeLog4
-rw-r--r--fs/hfs/extent.c21
-rw-r--r--fs/hfs/file.c35
-rw-r--r--fs/hfs/hfs_btree.h24
-rw-r--r--fs/hfs/inode.c6
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;