mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-25 03:37:45 +03:00
Rebase master to b117
This commit is contained in:
+79
-5
@@ -19,12 +19,10 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
#include <sys/spa.h>
|
||||
#include <sys/dmu.h>
|
||||
#include <sys/zfs_context.h>
|
||||
@@ -78,8 +76,8 @@ zap_normalize(zap_t *zap, const char *name, char *namenorm)
|
||||
|
||||
err = 0;
|
||||
(void) u8_textprep_str((char *)name, &inlen, namenorm, &outlen,
|
||||
zap->zap_normflags | U8_TEXTPREP_IGNORE_NULL, U8_UNICODE_LATEST,
|
||||
&err);
|
||||
zap->zap_normflags | U8_TEXTPREP_IGNORE_NULL |
|
||||
U8_TEXTPREP_IGNORE_INVALID, U8_UNICODE_LATEST, &err);
|
||||
|
||||
return (err);
|
||||
}
|
||||
@@ -1067,3 +1065,79 @@ zap_get_stats(objset_t *os, uint64_t zapobj, zap_stats_t *zs)
|
||||
zap_unlockdir(zap);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
zap_count_write(objset_t *os, uint64_t zapobj, const char *name, int add,
|
||||
uint64_t *towrite, uint64_t *tooverwrite, uint64_t dn_datablkshift)
|
||||
{
|
||||
zap_t *zap;
|
||||
int err = 0;
|
||||
|
||||
|
||||
/*
|
||||
* Since, we don't have a name, we cannot figure out which blocks will
|
||||
* be affected in this operation. So, account for the worst case :
|
||||
* - 3 blocks overwritten: target leaf, ptrtbl block, header block
|
||||
* - 4 new blocks written if adding:
|
||||
* - 2 blocks for possibly split leaves,
|
||||
* - 2 grown ptrtbl blocks
|
||||
*
|
||||
* This also accomodates the case where an add operation to a fairly
|
||||
* large microzap results in a promotion to fatzap.
|
||||
*/
|
||||
if (name == NULL) {
|
||||
*towrite += (3 + (add ? 4 : 0)) * SPA_MAXBLOCKSIZE;
|
||||
return (err);
|
||||
}
|
||||
|
||||
/*
|
||||
* We lock the zap with adding == FALSE. Because, if we pass
|
||||
* the actual value of add, it could trigger a mzap_upgrade().
|
||||
* At present we are just evaluating the possibility of this operation
|
||||
* and hence we donot want to trigger an upgrade.
|
||||
*/
|
||||
err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
|
||||
if (err)
|
||||
return (err);
|
||||
|
||||
if (!zap->zap_ismicro) {
|
||||
zap_name_t *zn = zap_name_alloc(zap, name, MT_EXACT);
|
||||
if (zn) {
|
||||
err = fzap_count_write(zn, add, towrite,
|
||||
tooverwrite);
|
||||
zap_name_free(zn);
|
||||
} else {
|
||||
/*
|
||||
* We treat this case as similar to (name == NULL)
|
||||
*/
|
||||
*towrite += (3 + (add ? 4 : 0)) * SPA_MAXBLOCKSIZE;
|
||||
}
|
||||
} else {
|
||||
if (!add) {
|
||||
if (dmu_buf_freeable(zap->zap_dbuf))
|
||||
*tooverwrite += SPA_MAXBLOCKSIZE;
|
||||
else
|
||||
*towrite += SPA_MAXBLOCKSIZE;
|
||||
} else {
|
||||
/*
|
||||
* We are here if we are adding and (name != NULL).
|
||||
* It is hard to find out if this add will promote this
|
||||
* microzap to fatzap. Hence, we assume the worst case
|
||||
* and account for the blocks assuming this microzap
|
||||
* would be promoted to a fatzap.
|
||||
*
|
||||
* 1 block overwritten : header block
|
||||
* 4 new blocks written : 2 new split leaf, 2 grown
|
||||
* ptrtbl blocks
|
||||
*/
|
||||
if (dmu_buf_freeable(zap->zap_dbuf))
|
||||
*tooverwrite += 1 << dn_datablkshift;
|
||||
else
|
||||
*towrite += 1 << dn_datablkshift;
|
||||
*towrite += 4 << dn_datablkshift;
|
||||
}
|
||||
}
|
||||
|
||||
zap_unlockdir(zap);
|
||||
return (err);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user