16 Sep, 2020

2 commits

  • Refactor the code that sets the default quota grace period into a helper
    function so that we can override the ondisk behavior later.

    Signed-off-by: Darrick J. Wong
    Reviewed-by: Amir Goldstein
    Reviewed-by: Christoph Hellwig
    Reviewed-by: Allison Collins
    Reviewed-by: Dave Chinner

    Darrick J. Wong
     
  • Define explicit limits on the range of quota grace period expiration
    timeouts and refactor the code that modifies the timeouts into helpers
    that clamp the values appropriately. Note that we'll refactor the
    default grace period timer separately.

    Signed-off-by: Darrick J. Wong
    Reviewed-by: Christoph Hellwig
    Reviewed-by: Allison Collins
    Reviewed-by: Dave Chinner

    Darrick J. Wong
     

29 Jul, 2020

16 commits

  • Create a new type (xfs_dqtype_t) to represent the type of an incore
    dquot (user, group, project, or none). Rename the incore dquot's
    dq_flags field to q_type.

    This allows us to replace all the "uint type" arguments to the quota
    functions with "xfs_dqtype_t type", to make it obvious when we're
    passing a quota type argument into a function.

    Signed-off-by: Darrick J. Wong
    Reviewed-by: Dave Chinner
    Reviewed-by: Christoph Hellwig

    Darrick J. Wong
     
  • When XFS' quota functions take a parameter for the quota type, they only
    care about the three quota record types (user, group, project).
    Internal state flags and whatnot should never be passed by callers and
    are an error. Now that we've moved responsibility for filtering out
    internal state to the callers, we can drop the masking everywhere else.

    In other words, if you call a quota function, you must only pass in
    one of XFS_DQTYPE_{USER,GROUP,PROJ}.

    Signed-off-by: Darrick J. Wong
    Reviewed-by: Dave Chinner
    Reviewed-by: Christoph Hellwig

    Darrick J. Wong
     
  • Always use the xfs_dquot_type helper to extract the quota type from an
    incore dquot. This moves responsibility for filtering internal state
    information and whatnot to anybody passing around a struct xfs_dquot.

    Signed-off-by: Darrick J. Wong
    Reviewed-by: Dave Chinner
    Reviewed-by: Christoph Hellwig

    Darrick J. Wong
     
  • Remove these macros and use xfs_dquot_type() for everything.

    Signed-off-by: Darrick J. Wong
    Reviewed-by: Dave Chinner
    Reviewed-by: Christoph Hellwig

    Darrick J. Wong
     
  • Create a small helper to test if enforcement is enabled for a
    given incore dquot and replace the open-code logic testing.

    Signed-off-by: Darrick J. Wong
    Reviewed-by: Dave Chinner
    Reviewed-by: Christoph Hellwig

    Darrick J. Wong
     
  • We're going to split up the incore dquot state flags from the ondisk
    dquot flags (eventually renaming this "type") so start by renaming the
    three flags and the bitmask that are going to participate in this.

    Signed-off-by: Darrick J. Wong
    Reviewed-by: Dave Chinner
    Reviewed-by: Christoph Hellwig

    Darrick J. Wong
     
  • struct xfs_dquot already has a pointer to the xfs mount, so remove the
    redundant parameter from xfs_qm_adjust_dq*.

    Signed-off-by: Darrick J. Wong
    Reviewed-by: Chandan Babu R
    Reviewed-by: Christoph Hellwig

    Darrick J. Wong
     
  • Now that we've stopped using qcore entirely, drop it from the incore
    dquot.

    Signed-off-by: Darrick J. Wong
    Reviewed-by: Chandan Babu R
    Reviewed-by: Christoph Hellwig

    Darrick J. Wong
     
  • Add timers fields to the incore dquot, and use that instead of the ones
    in qcore. This eliminates a bunch of endian conversions and will
    eventually allow us to remove qcore entirely.

    Signed-off-by: Darrick J. Wong
    Reviewed-by: Chandan Babu R
    Reviewed-by: Christoph Hellwig
    Reviewed-by: Allison Collins

    Darrick J. Wong
     
  • Add warning counter fields to the incore dquot, and use that instead of
    the ones in qcore. This eliminates a bunch of endian conversions and
    will eventually allow us to remove qcore entirely.

    Signed-off-by: Darrick J. Wong
    Reviewed-by: Chandan Babu R
    Reviewed-by: Christoph Hellwig
    Reviewed-by: Allison Collins

    Darrick J. Wong
     
  • Add counter fields to the incore dquot, and use that instead of the ones
    in qcore. This eliminates a bunch of endian conversions and will
    eventually allow us to remove qcore entirely.

    Signed-off-by: Darrick J. Wong
    Reviewed-by: Chandan Babu R
    Reviewed-by: Christoph Hellwig
    Reviewed-by: Allison Collins

    Darrick J. Wong
     
  • Add limits fields in the incore dquot, and use that instead of the ones
    in qcore. This eliminates a bunch of endian conversions and will
    eventually allow us to remove qcore entirely.

    Signed-off-by: Darrick J. Wong
    Reviewed-by: Chandan Babu R
    Reviewed-by: Christoph Hellwig
    Reviewed-by: Allison Collins

    Darrick J. Wong
     
  • Introduce a new struct xfs_dquot_res that we'll use to track all the
    incore data for a particular resource type (block, inode, rt block).
    This will help us (once we've eliminated q_core) to declutter quota
    functions that currently open-code field access or pass around fields
    around explicitly.

    Signed-off-by: Darrick J. Wong
    Reviewed-by: Chandan Babu R
    Reviewed-by: Christoph Hellwig
    Reviewed-by: Allison Collins

    Darrick J. Wong
     
  • Add a dquot id field to the incore dquot, and use that instead of the
    one in qcore. This eliminates a bunch of endian conversions and will
    eventually allow us to remove qcore entirely.

    We also rearrange the start of xfs_dquot to remove padding holes, saving
    8 bytes.

    Signed-off-by: Darrick J. Wong
    Reviewed-by: Chandan Babu R
    Reviewed-by: Christoph Hellwig
    Reviewed-by: Allison Collins

    Darrick J. Wong
     
  • Use the incore dq_flags to figure out the dquot type. This is the first
    step towards removing xfs_disk_dquot from the incore dquot.

    Signed-off-by: Darrick J. Wong
    Reviewed-by: Christoph Hellwig
    Reviewed-by: Chandan Babu R

    Darrick J. Wong
     
  • Rename the existing incore dquot "dq_flags" field to "q_flags" to match
    everything else in the structure, then move the two actual dquot state
    flags to the XFS_DQFLAG_ namespace from XFS_DQ_.

    Signed-off-by: Darrick J. Wong
    Reviewed-by: Christoph Hellwig
    Reviewed-by: Chandan Babu R

    Darrick J. Wong
     

27 May, 2020

1 commit

  • Pass xfs_dquot rather than xfs_disk_dquot to xfs_qm_adjust_dqtimers;
    this makes it symmetric with xfs_qm_adjust_dqlimits and will help
    the next patch.

    Signed-off-by: Eric Sandeen
    Reviewed-by: Allison Collins
    Reviewed-by: Christoph Hellwig
    Reviewed-by: Darrick J. Wong
    Signed-off-by: Darrick J. Wong

    Eric Sandeen
     

14 Nov, 2019

2 commits


12 Jun, 2019

1 commit


07 Jun, 2018

1 commit

  • Remove the verbose license text from XFS files and replace them
    with SPDX tags. This does not change the license of any of the code,
    merely refers to the common, up-to-date license files in LICENSES/

    This change was mostly scripted. fs/xfs/Makefile and
    fs/xfs/libxfs/xfs_fs.h were modified by hand, the rest were detected
    and modified by the following command:

    for f in `git grep -l "GNU General" fs/xfs/` ; do
    echo $f
    cat $f | awk -f hdr.awk > $f.new
    mv -f $f.new $f
    done

    And the hdr.awk script that did the modification (including
    detecting the difference between GPL-2.0 and GPL-2.0+ licenses)
    is as follows:

    $ cat hdr.awk
    BEGIN {
    hdr = 1.0
    tag = "GPL-2.0"
    str = ""
    }

    /^ \* This program is free software/ {
    hdr = 2.0;
    next
    }

    /any later version./ {
    tag = "GPL-2.0+"
    next
    }

    /^ \*\// {
    if (hdr > 0.0) {
    print "// SPDX-License-Identifier: " tag
    print str
    print $0
    str=""
    hdr = 0.0
    next
    }
    print $0
    next
    }

    /^ \* / {
    if (hdr > 1.0)
    next
    if (hdr > 0.0) {
    if (str != "")
    str = str "\n"
    str = str $0
    next
    }
    print $0
    next
    }

    /^ \*/ {
    if (hdr > 0.0)
    next
    print $0
    next
    }

    // {
    if (hdr > 0.0) {
    if (str != "")
    str = str "\n"
    str = str $0
    next
    }
    print $0
    }

    END { }
    $

    Signed-off-by: Dave Chinner
    Reviewed-by: Darrick J. Wong
    Signed-off-by: Darrick J. Wong

    Dave Chinner
     

