15 Jan, 2012

1 commit

  • * 'for-3.3' of git://linux-nfs.org/~bfields/linux: (31 commits)
    nfsd4: nfsd4_create_clid_dir return value is unused
    NFSD: Change name of extended attribute containing junction
    svcrpc: don't revert to SVC_POOL_DEFAULT on nfsd shutdown
    svcrpc: fix double-free on shutdown of nfsd after changing pool mode
    nfsd4: be forgiving in the absence of the recovery directory
    nfsd4: fix spurious 4.1 post-reboot failures
    NFSD: forget_delegations should use list_for_each_entry_safe
    NFSD: Only reinitilize the recall_lru list under the recall lock
    nfsd4: initialize special stateid's at compile time
    NFSd: use network-namespace-aware cache registering routines
    SUNRPC: create svc_xprt in proper network namespace
    svcrpc: update outdated BKL comment
    nfsd41: allow non-reclaim open-by-fh's in 4.1
    svcrpc: avoid memory-corruption on pool shutdown
    svcrpc: destroy server sockets all at once
    svcrpc: make svc_delete_xprt static
    nfsd: Fix oops when parsing a 0 length export
    nfsd4: Use kmemdup rather than duplicating its implementation
    nfsd4: add a separate (lockowner, inode) lookup
    nfsd4: fix CONFIG_NFSD_FAULT_INJECTION compile error
    ...

    Linus Torvalds
     

04 Jan, 2012

1 commit


08 Dec, 2011

1 commit


05 Jan, 2011

3 commits

  • Supposes cache_check runs simultaneously with an update on a different
    CPU:

    cache_check task doing update
    ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^

    1. test for CACHE_VALID 1'. set entry->data
    & !CACHE_NEGATIVE

    2. use entry->data 2'. set CACHE_VALID

    If the two memory writes performed in step 1' and 2' appear misordered
    with respect to the reads in step 1 and 2, then the caller could get
    stale data at step 2 even though it saw CACHE_VALID set on the cache
    entry.

    Add memory barriers to prevent this.

    Reviewed-by: NeilBrown
    Signed-off-by: J. Bruce Fields

    J. Bruce Fields
     
  • We attempt to turn a cache entry negative in place. But that entry may
    already have been filled in by some other task since we last checked
    whether it was valid, so we could be modifying an already-valid entry.
    If nothing else there's a likely leak in such a case when the entry is
    eventually put() and contents are not freed because it has
    CACHE_NEGATIVE set.

    So, take the cache_lock just as sunrpc_cache_update() does.

    Reviewed-by: NeilBrown
    Signed-off-by: J. Bruce Fields

    J. Bruce Fields
     
  • Commit d29068c431599fa "sunrpc: Simplify cache_defer_req and related
    functions." asserted that cache_check() could determine success or
    failure of cache_defer_req() by checking the CACHE_PENDING bit.

    This isn't quite right.

    We need to know whether cache_defer_req() created a deferred request,
    in which case sending an rpc reply has become the responsibility of the
    deferred request, and it is important that we not send our own reply,
    resulting in two different replies to the same request.

    And the CACHE_PENDING bit doesn't tell us that; we could have
    succesfully created a deferred request at the same time as another
    thread cleared the CACHE_PENDING bit.

    So, partially revert that commit, to ensure that cache_check() returns
    -EAGAIN if and only if a deferred request has been created.

    Signed-off-by: J. Bruce Fields
    Acked-by: NeilBrown

    J. Bruce Fields
     

27 Oct, 2010

1 commit

  • * 'for-2.6.37' of git://linux-nfs.org/~bfields/linux: (99 commits)
    svcrpc: svc_tcp_sendto XPT_DEAD check is redundant
    svcrpc: no need for XPT_DEAD check in svc_xprt_enqueue
    svcrpc: assume svc_delete_xprt() called only once
    svcrpc: never clear XPT_BUSY on dead xprt
    nfsd4: fix connection allocation in sequence()
    nfsd4: only require krb5 principal for NFSv4.0 callbacks
    nfsd4: move minorversion to client
    nfsd4: delay session removal till free_client
    nfsd4: separate callback change and callback probe
    nfsd4: callback program number is per-session
    nfsd4: track backchannel connections
    nfsd4: confirm only on succesful create_session
    nfsd4: make backchannel sequence number per-session
    nfsd4: use client pointer to backchannel session
    nfsd4: move callback setup into session init code
    nfsd4: don't cache seq_misordered replies
    SUNRPC: Properly initialize sock_xprt.srcaddr in all cases
    SUNRPC: Use conventional switch statement when reclassifying sockets
    sunrpc/xprtrdma: clean up workqueue usage
    sunrpc: Turn list_for_each-s into the ..._entry-s
    ...

    Fix up trivial conflicts (two different deprecation notices added in
    separate branches) in Documentation/feature-removal-schedule.txt

    Linus Torvalds
     

