static int libzfs_update_stats(zfs_handle_t *p_zfs) { objset_t *p_os; nvlist_t *pnv_allprops, *pnv_userprops; int i_error; if((i_error = dmu_objset_hold(p_zfs->zfs_name, FTAG, &p_os))) return i_error; dmu_objset_fast_stat(p_os, &p_zfs->zfs_dmustats); if((i_error = dsl_prop_get_all(p_os, &pnv_allprops)) == 0) { dmu_objset_stats(p_os, pnv_allprops); if(!p_zfs->zfs_dmustats.dds_inconsistent) { if(dmu_objset_type(p_os) == DMU_OST_ZVOL) assert(zvol_get_stats(p_os, pnv_allprops) == 0); } } dmu_objset_rele(p_os, FTAG); // Continue processing the stats if((pnv_userprops = process_user_props(p_zfs, pnv_allprops)) == NULL) { nvlist_free(pnv_allprops); return 1; } nvlist_free(p_zfs->zfs_props); nvlist_free(p_zfs->zfs_user_props); p_zfs->zfs_props = pnv_allprops; p_zfs->zfs_user_props = pnv_userprops; return 0; }
static int zfs_statvfs(vfs_t *vfsp, struct statvfs64 *statp) { zfsvfs_t *zfsvfs = vfsp->vfs_data; dmu_objset_stats_t dstats; dev32_t d32; ZFS_ENTER(zfsvfs); dmu_objset_stats(zfsvfs->z_os, &dstats); /* * The underlying storage pool actually uses multiple block sizes. * We report the fragsize as the smallest block size we support, * and we report our blocksize as the filesystem's maximum blocksize. */ statp->f_frsize = 1UL << SPA_MINBLOCKSHIFT; statp->f_bsize = zfsvfs->z_max_blksz; /* * The following report "total" blocks of various kinds in the * file system, but reported in terms of f_frsize - the * "fragment" size. */ statp->f_blocks = (dstats.dds_space_refd + dstats.dds_available) >> SPA_MINBLOCKSHIFT; statp->f_bfree = dstats.dds_available >> SPA_MINBLOCKSHIFT; statp->f_bavail = statp->f_bfree; /* no root reservation */ /* * statvfs() should really be called statufs(), because it assumes * static metadata. ZFS doesn't preallocate files, so the best * we can do is report the max that could possibly fit in f_files, * and that minus the number actually used in f_ffree. * For f_ffree, report the smaller of the number of object available * and the number of blocks (each object will take at least a block). */ statp->f_ffree = MIN(dstats.dds_objects_avail, statp->f_bfree); statp->f_favail = statp->f_ffree; /* no "root reservation" */ statp->f_files = statp->f_ffree + dstats.dds_objects_used; (void) cmpldev(&d32, vfsp->vfs_dev); statp->f_fsid = d32; /* * We're a zfs filesystem. */ (void) strcpy(statp->f_basetype, vfssw[vfsp->vfs_fstype].vsw_name); statp->f_flag = vf_to_stf(vfsp->vfs_flag); statp->f_namemax = ZFS_MAXNAMELEN; /* * We have all of 32 characters to stuff a string here. * Is there anything useful we could/should provide? */ bzero(statp->f_fstr, sizeof (statp->f_fstr)); ZFS_EXIT(zfsvfs); return (0); }