16 May, 2018

1 commit

  • Create a helper function to iterate all the dquots of a given type in
    the system, and refactor the dquot scrub to use it. This will get more
    use in the quota repair code.

    Signed-off-by: Darrick J. Wong
    Reviewed-by: Brian Foster
    Reviewed-by: Christoph Hellwig

    Darrick J. Wong
     

10 May, 2018

4 commits

  • DQALLOC is only ever used with xfs_qm_dqget*, and the only flag that the
    _dqget family of functions cares about is DQALLOC. Therefore, change
    it to a boolean 'can alloc?' flag for the dqget interfaces where that
    makes sense.

    Signed-off-by: Darrick J. Wong
    Reviewed-by: Brian Foster

    Darrick J. Wong
     
  • The quota initialization code needs an "uncached" variant of _dqget to
    read in default quota limits and timers before the dquot cache is fully
    set up. We've already split up _dqget into its component pieces so
    create a fourth variant to address this need, and make dqread internal
    to xfs_dquot.c again.

    Signed-off-by: Darrick J. Wong
    Reviewed-by: Brian Foster
    Reviewed-by: Christoph Hellwig

    Darrick J. Wong
     
  • There are two uses of dqget here -- one is to return the dquot for a
    given type and id, and the other is to return the dquot for a given type
    and inode. Those are two separate things, so split them into two
    smaller functions.

    Signed-off-by: Darrick J. Wong
    Reviewed-by: Brian Foster
    Reviewed-by: Christoph Hellwig

    Darrick J. Wong
     
  • There's only one caller of DQNEXT and its semantics can be moved into a
    separate function, so create the function and get rid of the flag.

    Signed-off-by: Darrick J. Wong
    Reviewed-by: Brian Foster
    Reviewed-by: Christoph Hellwig

    Darrick J. Wong
     