23 Oct, 2010

1 commit

  • * 'llseek' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/bkl:
    vfs: make no_llseek the default
    vfs: don't use BKL in default_llseek
    llseek: automatically add .llseek fop
    libfs: use generic_file_llseek for simple_attr
    mac80211: disallow seeks in minstrel debug code
    lirc: make chardev nonseekable
    viotape: use noop_llseek
    raw: use explicit llseek file operations
    ibmasmfs: use generic_file_llseek
    spufs: use llseek in all file operations
    arm/omap: use generic_file_llseek in iommu_debug
    lkdtm: use generic_file_llseek in debugfs
    net/wireless: use generic_file_llseek in debugfs
    drm: use noop_llseek

    Linus Torvalds
     

19 Oct, 2010

1 commit

  • The sunrpc cache_ioctl function does not need the big kernel lock
    because it uses its own queue_lock already.

    rpc_pipe_ioctl apparently should be using i_lock like the other
    operations on the pipe file descriptor do.

    Signed-off-by: Arnd Bergmann

    Arnd Bergmann
     

15 Oct, 2010

1 commit

  • All file_operations should get a .llseek operation so we can make
    nonseekable_open the default for future file operations without a
    .llseek pointer.

    The three cases that we can automatically detect are no_llseek, seq_lseek
    and default_llseek. For cases where we can we can automatically prove that
    the file offset is always ignored, we use noop_llseek, which maintains
    the current behavior of not returning an error from a seek.

    New drivers should normally not use noop_llseek but instead use no_llseek
    and call nonseekable_open at open time. Existing drivers can be converted
    to do the same when the maintainer knows for certain that no user code
    relies on calling seek on the device file.

    The generated code is often incorrectly indented and right now contains
    comments that clarify for each added line why a specific variant was
    chosen. In the version that gets submitted upstream, the comments will
    be gone and I will manually fix the indentation, because there does not
    seem to be a way to do that using coccinelle.

    Some amount of new code is currently sitting in linux-next that should get
    the same modifications, which I will do at the end of the merge window.

    Many thanks to Julia Lawall for helping me learn to write a semantic
    patch that does all this.

    ===== begin semantic patch =====
    // This adds an llseek= method to all file operations,
    // as a preparation for making no_llseek the default.
    //
    // The rules are
    // - use no_llseek explicitly if we do nonseekable_open
    // - use seq_lseek for sequential files
    // - use default_llseek if we know we access f_pos
    // - use noop_llseek if we know we don't access f_pos,
    // but we still want to allow users to call lseek
    //
    @ open1 exists @
    identifier nested_open;
    @@
    nested_open(...)
    {

    }

    @ open exists@
    identifier open_f;
    identifier i, f;
    identifier open1.nested_open;
    @@
    int open_f(struct inode *i, struct file *f)
    {

    }

    @ read disable optional_qualifier exists @
    identifier read_f;
    identifier f, p, s, off;
    type ssize_t, size_t, loff_t;
    expression E;
    identifier func;
    @@
    ssize_t read_f(struct file *f, char *p, size_t s, loff_t *off)
    {

    }

    @ read_no_fpos disable optional_qualifier exists @
    identifier read_f;
    identifier f, p, s, off;
    type ssize_t, size_t, loff_t;
    @@
    ssize_t read_f(struct file *f, char *p, size_t s, loff_t *off)
    {
    ... when != off
    }

    @ write @
    identifier write_f;
    identifier f, p, s, off;
    type ssize_t, size_t, loff_t;
    expression E;
    identifier func;
    @@
    ssize_t write_f(struct file *f, const char *p, size_t s, loff_t *off)
    {

    }

    @ write_no_fpos @
    identifier write_f;
    identifier f, p, s, off;
    type ssize_t, size_t, loff_t;
    @@
    ssize_t write_f(struct file *f, const char *p, size_t s, loff_t *off)
    {
    ... when != off
    }

    @ fops0 @
    identifier fops;
    @@
    struct file_operations fops = {
    ...
    };

    @ has_llseek depends on fops0 @
    identifier fops0.fops;
    identifier llseek_f;
    @@
    struct file_operations fops = {
    ...
    .llseek = llseek_f,
    ...
    };

    @ has_read depends on fops0 @
    identifier fops0.fops;
    identifier read_f;
    @@
    struct file_operations fops = {
    ...
    .read = read_f,
    ...
    };

    @ has_write depends on fops0 @
    identifier fops0.fops;
    identifier write_f;
    @@
    struct file_operations fops = {
    ...
    .write = write_f,
    ...
    };

    @ has_open depends on fops0 @
    identifier fops0.fops;
    identifier open_f;
    @@
    struct file_operations fops = {
    ...
    .open = open_f,
    ...
    };

    // use no_llseek if we call nonseekable_open
    ////////////////////////////////////////////
    @ nonseekable1 depends on !has_llseek && has_open @
    identifier fops0.fops;
    identifier nso ~= "nonseekable_open";
    @@
    struct file_operations fops = {
    ... .open = nso, ...
    +.llseek = no_llseek, /* nonseekable */
    };

    @ nonseekable2 depends on !has_llseek @
    identifier fops0.fops;
    identifier open.open_f;
    @@
    struct file_operations fops = {
    ... .open = open_f, ...
    +.llseek = no_llseek, /* open uses nonseekable */
    };

    // use seq_lseek for sequential files
    /////////////////////////////////////
    @ seq depends on !has_llseek @
    identifier fops0.fops;
    identifier sr ~= "seq_read";
    @@
    struct file_operations fops = {
    ... .read = sr, ...
    +.llseek = seq_lseek, /* we have seq_read */
    };

    // use default_llseek if there is a readdir
    ///////////////////////////////////////////
    @ fops1 depends on !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    identifier readdir_e;
    @@
    // any other fop is used that changes pos
    struct file_operations fops = {
    ... .readdir = readdir_e, ...
    +.llseek = default_llseek, /* readdir is present */
    };

    // use default_llseek if at least one of read/write touches f_pos
    /////////////////////////////////////////////////////////////////
    @ fops2 depends on !fops1 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    identifier read.read_f;
    @@
    // read fops use offset
    struct file_operations fops = {
    ... .read = read_f, ...
    +.llseek = default_llseek, /* read accesses f_pos */
    };

    @ fops3 depends on !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    identifier write.write_f;
    @@
    // write fops use offset
    struct file_operations fops = {
    ... .write = write_f, ...
    + .llseek = default_llseek, /* write accesses f_pos */
    };

    // Use noop_llseek if neither read nor write accesses f_pos
    ///////////////////////////////////////////////////////////

    @ fops4 depends on !fops1 && !fops2 && !fops3 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    identifier read_no_fpos.read_f;
    identifier write_no_fpos.write_f;
    @@
    // write fops use offset
    struct file_operations fops = {
    ...
    .write = write_f,
    .read = read_f,
    ...
    +.llseek = noop_llseek, /* read and write both use no f_pos */
    };

    @ depends on has_write && !has_read && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    identifier write_no_fpos.write_f;
    @@
    struct file_operations fops = {
    ... .write = write_f, ...
    +.llseek = noop_llseek, /* write uses no f_pos */
    };

    @ depends on has_read && !has_write && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    identifier read_no_fpos.read_f;
    @@
    struct file_operations fops = {
    ... .read = read_f, ...
    +.llseek = noop_llseek, /* read uses no f_pos */
    };

    @ depends on !has_read && !has_write && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    @@
    struct file_operations fops = {
    ...
    +.llseek = noop_llseek, /* no read or write fn */
    };
    ===== End semantic patch =====

    Signed-off-by: Arnd Bergmann
    Cc: Julia Lawall
    Cc: Christoph Hellwig

    Arnd Bergmann
     

