07 Mar, 2011

1 commit

  • mlog_exit is used to record the exit status of a function.
    But because it is added in so many functions, if we enable it,
    the system logs get filled up quickly and cause too much I/O.
    So actually no one can open it for a production system or even
    for a test.

    This patch just try to remove it or change it. So:
    1. if all the error paths already use mlog_errno, it is just removed.
    Otherwise, it will be replaced by mlog_errno.
    2. if it is used to print some return value, it is replaced with
    mlog(0,...).
    mlog_exit_ptr is changed to mlog(0.
    All those mlog(0,...) will be replaced with trace events later.

    Signed-off-by: Tao Ma

    Tao Ma
     

22 Feb, 2011

2 commits

  • Since all 4 files, localalloc.c, suballoc.c, alloc.c and
    resize.c, which use DISK_ALLOC are changed to trace events,
    Remove masklog DISK_ALLOC totally.

    Signed-off-by: Tao Ma

    Tao Ma
     
  • This is the 2nd step to remove the debug info of DISK_ALLOC.

    So this patch removes all mlog(0,...) from localalloc.c and adds
    the corresponding tracepoints. Different mlogs have different
    solutions.
    1. Some are replaced with trace event directly.
    2. Some are replaced while some new parameters are added.
    3. Some are combined into one trace events.
    4. Some redundant mlogs are removed.

    Signed-off-by: Tao Ma

    Tao Ma
     

21 Feb, 2011

1 commit

  • ENTRY is used to record the entry of a function.
    But because it is added in so many functions, if we enable it,
    the system logs get filled up quickly and cause too much I/O.
    So actually no one can open it for a production system or even
    for a test.

    So for mlog_entry_void, we just remove it.
    for mlog_entry(...), we replace it with mlog(0,...), and they
    will be replace by trace event later.

    Signed-off-by: Tao Ma

    Tao Ma
     

16 Jun, 2010

1 commit

  • In commit 6b82021b9e91cd689fdffadbcdb9a42597bbe764, we increase
    our local alloc size and calculate how much megabytes we can
    get according to group size and volume size.
    But we also need to check the maximum bits a local alloc block
    bitmap can have. With a bs=512, cs=32K, local volume with 160G,
    it calculate 96MB while the maximum local alloc size is only
    76M. So the bitmap will overflow and corrupt the system truncate
    log file. See bug
    http://oss.oracle.com/bugzilla/show_bug.cgi?id=1262

    Signed-off-by: Tao Ma
    Acked-by: Mark Fasheh
    Signed-off-by: Joel Becker

    Tao Ma
     

06 May, 2010

7 commits

  • They all take an ocfs2_alloc_context, which has the allocation inode.

    Signed-off-by: Joel Becker
    Signed-off-by: Tao Ma

    Joel Becker
     
  • Two tiny cleanup for allocation reservation.
    1. Remove some extra codes in ocfs2_local_alloc_find_clear_bits.
    2. Remove an unuseful variables in ocfs2_find_resv_lhs.

    Signed-off-by: Tao Ma
    Acked-by: Mark Fasheh
    Signed-off-by: Joel Becker

    Tao Ma
     
  • I have observed that the current size of 8M gives us pretty poor
    fragmentation on multi-threaded workloads which do lots of writes.

    Generally, I can increase the size of local alloc windows and observe a
    marked decrease in fragmentation, even up and beyond window sizes of 512
    megabytes. This makes sense for a couple reasons - larger local alloc means
    more room for reservation windows. On multi-node workloads the larger local
    alloc helps as well because we don't have to do window slides as often.

    Also, I removed the OCFS2_DEFAULT_LOCAL_ALLOC_SIZE constant as it is no
    longer used and the comment above it was out of date.

    To test fragmentation, I used a workload which launched 4 threads that did
    4k writes into a series of about 140 alternating files.

    With resv_level=2, and a 4k/4k file system I observed the following average
    fragmentation for various localalloc= parameters:

    localalloc= avg. fragmentation
    8 48
    32 16
    64 10
    120 7

    On larger cluster sizes, the difference is more dramatic.

    The new default size top out at 256M, which we'll only get for cluster
    sizes of 32K and above.

    Signed-off-by: Mark Fasheh
    Signed-off-by: Joel Becker

    Mark Fasheh
     
  • This patch pulls the local alloc sizing code into localalloc.c and provides
    a callout to it from ocfs2_fill_super(). Behavior is essentially unchanged
    except that I correctly calculate the maximum local alloc size. The old code
    in ocfs2_parse_options() calculated the max size as:

    ocfs2_local_alloc_size(sb) * 8

    which is correct, in bits. Unfortunately though the option passed in is in
    megabytes. Ultimately, this bug made no real difference - the shrink code
    would catch a too-large size and bring it down to something reasonable.
    Still, it's less than efficient as-is.

    Signed-off-by: Mark Fasheh
    Signed-off-by: Joel Becker

    Mark Fasheh
     
  • Inodes are always allocated from the global bitmap now so we don't need this
    any more. Also, the existing implementation bounces reservations around
    needlessly.

    Signed-off-by: Mark Fasheh

    Mark Fasheh
     
  • This patch improves Ocfs2 allocation policy by allowing an inode to
    reserve a portion of the local alloc bitmap for itself. The reserved
    portion (allocation window) is advisory in that other allocation
    windows might steal it if the local alloc bitmap becomes
    full. Otherwise, the reservations are honored and guaranteed to be
    free. When the local alloc window is moved to a different portion of
    the bitmap, existing reservations are discarded.

    Reservation windows are represented internally by a red-black
    tree. Within that tree, each node represents the reservation window of
    one inode. An LRU of active reservations is also maintained. When new
    data is written, we allocate it from the inodes window. When all bits
    in a window are exhausted, we allocate a new one as close to the
    previous one as possible. Should we not find free space, an existing
    reservation is pulled off the LRU and cannibalized.

    Signed-off-by: Mark Fasheh

    Mark Fasheh
     
  • jbd[2]_journal_dirty_metadata() only returns 0. It's been returning 0
    since before the kernel moved to git. There is no point in checking
    this error.

    ocfs2_journal_dirty() has been faithfully returning the status since the
    beginning. All over ocfs2, we have blocks of code checking this can't
    fail status. In the past few years, we've tried to avoid adding these
    checks, because they are pointless. But anyone who looks at our code
    assumes they are needed.

    Finally, ocfs2_journal_dirty() is made a void function. All error
    checking is removed from other files. We'll BUG_ON() the status of
    jbd2_journal_dirty_metadata() just in case they change it someday. They
    won't.

    Signed-off-by: Joel Becker

    Joel Becker
     

13 Apr, 2010

2 commits


24 Mar, 2010

1 commit

  • When the local alloc file changes windows, unused bits are freed back to the
    global bitmap. By defnition, those bits can not be in use by any file. Also,
    the local alloc will never have been able to allocate those bits if they
    were part of a previous truncate. Therefore it makes sense that we should
    clear unused local alloc bits in the undo buffer so that they can be used
    immediatly.

    [ Modified to call it ocfs2_release_clusters() -- Joel ]

    Signed-off-by: Mark Fasheh
    Signed-off-by: Joel Becker

    Mark Fasheh
     

19 Mar, 2010

1 commit

  • What we were doing before was to ask for the current window size as the
    maximum allocation. This had the effect of limiting the amount of allocation
    we could get for the local alloc during times when the window size was
    shrunk due to fragmentation. In some cases, that could actually *increase*
    fragmentation by artificially limiting the number of bits we can accept. So
    while we still want to ask for a minimum number of bits equal to window
    size, there is no reason why we should limit the number of bits the local
    alloc should accept. Hence always allow the maximum number of local alloc
    bits.

    Signed-off-by: Mark Fasheh
    Signed-off-by: Joel Becker

    Mark Fasheh
     

27 Feb, 2010

1 commit

  • This patch add extent block (metadata) stealing mechanism for
    extent allocation. This mechanism is same as the inode stealing.
    if no room in slot specific extent_alloc, we will try to
    allocate extent block from the next slot.

    Signed-off-by: Tiger Yang
    Acked-by: Tao Ma
    Signed-off-by: Joel Becker

    Tiger Yang
     

05 Sep, 2009

2 commits

  • The next step in divorcing metadata I/O management from struct inode is
    to pass struct ocfs2_caching_info to the journal functions. Thus the
    journal locks a metadata cache with the cache io_lock function. It also
    can compare ci_last_trans and ci_created_trans directly.

    This is a large patch because of all the places we change
    ocfs2_journal_access..(handle, inode, ...) to
    ocfs2_journal_access..(handle, INODE_CACHE(inode), ...).

    Signed-off-by: Joel Becker

    Joel Becker
     
  • We are really passing the inode into the ocfs2_read/write_blocks()
    functions to get at the metadata cache. This commit passes the cache
    directly into the metadata block functions, divorcing them from the
    inode.

    Signed-off-by: Joel Becker

    Joel Becker
     

04 Apr, 2009

1 commit


06 Jan, 2009

2 commits

  • The per-metadata-type ocfs2_journal_access_*() functions hook up jbd2
    commit triggers and allow us to compute metadata ecc right before the
    buffers are written out. This commit provides ecc for inodes, extent
    blocks, group descriptors, and quota blocks. It is not safe to use
    extened attributes and metaecc at the same time yet.

    The ocfs2_extent_tree and ocfs2_path abstractions in alloc.c both hide
    the type of block at their root. Before, it didn't matter, but now the
    root block must use the appropriate ocfs2_journal_access_*() function.
    To keep this abstract, the structures now have a pointer to the matching
    journal_access function and a wrapper call to call it.

    A few places use naked ocfs2_write_block() calls instead of adding the
    blocks to the journal. We make sure to calculate their checksum and ecc
    before the write.

    Since we pass around the journal_access functions. Let's typedef them
    in ocfs2.h.

    Signed-off-by: Joel Becker
    Signed-off-by: Mark Fasheh

    Joel Becker
     
  • The ocfs2 code currently reads inodes off disk with a simple
    ocfs2_read_block() call. Each place that does this has a different set
    of sanity checks it performs. Some check only the signature. A couple
    validate the block number (the block read vs di->i_blkno). A couple
    others check for VALID_FL. Only one place validates i_fs_generation. A
    couple check nothing. Even when an error is found, they don't all do
    the same thing.

    We wrap inode reading into ocfs2_read_inode_block(). This will validate
    all the above fields, going readonly if they are invalid (they never
    should be). ocfs2_read_inode_block_full() is provided for the places
    that want to pass read_block flags. Every caller is passing a struct
    inode with a valid ip_blkno, so we don't need a separate blkno argument
    either.

    We will remove the validation checks from the rest of the code in a
    later commit, as they are no longer necessary.

    Signed-off-by: Joel Becker
    Signed-off-by: Mark Fasheh

    Joel Becker
     

15 Oct, 2008

3 commits

  • ocfs2_read_blocks() currently requires the CACHED flag for cached I/O.
    However, that's the common case. Let's flip it around and provide an
    IGNORE_CACHE flag for the special users. This has the added benefit of
    cleaning up the code some (ignore_cache takes on its special meaning
    earlier in the loop).

    Signed-off-by: Joel Becker
    Signed-off-by: Mark Fasheh

    Joel Becker
     
  • More than 30 callers of ocfs2_read_block() pass exactly OCFS2_BH_CACHED.
    Only six pass a different flag set. Rather than have every caller care,
    let's make ocfs2_read_block() take no flags and always do a cached read.
    The remaining six places can call ocfs2_read_blocks() directly.

    Signed-off-by: Joel Becker
    Signed-off-by: Mark Fasheh

    Joel Becker
     
  • Now that synchronous readers are using ocfs2_read_blocks_sync(), all
    callers of ocfs2_read_blocks() are passing an inode. Use it
    unconditionally. Since it's there, we don't need to pass the
    ocfs2_super either.

    Signed-off-by: Joel Becker
    Signed-off-by: Mark Fasheh

    Joel Becker
     

14 Oct, 2008

6 commits

  • This is pointless as brelse() already does the check.

    Signed-off-by: Mark Fasheh

    Mark Fasheh
     
  • It can also be moved into ocfs2_la_debug_read().

    Signed-off-by: Mark Fasheh

    Mark Fasheh
     
  • ocfs2 inode numbers are block numbers. For any filesystem with less
    than 2^32 blocks, this is not a problem. However, when ocfs2 starts
    using JDB2, it will be able to support filesystems with more than 2^32
    blocks. This would result in inode numbers higher than 2^32.

    The problem is that stat(2) can't handle those numbers on 32bit
    machines. The simple solution is to have ocfs2 allocate all inodes
    below that boundary.

    The suballoc code is changed to honor an optional block limit. Only the
    inode suballocator sets that limit - all other allocations stay unlimited.

    The biggest trick is to grow the inode suballocator beneath that limit.
    There's no point in allocating block groups that are above the limit,
    then rejecting their elements later on. We want to prevent the inode
    allocator from ever having block groups above the limit. This involves
    a little gyration with the local alloc code. If the local alloc window
    is above the limit, it signals the caller to try the global bitmap but
    does not disable the local alloc file (which can be used for other
    allocations).

    [ Minor cleanup - removed an ML_NOTICE comment. --Mark ]

    Signed-off-by: Joel Becker
    Signed-off-by: Mark Fasheh

    Joel Becker
     
  • A per-mount debugfs file, "local_alloc" is created which when read will
    expose live state of the nodes local alloc file. Performance impact is
    minimal, only a bit of memory overhead per mount point. Still, the code is
    hidden behind CONFIG_OCFS2_FS_STATS. This feature will help us debug
    local alloc performance problems on a live system.

    Signed-off-by: Mark Fasheh

    Mark Fasheh
     
  • Ocfs2's local allocator disables itself for the duration of a mount point
    when it has trouble allocating a large enough area from the primary bitmap.
    That can cause performance problems, especially for disks which were only
    temporarily full or fragmented. This patch allows for the allocator to
    shrink it's window first, before being disabled. Later, it can also be
    re-enabled so that any performance drop is minimized.

    To do this, we allow the value of osb->local_alloc_bits to be shrunk when
    needed. The default value is recorded in a mostly read-only variable so that
    we can re-initialize when required.

    Locking had to be updated so that we could protect changes to
    local_alloc_bits. Mostly this involves protecting various local alloc values
    with the osb spinlock. A new state is also added, OCFS2_LA_THROTTLED, which
    is used when the local allocator is has shrunk, but is not disabled. If the
    available space dips below 1 megabyte, the local alloc file is disabled. In
    either case, local alloc is re-enabled 30 seconds after the event, or when
    an appropriate amount of bits is seen in the primary bitmap.

    Signed-off-by: Mark Fasheh

    Mark Fasheh
     
  • Do this instead of tracking absolute local alloc size. This avoids
    needless re-calculatiion of bits from bytes in localalloc.c. Additionally,
    the value is now in a more natural unit for internal file system bitmap
    work.

    Signed-off-by: Mark Fasheh

    Mark Fasheh
     

15 Jul, 2008

1 commit


01 May, 2008

1 commit

  • kmalloc() during a localalloc window move can trigger the mm to prune
    the dcache which inturn can trigger the fs to delete an inode causing
    it start a recursive transaction.

    The fix also makes the change in kmalloc during localalloc shutdown
    just to be safe.

    Fixes oss bugzilla#901
    http://oss.oracle.com/bugzilla/show_bug.cgi?id=901

    Signed-off-by: Sunil Mushran
    Signed-off-by: Mark Fasheh

    Sunil Mushran
     

18 Apr, 2008

2 commits

  • Inode allocation is modified to look in other nodes allocators during
    extreme out of space situations. We retry our own slot when space is freed
    back to the global bitmap, or whenever we've allocated more than 1024 inodes
    from another slot.

    Signed-off-by: Tao Ma
    Signed-off-by: Mark Fasheh

    Tao Ma
     
  • In inode stealing, we no longer restrict the allocation to
    happen in the local node. So it is neccessary for us to add
    a new member in ocfs2_alloc_context to indicate which slot
    we are using for allocation. We also modify the process of
    local alloc so that this member can be used there also.

    Signed-off-by: Tao Ma
    Signed-off-by: Sunil Mushran
    Signed-off-by: Mark Fasheh

    Tao Ma
     

04 Mar, 2008

2 commits

  • replace all:
    little_endian_variable = cpu_to_leX(leX_to_cpu(little_endian_variable) +
    expression_in_cpu_byteorder);
    with:
    leX_add_cpu(&little_endian_variable, expression_in_cpu_byteorder);
    generated with semantic patch

    Signed-off-by: Marcin Slusarz
    Signed-off-by: Mark Fasheh

    Marcin Slusarz
     
  • Commit 2fbe8d1ebe004425b4f7b8bba345623d2280be82 disabled localalloc
    for local mounts. This caused issues as ocfs2 uses localalloc to
    provide write locality. This patch enables localalloc for local mounts.

    Signed-off-by: Sunil Mushran
    Signed-off-by: Mark Fasheh

    Sunil Mushran
     

26 Jan, 2008

2 commits

  • Local alloc is a performance optimization in ocfs2 in which a node
    takes a window of bits from the global bitmap and then uses that for
    all small local allocations. This window size is fixed to 8MB currently.
    This patch allows users to specify the window size in MB including
    disabling it by passing in 0. If the number specified is too large,
    the fs will use the default value of 8MB.

    mount -o localalloc=X /dev/sdX /mntpoint

    Signed-off-by: Sunil Mushran
    Signed-off-by: Mark Fasheh

    Sunil Mushran
     
  • Call this the "inode_lock" now, since it covers both data and meta data.
    This patch makes no functional changes.

    Signed-off-by: Mark Fasheh

    Mark Fasheh
     

28 Nov, 2007

1 commit

  • Enable expensive bitmap scanning only if DEBUG option is enabled.
    The bitmap scanning quite loads the CPU and on my machine the write
    throughput of dd if=/dev/zero of=/ocfs2/file bs=1M count=500 conv=sync
    improves from 37 MB/s to 45.4 MB/s in local mode...

    Signed-off-by: Jan Kara
    Signed-off-by: Mark Fasheh

    Jan Kara