struct osd_device *osd = osd_dt_dev(d);
/* dmu will call commit callback with error code during abort */
if (!lu_device_is_md(&d->dd_lu_dev) && rc == -ENOSPC)
- CERROR("%s: failed to start transaction due to ENOSPC. "
- "Metadata overhead is underestimated or "
- "grant_ratio is too low.\n", osd->od_svname);
+ CERROR("%s: failed to start transaction due to ENOSPC"
+ "\n", osd->od_svname);
else
CERROR("%s: can't assign tx: rc = %d\n",
osd->od_svname, rc);
* for internal files to be created/unlinked when space is tight.
*/
CLASSERT(OSD_STATFS_RESERVED_SIZE > 0);
- if (likely(osfs->os_blocks >= OSD_STATFS_RESERVED_SIZE))
+ reserved = OSD_STATFS_RESERVED_SIZE >> bshift;
+ if (likely(osfs->os_blocks >= reserved << OSD_STATFS_RESERVED_SHIFT))
reserved = osfs->os_blocks >> OSD_STATFS_RESERVED_SHIFT;
- else
- reserved = OSD_STATFS_RESERVED_SIZE >> bshift;
osfs->os_blocks -= reserved;
- osfs->os_bfree -= MIN(reserved, osfs->os_bfree);
- osfs->os_bavail -= MIN(reserved, osfs->os_bavail);
+ osfs->os_bfree -= min(reserved, osfs->os_bfree);
+ osfs->os_bavail -= min(reserved, osfs->os_bavail);
/*
* The availobjs value returned from dmu_objset_space() is largely
osfs->os_namelen = MAXNAMELEN;
osfs->os_maxbytes = OBD_OBJECT_EOF;
- /* ZFS XXX: fill in appropriate OS_STATE_{DEGRADED,READONLY} flags
- osfs->os_state = vf_to_stf(vfsp->vfs_flag);
- if (sb->s_flags & MS_RDONLY)
- osfs->os_state |= OS_STATE_READONLY;
- */
+ if (!spa_writeable(dmu_objset_spa(os)) ||
+ osd->od_dev_set_rdonly || osd->od_prop_rdonly)
+ osfs->os_state |= OS_STATE_READONLY;
return 0;
}
*/
param->ddp_max_name_len = MAXNAMELEN;
param->ddp_max_nlink = 1 << 31; /* it's 8byte on a disk */
- param->ddp_block_shift = 12; /* XXX */
+ param->ddp_symlink_max = PATH_MAX;
param->ddp_mount_type = LDD_MT_ZFS;
param->ddp_mntopts = MNTOPT_USERXATTR;
/* for maxbytes, report same value as ZPL */
param->ddp_maxbytes = MAX_LFS_FILESIZE;
- /* Default reserved fraction of the available space that should be kept
- * for error margin. Unfortunately, there are many factors that can
- * impact the overhead with zfs, so let's be very cautious for now and
- * reserve 20% of the available space which is not given out as grant.
- * This tunable can be changed on a live system via procfs if needed. */
- param->ddp_grant_reserved = 20;
-
/* inodes are dynamically allocated, so we report the per-inode space
* consumption to upper layers. This static value is not really accurate
* and we should use the same logic as in udmu_objset_statfs() to
* estimate the real size consumed by an object */
param->ddp_inodespace = OSD_DNODE_EST_COUNT;
- /* per-fragment overhead to be used by the client code */
- param->ddp_grant_frag = osd_blk_insert_cost(osd);
+ /* Although ZFS isn't an extent-based filesystem, the metadata overhead
+ * (i.e. 7 levels of indirect blocks, see osd_blk_insert_cost()) should
+ * not be accounted for every single new block insertion.
+ * Instead, the maximum extent size is set to the number of blocks that
+ * can fit into a single contiguous indirect block. There would be some
+ * cases where this crosses indirect blocks, but it also won't have 7
+ * new levels of indirect blocks in that case either, so it will still
+ * have enough reserved space for the extra indirect block */
+ param->ddp_max_extent_blks =
+ (1 << (DN_MAX_INDBLKSHIFT - SPA_BLKPTRSHIFT));
+ param->ddp_extent_tax = osd_blk_insert_cost(osd);
}
/*
CERROR("%s: *** setting device %s read-only ***\n",
osd->od_svname, LUSTRE_OSD_ZFS_NAME);
- osd->od_rdonly = 1;
+ osd->od_dev_set_rdonly = 1;
spa_freeze(dmu_objset_spa(osd->od_os));
RETURN(0);
osd->od_max_blksz = newval;
}
+static void osd_readonly_changed_cb(void *arg, uint64_t newval)
+{
+ struct osd_device *osd = arg;
+
+ osd->od_prop_rdonly = !!newval;
+}
+
/*
* This function unregisters all registered callbacks. It's harmless to
* unregister callbacks that were never registered so it is used to safely
osd_xattr_changed_cb, o);
(void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_RECORDSIZE),
osd_recordsize_changed_cb, o);
+ (void) dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_READONLY),
+ osd_readonly_changed_cb, o);
if (o->arc_prune_cb != NULL) {
arc_remove_prune_callback(o->arc_prune_cb);
if (rc)
GOTO(err, rc);
+ rc = -dsl_prop_register(ds, zfs_prop_to_name(ZFS_PROP_READONLY),
+ osd_readonly_changed_cb, o);
+ if (rc)
+ GOTO(err, rc);
+
o->arc_prune_cb = arc_add_prune_callback(arc_prune_func, o);
err:
dsl_pool_config_exit(dp, FTAG);
rc = -dmu_objset_own(o->od_mntdev, DMU_OST_ZFS, B_FALSE, o, &o->od_os);
if (rc) {
+ CERROR("%s: can't open %s\n", o->od_svname, o->od_mntdev);
o->od_os = NULL;
goto out;
}
rc = osd_objset_open(o);
if (rc)
- GOTO(err, rc);
+ RETURN(rc);
o->od_xattr_in_sa = B_TRUE;
o->od_max_blksz = SPA_OLD_MAXBLOCKSIZE;
osd_unlinked_drain(env, o);
err:
if (rc) {
- dmu_objset_disown(o->od_os, o);
+ if (o->od_os)
+ dmu_objset_disown(o->od_os, o);
o->od_os = NULL;
}
struct lu_device_type *type,
struct lustre_cfg *cfg)
{
- struct osd_device *dev;
- int rc;
+ struct osd_device *dev;
+ struct osd_seq_list *osl;
+ int rc;
OBD_ALLOC_PTR(dev);
if (dev == NULL)
return ERR_PTR(-ENOMEM);
+ osl = &dev->od_seq_list;
+ INIT_LIST_HEAD(&osl->osl_seq_list);
+ rwlock_init(&osl->osl_seq_list_lock);
+ sema_init(&osl->osl_seq_init_sem, 1);
+
rc = dt_device_init(&dev->od_dt_dev, type);
if (rc == 0) {
rc = osd_device_init0(env, dev, cfg);
}
extern unsigned int osd_oi_count;
-CFS_MODULE_PARM(osd_oi_count, "i", int, 0444,
- "Number of Object Index containers to be created, "
- "it's only valid for new filesystem.");
+module_param(osd_oi_count, int, 0444);
+MODULE_PARM_DESC(osd_oi_count, "Number of Object Index containers to be created, it's only valid for new filesystem.");
MODULE_AUTHOR("OpenSFS, Inc. <http://www.lustre.org/>");
MODULE_DESCRIPTION("Lustre Object Storage Device ("LUSTRE_OSD_ZFS_NAME")");