09 Jan, 2015

1 commit


24 Jul, 2014

1 commit

  • From: Brian Foster

    Speculative preallocation and and the associated throttling metrics
    assume we're working with large files on large filesystems. Users have
    reported inefficiencies in these mechanisms when we happen to be dealing
    with large files on smaller filesystems. This can occur because while
    prealloc throttling is aggressive under low free space conditions, it is
    not active until we reach 5% free space or less.

    For example, a 40GB filesystem has enough space for several files large
    enough to have multi-GB preallocations at any given time. If those files
    are slow growing, they might reserve preallocation for long periods of
    time as well as avoid the background scanner due to frequent
    modification. If a new file is written under these conditions, said file
    has no access to this already reserved space and premature ENOSPC is
    imminent.

    To handle this scenario, modify the buffered write ENOSPC handling and
    retry sequence to invoke an eofblocks scan. In the smaller filesystem
    scenario, the eofblocks scan resets the usage of preallocation such that
    when the 5% free space threshold is met, throttling effectively takes
    over to provide fair and efficient preallocation until legitimate
    ENOSPC.

    The eofblocks scan is selective based on the nature of the failure. For
    example, an EDQUOT failure in a particular quota will use a filtered
    scan for that quota. Because we don't know which quota might have caused
    an allocation failure at any given time, we include each applicable
    quota determined to be under low free space conditions in the scan.

    Signed-off-by: Brian Foster
    Reviewed-by: Dave Chinner
    Signed-off-by: Dave Chinner

    Brian Foster
     

05 May, 2014

