30 Mar, 2010

1 commit

  • …it slab.h inclusion from percpu.h

    percpu.h is included by sched.h and module.h and thus ends up being
    included when building most .c files. percpu.h includes slab.h which
    in turn includes gfp.h making everything defined by the two files
    universally available and complicating inclusion dependencies.

    percpu.h -> slab.h dependency is about to be removed. Prepare for
    this change by updating users of gfp and slab facilities include those
    headers directly instead of assuming availability. As this conversion
    needs to touch large number of source files, the following script is
    used as the basis of conversion.

    http://userweb.kernel.org/~tj/misc/slabh-sweep.py

    The script does the followings.

    * Scan files for gfp and slab usages and update includes such that
    only the necessary includes are there. ie. if only gfp is used,
    gfp.h, if slab is used, slab.h.

    * When the script inserts a new include, it looks at the include
    blocks and try to put the new include such that its order conforms
    to its surrounding. It's put in the include block which contains
    core kernel includes, in the same order that the rest are ordered -
    alphabetical, Christmas tree, rev-Xmas-tree or at the end if there
    doesn't seem to be any matching order.

    * If the script can't find a place to put a new include (mostly
    because the file doesn't have fitting include block), it prints out
    an error message indicating which .h file needs to be added to the
    file.

    The conversion was done in the following steps.

    1. The initial automatic conversion of all .c files updated slightly
    over 4000 files, deleting around 700 includes and adding ~480 gfp.h
    and ~3000 slab.h inclusions. The script emitted errors for ~400
    files.

    2. Each error was manually checked. Some didn't need the inclusion,
    some needed manual addition while adding it to implementation .h or
    embedding .c file was more appropriate for others. This step added
    inclusions to around 150 files.

    3. The script was run again and the output was compared to the edits
    from #2 to make sure no file was left behind.

    4. Several build tests were done and a couple of problems were fixed.
    e.g. lib/decompress_*.c used malloc/free() wrappers around slab
    APIs requiring slab.h to be added manually.

    5. The script was run on all .h files but without automatically
    editing them as sprinkling gfp.h and slab.h inclusions around .h
    files could easily lead to inclusion dependency hell. Most gfp.h
    inclusion directives were ignored as stuff from gfp.h was usually
    wildly available and often used in preprocessor macros. Each
    slab.h inclusion directive was examined and added manually as
    necessary.

    6. percpu.h was updated not to include slab.h.

    7. Build test were done on the following configurations and failures
    were fixed. CONFIG_GCOV_KERNEL was turned off for all tests (as my
    distributed build env didn't work with gcov compiles) and a few
    more options had to be turned off depending on archs to make things
    build (like ipr on powerpc/64 which failed due to missing writeq).

    * x86 and x86_64 UP and SMP allmodconfig and a custom test config.
    * powerpc and powerpc64 SMP allmodconfig
    * sparc and sparc64 SMP allmodconfig
    * ia64 SMP allmodconfig
    * s390 SMP allmodconfig
    * alpha SMP allmodconfig
    * um on x86_64 SMP allmodconfig

    8. percpu.h modifications were reverted so that it could be applied as
    a separate patch and serve as bisection point.

    Given the fact that I had only a couple of failures from tests on step
    6, I'm fairly confident about the coverage of this conversion patch.
    If there is a breakage, it's likely to be something in one of the arch
    headers which should be easily discoverable easily on most builds of
    the specific arch.

    Signed-off-by: Tejun Heo <tj@kernel.org>
    Guess-its-ok-by: Christoph Lameter <cl@linux-foundation.org>
    Cc: Ingo Molnar <mingo@redhat.com>
    Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>

    Tejun Heo
     

29 Mar, 2010

1 commit


23 Mar, 2010

18 commits

  • Clear pointer to mds request after dropping the reference to
    ensure we don't drop it again, as there is at least one error
    path through this function that does not reset fi->last_readdir
    to a new value.

    Signed-off-by: Sage Weil

    Sage Weil
     
  • Fix a broken check that a reply came back from the same MDS we sent the
    request to. I don't think a case that actually triggers this would ever
    come up in practice, but it's clearly wrong and easy to fix.

    Reported-by: Dan Carpenter
    Signed-off-by: Sage Weil

    Sage Weil
     
  • Return ERR_PTR(-ENOMEM) if kmalloc() fails. We handle allocation
    failures the same way later in the function.

    Signed-off-by: Dan Carpenter
    Signed-off-by: Sage Weil

    Dan Carpenter
     
  • Return error to original caller if register_session() fails.

    Signed-off-by: Sage Weil

    Sage Weil
     
  • Currently, if the wait_event_interruptible is interrupted, we
    return EAGAIN unconditionally and loop, such that we aren't, in
    fact, interruptible. So, propagate ERESTARTSYS if we get it.

    Signed-off-by: Sage Weil

    Sage Weil
     
  • We were rebuilding the snap context when it was not necessary
    (i.e. when the realm seq hadn't changed _and_ the parent seq
    was still older), which caused page snapc pointers to not match
    the realm's snapc pointer (even though the snap context itself
    was identical). This confused begin_write and put it into an
    endless loop.

    The correct logic is: rebuild snapc if _my_ realm seq changed, or
    if my parent realm's seq is newer than mine (and thus mine needs
    to be rebuilt too).

    Signed-off-by: Sage Weil

    Sage Weil
     
  • We get a fault callback on _every_ tcp connection fault. Normally, we
    want to reopen the connection when that happens. If the address we have
    is bad, however, and connection attempts always result in a connection
    refused or similar error, explicitly closing and reopening the msgr
    connection just prevents the messenger's backoff logic from kicking in.
    The result can be a console full of

    [ 3974.417106] ceph: osd11 10.3.14.138:6800 connection failed
    [ 3974.423295] ceph: osd11 10.3.14.138:6800 connection failed
    [ 3974.429709] ceph: osd11 10.3.14.138:6800 connection failed

    Instead, if we get a fault, and have outstanding requests, but the osd
    address hasn't changed and the connection never successfully connected in
    the first place, do nothing to the osd connection. The messenger layer
    will back off and retry periodically, because we never connected and thus
    the lossy bit is not set.

    Instead, touch each request's r_stamp so that handle_timeout can tell the
    request is still alive and kicking.

    Signed-off-by: Sage Weil

    Sage Weil
     
  • Make variable name slightly more generic, since it will (soon)
    reflect either the time the request was sent OR the time it was
    last determined to be still retrying.

    Signed-off-by: Sage Weil

    Sage Weil
     
  • The messenger fault was clearing the BUSY bit, for reasons unclear. This
    made it possible for the con->ops->fault function to reopen the connection,
    and requeue work in the workqueue--even though the current thread was
    already in con_work.

    This avoids a problem where the client busy loops with connection failures
    on an unreachable OSD, but doesn't address the root cause of that problem.

    Signed-off-by: Sage Weil

    Sage Weil
     
  • Prevent duplicate 'mds0 caps stale' message from spamming the console every
    few seconds while the MDS restarts. Set s_renew_requested earlier, so that
    we only print the message once, even if we don't send an actual request.

    Signed-off-by: Sage Weil

    Sage Weil
     
  • The incremental map decoding of pg pool updates wasn't skipping
    the snaps and removed_snaps vectors. This caused osd requests
    to stall when pool snapshots were created or fs snapshots were
    deleted. Use a common helper for full and incremental map
    decoders that decodes pools properly.

    Signed-off-by: Sage Weil

    Sage Weil
     
  • The wait_unsafe_requests() helper dropped the mdsc mutex to wait
    for each request to complete, and then examined r_node to get the
    next request after retaking the lock. But the request completion
    removes the request from the tree, so r_node was always undefined
    at this point. Since it's a small race, it usually led to a
    valid request, but not always. The result was an occasional
    crash in rb_next() while dereferencing node->rb_left.

    Fix this by clearing the rb_node when removing the request from
    the request tree, and not walking off into the weeds when we
    are done waiting for a request. Since the request we waited on
    will _always_ be out of the request tree, take a ref on the next
    request, in the hopes that it won't be. But if it is, it's ok:
    we can start over from the beginning (and traverse over older read
    requests again).

    Signed-off-by: Sage Weil

    Sage Weil
     
  • We were releasing used caps (e.g. FILE_CACHE) from encode_inode_release
    with MDS requests (e.g. setattr). We don't carry refs on most caps, so
    this code worked most of the time, but for setattr (utimes) we try to
    drop Fscr.

    This causes cap state to get slightly out of sync with reality, and may
    result in subsequent mds revoke messages getting ignored.

    Fix by only releasing unused caps.

    Signed-off-by: Sage Weil

    Sage Weil
     
  • Drop session mutex unconditionally in handle_cap_grant, and do the
    check_caps from the handle_cap_grant helper. This avoids using a magic
    return value.

    Also avoid using a flag variable in the IMPORT case and call
    check_caps at the appropriate point.

    Signed-off-by: Sage Weil

    Sage Weil
     
  • Passing a session pointer to ceph_check_caps() used to mean it would leave
    the session mutex locked. That wasn't always possible if it wasn't passed
    CHECK_CAPS_AUTHONLY. If could unlock the passed session and lock a
    differet session mutex, which was clearly wrong, and also emitted a
    warning when it a racing CPU retook it and we did an unlock from the wrong
    context.

    This was only a problem when there was more than one MDS.

    First, make ceph_check_caps unconditionally drop the session mutex, so that
    it is free to lock other sessions as needed. Then adjust the one caller
    that passes in a session (handle_cap_grant) accordingly.

    Signed-off-by: Sage Weil

    Sage Weil
     
  • If we don't have the exported cap it's because we already released it. No
    need to WARN.

    Signed-off-by: Sage Weil

    Sage Weil
     
  • This causes an oops when debug output is enabled and we kick
    an osd request with no current r_osd (sometime after an osd
    failure). Check the pointer before dereferencing.

    Signed-off-by: Sage Weil

    Sage Weil
     
  • Previously we would decode state directly into our current ticket_handler.
    This is problematic if for some reason we fail to decode, because we end
    up with half new state and half old state.

    We are probably already in bad shape if we get an update we can't decode,
    but we may as well be tidy anyway. Decode into new_* temporaries and
    update the ticket_handler only on success.

    Signed-off-by: Sage Weil

    Sage Weil
     

