/* * linux/fs/hfs/super.c * * Copyright (C) 1995-1997 Paul H. Hargrove * (C) 2003 Ardis Technologies <roman@ardistech.com> * This file may be distributed under the terms of the GNU General Public License. * * This file contains hfs_read_super(), some of the super_ops and * init_hfs_fs() and exit_hfs_fs(). The remaining super_ops are in * inode.c since they deal with inodes. * * Based on the minix file system code, (C) 1991, 1992 by Linus Torvalds
*/
/* * hfs_put_super() * * This is the put_super() entry in the super_operations structure for * HFS filesystems. The purpose is to release the resources * associated with the superblock sb.
*/ staticvoid hfs_put_super(struct super_block *sb)
{
cancel_delayed_work_sync(&HFS_SB(sb)->mdb_work);
hfs_mdb_close(sb); /* release the MDB's resources */
hfs_mdb_put(sb);
}
/* * hfs_statfs() * * This is the statfs() entry in the super_operations structure for * HFS filesystems. The purpose is to return various data about the * filesystem. * * changed f_files/f_ffree to reflect the fs_ablock/free_ablocks.
*/ staticint hfs_statfs(struct dentry *dentry, struct kstatfs *buf)
{ struct super_block *sb = dentry->d_sb;
u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
/* * hfs_parse_param() * * This function is called by the vfs to parse the mount options.
*/ staticint hfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
{ struct hfs_sb_info *hsb = fc->s_fs_info; struct fs_parse_result result; int opt;
/* hfs does not honor any fs-specific options on remount */ if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE) return 0;
switch (opt) { case opt_uid:
hsb->s_uid = result.uid; break; case opt_gid:
hsb->s_gid = result.gid; break; case opt_umask:
hsb->s_file_umask = (umode_t)result.uint_32;
hsb->s_dir_umask = (umode_t)result.uint_32; break; case opt_file_umask:
hsb->s_file_umask = (umode_t)result.uint_32; break; case opt_dir_umask:
hsb->s_dir_umask = (umode_t)result.uint_32; break; case opt_part:
hsb->part = result.uint_32; break; case opt_session:
hsb->session = result.uint_32; break; case opt_type: if (strlen(param->string) != 4) {
pr_err("type requires a 4 character value\n"); return -EINVAL;
}
memcpy(&hsb->s_type, param->string, 4); break; case opt_creator: if (strlen(param->string) != 4) {
pr_err("creator requires a 4 character value\n"); return -EINVAL;
}
memcpy(&hsb->s_creator, param->string, 4); break; case opt_quiet:
hsb->s_quiet = 1; break; case opt_codepage: if (hsb->nls_disk) {
pr_err("unable to change codepage\n"); return -EINVAL;
}
hsb->nls_disk = load_nls(param->string); if (!hsb->nls_disk) {
pr_err("unable to load codepage \"%s\"\n",
param->string); return -EINVAL;
} break; case opt_iocharset: if (hsb->nls_io) {
pr_err("unable to change iocharset\n"); return -EINVAL;
}
hsb->nls_io = load_nls(param->string); if (!hsb->nls_io) {
pr_err("unable to load iocharset \"%s\"\n",
param->string); return -EINVAL;
} break; default: return -EINVAL;
}
return 0;
}
/* * hfs_read_super() * * This is the function that is responsible for mounting an HFS * filesystem. It performs all the tasks necessary to get enough data * from the disk to read the root inode. This includes parsing the * mount options, dealing with Macintosh partitions, reading the * superblock and the allocation bitmap blocks, calling * hfs_btree_init() to get the necessary data about the extents and * catalog B-trees and, finally, reading the root inode into memory.
*/ staticint hfs_fill_super(struct super_block *sb, struct fs_context *fc)
{ struct hfs_sb_info *sbi = HFS_SB(sb); struct hfs_find_data fd;
hfs_cat_rec rec; struct inode *root_inode; int silent = fc->sb_flags & SB_SILENT; int res;
/* load_nls_default does not fail */ if (sbi->nls_disk && !sbi->nls_io)
sbi->nls_io = load_nls_default();
sbi->s_dir_umask &= 0777;
sbi->s_file_umask &= 0577;
res = hfs_mdb_get(sb); if (res) { if (!silent)
pr_warn("can't find a HFS filesystem on dev %s\n",
hfs_mdb_name(sb));
res = -EINVAL; goto bail;
}
/* try to get the root inode */
res = hfs_find_init(HFS_SB(sb)->cat_tree, &fd); if (res) goto bail_no_root;
res = hfs_cat_find_brec(sb, HFS_ROOT_CNID, &fd); if (!res) { if (fd.entrylength != sizeof(rec.dir)) {
res = -EIO; goto bail_hfs_find;
}
hfs_bnode_read(fd.bnode, &rec, fd.entryoffset, fd.entrylength); if (rec.type != HFS_CDR_DIR)
res = -EIO;
} if (res) goto bail_hfs_find;
res = -EINVAL;
root_inode = hfs_iget(sb, &fd.search_key->cat, &rec);
hfs_find_exit(&fd); if (!root_inode) goto bail_no_root;
set_default_d_op(sb, &hfs_dentry_operations);
res = -ENOMEM;
sb->s_root = d_make_root(root_inode); if (!sb->s_root) goto bail_no_root;
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.