1 commit

  • group and project quota hints are currently stored on the user
    dquot. If we are attaching quotas to the inode, then the group and
    project dquots are stored as hints on the user dquot to save having
    to look them up again later.

    The thing is, the hints are not used for that inode for the rest of
    the life of the inode - the dquots are attached directly to the
    inode itself - so the only time the hints are used is when an inode
    first has dquots attached.

    When the hints on the user dquot don't match the dquots being
    attache dto the inode, they are then removed and replaced with the
    new hints. If a user is concurrently modifying files in different
    group and/or project contexts, then this leads to thrashing of the
    hints attached to user dquot.

    If user quotas are not enabled, then hints are never even used.

    So, if the hints are used to avoid the cost of the lookup, is the
    cost of the lookup significant enough to justify the hint
    infrstructure? Maybe it was once, when there was a global quota
    manager shared between all XFS filesystems and was hash table based.

    However, lookups are now much simpler, requiring only a single lock and
    radix tree lookup local to the filesystem and no hash or LRU
    manipulations to be made. Hence the cost of lookup is much lower
    than when hints were implemented. Turns out that benchmarks show
    that, too, with thir being no differnce in performance when doing
    file creation workloads as a single user with user, group and
    project quotas enabled - the hints do not make the code go any
    faster. In fact, removing the hints shows a 2-3% reduction in the
    time it takes to create 50 million inodes....

    So, let's just get rid of the hints and the complexity around them.

    Signed-off-by: Dave Chinner
    Reviewed-by: Christoph Hellwig
    Signed-off-by: Dave Chinner

    Dave Chinner
     

24 Oct, 2013

1 commit

  • All of the buffer operations structures are needed to be exported
    for xfs_db, so move them all to a common location rather than
    spreading them all over the place. They are verifying the on-disk
    format, so while xfs_format.h might be a good place, it is not part
    of the on disk format.

    Hence we need to create a new header file that we centralise these
    related definitions. Start by moving the bffer operations
    structures, and then also move all the other definitions that have
    crept into xfs_log_format.h and xfs_format.h as there was no other
    shared header file to put them in.

    Signed-off-by: Dave Chinner
    Reviewed-by: Christoph Hellwig
    Signed-off-by: Ben Myers

    Dave Chinner
     

11 Jul, 2013

1 commit

  • Add project quota changes to all the places where group quota field
    is used:
    * add separate project quota members into various structures
    * split project quota and group quotas so that instead of overriding
    the group quota members incore, the new project quota members are
    used instead
    * get rid of usage of the OQUOTA flag incore, in favor of separate
    group and project quota flags.
    * add a project dquot argument to various functions.

    Not using the pquotino field from superblock yet.

    Signed-off-by: Chandra Seetharaman
    Reviewed-by: Ben Myers
    Signed-off-by: Ben Myers

    Chandra Seetharaman
     

29 Jun, 2013

1 commit


23 Mar, 2013

2 commits

  • Enable tracking of high and low watermarks for preallocation
    throttling of files under quota restrictions. These values are
    calculated when the quota limit is read from disk or modified and
    cached for later use by the throttling algorithm.

    The high watermark specifies when preallocation is disabled, the
    low watermark specifies when throttling is enabled and the low free
    space data structure contains precalculated low free space limits
    to serve as input to determine the level of throttling required.

    Note that the low free space data structure is based on the
    existing global low free space data structure with the exception of
    using three stages (5%, 3% and 1%) rather than five to reduce the
    impact of xfs_dquot memory overhead.

    Signed-off-by: Brian Foster
    Reviewed-by: Mark Tinguely
    Signed-off-by: Ben Myers

    Brian Foster
     
  • Modify xfs_qm_adjust_dqlimits() to take the xfs_dquot as a
    parameter instead of just the xfs_disk_dquot_t so we can update
    in-memory fields if necessary.

    Signed-off-by: Brian Foster
    Reviewed-by: Mark Tinguely
    Signed-off-by: Ben Myers

    Brian Foster
     

16 Nov, 2012