21 Mar, 2010

6 commits

  • Release the old ticket_blob buffer when we get an updated service ticket
    from the monitor. Previously these were getting leaked.

    Signed-off-by: Sage Weil

    Sage Weil
     
  • The buffer size was incorrectly calculated for the ceph_x_encrypt()
    encapsulated ticket blob. Use a helper (with correct arithmetic) and
    BUG out if we were wrong.

    Signed-off-by: Sage Weil

    Sage Weil
     
  • We were failing to reconnect to services due to an old authenticator, even
    though we had the new ticket, because we weren't properly retrying the
    connect handshake, because we were calling an old/incorrect helper that
    left in_base_pos incorrect. The result was a failure to reconnect to the
    OSD or MDS (with an authentication error) if the MDS restarted after the
    service had been up a few hours (long enough for the original authenticator
    to be invalid). This was only a problem if the AUTH_X authentication was
    enabled.

    Now that the 'negotiate' and 'connect' stages are fully separated, we
    should use the prepare_read_connect() helper instead, and remove the
    obsolete one.

    Signed-off-by: Sage Weil

    Sage Weil
     
  • When an inode was dropped while being migrated between two MDSs,
    i_cap_exporting_issued was non-zero such that issue caps were non-zero and
    __ceph_is_any_caps(ci) was true. This prevented the inode from being
    removed from the snap realm, even as it was dropped from the cache.

    Fix this by dropping any residual i_snap_realm ref in destroy_inode.

    Signed-off-by: Sage Weil

    Sage Weil
     
  • All ci->i_snap_realm_item/realm->inodes_with_caps manipulation should be
    protected by realm->inodes_with_caps_lock. This bug would have only bit
    us in a rare race with a realm split (during some snap creations).

    Signed-off-by: Sage Weil

    Sage Weil
     
  • Added assertion, and cleared one case where the implemented caps were
    not following the issued caps.

    Signed-off-by: Yehuda Sadeh
    Signed-off-by: Sage Weil

    Sage Weil
     

