diff options
Diffstat (limited to 'fs/hfsplus')
| -rw-r--r-- | fs/hfsplus/bfind.c | 3 | ||||
| -rw-r--r-- | fs/hfsplus/bitmap.c | 8 | ||||
| -rw-r--r-- | fs/hfsplus/bnode.c | 11 | ||||
| -rw-r--r-- | fs/hfsplus/brec.c | 2 | ||||
| -rw-r--r-- | fs/hfsplus/btree.c | 37 | ||||
| -rw-r--r-- | fs/hfsplus/catalog.c | 44 | ||||
| -rw-r--r-- | fs/hfsplus/dir.c | 47 | ||||
| -rw-r--r-- | fs/hfsplus/extents.c | 6 | ||||
| -rw-r--r-- | fs/hfsplus/hfsplus_fs.h | 15 | ||||
| -rw-r--r-- | fs/hfsplus/hfsplus_raw.h | 13 | ||||
| -rw-r--r-- | fs/hfsplus/inode.c | 25 | ||||
| -rw-r--r-- | fs/hfsplus/ioctl.c | 1 | ||||
| -rw-r--r-- | fs/hfsplus/options.c | 18 | ||||
| -rw-r--r-- | fs/hfsplus/super.c | 75 | ||||
| -rw-r--r-- | fs/hfsplus/unicode.c | 30 | ||||
| -rw-r--r-- | fs/hfsplus/wrapper.c | 17 |
16 files changed, 199 insertions, 153 deletions
diff --git a/fs/hfsplus/bfind.c b/fs/hfsplus/bfind.c index 257cdde0514b..5007a41f1be9 100644 --- a/fs/hfsplus/bfind.c +++ b/fs/hfsplus/bfind.c | |||
| @@ -64,7 +64,6 @@ int __hfs_brec_find(struct hfs_bnode *bnode, struct hfs_find_data *fd) | |||
| 64 | else | 64 | else |
| 65 | e = rec - 1; | 65 | e = rec - 1; |
| 66 | } while (b <= e); | 66 | } while (b <= e); |
| 67 | //printk("%d: %d,%d,%d\n", bnode->this, b, e, rec); | ||
| 68 | if (rec != e && e >= 0) { | 67 | if (rec != e && e >= 0) { |
| 69 | len = hfs_brec_lenoff(bnode, e, &off); | 68 | len = hfs_brec_lenoff(bnode, e, &off); |
| 70 | keylen = hfs_brec_keylen(bnode, e); | 69 | keylen = hfs_brec_keylen(bnode, e); |
| @@ -127,7 +126,7 @@ int hfs_brec_find(struct hfs_find_data *fd) | |||
| 127 | return res; | 126 | return res; |
| 128 | 127 | ||
| 129 | invalid: | 128 | invalid: |
| 130 | printk("HFS+-fs: inconsistency in B*Tree (%d,%d,%d,%u,%u)\n", | 129 | printk(KERN_ERR "hfs: inconsistency in B*Tree (%d,%d,%d,%u,%u)\n", |
| 131 | height, bnode->height, bnode->type, nidx, parent); | 130 | height, bnode->height, bnode->type, nidx, parent); |
| 132 | res = -EIO; | 131 | res = -EIO; |
| 133 | release: | 132 | release: |
diff --git a/fs/hfsplus/bitmap.c b/fs/hfsplus/bitmap.c index c7d316455fa0..9fb51632303c 100644 --- a/fs/hfsplus/bitmap.c +++ b/fs/hfsplus/bitmap.c | |||
| @@ -29,7 +29,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, u32 offset, u32 *ma | |||
| 29 | return size; | 29 | return size; |
| 30 | 30 | ||
| 31 | dprint(DBG_BITMAP, "block_allocate: %u,%u,%u\n", size, offset, len); | 31 | dprint(DBG_BITMAP, "block_allocate: %u,%u,%u\n", size, offset, len); |
| 32 | down(&HFSPLUS_SB(sb).alloc_file->i_sem); | 32 | mutex_lock(&HFSPLUS_SB(sb).alloc_file->i_mutex); |
| 33 | mapping = HFSPLUS_SB(sb).alloc_file->i_mapping; | 33 | mapping = HFSPLUS_SB(sb).alloc_file->i_mapping; |
| 34 | page = read_cache_page(mapping, offset / PAGE_CACHE_BITS, | 34 | page = read_cache_page(mapping, offset / PAGE_CACHE_BITS, |
| 35 | (filler_t *)mapping->a_ops->readpage, NULL); | 35 | (filler_t *)mapping->a_ops->readpage, NULL); |
| @@ -143,7 +143,7 @@ done: | |||
| 143 | sb->s_dirt = 1; | 143 | sb->s_dirt = 1; |
| 144 | dprint(DBG_BITMAP, "-> %u,%u\n", start, *max); | 144 | dprint(DBG_BITMAP, "-> %u,%u\n", start, *max); |
| 145 | out: | 145 | out: |
| 146 | up(&HFSPLUS_SB(sb).alloc_file->i_sem); | 146 | mutex_unlock(&HFSPLUS_SB(sb).alloc_file->i_mutex); |
| 147 | return start; | 147 | return start; |
| 148 | } | 148 | } |
| 149 | 149 | ||
| @@ -164,7 +164,7 @@ int hfsplus_block_free(struct super_block *sb, u32 offset, u32 count) | |||
| 164 | if ((offset + count) > HFSPLUS_SB(sb).total_blocks) | 164 | if ((offset + count) > HFSPLUS_SB(sb).total_blocks) |
| 165 | return -2; | 165 | return -2; |
| 166 | 166 | ||
| 167 | down(&HFSPLUS_SB(sb).alloc_file->i_sem); | 167 | mutex_lock(&HFSPLUS_SB(sb).alloc_file->i_mutex); |
| 168 | mapping = HFSPLUS_SB(sb).alloc_file->i_mapping; | 168 | mapping = HFSPLUS_SB(sb).alloc_file->i_mapping; |
| 169 | pnr = offset / PAGE_CACHE_BITS; | 169 | pnr = offset / PAGE_CACHE_BITS; |
| 170 | page = read_cache_page(mapping, pnr, (filler_t *)mapping->a_ops->readpage, NULL); | 170 | page = read_cache_page(mapping, pnr, (filler_t *)mapping->a_ops->readpage, NULL); |
| @@ -215,7 +215,7 @@ out: | |||
| 215 | kunmap(page); | 215 | kunmap(page); |
| 216 | HFSPLUS_SB(sb).free_blocks += len; | 216 | HFSPLUS_SB(sb).free_blocks += len; |
| 217 | sb->s_dirt = 1; | 217 | sb->s_dirt = 1; |
| 218 | up(&HFSPLUS_SB(sb).alloc_file->i_sem); | 218 | mutex_unlock(&HFSPLUS_SB(sb).alloc_file->i_mutex); |
| 219 | 219 | ||
| 220 | return 0; | 220 | return 0; |
| 221 | } | 221 | } |
diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 930cd9212de8..8f07e8fbd03d 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c | |||
| @@ -358,7 +358,7 @@ void hfs_bnode_unlink(struct hfs_bnode *node) | |||
| 358 | 358 | ||
| 359 | // move down? | 359 | // move down? |
| 360 | if (!node->prev && !node->next) { | 360 | if (!node->prev && !node->next) { |
| 361 | printk("hfs_btree_del_level\n"); | 361 | printk(KERN_DEBUG "hfs_btree_del_level\n"); |
| 362 | } | 362 | } |
| 363 | if (!node->parent) { | 363 | if (!node->parent) { |
| 364 | tree->root = 0; | 364 | tree->root = 0; |
| @@ -379,7 +379,7 @@ struct hfs_bnode *hfs_bnode_findhash(struct hfs_btree *tree, u32 cnid) | |||
| 379 | struct hfs_bnode *node; | 379 | struct hfs_bnode *node; |
| 380 | 380 | ||
| 381 | if (cnid >= tree->node_count) { | 381 | if (cnid >= tree->node_count) { |
| 382 | printk("HFS+-fs: request for non-existent node %d in B*Tree\n", cnid); | 382 | printk(KERN_ERR "hfs: request for non-existent node %d in B*Tree\n", cnid); |
| 383 | return NULL; | 383 | return NULL; |
| 384 | } | 384 | } |
| 385 | 385 | ||
| @@ -402,7 +402,7 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid) | |||
| 402 | loff_t off; | 402 | loff_t off; |
| 403 | 403 | ||
| 404 | if (cnid >= tree->node_count) { | 404 | if (cnid >= tree->node_count) { |
| 405 | printk("HFS+-fs: request for non-existent node %d in B*Tree\n", cnid); | 405 | printk(KERN_ERR "hfs: request for non-existent node %d in B*Tree\n", cnid); |
| 406 | return NULL; | 406 | return NULL; |
| 407 | } | 407 | } |
| 408 | 408 | ||
| @@ -576,8 +576,9 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) | |||
| 576 | node = hfs_bnode_findhash(tree, num); | 576 | node = hfs_bnode_findhash(tree, num); |
| 577 | spin_unlock(&tree->hash_lock); | 577 | spin_unlock(&tree->hash_lock); |
| 578 | if (node) { | 578 | if (node) { |
| 579 | printk("new node %u already hashed?\n", num); | 579 | printk(KERN_CRIT "new node %u already hashed?\n", num); |
| 580 | BUG(); | 580 | WARN_ON(1); |
| 581 | return node; | ||
| 581 | } | 582 | } |
| 582 | node = __hfs_bnode_create(tree, num); | 583 | node = __hfs_bnode_create(tree, num); |
| 583 | if (!node) | 584 | if (!node) |
diff --git a/fs/hfsplus/brec.c b/fs/hfsplus/brec.c index 0ccef2ab790c..c88e5d72a402 100644 --- a/fs/hfsplus/brec.c +++ b/fs/hfsplus/brec.c | |||
| @@ -360,7 +360,7 @@ again: | |||
| 360 | end_off = hfs_bnode_read_u16(parent, end_rec_off); | 360 | end_off = hfs_bnode_read_u16(parent, end_rec_off); |
| 361 | if (end_rec_off - end_off < diff) { | 361 | if (end_rec_off - end_off < diff) { |
| 362 | 362 | ||
| 363 | printk("splitting index node...\n"); | 363 | printk(KERN_DEBUG "hfs: splitting index node...\n"); |
| 364 | fd->bnode = parent; | 364 | fd->bnode = parent; |
| 365 | new_node = hfs_bnode_split(fd); | 365 | new_node = hfs_bnode_split(fd); |
| 366 | if (IS_ERR(new_node)) | 366 | if (IS_ERR(new_node)) |
diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c index 44326aa2bd34..a67edfa34e9e 100644 --- a/fs/hfsplus/btree.c +++ b/fs/hfsplus/btree.c | |||
| @@ -31,17 +31,8 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id) | |||
| 31 | 31 | ||
| 32 | init_MUTEX(&tree->tree_lock); | 32 | init_MUTEX(&tree->tree_lock); |
| 33 | spin_lock_init(&tree->hash_lock); | 33 | spin_lock_init(&tree->hash_lock); |
| 34 | /* Set the correct compare function */ | ||
| 35 | tree->sb = sb; | 34 | tree->sb = sb; |
| 36 | tree->cnid = id; | 35 | tree->cnid = id; |
| 37 | if (id == HFSPLUS_EXT_CNID) { | ||
| 38 | tree->keycmp = hfsplus_ext_cmp_key; | ||
| 39 | } else if (id == HFSPLUS_CAT_CNID) { | ||
| 40 | tree->keycmp = hfsplus_cat_cmp_key; | ||
| 41 | } else { | ||
| 42 | printk("HFS+-fs: unknown B*Tree requested\n"); | ||
| 43 | goto free_tree; | ||
| 44 | } | ||
| 45 | tree->inode = iget(sb, id); | 36 | tree->inode = iget(sb, id); |
| 46 | if (!tree->inode) | 37 | if (!tree->inode) |
| 47 | goto free_tree; | 38 | goto free_tree; |
| @@ -64,6 +55,20 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id) | |||
| 64 | tree->max_key_len = be16_to_cpu(head->max_key_len); | 55 | tree->max_key_len = be16_to_cpu(head->max_key_len); |
| 65 | tree->depth = be16_to_cpu(head->depth); | 56 | tree->depth = be16_to_cpu(head->depth); |
| 66 | 57 | ||
| 58 | /* Set the correct compare function */ | ||
| 59 | if (id == HFSPLUS_EXT_CNID) { | ||
| 60 | tree->keycmp = hfsplus_ext_cmp_key; | ||
| 61 | } else if (id == HFSPLUS_CAT_CNID) { | ||
| 62 | if ((HFSPLUS_SB(sb).flags & HFSPLUS_SB_HFSX) && | ||
| 63 | (head->key_type == HFSPLUS_KEY_BINARY)) | ||
| 64 | tree->keycmp = hfsplus_cat_bin_cmp_key; | ||
| 65 | else | ||
| 66 | tree->keycmp = hfsplus_cat_case_cmp_key; | ||
| 67 | } else { | ||
| 68 | printk(KERN_ERR "hfs: unknown B*Tree requested\n"); | ||
| 69 | goto fail_page; | ||
| 70 | } | ||
| 71 | |||
| 67 | size = tree->node_size; | 72 | size = tree->node_size; |
| 68 | if (!size || size & (size - 1)) | 73 | if (!size || size & (size - 1)) |
| 69 | goto fail_page; | 74 | goto fail_page; |
| @@ -99,7 +104,7 @@ void hfs_btree_close(struct hfs_btree *tree) | |||
| 99 | while ((node = tree->node_hash[i])) { | 104 | while ((node = tree->node_hash[i])) { |
| 100 | tree->node_hash[i] = node->next_hash; | 105 | tree->node_hash[i] = node->next_hash; |
| 101 | if (atomic_read(&node->refcnt)) | 106 | if (atomic_read(&node->refcnt)) |
| 102 | printk("HFS+: node %d:%d still has %d user(s)!\n", | 107 | printk(KERN_CRIT "hfs: node %d:%d still has %d user(s)!\n", |
| 103 | node->tree->cnid, node->this, atomic_read(&node->refcnt)); | 108 | node->tree->cnid, node->this, atomic_read(&node->refcnt)); |
| 104 | hfs_bnode_free(node); | 109 | hfs_bnode_free(node); |
| 105 | tree->node_hash_cnt--; | 110 | tree->node_hash_cnt--; |
| @@ -223,10 +228,6 @@ struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree) | |||
| 223 | tree->free_nodes--; | 228 | tree->free_nodes--; |
| 224 | mark_inode_dirty(tree->inode); | 229 | mark_inode_dirty(tree->inode); |
| 225 | hfs_bnode_put(node); | 230 | hfs_bnode_put(node); |
| 226 | if (!idx) { | ||
| 227 | printk("unexpected idx %u (%u)\n", idx, node->this); | ||
| 228 | BUG(); | ||
| 229 | } | ||
| 230 | return hfs_bnode_create(tree, idx); | 231 | return hfs_bnode_create(tree, idx); |
| 231 | } | 232 | } |
| 232 | } | 233 | } |
| @@ -242,7 +243,7 @@ struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree) | |||
| 242 | kunmap(*pagep); | 243 | kunmap(*pagep); |
| 243 | nidx = node->next; | 244 | nidx = node->next; |
| 244 | if (!nidx) { | 245 | if (!nidx) { |
| 245 | printk("create new bmap node...\n"); | 246 | printk(KERN_DEBUG "hfs: create new bmap node...\n"); |
| 246 | next_node = hfs_bmap_new_bmap(node, idx); | 247 | next_node = hfs_bmap_new_bmap(node, idx); |
| 247 | } else | 248 | } else |
| 248 | next_node = hfs_bnode_find(tree, nidx); | 249 | next_node = hfs_bnode_find(tree, nidx); |
| @@ -284,7 +285,7 @@ void hfs_bmap_free(struct hfs_bnode *node) | |||
| 284 | hfs_bnode_put(node); | 285 | hfs_bnode_put(node); |
| 285 | if (!i) { | 286 | if (!i) { |
| 286 | /* panic */; | 287 | /* panic */; |
| 287 | printk("HFS: unable to free bnode %u. bmap not found!\n", node->this); | 288 | printk(KERN_CRIT "hfs: unable to free bnode %u. bmap not found!\n", node->this); |
| 288 | return; | 289 | return; |
| 289 | } | 290 | } |
| 290 | node = hfs_bnode_find(tree, i); | 291 | node = hfs_bnode_find(tree, i); |
| @@ -292,7 +293,7 @@ void hfs_bmap_free(struct hfs_bnode *node) | |||
| 292 | return; | 293 | return; |
| 293 | if (node->type != HFS_NODE_MAP) { | 294 | if (node->type != HFS_NODE_MAP) { |
| 294 | /* panic */; | 295 | /* panic */; |
| 295 | printk("HFS: invalid bmap found! (%u,%d)\n", node->this, node->type); | 296 | printk(KERN_CRIT "hfs: invalid bmap found! (%u,%d)\n", node->this, node->type); |
| 296 | hfs_bnode_put(node); | 297 | hfs_bnode_put(node); |
| 297 | return; | 298 | return; |
| 298 | } | 299 | } |
| @@ -305,7 +306,7 @@ void hfs_bmap_free(struct hfs_bnode *node) | |||
| 305 | m = 1 << (~nidx & 7); | 306 | m = 1 << (~nidx & 7); |
| 306 | byte = data[off]; | 307 | byte = data[off]; |
| 307 | if (!(byte & m)) { | 308 | if (!(byte & m)) { |
| 308 | printk("HFS: trying to free free bnode %u(%d)\n", node->this, node->type); | 309 | printk(KERN_CRIT "hfs: trying to free free bnode %u(%d)\n", node->this, node->type); |
| 309 | kunmap(page); | 310 | kunmap(page); |
| 310 | hfs_bnode_put(node); | 311 | hfs_bnode_put(node); |
| 311 | return; | 312 | return; |
diff --git a/fs/hfsplus/catalog.c b/fs/hfsplus/catalog.c index 94712790c8b3..f2d7c49ce759 100644 --- a/fs/hfsplus/catalog.c +++ b/fs/hfsplus/catalog.c | |||
| @@ -13,7 +13,8 @@ | |||
| 13 | #include "hfsplus_fs.h" | 13 | #include "hfsplus_fs.h" |
| 14 | #include "hfsplus_raw.h" | 14 | #include "hfsplus_raw.h" |
| 15 | 15 | ||
| 16 | int hfsplus_cat_cmp_key(hfsplus_btree_key *k1, hfsplus_btree_key *k2) | 16 | int hfsplus_cat_case_cmp_key(const hfsplus_btree_key *k1, |
| 17 | const hfsplus_btree_key *k2) | ||
| 17 | { | 18 | { |
| 18 | __be32 k1p, k2p; | 19 | __be32 k1p, k2p; |
| 19 | 20 | ||
| @@ -22,7 +23,20 @@ int hfsplus_cat_cmp_key(hfsplus_btree_key *k1, hfsplus_btree_key *k2) | |||
| 22 | if (k1p != k2p) | 23 | if (k1p != k2p) |
| 23 | return be32_to_cpu(k1p) < be32_to_cpu(k2p) ? -1 : 1; | 24 | return be32_to_cpu(k1p) < be32_to_cpu(k2p) ? -1 : 1; |
| 24 | 25 | ||
| 25 | return hfsplus_unistrcmp(&k1->cat.name, &k2->cat.name); | 26 | return hfsplus_strcasecmp(&k1->cat.name, &k2->cat.name); |
| 27 | } | ||
| 28 | |||
| 29 | int hfsplus_cat_bin_cmp_key(const hfsplus_btree_key *k1, | ||
| 30 | const hfsplus_btree_key *k2) | ||
| 31 | { | ||
| 32 | __be32 k1p, k2p; | ||
| 33 | |||
| 34 | k1p = k1->cat.parent; | ||
| 35 | k2p = k2->cat.parent; | ||
| 36 | if (k1p != k2p) | ||
| 37 | return be32_to_cpu(k1p) < be32_to_cpu(k2p) ? -1 : 1; | ||
| 38 | |||
| 39 | return hfsplus_strcmp(&k1->cat.name, &k2->cat.name); | ||
| 26 | } | 40 | } |
| 27 | 41 | ||
| 28 | void hfsplus_cat_build_key(struct super_block *sb, hfsplus_btree_key *key, | 42 | void hfsplus_cat_build_key(struct super_block *sb, hfsplus_btree_key *key, |
| @@ -80,8 +94,11 @@ static int hfsplus_cat_build_record(hfsplus_cat_entry *entry, u32 cnid, struct i | |||
| 80 | memset(folder, 0, sizeof(*folder)); | 94 | memset(folder, 0, sizeof(*folder)); |
| 81 | folder->type = cpu_to_be16(HFSPLUS_FOLDER); | 95 | folder->type = cpu_to_be16(HFSPLUS_FOLDER); |
| 82 | folder->id = cpu_to_be32(inode->i_ino); | 96 | folder->id = cpu_to_be32(inode->i_ino); |
| 83 | folder->create_date = folder->content_mod_date = | 97 | HFSPLUS_I(inode).create_date = |
| 84 | folder->attribute_mod_date = folder->access_date = hfsp_now2mt(); | 98 | folder->create_date = |
| 99 | folder->content_mod_date = | ||
| 100 | folder->attribute_mod_date = | ||
| 101 | folder->access_date = hfsp_now2mt(); | ||
| 85 | hfsplus_set_perms(inode, &folder->permissions); | 102 | hfsplus_set_perms(inode, &folder->permissions); |
| 86 | if (inode == HFSPLUS_SB(inode->i_sb).hidden_dir) | 103 | if (inode == HFSPLUS_SB(inode->i_sb).hidden_dir) |
| 87 | /* invisible and namelocked */ | 104 | /* invisible and namelocked */ |
| @@ -95,18 +112,27 @@ static int hfsplus_cat_build_record(hfsplus_cat_entry *entry, u32 cnid, struct i | |||
| 95 | file->type = cpu_to_be16(HFSPLUS_FILE); | 112 | file->type = cpu_to_be16(HFSPLUS_FILE); |
| 96 | file->flags = cpu_to_be16(HFSPLUS_FILE_THREAD_EXISTS); | 113 | file->flags = cpu_to_be16(HFSPLUS_FILE_THREAD_EXISTS); |
| 97 | file->id = cpu_to_be32(cnid); | 114 | file->id = cpu_to_be32(cnid); |
| 98 | file->create_date = file->content_mod_date = | 115 | HFSPLUS_I(inode).create_date = |
| 99 | file->attribute_mod_date = file->access_date = hfsp_now2mt(); | 116 | file->create_date = |
| 117 | file->content_mod_date = | ||
| 118 | file->attribute_mod_date = | ||
| 119 | file->access_date = hfsp_now2mt(); | ||
| 100 | if (cnid == inode->i_ino) { | 120 | if (cnid == inode->i_ino) { |
| 101 | hfsplus_set_perms(inode, &file->permissions); | 121 | hfsplus_set_perms(inode, &file->permissions); |
| 102 | file->user_info.fdType = cpu_to_be32(HFSPLUS_SB(inode->i_sb).type); | 122 | if (S_ISLNK(inode->i_mode)) { |
| 103 | file->user_info.fdCreator = cpu_to_be32(HFSPLUS_SB(inode->i_sb).creator); | 123 | file->user_info.fdType = cpu_to_be32(HFSP_SYMLINK_TYPE); |
| 124 | file->user_info.fdCreator = cpu_to_be32(HFSP_SYMLINK_CREATOR); | ||
| 125 | } else { | ||
| 126 | file->user_info.fdType = cpu_to_be32(HFSPLUS_SB(inode->i_sb).type); | ||
| 127 | file->user_info.fdCreator = cpu_to_be32(HFSPLUS_SB(inode->i_sb).creator); | ||
| 128 | } | ||
| 104 | if ((file->permissions.rootflags | file->permissions.userflags) & HFSPLUS_FLG_IMMUTABLE) | 129 | if ((file->permissions.rootflags | file->permissions.userflags) & HFSPLUS_FLG_IMMUTABLE) |
| 105 | file->flags |= cpu_to_be16(HFSPLUS_FILE_LOCKED); | 130 | file->flags |= cpu_to_be16(HFSPLUS_FILE_LOCKED); |
| 106 | } else { | 131 | } else { |
| 107 | file->user_info.fdType = cpu_to_be32(HFSP_HARDLINK_TYPE); | 132 | file->user_info.fdType = cpu_to_be32(HFSP_HARDLINK_TYPE); |
| 108 | file->user_info.fdCreator = cpu_to_be32(HFSP_HFSPLUS_CREATOR); | 133 | file->user_info.fdCreator = cpu_to_be32(HFSP_HFSPLUS_CREATOR); |
| 109 | file->user_info.fdFlags = cpu_to_be16(0x100); | 134 | file->user_info.fdFlags = cpu_to_be16(0x100); |
| 135 | file->create_date = HFSPLUS_I(HFSPLUS_SB(inode->i_sb).hidden_dir).create_date; | ||
| 110 | file->permissions.dev = cpu_to_be32(HFSPLUS_I(inode).dev); | 136 | file->permissions.dev = cpu_to_be32(HFSPLUS_I(inode).dev); |
| 111 | } | 137 | } |
| 112 | return sizeof(*file); | 138 | return sizeof(*file); |
| @@ -139,7 +165,7 @@ int hfsplus_find_cat(struct super_block *sb, u32 cnid, | |||
| 139 | 165 | ||
| 140 | type = be16_to_cpu(tmp.type); | 166 | type = be16_to_cpu(tmp.type); |
| 141 | if (type != HFSPLUS_FOLDER_THREAD && type != HFSPLUS_FILE_THREAD) { | 167 | if (type != HFSPLUS_FOLDER_THREAD && type != HFSPLUS_FILE_THREAD) { |
| 142 | printk("HFS+-fs: Found bad thread record in catalog\n"); | 168 | printk(KERN_ERR "hfs: found bad thread record in catalog\n"); |
| 143 | return -EIO; | 169 | return -EIO; |
| 144 | } | 170 | } |
| 145 | 171 | ||
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 50c8f44b6c66..01a6fe3a395c 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c | |||
| @@ -66,25 +66,32 @@ again: | |||
| 66 | } | 66 | } |
| 67 | cnid = be32_to_cpu(entry.file.id); | 67 | cnid = be32_to_cpu(entry.file.id); |
| 68 | if (entry.file.user_info.fdType == cpu_to_be32(HFSP_HARDLINK_TYPE) && | 68 | if (entry.file.user_info.fdType == cpu_to_be32(HFSP_HARDLINK_TYPE) && |
| 69 | entry.file.user_info.fdCreator == cpu_to_be32(HFSP_HFSPLUS_CREATOR)) { | 69 | entry.file.user_info.fdCreator == cpu_to_be32(HFSP_HFSPLUS_CREATOR) && |
| 70 | (entry.file.create_date == HFSPLUS_I(HFSPLUS_SB(sb).hidden_dir).create_date || | ||
| 71 | entry.file.create_date == HFSPLUS_I(sb->s_root->d_inode).create_date) && | ||
| 72 | HFSPLUS_SB(sb).hidden_dir) { | ||
| 70 | struct qstr str; | 73 | struct qstr str; |
| 71 | char name[32]; | 74 | char name[32]; |
| 72 | 75 | ||
| 73 | if (dentry->d_fsdata) { | 76 | if (dentry->d_fsdata) { |
| 74 | err = -ENOENT; | 77 | /* |
| 75 | inode = NULL; | 78 | * We found a link pointing to another link, |
| 76 | goto out; | 79 | * so ignore it and treat it as regular file. |
| 80 | */ | ||
| 81 | cnid = (unsigned long)dentry->d_fsdata; | ||
| 82 | linkid = 0; | ||
| 83 | } else { | ||
| 84 | dentry->d_fsdata = (void *)(unsigned long)cnid; | ||
| 85 | linkid = be32_to_cpu(entry.file.permissions.dev); | ||
| 86 | str.len = sprintf(name, "iNode%d", linkid); | ||
| 87 | str.name = name; | ||
| 88 | hfsplus_cat_build_key(sb, fd.search_key, HFSPLUS_SB(sb).hidden_dir->i_ino, &str); | ||
| 89 | goto again; | ||
| 77 | } | 90 | } |
| 78 | dentry->d_fsdata = (void *)(unsigned long)cnid; | ||
| 79 | linkid = be32_to_cpu(entry.file.permissions.dev); | ||
| 80 | str.len = sprintf(name, "iNode%d", linkid); | ||
| 81 | str.name = name; | ||
| 82 | hfsplus_cat_build_key(sb, fd.search_key, HFSPLUS_SB(sb).hidden_dir->i_ino, &str); | ||
| 83 | goto again; | ||
| 84 | } else if (!dentry->d_fsdata) | 91 | } else if (!dentry->d_fsdata) |
| 85 | dentry->d_fsdata = (void *)(unsigned long)cnid; | 92 | dentry->d_fsdata = (void *)(unsigned long)cnid; |
| 86 | } else { | 93 | } else { |
| 87 | printk("HFS+-fs: Illegal catalog entry type in lookup\n"); | 94 | printk(KERN_ERR "hfs: invalid catalog entry type in lookup\n"); |
| 88 | err = -EIO; | 95 | err = -EIO; |
| 89 | goto fail; | 96 | goto fail; |
| 90 | } | 97 | } |
| @@ -132,12 +139,12 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
| 132 | case 1: | 139 | case 1: |
| 133 | hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength); | 140 | hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength); |
| 134 | if (be16_to_cpu(entry.type) != HFSPLUS_FOLDER_THREAD) { | 141 | if (be16_to_cpu(entry.type) != HFSPLUS_FOLDER_THREAD) { |
| 135 | printk("HFS+-fs: bad catalog folder thread\n"); | 142 | printk(KERN_ERR "hfs: bad catalog folder thread\n"); |
| 136 | err = -EIO; | 143 | err = -EIO; |
| 137 | goto out; | 144 | goto out; |
| 138 | } | 145 | } |
| 139 | if (fd.entrylength < HFSPLUS_MIN_THREAD_SZ) { | 146 | if (fd.entrylength < HFSPLUS_MIN_THREAD_SZ) { |
| 140 | printk("HFS+-fs: truncated catalog thread\n"); | 147 | printk(KERN_ERR "hfs: truncated catalog thread\n"); |
| 141 | err = -EIO; | 148 | err = -EIO; |
| 142 | goto out; | 149 | goto out; |
| 143 | } | 150 | } |
| @@ -156,7 +163,7 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
| 156 | 163 | ||
| 157 | for (;;) { | 164 | for (;;) { |
| 158 | if (be32_to_cpu(fd.key->cat.parent) != inode->i_ino) { | 165 | if (be32_to_cpu(fd.key->cat.parent) != inode->i_ino) { |
| 159 | printk("HFS+-fs: walked past end of dir\n"); | 166 | printk(KERN_ERR "hfs: walked past end of dir\n"); |
| 160 | err = -EIO; | 167 | err = -EIO; |
| 161 | goto out; | 168 | goto out; |
| 162 | } | 169 | } |
| @@ -168,7 +175,7 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
| 168 | goto out; | 175 | goto out; |
| 169 | if (type == HFSPLUS_FOLDER) { | 176 | if (type == HFSPLUS_FOLDER) { |
| 170 | if (fd.entrylength < sizeof(struct hfsplus_cat_folder)) { | 177 | if (fd.entrylength < sizeof(struct hfsplus_cat_folder)) { |
| 171 | printk("HFS+-fs: small dir entry\n"); | 178 | printk(KERN_ERR "hfs: small dir entry\n"); |
| 172 | err = -EIO; | 179 | err = -EIO; |
| 173 | goto out; | 180 | goto out; |
| 174 | } | 181 | } |
| @@ -180,7 +187,7 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
| 180 | break; | 187 | break; |
| 181 | } else if (type == HFSPLUS_FILE) { | 188 | } else if (type == HFSPLUS_FILE) { |
| 182 | if (fd.entrylength < sizeof(struct hfsplus_cat_file)) { | 189 | if (fd.entrylength < sizeof(struct hfsplus_cat_file)) { |
| 183 | printk("HFS+-fs: small file entry\n"); | 190 | printk(KERN_ERR "hfs: small file entry\n"); |
| 184 | err = -EIO; | 191 | err = -EIO; |
| 185 | goto out; | 192 | goto out; |
| 186 | } | 193 | } |
| @@ -188,7 +195,7 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
| 188 | be32_to_cpu(entry.file.id), DT_REG)) | 195 | be32_to_cpu(entry.file.id), DT_REG)) |
| 189 | break; | 196 | break; |
| 190 | } else { | 197 | } else { |
| 191 | printk("HFS+-fs: bad catalog entry type\n"); | 198 | printk(KERN_ERR "hfs: bad catalog entry type\n"); |
| 192 | err = -EIO; | 199 | err = -EIO; |
| 193 | goto out; | 200 | goto out; |
| 194 | } | 201 | } |
| @@ -330,7 +337,8 @@ static int hfsplus_unlink(struct inode *dir, struct dentry *dentry) | |||
| 330 | if (res) | 337 | if (res) |
| 331 | return res; | 338 | return res; |
| 332 | 339 | ||
| 333 | inode->i_nlink--; | 340 | if (inode->i_nlink > 0) |
| 341 | inode->i_nlink--; | ||
| 334 | hfsplus_delete_inode(inode); | 342 | hfsplus_delete_inode(inode); |
| 335 | if (inode->i_ino != cnid && !inode->i_nlink) { | 343 | if (inode->i_ino != cnid && !inode->i_nlink) { |
| 336 | if (!atomic_read(&HFSPLUS_I(inode).opencnt)) { | 344 | if (!atomic_read(&HFSPLUS_I(inode).opencnt)) { |
| @@ -339,7 +347,8 @@ static int hfsplus_unlink(struct inode *dir, struct dentry *dentry) | |||
| 339 | hfsplus_delete_inode(inode); | 347 | hfsplus_delete_inode(inode); |
| 340 | } else | 348 | } else |
| 341 | inode->i_flags |= S_DEAD; | 349 | inode->i_flags |= S_DEAD; |
| 342 | } | 350 | } else |
| 351 | inode->i_nlink = 0; | ||
| 343 | inode->i_ctime = CURRENT_TIME_SEC; | 352 | inode->i_ctime = CURRENT_TIME_SEC; |
| 344 | mark_inode_dirty(inode); | 353 | mark_inode_dirty(inode); |
| 345 | 354 | ||
diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c index e3ff56a03011..1a7480089e82 100644 --- a/fs/hfsplus/extents.c +++ b/fs/hfsplus/extents.c | |||
| @@ -16,7 +16,8 @@ | |||
| 16 | #include "hfsplus_raw.h" | 16 | #include "hfsplus_raw.h" |
| 17 | 17 | ||
| 18 | /* Compare two extents keys, returns 0 on same, pos/neg for difference */ | 18 | /* Compare two extents keys, returns 0 on same, pos/neg for difference */ |
| 19 | int hfsplus_ext_cmp_key(hfsplus_btree_key *k1, hfsplus_btree_key *k2) | 19 | int hfsplus_ext_cmp_key(const hfsplus_btree_key *k1, |
| 20 | const hfsplus_btree_key *k2) | ||
| 20 | { | 21 | { |
| 21 | __be32 k1id, k2id; | 22 | __be32 k1id, k2id; |
| 22 | __be32 k1s, k2s; | 23 | __be32 k1s, k2s; |
| @@ -349,10 +350,9 @@ int hfsplus_file_extend(struct inode *inode) | |||
| 349 | 350 | ||
| 350 | if (HFSPLUS_SB(sb).alloc_file->i_size * 8 < HFSPLUS_SB(sb).total_blocks - HFSPLUS_SB(sb).free_blocks + 8) { | 351 | if (HFSPLUS_SB(sb).alloc_file->i_size * 8 < HFSPLUS_SB(sb).total_blocks - HFSPLUS_SB(sb).free_blocks + 8) { |
| 351 | // extend alloc file | 352 | // extend alloc file |
| 352 | printk("extend alloc file! (%Lu,%u,%u)\n", HFSPLUS_SB(sb).alloc_file->i_size * 8, | 353 | printk(KERN_ERR "hfs: extend alloc file! (%Lu,%u,%u)\n", HFSPLUS_SB(sb).alloc_file->i_size * 8, |
| 353 | HFSPLUS_SB(sb).total_blocks, HFSPLUS_SB(sb).free_blocks); | 354 | HFSPLUS_SB(sb).total_blocks, HFSPLUS_SB(sb).free_blocks); |
| 354 | return -ENOSPC; | 355 | return -ENOSPC; |
| 355 | //BUG(); | ||
| 356 | } | 356 | } |
| 357 | 357 | ||
| 358 | down(&HFSPLUS_I(inode).extents_lock); | 358 | down(&HFSPLUS_I(inode).extents_lock); |
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index df16fcbff3fb..7ae393637a0c 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h | |||
| @@ -36,7 +36,7 @@ | |||
| 36 | #define HFSPLUS_TYPE_DATA 0x00 | 36 | #define HFSPLUS_TYPE_DATA 0x00 |
| 37 | #define HFSPLUS_TYPE_RSRC 0xFF | 37 | #define HFSPLUS_TYPE_RSRC 0xFF |
| 38 | 38 | ||
| 39 | typedef int (*btree_keycmp)(hfsplus_btree_key *, hfsplus_btree_key *); | 39 | typedef int (*btree_keycmp)(const hfsplus_btree_key *, const hfsplus_btree_key *); |
| 40 | 40 | ||
| 41 | #define NODE_HASH_SIZE 256 | 41 | #define NODE_HASH_SIZE 256 |
| 42 | 42 | ||
| @@ -143,15 +143,13 @@ struct hfsplus_sb_info { | |||
| 143 | 143 | ||
| 144 | unsigned long flags; | 144 | unsigned long flags; |
| 145 | 145 | ||
| 146 | atomic_t inode_cnt; | ||
| 147 | u32 last_inode_cnt; | ||
| 148 | |||
| 149 | struct hlist_head rsrc_inodes; | 146 | struct hlist_head rsrc_inodes; |
| 150 | }; | 147 | }; |
| 151 | 148 | ||
| 152 | #define HFSPLUS_SB_WRITEBACKUP 0x0001 | 149 | #define HFSPLUS_SB_WRITEBACKUP 0x0001 |
| 153 | #define HFSPLUS_SB_NODECOMPOSE 0x0002 | 150 | #define HFSPLUS_SB_NODECOMPOSE 0x0002 |
| 154 | #define HFSPLUS_SB_FORCE 0x0004 | 151 | #define HFSPLUS_SB_FORCE 0x0004 |
| 152 | #define HFSPLUS_SB_HFSX 0x0008 | ||
| 155 | 153 | ||
| 156 | 154 | ||
| 157 | struct hfsplus_inode_info { | 155 | struct hfsplus_inode_info { |
| @@ -168,6 +166,7 @@ struct hfsplus_inode_info { | |||
| 168 | struct inode *rsrc_inode; | 166 | struct inode *rsrc_inode; |
| 169 | unsigned long flags; | 167 | unsigned long flags; |
| 170 | 168 | ||
| 169 | __be32 create_date; | ||
| 171 | /* Device number in hfsplus_permissions in catalog */ | 170 | /* Device number in hfsplus_permissions in catalog */ |
| 172 | u32 dev; | 171 | u32 dev; |
| 173 | /* BSD system and user file flags */ | 172 | /* BSD system and user file flags */ |
| @@ -306,7 +305,8 @@ int hfs_brec_read(struct hfs_find_data *, void *, int); | |||
| 306 | int hfs_brec_goto(struct hfs_find_data *, int); | 305 | int hfs_brec_goto(struct hfs_find_data *, int); |
| 307 | 306 | ||
| 308 | /* catalog.c */ | 307 | /* catalog.c */ |
| 309 | int hfsplus_cat_cmp_key(hfsplus_btree_key *, hfsplus_btree_key *); | 308 | int hfsplus_cat_case_cmp_key(const hfsplus_btree_key *, const hfsplus_btree_key *); |
| 309 | int hfsplus_cat_bin_cmp_key(const hfsplus_btree_key *, const hfsplus_btree_key *); | ||
| 310 | void hfsplus_cat_build_key(struct super_block *sb, hfsplus_btree_key *, u32, struct qstr *); | 310 | void hfsplus_cat_build_key(struct super_block *sb, hfsplus_btree_key *, u32, struct qstr *); |
| 311 | int hfsplus_find_cat(struct super_block *, u32, struct hfs_find_data *); | 311 | int hfsplus_find_cat(struct super_block *, u32, struct hfs_find_data *); |
| 312 | int hfsplus_create_cat(u32, struct inode *, struct qstr *, struct inode *); | 312 | int hfsplus_create_cat(u32, struct inode *, struct qstr *, struct inode *); |
| @@ -315,7 +315,7 @@ int hfsplus_rename_cat(u32, struct inode *, struct qstr *, | |||
| 315 | struct inode *, struct qstr *); | 315 | struct inode *, struct qstr *); |
| 316 | 316 | ||
| 317 | /* extents.c */ | 317 | /* extents.c */ |
| 318 | int hfsplus_ext_cmp_key(hfsplus_btree_key *, hfsplus_btree_key *); | 318 | int hfsplus_ext_cmp_key(const hfsplus_btree_key *, const hfsplus_btree_key *); |
| 319 | void hfsplus_ext_write_extent(struct inode *); | 319 | void hfsplus_ext_write_extent(struct inode *); |
| 320 | int hfsplus_get_block(struct inode *, sector_t, struct buffer_head *, int); | 320 | int hfsplus_get_block(struct inode *, sector_t, struct buffer_head *, int); |
| 321 | int hfsplus_free_fork(struct super_block *, u32, struct hfsplus_fork_raw *, int); | 321 | int hfsplus_free_fork(struct super_block *, u32, struct hfsplus_fork_raw *, int); |
| @@ -353,7 +353,8 @@ extern u16 hfsplus_decompose_table[]; | |||
| 353 | extern u16 hfsplus_compose_table[]; | 353 | extern u16 hfsplus_compose_table[]; |
| 354 | 354 | ||
| 355 | /* unicode.c */ | 355 | /* unicode.c */ |
| 356 | int hfsplus_unistrcmp(const struct hfsplus_unistr *, const struct hfsplus_unistr *); | 356 | int hfsplus_strcasecmp(const struct hfsplus_unistr *, const struct hfsplus_unistr *); |
| 357 | int hfsplus_strcmp(const struct hfsplus_unistr *, const struct hfsplus_unistr *); | ||
| 357 | int hfsplus_uni2asc(struct super_block *, const struct hfsplus_unistr *, char *, int *); | 358 | int hfsplus_uni2asc(struct super_block *, const struct hfsplus_unistr *, char *, int *); |
| 358 | int hfsplus_asc2uni(struct super_block *, struct hfsplus_unistr *, const char *, int); | 359 | int hfsplus_asc2uni(struct super_block *, struct hfsplus_unistr *, const char *, int); |
| 359 | 360 | ||
diff --git a/fs/hfsplus/hfsplus_raw.h b/fs/hfsplus/hfsplus_raw.h index b4fbed633219..49205531a500 100644 --- a/fs/hfsplus/hfsplus_raw.h +++ b/fs/hfsplus/hfsplus_raw.h | |||
| @@ -22,8 +22,10 @@ | |||
| 22 | #define HFSPLUS_SECTOR_SHIFT 9 | 22 | #define HFSPLUS_SECTOR_SHIFT 9 |
| 23 | #define HFSPLUS_VOLHEAD_SECTOR 2 | 23 | #define HFSPLUS_VOLHEAD_SECTOR 2 |
| 24 | #define HFSPLUS_VOLHEAD_SIG 0x482b | 24 | #define HFSPLUS_VOLHEAD_SIG 0x482b |
| 25 | #define HFSPLUS_VOLHEAD_SIGX 0x4858 | ||
| 25 | #define HFSPLUS_SUPER_MAGIC 0x482b | 26 | #define HFSPLUS_SUPER_MAGIC 0x482b |
| 26 | #define HFSPLUS_CURRENT_VERSION 4 | 27 | #define HFSPLUS_MIN_VERSION 4 |
| 28 | #define HFSPLUS_CURRENT_VERSION 5 | ||
| 27 | 29 | ||
| 28 | #define HFSP_WRAP_MAGIC 0x4244 | 30 | #define HFSP_WRAP_MAGIC 0x4244 |
| 29 | #define HFSP_WRAP_ATTRIB_SLOCK 0x8000 | 31 | #define HFSP_WRAP_ATTRIB_SLOCK 0x8000 |
| @@ -41,6 +43,9 @@ | |||
| 41 | #define HFSP_HARDLINK_TYPE 0x686c6e6b /* 'hlnk' */ | 43 | #define HFSP_HARDLINK_TYPE 0x686c6e6b /* 'hlnk' */ |
| 42 | #define HFSP_HFSPLUS_CREATOR 0x6866732b /* 'hfs+' */ | 44 | #define HFSP_HFSPLUS_CREATOR 0x6866732b /* 'hfs+' */ |
| 43 | 45 | ||
| 46 | #define HFSP_SYMLINK_TYPE 0x736c6e6b /* 'slnk' */ | ||
| 47 | #define HFSP_SYMLINK_CREATOR 0x72686170 /* 'rhap' */ | ||
| 48 | |||
| 44 | #define HFSP_MOUNT_VERSION 0x482b4c78 /* 'H+Lx' */ | 49 | #define HFSP_MOUNT_VERSION 0x482b4c78 /* 'H+Lx' */ |
| 45 | 50 | ||
| 46 | /* Structures used on disk */ | 51 | /* Structures used on disk */ |
| @@ -161,7 +166,7 @@ struct hfs_btree_header_rec { | |||
| 161 | u16 reserved1; | 166 | u16 reserved1; |
| 162 | __be32 clump_size; | 167 | __be32 clump_size; |
| 163 | u8 btree_type; | 168 | u8 btree_type; |
| 164 | u8 reserved2; | 169 | u8 key_type; |
| 165 | __be32 attributes; | 170 | __be32 attributes; |
| 166 | u32 reserved3[16]; | 171 | u32 reserved3[16]; |
| 167 | } __packed; | 172 | } __packed; |
| @@ -186,6 +191,10 @@ struct hfs_btree_header_rec { | |||
| 186 | #define HFSPLUS_EXCH_CNID 15 /* ExchangeFiles temp id */ | 191 | #define HFSPLUS_EXCH_CNID 15 /* ExchangeFiles temp id */ |
| 187 | #define HFSPLUS_FIRSTUSER_CNID 16 /* first available user id */ | 192 | #define HFSPLUS_FIRSTUSER_CNID 16 /* first available user id */ |
| 188 | 193 | ||
| 194 | /* btree key type */ | ||
| 195 | #define HFSPLUS_KEY_CASEFOLDING 0xCF /* case-insensitive */ | ||
| 196 | #define HFSPLUS_KEY_BINARY 0xBC /* case-sensitive */ | ||
| 197 | |||
| 189 | /* HFS+ catalog entry key */ | 198 | /* HFS+ catalog entry key */ |
| 190 | struct hfsplus_cat_key { | 199 | struct hfsplus_cat_key { |
| 191 | __be16 key_len; | 200 | __be16 key_len; |
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index fc98583cf045..12ed2b7d046b 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c | |||
| @@ -18,13 +18,11 @@ | |||
| 18 | 18 | ||
| 19 | static int hfsplus_readpage(struct file *file, struct page *page) | 19 | static int hfsplus_readpage(struct file *file, struct page *page) |
| 20 | { | 20 | { |
| 21 | //printk("readpage: %lu\n", page->index); | ||
| 22 | return block_read_full_page(page, hfsplus_get_block); | 21 | return block_read_full_page(page, hfsplus_get_block); |
| 23 | } | 22 | } |
| 24 | 23 | ||
| 25 | static int hfsplus_writepage(struct page *page, struct writeback_control *wbc) | 24 | static int hfsplus_writepage(struct page *page, struct writeback_control *wbc) |
| 26 | { | 25 | { |
| 27 | //printk("writepage: %lu\n", page->index); | ||
| 28 | return block_write_full_page(page, hfsplus_get_block, wbc); | 26 | return block_write_full_page(page, hfsplus_get_block, wbc); |
| 29 | } | 27 | } |
| 30 | 28 | ||
| @@ -92,7 +90,6 @@ static int hfsplus_releasepage(struct page *page, gfp_t mask) | |||
| 92 | } while (--i && nidx < tree->node_count); | 90 | } while (--i && nidx < tree->node_count); |
| 93 | spin_unlock(&tree->hash_lock); | 91 | spin_unlock(&tree->hash_lock); |
| 94 | } | 92 | } |
| 95 | //printk("releasepage: %lu,%x = %d\n", page->index, mask, res); | ||
| 96 | return res ? try_to_free_buffers(page) : 0; | 93 | return res ? try_to_free_buffers(page) : 0; |
| 97 | } | 94 | } |
| 98 | 95 | ||
| @@ -182,11 +179,6 @@ static struct dentry *hfsplus_file_lookup(struct inode *dir, struct dentry *dent | |||
| 182 | igrab(dir); | 179 | igrab(dir); |
| 183 | hlist_add_head(&inode->i_hash, &HFSPLUS_SB(sb).rsrc_inodes); | 180 | hlist_add_head(&inode->i_hash, &HFSPLUS_SB(sb).rsrc_inodes); |
| 184 | mark_inode_dirty(inode); | 181 | mark_inode_dirty(inode); |
| 185 | { | ||
| 186 | void hfsplus_inode_check(struct super_block *sb); | ||
| 187 | atomic_inc(&HFSPLUS_SB(sb).inode_cnt); | ||
| 188 | hfsplus_inode_check(sb); | ||
| 189 | } | ||
| 190 | out: | 182 | out: |
| 191 | d_add(dentry, inode); | 183 | d_add(dentry, inode); |
| 192 | return NULL; | 184 | return NULL; |
| @@ -276,13 +268,13 @@ static int hfsplus_file_release(struct inode *inode, struct file *file) | |||
| 276 | if (atomic_read(&file->f_count) != 0) | 268 | if (atomic_read(&file->f_count) != 0) |
| 277 | return 0; | 269 | return 0; |
| 278 | if (atomic_dec_and_test(&HFSPLUS_I(inode).opencnt)) { | 270 | if (atomic_dec_and_test(&HFSPLUS_I(inode).opencnt)) { |
| 279 | down(&inode->i_sem); | 271 | mutex_lock(&inode->i_mutex); |
| 280 | hfsplus_file_truncate(inode); | 272 | hfsplus_file_truncate(inode); |
| 281 | if (inode->i_flags & S_DEAD) { | 273 | if (inode->i_flags & S_DEAD) { |
| 282 | hfsplus_delete_cat(inode->i_ino, HFSPLUS_SB(sb).hidden_dir, NULL); | 274 | hfsplus_delete_cat(inode->i_ino, HFSPLUS_SB(sb).hidden_dir, NULL); |
| 283 | hfsplus_delete_inode(inode); | 275 | hfsplus_delete_inode(inode); |
| 284 | } | 276 | } |
| 285 | up(&inode->i_sem); | 277 | mutex_unlock(&inode->i_mutex); |
| 286 | } | 278 | } |
| 287 | return 0; | 279 | return 0; |
| 288 | } | 280 | } |
| @@ -317,11 +309,6 @@ struct inode *hfsplus_new_inode(struct super_block *sb, int mode) | |||
| 317 | if (!inode) | 309 | if (!inode) |
| 318 | return NULL; | 310 | return NULL; |
| 319 | 311 | ||
| 320 | { | ||
| 321 | void hfsplus_inode_check(struct super_block *sb); | ||
| 322 | atomic_inc(&HFSPLUS_SB(sb).inode_cnt); | ||
| 323 | hfsplus_inode_check(sb); | ||
| 324 | } | ||
| 325 | inode->i_ino = HFSPLUS_SB(sb).next_cnid++; | 312 | inode->i_ino = HFSPLUS_SB(sb).next_cnid++; |
| 326 | inode->i_mode = mode; | 313 | inode->i_mode = mode; |
| 327 | inode->i_uid = current->fsuid; | 314 | inode->i_uid = current->fsuid; |
| @@ -444,7 +431,8 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) | |||
| 444 | inode->i_size = 2 + be32_to_cpu(folder->valence); | 431 | inode->i_size = 2 + be32_to_cpu(folder->valence); |
| 445 | inode->i_atime = hfsp_mt2ut(folder->access_date); | 432 | inode->i_atime = hfsp_mt2ut(folder->access_date); |
| 446 | inode->i_mtime = hfsp_mt2ut(folder->content_mod_date); | 433 | inode->i_mtime = hfsp_mt2ut(folder->content_mod_date); |
| 447 | inode->i_ctime = inode->i_mtime; | 434 | inode->i_ctime = hfsp_mt2ut(folder->attribute_mod_date); |
| 435 | HFSPLUS_I(inode).create_date = folder->create_date; | ||
| 448 | HFSPLUS_I(inode).fs_blocks = 0; | 436 | HFSPLUS_I(inode).fs_blocks = 0; |
| 449 | inode->i_op = &hfsplus_dir_inode_operations; | 437 | inode->i_op = &hfsplus_dir_inode_operations; |
| 450 | inode->i_fop = &hfsplus_dir_operations; | 438 | inode->i_fop = &hfsplus_dir_operations; |
| @@ -475,9 +463,10 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) | |||
| 475 | } | 463 | } |
| 476 | inode->i_atime = hfsp_mt2ut(file->access_date); | 464 | inode->i_atime = hfsp_mt2ut(file->access_date); |
| 477 | inode->i_mtime = hfsp_mt2ut(file->content_mod_date); | 465 | inode->i_mtime = hfsp_mt2ut(file->content_mod_date); |
| 478 | inode->i_ctime = inode->i_mtime; | 466 | inode->i_ctime = hfsp_mt2ut(file->attribute_mod_date); |
| 467 | HFSPLUS_I(inode).create_date = file->create_date; | ||
| 479 | } else { | 468 | } else { |
| 480 | printk("HFS+-fs: bad catalog entry used to create inode\n"); | 469 | printk(KERN_ERR "hfs: bad catalog entry used to create inode\n"); |
| 481 | res = -EIO; | 470 | res = -EIO; |
| 482 | } | 471 | } |
| 483 | return res; | 472 | return res; |
diff --git a/fs/hfsplus/ioctl.c b/fs/hfsplus/ioctl.c index e07aa096e07c..13cf848ac833 100644 --- a/fs/hfsplus/ioctl.c +++ b/fs/hfsplus/ioctl.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | * hfsplus ioctls | 12 | * hfsplus ioctls |
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | #include <linux/capability.h> | ||
| 15 | #include <linux/fs.h> | 16 | #include <linux/fs.h> |
| 16 | #include <linux/sched.h> | 17 | #include <linux/sched.h> |
| 17 | #include <linux/xattr.h> | 18 | #include <linux/xattr.h> |
diff --git a/fs/hfsplus/options.c b/fs/hfsplus/options.c index 935dafba0078..dc64fac00831 100644 --- a/fs/hfsplus/options.c +++ b/fs/hfsplus/options.c | |||
| @@ -83,58 +83,58 @@ int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi) | |||
| 83 | switch (token) { | 83 | switch (token) { |
| 84 | case opt_creator: | 84 | case opt_creator: |
| 85 | if (match_fourchar(&args[0], &sbi->creator)) { | 85 | if (match_fourchar(&args[0], &sbi->creator)) { |
| 86 | printk("HFS+-fs: creator requires a 4 character value\n"); | 86 | printk(KERN_ERR "hfs: creator requires a 4 character value\n"); |
| 87 | return 0; | 87 | return 0; |
| 88 | } | 88 | } |
| 89 | break; | 89 | break; |
| 90 | case opt_type: | 90 | case opt_type: |
| 91 | if (match_fourchar(&args[0], &sbi->type)) { | 91 | if (match_fourchar(&args[0], &sbi->type)) { |
| 92 | printk("HFS+-fs: type requires a 4 character value\n"); | 92 | printk(KERN_ERR "hfs: type requires a 4 character value\n"); |
| 93 | return 0; | 93 | return 0; |
| 94 | } | 94 | } |
| 95 | break; | 95 | break; |
| 96 | case opt_umask: | 96 | case opt_umask: |
| 97 | if (match_octal(&args[0], &tmp)) { | 97 | if (match_octal(&args[0], &tmp)) { |
| 98 | printk("HFS+-fs: umask requires a value\n"); | 98 | printk(KERN_ERR "hfs: umask requires a value\n"); |
| 99 | return 0; | 99 | return 0; |
| 100 | } | 100 | } |
| 101 | sbi->umask = (umode_t)tmp; | 101 | sbi->umask = (umode_t)tmp; |
| 102 | break; | 102 | break; |
| 103 | case opt_uid: | 103 | case opt_uid: |
| 104 | if (match_int(&args[0], &tmp)) { | 104 | if (match_int(&args[0], &tmp)) { |
| 105 | printk("HFS+-fs: uid requires an argument\n"); | 105 | printk(KERN_ERR "hfs: uid requires an argument\n"); |
| 106 | return 0; | 106 | return 0; |
| 107 | } | 107 | } |
| 108 | sbi->uid = (uid_t)tmp; | 108 | sbi->uid = (uid_t)tmp; |
| 109 | break; | 109 | break; |
| 110 | case opt_gid: | 110 | case opt_gid: |
| 111 | if (match_int(&args[0], &tmp)) { | 111 | if (match_int(&args[0], &tmp)) { |
| 112 | printk("HFS+-fs: gid requires an argument\n"); | 112 | printk(KERN_ERR "hfs: gid requires an argument\n"); |
| 113 | return 0; | 113 | return 0; |
| 114 | } | 114 | } |
| 115 | sbi->gid = (gid_t)tmp; | 115 | sbi->gid = (gid_t)tmp; |
| 116 | break; | 116 | break; |
| 117 | case opt_part: | 117 | case opt_part: |
| 118 | if (match_int(&args[0], &sbi->part)) { | 118 | if (match_int(&args[0], &sbi->part)) { |
| 119 | printk("HFS+-fs: part requires an argument\n"); | 119 | printk(KERN_ERR "hfs: part requires an argument\n"); |
| 120 | return 0; | 120 | return 0; |
| 121 | } | 121 | } |
| 122 | break; | 122 | break; |
| 123 | case opt_session: | 123 | case opt_session: |
| 124 | if (match_int(&args[0], &sbi->session)) { | 124 | if (match_int(&args[0], &sbi->session)) { |
| 125 | printk("HFS+-fs: session requires an argument\n"); | 125 | printk(KERN_ERR "hfs: session requires an argument\n"); |
| 126 | return 0; | 126 | return 0; |
| 127 | } | 127 | } |
| 128 | break; | 128 | break; |
| 129 | case opt_nls: | 129 | case opt_nls: |
| 130 | if (sbi->nls) { | 130 | if (sbi->nls) { |
| 131 | printk("HFS+-fs: unable to change nls mapping\n"); | 131 | printk(KERN_ERR "hfs: unable to change nls mapping\n"); |
| 132 | return 0; | 132 | return 0; |
| 133 | } | 133 | } |
| 134 | p = match_strdup(&args[0]); | 134 | p = match_strdup(&args[0]); |
| 135 | sbi->nls = load_nls(p); | 135 | sbi->nls = load_nls(p); |
| 136 | if (!sbi->nls) { | 136 | if (!sbi->nls) { |
| 137 | printk("HFS+-fs: unable to load nls mapping \"%s\"\n", p); | 137 | printk(KERN_ERR "hfs: unable to load nls mapping \"%s\"\n", p); |
| 138 | kfree(p); | 138 | kfree(p); |
| 139 | return 0; | 139 | return 0; |
| 140 | } | 140 | } |
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 8093351bd7c3..7843f792a4b7 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
| @@ -22,29 +22,12 @@ static void hfsplus_destroy_inode(struct inode *inode); | |||
| 22 | 22 | ||
| 23 | #include "hfsplus_fs.h" | 23 | #include "hfsplus_fs.h" |
| 24 | 24 | ||
| 25 | void hfsplus_inode_check(struct super_block *sb) | ||
| 26 | { | ||
| 27 | #if 0 | ||
| 28 | u32 cnt = atomic_read(&HFSPLUS_SB(sb).inode_cnt); | ||
| 29 | u32 last_cnt = HFSPLUS_SB(sb).last_inode_cnt; | ||
| 30 | |||
| 31 | if (cnt <= (last_cnt / 2) || | ||
| 32 | cnt >= (last_cnt * 2)) { | ||
| 33 | HFSPLUS_SB(sb).last_inode_cnt = cnt; | ||
| 34 | printk("inode_check: %u,%u,%u\n", cnt, last_cnt, | ||
| 35 | HFSPLUS_SB(sb).cat_tree ? HFSPLUS_SB(sb).cat_tree->node_hash_cnt : 0); | ||
| 36 | } | ||
| 37 | #endif | ||
| 38 | } | ||
| 39 | |||
| 40 | static void hfsplus_read_inode(struct inode *inode) | 25 | static void hfsplus_read_inode(struct inode *inode) |
| 41 | { | 26 | { |
| 42 | struct hfs_find_data fd; | 27 | struct hfs_find_data fd; |
| 43 | struct hfsplus_vh *vhdr; | 28 | struct hfsplus_vh *vhdr; |
| 44 | int err; | 29 | int err; |
| 45 | 30 | ||
| 46 | atomic_inc(&HFSPLUS_SB(inode->i_sb).inode_cnt); | ||
| 47 | hfsplus_inode_check(inode->i_sb); | ||
| 48 | INIT_LIST_HEAD(&HFSPLUS_I(inode).open_dir_list); | 31 | INIT_LIST_HEAD(&HFSPLUS_I(inode).open_dir_list); |
| 49 | init_MUTEX(&HFSPLUS_I(inode).extents_lock); | 32 | init_MUTEX(&HFSPLUS_I(inode).extents_lock); |
| 50 | HFSPLUS_I(inode).flags = 0; | 33 | HFSPLUS_I(inode).flags = 0; |
| @@ -155,12 +138,10 @@ static int hfsplus_write_inode(struct inode *inode, int unused) | |||
| 155 | static void hfsplus_clear_inode(struct inode *inode) | 138 | static void hfsplus_clear_inode(struct inode *inode) |
| 156 | { | 139 | { |
| 157 | dprint(DBG_INODE, "hfsplus_clear_inode: %lu\n", inode->i_ino); | 140 | dprint(DBG_INODE, "hfsplus_clear_inode: %lu\n", inode->i_ino); |
| 158 | atomic_dec(&HFSPLUS_SB(inode->i_sb).inode_cnt); | ||
| 159 | if (HFSPLUS_IS_RSRC(inode)) { | 141 | if (HFSPLUS_IS_RSRC(inode)) { |
| 160 | HFSPLUS_I(HFSPLUS_I(inode).rsrc_inode).rsrc_inode = NULL; | 142 | HFSPLUS_I(HFSPLUS_I(inode).rsrc_inode).rsrc_inode = NULL; |
| 161 | iput(HFSPLUS_I(inode).rsrc_inode); | 143 | iput(HFSPLUS_I(inode).rsrc_inode); |
| 162 | } | 144 | } |
| 163 | hfsplus_inode_check(inode->i_sb); | ||
| 164 | } | 145 | } |
| 165 | 146 | ||
| 166 | static void hfsplus_write_super(struct super_block *sb) | 147 | static void hfsplus_write_super(struct super_block *sb) |
| @@ -188,7 +169,7 @@ static void hfsplus_write_super(struct super_block *sb) | |||
| 188 | block = HFSPLUS_SB(sb).blockoffset; | 169 | block = HFSPLUS_SB(sb).blockoffset; |
| 189 | block += (HFSPLUS_SB(sb).sect_count - 2) >> (sb->s_blocksize_bits - 9); | 170 | block += (HFSPLUS_SB(sb).sect_count - 2) >> (sb->s_blocksize_bits - 9); |
| 190 | offset = ((HFSPLUS_SB(sb).sect_count - 2) << 9) & (sb->s_blocksize - 1); | 171 | offset = ((HFSPLUS_SB(sb).sect_count - 2) << 9) & (sb->s_blocksize - 1); |
| 191 | printk("backup: %u,%u,%u,%u\n", HFSPLUS_SB(sb).blockoffset, | 172 | printk(KERN_DEBUG "hfs: backup: %u,%u,%u,%u\n", HFSPLUS_SB(sb).blockoffset, |
| 192 | HFSPLUS_SB(sb).sect_count, block, offset); | 173 | HFSPLUS_SB(sb).sect_count, block, offset); |
| 193 | bh = sb_bread(sb, block); | 174 | bh = sb_bread(sb, block); |
| 194 | if (bh) { | 175 | if (bh) { |
| @@ -198,7 +179,7 @@ static void hfsplus_write_super(struct super_block *sb) | |||
| 198 | mark_buffer_dirty(bh); | 179 | mark_buffer_dirty(bh); |
| 199 | brelse(bh); | 180 | brelse(bh); |
| 200 | } else | 181 | } else |
| 201 | printk("backup not found!\n"); | 182 | printk(KERN_WARNING "hfs: backup not found!\n"); |
| 202 | } | 183 | } |
| 203 | } | 184 | } |
| 204 | HFSPLUS_SB(sb).flags &= ~HFSPLUS_SB_WRITEBACKUP; | 185 | HFSPLUS_SB(sb).flags &= ~HFSPLUS_SB_WRITEBACKUP; |
| @@ -259,18 +240,18 @@ static int hfsplus_remount(struct super_block *sb, int *flags, char *data) | |||
| 259 | return -EINVAL; | 240 | return -EINVAL; |
| 260 | 241 | ||
| 261 | if (!(vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_UNMNT))) { | 242 | if (!(vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_UNMNT))) { |
| 262 | printk("HFS+-fs warning: Filesystem was not cleanly unmounted, " | 243 | printk(KERN_WARNING "hfs: filesystem was not cleanly unmounted, " |
| 263 | "running fsck.hfsplus is recommended. leaving read-only.\n"); | 244 | "running fsck.hfsplus is recommended. leaving read-only.\n"); |
| 264 | sb->s_flags |= MS_RDONLY; | 245 | sb->s_flags |= MS_RDONLY; |
| 265 | *flags |= MS_RDONLY; | 246 | *flags |= MS_RDONLY; |
| 266 | } else if (sbi.flags & HFSPLUS_SB_FORCE) { | 247 | } else if (sbi.flags & HFSPLUS_SB_FORCE) { |
| 267 | /* nothing */ | 248 | /* nothing */ |
| 268 | } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) { | 249 | } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) { |
| 269 | printk("HFS+-fs: Filesystem is marked locked, leaving read-only.\n"); | 250 | printk(KERN_WARNING "hfs: filesystem is marked locked, leaving read-only.\n"); |
| 270 | sb->s_flags |= MS_RDONLY; | 251 | sb->s_flags |= MS_RDONLY; |
| 271 | *flags |= MS_RDONLY; | 252 | *flags |= MS_RDONLY; |
| 272 | } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) { | 253 | } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) { |
| 273 | printk("HFS+-fs: Filesystem is marked journaled, leaving read-only.\n"); | 254 | printk(KERN_WARNING "hfs: filesystem is marked journaled, leaving read-only.\n"); |
| 274 | sb->s_flags |= MS_RDONLY; | 255 | sb->s_flags |= MS_RDONLY; |
| 275 | *flags |= MS_RDONLY; | 256 | *flags |= MS_RDONLY; |
| 276 | } | 257 | } |
| @@ -311,8 +292,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
| 311 | INIT_HLIST_HEAD(&sbi->rsrc_inodes); | 292 | INIT_HLIST_HEAD(&sbi->rsrc_inodes); |
| 312 | hfsplus_fill_defaults(sbi); | 293 | hfsplus_fill_defaults(sbi); |
| 313 | if (!hfsplus_parse_options(data, sbi)) { | 294 | if (!hfsplus_parse_options(data, sbi)) { |
| 314 | if (!silent) | 295 | printk(KERN_ERR "hfs: unable to parse mount options\n"); |
| 315 | printk("HFS+-fs: unable to parse mount options\n"); | ||
| 316 | err = -EINVAL; | 296 | err = -EINVAL; |
| 317 | goto cleanup; | 297 | goto cleanup; |
| 318 | } | 298 | } |
| @@ -320,8 +300,8 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
| 320 | /* temporarily use utf8 to correctly find the hidden dir below */ | 300 | /* temporarily use utf8 to correctly find the hidden dir below */ |
| 321 | nls = sbi->nls; | 301 | nls = sbi->nls; |
| 322 | sbi->nls = load_nls("utf8"); | 302 | sbi->nls = load_nls("utf8"); |
| 323 | if (!nls) { | 303 | if (!sbi->nls) { |
| 324 | printk("HFS+: unable to load nls for utf8\n"); | 304 | printk(KERN_ERR "hfs: unable to load nls for utf8\n"); |
| 325 | err = -EINVAL; | 305 | err = -EINVAL; |
| 326 | goto cleanup; | 306 | goto cleanup; |
| 327 | } | 307 | } |
| @@ -329,17 +309,17 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
| 329 | /* Grab the volume header */ | 309 | /* Grab the volume header */ |
| 330 | if (hfsplus_read_wrapper(sb)) { | 310 | if (hfsplus_read_wrapper(sb)) { |
| 331 | if (!silent) | 311 | if (!silent) |
| 332 | printk("HFS+-fs: unable to find HFS+ superblock\n"); | 312 | printk(KERN_WARNING "hfs: unable to find HFS+ superblock\n"); |
| 333 | err = -EINVAL; | 313 | err = -EINVAL; |
| 334 | goto cleanup; | 314 | goto cleanup; |
| 335 | } | 315 | } |
| 336 | vhdr = HFSPLUS_SB(sb).s_vhdr; | 316 | vhdr = HFSPLUS_SB(sb).s_vhdr; |
| 337 | 317 | ||
| 338 | /* Copy parts of the volume header into the superblock */ | 318 | /* Copy parts of the volume header into the superblock */ |
| 339 | sb->s_magic = be16_to_cpu(vhdr->signature); | 319 | sb->s_magic = HFSPLUS_VOLHEAD_SIG; |
| 340 | if (be16_to_cpu(vhdr->version) != HFSPLUS_CURRENT_VERSION) { | 320 | if (be16_to_cpu(vhdr->version) < HFSPLUS_MIN_VERSION || |
| 341 | if (!silent) | 321 | be16_to_cpu(vhdr->version) > HFSPLUS_CURRENT_VERSION) { |
| 342 | printk("HFS+-fs: wrong filesystem version\n"); | 322 | printk(KERN_ERR "hfs: wrong filesystem version\n"); |
| 343 | goto cleanup; | 323 | goto cleanup; |
| 344 | } | 324 | } |
| 345 | HFSPLUS_SB(sb).total_blocks = be32_to_cpu(vhdr->total_blocks); | 325 | HFSPLUS_SB(sb).total_blocks = be32_to_cpu(vhdr->total_blocks); |
| @@ -360,20 +340,17 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
| 360 | sb->s_maxbytes = MAX_LFS_FILESIZE; | 340 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
| 361 | 341 | ||
| 362 | if (!(vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_UNMNT))) { | 342 | if (!(vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_UNMNT))) { |
| 363 | if (!silent) | 343 | printk(KERN_WARNING "hfs: Filesystem was not cleanly unmounted, " |
| 364 | printk("HFS+-fs warning: Filesystem was not cleanly unmounted, " | 344 | "running fsck.hfsplus is recommended. mounting read-only.\n"); |
| 365 | "running fsck.hfsplus is recommended. mounting read-only.\n"); | ||
| 366 | sb->s_flags |= MS_RDONLY; | 345 | sb->s_flags |= MS_RDONLY; |
| 367 | } else if (sbi->flags & HFSPLUS_SB_FORCE) { | 346 | } else if (sbi->flags & HFSPLUS_SB_FORCE) { |
| 368 | /* nothing */ | 347 | /* nothing */ |
| 369 | } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) { | 348 | } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) { |
| 370 | if (!silent) | 349 | printk(KERN_WARNING "hfs: Filesystem is marked locked, mounting read-only.\n"); |
| 371 | printk("HFS+-fs: Filesystem is marked locked, mounting read-only.\n"); | ||
| 372 | sb->s_flags |= MS_RDONLY; | 350 | sb->s_flags |= MS_RDONLY; |
| 373 | } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) { | 351 | } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) { |
| 374 | if (!silent) | 352 | printk(KERN_WARNING "hfs: write access to a jounaled filesystem is not supported, " |
| 375 | printk("HFS+-fs: write access to a jounaled filesystem is not supported, " | 353 | "use the force option at your own risk, mounting read-only.\n"); |
| 376 | "use the force option at your own risk, mounting read-only.\n"); | ||
| 377 | sb->s_flags |= MS_RDONLY; | 354 | sb->s_flags |= MS_RDONLY; |
| 378 | } | 355 | } |
| 379 | sbi->flags &= ~HFSPLUS_SB_FORCE; | 356 | sbi->flags &= ~HFSPLUS_SB_FORCE; |
| @@ -381,21 +358,18 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
| 381 | /* Load metadata objects (B*Trees) */ | 358 | /* Load metadata objects (B*Trees) */ |
| 382 | HFSPLUS_SB(sb).ext_tree = hfs_btree_open(sb, HFSPLUS_EXT_CNID); | 359 | HFSPLUS_SB(sb).ext_tree = hfs_btree_open(sb, HFSPLUS_EXT_CNID); |
| 383 | if (!HFSPLUS_SB(sb).ext_tree) { | 360 | if (!HFSPLUS_SB(sb).ext_tree) { |
| 384 | if (!silent) | 361 | printk(KERN_ERR "hfs: failed to load extents file\n"); |
| 385 | printk("HFS+-fs: failed to load extents file\n"); | ||
| 386 | goto cleanup; | 362 | goto cleanup; |
| 387 | } | 363 | } |
| 388 | HFSPLUS_SB(sb).cat_tree = hfs_btree_open(sb, HFSPLUS_CAT_CNID); | 364 | HFSPLUS_SB(sb).cat_tree = hfs_btree_open(sb, HFSPLUS_CAT_CNID); |
| 389 | if (!HFSPLUS_SB(sb).cat_tree) { | 365 | if (!HFSPLUS_SB(sb).cat_tree) { |
| 390 | if (!silent) | 366 | printk(KERN_ERR "hfs: failed to load catalog file\n"); |
| 391 | printk("HFS+-fs: failed to load catalog file\n"); | ||
| 392 | goto cleanup; | 367 | goto cleanup; |
| 393 | } | 368 | } |
| 394 | 369 | ||
| 395 | HFSPLUS_SB(sb).alloc_file = iget(sb, HFSPLUS_ALLOC_CNID); | 370 | HFSPLUS_SB(sb).alloc_file = iget(sb, HFSPLUS_ALLOC_CNID); |
| 396 | if (!HFSPLUS_SB(sb).alloc_file) { | 371 | if (!HFSPLUS_SB(sb).alloc_file) { |
| 397 | if (!silent) | 372 | printk(KERN_ERR "hfs: failed to load allocation file\n"); |
| 398 | printk("HFS+-fs: failed to load allocation file\n"); | ||
| 399 | goto cleanup; | 373 | goto cleanup; |
| 400 | } | 374 | } |
| 401 | 375 | ||
| @@ -403,8 +377,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
| 403 | root = iget(sb, HFSPLUS_ROOT_CNID); | 377 | root = iget(sb, HFSPLUS_ROOT_CNID); |
| 404 | sb->s_root = d_alloc_root(root); | 378 | sb->s_root = d_alloc_root(root); |
| 405 | if (!sb->s_root) { | 379 | if (!sb->s_root) { |
| 406 | if (!silent) | 380 | printk(KERN_ERR "hfs: failed to load root directory\n"); |
| 407 | printk("HFS+-fs: failed to load root directory\n"); | ||
| 408 | iput(root); | 381 | iput(root); |
| 409 | goto cleanup; | 382 | goto cleanup; |
| 410 | } | 383 | } |
| @@ -438,7 +411,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
| 438 | sync_dirty_buffer(HFSPLUS_SB(sb).s_vhbh); | 411 | sync_dirty_buffer(HFSPLUS_SB(sb).s_vhbh); |
| 439 | 412 | ||
| 440 | if (!HFSPLUS_SB(sb).hidden_dir) { | 413 | if (!HFSPLUS_SB(sb).hidden_dir) { |
| 441 | printk("HFS+: create hidden dir...\n"); | 414 | printk(KERN_DEBUG "hfs: create hidden dir...\n"); |
| 442 | HFSPLUS_SB(sb).hidden_dir = hfsplus_new_inode(sb, S_IFDIR); | 415 | HFSPLUS_SB(sb).hidden_dir = hfsplus_new_inode(sb, S_IFDIR); |
| 443 | hfsplus_create_cat(HFSPLUS_SB(sb).hidden_dir->i_ino, sb->s_root->d_inode, | 416 | hfsplus_create_cat(HFSPLUS_SB(sb).hidden_dir->i_ino, sb->s_root->d_inode, |
| 444 | &str, HFSPLUS_SB(sb).hidden_dir); | 417 | &str, HFSPLUS_SB(sb).hidden_dir); |
| @@ -518,7 +491,7 @@ static void __exit exit_hfsplus_fs(void) | |||
| 518 | { | 491 | { |
| 519 | unregister_filesystem(&hfsplus_fs_type); | 492 | unregister_filesystem(&hfsplus_fs_type); |
| 520 | if (kmem_cache_destroy(hfsplus_inode_cachep)) | 493 | if (kmem_cache_destroy(hfsplus_inode_cachep)) |
| 521 | printk(KERN_INFO "hfsplus_inode_cache: not all structures were freed\n"); | 494 | printk(KERN_ERR "hfsplus_inode_cache: not all structures were freed\n"); |
| 522 | } | 495 | } |
| 523 | 496 | ||
| 524 | module_init(init_hfsplus_fs) | 497 | module_init(init_hfsplus_fs) |
diff --git a/fs/hfsplus/unicode.c b/fs/hfsplus/unicode.c index 060c69048c3d..689c8bd721fb 100644 --- a/fs/hfsplus/unicode.c +++ b/fs/hfsplus/unicode.c | |||
| @@ -28,7 +28,8 @@ static inline u16 case_fold(u16 c) | |||
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | /* Compare unicode strings, return values like normal strcmp */ | 30 | /* Compare unicode strings, return values like normal strcmp */ |
| 31 | int hfsplus_unistrcmp(const struct hfsplus_unistr *s1, const struct hfsplus_unistr *s2) | 31 | int hfsplus_strcasecmp(const struct hfsplus_unistr *s1, |
| 32 | const struct hfsplus_unistr *s2) | ||
| 32 | { | 33 | { |
| 33 | u16 len1, len2, c1, c2; | 34 | u16 len1, len2, c1, c2; |
| 34 | const hfsplus_unichr *p1, *p2; | 35 | const hfsplus_unichr *p1, *p2; |
| @@ -59,6 +60,33 @@ int hfsplus_unistrcmp(const struct hfsplus_unistr *s1, const struct hfsplus_unis | |||
| 59 | } | 60 | } |
| 60 | } | 61 | } |
| 61 | 62 | ||
| 63 | /* Compare names as a sequence of 16-bit unsigned integers */ | ||
| 64 | int hfsplus_strcmp(const struct hfsplus_unistr *s1, | ||
| 65 | const struct hfsplus_unistr *s2) | ||
| 66 | { | ||
| 67 | u16 len1, len2, c1, c2; | ||
| 68 | const hfsplus_unichr *p1, *p2; | ||
| 69 | int len; | ||
| 70 | |||
| 71 | len1 = be16_to_cpu(s1->length); | ||
| 72 | len2 = be16_to_cpu(s2->length); | ||
| 73 | p1 = s1->unicode; | ||
| 74 | p2 = s2->unicode; | ||
| 75 | |||
| 76 | for (len = min(len1, len2); len > 0; len--) { | ||
| 77 | c1 = be16_to_cpu(*p1); | ||
| 78 | c2 = be16_to_cpu(*p2); | ||
| 79 | if (c1 != c2) | ||
| 80 | return c1 < c2 ? -1 : 1; | ||
| 81 | p1++; | ||
| 82 | p2++; | ||
| 83 | } | ||
| 84 | |||
| 85 | return len1 < len2 ? -1 : | ||
| 86 | len1 > len2 ? 1 : 0; | ||
| 87 | } | ||
| 88 | |||
| 89 | |||
| 62 | #define Hangul_SBase 0xac00 | 90 | #define Hangul_SBase 0xac00 |
| 63 | #define Hangul_LBase 0x1100 | 91 | #define Hangul_LBase 0x1100 |
| 64 | #define Hangul_VBase 0x1161 | 92 | #define Hangul_VBase 0x1161 |
diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c index 95455e839231..72cab78f0509 100644 --- a/fs/hfsplus/wrapper.c +++ b/fs/hfsplus/wrapper.c | |||
| @@ -28,8 +28,11 @@ static int hfsplus_read_mdb(void *bufptr, struct hfsplus_wd *wd) | |||
| 28 | { | 28 | { |
| 29 | u32 extent; | 29 | u32 extent; |
| 30 | u16 attrib; | 30 | u16 attrib; |
| 31 | __be16 sig; | ||
| 31 | 32 | ||
| 32 | if (be16_to_cpu(*(__be16 *)(bufptr + HFSP_WRAPOFF_EMBEDSIG)) != HFSPLUS_VOLHEAD_SIG) | 33 | sig = *(__be16 *)(bufptr + HFSP_WRAPOFF_EMBEDSIG); |
| 34 | if (sig != cpu_to_be16(HFSPLUS_VOLHEAD_SIG) && | ||
| 35 | sig != cpu_to_be16(HFSPLUS_VOLHEAD_SIGX)) | ||
| 33 | return 0; | 36 | return 0; |
| 34 | 37 | ||
| 35 | attrib = be16_to_cpu(*(__be16 *)(bufptr + HFSP_WRAPOFF_ATTRIB)); | 38 | attrib = be16_to_cpu(*(__be16 *)(bufptr + HFSP_WRAPOFF_ATTRIB)); |
| @@ -70,7 +73,7 @@ static int hfsplus_get_last_session(struct super_block *sb, | |||
| 70 | *start = (sector_t)te.cdte_addr.lba << 2; | 73 | *start = (sector_t)te.cdte_addr.lba << 2; |
| 71 | return 0; | 74 | return 0; |
| 72 | } | 75 | } |
| 73 | printk(KERN_ERR "HFS: Invalid session number or type of track\n"); | 76 | printk(KERN_ERR "hfs: invalid session number or type of track\n"); |
| 74 | return -EINVAL; | 77 | return -EINVAL; |
| 75 | } | 78 | } |
| 76 | ms_info.addr_format = CDROM_LBA; | 79 | ms_info.addr_format = CDROM_LBA; |
| @@ -114,6 +117,10 @@ int hfsplus_read_wrapper(struct super_block *sb) | |||
| 114 | } | 117 | } |
| 115 | if (vhdr->signature == cpu_to_be16(HFSPLUS_VOLHEAD_SIG)) | 118 | if (vhdr->signature == cpu_to_be16(HFSPLUS_VOLHEAD_SIG)) |
| 116 | break; | 119 | break; |
| 120 | if (vhdr->signature == cpu_to_be16(HFSPLUS_VOLHEAD_SIGX)) { | ||
| 121 | HFSPLUS_SB(sb).flags |= HFSPLUS_SB_HFSX; | ||
| 122 | break; | ||
| 123 | } | ||
| 117 | brelse(bh); | 124 | brelse(bh); |
| 118 | 125 | ||
| 119 | /* check for a partition block | 126 | /* check for a partition block |
| @@ -143,7 +150,7 @@ int hfsplus_read_wrapper(struct super_block *sb) | |||
| 143 | blocksize >>= 1; | 150 | blocksize >>= 1; |
| 144 | 151 | ||
| 145 | if (sb_set_blocksize(sb, blocksize) != blocksize) { | 152 | if (sb_set_blocksize(sb, blocksize) != blocksize) { |
| 146 | printk("HFS+: unable to blocksize to %u!\n", blocksize); | 153 | printk(KERN_ERR "hfs: unable to set blocksize to %u!\n", blocksize); |
| 147 | return -EINVAL; | 154 | return -EINVAL; |
| 148 | } | 155 | } |
| 149 | 156 | ||
| @@ -158,7 +165,9 @@ int hfsplus_read_wrapper(struct super_block *sb) | |||
| 158 | return -EIO; | 165 | return -EIO; |
| 159 | 166 | ||
| 160 | /* should still be the same... */ | 167 | /* should still be the same... */ |
| 161 | if (be16_to_cpu(vhdr->signature) != HFSPLUS_VOLHEAD_SIG) | 168 | if (vhdr->signature != (HFSPLUS_SB(sb).flags & HFSPLUS_SB_HFSX ? |
| 169 | cpu_to_be16(HFSPLUS_VOLHEAD_SIGX) : | ||
| 170 | cpu_to_be16(HFSPLUS_VOLHEAD_SIG))) | ||
| 162 | goto error; | 171 | goto error; |
| 163 | HFSPLUS_SB(sb).s_vhbh = bh; | 172 | HFSPLUS_SB(sb).s_vhbh = bh; |
| 164 | HFSPLUS_SB(sb).s_vhdr = vhdr; | 173 | HFSPLUS_SB(sb).s_vhdr = vhdr; |
