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
+13 -9
View File
@@ -287,7 +287,7 @@ void
zfs_unlinked_drain(zfsvfs_t *zfsvfs)
{
zap_cursor_t zc;
zap_attribute_t zap;
zap_attribute_t *zap;
dmu_object_info_t doi;
znode_t *zp;
dmu_tx_t *tx;
@@ -296,8 +296,9 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs)
/*
* Iterate over the contents of the unlinked set.
*/
zap = zap_attribute_alloc();
for (zap_cursor_init(&zc, zfsvfs->z_os, zfsvfs->z_unlinkedobj);
zap_cursor_retrieve(&zc, &zap) == 0;
zap_cursor_retrieve(&zc, zap) == 0;
zap_cursor_advance(&zc)) {
/*
@@ -305,7 +306,7 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs)
*/
error = dmu_object_info(zfsvfs->z_os,
zap.za_first_integer, &doi);
zap->za_first_integer, &doi);
if (error != 0)
continue;
@@ -315,7 +316,7 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs)
* 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.
@@ -351,6 +352,7 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs)
vput(ZTOV(zp));
}
zap_cursor_fini(&zc);
zap_attribute_free(zap);
}
/*
@@ -368,18 +370,19 @@ static int
zfs_purgedir(znode_t *dzp)
{
zap_cursor_t zc;
zap_attribute_t zap;
zap_attribute_t *zap;
znode_t *xzp;
dmu_tx_t *tx;
zfsvfs_t *zfsvfs = dzp->z_zfsvfs;
int skipped = 0;
int error;
zap = zap_attribute_alloc();
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;
@@ -391,7 +394,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 ? */
@@ -405,7 +408,7 @@ zfs_purgedir(znode_t *dzp)
continue;
}
error = zfs_link_destroy(dzp, zap.za_name, xzp, tx, 0, NULL);
error = zfs_link_destroy(dzp, zap->za_name, xzp, tx, 0, NULL);
if (error)
skipped += 1;
dmu_tx_commit(tx);
@@ -413,6 +416,7 @@ zfs_purgedir(znode_t *dzp)
vput(ZTOV(xzp));
}
zap_cursor_fini(&zc);
zap_attribute_free(zap);
if (error != ENOENT)
skipped += 1;
return (skipped);
+17 -15
View File
@@ -1568,7 +1568,7 @@ zfs_readdir(vnode_t *vp, zfs_uio_t *uio, cred_t *cr, int *eofp,
caddr_t outbuf;
size_t bufsize;
zap_cursor_t zc;
zap_attribute_t zap;
zap_attribute_t *zap;
uint_t bytes_wanted;
uint64_t offset; /* must be unsigned; checks for < 1 */
uint64_t parent;
@@ -1616,6 +1616,7 @@ zfs_readdir(vnode_t *vp, zfs_uio_t *uio, cred_t *cr, int *eofp,
os = zfsvfs->z_os;
offset = zfs_uio_offset(uio);
prefetch = zp->z_zn_prefetch;
zap = zap_attribute_alloc();
/*
* Initialize the iterator cursor.
@@ -1671,33 +1672,33 @@ zfs_readdir(vnode_t *vp, zfs_uio_t *uio, cred_t *cr, int *eofp,
* 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 ((*eofp = (error == ENOENT)) != 0)
break;
else
goto update;
}
if (zap.za_integer_length != 8 ||
zap.za_num_integers != 1) {
if (zap->za_integer_length != 8 ||
zap->za_num_integers != 1) {
cmn_err(CE_WARN, "zap_readdir: bad directory "
"entry, obj = %lld, offset = %lld\n",
(u_longlong_t)zp->z_id,
@@ -1706,15 +1707,15 @@ zfs_readdir(vnode_t *vp, zfs_uio_t *uio, cred_t *cr, int *eofp,
goto update;
}
objnum = ZFS_DIRENT_OBJ(zap.za_first_integer);
objnum = ZFS_DIRENT_OBJ(zap->za_first_integer);
/*
* MacOS X can extract the object type here such as:
* uint8_t type = ZFS_DIRENT_TYPE(zap.za_first_integer);
*/
type = ZFS_DIRENT_TYPE(zap.za_first_integer);
type = ZFS_DIRENT_TYPE(zap->za_first_integer);
}
reclen = DIRENT64_RECLEN(strlen(zap.za_name));
reclen = DIRENT64_RECLEN(strlen(zap->za_name));
/*
* Will this entry fit in the buffer?
@@ -1734,10 +1735,10 @@ zfs_readdir(vnode_t *vp, zfs_uio_t *uio, cred_t *cr, int *eofp,
*/
odp->d_ino = objnum;
odp->d_reclen = reclen;
odp->d_namlen = strlen(zap.za_name);
odp->d_namlen = strlen(zap->za_name);
/* NOTE: d_off is the offset for the *next* entry. */
next = &odp->d_off;
strlcpy(odp->d_name, zap.za_name, odp->d_namlen + 1);
strlcpy(odp->d_name, zap->za_name, odp->d_namlen + 1);
odp->d_type = type;
dirent_terminate(odp);
odp = (dirent64_t *)((intptr_t)odp + reclen);
@@ -1788,6 +1789,7 @@ zfs_readdir(vnode_t *vp, zfs_uio_t *uio, cred_t *cr, int *eofp,
update:
zap_cursor_fini(&zc);
zap_attribute_free(zap);
if (zfs_uio_segflg(uio) != UIO_SYSSPACE || zfs_uio_iovcnt(uio) != 1)
kmem_free(outbuf, bufsize);