06 Mar, 2010

1 commit


05 Mar, 2010

1 commit

  • This simplifies the process of timing out messages. We
    keep lru of current messages that are in flight. If a
    timeout has passed, we reset the osd connection, so that
    messages will be retransmitted. This is a failsafe in case
    we hit some sort of problem sending out message to the OSD.
    Normally, we'll get notification via an updated osdmap if
    there are problems.

    If a request is older than the keepalive timeout, send a
    keepalive to ensure we detect any breaks in the TCP connection.

    Signed-off-by: Yehuda Sadeh
    Signed-off-by: Sage Weil

    Yehuda Sadeh
     

02 Mar, 2010

9 commits


27 Feb, 2010

2 commits

  • The must_resend flag is always true, not false. In any case, we can
    just ignore it anyway.

    Signed-off-by: Sage Weil

    Sage Weil
     
  • We used to try to avoid freeing and then reallocating the osd
    struct. This is a bit fragile due to potential interactions with
    other references (beyond o_requests), and may be the cause of
    this crash:

    [120633.442358] BUG: unable to handle kernel NULL pointer dereference at (null)
    [120633.443292] IP: [] rb_erase+0x11d/0x277
    [120633.443292] PGD f7ff3067 PUD f7f53067 PMD 0
    [120633.443292] Oops: 0000 [#1] PREEMPT SMP
    [120633.443292] last sysfs file: /sys/kernel/uevent_seqnum
    [120633.443292] CPU 1
    [120633.443292] Modules linked in: ceph fan ac battery psmouse ehci_hcd ide_pci_generic ohci_hcd thermal processor button
    [120633.443292] Pid: 3023, comm: ceph-msgr/1 Not tainted 2.6.32-rc2 #12 H8SSL
    [120633.443292] RIP: 0010:[] [] rb_erase+0x11d/0x277
    [120633.443292] RSP: 0018:ffff8800f7b13a50 EFLAGS: 00010246
    [120633.443292] RAX: ffff880022907819 RBX: ffff880022907818 RCX: 0000000000000000
    [120633.443292] RDX: ffff8800f7b13a80 RSI: ffff8800f587eb48 RDI: 0000000000000000
    [120633.443292] RBP: ffff8800f7b13a60 R08: 0000000000000000 R09: 0000000000000004
    [120633.443292] R10: 0000000000000000 R11: ffff8800c4441000 R12: ffff8800f587eb48
    [120633.443292] R13: ffff8800f58eaa00 R14: ffff8800f413c000 R15: 0000000000000001
    [120633.443292] FS: 00007fbef6e226e0(0000) GS:ffff880009200000(0000) knlGS:0000000000000000
    [120633.443292] CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b
    [120633.443292] CR2: 0000000000000000 CR3: 00000000f7c53000 CR4: 00000000000006e0
    [120633.443292] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
    [120633.443292] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
    [120633.443292] Process ceph-msgr/1 (pid: 3023, threadinfo ffff8800f7b12000, task ffff8800f5858b40)
    [120633.443292] Stack:
    [120633.443292] ffff8800f413c000 ffff8800f587e9c0 ffff8800f7b13a80 ffffffffa0098a86
    [120633.443292] 00000000000006f1 0000000000000000 ffff8800f7b13af0 ffffffffa009959b
    [120633.443292] ffff8800f413c000 ffff880022a68400 ffff880022a68400 ffff8800f587e9c0
    [120633.443292] Call Trace:
    [120633.443292] [] __remove_osd+0x4d/0xbc [ceph]
    [120633.443292] [] __map_osds+0x199/0x4fa [ceph]
    [120633.443292] [] ? __send_request+0xf8/0x186 [ceph]
    [120633.443292] [] kick_requests+0x169/0x3cb [ceph]
    [120633.443292] [] ceph_osdc_handle_map+0x370/0x522 [ceph]

    Since we're probably screwed anyway if a small kmalloc is
    failing, don't bother with trying to be clever here.

    Signed-off-by: Sage Weil

    Sage Weil
     

26 Feb, 2010

1 commit