12 Oct, 2010

2 commits

  • We limit the number of 'defer' requests to DFR_MAX.

    The imposition of this limit is spread about a bit - sometime we don't
    add new things to the list, sometimes we remove old things.

    Also it is currently applied to requests which we are 'waiting' for
    rather than 'deferring'. This doesn't seem ideal as 'waiting'
    requests are naturally limited by the number of threads.

    So gather the DFR_MAX handling code to one place and only apply it to
    requests that are actually being deferred.

    This means that not all 'cache_deferred_req' structures go on the
    'cache_defer_list, so we need to be careful when adding and removing
    things.

    Signed-off-by: NeilBrown
    Signed-off-by: J. Bruce Fields

    NeilBrown
     
  • The return value from cache_defer_req is somewhat confusing.
    Various different error codes are returned, but the single caller is
    only interested in success or failure.

    In fact it can measure this success or failure itself by checking
    CACHE_PENDING, which makes the point of the code more explicit.

    So change cache_defer_req to return 'void' and test CACHE_PENDING
    after it completes, to see if the request was actually deferred or
    not.

    Similarly setup_deferral and cache_wait_req don't need a return value,
    so make them void and remove some code.

    The call to cache_revisit_request (to guard against a race) is only
    needed for the second call to setup_deferral, so move it out of
    setup_deferral to after that second call. With the first call the
    race is handled differently (by explicitly calling
    'wait_for_completion').

    Signed-off-by: NeilBrown
    Signed-off-by: J. Bruce Fields

    NeilBrown
     