3 commits

  • To separate the verifiers from iodone functions and associate read
    and write verifiers at the same time, introduce a buffer verifier
    operations structure to the xfs_buf.

    This avoids the need for assigning the write verifier, clearing the
    iodone function and re-running ioend processing in the read
    verifier, and gets rid of the nasty "b_pre_io" name for the write
    verifier function pointer. If we ever need to, it will also be
    easier to add further content specific callbacks to a buffer with an
    ops structure in place.

    We also avoid needing to export verifier functions, instead we
    can simply export the ops structures for those that are needed
    outside the function they are defined in.

    This patch also fixes a directory block readahead verifier issue
    it exposed.

    This patch also adds ops callbacks to the inode/alloc btree blocks
    initialised by growfs. These will need more work before they will
    work with CRCs.

    Signed-off-by: Dave Chinner
    Reviewed-by: Phil White
    Signed-off-by: Ben Myers

    Dave Chinner
     
  • These verifiers are essentially the same code as the read verifiers,
    but do not require ioend processing. Hence factor the read verifier
    functions and add a new write verifier wrapper that is used as the
    callback.

    This is done as one large patch for all verifiers rather than one
    patch per verifier as the change is largely mechanical. This
    includes hooking up the write verifier via the read verifier
    function.

    Hooking up the write verifier for buffers obtained via
    xfs_trans_get_buf() will be done in a separate patch as that touches
    code in many different places rather than just the verifier
    functions.

    Signed-off-by: Dave Chinner
    Reviewed-by: Mark Tinguely
    Signed-off-by: Ben Myers

    Dave Chinner
     
  • Add a dquot buffer verify callback function and pass it into the
    buffer read functions. This checks all the dquots in a buffer, but
    cannot completely verify the dquot ids are correct. Also, errors
    cannot be repaired, so an additional function is added to repair bad
    dquots in the buffer if such an error is detected in a context where
    repair is allowed.

    Signed-off-by: Dave Chinner
    Reviewed-by: Christoph Hellwig
    Reviewed-by: Phil White
    Signed-off-by: Ben Myers

    Dave Chinner
     

15 May, 2012

1 commit

  • Queue delwri buffers on a local on-stack list instead of a per-buftarg one,
    and write back the buffers per-process instead of by waking up xfsbufd.

    This is now easily doable given that we have very few places left that write
    delwri buffers:

    - log recovery:
    Only done at mount time, and already forcing out the buffers
    synchronously using xfs_flush_buftarg

    - quotacheck:
    Same story.

    - dquot reclaim:
    Writes out dirty dquots on the LRU under memory pressure. We might
    want to look into doing more of this via xfsaild, but it's already
    more optimal than the synchronous inode reclaim that writes each
    buffer synchronously.

    - xfsaild:
    This is the main beneficiary of the change. By keeping a local list
    of buffers to write we reduce latency of writing out buffers, and
    more importably we can remove all the delwri list promotions which
    were hitting the buffer cache hard under sustained metadata loads.

    The implementation is very straight forward - xfs_buf_delwri_queue now gets
    a new list_head pointer that it adds the delwri buffers to, and all callers
    need to eventually submit the list using xfs_buf_delwi_submit or
    xfs_buf_delwi_submit_nowait. Buffers that already are on a delwri list are
    skipped in xfs_buf_delwri_queue, assuming they already are on another delwri
    list. The biggest change to pass down the buffer list was done to the AIL
    pushing. Now that we operate on buffers the trylock, push and pushbuf log
    item methods are merged into a single push routine, which tries to lock the
    item, and if possible add the buffer that needs writeback to the buffer list.
    This leads to much simpler code than the previous split but requires the
    individual IOP_PUSH instances to unlock and reacquire the AIL around calls
    to blocking routines.

    Given that xfsailds now also handle writing out buffers, the conditions for
    log forcing and the sleep times needed some small changes. The most
    important one is that we consider an AIL busy as long we still have buffers
    to push, and the other one is that we do increment the pushed LSN for
    buffers that are under flushing at this moment, but still count them towards
    the stuck items for restart purposes. Without this we could hammer on stuck
    items without ever forcing the log and not make progress under heavy random
    delete workloads on fast flash storage devices.

    [ Dave Chinner:
    - rebase on previous patches.
    - improved comments for XBF_DELWRI_Q handling
    - fix XBF_ASYNC handling in queue submission (test 106 failure)
    - rename delwri submit function buffer list parameters for clarity
    - xfs_efd_item_push() should return XFS_ITEM_PINNED ]

    Signed-off-by: Christoph Hellwig
    Reviewed-by: Dave Chinner
    Reviewed-by: Mark Tinguely
    Signed-off-by: Ben Myers

    Christoph Hellwig