04 May, 2013

1 commit

  • Pull nfsd changes from J Bruce Fields:
    "Highlights include:

    - Some more DRC cleanup and performance work from Jeff Layton

    - A gss-proxy upcall from Simo Sorce: currently krb5 mounts to the
    server using credentials from Active Directory often fail due to
    limitations of the svcgssd upcall interface. This replacement
    lifts those limitations. The existing upcall is still supported
    for backwards compatibility.

    - More NFSv4.1 support: at this point, if a user with a current
    client who upgrades from 4.0 to 4.1 should see no regressions. In
    theory we do everything a 4.1 server is required to do. Patches
    for a couple minor exceptions are ready for 3.11, and with those
    and some more testing I'd like to turn 4.1 on by default in 3.11."

    Fix up semantic conflict as per Stephen Rothwell and linux-next:

    Commit 030d794bf498 ("SUNRPC: Use gssproxy upcall for server RPCGSS
    authentication") adds two new users of "PDE(inode)->data", but we're
    supposed to use "PDE_DATA(inode)" instead since commit d9dda78bad87
    ("procfs: new helper - PDE_DATA(inode)").

    The old PDE() macro is no longer available since commit c30480b92cf4
    ("proc: Make the PROC_I() and PDE() macros internal to procfs")

    * 'for-3.10' of git://linux-nfs.org/~bfields/linux: (60 commits)
    NFSD: SECINFO doesn't handle unsupported pseudoflavors correctly
    NFSD: Simplify GSS flavor encoding in nfsd4_do_encode_secinfo()
    nfsd: make symbol nfsd_reply_cache_shrinker static
    svcauth_gss: fix error return code in rsc_parse()
    nfsd4: don't remap EISDIR errors in rename
    svcrpc: fix gss-proxy to respect user namespaces
    SUNRPC: gssp_procedures[] can be static
    SUNRPC: define {create,destroy}_use_gss_proxy_proc_entry in !PROC case
    nfsd4: better error return to indicate SSV non-support
    nfsd: fix EXDEV checking in rename
    SUNRPC: Use gssproxy upcall for server RPCGSS authentication.
    SUNRPC: Add RPC based upcall mechanism for RPCGSS auth
    SUNRPC: conditionally return endtime from import_sec_context
    SUNRPC: allow disabling idle timeout
    SUNRPC: attempt AF_LOCAL connect on setup
    nfsd: Decode and send 64bit time values
    nfsd4: put_client_renew_locked can be static
    nfsd4: remove unused macro
    nfsd4: remove some useless code
    nfsd4: implement SEQ4_STATUS_RECALLABLE_STATE_REVOKED
    ...

    Linus Torvalds
     

02 May, 2013

1 commit

  • Pull VFS updates from Al Viro,

    Misc cleanups all over the place, mainly wrt /proc interfaces (switch
    create_proc_entry to proc_create(), get rid of the deprecated
    create_proc_read_entry() in favor of using proc_create_data() and
    seq_file etc).

    7kloc removed.

    * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (204 commits)
    don't bother with deferred freeing of fdtables
    proc: Move non-public stuff from linux/proc_fs.h to fs/proc/internal.h
    proc: Make the PROC_I() and PDE() macros internal to procfs
    proc: Supply a function to remove a proc entry by PDE
    take cgroup_open() and cpuset_open() to fs/proc/base.c
    ppc: Clean up scanlog
    ppc: Clean up rtas_flash driver somewhat
    hostap: proc: Use remove_proc_subtree()
    drm: proc: Use remove_proc_subtree()
    drm: proc: Use minor->index to label things, not PDE->name
    drm: Constify drm_proc_list[]
    zoran: Don't print proc_dir_entry data in debug
    reiserfs: Don't access the proc_dir_entry in r_open(), r_start() r_show()
    proc: Supply an accessor for getting the data from a PDE's parent
    airo: Use remove_proc_subtree()
    rtl8192u: Don't need to save device proc dir PDE
    rtl8187se: Use a dir under /proc/net/r8180/
    proc: Add proc_mkdir_data()
    proc: Move some bits from linux/proc_fs.h to linux/{of.h,signal.h,tty.h}
    proc: Move PDE_NET() to fs/proc/proc_net.c
    ...

    Linus Torvalds
     

30 Apr, 2013

1 commit


10 Apr, 2013

1 commit

  • The only part of proc_dir_entry the code outside of fs/proc
    really cares about is PDE(inode)->data. Provide a helper
    for that; static inline for now, eventually will be moved
    to fs/proc, along with the knowledge of struct proc_dir_entry
    layout.

    Signed-off-by: Al Viro

    Al Viro
     

04 Apr, 2013

1 commit


01 Mar, 2013

1 commit

  • Pull nfsd changes from J Bruce Fields:
    "Miscellaneous bugfixes, plus:

    - An overhaul of the DRC cache by Jeff Layton. The main effect is
    just to make it larger. This decreases the chances of intermittent
    errors especially in the UDP case. But we'll need to watch for any
    reports of performance regressions.

    - Containerized nfsd: with some limitations, we now support
    per-container nfs-service, thanks to extensive work from Stanislav
    Kinsbursky over the last year."

    Some notes about conflicts, since there were *two* non-data semantic
    conflicts here:

    - idr_remove_all() had been added by a memory leak fix, but has since
    become deprecated since idr_destroy() does it for us now.

    - xs_local_connect() had been added by this branch to make AF_LOCAL
    connections be synchronous, but in the meantime Trond had changed the
    calling convention in order to avoid a RCU dereference.

    There were a couple of more obvious actual source-level conflicts due to
    the hlist traversal changes and one just due to code changes next to
    each other, but those were trivial.

    * 'for-3.9' of git://linux-nfs.org/~bfields/linux: (49 commits)
    SUNRPC: make AF_LOCAL connect synchronous
    nfsd: fix compiler warning about ambiguous types in nfsd_cache_csum
    svcrpc: fix rpc server shutdown races
    svcrpc: make svc_age_temp_xprts enqueue under sv_lock
    lockd: nlmclnt_reclaim(): avoid stack overflow
    nfsd: enable NFSv4 state in containers
    nfsd: disable usermode helper client tracker in container
    nfsd: use proper net while reading "exports" file
    nfsd: containerize NFSd filesystem
    nfsd: fix comments on nfsd_cache_lookup
    SUNRPC: move cache_detail->cache_request callback call to cache_read()
    SUNRPC: remove "cache_request" argument in sunrpc_cache_pipe_upcall() function
    SUNRPC: rework cache upcall logic
    SUNRPC: introduce cache_detail->cache_request callback
    NFS: simplify and clean cache library
    NFS: use SUNRPC cache creation and destruction helper for DNS cache
    nfsd4: free_stid can be static
    nfsd: keep a checksum of the first 256 bytes of request
    sunrpc: trim off trailing checksum before returning decrypted or integrity authenticated buffer
    sunrpc: fix comment in struct xdr_buf definition
    ...

    Linus Torvalds
     

28 Feb, 2013

1 commit

  • I'm not sure why, but the hlist for each entry iterators were conceived

    list_for_each_entry(pos, head, member)

    The hlist ones were greedy and wanted an extra parameter:

    hlist_for_each_entry(tpos, pos, head, member)

    Why did they need an extra pos parameter? I'm not quite sure. Not only
    they don't really need it, it also prevents the iterator from looking
    exactly like the list iterator, which is unfortunate.

    Besides the semantic patch, there was some manual work required:

    - Fix up the actual hlist iterators in linux/list.h
    - Fix up the declaration of other iterators based on the hlist ones.
    - A very small amount of places were using the 'node' parameter, this
    was modified to use 'obj->member' instead.
    - Coccinelle didn't handle the hlist_for_each_entry_safe iterator
    properly, so those had to be fixed up manually.

    The semantic patch which is mostly the work of Peter Senna Tschudin is here:

    @@
    iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;

    type T;
    expression a,c,d,e;
    identifier b;
    statement S;
    @@

    -T b;

    [akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
    [akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
    [akpm@linux-foundation.org: checkpatch fixes]
    [akpm@linux-foundation.org: fix warnings]
    [akpm@linux-foudnation.org: redo intrusive kvm changes]
    Tested-by: Peter Senna Tschudin
    Acked-by: Paul E. McKenney
    Signed-off-by: Sasha Levin
    Cc: Wu Fengguang
    Cc: Marcelo Tosatti
    Cc: Gleb Natapov
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Sasha Levin
     

23 Feb, 2013

1 commit


15 Feb, 2013

3 commits

  • The reason to move cache_request() callback call from
    sunrpc_cache_pipe_upcall() to cache_read() is that this garantees, that cache
    access will be done userspace process context (only userspace process have
    proper root context).
    This is required for NFSd support in container: svc_export_request() (which is
    cache_request callback) calls d_path(), which, in turn, traverse dentry up to
    current->fs->root. Kernel threads always have global root, while container
    have be in "root jail" - i.e. have it's own nested root.

    Signed-off-by: Stanislav Kinsbursky
    Signed-off-by: J. Bruce Fields

    Stanislav Kinsbursky
     
  • Passing this pointer is redundant since it's stored on cache_detail structure,
    which is also passed to sunrpc_cache_pipe_upcall () function.

    Signed-off-by: Stanislav Kinsbursky
    Signed-off-by: J. Bruce Fields

    Stanislav Kinsbursky
     
  • For most of SUNRPC caches (except NFS DNS cache) cache_detail->cache_upcall is
    redundant since all that it's implementations are doing is calling
    sunrpc_cache_pipe_upcall() with proper function address argument.
    Cache request function address is now stored on cache_detail structure and
    thus all the code can be simplified.
    Now, for those cache details, which doesn't have cache_upcall callback (the
    only one, which still has is nfs_dns_resolve_template)
    sunrpc_cache_pipe_upcall will be called instead.

    Signed-off-by: Stanislav Kinsbursky
    Signed-off-by: J. Bruce Fields

    Stanislav Kinsbursky
     

24 Jan, 2013

1 commit


05 Nov, 2012

1 commit


18 Oct, 2012

1 commit

  • The buffer size in read_flush() is too small for the longest possible values
    for it. This can lead to a kernel stack corruption:

    [ 43.047329] Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: ffffffff833e64b4
    [ 43.047329]
    [ 43.049030] Pid: 6015, comm: trinity-child18 Tainted: G W 3.5.0-rc7-next-20120716-sasha #221
    [ 43.050038] Call Trace:
    [ 43.050435] [] panic+0xcd/0x1f4
    [ 43.050931] [] ? read_flush.isra.7+0xe4/0x100
    [ 43.051602] [] __stack_chk_fail+0x16/0x20
    [ 43.052206] [] read_flush.isra.7+0xe4/0x100
    [ 43.052951] [] ? read_flush_pipefs+0x30/0x30
    [ 43.053594] [] read_flush_procfs+0x2c/0x30
    [ 43.053596] [] proc_reg_read+0x9c/0xd0
    [ 43.053596] [] ? proc_reg_write+0xd0/0xd0
    [ 43.053596] [] do_loop_readv_writev+0x4b/0x90
    [ 43.053596] [] do_readv_writev+0xf6/0x1d0
    [ 43.053596] [] vfs_readv+0x3e/0x60
    [ 43.053596] [] sys_readv+0x48/0xb0
    [ 43.053596] [] system_call_fastpath+0x1a/0x1f

    Signed-off-by: Sasha Levin
    Cc: stable@kernel.org
    Signed-off-by: J. Bruce Fields

    Sasha Levin
     

22 Aug, 2012

1 commit


12 Jul, 2012

1 commit

  • Entries that are in a sunrpc cache but are not valid should be reported
    with a leading '#' so they look like a comment.
    Commit d202cce8963d9 (sunrpc: never return expired entries in sunrpc_cache_lookup)
    broke this for expired entries.

    This particularly applies to entries that have been replaced by newer entries.
    sunrpc_cache_update sets the expiry of the replaced entry to '0', but it
    remains in the cache until the next 'cache_clean'.
    The result is that if you

    echo 0 2000000000 1 0 > /proc/net/rpc/auth.unix.gid/channel

    several times, then

    cat /proc/net/rpc/auth.unix.gid/content

    It will display multiple entries for the one uid, which is at least confusing:

    #uid cnt: gids...
    0 1: 0
    0 1: 0
    0 1: 0

    With this patch, expired entries are marked as comments so you get

    #uid cnt: gids...
    0 1: 0
    # 0 1: 0
    # 0 1: 0

    These expired entries will never be seen by cache_check() as they are always
    *after* a non-expired entry with the same key - so the extra check is only
    needed in c_show()

    Signed-off-by: NeilBrown

    --
    It's not a big problem, but it had me confused for a while, so it could
    well confuse others.
    Thanks,
    NeilBrown
    Signed-off-by: J. Bruce Fields

    NeilBrown
     

16 Apr, 2012

1 commit


26 Mar, 2012

1 commit


04 Feb, 2012

1 commit


01 Feb, 2012

3 commits


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