int zfs_domount(struct super_block *sb, void *data, int silent) { zpl_mount_data_t *zmd = data; const char *osname = zmd->z_osname; zfs_sb_t *zsb; struct inode *root_inode; uint64_t recordsize; int error; error = zfs_sb_create(osname, &zsb); if (error) return (error); if ((error = dsl_prop_get_integer(osname, "recordsize", &recordsize, NULL))) goto out; zsb->z_sb = sb; sb->s_fs_info = zsb; sb->s_magic = ZFS_SUPER_MAGIC; sb->s_maxbytes = MAX_LFS_FILESIZE; sb->s_time_gran = 1; sb->s_blocksize = recordsize; sb->s_blocksize_bits = ilog2(recordsize); #ifdef HAVE_BDI /* * 2.6.32 API change, * Added backing_device_info (BDI) per super block interfaces. A BDI * must be configured when using a non-device backed filesystem for * proper writeback. This is not required for older pdflush kernels. * * NOTE: Linux read-ahead is disabled in favor of zfs read-ahead. */ zsb->z_bdi.ra_pages = 0; sb->s_bdi = &zsb->z_bdi; error = -bdi_setup_and_register(&zsb->z_bdi, "zfs", BDI_CAP_MAP_COPY); if (error) goto out; #endif /* HAVE_BDI */ /* Set callback operations for the file system. */ sb->s_op = &zpl_super_operations; sb->s_xattr = zpl_xattr_handlers; sb->s_export_op = &zpl_export_operations; #ifdef HAVE_S_D_OP sb->s_d_op = &zpl_dentry_operations; #endif /* HAVE_S_D_OP */ /* Set features for file system. */ zfs_set_fuid_feature(zsb); if (dmu_objset_is_snapshot(zsb->z_os)) { uint64_t pval; atime_changed_cb(zsb, B_FALSE); readonly_changed_cb(zsb, B_TRUE); if ((error = dsl_prop_get_integer(osname,"xattr",&pval,NULL))) goto out; xattr_changed_cb(zsb, pval); if ((error = dsl_prop_get_integer(osname,"acltype",&pval,NULL))) goto out; acltype_changed_cb(zsb, pval); zsb->z_issnap = B_TRUE; zsb->z_os->os_sync = ZFS_SYNC_DISABLED; mutex_enter(&zsb->z_os->os_user_ptr_lock); dmu_objset_set_user(zsb->z_os, zsb); mutex_exit(&zsb->z_os->os_user_ptr_lock); } else { error = zfs_sb_setup(zsb, B_TRUE); } /* Allocate a root inode for the filesystem. */ error = zfs_root(zsb, &root_inode); if (error) { (void) zfs_umount(sb); goto out; } /* Allocate a root dentry for the filesystem */ sb->s_root = d_make_root(root_inode); if (sb->s_root == NULL) { (void) zfs_umount(sb); error = SET_ERROR(ENOMEM); goto out; } if (!zsb->z_issnap) zfsctl_create(zsb); out: if (error) { dmu_objset_disown(zsb->z_os, zsb); zfs_sb_free(zsb); } return (error); }
int zfs_domount(struct super_block *sb, void *data, int silent) { zpl_mount_data_t *zmd = data; const char *osname = zmd->z_osname; zfs_sb_t *zsb; struct inode *root_inode; uint64_t recordsize; int error; error = zfs_sb_create(osname, &zsb); if (error) return (error); if ((error = dsl_prop_get_integer(osname, "recordsize", &recordsize, NULL))) goto out; zsb->z_sb = sb; sb->s_fs_info = zsb; sb->s_magic = ZFS_SUPER_MAGIC; sb->s_maxbytes = MAX_LFS_FILESIZE; sb->s_time_gran = 1; sb->s_blocksize = recordsize; sb->s_blocksize_bits = ilog2(recordsize); zsb->z_bdi.ra_pages = 0; sb->s_bdi = &zsb->z_bdi; error = -zpl_bdi_setup_and_register(&zsb->z_bdi, "zfs"); if (error) goto out; /* Set callback operations for the file system. */ sb->s_op = &zpl_super_operations; sb->s_xattr = zpl_xattr_handlers; sb->s_export_op = &zpl_export_operations; #ifdef HAVE_S_D_OP sb->s_d_op = &zpl_dentry_operations; #endif /* HAVE_S_D_OP */ /* Set features for file system. */ zfs_set_fuid_feature(zsb); if (dmu_objset_is_snapshot(zsb->z_os)) { uint64_t pval; atime_changed_cb(zsb, B_FALSE); readonly_changed_cb(zsb, B_TRUE); if ((error = dsl_prop_get_integer(osname, "xattr", &pval, NULL))) goto out; xattr_changed_cb(zsb, pval); if ((error = dsl_prop_get_integer(osname, "acltype", &pval, NULL))) goto out; acltype_changed_cb(zsb, pval); zsb->z_issnap = B_TRUE; zsb->z_os->os_sync = ZFS_SYNC_DISABLED; mutex_enter(&zsb->z_os->os_user_ptr_lock); dmu_objset_set_user(zsb->z_os, zsb); mutex_exit(&zsb->z_os->os_user_ptr_lock); } else { error = zfs_sb_setup(zsb, B_TRUE); } /* Allocate a root inode for the filesystem. */ error = zfs_root(zsb, &root_inode); if (error) { (void) zfs_umount(sb); goto out; } /* Allocate a root dentry for the filesystem */ sb->s_root = d_make_root(root_inode); if (sb->s_root == NULL) { (void) zfs_umount(sb); error = SET_ERROR(ENOMEM); goto out; } if (!zsb->z_issnap) zfsctl_create(zsb); zsb->z_arc_prune = arc_add_prune_callback(zpl_prune_sb, sb); out: if (error) { dmu_objset_disown(zsb->z_os, zsb); zfs_sb_free(zsb); } return (error); }