From 6f80dfe55fcbde1e588bc2cfa1273403b710872d Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sun, 7 Nov 2010 23:01:17 +0100 Subject: [PATCH 01/17] hfsplus: fix option parsing during remount hfsplus only actually uses the force option during remount, but it uses the full option parser with a fake superblock to do so. This means remount will fail if any nls option is set (which happens frequently with older mount tools), even if it is the same. Fix this by adding a simpler version of the parser that only parses the force option for remount. Signed-off-by: Christoph Hellwig --- fs/hfsplus/hfsplus_fs.h | 1 + fs/hfsplus/options.c | 26 ++++++++++++++++++++++++++ fs/hfsplus/super.c | 8 +++----- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index cb3653efb57a2..f07aa640c27d3 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h @@ -362,6 +362,7 @@ ssize_t hfsplus_listxattr(struct dentry *dentry, char *buffer, size_t size); /* options.c */ int hfsplus_parse_options(char *, struct hfsplus_sb_info *); +int hfsplus_parse_options_remount(char *input, int *force); void hfsplus_fill_defaults(struct hfsplus_sb_info *); int hfsplus_show_options(struct seq_file *, struct vfsmount *); diff --git a/fs/hfsplus/options.c b/fs/hfsplus/options.c index f9ab276a4d8de..43b02b5525eb2 100644 --- a/fs/hfsplus/options.c +++ b/fs/hfsplus/options.c @@ -65,6 +65,32 @@ static inline int match_fourchar(substring_t *arg, u32 *result) return 0; } +int hfsplus_parse_options_remount(char *input, int *force) +{ + char *p; + substring_t args[MAX_OPT_ARGS]; + int token; + + if (!input) + return 0; + + while ((p = strsep(&input, ",")) != NULL) { + if (!*p) + continue; + + token = match_token(p, tokens, args); + switch (token) { + case opt_force: + *force = 1; + break; + default: + break; + } + } + + return 1; +} + /* Parse options from mount. Returns 0 on failure */ /* input is the options passed to mount() as a string */ int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi) diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 52cc746d3ba36..1c356a2fba01a 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -263,11 +263,9 @@ static int hfsplus_remount(struct super_block *sb, int *flags, char *data) return 0; if (!(*flags & MS_RDONLY)) { struct hfsplus_vh *vhdr = HFSPLUS_SB(sb)->s_vhdr; - struct hfsplus_sb_info sbi; + int force = 0; - memset(&sbi, 0, sizeof(struct hfsplus_sb_info)); - sbi.nls = HFSPLUS_SB(sb)->nls; - if (!hfsplus_parse_options(data, &sbi)) + if (!hfsplus_parse_options_remount(data, &force)) return -EINVAL; if (!(vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_UNMNT))) { @@ -275,7 +273,7 @@ static int hfsplus_remount(struct super_block *sb, int *flags, char *data) "running fsck.hfsplus is recommended. leaving read-only.\n"); sb->s_flags |= MS_RDONLY; *flags |= MS_RDONLY; - } else if (test_bit(HFSPLUS_SB_FORCE, &sbi.flags)) { + } else if (force) { /* nothing */ } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) { printk(KERN_WARNING "hfs: filesystem is marked locked, leaving read-only.\n"); From 6d1bbfc4c0458c514126ccf7d6ce9232d9dbc872 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 23 Nov 2010 14:37:40 +0100 Subject: [PATCH 02/17] hfsplus: silence a few debug printks Turn a few noisy debug printks that show up during xfstests into complied out debug print statements. Signed-off-by: Christoph Hellwig --- fs/hfsplus/bnode.c | 2 +- fs/hfsplus/brec.c | 2 +- fs/hfsplus/btree.c | 2 +- fs/hfsplus/super.c | 2 -- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 29da6574ba779..c8aa1659b8385 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -358,7 +358,7 @@ void hfs_bnode_unlink(struct hfs_bnode *node) // move down? if (!node->prev && !node->next) { - printk(KERN_DEBUG "hfs_btree_del_level\n"); + dprint(DBG_BNODE_MOD, "hfs_btree_del_level\n"); } if (!node->parent) { tree->root = 0; diff --git a/fs/hfsplus/brec.c b/fs/hfsplus/brec.c index 2f39d05443e1a..81f7e6e51d5ae 100644 --- a/fs/hfsplus/brec.c +++ b/fs/hfsplus/brec.c @@ -375,7 +375,7 @@ static int hfs_brec_update_parent(struct hfs_find_data *fd) end_off = hfs_bnode_read_u16(parent, end_rec_off); if (end_rec_off - end_off < diff) { - printk(KERN_DEBUG "hfs: splitting index node...\n"); + dprint(DBG_BNODE_MOD, "hfs: splitting index node.\n"); fd->bnode = parent; new_node = hfs_bnode_split(fd); if (IS_ERR(new_node)) diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c index 22e4d4e329999..97556f932d57f 100644 --- a/fs/hfsplus/btree.c +++ b/fs/hfsplus/btree.c @@ -287,7 +287,7 @@ struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree) kunmap(*pagep); nidx = node->next; if (!nidx) { - printk(KERN_DEBUG "hfs: create new bmap node...\n"); + dprint(DBG_BNODE_MOD, "hfs: create new bmap node.\n"); next_node = hfs_bmap_new_bmap(node, idx); } else next_node = hfs_bnode_find(tree, nidx); diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 1c356a2fba01a..9bda9fd355111 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -451,8 +451,6 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) sync_dirty_buffer(sbi->s_vhbh); if (!sbi->hidden_dir) { - printk(KERN_DEBUG "hfs: create hidden dir...\n"); - mutex_lock(&sbi->vh_mutex); sbi->hidden_dir = hfsplus_new_inode(sb, S_IFDIR); hfsplus_create_cat(sbi->hidden_dir->i_ino, sb->s_root->d_inode, From 3b5ce8ae31e3c66655207907527476bbd3e5063b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 23 Nov 2010 14:37:43 +0100 Subject: [PATCH 03/17] hfsplus: always use hfsplus_sync_fs to write the volume header Remove opencoded writing of the volume header in hfsplus_fill_super and hfsplus_put_super and offload it to hfsplus_sync_fs. In the put_super case this means we only write the superblock once instead of twice. Signed-off-by: Christoph Hellwig --- fs/hfsplus/super.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 9bda9fd355111..6a23490586188 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -215,16 +215,14 @@ static void hfsplus_put_super(struct super_block *sb) if (!sb->s_fs_info) return; - if (sb->s_dirt) - hfsplus_write_super(sb); if (!(sb->s_flags & MS_RDONLY) && sbi->s_vhdr) { struct hfsplus_vh *vhdr = sbi->s_vhdr; vhdr->modify_date = hfsp_now2mt(); vhdr->attributes |= cpu_to_be32(HFSPLUS_VOL_UNMNT); vhdr->attributes &= cpu_to_be32(~HFSPLUS_VOL_INCNSTNT); - mark_buffer_dirty(sbi->s_vhbh); - sync_dirty_buffer(sbi->s_vhbh); + + hfsplus_sync_fs(sb, 1); } hfs_btree_close(sbi->cat_tree); @@ -447,8 +445,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) be32_add_cpu(&vhdr->write_count, 1); vhdr->attributes &= cpu_to_be32(~HFSPLUS_VOL_UNMNT); vhdr->attributes |= cpu_to_be32(HFSPLUS_VOL_INCNSTNT); - mark_buffer_dirty(sbi->s_vhbh); - sync_dirty_buffer(sbi->s_vhbh); + hfsplus_sync_fs(sb, 1); if (!sbi->hidden_dir) { mutex_lock(&sbi->vh_mutex); From 52399b171dfaea02b6944cd6feba49b624147126 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 23 Nov 2010 14:37:47 +0100 Subject: [PATCH 04/17] hfsplus: use raw bio access for the volume headers The hfsplus backup volume header is located two blocks from the end of the device. In case of device sizes that are not 4k aligned this means we can't access it using buffer_heads when using the default 4k block size. Switch to using raw bios to read/write all buffer headers. We were not relying on any caching behaviour of the buffer heads anyway. Additionally always read in the backup volume header during mount to verify that we can actually read it. Signed-off-by: Christoph Hellwig --- fs/hfsplus/hfsplus_fs.h | 8 +- fs/hfsplus/super.c | 48 ++++++------ fs/hfsplus/wrapper.c | 163 +++++++++++++++++++++++++--------------- 3 files changed, 131 insertions(+), 88 deletions(-) diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index f07aa640c27d3..276ddb0fd0fd3 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h @@ -107,8 +107,8 @@ struct hfsplus_vh; struct hfs_btree; struct hfsplus_sb_info { - struct buffer_head *s_vhbh; struct hfsplus_vh *s_vhdr; + struct hfsplus_vh *s_backup_vhdr; struct hfs_btree *ext_tree; struct hfs_btree *cat_tree; struct hfs_btree *attr_tree; @@ -118,7 +118,8 @@ struct hfsplus_sb_info { /* Runtime variables */ u32 blockoffset; - u32 sect_count; + sector_t part_start; + sector_t sect_count; int fs_shift; /* immutable data from the volume header */ @@ -385,8 +386,9 @@ int hfsplus_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr * /* wrapper.c */ int hfsplus_read_wrapper(struct super_block *); - int hfs_part_find(struct super_block *, sector_t *, sector_t *); +int hfsplus_submit_bio(struct block_device *bdev, sector_t sector, + void *data, int rw); /* access macros */ static inline struct hfsplus_sb_info *HFSPLUS_SB(struct super_block *sb) diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 6a23490586188..fe8f7bffbea50 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -157,45 +157,40 @@ int hfsplus_sync_fs(struct super_block *sb, int wait) { struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); struct hfsplus_vh *vhdr = sbi->s_vhdr; + int write_backup = 0; + int error, error2; dprint(DBG_SUPER, "hfsplus_write_super\n"); - mutex_lock(&sbi->vh_mutex); - mutex_lock(&sbi->alloc_mutex); sb->s_dirt = 0; + mutex_lock(&sbi->vh_mutex); + mutex_lock(&sbi->alloc_mutex); vhdr->free_blocks = cpu_to_be32(sbi->free_blocks); vhdr->next_cnid = cpu_to_be32(sbi->next_cnid); vhdr->folder_count = cpu_to_be32(sbi->folder_count); vhdr->file_count = cpu_to_be32(sbi->file_count); - mark_buffer_dirty(sbi->s_vhbh); if (test_and_clear_bit(HFSPLUS_SB_WRITEBACKUP, &sbi->flags)) { - if (sbi->sect_count) { - struct buffer_head *bh; - u32 block, offset; - - block = sbi->blockoffset; - block += (sbi->sect_count - 2) >> (sb->s_blocksize_bits - 9); - offset = ((sbi->sect_count - 2) << 9) & (sb->s_blocksize - 1); - printk(KERN_DEBUG "hfs: backup: %u,%u,%u,%u\n", - sbi->blockoffset, sbi->sect_count, - block, offset); - bh = sb_bread(sb, block); - if (bh) { - vhdr = (struct hfsplus_vh *)(bh->b_data + offset); - if (be16_to_cpu(vhdr->signature) == HFSPLUS_VOLHEAD_SIG) { - memcpy(vhdr, sbi->s_vhdr, sizeof(*vhdr)); - mark_buffer_dirty(bh); - brelse(bh); - } else - printk(KERN_WARNING "hfs: backup not found!\n"); - } - } + memcpy(sbi->s_backup_vhdr, sbi->s_vhdr, sizeof(*sbi->s_vhdr)); + write_backup = 1; } + + error = hfsplus_submit_bio(sb->s_bdev, + sbi->part_start + HFSPLUS_VOLHEAD_SECTOR, + sbi->s_vhdr, WRITE_SYNC); + if (!write_backup) + goto out; + + error2 = hfsplus_submit_bio(sb->s_bdev, + sbi->part_start + sbi->sect_count - 2, + sbi->s_backup_vhdr, WRITE_SYNC); + if (!error) + error2 = error; +out: mutex_unlock(&sbi->alloc_mutex); mutex_unlock(&sbi->vh_mutex); - return 0; + return error; } static void hfsplus_write_super(struct super_block *sb) @@ -229,7 +224,8 @@ static void hfsplus_put_super(struct super_block *sb) hfs_btree_close(sbi->ext_tree); iput(sbi->alloc_file); iput(sbi->hidden_dir); - brelse(sbi->s_vhbh); + kfree(sbi->s_vhdr); + kfree(sbi->s_backup_vhdr); unload_nls(sbi->nls); kfree(sb->s_fs_info); sb->s_fs_info = NULL; diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c index 8972c20b32169..15e0eabb489ef 100644 --- a/fs/hfsplus/wrapper.c +++ b/fs/hfsplus/wrapper.c @@ -24,6 +24,40 @@ struct hfsplus_wd { u16 embed_count; }; +static void hfsplus_end_io_sync(struct bio *bio, int err) +{ + if (err) + clear_bit(BIO_UPTODATE, &bio->bi_flags); + complete(bio->bi_private); +} + +int hfsplus_submit_bio(struct block_device *bdev, sector_t sector, + void *data, int rw) +{ + DECLARE_COMPLETION_ONSTACK(wait); + struct bio *bio; + + bio = bio_alloc(GFP_NOIO, 1); + bio->bi_sector = sector; + bio->bi_bdev = bdev; + bio->bi_end_io = hfsplus_end_io_sync; + bio->bi_private = &wait; + + /* + * We always submit one sector at a time, so bio_add_page must not fail. + */ + if (bio_add_page(bio, virt_to_page(data), HFSPLUS_SECTOR_SIZE, + offset_in_page(data)) != HFSPLUS_SECTOR_SIZE) + BUG(); + + submit_bio(rw, bio); + wait_for_completion(&wait); + + if (!bio_flagged(bio, BIO_UPTODATE)) + return -EIO; + return 0; +} + static int hfsplus_read_mdb(void *bufptr, struct hfsplus_wd *wd) { u32 extent; @@ -88,100 +122,111 @@ static int hfsplus_get_last_session(struct super_block *sb, int hfsplus_read_wrapper(struct super_block *sb) { struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); - struct buffer_head *bh; - struct hfsplus_vh *vhdr; struct hfsplus_wd wd; sector_t part_start, part_size; u32 blocksize; + int error = 0; + error = -EINVAL; blocksize = sb_min_blocksize(sb, HFSPLUS_SECTOR_SIZE); if (!blocksize) - return -EINVAL; + goto out; if (hfsplus_get_last_session(sb, &part_start, &part_size)) - return -EINVAL; + goto out; if ((u64)part_start + part_size > 0x100000000ULL) { pr_err("hfs: volumes larger than 2TB are not supported yet\n"); - return -EINVAL; + goto out; } - while (1) { - bh = sb_bread512(sb, part_start + HFSPLUS_VOLHEAD_SECTOR, vhdr); - if (!bh) - return -EIO; - - if (vhdr->signature == cpu_to_be16(HFSP_WRAP_MAGIC)) { - if (!hfsplus_read_mdb(vhdr, &wd)) - goto error; - wd.ablk_size >>= HFSPLUS_SECTOR_SHIFT; - part_start += wd.ablk_start + wd.embed_start * wd.ablk_size; - part_size = wd.embed_count * wd.ablk_size; - brelse(bh); - bh = sb_bread512(sb, part_start + HFSPLUS_VOLHEAD_SECTOR, vhdr); - if (!bh) - return -EIO; - } - if (vhdr->signature == cpu_to_be16(HFSPLUS_VOLHEAD_SIG)) - break; - if (vhdr->signature == cpu_to_be16(HFSPLUS_VOLHEAD_SIGX)) { - set_bit(HFSPLUS_SB_HFSX, &sbi->flags); - break; - } - brelse(bh); - /* check for a partition block + error = -ENOMEM; + sbi->s_vhdr = kmalloc(HFSPLUS_SECTOR_SIZE, GFP_KERNEL); + if (!sbi->s_vhdr) + goto out; + sbi->s_backup_vhdr = kmalloc(HFSPLUS_SECTOR_SIZE, GFP_KERNEL); + if (!sbi->s_backup_vhdr) + goto out_free_vhdr; + +reread: + error = hfsplus_submit_bio(sb->s_bdev, + part_start + HFSPLUS_VOLHEAD_SECTOR, + sbi->s_vhdr, READ); + if (error) + goto out_free_backup_vhdr; + + error = -EINVAL; + switch (sbi->s_vhdr->signature) { + case cpu_to_be16(HFSPLUS_VOLHEAD_SIGX): + set_bit(HFSPLUS_SB_HFSX, &sbi->flags); + /*FALLTHRU*/ + case cpu_to_be16(HFSPLUS_VOLHEAD_SIG): + break; + case cpu_to_be16(HFSP_WRAP_MAGIC): + if (!hfsplus_read_mdb(sbi->s_vhdr, &wd)) + goto out; + wd.ablk_size >>= HFSPLUS_SECTOR_SHIFT; + part_start += wd.ablk_start + wd.embed_start * wd.ablk_size; + part_size = wd.embed_count * wd.ablk_size; + goto reread; + default: + /* + * Check for a partition block. + * * (should do this only for cdrom/loop though) */ if (hfs_part_find(sb, &part_start, &part_size)) - return -EINVAL; + goto out; + goto reread; + } + + error = hfsplus_submit_bio(sb->s_bdev, + part_start + part_size - 2, + sbi->s_backup_vhdr, READ); + if (error) + goto out_free_backup_vhdr; + + error = -EINVAL; + if (sbi->s_backup_vhdr->signature != sbi->s_vhdr->signature) { + printk(KERN_WARNING + "hfs: invalid secondary volume header\n"); + goto out_free_backup_vhdr; } - blocksize = be32_to_cpu(vhdr->blocksize); - brelse(bh); + blocksize = be32_to_cpu(sbi->s_vhdr->blocksize); - /* block size must be at least as large as a sector - * and a multiple of 2 + /* + * Block size must be at least as large as a sector and a multiple of 2. */ - if (blocksize < HFSPLUS_SECTOR_SIZE || - ((blocksize - 1) & blocksize)) - return -EINVAL; + if (blocksize < HFSPLUS_SECTOR_SIZE || ((blocksize - 1) & blocksize)) + goto out_free_backup_vhdr; sbi->alloc_blksz = blocksize; sbi->alloc_blksz_shift = 0; while ((blocksize >>= 1) != 0) sbi->alloc_blksz_shift++; blocksize = min(sbi->alloc_blksz, (u32)PAGE_SIZE); - /* align block size to block offset */ + /* + * Align block size to block offset. + */ while (part_start & ((blocksize >> HFSPLUS_SECTOR_SHIFT) - 1)) blocksize >>= 1; if (sb_set_blocksize(sb, blocksize) != blocksize) { printk(KERN_ERR "hfs: unable to set blocksize to %u!\n", blocksize); - return -EINVAL; + goto out_free_backup_vhdr; } sbi->blockoffset = part_start >> (sb->s_blocksize_bits - HFSPLUS_SECTOR_SHIFT); + sbi->part_start = part_start; sbi->sect_count = part_size; sbi->fs_shift = sbi->alloc_blksz_shift - sb->s_blocksize_bits; - - bh = sb_bread512(sb, part_start + HFSPLUS_VOLHEAD_SECTOR, vhdr); - if (!bh) - return -EIO; - - /* should still be the same... */ - if (test_bit(HFSPLUS_SB_HFSX, &sbi->flags)) { - if (vhdr->signature != cpu_to_be16(HFSPLUS_VOLHEAD_SIGX)) - goto error; - } else { - if (vhdr->signature != cpu_to_be16(HFSPLUS_VOLHEAD_SIG)) - goto error; - } - - sbi->s_vhbh = bh; - sbi->s_vhdr = vhdr; - return 0; - error: - brelse(bh); - return -EINVAL; + +out_free_backup_vhdr: + kfree(sbi->s_backup_vhdr); +out_free_vhdr: + kfree(sbi->s_vhdr); +out: + return error; } From 358f26d52680cb150907302d4334359de7dd2d59 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 23 Nov 2010 14:37:51 +0100 Subject: [PATCH 05/17] hfsplus: use raw bio access for partition tables Switch the hfsplus partition table reding for cdroms to use our bio helpers. Again we don't rely on any caching in the buffer_heads, and this gets rid of the last buffer_head use in hfsplus. Signed-off-by: Christoph Hellwig --- fs/hfsplus/hfsplus_fs.h | 17 ------ fs/hfsplus/part_tbl.c | 124 +++++++++++++++++++++++----------------- 2 files changed, 71 insertions(+), 70 deletions(-) diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index 276ddb0fd0fd3..0d8532d966943 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h @@ -401,23 +401,6 @@ static inline struct hfsplus_inode_info *HFSPLUS_I(struct inode *inode) return list_entry(inode, struct hfsplus_inode_info, vfs_inode); } -#define sb_bread512(sb, sec, data) ({ \ - struct buffer_head *__bh; \ - sector_t __block; \ - loff_t __start; \ - int __offset; \ - \ - __start = (loff_t)(sec) << HFSPLUS_SECTOR_SHIFT;\ - __block = __start >> (sb)->s_blocksize_bits; \ - __offset = __start & ((sb)->s_blocksize - 1); \ - __bh = sb_bread((sb), __block); \ - if (likely(__bh != NULL)) \ - data = (void *)(__bh->b_data + __offset);\ - else \ - data = NULL; \ - __bh; \ -}) - /* time macros */ #define __hfsp_mt2ut(t) (be32_to_cpu(t) - 2082844800U) #define __hfsp_ut2mt(t) (cpu_to_be32(t + 2082844800U)) diff --git a/fs/hfsplus/part_tbl.c b/fs/hfsplus/part_tbl.c index 208b16c645cc2..58918222a6048 100644 --- a/fs/hfsplus/part_tbl.c +++ b/fs/hfsplus/part_tbl.c @@ -13,6 +13,7 @@ * */ +#include #include "hfsplus_fs.h" /* offsets to various blocks */ @@ -65,70 +66,87 @@ struct old_pmap { } pdEntry[42]; } __packed; +static int hfs_parse_old_pmap(struct super_block *sb, struct old_pmap *pm, + sector_t *part_start, sector_t *part_size) +{ + struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); + int i; + + for (i = 0; i < 42; i++) { + struct old_pmap_entry *p = &pm->pdEntry[i]; + + if (p->pdStart && p->pdSize && + p->pdFSID == cpu_to_be32(0x54465331)/*"TFS1"*/ && + (sbi->part < 0 || sbi->part == i)) { + *part_start += be32_to_cpu(p->pdStart); + *part_size = be32_to_cpu(p->pdSize); + return 0; + } + } + + return -ENOENT; +} + +static int hfs_parse_new_pmap(struct super_block *sb, struct new_pmap *pm, + sector_t *part_start, sector_t *part_size) +{ + struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); + int size = be32_to_cpu(pm->pmMapBlkCnt); + int res; + int i = 0; + + do { + if (!memcmp(pm->pmPartType,"Apple_HFS", 9) && + (sbi->part < 0 || sbi->part == i)) { + *part_start += be32_to_cpu(pm->pmPyPartStart); + *part_size = be32_to_cpu(pm->pmPartBlkCnt); + return 0; + } + + if (++i >= size) + return -ENOENT; + + res = hfsplus_submit_bio(sb->s_bdev, + *part_start + HFS_PMAP_BLK + i, + pm, READ); + if (res) + return res; + } while (pm->pmSig == cpu_to_be16(HFS_NEW_PMAP_MAGIC)); + + return -ENOENT; +} + /* - * hfs_part_find() - * - * Parse the partition map looking for the - * start and length of the 'part'th HFS partition. + * Parse the partition map looking for the start and length of a + * HFS/HFS+ partition. */ int hfs_part_find(struct super_block *sb, - sector_t *part_start, sector_t *part_size) + sector_t *part_start, sector_t *part_size) { - struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); - struct buffer_head *bh; - __be16 *data; - int i, size, res; + void *data; + int res; + + data = kmalloc(HFSPLUS_SECTOR_SIZE, GFP_KERNEL); + if (!data) + return -ENOMEM; - res = -ENOENT; - bh = sb_bread512(sb, *part_start + HFS_PMAP_BLK, data); - if (!bh) - return -EIO; + res = hfsplus_submit_bio(sb->s_bdev, *part_start + HFS_PMAP_BLK, + data, READ); + if (res) + return res; - switch (be16_to_cpu(*data)) { + switch (be16_to_cpu(*((__be16 *)data))) { case HFS_OLD_PMAP_MAGIC: - { - struct old_pmap *pm; - struct old_pmap_entry *p; - - pm = (struct old_pmap *)bh->b_data; - p = pm->pdEntry; - size = 42; - for (i = 0; i < size; p++, i++) { - if (p->pdStart && p->pdSize && - p->pdFSID == cpu_to_be32(0x54465331)/*"TFS1"*/ && - (sbi->part < 0 || sbi->part == i)) { - *part_start += be32_to_cpu(p->pdStart); - *part_size = be32_to_cpu(p->pdSize); - res = 0; - } - } + res = hfs_parse_old_pmap(sb, data, part_start, part_size); break; - } case HFS_NEW_PMAP_MAGIC: - { - struct new_pmap *pm; - - pm = (struct new_pmap *)bh->b_data; - size = be32_to_cpu(pm->pmMapBlkCnt); - for (i = 0; i < size;) { - if (!memcmp(pm->pmPartType,"Apple_HFS", 9) && - (sbi->part < 0 || sbi->part == i)) { - *part_start += be32_to_cpu(pm->pmPyPartStart); - *part_size = be32_to_cpu(pm->pmPartBlkCnt); - res = 0; - break; - } - brelse(bh); - bh = sb_bread512(sb, *part_start + HFS_PMAP_BLK + ++i, pm); - if (!bh) - return -EIO; - if (pm->pmSig != cpu_to_be16(HFS_NEW_PMAP_MAGIC)) - break; - } + res = hfs_parse_new_pmap(sb, data, part_start, part_size); + break; + default: + res = -ENOENT; break; - } } - brelse(bh); + kfree(data); return res; } From 7dc4f001123f9ebe3b010a6c26acd18698ad205f Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 23 Nov 2010 14:37:57 +0100 Subject: [PATCH 06/17] hfsplus: make sure sync writes out all metadata hfsplus stores all metadata except for the volume headers in special inodes. While these are marked hashed and periodically written out by the flusher threads, we can't rely on that for sync. For the case of a data integrity sync the VM has life-lock avoidance code that avoids writing inodes again that are redirtied during the sync, which is something that can happen easily for hfsplus. So make sure we explicitly write out the metadata inodes at the beginning of hfsplus_sync_fs. Signed-off-by: Christoph Hellwig --- fs/hfsplus/super.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index fe8f7bffbea50..df6bea02b2b47 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -164,6 +164,22 @@ int hfsplus_sync_fs(struct super_block *sb, int wait) sb->s_dirt = 0; + /* + * Explicitly write out the special metadata inodes. + * + * While these special inodes are marked as hashed and written + * out peridocically by the flusher threads we redirty them + * during writeout of normal inodes, and thus the life lock + * prevents us from getting the latest state to disk. + */ + error = filemap_write_and_wait(sbi->cat_tree->inode->i_mapping); + error2 = filemap_write_and_wait(sbi->ext_tree->inode->i_mapping); + if (!error) + error = error2; + error2 = filemap_write_and_wait(sbi->alloc_file->i_mapping); + if (!error) + error = error2; + mutex_lock(&sbi->vh_mutex); mutex_lock(&sbi->alloc_mutex); vhdr->free_blocks = cpu_to_be32(sbi->free_blocks); @@ -176,9 +192,11 @@ int hfsplus_sync_fs(struct super_block *sb, int wait) write_backup = 1; } - error = hfsplus_submit_bio(sb->s_bdev, + error2 = hfsplus_submit_bio(sb->s_bdev, sbi->part_start + HFSPLUS_VOLHEAD_SECTOR, sbi->s_vhdr, WRITE_SYNC); + if (!error) + error = error2; if (!write_backup) goto out; From f02e26f8d90f8cde98314c72c2e890bc281a8346 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 23 Nov 2010 14:38:02 +0100 Subject: [PATCH 07/17] hfsplus: avoid useless work in hfsplus_sync_fs There is no reason to write out the metadata inodes or volume headers during a non-blocking sync, as we are almost guaranteed to dirty them again during the inode writeouts. Signed-off-by: Christoph Hellwig --- fs/hfsplus/super.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index df6bea02b2b47..56e6cf80c5e07 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -160,6 +160,9 @@ int hfsplus_sync_fs(struct super_block *sb, int wait) int write_backup = 0; int error, error2; + if (!wait) + return 0; + dprint(DBG_SUPER, "hfsplus_write_super\n"); sb->s_dirt = 0; From 281469766bdde2d14bc73e1fec347e6dd7f63319 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 23 Nov 2010 14:38:06 +0100 Subject: [PATCH 08/17] hfsplus: simplify fsync Remove lots of code we don't need from fsync, we just need to call ->write_inode on the inode if it's dirty, for which sync_inode_metadata is a lot more efficient than write_inode_now, and we need to write out the various metadata inodes, which we now do explicitly instead of by calling ->sync_fs. Signed-off-by: Christoph Hellwig --- fs/hfsplus/inode.c | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index 8afd7e84f98d5..be68961da9977 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -302,29 +302,28 @@ static int hfsplus_setattr(struct dentry *dentry, struct iattr *attr) return 0; } -static int hfsplus_file_fsync(struct file *filp, int datasync) +static int hfsplus_file_fsync(struct file *file, int datasync) { - struct inode *inode = filp->f_mapping->host; - struct super_block * sb; - int ret, err; - - /* sync the inode to buffers */ - ret = write_inode_now(inode, 0); - - /* sync the superblock to buffers */ - sb = inode->i_sb; - if (sb->s_dirt) { - if (!(sb->s_flags & MS_RDONLY)) - hfsplus_sync_fs(sb, 1); - else - sb->s_dirt = 0; - } + struct inode *inode = file->f_mapping->host; + struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); + int error, error2; - /* .. finally sync the buffers to disk */ - err = sync_blockdev(sb->s_bdev); - if (!ret) - ret = err; - return ret; + /* + * Sync inode metadata into the catalog and extent trees. + */ + sync_inode_metadata(inode, 1); + + /* + * And explicitly write out the btrees. + */ + error = filemap_write_and_wait(sbi->cat_tree->inode->i_mapping); + error2 = filemap_write_and_wait(sbi->ext_tree->inode->i_mapping); + if (!error) + error = error2; + error2 = filemap_write_and_wait(sbi->alloc_file->i_mapping); + if (!error) + error = error2; + return error; } static const struct inode_operations hfsplus_file_inode_operations = { From eb29d66d4f2dc98a81ae590bbdddc8cfa8964d73 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 23 Nov 2010 14:38:10 +0100 Subject: [PATCH 09/17] hfsplus: write up fsync for directories fsync is supposed to not just work on regular files, but also on directories. Fortunately enough hfsplus_file_fsync works just fine for directories, so we can just wire it up. Signed-off-by: Christoph Hellwig --- fs/hfsplus/dir.c | 1 + fs/hfsplus/hfsplus_fs.h | 1 + fs/hfsplus/inode.c | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 9d59c0571f598..e44c78a837e8c 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c @@ -485,6 +485,7 @@ const struct inode_operations hfsplus_dir_inode_operations = { }; const struct file_operations hfsplus_dir_operations = { + .fsync = hfsplus_file_fsync, .read = generic_read_dir, .readdir = hfsplus_readdir, .unlocked_ioctl = hfsplus_ioctl, diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index 0d8532d966943..625549579e9ea 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h @@ -352,6 +352,7 @@ int hfsplus_cat_read_inode(struct inode *, struct hfs_find_data *); int hfsplus_cat_write_inode(struct inode *); struct inode *hfsplus_new_inode(struct super_block *, int); void hfsplus_delete_inode(struct inode *); +int hfsplus_file_fsync(struct file *file, int datasync); /* ioctl.c */ long hfsplus_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index be68961da9977..8cd8dc2e7fdd8 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -302,7 +302,7 @@ static int hfsplus_setattr(struct dentry *dentry, struct iattr *attr) return 0; } -static int hfsplus_file_fsync(struct file *file, int datasync) +int hfsplus_file_fsync(struct file *file, int datasync) { struct inode *inode = file->f_mapping->host; struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); From b33b7921db14abcd10c30d0ccfc68e364f5ef7fe Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 23 Nov 2010 14:38:13 +0100 Subject: [PATCH 10/17] hfsplus: split up inode flags Split the flags field in the hfsplus inode into an extent_state flag that is locked by the extent_lock, and a new flags field that uses atomic bitops. The second will grow more flags in the next patch. Signed-off-by: Christoph Hellwig --- fs/hfsplus/extents.c | 20 ++++++++++---------- fs/hfsplus/hfsplus_fs.h | 18 ++++++++++++------ fs/hfsplus/inode.c | 9 ++++++--- fs/hfsplus/super.c | 1 + 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c index 0c9cb1820a523..06b4fc3151a39 100644 --- a/fs/hfsplus/extents.c +++ b/fs/hfsplus/extents.c @@ -95,24 +95,24 @@ static void __hfsplus_ext_write_extent(struct inode *inode, struct hfs_find_data HFSPLUS_TYPE_RSRC : HFSPLUS_TYPE_DATA); res = hfs_brec_find(fd); - if (hip->flags & HFSPLUS_FLG_EXT_NEW) { + if (hip->extent_state & HFSPLUS_EXT_NEW) { if (res != -ENOENT) return; hfs_brec_insert(fd, hip->cached_extents, sizeof(hfsplus_extent_rec)); - hip->flags &= ~(HFSPLUS_FLG_EXT_DIRTY | HFSPLUS_FLG_EXT_NEW); + hip->extent_state &= ~(HFSPLUS_EXT_DIRTY | HFSPLUS_EXT_NEW); } else { if (res) return; hfs_bnode_write(fd->bnode, hip->cached_extents, fd->entryoffset, fd->entrylength); - hip->flags &= ~HFSPLUS_FLG_EXT_DIRTY; + hip->extent_state &= ~HFSPLUS_EXT_DIRTY; } } static void hfsplus_ext_write_extent_locked(struct inode *inode) { - if (HFSPLUS_I(inode)->flags & HFSPLUS_FLG_EXT_DIRTY) { + if (HFSPLUS_I(inode)->extent_state & HFSPLUS_EXT_DIRTY) { struct hfs_find_data fd; hfs_find_init(HFSPLUS_SB(inode->i_sb)->ext_tree, &fd); @@ -155,7 +155,7 @@ static inline int __hfsplus_ext_cache_extent(struct hfs_find_data *fd, struct in WARN_ON(!mutex_is_locked(&hip->extents_lock)); - if (hip->flags & HFSPLUS_FLG_EXT_DIRTY) + if (hip->extent_state & HFSPLUS_EXT_DIRTY) __hfsplus_ext_write_extent(inode, fd); res = __hfsplus_ext_read_extent(fd, hip->cached_extents, inode->i_ino, @@ -167,7 +167,7 @@ static inline int __hfsplus_ext_cache_extent(struct hfs_find_data *fd, struct in hip->cached_blocks = hfsplus_ext_block_count(hip->cached_extents); } else { hip->cached_start = hip->cached_blocks = 0; - hip->flags &= ~(HFSPLUS_FLG_EXT_DIRTY | HFSPLUS_FLG_EXT_NEW); + hip->extent_state &= ~(HFSPLUS_EXT_DIRTY | HFSPLUS_EXT_NEW); } return res; } @@ -429,7 +429,7 @@ int hfsplus_file_extend(struct inode *inode) start, len); if (!res) { hfsplus_dump_extent(hip->cached_extents); - hip->flags |= HFSPLUS_FLG_EXT_DIRTY; + hip->extent_state |= HFSPLUS_EXT_DIRTY; hip->cached_blocks += len; } else if (res == -ENOSPC) goto insert_extent; @@ -450,7 +450,7 @@ int hfsplus_file_extend(struct inode *inode) hip->cached_extents[0].start_block = cpu_to_be32(start); hip->cached_extents[0].block_count = cpu_to_be32(len); hfsplus_dump_extent(hip->cached_extents); - hip->flags |= HFSPLUS_FLG_EXT_DIRTY | HFSPLUS_FLG_EXT_NEW; + hip->extent_state |= HFSPLUS_EXT_DIRTY | HFSPLUS_EXT_NEW; hip->cached_start = hip->alloc_blocks; hip->cached_blocks = len; @@ -513,12 +513,12 @@ void hfsplus_file_truncate(struct inode *inode) alloc_cnt - start, alloc_cnt - blk_cnt); hfsplus_dump_extent(hip->cached_extents); if (blk_cnt > start) { - hip->flags |= HFSPLUS_FLG_EXT_DIRTY; + hip->extent_state |= HFSPLUS_EXT_DIRTY; break; } alloc_cnt = start; hip->cached_start = hip->cached_blocks = 0; - hip->flags &= ~(HFSPLUS_FLG_EXT_DIRTY | HFSPLUS_FLG_EXT_NEW); + hip->extent_state &= ~(HFSPLUS_EXT_DIRTY | HFSPLUS_EXT_NEW); hfs_brec_remove(&fd); } hfs_find_exit(&fd); diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index 625549579e9ea..9889d0033b8f3 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h @@ -171,7 +171,7 @@ struct hfsplus_inode_info { u32 cached_blocks; hfsplus_extent_rec first_extents; hfsplus_extent_rec cached_extents; - unsigned long flags; + unsigned int extent_state; struct mutex extents_lock; /* @@ -185,6 +185,11 @@ struct hfsplus_inode_info { */ u32 linkid; + /* + * Accessed using atomic bitops. + */ + unsigned long flags; + /* * Protected by i_mutex. */ @@ -196,12 +201,13 @@ struct hfsplus_inode_info { struct inode vfs_inode; }; -#define HFSPLUS_FLG_RSRC 0x0001 -#define HFSPLUS_FLG_EXT_DIRTY 0x0002 -#define HFSPLUS_FLG_EXT_NEW 0x0004 +#define HFSPLUS_EXT_DIRTY 0x0001 +#define HFSPLUS_EXT_NEW 0x0002 + +#define HFSPLUS_I_RSRC 0 /* represents a resource fork */ -#define HFSPLUS_IS_DATA(inode) (!(HFSPLUS_I(inode)->flags & HFSPLUS_FLG_RSRC)) -#define HFSPLUS_IS_RSRC(inode) (HFSPLUS_I(inode)->flags & HFSPLUS_FLG_RSRC) +#define HFSPLUS_IS_RSRC(inode) \ + test_bit(HFSPLUS_I_RSRC, &HFSPLUS_I(inode)->flags) struct hfs_find_data { /* filled by caller */ diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index 8cd8dc2e7fdd8..0946e2cdca5e9 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -190,7 +190,9 @@ static struct dentry *hfsplus_file_lookup(struct inode *dir, struct dentry *dent inode->i_ino = dir->i_ino; INIT_LIST_HEAD(&hip->open_dir_list); mutex_init(&hip->extents_lock); - hip->flags = HFSPLUS_FLG_RSRC; + hip->extent_state = 0; + hip->flags = 0; + set_bit(HFSPLUS_I_RSRC, &hip->flags); hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd); err = hfsplus_find_cat(sb, dir->i_ino, &fd); @@ -369,6 +371,7 @@ struct inode *hfsplus_new_inode(struct super_block *sb, int mode) INIT_LIST_HEAD(&hip->open_dir_list); mutex_init(&hip->extents_lock); atomic_set(&hip->opencnt, 0); + hip->extent_state = 0; hip->flags = 0; memset(hip->first_extents, 0, sizeof(hfsplus_extent_rec)); memset(hip->cached_extents, 0, sizeof(hfsplus_extent_rec)); @@ -498,8 +501,8 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) hfs_bnode_read(fd->bnode, &entry, fd->entryoffset, sizeof(struct hfsplus_cat_file)); - hfsplus_inode_read_fork(inode, HFSPLUS_IS_DATA(inode) ? - &file->data_fork : &file->rsrc_fork); + hfsplus_inode_read_fork(inode, HFSPLUS_IS_RSRC(inode) ? + &file->rsrc_fork : &file->data_fork); hfsplus_get_perms(inode, &file->permissions, 0); inode->i_nlink = 1; if (S_ISREG(inode->i_mode)) { diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 56e6cf80c5e07..985423728e1d1 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -66,6 +66,7 @@ struct inode *hfsplus_iget(struct super_block *sb, unsigned long ino) INIT_LIST_HEAD(&HFSPLUS_I(inode)->open_dir_list); mutex_init(&HFSPLUS_I(inode)->extents_lock); HFSPLUS_I(inode)->flags = 0; + HFSPLUS_I(inode)->extent_state = 0; HFSPLUS_I(inode)->rsrc_inode = NULL; atomic_set(&HFSPLUS_I(inode)->opencnt, 0); From e34947056076ca5467ee8256d2d9cbc594a79b37 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 23 Nov 2010 14:38:15 +0100 Subject: [PATCH 11/17] hfsplus: optimize fsync Avoid doing unessecary work in fsync. Do nothing unless the inode was marked dirty, and only write the various metadata inodes out if they contain any dirty state from this inode. This is archived by adding three new dirty bits to the hfsplus-specific inode which are set in the correct places. Signed-off-by: Christoph Hellwig --- fs/hfsplus/catalog.c | 10 ++++++---- fs/hfsplus/extents.c | 30 +++++++++++++++++++++++------- fs/hfsplus/hfsplus_fs.h | 37 ++++++++++++++++++++++++++----------- fs/hfsplus/inode.c | 27 +++++++++++++++++++-------- fs/hfsplus/ioctl.c | 4 +++- fs/hfsplus/super.c | 2 +- 6 files changed, 78 insertions(+), 32 deletions(-) diff --git a/fs/hfsplus/catalog.c b/fs/hfsplus/catalog.c index 8af45fc5b051a..0aa40b36a9e75 100644 --- a/fs/hfsplus/catalog.c +++ b/fs/hfsplus/catalog.c @@ -227,7 +227,8 @@ int hfsplus_create_cat(u32 cnid, struct inode *dir, struct qstr *str, struct ino dir->i_size++; dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; - mark_inode_dirty(dir); + hfsplus_mark_inode_dirty(dir, HFSPLUS_I_CAT_DIRTY); + hfs_find_exit(&fd); return 0; @@ -308,7 +309,7 @@ int hfsplus_delete_cat(u32 cnid, struct inode *dir, struct qstr *str) dir->i_size--; dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; - mark_inode_dirty(dir); + hfsplus_mark_inode_dirty(dir, HFSPLUS_I_CAT_DIRTY); out: hfs_find_exit(&fd); @@ -353,7 +354,6 @@ int hfsplus_rename_cat(u32 cnid, goto out; dst_dir->i_size++; dst_dir->i_mtime = dst_dir->i_ctime = CURRENT_TIME_SEC; - mark_inode_dirty(dst_dir); /* finally remove the old entry */ hfsplus_cat_build_key(sb, src_fd.search_key, src_dir->i_ino, src_name); @@ -365,7 +365,6 @@ int hfsplus_rename_cat(u32 cnid, goto out; src_dir->i_size--; src_dir->i_mtime = src_dir->i_ctime = CURRENT_TIME_SEC; - mark_inode_dirty(src_dir); /* remove old thread entry */ hfsplus_cat_build_key(sb, src_fd.search_key, cnid, NULL); @@ -387,6 +386,9 @@ int hfsplus_rename_cat(u32 cnid, goto out; } err = hfs_brec_insert(&dst_fd, &entry, entry_size); + + hfsplus_mark_inode_dirty(dst_dir, HFSPLUS_I_CAT_DIRTY); + hfsplus_mark_inode_dirty(src_dir, HFSPLUS_I_CAT_DIRTY); out: hfs_bnode_put(dst_fd.bnode); hfs_find_exit(&src_fd); diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c index 06b4fc3151a39..b1127ef267505 100644 --- a/fs/hfsplus/extents.c +++ b/fs/hfsplus/extents.c @@ -108,6 +108,14 @@ static void __hfsplus_ext_write_extent(struct inode *inode, struct hfs_find_data fd->entryoffset, fd->entrylength); hip->extent_state &= ~HFSPLUS_EXT_DIRTY; } + + /* + * We can't just use hfsplus_mark_inode_dirty here, because we + * also get called from hfsplus_write_inode, which should not + * redirty the inode. Instead the callers have to be careful + * to explicily mark the inode dirty, too. + */ + set_bit(HFSPLUS_I_EXT_DIRTY, &hip->flags); } static void hfsplus_ext_write_extent_locked(struct inode *inode) @@ -197,6 +205,7 @@ int hfsplus_get_block(struct inode *inode, sector_t iblock, struct hfsplus_inode_info *hip = HFSPLUS_I(inode); int res = -EIO; u32 ablock, dblock, mask; + int was_dirty = 0; int shift; /* Convert inode block to disk allocation block */ @@ -223,14 +232,20 @@ int hfsplus_get_block(struct inode *inode, sector_t iblock, return -EIO; mutex_lock(&hip->extents_lock); + + /* + * hfsplus_ext_read_extent will write out a cached extent into + * the extents btree. In that case we may have to mark the inode + * dirty even for a pure read of an extent here. + */ + was_dirty = (hip->extent_state & HFSPLUS_EXT_DIRTY); res = hfsplus_ext_read_extent(inode, ablock); - if (!res) { - dblock = hfsplus_ext_find_block(hip->cached_extents, - ablock - hip->cached_start); - } else { + if (res) { mutex_unlock(&hip->extents_lock); return -EIO; } + dblock = hfsplus_ext_find_block(hip->cached_extents, + ablock - hip->cached_start); mutex_unlock(&hip->extents_lock); done: @@ -242,8 +257,9 @@ int hfsplus_get_block(struct inode *inode, sector_t iblock, hip->phys_size += sb->s_blocksize; hip->fs_blocks++; inode_add_bytes(inode, sb->s_blocksize); - mark_inode_dirty(inode); } + if (create || was_dirty) + mark_inode_dirty(inode); return 0; } @@ -438,7 +454,7 @@ int hfsplus_file_extend(struct inode *inode) mutex_unlock(&hip->extents_lock); if (!res) { hip->alloc_blocks += len; - mark_inode_dirty(inode); + hfsplus_mark_inode_dirty(inode, HFSPLUS_I_ALLOC_DIRTY); } return res; @@ -529,5 +545,5 @@ void hfsplus_file_truncate(struct inode *inode) hip->phys_size = inode->i_size; hip->fs_blocks = (inode->i_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits; inode_set_bytes(inode, hip->fs_blocks << sb->s_blocksize_bits); - mark_inode_dirty(inode); + hfsplus_mark_inode_dirty(inode, HFSPLUS_I_ALLOC_DIRTY); } diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index 9889d0033b8f3..65c698f78ef73 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h @@ -157,6 +157,11 @@ struct hfsplus_sb_info { #define HFSPLUS_SB_HFSX 3 #define HFSPLUS_SB_CASEFOLD 4 +static inline struct hfsplus_sb_info *HFSPLUS_SB(struct super_block *sb) +{ + return sb->s_fs_info; +} + struct hfsplus_inode_info { atomic_t opencnt; @@ -205,10 +210,31 @@ struct hfsplus_inode_info { #define HFSPLUS_EXT_NEW 0x0002 #define HFSPLUS_I_RSRC 0 /* represents a resource fork */ +#define HFSPLUS_I_CAT_DIRTY 1 /* has changes in the catalog tree */ +#define HFSPLUS_I_EXT_DIRTY 2 /* has changes in the extent tree */ +#define HFSPLUS_I_ALLOC_DIRTY 3 /* has changes in the allocation file */ #define HFSPLUS_IS_RSRC(inode) \ test_bit(HFSPLUS_I_RSRC, &HFSPLUS_I(inode)->flags) +static inline struct hfsplus_inode_info *HFSPLUS_I(struct inode *inode) +{ + return list_entry(inode, struct hfsplus_inode_info, vfs_inode); +} + +/* + * Mark an inode dirty, and also mark the btree in which the + * specific type of metadata is stored. + * For data or metadata that gets written back by into the catalog btree + * by hfsplus_write_inode a plain mark_inode_dirty call is enough. + */ +static inline void hfsplus_mark_inode_dirty(struct inode *inode, + unsigned int flag) +{ + set_bit(flag, &HFSPLUS_I(inode)->flags); + mark_inode_dirty(inode); +} + struct hfs_find_data { /* filled by caller */ hfsplus_btree_key *search_key; @@ -397,17 +423,6 @@ int hfs_part_find(struct super_block *, sector_t *, sector_t *); int hfsplus_submit_bio(struct block_device *bdev, sector_t sector, void *data, int rw); -/* access macros */ -static inline struct hfsplus_sb_info *HFSPLUS_SB(struct super_block *sb) -{ - return sb->s_fs_info; -} - -static inline struct hfsplus_inode_info *HFSPLUS_I(struct inode *inode) -{ - return list_entry(inode, struct hfsplus_inode_info, vfs_inode); -} - /* time macros */ #define __hfsp_mt2ut(t) (be32_to_cpu(t) - 2082844800U) #define __hfsp_ut2mt(t) (cpu_to_be32(t + 2082844800U)) diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index 0946e2cdca5e9..bf6535b73261e 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -307,8 +307,9 @@ static int hfsplus_setattr(struct dentry *dentry, struct iattr *attr) int hfsplus_file_fsync(struct file *file, int datasync) { struct inode *inode = file->f_mapping->host; + struct hfsplus_inode_info *hip = HFSPLUS_I(inode); struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); - int error, error2; + int error = 0, error2; /* * Sync inode metadata into the catalog and extent trees. @@ -318,13 +319,21 @@ int hfsplus_file_fsync(struct file *file, int datasync) /* * And explicitly write out the btrees. */ - error = filemap_write_and_wait(sbi->cat_tree->inode->i_mapping); - error2 = filemap_write_and_wait(sbi->ext_tree->inode->i_mapping); - if (!error) - error = error2; - error2 = filemap_write_and_wait(sbi->alloc_file->i_mapping); - if (!error) - error = error2; + if (test_and_clear_bit(HFSPLUS_I_CAT_DIRTY, &hip->flags)) + error = filemap_write_and_wait(sbi->cat_tree->inode->i_mapping); + + if (test_and_clear_bit(HFSPLUS_I_EXT_DIRTY, &hip->flags)) { + error2 = filemap_write_and_wait(sbi->ext_tree->inode->i_mapping); + if (!error) + error = error2; + } + + if (test_and_clear_bit(HFSPLUS_I_ALLOC_DIRTY, &hip->flags)) { + error2 = filemap_write_and_wait(sbi->alloc_file->i_mapping); + if (!error) + error = error2; + } + return error; } @@ -590,6 +599,8 @@ int hfsplus_cat_write_inode(struct inode *inode) hfs_bnode_write(fd.bnode, &entry, fd.entryoffset, sizeof(struct hfsplus_cat_file)); } + + set_bit(HFSPLUS_I_CAT_DIRTY, &HFSPLUS_I(inode)->flags); out: hfs_find_exit(&fd); return 0; diff --git a/fs/hfsplus/ioctl.c b/fs/hfsplus/ioctl.c index 40a85a3ded6ef..f5a7224f4cbbe 100644 --- a/fs/hfsplus/ioctl.c +++ b/fs/hfsplus/ioctl.c @@ -147,9 +147,11 @@ int hfsplus_setxattr(struct dentry *dentry, const char *name, res = -ERANGE; } else res = -EOPNOTSUPP; - if (!res) + if (!res) { hfs_bnode_write(fd.bnode, &entry, fd.entryoffset, sizeof(struct hfsplus_cat_file)); + hfsplus_mark_inode_dirty(inode, HFSPLUS_I_CAT_DIRTY); + } out: hfs_find_exit(&fd); return res; diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 985423728e1d1..036650123c4c5 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -472,7 +472,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) &str, sbi->hidden_dir); mutex_unlock(&sbi->vh_mutex); - mark_inode_dirty(sbi->hidden_dir); + hfsplus_mark_inode_dirty(sbi->hidden_dir, HFSPLUS_I_CAT_DIRTY); } out: unload_nls(sbi->nls); From 34a2d313c51f47cae50ccb89f4196462665f2c48 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 23 Nov 2010 14:38:21 +0100 Subject: [PATCH 12/17] hfsplus: flush disk caches in sync and fsync Flush the disk cache in fsync and sync to make sure data actually is on disk on completion of these system calls. There is a nobarrier mount option to disable this behaviour. It's slightly misnamed now that barrier actually are gone, but it matches the name used by all major filesystems. Signed-off-by: Christoph Hellwig --- fs/hfsplus/hfsplus_fs.h | 1 + fs/hfsplus/inode.c | 4 ++++ fs/hfsplus/options.c | 11 +++++++++++ fs/hfsplus/super.c | 5 +++++ 4 files changed, 21 insertions(+) diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index 65c698f78ef73..17ac254e72cb1 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h @@ -156,6 +156,7 @@ struct hfsplus_sb_info { #define HFSPLUS_SB_FORCE 2 #define HFSPLUS_SB_HFSX 3 #define HFSPLUS_SB_CASEFOLD 4 +#define HFSPLUS_SB_NOBARRIER 5 static inline struct hfsplus_sb_info *HFSPLUS_SB(struct super_block *sb) { diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index bf6535b73261e..bda7464c205d1 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -8,6 +8,7 @@ * Inode handling routines */ +#include #include #include #include @@ -334,6 +335,9 @@ int hfsplus_file_fsync(struct file *file, int datasync) error = error2; } + if (!test_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags)) + blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL); + return error; } diff --git a/fs/hfsplus/options.c b/fs/hfsplus/options.c index 43b02b5525eb2..dbd9d0c426cb3 100644 --- a/fs/hfsplus/options.c +++ b/fs/hfsplus/options.c @@ -23,6 +23,7 @@ enum { opt_umask, opt_uid, opt_gid, opt_part, opt_session, opt_nls, opt_nodecompose, opt_decompose, + opt_barrier, opt_nobarrier, opt_force, opt_err }; @@ -37,6 +38,8 @@ static const match_table_t tokens = { { opt_nls, "nls=%s" }, { opt_decompose, "decompose" }, { opt_nodecompose, "nodecompose" }, + { opt_barrier, "barrier" }, + { opt_nobarrier, "nobarrier" }, { opt_force, "force" }, { opt_err, NULL } }; @@ -174,6 +177,12 @@ int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi) case opt_nodecompose: set_bit(HFSPLUS_SB_NODECOMPOSE, &sbi->flags); break; + case opt_barrier: + clear_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags); + break; + case opt_nobarrier: + set_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags); + break; case opt_force: set_bit(HFSPLUS_SB_FORCE, &sbi->flags); break; @@ -212,5 +221,7 @@ int hfsplus_show_options(struct seq_file *seq, struct vfsmount *mnt) seq_printf(seq, ",nls=%s", sbi->nls->charset); if (test_bit(HFSPLUS_SB_NODECOMPOSE, &sbi->flags)) seq_printf(seq, ",nodecompose"); + if (test_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags)) + seq_printf(seq, ",nobarrier"); return 0; } diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 036650123c4c5..154478c71f25f 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -212,6 +213,10 @@ int hfsplus_sync_fs(struct super_block *sb, int wait) out: mutex_unlock(&sbi->alloc_mutex); mutex_unlock(&sbi->vh_mutex); + + if (!test_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags)) + blkdev_issue_flush(sb->s_bdev, GFP_KERNEL, NULL); + return error; } From 596276c3571e2108f4b336be545ece2eacf3da59 Mon Sep 17 00:00:00 2001 From: Anton Salikhmetov Date: Thu, 16 Dec 2010 14:44:51 +0200 Subject: [PATCH 13/17] hfsplus: fix an artifact in ioctl flag checking Fix a flag checking artifact in hfsplus_ioctl_getflags() routine found while doing clean-up against assignments inside `if's. Signed-off-by: Anton Salikhmetov Signed-off-by: Christoph Hellwig --- fs/hfsplus/ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/hfsplus/ioctl.c b/fs/hfsplus/ioctl.c index f5a7224f4cbbe..508ce662ce122 100644 --- a/fs/hfsplus/ioctl.c +++ b/fs/hfsplus/ioctl.c @@ -28,7 +28,7 @@ static int hfsplus_ioctl_getflags(struct file *file, int __user *user_flags) if (inode->i_flags & S_IMMUTABLE) flags |= FS_IMMUTABLE_FL; - if (inode->i_flags |= S_APPEND) + if (inode->i_flags & S_APPEND) flags |= FS_APPEND_FL; if (hip->userflags & HFSPLUS_FLG_NODUMP) flags |= FS_NODUMP_FL; From 2753cc281c9a0e8a0a45ee2b8110866a9fe63bdd Mon Sep 17 00:00:00 2001 From: Anton Salikhmetov Date: Thu, 16 Dec 2010 18:08:38 +0200 Subject: [PATCH 14/17] hfsplus: over 80 character lines clean-up Match coding style line length limitation where checkpatch.pl reported over-80-character-line warnings. Signed-off-by: Anton Salikhmetov Signed-off-by: Christoph Hellwig --- fs/hfsplus/bfind.c | 6 ++-- fs/hfsplus/bitmap.c | 3 +- fs/hfsplus/bnode.c | 41 +++++++++++++++------- fs/hfsplus/brec.c | 26 +++++++++----- fs/hfsplus/btree.c | 31 ++++++++++++----- fs/hfsplus/catalog.c | 75 ++++++++++++++++++++++++++-------------- fs/hfsplus/dir.c | 34 ++++++++++++------ fs/hfsplus/extents.c | 28 ++++++++++----- fs/hfsplus/hfsplus_fs.h | 30 ++++++++++------ fs/hfsplus/hfsplus_raw.h | 3 +- fs/hfsplus/inode.c | 26 +++++++++----- fs/hfsplus/options.c | 7 ++-- fs/hfsplus/part_tbl.c | 3 +- fs/hfsplus/super.c | 34 ++++++++++++------ fs/hfsplus/unicode.c | 21 +++++++---- fs/hfsplus/wrapper.c | 15 +++++--- 16 files changed, 260 insertions(+), 123 deletions(-) diff --git a/fs/hfsplus/bfind.c b/fs/hfsplus/bfind.c index d182438c7ae4b..5d799c13205f5 100644 --- a/fs/hfsplus/bfind.c +++ b/fs/hfsplus/bfind.c @@ -22,7 +22,8 @@ int hfs_find_init(struct hfs_btree *tree, struct hfs_find_data *fd) return -ENOMEM; fd->search_key = ptr; fd->key = ptr + tree->max_key_len + 2; - dprint(DBG_BNODE_REFS, "find_init: %d (%p)\n", tree->cnid, __builtin_return_address(0)); + dprint(DBG_BNODE_REFS, "find_init: %d (%p)\n", + tree->cnid, __builtin_return_address(0)); mutex_lock(&tree->tree_lock); return 0; } @@ -31,7 +32,8 @@ void hfs_find_exit(struct hfs_find_data *fd) { hfs_bnode_put(fd->bnode); kfree(fd->search_key); - dprint(DBG_BNODE_REFS, "find_exit: %d (%p)\n", fd->tree->cnid, __builtin_return_address(0)); + dprint(DBG_BNODE_REFS, "find_exit: %d (%p)\n", + fd->tree->cnid, __builtin_return_address(0)); mutex_unlock(&fd->tree->tree_lock); fd->tree = NULL; } diff --git a/fs/hfsplus/bitmap.c b/fs/hfsplus/bitmap.c index ad57f5991eb1f..1cad80c789cb4 100644 --- a/fs/hfsplus/bitmap.c +++ b/fs/hfsplus/bitmap.c @@ -15,7 +15,8 @@ #define PAGE_CACHE_BITS (PAGE_CACHE_SIZE * 8) -int hfsplus_block_allocate(struct super_block *sb, u32 size, u32 offset, u32 *max) +int hfsplus_block_allocate(struct super_block *sb, u32 size, + u32 offset, u32 *max) { struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); struct page *page; diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index c8aa1659b8385..cf7dc8dac766b 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -212,7 +212,8 @@ void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len) dst_page--; } src -= len; - memmove(kmap(*dst_page) + src, kmap(*src_page) + src, len); + memmove(kmap(*dst_page) + src, + kmap(*src_page) + src, len); kunmap(*src_page); set_page_dirty(*dst_page); kunmap(*dst_page); @@ -250,14 +251,16 @@ void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len) if (src == dst) { l = min(len, (int)PAGE_CACHE_SIZE - src); - memmove(kmap(*dst_page) + src, kmap(*src_page) + src, l); + memmove(kmap(*dst_page) + src, + kmap(*src_page) + src, l); kunmap(*src_page); set_page_dirty(*dst_page); kunmap(*dst_page); while ((len -= l) != 0) { l = min(len, (int)PAGE_CACHE_SIZE); - memmove(kmap(*++dst_page), kmap(*++src_page), l); + memmove(kmap(*++dst_page), + kmap(*++src_page), l); kunmap(*src_page); set_page_dirty(*dst_page); kunmap(*dst_page); @@ -268,7 +271,8 @@ void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len) do { src_ptr = kmap(*src_page) + src; dst_ptr = kmap(*dst_page) + dst; - if (PAGE_CACHE_SIZE - src < PAGE_CACHE_SIZE - dst) { + if (PAGE_CACHE_SIZE - src < + PAGE_CACHE_SIZE - dst) { l = PAGE_CACHE_SIZE - src; src = 0; dst += l; @@ -340,7 +344,8 @@ void hfs_bnode_unlink(struct hfs_bnode *node) return; tmp->next = node->next; cnid = cpu_to_be32(tmp->next); - hfs_bnode_write(tmp, &cnid, offsetof(struct hfs_bnode_desc, next), 4); + hfs_bnode_write(tmp, &cnid, + offsetof(struct hfs_bnode_desc, next), 4); hfs_bnode_put(tmp); } else if (node->type == HFS_NODE_LEAF) tree->leaf_head = node->next; @@ -351,7 +356,8 @@ void hfs_bnode_unlink(struct hfs_bnode *node) return; tmp->prev = node->prev; cnid = cpu_to_be32(tmp->prev); - hfs_bnode_write(tmp, &cnid, offsetof(struct hfs_bnode_desc, prev), 4); + hfs_bnode_write(tmp, &cnid, + offsetof(struct hfs_bnode_desc, prev), 4); hfs_bnode_put(tmp); } else if (node->type == HFS_NODE_LEAF) tree->leaf_tail = node->prev; @@ -379,7 +385,9 @@ struct hfs_bnode *hfs_bnode_findhash(struct hfs_btree *tree, u32 cnid) struct hfs_bnode *node; if (cnid >= tree->node_count) { - printk(KERN_ERR "hfs: request for non-existent node %d in B*Tree\n", cnid); + printk(KERN_ERR "hfs: request for non-existent node " + "%d in B*Tree\n", + cnid); return NULL; } @@ -402,7 +410,9 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid) loff_t off; if (cnid >= tree->node_count) { - printk(KERN_ERR "hfs: request for non-existent node %d in B*Tree\n", cnid); + printk(KERN_ERR "hfs: request for non-existent node " + "%d in B*Tree\n", + cnid); return NULL; } @@ -429,7 +439,8 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid) } else { spin_unlock(&tree->hash_lock); kfree(node); - wait_event(node2->lock_wq, !test_bit(HFS_BNODE_NEW, &node2->flags)); + wait_event(node2->lock_wq, + !test_bit(HFS_BNODE_NEW, &node2->flags)); return node2; } spin_unlock(&tree->hash_lock); @@ -483,7 +494,8 @@ struct hfs_bnode *hfs_bnode_find(struct hfs_btree *tree, u32 num) if (node) { hfs_bnode_get(node); spin_unlock(&tree->hash_lock); - wait_event(node->lock_wq, !test_bit(HFS_BNODE_NEW, &node->flags)); + wait_event(node->lock_wq, + !test_bit(HFS_BNODE_NEW, &node->flags)); if (test_bit(HFS_BNODE_ERROR, &node->flags)) goto node_error; return node; @@ -497,7 +509,8 @@ struct hfs_bnode *hfs_bnode_find(struct hfs_btree *tree, u32 num) if (!test_bit(HFS_BNODE_NEW, &node->flags)) return node; - desc = (struct hfs_bnode_desc *)(kmap(node->page[0]) + node->page_offset); + desc = (struct hfs_bnode_desc *)(kmap(node->page[0]) + + node->page_offset); node->prev = be32_to_cpu(desc->prev); node->next = be32_to_cpu(desc->next); node->num_recs = be16_to_cpu(desc->num_recs); @@ -607,7 +620,8 @@ void hfs_bnode_get(struct hfs_bnode *node) if (node) { atomic_inc(&node->refcnt); dprint(DBG_BNODE_REFS, "get_node(%d:%d): %d\n", - node->tree->cnid, node->this, atomic_read(&node->refcnt)); + node->tree->cnid, node->this, + atomic_read(&node->refcnt)); } } @@ -619,7 +633,8 @@ void hfs_bnode_put(struct hfs_bnode *node) int i; dprint(DBG_BNODE_REFS, "put_node(%d:%d): %d\n", - node->tree->cnid, node->this, atomic_read(&node->refcnt)); + node->tree->cnid, node->this, + atomic_read(&node->refcnt)); BUG_ON(!atomic_read(&node->refcnt)); if (!atomic_dec_and_lock(&node->refcnt, &tree->hash_lock)) return; diff --git a/fs/hfsplus/brec.c b/fs/hfsplus/brec.c index 81f7e6e51d5ae..2312de34bd426 100644 --- a/fs/hfsplus/brec.c +++ b/fs/hfsplus/brec.c @@ -39,7 +39,8 @@ u16 hfs_brec_keylen(struct hfs_bnode *node, u16 rec) !(node->tree->attributes & HFS_TREE_VARIDXKEYS)) { retval = node->tree->max_key_len + 2; } else { - recoff = hfs_bnode_read_u16(node, node->tree->node_size - (rec + 1) * 2); + recoff = hfs_bnode_read_u16(node, + node->tree->node_size - (rec + 1) * 2); if (!recoff) return 0; @@ -84,7 +85,8 @@ int hfs_brec_insert(struct hfs_find_data *fd, void *entry, int entry_len) end_rec_off = tree->node_size - (node->num_recs + 1) * 2; end_off = hfs_bnode_read_u16(node, end_rec_off); end_rec_off -= 2; - dprint(DBG_BNODE_MOD, "insert_rec: %d, %d, %d, %d\n", rec, size, end_off, end_rec_off); + dprint(DBG_BNODE_MOD, "insert_rec: %d, %d, %d, %d\n", + rec, size, end_off, end_rec_off); if (size > end_rec_off - end_off) { if (new_node) panic("not enough room!\n"); @@ -99,7 +101,9 @@ int hfs_brec_insert(struct hfs_find_data *fd, void *entry, int entry_len) } node->num_recs++; /* write new last offset */ - hfs_bnode_write_u16(node, offsetof(struct hfs_bnode_desc, num_recs), node->num_recs); + hfs_bnode_write_u16(node, + offsetof(struct hfs_bnode_desc, num_recs), + node->num_recs); hfs_bnode_write_u16(node, end_rec_off, end_off + size); data_off = end_off; data_rec_off = end_rec_off + 2; @@ -151,7 +155,8 @@ int hfs_brec_insert(struct hfs_find_data *fd, void *entry, int entry_len) if (tree->attributes & HFS_TREE_VARIDXKEYS) key_len = be16_to_cpu(fd->search_key->key_len) + 2; else { - fd->search_key->key_len = cpu_to_be16(tree->max_key_len); + fd->search_key->key_len = + cpu_to_be16(tree->max_key_len); key_len = tree->max_key_len + 2; } goto again; @@ -180,7 +185,8 @@ int hfs_brec_remove(struct hfs_find_data *fd) mark_inode_dirty(tree->inode); } hfs_bnode_dump(node); - dprint(DBG_BNODE_MOD, "remove_rec: %d, %d\n", fd->record, fd->keylength + fd->entrylength); + dprint(DBG_BNODE_MOD, "remove_rec: %d, %d\n", + fd->record, fd->keylength + fd->entrylength); if (!--node->num_recs) { hfs_bnode_unlink(node); if (!node->parent) @@ -194,7 +200,9 @@ int hfs_brec_remove(struct hfs_find_data *fd) __hfs_brec_find(node, fd); goto again; } - hfs_bnode_write_u16(node, offsetof(struct hfs_bnode_desc, num_recs), node->num_recs); + hfs_bnode_write_u16(node, + offsetof(struct hfs_bnode_desc, num_recs), + node->num_recs); if (rec_off == end_off) goto skip; @@ -364,7 +372,8 @@ static int hfs_brec_update_parent(struct hfs_find_data *fd) newkeylen = hfs_bnode_read_u16(node, 14) + 2; else fd->keylength = newkeylen = tree->max_key_len + 2; - dprint(DBG_BNODE_MOD, "update_rec: %d, %d, %d\n", rec, fd->keylength, newkeylen); + dprint(DBG_BNODE_MOD, "update_rec: %d, %d, %d\n", + rec, fd->keylength, newkeylen); rec_off = tree->node_size - (rec + 2) * 2; end_rec_off = tree->node_size - (parent->num_recs + 1) * 2; @@ -383,7 +392,8 @@ static int hfs_brec_update_parent(struct hfs_find_data *fd) parent = fd->bnode; rec = fd->record; rec_off = tree->node_size - (rec + 2) * 2; - end_rec_off = tree->node_size - (parent->num_recs + 1) * 2; + end_rec_off = tree->node_size - + (parent->num_recs + 1) * 2; } } diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c index 97556f932d57f..21023d9f8ff3d 100644 --- a/fs/hfsplus/btree.c +++ b/fs/hfsplus/btree.c @@ -51,7 +51,8 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id) goto free_inode; /* Load the header */ - head = (struct hfs_btree_header_rec *)(kmap(page) + sizeof(struct hfs_bnode_desc)); + head = (struct hfs_btree_header_rec *)(kmap(page) + + sizeof(struct hfs_bnode_desc)); tree->root = be32_to_cpu(head->root); tree->leaf_count = be32_to_cpu(head->leaf_count); tree->leaf_head = be32_to_cpu(head->leaf_head); @@ -115,7 +116,9 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id) tree->node_size_shift = ffs(size) - 1; - tree->pages_per_bnode = (tree->node_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; + tree->pages_per_bnode = + (tree->node_size + PAGE_CACHE_SIZE - 1) >> + PAGE_CACHE_SHIFT; kunmap(page); page_cache_release(page); @@ -144,8 +147,10 @@ void hfs_btree_close(struct hfs_btree *tree) while ((node = tree->node_hash[i])) { tree->node_hash[i] = node->next_hash; if (atomic_read(&node->refcnt)) - printk(KERN_CRIT "hfs: node %d:%d still has %d user(s)!\n", - node->tree->cnid, node->this, atomic_read(&node->refcnt)); + printk(KERN_CRIT "hfs: node %d:%d " + "still has %d user(s)!\n", + node->tree->cnid, node->this, + atomic_read(&node->refcnt)); hfs_bnode_free(node); tree->node_hash_cnt--; } @@ -166,7 +171,8 @@ void hfs_btree_write(struct hfs_btree *tree) return; /* Load the header */ page = node->page[0]; - head = (struct hfs_btree_header_rec *)(kmap(page) + sizeof(struct hfs_bnode_desc)); + head = (struct hfs_btree_header_rec *)(kmap(page) + + sizeof(struct hfs_bnode_desc)); head->root = cpu_to_be32(tree->root); head->leaf_count = cpu_to_be32(tree->leaf_count); @@ -272,7 +278,8 @@ struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree) tree->free_nodes--; mark_inode_dirty(tree->inode); hfs_bnode_put(node); - return hfs_bnode_create(tree, idx); + return hfs_bnode_create(tree, + idx); } } } @@ -329,7 +336,9 @@ void hfs_bmap_free(struct hfs_bnode *node) hfs_bnode_put(node); if (!i) { /* panic */; - printk(KERN_CRIT "hfs: unable to free bnode %u. bmap not found!\n", node->this); + printk(KERN_CRIT "hfs: unable to free bnode %u. " + "bmap not found!\n", + node->this); return; } node = hfs_bnode_find(tree, i); @@ -337,7 +346,9 @@ void hfs_bmap_free(struct hfs_bnode *node) return; if (node->type != HFS_NODE_MAP) { /* panic */; - printk(KERN_CRIT "hfs: invalid bmap found! (%u,%d)\n", node->this, node->type); + printk(KERN_CRIT "hfs: invalid bmap found! " + "(%u,%d)\n", + node->this, node->type); hfs_bnode_put(node); return; } @@ -350,7 +361,9 @@ void hfs_bmap_free(struct hfs_bnode *node) m = 1 << (~nidx & 7); byte = data[off]; if (!(byte & m)) { - printk(KERN_CRIT "hfs: trying to free free bnode %u(%d)\n", node->this, node->type); + printk(KERN_CRIT "hfs: trying to free free bnode " + "%u(%d)\n", + node->this, node->type); kunmap(page); hfs_bnode_put(node); return; diff --git a/fs/hfsplus/catalog.c b/fs/hfsplus/catalog.c index 0aa40b36a9e75..b4ba1b3193336 100644 --- a/fs/hfsplus/catalog.c +++ b/fs/hfsplus/catalog.c @@ -91,7 +91,8 @@ void hfsplus_cat_set_perms(struct inode *inode, struct hfsplus_perm *perms) perms->dev = 0; } -static int hfsplus_cat_build_record(hfsplus_cat_entry *entry, u32 cnid, struct inode *inode) +static int hfsplus_cat_build_record(hfsplus_cat_entry *entry, + u32 cnid, struct inode *inode) { struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); @@ -128,20 +129,32 @@ static int hfsplus_cat_build_record(hfsplus_cat_entry *entry, u32 cnid, struct i if (cnid == inode->i_ino) { hfsplus_cat_set_perms(inode, &file->permissions); if (S_ISLNK(inode->i_mode)) { - file->user_info.fdType = cpu_to_be32(HFSP_SYMLINK_TYPE); - file->user_info.fdCreator = cpu_to_be32(HFSP_SYMLINK_CREATOR); + file->user_info.fdType = + cpu_to_be32(HFSP_SYMLINK_TYPE); + file->user_info.fdCreator = + cpu_to_be32(HFSP_SYMLINK_CREATOR); } else { - file->user_info.fdType = cpu_to_be32(sbi->type); - file->user_info.fdCreator = cpu_to_be32(sbi->creator); + file->user_info.fdType = + cpu_to_be32(sbi->type); + file->user_info.fdCreator = + cpu_to_be32(sbi->creator); } - if ((file->permissions.rootflags | file->permissions.userflags) & HFSPLUS_FLG_IMMUTABLE) - file->flags |= cpu_to_be16(HFSPLUS_FILE_LOCKED); + if (HFSPLUS_FLG_IMMUTABLE & + (file->permissions.rootflags | + file->permissions.userflags)) + file->flags |= + cpu_to_be16(HFSPLUS_FILE_LOCKED); } else { - file->user_info.fdType = cpu_to_be32(HFSP_HARDLINK_TYPE); - file->user_info.fdCreator = cpu_to_be32(HFSP_HFSPLUS_CREATOR); - file->user_info.fdFlags = cpu_to_be16(0x100); - file->create_date = HFSPLUS_I(sbi->hidden_dir)->create_date; - file->permissions.dev = cpu_to_be32(HFSPLUS_I(inode)->linkid); + file->user_info.fdType = + cpu_to_be32(HFSP_HARDLINK_TYPE); + file->user_info.fdCreator = + cpu_to_be32(HFSP_HFSPLUS_CREATOR); + file->user_info.fdFlags = + cpu_to_be16(0x100); + file->create_date = + HFSPLUS_I(sbi->hidden_dir)->create_date; + file->permissions.dev = + cpu_to_be32(HFSPLUS_I(inode)->linkid); } return sizeof(*file); } @@ -182,12 +195,14 @@ int hfsplus_find_cat(struct super_block *sb, u32 cnid, return -EIO; } - hfsplus_cat_build_key_uni(fd->search_key, be32_to_cpu(tmp.thread.parentID), - &tmp.thread.nodeName); + hfsplus_cat_build_key_uni(fd->search_key, + be32_to_cpu(tmp.thread.parentID), + &tmp.thread.nodeName); return hfs_brec_find(fd); } -int hfsplus_create_cat(u32 cnid, struct inode *dir, struct qstr *str, struct inode *inode) +int hfsplus_create_cat(u32 cnid, struct inode *dir, + struct qstr *str, struct inode *inode) { struct super_block *sb = dir->i_sb; struct hfs_find_data fd; @@ -195,13 +210,15 @@ int hfsplus_create_cat(u32 cnid, struct inode *dir, struct qstr *str, struct ino int entry_size; int err; - dprint(DBG_CAT_MOD, "create_cat: %s,%u(%d)\n", str->name, cnid, inode->i_nlink); + dprint(DBG_CAT_MOD, "create_cat: %s,%u(%d)\n", + str->name, cnid, inode->i_nlink); hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd); hfsplus_cat_build_key(sb, fd.search_key, cnid, NULL); - entry_size = hfsplus_fill_cat_thread(sb, &entry, S_ISDIR(inode->i_mode) ? + entry_size = hfsplus_fill_cat_thread(sb, &entry, + S_ISDIR(inode->i_mode) ? HFSPLUS_FOLDER_THREAD : HFSPLUS_FILE_THREAD, - dir->i_ino, str); + dir->i_ino, str); err = hfs_brec_find(&fd); if (err != -ENOENT) { if (!err) @@ -250,7 +267,8 @@ int hfsplus_delete_cat(u32 cnid, struct inode *dir, struct qstr *str) int err, off; u16 type; - dprint(DBG_CAT_MOD, "delete_cat: %s,%u\n", str ? str->name : NULL, cnid); + dprint(DBG_CAT_MOD, "delete_cat: %s,%u\n", + str ? str->name : NULL, cnid); hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd); if (!str) { @@ -261,11 +279,15 @@ int hfsplus_delete_cat(u32 cnid, struct inode *dir, struct qstr *str) if (err) goto out; - off = fd.entryoffset + offsetof(struct hfsplus_cat_thread, nodeName); + off = fd.entryoffset + + offsetof(struct hfsplus_cat_thread, nodeName); fd.search_key->cat.parent = cpu_to_be32(dir->i_ino); - hfs_bnode_read(fd.bnode, &fd.search_key->cat.name.length, off, 2); + hfs_bnode_read(fd.bnode, + &fd.search_key->cat.name.length, off, 2); len = be16_to_cpu(fd.search_key->cat.name.length) * 2; - hfs_bnode_read(fd.bnode, &fd.search_key->cat.name.unicode, off + 2, len); + hfs_bnode_read(fd.bnode, + &fd.search_key->cat.name.unicode, + off + 2, len); fd.search_key->key_len = cpu_to_be16(6 + len); } else hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino, str); @@ -282,7 +304,8 @@ int hfsplus_delete_cat(u32 cnid, struct inode *dir, struct qstr *str) hfsplus_free_fork(sb, cnid, &fork, HFSPLUS_TYPE_DATA); #endif - off = fd.entryoffset + offsetof(struct hfsplus_cat_file, rsrc_fork); + off = fd.entryoffset + + offsetof(struct hfsplus_cat_file, rsrc_fork); hfs_bnode_read(fd.bnode, &fork, off, sizeof(fork)); hfsplus_free_fork(sb, cnid, &fork, HFSPLUS_TYPE_RSRC); } @@ -326,7 +349,8 @@ int hfsplus_rename_cat(u32 cnid, int entry_size, type; int err = 0; - dprint(DBG_CAT_MOD, "rename_cat: %u - %lu,%s - %lu,%s\n", cnid, src_dir->i_ino, src_name->name, + dprint(DBG_CAT_MOD, "rename_cat: %u - %lu,%s - %lu,%s\n", + cnid, src_dir->i_ino, src_name->name, dst_dir->i_ino, dst_name->name); hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &src_fd); dst_fd = src_fd; @@ -378,7 +402,8 @@ int hfsplus_rename_cat(u32 cnid, /* create new thread entry */ hfsplus_cat_build_key(sb, dst_fd.search_key, cnid, NULL); - entry_size = hfsplus_fill_cat_thread(sb, &entry, type, dst_dir->i_ino, dst_name); + entry_size = hfsplus_fill_cat_thread(sb, &entry, type, + dst_dir->i_ino, dst_name); err = hfs_brec_find(&dst_fd); if (err != -ENOENT) { if (!err) diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index e44c78a837e8c..c423942793eec 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c @@ -66,11 +66,17 @@ static struct dentry *hfsplus_lookup(struct inode *dir, struct dentry *dentry, goto fail; } cnid = be32_to_cpu(entry.file.id); - if (entry.file.user_info.fdType == cpu_to_be32(HFSP_HARDLINK_TYPE) && - entry.file.user_info.fdCreator == cpu_to_be32(HFSP_HFSPLUS_CREATOR) && - (entry.file.create_date == HFSPLUS_I(HFSPLUS_SB(sb)->hidden_dir)->create_date || - entry.file.create_date == HFSPLUS_I(sb->s_root->d_inode)->create_date) && - HFSPLUS_SB(sb)->hidden_dir) { + if (entry.file.user_info.fdType == + cpu_to_be32(HFSP_HARDLINK_TYPE) && + entry.file.user_info.fdCreator == + cpu_to_be32(HFSP_HFSPLUS_CREATOR) && + (entry.file.create_date == + HFSPLUS_I(HFSPLUS_SB(sb)->hidden_dir)-> + create_date || + entry.file.create_date == + HFSPLUS_I(sb->s_root->d_inode)-> + create_date) && + HFSPLUS_SB(sb)->hidden_dir) { struct qstr str; char name[32]; @@ -83,11 +89,13 @@ static struct dentry *hfsplus_lookup(struct inode *dir, struct dentry *dentry, linkid = 0; } else { dentry->d_fsdata = (void *)(unsigned long)cnid; - linkid = be32_to_cpu(entry.file.permissions.dev); + linkid = + be32_to_cpu(entry.file.permissions.dev); str.len = sprintf(name, "iNode%d", linkid); str.name = name; hfsplus_cat_build_key(sb, fd.search_key, - HFSPLUS_SB(sb)->hidden_dir->i_ino, &str); + HFSPLUS_SB(sb)->hidden_dir->i_ino, + &str); goto again; } } else if (!dentry->d_fsdata) @@ -139,7 +147,8 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) filp->f_pos++; /* fall through */ case 1: - hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength); + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, + fd.entrylength); if (be16_to_cpu(entry.type) != HFSPLUS_FOLDER_THREAD) { printk(KERN_ERR "hfs: bad catalog folder thread\n"); err = -EIO; @@ -169,14 +178,16 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) err = -EIO; goto out; } - hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength); + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, + fd.entrylength); type = be16_to_cpu(entry.type); len = HFSPLUS_MAX_STRLEN; err = hfsplus_uni2asc(sb, &fd.key->cat.name, strbuf, &len); if (err) goto out; if (type == HFSPLUS_FOLDER) { - if (fd.entrylength < sizeof(struct hfsplus_cat_folder)) { + if (fd.entrylength < + sizeof(struct hfsplus_cat_folder)) { printk(KERN_ERR "hfs: small dir entry\n"); err = -EIO; goto out; @@ -273,7 +284,8 @@ static int hfsplus_link(struct dentry *src_dentry, struct inode *dst_dir, HFSPLUS_I(inode)->linkid = id; cnid = sbi->next_cnid++; src_dentry->d_fsdata = (void *)(unsigned long)cnid; - res = hfsplus_create_cat(cnid, src_dir, &src_dentry->d_name, inode); + res = hfsplus_create_cat(cnid, src_dir, + &src_dentry->d_name, inode); if (res) /* panic? */ goto out; diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c index b1127ef267505..1ae2fe5cfa744 100644 --- a/fs/hfsplus/extents.c +++ b/fs/hfsplus/extents.c @@ -83,7 +83,8 @@ static u32 hfsplus_ext_lastblock(struct hfsplus_extent *ext) return be32_to_cpu(ext->start_block) + be32_to_cpu(ext->block_count); } -static void __hfsplus_ext_write_extent(struct inode *inode, struct hfs_find_data *fd) +static void __hfsplus_ext_write_extent(struct inode *inode, + struct hfs_find_data *fd) { struct hfsplus_inode_info *hip = HFSPLUS_I(inode); int res; @@ -152,11 +153,13 @@ static inline int __hfsplus_ext_read_extent(struct hfs_find_data *fd, return -ENOENT; if (fd->entrylength != sizeof(hfsplus_extent_rec)) return -EIO; - hfs_bnode_read(fd->bnode, extent, fd->entryoffset, sizeof(hfsplus_extent_rec)); + hfs_bnode_read(fd->bnode, extent, fd->entryoffset, + sizeof(hfsplus_extent_rec)); return 0; } -static inline int __hfsplus_ext_cache_extent(struct hfs_find_data *fd, struct inode *inode, u32 block) +static inline int __hfsplus_ext_cache_extent(struct hfs_find_data *fd, + struct inode *inode, u32 block) { struct hfsplus_inode_info *hip = HFSPLUS_I(inode); int res; @@ -172,7 +175,8 @@ static inline int __hfsplus_ext_cache_extent(struct hfs_find_data *fd, struct in HFSPLUS_TYPE_DATA); if (!res) { hip->cached_start = be32_to_cpu(fd->key->ext.start_block); - hip->cached_blocks = hfsplus_ext_block_count(hip->cached_extents); + hip->cached_blocks = + hfsplus_ext_block_count(hip->cached_extents); } else { hip->cached_start = hip->cached_blocks = 0; hip->extent_state &= ~(HFSPLUS_EXT_DIRTY | HFSPLUS_EXT_NEW); @@ -249,9 +253,12 @@ int hfsplus_get_block(struct inode *inode, sector_t iblock, mutex_unlock(&hip->extents_lock); done: - dprint(DBG_EXTENT, "get_block(%lu): %llu - %u\n", inode->i_ino, (long long)iblock, dblock); + dprint(DBG_EXTENT, "get_block(%lu): %llu - %u\n", + inode->i_ino, (long long)iblock, dblock); mask = (1 << sbi->fs_shift) - 1; - map_bh(bh_result, sb, (dblock << sbi->fs_shift) + sbi->blockoffset + (iblock & mask)); + map_bh(bh_result, sb, + (dblock << sbi->fs_shift) + sbi->blockoffset + + (iblock & mask)); if (create) { set_buffer_new(bh_result); hip->phys_size += sb->s_blocksize; @@ -342,7 +349,8 @@ static int hfsplus_free_extents(struct super_block *sb, } } -int hfsplus_free_fork(struct super_block *sb, u32 cnid, struct hfsplus_fork_raw *fork, int type) +int hfsplus_free_fork(struct super_block *sb, u32 cnid, + struct hfsplus_fork_raw *fork, int type) { struct hfs_find_data fd; hfsplus_extent_rec ext_entry; @@ -497,7 +505,8 @@ void hfsplus_file_truncate(struct inode *inode) &page, &fsdata); if (res) return; - res = pagecache_write_end(NULL, mapping, size, 0, 0, page, fsdata); + res = pagecache_write_end(NULL, mapping, size, + 0, 0, page, fsdata); if (res < 0) return; mark_inode_dirty(inode); @@ -543,7 +552,8 @@ void hfsplus_file_truncate(struct inode *inode) hip->alloc_blocks = blk_cnt; out: hip->phys_size = inode->i_size; - hip->fs_blocks = (inode->i_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits; + hip->fs_blocks = (inode->i_size + sb->s_blocksize - 1) >> + sb->s_blocksize_bits; inode_set_bytes(inode, hip->fs_blocks << sb->s_blocksize_bits); hfsplus_mark_inode_dirty(inode, HFSPLUS_I_ALLOC_DIRTY); } diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index 17ac254e72cb1..c4abec1678268 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h @@ -37,7 +37,8 @@ #define HFSPLUS_TYPE_DATA 0x00 #define HFSPLUS_TYPE_RSRC 0xFF -typedef int (*btree_keycmp)(const hfsplus_btree_key *, const hfsplus_btree_key *); +typedef int (*btree_keycmp)(const hfsplus_btree_key *, + const hfsplus_btree_key *); #define NODE_HASH_SIZE 256 @@ -352,9 +353,12 @@ int hfs_brec_read(struct hfs_find_data *, void *, int); int hfs_brec_goto(struct hfs_find_data *, int); /* catalog.c */ -int hfsplus_cat_case_cmp_key(const hfsplus_btree_key *, const hfsplus_btree_key *); -int hfsplus_cat_bin_cmp_key(const hfsplus_btree_key *, const hfsplus_btree_key *); -void hfsplus_cat_build_key(struct super_block *sb, hfsplus_btree_key *, u32, struct qstr *); +int hfsplus_cat_case_cmp_key(const hfsplus_btree_key *, + const hfsplus_btree_key *); +int hfsplus_cat_bin_cmp_key(const hfsplus_btree_key *, + const hfsplus_btree_key *); +void hfsplus_cat_build_key(struct super_block *sb, + hfsplus_btree_key *, u32, struct qstr *); int hfsplus_find_cat(struct super_block *, u32, struct hfs_find_data *); int hfsplus_create_cat(u32, struct inode *, struct qstr *, struct inode *); int hfsplus_delete_cat(u32, struct inode *, struct qstr *); @@ -370,7 +374,8 @@ extern const struct file_operations hfsplus_dir_operations; int hfsplus_ext_cmp_key(const hfsplus_btree_key *, const hfsplus_btree_key *); void hfsplus_ext_write_extent(struct inode *); int hfsplus_get_block(struct inode *, sector_t, struct buffer_head *, int); -int hfsplus_free_fork(struct super_block *, u32, struct hfsplus_fork_raw *, int); +int hfsplus_free_fork(struct super_block *, u32, + struct hfsplus_fork_raw *, int); int hfsplus_file_extend(struct inode *); void hfsplus_file_truncate(struct inode *); @@ -411,12 +416,17 @@ extern u16 hfsplus_decompose_table[]; extern u16 hfsplus_compose_table[]; /* unicode.c */ -int hfsplus_strcasecmp(const struct hfsplus_unistr *, const struct hfsplus_unistr *); -int hfsplus_strcmp(const struct hfsplus_unistr *, const struct hfsplus_unistr *); -int hfsplus_uni2asc(struct super_block *, const struct hfsplus_unistr *, char *, int *); -int hfsplus_asc2uni(struct super_block *, struct hfsplus_unistr *, const char *, int); +int hfsplus_strcasecmp(const struct hfsplus_unistr *, + const struct hfsplus_unistr *); +int hfsplus_strcmp(const struct hfsplus_unistr *, + const struct hfsplus_unistr *); +int hfsplus_uni2asc(struct super_block *, + const struct hfsplus_unistr *, char *, int *); +int hfsplus_asc2uni(struct super_block *, + struct hfsplus_unistr *, const char *, int); int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str); -int hfsplus_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *s2); +int hfsplus_compare_dentry(struct dentry *dentry, + struct qstr *s1, struct qstr *s2); /* wrapper.c */ int hfsplus_read_wrapper(struct super_block *); diff --git a/fs/hfsplus/hfsplus_raw.h b/fs/hfsplus/hfsplus_raw.h index 6892899fd6fbb..927cdd6d5bf59 100644 --- a/fs/hfsplus/hfsplus_raw.h +++ b/fs/hfsplus/hfsplus_raw.h @@ -36,7 +36,8 @@ #define HFSP_WRAPOFF_EMBEDSIG 0x7C #define HFSP_WRAPOFF_EMBEDEXT 0x7E -#define HFSP_HIDDENDIR_NAME "\xe2\x90\x80\xe2\x90\x80\xe2\x90\x80\xe2\x90\x80HFS+ Private Data" +#define HFSP_HIDDENDIR_NAME \ + "\xe2\x90\x80\xe2\x90\x80\xe2\x90\x80\xe2\x90\x80HFS+ Private Data" #define HFSP_HARDLINK_TYPE 0x686c6e6b /* 'hlnk' */ #define HFSP_HFSPLUS_CREATOR 0x6866732b /* 'hfs+' */ diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index bda7464c205d1..8d7350e5ce0d7 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -78,7 +78,8 @@ static int hfsplus_releasepage(struct page *page, gfp_t mask) if (!tree) return 0; if (tree->node_size >= PAGE_CACHE_SIZE) { - nidx = page->index >> (tree->node_size_shift - PAGE_CACHE_SHIFT); + nidx = page->index >> + (tree->node_size_shift - PAGE_CACHE_SHIFT); spin_lock(&tree->hash_lock); node = hfs_bnode_findhash(tree, nidx); if (!node) @@ -91,7 +92,8 @@ static int hfsplus_releasepage(struct page *page, gfp_t mask) } spin_unlock(&tree->hash_lock); } else { - nidx = page->index << (PAGE_CACHE_SHIFT - tree->node_size_shift); + nidx = page->index << + (PAGE_CACHE_SHIFT - tree->node_size_shift); i = 1 << (PAGE_CACHE_SHIFT - tree->node_size_shift); spin_lock(&tree->hash_lock); do { @@ -167,8 +169,8 @@ const struct dentry_operations hfsplus_dentry_operations = { .d_compare = hfsplus_compare_dentry, }; -static struct dentry *hfsplus_file_lookup(struct inode *dir, struct dentry *dentry, - struct nameidata *nd) +static struct dentry *hfsplus_file_lookup(struct inode *dir, + struct dentry *dentry, struct nameidata *nd) { struct hfs_find_data fd; struct super_block *sb = dir->i_sb; @@ -222,7 +224,8 @@ static struct dentry *hfsplus_file_lookup(struct inode *dir, struct dentry *dent return NULL; } -static void hfsplus_get_perms(struct inode *inode, struct hfsplus_perm *perms, int dir) +static void hfsplus_get_perms(struct inode *inode, + struct hfsplus_perm *perms, int dir) { struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); u16 mode; @@ -324,7 +327,8 @@ int hfsplus_file_fsync(struct file *file, int datasync) error = filemap_write_and_wait(sbi->cat_tree->inode->i_mapping); if (test_and_clear_bit(HFSPLUS_I_EXT_DIRTY, &hip->flags)) { - error2 = filemap_write_and_wait(sbi->ext_tree->inode->i_mapping); + error2 = + filemap_write_and_wait(sbi->ext_tree->inode->i_mapping); if (!error) error = error2; } @@ -472,7 +476,8 @@ void hfsplus_inode_read_fork(struct inode *inode, struct hfsplus_fork_raw *fork) } } -void hfsplus_inode_write_fork(struct inode *inode, struct hfsplus_fork_raw *fork) +void hfsplus_inode_write_fork(struct inode *inode, + struct hfsplus_fork_raw *fork) { memcpy(&fork->extents, &HFSPLUS_I(inode)->first_extents, sizeof(hfsplus_extent_rec)); @@ -520,7 +525,8 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) inode->i_nlink = 1; if (S_ISREG(inode->i_mode)) { if (file->permissions.dev) - inode->i_nlink = be32_to_cpu(file->permissions.dev); + inode->i_nlink = + be32_to_cpu(file->permissions.dev); inode->i_op = &hfsplus_file_inode_operations; inode->i_fop = &hfsplus_file_operations; inode->i_mapping->a_ops = &hfsplus_aops; @@ -593,7 +599,9 @@ int hfsplus_cat_write_inode(struct inode *inode) sizeof(struct hfsplus_cat_file)); hfsplus_inode_write_fork(inode, &file->data_fork); hfsplus_cat_set_perms(inode, &file->permissions); - if ((file->permissions.rootflags | file->permissions.userflags) & HFSPLUS_FLG_IMMUTABLE) + if (HFSPLUS_FLG_IMMUTABLE & + (file->permissions.rootflags | + file->permissions.userflags)) file->flags |= cpu_to_be16(HFSPLUS_FILE_LOCKED); else file->flags &= cpu_to_be16(~HFSPLUS_FILE_LOCKED); diff --git a/fs/hfsplus/options.c b/fs/hfsplus/options.c index dbd9d0c426cb3..bb62a5882147e 100644 --- a/fs/hfsplus/options.c +++ b/fs/hfsplus/options.c @@ -165,7 +165,9 @@ int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi) if (p) sbi->nls = load_nls(p); if (!sbi->nls) { - printk(KERN_ERR "hfs: unable to load nls mapping \"%s\"\n", p); + printk(KERN_ERR "hfs: unable to load " + "nls mapping \"%s\"\n", + p); kfree(p); return 0; } @@ -212,7 +214,8 @@ int hfsplus_show_options(struct seq_file *seq, struct vfsmount *mnt) seq_printf(seq, ",creator=%.4s", (char *)&sbi->creator); if (sbi->type != HFSPLUS_DEF_CR_TYPE) seq_printf(seq, ",type=%.4s", (char *)&sbi->type); - seq_printf(seq, ",umask=%o,uid=%u,gid=%u", sbi->umask, sbi->uid, sbi->gid); + seq_printf(seq, ",umask=%o,uid=%u,gid=%u", sbi->umask, + sbi->uid, sbi->gid); if (sbi->part >= 0) seq_printf(seq, ",part=%u", sbi->part); if (sbi->session >= 0) diff --git a/fs/hfsplus/part_tbl.c b/fs/hfsplus/part_tbl.c index 58918222a6048..79eea8efad8e4 100644 --- a/fs/hfsplus/part_tbl.c +++ b/fs/hfsplus/part_tbl.c @@ -2,7 +2,8 @@ * linux/fs/hfsplus/part_tbl.c * * Copyright (C) 1996-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU General Public License. + * This file may be distributed under the terms of + * the GNU General Public License. * * Original code to handle the new style Mac partition table based on * a patch contributed by Holger Schemel (aeglos@valinor.owl.de). diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 154478c71f25f..3c9f30e9cd361 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -290,18 +290,25 @@ static int hfsplus_remount(struct super_block *sb, int *flags, char *data) return -EINVAL; if (!(vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_UNMNT))) { - printk(KERN_WARNING "hfs: filesystem was not cleanly unmounted, " - "running fsck.hfsplus is recommended. leaving read-only.\n"); + printk(KERN_WARNING "hfs: filesystem was " + "not cleanly unmounted, " + "running fsck.hfsplus is recommended. " + "leaving read-only.\n"); sb->s_flags |= MS_RDONLY; *flags |= MS_RDONLY; } else if (force) { /* nothing */ - } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) { - printk(KERN_WARNING "hfs: filesystem is marked locked, leaving read-only.\n"); + } else if (vhdr->attributes & + cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) { + printk(KERN_WARNING "hfs: filesystem is marked locked, " + "leaving read-only.\n"); sb->s_flags |= MS_RDONLY; *flags |= MS_RDONLY; - } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) { - printk(KERN_WARNING "hfs: filesystem is marked journaled, leaving read-only.\n"); + } else if (vhdr->attributes & + cpu_to_be32(HFSPLUS_VOL_JOURNALED)) { + printk(KERN_WARNING "hfs: filesystem is " + "marked journaled, " + "leaving read-only.\n"); sb->s_flags |= MS_RDONLY; *flags |= MS_RDONLY; } @@ -391,17 +398,22 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) sb->s_maxbytes = MAX_LFS_FILESIZE; if (!(vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_UNMNT))) { - printk(KERN_WARNING "hfs: Filesystem was not cleanly unmounted, " - "running fsck.hfsplus is recommended. mounting read-only.\n"); + printk(KERN_WARNING "hfs: Filesystem was " + "not cleanly unmounted, " + "running fsck.hfsplus is recommended. " + "mounting read-only.\n"); sb->s_flags |= MS_RDONLY; } else if (test_and_clear_bit(HFSPLUS_SB_FORCE, &sbi->flags)) { /* nothing */ } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) { printk(KERN_WARNING "hfs: Filesystem is marked locked, mounting read-only.\n"); sb->s_flags |= MS_RDONLY; - } else if ((vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) && !(sb->s_flags & MS_RDONLY)) { - printk(KERN_WARNING "hfs: write access to a journaled filesystem is not supported, " - "use the force option at your own risk, mounting read-only.\n"); + } else if ((vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) && + !(sb->s_flags & MS_RDONLY)) { + printk(KERN_WARNING "hfs: write access to " + "a journaled filesystem is not supported, " + "use the force option at your own risk, " + "mounting read-only.\n"); sb->s_flags |= MS_RDONLY; } diff --git a/fs/hfsplus/unicode.c b/fs/hfsplus/unicode.c index b66d67de882c3..15703e81174e2 100644 --- a/fs/hfsplus/unicode.c +++ b/fs/hfsplus/unicode.c @@ -118,7 +118,9 @@ static u16 *hfsplus_compose_lookup(u16 *p, u16 cc) return NULL; } -int hfsplus_uni2asc(struct super_block *sb, const struct hfsplus_unistr *ustr, char *astr, int *len_p) +int hfsplus_uni2asc(struct super_block *sb, + const struct hfsplus_unistr *ustr, + char *astr, int *len_p) { const hfsplus_unichr *ip; struct nls_table *nls = HFSPLUS_SB(sb)->nls; @@ -171,7 +173,8 @@ int hfsplus_uni2asc(struct super_block *sb, const struct hfsplus_unistr *ustr, c goto same; c1 = be16_to_cpu(*ip); if (likely(compose)) - ce1 = hfsplus_compose_lookup(hfsplus_compose_table, c1); + ce1 = hfsplus_compose_lookup( + hfsplus_compose_table, c1); if (ce1) break; switch (c0) { @@ -199,7 +202,8 @@ int hfsplus_uni2asc(struct super_block *sb, const struct hfsplus_unistr *ustr, c if (ce2) { i = 1; while (i < ustrlen) { - ce1 = hfsplus_compose_lookup(ce2, be16_to_cpu(ip[i])); + ce1 = hfsplus_compose_lookup(ce2, + be16_to_cpu(ip[i])); if (!ce1) break; i++; @@ -363,7 +367,8 @@ int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str) * Composed unicode characters are decomposed and case-folding is performed * if the appropriate bits are (un)set on the superblock. */ -int hfsplus_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *s2) +int hfsplus_compare_dentry(struct dentry *dentry, + struct qstr *s1, struct qstr *s2) { struct super_block *sb = dentry->d_sb; int casefold, decompose, size; @@ -388,7 +393,9 @@ int hfsplus_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr * astr1 += size; len1 -= size; - if (!decompose || !(dstr1 = decompose_unichar(c, &dsize1))) { + if (decompose) + dstr1 = decompose_unichar(c, &dsize1); + if (!decompose || !dstr1) { c1 = c; dstr1 = &c1; dsize1 = 1; @@ -400,7 +407,9 @@ int hfsplus_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr * astr2 += size; len2 -= size; - if (!decompose || !(dstr2 = decompose_unichar(c, &dsize2))) { + if (decompose) + dstr2 = decompose_unichar(c, &dsize2); + if (!decompose || !dstr2) { c2 = c; dstr2 = &c2; dsize2 = 1; diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c index 15e0eabb489ef..196231794f646 100644 --- a/fs/hfsplus/wrapper.c +++ b/fs/hfsplus/wrapper.c @@ -74,12 +74,14 @@ static int hfsplus_read_mdb(void *bufptr, struct hfsplus_wd *wd) !(attrib & HFSP_WRAP_ATTRIB_SPARED)) return 0; - wd->ablk_size = be32_to_cpu(*(__be32 *)(bufptr + HFSP_WRAPOFF_ABLKSIZE)); + wd->ablk_size = + be32_to_cpu(*(__be32 *)(bufptr + HFSP_WRAPOFF_ABLKSIZE)); if (wd->ablk_size < HFSPLUS_SECTOR_SIZE) return 0; if (wd->ablk_size % HFSPLUS_SECTOR_SIZE) return 0; - wd->ablk_start = be16_to_cpu(*(__be16 *)(bufptr + HFSP_WRAPOFF_ABLKSTART)); + wd->ablk_start = + be16_to_cpu(*(__be16 *)(bufptr + HFSP_WRAPOFF_ABLKSTART)); extent = get_unaligned_be32(bufptr + HFSP_WRAPOFF_EMBEDEXT); wd->embed_start = (extent >> 16) & 0xFFFF; @@ -102,7 +104,8 @@ static int hfsplus_get_last_session(struct super_block *sb, if (HFSPLUS_SB(sb)->session >= 0) { te.cdte_track = HFSPLUS_SB(sb)->session; te.cdte_format = CDROM_LBA; - res = ioctl_by_bdev(sb->s_bdev, CDROMREADTOCENTRY, (unsigned long)&te); + res = ioctl_by_bdev(sb->s_bdev, + CDROMREADTOCENTRY, (unsigned long)&te); if (!res && (te.cdte_ctrl & CDROM_DATA_TRACK) == 4) { *start = (sector_t)te.cdte_addr.lba << 2; return 0; @@ -111,7 +114,8 @@ static int hfsplus_get_last_session(struct super_block *sb, return -EINVAL; } ms_info.addr_format = CDROM_LBA; - res = ioctl_by_bdev(sb->s_bdev, CDROMMULTISESSION, (unsigned long)&ms_info); + res = ioctl_by_bdev(sb->s_bdev, CDROMMULTISESSION, + (unsigned long)&ms_info); if (!res && ms_info.xa_flag) *start = (sector_t)ms_info.addr.lba << 2; return 0; @@ -212,7 +216,8 @@ int hfsplus_read_wrapper(struct super_block *sb) blocksize >>= 1; if (sb_set_blocksize(sb, blocksize) != blocksize) { - printk(KERN_ERR "hfs: unable to set blocksize to %u!\n", blocksize); + printk(KERN_ERR "hfs: unable to set blocksize to %u!\n", + blocksize); goto out_free_backup_vhdr; } From 21f2296a598c4089e0a9bdf54634269ac913a693 Mon Sep 17 00:00:00 2001 From: Anton Salikhmetov Date: Thu, 16 Dec 2010 18:08:39 +0200 Subject: [PATCH 15/17] hfsplus: C99 comments clean-up Match coding style restriction against C99 comments where checkpatch.pl reported errors about their usage. Signed-off-by: Anton Salikhmetov Signed-off-by: Christoph Hellwig --- fs/hfsplus/bnode.c | 18 ++++++++++-------- fs/hfsplus/extents.c | 2 +- fs/hfsplus/hfsplus_fs.h | 9 +++++---- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index cf7dc8dac766b..c8f4ea4bb5ed7 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -42,7 +42,7 @@ void hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len) u16 hfs_bnode_read_u16(struct hfs_bnode *node, int off) { __be16 data; - // optimize later... + /* TODO: optimize later... */ hfs_bnode_read(node, &data, off, 2); return be16_to_cpu(data); } @@ -50,7 +50,7 @@ u16 hfs_bnode_read_u16(struct hfs_bnode *node, int off) u8 hfs_bnode_read_u8(struct hfs_bnode *node, int off) { u8 data; - // optimize later... + /* TODO: optimize later... */ hfs_bnode_read(node, &data, off, 1); return data; } @@ -96,7 +96,7 @@ void hfs_bnode_write(struct hfs_bnode *node, void *buf, int off, int len) void hfs_bnode_write_u16(struct hfs_bnode *node, int off, u16 data) { __be16 v = cpu_to_be16(data); - // optimize later... + /* TODO: optimize later... */ hfs_bnode_write(node, &v, off, 2); } @@ -362,7 +362,7 @@ void hfs_bnode_unlink(struct hfs_bnode *node) } else if (node->type == HFS_NODE_LEAF) tree->leaf_tail = node->prev; - // move down? + /* move down? */ if (!node->prev && !node->next) { dprint(DBG_BNODE_MOD, "hfs_btree_del_level\n"); } @@ -569,11 +569,13 @@ struct hfs_bnode *hfs_bnode_find(struct hfs_btree *tree, u32 num) void hfs_bnode_free(struct hfs_bnode *node) { - //int i; +#if 0 + int i; - //for (i = 0; i < node->tree->pages_per_bnode; i++) - // if (node->page[i]) - // page_cache_release(node->page[i]); + for (i = 0; i < node->tree->pages_per_bnode; i++) + if (node->page[i]) + page_cache_release(node->page[i]); +#endif kfree(node); } diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c index 1ae2fe5cfa744..4b693b5b6230b 100644 --- a/fs/hfsplus/extents.c +++ b/fs/hfsplus/extents.c @@ -399,7 +399,7 @@ int hfsplus_file_extend(struct inode *inode) if (sbi->alloc_file->i_size * 8 < sbi->total_blocks - sbi->free_blocks + 8) { - // extend alloc file + /* extend alloc file */ printk(KERN_ERR "hfs: extend alloc file! (%Lu,%u,%u)\n", sbi->alloc_file->i_size * 8, sbi->total_blocks, sbi->free_blocks); diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index c4abec1678268..a15e1c11e8209 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h @@ -23,9 +23,11 @@ #define DBG_EXTENT 0x00000020 #define DBG_BITMAP 0x00000040 -//#define DBG_MASK (DBG_EXTENT|DBG_INODE|DBG_BNODE_MOD) -//#define DBG_MASK (DBG_BNODE_MOD|DBG_CAT_MOD|DBG_INODE) -//#define DBG_MASK (DBG_CAT_MOD|DBG_BNODE_REFS|DBG_INODE|DBG_EXTENT) +#if 0 +#define DBG_MASK (DBG_EXTENT|DBG_INODE|DBG_BNODE_MOD) +#define DBG_MASK (DBG_BNODE_MOD|DBG_CAT_MOD|DBG_INODE) +#define DBG_MASK (DBG_CAT_MOD|DBG_BNODE_REFS|DBG_INODE|DBG_EXTENT) +#endif #define DBG_MASK (0) #define dprint(flg, fmt, args...) \ @@ -62,7 +64,6 @@ struct hfs_btree { unsigned int max_key_len; unsigned int depth; - //unsigned int map1_size, map_size; struct mutex tree_lock; unsigned int pages_per_bnode; From 20b7643d8ee44254fc972d42655bace81e7ab50a Mon Sep 17 00:00:00 2001 From: Anton Salikhmetov Date: Thu, 16 Dec 2010 18:08:40 +0200 Subject: [PATCH 16/17] hfsplus: spaces/indentation clean-up Fix incorrect spaces and indentation reported by checkpatch.pl. Signed-off-by: Anton Salikhmetov Signed-off-by: Christoph Hellwig --- fs/hfsplus/dir.c | 2 +- fs/hfsplus/inode.c | 2 +- fs/hfsplus/part_tbl.c | 4 ++-- fs/hfsplus/unicode.c | 20 ++++++++++---------- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index c423942793eec..f611d55c9f5e7 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c @@ -213,7 +213,7 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) err = -EIO; goto out; } - next: +next: filp->f_pos++; if (filp->f_pos >= inode->i_size) goto out; diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index 8d7350e5ce0d7..a8df651747f0e 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -355,7 +355,7 @@ static const struct inode_operations hfsplus_file_inode_operations = { }; static const struct file_operations hfsplus_file_operations = { - .llseek = generic_file_llseek, + .llseek = generic_file_llseek, .read = do_sync_read, .aio_read = generic_file_aio_read, .write = do_sync_write, diff --git a/fs/hfsplus/part_tbl.c b/fs/hfsplus/part_tbl.c index 79eea8efad8e4..d66ad113b1cc4 100644 --- a/fs/hfsplus/part_tbl.c +++ b/fs/hfsplus/part_tbl.c @@ -60,7 +60,7 @@ struct new_pmap { */ struct old_pmap { __be16 pdSig; /* Signature bytes */ - struct old_pmap_entry { + struct old_pmap_entry { __be32 pdStart; __be32 pdSize; __be32 pdFSID; @@ -97,7 +97,7 @@ static int hfs_parse_new_pmap(struct super_block *sb, struct new_pmap *pm, int i = 0; do { - if (!memcmp(pm->pmPartType,"Apple_HFS", 9) && + if (!memcmp(pm->pmPartType, "Apple_HFS", 9) && (sbi->part < 0 || sbi->part == i)) { *part_start += be32_to_cpu(pm->pmPyPartStart); *part_size = be32_to_cpu(pm->pmPartBlkCnt); diff --git a/fs/hfsplus/unicode.c b/fs/hfsplus/unicode.c index 15703e81174e2..7dd90a540546c 100644 --- a/fs/hfsplus/unicode.c +++ b/fs/hfsplus/unicode.c @@ -17,14 +17,14 @@ /* Returns folded char, or 0 if ignorable */ static inline u16 case_fold(u16 c) { - u16 tmp; - - tmp = hfsplus_case_fold_table[c >> 8]; - if (tmp) - tmp = hfsplus_case_fold_table[tmp + (c & 0xff)]; - else - tmp = c; - return tmp; + u16 tmp; + + tmp = hfsplus_case_fold_table[c >> 8]; + if (tmp) + tmp = hfsplus_case_fold_table[tmp + (c & 0xff)]; + else + tmp = c; + return tmp; } /* Compare unicode strings, return values like normal strcmp */ @@ -215,7 +215,7 @@ int hfsplus_uni2asc(struct super_block *sb, goto done; } } - same: +same: switch (c0) { case 0: cc = 0x2400; @@ -226,7 +226,7 @@ int hfsplus_uni2asc(struct super_block *sb, default: cc = c0; } - done: +done: res = nls->uni2char(cc, op, len); if (res < 0) { if (res == -ENAMETOOLONG) From b2837fcf4994e699a4def002e26f274d95b387c1 Mon Sep 17 00:00:00 2001 From: Anton Salikhmetov Date: Thu, 16 Dec 2010 18:08:41 +0200 Subject: [PATCH 17/17] hfsplus: %L-to-%ll, macro correction, and remove unneeded braces Clean-up based on checkpatch.pl report against unnecessary braces (`{' and `}'), non-standard format option %Lu (%llu recommended) as well as one trailing statement in a macro definition which should have been on the next line. Signed-off-by: Anton Salikhmetov Signed-off-by: Christoph Hellwig --- fs/hfsplus/bnode.c | 9 +++------ fs/hfsplus/extents.c | 16 +++++++++------- fs/hfsplus/hfsplus_fs.h | 3 ++- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index c8f4ea4bb5ed7..1c42cc5b899f3 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -363,9 +363,8 @@ void hfs_bnode_unlink(struct hfs_bnode *node) tree->leaf_tail = node->prev; /* move down? */ - if (!node->prev && !node->next) { + if (!node->prev && !node->next) dprint(DBG_BNODE_MOD, "hfs_btree_del_level\n"); - } if (!node->parent) { tree->root = 0; tree->depth = 0; @@ -392,11 +391,9 @@ struct hfs_bnode *hfs_bnode_findhash(struct hfs_btree *tree, u32 cnid) } for (node = tree->node_hash[hfs_bnode_hash(cnid)]; - node; node = node->next_hash) { - if (node->this == cnid) { + node; node = node->next_hash) + if (node->this == cnid) return node; - } - } return NULL; } diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c index 4b693b5b6230b..52a0bcaa7b6d7 100644 --- a/fs/hfsplus/extents.c +++ b/fs/hfsplus/extents.c @@ -397,12 +397,13 @@ int hfsplus_file_extend(struct inode *inode) u32 start, len, goal; int res; - if (sbi->alloc_file->i_size * 8 < - sbi->total_blocks - sbi->free_blocks + 8) { + if (sbi->total_blocks - sbi->free_blocks + 8 > + sbi->alloc_file->i_size * 8) { /* extend alloc file */ - printk(KERN_ERR "hfs: extend alloc file! (%Lu,%u,%u)\n", - sbi->alloc_file->i_size * 8, - sbi->total_blocks, sbi->free_blocks); + printk(KERN_ERR "hfs: extend alloc file! " + "(%llu,%u,%u)\n", + sbi->alloc_file->i_size * 8, + sbi->total_blocks, sbi->free_blocks); return -ENOSPC; } @@ -490,8 +491,9 @@ void hfsplus_file_truncate(struct inode *inode) u32 alloc_cnt, blk_cnt, start; int res; - dprint(DBG_INODE, "truncate: %lu, %Lu -> %Lu\n", - inode->i_ino, (long long)hip->phys_size, inode->i_size); + dprint(DBG_INODE, "truncate: %lu, %llu -> %llu\n", + inode->i_ino, (long long)hip->phys_size, + inode->i_size); if (inode->i_size > hip->phys_size) { struct address_space *mapping = inode->i_mapping; diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index a15e1c11e8209..f7cbdf89ac9b0 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h @@ -31,7 +31,8 @@ #define DBG_MASK (0) #define dprint(flg, fmt, args...) \ - if (flg & DBG_MASK) printk(fmt , ## args) + if (flg & DBG_MASK) \ + printk(fmt , ## args) /* Runtime config options */ #define HFSPLUS_DEF_CR_TYPE 0x3F3F3F3F /* '????' */