Allocate zap_attribute_t from kmem instead of stack

This patch is preparatory work for long name feature. It changes all
users of zap_attribute_t to allocate it from kmem instead of stack. It
also make zap_attribute_t and zap_name_t structure variable length.

Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Signed-off-by: Chunwei Chen <david.chen@nutanix.com>
Closes #15921
This commit is contained in:
Sanjeev Bagewadi
2021-02-02 13:54:15 +00:00
committed by Brian Behlendorf
parent 141368a4b6
commit 3cf2bfa570
35 changed files with 513 additions and 365 deletions
+11 -9
View File
@@ -476,7 +476,7 @@ zfs_unlinked_drain_task(void *arg)
{
zfsvfs_t *zfsvfs = arg;
zap_cursor_t zc;
zap_attribute_t zap;
zap_attribute_t *zap = zap_attribute_alloc();
dmu_object_info_t doi;
znode_t *zp;
int error;
@@ -487,7 +487,7 @@ zfs_unlinked_drain_task(void *arg)
* Iterate over the contents of the unlinked set.
*/
for (zap_cursor_init(&zc, zfsvfs->z_os, zfsvfs->z_unlinkedobj);
zap_cursor_retrieve(&zc, &zap) == 0 && !zfsvfs->z_drain_cancel;
zap_cursor_retrieve(&zc, zap) == 0 && !zfsvfs->z_drain_cancel;
zap_cursor_advance(&zc)) {
/*
@@ -495,7 +495,7 @@ zfs_unlinked_drain_task(void *arg)
*/
error = dmu_object_info(zfsvfs->z_os,
zap.za_first_integer, &doi);
zap->za_first_integer, &doi);
if (error != 0)
continue;
@@ -505,7 +505,7 @@ zfs_unlinked_drain_task(void *arg)
* We need to re-mark these list entries for deletion,
* so we pull them back into core and set zp->z_unlinked.
*/
error = zfs_zget(zfsvfs, zap.za_first_integer, &zp);
error = zfs_zget(zfsvfs, zap->za_first_integer, &zp);
/*
* We may pick up znodes that are already marked for deletion.
@@ -532,6 +532,7 @@ zfs_unlinked_drain_task(void *arg)
zfsvfs->z_draining = B_FALSE;
zfsvfs->z_drain_task = TASKQID_INVALID;
zap_attribute_free(zap);
}
/*
@@ -589,7 +590,7 @@ static int
zfs_purgedir(znode_t *dzp)
{
zap_cursor_t zc;
zap_attribute_t zap;
zap_attribute_t *zap = zap_attribute_alloc();
znode_t *xzp;
dmu_tx_t *tx;
zfsvfs_t *zfsvfs = ZTOZSB(dzp);
@@ -598,10 +599,10 @@ zfs_purgedir(znode_t *dzp)
int error;
for (zap_cursor_init(&zc, zfsvfs->z_os, dzp->z_id);
(error = zap_cursor_retrieve(&zc, &zap)) == 0;
(error = zap_cursor_retrieve(&zc, zap)) == 0;
zap_cursor_advance(&zc)) {
error = zfs_zget(zfsvfs,
ZFS_DIRENT_OBJ(zap.za_first_integer), &xzp);
ZFS_DIRENT_OBJ(zap->za_first_integer), &xzp);
if (error) {
skipped += 1;
continue;
@@ -612,7 +613,7 @@ zfs_purgedir(znode_t *dzp)
tx = dmu_tx_create(zfsvfs->z_os);
dmu_tx_hold_sa(tx, dzp->z_sa_hdl, B_FALSE);
dmu_tx_hold_zap(tx, dzp->z_id, FALSE, zap.za_name);
dmu_tx_hold_zap(tx, dzp->z_id, FALSE, zap->za_name);
dmu_tx_hold_sa(tx, xzp->z_sa_hdl, B_FALSE);
dmu_tx_hold_zap(tx, zfsvfs->z_unlinkedobj, FALSE, NULL);
/* Is this really needed ? */
@@ -627,7 +628,7 @@ zfs_purgedir(znode_t *dzp)
}
memset(&dl, 0, sizeof (dl));
dl.dl_dzp = dzp;
dl.dl_name = zap.za_name;
dl.dl_name = zap->za_name;
error = zfs_link_destroy(&dl, xzp, tx, 0, NULL);
if (error)
@@ -637,6 +638,7 @@ zfs_purgedir(znode_t *dzp)
zfs_zrele_async(xzp);
}
zap_cursor_fini(&zc);
zap_attribute_free(zap);
if (error != ENOENT)
skipped += 1;
return (skipped);
+23 -19
View File
@@ -1523,7 +1523,7 @@ zfs_readdir(struct inode *ip, struct dir_context *ctx, cred_t *cr)
zfsvfs_t *zfsvfs = ITOZSB(ip);
objset_t *os;
zap_cursor_t zc;
zap_attribute_t zap;
zap_attribute_t *zap;
int error;
uint8_t prefetch;
uint8_t type;
@@ -1548,6 +1548,7 @@ zfs_readdir(struct inode *ip, struct dir_context *ctx, cred_t *cr)
os = zfsvfs->z_os;
offset = ctx->pos;
prefetch = zp->z_zn_prefetch;
zap = zap_attribute_alloc();
/*
* Initialize the iterator cursor.
@@ -1573,25 +1574,25 @@ zfs_readdir(struct inode *ip, struct dir_context *ctx, cred_t *cr)
* Special case `.', `..', and `.zfs'.
*/
if (offset == 0) {
(void) strcpy(zap.za_name, ".");
zap.za_normalization_conflict = 0;
(void) strcpy(zap->za_name, ".");
zap->za_normalization_conflict = 0;
objnum = zp->z_id;
type = DT_DIR;
} else if (offset == 1) {
(void) strcpy(zap.za_name, "..");
zap.za_normalization_conflict = 0;
(void) strcpy(zap->za_name, "..");
zap->za_normalization_conflict = 0;
objnum = parent;
type = DT_DIR;
} else if (offset == 2 && zfs_show_ctldir(zp)) {
(void) strcpy(zap.za_name, ZFS_CTLDIR_NAME);
zap.za_normalization_conflict = 0;
(void) strcpy(zap->za_name, ZFS_CTLDIR_NAME);
zap->za_normalization_conflict = 0;
objnum = ZFSCTL_INO_ROOT;
type = DT_DIR;
} else {
/*
* Grab next entry.
*/
if ((error = zap_cursor_retrieve(&zc, &zap))) {
if ((error = zap_cursor_retrieve(&zc, zap))) {
if (error == ENOENT)
break;
else
@@ -1605,24 +1606,24 @@ zfs_readdir(struct inode *ip, struct dir_context *ctx, cred_t *cr)
*
* XXX: This should be a feature flag for compatibility
*/
if (zap.za_integer_length != 8 ||
zap.za_num_integers == 0) {
if (zap->za_integer_length != 8 ||
zap->za_num_integers == 0) {
cmn_err(CE_WARN, "zap_readdir: bad directory "
"entry, obj = %lld, offset = %lld, "
"length = %d, num = %lld\n",
(u_longlong_t)zp->z_id,
(u_longlong_t)offset,
zap.za_integer_length,
(u_longlong_t)zap.za_num_integers);
zap->za_integer_length,
(u_longlong_t)zap->za_num_integers);
error = SET_ERROR(ENXIO);
goto update;
}
objnum = ZFS_DIRENT_OBJ(zap.za_first_integer);
type = ZFS_DIRENT_TYPE(zap.za_first_integer);
objnum = ZFS_DIRENT_OBJ(zap->za_first_integer);
type = ZFS_DIRENT_TYPE(zap->za_first_integer);
}
done = !dir_emit(ctx, zap.za_name, strlen(zap.za_name),
done = !dir_emit(ctx, zap->za_name, strlen(zap->za_name),
objnum, type);
if (done)
break;
@@ -1645,6 +1646,7 @@ zfs_readdir(struct inode *ip, struct dir_context *ctx, cred_t *cr)
update:
zap_cursor_fini(&zc);
zap_attribute_free(zap);
if (error == ENOENT)
error = 0;
out:
@@ -1743,7 +1745,7 @@ zfs_setattr_dir(znode_t *dzp)
zfsvfs_t *zfsvfs = ZTOZSB(dzp);
objset_t *os = zfsvfs->z_os;
zap_cursor_t zc;
zap_attribute_t zap;
zap_attribute_t *zap;
zfs_dirlock_t *dl;
znode_t *zp = NULL;
dmu_tx_t *tx = NULL;
@@ -1752,15 +1754,16 @@ zfs_setattr_dir(znode_t *dzp)
int count;
int err;
zap = zap_attribute_alloc();
zap_cursor_init(&zc, os, dzp->z_id);
while ((err = zap_cursor_retrieve(&zc, &zap)) == 0) {
while ((err = zap_cursor_retrieve(&zc, zap)) == 0) {
count = 0;
if (zap.za_integer_length != 8 || zap.za_num_integers != 1) {
if (zap->za_integer_length != 8 || zap->za_num_integers != 1) {
err = ENXIO;
break;
}
err = zfs_dirent_lock(&dl, dzp, (char *)zap.za_name, &zp,
err = zfs_dirent_lock(&dl, dzp, (char *)zap->za_name, &zp,
ZEXISTS, NULL, NULL);
if (err == ENOENT)
goto next;
@@ -1852,6 +1855,7 @@ next:
zfs_dirent_unlock(dl);
}
zap_cursor_fini(&zc);
zap_attribute_free(zap);
return (err == ENOENT ? 0 : err);
}
+6 -4
View File
@@ -153,19 +153,20 @@ static int
zpl_xattr_readdir(struct inode *dxip, xattr_filldir_t *xf)
{
zap_cursor_t zc;
zap_attribute_t zap;
zap_attribute_t *zap = zap_attribute_alloc();
int error;
zap_cursor_init(&zc, ITOZSB(dxip)->z_os, ITOZ(dxip)->z_id);
while ((error = -zap_cursor_retrieve(&zc, &zap)) == 0) {
while ((error = -zap_cursor_retrieve(&zc, zap)) == 0) {
if (zap.za_integer_length != 8 || zap.za_num_integers != 1) {
if (zap->za_integer_length != 8 || zap->za_num_integers != 1) {
error = -ENXIO;
break;
}
error = zpl_xattr_filldir(xf, zap.za_name, strlen(zap.za_name));
error = zpl_xattr_filldir(xf, zap->za_name,
strlen(zap->za_name));
if (error)
break;
@@ -173,6 +174,7 @@ zpl_xattr_readdir(struct inode *dxip, xattr_filldir_t *xf)
}
zap_cursor_fini(&zc);
zap_attribute_free(zap);
if (error == -ENOENT)
error = 0;