staticint 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;
if (!wait) return 0;
hfs_dbg(SUPER, "hfsplus_sync_fs\n");
/* * 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; if (sbi->attr_tree) {
error2 =
filemap_write_and_wait(sbi->attr_tree->inode->i_mapping); if (!error)
error = error2;
}
error2 = filemap_write_and_wait(sbi->alloc_file->i_mapping); if (!error)
error = error2;
err = -EINVAL; if (!sbi->nls) { /* try utf8 first, as this is the old default behaviour */
sbi->nls = load_nls("utf8"); if (!sbi->nls)
sbi->nls = load_nls_default();
}
/* temporarily use utf8 to correctly find the hidden dir below */
nls = sbi->nls;
sbi->nls = load_nls("utf8"); if (!sbi->nls) {
pr_err("unable to load nls for utf8\n"); goto out_unload_nls;
}
/* Grab the volume header */ if (hfsplus_read_wrapper(sb)) { if (!silent)
pr_warn("unable to find HFS+ superblock\n"); goto out_unload_nls;
}
vhdr = sbi->s_vhdr;
/* Copy parts of the volume header into the superblock */
sb->s_magic = HFSPLUS_VOLHEAD_SIG; if (be16_to_cpu(vhdr->version) < HFSPLUS_MIN_VERSION ||
be16_to_cpu(vhdr->version) > HFSPLUS_CURRENT_VERSION) {
pr_err("wrong filesystem version\n"); goto out_free_vhdr;
}
sbi->total_blocks = be32_to_cpu(vhdr->total_blocks);
sbi->free_blocks = be32_to_cpu(vhdr->free_blocks);
sbi->next_cnid = be32_to_cpu(vhdr->next_cnid);
sbi->file_count = be32_to_cpu(vhdr->file_count);
sbi->folder_count = be32_to_cpu(vhdr->folder_count);
sbi->data_clump_blocks =
be32_to_cpu(vhdr->data_clump_sz) >> sbi->alloc_blksz_shift; if (!sbi->data_clump_blocks)
sbi->data_clump_blocks = 1;
sbi->rsrc_clump_blocks =
be32_to_cpu(vhdr->rsrc_clump_sz) >> sbi->alloc_blksz_shift; if (!sbi->rsrc_clump_blocks)
sbi->rsrc_clump_blocks = 1;
if ((last_fs_block > (sector_t)(~0ULL) >> (sbi->alloc_blksz_shift - 9)) ||
(last_fs_page > (pgoff_t)(~0ULL))) {
pr_err("filesystem size too large\n"); goto out_free_vhdr;
}
/* Set up operations so we can load metadata */
sb->s_op = &hfsplus_sops;
sb->s_maxbytes = MAX_LFS_FILESIZE;
if (!(vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_UNMNT))) {
pr_warn("Filesystem was not cleanly unmounted, running fsck.hfsplus is recommended. mounting read-only.\n");
sb->s_flags |= SB_RDONLY;
} elseif (test_and_clear_bit(HFSPLUS_SB_FORCE, &sbi->flags)) { /* nothing */
} elseif (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) {
pr_warn("Filesystem is marked locked, mounting read-only.\n");
sb->s_flags |= SB_RDONLY;
} elseif ((vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) &&
!sb_rdonly(sb)) {
pr_warn("write access to a journaled filesystem is not supported, use the force option at your own risk, mounting read-only.\n");
sb->s_flags |= SB_RDONLY;
}
err = -EINVAL;
/* Load metadata objects (B*Trees) */
sbi->ext_tree = hfs_btree_open(sb, HFSPLUS_EXT_CNID); if (!sbi->ext_tree) {
pr_err("failed to load extents file\n"); goto out_free_vhdr;
}
sbi->cat_tree = hfs_btree_open(sb, HFSPLUS_CAT_CNID); if (!sbi->cat_tree) {
pr_err("failed to load catalog file\n"); goto out_close_ext_tree;
}
atomic_set(&sbi->attr_tree_state, HFSPLUS_EMPTY_ATTR_TREE); if (vhdr->attr_file.total_blocks != 0) {
sbi->attr_tree = hfs_btree_open(sb, HFSPLUS_ATTR_CNID); if (!sbi->attr_tree) {
pr_err("failed to load attributes file\n"); goto out_close_cat_tree;
}
atomic_set(&sbi->attr_tree_state, HFSPLUS_VALID_ATTR_TREE);
}
sb->s_xattr = hfsplus_xattr_handlers;
if (!sb_rdonly(sb)) { /* * H+LX == hfsplusutils, H+Lx == this driver, H+lx is unused * all three are registered with Apple for our use
*/
vhdr->last_mount_vers = cpu_to_be32(HFSP_MOUNT_VERSION);
vhdr->modify_date = hfsp_now2mt();
be32_add_cpu(&vhdr->write_count, 1);
vhdr->attributes &= cpu_to_be32(~HFSPLUS_VOL_UNMNT);
vhdr->attributes |= cpu_to_be32(HFSPLUS_VOL_INCNSTNT);
hfsplus_sync_fs(sb, 1);
/* * Make sure all delayed rcu free inodes are flushed before we * destroy cache.
*/
rcu_barrier();
hfsplus_destroy_attr_tree_cache();
kmem_cache_destroy(hfsplus_inode_cachep);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.