• Sage Weil's avatar
    ceph: fix cap flush race reentrancy · db354052
    Sage Weil authored
    In e9964c10 we change cap flushing to do a delicate dance because some
    inodes on the cap_dirty list could be in a migrating state (got EXPORT but
    not IMPORT) in which we couldn't actually flush and move from
    dirty->flushing, breaking the while (!empty) { process first } loop
    structure.  It worked for a single sync thread, but was not reentrant and
    triggered infinite loops when multiple syncers came along.
    
    Instead, move inodes with dirty to a separate cap_dirty_migrating list
    when in the limbo export-but-no-import state, allowing us to go back to
    the simple loop structure (which was reentrant).  This is cleaner and more
    robust.
    
    Audited the cap_dirty users and this looks fine:
    list_empty(&ci->i_dirty_item) is still a reliable indicator of whether we
    have dirty caps (which list we're on is irrelevant) and list_del_init()
    calls still do the right thing.
    Signed-off-by: default avatarSage Weil <sage@newdream.net>
    db354052
caps.c 84 KB