►
From YouTube: Adding Logical Quotas to ZFS by Sanjeev Bagewadi
Description
From the 2021 OpenZFS Developer Summit
slides: https://docs.google.com/presentation/d/1o2bhd5eKNoJhzqyj9GjA7lsZPhATL6NxozvZ5XCOjUo
Details: https://openzfs.org/wiki/OpenZFS_Developer_Summit_2021
A
A
So
earlier
we
were,
we
were
not
using
compression,
so
we
had
not
enabled
zfs
compression
because
for
us
the
compression
was
done
at
the
back
end
on
the
nutanix
eos
platform.
But
then
at
some
point
we
figured
that
it
might
be
better
for
us
to
enable
compression
in
files
and
rather
than
doing
it
on
the
back
for
various
reasons.
A
So
as
part
of
that
work,
one
of
the
requirements
that
came
up
was
the
quotas
need
to
be
on
the
actual
size
and
not
on
the
compressed
size.
So
the
if
you
look
at
the
current
the
default
implementation
that
we
have
on
cfs
the
quotas
are
applied
on
the
compressed
size.
So
if,
if
compression
is
enabled,
the
quotas
are
applied
on
the
actual
blocks
that
are
written
to
disk
and
not
prior
to
the
compression.
A
So
that
was
the
thing
that
came
in
as
a
requirement
and
we
are
trying
to
figure
out
how
to
implement
that.
So
before
we
jump
into
the
actual
implementation
or
the
changes
that
we
made.
Let's
take
a
look
at
what
the
default
cfs
has
in
it,
so
each
d
node
keeps
track
of
the
blocks
consumed
by
that
d
node
in
dn
used.
So
if
you
look
at
the
denode
fizz,
it's
essentially
keeping
track
and
indian
used
and
also
in
the
block
pointer.
A
A
The
other
thing
that
we,
if
we
look
at
the
user
and
group
consumptions
those
are
maintained
in
in
the
special
denotes
that
we
have,
which
is
minus
one
and
minus
-2,
where
we
keep
track
of
the
blocks
consumed
by
each
each
user.
It's
an
indexed
access,
it's
essentially
a
zap
where
we
index
based
on
the
uids
and
gids,
not
exactly
them,
but
yeah
sort
of
that
gives
you
an
idea
of
what's
happening
there
so
and
for
the
data
set
consumption.
A
I
think
I
think
we
are
fairly
covered,
because
at
the
data
set
level
we
keep
track
of
both
the
compressed
and
uncompressed
count,
and
you
we
in
fact
use
this
for
zfs
uses
this
for,
for
the
compressor
ratio,
computation
and
the
space
calculation
itself
is,
is
updated
as
part
of
the
kha
sync
done
by
these
two
routines,
which
is
the
node
video
space
and
do
user
quota
cache
flush.
So
these
are
the
routines
which
are
which
are
responsible
for
doing
doing
the
updates
in
there.
A
A
So
the
changes
that
we
needed
were
one
like.
We
saw
earlier
the
d
node
we
needed.
We
need
some
field
to
keep
track
of
what
its
logical
size
is,
and
we
also
needed
to
keep
track
of
the
logical
consumption
for
the
uids
and
gids.
So
those
are
the
two
changes
that
that
we
needed
so
for
the
d
node.
What
we
chose
was
the
the
impact
three
in
in
field
in
in
genome
phase.
A
So
we
picked
that
field
to
pick
to
maintain
the
logical
size,
so
we
call
it
dnl
l
used
instead
of
as
in
drawing
parallels
from
d
and
use,
we
call
it
dnl
used,
which
is
the
logically
used
of
that
keynote.
So
that's
a
new
field
that
we
added
in
there
and
for
the
user
and
groups
those
so
the
user
in
group
was
essentially
one
value
that
we
maintained
earlier
right.
It
was
just
one
value
which
told
us
how
many
blocks
or
how
many
bytes
each
of
those
users
consumed.
A
A
That
the
zap,
which
could
have
been
a
micros
app
if
the
number
of
users
is
limited,
definitely
switches
to
fat
zap
in
this
case,
but
for
all
practical
reasons
or
for
for
all
practical
uses,
you
may
not
really
have
a
micros
app
there
if
in
in
a
real
world
case,
so
the
number
of
users
could
be
much
larger
and
hence
it
would
already
be
a
fraction.
So
this
was
not
a
problem,
a
couple
of
reasons
why?
So?
That
was
one
of
the
reasons
why
we
decided
to
go
down
this
path.
A
So
what
we
did
in
addition
to
these
two
things
is
added:
a
data
set
property
which,
which
is
just
a
binary,
switch
a
flip
on
or
flip
off,
so
called
logical
quota.
A
So
if
you
say
logical
quota
is
on
all
the
enforcement
code,
which
is
when
you
are
trying
to
do
a
dm
utx
assign
that's
the
one
where,
where
you
check
against
the
quotas,
it
would
start
using
the
logical
quotas,
whereas
if,
if
logical
quota
is
off,
it
falls
back
to
the
current
implementation
that
we
have,
which
is
you
apply
it
on
the
physical
block
allocations?
A
So
that
was
those
were
the
changes
that
we
did
and
a
couple
of
other
things
that
that
we
modified
is
in
the
in
the
vfs
or
in
the
vm
ops,
where
the
the
back
end
for
for
stat,
which
is
your
zfs,
get
actor
there.
Depending
on
the
on
the
data
set
value
on
the
data
set
value
for
logical
quota,
we
switch
to
reporting
the
l
used
instead
of
the
used
dna
used.
A
I
made
a
small
change
in
in
zdb
so
that
it
reports
both
the
sizes,
which
is
the
the
l
used
of
the
d
node.
So
those
are
the
changes
that
we
made
and.
A
So
some
challenges
we
had
was:
we
were
not
able
to
convert
the
existing
or
start
supporting
the
compress
compression
on
on
the
reason
I
bring
in
compression.
Of
course,
zfs
does
support
enabling
or
disabling
operation,
but
for
our
purpose
the
logical
quota
you're
not
able
to
enable
it
on
the
fly
for
existing
data
set.
So
we
we
switched
to
using
it
only
on
a
new
data
set,
so
that
was
that
was
one
change,
or
rather
that
was
a
challenge.
A
There's
couple
of
other
things,
wherein
we
had
an
interesting
issue
where
our
record
sizes
or
sorry
the
the
sector
size
that
we
support
was
4k
and
if
you
had
a
smaller
block,
which
is
like
512
bytes,
you
just
allocate
you'd
still
end
up
allocating
a
4k
sector,
for
it
so
had
to
fix
that
problem,
because
if
you,
if
you
just
went
with
the
l
size
for
all
the
computation
things,
go
wonky
when
you
have
a
large
number
of
small
files,
so
we
had
to
make
that
wherein
it's,
it's
actually
a
max
of
l,
size
and
a
size.
A
So
you
you,
if,
if
you
well
get
that
that's
a
fix-
and
I
have
I
am
yet
to
bring
that
into
the
port.
So
at
what
stage
is
this
work
right
now?
We.
A
The
the
I
haven't
integrated
this
with
the
project
quotas,
yet
I'm
still
working
on
that
one
trying
to
figure
out
how
how
this
should
integrate.
With
that
the
changes
I
have
put
it
out
on
on
the
link
there,
so
you
can
go,
take
a
look
at
it
I'll
I'll,
be
working
on
it
for
some
time
to
make
sure
it
integrates
with
the
project
quota
so
I'll
get
that
sorted
out.
B
I
think
this
is
really
cool.
You
know
I,
I
did
all
the
quota
stuff
way
back
in
the
day
and
it's
cool
to
see
that
it
extended.
B
One
question
that
I
had
was
what
your
plans
are
or
if
you
have
plans
to
change
the
way
that
the
you
know
right
now,
you're
talking
about
a
logical
quota
that
controls
the
behavior
of
all
the
other
quotas
versus.
I
think
we
had
talked
offline
about
the
possibility
of
adding
keeping
the
behavior
of
the
current
quotas
and
adding
new
quotas
that
are,
like
you
know,
logical.
B
One
gig
logical
refused
equals
whatever
logical
user
used
equals
whatever.
I
was
curious
if
you
had
thoughts
on
how
doable
that
is,
and
if.
A
C
A
Yes,
it's
it's
definitely
doable
because
the
way
I
would
look
at
it
for
the
general
consumption
is
that
this
brings
in
an
additional
field
in
the
d
node,
and
now
you
have
pretty
much
all
the
control,
because
your
block
pointers
tell
us
what
the
logical
size
is
now.
The
d
node
also
tells
you
what
the
logical
size
is
and
at
the
same
point
for
every
user
and
group
you
now
we
now
we
can
now
keep
track
of
the
logical
consumption.
A
So
once
the
those
fundamental
counts
are
available,
we
could
easily
build
up
logical
quotas
on
top
of
it
as
as
individual
properties.
So
it's
it's
definitely
possible
in
there
today
for
our
use
case.
It
is
we
just
wanted
a
simple
switch
to
flip
it,
whereas
it
can
easily
be
extended
to
have
additional
additional
quotas
applied.
So
it's
doable.
B
Yeah,
well
thanks
alan
did
you
want
to
ask
your
question:
live.
D
Sure
I
actually
had
a
different
question:
do
you
ever
run
into
problems
with
users
having
quotas
and,
if
they're,
very
near
the
quota?
The
performance
is
really
bad
like
right,
performance.
A
Yes,
yes,
we
do
see
that
in
fact
it
it's
it's
a
little.
It's
a
little
tricky
with
with
our
cases
where,
if,
if
you
draw
correlation
to
what
jitendra
was
saying
earlier
about
distributed
shares,
so
we
we
have
slightly
more
odd
problems
in
there,
because
the
the
distributed
chair
itself
is
actually
scattered
across
data
sets
right.
So
assimilating
them
sort
of
becomes
a
problem,
and
there
are
quota
runs
that
we
see,
but
with
respect
to
the
usage.
A
Yes,
we
do
see
it
dropping
so
because
every
time
you
try
to
do
a
demure
text
assign
it
it
sort
of
sees
that
you're
close
to
it,
and
since
we
overestimate
as
part
of
the
assign.
A
C
D
Interested
in
other
people
running
into
this
problem-
and
I
think
the
easiest
way
to
tell
is
there's
a
a
k
stat
under
the
dmu
tx
that
counts.
How
many
times
the
system
stopped
assigning,
because
it
thought
the
quota
was
full
and
if
the.
A
In
fact,
when
we
are
computing,
probably
I
should
just
bring
this
and
because
so
the
logical
size
that
we
are
trying
to
assign
there's
a
couple
of
other
tricky
things
that
we
have
to
deal
with,
wherein
whom
do
you
charge
the
the
metadata
or
the
indirect
blocks?
And
how
do
you?
A
How
do
we
charge
them
because
those
are
kept
in
replicate
so
there's
some
compromise
that
we
worked
on
that
we
said
if
it's,
if
it's
not
a
data
block,
then
you
charge
don't
charge
for
the
duplicates
and
stuff
like
that.
A
It's
not
in
directly
in
in
the
context
of
your
question,
but
yeah.
C
D
Let
maybe
let
mark
have
his
question
first
in
case.
C
Is
that
a
simple
question
you
mentioned
that
logical
quotas
only
worked
on
new
data
sets
right,
so
you
could
have
an
environment
where
you
had
old
and
new
data
sets
where
old
data
sets
would
have.
Physical
quotas
and
new
data
sets
would
have
logical
quotas.
Is
that
correct.
A
That's
true
mark,
in
fact
we
went
a
little
further
in
our
use
case.
Yeah
I
mean
for
general
purpose.
Yes,
you,
you
could
still
do
that
between
each
data
set.
You
could
you
could
turn
on
logical
quotas.
C
A
A
Yes,
because
the
the
the
property
that
I
was
talking
about
is
the
data
set
level
property,
the
logical
quota,
property.
A
C
D
My
second
question
was
about
when
you
added
the
accounting
for
how
much
logical
space
has
been
used.
Does
that
extend
to
snapshots
like
currently,
there
is
no
l
used
property
on
a
snapshot,
but
is
there
now,
in
your
code.
A
D
Different,
basically,
where
that
that
unique
value
is,
I
think
it's
actually
stored
in
the
the
object,
as
the
field
unique
when
that's
calculated
it'd
be
helpful
to
calculate
the
logical
size
of
that
data
as
well
and
store
that
so
that
you
can
actually
see
the
logical
used
on
a
snapshot.
Instead
of
only
the
physically
used.