int
zfs_create_share_dir(zfs_sb_t *zsb, dmu_tx_t *tx)
{
-#ifdef HAVE_SHARE
+#ifdef HAVE_SMB_SHARE
zfs_acl_ids_t acl_ids;
vattr_t vattr;
znode_t *sharezp;
return (error);
#else
return (0);
-#endif /* HAVE_SHARE */
+#endif /* HAVE_SMB_SHARE */
}
static void
static void
zfs_inode_set_ops(zfs_sb_t *zsb, struct inode *ip)
{
- uint64_t rdev;
+ uint64_t rdev = 0;
switch (ip->i_mode & S_IFMT) {
case S_IFREG:
ip->i_op = &zpl_symlink_inode_operations;
break;
+ /*
+ * rdev is only stored in a SA only for device files.
+ */
case S_IFCHR:
case S_IFBLK:
- case S_IFIFO:
- case S_IFSOCK:
VERIFY(sa_lookup(ITOZ(ip)->z_sa_hdl, SA_ZPL_RDEV(zsb),
&rdev, sizeof (rdev)) == 0);
+ /*FALLTHROUGH*/
+ case S_IFIFO:
+ case S_IFSOCK:
init_special_inode(ip, ip->i_mode, rdev);
ip->i_op = &zpl_special_inode_operations;
break;
static znode_t *
zfs_znode_alloc(zfs_sb_t *zsb, dmu_buf_t *db, int blksz,
dmu_object_type_t obj_type, uint64_t obj, sa_handle_t *hdl,
- struct dentry *dentry)
+ struct dentry *dentry, struct inode *dip)
{
znode_t *zp;
struct inode *ip;
}
ip->i_ino = obj;
- ip->i_mode = zp->z_mode;
- ip->i_mtime = ip->i_atime = ip->i_ctime = CURRENT_TIME_SEC;
+ zfs_inode_update(zp);
zfs_inode_set_ops(zsb, ip);
if (insert_inode_locked(ip))
goto error;
- if (dentry)
+ if (dentry) {
+ if (zpl_xattr_security_init(ip, dip, &dentry->d_name))
+ goto error;
+
d_instantiate(dentry, ip);
+ }
mutex_enter(&zsb->z_znodes_lock);
list_insert_tail(&zsb->z_all_znodes, zp);
size = links = 0;
}
- if (S_ISBLK(vap->va_mode) || S_ISCHR(vap->va_mode) ||
- S_ISFIFO(vap->va_mode) || S_ISSOCK(vap->va_mode))
+ if (S_ISBLK(vap->va_mode) || S_ISCHR(vap->va_mode))
rdev = vap->va_rdev;
parent = dzp->z_id;
&empty_xattr, 8);
}
if (obj_type == DMU_OT_ZNODE ||
- (S_ISBLK(vap->va_mode) || S_ISCHR(vap->va_mode) ||
- S_ISFIFO(vap->va_mode) || S_ISSOCK(vap->va_mode))) {
+ (S_ISBLK(vap->va_mode) || S_ISCHR(vap->va_mode))) {
SA_ADD_BULK_ATTR(sa_attrs, cnt, SA_ZPL_RDEV(zsb),
NULL, &rdev, 8);
}
if (!(flag & IS_ROOT_NODE)) {
*zpp = zfs_znode_alloc(zsb, db, 0, obj_type, obj, sa_hdl,
- vap->va_dentry);
+ vap->va_dentry, ZTOI(dzp));
ASSERT(*zpp != NULL);
ASSERT(dzp != NULL);
- err = zpl_xattr_security_init(ZTOI(*zpp), ZTOI(dzp));
- ASSERT3S(err, ==, 0);
} else {
/*
* If we are creating the root node, the "parent" we
* bonus buffer.
*/
zp = zfs_znode_alloc(zsb, db, doi.doi_data_block_size,
- doi.doi_bonus_type, obj_num, NULL, NULL);
+ doi.doi_bonus_type, obj_num, NULL, NULL, NULL);
if (zp == NULL) {
err = ENOENT;
} else {
dmu_object_size_from_db(sa_get_db(zp->z_sa_hdl), &zp->z_blksz, &dummy);
}
-#ifdef HAVE_MMAP
-/*
- * This is a dummy interface used when pvn_vplist_dirty() should *not*
- * be calling back into the fs for a putpage(). E.g.: when truncating
- * a file, the pages being "thrown away* don't need to be written out.
- */
-/* ARGSUSED */
-static int
-zfs_no_putpage(vnode_t *vp, page_t *pp, u_offset_t *offp, size_t *lenp,
- int flags, cred_t *cr)
-{
- ASSERT(0);
- return (0);
-}
-#endif /* HAVE_MMAP */
-
/*
* Increase the file length
*
int
zfs_freesp(znode_t *zp, uint64_t off, uint64_t len, int flag, boolean_t log)
{
-#ifdef HAVE_MANDLOCKS
struct inode *ip = ZTOI(zp);
-#endif /* HAVE_MANDLOCKS */
dmu_tx_t *tx;
zfs_sb_t *zsb = ZTOZSB(zp);
zilog_t *zilog = zsb->z_log;
return (error);
}
-#ifdef HAVE_MANDLOCKS
/*
* Check for any locks in the region to be freed.
*/
-
- if (MANDLOCK(ip, (mode_t)mode)) {
+ if (ip->i_flock && mandatory_lock(ip)) {
uint64_t length = (len ? len : zp->z_size - off);
- if (error = chklock(ip, FWRITE, off, length, flag, NULL))
- return (error);
+ if (!lock_may_write(ip, off, length))
+ return (EAGAIN);
}
-#endif /* HAVE_MANDLOCKS */
if (len == 0) {
error = zfs_trunc(zp, off);
void
zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
{
+ struct super_block *sb;
+ zfs_sb_t *zsb;
uint64_t moid, obj, sa_obj, version;
+ uint64_t sense = ZFS_CASE_SENSITIVE;
uint64_t norm = 0;
nvpair_t *elem;
int error;
- timestruc_t now;
- dmu_buf_t *db;
- znode_phys_t *pzp;
+ int i;
+ znode_t *rootzp = NULL;
+ vattr_t vattr;
+ znode_t *zp;
+ zfs_acl_ids_t acl_ids;
/*
* First attempt to create master node.
ASSERT(error == 0);
if (strcmp(name, zfs_prop_to_name(ZFS_PROP_NORMALIZE)) == 0)
norm = val;
+ else if (strcmp(name, zfs_prop_to_name(ZFS_PROP_CASE)) == 0)
+ sense = val;
}
ASSERT(version != 0);
error = zap_update(os, moid, ZPL_VERSION_STR, 8, 1, &version, tx);
ASSERT(error == 0);
/*
- * Create root znode with code free of VFS dependencies. This
- * is important because without a registered filesystem and super
- * block all the required VFS hooks will be missing. The critical
- * thing is to just crete the required root znode.
+ * Create root znode. Create minimal znode/inode/zsb/sb
+ * to allow zfs_mknode to work.
*/
- obj = zap_create_norm(os, norm, DMU_OT_DIRECTORY_CONTENTS,
- DMU_OT_ZNODE, sizeof (znode_phys_t), tx);
+ vattr.va_mask = ATTR_MODE|ATTR_UID|ATTR_GID;
+ vattr.va_mode = S_IFDIR|0755;
+ vattr.va_uid = crgetuid(cr);
+ vattr.va_gid = crgetgid(cr);
- VERIFY(0 == dmu_bonus_hold(os, obj, FTAG, &db));
- dmu_buf_will_dirty(db, tx);
+ rootzp = kmem_cache_alloc(znode_cache, KM_SLEEP);
+ rootzp->z_moved = 0;
+ rootzp->z_unlinked = 0;
+ rootzp->z_atime_dirty = 0;
+ rootzp->z_is_sa = USE_SA(version, os);
+
+ zsb = kmem_zalloc(sizeof (zfs_sb_t), KM_SLEEP);
+ zsb->z_os = os;
+ zsb->z_parent = zsb;
+ zsb->z_version = version;
+ zsb->z_use_fuids = USE_FUIDS(version, os);
+ zsb->z_use_sa = USE_SA(version, os);
+ zsb->z_norm = norm;
+
+ sb = kmem_zalloc(sizeof (struct super_block), KM_SLEEP);
+ sb->s_fs_info = zsb;
+
+ ZTOI(rootzp)->i_sb = sb;
+
+ error = sa_setup(os, sa_obj, zfs_attr_table, ZPL_END,
+ &zsb->z_attr_table);
+
+ ASSERT(error == 0);
/*
- * Initialize the znode physical data to zero.
+ * Fold case on file systems that are always or sometimes case
+ * insensitive.
*/
- ASSERT(db->db_size >= sizeof (znode_phys_t));
- bzero(db->db_data, db->db_size);
- pzp = db->db_data;
+ if (sense == ZFS_CASE_INSENSITIVE || sense == ZFS_CASE_MIXED)
+ zsb->z_norm |= U8_TEXTPREP_TOUPPER;
- if (USE_FUIDS(version, os))
- pzp->zp_flags = ZFS_ARCHIVE | ZFS_AV_MODIFIED;
+ mutex_init(&zsb->z_znodes_lock, NULL, MUTEX_DEFAULT, NULL);
+ list_create(&zsb->z_all_znodes, sizeof (znode_t),
+ offsetof(znode_t, z_link_node));
- pzp->zp_size = 2; /* "." and ".." */
- pzp->zp_links = 2;
- pzp->zp_parent = obj;
- pzp->zp_gen = dmu_tx_get_txg(tx);
- pzp->zp_mode = S_IFDIR | 0755;
- pzp->zp_flags = ZFS_ACL_TRIVIAL;
+ for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
+ mutex_init(&zsb->z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL);
- gethrestime(&now);
+ VERIFY(0 == zfs_acl_ids_create(rootzp, IS_ROOT_NODE, &vattr,
+ cr, NULL, &acl_ids));
+ zfs_mknode(rootzp, &vattr, tx, cr, IS_ROOT_NODE, &zp, &acl_ids);
+ ASSERT3P(zp, ==, rootzp);
+ error = zap_add(os, moid, ZFS_ROOT_OBJ, 8, 1, &rootzp->z_id, tx);
+ ASSERT(error == 0);
+ zfs_acl_ids_free(&acl_ids);
- ZFS_TIME_ENCODE(&now, pzp->zp_crtime);
- ZFS_TIME_ENCODE(&now, pzp->zp_ctime);
- ZFS_TIME_ENCODE(&now, pzp->zp_atime);
- ZFS_TIME_ENCODE(&now, pzp->zp_mtime);
+ atomic_set(&ZTOI(rootzp)->i_count, 0);
+ sa_handle_destroy(rootzp->z_sa_hdl);
+ kmem_free(sb, sizeof (struct super_block));
+ kmem_free(zsb, sizeof (zfs_sb_t));
+ kmem_cache_free(znode_cache, rootzp);
+
+ /*
+ * Create shares directory
+ */
+
+ error = zfs_create_share_dir(zsb, tx);
- error = zap_add(os, moid, ZFS_ROOT_OBJ, 8, 1, &obj, tx);
ASSERT(error == 0);
- dmu_buf_rele(db, FTAG);
+ for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
+ mutex_destroy(&zsb->z_hold_mtx[i]);
}
-
#endif /* _KERNEL */
static int