02 Oct, 2010

1 commit

  • If we set up to wait for a cache item to be filled in, and then find
    that it is no longer pending, it could be that some other thread is
    in 'cache_revisit_request' and has moved our request to its 'pending' list.
    So when our setup_deferral calls cache_revisit_request it will find nothing to
    put on the pending list, and do nothing.

    We then return from cache_wait_req, thus leaving the 'sleeper'
    on-stack structure open to being corrupted by subsequent stack usage.

    However that 'sleeper' could still be on the 'pending' list that the
    other thread is looking at and so any corruption could cause it to behave badly.

    To avoid this race we simply take the same path as if the
    'wait_for_completion_interruptible_timeout' was interrupted and if the
    sleeper is no longer on the list (which it won't be) we wait on the
    completion - which will ensure that any other cache_revisit_request
    will have let go of the sleeper.

    Signed-off-by: NeilBrown
    Signed-off-by: J. Bruce Fields

    NeilBrown
     

27 Sep, 2010

2 commits


23 Sep, 2010

1 commit


22 Sep, 2010

2 commits


20 Sep, 2010

1 commit

  • The last_close field of a cache_detail is initialized to zero, so the
    condition

    detail->last_close < seconds_since_boot() - 30

    may be false even for a cache that was never opened.

    However, we want to immediately fail upcalls to caches that were never
    opened: in the case of the auth_unix_gid cache, especially, which may
    never be opened by mountd (if the --manage-gids option is not set), we
    want to fail the upcall immediately. Otherwise client requests will be
    dropped unnecessarily on reboot.

    Also document these conditions.

    Signed-off-by: J. Bruce Fields

    J. Bruce Fields
     

08 Sep, 2010

4 commits

  • Attempt to make obvious the first-try-sleeping-then-try-deferral logic
    by putting that logic into a top-level function that calls helpers.

    Signed-off-by: J. Bruce Fields

    J. Bruce Fields
     
  • Pull out some code into helper functions, fix a typo.

    Signed-off-by: J. Bruce Fields

    J. Bruce Fields
     
  • The current practice of waiting for cache updates by queueing the
    whole request to be retried has (at least) two problems.

    1/ With NFSv4, requests can be quite complex and re-trying a whole
    request when a later part fails should only be a last-resort, not a
    normal practice.

    2/ Large requests, and in particular any 'write' request, will not be
    queued by the current code and doing so would be undesirable.

    In many cases only a very sort wait is needed before the cache gets
    valid data.

    So, providing the underlying transport permits it by setting
    ->thread_wait,
    arrange to wait briefly for an upcall to be completed (as reflected in
    the clearing of CACHE_PENDING).
    If the short wait was not long enough and CACHE_PENDING is still set,
    fall back on the old approach.

    The 'thread_wait' value is set to 5 seconds when there are spare
    threads, and 1 second when there are no spare threads.

    These values are probably much higher than needed, but will ensure
    some forward progress.

    Note that as we only request an update for a non-valid item, and as
    non-valid items are updated in place it is extremely unlikely that
    cache_check will return -ETIMEDOUT. Normally cache_defer_req will
    sleep for a short while and then find that the item is_valid.

    Signed-off-by: NeilBrown
    Signed-off-by: J. Bruce Fields

    NeilBrown
     
  • This protects us from confusion when the wallclock time changes.

    We convert to and from wallclock when setting or reading expiry
    times.

    Also use seconds since boot for last_clost time.

    Signed-off-by: NeilBrown
    Signed-off-by: J. Bruce Fields

    NeilBrown
     

07 Aug, 2010

1 commit


07 Jul, 2010

1 commit

  • This patch makes the cache_cleaner workqueue deferrable, to prevent
    unnecessary system wake-ups, which is very important for embedded
    battery-powered devices.

    do_cache_clean() is called every 30 seconds at the moment, and often
    makes the system wake up from its power-save sleep state. With this
    change, when the workqueue uses a deferrable timer, the
    do_cache_clean() invocation will be delayed and combined with the
    closest "real" wake-up. This improves the power consumption situation.

    Note, I tried to create a DECLARE_DELAYED_WORK_DEFERRABLE() helper
    macro, similar to DECLARE_DELAYED_WORK(), but failed because of the
    way the timer wheel core stores the deferrable flag (it is the
    LSBit in the time->base pointer). My attempt to define a static
    variable with this bit set ended up with the "initializer element is
    not constant" error.

    Thus, I have to use run-time initialization, so I created a new
    cache_initialize() function which is called once when sunrpc is
    being initialized.

    Signed-off-by: Artem Bityutskiy
    Signed-off-by: J. Bruce Fields

    Artem Bityutskiy
     

24 May, 2010

1 commit

  • * 'bkl/ioctl' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/random-tracing:
    uml: Pushdown the bkl from harddog_kern ioctl
    sunrpc: Pushdown the bkl from sunrpc cache ioctl
    sunrpc: Pushdown the bkl from ioctl
    autofs4: Pushdown the bkl from ioctl
    uml: Convert to unlocked_ioctls to remove implicit BKL
    ncpfs: BKL ioctl pushdown
    coda: Clean-up whitespace problems in pioctl.c
    coda: BKL ioctl pushdown
    drivers: Push down BKL into various drivers
    isdn: Push down BKL into ioctl functions
    scsi: Push down BKL into ioctl functions
    dvb: Push down BKL into ioctl functions
    smbfs: Push down BKL into ioctl function
    coda/psdev: Remove BKL from ioctl function
    um/mmapper: Remove BKL usage
    sn_hwperf: Kill BKL usage
    hfsplus: Push down BKL into ioctl function

    Linus Torvalds
     

22 May, 2010

1 commit


20 May, 2010

1 commit

  • * 'for-2.6.35' of git://linux-nfs.org/~bfields/linux: (45 commits)
    Revert "nfsd4: distinguish expired from stale stateids"
    nfsd: safer initialization order in find_file()
    nfs4: minor callback code simplification, comment
    NFSD: don't report compiled-out versions as present
    nfsd4: implement reclaim_complete
    nfsd4: nfsd4_destroy_session must set callback client under the state lock
    nfsd4: keep a reference count on client while in use
    nfsd4: mark_client_expired
    nfsd4: introduce nfs4_client.cl_refcount
    nfsd4: refactor expire_client
    nfsd4: extend the client_lock to cover cl_lru
    nfsd4: use list_move in move_to_confirmed
    nfsd4: fold release_session into expire_client
    nfsd4: rename sessionid_lock to client_lock
    nfsd4: fix bare destroy_session null dereference
    nfsd4: use local variable in nfs4svc_encode_compoundres
    nfsd: further comment typos
    sunrpc: centralise most calls to svc_xprt_received
    nfsd4: fix unlikely race in session replay case
    nfsd4: fix filehandle comment
    ...

    Linus Torvalds
     

17 May, 2010

2 commits

  • Now that cache_ioctl_procfs() calls the bkl explicitly, we need to
    include the relevant header as well.

    This fixes the following build error:

    net/sunrpc/cache.c: In function 'cache_ioctl_procfs':
    net/sunrpc/cache.c:1355: error: implicit declaration of function 'lock_kernel'
    net/sunrpc/cache.c:1359: error: implicit declaration of function 'unlock_kernel'

    Reported-by: Stephen Rothwell
    Signed-off-by: Frederic Weisbecker

    Frederic Weisbecker
     
  • Push down the bkl from procfs's ioctl main handler to its users.
    Only three procfs users implement an ioctl (non unlocked) handler.
    Turn them into unlocked_ioctl and push down the Devil inside.

    v2: PDE(inode)->data doesn't need to be under bkl
    v3: And don't forget to git-add the result
    v4: Use wrappers to pushdown instead of an invasive and error prone
    handlers surgery.

    Signed-off-by: Frederic Weisbecker
    Acked-by: Arnd Bergmann
    Cc: Thomas Gleixner
    Cc: Andrew Morton
    Cc: Ingo Molnar
    Cc: John Kacur
    Cc: KAMEZAWA Hiroyuki
    Cc: Al Viro
    Cc: Alexey Dobriyan

    Frederic Weisbecker
     

24 Mar, 2010

1 commit


15 Mar, 2010

3 commits

  • If sunrpc_cache_lookup finds an expired entry, remove it from
    the cache and return a freshly created non-VALID entry instead.
    This ensures that we only ever get a usable entry, or an
    entry that will become usable once an update arrives.
    i.e. we will never need to repeat the lookup.

    This allows us to remove the 'is_expired' test from cache_check
    (i.e. from cache_is_valid). cache_check should never get an expired
    entry as 'lookup' will never return one. If it does happen - due to
    inconvenient timing - then just accept it as still valid, it won't be
    very much past it's use-by date.

    Signed-off-by: NeilBrown
    Signed-off-by: J. Bruce Fields

    NeilBrown
     
  • This removes a tiny bit of code duplication, but more important
    prepares for following patch which will perform the expiry check in
    cache_lookup and the rest of the validity check in cache_check.

    Signed-off-by: NeilBrown
    Signed-off-by: J. Bruce Fields

    NeilBrown
     
  • currently expired entries remain in the auth caches as long
    as there is a reference.
    This was needed long ago when the auth_domain cache used the same
    cache infrastructure. But since that (being a very different sort
    of cache) was separated, this test is no longer needed.

    So remove the test on refcnt and tidy up the surrounding code.

    This allows the cache_dequeue call (which needed to be there to
    drop a potentially awkward reference) can be moved outside of the
    spinlock which is a better place for it.

    Signed-off-by: NeilBrown
    Signed-off-by: J. Bruce Fields

    NeilBrown
     

30 Nov, 2009

1 commit


19 Sep, 2009

1 commit

  • In cache_defer_req, 'dreq' is used for two significantly different
    values that happen to be of the same type.

    This is both confusing, and makes it hard to extend the range of one of
    the values as we will in the next patch.
    So introduce 'discard' to take one of the values.

    Signed-off-by: NeilBrown
    Signed-off-by: J. Bruce Fields

    NeilBrown
     

18 Sep, 2009

1 commit


12 Sep, 2009

2 commits

  • The extra call to cache_revisit_request in cache_fresh_unlocked is not
    needed, as should have been fairly clear at the time of
    commit 4013edea9a0b6cdcb1fdf5d4011e47e068fd6efb

    If there are requests to be revisited, then we can be sure that
    CACHE_PENDING is set, so the second call is sufficient.

    So remove the first call.
    Then remove the 'new' parameter,
    then remove the return value for cache_fresh_locked which is only used
    to provide the value for 'new'.

    Signed-off-by: NeilBrown
    Signed-off-by: J. Bruce Fields

    NeilBrown
     
  • As "cache_defer_req" does not sound like a predicate, having it return
    a boolean value can be confusing. It is more consistent to return
    0 for success and negative for error.

    Exactly what error code to return is not important as we don't
    differentiate between reasons why the request wasn't deferred,
    we only care about whether it was deferred or not.

    Signed-off-by: NeilBrown
    Signed-off-by: J. Bruce Fields

    NeilBrown
     

21 Aug, 2009

1 commit