Skip to contentSkip to conversation

5.10.220-rc1 review

PATCH In review Greg Kroah-Hartman 14 participants 802 messages Jun 18, 2024 – Jul 24, 2024 Page 1 of 8

Subsystems (7)
lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 5.10.220-rc1 review

This is the start of the stable review cycle for the 5.10.220 release. There are 770 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Thu, 20 Jun 2024 12:32:00 +0000. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

	https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.10.220-rc1.gz

or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.10.y
and the diffstat can be found below.

thanks,

greg k-h

-------------
Pseudo-Shortlog of commits:

Greg Kroah-Hartman <[email protected]>

    Linux 5.10.220-rc1

Trond Myklebust <[email protected]>
nfsd: Fix a regression in nfsd_setattr()

NeilBrown <[email protected]>
nfsd: don't call locks_release_private() twice concurrently

NeilBrown <[email protected]>
nfsd: don't take fi_lock in nfsd_break_deleg_cb()

NeilBrown <[email protected]>
nfsd: fix RELEASE_LOCKOWNER

Jeff Layton <[email protected]>
nfsd: drop the nfsd_put helper

NeilBrown <[email protected]>
nfsd: call nfsd_last_thread() before final nfsd_put()

NeilBrown <[email protected]>
NFSD: fix possible oops when nfsd/pool_stats is closed.

Chuck Lever <[email protected]>
Documentation: Add missing documentation for EXPORT_OP flags

NeilBrown <[email protected]>
nfsd: separate nfsd_last_thread() from nfsd_put()

NeilBrown <[email protected]>
nfsd: Simplify code around svc_exit_thread() call in nfsd()

Chuck Lever <[email protected]>
nfsd: don't allow nfsd threads to be signalled.

Tavian Barnes <[email protected]>
nfsd: Fix creation time serialization order

Chuck Lever <[email protected]>
NFSD: Add an nfsd4_encode_nfstime4() helper

NeilBrown <[email protected]>
lockd: drop inappropriate svc_get() from locked_get()

Dan Carpenter <[email protected]>
nfsd: fix double fget() bug in __write_ports_addfd()

Jeff Layton <[email protected]>
nfsd: make a copy of struct iattr before calling notify_change

Dai Ngo <[email protected]>
NFSD: Fix problem of COMMIT and NFS4ERR_DELAY in infinite loop

Jeff Layton <[email protected]>
nfsd: simplify the delayed disposal list code

Chuck Lever <[email protected]>
NFSD: Convert filecache to rhltable

Jeff Layton <[email protected]>
nfsd: allow reaping files still under writeback

Jeff Layton <[email protected]>
nfsd: update comment over __nfsd_file_cache_purge

Jeff Layton <[email protected]>
nfsd: don't take/put an extra reference when putting a file

Jeff Layton <[email protected]>
nfsd: add some comments to nfsd_file_do_acquire

Jeff Layton <[email protected]>
nfsd: don't kill nfsd_files because of lease break error

Jeff Layton <[email protected]>
nfsd: simplify test_bit return in NFSD_FILE_KEY_FULL comparator

Jeff Layton <[email protected]>
nfsd: NFSD_FILE_KEY_INODE only needs to find GC'ed entries

Jeff Layton <[email protected]>
nfsd: don't open-code clear_and_wake_up_bit

Jeff Layton <[email protected]>
nfsd: call op_release, even when op_func returns an error

Chuck Lever <[email protected]>

    NFSD: Avoid calling OPDESC() with ops->opnum == OP_ILLEGAL

Jeff Layton <[email protected]>
nfsd: don't replace page in rq_pages if it's a continuation of last page

Jeff Layton <[email protected]>
lockd: set file_lock start and end when decoding nlm4 testargs

Chuck Lever <[email protected]>
NFSD: Protect against filesystem freezing

Chuck Lever <[email protected]>
NFSD: copy the whole verifier in nfsd_copy_write_verifier

Jeff Layton <[email protected]>
nfsd: don't fsync nfsd_files on last close

Jeff Layton <[email protected]>
nfsd: fix courtesy client with deny mode handling in nfs4_upgrade_open

Dai Ngo <[email protected]>
NFSD: fix problems with cleanup on errors in nfsd4_copy

Jeff Layton <[email protected]>
nfsd: don't hand out delegation on setuid files being opened for write

Dai Ngo <[email protected]>
NFSD: fix leaked reference count of nfsd4_ssc_umount_item

Jeff Layton <[email protected]>
nfsd: clean up potential nfsd_file refcount leaks in COPY codepath

Jeff Layton <[email protected]>
nfsd: allow nfsd_file_get to sanely handle a NULL pointer

Dai Ngo <[email protected]>
NFSD: enhance inter-server copy cleanup

Jeff Layton <[email protected]>
nfsd: don't destroy global nfs4_file table in per-net shutdown

Jeff Layton <[email protected]>
nfsd: don't free files unconditionally in __nfsd_file_cache_purge

Dai Ngo <[email protected]>
NFSD: replace delayed_work with work_struct for nfsd_client_shrinker

Dai Ngo <[email protected]>
NFSD: register/unregister of nfsd-client shrinker at nfsd startup/shutdown time

Xingyuan Mo <[email protected]>
NFSD: fix use-after-free in nfsd4_ssc_setup_dul()

Chuck Lever <[email protected]>
NFSD: Use set_bit(RQ_DROPME)

Chuck Lever <[email protected]>
Revert "SUNRPC: Use RMW bitops in single-threaded hot paths"

Jeff Layton <[email protected]>
nfsd: fix handling of cached open files in nfsd4_open codepath

Jeff Layton <[email protected]>
nfsd: rework refcounting in filecache

Kees Cook <[email protected]>
NFSD: Avoid clashing function prototypes

Chuck Lever <[email protected]>
NFSD: Use only RQ_DROPME to signal the need to drop a reply

Dai Ngo <[email protected]>
NFSD: add delegation reaper to react to low memory condition

Dai Ngo <[email protected]>
NFSD: add support for sending CB_RECALL_ANY

Dai Ngo <[email protected]>
NFSD: refactoring courtesy_client_reaper to a generic low memory shrinker

Brian Foster <[email protected]>
NFSD: pass range end to vfs_fsync_range() instead of count

Jeff Layton <[email protected]>
lockd: fix file selection in nlmsvc_cancel_blocked

Jeff Layton <[email protected]>
lockd: ensure we use the correct file descriptor when unlocking

Jeff Layton <[email protected]>
lockd: set missing fl_flags field when retrieving args

Xiu Jianfeng <[email protected]>
NFSD: Use struct_size() helper in alloc_session()

Jeff Layton <[email protected]>
nfsd: return error if nfs4_setacl fails

Trond Myklebust <[email protected]>
lockd: set other missing fields when unlocking files

Chuck Lever <[email protected]>
NFSD: Add an nfsd_file_fsync tracepoint

Jeff Layton <[email protected]>
nfsd: fix up the filecache laundrette scheduling

Jeff Layton <[email protected]>
nfsd: reorganize filecache.c

Jeff Layton <[email protected]>
nfsd: remove the pages_flushed statistic from filecache

Chuck Lever <[email protected]>
NFSD: Fix licensing header in filecache.c

Chuck Lever <[email protected]>
NFSD: Use rhashtable for managing nfs4_file objects

Chuck Lever <[email protected]>
NFSD: Refactor find_file()

Chuck Lever <[email protected]>
NFSD: Clean up find_or_add_file()

Chuck Lever <[email protected]>
NFSD: Add a nfsd4_file_hash_remove() helper

Chuck Lever <[email protected]>
NFSD: Clean up nfsd4_init_file()

Chuck Lever <[email protected]>
NFSD: Update file_hashtbl() helpers

Chuck Lever <[email protected]>
NFSD: Use const pointers as parameters to fh_ helpers

Chuck Lever <[email protected]>
NFSD: Trace delegation revocations

Chuck Lever <[email protected]>
NFSD: Trace stateids returned via DELEGRETURN

Chuck Lever <[email protected]>
NFSD: Clean up nfs4_preprocess_stateid_op() call sites

Chuck Lever <[email protected]>
NFSD: Flesh out a documenting comment for filecache.c

Chuck Lever <[email protected]>
NFSD: Add an NFSD_FILE_GC flag to enable nfsd_file garbage collection

Chuck Lever <[email protected]>
NFSD: Revert "NFSD: NFSv4 CLOSE should release an nfsd_file immediately"

Chuck Lever <[email protected]>
NFSD: Pass the target nfsd_file to nfsd_commit()

David Disseldorp <[email protected]>
exportfs: use pr_debug for unreachable debug statements

Jeff Layton <[email protected]>
nfsd: allow disabling NFSv2 at compile time

Jeff Layton <[email protected]>
nfsd: move nfserrno() to vfs.c

Jeff Layton <[email protected]>
nfsd: ignore requests to disable unsupported versions

Chuck Lever <[email protected]>
NFSD: Finish converting the NFSv3 GETACL result encoder

Chuck Lever <[email protected]>
NFSD: Finish converting the NFSv2 GETACL result encoder

Colin Ian King <[email protected]>
NFSD: Remove redundant assignment to variable host_err

Anna Schumaker <[email protected]>
NFSD: Simplify READ_PLUS

Jeff Layton <[email protected]>
nfsd: use locks_inode_context helper

Jeff Layton <[email protected]>
lockd: use locks_inode_context helper

Jeff Layton <[email protected]>
filelock: add a new locks_inode_context accessor function

Chuck Lever <[email protected]>
NFSD: Fix reads with a non-zero offset that don't end on a page boundary

Jeff Layton <[email protected]>
nfsd: put the export reference in nfsd4_verify_deleg_dentry

Jeff Layton <[email protected]>
nfsd: fix use-after-free in nfsd_file_do_acquire tracepoint

Jeff Layton <[email protected]>
nfsd: fix net-namespace logic in __nfsd_file_cache_purge

Tetsuo Handa <[email protected]>
NFSD: unregister shrinker when nfsd_init_net() fails

Jeff Layton <[email protected]>
nfsd: rework hashtable handling in nfsd_do_file_acquire

Jeff Layton <[email protected]>
nfsd: fix nfsd_file_unhash_and_dispose

Gaosheng Cui <[email protected]>
fanotify: Remove obsoleted fanotify_event_has_path()

Gaosheng Cui <[email protected]>
fsnotify: remove unused declaration

Al Viro <[email protected]>
fs/notify: constify path

Jeff Layton <[email protected]>
nfsd: extra checks when freeing delegation stateids

Jeff Layton <[email protected]>
nfsd: make nfsd4_run_cb a bool return function

Jeff Layton <[email protected]>
nfsd: fix comments about spinlock handling with delegations

Jeff Layton <[email protected]>
nfsd: only fill out return pointer on success in nfsd4_lookup_stateid

Chuck Lever <[email protected]>
NFSD: Cap rsize_bop result based on send buffer size

Chuck Lever <[email protected]>
NFSD: Rename the fields in copy_stateid_t

ChenXiaoSong <[email protected]>
nfsd: use DEFINE_SHOW_ATTRIBUTE to define nfsd_file_cache_stats_fops

ChenXiaoSong <[email protected]>
nfsd: use DEFINE_SHOW_ATTRIBUTE to define nfsd_reply_cache_stats_fops

ChenXiaoSong <[email protected]>
nfsd: use DEFINE_SHOW_ATTRIBUTE to define client_info_fops

ChenXiaoSong <[email protected]>
nfsd: use DEFINE_SHOW_ATTRIBUTE to define export_features_fops and supported_enctypes_fops

ChenXiaoSong <[email protected]>
nfsd: use DEFINE_PROC_SHOW_ATTRIBUTE to define nfsd_proc_ops

Chuck Lever <[email protected]>
NFSD: Pack struct nfsd4_compoundres

Chuck Lever <[email protected]>
NFSD: Remove unused nfsd4_compoundargs::cachetype field

Chuck Lever <[email protected]>
NFSD: Remove "inline" directives on op_rsize_bop helpers

Chuck Lever <[email protected]>
NFSD: Clean up nfs4svc_encode_compoundres()

Chuck Lever <[email protected]>
NFSD: Clean up WRITE arg decoders

Chuck Lever <[email protected]>
NFSD: Use xdr_inline_decode() to decode NFSv3 symlinks

Chuck Lever <[email protected]>
NFSD: Refactor common code out of dirlist helpers

Chuck Lever <[email protected]>
NFSD: Reduce amount of struct nfsd4_compoundargs that needs clearing

Chuck Lever <[email protected]>
SUNRPC: Parametrize how much of argsize should be zeroed

Dai Ngo <[email protected]>
NFSD: add shrinker to reap courtesy clients on low memory condition

Dai Ngo <[email protected]>
NFSD: keep track of the number of courtesy clients in the system

Chuck Lever <[email protected]>
NFSD: Make nfsd4_remove() wait before returning NFS4ERR_DELAY

Chuck Lever <[email protected]>
NFSD: Make nfsd4_rename() wait before returning NFS4ERR_DELAY

Chuck Lever <[email protected]>
NFSD: Make nfsd4_setattr() wait before returning NFS4ERR_DELAY

Chuck Lever <[email protected]>
NFSD: Refactor nfsd_setattr()

Chuck Lever <[email protected]>
NFSD: Add a mechanism to wait for a DELEGRETURN

Chuck Lever <[email protected]>
NFSD: Add tracepoints to report NFSv4 callback completions

Gaosheng Cui <[email protected]>
nfsd: remove nfsd4_prepare_cb_recall() declaration

Jeff Layton <[email protected]>
nfsd: clean up mounted_on_fileid handling

Chuck Lever <[email protected]>
NFSD: Fix handling of oversized NFSv4 COMPOUND requests

NeilBrown <[email protected]>
NFSD: drop fname and flen args from nfsd_create_locked()

Chuck Lever <[email protected]>
NFSD: Protect against send buffer overflow in NFSv3 READ

Chuck Lever <[email protected]>
NFSD: Protect against send buffer overflow in NFSv2 READ

Chuck Lever <[email protected]>
NFSD: Protect against send buffer overflow in NFSv3 READDIR

Chuck Lever <[email protected]>
NFSD: Protect against send buffer overflow in NFSv2 READDIR

Chuck Lever <[email protected]>
NFSD: Increase NFSD_MAX_OPS_PER_COMPOUND

Christophe JAILLET <[email protected]>
nfsd: Propagate some error code returned by memdup_user()

Christophe JAILLET <[email protected]>
nfsd: Avoid some useless tests

Jinpeng Cui <[email protected]>
NFSD: remove redundant variable status

Olga Kornievskaia <[email protected]>
NFSD enforce filehandle check for source file in COPY

Wolfram Sang <[email protected]>
lockd: move from strlcpy with unused retval to strscpy

Wolfram Sang <[email protected]>
NFSD: move from strlcpy with unused retval to strscpy

Al Viro <[email protected]>
nfsd_splice_actor(): handle compound pages

NeilBrown <[email protected]>
NFSD: fix regression with setting ACLs.

Jeff Layton <[email protected]>
lockd: detect and reject lock arguments that overflow

NeilBrown <[email protected]>
NFSD: discard fh_locked flag and fh_lock/fh_unlock

NeilBrown <[email protected]>
NFSD: use (un)lock_inode instead of fh_(un)lock for file operations

NeilBrown <[email protected]>
NFSD: use explicit lock/unlock for directory ops

NeilBrown <[email protected]>
NFSD: reduce locking in nfsd_lookup()

NeilBrown <[email protected]>
NFSD: only call fh_unlock() once in nfsd_link()

NeilBrown <[email protected]>
NFSD: always drop directory lock in nfsd_unlink()

NeilBrown <[email protected]>
NFSD: change nfsd_create()/nfsd_symlink() to unlock directory before returning.

NeilBrown <[email protected]>
NFSD: add posix ACLs to struct nfsd_attrs

NeilBrown <[email protected]>
NFSD: add security label to struct nfsd_attrs

NeilBrown <[email protected]>
NFSD: set attributes when creating symlinks

NeilBrown <[email protected]>
NFSD: introduce struct nfsd_attrs

Jeff Layton <[email protected]>
NFSD: verify the opened dentry after setting a delegation

Jeff Layton <[email protected]>
NFSD: drop fh argument from alloc_init_deleg

Chuck Lever <[email protected]>
NFSD: Move copy offload callback arguments into a separate structure

Chuck Lever <[email protected]>
NFSD: Add nfsd4_send_cb_offload()

Chuck Lever <[email protected]>
NFSD: Remove kmalloc from nfsd4_do_async_copy()

Chuck Lever <[email protected]>
NFSD: Refactor nfsd4_do_copy()

Chuck Lever <[email protected]>

    NFSD: Refactor nfsd4_cleanup_inter_ssc() (2/2)

Chuck Lever <[email protected]>

    NFSD: Refactor nfsd4_cleanup_inter_ssc() (1/2)

Chuck Lever <[email protected]>
NFSD: Replace boolean fields in struct nfsd4_copy

Chuck Lever <[email protected]>
NFSD: Make nfs4_put_copy() static

Chuck Lever <[email protected]>
NFSD: Reorder the fields in struct nfsd4_op

Chuck Lever <[email protected]>
NFSD: Shrink size of struct nfsd4_copy

Chuck Lever <[email protected]>
NFSD: Shrink size of struct nfsd4_copy_notify

Chuck Lever <[email protected]>
NFSD: nfserrno(-ENOMEM) is nfserr_jukebox

Chuck Lever <[email protected]>
NFSD: Fix strncpy() fortify warning

Chuck Lever <[email protected]>
NFSD: Clean up nfsd4_encode_readlink()

Chuck Lever <[email protected]>
NFSD: Use xdr_pad_size()

Chuck Lever <[email protected]>
NFSD: Simplify starting_len

Chuck Lever <[email protected]>
NFSD: Optimize nfsd4_encode_readv()

Chuck Lever <[email protected]>
NFSD: Add an nfsd4_read::rd_eof field

Chuck Lever <[email protected]>
NFSD: Clean up SPLICE_OK in nfsd4_encode_read()

Chuck Lever <[email protected]>
NFSD: Optimize nfsd4_encode_fattr()

Chuck Lever <[email protected]>
NFSD: Optimize nfsd4_encode_operation()

Jeff Layton <[email protected]>
nfsd: silence extraneous printk on nfsd.ko insertion

Dai Ngo <[email protected]>
NFSD: limit the number of v4 clients to 1024 per 1GB of system memory

Dai Ngo <[email protected]>
NFSD: keep track of the number of v4 clients in the system

Dai Ngo <[email protected]>
NFSD: refactoring v4 specific code to a helper in nfs4state.c

Chuck Lever <[email protected]>
NFSD: Ensure nf_inode is never dereferenced

Chuck Lever <[email protected]>
NFSD: NFSv4 CLOSE should release an nfsd_file immediately

Chuck Lever <[email protected]>
NFSD: Move nfsd_file_trace_alloc() tracepoint

Chuck Lever <[email protected]>
NFSD: Separate tracepoints for acquire and create

Chuck Lever <[email protected]>
NFSD: Clean up unused code after rhashtable conversion

Chuck Lever <[email protected]>
NFSD: Convert the filecache to use rhashtable

Chuck Lever <[email protected]>
NFSD: Set up an rhashtable for the filecache

Chuck Lever <[email protected]>
NFSD: Replace the "init once" mechanism

Chuck Lever <[email protected]>
NFSD: Remove nfsd_file::nf_hashval

Chuck Lever <[email protected]>
NFSD: nfsd_file_hash_remove can compute hashval

Chuck Lever <[email protected]>
NFSD: Refactor __nfsd_file_close_inode()

Chuck Lever <[email protected]>

    NFSD: nfsd_file_unhash can compute hashval from nf->nf_inode

Chuck Lever <[email protected]>
NFSD: Remove lockdep assertion from unhash_and_release_locked()

Chuck Lever <[email protected]>
NFSD: No longer record nf_hashval in the trace log

Chuck Lever <[email protected]>
NFSD: Never call nfsd_file_gc() in foreground paths

Chuck Lever <[email protected]>
NFSD: Fix the filecache LRU shrinker

Chuck Lever <[email protected]>
NFSD: Leave open files out of the filecache LRU

Chuck Lever <[email protected]>
NFSD: Trace filecache LRU activity

Chuck Lever <[email protected]>
NFSD: WARN when freeing an item still linked via nf_lru

Chuck Lever <[email protected]>
NFSD: Hook up the filecache stat file

Chuck Lever <[email protected]>
NFSD: Zero counters when the filecache is re-initialized

Chuck Lever <[email protected]>
NFSD: Record number of flush calls

Chuck Lever <[email protected]>
NFSD: Report the number of items evicted by the LRU walk

Chuck Lever <[email protected]>
NFSD: Refactor nfsd_file_lru_scan()

Chuck Lever <[email protected]>
NFSD: Refactor nfsd_file_gc()

Chuck Lever <[email protected]>
NFSD: Add nfsd_file_lru_dispose_list() helper

Chuck Lever <[email protected]>
NFSD: Report average age of filecache items

Chuck Lever <[email protected]>
NFSD: Report count of freed filecache items

Chuck Lever <[email protected]>
NFSD: Report count of calls to nfsd_file_acquire()

Chuck Lever <[email protected]>
NFSD: Report filecache LRU size

Chuck Lever <[email protected]>
NFSD: Demote a WARN to a pr_warn()

Colin Ian King <[email protected]>
nfsd: remove redundant assignment to variable len

Zhang Jiaming <[email protected]>
NFSD: Fix space and spelling mistake

Benjamin Coddington <[email protected]>
NLM: Defend against file_lock changes after vfs_test_lock()

Chuck Lever <[email protected]>
SUNRPC: Fix xdr_encode_bool()

Jeff Layton <[email protected]>
nfsd: eliminate the NFSD_FILE_BREAK_* flags

Xin Gao <[email protected]>
fsnotify: Fix comment typo

Amir Goldstein <[email protected]>
fanotify: introduce FAN_MARK_IGNORE

Amir Goldstein <[email protected]>
fanotify: cleanups for fanotify_mark() input validations

Amir Goldstein <[email protected]>
fanotify: prepare for setting event flags in ignore mask

Oliver Ford <[email protected]>
fs: inotify: Fix typo in inotify comment

Jeff Layton <[email protected]>
lockd: fix nlm_close_files

Jeff Layton <[email protected]>
lockd: set fl_owner when unlocking files

Chuck Lever <[email protected]>
NFSD: Decode NFSv4 birth time attribute

NeilBrown <[email protected]>
NFS: restore module put when manager exits.

Amir Goldstein <[email protected]>
fanotify: refine the validation checks on non-dir inode mask

Chuck Lever <[email protected]>
SUNRPC: Optimize xdr_reserve_space()

Chuck Lever <[email protected]>
NFSD: Fix potential use-after-free in nfsd_file_put()

Chuck Lever <[email protected]>
NFSD: nfsd_file_put() can sleep

Chuck Lever <[email protected]>
NFSD: Add documenting comment for nfsd4_release_lockowner()

Chuck Lever <[email protected]>
NFSD: Modernize nfsd4_release_lockowner()

Julian Schroeder <[email protected]>
nfsd: destroy percpu stats counters after reply cache shutdown

Zhang Xiaoxu <[email protected]>
nfsd: Fix null-ptr-deref in nfsd_fill_super()

Zhang Xiaoxu <[email protected]>
nfsd: Unregister the cld notifier when laundry_wq create failed

Chuck Lever <[email protected]>
SUNRPC: Use RMW bitops in single-threaded hot paths

Chuck Lever <[email protected]>
NFSD: Clean up the show_nf_flags() macro

Chuck Lever <[email protected]>
NFSD: Trace filecache opens

Chuck Lever <[email protected]>
NFSD: Move documenting comment for nfsd4_process_open2()

Chuck Lever <[email protected]>
NFSD: Fix whitespace

Chuck Lever <[email protected]>
NFSD: Remove dprintk call sites from tail of nfsd4_open()

Chuck Lever <[email protected]>
NFSD: Instantiate a struct file when creating a regular NFSv4 file

Chuck Lever <[email protected]>
NFSD: Clean up nfsd_open_verified()

Chuck Lever <[email protected]>
NFSD: Remove do_nfsd_create()

Chuck Lever <[email protected]>
NFSD: Refactor NFSv4 OPEN(CREATE)

Chuck Lever <[email protected]>
NFSD: Refactor NFSv3 CREATE

Chuck Lever <[email protected]>
NFSD: Refactor nfsd_create_setattr()

Chuck Lever <[email protected]>
NFSD: Avoid calling fh_drop_write() twice in do_nfsd_create()

Chuck Lever <[email protected]>
NFSD: Clean up nfsd3_proc_create()

Dai Ngo <[email protected]>
NFSD: Show state of courtesy client in client info

Dai Ngo <[email protected]>
NFSD: add support for lock conflict to courteous server

Dai Ngo <[email protected]>
fs/lock: add 2 callbacks to lock_manager_operations to resolve conflict

Dai Ngo <[email protected]>
fs/lock: add helper locks_owner_has_blockers to check for blockers

Dai Ngo <[email protected]>
NFSD: move create/destroy of laundry_wq to init_nfsd and exit_nfsd

Dai Ngo <[email protected]>
NFSD: add support for share reservation conflict to courteous server

Dai Ngo <[email protected]>
NFSD: add courteous server support for thread with only delegation

Chuck Lever <[email protected]>
NFSD: Clean up nfsd_splice_actor()

Vasily Averin <[email protected]>
fanotify: fix incorrect fmode_t casts

Amir Goldstein <[email protected]>
fsnotify: consistent behavior for parent not watching children

Amir Goldstein <[email protected]>
fsnotify: introduce mark type iterator

Amir Goldstein <[email protected]>
fanotify: enable "evictable" inode marks

Amir Goldstein <[email protected]>
fanotify: use fsnotify group lock helpers

Amir Goldstein <[email protected]>
fanotify: implement "evictable" inode marks

Amir Goldstein <[email protected]>
fanotify: factor out helper fanotify_mark_update_flags()

Amir Goldstein <[email protected]>
fanotify: create helper fanotify_mark_user_flags()

Amir Goldstein <[email protected]>
fsnotify: allow adding an inode mark without pinning inode

Amir Goldstein <[email protected]>
dnotify: use fsnotify group lock helpers

Amir Goldstein <[email protected]>
nfsd: use fsnotify group lock helpers

Amir Goldstein <[email protected]>
inotify: use fsnotify group lock helpers

Amir Goldstein <[email protected]>
fsnotify: create helpers for group mark_mutex lock

Amir Goldstein <[email protected]>
fsnotify: make allow_dups a property of the group

Amir Goldstein <[email protected]>
fsnotify: pass flags argument to fsnotify_alloc_group()

Amir Goldstein <[email protected]>
inotify: move control flags from mask to mark flags

Dai Ngo <[email protected]>

    fs/lock: documentation cleanup. Replace inode->i_lock with flc_lock.

Amir Goldstein <[email protected]>
fanotify: do not allow setting dirent events in mask of non-dir

Trond Myklebust <[email protected]>
nfsd: Clean up nfsd_file_put()

Trond Myklebust <[email protected]>
nfsd: Fix a write performance regression

Haowen Bai <[email protected]>
SUNRPC: Return true/false (not 1/0) from bool functions

Bang Li <[email protected]>
fsnotify: remove redundant parameter judgment

Amir Goldstein <[email protected]>
fsnotify: optimize FS_MODIFY events with no ignored masks

Amir Goldstein <[email protected]>
fsnotify: fix merge with parent's ignored mask

Jakob Koschel <[email protected]>
nfsd: fix using the correct variable for sizeof()

Chuck Lever <[email protected]>
NFSD: Clean up _lm_ operation names

Chuck Lever <[email protected]>
NFSD: Remove CONFIG_NFSD_V3

Chuck Lever <[email protected]>
NFSD: Move svc_serv_ops::svo_function into struct svc_serv

Chuck Lever <[email protected]>
NFSD: Remove svc_serv_ops::svo_module

Chuck Lever <[email protected]>
SUNRPC: Remove svc_shutdown_net()

Chuck Lever <[email protected]>
SUNRPC: Rename svc_close_xprt()

Chuck Lever <[email protected]>
SUNRPC: Rename svc_create_xprt()

Chuck Lever <[email protected]>
SUNRPC: Remove svo_shutdown method

Chuck Lever <[email protected]>
SUNRPC: Merge svc_do_enqueue_xprt() into svc_enqueue_xprt()

Chuck Lever <[email protected]>
SUNRPC: Remove the .svo_enqueue_xprt method

Chuck Lever <[email protected]>
NFSD: Streamline the rare "found" case

Chuck Lever <[email protected]>
NFSD: Skip extra computation for RC_NOCACHE case

Chuck Lever <[email protected]>
NFSD: De-duplicate hash bucket indexing

Ondrej Valousek <[email protected]>
nfsd: Add support for the birth time attribute

Chuck Lever <[email protected]>
NFSD: Deprecate NFS_OFFSET_MAX

Chuck Lever <[email protected]>
NFSD: COMMIT operations must not return NFS?ERR_INVAL

Chuck Lever <[email protected]>
NFSD: Fix NFSv3 SETATTR/CREATE's handling of large file sizes

Chuck Lever <[email protected]>
NFSD: Fix ia_size underflow

Chuck Lever <[email protected]>
NFSD: Fix the behavior of READ near OFFSET_MAX

J. Bruce Fields <[email protected]>
lockd: fix failure to cleanup client locks

J. Bruce Fields <[email protected]>
lockd: fix server crash on reboot of client holding lock

Yang Li <[email protected]>
fanotify: remove variable set but not used

J. Bruce Fields <[email protected]>
nfsd: fix crash on COPY_NOTIFY with special stateid

Chuck Lever <[email protected]>
NFSD: Move fill_pre_wcc() and fill_post_wcc()

Chuck Lever <[email protected]>
Revert "nfsd: skip some unnecessary stats in the v4 case"

Chuck Lever <[email protected]>
NFSD: Trace boot verifier resets

Chuck Lever <[email protected]>
NFSD: Rename boot verifier functions

Chuck Lever <[email protected]>
NFSD: Clean up the nfsd_net::nfssvc_boot field

Chuck Lever <[email protected]>
NFSD: Write verifier might go backwards

Trond Myklebust <[email protected]>
nfsd: Add a tracepoint for errors in nfsd4_clone_file_range()

Chuck Lever <[email protected]>

    NFSD: De-duplicate net_generic(nf->nf_net, nfsd_net_id)

Chuck Lever <[email protected]>
NFSD: De-duplicate net_generic(SVC_NET(rqstp), nfsd_net_id)

Chuck Lever <[email protected]>
NFSD: Clean up nfsd_vfs_write()

Jeff Layton <[email protected]>
nfsd: Retry once in nfsd_open on an -EOPENSTALE return

Jeff Layton <[email protected]>
nfsd: Add errno mapping for EREMOTEIO

Peng Tao <[email protected]>
nfsd: map EBADF

Chuck Lever <[email protected]>
NFSD: Fix zero-length NFSv3 WRITEs

Vasily Averin <[email protected]>
nfsd4: add refcount for nfsd4_blocked_lock

J. Bruce Fields <[email protected]>

    nfs: block notification on fs with its own ->lock

Chuck Lever <[email protected]>
NFSD: De-duplicate nfsd4_decode_bitmap4()

J. Bruce Fields <[email protected]>
nfsd: improve stateid access bitmask documentation

Chuck Lever <[email protected]>
NFSD: Combine XDR error tracepoints

NeilBrown <[email protected]>
NFSD: simplify per-net file cache management

Jiapeng Chong <[email protected]>
NFSD: Fix inconsistent indenting

Chuck Lever <[email protected]>
NFSD: Remove be32_to_cpu() from DRC hash function

NeilBrown <[email protected]>
NFS: switch the callback service back to non-pooled.

NeilBrown <[email protected]>
lockd: use svc_set_num_threads() for thread start and stop

NeilBrown <[email protected]>

    SUNRPC: always treat sv_nrpools==1 as "not pooled"

NeilBrown <[email protected]>
SUNRPC: move the pool_map definitions (back) into svc.c

NeilBrown <[email protected]>
lockd: rename lockd_create_svc() to lockd_get()

NeilBrown <[email protected]>
lockd: introduce lockd_put()

NeilBrown <[email protected]>
lockd: move svc_exit_thread() into the thread

NeilBrown <[email protected]>
lockd: move lockd_start_svc() call into lockd_create_svc()

NeilBrown <[email protected]>
lockd: simplify management of network status notifiers

NeilBrown <[email protected]>
lockd: introduce nlmsvc_serv

NeilBrown <[email protected]>
NFSD: simplify locking for network notifier.

NeilBrown <[email protected]>
SUNRPC: discard svo_setup and rename svc_set_num_threads_sync()

NeilBrown <[email protected]>
NFSD: Make it possible to use svc_set_num_threads_sync

NeilBrown <[email protected]>
NFSD: narrow nfsd_mutex protection in nfsd thread

NeilBrown <[email protected]>
SUNRPC: use sv_lock to protect updates to sv_nrthreads.

NeilBrown <[email protected]>
nfsd: make nfsd_stats.th_cnt atomic_t

NeilBrown <[email protected]>

    SUNRPC: stop using ->sv_nrthreads as a refcount

NeilBrown <[email protected]>
SUNRPC/NFSD: clean up get/put functions.

NeilBrown <[email protected]>
SUNRPC: change svc_get() to return the svc.

NeilBrown <[email protected]>
NFSD: handle errors better in write_ports_addfd()

Chuck Lever <[email protected]>
NFSD: Fix sparse warning

Eric W. Biederman <[email protected]>
exit: Rename module_put_and_exit to module_put_and_kthread_exit

Eric W. Biederman <[email protected]>
exit: Implement kthread_exit

Amir Goldstein <[email protected]>
fanotify: wire up FAN_RENAME event

Amir Goldstein <[email protected]>
fanotify: report old and/or new parent+name in FAN_RENAME event

Amir Goldstein <[email protected]>
fanotify: record either old name new name or both for FAN_RENAME

Amir Goldstein <[email protected]>
fanotify: record old and new parent and name in FAN_RENAME event

Amir Goldstein <[email protected]>
fanotify: support secondary dir fh and name in fanotify_info

Amir Goldstein <[email protected]>
fanotify: use helpers to parcel fanotify_info buffer

Amir Goldstein <[email protected]>
fanotify: use macros to get the offset to fanotify_info buffer

Amir Goldstein <[email protected]>
fsnotify: generate FS_RENAME event with rich information

Amir Goldstein <[email protected]>
fanotify: introduce group flag FAN_REPORT_TARGET_FID

Amir Goldstein <[email protected]>
fsnotify: separate mark iterator type from object type enum

Amir Goldstein <[email protected]>
fsnotify: clarify object type argument

Chuck Lever <[email protected]>
NFSD: Fix READDIR buffer overflow

Chuck Lever <[email protected]>
NFSD: Fix exposure in nfsd4_decode_bitmap()

J. Bruce Fields <[email protected]>
nfsd4: remove obselete comment

Changcheng Deng <[email protected]>
NFSD:fix boolreturn.cocci warning

J. Bruce Fields <[email protected]>
nfsd: update create verifier comment

Chuck Lever <[email protected]>
SUNRPC: Change return value type of .pc_encode

Chuck Lever <[email protected]>
SUNRPC: Replace the "__be32 *p" parameter to .pc_encode

Chuck Lever <[email protected]>
NFSD: Save location of NFSv4 COMPOUND status

Chuck Lever <[email protected]>
SUNRPC: Change return value type of .pc_decode

Chuck Lever <[email protected]>
SUNRPC: Replace the "__be32 *p" parameter to .pc_decode

Chuck Lever <[email protected]>
NFSD: Have legacy NFSD WRITE decoders use xdr_stream_subsegment()

Colin Ian King <[email protected]>
NFSD: Initialize pointer ni with NULL and not plain integer 0

NeilBrown <[email protected]>
NFSD: simplify struct nfsfh

NeilBrown <[email protected]>
NFSD: drop support for ancient filehandles

NeilBrown <[email protected]>
NFSD: move filehandle format declarations out of "uapi".

Chuck Lever <[email protected]>
NFSD: Optimize DRC bucket pruning

Chuck Lever <[email protected]>
SUNRPC: Trace calls to .rpc_call_done

Gabriel Krisman Bertazi <[email protected]>
fanotify: Allow users to request FAN_FS_ERROR events

Gabriel Krisman Bertazi <[email protected]>
fanotify: Emit generic error info for error event

Gabriel Krisman Bertazi <[email protected]>
fanotify: Report fid info for file related file system errors

Gabriel Krisman Bertazi <[email protected]>
fanotify: WARN_ON against too large file handles

Gabriel Krisman Bertazi <[email protected]>
fanotify: Add helpers to decide whether to report FID/DFID

Gabriel Krisman Bertazi <[email protected]>
fanotify: Wrap object_fh inline space in a creator macro

Gabriel Krisman Bertazi <[email protected]>
fanotify: Support merging of error events

Gabriel Krisman Bertazi <[email protected]>
fanotify: Support enqueueing of error events

Gabriel Krisman Bertazi <[email protected]>
fanotify: Pre-allocate pool of error events

Gabriel Krisman Bertazi <[email protected]>
fanotify: Reserve UAPI bits for FAN_FS_ERROR

Gabriel Krisman Bertazi <[email protected]>
fsnotify: Support FS_ERROR event type

Gabriel Krisman Bertazi <[email protected]>
fanotify: Require fid_mode for any non-fd event

Gabriel Krisman Bertazi <[email protected]>
fanotify: Encode empty file handle when no inode is provided

Gabriel Krisman Bertazi <[email protected]>
fanotify: Allow file handle encoding for unhashed events

Gabriel Krisman Bertazi <[email protected]>
fanotify: Support null inode event in fanotify_dfid_inode

Gabriel Krisman Bertazi <[email protected]>
fsnotify: Pass group argument to free_event

Gabriel Krisman Bertazi <[email protected]>
fsnotify: Protect fsnotify_handle_inode_event from no-inode events

Gabriel Krisman Bertazi <[email protected]>
fsnotify: Retrieve super block from the data field

Gabriel Krisman Bertazi <[email protected]>
fsnotify: Add wrapper around fsnotify_add_event

Gabriel Krisman Bertazi <[email protected]>
fsnotify: Add helper to detect overflow_event

Gabriel Krisman Bertazi <[email protected]>
inotify: Don't force FS_IN_IGNORED

Gabriel Krisman Bertazi <[email protected]>
fanotify: Split fsid check from other fid mode checks

Gabriel Krisman Bertazi <[email protected]>
fanotify: Fold event size calculation to its own function

Gabriel Krisman Bertazi <[email protected]>
fsnotify: Don't insert unmergeable events in hashtable

Amir Goldstein <[email protected]>
fsnotify: clarify contract for create event hooks

Amir Goldstein <[email protected]>
fsnotify: pass dentry instead of inode data

Amir Goldstein <[email protected]>
fsnotify: pass data_type to fsnotify_name()

Trond Myklebust <[email protected]>
nfsd: Fix a warning for nfsd_file_close_inode

Chuck Lever <[email protected]>
NLM: Fix svcxdr_encode_owner()

Amir Goldstein <[email protected]>
fsnotify: fix sb_connectors leak

Chuck Lever <[email protected]>
NFS: Remove unused callback void decoder

Chuck Lever <[email protected]>
NFS: Add a private local dispatcher for NFSv4 callback operations

Chuck Lever <[email protected]>
SUNRPC: Eliminate the RQ_AUTHERR flag

Chuck Lever <[email protected]>
SUNRPC: Set rq_auth_stat in the pg_authenticate() callout

Chuck Lever <[email protected]>
SUNRPC: Add svc_rqst::rq_auth_stat

J. Bruce Fields <[email protected]>
nfs: don't allow reexport reclaims

J. Bruce Fields <[email protected]>
lockd: don't attempt blocking locks on nfs reexports

J. Bruce Fields <[email protected]>
nfs: don't atempt blocking locks on nfs reexports

J. Bruce Fields <[email protected]>
Keep read and write fds with each nlm_file

J. Bruce Fields <[email protected]>
lockd: update nlm_lookup_file reexport comment

J. Bruce Fields <[email protected]>
nlm: minor refactoring

J. Bruce Fields <[email protected]>
nlm: minor nlm_lookup_file argument change

Jia He <[email protected]>
lockd: change the proc_handler for nsm_use_hostnames

Jia He <[email protected]>
sysctl: introduce new proc handler proc_dobool

NeilBrown <[email protected]>
NFSD: remove vanity comments

Chuck Lever <[email protected]>
NFSD: Batch release pages during splice read

Chuck Lever <[email protected]>
SUNRPC: Add svc_rqst_replace_page() API

Chuck Lever <[email protected]>
NFSD: Clean up splice actor

Amir Goldstein <[email protected]>
fsnotify: optimize the case of no marks of any type

Amir Goldstein <[email protected]>
fsnotify: count all objects with attached connectors

Amir Goldstein <[email protected]>
fsnotify: count s_fsnotify_inode_refs for attached connectors

Amir Goldstein <[email protected]>
fsnotify: replace igrab() with ihold() on attach connector

Matthew Bobrowski <[email protected]>
fanotify: add pidfd support to the fanotify API

Matthew Bobrowski <[email protected]>
fanotify: introduce a generic info record copying helper

Matthew Bobrowski <[email protected]>
fanotify: minor cosmetic adjustments to fid labels

Matthew Bobrowski <[email protected]>
kernel/pid.c: implement additional checks upon pidfd_create() parameters

Matthew Bobrowski <[email protected]>
kernel/pid.c: remove static qualifier from pidfd_create()

J. Bruce Fields <[email protected]>
nfsd: fix NULL dereference in nfs3svc_encode_getaclres

Chuck Lever <[email protected]>
NFSD: Prevent a possible oops in the nfs_dirent() tracepoint

Colin Ian King <[email protected]>
nfsd: remove redundant assignment to pointer 'this'

Chuck Lever <[email protected]>
lockd: Update the NLMv4 SHARE results encoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Update the NLMv4 nlm_res results encoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Update the NLMv4 TEST results encoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Update the NLMv4 void results encoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Update the NLMv4 FREE_ALL arguments decoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Update the NLMv4 SHARE arguments decoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Update the NLMv4 SM_NOTIFY arguments decoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Update the NLMv4 nlm_res arguments decoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Update the NLMv4 UNLOCK arguments decoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Update the NLMv4 CANCEL arguments decoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Update the NLMv4 LOCK arguments decoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Update the NLMv4 TEST arguments decoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Update the NLMv4 void arguments decoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Update the NLMv1 SHARE results encoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Update the NLMv1 nlm_res results encoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Update the NLMv1 TEST results encoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Update the NLMv1 void results encoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Update the NLMv1 FREE_ALL arguments decoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Update the NLMv1 SHARE arguments decoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Update the NLMv1 SM_NOTIFY arguments decoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Update the NLMv1 nlm_res arguments decoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Update the NLMv1 UNLOCK arguments decoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Update the NLMv1 CANCEL arguments decoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Update the NLMv1 LOCK arguments decoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Update the NLMv1 TEST arguments decoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Update the NLMv1 void argument decoder to use struct xdr_stream

Chuck Lever <[email protected]>
lockd: Common NLM XDR helpers

Chuck Lever <[email protected]>
lockd: Create a simplified .vs_dispatch method for NLM requests

Chuck Lever <[email protected]>
lockd: Remove stale comments

J. Bruce Fields <[email protected]>
nfsd: rpc_peeraddr2str needs rcu lock

Wei Yongjun <[email protected]>
NFSD: Fix error return code in nfsd4_interssc_connect()

Dai Ngo <[email protected]>
nfsd: fix kernel test robot warning in SSC code

Dave Wysochanski <[email protected]>
nfsd4: Expose the callback address and state of each NFS4 client

J. Bruce Fields <[email protected]>
nfsd: move fsnotify on client creation outside spinlock

Dai Ngo <[email protected]>
NFSD: delay unmount source's export after inter-server copy completed.

Olga Kornievskaia <[email protected]>
NFSD add vfs_fsync after async copy is done

J. Bruce Fields <[email protected]>
nfsd: move some commit_metadata()s outside the inode lock

Yu Hsiang Huang <[email protected]>
nfsd: Prevent truncation of an unlinked inode from blocking access to its directory

Chuck Lever <[email protected]>
NFSD: Update nfsd_cb_args tracepoint

Chuck Lever <[email protected]>
NFSD: Remove the nfsd_cb_work and nfsd_cb_done tracepoints

Chuck Lever <[email protected]>
NFSD: Add an nfsd_cb_probe tracepoint

Chuck Lever <[email protected]>
NFSD: Replace the nfsd_deleg_break tracepoint

Chuck Lever <[email protected]>
NFSD: Add an nfsd_cb_offload tracepoint

Chuck Lever <[email protected]>
NFSD: Add an nfsd_cb_lm_notify tracepoint

Chuck Lever <[email protected]>
NFSD: Enhance the nfsd_cb_setup tracepoint

Chuck Lever <[email protected]>
NFSD: Adjust cb_shutdown tracepoint

Chuck Lever <[email protected]>
NFSD: Add cb_lost tracepoint

Chuck Lever <[email protected]>
NFSD: Drop TRACE_DEFINE_ENUM for NFSD4_CB_<state> macros

Chuck Lever <[email protected]>
NFSD: Capture every CB state transition

Chuck Lever <[email protected]>
NFSD: Constify @fh argument of knfsd_fh_hash()

Chuck Lever <[email protected]>
NFSD: Add tracepoints for EXCHANGEID edge cases

Chuck Lever <[email protected]>
NFSD: Add tracepoints for SETCLIENTID edge cases

Chuck Lever <[email protected]>
NFSD: Add a couple more nfsd_clid_expired call sites

Chuck Lever <[email protected]>
NFSD: Add nfsd_clid_destroyed tracepoint

Chuck Lever <[email protected]>
NFSD: Add nfsd_clid_reclaim_complete tracepoint

Chuck Lever <[email protected]>
NFSD: Add nfsd_clid_confirmed tracepoint

Chuck Lever <[email protected]>
NFSD: Remove trace_nfsd_clid_inuse_err

Chuck Lever <[email protected]>
NFSD: Add nfsd_clid_verf_mismatch tracepoint

Chuck Lever <[email protected]>
NFSD: Add nfsd_clid_cred_mismatch tracepoint

Chuck Lever <[email protected]>
NFSD: Add an RPC authflavor tracepoint display helper

Amir Goldstein <[email protected]>
fanotify: fix permission model of unprivileged group

Trond Myklebust <[email protected]>
NFS: fix nfs_fetch_iversion()

Dai Ngo <[email protected]>
NFSv4.2: Remove ifdef CONFIG_NFSD from NFSv4.2 client SSC code.

Gustavo A. R. Silva <[email protected]>
nfsd: Fix fall-through warnings for Clang

J. Bruce Fields <[email protected]>
nfsd: grant read delegations to clients holding writes

J. Bruce Fields <[email protected]>
nfsd: reshuffle some code

J. Bruce Fields <[email protected]>
nfsd: track filehandle aliasing in nfs4_files

J. Bruce Fields <[email protected]>
nfsd: hash nfs4_files by inode number

Vasily Averin <[email protected]>
nfsd: removed unused argument in nfsd_startup_generic()

Jiapeng Chong <[email protected]>
nfsd: remove unused function

Christian Brauner <[email protected]>
fanotify_user: use upper_32_bits() to verify mask

Amir Goldstein <[email protected]>
fanotify: support limited functionality for unprivileged users

Amir Goldstein <[email protected]>
fanotify: configurable limits via sysfs

Amir Goldstein <[email protected]>
fanotify: limit number of event merge attempts

Amir Goldstein <[email protected]>
fsnotify: use hash table for faster events merge

Amir Goldstein <[email protected]>
fanotify: mix event info and pid into merge key hash

Amir Goldstein <[email protected]>
fanotify: reduce event objectid to 29-bit hash

Chuck Lever <[email protected]>
Revert "fanotify: limit number of event merge attempts"

Amir Goldstein <[email protected]>
fsnotify: allow fsnotify_{peek,remove}_first_event with empty queue

Guobin Huang <[email protected]>
NFSD: Use DEFINE_SPINLOCK() for spinlock

Gustavo A. R. Silva <[email protected]>
UAPI: nfsfh.h: Replace one-element array with flexible-array member

Chuck Lever <[email protected]>
SUNRPC: Export svc_xprt_received()

NeilBrown <[email protected]>
nfsd: report client confirmation status in "info" file

J. Bruce Fields <[email protected]>
nfsd: don't ignore high bits of copy count

J. Bruce Fields <[email protected]>
nfsd: COPY with length 0 should copy to end of file

Ricardo Ribalda <[email protected]>
nfsd: Fix typo "accesible"

Paul Menzel <[email protected]>
nfsd: Log client tracking type log message as info instead of warning

J. Bruce Fields <[email protected]>
nfsd: helper for laundromat expiry calculations

Chuck Lever <[email protected]>
NFSD: Clean up NFSDDBG_FACILITY macro

Chuck Lever <[email protected]>
NFSD: Add a tracepoint to record directory entry encoding

Chuck Lever <[email protected]>
NFSD: Clean up after updating NFSv3 ACL encoders

Chuck Lever <[email protected]>
NFSD: Update the NFSv3 SETACL result encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv3 GETACL result encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Clean up after updating NFSv2 ACL encoders

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 ACL ACCESS result encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 ACL GETATTR result encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 SETACL result encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 GETACL result encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Add an xdr_stream-based encoder for NFSv2/3 ACLs

Chuck Lever <[email protected]>
NFSD: Remove unused NFSv2 directory entry encoders

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 READDIR entry encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 READDIR result encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Count bytes instead of pages in the NFSv2 READDIR encoder

Chuck Lever <[email protected]>
NFSD: Add a helper that encodes NFSv3 directory offset cookies, again

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 STATFS result encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 READ result encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 READLINK result encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 diropres encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 attrstat encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 stat encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Reduce svc_rqst::rq_pages churn during READDIR operations

Chuck Lever <[email protected]>
NFSD: Remove unused NFSv3 directory entry encoders

Chuck Lever <[email protected]>
NFSD: Update NFSv3 READDIR entry encoders to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv3 READDIR3res encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Count bytes instead of pages in the NFSv3 READDIR encoder

Chuck Lever <[email protected]>
NFSD: Add a helper that encodes NFSv3 directory offset cookies

Chuck Lever <[email protected]>
NFSD: Update the NFSv3 COMMIT3res encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv3 PATHCONF3res encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv3 FSINFO3res encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv3 FSSTAT3res encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv3 LINK3res encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv3 RENAMEv3res encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv3 CREATE family of encoders to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv3 WRITE3res encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv3 READ3res encode to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv3 READLINK3res encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv3 wccstat result encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv3 LOOKUP3res encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv3 ACCESS3res encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the GETATTR3res encoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Extract the svcxdr_init_encode() helper

Christian Brauner <[email protected]>
namei: introduce struct renamedata

Christian Brauner <[email protected]>
fs: add file and path permissions helpers

Christoph Hellwig <[email protected]>
kallsyms: only build {,module_}kallsyms_on_each_symbol when required

Christoph Hellwig <[email protected]>
kallsyms: refactor {,module_}kallsyms_on_each_symbol

Christoph Hellwig <[email protected]>
module: use RCU to synchronize find_module

Christoph Hellwig <[email protected]>
module: unexport find_module and module_mutex

Shakeel Butt <[email protected]>
inotify, memcg: account inotify instances to kmemcg

J. Bruce Fields <[email protected]>
nfsd: skip some unnecessary stats in the v4 case

J. Bruce Fields <[email protected]>
nfs: use change attribute for NFS re-exports

Dai Ngo <[email protected]>
NFSv4_2: SSC helper should use its own config.

J. Bruce Fields <[email protected]>

    nfsd: cstate->session->se_client -> cstate->clp

J. Bruce Fields <[email protected]>
nfsd: simplify nfsd4_check_open_reclaim

J. Bruce Fields <[email protected]>
nfsd: remove unused set_client argument

J. Bruce Fields <[email protected]>
nfsd: find_cpntf_state cleanup

J. Bruce Fields <[email protected]>
nfsd: refactor set_client

J. Bruce Fields <[email protected]>

    nfsd: rename lookup_clientid->set_client

J. Bruce Fields <[email protected]>
nfsd: simplify nfsd_renew

J. Bruce Fields <[email protected]>
nfsd: simplify process_lock

J. Bruce Fields <[email protected]>
nfsd4: simplify process_lookup1

Amir Goldstein <[email protected]>
nfsd: report per-export stats

Amir Goldstein <[email protected]>
nfsd: protect concurrent access to nfsd stats counters

Amir Goldstein <[email protected]>
nfsd: remove unused stats counters

Chuck Lever <[email protected]>
NFSD: Clean up after updating NFSv3 ACL decoders

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 SETACL argument decoder to use struct xdr_stream, again

Chuck Lever <[email protected]>
NFSD: Update the NFSv3 GETACL argument decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Clean up after updating NFSv2 ACL decoders

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 ACL ACCESS argument decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 ACL GETATTR argument decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 SETACL argument decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Add an xdr_stream-based decoder for NFSv2/3 ACLs

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 GETACL argument decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Remove argument length checking in nfsd_dispatch()

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 SYMLINK argument decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 CREATE argument decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 SETATTR argument decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 LINK argument decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 RENAME argument decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update NFSv2 diropargs decoding to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 READDIR argument decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Add helper to set up the pages where the dirlist is encoded, again

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 READLINK argument decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 WRITE argument decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 READ argument decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv2 GETATTR argument decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the MKNOD3args decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the SYMLINK3args decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the MKDIR3args decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the CREATE3args decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the SETATTR3args decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the LINK3args decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the RENAME3args decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update the NFSv3 DIROPargs decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update COMMIT3arg decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update READDIR3args decoders to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Add helper to set up the pages where the dirlist is encoded

Chuck Lever <[email protected]>
NFSD: Fix returned READDIR offset cookie

Chuck Lever <[email protected]>
NFSD: Update READLINK3arg decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update WRITE3arg decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update READ3arg decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update ACCESS3arg decoder to use struct xdr_stream

Chuck Lever <[email protected]>
NFSD: Update GETATTR3args decoder to use struct xdr_stream

Chuck Lever <[email protected]>
SUNRPC: Move definition of XDR_UNIT

Chuck Lever <[email protected]>
SUNRPC: Display RPC procedure names instead of proc numbers

Chuck Lever <[email protected]>
SUNRPC: Make trace_svc_process() display the RPC procedure symbolically

Chuck Lever <[email protected]>
NFSD: Restore NFSv4 decoding's SAVEMEM functionality

Chuck Lever <[email protected]>
NFSD: Fix sparse warning in nfssvc.c

Zheng Yongjun <[email protected]>
fs/lockd: convert comma to semicolon

Waiman Long <[email protected]>
inotify: Increase default inotify.max_user_watches limit to 1048576

Eric W. Biederman <[email protected]>
file: Replace ksys_close with close_fd

Eric W. Biederman <[email protected]>
file: Rename __close_fd to close_fd and remove the files parameter

Eric W. Biederman <[email protected]>
file: Merge __alloc_fd into alloc_fd

Eric W. Biederman <[email protected]>
file: In f_dupfd read RLIMIT_NOFILE once.

Eric W. Biederman <[email protected]>
file: Merge __fd_install into fd_install

Eric W. Biederman <[email protected]>
proc/fd: In fdinfo seq_show don't use get_files_struct

Eric W. Biederman <[email protected]>
proc/fd: In proc_readfd_common use task_lookup_next_fd_rcu

Eric W. Biederman <[email protected]>
file: Implement task_lookup_next_fd_rcu

Eric W. Biederman <[email protected]>
kcmp: In get_file_raw_ptr use task_lookup_fd_rcu

Eric W. Biederman <[email protected]>
proc/fd: In tid_fd_mode use task_lookup_fd_rcu

Eric W. Biederman <[email protected]>
file: Implement task_lookup_fd_rcu

Eric W. Biederman <[email protected]>
file: Rename fcheck lookup_fd_rcu

Eric W. Biederman <[email protected]>
file: Replace fcheck_files with files_lookup_fd_rcu

Eric W. Biederman <[email protected]>
file: Factor files_lookup_fd_locked out of fcheck_files

Eric W. Biederman <[email protected]>
file: Rename __fcheck_files to files_lookup_fd_raw

Chuck Lever <[email protected]>
Revert "fget: clarify and improve __fget_files() implementation"

Eric W. Biederman <[email protected]>
proc/fd: In proc_fd_link use fget_task

Eric W. Biederman <[email protected]>
bpf: In bpf_task_fd_query use fget_task

Eric W. Biederman <[email protected]>
kcmp: In kcmp_epoll_target use fget_task

Eric W. Biederman <[email protected]>
exec: Remove reset_files_struct

Eric W. Biederman <[email protected]>
exec: Simplify unshare_files

Eric W. Biederman <[email protected]>
exec: Move unshare_files to fix posix file locking during exec

Eric W. Biederman <[email protected]>
exec: Don't open code get_close_on_exec

Trond Myklebust <[email protected]>
nfsd: Record NFSv4 pre/post-op attributes as non-atomic

Trond Myklebust <[email protected]>
nfsd: Set PF_LOCAL_THROTTLE on local filesystems only

Trond Myklebust <[email protected]>
nfsd: Fix up nfsd to ensure that timeout errors don't result in ESTALE

Trond Myklebust <[email protected]>
exportfs: Add a function to return the raw output from fh_to_dentry()

Jeff Layton <[email protected]>
nfsd: close cached files prior to a REMOVE or RENAME that would replace target

Jeff Layton <[email protected]>
nfsd: allow filesystems to opt out of subtree checking

Jeff Layton <[email protected]>
nfsd: add a new EXPORT_OP_NOWCC flag to struct export_operations

J. Bruce Fields <[email protected]>
Revert "nfsd4: support change_attr_type attribute"

J. Bruce Fields <[email protected]>
nfsd4: don't query change attribute in v2/v3 case

J. Bruce Fields <[email protected]>
nfsd: minor nfsd4_change_attribute cleanup

J. Bruce Fields <[email protected]>
nfsd: simplify nfsd4_change_info

J. Bruce Fields <[email protected]>
nfsd: only call inode_query_iversion in the I_VERSION case

Chuck Lever <[email protected]>
NFSD: Remove macros that are no longer used

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_compound()

Chuck Lever <[email protected]>
NFSD: Make nfsd4_ops::opnum a u32

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_listxattrs()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_setxattr()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_xattr_name()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_clone()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_seek()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_offload_status()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_copy_notify()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_copy()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_nl4_server()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_fallocate()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_reclaim_complete()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_destroy_clientid()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_test_stateid()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_sequence()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_secinfo_no_name()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_layoutreturn()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_layoutget()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_layoutcommit()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_getdeviceinfo()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_free_stateid()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_destroy_session()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_create_session()

Chuck Lever <[email protected]>
NFSD: Add a helper to decode channel_attrs4

Chuck Lever <[email protected]>
NFSD: Add a helper to decode nfs_impl_id4

Chuck Lever <[email protected]>
NFSD: Add a helper to decode state_protect4_a

Chuck Lever <[email protected]>
NFSD: Add a separate decoder for ssv_sp_parms

Chuck Lever <[email protected]>
NFSD: Add a separate decoder to handle state_protect_ops

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_bind_conn_to_session()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_backchannel_ctl()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_cb_sec()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_release_lockowner()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_write()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_verify()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_setclientid_confirm()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_setclientid()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_setattr()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_secinfo()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_renew()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_rename()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_remove()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_readdir()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_read()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_putfh()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_open_downgrade()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_open_confirm()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_open()

Chuck Lever <[email protected]>
NFSD: Add helper to decode OPEN's open_claim4 argument

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_share_deny()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_share_access()

Chuck Lever <[email protected]>
NFSD: Add helper to decode OPEN's openflag4 argument

Chuck Lever <[email protected]>
NFSD: Add helper to decode OPEN's createhow4 argument

Chuck Lever <[email protected]>
NFSD: Add helper to decode NFSv4 verifiers

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_lookup()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_locku()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_lockt()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_lock()

Chuck Lever <[email protected]>
NFSD: Add helper for decoding locker4

Chuck Lever <[email protected]>
NFSD: Add helpers to decode a clientid4 and an NFSv4 state owner

Chuck Lever <[email protected]>
NFSD: Relocate nfsd4_decode_opaque()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_link()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_getattr()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_delegreturn()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_create()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_fattr()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros that decode the fattr4 umask attribute

Chuck Lever <[email protected]>
NFSD: Replace READ* macros that decode the fattr4 security label attribute

Chuck Lever <[email protected]>
NFSD: Replace READ* macros that decode the fattr4 time_set attributes

Chuck Lever <[email protected]>
NFSD: Replace READ* macros that decode the fattr4 owner_group attribute

Chuck Lever <[email protected]>
NFSD: Replace READ* macros that decode the fattr4 owner attribute

Chuck Lever <[email protected]>
NFSD: Replace READ* macros that decode the fattr4 mode attribute

Chuck Lever <[email protected]>
NFSD: Replace READ* macros that decode the fattr4 acl attribute

Chuck Lever <[email protected]>
NFSD: Replace READ* macros that decode the fattr4 size attribute

Chuck Lever <[email protected]>
NFSD: Change the way the expected length of a fattr4 is checked

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_commit()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_close()

Chuck Lever <[email protected]>
NFSD: Replace READ* macros in nfsd4_decode_access()

Chuck Lever <[email protected]>
NFSD: Replace the internals of the READ_BUF() macro

Chuck Lever <[email protected]>
NFSD: Add tracepoints in nfsd4_decode/encode_compound()

Chuck Lever <[email protected]>
NFSD: Add tracepoints in nfsd_dispatch()

Chuck Lever <[email protected]>
NFSD: Add common helpers to decode void args and encode void results

Chuck Lever <[email protected]>
SUNRPC: Prepare for xdr_stream-style decoding on the server-side

Chuck Lever <[email protected]>
SUNRPC: Add xdr_set_scratch_page() and xdr_reset_scratch_buffer()

Huang Guobin <[email protected]>
nfsd: Fix error return code in nfsd_file_cache_init()

Chuck Lever <[email protected]>
NFSD: Add SPDX header for fs/nfsd/trace.c

Chuck Lever <[email protected]>

    NFSD: Remove extra "0x" in tracepoint format specifier

Chuck Lever <[email protected]>
NFSD: Clean up the show_nf_may macro

Alex Shi <[email protected]>
nfsd/nfs3: remove unused macro nfsd3_fhandleres

Tom Rix <[email protected]>
NFSD: A semicolon is not needed after a switch statement.

Chuck Lever <[email protected]>
NFSD: Invoke svc_encode_result_payload() in "read" NFSD encoders

Chuck Lever <[email protected]>
SUNRPC: Rename svc_encode_read_payload()

-------------

Diffstat:

 Documentation/filesystems/files.rst          |    8 +-
 Documentation/filesystems/locking.rst        |   10 +-
 Documentation/filesystems/nfs/exporting.rst  |   78 +
 Makefile                                     |    4 +-
 arch/powerpc/platforms/cell/spufs/coredump.c |    2 +-
 crypto/algboss.c                             |    4 +-
 fs/Kconfig                                   |    6 +-
 fs/autofs/dev-ioctl.c                        |    5 +-
 fs/cachefiles/namei.c                        |    9 +-
 fs/cifs/connect.c                            |    2 +-
 fs/coredump.c                                |    5 +-
 fs/ecryptfs/inode.c                          |   10 +-
 fs/exec.c                                    |   29 +-
 fs/exportfs/expfs.c                          |   40 +-
 fs/file.c                                    |  177 +-
 fs/init.c                                    |    6 +-
 fs/lockd/clnt4xdr.c                          |    9 +-
 fs/lockd/clntproc.c                          |    3 -
 fs/lockd/host.c                              |    4 +-
 fs/lockd/svc.c                               |  262 +-
 fs/lockd/svc4proc.c                          |   70 +-
 fs/lockd/svclock.c                           |   67 +-
 fs/lockd/svcproc.c                           |   62 +-
 fs/lockd/svcsubs.c                           |  123 +-
 fs/lockd/svcxdr.h                            |  142 +
 fs/lockd/xdr.c                               |  448 +--
 fs/lockd/xdr4.c                              |  472 ++--
 fs/locks.c                                   |  102 +-
 fs/namei.c                                   |   21 +-
 fs/nfs/blocklayout/blocklayout.c             |    2 +-
 fs/nfs/blocklayout/dev.c                     |    2 +-
 fs/nfs/callback.c                            |  111 +-
 fs/nfs/callback_xdr.c                        |   33 +-
 fs/nfs/dir.c                                 |    2 +-
 fs/nfs/export.c                              |   17 +
 fs/nfs/file.c                                |    3 +
 fs/nfs/filelayout/filelayout.c               |    4 +-
 fs/nfs/filelayout/filelayoutdev.c            |    2 +-
 fs/nfs/flexfilelayout/flexfilelayout.c       |    4 +-
 fs/nfs/flexfilelayout/flexfilelayoutdev.c    |    2 +-
 fs/nfs/nfs42xdr.c                            |    2 +-
 fs/nfs/nfs4state.c                           |    2 +-
 fs/nfs/nfs4xdr.c                             |    6 +-
 fs/nfs/pagelist.c                            |    3 -
 fs/nfs/super.c                               |    8 +
 fs/nfs/write.c                               |    3 -
 fs/nfs_common/Makefile                       |    2 +-
 fs/nfs_common/nfs_ssc.c                      |    2 -
 fs/nfs_common/nfsacl.c                       |  123 +
 fs/nfsd/Kconfig                              |   36 +-
 fs/nfsd/Makefile                             |    8 +-
 fs/nfsd/acl.h                                |    6 +-
 fs/nfsd/blocklayout.c                        |    1 +
 fs/nfsd/blocklayoutxdr.c                     |    1 +
 fs/nfsd/cache.h                              |    2 +-
 fs/nfsd/export.c                             |   74 +-
 fs/nfsd/export.h                             |   16 +-
 fs/nfsd/filecache.c                          | 1229 +++++----
 fs/nfsd/filecache.h                          |   23 +-
 fs/nfsd/flexfilelayout.c                     |    3 +-
 fs/nfsd/lockd.c                              |   10 +-
 fs/nfsd/netns.h                              |   63 +-
 fs/nfsd/nfs2acl.c                            |  214 +-
 fs/nfsd/nfs3acl.c                            |  140 +-
 fs/nfsd/nfs3proc.c                           |  396 ++-
 fs/nfsd/nfs3xdr.c                            | 1763 ++++++------
 fs/nfsd/nfs4acl.c                            |   45 +-
 fs/nfsd/nfs4callback.c                       |  168 +-
 fs/nfsd/nfs4idmap.c                          |    9 +-
 fs/nfsd/nfs4layouts.c                        |    4 +-
 fs/nfsd/nfs4proc.c                           | 1111 +++++---
 fs/nfsd/nfs4recover.c                        |   20 +-
 fs/nfsd/nfs4state.c                          | 1725 ++++++++----
 fs/nfsd/nfs4xdr.c                            | 3763 ++++++++++++++------------
 fs/nfsd/nfscache.c                           |  115 +-
 fs/nfsd/nfsctl.c                             |  169 +-
 fs/nfsd/nfsd.h                               |   50 +-
 fs/nfsd/nfsfh.c                              |  291 +-
 fs/nfsd/nfsfh.h                              |  179 +-
 fs/nfsd/nfsproc.c                            |  262 +-
 fs/nfsd/nfssvc.c                             |  356 ++-
 fs/nfsd/nfsxdr.c                             |  834 +++---
 fs/nfsd/state.h                              |   69 +-
 fs/nfsd/stats.c                              |  126 +-
 fs/nfsd/stats.h                              |   96 +-
 fs/nfsd/trace.c                              |    1 +
 fs/nfsd/trace.h                              |  894 +++++-
 fs/nfsd/vfs.c                                |  931 +++----
 fs/nfsd/vfs.h                                |   60 +-
 fs/nfsd/xdr.h                                |   68 +-
 fs/nfsd/xdr3.h                               |  116 +-
 fs/nfsd/xdr4.h                               |  127 +-
 fs/nfsd/xdr4cb.h                             |    6 +
 fs/notify/dnotify/dnotify.c                  |   17 +-
 fs/notify/fanotify/fanotify.c                |  487 +++-
 fs/notify/fanotify/fanotify.h                |  252 +-
 fs/notify/fanotify/fanotify_user.c           |  882 ++++--
 fs/notify/fdinfo.c                           |   19 +-
 fs/notify/fsnotify.c                         |  183 +-
 fs/notify/fsnotify.h                         |   19 +-
 fs/notify/group.c                            |   38 +-
 fs/notify/inotify/inotify.h                  |   11 +-
 fs/notify/inotify/inotify_fsnotify.c         |   12 +-
 fs/notify/inotify/inotify_user.c             |   87 +-
 fs/notify/mark.c                             |  172 +-
 fs/notify/notification.c                     |   78 +-
 fs/open.c                                    |   49 +-
 fs/overlayfs/overlayfs.h                     |    9 +-
 fs/proc/fd.c                                 |   48 +-
 fs/udf/file.c                                |    2 +-
 fs/verity/enable.c                           |    2 +-
 include/linux/dnotify.h                      |    2 +-
 include/linux/errno.h                        |    1 +
 include/linux/exportfs.h                     |   15 +
 include/linux/fanotify.h                     |   74 +-
 include/linux/fdtable.h                      |   37 +-
 include/linux/fs.h                           |   54 +-
 include/linux/fsnotify.h                     |   77 +-
 include/linux/fsnotify_backend.h             |  372 ++-
 include/linux/iversion.h                     |   13 +
 include/linux/kallsyms.h                     |   17 +-
 include/linux/kthread.h                      |    1 +
 include/linux/lockd/bind.h                   |    3 +-
 include/linux/lockd/lockd.h                  |   17 +-
 include/linux/lockd/xdr.h                    |   35 +-
 include/linux/lockd/xdr4.h                   |   33 +-
 include/linux/module.h                       |   24 +-
 include/linux/nfs.h                          |    8 -
 include/linux/nfs4.h                         |   21 +-
 include/linux/nfs_ssc.h                      |   14 +
 include/linux/nfsacl.h                       |    6 +
 include/linux/pid.h                          |    1 +
 include/linux/sched/user.h                   |    3 -
 include/linux/sunrpc/msg_prot.h              |    3 -
 include/linux/sunrpc/svc.h                   |  151 +-
 include/linux/sunrpc/svc_rdma.h              |    4 +-
 include/linux/sunrpc/svc_xprt.h              |   16 +-
 include/linux/sunrpc/svcauth.h               |    4 +-
 include/linux/sunrpc/svcsock.h               |    7 +-
 include/linux/sunrpc/xdr.h                   |  153 +-
 include/linux/syscalls.h                     |   12 -
 include/linux/sysctl.h                       |    2 +
 include/linux/user_namespace.h               |    4 +
 include/trace/events/sunrpc.h                |   26 +-
 include/uapi/linux/fanotify.h                |   42 +
 include/uapi/linux/nfs3.h                    |    6 +
 include/uapi/linux/nfsd/nfsfh.h              |  105 -
 kernel/audit_fsnotify.c                      |    8 +-
 kernel/audit_tree.c                          |    2 +-
 kernel/audit_watch.c                         |    5 +-
 kernel/bpf/inode.c                           |    2 +-
 kernel/bpf/syscall.c                         |   20 +-
 kernel/bpf/task_iter.c                       |    2 +-
 kernel/fork.c                                |   12 +-
 kernel/kallsyms.c                            |    8 +-
 kernel/kcmp.c                                |   29 +-
 kernel/kthread.c                             |   23 +-
 kernel/livepatch/core.c                      |    7 +-
 kernel/module.c                              |   26 +-
 kernel/pid.c                                 |   15 +-
 kernel/sys.c                                 |    2 +-
 kernel/sysctl.c                              |   54 +-
 kernel/trace/trace_kprobe.c                  |    4 +-
 kernel/ucount.c                              |    4 +
 mm/madvise.c                                 |    2 +-
 mm/memcontrol.c                              |    2 +-
 mm/mincore.c                                 |    2 +-
 net/bluetooth/bnep/core.c                    |    2 +-
 net/bluetooth/cmtp/core.c                    |    2 +-
 net/bluetooth/hidp/core.c                    |    2 +-
 net/sunrpc/auth_gss/gss_rpc_xdr.c            |    2 +-
 net/sunrpc/auth_gss/svcauth_gss.c            |   47 +-
 net/sunrpc/sched.c                           |    1 +
 net/sunrpc/svc.c                             |  314 ++-
 net/sunrpc/svc_xprt.c                        |  104 +-
 net/sunrpc/svcauth.c                         |    8 +-
 net/sunrpc/svcauth_unix.c                    |   18 +-
 net/sunrpc/svcsock.c                         |   32 +-
 net/sunrpc/xdr.c                             |  112 +-
 net/sunrpc/xprtrdma/svc_rdma_backchannel.c   |    2 +-
 net/sunrpc/xprtrdma/svc_rdma_sendto.c        |   32 +-
 net/sunrpc/xprtrdma/svc_rdma_transport.c     |    2 +-
 net/unix/af_unix.c                           |    2 +-
 tools/objtool/check.c                        |    3 +-
 184 files changed, 13912 insertions(+), 8825 deletions(-)
author maintainer
#1 lore raw

PATCH 1/770 SUNRPC: Rename svc_encode_read_payload()

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 03493bca084fdca48abc59b00e06ce733aa9eb7d ]

Clean up: "result payload" is a less confusing name for these payloads. "READ payload" reflects only the NFS usage.

---
 fs/nfsd/nfs4xdr.c                        |  2 +-
 include/linux/sunrpc/svc.h               |  6 +++---
 include/linux/sunrpc/svc_rdma.h          |  4 ++--
 include/linux/sunrpc/svc_xprt.h          |  4 ++--
 net/sunrpc/svc.c                         | 11 ++++++-----
 net/sunrpc/svcsock.c                     |  8 ++++----
 net/sunrpc/xprtrdma/svc_rdma_sendto.c    |  8 ++++----
 net/sunrpc/xprtrdma/svc_rdma_transport.c |  2 +-
 8 files changed, 23 insertions(+), 22 deletions(-)
fs/nfsd/nfs4xdr.c +1 -1
index dbfa24cf33906..9971d3c295731 100644
@@ -3843,7 +3843,7 @@ static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp,
 	read->rd_length = maxcount;
 	if (nfserr)
 		return nfserr;
-	if (svc_encode_read_payload(resp->rqstp, starting_len + 8, maxcount))
+	if (svc_encode_result_payload(resp->rqstp, starting_len + 8, maxcount))
 		return nfserr_io;
 	xdr_truncate_encode(xdr, starting_len + 8 + xdr_align_size(maxcount));
 
include/linux/sunrpc/svc.h +3 -3
index 386628b36bc75..c220b734fa69e 100644
@@ -519,9 +519,9 @@ void		   svc_wake_up(struct svc_serv *);
 void		   svc_reserve(struct svc_rqst *rqstp, int space);
 struct svc_pool *  svc_pool_for_cpu(struct svc_serv *serv, int cpu);
 char *		   svc_print_addr(struct svc_rqst *, char *, size_t);
-int		   svc_encode_read_payload(struct svc_rqst *rqstp,
-					   unsigned int offset,
-					   unsigned int length);
+int		   svc_encode_result_payload(struct svc_rqst *rqstp,
+					     unsigned int offset,
+					     unsigned int length);
 unsigned int	   svc_fill_write_vector(struct svc_rqst *rqstp,
 					 struct page **pages,
 					 struct kvec *first, size_t total);
include/linux/sunrpc/svc_rdma.h +2 -2
index 9dc3a3b88391b..2b870a3f391b1 100644
@@ -207,8 +207,8 @@ extern void svc_rdma_send_error_msg(struct svcxprt_rdma *rdma,
 				    struct svc_rdma_recv_ctxt *rctxt,
 				    int status);
 extern int svc_rdma_sendto(struct svc_rqst *);
-extern int svc_rdma_read_payload(struct svc_rqst *rqstp, unsigned int offset,
-				 unsigned int length);
+extern int svc_rdma_result_payload(struct svc_rqst *rqstp, unsigned int offset,
+				   unsigned int length);
 
 /* svc_rdma_transport.c */
 extern struct svc_xprt_class svc_rdma_class;
include/linux/sunrpc/svc_xprt.h +2 -2
index aca35ab5cff24..92455e0d52445 100644
@@ -21,8 +21,8 @@ struct svc_xprt_ops {
 	int		(*xpo_has_wspace)(struct svc_xprt *);
 	int		(*xpo_recvfrom)(struct svc_rqst *);
 	int		(*xpo_sendto)(struct svc_rqst *);
-	int		(*xpo_read_payload)(struct svc_rqst *, unsigned int,
-					    unsigned int);
+	int		(*xpo_result_payload)(struct svc_rqst *, unsigned int,
+					      unsigned int);
 	void		(*xpo_release_rqst)(struct svc_rqst *);
 	void		(*xpo_detach)(struct svc_xprt *);
 	void		(*xpo_free)(struct svc_xprt *);
net/sunrpc/svc.c +6 -5
index cfe8b911ca013..e4e4e203ecdad 100644
@@ -1626,7 +1626,7 @@ u32 svc_max_payload(const struct svc_rqst *rqstp)
 EXPORT_SYMBOL_GPL(svc_max_payload);
 
 /**
- * svc_encode_read_payload - mark a range of bytes as a READ payload
+ * svc_encode_result_payload - mark a range of bytes as a result payload
  * @rqstp: svc_rqst to operate on
  * @offset: payload's byte offset in rqstp->rq_res
  * @length: size of payload, in bytes
@@ -1634,12 +1634,13 @@ EXPORT_SYMBOL_GPL(svc_max_payload);
  * Returns zero on success, or a negative errno if a permanent
  * error occurred.
  */
-int svc_encode_read_payload(struct svc_rqst *rqstp, unsigned int offset,
-			    unsigned int length)
+int svc_encode_result_payload(struct svc_rqst *rqstp, unsigned int offset,
+			      unsigned int length)
 {
-	return rqstp->rq_xprt->xpt_ops->xpo_read_payload(rqstp, offset, length);
+	return rqstp->rq_xprt->xpt_ops->xpo_result_payload(rqstp, offset,
+							   length);
 }
-EXPORT_SYMBOL_GPL(svc_encode_read_payload);
+EXPORT_SYMBOL_GPL(svc_encode_result_payload);
 
 /**
  * svc_fill_write_vector - Construct data argument for VFS write call
net/sunrpc/svcsock.c +4 -4
index 3d5ee042c5015..90f6231d6ed67 100644
@@ -181,8 +181,8 @@ static void svc_set_cmsg_data(struct svc_rqst *rqstp, struct cmsghdr *cmh)
 	}
 }
 
-static int svc_sock_read_payload(struct svc_rqst *rqstp, unsigned int offset,
-				 unsigned int length)
+static int svc_sock_result_payload(struct svc_rqst *rqstp, unsigned int offset,
+				   unsigned int length)
 {
 	return 0;
 }
@@ -635,7 +635,7 @@ static const struct svc_xprt_ops svc_udp_ops = {
 	.xpo_create = svc_udp_create,
 	.xpo_recvfrom = svc_udp_recvfrom,
 	.xpo_sendto = svc_udp_sendto,
-	.xpo_read_payload = svc_sock_read_payload,
+	.xpo_result_payload = svc_sock_result_payload,
 	.xpo_release_rqst = svc_udp_release_rqst,
 	.xpo_detach = svc_sock_detach,
 	.xpo_free = svc_sock_free,
@@ -1209,7 +1209,7 @@ static const struct svc_xprt_ops svc_tcp_ops = {
 	.xpo_create = svc_tcp_create,
 	.xpo_recvfrom = svc_tcp_recvfrom,
 	.xpo_sendto = svc_tcp_sendto,
-	.xpo_read_payload = svc_sock_read_payload,
+	.xpo_result_payload = svc_sock_result_payload,
 	.xpo_release_rqst = svc_tcp_release_rqst,
 	.xpo_detach = svc_tcp_sock_detach,
 	.xpo_free = svc_sock_free,
net/sunrpc/xprtrdma/svc_rdma_sendto.c +4 -4
index c3d588b149aaa..c8411b4f3492a 100644
@@ -979,19 +979,19 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
 }
 
 /**
- * svc_rdma_read_payload - special processing for a READ payload
+ * svc_rdma_result_payload - special processing for a result payload
  * @rqstp: svc_rqst to operate on
  * @offset: payload's byte offset in @xdr
  * @length: size of payload, in bytes
  *
  * Returns zero on success.
  *
- * For the moment, just record the xdr_buf location of the READ
+ * For the moment, just record the xdr_buf location of the result
  * payload. svc_rdma_sendto will use that location later when
  * we actually send the payload.
  */
-int svc_rdma_read_payload(struct svc_rqst *rqstp, unsigned int offset,
-			  unsigned int length)
+int svc_rdma_result_payload(struct svc_rqst *rqstp, unsigned int offset,
+			    unsigned int length)
 {
 	struct svc_rdma_recv_ctxt *rctxt = rqstp->rq_xprt_ctxt;
 
net/sunrpc/xprtrdma/svc_rdma_transport.c +1 -1
index 5f7e3d12523fe..c895f80df659c 100644
@@ -80,7 +80,7 @@ static const struct svc_xprt_ops svc_rdma_ops = {
 	.xpo_create = svc_rdma_create,
 	.xpo_recvfrom = svc_rdma_recvfrom,
 	.xpo_sendto = svc_rdma_sendto,
-	.xpo_read_payload = svc_rdma_read_payload,
+	.xpo_result_payload = svc_rdma_result_payload,
 	.xpo_release_rqst = svc_rdma_release_rqst,
 	.xpo_detach = svc_rdma_detach,
 	.xpo_free = svc_rdma_free,
Signature · 1 line
2.43.0
author maintainer
#2 lore raw

PATCH 2/770 NFSD: Invoke svc_encode_result_payload() in "read" NFSD encoders

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 76e5492b161f555c0fb69cad9eb39a7d8467f5fe ]

Have the NFSD encoders annotate the boundaries of every direct-data-placement eligible result data payload. Then change svcrdma to use that annotation instead of the xdr->page_len when handling Write chunks.

For NFSv4 on RDMA, that enables the ability to recognize multiple result payloads per compound. This is a pre-requisite for supporting multiple Write chunks per RPC transaction.

---
 fs/nfsd/nfs3xdr.c                     |  7 +++++
 fs/nfsd/nfs4xdr.c                     | 41 +++++++++++++++++++--------
 fs/nfsd/nfsxdr.c                      |  6 ++++
 net/sunrpc/xprtrdma/svc_rdma_sendto.c | 24 +++++-----------
 4 files changed, 49 insertions(+), 29 deletions(-)
fs/nfsd/nfs3xdr.c +7 -0
index 716566da400e1..27b24823f7c42 100644
@@ -707,6 +707,7 @@ int
 nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p)
 {
 	struct nfsd3_readlinkres *resp = rqstp->rq_resp;
+	struct kvec *head = rqstp->rq_res.head;
 
 	*p++ = resp->status;
 	p = encode_post_op_attr(rqstp, p, &resp->fh);
@@ -720,6 +721,8 @@ nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p)
 			*p = 0;
 			rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3);
 		}
+		if (svc_encode_result_payload(rqstp, head->iov_len, resp->len))
+			return 0;
 		return 1;
 	} else
 		return xdr_ressize_check(rqstp, p);
@@ -730,6 +733,7 @@ int
 nfs3svc_encode_readres(struct svc_rqst *rqstp, __be32 *p)
 {
 	struct nfsd3_readres *resp = rqstp->rq_resp;
+	struct kvec *head = rqstp->rq_res.head;
 
 	*p++ = resp->status;
 	p = encode_post_op_attr(rqstp, p, &resp->fh);
@@ -746,6 +750,9 @@ nfs3svc_encode_readres(struct svc_rqst *rqstp, __be32 *p)
 			*p = 0;
 			rqstp->rq_res.tail[0].iov_len = 4 - (resp->count & 3);
 		}
+		if (svc_encode_result_payload(rqstp, head->iov_len,
+					      resp->count))
+			return 0;
 		return 1;
 	} else
 		return xdr_ressize_check(rqstp, p);
fs/nfsd/nfs4xdr.c +29 -12

78 lines not on this page · raw message

fs/nfsd/nfsxdr.c +6 -0
index 8a288c8fcd57c..9e00a902113e3 100644
@@ -469,6 +469,7 @@ int
 nfssvc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p)
 {
 	struct nfsd_readlinkres *resp = rqstp->rq_resp;
+	struct kvec *head = rqstp->rq_res.head;
 
 	*p++ = resp->status;
 	if (resp->status != nfs_ok)
@@ -483,6 +484,8 @@ nfssvc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p)
 		*p = 0;
 		rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3);
 	}
+	if (svc_encode_result_payload(rqstp, head->iov_len, resp->len))
+		return 0;
 	return 1;
 }
 
@@ -490,6 +493,7 @@ int
 nfssvc_encode_readres(struct svc_rqst *rqstp, __be32 *p)
 {
 	struct nfsd_readres *resp = rqstp->rq_resp;
+	struct kvec *head = rqstp->rq_res.head;
 
 	*p++ = resp->status;
 	if (resp->status != nfs_ok)
@@ -507,6 +511,8 @@ nfssvc_encode_readres(struct svc_rqst *rqstp, __be32 *p)
 		*p = 0;
 		rqstp->rq_res.tail[0].iov_len = 4 - (resp->count&3);
 	}
+	if (svc_encode_result_payload(rqstp, head->iov_len, resp->count))
+		return 0;
 	return 1;
 }
 
net/sunrpc/xprtrdma/svc_rdma_sendto.c +7 -17
index c8411b4f3492a..d6436c13d5c47 100644
@@ -448,7 +448,6 @@ static ssize_t svc_rdma_encode_write_chunk(__be32 *src,
  * svc_rdma_encode_write_list - Encode RPC Reply's Write chunk list
  * @rctxt: Reply context with information about the RPC Call
  * @sctxt: Send context for the RPC Reply
- * @length: size in bytes of the payload in the first Write chunk
  *
  * The client provides a Write chunk list in the Call message. Fill
  * in the segments in the first Write chunk in the Reply's transport
@@ -465,12 +464,12 @@ static ssize_t svc_rdma_encode_write_chunk(__be32 *src,
  */
 static ssize_t
 svc_rdma_encode_write_list(const struct svc_rdma_recv_ctxt *rctxt,
-			   struct svc_rdma_send_ctxt *sctxt,
-			   unsigned int length)
+			   struct svc_rdma_send_ctxt *sctxt)
 {
 	ssize_t len, ret;
 
-	ret = svc_rdma_encode_write_chunk(rctxt->rc_write_list, sctxt, length);
+	ret = svc_rdma_encode_write_chunk(rctxt->rc_write_list, sctxt,
+					  rctxt->rc_read_payload_length);
 	if (ret < 0)
 		return ret;
 	len = ret;
@@ -923,21 +922,12 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
 		goto err0;
 	if (wr_lst) {
 		/* XXX: Presume the client sent only one Write chunk */
-		unsigned long offset;
-		unsigned int length;
-
-		if (rctxt->rc_read_payload_length) {
-			offset = rctxt->rc_read_payload_offset;
-			length = rctxt->rc_read_payload_length;
-		} else {
-			offset = xdr->head[0].iov_len;
-			length = xdr->page_len;
-		}
-		ret = svc_rdma_send_write_chunk(rdma, wr_lst, xdr, offset,
-						length);
+		ret = svc_rdma_send_write_chunk(rdma, wr_lst, xdr,
+						rctxt->rc_read_payload_offset,
+						rctxt->rc_read_payload_length);
 		if (ret < 0)
 			goto err2;
-		if (svc_rdma_encode_write_list(rctxt, sctxt, length) < 0)
+		if (svc_rdma_encode_write_list(rctxt, sctxt) < 0)
 			goto err0;
 	} else {
 		if (xdr_stream_encode_item_absent(&sctxt->sc_stream) < 0)
Signature · 1 line
2.43.0
author maintainer
#3 lore raw

PATCH 3/770 NFSD: A semicolon is not needed after a switch statement.

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tom Rix <[email protected]>

[ Upstream commit 25fef48bdbe7cac5ba5577eab6a750e1caea43bc ]

---
 fs/nfsd/nfs4xdr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfsd/nfs4xdr.c +1 -1
index 4b3344296ed0e..fd9107332a20f 100644
@@ -2558,7 +2558,7 @@ static u32 nfs4_file_type(umode_t mode)
 	case S_IFREG:	return NF4REG;
 	case S_IFSOCK:	return NF4SOCK;
 	default:	return NF4BAD;
-	};
+	}
 }
 
 static inline __be32
Signature · 1 line
2.43.0
author maintainer
#4 lore raw

PATCH 4/770 nfsd/nfs3: remove unused macro nfsd3_fhandleres

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alex Shi <[email protected]>

[ Upstream commit 71fd721839a74d945c242299f6be29a246fc2131 ]

The macro is unused, remove it to tame gcc warning:
fs/nfsd/nfs3proc.c:702:0: warning: macro "nfsd3_fhandleres" is not used [-Wunused-macros]

---
 fs/nfsd/nfs3proc.c | 1 -
 1 file changed, 1 deletion(-)
fs/nfsd/nfs3proc.c +0 -1
index 981a4e4c9a3cf..eba84417406ca 100644
@@ -694,7 +694,6 @@ nfsd3_proc_commit(struct svc_rqst *rqstp)
 #define nfsd3_mkdirargs			nfsd3_createargs
 #define nfsd3_readdirplusargs		nfsd3_readdirargs
 #define nfsd3_fhandleargs		nfsd_fhandle
-#define nfsd3_fhandleres		nfsd3_attrstat
 #define nfsd3_attrstatres		nfsd3_attrstat
 #define nfsd3_wccstatres		nfsd3_attrstat
 #define nfsd3_createres			nfsd3_diropres
Signature · 1 line
2.43.0
author maintainer
#5 lore raw

PATCH 5/770 NFSD: Clean up the show_nf_may macro

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit b76278ae68848cea13b325d247aa5cf31c87edac ]

Display all currently possible NFSD_MAY permission flags.

Move and rename show_nf_may with a more generic name because the NFSD_MAY permission flags are used in other places besides the file cache.

---
 fs/nfsd/trace.h | 40 ++++++++++++++++++++++++++--------------
 1 file changed, 26 insertions(+), 14 deletions(-)
fs/nfsd/trace.h +26 -14
index a952f4a9b2a68..7bb1c398daa51 100644
@@ -12,6 +12,22 @@
 #include "export.h"
 #include "nfsfh.h"
 
+#define show_nfsd_may_flags(x)						\
+	__print_flags(x, "|",						\
+		{ NFSD_MAY_EXEC,		"EXEC" },		\
+		{ NFSD_MAY_WRITE,		"WRITE" },		\
+		{ NFSD_MAY_READ,		"READ" },		\
+		{ NFSD_MAY_SATTR,		"SATTR" },		\
+		{ NFSD_MAY_TRUNC,		"TRUNC" },		\
+		{ NFSD_MAY_LOCK,		"LOCK" },		\
+		{ NFSD_MAY_OWNER_OVERRIDE,	"OWNER_OVERRIDE" },	\
+		{ NFSD_MAY_LOCAL_ACCESS,	"LOCAL_ACCESS" },	\
+		{ NFSD_MAY_BYPASS_GSS_ON_ROOT,	"BYPASS_GSS_ON_ROOT" },	\
+		{ NFSD_MAY_NOT_BREAK_LEASE,	"NOT_BREAK_LEASE" },	\
+		{ NFSD_MAY_BYPASS_GSS,		"BYPASS_GSS" },		\
+		{ NFSD_MAY_READ_IF_EXEC,	"READ_IF_EXEC" },	\
+		{ NFSD_MAY_64BIT_COOKIE,	"64BIT_COOKIE" })
+
 TRACE_EVENT(nfsd_compound,
 	TP_PROTO(const struct svc_rqst *rqst,
 		 u32 args_opcnt),
@@ -392,6 +408,9 @@ TRACE_EVENT(nfsd_clid_inuse_err,
 		__entry->cl_boot, __entry->cl_id)
 )
 
+/*
+ * from fs/nfsd/filecache.h
+ */
 TRACE_DEFINE_ENUM(NFSD_FILE_HASHED);
 TRACE_DEFINE_ENUM(NFSD_FILE_PENDING);
 TRACE_DEFINE_ENUM(NFSD_FILE_BREAK_READ);
@@ -406,13 +425,6 @@ TRACE_DEFINE_ENUM(NFSD_FILE_REFERENCED);
 		{ 1 << NFSD_FILE_BREAK_WRITE,	"BREAK_WRITE" },	\
 		{ 1 << NFSD_FILE_REFERENCED,	"REFERENCED"})
 
-/* FIXME: This should probably be fleshed out in the future. */
-#define show_nf_may(val)						\
-	__print_flags(val, "|",						\
-		{ NFSD_MAY_READ,		"READ" },		\
-		{ NFSD_MAY_WRITE,		"WRITE" },		\
-		{ NFSD_MAY_NOT_BREAK_LEASE,	"NOT_BREAK_LEASE" })
-
 DECLARE_EVENT_CLASS(nfsd_file_class,
 	TP_PROTO(struct nfsd_file *nf),
 	TP_ARGS(nf),
@@ -437,7 +449,7 @@ DECLARE_EVENT_CLASS(nfsd_file_class,
 		__entry->nf_inode,
 		__entry->nf_ref,
 		show_nf_flags(__entry->nf_flags),
-		show_nf_may(__entry->nf_may),
+		show_nfsd_may_flags(__entry->nf_may),
 		__entry->nf_file)
 )
 
@@ -463,10 +475,10 @@ TRACE_EVENT(nfsd_file_acquire,
 		__field(u32, xid)
 		__field(unsigned int, hash)
 		__field(void *, inode)
-		__field(unsigned int, may_flags)
+		__field(unsigned long, may_flags)
 		__field(int, nf_ref)
 		__field(unsigned long, nf_flags)
-		__field(unsigned char, nf_may)
+		__field(unsigned long, nf_may)
 		__field(struct file *, nf_file)
 		__field(u32, status)
 	),
@@ -485,10 +497,10 @@ TRACE_EVENT(nfsd_file_acquire,
 
 	TP_printk("xid=0x%x hash=0x%x inode=0x%p may_flags=%s ref=%d nf_flags=%s nf_may=%s nf_file=0x%p status=%u",
 			__entry->xid, __entry->hash, __entry->inode,
-			show_nf_may(__entry->may_flags), __entry->nf_ref,
-			show_nf_flags(__entry->nf_flags),
-			show_nf_may(__entry->nf_may), __entry->nf_file,
-			__entry->status)
+			show_nfsd_may_flags(__entry->may_flags),
+			__entry->nf_ref, show_nf_flags(__entry->nf_flags),
+			show_nfsd_may_flags(__entry->nf_may),
+			__entry->nf_file, __entry->status)
 );
 
 DECLARE_EVENT_CLASS(nfsd_file_search_class,
Signature · 1 line
2.43.0
author maintainer
#6 lore raw

PATCH 6/770 NFSD: Remove extra "0x" in tracepoint format specifier

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 3a90e1dff16afdae6e1c918bfaff24f4d0f84869 ]

Clean up: %p adds its own 0x already.

---
 fs/nfsd/trace.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
fs/nfsd/trace.h +4 -4
index 7bb1c398daa51..9239d97b682c7 100644
@@ -444,7 +444,7 @@ DECLARE_EVENT_CLASS(nfsd_file_class,
 		__entry->nf_may = nf->nf_may;
 		__entry->nf_file = nf->nf_file;
 	),
-	TP_printk("hash=0x%x inode=0x%p ref=%d flags=%s may=%s file=%p",
+	TP_printk("hash=0x%x inode=%p ref=%d flags=%s may=%s file=%p",
 		__entry->nf_hashval,
 		__entry->nf_inode,
 		__entry->nf_ref,
@@ -495,7 +495,7 @@ TRACE_EVENT(nfsd_file_acquire,
 		__entry->status = be32_to_cpu(status);
 	),
 
-	TP_printk("xid=0x%x hash=0x%x inode=0x%p may_flags=%s ref=%d nf_flags=%s nf_may=%s nf_file=0x%p status=%u",
+	TP_printk("xid=0x%x hash=0x%x inode=%p may_flags=%s ref=%d nf_flags=%s nf_may=%s nf_file=%p status=%u",
 			__entry->xid, __entry->hash, __entry->inode,
 			show_nfsd_may_flags(__entry->may_flags),
 			__entry->nf_ref, show_nf_flags(__entry->nf_flags),
@@ -516,7 +516,7 @@ DECLARE_EVENT_CLASS(nfsd_file_search_class,
 		__entry->hash = hash;
 		__entry->found = found;
 	),
-	TP_printk("hash=0x%x inode=0x%p found=%d", __entry->hash,
+	TP_printk("hash=0x%x inode=%p found=%d", __entry->hash,
 			__entry->inode, __entry->found)
 );
 
@@ -544,7 +544,7 @@ TRACE_EVENT(nfsd_file_fsnotify_handle_event,
 		__entry->mode = inode->i_mode;
 		__entry->mask = mask;
 	),
-	TP_printk("inode=0x%p nlink=%u mode=0%ho mask=0x%x", __entry->inode,
+	TP_printk("inode=%p nlink=%u mode=0%ho mask=0x%x", __entry->inode,
 			__entry->nlink, __entry->mode, __entry->mask)
 );
 
Signature · 1 line
2.43.0
author maintainer
#7 lore raw

PATCH 7/770 NFSD: Add SPDX header for fs/nfsd/trace.c

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit f45a444cfe582b85af937a30d35d68d9a84399dd ]

Clean up.

The file was contributed in 2014 by Christoph Hellwig in commit 31ef83dc0538 ("nfsd: add trace events").

---
 fs/nfsd/trace.c | 1 +
 1 file changed, 1 insertion(+)
fs/nfsd/trace.c +1 -0
index 90967466a1e56..f008b95ceec2e 100644
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 
 #define CREATE_TRACE_POINTS
 #include "trace.h"
Signature · 1 line
2.43.0
author maintainer
#8 lore raw

PATCH 8/770 nfsd: Fix error return code in nfsd_file_cache_init()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Huang Guobin <[email protected]>

[ Upstream commit 231307df246eb29f30092836524ebb1fcb8f5b25 ]

Fix to return PTR_ERR() error code from the error handling case instead of 0 in function nfsd_file_cache_init(), as done elsewhere in this function.

Fixes 65294c1f2c5e7("nfsd: add a new struct file caching facility to nfsd")
---
 fs/nfsd/filecache.c | 1 +
 1 file changed, 1 insertion(+)
fs/nfsd/filecache.c +1 -0
index e30e1ddc1aceb..d0748ff04b92f 100644
@@ -684,6 +684,7 @@ nfsd_file_cache_init(void)
 	if (IS_ERR(nfsd_file_fsnotify_group)) {
 		pr_err("nfsd: unable to create fsnotify group: %ld\n",
 			PTR_ERR(nfsd_file_fsnotify_group));
+		ret = PTR_ERR(nfsd_file_fsnotify_group);
 		nfsd_file_fsnotify_group = NULL;
 		goto out_notifier;
 	}
Signature · 1 line
2.43.0
author maintainer
#9 lore raw

PATCH 9/770 SUNRPC: Add xdr_set_scratch_page() and xdr_reset_scratch_buffer()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 0ae4c3e8a64ace1b8d7de033b0751afe43024416 ]

Clean up: De-duplicate some frequently-used code.

---
 fs/nfs/blocklayout/blocklayout.c          |  2 +-
 fs/nfs/blocklayout/dev.c                  |  2 +-
 fs/nfs/dir.c                              |  2 +-
 fs/nfs/filelayout/filelayout.c            |  2 +-
 fs/nfs/filelayout/filelayoutdev.c         |  2 +-
 fs/nfs/flexfilelayout/flexfilelayout.c    |  2 +-
 fs/nfs/flexfilelayout/flexfilelayoutdev.c |  2 +-
 fs/nfs/nfs42xdr.c                         |  2 +-
 fs/nfs/nfs4xdr.c                          |  6 ++--
 fs/nfsd/nfs4proc.c                        |  2 +-
 include/linux/sunrpc/xdr.h                | 44 ++++++++++++++++++++++-
 net/sunrpc/auth_gss/gss_rpc_xdr.c         |  2 +-
 net/sunrpc/xdr.c                          | 28 +++------------
 13 files changed, 59 insertions(+), 39 deletions(-)
fs/nfs/blocklayout/blocklayout.c +1 -1
index 73000aa2d220b..a9e563145e0c2 100644
@@ -699,7 +699,7 @@ bl_alloc_lseg(struct pnfs_layout_hdr *lo, struct nfs4_layoutget_res *lgr,
 
 	xdr_init_decode_pages(&xdr, &buf,
 			lgr->layoutp->pages, lgr->layoutp->len);
-	xdr_set_scratch_buffer(&xdr, page_address(scratch), PAGE_SIZE);
+	xdr_set_scratch_page(&xdr, scratch);
 
 	status = -EIO;
 	p = xdr_inline_decode(&xdr, 4);
fs/nfs/blocklayout/dev.c +1 -1
index 6e3a14fdff9c8..16412d6636e86 100644
@@ -510,7 +510,7 @@ bl_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev,
 		goto out;
 
 	xdr_init_decode_pages(&xdr, &buf, pdev->pages, pdev->pglen);
-	xdr_set_scratch_buffer(&xdr, page_address(scratch), PAGE_SIZE);
+	xdr_set_scratch_page(&xdr, scratch);
 
 	p = xdr_inline_decode(&xdr, sizeof(__be32));
 	if (!p)
fs/nfs/dir.c +1 -1
index 9f88ca7b20015..935029632d5f6 100644
@@ -576,7 +576,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en
 		goto out_nopages;
 
 	xdr_init_decode_pages(&stream, &buf, xdr_pages, buflen);
-	xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);
+	xdr_set_scratch_page(&stream, scratch);
 
 	do {
 		if (entry->label)
fs/nfs/filelayout/filelayout.c +1 -1
index deecfb50dd7e3..45eec08ec904f 100644
@@ -666,7 +666,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo,
 		return -ENOMEM;
 
 	xdr_init_decode_pages(&stream, &buf, lgr->layoutp->pages, lgr->layoutp->len);
-	xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);
+	xdr_set_scratch_page(&stream, scratch);
 
 	/* 20 = ufl_util (4), first_stripe_index (4), pattern_offset (8),
 	 * num_fh (4) */
fs/nfs/filelayout/filelayoutdev.c +1 -1
index d913e818858f3..86c3f7e69ec42 100644
@@ -82,7 +82,7 @@ nfs4_fl_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev,
 		goto out_err;
 
 	xdr_init_decode_pages(&stream, &buf, pdev->pages, pdev->pglen);
-	xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);
+	xdr_set_scratch_page(&stream, scratch);
 
 	/* Get the stripe count (number of stripe index) */
 	p = xdr_inline_decode(&stream, 4);
fs/nfs/flexfilelayout/flexfilelayout.c +1 -1
index e4f2820ba5a59..f2ae271fe7ec7 100644
@@ -378,7 +378,7 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,
 
 	xdr_init_decode_pages(&stream, &buf, lgr->layoutp->pages,
 			      lgr->layoutp->len);
-	xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);
+	xdr_set_scratch_page(&stream, scratch);
 
 	/* stripe unit and mirror_array_cnt */
 	rc = -EIO;
fs/nfs/flexfilelayout/flexfilelayoutdev.c +1 -1
index 1f12297109b41..bfa7202ca7be1 100644
@@ -69,7 +69,7 @@ nfs4_ff_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev,
 	INIT_LIST_HEAD(&dsaddrs);
 
 	xdr_init_decode_pages(&stream, &buf, pdev->pages, pdev->pglen);
-	xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);
+	xdr_set_scratch_page(&stream, scratch);
 
 	/* multipath count */
 	p = xdr_inline_decode(&stream, 4);
fs/nfs/nfs42xdr.c +1 -1
index f2248d9d4db51..df5bee2f505c4 100644
@@ -1536,7 +1536,7 @@ static int nfs4_xdr_dec_listxattrs(struct rpc_rqst *rqstp,
 	struct compound_hdr hdr;
 	int status;
 
-	xdr_set_scratch_buffer(xdr, page_address(res->scratch), PAGE_SIZE);
+	xdr_set_scratch_page(xdr, res->scratch);
 
 	status = decode_compound_hdr(xdr, &hdr);
 	if (status)
fs/nfs/nfs4xdr.c +2 -4
index f1e599553f2be..4e5c6cb770ad5 100644
@@ -6404,10 +6404,8 @@ nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
 	struct compound_hdr hdr;
 	int status;
 
-	if (res->acl_scratch != NULL) {
-		void *p = page_address(res->acl_scratch);
-		xdr_set_scratch_buffer(xdr, p, PAGE_SIZE);
-	}
+	if (res->acl_scratch != NULL)
+		xdr_set_scratch_page(xdr, res->acl_scratch);
 	status = decode_compound_hdr(xdr, &hdr);
 	if (status)
 		goto out;
fs/nfsd/nfs4proc.c +1 -1
index e84996c3867c7..c01b6f7462fcb 100644
@@ -2266,7 +2266,7 @@ static void svcxdr_init_encode(struct svc_rqst *rqstp,
 	xdr->end = head->iov_base + PAGE_SIZE - rqstp->rq_auth_slack;
 	/* Tail and page_len should be zero at this point: */
 	buf->len = buf->head[0].iov_len;
-	xdr->scratch.iov_len = 0;
+	xdr_reset_scratch_buffer(xdr);
 	xdr->page_ptr = buf->pages - 1;
 	buf->buflen = PAGE_SIZE * (1 + rqstp->rq_page_end - buf->pages)
 		- rqstp->rq_auth_slack;
include/linux/sunrpc/xdr.h +43 -1

56 lines not on this page · raw message

net/sunrpc/auth_gss/gss_rpc_xdr.c +1 -1
index e265b8d38aa14..a857fc99431ce 100644
@@ -800,7 +800,7 @@ int gssx_dec_accept_sec_context(struct rpc_rqst *rqstp,
 	scratch = alloc_page(GFP_KERNEL);
 	if (!scratch)
 		return -ENOMEM;
-	xdr_set_scratch_buffer(xdr, page_address(scratch), PAGE_SIZE);
+	xdr_set_scratch_page(xdr, scratch);
 
 	/* res->status */
 	err = gssx_dec_status(xdr, &res->status);
net/sunrpc/xdr.c +4 -24
index d84bb5037bb5b..02adc5c7f034d 100644
@@ -669,7 +669,7 @@ void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p,
 	struct kvec *iov = buf->head;
 	int scratch_len = buf->buflen - buf->page_len - buf->tail[0].iov_len;
 
-	xdr_set_scratch_buffer(xdr, NULL, 0);
+	xdr_reset_scratch_buffer(xdr);
 	BUG_ON(scratch_len < 0);
 	xdr->buf = buf;
 	xdr->iov = iov;
@@ -713,7 +713,7 @@ inline void xdr_commit_encode(struct xdr_stream *xdr)
 	page = page_address(*xdr->page_ptr);
 	memcpy(xdr->scratch.iov_base, page, shift);
 	memmove(page, page + shift, (void *)xdr->p - page);
-	xdr->scratch.iov_len = 0;
+	xdr_reset_scratch_buffer(xdr);
 }
 EXPORT_SYMBOL_GPL(xdr_commit_encode);
 
@@ -743,8 +743,7 @@ static __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr,
 	 * the "scratch" iov to track any temporarily unused fragment of
 	 * space at the end of the previous buffer:
 	 */
-	xdr->scratch.iov_base = xdr->p;
-	xdr->scratch.iov_len = frag1bytes;
+	xdr_set_scratch_buffer(xdr, xdr->p, frag1bytes);
 	p = page_address(*xdr->page_ptr);
 	/*
 	 * Note this is where the next encode will start after we've
@@ -1056,8 +1055,7 @@ void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p,
 		     struct rpc_rqst *rqst)
 {
 	xdr->buf = buf;
-	xdr->scratch.iov_base = NULL;
-	xdr->scratch.iov_len = 0;
+	xdr_reset_scratch_buffer(xdr);
 	xdr->nwords = XDR_QUADLEN(buf->len);
 	if (buf->head[0].iov_len != 0)
 		xdr_set_iov(xdr, buf->head, buf->len);
@@ -1105,24 +1103,6 @@ static __be32 * __xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes)
 	return p;
 }
 
-/**
- * xdr_set_scratch_buffer - Attach a scratch buffer for decoding data.
- * @xdr: pointer to xdr_stream struct
- * @buf: pointer to an empty buffer
- * @buflen: size of 'buf'
- *
- * The scratch buffer is used when decoding from an array of pages.
- * If an xdr_inline_decode() call spans across page boundaries, then
- * we copy the data into the scratch buffer in order to allow linear
- * access.
- */
-void xdr_set_scratch_buffer(struct xdr_stream *xdr, void *buf, size_t buflen)
-{
-	xdr->scratch.iov_base = buf;
-	xdr->scratch.iov_len = buflen;
-}
-EXPORT_SYMBOL_GPL(xdr_set_scratch_buffer);
-
 static __be32 *xdr_copy_to_scratch(struct xdr_stream *xdr, size_t nbytes)
 {
 	__be32 *p;
Signature · 1 line
2.43.0
author maintainer
#10 lore raw

PATCH 10/770 SUNRPC: Prepare for xdr_stream-style decoding on the server-side

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 5191955d6fc65e6d4efe8f4f10a6028298f57281 ]

A "permanent" struct xdr_stream is allocated in struct svc_rqst so that it is usable by all server-side decoders. A per-rqst scratch buffer is also allocated to handle decoding XDR data items that cross page boundaries.

To demonstrate how it will be used, add the first call site for the new svcxdr_init_decode() API.

As an additional part of the overall conversion, add symbolic constants for successful and failed XDR operations. Returning "0" is overloaded. Sometimes it means something failed, but sometimes it means success. To make it more clear when XDR decoding functions succeed or fail, introduce symbolic constants.

---
 fs/nfsd/nfssvc.c           |  2 ++
 include/linux/sunrpc/svc.h | 16 ++++++++++++++++
 net/sunrpc/svc.c           |  5 +++++
 3 files changed, 23 insertions(+)
fs/nfsd/nfssvc.c +2 -0
index 2e61a565cdbd8..311b287c5024f 100644
@@ -1052,6 +1052,8 @@ int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
 	 * (necessary in the NFSv4.0 compound case)
 	 */
 	rqstp->rq_cachetype = proc->pc_cachetype;
+
+	svcxdr_init_decode(rqstp);
 	if (!proc->pc_decode(rqstp, argv->iov_base))
 		goto out_decode_err;
 
include/linux/sunrpc/svc.h +16 -0
index c220b734fa69e..34c2a69820e93 100644
@@ -247,6 +247,8 @@ struct svc_rqst {
 
 	size_t			rq_xprt_hlen;	/* xprt header len */
 	struct xdr_buf		rq_arg;
+	struct xdr_stream	rq_arg_stream;
+	struct page		*rq_scratch_page;
 	struct xdr_buf		rq_res;
 	struct page		*rq_pages[RPCSVC_MAXPAGES + 1];
 	struct page *		*rq_respages;	/* points into rq_pages */
@@ -557,4 +559,18 @@ static inline void svc_reserve_auth(struct svc_rqst *rqstp, int space)
 	svc_reserve(rqstp, space + rqstp->rq_auth_slack);
 }
 
+/**
+ * svcxdr_init_decode - Prepare an xdr_stream for svc Call decoding
+ * @rqstp: controlling server RPC transaction context
+ *
+ */
+static inline void svcxdr_init_decode(struct svc_rqst *rqstp)
+{
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
+	struct kvec *argv = rqstp->rq_arg.head;
+
+	xdr_init_decode(xdr, &rqstp->rq_arg, argv->iov_base, NULL);
+	xdr_set_scratch_page(xdr, rqstp->rq_scratch_page);
+}
+
 #endif /* SUNRPC_SVC_H */
net/sunrpc/svc.c +5 -0
index e4e4e203ecdad..73e02ba4ed53a 100644
@@ -614,6 +614,10 @@ svc_rqst_alloc(struct svc_serv *serv, struct svc_pool *pool, int node)
 	rqstp->rq_server = serv;
 	rqstp->rq_pool = pool;
 
+	rqstp->rq_scratch_page = alloc_pages_node(node, GFP_KERNEL, 0);
+	if (!rqstp->rq_scratch_page)
+		goto out_enomem;
+
 	rqstp->rq_argp = kmalloc_node(serv->sv_xdrsize, GFP_KERNEL, node);
 	if (!rqstp->rq_argp)
 		goto out_enomem;
@@ -846,6 +850,7 @@ void
 svc_rqst_free(struct svc_rqst *rqstp)
 {
 	svc_release_buffer(rqstp);
+	put_page(rqstp->rq_scratch_page);
 	kfree(rqstp->rq_resp);
 	kfree(rqstp->rq_argp);
 	kfree(rqstp->rq_auth_data);
Signature · 1 line
2.43.0
author maintainer
#11 lore raw

PATCH 11/770 NFSD: Add common helpers to decode void args and encode void results

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 788f7183fba86b46074c16e7d57ea09302badff4 ]

Start off the conversion to xdr_stream by de-duplicating the functions that decode void arguments and encode void results.

---
 fs/nfsd/nfs2acl.c  | 21 ++++-----------------
 fs/nfsd/nfs3acl.c  |  8 ++++----
 fs/nfsd/nfs3proc.c | 10 ++++------
 fs/nfsd/nfs3xdr.c  | 11 -----------
 fs/nfsd/nfs4proc.c | 11 ++++-------
 fs/nfsd/nfs4xdr.c  | 12 ------------
 fs/nfsd/nfsd.h     |  8 ++++++++
 fs/nfsd/nfsproc.c  | 25 ++++++++++++-------------
 fs/nfsd/nfssvc.c   | 28 ++++++++++++++++++++++++++++
 fs/nfsd/nfsxdr.c   | 10 ----------
 fs/nfsd/xdr.h      |  2 --
 fs/nfsd/xdr3.h     |  2 --
 fs/nfsd/xdr4.h     |  2 --
 13 files changed, 64 insertions(+), 86 deletions(-)
fs/nfsd/nfs2acl.c +4 -17
index 6a900f770dd23..b0f66604532a5 100644
@@ -185,10 +185,6 @@ static __be32 nfsacld_proc_access(struct svc_rqst *rqstp)
 /*
  * XDR decode functions
  */
-static int nfsaclsvc_decode_voidarg(struct svc_rqst *rqstp, __be32 *p)
-{
-	return 1;
-}
 
 static int nfsaclsvc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p)
 {
@@ -255,15 +251,6 @@ static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p)
  * XDR encode functions
  */
 
-/*
- * There must be an encoding function for void results so svc_process
- * will work properly.
- */
-static int nfsaclsvc_encode_voidres(struct svc_rqst *rqstp, __be32 *p)
-{
-	return xdr_ressize_check(rqstp, p);
-}
-
 /* GETACL */
 static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p)
 {
@@ -378,10 +365,10 @@ struct nfsd3_voidargs { int dummy; };
 static const struct svc_procedure nfsd_acl_procedures2[5] = {
 	[ACLPROC2_NULL] = {
 		.pc_func = nfsacld_proc_null,
-		.pc_decode = nfsaclsvc_decode_voidarg,
-		.pc_encode = nfsaclsvc_encode_voidres,
-		.pc_argsize = sizeof(struct nfsd3_voidargs),
-		.pc_ressize = sizeof(struct nfsd3_voidargs),
+		.pc_decode = nfssvc_decode_voidarg,
+		.pc_encode = nfssvc_encode_voidres,
+		.pc_argsize = sizeof(struct nfsd_voidargs),
+		.pc_ressize = sizeof(struct nfsd_voidres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST,
 	},
fs/nfsd/nfs3acl.c +4 -4
index 34a394e50e1d1..7c30876a31a1b 100644
@@ -245,10 +245,10 @@ struct nfsd3_voidargs { int dummy; };
 static const struct svc_procedure nfsd_acl_procedures3[3] = {
 	[ACLPROC3_NULL] = {
 		.pc_func = nfsd3_proc_null,
-		.pc_decode = nfs3svc_decode_voidarg,
-		.pc_encode = nfs3svc_encode_voidres,
-		.pc_argsize = sizeof(struct nfsd3_voidargs),
-		.pc_ressize = sizeof(struct nfsd3_voidargs),
+		.pc_decode = nfssvc_decode_voidarg,
+		.pc_encode = nfssvc_encode_voidres,
+		.pc_argsize = sizeof(struct nfsd_voidargs),
+		.pc_ressize = sizeof(struct nfsd_voidres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST,
 	},
fs/nfsd/nfs3proc.c +4 -6
index eba84417406ca..3257233d1a655 100644
@@ -697,8 +697,6 @@ nfsd3_proc_commit(struct svc_rqst *rqstp)
 #define nfsd3_attrstatres		nfsd3_attrstat
 #define nfsd3_wccstatres		nfsd3_attrstat
 #define nfsd3_createres			nfsd3_diropres
-#define nfsd3_voidres			nfsd3_voidargs
-struct nfsd3_voidargs { int dummy; };
 
 #define ST 1		/* status*/
 #define FH 17		/* filehandle with length */
@@ -709,10 +707,10 @@ struct nfsd3_voidargs { int dummy; };
 static const struct svc_procedure nfsd_procedures3[22] = {
 	[NFS3PROC_NULL] = {
 		.pc_func = nfsd3_proc_null,
-		.pc_decode = nfs3svc_decode_voidarg,
-		.pc_encode = nfs3svc_encode_voidres,
-		.pc_argsize = sizeof(struct nfsd3_voidargs),
-		.pc_ressize = sizeof(struct nfsd3_voidres),
+		.pc_decode = nfssvc_decode_voidarg,
+		.pc_encode = nfssvc_encode_voidres,
+		.pc_argsize = sizeof(struct nfsd_voidargs),
+		.pc_ressize = sizeof(struct nfsd_voidres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST,
 	},
fs/nfsd/nfs3xdr.c +0 -11
index 27b24823f7c42..0d75d201db1b3 100644
@@ -304,11 +304,6 @@ void fill_post_wcc(struct svc_fh *fhp)
 /*
  * XDR decode functions
  */
-int
-nfs3svc_decode_voidarg(struct svc_rqst *rqstp, __be32 *p)
-{
-	return 1;
-}
 
 int
 nfs3svc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p)
@@ -642,12 +637,6 @@ nfs3svc_decode_commitargs(struct svc_rqst *rqstp, __be32 *p)
  * XDR encode functions
  */
 
-int
-nfs3svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p)
-{
-	return xdr_ressize_check(rqstp, p);
-}
-
 /* GETATTR */
 int
 nfs3svc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p)
fs/nfsd/nfs4proc.c +4 -7
index c01b6f7462fcb..55a46e7c152b9 100644
@@ -3285,16 +3285,13 @@ static const char *nfsd4_op_name(unsigned opnum)
 	return "unknown_operation";
 }
 
-#define nfsd4_voidres			nfsd4_voidargs
-struct nfsd4_voidargs { int dummy; };
-
 static const struct svc_procedure nfsd_procedures4[2] = {
 	[NFSPROC4_NULL] = {
 		.pc_func = nfsd4_proc_null,
-		.pc_decode = nfs4svc_decode_voidarg,
-		.pc_encode = nfs4svc_encode_voidres,
-		.pc_argsize = sizeof(struct nfsd4_voidargs),
-		.pc_ressize = sizeof(struct nfsd4_voidres),
+		.pc_decode = nfssvc_decode_voidarg,
+		.pc_encode = nfssvc_encode_voidres,
+		.pc_argsize = sizeof(struct nfsd_voidargs),
+		.pc_ressize = sizeof(struct nfsd_voidres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = 1,
 	},
fs/nfsd/nfs4xdr.c +0 -12
index fd9107332a20f..c176d0090f7c8 100644
@@ -5288,12 +5288,6 @@ nfsd4_encode_replay(struct xdr_stream *xdr, struct nfsd4_op *op)
 	p = xdr_encode_opaque_fixed(p, rp->rp_buf, rp->rp_buflen);
 }
 
-int
-nfs4svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p)
-{
-        return xdr_ressize_check(rqstp, p);
-}
-
 void nfsd4_release_compoundargs(struct svc_rqst *rqstp)
 {
 	struct nfsd4_compoundargs *args = rqstp->rq_argp;
@@ -5311,12 +5305,6 @@ void nfsd4_release_compoundargs(struct svc_rqst *rqstp)
 	}
 }
 
-int
-nfs4svc_decode_voidarg(struct svc_rqst *rqstp, __be32 *p)
-{
-	return 1;
-}
-
 int
 nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p)
 {
fs/nfsd/nfsd.h +8 -0
index 4362d295ed340..3eaa81e001f9c 100644
@@ -73,6 +73,14 @@ extern unsigned long		nfsd_drc_mem_used;
 
 extern const struct seq_operations nfs_exports_op;
 
+/*
+ * Common void argument and result helpers
+ */
+struct nfsd_voidargs { };
+struct nfsd_voidres { };
+int		nfssvc_decode_voidarg(struct svc_rqst *rqstp, __be32 *p);
+int		nfssvc_encode_voidres(struct svc_rqst *rqstp, __be32 *p);
+
 /*
  * Function prototypes.
  */
fs/nfsd/nfsproc.c +12 -13
index bbd01e8397f6e..dbd8d36046539 100644
@@ -609,7 +609,6 @@ nfsd_proc_statfs(struct svc_rqst *rqstp)
  * NFSv2 Server procedures.
  * Only the results of non-idempotent operations are cached.
  */
-struct nfsd_void { int dummy; };
 
 #define ST 1		/* status */
 #define FH 8		/* filehandle */
@@ -618,10 +617,10 @@ struct nfsd_void { int dummy; };
 static const struct svc_procedure nfsd_procedures2[18] = {
 	[NFSPROC_NULL] = {
 		.pc_func = nfsd_proc_null,
-		.pc_decode = nfssvc_decode_void,
-		.pc_encode = nfssvc_encode_void,
-		.pc_argsize = sizeof(struct nfsd_void),
-		.pc_ressize = sizeof(struct nfsd_void),
+		.pc_decode = nfssvc_decode_voidarg,
+		.pc_encode = nfssvc_encode_voidres,
+		.pc_argsize = sizeof(struct nfsd_voidargs),
+		.pc_ressize = sizeof(struct nfsd_voidres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = 0,
 	},
@@ -647,10 +646,10 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 	},
 	[NFSPROC_ROOT] = {
 		.pc_func = nfsd_proc_root,
-		.pc_decode = nfssvc_decode_void,
-		.pc_encode = nfssvc_encode_void,
-		.pc_argsize = sizeof(struct nfsd_void),
-		.pc_ressize = sizeof(struct nfsd_void),
+		.pc_decode = nfssvc_decode_voidarg,
+		.pc_encode = nfssvc_encode_voidres,
+		.pc_argsize = sizeof(struct nfsd_voidargs),
+		.pc_ressize = sizeof(struct nfsd_voidres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = 0,
 	},
@@ -685,10 +684,10 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 	},
 	[NFSPROC_WRITECACHE] = {
 		.pc_func = nfsd_proc_writecache,
-		.pc_decode = nfssvc_decode_void,
-		.pc_encode = nfssvc_encode_void,
-		.pc_argsize = sizeof(struct nfsd_void),
-		.pc_ressize = sizeof(struct nfsd_void),
+		.pc_decode = nfssvc_decode_voidarg,
+		.pc_encode = nfssvc_encode_voidres,
+		.pc_argsize = sizeof(struct nfsd_voidargs),
+		.pc_ressize = sizeof(struct nfsd_voidres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = 0,
 	},
fs/nfsd/nfssvc.c +28 -0
index 311b287c5024f..c81d49b07971c 100644
@@ -1107,6 +1107,34 @@ int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
 	return 1;
 }
 
+/**
+ * nfssvc_decode_voidarg - Decode void arguments
+ * @rqstp: Server RPC transaction context
+ * @p: buffer containing arguments to decode
+ *
+ * Return values:
+ *   %0: Arguments were not valid
+ *   %1: Decoding was successful
+ */
+int nfssvc_decode_voidarg(struct svc_rqst *rqstp, __be32 *p)
+{
+	return 1;
+}
+
+/**
+ * nfssvc_encode_voidres - Encode void results
+ * @rqstp: Server RPC transaction context
+ * @p: buffer in which to encode results
+ *
+ * Return values:
+ *   %0: Local error while encoding
+ *   %1: Encoding was successful
+ */
+int nfssvc_encode_voidres(struct svc_rqst *rqstp, __be32 *p)
+{
+        return xdr_ressize_check(rqstp, p);
+}
+
 int nfsd_pool_stats_open(struct inode *inode, struct file *file)
 {
 	int ret;
fs/nfsd/nfsxdr.c +0 -10
index 9e00a902113e3..7aa6e8aca2c1a 100644
@@ -192,11 +192,6 @@ __be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *f
 /*
  * XDR decode functions
  */
-int
-nfssvc_decode_void(struct svc_rqst *rqstp, __be32 *p)
-{
-	return xdr_argsize_check(rqstp, p);
-}
 
 int
 nfssvc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p)
@@ -423,11 +418,6 @@ nfssvc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p)
 /*
  * XDR encode functions
  */
-int
-nfssvc_encode_void(struct svc_rqst *rqstp, __be32 *p)
-{
-	return xdr_ressize_check(rqstp, p);
-}
 
 int
 nfssvc_encode_stat(struct svc_rqst *rqstp, __be32 *p)
fs/nfsd/xdr.h +0 -2
index b8cc6a4b2e0ec..edd87688ff863 100644
@@ -144,7 +144,6 @@ union nfsd_xdrstore {
 #define NFS2_SVC_XDRSIZE	sizeof(union nfsd_xdrstore)
 
 
-int nfssvc_decode_void(struct svc_rqst *, __be32 *);
 int nfssvc_decode_fhandle(struct svc_rqst *, __be32 *);
 int nfssvc_decode_sattrargs(struct svc_rqst *, __be32 *);
 int nfssvc_decode_diropargs(struct svc_rqst *, __be32 *);
@@ -156,7 +155,6 @@ int nfssvc_decode_readlinkargs(struct svc_rqst *, __be32 *);
 int nfssvc_decode_linkargs(struct svc_rqst *, __be32 *);
 int nfssvc_decode_symlinkargs(struct svc_rqst *, __be32 *);
 int nfssvc_decode_readdirargs(struct svc_rqst *, __be32 *);
-int nfssvc_encode_void(struct svc_rqst *, __be32 *);
 int nfssvc_encode_stat(struct svc_rqst *, __be32 *);
 int nfssvc_encode_attrstat(struct svc_rqst *, __be32 *);
 int nfssvc_encode_diropres(struct svc_rqst *, __be32 *);
fs/nfsd/xdr3.h +0 -2
index ae6fa6c9cb467..456fcd7a10383 100644
@@ -273,7 +273,6 @@ union nfsd3_xdrstore {
 
 #define NFS3_SVC_XDRSIZE		sizeof(union nfsd3_xdrstore)
 
-int nfs3svc_decode_voidarg(struct svc_rqst *, __be32 *);
 int nfs3svc_decode_fhandle(struct svc_rqst *, __be32 *);
 int nfs3svc_decode_sattrargs(struct svc_rqst *, __be32 *);
 int nfs3svc_decode_diropargs(struct svc_rqst *, __be32 *);
@@ -290,7 +289,6 @@ int nfs3svc_decode_symlinkargs(struct svc_rqst *, __be32 *);
 int nfs3svc_decode_readdirargs(struct svc_rqst *, __be32 *);
 int nfs3svc_decode_readdirplusargs(struct svc_rqst *, __be32 *);
 int nfs3svc_decode_commitargs(struct svc_rqst *, __be32 *);
-int nfs3svc_encode_voidres(struct svc_rqst *, __be32 *);
 int nfs3svc_encode_attrstat(struct svc_rqst *, __be32 *);
 int nfs3svc_encode_wccstat(struct svc_rqst *, __be32 *);
 int nfs3svc_encode_diropres(struct svc_rqst *, __be32 *);
fs/nfsd/xdr4.h +0 -2
index 679d40af1bbb1..37f89ad5e9923 100644
@@ -781,8 +781,6 @@ set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
 
 
 bool nfsd4_mach_creds_match(struct nfs4_client *cl, struct svc_rqst *rqstp);
-int nfs4svc_decode_voidarg(struct svc_rqst *, __be32 *);
-int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *);
 int nfs4svc_decode_compoundargs(struct svc_rqst *, __be32 *);
 int nfs4svc_encode_compoundres(struct svc_rqst *, __be32 *);
 __be32 nfsd4_check_resp_size(struct nfsd4_compoundres *, u32);
Signature · 1 line
2.43.0
author maintainer
#12 lore raw

PATCH 12/770 NFSD: Add tracepoints in nfsd_dispatch()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 0dfdad1c1d1b77b9b085f4da390464dd0ac5647a ]

For troubleshooting purposes, record GARBAGE_ARGS and CANT_ENCODE failures.

---
 fs/nfsd/nfssvc.c | 17 ++++----------
 fs/nfsd/trace.h  | 60 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+), 12 deletions(-)
fs/nfsd/nfssvc.c +5 -12
index c81d49b07971c..3fb9607d67a37 100644
@@ -29,6 +29,8 @@
 #include "netns.h"
 #include "filecache.h"
 
+#include "trace.h"
+
 #define NFSDDBG_FACILITY	NFSDDBG_SVC
 
 bool inter_copy_offload_enable;
@@ -1041,11 +1043,8 @@ int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
 	struct kvec *resv = &rqstp->rq_res.head[0];
 	__be32 *p;
 
-	dprintk("nfsd_dispatch: vers %d proc %d\n",
-				rqstp->rq_vers, rqstp->rq_proc);
-
 	if (nfs_request_too_big(rqstp, proc))
-		goto out_too_large;
+		goto out_decode_err;
 
 	/*
 	 * Give the xdr decoder a chance to change this if it wants
@@ -1084,24 +1083,18 @@ int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
 out_cached_reply:
 	return 1;
 
-out_too_large:
-	dprintk("nfsd: NFSv%d argument too large\n", rqstp->rq_vers);
-	*statp = rpc_garbage_args;
-	return 1;
-
 out_decode_err:
-	dprintk("nfsd: failed to decode arguments!\n");
+	trace_nfsd_garbage_args_err(rqstp);
 	*statp = rpc_garbage_args;
 	return 1;
 
 out_update_drop:
-	dprintk("nfsd: Dropping request; may be revisited later\n");
 	nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
 out_dropit:
 	return 0;
 
 out_encode_err:
-	dprintk("nfsd: failed to encode result!\n");
+	trace_nfsd_cant_encode_err(rqstp);
 	nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
 	*statp = rpc_system_err;
 	return 1;
fs/nfsd/trace.h +60 -0

66 lines not on this page · raw message

Signature · 1 line
2.43.0
author maintainer
#13 lore raw

PATCH 13/770 NFSD: Add tracepoints in nfsd4_decode/encode_compound()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 08281341be8ebc97ee47999812bcf411942baa1e ]

For troubleshooting purposes, record failures to decode NFSv4 operation arguments and encode operation results.

trace_nfsd_compound_decode_err() replaces the dprintk() call sites that are embedded in READ_* macros that are about to be removed.

---
 fs/nfsd/nfs4xdr.c | 13 +++++++--
 fs/nfsd/trace.h   | 68 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+), 2 deletions(-)
fs/nfsd/nfs4xdr.c +11 -2
index c176d0090f7c8..101ada3636b78 100644
@@ -54,6 +54,8 @@
 #include "pnfs.h"
 #include "filecache.h"
 
+#include "trace.h"
+
 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
 #include <linux/security.h>
 #endif
@@ -2248,9 +2250,14 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
 		READ_BUF(4);
 		op->opnum = be32_to_cpup(p++);
 
-		if (nfsd4_opnum_in_range(argp, op))
+		if (nfsd4_opnum_in_range(argp, op)) {
 			op->status = nfsd4_dec_ops[op->opnum](argp, &op->u);
-		else {
+			if (op->status != nfs_ok)
+				trace_nfsd_compound_decode_err(argp->rqstp,
+							       argp->opcnt, i,
+							       op->opnum,
+							       op->status);
+		} else {
 			op->opnum = OP_ILLEGAL;
 			op->status = nfserr_op_illegal;
 		}
@@ -5220,6 +5227,8 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
 	       !nfsd4_enc_ops[op->opnum]);
 	encoder = nfsd4_enc_ops[op->opnum];
 	op->status = encoder(resp, op->status, &op->u);
+	if (op->status)
+		trace_nfsd_compound_encode_err(rqstp, op->opnum, op->status);
 	if (opdesc && opdesc->op_release)
 		opdesc->op_release(&op->u);
 	xdr_commit_encode(xdr);
fs/nfsd/trace.h +68 -0

80 lines not on this page · raw message

Signature · 1 line
2.43.0
author maintainer
#14 lore raw

PATCH 14/770 NFSD: Replace the internals of the READ_BUF() macro

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit c1346a1216ab5cb04a265380ac9035d91b16b6d5 ]

Convert the READ_BUF macro in nfs4xdr.c from open code to instead use the new xdr_stream-style decoders already in use by the encode side (and by the in-kernel NFS client implementation). Once this conversion is done, each individual NFSv4 argument decoder can be independently cleaned up to replace these macros with C code.

---
 fs/nfsd/nfs4proc.c         |   4 +-
 fs/nfsd/nfs4xdr.c          | 181 ++++++-------------------------------
 fs/nfsd/xdr4.h             |  10 +-
 include/linux/sunrpc/xdr.h |   2 +
 net/sunrpc/xdr.c           |  45 +++++++++
 5 files changed, 77 insertions(+), 165 deletions(-)
fs/nfsd/nfs4proc.c +2 -2
index 55a46e7c152b9..95545a61bfc77 100644
@@ -1024,8 +1024,8 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 
 	write->wr_how_written = write->wr_stable_how;
 
-	nvecs = svc_fill_write_vector(rqstp, write->wr_pagelist,
-				      &write->wr_head, write->wr_buflen);
+	nvecs = svc_fill_write_vector(rqstp, write->wr_payload.pages,
+				      write->wr_payload.head, write->wr_buflen);
 	WARN_ON_ONCE(nvecs > ARRAY_SIZE(rqstp->rq_vec));
 
 	status = nfsd_vfs_write(rqstp, &cstate->current_fh, nf,
fs/nfsd/nfs4xdr.c +26 -155

253 lines not on this page · raw message

fs/nfsd/xdr4.h +2 -8
index 37f89ad5e9923..0eb13bd603ea6 100644
@@ -419,8 +419,7 @@ struct nfsd4_write {
 	u64		wr_offset;          /* request */
 	u32		wr_stable_how;      /* request */
 	u32		wr_buflen;          /* request */
-	struct kvec	wr_head;
-	struct page **	wr_pagelist;        /* request */
+	struct xdr_buf	wr_payload;         /* request */
 
 	u32		wr_bytes_written;   /* response */
 	u32		wr_how_written;     /* response */
@@ -696,15 +695,10 @@ struct svcxdr_tmpbuf {
 
 struct nfsd4_compoundargs {
 	/* scratch variables for XDR decode */
-	__be32 *			p;
-	__be32 *			end;
-	struct page **			pagelist;
-	int				pagelen;
-	bool				tail;
 	__be32				tmp[8];
 	__be32 *			tmpp;
+	struct xdr_stream		*xdr;
 	struct svcxdr_tmpbuf		*to_free;
-
 	struct svc_rqst			*rqstp;
 
 	u32				taglen;
include/linux/sunrpc/xdr.h +2 -0
index 0c8cab6210b3b..c03f7bf585c96 100644
@@ -252,6 +252,8 @@ extern void xdr_enter_page(struct xdr_stream *xdr, unsigned int len);
 extern int xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len, int (*actor)(struct scatterlist *, void *), void *data);
 extern uint64_t xdr_align_data(struct xdr_stream *, uint64_t, uint32_t);
 extern uint64_t xdr_expand_hole(struct xdr_stream *, uint64_t, uint64_t);
+extern bool xdr_stream_subsegment(struct xdr_stream *xdr, struct xdr_buf *subbuf,
+				  unsigned int len);
 
 /**
  * xdr_set_scratch_buffer - Attach a scratch buffer for decoding data.
net/sunrpc/xdr.c +45 -0

51 lines not on this page · raw message

Signature · 1 line
2.43.0
author maintainer
#15 lore raw

PATCH 15/770 NFSD: Replace READ* macros in nfsd4_decode_access()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit d169a6a9e5fd7f9e4b74e5e5d2e5a4fd0f84ef05 ]

---
 fs/nfsd/nfs4xdr.c | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)
fs/nfsd/nfs4xdr.c +13 -11
index 8c694844f0efb..f3d54af9de92a 100644
@@ -439,17 +439,6 @@ nfsd4_decode_stateid(struct nfsd4_compoundargs *argp, stateid_t *sid)
 	DECODE_TAIL;
 }
 
-static __be32
-nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access)
-{
-	DECODE_HEAD;
-
-	READ_BUF(4);
-	access->ac_req_access = be32_to_cpup(p++);
-
-	DECODE_TAIL;
-}
-
 static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_cb_sec *cbs)
 {
 	DECODE_HEAD;
@@ -531,6 +520,19 @@ static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_
 	DECODE_TAIL;
 }
 
+/*
+ * NFSv4 operation argument decoders
+ */
+
+static __be32
+nfsd4_decode_access(struct nfsd4_compoundargs *argp,
+		    struct nfsd4_access *access)
+{
+	if (xdr_stream_decode_u32(argp->xdr, &access->ac_req_access) < 0)
+		return nfserr_bad_xdr;
+	return nfs_ok;
+}
+
 static __be32 nfsd4_decode_backchannel_ctl(struct nfsd4_compoundargs *argp, struct nfsd4_backchannel_ctl *bc)
 {
 	DECODE_HEAD;
Signature · 1 line
2.43.0
author maintainer
#16 lore raw

PATCH 16/770 NFSD: Replace READ* macros in nfsd4_decode_close()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit d3d2f38154571e70d5806b5c5264bf61c101ea15 ]

---
 fs/nfsd/nfs4xdr.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)
fs/nfsd/nfs4xdr.c +16 -7
index f3d54af9de92a..ca02478534931 100644
@@ -439,6 +439,19 @@ nfsd4_decode_stateid(struct nfsd4_compoundargs *argp, stateid_t *sid)
 	DECODE_TAIL;
 }
 
+static __be32
+nfsd4_decode_stateid4(struct nfsd4_compoundargs *argp, stateid_t *sid)
+{
+	__be32 *p;
+
+	p = xdr_inline_decode(argp->xdr, NFS4_STATEID_SIZE);
+	if (!p)
+		return nfserr_bad_xdr;
+	sid->si_generation = be32_to_cpup(p++);
+	memcpy(&sid->si_opaque, p, sizeof(sid->si_opaque));
+	return nfs_ok;
+}
+
 static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_cb_sec *cbs)
 {
 	DECODE_HEAD;
@@ -559,13 +572,9 @@ static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp,
 static __be32
 nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
 {
-	DECODE_HEAD;
-
-	READ_BUF(4);
-	close->cl_seqid = be32_to_cpup(p++);
-	return nfsd4_decode_stateid(argp, &close->cl_stateid);
-
-	DECODE_TAIL;
+	if (xdr_stream_decode_u32(argp->xdr, &close->cl_seqid) < 0)
+		return nfserr_bad_xdr;
+	return nfsd4_decode_stateid4(argp, &close->cl_stateid);
 }
 
 
Signature · 1 line
2.43.0
author maintainer
#17 lore raw

PATCH 17/770 NFSD: Replace READ* macros in nfsd4_decode_commit()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit cbd9abb3706e96563b36af67595707a7054ab693 ]

---
 fs/nfsd/nfs4xdr.c          | 12 +++++-------
 include/linux/sunrpc/xdr.h | 21 +++++++++++++++++++++
 2 files changed, 26 insertions(+), 7 deletions(-)
fs/nfsd/nfs4xdr.c +5 -7
index ca02478534931..8251b905d5479 100644
@@ -581,13 +581,11 @@ nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
 static __be32
 nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit)
 {
-	DECODE_HEAD;
-
-	READ_BUF(12);
-	p = xdr_decode_hyper(p, &commit->co_offset);
-	commit->co_count = be32_to_cpup(p++);
-
-	DECODE_TAIL;
+	if (xdr_stream_decode_u64(argp->xdr, &commit->co_offset) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u32(argp->xdr, &commit->co_count) < 0)
+		return nfserr_bad_xdr;
+	return nfs_ok;
 }
 
 static __be32
include/linux/sunrpc/xdr.h +21 -0
index c03f7bf585c96..6b17575437474 100644
@@ -569,6 +569,27 @@ xdr_stream_decode_u32(struct xdr_stream *xdr, __u32 *ptr)
 	return 0;
 }
 
+/**
+ * xdr_stream_decode_u64 - Decode a 64-bit integer
+ * @xdr: pointer to xdr_stream
+ * @ptr: location to store 64-bit integer
+ *
+ * Return values:
+ *   %0 on success
+ *   %-EBADMSG on XDR buffer overflow
+ */
+static inline ssize_t
+xdr_stream_decode_u64(struct xdr_stream *xdr, __u64 *ptr)
+{
+	const size_t count = sizeof(*ptr);
+	__be32 *p = xdr_inline_decode(xdr, count);
+
+	if (unlikely(!p))
+		return -EBADMSG;
+	xdr_decode_hyper(p, ptr);
+	return 0;
+}
+
 /**
  * xdr_stream_decode_opaque_fixed - Decode fixed length opaque xdr data
  * @xdr: pointer to xdr_stream
Signature · 1 line
2.43.0
author maintainer
#18 lore raw

PATCH 18/770 NFSD: Change the way the expected length of a fattr4 is checked

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 081d53fe0b43c47c36d1832b759bf14edde9cdbb ]

Because the fattr4 is now managed in an xdr_stream, all that is needed is to store the initial position of the stream before decoding the attribute list. Then the actual length of the list is computed using the final stream position, after decoding is complete.

No behavior change is expected.

---
 fs/nfsd/nfs4xdr.c | 34 +++++++++++-----------------------
 1 file changed, 11 insertions(+), 23 deletions(-)
fs/nfsd/nfs4xdr.c +11 -23
index 8251b905d5479..de5ac334cb8ab 100644
@@ -250,7 +250,8 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 		   struct iattr *iattr, struct nfs4_acl **acl,
 		   struct xdr_netobj *label, int *umask)
 {
-	int expected_len, len = 0;
+	unsigned int starting_pos;
+	u32 attrlist4_count;
 	u32 dummy32;
 	char *buf;
 
@@ -267,12 +268,12 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 		return nfserr_attrnotsupp;
 	}
 
-	READ_BUF(4);
-	expected_len = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &attrlist4_count) < 0)
+		return nfserr_bad_xdr;
+	starting_pos = xdr_stream_pos(argp->xdr);
 
 	if (bmval[0] & FATTR4_WORD0_SIZE) {
 		READ_BUF(8);
-		len += 8;
 		p = xdr_decode_hyper(p, &iattr->ia_size);
 		iattr->ia_valid |= ATTR_SIZE;
 	}
@@ -280,7 +281,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 		u32 nace;
 		struct nfs4_ace *ace;
 
-		READ_BUF(4); len += 4;
+		READ_BUF(4);
 		nace = be32_to_cpup(p++);
 
 		if (nace > xdr_stream_remaining(argp->xdr) / sizeof(struct nfs4_ace))
@@ -297,13 +298,12 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 
 		(*acl)->naces = nace;
 		for (ace = (*acl)->aces; ace < (*acl)->aces + nace; ace++) {
-			READ_BUF(16); len += 16;
+			READ_BUF(16);
 			ace->type = be32_to_cpup(p++);
 			ace->flag = be32_to_cpup(p++);
 			ace->access_mask = be32_to_cpup(p++);
 			dummy32 = be32_to_cpup(p++);
 			READ_BUF(dummy32);
-			len += XDR_QUADLEN(dummy32) << 2;
 			READMEM(buf, dummy32);
 			ace->whotype = nfs4_acl_get_whotype(buf, dummy32);
 			status = nfs_ok;
@@ -322,17 +322,14 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 		*acl = NULL;
 	if (bmval[1] & FATTR4_WORD1_MODE) {
 		READ_BUF(4);
-		len += 4;
 		iattr->ia_mode = be32_to_cpup(p++);
 		iattr->ia_mode &= (S_IFMT | S_IALLUGO);
 		iattr->ia_valid |= ATTR_MODE;
 	}
 	if (bmval[1] & FATTR4_WORD1_OWNER) {
 		READ_BUF(4);
-		len += 4;
 		dummy32 = be32_to_cpup(p++);
 		READ_BUF(dummy32);
-		len += (XDR_QUADLEN(dummy32) << 2);
 		READMEM(buf, dummy32);
 		if ((status = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid)))
 			return status;
@@ -340,10 +337,8 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 	}
 	if (bmval[1] & FATTR4_WORD1_OWNER_GROUP) {
 		READ_BUF(4);
-		len += 4;
 		dummy32 = be32_to_cpup(p++);
 		READ_BUF(dummy32);
-		len += (XDR_QUADLEN(dummy32) << 2);
 		READMEM(buf, dummy32);
 		if ((status = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid)))
 			return status;
@@ -351,11 +346,9 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 	}
 	if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) {
 		READ_BUF(4);
-		len += 4;
 		dummy32 = be32_to_cpup(p++);
 		switch (dummy32) {
 		case NFS4_SET_TO_CLIENT_TIME:
-			len += 12;
 			status = nfsd4_decode_time(argp, &iattr->ia_atime);
 			if (status)
 				return status;
@@ -370,11 +363,9 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 	}
 	if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) {
 		READ_BUF(4);
-		len += 4;
 		dummy32 = be32_to_cpup(p++);
 		switch (dummy32) {
 		case NFS4_SET_TO_CLIENT_TIME:
-			len += 12;
 			status = nfsd4_decode_time(argp, &iattr->ia_mtime);
 			if (status)
 				return status;
@@ -392,18 +383,14 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 	if (IS_ENABLED(CONFIG_NFSD_V4_SECURITY_LABEL) &&
 	    bmval[2] & FATTR4_WORD2_SECURITY_LABEL) {
 		READ_BUF(4);
-		len += 4;
 		dummy32 = be32_to_cpup(p++); /* lfs: we don't use it */
 		READ_BUF(4);
-		len += 4;
 		dummy32 = be32_to_cpup(p++); /* pi: we don't use it either */
 		READ_BUF(4);
-		len += 4;
 		dummy32 = be32_to_cpup(p++);
 		READ_BUF(dummy32);
 		if (dummy32 > NFS4_MAXLABELLEN)
 			return nfserr_badlabel;
-		len += (XDR_QUADLEN(dummy32) << 2);
 		READMEM(buf, dummy32);
 		label->len = dummy32;
 		label->data = svcxdr_dupstr(argp, buf, dummy32);
@@ -414,15 +401,16 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 		if (!umask)
 			goto xdr_error;
 		READ_BUF(8);
-		len += 8;
 		dummy32 = be32_to_cpup(p++);
 		iattr->ia_mode = dummy32 & (S_IFMT | S_IALLUGO);
 		dummy32 = be32_to_cpup(p++);
 		*umask = dummy32 & S_IRWXUGO;
 		iattr->ia_valid |= ATTR_MODE;
 	}
-	if (len != expected_len)
-		goto xdr_error;
+
+	/* request sanity: did attrlist4 contain the expected number of words? */
+	if (attrlist4_count != xdr_stream_pos(argp->xdr) - starting_pos)
+		return nfserr_bad_xdr;
 
 	DECODE_TAIL;
 }
Signature · 1 line
2.43.0
author maintainer
#19 lore raw

PATCH 19/770 NFSD: Replace READ* macros that decode the fattr4 size attribute

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 2ac1b9b2afbbacf597dbec722b23b6be62e4e41e ]

---
 fs/nfsd/nfs4xdr.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
fs/nfsd/nfs4xdr.c +5 -2
index de5ac334cb8ab..5ec0c2dac3348 100644
@@ -273,8 +273,11 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 	starting_pos = xdr_stream_pos(argp->xdr);
 
 	if (bmval[0] & FATTR4_WORD0_SIZE) {
-		READ_BUF(8);
-		p = xdr_decode_hyper(p, &iattr->ia_size);
+		u64 size;
+
+		if (xdr_stream_decode_u64(argp->xdr, &size) < 0)
+			return nfserr_bad_xdr;
+		iattr->ia_size = size;
 		iattr->ia_valid |= ATTR_SIZE;
 	}
 	if (bmval[0] & FATTR4_WORD0_ACL) {
Signature · 1 line
2.43.0
author maintainer
#20 lore raw

PATCH 20/770 NFSD: Replace READ* macros that decode the fattr4 acl attribute

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit c941a96823cf52e742606b486b81ab346bf111c9 ]

Refactor for clarity and to move infrequently-used code out of line.

---
 fs/nfsd/nfs4xdr.c | 107 +++++++++++++++++++++++++++++-----------------
 1 file changed, 67 insertions(+), 40 deletions(-)
fs/nfsd/nfs4xdr.c +67 -40
index 5ec0c2dac3348..0fe57ca0f31ac 100644
@@ -245,6 +245,70 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
 	DECODE_TAIL;
 }
 
+static __be32
+nfsd4_decode_nfsace4(struct nfsd4_compoundargs *argp, struct nfs4_ace *ace)
+{
+	__be32 *p, status;
+	u32 length;
+
+	if (xdr_stream_decode_u32(argp->xdr, &ace->type) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u32(argp->xdr, &ace->flag) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u32(argp->xdr, &ace->access_mask) < 0)
+		return nfserr_bad_xdr;
+
+	if (xdr_stream_decode_u32(argp->xdr, &length) < 0)
+		return nfserr_bad_xdr;
+	p = xdr_inline_decode(argp->xdr, length);
+	if (!p)
+		return nfserr_bad_xdr;
+	ace->whotype = nfs4_acl_get_whotype((char *)p, length);
+	if (ace->whotype != NFS4_ACL_WHO_NAMED)
+		status = nfs_ok;
+	else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
+		status = nfsd_map_name_to_gid(argp->rqstp,
+				(char *)p, length, &ace->who_gid);
+	else
+		status = nfsd_map_name_to_uid(argp->rqstp,
+				(char *)p, length, &ace->who_uid);
+
+	return status;
+}
+
+/* A counted array of nfsace4's */
+static noinline __be32
+nfsd4_decode_acl(struct nfsd4_compoundargs *argp, struct nfs4_acl **acl)
+{
+	struct nfs4_ace *ace;
+	__be32 status;
+	u32 count;
+
+	if (xdr_stream_decode_u32(argp->xdr, &count) < 0)
+		return nfserr_bad_xdr;
+
+	if (count > xdr_stream_remaining(argp->xdr) / 20)
+		/*
+		 * Even with 4-byte names there wouldn't be
+		 * space for that many aces; something fishy is
+		 * going on:
+		 */
+		return nfserr_fbig;
+
+	*acl = svcxdr_tmpalloc(argp, nfs4_acl_bytes(count));
+	if (*acl == NULL)
+		return nfserr_jukebox;
+
+	(*acl)->naces = count;
+	for (ace = (*acl)->aces; ace < (*acl)->aces + count; ace++) {
+		status = nfsd4_decode_nfsace4(argp, ace);
+		if (status)
+			return status;
+	}
+
+	return nfs_ok;
+}
+
 static __be32
 nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 		   struct iattr *iattr, struct nfs4_acl **acl,
@@ -281,46 +345,9 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 		iattr->ia_valid |= ATTR_SIZE;
 	}
 	if (bmval[0] & FATTR4_WORD0_ACL) {
-		u32 nace;
-		struct nfs4_ace *ace;
-
-		READ_BUF(4);
-		nace = be32_to_cpup(p++);
-
-		if (nace > xdr_stream_remaining(argp->xdr) / sizeof(struct nfs4_ace))
-			/*
-			 * Even with 4-byte names there wouldn't be
-			 * space for that many aces; something fishy is
-			 * going on:
-			 */
-			return nfserr_fbig;
-
-		*acl = svcxdr_tmpalloc(argp, nfs4_acl_bytes(nace));
-		if (*acl == NULL)
-			return nfserr_jukebox;
-
-		(*acl)->naces = nace;
-		for (ace = (*acl)->aces; ace < (*acl)->aces + nace; ace++) {
-			READ_BUF(16);
-			ace->type = be32_to_cpup(p++);
-			ace->flag = be32_to_cpup(p++);
-			ace->access_mask = be32_to_cpup(p++);
-			dummy32 = be32_to_cpup(p++);
-			READ_BUF(dummy32);
-			READMEM(buf, dummy32);
-			ace->whotype = nfs4_acl_get_whotype(buf, dummy32);
-			status = nfs_ok;
-			if (ace->whotype != NFS4_ACL_WHO_NAMED)
-				;
-			else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
-				status = nfsd_map_name_to_gid(argp->rqstp,
-						buf, dummy32, &ace->who_gid);
-			else
-				status = nfsd_map_name_to_uid(argp->rqstp,
-						buf, dummy32, &ace->who_uid);
-			if (status)
-				return status;
-		}
+		status = nfsd4_decode_acl(argp, acl);
+		if (status)
+			return status;
 	} else
 		*acl = NULL;
 	if (bmval[1] & FATTR4_WORD1_MODE) {
Signature · 1 line
2.43.0
author maintainer
#21 lore raw

PATCH 21/770 NFSD: Replace READ* macros that decode the fattr4 mode attribute

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 1c8f0ad7dd35fd12307904036c7c839f77b6e3f9 ]

---
 fs/nfsd/nfs4xdr.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
fs/nfsd/nfs4xdr.c +5 -2
index 0fe57ca0f31ac..9dc73ab95eac9 100644
@@ -351,8 +351,11 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 	} else
 		*acl = NULL;
 	if (bmval[1] & FATTR4_WORD1_MODE) {
-		READ_BUF(4);
-		iattr->ia_mode = be32_to_cpup(p++);
+		u32 mode;
+
+		if (xdr_stream_decode_u32(argp->xdr, &mode) < 0)
+			return nfserr_bad_xdr;
+		iattr->ia_mode = mode;
 		iattr->ia_mode &= (S_IFMT | S_IALLUGO);
 		iattr->ia_valid |= ATTR_MODE;
 	}
Signature · 1 line
2.43.0
author maintainer
#22 lore raw

PATCH 22/770 NFSD: Replace READ* macros that decode the fattr4 owner attribute

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 9853a5ac9be381917e9be0b4133cd4ac5a7ad875 ]

---
 fs/nfsd/nfs4xdr.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)
fs/nfsd/nfs4xdr.c +10 -5
index 9dc73ab95eac9..7dc6b79e51fd0 100644
@@ -360,11 +360,16 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 		iattr->ia_valid |= ATTR_MODE;
 	}
 	if (bmval[1] & FATTR4_WORD1_OWNER) {
-		READ_BUF(4);
-		dummy32 = be32_to_cpup(p++);
-		READ_BUF(dummy32);
-		READMEM(buf, dummy32);
-		if ((status = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid)))
+		u32 length;
+
+		if (xdr_stream_decode_u32(argp->xdr, &length) < 0)
+			return nfserr_bad_xdr;
+		p = xdr_inline_decode(argp->xdr, length);
+		if (!p)
+			return nfserr_bad_xdr;
+		status = nfsd_map_name_to_uid(argp->rqstp, (char *)p, length,
+					      &iattr->ia_uid);
+		if (status)
 			return status;
 		iattr->ia_valid |= ATTR_UID;
 	}
Signature · 1 line
2.43.0
author maintainer
#23 lore raw

PATCH 23/770 NFSD: Replace READ* macros that decode the fattr4 owner_group attribute

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 393c31dd27f83adb06b07a1b5f0a5b8966a0f01e ]

---
 fs/nfsd/nfs4xdr.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)
fs/nfsd/nfs4xdr.c +10 -5
index 7dc6b79e51fd0..979f1d384cd0f 100644
@@ -374,11 +374,16 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 		iattr->ia_valid |= ATTR_UID;
 	}
 	if (bmval[1] & FATTR4_WORD1_OWNER_GROUP) {
-		READ_BUF(4);
-		dummy32 = be32_to_cpup(p++);
-		READ_BUF(dummy32);
-		READMEM(buf, dummy32);
-		if ((status = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid)))
+		u32 length;
+
+		if (xdr_stream_decode_u32(argp->xdr, &length) < 0)
+			return nfserr_bad_xdr;
+		p = xdr_inline_decode(argp->xdr, length);
+		if (!p)
+			return nfserr_bad_xdr;
+		status = nfsd_map_name_to_gid(argp->rqstp, (char *)p, length,
+					      &iattr->ia_gid);
+		if (status)
 			return status;
 		iattr->ia_valid |= ATTR_GID;
 	}
Signature · 1 line
2.43.0
author maintainer
#24 lore raw

PATCH 24/770 NFSD: Replace READ* macros that decode the fattr4 time_set attributes

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 1c3eff7ea4a98c642134ee493001ae13b79ff38c ]

---
 fs/nfsd/nfs4xdr.c | 39 +++++++++++++++++++++++++++++----------
 1 file changed, 29 insertions(+), 10 deletions(-)
fs/nfsd/nfs4xdr.c +29 -10
index 979f1d384cd0f..09975786e71b2 100644
@@ -219,6 +219,21 @@ nfsd4_decode_time(struct nfsd4_compoundargs *argp, struct timespec64 *tv)
 	DECODE_TAIL;
 }
 
+static __be32
+nfsd4_decode_nfstime4(struct nfsd4_compoundargs *argp, struct timespec64 *tv)
+{
+	__be32 *p;
+
+	p = xdr_inline_decode(argp->xdr, XDR_UNIT * 3);
+	if (!p)
+		return nfserr_bad_xdr;
+	p = xdr_decode_hyper(p, &tv->tv_sec);
+	tv->tv_nsec = be32_to_cpup(p++);
+	if (tv->tv_nsec >= (u32)1000000000)
+		return nfserr_inval;
+	return nfs_ok;
+}
+
 static __be32
 nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
 {
@@ -388,11 +403,13 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 		iattr->ia_valid |= ATTR_GID;
 	}
 	if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) {
-		READ_BUF(4);
-		dummy32 = be32_to_cpup(p++);
-		switch (dummy32) {
+		u32 set_it;
+
+		if (xdr_stream_decode_u32(argp->xdr, &set_it) < 0)
+			return nfserr_bad_xdr;
+		switch (set_it) {
 		case NFS4_SET_TO_CLIENT_TIME:
-			status = nfsd4_decode_time(argp, &iattr->ia_atime);
+			status = nfsd4_decode_nfstime4(argp, &iattr->ia_atime);
 			if (status)
 				return status;
 			iattr->ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET);
@@ -401,15 +418,17 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 			iattr->ia_valid |= ATTR_ATIME;
 			break;
 		default:
-			goto xdr_error;
+			return nfserr_bad_xdr;
 		}
 	}
 	if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) {
-		READ_BUF(4);
-		dummy32 = be32_to_cpup(p++);
-		switch (dummy32) {
+		u32 set_it;
+
+		if (xdr_stream_decode_u32(argp->xdr, &set_it) < 0)
+			return nfserr_bad_xdr;
+		switch (set_it) {
 		case NFS4_SET_TO_CLIENT_TIME:
-			status = nfsd4_decode_time(argp, &iattr->ia_mtime);
+			status = nfsd4_decode_nfstime4(argp, &iattr->ia_mtime);
 			if (status)
 				return status;
 			iattr->ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET);
@@ -418,7 +437,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 			iattr->ia_valid |= ATTR_MTIME;
 			break;
 		default:
-			goto xdr_error;
+			return nfserr_bad_xdr;
 		}
 	}
 
Signature · 1 line
2.43.0
author maintainer
#25 lore raw

PATCH 25/770 NFSD: Replace READ* macros that decode the fattr4 security label attribute

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit dabe91828f92cd493e9e75efbc10f9878d2a73fe ]

---
 fs/nfsd/nfs4xdr.c | 46 ++++++++++++++++++++++++++++++----------------
 1 file changed, 30 insertions(+), 16 deletions(-)
fs/nfsd/nfs4xdr.c +30 -16
index 09975786e71b2..453a902c7490a 100644
@@ -324,6 +324,33 @@ nfsd4_decode_acl(struct nfsd4_compoundargs *argp, struct nfs4_acl **acl)
 	return nfs_ok;
 }
 
+static noinline __be32
+nfsd4_decode_security_label(struct nfsd4_compoundargs *argp,
+			    struct xdr_netobj *label)
+{
+	u32 lfs, pi, length;
+	__be32 *p;
+
+	if (xdr_stream_decode_u32(argp->xdr, &lfs) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u32(argp->xdr, &pi) < 0)
+		return nfserr_bad_xdr;
+
+	if (xdr_stream_decode_u32(argp->xdr, &length) < 0)
+		return nfserr_bad_xdr;
+	if (length > NFS4_MAXLABELLEN)
+		return nfserr_badlabel;
+	p = xdr_inline_decode(argp->xdr, length);
+	if (!p)
+		return nfserr_bad_xdr;
+	label->len = length;
+	label->data = svcxdr_dupstr(argp, p, length);
+	if (!label->data)
+		return nfserr_jukebox;
+
+	return nfs_ok;
+}
+
 static __be32
 nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 		   struct iattr *iattr, struct nfs4_acl **acl,
@@ -332,7 +359,6 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 	unsigned int starting_pos;
 	u32 attrlist4_count;
 	u32 dummy32;
-	char *buf;
 
 	DECODE_HEAD;
 	iattr->ia_valid = 0;
@@ -440,24 +466,12 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 			return nfserr_bad_xdr;
 		}
 	}
-
 	label->len = 0;
 	if (IS_ENABLED(CONFIG_NFSD_V4_SECURITY_LABEL) &&
 	    bmval[2] & FATTR4_WORD2_SECURITY_LABEL) {
-		READ_BUF(4);
-		dummy32 = be32_to_cpup(p++); /* lfs: we don't use it */
-		READ_BUF(4);
-		dummy32 = be32_to_cpup(p++); /* pi: we don't use it either */
-		READ_BUF(4);
-		dummy32 = be32_to_cpup(p++);
-		READ_BUF(dummy32);
-		if (dummy32 > NFS4_MAXLABELLEN)
-			return nfserr_badlabel;
-		READMEM(buf, dummy32);
-		label->len = dummy32;
-		label->data = svcxdr_dupstr(argp, buf, dummy32);
-		if (!label->data)
-			return nfserr_jukebox;
+		status = nfsd4_decode_security_label(argp, label);
+		if (status)
+			return status;
 	}
 	if (bmval[2] & FATTR4_WORD2_MODE_UMASK) {
 		if (!umask)
Signature · 1 line
2.43.0
author maintainer
#26 lore raw

PATCH 26/770 NFSD: Replace READ* macros that decode the fattr4 umask attribute

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 66f0476c704c86d44aa9da19d4753df66f2dbc96 ]

---
 fs/nfsd/nfs4xdr.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)
fs/nfsd/nfs4xdr.c +9 -7
index 453a902c7490a..2d97bbff13b68 100644
@@ -358,7 +358,6 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 {
 	unsigned int starting_pos;
 	u32 attrlist4_count;
-	u32 dummy32;
 
 	DECODE_HEAD;
 	iattr->ia_valid = 0;
@@ -474,13 +473,16 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 			return status;
 	}
 	if (bmval[2] & FATTR4_WORD2_MODE_UMASK) {
+		u32 mode, mask;
+
 		if (!umask)
-			goto xdr_error;
-		READ_BUF(8);
-		dummy32 = be32_to_cpup(p++);
-		iattr->ia_mode = dummy32 & (S_IFMT | S_IALLUGO);
-		dummy32 = be32_to_cpup(p++);
-		*umask = dummy32 & S_IRWXUGO;
+			return nfserr_bad_xdr;
+		if (xdr_stream_decode_u32(argp->xdr, &mode) < 0)
+			return nfserr_bad_xdr;
+		iattr->ia_mode = mode & (S_IFMT | S_IALLUGO);
+		if (xdr_stream_decode_u32(argp->xdr, &mask) < 0)
+			return nfserr_bad_xdr;
+		*umask = mask & S_IRWXUGO;
 		iattr->ia_valid |= ATTR_MODE;
 	}
 
Signature · 1 line
2.43.0
author maintainer
#27 lore raw

PATCH 27/770 NFSD: Replace READ* macros in nfsd4_decode_fattr()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit d1c263a031e876ac3ca5223c728e4d98ed50b3c0 ]

Let's be more careful to avoid overrunning the memory that backs the bitmap array. This requires updating the synopsis of nfsd4_decode_fattr().

Bruce points out that a server needs to be careful to return nfs_ok when a client presents bitmap bits the server doesn't support. This includes bits in bitmap words the server might not yet support.

The current READ* based implementation is good about that, but that requirement hasn't been documented.

---
 fs/nfsd/nfs4xdr.c | 82 ++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 64 insertions(+), 18 deletions(-)
fs/nfsd/nfs4xdr.c +64 -18
index 2d97bbff13b68..c916e5d9d3074 100644
@@ -260,6 +260,46 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
 	DECODE_TAIL;
 }
 
+/**
+ * nfsd4_decode_bitmap4 - Decode an NFSv4 bitmap4
+ * @argp: NFSv4 compound argument structure
+ * @bmval: pointer to an array of u32's to decode into
+ * @bmlen: size of the @bmval array
+ *
+ * The server needs to return nfs_ok rather than nfserr_bad_xdr when
+ * encountering bitmaps containing bits it does not recognize. This
+ * includes bits in bitmap words past WORDn, where WORDn is the last
+ * bitmap WORD the implementation currently supports. Thus we are
+ * careful here to simply ignore bits in bitmap words that this
+ * implementation has yet to support explicitly.
+ *
+ * Return values:
+ *   %nfs_ok: @bmval populated successfully
+ *   %nfserr_bad_xdr: the encoded bitmap was invalid
+ */
+static __be32
+nfsd4_decode_bitmap4(struct nfsd4_compoundargs *argp, u32 *bmval, u32 bmlen)
+{
+	u32 i, count;
+	__be32 *p;
+
+	if (xdr_stream_decode_u32(argp->xdr, &count) < 0)
+		return nfserr_bad_xdr;
+	/* request sanity */
+	if (count > 1000)
+		return nfserr_bad_xdr;
+	p = xdr_inline_decode(argp->xdr, count << 2);
+	if (!p)
+		return nfserr_bad_xdr;
+	i = 0;
+	while (i < count)
+		bmval[i++] = be32_to_cpup(p++);
+	while (i < bmlen)
+		bmval[i++] = 0;
+
+	return nfs_ok;
+}
+
 static __be32
 nfsd4_decode_nfsace4(struct nfsd4_compoundargs *argp, struct nfs4_ace *ace)
 {
@@ -352,17 +392,18 @@ nfsd4_decode_security_label(struct nfsd4_compoundargs *argp,
 }
 
 static __be32
-nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
-		   struct iattr *iattr, struct nfs4_acl **acl,
-		   struct xdr_netobj *label, int *umask)
+nfsd4_decode_fattr4(struct nfsd4_compoundargs *argp, u32 *bmval, u32 bmlen,
+		    struct iattr *iattr, struct nfs4_acl **acl,
+		    struct xdr_netobj *label, int *umask)
 {
 	unsigned int starting_pos;
 	u32 attrlist4_count;
+	__be32 *p, status;
 
-	DECODE_HEAD;
 	iattr->ia_valid = 0;
-	if ((status = nfsd4_decode_bitmap(argp, bmval)))
-		return status;
+	status = nfsd4_decode_bitmap4(argp, bmval, bmlen);
+	if (status)
+		return nfserr_bad_xdr;
 
 	if (bmval[0] & ~NFSD_WRITEABLE_ATTRS_WORD0
 	    || bmval[1] & ~NFSD_WRITEABLE_ATTRS_WORD1
@@ -490,7 +531,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 	if (attrlist4_count != xdr_stream_pos(argp->xdr) - starting_pos)
 		return nfserr_bad_xdr;
 
-	DECODE_TAIL;
+	return nfs_ok;
 }
 
 static __be32
@@ -690,9 +731,10 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create
 	if ((status = check_filename(create->cr_name, create->cr_namelen)))
 		return status;
 
-	status = nfsd4_decode_fattr(argp, create->cr_bmval, &create->cr_iattr,
-				    &create->cr_acl, &create->cr_label,
-				    &create->cr_umask);
+	status = nfsd4_decode_fattr4(argp, create->cr_bmval,
+				    ARRAY_SIZE(create->cr_bmval),
+				    &create->cr_iattr, &create->cr_acl,
+				    &create->cr_label, &create->cr_umask);
 	if (status)
 		goto out;
 
@@ -941,9 +983,10 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 		switch (open->op_createmode) {
 		case NFS4_CREATE_UNCHECKED:
 		case NFS4_CREATE_GUARDED:
-			status = nfsd4_decode_fattr(argp, open->op_bmval,
-				&open->op_iattr, &open->op_acl, &open->op_label,
-				&open->op_umask);
+			status = nfsd4_decode_fattr4(argp, open->op_bmval,
+						     ARRAY_SIZE(open->op_bmval),
+						     &open->op_iattr, &open->op_acl,
+						     &open->op_label, &open->op_umask);
 			if (status)
 				goto out;
 			break;
@@ -956,9 +999,10 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 				goto xdr_error;
 			READ_BUF(NFS4_VERIFIER_SIZE);
 			COPYMEM(open->op_verf.data, NFS4_VERIFIER_SIZE);
-			status = nfsd4_decode_fattr(argp, open->op_bmval,
-				&open->op_iattr, &open->op_acl, &open->op_label,
-				&open->op_umask);
+			status = nfsd4_decode_fattr4(argp, open->op_bmval,
+						     ARRAY_SIZE(open->op_bmval),
+						     &open->op_iattr, &open->op_acl,
+						     &open->op_label, &open->op_umask);
 			if (status)
 				goto out;
 			break;
@@ -1194,8 +1238,10 @@ nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *seta
 	status = nfsd4_decode_stateid(argp, &setattr->sa_stateid);
 	if (status)
 		return status;
-	return nfsd4_decode_fattr(argp, setattr->sa_bmval, &setattr->sa_iattr,
-				  &setattr->sa_acl, &setattr->sa_label, NULL);
+	return nfsd4_decode_fattr4(argp, setattr->sa_bmval,
+				   ARRAY_SIZE(setattr->sa_bmval),
+				   &setattr->sa_iattr, &setattr->sa_acl,
+				   &setattr->sa_label, NULL);
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#28 lore raw

PATCH 28/770 NFSD: Replace READ* macros in nfsd4_decode_create()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 000dfa18b3df9c62df5f768f9187cf1a94ded71d ]

A dedicated decoder for component4 is introduced here, which will be used by other operation decoders in subsequent patches.

---
 fs/nfsd/nfs4xdr.c | 58 ++++++++++++++++++++++++++++++++---------------
 1 file changed, 40 insertions(+), 18 deletions(-)
fs/nfsd/nfs4xdr.c +40 -18
index c916e5d9d3074..8f296f5568b11 100644
@@ -92,6 +92,8 @@ check_filename(char *str, int len)
 
 	if (len == 0)
 		return nfserr_inval;
+	if (len > NFS4_MAXNAMLEN)
+		return nfserr_nametoolong;
 	if (isdotent(str, len))
 		return nfserr_badname;
 	for (i = 0; i < len; i++)
@@ -205,6 +207,27 @@ static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes)
 	return ret;
 }
 
+static __be32
+nfsd4_decode_component4(struct nfsd4_compoundargs *argp, char **namp, u32 *lenp)
+{
+	__be32 *p, status;
+
+	if (xdr_stream_decode_u32(argp->xdr, lenp) < 0)
+		return nfserr_bad_xdr;
+	p = xdr_inline_decode(argp->xdr, *lenp);
+	if (!p)
+		return nfserr_bad_xdr;
+	status = check_filename((char *)p, *lenp);
+	if (status)
+		return status;
+	*namp = svcxdr_tmpalloc(argp, *lenp);
+	if (!*namp)
+		return nfserr_jukebox;
+	memcpy(*namp, p, *lenp);
+
+	return nfs_ok;
+}
+
 static __be32
 nfsd4_decode_time(struct nfsd4_compoundargs *argp, struct timespec64 *tv)
 {
@@ -698,24 +721,27 @@ nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit
 static __be32
 nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create)
 {
-	DECODE_HEAD;
+	__be32 *p, status;
 
-	READ_BUF(4);
-	create->cr_type = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &create->cr_type) < 0)
+		return nfserr_bad_xdr;
 	switch (create->cr_type) {
 	case NF4LNK:
-		READ_BUF(4);
-		create->cr_datalen = be32_to_cpup(p++);
-		READ_BUF(create->cr_datalen);
+		if (xdr_stream_decode_u32(argp->xdr, &create->cr_datalen) < 0)
+			return nfserr_bad_xdr;
+		p = xdr_inline_decode(argp->xdr, create->cr_datalen);
+		if (!p)
+			return nfserr_bad_xdr;
 		create->cr_data = svcxdr_dupstr(argp, p, create->cr_datalen);
 		if (!create->cr_data)
 			return nfserr_jukebox;
 		break;
 	case NF4BLK:
 	case NF4CHR:
-		READ_BUF(8);
-		create->cr_specdata1 = be32_to_cpup(p++);
-		create->cr_specdata2 = be32_to_cpup(p++);
+		if (xdr_stream_decode_u32(argp->xdr, &create->cr_specdata1) < 0)
+			return nfserr_bad_xdr;
+		if (xdr_stream_decode_u32(argp->xdr, &create->cr_specdata2) < 0)
+			return nfserr_bad_xdr;
 		break;
 	case NF4SOCK:
 	case NF4FIFO:
@@ -723,22 +749,18 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create
 	default:
 		break;
 	}
-
-	READ_BUF(4);
-	create->cr_namelen = be32_to_cpup(p++);
-	READ_BUF(create->cr_namelen);
-	SAVEMEM(create->cr_name, create->cr_namelen);
-	if ((status = check_filename(create->cr_name, create->cr_namelen)))
+	status = nfsd4_decode_component4(argp, &create->cr_name,
+					 &create->cr_namelen);
+	if (status)
 		return status;
-
 	status = nfsd4_decode_fattr4(argp, create->cr_bmval,
 				    ARRAY_SIZE(create->cr_bmval),
 				    &create->cr_iattr, &create->cr_acl,
 				    &create->cr_label, &create->cr_umask);
 	if (status)
-		goto out;
+		return status;
 
-	DECODE_TAIL;
+	return nfs_ok;
 }
 
 static inline __be32
Signature · 1 line
2.43.0
author maintainer
#29 lore raw

PATCH 29/770 NFSD: Replace READ* macros in nfsd4_decode_delegreturn()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 95e6482cedfc0785b85db49b72a05323bbf41750 ]

---
 fs/nfsd/nfs4xdr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfsd/nfs4xdr.c +1 -1
index 8f296f5568b11..234d500961230 100644
@@ -766,7 +766,7 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create
 static inline __be32
 nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr)
 {
-	return nfsd4_decode_stateid(argp, &dr->dr_stateid);
+	return nfsd4_decode_stateid4(argp, &dr->dr_stateid);
 }
 
 static inline __be32
Signature · 1 line
2.43.0
author maintainer
#30 lore raw

PATCH 30/770 NFSD: Replace READ* macros in nfsd4_decode_getattr()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit f759eff260f1f0b0f56531517762f27ee3233506 ]

---
 fs/nfsd/nfs4xdr.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
fs/nfsd/nfs4xdr.c +2 -1
index 234d500961230..70ce48340c1b7 100644
@@ -772,7 +772,8 @@ nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegretu
 static inline __be32
 nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr)
 {
-	return nfsd4_decode_bitmap(argp, getattr->ga_bmval);
+	return nfsd4_decode_bitmap4(argp, getattr->ga_bmval,
+				    ARRAY_SIZE(getattr->ga_bmval));
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#31 lore raw

PATCH 31/770 NFSD: Replace READ* macros in nfsd4_decode_link()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 5c505d128691c70991b766dd6a3faf49fa59ecfb ]

---
 fs/nfsd/nfs4xdr.c | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)
fs/nfsd/nfs4xdr.c +1 -10
index 70ce48340c1b7..4596b8cef222c 100644
@@ -779,16 +779,7 @@ nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *geta
 static __be32
 nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link)
 {
-	DECODE_HEAD;
-
-	READ_BUF(4);
-	link->li_namelen = be32_to_cpup(p++);
-	READ_BUF(link->li_namelen);
-	SAVEMEM(link->li_name, link->li_namelen);
-	if ((status = check_filename(link->li_name, link->li_namelen)))
-		return status;
-
-	DECODE_TAIL;
+	return nfsd4_decode_component4(argp, &link->li_name, &link->li_namelen);
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#32 lore raw

PATCH 32/770 NFSD: Relocate nfsd4_decode_opaque()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 5dcbfabb676b2b6d97767209cf707eb463ca232a ]

Enable nfsd4_decode_opaque() to be used in more decoders, and replace the READ* macros in nfsd4_decode_opaque().

---
 fs/nfsd/nfs4xdr.c | 43 +++++++++++++++++++++++++++----------------
 1 file changed, 27 insertions(+), 16 deletions(-)
fs/nfsd/nfs4xdr.c +27 -16
index 4596b8cef222c..b3459059cec1b 100644
@@ -207,6 +207,33 @@ static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes)
 	return ret;
 }
 
+
+/*
+ * NFSv4 basic data type decoders
+ */
+
+static __be32
+nfsd4_decode_opaque(struct nfsd4_compoundargs *argp, struct xdr_netobj *o)
+{
+	__be32 *p;
+	u32 len;
+
+	if (xdr_stream_decode_u32(argp->xdr, &len) < 0)
+		return nfserr_bad_xdr;
+	if (len == 0 || len > NFS4_OPAQUE_LIMIT)
+		return nfserr_bad_xdr;
+	p = xdr_inline_decode(argp->xdr, len);
+	if (!p)
+		return nfserr_bad_xdr;
+	o->data = svcxdr_tmpalloc(argp, len);
+	if (!o->data)
+		return nfserr_jukebox;
+	o->len = len;
+	memcpy(o->data, p, len);
+
+	return nfs_ok;
+}
+
 static __be32
 nfsd4_decode_component4(struct nfsd4_compoundargs *argp, char **namp, u32 *lenp)
 {
@@ -943,22 +970,6 @@ static __be32 nfsd4_decode_share_deny(struct nfsd4_compoundargs *argp, u32 *x)
 	return nfserr_bad_xdr;
 }
 
-static __be32 nfsd4_decode_opaque(struct nfsd4_compoundargs *argp, struct xdr_netobj *o)
-{
-	DECODE_HEAD;
-
-	READ_BUF(4);
-	o->len = be32_to_cpup(p++);
-
-	if (o->len == 0 || o->len > NFS4_OPAQUE_LIMIT)
-		return nfserr_bad_xdr;
-
-	READ_BUF(o->len);
-	SAVEMEM(o->data, o->len);
-
-	DECODE_TAIL;
-}
-
 static __be32
 nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 {
Signature · 1 line
2.43.0
author maintainer
#33 lore raw

PATCH 33/770 NFSD: Add helpers to decode a clientid4 and an NFSv4 state owner

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 144e82694092ff80b5e64749d6822cd8947587f2 ]

These helpers will also be used to simplify decoders in subsequent patches.

---
 fs/nfsd/nfs4xdr.c | 34 +++++++++++++++++++++++++++++-----
 1 file changed, 29 insertions(+), 5 deletions(-)
fs/nfsd/nfs4xdr.c +29 -5
index b3459059cec1b..63140cd4c50e4 100644
@@ -609,6 +609,30 @@ nfsd4_decode_stateid4(struct nfsd4_compoundargs *argp, stateid_t *sid)
 	return nfs_ok;
 }
 
+static __be32
+nfsd4_decode_clientid4(struct nfsd4_compoundargs *argp, clientid_t *clientid)
+{
+	__be32 *p;
+
+	p = xdr_inline_decode(argp->xdr, sizeof(__be64));
+	if (!p)
+		return nfserr_bad_xdr;
+	memcpy(clientid, p, sizeof(*clientid));
+	return nfs_ok;
+}
+
+static __be32
+nfsd4_decode_state_owner4(struct nfsd4_compoundargs *argp,
+			  clientid_t *clientid, struct xdr_netobj *owner)
+{
+	__be32 status;
+
+	status = nfsd4_decode_clientid4(argp, clientid);
+	if (status)
+		return status;
+	return nfsd4_decode_opaque(argp, owner);
+}
+
 static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_cb_sec *cbs)
 {
 	DECODE_HEAD;
@@ -832,12 +856,12 @@ nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
 		status = nfsd4_decode_stateid(argp, &lock->lk_new_open_stateid);
 		if (status)
 			return status;
-		READ_BUF(8 + sizeof(clientid_t));
+		READ_BUF(4);
 		lock->lk_new_lock_seqid = be32_to_cpup(p++);
-		COPYMEM(&lock->lk_new_clientid, sizeof(clientid_t));
-		lock->lk_new_owner.len = be32_to_cpup(p++);
-		READ_BUF(lock->lk_new_owner.len);
-		READMEM(lock->lk_new_owner.data, lock->lk_new_owner.len);
+		status = nfsd4_decode_state_owner4(argp, &lock->lk_new_clientid,
+						   &lock->lk_new_owner);
+		if (status)
+			return status;
 	} else {
 		status = nfsd4_decode_stateid(argp, &lock->lk_old_lock_stateid);
 		if (status)
Signature · 1 line
2.43.0
author maintainer
#34 lore raw

PATCH 34/770 NFSD: Add helper for decoding locker4

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 8918cc0d2b72db9997390626010b182c4500d749 ]

Refactor for clarity.

---
 fs/nfsd/nfs4xdr.c          | 64 +++++++++++++++++++++++++-------------
 include/linux/sunrpc/xdr.h | 21 +++++++++++++
 2 files changed, 64 insertions(+), 21 deletions(-)
fs/nfsd/nfs4xdr.c +43 -21
index 63140cd4c50e4..15ed5249e2c74 100644
@@ -833,6 +833,48 @@ nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link)
 	return nfsd4_decode_component4(argp, &link->li_name, &link->li_namelen);
 }
 
+static __be32
+nfsd4_decode_open_to_lock_owner4(struct nfsd4_compoundargs *argp,
+				 struct nfsd4_lock *lock)
+{
+	__be32 status;
+
+	if (xdr_stream_decode_u32(argp->xdr, &lock->lk_new_open_seqid) < 0)
+		return nfserr_bad_xdr;
+	status = nfsd4_decode_stateid4(argp, &lock->lk_new_open_stateid);
+	if (status)
+		return status;
+	if (xdr_stream_decode_u32(argp->xdr, &lock->lk_new_lock_seqid) < 0)
+		return nfserr_bad_xdr;
+	return nfsd4_decode_state_owner4(argp, &lock->lk_new_clientid,
+					 &lock->lk_new_owner);
+}
+
+static __be32
+nfsd4_decode_exist_lock_owner4(struct nfsd4_compoundargs *argp,
+			       struct nfsd4_lock *lock)
+{
+	__be32 status;
+
+	status = nfsd4_decode_stateid4(argp, &lock->lk_old_lock_stateid);
+	if (status)
+		return status;
+	if (xdr_stream_decode_u32(argp->xdr, &lock->lk_old_lock_seqid) < 0)
+		return nfserr_bad_xdr;
+
+	return nfs_ok;
+}
+
+static __be32
+nfsd4_decode_locker4(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
+{
+	if (xdr_stream_decode_bool(argp->xdr, &lock->lk_is_new) < 0)
+		return nfserr_bad_xdr;
+	if (lock->lk_is_new)
+		return nfsd4_decode_open_to_lock_owner4(argp, lock);
+	return nfsd4_decode_exist_lock_owner4(argp, lock);
+}
+
 static __be32
 nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
 {
@@ -848,27 +890,7 @@ nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
 	lock->lk_reclaim = be32_to_cpup(p++);
 	p = xdr_decode_hyper(p, &lock->lk_offset);
 	p = xdr_decode_hyper(p, &lock->lk_length);
-	lock->lk_is_new = be32_to_cpup(p++);
-
-	if (lock->lk_is_new) {
-		READ_BUF(4);
-		lock->lk_new_open_seqid = be32_to_cpup(p++);
-		status = nfsd4_decode_stateid(argp, &lock->lk_new_open_stateid);
-		if (status)
-			return status;
-		READ_BUF(4);
-		lock->lk_new_lock_seqid = be32_to_cpup(p++);
-		status = nfsd4_decode_state_owner4(argp, &lock->lk_new_clientid,
-						   &lock->lk_new_owner);
-		if (status)
-			return status;
-	} else {
-		status = nfsd4_decode_stateid(argp, &lock->lk_old_lock_stateid);
-		if (status)
-			return status;
-		READ_BUF(4);
-		lock->lk_old_lock_seqid = be32_to_cpup(p++);
-	}
+	status = nfsd4_decode_locker4(argp, lock);
 
 	DECODE_TAIL;
 }
include/linux/sunrpc/xdr.h +21 -0
index 6b17575437474..f6569b620beab 100644
@@ -548,6 +548,27 @@ static inline bool xdr_item_is_present(const __be32 *p)
 	return *p != xdr_zero;
 }
 
+/**
+ * xdr_stream_decode_bool - Decode a boolean
+ * @xdr: pointer to xdr_stream
+ * @ptr: pointer to a u32 in which to store the result
+ *
+ * Return values:
+ *   %0 on success
+ *   %-EBADMSG on XDR buffer overflow
+ */
+static inline ssize_t
+xdr_stream_decode_bool(struct xdr_stream *xdr, __u32 *ptr)
+{
+	const size_t count = sizeof(*ptr);
+	__be32 *p = xdr_inline_decode(xdr, count);
+
+	if (unlikely(!p))
+		return -EBADMSG;
+	*ptr = (*p != xdr_zero);
+	return 0;
+}
+
 /**
  * xdr_stream_decode_u32 - Decode a 32-bit integer
  * @xdr: pointer to xdr_stream
Signature · 1 line
2.43.0
author maintainer
#35 lore raw

PATCH 35/770 NFSD: Replace READ* macros in nfsd4_decode_lock()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 7c59deed5cd2e1cfc6cbecf06f4584ac53755f53 ]

---
 fs/nfsd/nfs4xdr.c | 24 ++++++++++--------------
 1 file changed, 10 insertions(+), 14 deletions(-)
fs/nfsd/nfs4xdr.c +10 -14
index 15ed5249e2c74..b50d2987bb6e8 100644
@@ -878,21 +878,17 @@ nfsd4_decode_locker4(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
 static __be32
 nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
 {
-	DECODE_HEAD;
-
-	/*
-	* type, reclaim(boolean), offset, length, new_lock_owner(boolean)
-	*/
-	READ_BUF(28);
-	lock->lk_type = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &lock->lk_type) < 0)
+		return nfserr_bad_xdr;
 	if ((lock->lk_type < NFS4_READ_LT) || (lock->lk_type > NFS4_WRITEW_LT))
-		goto xdr_error;
-	lock->lk_reclaim = be32_to_cpup(p++);
-	p = xdr_decode_hyper(p, &lock->lk_offset);
-	p = xdr_decode_hyper(p, &lock->lk_length);
-	status = nfsd4_decode_locker4(argp, lock);
-
-	DECODE_TAIL;
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_bool(argp->xdr, &lock->lk_reclaim) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u64(argp->xdr, &lock->lk_offset) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u64(argp->xdr, &lock->lk_length) < 0)
+		return nfserr_bad_xdr;
+	return nfsd4_decode_locker4(argp, lock);
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#36 lore raw

PATCH 36/770 NFSD: Replace READ* macros in nfsd4_decode_lockt()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 0a146f04aa0fa7a57aaed3913d1c2732b3853f31 ]

---
 fs/nfsd/nfs4xdr.c | 24 ++++++++++--------------
 1 file changed, 10 insertions(+), 14 deletions(-)
fs/nfsd/nfs4xdr.c +10 -14
index b50d2987bb6e8..4f2680650a567 100644
@@ -894,20 +894,16 @@ nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
 static __be32
 nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt)
 {
-	DECODE_HEAD;
-		        
-	READ_BUF(32);
-	lockt->lt_type = be32_to_cpup(p++);
-	if((lockt->lt_type < NFS4_READ_LT) || (lockt->lt_type > NFS4_WRITEW_LT))
-		goto xdr_error;
-	p = xdr_decode_hyper(p, &lockt->lt_offset);
-	p = xdr_decode_hyper(p, &lockt->lt_length);
-	COPYMEM(&lockt->lt_clientid, 8);
-	lockt->lt_owner.len = be32_to_cpup(p++);
-	READ_BUF(lockt->lt_owner.len);
-	READMEM(lockt->lt_owner.data, lockt->lt_owner.len);
-
-	DECODE_TAIL;
+	if (xdr_stream_decode_u32(argp->xdr, &lockt->lt_type) < 0)
+		return nfserr_bad_xdr;
+	if ((lockt->lt_type < NFS4_READ_LT) || (lockt->lt_type > NFS4_WRITEW_LT))
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u64(argp->xdr, &lockt->lt_offset) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u64(argp->xdr, &lockt->lt_length) < 0)
+		return nfserr_bad_xdr;
+	return nfsd4_decode_state_owner4(argp, &lockt->lt_clientid,
+					 &lockt->lt_owner);
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#37 lore raw

PATCH 37/770 NFSD: Replace READ* macros in nfsd4_decode_locku()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit ca9cf9fc27f8f722e9eb2763173ba01f6ac3dad1 ]

---
 fs/nfsd/nfs4xdr.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)
fs/nfsd/nfs4xdr.c +12 -10
index 4f2680650a567..3c20a1f8eaa91 100644
@@ -909,21 +909,23 @@ nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt)
 static __be32
 nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku)
 {
-	DECODE_HEAD;
+	__be32 status;
 
-	READ_BUF(8);
-	locku->lu_type = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &locku->lu_type) < 0)
+		return nfserr_bad_xdr;
 	if ((locku->lu_type < NFS4_READ_LT) || (locku->lu_type > NFS4_WRITEW_LT))
-		goto xdr_error;
-	locku->lu_seqid = be32_to_cpup(p++);
-	status = nfsd4_decode_stateid(argp, &locku->lu_stateid);
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u32(argp->xdr, &locku->lu_seqid) < 0)
+		return nfserr_bad_xdr;
+	status = nfsd4_decode_stateid4(argp, &locku->lu_stateid);
 	if (status)
 		return status;
-	READ_BUF(16);
-	p = xdr_decode_hyper(p, &locku->lu_offset);
-	p = xdr_decode_hyper(p, &locku->lu_length);
+	if (xdr_stream_decode_u64(argp->xdr, &locku->lu_offset) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u64(argp->xdr, &locku->lu_length) < 0)
+		return nfserr_bad_xdr;
 
-	DECODE_TAIL;
+	return nfs_ok;
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#38 lore raw

PATCH 38/770 NFSD: Replace READ* macros in nfsd4_decode_lookup()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 3d5877e8e03f60d7cc804d7b230ff9c00c9c07bd ]

---
 fs/nfsd/nfs4xdr.c | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)
fs/nfsd/nfs4xdr.c +1 -10
index 3c20a1f8eaa91..431ab9d604be7 100644
@@ -931,16 +931,7 @@ nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku)
 static __be32
 nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup)
 {
-	DECODE_HEAD;
-
-	READ_BUF(4);
-	lookup->lo_len = be32_to_cpup(p++);
-	READ_BUF(lookup->lo_len);
-	SAVEMEM(lookup->lo_name, lookup->lo_len);
-	if ((status = check_filename(lookup->lo_name, lookup->lo_len)))
-		return status;
-
-	DECODE_TAIL;
+	return nfsd4_decode_component4(argp, &lookup->lo_name, &lookup->lo_len);
 }
 
 static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *share_access, u32 *deleg_want, u32 *deleg_when)
Signature · 1 line
2.43.0
author maintainer
#39 lore raw

PATCH 39/770 NFSD: Add helper to decode NFSv4 verifiers

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 796dd1c6b680959ac968b52aa507911b288b1749 ]

This helper will be used to simplify decoders in subsequent patches.

---
 fs/nfsd/nfs4xdr.c | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)
fs/nfsd/nfs4xdr.c +18 -4
index 431ab9d604be7..1a2dc52c4340b 100644
@@ -284,6 +284,18 @@ nfsd4_decode_nfstime4(struct nfsd4_compoundargs *argp, struct timespec64 *tv)
 	return nfs_ok;
 }
 
+static __be32
+nfsd4_decode_verifier4(struct nfsd4_compoundargs *argp, nfs4_verifier *verf)
+{
+	__be32 *p;
+
+	p = xdr_inline_decode(argp->xdr, NFS4_VERIFIER_SIZE);
+	if (!p)
+		return nfserr_bad_xdr;
+	memcpy(verf->data, p, sizeof(verf->data));
+	return nfs_ok;
+}
+
 static __be32
 nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
 {
@@ -1047,14 +1059,16 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 				goto out;
 			break;
 		case NFS4_CREATE_EXCLUSIVE:
-			READ_BUF(NFS4_VERIFIER_SIZE);
-			COPYMEM(open->op_verf.data, NFS4_VERIFIER_SIZE);
+			status = nfsd4_decode_verifier4(argp, &open->op_verf);
+			if (status)
+				return status;
 			break;
 		case NFS4_CREATE_EXCLUSIVE4_1:
 			if (argp->minorversion < 1)
 				goto xdr_error;
-			READ_BUF(NFS4_VERIFIER_SIZE);
-			COPYMEM(open->op_verf.data, NFS4_VERIFIER_SIZE);
+			status = nfsd4_decode_verifier4(argp, &open->op_verf);
+			if (status)
+				return status;
 			status = nfsd4_decode_fattr4(argp, open->op_bmval,
 						     ARRAY_SIZE(open->op_bmval),
 						     &open->op_iattr, &open->op_acl,
Signature · 1 line
2.43.0
author maintainer
#40 lore raw

PATCH 40/770 NFSD: Add helper to decode OPENs createhow4 argument

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit bf33bab3c4182cdd795983f14de5606e82fab377 ]

Refactor for clarity.

---
 fs/nfsd/nfs4xdr.c | 78 +++++++++++++++++++++++++++--------------------
 1 file changed, 45 insertions(+), 33 deletions(-)
fs/nfsd/nfs4xdr.c +45 -33
index 1a2dc52c4340b..62096b2a57b35 100644
@@ -946,6 +946,48 @@ nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup
 	return nfsd4_decode_component4(argp, &lookup->lo_name, &lookup->lo_len);
 }
 
+static __be32
+nfsd4_decode_createhow4(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
+{
+	__be32 status;
+
+	if (xdr_stream_decode_u32(argp->xdr, &open->op_createmode) < 0)
+		return nfserr_bad_xdr;
+	switch (open->op_createmode) {
+	case NFS4_CREATE_UNCHECKED:
+	case NFS4_CREATE_GUARDED:
+		status = nfsd4_decode_fattr4(argp, open->op_bmval,
+					     ARRAY_SIZE(open->op_bmval),
+					     &open->op_iattr, &open->op_acl,
+					     &open->op_label, &open->op_umask);
+		if (status)
+			return status;
+		break;
+	case NFS4_CREATE_EXCLUSIVE:
+		status = nfsd4_decode_verifier4(argp, &open->op_verf);
+		if (status)
+			return status;
+		break;
+	case NFS4_CREATE_EXCLUSIVE4_1:
+		if (argp->minorversion < 1)
+			return nfserr_bad_xdr;
+		status = nfsd4_decode_verifier4(argp, &open->op_verf);
+		if (status)
+			return status;
+		status = nfsd4_decode_fattr4(argp, open->op_bmval,
+					     ARRAY_SIZE(open->op_bmval),
+					     &open->op_iattr, &open->op_acl,
+					     &open->op_label, &open->op_umask);
+		if (status)
+			return status;
+		break;
+	default:
+		return nfserr_bad_xdr;
+	}
+
+	return nfs_ok;
+}
+
 static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *share_access, u32 *deleg_want, u32 *deleg_when)
 {
 	__be32 *p;
@@ -1046,39 +1088,9 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 	case NFS4_OPEN_NOCREATE:
 		break;
 	case NFS4_OPEN_CREATE:
-		READ_BUF(4);
-		open->op_createmode = be32_to_cpup(p++);
-		switch (open->op_createmode) {
-		case NFS4_CREATE_UNCHECKED:
-		case NFS4_CREATE_GUARDED:
-			status = nfsd4_decode_fattr4(argp, open->op_bmval,
-						     ARRAY_SIZE(open->op_bmval),
-						     &open->op_iattr, &open->op_acl,
-						     &open->op_label, &open->op_umask);
-			if (status)
-				goto out;
-			break;
-		case NFS4_CREATE_EXCLUSIVE:
-			status = nfsd4_decode_verifier4(argp, &open->op_verf);
-			if (status)
-				return status;
-			break;
-		case NFS4_CREATE_EXCLUSIVE4_1:
-			if (argp->minorversion < 1)
-				goto xdr_error;
-			status = nfsd4_decode_verifier4(argp, &open->op_verf);
-			if (status)
-				return status;
-			status = nfsd4_decode_fattr4(argp, open->op_bmval,
-						     ARRAY_SIZE(open->op_bmval),
-						     &open->op_iattr, &open->op_acl,
-						     &open->op_label, &open->op_umask);
-			if (status)
-				goto out;
-			break;
-		default:
-			goto xdr_error;
-		}
+		status = nfsd4_decode_createhow4(argp, open);
+		if (status)
+			return status;
 		break;
 	default:
 		goto xdr_error;
Signature · 1 line
2.43.0
author maintainer
#41 lore raw

PATCH 41/770 NFSD: Add helper to decode OPENs openflag4 argument

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit e6ec04b27bfb4869c0e35fbcf24333d379f101d5 ]

Refactor for clarity.

---
 fs/nfsd/nfs4xdr.c | 38 +++++++++++++++++++++++++-------------
 1 file changed, 25 insertions(+), 13 deletions(-)
fs/nfsd/nfs4xdr.c +25 -13
index 62096b2a57b35..76715d1935ade 100644
@@ -988,6 +988,28 @@ nfsd4_decode_createhow4(struct nfsd4_compoundargs *argp, struct nfsd4_open *open
 	return nfs_ok;
 }
 
+static __be32
+nfsd4_decode_openflag4(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
+{
+	__be32 status;
+
+	if (xdr_stream_decode_u32(argp->xdr, &open->op_create) < 0)
+		return nfserr_bad_xdr;
+	switch (open->op_create) {
+	case NFS4_OPEN_NOCREATE:
+		break;
+	case NFS4_OPEN_CREATE:
+		status = nfsd4_decode_createhow4(argp, open);
+		if (status)
+			return status;
+		break;
+	default:
+		return nfserr_bad_xdr;
+	}
+
+	return nfs_ok;
+}
+
 static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *share_access, u32 *deleg_want, u32 *deleg_when)
 {
 	__be32 *p;
@@ -1082,19 +1104,9 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 	status = nfsd4_decode_opaque(argp, &open->op_owner);
 	if (status)
 		goto xdr_error;
-	READ_BUF(4);
-	open->op_create = be32_to_cpup(p++);
-	switch (open->op_create) {
-	case NFS4_OPEN_NOCREATE:
-		break;
-	case NFS4_OPEN_CREATE:
-		status = nfsd4_decode_createhow4(argp, open);
-		if (status)
-			return status;
-		break;
-	default:
-		goto xdr_error;
-	}
+	status = nfsd4_decode_openflag4(argp, open);
+	if (status)
+		return status;
 
 	/* open_claim */
 	READ_BUF(4);
Signature · 1 line
2.43.0
author maintainer
#42 lore raw

PATCH 42/770 NFSD: Replace READ* macros in nfsd4_decode_share_access()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 9aa62f5199749b274454b6d7d914c9b2a5e77031 ]

---
 fs/nfsd/nfs4xdr.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
fs/nfsd/nfs4xdr.c +2 -4
index 76715d1935ade..a43b39940ab25 100644
@@ -1012,11 +1012,10 @@ nfsd4_decode_openflag4(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 
 static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *share_access, u32 *deleg_want, u32 *deleg_when)
 {
-	__be32 *p;
 	u32 w;
 
-	READ_BUF(4);
-	w = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &w) < 0)
+		return nfserr_bad_xdr;
 	*share_access = w & NFS4_SHARE_ACCESS_MASK;
 	*deleg_want = w & NFS4_SHARE_WANT_MASK;
 	if (deleg_when)
@@ -1059,7 +1058,6 @@ static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *sh
 	      NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED):
 		return nfs_ok;
 	}
-xdr_error:
 	return nfserr_bad_xdr;
 }
 
Signature · 1 line
2.43.0
author maintainer
#43 lore raw

PATCH 43/770 NFSD: Replace READ* macros in nfsd4_decode_share_deny()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit b07bebd9eb9842e2d0dea87efeb92884556e55b0 ]

---
 fs/nfsd/nfs4xdr.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)
fs/nfsd/nfs4xdr.c +4 -7
index a43b39940ab25..a9257ec9d151d 100644
@@ -1063,16 +1063,13 @@ static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *sh
 
 static __be32 nfsd4_decode_share_deny(struct nfsd4_compoundargs *argp, u32 *x)
 {
-	__be32 *p;
-
-	READ_BUF(4);
-	*x = be32_to_cpup(p++);
-	/* Note: unlinke access bits, deny bits may be zero. */
+	if (xdr_stream_decode_u32(argp->xdr, x) < 0)
+		return nfserr_bad_xdr;
+	/* Note: unlike access bits, deny bits may be zero. */
 	if (*x & ~NFS4_SHARE_DENY_BOTH)
 		return nfserr_bad_xdr;
+
 	return nfs_ok;
-xdr_error:
-	return nfserr_bad_xdr;
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#44 lore raw

PATCH 44/770 NFSD: Add helper to decode OPENs open_claim4 argument

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 1708e50b0145f393acbec9e319bdf0e33f765d25 ]

Refactor for clarity.

Note that op_fname is the only instance of an NFSv4 filename stored in a struct xdr_netobj. Convert it to a u32/char * pair so that the new nfsd4_decode_filename() helper can be used.

---
 fs/nfsd/nfs4proc.c |  8 ++--
 fs/nfsd/nfs4xdr.c  | 95 ++++++++++++++++++++++++----------------------
 fs/nfsd/xdr4.h     |  3 +-
 3 files changed, 56 insertions(+), 50 deletions(-)
fs/nfsd/nfs4proc.c +4 -4
index 95545a61bfc77..a038d1e182ff3 100644
@@ -257,8 +257,8 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru
 		 * in NFSv4 as in v3 except EXCLUSIVE4_1.
 		 */
 		current->fs->umask = open->op_umask;
-		status = do_nfsd_create(rqstp, current_fh, open->op_fname.data,
-					open->op_fname.len, &open->op_iattr,
+		status = do_nfsd_create(rqstp, current_fh, open->op_fname,
+					open->op_fnamelen, &open->op_iattr,
 					*resfh, open->op_createmode,
 					(u32 *)open->op_verf.data,
 					&open->op_truncate, &open->op_created);
@@ -283,7 +283,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru
 		 * a chance to an acquire a delegation if appropriate.
 		 */
 		status = nfsd_lookup(rqstp, current_fh,
-				     open->op_fname.data, open->op_fname.len, *resfh);
+				     open->op_fname, open->op_fnamelen, *resfh);
 	if (status)
 		goto out;
 	status = nfsd_check_obj_isreg(*resfh);
@@ -360,7 +360,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	bool reclaim = false;
 
 	dprintk("NFSD: nfsd4_open filename %.*s op_openowner %p\n",
-		(int)open->op_fname.len, open->op_fname.data,
+		(int)open->op_fnamelen, open->op_fname,
 		open->op_openowner);
 
 	/* This check required by spec. */
fs/nfsd/nfs4xdr.c +50 -45

107 lines not on this page · raw message

fs/nfsd/xdr4.h +2 -1
index 0eb13bd603ea6..6245004a9993b 100644
@@ -252,7 +252,8 @@ struct nfsd4_listxattrs {
 
 struct nfsd4_open {
 	u32		op_claim_type;      /* request */
-	struct xdr_netobj op_fname;	    /* request - everything but CLAIM_PREV */
+	u32		op_fnamelen;
+	char *		op_fname;	    /* request - everything but CLAIM_PREV */
 	u32		op_delegate_type;   /* request - CLAIM_PREV only */
 	stateid_t       op_delegate_stateid; /* request - response */
 	u32		op_why_no_deleg;    /* response - DELEG_NONE_EXT only */
Signature · 1 line
2.43.0
author maintainer
#45 lore raw

PATCH 45/770 NFSD: Replace READ* macros in nfsd4_decode_open()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 61e5e0b3ec713d1365008c8af3fe5fdd262e2a60 ]

---
 fs/nfsd/nfs4xdr.c | 24 ++++++++++--------------
 1 file changed, 10 insertions(+), 14 deletions(-)
fs/nfsd/nfs4xdr.c +10 -14
index 3e0fca521c39b..2de54e84a3ab0 100644
@@ -1124,7 +1124,7 @@ nfsd4_decode_open_claim4(struct nfsd4_compoundargs *argp,
 static __be32
 nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 {
-	DECODE_HEAD;
+	__be32 status;
 	u32 dummy;
 
 	memset(open->op_bmval, 0, sizeof(open->op_bmval));
@@ -1132,28 +1132,24 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 	open->op_openowner = NULL;
 
 	open->op_xdr_error = 0;
-	/* seqid, share_access, share_deny, clientid, ownerlen */
-	READ_BUF(4);
-	open->op_seqid = be32_to_cpup(p++);
-	/* decode, yet ignore deleg_when until supported */
+	if (xdr_stream_decode_u32(argp->xdr, &open->op_seqid) < 0)
+		return nfserr_bad_xdr;
+	/* deleg_want is ignored */
 	status = nfsd4_decode_share_access(argp, &open->op_share_access,
 					   &open->op_deleg_want, &dummy);
 	if (status)
-		goto xdr_error;
+		return status;
 	status = nfsd4_decode_share_deny(argp, &open->op_share_deny);
 	if (status)
-		goto xdr_error;
-	READ_BUF(sizeof(clientid_t));
-	COPYMEM(&open->op_clientid, sizeof(clientid_t));
-	status = nfsd4_decode_opaque(argp, &open->op_owner);
+		return status;
+	status = nfsd4_decode_state_owner4(argp, &open->op_clientid,
+					   &open->op_owner);
 	if (status)
-		goto xdr_error;
+		return status;
 	status = nfsd4_decode_openflag4(argp, open);
 	if (status)
 		return status;
-	status = nfsd4_decode_open_claim4(argp, open);
-
-	DECODE_TAIL;
+	return nfsd4_decode_open_claim4(argp, open);
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#46 lore raw

PATCH 46/770 NFSD: Replace READ* macros in nfsd4_decode_open_confirm()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 06bee693a1f1cb774b91000f05a6e183c257d8e9 ]

---
 fs/nfsd/nfs4xdr.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
fs/nfsd/nfs4xdr.c +5 -5
index 2de54e84a3ab0..7b6fb11cdc809 100644
@@ -1155,18 +1155,18 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 static __be32
 nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf)
 {
-	DECODE_HEAD;
+	__be32 status;
 
 	if (argp->minorversion >= 1)
 		return nfserr_notsupp;
 
-	status = nfsd4_decode_stateid(argp, &open_conf->oc_req_stateid);
+	status = nfsd4_decode_stateid4(argp, &open_conf->oc_req_stateid);
 	if (status)
 		return status;
-	READ_BUF(4);
-	open_conf->oc_seqid = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &open_conf->oc_seqid) < 0)
+		return nfserr_bad_xdr;
 
-	DECODE_TAIL;
+	return nfs_ok;
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#47 lore raw

PATCH 47/770 NFSD: Replace READ* macros in nfsd4_decode_open_downgrade()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit dca71651f097ea608945d7a66bf62761a630de9a ]

---
 fs/nfsd/nfs4xdr.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)
fs/nfsd/nfs4xdr.c +7 -9
index 7b6fb11cdc809..95c755473899f 100644
@@ -1172,21 +1172,19 @@ nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_con
 static __be32
 nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_downgrade *open_down)
 {
-	DECODE_HEAD;
-		    
-	status = nfsd4_decode_stateid(argp, &open_down->od_stateid);
+	__be32 status;
+
+	status = nfsd4_decode_stateid4(argp, &open_down->od_stateid);
 	if (status)
 		return status;
-	READ_BUF(4);
-	open_down->od_seqid = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &open_down->od_seqid) < 0)
+		return nfserr_bad_xdr;
+	/* deleg_want is ignored */
 	status = nfsd4_decode_share_access(argp, &open_down->od_share_access,
 					   &open_down->od_deleg_want, NULL);
 	if (status)
 		return status;
-	status = nfsd4_decode_share_deny(argp, &open_down->od_share_deny);
-	if (status)
-		return status;
-	DECODE_TAIL;
+	return nfsd4_decode_share_deny(argp, &open_down->od_share_deny);
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#48 lore raw

PATCH 48/770 NFSD: Replace READ* macros in nfsd4_decode_putfh()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit a73bed98413b1d9eb4466f776a56d2fde8b3b2c9 ]

---
 fs/nfsd/nfs4xdr.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)
fs/nfsd/nfs4xdr.c +12 -7
index 95c755473899f..149948393ccb1 100644
@@ -1190,16 +1190,21 @@ nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_d
 static __be32
 nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh)
 {
-	DECODE_HEAD;
+	__be32 *p;
 
-	READ_BUF(4);
-	putfh->pf_fhlen = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &putfh->pf_fhlen) < 0)
+		return nfserr_bad_xdr;
 	if (putfh->pf_fhlen > NFS4_FHSIZE)
-		goto xdr_error;
-	READ_BUF(putfh->pf_fhlen);
-	SAVEMEM(putfh->pf_fhval, putfh->pf_fhlen);
+		return nfserr_bad_xdr;
+	p = xdr_inline_decode(argp->xdr, putfh->pf_fhlen);
+	if (!p)
+		return nfserr_bad_xdr;
+	putfh->pf_fhval = svcxdr_tmpalloc(argp, putfh->pf_fhlen);
+	if (!putfh->pf_fhval)
+		return nfserr_jukebox;
+	memcpy(putfh->pf_fhval, p, putfh->pf_fhlen);
 
-	DECODE_TAIL;
+	return nfs_ok;
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#49 lore raw

PATCH 49/770 NFSD: Replace READ* macros in nfsd4_decode_read()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 3909c3bc604688503e31ddceb429dc156c4720c1 ]

---
 fs/nfsd/nfs4xdr.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
fs/nfsd/nfs4xdr.c +7 -6
index 149948393ccb1..c9652040d748b 100644
@@ -1218,16 +1218,17 @@ nfsd4_decode_putpubfh(struct nfsd4_compoundargs *argp, void *p)
 static __be32
 nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read)
 {
-	DECODE_HEAD;
+	__be32 status;
 
-	status = nfsd4_decode_stateid(argp, &read->rd_stateid);
+	status = nfsd4_decode_stateid4(argp, &read->rd_stateid);
 	if (status)
 		return status;
-	READ_BUF(12);
-	p = xdr_decode_hyper(p, &read->rd_offset);
-	read->rd_length = be32_to_cpup(p++);
+	if (xdr_stream_decode_u64(argp->xdr, &read->rd_offset) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u32(argp->xdr, &read->rd_length) < 0)
+		return nfserr_bad_xdr;
 
-	DECODE_TAIL;
+	return nfs_ok;
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#50 lore raw

PATCH 50/770 NFSD: Replace READ* macros in nfsd4_decode_readdir()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 0dfaf2a371436860ace6af889e6cd8410ee63164 ]

---
 fs/nfsd/nfs4xdr.c | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)
fs/nfsd/nfs4xdr.c +14 -9
index c9652040d748b..6036f8d595efa 100644
@@ -1234,17 +1234,22 @@ nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read)
 static __be32
 nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *readdir)
 {
-	DECODE_HEAD;
+	__be32 status;
 
-	READ_BUF(24);
-	p = xdr_decode_hyper(p, &readdir->rd_cookie);
-	COPYMEM(readdir->rd_verf.data, sizeof(readdir->rd_verf.data));
-	readdir->rd_dircount = be32_to_cpup(p++);
-	readdir->rd_maxcount = be32_to_cpup(p++);
-	if ((status = nfsd4_decode_bitmap(argp, readdir->rd_bmval)))
-		goto out;
+	if (xdr_stream_decode_u64(argp->xdr, &readdir->rd_cookie) < 0)
+		return nfserr_bad_xdr;
+	status = nfsd4_decode_verifier4(argp, &readdir->rd_verf);
+	if (status)
+		return status;
+	if (xdr_stream_decode_u32(argp->xdr, &readdir->rd_dircount) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u32(argp->xdr, &readdir->rd_maxcount) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_uint32_array(argp->xdr, readdir->rd_bmval,
+					   ARRAY_SIZE(readdir->rd_bmval)) < 0)
+		return nfserr_bad_xdr;
 
-	DECODE_TAIL;
+	return nfs_ok;
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#51 lore raw

PATCH 51/770 NFSD: Replace READ* macros in nfsd4_decode_remove()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit b7f5fbf219aecda98e32de305551e445f9438899 ]

---
 fs/nfsd/nfs4xdr.c | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)
fs/nfsd/nfs4xdr.c +1 -10
index 6036f8d595efa..d4e1e3138739c 100644
@@ -1255,16 +1255,7 @@ nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *read
 static __be32
 nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove)
 {
-	DECODE_HEAD;
-
-	READ_BUF(4);
-	remove->rm_namelen = be32_to_cpup(p++);
-	READ_BUF(remove->rm_namelen);
-	SAVEMEM(remove->rm_name, remove->rm_namelen);
-	if ((status = check_filename(remove->rm_name, remove->rm_namelen)))
-		return status;
-
-	DECODE_TAIL;
+	return nfsd4_decode_component4(argp, &remove->rm_name, &remove->rm_namelen);
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#52 lore raw

PATCH 52/770 NFSD: Replace READ* macros in nfsd4_decode_rename()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit ba881a0a5342b3aaf83958901ebe3fe752eaab46 ]

---
 fs/nfsd/nfs4xdr.c | 18 ++++--------------
 1 file changed, 4 insertions(+), 14 deletions(-)
fs/nfsd/nfs4xdr.c +4 -14
index d4e1e3138739c..adf4a6fb94d4c 100644
@@ -1261,22 +1261,12 @@ nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove
 static __be32
 nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename)
 {
-	DECODE_HEAD;
+	__be32 status;
 
-	READ_BUF(4);
-	rename->rn_snamelen = be32_to_cpup(p++);
-	READ_BUF(rename->rn_snamelen);
-	SAVEMEM(rename->rn_sname, rename->rn_snamelen);
-	READ_BUF(4);
-	rename->rn_tnamelen = be32_to_cpup(p++);
-	READ_BUF(rename->rn_tnamelen);
-	SAVEMEM(rename->rn_tname, rename->rn_tnamelen);
-	if ((status = check_filename(rename->rn_sname, rename->rn_snamelen)))
-		return status;
-	if ((status = check_filename(rename->rn_tname, rename->rn_tnamelen)))
+	status = nfsd4_decode_component4(argp, &rename->rn_sname, &rename->rn_snamelen);
+	if (status)
 		return status;
-
-	DECODE_TAIL;
+	return nfsd4_decode_component4(argp, &rename->rn_tname, &rename->rn_tnamelen);
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#53 lore raw

PATCH 53/770 NFSD: Replace READ* macros in nfsd4_decode_renew()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit d12f90458dc8c11734ba44ec88f109bf8de86ff0 ]

---
 fs/nfsd/nfs4xdr.c | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)
fs/nfsd/nfs4xdr.c +1 -9
index adf4a6fb94d4c..51b59b369d726 100644
@@ -1272,15 +1272,7 @@ nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename
 static __be32
 nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid)
 {
-	DECODE_HEAD;
-
-	if (argp->minorversion >= 1)
-		return nfserr_notsupp;
-
-	READ_BUF(sizeof(clientid_t));
-	COPYMEM(clientid, sizeof(clientid_t));
-
-	DECODE_TAIL;
+	return nfsd4_decode_clientid4(argp, clientid);
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#54 lore raw

PATCH 54/770 NFSD: Replace READ* macros in nfsd4_decode_secinfo()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit d0abdae5191a916d767164f6fc6c0e2e814a20a7 ]

---
 fs/nfsd/nfs4xdr.c | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)
fs/nfsd/nfs4xdr.c +1 -10
index 51b59b369d726..42d69c0207ce8 100644
@@ -1279,16 +1279,7 @@ static __be32
 nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp,
 		     struct nfsd4_secinfo *secinfo)
 {
-	DECODE_HEAD;
-
-	READ_BUF(4);
-	secinfo->si_namelen = be32_to_cpup(p++);
-	READ_BUF(secinfo->si_namelen);
-	SAVEMEM(secinfo->si_name, secinfo->si_namelen);
-	status = check_filename(secinfo->si_name, secinfo->si_namelen);
-	if (status)
-		return status;
-	DECODE_TAIL;
+	return nfsd4_decode_component4(argp, &secinfo->si_name, &secinfo->si_namelen);
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#55 lore raw

PATCH 55/770 NFSD: Replace READ* macros in nfsd4_decode_setattr()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 44592fe9479d8d4b88594365ab825f7b07afdf7c ]

---
 fs/nfsd/nfs4xdr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfsd/nfs4xdr.c +1 -1
index 42d69c0207ce8..cda56ca9ca3fc 100644
@@ -1298,7 +1298,7 @@ nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *seta
 {
 	__be32 status;
 
-	status = nfsd4_decode_stateid(argp, &setattr->sa_stateid);
+	status = nfsd4_decode_stateid4(argp, &setattr->sa_stateid);
 	if (status)
 		return status;
 	return nfsd4_decode_fattr4(argp, setattr->sa_bmval,
Signature · 1 line
2.43.0
author maintainer
#56 lore raw

PATCH 56/770 NFSD: Replace READ* macros in nfsd4_decode_setclientid()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 92fa6c08c251d52d0d7b46066ecf87b96a0c4b8f ]

---
 fs/nfsd/nfs4xdr.c | 47 +++++++++++++++++++++++++++++++----------------
 1 file changed, 31 insertions(+), 16 deletions(-)
fs/nfsd/nfs4xdr.c +31 -16
index cda56ca9ca3fc..0af51cc1adba3 100644
@@ -1310,31 +1310,46 @@ nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *seta
 static __be32
 nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid *setclientid)
 {
-	DECODE_HEAD;
+	__be32 *p, status;
 
 	if (argp->minorversion >= 1)
 		return nfserr_notsupp;
 
-	READ_BUF(NFS4_VERIFIER_SIZE);
-	COPYMEM(setclientid->se_verf.data, NFS4_VERIFIER_SIZE);
-
+	status = nfsd4_decode_verifier4(argp, &setclientid->se_verf);
+	if (status)
+		return status;
 	status = nfsd4_decode_opaque(argp, &setclientid->se_name);
 	if (status)
+		return status;
+	if (xdr_stream_decode_u32(argp->xdr, &setclientid->se_callback_prog) < 0)
 		return nfserr_bad_xdr;
-	READ_BUF(8);
-	setclientid->se_callback_prog = be32_to_cpup(p++);
-	setclientid->se_callback_netid_len = be32_to_cpup(p++);
-	READ_BUF(setclientid->se_callback_netid_len);
-	SAVEMEM(setclientid->se_callback_netid_val, setclientid->se_callback_netid_len);
-	READ_BUF(4);
-	setclientid->se_callback_addr_len = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &setclientid->se_callback_netid_len) < 0)
+		return nfserr_bad_xdr;
+	p = xdr_inline_decode(argp->xdr, setclientid->se_callback_netid_len);
+	if (!p)
+		return nfserr_bad_xdr;
+	setclientid->se_callback_netid_val = svcxdr_tmpalloc(argp,
+						setclientid->se_callback_netid_len);
+	if (!setclientid->se_callback_netid_val)
+		return nfserr_jukebox;
+	memcpy(setclientid->se_callback_netid_val, p,
+	       setclientid->se_callback_netid_len);
 
-	READ_BUF(setclientid->se_callback_addr_len);
-	SAVEMEM(setclientid->se_callback_addr_val, setclientid->se_callback_addr_len);
-	READ_BUF(4);
-	setclientid->se_callback_ident = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &setclientid->se_callback_addr_len) < 0)
+		return nfserr_bad_xdr;
+	p = xdr_inline_decode(argp->xdr, setclientid->se_callback_addr_len);
+	if (!p)
+		return nfserr_bad_xdr;
+	setclientid->se_callback_addr_val = svcxdr_tmpalloc(argp,
+						setclientid->se_callback_addr_len);
+	if (!setclientid->se_callback_addr_val)
+		return nfserr_jukebox;
+	memcpy(setclientid->se_callback_addr_val, p,
+	       setclientid->se_callback_addr_len);
+	if (xdr_stream_decode_u32(argp->xdr, &setclientid->se_callback_ident) < 0)
+		return nfserr_bad_xdr;
 
-	DECODE_TAIL;
+	return nfs_ok;
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#57 lore raw

PATCH 57/770 NFSD: Replace READ* macros in nfsd4_decode_setclientid_confirm()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit d1ca55149d67e5896f89a30053f5d83c002ac10e ]

---
 fs/nfsd/nfs4xdr.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)
fs/nfsd/nfs4xdr.c +5 -6
index 0af51cc1adba3..057cc1579f9b8 100644
@@ -1355,16 +1355,15 @@ nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclient
 static __be32
 nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid_confirm *scd_c)
 {
-	DECODE_HEAD;
+	__be32 status;
 
 	if (argp->minorversion >= 1)
 		return nfserr_notsupp;
 
-	READ_BUF(8 + NFS4_VERIFIER_SIZE);
-	COPYMEM(&scd_c->sc_clientid, 8);
-	COPYMEM(&scd_c->sc_confirm, NFS4_VERIFIER_SIZE);
-
-	DECODE_TAIL;
+	status = nfsd4_decode_clientid4(argp, &scd_c->sc_clientid);
+	if (status)
+		return status;
+	return nfsd4_decode_verifier4(argp, &scd_c->sc_confirm);
 }
 
 /* Also used for NVERIFY */
Signature · 1 line
2.43.0
author maintainer
#58 lore raw

PATCH 58/770 NFSD: Replace READ* macros in nfsd4_decode_verify()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 67cd453eeda86be90f83a0f4798f33832cf2d98c ]

---
 fs/nfsd/nfs4xdr.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)
fs/nfsd/nfs4xdr.c +15 -8
index 057cc1579f9b8..231a2628e3e6f 100644
@@ -1370,20 +1370,27 @@ nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_s
 static __be32
 nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify)
 {
-	DECODE_HEAD;
+	__be32 *p, status;
 
-	if ((status = nfsd4_decode_bitmap(argp, verify->ve_bmval)))
-		goto out;
+	status = nfsd4_decode_bitmap4(argp, verify->ve_bmval,
+				      ARRAY_SIZE(verify->ve_bmval));
+	if (status)
+		return status;
 
 	/* For convenience's sake, we compare raw xdr'd attributes in
 	 * nfsd4_proc_verify */
 
-	READ_BUF(4);
-	verify->ve_attrlen = be32_to_cpup(p++);
-	READ_BUF(verify->ve_attrlen);
-	SAVEMEM(verify->ve_attrval, verify->ve_attrlen);
+	if (xdr_stream_decode_u32(argp->xdr, &verify->ve_attrlen) < 0)
+		return nfserr_bad_xdr;
+	p = xdr_inline_decode(argp->xdr, verify->ve_attrlen);
+	if (!p)
+		return nfserr_bad_xdr;
+	verify->ve_attrval = svcxdr_tmpalloc(argp, verify->ve_attrlen);
+	if (!verify->ve_attrval)
+		return nfserr_jukebox;
+	memcpy(verify->ve_attrval, p, verify->ve_attrlen);
 
-	DECODE_TAIL;
+	return nfs_ok;
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#59 lore raw

PATCH 59/770 NFSD: Replace READ* macros in nfsd4_decode_write()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 244e2befcba80f42c65293b6c56282bb78f9f417 ]

---
 fs/nfsd/nfs4xdr.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)
fs/nfsd/nfs4xdr.c +11 -10
index 231a2628e3e6f..26744b7f0e35c 100644
@@ -1396,22 +1396,23 @@ nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify
 static __be32
 nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
 {
-	DECODE_HEAD;
+	__be32 status;
 
-	status = nfsd4_decode_stateid(argp, &write->wr_stateid);
+	status = nfsd4_decode_stateid4(argp, &write->wr_stateid);
 	if (status)
 		return status;
-	READ_BUF(16);
-	p = xdr_decode_hyper(p, &write->wr_offset);
-	write->wr_stable_how = be32_to_cpup(p++);
+	if (xdr_stream_decode_u64(argp->xdr, &write->wr_offset) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u32(argp->xdr, &write->wr_stable_how) < 0)
+		return nfserr_bad_xdr;
 	if (write->wr_stable_how > NFS_FILE_SYNC)
-		goto xdr_error;
-	write->wr_buflen = be32_to_cpup(p++);
-
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u32(argp->xdr, &write->wr_buflen) < 0)
+		return nfserr_bad_xdr;
 	if (!xdr_stream_subsegment(argp->xdr, &write->wr_payload, write->wr_buflen))
-		goto xdr_error;
+		return nfserr_bad_xdr;
 
-	DECODE_TAIL;
+	return nfs_ok;
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#60 lore raw

PATCH 60/770 NFSD: Replace READ* macros in nfsd4_decode_release_lockowner()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit a4a80c15ca4dd998ab5cbe87bd856c626a318a80 ]

---
 fs/nfsd/nfs4xdr.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
fs/nfsd/nfs4xdr.c +7 -7
index 26744b7f0e35c..cc406b7a530b6 100644
@@ -1418,20 +1418,20 @@ nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
 static __be32
 nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_release_lockowner *rlockowner)
 {
-	DECODE_HEAD;
+	__be32 status;
 
 	if (argp->minorversion >= 1)
 		return nfserr_notsupp;
 
-	READ_BUF(12);
-	COPYMEM(&rlockowner->rl_clientid, sizeof(clientid_t));
-	rlockowner->rl_owner.len = be32_to_cpup(p++);
-	READ_BUF(rlockowner->rl_owner.len);
-	READMEM(rlockowner->rl_owner.data, rlockowner->rl_owner.len);
+	status = nfsd4_decode_state_owner4(argp, &rlockowner->rl_clientid,
+					   &rlockowner->rl_owner);
+	if (status)
+		return status;
 
 	if (argp->minorversion && !zero_clientid(&rlockowner->rl_clientid))
 		return nfserr_inval;
-	DECODE_TAIL;
+
+	return nfs_ok;
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#61 lore raw

PATCH 61/770 NFSD: Replace READ* macros in nfsd4_decode_cb_sec()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 1a99440807bfc66597aaa2e0f0213c319b023e34 ]

---
 fs/nfsd/nfs4xdr.c | 165 ++++++++++++++++++++++++++++++----------------
 1 file changed, 107 insertions(+), 58 deletions(-)
fs/nfsd/nfs4xdr.c +107 -58
index cc406b7a530b6..6f3c86bee6211 100644
@@ -212,6 +212,25 @@ static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes)
  * NFSv4 basic data type decoders
  */
 
+/*
+ * This helper handles variable-length opaques which belong to protocol
+ * elements that this implementation does not support.
+ */
+static __be32
+nfsd4_decode_ignored_string(struct nfsd4_compoundargs *argp, u32 maxlen)
+{
+	u32 len;
+
+	if (xdr_stream_decode_u32(argp->xdr, &len) < 0)
+		return nfserr_bad_xdr;
+	if (maxlen && len > maxlen)
+		return nfserr_bad_xdr;
+	if (!xdr_inline_decode(argp->xdr, len))
+		return nfserr_bad_xdr;
+
+	return nfs_ok;
+}
+
 static __be32
 nfsd4_decode_opaque(struct nfsd4_compoundargs *argp, struct xdr_netobj *o)
 {
@@ -645,87 +664,117 @@ nfsd4_decode_state_owner4(struct nfsd4_compoundargs *argp,
 	return nfsd4_decode_opaque(argp, owner);
 }
 
-static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_cb_sec *cbs)
+/* Defined in Appendix A of RFC 5531 */
+static __be32
+nfsd4_decode_authsys_parms(struct nfsd4_compoundargs *argp,
+			   struct nfsd4_cb_sec *cbs)
 {
-	DECODE_HEAD;
-	struct user_namespace *userns = nfsd_user_namespace(argp->rqstp);
-	u32 dummy, uid, gid;
-	char *machine_name;
-	int i;
-	int nr_secflavs;
+	u32 stamp, gidcount, uid, gid;
+	__be32 *p, status;
+
+	if (xdr_stream_decode_u32(argp->xdr, &stamp) < 0)
+		return nfserr_bad_xdr;
+	/* machine name */
+	status = nfsd4_decode_ignored_string(argp, 255);
+	if (status)
+		return status;
+	if (xdr_stream_decode_u32(argp->xdr, &uid) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u32(argp->xdr, &gid) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u32(argp->xdr, &gidcount) < 0)
+		return nfserr_bad_xdr;
+	if (gidcount > 16)
+		return nfserr_bad_xdr;
+	p = xdr_inline_decode(argp->xdr, gidcount << 2);
+	if (!p)
+		return nfserr_bad_xdr;
+	if (cbs->flavor == (u32)(-1)) {
+		struct user_namespace *userns = nfsd_user_namespace(argp->rqstp);
+
+		kuid_t kuid = make_kuid(userns, uid);
+		kgid_t kgid = make_kgid(userns, gid);
+		if (uid_valid(kuid) && gid_valid(kgid)) {
+			cbs->uid = kuid;
+			cbs->gid = kgid;
+			cbs->flavor = RPC_AUTH_UNIX;
+		} else {
+			dprintk("RPC_AUTH_UNIX with invalid uid or gid, ignoring!\n");
+		}
+	}
+
+	return nfs_ok;
+}
+
+static __be32
+nfsd4_decode_gss_cb_handles4(struct nfsd4_compoundargs *argp,
+			     struct nfsd4_cb_sec *cbs)
+{
+	__be32 status;
+	u32 service;
+
+	dprintk("RPC_AUTH_GSS callback secflavor not supported!\n");
+
+	if (xdr_stream_decode_u32(argp->xdr, &service) < 0)
+		return nfserr_bad_xdr;
+	if (service < RPC_GSS_SVC_NONE || service > RPC_GSS_SVC_PRIVACY)
+		return nfserr_bad_xdr;
+	/* gcbp_handle_from_server */
+	status = nfsd4_decode_ignored_string(argp, 0);
+	if (status)
+		return status;
+	/* gcbp_handle_from_client */
+	status = nfsd4_decode_ignored_string(argp, 0);
+	if (status)
+		return status;
+
+	return nfs_ok;
+}
+
+/* a counted array of callback_sec_parms4 items */
+static __be32
+nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_cb_sec *cbs)
+{
+	u32 i, secflavor, nr_secflavs;
+	__be32 status;
 
 	/* callback_sec_params4 */
-	READ_BUF(4);
-	nr_secflavs = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &nr_secflavs) < 0)
+		return nfserr_bad_xdr;
 	if (nr_secflavs)
 		cbs->flavor = (u32)(-1);
 	else
 		/* Is this legal? Be generous, take it to mean AUTH_NONE: */
 		cbs->flavor = 0;
+
 	for (i = 0; i < nr_secflavs; ++i) {
-		READ_BUF(4);
-		dummy = be32_to_cpup(p++);
-		switch (dummy) {
+		if (xdr_stream_decode_u32(argp->xdr, &secflavor) < 0)
+			return nfserr_bad_xdr;
+		switch (secflavor) {
 		case RPC_AUTH_NULL:
-			/* Nothing to read */
+			/* void */
 			if (cbs->flavor == (u32)(-1))
 				cbs->flavor = RPC_AUTH_NULL;
 			break;
 		case RPC_AUTH_UNIX:
-			READ_BUF(8);
-			/* stamp */
-			dummy = be32_to_cpup(p++);
-
-			/* machine name */
-			dummy = be32_to_cpup(p++);
-			READ_BUF(dummy);
-			SAVEMEM(machine_name, dummy);
-
-			/* uid, gid */
-			READ_BUF(8);
-			uid = be32_to_cpup(p++);
-			gid = be32_to_cpup(p++);
-
-			/* more gids */
-			READ_BUF(4);
-			dummy = be32_to_cpup(p++);
-			READ_BUF(dummy * 4);
-			if (cbs->flavor == (u32)(-1)) {
-				kuid_t kuid = make_kuid(userns, uid);
-				kgid_t kgid = make_kgid(userns, gid);
-				if (uid_valid(kuid) && gid_valid(kgid)) {
-					cbs->uid = kuid;
-					cbs->gid = kgid;
-					cbs->flavor = RPC_AUTH_UNIX;
-				} else {
-					dprintk("RPC_AUTH_UNIX with invalid"
-						"uid or gid ignoring!\n");
-				}
-			}
+			status = nfsd4_decode_authsys_parms(argp, cbs);
+			if (status)
+				return status;
 			break;
 		case RPC_AUTH_GSS:
-			dprintk("RPC_AUTH_GSS callback secflavor "
-				"not supported!\n");
-			READ_BUF(8);
-			/* gcbp_service */
-			dummy = be32_to_cpup(p++);
-			/* gcbp_handle_from_server */
-			dummy = be32_to_cpup(p++);
-			READ_BUF(dummy);
-			p += XDR_QUADLEN(dummy);
-			/* gcbp_handle_from_client */
-			READ_BUF(4);
-			dummy = be32_to_cpup(p++);
-			READ_BUF(dummy);
+			status = nfsd4_decode_gss_cb_handles4(argp, cbs);
+			if (status)
+				return status;
 			break;
 		default:
-			dprintk("Illegal callback secflavor\n");
 			return nfserr_inval;
 		}
 	}
-	DECODE_TAIL;
+
+	return nfs_ok;
 }
 
+
 /*
  * NFSv4 operation argument decoders
  */
Signature · 1 line
2.43.0
author maintainer
#62 lore raw

PATCH 62/770 NFSD: Replace READ* macros in nfsd4_decode_backchannel_ctl()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 0f81d96098f8eb707afe2f8d5c3fe0f9316ef5ce ]

---
 fs/nfsd/nfs4xdr.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)
fs/nfsd/nfs4xdr.c +7 -11
index 6f3c86bee6211..efd1504cd02b6 100644
@@ -788,17 +788,6 @@ nfsd4_decode_access(struct nfsd4_compoundargs *argp,
 	return nfs_ok;
 }
 
-static __be32 nfsd4_decode_backchannel_ctl(struct nfsd4_compoundargs *argp, struct nfsd4_backchannel_ctl *bc)
-{
-	DECODE_HEAD;
-
-	READ_BUF(4);
-	bc->bc_cb_program = be32_to_cpup(p++);
-	nfsd4_decode_cb_sec(argp, &bc->bc_cb_sec);
-
-	DECODE_TAIL;
-}
-
 static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts)
 {
 	DECODE_HEAD;
@@ -1483,6 +1472,13 @@ nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_rel
 	return nfs_ok;
 }
 
+static __be32 nfsd4_decode_backchannel_ctl(struct nfsd4_compoundargs *argp, struct nfsd4_backchannel_ctl *bc)
+{
+	if (xdr_stream_decode_u32(argp->xdr, &bc->bc_cb_program) < 0)
+		return nfserr_bad_xdr;
+	return nfsd4_decode_cb_sec(argp, &bc->bc_cb_sec);
+}
+
 static __be32
 nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
 			 struct nfsd4_exchange_id *exid)
Signature · 1 line
2.43.0
author maintainer
#63 lore raw

PATCH 63/770 NFSD: Replace READ* macros in nfsd4_decode_bind_conn_to_session()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 571e0451c4de0a545960ffaea16d969931afc563 ]

A dedicated sessionid4 decoder is introduced that will be used by other operation decoders in subsequent patches.

---
 fs/nfsd/nfs4xdr.c | 41 +++++++++++++++++++++++++++++------------
 1 file changed, 29 insertions(+), 12 deletions(-)
fs/nfsd/nfs4xdr.c +29 -12
index efd1504cd02b6..5dad32ab02ec4 100644
@@ -664,6 +664,19 @@ nfsd4_decode_state_owner4(struct nfsd4_compoundargs *argp,
 	return nfsd4_decode_opaque(argp, owner);
 }
 
+static __be32
+nfsd4_decode_sessionid4(struct nfsd4_compoundargs *argp,
+			struct nfs4_sessionid *sessionid)
+{
+	__be32 *p;
+
+	p = xdr_inline_decode(argp->xdr, NFS4_MAX_SESSIONID_LEN);
+	if (!p)
+		return nfserr_bad_xdr;
+	memcpy(sessionid->data, p, sizeof(sessionid->data));
+	return nfs_ok;
+}
+
 /* Defined in Appendix A of RFC 5531 */
 static __be32
 nfsd4_decode_authsys_parms(struct nfsd4_compoundargs *argp,
@@ -788,18 +801,6 @@ nfsd4_decode_access(struct nfsd4_compoundargs *argp,
 	return nfs_ok;
 }
 
-static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts)
-{
-	DECODE_HEAD;
-
-	READ_BUF(NFS4_MAX_SESSIONID_LEN + 8);
-	COPYMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN);
-	bcts->dir = be32_to_cpup(p++);
-	/* XXX: skipping ctsa_use_conn_in_rdma_mode.  Perhaps Tom Tucker
-	 * could help us figure out we should be using it. */
-	DECODE_TAIL;
-}
-
 static __be32
 nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
 {
@@ -1479,6 +1480,22 @@ static __be32 nfsd4_decode_backchannel_ctl(struct nfsd4_compoundargs *argp, stru
 	return nfsd4_decode_cb_sec(argp, &bc->bc_cb_sec);
 }
 
+static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts)
+{
+	u32 use_conn_in_rdma_mode;
+	__be32 status;
+
+	status = nfsd4_decode_sessionid4(argp, &bcts->sessionid);
+	if (status)
+		return status;
+	if (xdr_stream_decode_u32(argp->xdr, &bcts->dir) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u32(argp->xdr, &use_conn_in_rdma_mode) < 0)
+		return nfserr_bad_xdr;
+
+	return nfs_ok;
+}
+
 static __be32
 nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
 			 struct nfsd4_exchange_id *exid)
Signature · 1 line
2.43.0
author maintainer
#64 lore raw

PATCH 64/770 NFSD: Add a separate decoder to handle state_protect_ops

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 2548aa784d760567c2a77cbd8b7c55b211167c37 ]

Refactor for clarity and de-duplication of code.

---
 fs/nfsd/nfs4xdr.c | 66 +++++++++++++++++------------------------------
 1 file changed, 23 insertions(+), 43 deletions(-)
fs/nfsd/nfs4xdr.c +23 -43
index 5dad32ab02ec4..15535b14328e4 100644
@@ -315,32 +315,6 @@ nfsd4_decode_verifier4(struct nfsd4_compoundargs *argp, nfs4_verifier *verf)
 	return nfs_ok;
 }
 
-static __be32
-nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
-{
-	u32 bmlen;
-	DECODE_HEAD;
-
-	bmval[0] = 0;
-	bmval[1] = 0;
-	bmval[2] = 0;
-
-	READ_BUF(4);
-	bmlen = be32_to_cpup(p++);
-	if (bmlen > 1000)
-		goto xdr_error;
-
-	READ_BUF(bmlen << 2);
-	if (bmlen > 0)
-		bmval[0] = be32_to_cpup(p++);
-	if (bmlen > 1)
-		bmval[1] = be32_to_cpup(p++);
-	if (bmlen > 2)
-		bmval[2] = be32_to_cpup(p++);
-
-	DECODE_TAIL;
-}
-
 /**
  * nfsd4_decode_bitmap4 - Decode an NFSv4 bitmap4
  * @argp: NFSv4 compound argument structure
@@ -1496,6 +1470,24 @@ static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp,
 	return nfs_ok;
 }
 
+static __be32
+nfsd4_decode_state_protect_ops(struct nfsd4_compoundargs *argp,
+			       struct nfsd4_exchange_id *exid)
+{
+	__be32 status;
+
+	status = nfsd4_decode_bitmap4(argp, exid->spo_must_enforce,
+				      ARRAY_SIZE(exid->spo_must_enforce));
+	if (status)
+		return nfserr_bad_xdr;
+	status = nfsd4_decode_bitmap4(argp, exid->spo_must_allow,
+				      ARRAY_SIZE(exid->spo_must_allow));
+	if (status)
+		return nfserr_bad_xdr;
+
+	return nfs_ok;
+}
+
 static __be32
 nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
 			 struct nfsd4_exchange_id *exid)
@@ -1520,27 +1512,15 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
 	case SP4_NONE:
 		break;
 	case SP4_MACH_CRED:
-		/* spo_must_enforce */
-		status = nfsd4_decode_bitmap(argp,
-					exid->spo_must_enforce);
-		if (status)
-			goto out;
-		/* spo_must_allow */
-		status = nfsd4_decode_bitmap(argp, exid->spo_must_allow);
+		status = nfsd4_decode_state_protect_ops(argp, exid);
 		if (status)
-			goto out;
+			return status;
 		break;
 	case SP4_SSV:
 		/* ssp_ops */
-		READ_BUF(4);
-		dummy = be32_to_cpup(p++);
-		READ_BUF(dummy * 4);
-		p += dummy;
-
-		READ_BUF(4);
-		dummy = be32_to_cpup(p++);
-		READ_BUF(dummy * 4);
-		p += dummy;
+		status = nfsd4_decode_state_protect_ops(argp, exid);
+		if (status)
+			return status;
 
 		/* ssp_hash_algs<> */
 		READ_BUF(4);
Signature · 1 line
2.43.0
author maintainer
#65 lore raw

PATCH 65/770 NFSD: Add a separate decoder for ssv_sp_parms

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 547bfeb4cd8d491aabbd656d5a6f410cb4249b4e ]

Refactor for clarity.

---
 fs/nfsd/nfs4xdr.c | 70 +++++++++++++++++++++++++++++------------------
 1 file changed, 44 insertions(+), 26 deletions(-)
fs/nfsd/nfs4xdr.c +44 -26
index 15535b14328e4..8c5701367e4af 100644
@@ -1488,12 +1488,54 @@ nfsd4_decode_state_protect_ops(struct nfsd4_compoundargs *argp,
 	return nfs_ok;
 }
 
+/*
+ * This implementation currently does not support SP4_SSV.
+ * This decoder simply skips over these arguments.
+ */
+static noinline __be32
+nfsd4_decode_ssv_sp_parms(struct nfsd4_compoundargs *argp,
+			  struct nfsd4_exchange_id *exid)
+{
+	u32 count, window, num_gss_handles;
+	__be32 status;
+
+	/* ssp_ops */
+	status = nfsd4_decode_state_protect_ops(argp, exid);
+	if (status)
+		return status;
+
+	/* ssp_hash_algs<> */
+	if (xdr_stream_decode_u32(argp->xdr, &count) < 0)
+		return nfserr_bad_xdr;
+	while (count--) {
+		status = nfsd4_decode_ignored_string(argp, 0);
+		if (status)
+			return status;
+	}
+
+	/* ssp_encr_algs<> */
+	if (xdr_stream_decode_u32(argp->xdr, &count) < 0)
+		return nfserr_bad_xdr;
+	while (count--) {
+		status = nfsd4_decode_ignored_string(argp, 0);
+		if (status)
+			return status;
+	}
+
+	if (xdr_stream_decode_u32(argp->xdr, &window) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u32(argp->xdr, &num_gss_handles) < 0)
+		return nfserr_bad_xdr;
+
+	return nfs_ok;
+}
+
 static __be32
 nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
 			 struct nfsd4_exchange_id *exid)
 {
-	int dummy, tmp;
 	DECODE_HEAD;
+	int dummy;
 
 	READ_BUF(NFS4_VERIFIER_SIZE);
 	COPYMEM(exid->verifier.data, NFS4_VERIFIER_SIZE);
@@ -1517,33 +1559,9 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
 			return status;
 		break;
 	case SP4_SSV:
-		/* ssp_ops */
-		status = nfsd4_decode_state_protect_ops(argp, exid);
+		status = nfsd4_decode_ssv_sp_parms(argp, exid);
 		if (status)
 			return status;
-
-		/* ssp_hash_algs<> */
-		READ_BUF(4);
-		tmp = be32_to_cpup(p++);
-		while (tmp--) {
-			READ_BUF(4);
-			dummy = be32_to_cpup(p++);
-			READ_BUF(dummy);
-			p += XDR_QUADLEN(dummy);
-		}
-
-		/* ssp_encr_algs<> */
-		READ_BUF(4);
-		tmp = be32_to_cpup(p++);
-		while (tmp--) {
-			READ_BUF(4);
-			dummy = be32_to_cpup(p++);
-			READ_BUF(dummy);
-			p += XDR_QUADLEN(dummy);
-		}
-
-		/* ignore ssp_window and ssp_num_gss_handles: */
-		READ_BUF(8);
 		break;
 	default:
 		goto xdr_error;
Signature · 1 line
2.43.0
author maintainer
#66 lore raw

PATCH 66/770 NFSD: Add a helper to decode state_protect4_a

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 523ec6ed6fb80fd1537d748a06bffd060a8b3235 ]

Refactor for clarity.

Also, remove a stale comment. Commit ed94164398c9 ("nfsd: implement machine credential support for some operations") added support for SP4_MACH_CRED, so state_protect_a is no longer completely ignored.

---
 fs/nfsd/nfs4state.c |  2 +-
 fs/nfsd/nfs4xdr.c   | 44 +++++++++++++++++++++++++++-----------------
 fs/nfsd/xdr4.h      |  2 +-
 3 files changed, 29 insertions(+), 19 deletions(-)
fs/nfsd/nfs4state.c +1 -1
index d402ca0b535f0..e7ec7593eaaa3 100644
@@ -3089,7 +3089,7 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 
 	rpc_ntop(sa, addr_str, sizeof(addr_str));
 	dprintk("%s rqstp=%p exid=%p clname.len=%u clname.data=%p "
-		"ip_addr=%s flags %x, spa_how %d\n",
+		"ip_addr=%s flags %x, spa_how %u\n",
 		__func__, rqstp, exid, exid->clname.len, exid->clname.data,
 		addr_str, exid->flags, exid->spa_how);
 
fs/nfsd/nfs4xdr.c +27 -17

61 lines not on this page · raw message

fs/nfsd/xdr4.h +1 -1
index 6245004a9993b..232529bc1b798 100644
@@ -433,7 +433,7 @@ struct nfsd4_exchange_id {
 	u32		flags;
 	clientid_t	clientid;
 	u32		seqid;
-	int		spa_how;
+	u32		spa_how;
 	u32             spo_must_enforce[3];
 	u32             spo_must_allow[3];
 	struct xdr_netobj nii_domain;
Signature · 1 line
2.43.0
author maintainer
#67 lore raw

PATCH 67/770 NFSD: Add a helper to decode nfs_impl_id4

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 10ff84228197f47401833495ba19a50131323b4a ]

Refactor for clarity.

---
 fs/nfsd/nfs4xdr.c | 63 ++++++++++++++++++++++++++++-------------------
 1 file changed, 38 insertions(+), 25 deletions(-)
fs/nfsd/nfs4xdr.c +38 -25
index 6a4ab81e01ffc..e06e657c3d91c 100644
@@ -1558,12 +1558,47 @@ nfsd4_decode_state_protect4_a(struct nfsd4_compoundargs *argp,
 	return nfs_ok;
 }
 
+static __be32
+nfsd4_decode_nfs_impl_id4(struct nfsd4_compoundargs *argp,
+			  struct nfsd4_exchange_id *exid)
+{
+	__be32 status;
+	u32 count;
+
+	if (xdr_stream_decode_u32(argp->xdr, &count) < 0)
+		return nfserr_bad_xdr;
+	switch (count) {
+	case 0:
+		break;
+	case 1:
+		/* Note that RFC 8881 places no length limit on
+		 * nii_domain, but this implementation permits no
+		 * more than NFS4_OPAQUE_LIMIT bytes */
+		status = nfsd4_decode_opaque(argp, &exid->nii_domain);
+		if (status)
+			return status;
+		/* Note that RFC 8881 places no length limit on
+		 * nii_name, but this implementation permits no
+		 * more than NFS4_OPAQUE_LIMIT bytes */
+		status = nfsd4_decode_opaque(argp, &exid->nii_name);
+		if (status)
+			return status;
+		status = nfsd4_decode_nfstime4(argp, &exid->nii_time);
+		if (status)
+			return status;
+		break;
+	default:
+		return nfserr_bad_xdr;
+	}
+
+	return nfs_ok;
+}
+
 static __be32
 nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
 			 struct nfsd4_exchange_id *exid)
 {
-	DECODE_HEAD;
-	int dummy;
+	__be32 status;
 
 	status = nfsd4_decode_verifier4(argp, &exid->verifier);
 	if (status)
@@ -1576,29 +1611,7 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
 	status = nfsd4_decode_state_protect4_a(argp, exid);
 	if (status)
 		return status;
-
-	READ_BUF(4);    /* nfs_impl_id4 array length */
-	dummy = be32_to_cpup(p++);
-
-	if (dummy > 1)
-		goto xdr_error;
-
-	if (dummy == 1) {
-		status = nfsd4_decode_opaque(argp, &exid->nii_domain);
-		if (status)
-			goto xdr_error;
-
-		/* nii_name */
-		status = nfsd4_decode_opaque(argp, &exid->nii_name);
-		if (status)
-			goto xdr_error;
-
-		/* nii_date */
-		status = nfsd4_decode_time(argp, &exid->nii_time);
-		if (status)
-			goto xdr_error;
-	}
-	DECODE_TAIL;
+	return nfsd4_decode_nfs_impl_id4(argp, exid);
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#68 lore raw

PATCH 68/770 NFSD: Add a helper to decode channel_attrs4

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 3a3f1fbacb0960b628e5a9f07c78287312f7a99d ]

De-duplicate some code.

---
 fs/nfsd/nfs4xdr.c | 71 +++++++++++++++++++++++++----------------------
 1 file changed, 38 insertions(+), 33 deletions(-)
fs/nfsd/nfs4xdr.c +38 -33
index e06e657c3d91c..716a16961ff48 100644
@@ -1614,6 +1614,38 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
 	return nfsd4_decode_nfs_impl_id4(argp, exid);
 }
 
+static __be32
+nfsd4_decode_channel_attrs4(struct nfsd4_compoundargs *argp,
+			    struct nfsd4_channel_attrs *ca)
+{
+	__be32 *p;
+
+	p = xdr_inline_decode(argp->xdr, XDR_UNIT * 7);
+	if (!p)
+		return nfserr_bad_xdr;
+
+	/* headerpadsz is ignored */
+	p++;
+	ca->maxreq_sz = be32_to_cpup(p++);
+	ca->maxresp_sz = be32_to_cpup(p++);
+	ca->maxresp_cached = be32_to_cpup(p++);
+	ca->maxops = be32_to_cpup(p++);
+	ca->maxreqs = be32_to_cpup(p++);
+	ca->nr_rdma_attrs = be32_to_cpup(p);
+	switch (ca->nr_rdma_attrs) {
+	case 0:
+		break;
+	case 1:
+		if (xdr_stream_decode_u32(argp->xdr, &ca->rdma_attrs) < 0)
+			return nfserr_bad_xdr;
+		break;
+	default:
+		return nfserr_bad_xdr;
+	}
+
+	return nfs_ok;
+}
+
 static __be32
 nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
 			    struct nfsd4_create_session *sess)
@@ -1625,39 +1657,12 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
 	sess->seqid = be32_to_cpup(p++);
 	sess->flags = be32_to_cpup(p++);
 
-	/* Fore channel attrs */
-	READ_BUF(28);
-	p++; /* headerpadsz is always 0 */
-	sess->fore_channel.maxreq_sz = be32_to_cpup(p++);
-	sess->fore_channel.maxresp_sz = be32_to_cpup(p++);
-	sess->fore_channel.maxresp_cached = be32_to_cpup(p++);
-	sess->fore_channel.maxops = be32_to_cpup(p++);
-	sess->fore_channel.maxreqs = be32_to_cpup(p++);
-	sess->fore_channel.nr_rdma_attrs = be32_to_cpup(p++);
-	if (sess->fore_channel.nr_rdma_attrs == 1) {
-		READ_BUF(4);
-		sess->fore_channel.rdma_attrs = be32_to_cpup(p++);
-	} else if (sess->fore_channel.nr_rdma_attrs > 1) {
-		dprintk("Too many fore channel attr bitmaps!\n");
-		goto xdr_error;
-	}
-
-	/* Back channel attrs */
-	READ_BUF(28);
-	p++; /* headerpadsz is always 0 */
-	sess->back_channel.maxreq_sz = be32_to_cpup(p++);
-	sess->back_channel.maxresp_sz = be32_to_cpup(p++);
-	sess->back_channel.maxresp_cached = be32_to_cpup(p++);
-	sess->back_channel.maxops = be32_to_cpup(p++);
-	sess->back_channel.maxreqs = be32_to_cpup(p++);
-	sess->back_channel.nr_rdma_attrs = be32_to_cpup(p++);
-	if (sess->back_channel.nr_rdma_attrs == 1) {
-		READ_BUF(4);
-		sess->back_channel.rdma_attrs = be32_to_cpup(p++);
-	} else if (sess->back_channel.nr_rdma_attrs > 1) {
-		dprintk("Too many back channel attr bitmaps!\n");
-		goto xdr_error;
-	}
+	status = nfsd4_decode_channel_attrs4(argp, &sess->fore_channel);
+	if (status)
+		return status;
+	status = nfsd4_decode_channel_attrs4(argp, &sess->back_channel);
+	if (status)
+		return status;
 
 	READ_BUF(4);
 	sess->callback_prog = be32_to_cpup(p++);
Signature · 1 line
2.43.0
author maintainer
#69 lore raw

PATCH 69/770 NFSD: Replace READ* macros in nfsd4_decode_create_session()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 81243e3fe37ed547fc4ed8aab1cec2865540bb18 ]

---
 fs/nfsd/nfs4xdr.c | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)
fs/nfsd/nfs4xdr.c +14 -10
index 716a16961ff48..3e2e0de00c3a7 100644
@@ -1650,24 +1650,28 @@ static __be32
 nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
 			    struct nfsd4_create_session *sess)
 {
-	DECODE_HEAD;
-
-	READ_BUF(16);
-	COPYMEM(&sess->clientid, 8);
-	sess->seqid = be32_to_cpup(p++);
-	sess->flags = be32_to_cpup(p++);
+	__be32 status;
 
+	status = nfsd4_decode_clientid4(argp, &sess->clientid);
+	if (status)
+		return status;
+	if (xdr_stream_decode_u32(argp->xdr, &sess->seqid) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u32(argp->xdr, &sess->flags) < 0)
+		return nfserr_bad_xdr;
 	status = nfsd4_decode_channel_attrs4(argp, &sess->fore_channel);
 	if (status)
 		return status;
 	status = nfsd4_decode_channel_attrs4(argp, &sess->back_channel);
+	if (status)
+		return status;
+	if (xdr_stream_decode_u32(argp->xdr, &sess->callback_prog) < 0)
+		return nfserr_bad_xdr;
+	status = nfsd4_decode_cb_sec(argp, &sess->cb_sec);
 	if (status)
 		return status;
 
-	READ_BUF(4);
-	sess->callback_prog = be32_to_cpup(p++);
-	nfsd4_decode_cb_sec(argp, &sess->cb_sec);
-	DECODE_TAIL;
+	return nfs_ok;
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#70 lore raw

PATCH 70/770 NFSD: Replace READ* macros in nfsd4_decode_destroy_session()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 94e254af1f873b4b551db4c4549294f2c4d385ef ]

---
 fs/nfsd/nfs4xdr.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)
fs/nfsd/nfs4xdr.c +1 -5
index 3e2e0de00c3a7..7a0730688b2f0 100644
@@ -1678,11 +1678,7 @@ static __be32
 nfsd4_decode_destroy_session(struct nfsd4_compoundargs *argp,
 			     struct nfsd4_destroy_session *destroy_session)
 {
-	DECODE_HEAD;
-	READ_BUF(NFS4_MAX_SESSIONID_LEN);
-	COPYMEM(destroy_session->sessionid.data, NFS4_MAX_SESSIONID_LEN);
-
-	DECODE_TAIL;
+	return nfsd4_decode_sessionid4(argp, &destroy_session->sessionid);
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#71 lore raw

PATCH 71/770 NFSD: Replace READ* macros in nfsd4_decode_free_stateid()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit aec387d5909304810d899f7d90ae57df33f3a75c ]

---
 fs/nfsd/nfs4xdr.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)
fs/nfsd/nfs4xdr.c +1 -7
index 7a0730688b2f0..92988926d9540 100644
@@ -1685,13 +1685,7 @@ static __be32
 nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp,
 			  struct nfsd4_free_stateid *free_stateid)
 {
-	DECODE_HEAD;
-
-	READ_BUF(sizeof(stateid_t));
-	free_stateid->fr_stateid.si_generation = be32_to_cpup(p++);
-	COPYMEM(&free_stateid->fr_stateid.si_opaque, sizeof(stateid_opaque_t));
-
-	DECODE_TAIL;
+	return nfsd4_decode_stateid4(argp, &free_stateid->fr_stateid);
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#72 lore raw

PATCH 72/770 NFSD: Replace READ* macros in nfsd4_decode_getdeviceinfo()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 044959715f370b24870c95df3940add8710c5a29 ]

---
 fs/nfsd/nfs4xdr.c | 50 +++++++++++++++++++++++++++--------------------
 1 file changed, 29 insertions(+), 21 deletions(-)
fs/nfsd/nfs4xdr.c +29 -21
index 92988926d9540..11e32c244b23c 100644
@@ -638,6 +638,21 @@ nfsd4_decode_state_owner4(struct nfsd4_compoundargs *argp,
 	return nfsd4_decode_opaque(argp, owner);
 }
 
+#ifdef CONFIG_NFSD_PNFS
+static __be32
+nfsd4_decode_deviceid4(struct nfsd4_compoundargs *argp,
+		       struct nfsd4_deviceid *devid)
+{
+	__be32 *p;
+
+	p = xdr_inline_decode(argp->xdr, NFS4_DEVICEID4_SIZE);
+	if (!p)
+		return nfserr_bad_xdr;
+	memcpy(devid, p, sizeof(*devid));
+	return nfs_ok;
+}
+#endif /* CONFIG_NFSD_PNFS */
+
 static __be32
 nfsd4_decode_sessionid4(struct nfsd4_compoundargs *argp,
 			struct nfs4_sessionid *sessionid)
@@ -1765,27 +1780,20 @@ static __be32
 nfsd4_decode_getdeviceinfo(struct nfsd4_compoundargs *argp,
 		struct nfsd4_getdeviceinfo *gdev)
 {
-	DECODE_HEAD;
-	u32 num, i;
-
-	READ_BUF(sizeof(struct nfsd4_deviceid) + 3 * 4);
-	COPYMEM(&gdev->gd_devid, sizeof(struct nfsd4_deviceid));
-	gdev->gd_layout_type = be32_to_cpup(p++);
-	gdev->gd_maxcount = be32_to_cpup(p++);
-	num = be32_to_cpup(p++);
-	if (num) {
-		if (num > 1000)
-			goto xdr_error;
-		READ_BUF(4 * num);
-		gdev->gd_notify_types = be32_to_cpup(p++);
-		for (i = 1; i < num; i++) {
-			if (be32_to_cpup(p++)) {
-				status = nfserr_inval;
-				goto out;
-			}
-		}
-	}
-	DECODE_TAIL;
+	__be32 status;
+
+	status = nfsd4_decode_deviceid4(argp, &gdev->gd_devid);
+	if (status)
+		return status;
+	if (xdr_stream_decode_u32(argp->xdr, &gdev->gd_layout_type) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u32(argp->xdr, &gdev->gd_maxcount) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_uint32_array(argp->xdr,
+					   &gdev->gd_notify_types, 1) < 0)
+		return nfserr_bad_xdr;
+
+	return nfs_ok;
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#73 lore raw

PATCH 73/770 NFSD: Replace READ* macros in nfsd4_decode_layoutcommit()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 5185980d8a23001c2317c290129ab7ab20067e20 ]

---
 fs/nfsd/nfs4xdr.c | 120 ++++++++++++++++++++++------------------------
 1 file changed, 58 insertions(+), 62 deletions(-)
fs/nfsd/nfs4xdr.c +58 -62
index 11e32c244b23c..9cd7270e67adc 100644
@@ -274,20 +274,6 @@ nfsd4_decode_component4(struct nfsd4_compoundargs *argp, char **namp, u32 *lenp)
 	return nfs_ok;
 }
 
-static __be32
-nfsd4_decode_time(struct nfsd4_compoundargs *argp, struct timespec64 *tv)
-{
-	DECODE_HEAD;
-
-	READ_BUF(12);
-	p = xdr_decode_hyper(p, &tv->tv_sec);
-	tv->tv_nsec = be32_to_cpup(p++);
-	if (tv->tv_nsec >= (u32)1000000000)
-		return nfserr_inval;
-
-	DECODE_TAIL;
-}
-
 static __be32
 nfsd4_decode_nfstime4(struct nfsd4_compoundargs *argp, struct timespec64 *tv)
 {
@@ -651,6 +637,29 @@ nfsd4_decode_deviceid4(struct nfsd4_compoundargs *argp,
 	memcpy(devid, p, sizeof(*devid));
 	return nfs_ok;
 }
+
+static __be32
+nfsd4_decode_layoutupdate4(struct nfsd4_compoundargs *argp,
+			   struct nfsd4_layoutcommit *lcp)
+{
+	if (xdr_stream_decode_u32(argp->xdr, &lcp->lc_layout_type) < 0)
+		return nfserr_bad_xdr;
+	if (lcp->lc_layout_type < LAYOUT_NFSV4_1_FILES)
+		return nfserr_bad_xdr;
+	if (lcp->lc_layout_type >= LAYOUT_TYPE_MAX)
+		return nfserr_bad_xdr;
+
+	if (xdr_stream_decode_u32(argp->xdr, &lcp->lc_up_len) < 0)
+		return nfserr_bad_xdr;
+	if (lcp->lc_up_len > 0) {
+		lcp->lc_up_layout = xdr_inline_decode(argp->xdr, lcp->lc_up_len);
+		if (!lcp->lc_up_layout)
+			return nfserr_bad_xdr;
+	}
+
+	return nfs_ok;
+}
+
 #endif /* CONFIG_NFSD_PNFS */
 
 static __be32
@@ -1796,6 +1805,41 @@ nfsd4_decode_getdeviceinfo(struct nfsd4_compoundargs *argp,
 	return nfs_ok;
 }
 
+static __be32
+nfsd4_decode_layoutcommit(struct nfsd4_compoundargs *argp,
+			  struct nfsd4_layoutcommit *lcp)
+{
+	__be32 *p, status;
+
+	if (xdr_stream_decode_u64(argp->xdr, &lcp->lc_seg.offset) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u64(argp->xdr, &lcp->lc_seg.length) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_bool(argp->xdr, &lcp->lc_reclaim) < 0)
+		return nfserr_bad_xdr;
+	status = nfsd4_decode_stateid4(argp, &lcp->lc_sid);
+	if (status)
+		return status;
+	if (xdr_stream_decode_u32(argp->xdr, &lcp->lc_newoffset) < 0)
+		return nfserr_bad_xdr;
+	if (lcp->lc_newoffset) {
+		if (xdr_stream_decode_u64(argp->xdr, &lcp->lc_last_wr) < 0)
+			return nfserr_bad_xdr;
+	} else
+		lcp->lc_last_wr = 0;
+	p = xdr_inline_decode(argp->xdr, XDR_UNIT);
+	if (!p)
+		return nfserr_bad_xdr;
+	if (xdr_item_is_present(p)) {
+		status = nfsd4_decode_nfstime4(argp, &lcp->lc_mtime);
+		if (status)
+			return status;
+	} else {
+		lcp->lc_mtime.tv_nsec = UTIME_NOW;
+	}
+	return nfsd4_decode_layoutupdate4(argp, lcp);
+}
+
 static __be32
 nfsd4_decode_layoutget(struct nfsd4_compoundargs *argp,
 		struct nfsd4_layoutget *lgp)
@@ -1820,54 +1864,6 @@ nfsd4_decode_layoutget(struct nfsd4_compoundargs *argp,
 	DECODE_TAIL;
 }
 
-static __be32
-nfsd4_decode_layoutcommit(struct nfsd4_compoundargs *argp,
-		struct nfsd4_layoutcommit *lcp)
-{
-	DECODE_HEAD;
-	u32 timechange;
-
-	READ_BUF(20);
-	p = xdr_decode_hyper(p, &lcp->lc_seg.offset);
-	p = xdr_decode_hyper(p, &lcp->lc_seg.length);
-	lcp->lc_reclaim = be32_to_cpup(p++);
-
-	status = nfsd4_decode_stateid(argp, &lcp->lc_sid);
-	if (status)
-		return status;
-
-	READ_BUF(4);
-	lcp->lc_newoffset = be32_to_cpup(p++);
-	if (lcp->lc_newoffset) {
-		READ_BUF(8);
-		p = xdr_decode_hyper(p, &lcp->lc_last_wr);
-	} else
-		lcp->lc_last_wr = 0;
-	READ_BUF(4);
-	timechange = be32_to_cpup(p++);
-	if (timechange) {
-		status = nfsd4_decode_time(argp, &lcp->lc_mtime);
-		if (status)
-			return status;
-	} else {
-		lcp->lc_mtime.tv_nsec = UTIME_NOW;
-	}
-	READ_BUF(8);
-	lcp->lc_layout_type = be32_to_cpup(p++);
-
-	/*
-	 * Save the layout update in XDR format and let the layout driver deal
-	 * with it later.
-	 */
-	lcp->lc_up_len = be32_to_cpup(p++);
-	if (lcp->lc_up_len > 0) {
-		READ_BUF(lcp->lc_up_len);
-		READMEM(lcp->lc_up_layout, lcp->lc_up_len);
-	}
-
-	DECODE_TAIL;
-}
-
 static __be32
 nfsd4_decode_layoutreturn(struct nfsd4_compoundargs *argp,
 		struct nfsd4_layoutreturn *lrp)
Signature · 1 line
2.43.0
author maintainer
#74 lore raw

PATCH 74/770 NFSD: Replace READ* macros in nfsd4_decode_layoutget()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit c8e88e3aa73889421461f878cd569ef84f231ceb ]

---
 fs/nfsd/nfs4xdr.c | 31 +++++++++++++++++--------------
 1 file changed, 17 insertions(+), 14 deletions(-)
fs/nfsd/nfs4xdr.c +17 -14
index 9cd7270e67adc..837d2d8fb3ff8 100644
@@ -1844,24 +1844,27 @@ static __be32
 nfsd4_decode_layoutget(struct nfsd4_compoundargs *argp,
 		struct nfsd4_layoutget *lgp)
 {
-	DECODE_HEAD;
-
-	READ_BUF(36);
-	lgp->lg_signal = be32_to_cpup(p++);
-	lgp->lg_layout_type = be32_to_cpup(p++);
-	lgp->lg_seg.iomode = be32_to_cpup(p++);
-	p = xdr_decode_hyper(p, &lgp->lg_seg.offset);
-	p = xdr_decode_hyper(p, &lgp->lg_seg.length);
-	p = xdr_decode_hyper(p, &lgp->lg_minlength);
+	__be32 status;
 
-	status = nfsd4_decode_stateid(argp, &lgp->lg_sid);
+	if (xdr_stream_decode_u32(argp->xdr, &lgp->lg_signal) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u32(argp->xdr, &lgp->lg_layout_type) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u32(argp->xdr, &lgp->lg_seg.iomode) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u64(argp->xdr, &lgp->lg_seg.offset) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u64(argp->xdr, &lgp->lg_seg.length) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u64(argp->xdr, &lgp->lg_minlength) < 0)
+		return nfserr_bad_xdr;
+	status = nfsd4_decode_stateid4(argp, &lgp->lg_sid);
 	if (status)
 		return status;
+	if (xdr_stream_decode_u32(argp->xdr, &lgp->lg_maxcount) < 0)
+		return nfserr_bad_xdr;
 
-	READ_BUF(4);
-	lgp->lg_maxcount = be32_to_cpup(p++);
-
-	DECODE_TAIL;
+	return nfs_ok;
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#75 lore raw

PATCH 75/770 NFSD: Replace READ* macros in nfsd4_decode_layoutreturn()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 645fcad371420913c30e9aca80fc0a38f3acf432 ]

---
 fs/nfsd/nfs4xdr.c | 72 +++++++++++++++++++++++++++++------------------
 1 file changed, 44 insertions(+), 28 deletions(-)
fs/nfsd/nfs4xdr.c +44 -28
index 837d2d8fb3ff8..ae70070a58213 100644
@@ -660,6 +660,43 @@ nfsd4_decode_layoutupdate4(struct nfsd4_compoundargs *argp,
 	return nfs_ok;
 }
 
+static __be32
+nfsd4_decode_layoutreturn4(struct nfsd4_compoundargs *argp,
+			   struct nfsd4_layoutreturn *lrp)
+{
+	__be32 status;
+
+	if (xdr_stream_decode_u32(argp->xdr, &lrp->lr_return_type) < 0)
+		return nfserr_bad_xdr;
+	switch (lrp->lr_return_type) {
+	case RETURN_FILE:
+		if (xdr_stream_decode_u64(argp->xdr, &lrp->lr_seg.offset) < 0)
+			return nfserr_bad_xdr;
+		if (xdr_stream_decode_u64(argp->xdr, &lrp->lr_seg.length) < 0)
+			return nfserr_bad_xdr;
+		status = nfsd4_decode_stateid4(argp, &lrp->lr_sid);
+		if (status)
+			return status;
+		if (xdr_stream_decode_u32(argp->xdr, &lrp->lrf_body_len) < 0)
+			return nfserr_bad_xdr;
+		if (lrp->lrf_body_len > 0) {
+			lrp->lrf_body = xdr_inline_decode(argp->xdr, lrp->lrf_body_len);
+			if (!lrp->lrf_body)
+				return nfserr_bad_xdr;
+		}
+		break;
+	case RETURN_FSID:
+	case RETURN_ALL:
+		lrp->lr_seg.offset = 0;
+		lrp->lr_seg.length = NFS4_MAX_UINT64;
+		break;
+	default:
+		return nfserr_bad_xdr;
+	}
+
+	return nfs_ok;
+}
+
 #endif /* CONFIG_NFSD_PNFS */
 
 static __be32
@@ -1871,34 +1908,13 @@ static __be32
 nfsd4_decode_layoutreturn(struct nfsd4_compoundargs *argp,
 		struct nfsd4_layoutreturn *lrp)
 {
-	DECODE_HEAD;
-
-	READ_BUF(16);
-	lrp->lr_reclaim = be32_to_cpup(p++);
-	lrp->lr_layout_type = be32_to_cpup(p++);
-	lrp->lr_seg.iomode = be32_to_cpup(p++);
-	lrp->lr_return_type = be32_to_cpup(p++);
-	if (lrp->lr_return_type == RETURN_FILE) {
-		READ_BUF(16);
-		p = xdr_decode_hyper(p, &lrp->lr_seg.offset);
-		p = xdr_decode_hyper(p, &lrp->lr_seg.length);
-
-		status = nfsd4_decode_stateid(argp, &lrp->lr_sid);
-		if (status)
-			return status;
-
-		READ_BUF(4);
-		lrp->lrf_body_len = be32_to_cpup(p++);
-		if (lrp->lrf_body_len > 0) {
-			READ_BUF(lrp->lrf_body_len);
-			READMEM(lrp->lrf_body, lrp->lrf_body_len);
-		}
-	} else {
-		lrp->lr_seg.offset = 0;
-		lrp->lr_seg.length = NFS4_MAX_UINT64;
-	}
-
-	DECODE_TAIL;
+	if (xdr_stream_decode_bool(argp->xdr, &lrp->lr_reclaim) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u32(argp->xdr, &lrp->lr_layout_type) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u32(argp->xdr, &lrp->lr_seg.iomode) < 0)
+		return nfserr_bad_xdr;
+	return nfsd4_decode_layoutreturn4(argp, lrp);
 }
 #endif /* CONFIG_NFSD_PNFS */
 
Signature · 1 line
2.43.0
author maintainer
#76 lore raw

PATCH 76/770 NFSD: Replace READ* macros in nfsd4_decode_secinfo_no_name()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 53d70873e37c09a582167ed73d1858e3a2af0157 ]

---
 fs/nfsd/nfs4xdr.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)
fs/nfsd/nfs4xdr.c +8 -11
index ae70070a58213..0561b43855839 100644
@@ -1356,17 +1356,6 @@ nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp,
 	return nfsd4_decode_component4(argp, &secinfo->si_name, &secinfo->si_namelen);
 }
 
-static __be32
-nfsd4_decode_secinfo_no_name(struct nfsd4_compoundargs *argp,
-		     struct nfsd4_secinfo_no_name *sin)
-{
-	DECODE_HEAD;
-
-	READ_BUF(4);
-	sin->sin_style = be32_to_cpup(p++);
-	DECODE_TAIL;
-}
-
 static __be32
 nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr)
 {
@@ -1918,6 +1907,14 @@ nfsd4_decode_layoutreturn(struct nfsd4_compoundargs *argp,
 }
 #endif /* CONFIG_NFSD_PNFS */
 
+static __be32 nfsd4_decode_secinfo_no_name(struct nfsd4_compoundargs *argp,
+					   struct nfsd4_secinfo_no_name *sin)
+{
+	if (xdr_stream_decode_u32(argp->xdr, &sin->sin_style) < 0)
+		return nfserr_bad_xdr;
+	return nfs_ok;
+}
+
 static __be32
 nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp,
 		       struct nfsd4_fallocate *fallocate)
Signature · 1 line
2.43.0
author maintainer
#77 lore raw

PATCH 77/770 NFSD: Replace READ* macros in nfsd4_decode_sequence()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit cf907b11326d9360877d6c6ea8f75e1b29f39f2f ]

---
 fs/nfsd/nfs4xdr.c | 36 ++++++++++++++++++++----------------
 1 file changed, 20 insertions(+), 16 deletions(-)
fs/nfsd/nfs4xdr.c +20 -16
index 0561b43855839..3fe0d0228c4ac 100644
@@ -1738,22 +1738,6 @@ nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp,
 	return nfsd4_decode_stateid4(argp, &free_stateid->fr_stateid);
 }
 
-static __be32
-nfsd4_decode_sequence(struct nfsd4_compoundargs *argp,
-		      struct nfsd4_sequence *seq)
-{
-	DECODE_HEAD;
-
-	READ_BUF(NFS4_MAX_SESSIONID_LEN + 16);
-	COPYMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN);
-	seq->seqid = be32_to_cpup(p++);
-	seq->slotid = be32_to_cpup(p++);
-	seq->maxslots = be32_to_cpup(p++);
-	seq->cachethis = be32_to_cpup(p++);
-
-	DECODE_TAIL;
-}
-
 static __be32
 nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_stateid *test_stateid)
 {
@@ -1915,6 +1899,26 @@ static __be32 nfsd4_decode_secinfo_no_name(struct nfsd4_compoundargs *argp,
 	return nfs_ok;
 }
 
+static __be32
+nfsd4_decode_sequence(struct nfsd4_compoundargs *argp,
+		      struct nfsd4_sequence *seq)
+{
+	__be32 *p, status;
+
+	status = nfsd4_decode_sessionid4(argp, &seq->sessionid);
+	if (status)
+		return status;
+	p = xdr_inline_decode(argp->xdr, XDR_UNIT * 4);
+	if (!p)
+		return nfserr_bad_xdr;
+	seq->seqid = be32_to_cpup(p++);
+	seq->slotid = be32_to_cpup(p++);
+	seq->maxslots = be32_to_cpup(p++);
+	seq->cachethis = be32_to_cpup(p);
+
+	return nfs_ok;
+}
+
 static __be32
 nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp,
 		       struct nfsd4_fallocate *fallocate)
Signature · 1 line
2.43.0
author maintainer
#78 lore raw

PATCH 78/770 NFSD: Replace READ* macros in nfsd4_decode_test_stateid()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit b7a0c8f6e741bf9dee0d24e69d3ce51fa4ccce78 ]

---
 fs/nfsd/nfs4xdr.c | 61 +++++++++++++++++++----------------------------
 1 file changed, 25 insertions(+), 36 deletions(-)
fs/nfsd/nfs4xdr.c +25 -36
index 3fe0d0228c4ac..9642de1550431 100644
@@ -1738,42 +1738,6 @@ nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp,
 	return nfsd4_decode_stateid4(argp, &free_stateid->fr_stateid);
 }
 
-static __be32
-nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_stateid *test_stateid)
-{
-	int i;
-	__be32 *p, status;
-	struct nfsd4_test_stateid_id *stateid;
-
-	READ_BUF(4);
-	test_stateid->ts_num_ids = ntohl(*p++);
-
-	INIT_LIST_HEAD(&test_stateid->ts_stateid_list);
-
-	for (i = 0; i < test_stateid->ts_num_ids; i++) {
-		stateid = svcxdr_tmpalloc(argp, sizeof(*stateid));
-		if (!stateid) {
-			status = nfserrno(-ENOMEM);
-			goto out;
-		}
-
-		INIT_LIST_HEAD(&stateid->ts_id_list);
-		list_add_tail(&stateid->ts_id_list, &test_stateid->ts_stateid_list);
-
-		status = nfsd4_decode_stateid(argp, &stateid->ts_id_stateid);
-		if (status)
-			goto out;
-	}
-
-	status = 0;
-out:
-	return status;
-xdr_error:
-	dprintk("NFSD: xdr error (%s:%d)\n", __FILE__, __LINE__);
-	status = nfserr_bad_xdr;
-	goto out;
-}
-
 static __be32 nfsd4_decode_destroy_clientid(struct nfsd4_compoundargs *argp, struct nfsd4_destroy_clientid *dc)
 {
 	DECODE_HEAD;
@@ -1919,6 +1883,31 @@ nfsd4_decode_sequence(struct nfsd4_compoundargs *argp,
 	return nfs_ok;
 }
 
+static __be32
+nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_stateid *test_stateid)
+{
+	struct nfsd4_test_stateid_id *stateid;
+	__be32 status;
+	u32 i;
+
+	if (xdr_stream_decode_u32(argp->xdr, &test_stateid->ts_num_ids) < 0)
+		return nfserr_bad_xdr;
+
+	INIT_LIST_HEAD(&test_stateid->ts_stateid_list);
+	for (i = 0; i < test_stateid->ts_num_ids; i++) {
+		stateid = svcxdr_tmpalloc(argp, sizeof(*stateid));
+		if (!stateid)
+			return nfserrno(-ENOMEM);	/* XXX: not jukebox? */
+		INIT_LIST_HEAD(&stateid->ts_id_list);
+		list_add_tail(&stateid->ts_id_list, &test_stateid->ts_stateid_list);
+		status = nfsd4_decode_stateid4(argp, &stateid->ts_id_stateid);
+		if (status)
+			return status;
+	}
+
+	return nfs_ok;
+}
+
 static __be32
 nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp,
 		       struct nfsd4_fallocate *fallocate)
Signature · 1 line
2.43.0
author maintainer
#79 lore raw

PATCH 79/770 NFSD: Replace READ* macros in nfsd4_decode_destroy_clientid()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit c95f2ec3490586cbb33badc8f4c82d6aa4955078 ]

---
 fs/nfsd/nfs4xdr.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)
fs/nfsd/nfs4xdr.c +6 -10
index 9642de1550431..d0f0b7cd4e74e 100644
@@ -1738,16 +1738,6 @@ nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp,
 	return nfsd4_decode_stateid4(argp, &free_stateid->fr_stateid);
 }
 
-static __be32 nfsd4_decode_destroy_clientid(struct nfsd4_compoundargs *argp, struct nfsd4_destroy_clientid *dc)
-{
-	DECODE_HEAD;
-
-	READ_BUF(8);
-	COPYMEM(&dc->clientid, 8);
-
-	DECODE_TAIL;
-}
-
 static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, struct nfsd4_reclaim_complete *rc)
 {
 	DECODE_HEAD;
@@ -1908,6 +1898,12 @@ nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_sta
 	return nfs_ok;
 }
 
+static __be32 nfsd4_decode_destroy_clientid(struct nfsd4_compoundargs *argp,
+					    struct nfsd4_destroy_clientid *dc)
+{
+	return nfsd4_decode_clientid4(argp, &dc->clientid);
+}
+
 static __be32
 nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp,
 		       struct nfsd4_fallocate *fallocate)
Signature · 1 line
2.43.0
author maintainer
#80 lore raw

PATCH 80/770 NFSD: Replace READ* macros in nfsd4_decode_reclaim_complete()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 0d6467844d437e07db1e76d96176b1a55401018c ]

---
 fs/nfsd/nfs4xdr.c | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)
fs/nfsd/nfs4xdr.c +8 -10
index d0f0b7cd4e74e..2c684f7e74650 100644
@@ -1738,16 +1738,6 @@ nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp,
 	return nfsd4_decode_stateid4(argp, &free_stateid->fr_stateid);
 }
 
-static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, struct nfsd4_reclaim_complete *rc)
-{
-	DECODE_HEAD;
-
-	READ_BUF(4);
-	rc->rca_one_fs = be32_to_cpup(p++);
-
-	DECODE_TAIL;
-}
-
 #ifdef CONFIG_NFSD_PNFS
 static __be32
 nfsd4_decode_getdeviceinfo(struct nfsd4_compoundargs *argp,
@@ -1904,6 +1894,14 @@ static __be32 nfsd4_decode_destroy_clientid(struct nfsd4_compoundargs *argp,
 	return nfsd4_decode_clientid4(argp, &dc->clientid);
 }
 
+static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp,
+					    struct nfsd4_reclaim_complete *rc)
+{
+	if (xdr_stream_decode_bool(argp->xdr, &rc->rca_one_fs) < 0)
+		return nfserr_bad_xdr;
+	return nfs_ok;
+}
+
 static __be32
 nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp,
 		       struct nfsd4_fallocate *fallocate)
Signature · 1 line
2.43.0
author maintainer
#81 lore raw

PATCH 81/770 NFSD: Replace READ* macros in nfsd4_decode_fallocate()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 6aef27aaeae7611f98af08205acc79f5a8f3aa59 ]

---
 fs/nfsd/nfs4xdr.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
fs/nfsd/nfs4xdr.c +7 -7
index 2c684f7e74650..c8506bb6d8725 100644
@@ -1906,17 +1906,17 @@ static __be32
 nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp,
 		       struct nfsd4_fallocate *fallocate)
 {
-	DECODE_HEAD;
+	__be32 status;
 
-	status = nfsd4_decode_stateid(argp, &fallocate->falloc_stateid);
+	status = nfsd4_decode_stateid4(argp, &fallocate->falloc_stateid);
 	if (status)
 		return status;
+	if (xdr_stream_decode_u64(argp->xdr, &fallocate->falloc_offset) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u64(argp->xdr, &fallocate->falloc_length) < 0)
+		return nfserr_bad_xdr;
 
-	READ_BUF(16);
-	p = xdr_decode_hyper(p, &fallocate->falloc_offset);
-	xdr_decode_hyper(p, &fallocate->falloc_length);
-
-	DECODE_TAIL;
+	return nfs_ok;
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#82 lore raw

PATCH 82/770 NFSD: Replace READ* macros in nfsd4_decode_nl4_server()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit f49e4b4d58cc835d8bd0cc9663f7b9c5497e0e7e ]

---
 fs/nfsd/nfs4xdr.c | 34 ++++++++++++++++++++--------------
 1 file changed, 20 insertions(+), 14 deletions(-)
fs/nfsd/nfs4xdr.c +20 -14
index c8506bb6d8725..05aa36f92a929 100644
@@ -1941,36 +1941,42 @@ nfsd4_decode_clone(struct nfsd4_compoundargs *argp, struct nfsd4_clone *clone)
 static __be32 nfsd4_decode_nl4_server(struct nfsd4_compoundargs *argp,
 				      struct nl4_server *ns)
 {
-	DECODE_HEAD;
 	struct nfs42_netaddr *naddr;
+	__be32 *p;
 
-	READ_BUF(4);
-	ns->nl4_type = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &ns->nl4_type) < 0)
+		return nfserr_bad_xdr;
 
 	/* currently support for 1 inter-server source server */
 	switch (ns->nl4_type) {
 	case NL4_NETADDR:
 		naddr = &ns->u.nl4_addr;
 
-		READ_BUF(4);
-		naddr->netid_len = be32_to_cpup(p++);
+		if (xdr_stream_decode_u32(argp->xdr, &naddr->netid_len) < 0)
+			return nfserr_bad_xdr;
 		if (naddr->netid_len > RPCBIND_MAXNETIDLEN)
-			goto xdr_error;
+			return nfserr_bad_xdr;
 
-		READ_BUF(naddr->netid_len + 4); /* 4 for uaddr len */
-		COPYMEM(naddr->netid, naddr->netid_len);
+		p = xdr_inline_decode(argp->xdr, naddr->netid_len);
+		if (!p)
+			return nfserr_bad_xdr;
+		memcpy(naddr->netid, p, naddr->netid_len);
 
-		naddr->addr_len = be32_to_cpup(p++);
+		if (xdr_stream_decode_u32(argp->xdr, &naddr->addr_len) < 0)
+			return nfserr_bad_xdr;
 		if (naddr->addr_len > RPCBIND_MAXUADDRLEN)
-			goto xdr_error;
+			return nfserr_bad_xdr;
 
-		READ_BUF(naddr->addr_len);
-		COPYMEM(naddr->addr, naddr->addr_len);
+		p = xdr_inline_decode(argp->xdr, naddr->addr_len);
+		if (!p)
+			return nfserr_bad_xdr;
+		memcpy(naddr->addr, p, naddr->addr_len);
 		break;
 	default:
-		goto xdr_error;
+		return nfserr_bad_xdr;
 	}
-	DECODE_TAIL;
+
+	return nfs_ok;
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#83 lore raw

PATCH 83/770 NFSD: Replace READ* macros in nfsd4_decode_copy()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit e8febea7190bcbd1e608093acb67f2a5009556aa ]

---
 fs/nfsd/nfs4xdr.c | 41 ++++++++++++++++++++++-------------------
 fs/nfsd/xdr4.h    |  2 +-
 2 files changed, 23 insertions(+), 20 deletions(-)
fs/nfsd/nfs4xdr.c +22 -19
index 05aa36f92a929..2529368cbbc0b 100644
@@ -1982,40 +1982,44 @@ static __be32 nfsd4_decode_nl4_server(struct nfsd4_compoundargs *argp,
 static __be32
 nfsd4_decode_copy(struct nfsd4_compoundargs *argp, struct nfsd4_copy *copy)
 {
-	DECODE_HEAD;
 	struct nl4_server *ns_dummy;
-	int i, count;
+	u32 consecutive, i, count;
+	__be32 status;
 
-	status = nfsd4_decode_stateid(argp, &copy->cp_src_stateid);
+	status = nfsd4_decode_stateid4(argp, &copy->cp_src_stateid);
 	if (status)
 		return status;
-	status = nfsd4_decode_stateid(argp, &copy->cp_dst_stateid);
+	status = nfsd4_decode_stateid4(argp, &copy->cp_dst_stateid);
 	if (status)
 		return status;
+	if (xdr_stream_decode_u64(argp->xdr, &copy->cp_src_pos) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u64(argp->xdr, &copy->cp_dst_pos) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u64(argp->xdr, &copy->cp_count) < 0)
+		return nfserr_bad_xdr;
+	/* ca_consecutive: we always do consecutive copies */
+	if (xdr_stream_decode_u32(argp->xdr, &consecutive) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u32(argp->xdr, &copy->cp_synchronous) < 0)
+		return nfserr_bad_xdr;
 
-	READ_BUF(8 + 8 + 8 + 4 + 4 + 4);
-	p = xdr_decode_hyper(p, &copy->cp_src_pos);
-	p = xdr_decode_hyper(p, &copy->cp_dst_pos);
-	p = xdr_decode_hyper(p, &copy->cp_count);
-	p++; /* ca_consecutive: we always do consecutive copies */
-	copy->cp_synchronous = be32_to_cpup(p++);
-
-	count = be32_to_cpup(p++);
-
+	if (xdr_stream_decode_u32(argp->xdr, &count) < 0)
+		return nfserr_bad_xdr;
 	copy->cp_intra = false;
 	if (count == 0) { /* intra-server copy */
 		copy->cp_intra = true;
-		goto intra;
+		return nfs_ok;
 	}
 
-	/* decode all the supplied server addresses but use first */
+	/* decode all the supplied server addresses but use only the first */
 	status = nfsd4_decode_nl4_server(argp, &copy->cp_src);
 	if (status)
 		return status;
 
 	ns_dummy = kmalloc(sizeof(struct nl4_server), GFP_KERNEL);
 	if (ns_dummy == NULL)
-		return nfserrno(-ENOMEM);
+		return nfserrno(-ENOMEM);	/* XXX: jukebox? */
 	for (i = 0; i < count - 1; i++) {
 		status = nfsd4_decode_nl4_server(argp, ns_dummy);
 		if (status) {
@@ -2024,9 +2028,8 @@ nfsd4_decode_copy(struct nfsd4_compoundargs *argp, struct nfsd4_copy *copy)
 		}
 	}
 	kfree(ns_dummy);
-intra:
 
-	DECODE_TAIL;
+	return nfs_ok;
 }
 
 static __be32
@@ -4792,7 +4795,7 @@ nfsd4_encode_copy(struct nfsd4_compoundres *resp, __be32 nfserr,
 	__be32 *p;
 
 	nfserr = nfsd42_encode_write_res(resp, &copy->cp_res,
-			copy->cp_synchronous);
+					 !!copy->cp_synchronous);
 	if (nfserr)
 		return nfserr;
 
fs/nfsd/xdr4.h +1 -1
index 232529bc1b798..facc5762bf831 100644
@@ -554,7 +554,7 @@ struct nfsd4_copy {
 	bool			cp_intra;
 
 	/* both */
-	bool		cp_synchronous;
+	u32			cp_synchronous;
 
 	/* response */
 	struct nfsd42_write_res	cp_res;
Signature · 1 line
2.43.0
author maintainer
#84 lore raw

PATCH 84/770 NFSD: Replace READ* macros in nfsd4_decode_copy_notify()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit f9a953fb369bbd2135ccead3393ec1ef66544471 ]

---
 fs/nfsd/nfs4xdr.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
fs/nfsd/nfs4xdr.c +8 -8
index 2529368cbbc0b..09aea361c1755 100644
@@ -2032,25 +2032,25 @@ nfsd4_decode_copy(struct nfsd4_compoundargs *argp, struct nfsd4_copy *copy)
 	return nfs_ok;
 }
 
-static __be32
-nfsd4_decode_offload_status(struct nfsd4_compoundargs *argp,
-			    struct nfsd4_offload_status *os)
-{
-	return nfsd4_decode_stateid(argp, &os->stateid);
-}
-
 static __be32
 nfsd4_decode_copy_notify(struct nfsd4_compoundargs *argp,
 			 struct nfsd4_copy_notify *cn)
 {
 	__be32 status;
 
-	status = nfsd4_decode_stateid(argp, &cn->cpn_src_stateid);
+	status = nfsd4_decode_stateid4(argp, &cn->cpn_src_stateid);
 	if (status)
 		return status;
 	return nfsd4_decode_nl4_server(argp, &cn->cpn_dst);
 }
 
+static __be32
+nfsd4_decode_offload_status(struct nfsd4_compoundargs *argp,
+			    struct nfsd4_offload_status *os)
+{
+	return nfsd4_decode_stateid(argp, &os->stateid);
+}
+
 static __be32
 nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek)
 {
Signature · 1 line
2.43.0
author maintainer
#85 lore raw

PATCH 85/770 NFSD: Replace READ* macros in nfsd4_decode_offload_status()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 2846bb0525a73e00b3566fda535ea6a5879e2971 ]

---
 fs/nfsd/nfs4xdr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfsd/nfs4xdr.c +1 -1
index 09aea361c1755..101beb315d963 100644
@@ -2048,7 +2048,7 @@ static __be32
 nfsd4_decode_offload_status(struct nfsd4_compoundargs *argp,
 			    struct nfsd4_offload_status *os)
 {
-	return nfsd4_decode_stateid(argp, &os->stateid);
+	return nfsd4_decode_stateid4(argp, &os->stateid);
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#86 lore raw

PATCH 86/770 NFSD: Replace READ* macros in nfsd4_decode_seek()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 9d32b412fe0a6186cc57789d218e8f8299454ae2 ]

---
 fs/nfsd/nfs4xdr.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
fs/nfsd/nfs4xdr.c +7 -7
index 101beb315d963..2e2fae7e38db2 100644
@@ -2054,17 +2054,17 @@ nfsd4_decode_offload_status(struct nfsd4_compoundargs *argp,
 static __be32
 nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek)
 {
-	DECODE_HEAD;
+	__be32 status;
 
-	status = nfsd4_decode_stateid(argp, &seek->seek_stateid);
+	status = nfsd4_decode_stateid4(argp, &seek->seek_stateid);
 	if (status)
 		return status;
+	if (xdr_stream_decode_u64(argp->xdr, &seek->seek_offset) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u32(argp->xdr, &seek->seek_whence) < 0)
+		return nfserr_bad_xdr;
 
-	READ_BUF(8 + 4);
-	p = xdr_decode_hyper(p, &seek->seek_offset);
-	seek->seek_whence = be32_to_cpup(p);
-
-	DECODE_TAIL;
+	return nfs_ok;
 }
 
 /*
Signature · 1 line
2.43.0
author maintainer
#87 lore raw

PATCH 87/770 NFSD: Replace READ* macros in nfsd4_decode_clone()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 3dfd0b0e15671e2b4047ccb9222432f0b2d930be ]

---
 fs/nfsd/nfs4xdr.c | 52 +++++++++++++++++++----------------------------
 1 file changed, 21 insertions(+), 31 deletions(-)
fs/nfsd/nfs4xdr.c +21 -31
index 2e2fae7e38db2..bf2a2ef6a8b97 100644
@@ -575,18 +575,6 @@ nfsd4_decode_fattr4(struct nfsd4_compoundargs *argp, u32 *bmval, u32 bmlen,
 	return nfs_ok;
 }
 
-static __be32
-nfsd4_decode_stateid(struct nfsd4_compoundargs *argp, stateid_t *sid)
-{
-	DECODE_HEAD;
-
-	READ_BUF(sizeof(stateid_t));
-	sid->si_generation = be32_to_cpup(p++);
-	COPYMEM(&sid->si_opaque, sizeof(stateid_opaque_t));
-
-	DECODE_TAIL;
-}
-
 static __be32
 nfsd4_decode_stateid4(struct nfsd4_compoundargs *argp, stateid_t *sid)
 {
@@ -1919,25 +1907,6 @@ nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp,
 	return nfs_ok;
 }
 
-static __be32
-nfsd4_decode_clone(struct nfsd4_compoundargs *argp, struct nfsd4_clone *clone)
-{
-	DECODE_HEAD;
-
-	status = nfsd4_decode_stateid(argp, &clone->cl_src_stateid);
-	if (status)
-		return status;
-	status = nfsd4_decode_stateid(argp, &clone->cl_dst_stateid);
-	if (status)
-		return status;
-
-	READ_BUF(8 + 8 + 8);
-	p = xdr_decode_hyper(p, &clone->cl_src_pos);
-	p = xdr_decode_hyper(p, &clone->cl_dst_pos);
-	p = xdr_decode_hyper(p, &clone->cl_count);
-	DECODE_TAIL;
-}
-
 static __be32 nfsd4_decode_nl4_server(struct nfsd4_compoundargs *argp,
 				      struct nl4_server *ns)
 {
@@ -2067,6 +2036,27 @@ nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek)
 	return nfs_ok;
 }
 
+static __be32
+nfsd4_decode_clone(struct nfsd4_compoundargs *argp, struct nfsd4_clone *clone)
+{
+	__be32 status;
+
+	status = nfsd4_decode_stateid4(argp, &clone->cl_src_stateid);
+	if (status)
+		return status;
+	status = nfsd4_decode_stateid4(argp, &clone->cl_dst_stateid);
+	if (status)
+		return status;
+	if (xdr_stream_decode_u64(argp->xdr, &clone->cl_src_pos) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u64(argp->xdr, &clone->cl_dst_pos) < 0)
+		return nfserr_bad_xdr;
+	if (xdr_stream_decode_u64(argp->xdr, &clone->cl_count) < 0)
+		return nfserr_bad_xdr;
+
+	return nfs_ok;
+}
+
 /*
  * XDR data that is more than PAGE_SIZE in size is normally part of a
  * read or write. However, the size of extended attributes is limited
Signature · 1 line
2.43.0
author maintainer
#88 lore raw

PATCH 88/770 NFSD: Replace READ* macros in nfsd4_decode_xattr_name()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 830c71502ae0ae1677ac6c08ffbcf85a6e7b2937 ]

---
 fs/nfsd/nfs4xdr.c | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)
fs/nfsd/nfs4xdr.c +9 -12
index bf2a2ef6a8b97..1fcb668e4110d 100644
@@ -2117,25 +2117,22 @@ nfsd4_vbuf_from_vector(struct nfsd4_compoundargs *argp, struct xdr_buf *xdr,
 static __be32
 nfsd4_decode_xattr_name(struct nfsd4_compoundargs *argp, char **namep)
 {
-	DECODE_HEAD;
 	char *name, *sp, *dp;
 	u32 namelen, cnt;
+	__be32 *p;
 
-	READ_BUF(4);
-	namelen = be32_to_cpup(p++);
-
+	if (xdr_stream_decode_u32(argp->xdr, &namelen) < 0)
+		return nfserr_bad_xdr;
 	if (namelen > (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN))
 		return nfserr_nametoolong;
-
 	if (namelen == 0)
-		goto xdr_error;
-
-	READ_BUF(namelen);
-
+		return nfserr_bad_xdr;
+	p = xdr_inline_decode(argp->xdr, namelen);
+	if (!p)
+		return nfserr_bad_xdr;
 	name = svcxdr_tmpalloc(argp, namelen + XATTR_USER_PREFIX_LEN + 1);
 	if (!name)
 		return nfserr_jukebox;
-
 	memcpy(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
 
 	/*
@@ -2148,14 +2145,14 @@ nfsd4_decode_xattr_name(struct nfsd4_compoundargs *argp, char **namep)
 
 	while (cnt-- > 0) {
 		if (*sp == '\0')
-			goto xdr_error;
+			return nfserr_bad_xdr;
 		*dp++ = *sp++;
 	}
 	*dp = '\0';
 
 	*namep = name;
 
-	DECODE_TAIL;
+	return nfs_ok;
 }
 
 /*
Signature · 1 line
2.43.0
author maintainer
#89 lore raw

PATCH 89/770 NFSD: Replace READ* macros in nfsd4_decode_setxattr()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 403366a7e8e2930002157525cd44add7fa01bca9 ]

---
 fs/nfsd/nfs4xdr.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
fs/nfsd/nfs4xdr.c +7 -7
index 1fcb668e4110d..38610764d7161 100644
@@ -2184,11 +2184,11 @@ static __be32
 nfsd4_decode_setxattr(struct nfsd4_compoundargs *argp,
 		      struct nfsd4_setxattr *setxattr)
 {
-	DECODE_HEAD;
 	u32 flags, maxcount, size;
+	__be32 status;
 
-	READ_BUF(4);
-	flags = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &flags) < 0)
+		return nfserr_bad_xdr;
 
 	if (flags > SETXATTR4_REPLACE)
 		return nfserr_inval;
@@ -2201,8 +2201,8 @@ nfsd4_decode_setxattr(struct nfsd4_compoundargs *argp,
 	maxcount = svc_max_payload(argp->rqstp);
 	maxcount = min_t(u32, XATTR_SIZE_MAX, maxcount);
 
-	READ_BUF(4);
-	size = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &size) < 0)
+		return nfserr_bad_xdr;
 	if (size > maxcount)
 		return nfserr_xattr2big;
 
@@ -2211,12 +2211,12 @@ nfsd4_decode_setxattr(struct nfsd4_compoundargs *argp,
 		struct xdr_buf payload;
 
 		if (!xdr_stream_subsegment(argp->xdr, &payload, size))
-			goto xdr_error;
+			return nfserr_bad_xdr;
 		status = nfsd4_vbuf_from_vector(argp, &payload,
 						&setxattr->setxa_buf, size);
 	}
 
-	DECODE_TAIL;
+	return nfs_ok;
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#90 lore raw

PATCH 90/770 NFSD: Replace READ* macros in nfsd4_decode_listxattrs()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 2212036cadf4da3c4b0e4bd2a9a8c3d78617ab4f ]

---
 fs/nfsd/nfs4xdr.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
fs/nfsd/nfs4xdr.c +5 -5
index 38610764d7161..bf8eacab64952 100644
@@ -2223,11 +2223,10 @@ static __be32
 nfsd4_decode_listxattrs(struct nfsd4_compoundargs *argp,
 			struct nfsd4_listxattrs *listxattrs)
 {
-	DECODE_HEAD;
 	u32 maxcount;
 
-	READ_BUF(12);
-	p = xdr_decode_hyper(p, &listxattrs->lsxa_cookie);
+	if (xdr_stream_decode_u64(argp->xdr, &listxattrs->lsxa_cookie) < 0)
+		return nfserr_bad_xdr;
 
 	/*
 	 * If the cookie  is too large to have even one user.x attribute
@@ -2237,7 +2236,8 @@ nfsd4_decode_listxattrs(struct nfsd4_compoundargs *argp,
 	    (XATTR_LIST_MAX / (XATTR_USER_PREFIX_LEN + 2)))
 		return nfserr_badcookie;
 
-	maxcount = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &maxcount) < 0)
+		return nfserr_bad_xdr;
 	if (maxcount < 8)
 		/* Always need at least 2 words (length and one character) */
 		return nfserr_inval;
@@ -2245,7 +2245,7 @@ nfsd4_decode_listxattrs(struct nfsd4_compoundargs *argp,
 	maxcount = min(maxcount, svc_max_payload(argp->rqstp));
 	listxattrs->lsxa_maxcount = maxcount;
 
-	DECODE_TAIL;
+	return nfs_ok;
 }
 
 static __be32
Signature · 1 line
2.43.0
author maintainer
#91 lore raw

PATCH 91/770 NFSD: Make nfsd4_ops::opnum a u32

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 3a237b4af5b7b0e77588e120554077cab3341943 ]

Avoid passing a "pointer to int" argument to xdr_stream_decode_u32.

---
 fs/nfsd/nfs4proc.c | 2 +-
 fs/nfsd/nfs4xdr.c  | 7 +++----
 fs/nfsd/xdr4.h     | 2 +-
 3 files changed, 5 insertions(+), 6 deletions(-)
fs/nfsd/nfs4proc.c +1 -1
index a038d1e182ff3..6b06f0ad05615 100644
@@ -3272,7 +3272,7 @@ int nfsd4_max_reply(struct svc_rqst *rqstp, struct nfsd4_op *op)
 void warn_on_nonidempotent_op(struct nfsd4_op *op)
 {
 	if (OPDESC(op)->op_flags & OP_MODIFIES_SOMETHING) {
-		pr_err("unable to encode reply to nonidempotent op %d (%s)\n",
+		pr_err("unable to encode reply to nonidempotent op %u (%s)\n",
 			op->opnum, nfsd4_op_name(op->opnum));
 		WARN_ON_ONCE(1);
 	}
fs/nfsd/nfs4xdr.c +3 -4
index bf8eacab64952..085191b4b3aa5 100644
@@ -2419,9 +2419,8 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
 		op = &argp->ops[i];
 		op->replay = NULL;
 
-		READ_BUF(4);
-		op->opnum = be32_to_cpup(p++);
-
+		if (xdr_stream_decode_u32(argp->xdr, &op->opnum) < 0)
+			return nfserr_bad_xdr;
 		if (nfsd4_opnum_in_range(argp, op)) {
 			op->status = nfsd4_dec_ops[op->opnum](argp, &op->u);
 			if (op->status != nfs_ok)
@@ -5395,7 +5394,7 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
 	if (op->status && opdesc &&
 			!(opdesc->op_flags & OP_NONTRIVIAL_ERROR_ENCODE))
 		goto status;
-	BUG_ON(op->opnum < 0 || op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) ||
+	BUG_ON(op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) ||
 	       !nfsd4_enc_ops[op->opnum]);
 	encoder = nfsd4_enc_ops[op->opnum];
 	op->status = encoder(resp, op->status, &op->u);
fs/nfsd/xdr4.h +1 -1
index facc5762bf831..2c31f3a7d7c74 100644
@@ -615,7 +615,7 @@ struct nfsd4_copy_notify {
 };
 
 struct nfsd4_op {
-	int					opnum;
+	u32					opnum;
 	const struct nfsd4_operation *		opdesc;
 	__be32					status;
 	union nfsd4_op_u {
Signature · 1 line
2.43.0
author maintainer
#92 lore raw

PATCH 92/770 NFSD: Replace READ* macros in nfsd4_decode_compound()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit d9b74bdac6f24afc3101b6a5b6f59842610c9c94 ]

And clean-up: Now that we have removed the DECODE_TAIL macro from nfsd4_decode_compound(), we observe that there's no benefit for nfsd4_decode_compound() to return nfs_ok or nfserr_bad_xdr only to have its sole caller convert those values to one or zero, respectively. Have nfsd4_decode_compound() return 1/0 instead.

---
 fs/nfsd/nfs4xdr.c | 69 ++++++++++++++++++++---------------------------
 1 file changed, 29 insertions(+), 40 deletions(-)
fs/nfsd/nfs4xdr.c +29 -40
index 085191b4b3aa5..30604a3e70c0f 100644
@@ -186,28 +186,6 @@ svcxdr_dupstr(struct nfsd4_compoundargs *argp, void *buf, u32 len)
 	return p;
 }
 
-/**
- * savemem - duplicate a chunk of memory for later processing
- * @argp: NFSv4 compound argument structure to be freed with
- * @p: pointer to be duplicated
- * @nbytes: length to be duplicated
- *
- * Returns a pointer to a copy of @nbytes bytes of memory at @p
- * that are preserved until processing of the NFSv4 compound
- * operation described by @argp finishes.
- */
-static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes)
-{
-	void *ret;
-
-	ret = svcxdr_tmpalloc(argp, nbytes);
-	if (!ret)
-		return NULL;
-	memcpy(ret, p, nbytes);
-	return ret;
-}
-
-
 /*
  * NFSv4 basic data type decoders
  */
@@ -2372,43 +2350,54 @@ nfsd4_opnum_in_range(struct nfsd4_compoundargs *argp, struct nfsd4_op *op)
 	return true;
 }
 
-static __be32
+static int
 nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
 {
-	DECODE_HEAD;
 	struct nfsd4_op *op;
 	bool cachethis = false;
 	int auth_slack= argp->rqstp->rq_auth_slack;
 	int max_reply = auth_slack + 8; /* opcnt, status */
 	int readcount = 0;
 	int readbytes = 0;
+	__be32 *p;
 	int i;
 
-	READ_BUF(4);
-	argp->taglen = be32_to_cpup(p++);
-	READ_BUF(argp->taglen);
-	SAVEMEM(argp->tag, argp->taglen);
-	READ_BUF(8);
-	argp->minorversion = be32_to_cpup(p++);
-	argp->opcnt = be32_to_cpup(p++);
-	max_reply += 4 + (XDR_QUADLEN(argp->taglen) << 2);
-
-	if (argp->taglen > NFSD4_MAX_TAGLEN)
-		goto xdr_error;
+	if (xdr_stream_decode_u32(argp->xdr, &argp->taglen) < 0)
+		return 0;
+	max_reply += XDR_UNIT;
+	argp->tag = NULL;
+	if (unlikely(argp->taglen)) {
+		if (argp->taglen > NFSD4_MAX_TAGLEN)
+			return 0;
+		p = xdr_inline_decode(argp->xdr, argp->taglen);
+		if (!p)
+			return 0;
+		argp->tag = svcxdr_tmpalloc(argp, argp->taglen);
+		if (!argp->tag)
+			return 0;
+		memcpy(argp->tag, p, argp->taglen);
+		max_reply += xdr_align_size(argp->taglen);
+	}
+
+	if (xdr_stream_decode_u32(argp->xdr, &argp->minorversion) < 0)
+		return 0;
+	if (xdr_stream_decode_u32(argp->xdr, &argp->opcnt) < 0)
+		return 0;
+
 	/*
 	 * NFS4ERR_RESOURCE is a more helpful error than GARBAGE_ARGS
 	 * here, so we return success at the xdr level so that
 	 * nfsd4_proc can handle this is an NFS-level error.
 	 */
 	if (argp->opcnt > NFSD_MAX_OPS_PER_COMPOUND)
-		return 0;
+		return 1;
 
 	if (argp->opcnt > ARRAY_SIZE(argp->iops)) {
 		argp->ops = kzalloc(argp->opcnt * sizeof(*argp->ops), GFP_KERNEL);
 		if (!argp->ops) {
 			argp->ops = argp->iops;
 			dprintk("nfsd: couldn't allocate room for COMPOUND\n");
-			goto xdr_error;
+			return 0;
 		}
 	}
 
@@ -2420,7 +2409,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
 		op->replay = NULL;
 
 		if (xdr_stream_decode_u32(argp->xdr, &op->opnum) < 0)
-			return nfserr_bad_xdr;
+			return 0;
 		if (nfsd4_opnum_in_range(argp, op)) {
 			op->status = nfsd4_dec_ops[op->opnum](argp, &op->u);
 			if (op->status != nfs_ok)
@@ -2467,7 +2456,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
 	if (readcount > 1 || max_reply > PAGE_SIZE - auth_slack)
 		clear_bit(RQ_SPLICE_OK, &argp->rqstp->rq_flags);
 
-	DECODE_TAIL;
+	return 1;
 }
 
 static __be32 *encode_change(__be32 *p, struct kstat *stat, struct inode *inode,
@@ -5496,7 +5485,7 @@ nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p)
 	args->ops = args->iops;
 	args->rqstp = rqstp;
 
-	return !nfsd4_decode_compound(args);
+	return nfsd4_decode_compound(args);
 }
 
 int
Signature · 1 line
2.43.0
author maintainer
#93 lore raw

PATCH 93/770 NFSD: Remove macros that are no longer used

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 5cfc822f3e77b0477e6602d399116130317f537a ]

Now that all the NFSv4 decoder functions have been converted to make direct calls to the xdr helpers, remove the unused C macros.

---
 fs/nfsd/nfs4xdr.c | 40 ----------------------------------------
 fs/nfsd/xdr4.h    |  9 ---------
 2 files changed, 49 deletions(-)
fs/nfsd/nfs4xdr.c +0 -40
index 30604a3e70c0f..315be1c1ab85c 100644
@@ -102,45 +102,6 @@ check_filename(char *str, int len)
 	return 0;
 }
 
-#define DECODE_HEAD				\
-	__be32 *p;				\
-	__be32 status
-#define DECODE_TAIL				\
-	status = 0;				\
-out:						\
-	return status;				\
-xdr_error:					\
-	dprintk("NFSD: xdr error (%s:%d)\n",	\
-			__FILE__, __LINE__);	\
-	status = nfserr_bad_xdr;		\
-	goto out
-
-#define READMEM(x,nbytes) do {			\
-	x = (char *)p;				\
-	p += XDR_QUADLEN(nbytes);		\
-} while (0)
-#define SAVEMEM(x,nbytes) do {			\
-	if (!(x = (p==argp->tmp || p == argp->tmpp) ? \
- 		savemem(argp, p, nbytes) :	\
- 		(char *)p)) {			\
-		dprintk("NFSD: xdr error (%s:%d)\n", \
-				__FILE__, __LINE__); \
-		goto xdr_error;			\
-		}				\
-	p += XDR_QUADLEN(nbytes);		\
-} while (0)
-#define COPYMEM(x,nbytes) do {			\
-	memcpy((x), p, nbytes);			\
-	p += XDR_QUADLEN(nbytes);		\
-} while (0)
-#define READ_BUF(nbytes)			\
-	do {					\
-		p = xdr_inline_decode(argp->xdr,\
-				      nbytes);	\
-		if (!p)				\
-			goto xdr_error;		\
-	} while (0)
-
 static int zero_clientid(clientid_t *clid)
 {
 	return (clid->cl_boot == 0) && (clid->cl_id == 0);
@@ -5478,7 +5439,6 @@ nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p)
 	struct nfsd4_compoundargs *args = rqstp->rq_argp;
 
 	/* svcxdr_tmp_alloc */
-	args->tmpp = NULL;
 	args->to_free = NULL;
 
 	args->xdr = &rqstp->rq_arg_stream;
fs/nfsd/xdr4.h +0 -9
index 2c31f3a7d7c74..e12fbe382e3f3 100644
@@ -386,13 +386,6 @@ struct nfsd4_setclientid_confirm {
 	nfs4_verifier	sc_confirm;
 };
 
-struct nfsd4_saved_compoundargs {
-	__be32 *p;
-	__be32 *end;
-	int pagelen;
-	struct page **pagelist;
-};
-
 struct nfsd4_test_stateid_id {
 	__be32			ts_id_status;
 	stateid_t		ts_id_stateid;
@@ -696,8 +689,6 @@ struct svcxdr_tmpbuf {
 
 struct nfsd4_compoundargs {
 	/* scratch variables for XDR decode */
-	__be32				tmp[8];
-	__be32 *			tmpp;
 	struct xdr_stream		*xdr;
 	struct svcxdr_tmpbuf		*to_free;
 	struct svc_rqst			*rqstp;
Signature · 1 line
2.43.0
author maintainer
#94 lore raw

PATCH 94/770 nfsd: only call inode_query_iversion in the I_VERSION case

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: J. Bruce Fields <[email protected]>

[ Upstream commit 70b87f77294d16d3e567056ba4c9ee2b091a5b50 ]

inode_query_iversion() can modify i_version. Depending on the exported filesystem, that may not be safe. For example, if you're re-exporting NFS, NFS stores the server's change attribute in i_version and does not expect it to be modified locally. This has been observed causing unnecessary cache invalidations.

The way a filesystem indicates that it's OK to call inode_query_iverson() is by setting SB_I_VERSION.

So, move the I_VERSION check out of encode_change(), where it's used only in GETATTR responses, to nfsd4_change_attribute(), which is also called for pre- and post- operation attributes.

(Note we could also pull the NFSEXP_V4ROOT case into nfsd4_change_attribute() as well. That would actually be a no-op, since pre/post attrs are only used for metadata-modifying operations, and V4ROOT exports are read-only. But we might make the change in the future just for simplicity.)

---
 fs/nfsd/nfs3xdr.c |  5 ++---
 fs/nfsd/nfs4xdr.c |  6 +-----
 fs/nfsd/nfsfh.h   | 14 ++++++++++----
 3 files changed, 13 insertions(+), 12 deletions(-)
fs/nfsd/nfs3xdr.c +2 -3
index 0d75d201db1b3..5956b0317c55e 100644
@@ -291,14 +291,13 @@ void fill_post_wcc(struct svc_fh *fhp)
 		printk("nfsd: inode locked twice during operation.\n");
 
 	err = fh_getattr(fhp, &fhp->fh_post_attr);
-	fhp->fh_post_change = nfsd4_change_attribute(&fhp->fh_post_attr,
-						     d_inode(fhp->fh_dentry));
 	if (err) {
 		fhp->fh_post_saved = false;
-		/* Grab the ctime anyway - set_change_info might use it */
 		fhp->fh_post_attr.ctime = d_inode(fhp->fh_dentry)->i_ctime;
 	} else
 		fhp->fh_post_saved = true;
+	fhp->fh_post_change = nfsd4_change_attribute(&fhp->fh_post_attr,
+						     d_inode(fhp->fh_dentry));
 }
 
 /*
fs/nfsd/nfs4xdr.c +1 -5
index 315be1c1ab85c..bdcfb5f7021da 100644
@@ -2426,12 +2426,8 @@ static __be32 *encode_change(__be32 *p, struct kstat *stat, struct inode *inode,
 	if (exp->ex_flags & NFSEXP_V4ROOT) {
 		*p++ = cpu_to_be32(convert_to_wallclock(exp->cd->flush_time));
 		*p++ = 0;
-	} else if (IS_I_VERSION(inode)) {
+	} else
 		p = xdr_encode_hyper(p, nfsd4_change_attribute(stat, inode));
-	} else {
-		*p++ = cpu_to_be32(stat->ctime.tv_sec);
-		*p++ = cpu_to_be32(stat->ctime.tv_nsec);
-	}
 	return p;
 }
 
fs/nfsd/nfsfh.h +10 -4
index 56cfbc3615618..39d764b129fa3 100644
@@ -261,10 +261,16 @@ static inline u64 nfsd4_change_attribute(struct kstat *stat,
 {
 	u64 chattr;
 
-	chattr =  stat->ctime.tv_sec;
-	chattr <<= 30;
-	chattr += stat->ctime.tv_nsec;
-	chattr += inode_query_iversion(inode);
+	if (IS_I_VERSION(inode)) {
+		chattr =  stat->ctime.tv_sec;
+		chattr <<= 30;
+		chattr += stat->ctime.tv_nsec;
+		chattr += inode_query_iversion(inode);
+	} else {
+		chattr = stat->ctime.tv_sec;
+		chattr <<= 32;
+		chattr += stat->ctime.tv_nsec;
+	}
 	return chattr;
 }
 
Signature · 1 line
2.43.0
author maintainer
#95 lore raw

PATCH 95/770 nfsd: simplify nfsd4_change_info

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: J. Bruce Fields <[email protected]>

[ Upstream commit b2140338d8dca827ad9e83f3e026e9d51748b265 ]

It doesn't make sense to carry all these extra fields around. Just make everything into change attribute from the start.

This is just cleanup, there should be no change in behavior.

---
 fs/nfsd/nfs4xdr.c | 11 ++---------
 fs/nfsd/xdr4.h    | 11 -----------
 2 files changed, 2 insertions(+), 20 deletions(-)
fs/nfsd/nfs4xdr.c +2 -9
index bdcfb5f7021da..4df6c75d0eb7f 100644
@@ -2459,15 +2459,8 @@ static __be32 *encode_time_delta(__be32 *p, struct inode *inode)
 static __be32 *encode_cinfo(__be32 *p, struct nfsd4_change_info *c)
 {
 	*p++ = cpu_to_be32(c->atomic);
-	if (c->change_supported) {
-		p = xdr_encode_hyper(p, c->before_change);
-		p = xdr_encode_hyper(p, c->after_change);
-	} else {
-		*p++ = cpu_to_be32(c->before_ctime_sec);
-		*p++ = cpu_to_be32(c->before_ctime_nsec);
-		*p++ = cpu_to_be32(c->after_ctime_sec);
-		*p++ = cpu_to_be32(c->after_ctime_nsec);
-	}
+	p = xdr_encode_hyper(p, c->before_change);
+	p = xdr_encode_hyper(p, c->after_change);
 	return p;
 }
 
fs/nfsd/xdr4.h +0 -11
index e12fbe382e3f3..b4556e86e97c3 100644
@@ -76,12 +76,7 @@ static inline bool nfsd4_has_session(struct nfsd4_compound_state *cs)
 
 struct nfsd4_change_info {
 	u32		atomic;
-	bool		change_supported;
-	u32		before_ctime_sec;
-	u32		before_ctime_nsec;
 	u64		before_change;
-	u32		after_ctime_sec;
-	u32		after_ctime_nsec;
 	u64		after_change;
 };
 
@@ -754,15 +749,9 @@ set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
 {
 	BUG_ON(!fhp->fh_pre_saved);
 	cinfo->atomic = (u32)fhp->fh_post_saved;
-	cinfo->change_supported = IS_I_VERSION(d_inode(fhp->fh_dentry));
 
 	cinfo->before_change = fhp->fh_pre_change;
 	cinfo->after_change = fhp->fh_post_change;
-	cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec;
-	cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec;
-	cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec;
-	cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec;
-
 }
 
 
Signature · 1 line
2.43.0
author maintainer
#96 lore raw

PATCH 96/770 nfsd: minor nfsd4_change_attribute cleanup

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: J. Bruce Fields <[email protected]>

[ Upstream commit 4b03d99794eeed27650597a886247c6427ce1055 ]

Minor cleanup, no change in behavior.

Also pull out a common helper that'll be useful elsewhere.

---
 fs/nfsd/nfsfh.h          | 13 +++++--------
 include/linux/iversion.h | 13 +++++++++++++
 2 files changed, 18 insertions(+), 8 deletions(-)
fs/nfsd/nfsfh.h +5 -8
index 39d764b129fa3..45bd776290d52 100644
@@ -259,19 +259,16 @@ fh_clear_wcc(struct svc_fh *fhp)
 static inline u64 nfsd4_change_attribute(struct kstat *stat,
 					 struct inode *inode)
 {
-	u64 chattr;
-
 	if (IS_I_VERSION(inode)) {
+		u64 chattr;
+
 		chattr =  stat->ctime.tv_sec;
 		chattr <<= 30;
 		chattr += stat->ctime.tv_nsec;
 		chattr += inode_query_iversion(inode);
-	} else {
-		chattr = stat->ctime.tv_sec;
-		chattr <<= 32;
-		chattr += stat->ctime.tv_nsec;
-	}
-	return chattr;
+		return chattr;
+	} else
+		return time_to_chattr(&stat->ctime);
 }
 
 extern void fill_pre_wcc(struct svc_fh *fhp);
include/linux/iversion.h +13 -0
index 2917ef990d435..3bfebde5a1a6d 100644
@@ -328,6 +328,19 @@ inode_query_iversion(struct inode *inode)
 	return cur >> I_VERSION_QUERIED_SHIFT;
 }
 
+/*
+ * For filesystems without any sort of change attribute, the best we can
+ * do is fake one up from the ctime:
+ */
+static inline u64 time_to_chattr(struct timespec64 *t)
+{
+	u64 chattr = t->tv_sec;
+
+	chattr <<= 32;
+	chattr += t->tv_nsec;
+	return chattr;
+}
+
 /**
  * inode_eq_iversion_raw - check whether the raw i_version counter has changed
  * @inode: inode to check
Signature · 1 line
2.43.0
author maintainer
#97 lore raw

PATCH 97/770 nfsd4: dont query change attribute in v2/v3 case

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: J. Bruce Fields <[email protected]>

[ Upstream commit 942b20dc245590327ee0187c15c78174cd96dd52 ]

inode_query_iversion() has side effects, and there's no point calling it when we're not even going to use it.

We check whether we're currently processing a v4 request by checking fh_maxsize, which is arguably a little hacky; we could add a flag to svc_fh instead.

---
 fs/nfsd/nfs3xdr.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)
fs/nfsd/nfs3xdr.c +9 -5
index 5956b0317c55e..7d44e10a5f5dd 100644
@@ -259,11 +259,11 @@ void fill_pre_wcc(struct svc_fh *fhp)
 {
 	struct inode    *inode;
 	struct kstat	stat;
+	bool v4 = (fhp->fh_maxsize == NFS4_FHSIZE);
 	__be32 err;
 
 	if (fhp->fh_pre_saved)
 		return;
-
 	inode = d_inode(fhp->fh_dentry);
 	err = fh_getattr(fhp, &stat);
 	if (err) {
@@ -272,11 +272,12 @@ void fill_pre_wcc(struct svc_fh *fhp)
 		stat.ctime = inode->i_ctime;
 		stat.size  = inode->i_size;
 	}
+	if (v4)
+		fhp->fh_pre_change = nfsd4_change_attribute(&stat, inode);
 
 	fhp->fh_pre_mtime = stat.mtime;
 	fhp->fh_pre_ctime = stat.ctime;
 	fhp->fh_pre_size  = stat.size;
-	fhp->fh_pre_change = nfsd4_change_attribute(&stat, inode);
 	fhp->fh_pre_saved = true;
 }
 
@@ -285,6 +286,8 @@ void fill_pre_wcc(struct svc_fh *fhp)
  */
 void fill_post_wcc(struct svc_fh *fhp)
 {
+	bool v4 = (fhp->fh_maxsize == NFS4_FHSIZE);
+	struct inode *inode = d_inode(fhp->fh_dentry);
 	__be32 err;
 
 	if (fhp->fh_post_saved)
@@ -293,11 +296,12 @@ void fill_post_wcc(struct svc_fh *fhp)
 	err = fh_getattr(fhp, &fhp->fh_post_attr);
 	if (err) {
 		fhp->fh_post_saved = false;
-		fhp->fh_post_attr.ctime = d_inode(fhp->fh_dentry)->i_ctime;
+		fhp->fh_post_attr.ctime = inode->i_ctime;
 	} else
 		fhp->fh_post_saved = true;
-	fhp->fh_post_change = nfsd4_change_attribute(&fhp->fh_post_attr,
-						     d_inode(fhp->fh_dentry));
+	if (v4)
+		fhp->fh_post_change =
+			nfsd4_change_attribute(&fhp->fh_post_attr, inode);
 }
 
 /*
Signature · 1 line
2.43.0
author maintainer
#98 lore raw

PATCH 98/770 Revert "nfsd4: support change_attr_type attribute"

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: J. Bruce Fields <[email protected]>

This reverts commit a85857633b04d57f4524cca0a2bfaf87b2543f9f.

We're still factoring ctime into our change attribute even in the IS_I_VERSION case. If someone sets the system time backwards, a client could see the change attribute go backwards. Maybe we can just say "well, don't do that", but there's some question whether that's good enough, or whether we need a better guarantee.

Also, the client still isn't actually using the attribute.

While we're still figuring this out, let's just stop returning this attribute.

---
 fs/nfsd/nfs4xdr.c    | 10 ----------
 fs/nfsd/nfsd.h       |  1 -
 include/linux/nfs4.h |  8 --------
 3 files changed, 19 deletions(-)
fs/nfsd/nfs4xdr.c +0 -10
index 4df6c75d0eb7f..bb037e8eb8304 100644
@@ -3311,16 +3311,6 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
 			goto out;
 	}
 
-	if (bmval2 & FATTR4_WORD2_CHANGE_ATTR_TYPE) {
-		p = xdr_reserve_space(xdr, 4);
-		if (!p)
-			goto out_resource;
-		if (IS_I_VERSION(d_inode(dentry)))
-			*p++ = cpu_to_be32(NFS4_CHANGE_TYPE_IS_MONOTONIC_INCR);
-		else
-			*p++ = cpu_to_be32(NFS4_CHANGE_TYPE_IS_TIME_METADATA);
-	}
-
 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
 	if (bmval2 & FATTR4_WORD2_SECURITY_LABEL) {
 		status = nfsd4_encode_security_label(xdr, rqstp, context,
fs/nfsd/nfsd.h +0 -1
index 3eaa81e001f9c..2326428e2c5bf 100644
@@ -394,7 +394,6 @@ void		nfsd_lockd_shutdown(void);
 
 #define NFSD4_2_SUPPORTED_ATTRS_WORD2 \
 	(NFSD4_1_SUPPORTED_ATTRS_WORD2 | \
-	FATTR4_WORD2_CHANGE_ATTR_TYPE | \
 	FATTR4_WORD2_MODE_UMASK | \
 	NFSD4_2_SECURITY_ATTRS | \
 	FATTR4_WORD2_XATTR_SUPPORT)
include/linux/nfs4.h +0 -8
index 9dc7eeac924f0..5b4c67c91f56a 100644
@@ -385,13 +385,6 @@ enum lock_type4 {
 	NFS4_WRITEW_LT = 4
 };
 
-enum change_attr_type4 {
-	NFS4_CHANGE_TYPE_IS_MONOTONIC_INCR = 0,
-	NFS4_CHANGE_TYPE_IS_VERSION_COUNTER = 1,
-	NFS4_CHANGE_TYPE_IS_VERSION_COUNTER_NOPNFS = 2,
-	NFS4_CHANGE_TYPE_IS_TIME_METADATA = 3,
-	NFS4_CHANGE_TYPE_IS_UNDEFINED = 4
-};
 
 /* Mandatory Attributes */
 #define FATTR4_WORD0_SUPPORTED_ATTRS    (1UL << 0)
@@ -459,7 +452,6 @@ enum change_attr_type4 {
 #define FATTR4_WORD2_LAYOUT_BLKSIZE     (1UL << 1)
 #define FATTR4_WORD2_MDSTHRESHOLD       (1UL << 4)
 #define FATTR4_WORD2_CLONE_BLKSIZE	(1UL << 13)
-#define FATTR4_WORD2_CHANGE_ATTR_TYPE	(1UL << 15)
 #define FATTR4_WORD2_SECURITY_LABEL     (1UL << 16)
 #define FATTR4_WORD2_MODE_UMASK		(1UL << 17)
 #define FATTR4_WORD2_XATTR_SUPPORT	(1UL << 18)
Signature · 1 line
2.43.0
author maintainer
#99 lore raw

PATCH 99/770 nfsd: add a new EXPORT_OP_NOWCC flag to struct export_operations

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jeff Layton <[email protected]>

[ Upstream commit daab110e47f8d7aa6da66923e3ac1a8dbd2b2a72 ]

With NFSv3 nfsd will always attempt to send along WCC data to the client. This generally involves saving off the in-core inode information prior to doing the operation on the given filehandle, and then issuing a vfs_getattr to it after the op.

Some filesystems (particularly clustered or networked ones) have an expensive ->getattr inode operation. Atomicity is also often difficult or impossible to guarantee on such filesystems. For those, we're best off not trying to provide WCC information to the client at all, and to simply allow it to poll for that information as needed with a GETATTR RPC.

This patch adds a new flags field to struct export_operations, and defines a new EXPORT_OP_NOWCC flag that filesystems can use to indicate that nfsd should not attempt to provide WCC info in NFSv3 replies. It also adds a blurb about the new flags field and flag to the exporting documentation.

The server will also now skip collecting this information for NFSv2 as well, since that info is never used there anyway.

Note that this patch does not add this flag to any filesystem export_operations structures. This was originally developed to allow reexporting nfs via nfsd.

Other filesystems may want to consider enabling this flag too. It's hard to tell however which ones have export operations to enable export via knfsd and which ones mostly rely on them for open-by-filehandle support, so I'm leaving that up to the individual maintainers to decide. I am cc'ing the relevant lists for those filesystems that I think may want to consider adding this though.

---
 Documentation/filesystems/nfs/exporting.rst | 27 +++++++++++++++++++++
 fs/nfs/export.c                             |  1 +
 fs/nfsd/nfs3xdr.c                           |  7 ++++--
 fs/nfsd/nfsfh.c                             | 14 +++++++++++
 fs/nfsd/nfsfh.h                             |  2 +-
 include/linux/exportfs.h                    |  2 ++
 6 files changed, 50 insertions(+), 3 deletions(-)
Documentation/filesystems/nfs/exporting.rst +27 -0
index 33d588a01ace1..cbe542ad52333 100644
@@ -154,6 +154,11 @@ struct which has the following members:
     to find potential names, and matches inode numbers to find the correct
     match.
 
+  flags
+    Some filesystems may need to be handled differently than others. The
+    export_operations struct also includes a flags field that allows the
+    filesystem to communicate such information to nfsd. See the Export
+    Operations Flags section below for more explanation.
 
 A filehandle fragment consists of an array of 1 or more 4byte words,
 together with a one byte "type".
@@ -163,3 +168,25 @@ generated by encode_fh, in which case it will have been padded with
 nuls.  Rather, the encode_fh routine should choose a "type" which
 indicates the decode_fh how much of the filehandle is valid, and how
 it should be interpreted.
+
+Export Operations Flags
+-----------------------
+In addition to the operation vector pointers, struct export_operations also
+contains a "flags" field that allows the filesystem to communicate to nfsd
+that it may want to do things differently when dealing with it. The
+following flags are defined:
+
+  EXPORT_OP_NOWCC - disable NFSv3 WCC attributes on this filesystem
+    RFC 1813 recommends that servers always send weak cache consistency
+    (WCC) data to the client after each operation. The server should
+    atomically collect attributes about the inode, do an operation on it,
+    and then collect the attributes afterward. This allows the client to
+    skip issuing GETATTRs in some situations but means that the server
+    is calling vfs_getattr for almost all RPCs. On some filesystems
+    (particularly those that are clustered or networked) this is expensive
+    and atomicity is difficult to guarantee. This flag indicates to nfsd
+    that it should skip providing WCC attributes to the client in NFSv3
+    replies when doing operations on this filesystem. Consider enabling
+    this on filesystems that have an expensive ->getattr inode operation,
+    or when atomicity between pre and post operation attribute collection
+    is impossible to guarantee.
fs/nfs/export.c +1 -0
index 3430d6891e89f..8f4c528865c57 100644
@@ -171,4 +171,5 @@ const struct export_operations nfs_export_ops = {
 	.encode_fh = nfs_encode_fh,
 	.fh_to_dentry = nfs_fh_to_dentry,
 	.get_parent = nfs_get_parent,
+	.flags = EXPORT_OP_NOWCC,
 };
fs/nfsd/nfs3xdr.c +5 -2
index 7d44e10a5f5dd..34b880211e5ea 100644
@@ -206,7 +206,7 @@ static __be32 *
 encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
 {
 	struct dentry *dentry = fhp->fh_dentry;
-	if (dentry && d_really_is_positive(dentry)) {
+	if (!fhp->fh_no_wcc && dentry && d_really_is_positive(dentry)) {
 	        __be32 err;
 		struct kstat stat;
 
@@ -262,7 +262,7 @@ void fill_pre_wcc(struct svc_fh *fhp)
 	bool v4 = (fhp->fh_maxsize == NFS4_FHSIZE);
 	__be32 err;
 
-	if (fhp->fh_pre_saved)
+	if (fhp->fh_no_wcc || fhp->fh_pre_saved)
 		return;
 	inode = d_inode(fhp->fh_dentry);
 	err = fh_getattr(fhp, &stat);
@@ -290,6 +290,9 @@ void fill_post_wcc(struct svc_fh *fhp)
 	struct inode *inode = d_inode(fhp->fh_dentry);
 	__be32 err;
 
+	if (fhp->fh_no_wcc)
+		return;
+
 	if (fhp->fh_post_saved)
 		printk("nfsd: inode locked twice during operation.\n");
 
fs/nfsd/nfsfh.c +14 -0
index c81dbbad87920..9c29a523f4848 100644
@@ -291,6 +291,16 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp)
 
 	fhp->fh_dentry = dentry;
 	fhp->fh_export = exp;
+
+	switch (rqstp->rq_vers) {
+	case 3:
+		if (dentry->d_sb->s_export_op->flags & EXPORT_OP_NOWCC)
+			fhp->fh_no_wcc = true;
+		break;
+	case 2:
+		fhp->fh_no_wcc = true;
+	}
+
 	return 0;
 out:
 	exp_put(exp);
@@ -559,6 +569,9 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
 	 */
 	set_version_and_fsid_type(fhp, exp, ref_fh);
 
+	/* If we have a ref_fh, then copy the fh_no_wcc setting from it. */
+	fhp->fh_no_wcc = ref_fh ? ref_fh->fh_no_wcc : false;
+
 	if (ref_fh == fhp)
 		fh_put(ref_fh);
 
@@ -662,6 +675,7 @@ fh_put(struct svc_fh *fhp)
 		exp_put(exp);
 		fhp->fh_export = NULL;
 	}
+	fhp->fh_no_wcc = false;
 	return;
 }
 
fs/nfsd/nfsfh.h +1 -1
index 45bd776290d52..347d10aa62655 100644
@@ -35,6 +35,7 @@ typedef struct svc_fh {
 
 	bool			fh_locked;	/* inode locked by us */
 	bool			fh_want_write;	/* remount protection taken */
+	bool			fh_no_wcc;	/* no wcc data needed */
 	int			fh_flags;	/* FH flags */
 #ifdef CONFIG_NFSD_V3
 	bool			fh_post_saved;	/* post-op attrs saved */
@@ -54,7 +55,6 @@ typedef struct svc_fh {
 	struct kstat		fh_post_attr;	/* full attrs after operation */
 	u64			fh_post_change; /* nfsv4 change; see above */
 #endif /* CONFIG_NFSD_V3 */
-
 } svc_fh;
 #define NFSD4_FH_FOREIGN (1<<0)
 #define SET_FH_FLAG(c, f) ((c)->fh_flags |= (f))
include/linux/exportfs.h +2 -0
index 3ceb72b67a7aa..e7de0103a32e8 100644
@@ -213,6 +213,8 @@ struct export_operations {
 			  bool write, u32 *device_generation);
 	int (*commit_blocks)(struct inode *inode, struct iomap *iomaps,
 			     int nr_iomaps, struct iattr *iattr);
+#define	EXPORT_OP_NOWCC		(0x1)	/* Don't collect wcc data for NFSv3 replies */
+	unsigned long	flags;
 };
 
 extern int exportfs_encode_inode_fh(struct inode *inode, struct fid *fid,
Signature · 1 line
2.43.0
author maintainer
#100 lore raw

PATCH 100/770 nfsd: allow filesystems to opt out of subtree checking

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jeff Layton <[email protected]>

[ Upstream commit ba5e8187c55555519ae0b63c0fb681391bc42af9 ]

When we start allowing NFS to be reexported, then we have some problems when it comes to subtree checking. In principle, we could allow it, but it would mean encoding parent info in the filehandles and there may not be enough space for that in a NFSv3 filehandle.

To enforce this at export upcall time, we add a new export_ops flag that declares the filesystem ineligible for subtree checking.

---
 Documentation/filesystems/nfs/exporting.rst | 12 ++++++++++++
 fs/nfs/export.c                             |  2 +-
 fs/nfsd/export.c                            |  6 ++++++
 include/linux/exportfs.h                    |  1 +
 4 files changed, 20 insertions(+), 1 deletion(-)
Documentation/filesystems/nfs/exporting.rst +12 -0
index cbe542ad52333..960be64446cb9 100644
@@ -190,3 +190,15 @@ following flags are defined:
     this on filesystems that have an expensive ->getattr inode operation,
     or when atomicity between pre and post operation attribute collection
     is impossible to guarantee.
+
+  EXPORT_OP_NOSUBTREECHK - disallow subtree checking on this fs
+    Many NFS operations deal with filehandles, which the server must then
+    vet to ensure that they live inside of an exported tree. When the
+    export consists of an entire filesystem, this is trivial. nfsd can just
+    ensure that the filehandle live on the filesystem. When only part of a
+    filesystem is exported however, then nfsd must walk the ancestors of the
+    inode to ensure that it's within an exported subtree. This is an
+    expensive operation and not all filesystems can support it properly.
+    This flag exempts the filesystem from subtree checking and causes
+    exportfs to get back an error if it tries to enable subtree checking
+    on it.
fs/nfs/export.c +1 -1
index 8f4c528865c57..b9ba306bf9120 100644
@@ -171,5 +171,5 @@ const struct export_operations nfs_export_ops = {
 	.encode_fh = nfs_encode_fh,
 	.fh_to_dentry = nfs_fh_to_dentry,
 	.get_parent = nfs_get_parent,
-	.flags = EXPORT_OP_NOWCC,
+	.flags = EXPORT_OP_NOWCC|EXPORT_OP_NOSUBTREECHK,
 };
fs/nfsd/export.c +6 -0
index 21e404e7cb68c..81e7bb12aca69 100644
@@ -408,6 +408,12 @@ static int check_export(struct inode *inode, int *flags, unsigned char *uuid)
 		return -EINVAL;
 	}
 
+	if (inode->i_sb->s_export_op->flags & EXPORT_OP_NOSUBTREECHK &&
+	    !(*flags & NFSEXP_NOSUBTREECHECK)) {
+		dprintk("%s: %s does not support subtree checking!\n",
+			__func__, inode->i_sb->s_type->name);
+		return -EINVAL;
+	}
 	return 0;
 
 }
include/linux/exportfs.h +1 -0
index e7de0103a32e8..2fcbab0f6b612 100644
@@ -214,6 +214,7 @@ struct export_operations {
 	int (*commit_blocks)(struct inode *inode, struct iomap *iomaps,
 			     int nr_iomaps, struct iattr *iattr);
 #define	EXPORT_OP_NOWCC		(0x1)	/* Don't collect wcc data for NFSv3 replies */
+#define	EXPORT_OP_NOSUBTREECHK	(0x2)	/* Subtree checking is not supported! */
 	unsigned long	flags;
 };
 
Signature · 1 line
2.43.0
author maintainer
#101 lore raw

PATCH 101/770 nfsd: close cached files prior to a REMOVE or RENAME that would replace target

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jeff Layton <[email protected]>

[ Upstream commit 7f84b488f9add1d5cca3e6197c95914c7bd3c1cf ]

It's not uncommon for some workloads to do a bunch of I/O to a file and delete it just afterward. If knfsd has a cached open file however, then the file may still be open when the dentry is unlinked. If the underlying filesystem is nfs, then that could trigger it to do a sillyrename.

On a REMOVE or RENAME scan the nfsd_file cache for open files that correspond to the inode, and proactively unhash and put their references. This should prevent any delete-on-last-close activity from occurring, solely due to knfsd's open file cache.

This must be done synchronously though so we use the variants that call flush_delayed_fput. There are deadlock possibilities if you call flush_delayed_fput while holding locks, however. In the case of nfsd_rename, we don't even do the lookups of the dentries to be renamed until we've locked for rename.

Once we've figured out what the target dentry is for a rename, check to see whether there are cached open files associated with it. If there are, then unwind all of the locking, close them all, and then reattempt the rename.

None of this is really necessary for "typical" filesystems though. It's mostly of use for NFS, so declare a new export op flag and use that to determine whether to close the files beforehand.

---
 Documentation/filesystems/nfs/exporting.rst | 13 +++++++++++++
 fs/nfs/export.c                             |  2 +-
 fs/nfsd/vfs.c                               | 16 +++++++++-------
 include/linux/exportfs.h                    |  5 +++--
 4 files changed, 26 insertions(+), 10 deletions(-)
Documentation/filesystems/nfs/exporting.rst +13 -0
index 960be64446cb9..0e98edd353b5f 100644
@@ -202,3 +202,16 @@ following flags are defined:
     This flag exempts the filesystem from subtree checking and causes
     exportfs to get back an error if it tries to enable subtree checking
     on it.
+
+  EXPORT_OP_CLOSE_BEFORE_UNLINK - always close cached files before unlinking
+    On some exportable filesystems (such as NFS) unlinking a file that
+    is still open can cause a fair bit of extra work. For instance,
+    the NFS client will do a "sillyrename" to ensure that the file
+    sticks around while it's still open. When reexporting, that open
+    file is held by nfsd so we usually end up doing a sillyrename, and
+    then immediately deleting the sillyrenamed file just afterward when
+    the link count actually goes to zero. Sometimes this delete can race
+    with other operations (for instance an rmdir of the parent directory).
+    This flag causes nfsd to close any open files for this inode _before_
+    calling into the vfs to do an unlink or a rename that would replace
+    an existing file.
fs/nfs/export.c +1 -1
index b9ba306bf9120..5428713af5fee 100644
@@ -171,5 +171,5 @@ const struct export_operations nfs_export_ops = {
 	.encode_fh = nfs_encode_fh,
 	.fh_to_dentry = nfs_fh_to_dentry,
 	.get_parent = nfs_get_parent,
-	.flags = EXPORT_OP_NOWCC|EXPORT_OP_NOSUBTREECHK,
+	.flags = EXPORT_OP_NOWCC|EXPORT_OP_NOSUBTREECHK|EXPORT_OP_CLOSE_BEFORE_UNLINK,
 };
fs/nfsd/vfs.c +9 -7
index 31edb883afd0d..fb4e6c57ce0bb 100644
@@ -1739,7 +1739,7 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
 	struct inode	*fdir, *tdir;
 	__be32		err;
 	int		host_err;
-	bool		has_cached = false;
+	bool		close_cached = false;
 
 	err = fh_verify(rqstp, ffhp, S_IFDIR, NFSD_MAY_REMOVE);
 	if (err)
@@ -1798,8 +1798,9 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
 	if (ndentry == trap)
 		goto out_dput_new;
 
-	if (nfsd_has_cached_files(ndentry)) {
-		has_cached = true;
+	if ((ndentry->d_sb->s_export_op->flags & EXPORT_OP_CLOSE_BEFORE_UNLINK) &&
+	    nfsd_has_cached_files(ndentry)) {
+		close_cached = true;
 		goto out_dput_old;
 	} else {
 		host_err = vfs_rename(fdir, odentry, tdir, ndentry, NULL, 0);
@@ -1820,7 +1821,7 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
 	 * as that would do the wrong thing if the two directories
 	 * were the same, so again we do it by hand.
 	 */
-	if (!has_cached) {
+	if (!close_cached) {
 		fill_post_wcc(ffhp);
 		fill_post_wcc(tfhp);
 	}
@@ -1834,8 +1835,8 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
 	 * shouldn't be done with locks held however, so we delay it until this
 	 * point and then reattempt the whole shebang.
 	 */
-	if (has_cached) {
-		has_cached = false;
+	if (close_cached) {
+		close_cached = false;
 		nfsd_close_cached_files(ndentry);
 		dput(ndentry);
 		goto retry;
@@ -1887,7 +1888,8 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
 		type = d_inode(rdentry)->i_mode & S_IFMT;
 
 	if (type != S_IFDIR) {
-		nfsd_close_cached_files(rdentry);
+		if (rdentry->d_sb->s_export_op->flags & EXPORT_OP_CLOSE_BEFORE_UNLINK)
+			nfsd_close_cached_files(rdentry);
 		host_err = vfs_unlink(dirp, rdentry, NULL);
 	} else {
 		host_err = vfs_rmdir(dirp, rdentry);
include/linux/exportfs.h +3 -2
index 2fcbab0f6b612..d829403ffd3bb 100644
@@ -213,8 +213,9 @@ struct export_operations {
 			  bool write, u32 *device_generation);
 	int (*commit_blocks)(struct inode *inode, struct iomap *iomaps,
 			     int nr_iomaps, struct iattr *iattr);
-#define	EXPORT_OP_NOWCC		(0x1)	/* Don't collect wcc data for NFSv3 replies */
-#define	EXPORT_OP_NOSUBTREECHK	(0x2)	/* Subtree checking is not supported! */
+#define	EXPORT_OP_NOWCC			(0x1) /* don't collect v3 wcc data */
+#define	EXPORT_OP_NOSUBTREECHK		(0x2) /* no subtree checking */
+#define	EXPORT_OP_CLOSE_BEFORE_UNLINK	(0x4) /* close files before unlink */
 	unsigned long	flags;
 };
 
Signature · 1 line
2.43.0
author maintainer
#102 lore raw

PATCH 102/770 exportfs: Add a function to return the raw output from fh_to_dentry()

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Trond Myklebust <[email protected]>

[ Upstream commit d045465fc6cbfa4acfb5a7d817a7c1a57a078109 ]

In order to allow nfsd to accept return values that are not acceptable to overlayfs and others, add a new function.

---
 fs/exportfs/expfs.c      | 32 ++++++++++++++++++++++++--------
 include/linux/exportfs.h |  5 +++++
 2 files changed, 29 insertions(+), 8 deletions(-)
fs/exportfs/expfs.c +24 -8
index 2dd55b172d57f..0106eba46d5af 100644
@@ -417,9 +417,11 @@ int exportfs_encode_fh(struct dentry *dentry, struct fid *fid, int *max_len,
 }
 EXPORT_SYMBOL_GPL(exportfs_encode_fh);
 
-struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
-		int fh_len, int fileid_type,
-		int (*acceptable)(void *, struct dentry *), void *context)
+struct dentry *
+exportfs_decode_fh_raw(struct vfsmount *mnt, struct fid *fid, int fh_len,
+		       int fileid_type,
+		       int (*acceptable)(void *, struct dentry *),
+		       void *context)
 {
 	const struct export_operations *nop = mnt->mnt_sb->s_export_op;
 	struct dentry *result, *alias;
@@ -432,10 +434,8 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
 	if (!nop || !nop->fh_to_dentry)
 		return ERR_PTR(-ESTALE);
 	result = nop->fh_to_dentry(mnt->mnt_sb, fid, fh_len, fileid_type);
-	if (PTR_ERR(result) == -ENOMEM)
-		return ERR_CAST(result);
 	if (IS_ERR_OR_NULL(result))
-		return ERR_PTR(-ESTALE);
+		return result;
 
 	/*
 	 * If no acceptance criteria was specified by caller, a disconnected
@@ -561,10 +561,26 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
 
  err_result:
 	dput(result);
-	if (err != -ENOMEM)
-		err = -ESTALE;
 	return ERR_PTR(err);
 }
+EXPORT_SYMBOL_GPL(exportfs_decode_fh_raw);
+
+struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
+				  int fh_len, int fileid_type,
+				  int (*acceptable)(void *, struct dentry *),
+				  void *context)
+{
+	struct dentry *ret;
+
+	ret = exportfs_decode_fh_raw(mnt, fid, fh_len, fileid_type,
+				     acceptable, context);
+	if (IS_ERR_OR_NULL(ret)) {
+		if (ret == ERR_PTR(-ENOMEM))
+			return ret;
+		return ERR_PTR(-ESTALE);
+	}
+	return ret;
+}
 EXPORT_SYMBOL_GPL(exportfs_decode_fh);
 
 MODULE_LICENSE("GPL");
include/linux/exportfs.h +5 -0
index d829403ffd3bb..846df3c96730f 100644
@@ -223,6 +223,11 @@ extern int exportfs_encode_inode_fh(struct inode *inode, struct fid *fid,
 				    int *max_len, struct inode *parent);
 extern int exportfs_encode_fh(struct dentry *dentry, struct fid *fid,
 	int *max_len, int connectable);
+extern struct dentry *exportfs_decode_fh_raw(struct vfsmount *mnt,
+					     struct fid *fid, int fh_len,
+					     int fileid_type,
+					     int (*acceptable)(void *, struct dentry *),
+					     void *context);
 extern struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
 	int fh_len, int fileid_type, int (*acceptable)(void *, struct dentry *),
 	void *context);
Signature · 1 line
2.43.0
author maintainer
#103 lore raw

PATCH 103/770 nfsd: Fix up nfsd to ensure that timeout errors dont result in ESTALE

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Trond Myklebust <[email protected]>

[ Upstream commit 2e19d10c1438241de32467637a2a411971547991 ]

If the underlying filesystem times out, then we want knfsd to return NFSERR_JUKEBOX/DELAY rather than NFSERR_STALE.

---
 fs/nfsd/nfsfh.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)
fs/nfsd/nfsfh.c +12 -4
index 9c29a523f4848..e80a7525561d0 100644
@@ -268,12 +268,20 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp)
 	if (fileid_type == FILEID_ROOT)
 		dentry = dget(exp->ex_path.dentry);
 	else {
-		dentry = exportfs_decode_fh(exp->ex_path.mnt, fid,
-				data_left, fileid_type,
-				nfsd_acceptable, exp);
-		if (IS_ERR_OR_NULL(dentry))
+		dentry = exportfs_decode_fh_raw(exp->ex_path.mnt, fid,
+						data_left, fileid_type,
+						nfsd_acceptable, exp);
+		if (IS_ERR_OR_NULL(dentry)) {
 			trace_nfsd_set_fh_dentry_badhandle(rqstp, fhp,
 					dentry ?  PTR_ERR(dentry) : -ESTALE);
+			switch (PTR_ERR(dentry)) {
+			case -ENOMEM:
+			case -ETIMEDOUT:
+				break;
+			default:
+				dentry = ERR_PTR(-ESTALE);
+			}
+		}
 	}
 	if (dentry == NULL)
 		goto out;
Signature · 1 line
2.43.0
author maintainer
#104 lore raw

PATCH 104/770 nfsd: Set PF_LOCAL_THROTTLE on local filesystems only

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Trond Myklebust <[email protected]>

[ Upstream commit 01cbf3853959feec40ec9b9a399e12a021cd4d81 ]

Don't set PF_LOCAL_THROTTLE on remote filesystems like NFS, since they aren't expected to ever be subject to double buffering.

---
 fs/nfs/export.c          |  3 ++-
 fs/nfsd/vfs.c            | 13 +++++++++++--
 include/linux/exportfs.h |  1 +
 3 files changed, 14 insertions(+), 3 deletions(-)
fs/nfs/export.c +2 -1
index 5428713af5fee..48b879cfe6e3b 100644
@@ -171,5 +171,6 @@ const struct export_operations nfs_export_ops = {
 	.encode_fh = nfs_encode_fh,
 	.fh_to_dentry = nfs_fh_to_dentry,
 	.get_parent = nfs_get_parent,
-	.flags = EXPORT_OP_NOWCC|EXPORT_OP_NOSUBTREECHK|EXPORT_OP_CLOSE_BEFORE_UNLINK,
+	.flags = EXPORT_OP_NOWCC|EXPORT_OP_NOSUBTREECHK|
+		EXPORT_OP_CLOSE_BEFORE_UNLINK|EXPORT_OP_REMOTE_FS,
 };
fs/nfsd/vfs.c +11 -2
index fb4e6c57ce0bb..a515cbd0a7d8f 100644
@@ -986,6 +986,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
 				__be32 *verf)
 {
 	struct file		*file = nf->nf_file;
+	struct super_block	*sb = file_inode(file)->i_sb;
 	struct svc_export	*exp;
 	struct iov_iter		iter;
 	errseq_t		since;
@@ -993,12 +994,18 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
 	int			host_err;
 	int			use_wgather;
 	loff_t			pos = offset;
+	unsigned long		exp_op_flags = 0;
 	unsigned int		pflags = current->flags;
 	rwf_t			flags = 0;
+	bool			restore_flags = false;
 
 	trace_nfsd_write_opened(rqstp, fhp, offset, *cnt);
 
-	if (test_bit(RQ_LOCAL, &rqstp->rq_flags))
+	if (sb->s_export_op)
+		exp_op_flags = sb->s_export_op->flags;
+
+	if (test_bit(RQ_LOCAL, &rqstp->rq_flags) &&
+	    !(exp_op_flags & EXPORT_OP_REMOTE_FS)) {
 		/*
 		 * We want throttling in balance_dirty_pages()
 		 * and shrink_inactive_list() to only consider
@@ -1007,6 +1014,8 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
 		 * the client's dirty pages or its congested queue.
 		 */
 		current->flags |= PF_LOCAL_THROTTLE;
+		restore_flags = true;
+	}
 
 	exp = fhp->fh_export;
 	use_wgather = (rqstp->rq_vers == 2) && EX_WGATHER(exp);
@@ -1062,7 +1071,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
 		trace_nfsd_write_err(rqstp, fhp, offset, host_err);
 		nfserr = nfserrno(host_err);
 	}
-	if (test_bit(RQ_LOCAL, &rqstp->rq_flags))
+	if (restore_flags)
 		current_restore_flags(pflags, PF_LOCAL_THROTTLE);
 	return nfserr;
 }
include/linux/exportfs.h +1 -0
index 846df3c96730f..d93e8a6737bb0 100644
@@ -216,6 +216,7 @@ struct export_operations {
 #define	EXPORT_OP_NOWCC			(0x1) /* don't collect v3 wcc data */
 #define	EXPORT_OP_NOSUBTREECHK		(0x2) /* no subtree checking */
 #define	EXPORT_OP_CLOSE_BEFORE_UNLINK	(0x4) /* close files before unlink */
+#define EXPORT_OP_REMOTE_FS		(0x8) /* Filesystem is remote */
 	unsigned long	flags;
 };
 
Signature · 1 line
2.43.0
author maintainer
#105 lore raw

PATCH 105/770 nfsd: Record NFSv4 pre/post-op attributes as non-atomic

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Trond Myklebust <[email protected]>

[ Upstream commit 716a8bc7f706eeef80ab42c99d9f210eda845c81 ]

For the case of NFSv4, specify to the client that the pre/post-op attributes were not recorded atomically with the main operation.

---
 fs/nfs/export.c          | 3 ++-
 fs/nfsd/nfsfh.c          | 4 ++++
 fs/nfsd/nfsfh.h          | 5 +++++
 fs/nfsd/xdr4.h           | 2 +-
 include/linux/exportfs.h | 3 +++
 5 files changed, 15 insertions(+), 2 deletions(-)
fs/nfs/export.c +2 -1
index 48b879cfe6e3b..7412bb164fa77 100644
@@ -172,5 +172,6 @@ const struct export_operations nfs_export_ops = {
 	.fh_to_dentry = nfs_fh_to_dentry,
 	.get_parent = nfs_get_parent,
 	.flags = EXPORT_OP_NOWCC|EXPORT_OP_NOSUBTREECHK|
-		EXPORT_OP_CLOSE_BEFORE_UNLINK|EXPORT_OP_REMOTE_FS,
+		EXPORT_OP_CLOSE_BEFORE_UNLINK|EXPORT_OP_REMOTE_FS|
+		EXPORT_OP_NOATOMIC_ATTR,
 };
fs/nfsd/nfsfh.c +4 -0
index e80a7525561d0..66f2ef67792a7 100644
@@ -301,6 +301,10 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp)
 	fhp->fh_export = exp;
 
 	switch (rqstp->rq_vers) {
+	case 4:
+		if (dentry->d_sb->s_export_op->flags & EXPORT_OP_NOATOMIC_ATTR)
+			fhp->fh_no_atomic_attr = true;
+		break;
 	case 3:
 		if (dentry->d_sb->s_export_op->flags & EXPORT_OP_NOWCC)
 			fhp->fh_no_wcc = true;
fs/nfsd/nfsfh.h +5 -0
index 347d10aa62655..cb20c2cd34695 100644
@@ -36,6 +36,11 @@ typedef struct svc_fh {
 	bool			fh_locked;	/* inode locked by us */
 	bool			fh_want_write;	/* remount protection taken */
 	bool			fh_no_wcc;	/* no wcc data needed */
+	bool			fh_no_atomic_attr;
+						/*
+						 * wcc data is not atomic with
+						 * operation
+						 */
 	int			fh_flags;	/* FH flags */
 #ifdef CONFIG_NFSD_V3
 	bool			fh_post_saved;	/* post-op attrs saved */
fs/nfsd/xdr4.h +1 -1
index b4556e86e97c3..a60ff5ce1a375 100644
@@ -748,7 +748,7 @@ static inline void
 set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
 {
 	BUG_ON(!fhp->fh_pre_saved);
-	cinfo->atomic = (u32)fhp->fh_post_saved;
+	cinfo->atomic = (u32)(fhp->fh_post_saved && !fhp->fh_no_atomic_attr);
 
 	cinfo->before_change = fhp->fh_pre_change;
 	cinfo->after_change = fhp->fh_post_change;
include/linux/exportfs.h +3 -0
index d93e8a6737bb0..9f4d4bcbf251d 100644
@@ -217,6 +217,9 @@ struct export_operations {
 #define	EXPORT_OP_NOSUBTREECHK		(0x2) /* no subtree checking */
 #define	EXPORT_OP_CLOSE_BEFORE_UNLINK	(0x4) /* close files before unlink */
 #define EXPORT_OP_REMOTE_FS		(0x8) /* Filesystem is remote */
+#define EXPORT_OP_NOATOMIC_ATTR		(0x10) /* Filesystem cannot supply
+						  atomic attribute updates
+						*/
 	unsigned long	flags;
 };
 
Signature · 1 line
2.43.0
author maintainer
#106 lore raw

PATCH 106/770 exec: Dont open code get_close_on_exec

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric W. Biederman <[email protected]>

[ Upstream commit 878f12dbb8f514799d126544d59be4d2675caac3 ]

Al Viro pointed out that using the phrase "close_on_exec(fd, rcu_dereference_raw(current->files->fdt))" instead of wrapping it in rcu_read_lock(), rcu_read_unlock() is a very questionable optimization[1].

Once wrapped with rcu_read_lock()/rcu_read_unlock() that phrase becomes equivalent the helper function get_close_on_exec so simplify the code and make it more robust by simply using get_close_on_exec.

[1] https://lkml.kernel.org/r/[email protected]

---
 fs/exec.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
fs/exec.c +1 -2
index ebe9011955b9b..fb8813cc532d0 100644
@@ -1821,8 +1821,7 @@ static int bprm_execve(struct linux_binprm *bprm,
 	 * inaccessible after exec. Relies on having exclusive access to
 	 * current->files (due to unshare_files above).
 	 */
-	if (bprm->fdpath &&
-	    close_on_exec(fd, rcu_dereference_raw(current->files->fdt)))
+	if (bprm->fdpath && get_close_on_exec(fd))
 		bprm->interp_flags |= BINPRM_FLAGS_PATH_INACCESSIBLE;
 
 	/* Set the unchanging part of bprm->cred */
Signature · 1 line
2.43.0
author maintainer
#107 lore raw

PATCH 107/770 exec: Move unshare_files to fix posix file locking during exec

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric W. Biederman <[email protected]>

[ Upstream commit b6043501289ebf169ae19b810a882d517377302f ]

Many moons ago the binfmts were doing some very questionable things with file descriptors and an unsharing of the file descriptor table was added to make things better[1][2]. The helper steal_lockss was added to avoid breaking the userspace programs[3][4][6].

Unfortunately it turned out that steal_locks did not work for network file systems[5], so it was removed to see if anyone would complain[7][8]. It was thought at the time that NPTL would not be affected as the unshare_files happened after the other threads were killed[8]. Unfortunately because there was an unshare_files in binfmt_elf.c before the threads were killed this analysis was incorrect.

This unshare_files in binfmt_elf.c resulted in the unshares_files happening whenever threads were present. Which led to unshare_files being moved to the start of do_execve[9].

Later the problems were rediscovered and the suggested approach was to readd steal_locks under a different name[10]. I happened to be reviewing patches and I noticed that this approach was a step backwards[11].

I proposed simply moving unshare_files[12] and it was pointed out that moving unshare_files without auditing the code was also unsafe[13].

There were then several attempts to solve this[14][15][16] and I even posted this set of changes[17]. Unfortunately because auditing all of execve is time consuming this change did not make it in at the time.

Well now that I am cleaning up exec I have made the time to read through all of the binfmts and the only playing with file descriptors is either the security modules closing them in security_bprm_committing_creds or is in the generic code in fs/exec.c. None of it happens before begin_new_exec is called.

So move unshare_files into begin_new_exec, after the point of no return. If memory is very very very low and the application calling exec is sharing file descriptor tables between processes we might fail past the point of no return. Which is unfortunate but no different than any of the other places where we allocate memory after the point of no return.

This movement allows another process that shares the file table, or another thread of the same process and that closes files or changes their close on exec behavior and races with execve to cause some unexpected things to happen. There is only one time of check to time of use race and it is just there so that execve fails instead of an interpreter failing when it tries to open the file it is supposed
to be interpreting. Failing later if userspace is being silly is
not a problem.

With this change it the following discription from the removal of steal_locks[8] finally becomes true.

Apps using NPTL are not affected, since all other threads are killed before execve.

Apps using LinuxThreads are only affected if they

- have multiple threads during exec (LinuxThreads doesn't kill other threads, the app may do it with pthread_kill_other_threads_np())
- rely on POSIX locks being inherited across exec

Both conditions are documented, but not their interaction.

Apps using clone() natively are affected if they

- use clone(CLONE_FILES)
- rely on POSIX locks being inherited across exec

I have investigated some paths to make it possible to solve this without moving unshare_files but they all look more complicated[18].

History-tree: git://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git
[1] 02cda956de0b ("[PATCH] unshare_files"
[2] 04e9bcb4d106 ("[PATCH] use new unshare_files helper")
[3] 088f5d7244de ("[PATCH] add steal_locks helper")
[4] 02c541ec8ffa ("[PATCH] use new steal_locks helper")
[5] https://lkml.kernel.org/r/[email protected]
[6] https://lkml.kernel.org/r/[email protected]
[7] https://lkml.kernel.org/r/[email protected]
[8] c89681ed7d0e ("[PATCH] remove steal_locks()")
[9] fd8328be874f ("[PATCH] sanitize handling of shared descriptor tables in failing execve()")
[10] https://lkml.kernel.org/r/[email protected]
[11] https://lkml.kernel.org/r/[email protected]
[12] https://lkml.kernel.org/r/[email protected]
[13] https://lkml.kernel.org/r/[email protected]
[14] https://lkml.kernel.org/r/[email protected]
[15] https://lkml.kernel.org/r/[email protected]
[16] https://lkml.kernel.org/r/[email protected]
[17] https://lkml.kernel.org/r/[email protected]
[18] https://lkml.kernel.org/r/[email protected]

v1: https://lkml.kernel.org/r/[email protected]

---
 fs/exec.c | 29 +++++++++++++++--------------
 1 file changed, 15 insertions(+), 14 deletions(-)
fs/exec.c +15 -14
index fb8813cc532d0..42952cf90f4af 100644
@@ -1245,6 +1245,7 @@ void __set_task_comm(struct task_struct *tsk, const char *buf, bool exec)
 int begin_new_exec(struct linux_binprm * bprm)
 {
 	struct task_struct *me = current;
+	struct files_struct *displaced;
 	int retval;
 
 	/* Once we are committed compute the creds */
@@ -1264,6 +1265,13 @@ int begin_new_exec(struct linux_binprm * bprm)
 	if (retval)
 		goto out;
 
+	/* Ensure the files table is not shared. */
+	retval = unshare_files(&displaced);
+	if (retval)
+		goto out;
+	if (displaced)
+		put_files_struct(displaced);
+
 	/*
 	 * Must be called _before_ exec_mmap() as bprm->mm is
 	 * not visibile until then. This also enables the update
@@ -1789,7 +1797,6 @@ static int bprm_execve(struct linux_binprm *bprm,
 		       int fd, struct filename *filename, int flags)
 {
 	struct file *file;
-	struct files_struct *displaced;
 	int retval;
 
 	/*
@@ -1797,13 +1804,9 @@ static int bprm_execve(struct linux_binprm *bprm,
 	 */
 	io_uring_task_cancel();
 
-	retval = unshare_files(&displaced);
-	if (retval)
-		return retval;
-
 	retval = prepare_bprm_creds(bprm);
 	if (retval)
-		goto out_files;
+		return retval;
 
 	check_unsafe_exec(bprm);
 	current->in_execve = 1;
@@ -1818,8 +1821,12 @@ static int bprm_execve(struct linux_binprm *bprm,
 	bprm->file = file;
 	/*
 	 * Record that a name derived from an O_CLOEXEC fd will be
-	 * inaccessible after exec. Relies on having exclusive access to
-	 * current->files (due to unshare_files above).
+	 * inaccessible after exec.  This allows the code in exec to
+	 * choose to fail when the executable is not mmaped into the
+	 * interpreter and an open file descriptor is not passed to
+	 * the interpreter.  This makes for a better user experience
+	 * than having the interpreter start and then immediately fail
+	 * when it finds the executable is inaccessible.
 	 */
 	if (bprm->fdpath && get_close_on_exec(fd))
 		bprm->interp_flags |= BINPRM_FLAGS_PATH_INACCESSIBLE;
@@ -1839,8 +1846,6 @@ static int bprm_execve(struct linux_binprm *bprm,
 	rseq_execve(current);
 	acct_update_integrals(current);
 	task_numa_free(current, false);
-	if (displaced)
-		put_files_struct(displaced);
 	return retval;
 
 out:
@@ -1857,10 +1862,6 @@ static int bprm_execve(struct linux_binprm *bprm,
 	current->fs->in_exec = 0;
 	current->in_execve = 0;
 
-out_files:
-	if (displaced)
-		reset_files_struct(displaced);
-
 	return retval;
 }
 
Signature · 1 line
2.43.0
author maintainer
#108 lore raw

PATCH 108/770 exec: Simplify unshare_files

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric W. Biederman <[email protected]>

[ Upstream commit 1f702603e7125a390b5cdf5ce00539781cfcc86a ]

Now that exec no longer needs to return the unshared files to their previous value there is no reason to return displaced.

Instead when unshare_fd creates a copy of the file table, call put_files_struct before returning from unshare_files.

v1: https://lkml.kernel.org/r/[email protected]

---
 fs/coredump.c           |  5 +----
 fs/exec.c               |  5 +----
 include/linux/fdtable.h |  2 +-
 kernel/fork.c           | 12 ++++++------
 4 files changed, 9 insertions(+), 15 deletions(-)
fs/coredump.c +1 -4
index 9d91e831ed0b2..7b085975ea163 100644
@@ -590,7 +590,6 @@ void do_coredump(const kernel_siginfo_t *siginfo)
 	int ispipe;
 	size_t *argv = NULL;
 	int argc = 0;
-	struct files_struct *displaced;
 	/* require nonrelative corefile path and be extra careful */
 	bool need_suid_safe = false;
 	bool core_dumped = false;
@@ -797,11 +796,9 @@ void do_coredump(const kernel_siginfo_t *siginfo)
 	}
 
 	/* get us an unshared descriptor table; almost always a no-op */
-	retval = unshare_files(&displaced);
+	retval = unshare_files();
 	if (retval)
 		goto close_fail;
-	if (displaced)
-		put_files_struct(displaced);
 	if (!dump_interrupted()) {
 		/*
 		 * umh disabled with CONFIG_STATIC_USERMODEHELPER_PATH="" would
fs/exec.c +1 -4
index 42952cf90f4af..d5c8f085235bc 100644
@@ -1245,7 +1245,6 @@ void __set_task_comm(struct task_struct *tsk, const char *buf, bool exec)
 int begin_new_exec(struct linux_binprm * bprm)
 {
 	struct task_struct *me = current;
-	struct files_struct *displaced;
 	int retval;
 
 	/* Once we are committed compute the creds */
@@ -1266,11 +1265,9 @@ int begin_new_exec(struct linux_binprm * bprm)
 		goto out;
 
 	/* Ensure the files table is not shared. */
-	retval = unshare_files(&displaced);
+	retval = unshare_files();
 	if (retval)
 		goto out;
-	if (displaced)
-		put_files_struct(displaced);
 
 	/*
 	 * Must be called _before_ exec_mmap() as bprm->mm is
include/linux/fdtable.h +1 -1
index f1a99d3e55707..b32ab2163dc2d 100644
@@ -109,7 +109,7 @@ struct task_struct;
 struct files_struct *get_files_struct(struct task_struct *);
 void put_files_struct(struct files_struct *fs);
 void reset_files_struct(struct files_struct *);
-int unshare_files(struct files_struct **);
+int unshare_files(void);
 struct files_struct *dup_fd(struct files_struct *, unsigned, int *) __latent_entropy;
 void do_close_on_exec(struct files_struct *);
 int iterate_fd(struct files_struct *, unsigned,
kernel/fork.c +6 -6
index 633b0af1d1a73..8b8a5a172b158 100644
@@ -3077,21 +3077,21 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
  *	the exec layer of the kernel.
  */
 
-int unshare_files(struct files_struct **displaced)
+int unshare_files(void)
 {
 	struct task_struct *task = current;
-	struct files_struct *copy = NULL;
+	struct files_struct *old, *copy = NULL;
 	int error;
 
 	error = unshare_fd(CLONE_FILES, NR_OPEN_MAX, &copy);
-	if (error || !copy) {
-		*displaced = NULL;
+	if (error || !copy)
 		return error;
-	}
-	*displaced = task->files;
+
+	old = task->files;
 	task_lock(task);
 	task->files = copy;
 	task_unlock(task);
+	put_files_struct(old);
 	return 0;
 }
 
Signature · 1 line
2.43.0
author maintainer
#109 lore raw

PATCH 109/770 exec: Remove reset_files_struct

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric W. Biederman <[email protected]>

[ Upstream commit 950db38ff2c01b7aabbd7ab4a50b7992750fa63d ]

Now that exec no longer needs to restore the previous value of current->files on error there are no more callers of reset_files_struct so remove it.

v1: https://lkml.kernel.org/r/[email protected]

---
 fs/file.c               | 12 ------------
 include/linux/fdtable.h |  1 -
 2 files changed, 13 deletions(-)
fs/file.c +0 -12
index d6bc73960e4ac..5065252bb474e 100644
@@ -466,18 +466,6 @@ void put_files_struct(struct files_struct *files)
 	}
 }
 
-void reset_files_struct(struct files_struct *files)
-{
-	struct task_struct *tsk = current;
-	struct files_struct *old;
-
-	old = tsk->files;
-	task_lock(tsk);
-	tsk->files = files;
-	task_unlock(tsk);
-	put_files_struct(old);
-}
-
 void exit_files(struct task_struct *tsk)
 {
 	struct files_struct * files = tsk->files;
include/linux/fdtable.h +0 -1
index b32ab2163dc2d..c0ca6fb3f0f95 100644
@@ -108,7 +108,6 @@ struct task_struct;
 
 struct files_struct *get_files_struct(struct task_struct *);
 void put_files_struct(struct files_struct *fs);
-void reset_files_struct(struct files_struct *);
 int unshare_files(void);
 struct files_struct *dup_fd(struct files_struct *, unsigned, int *) __latent_entropy;
 void do_close_on_exec(struct files_struct *);
Signature · 1 line
2.43.0
author maintainer
#110 lore raw

PATCH 110/770 kcmp: In kcmp_epoll_target use fget_task

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric W. Biederman <[email protected]>

[ Upstream commit f43c283a89a7dc531a47d4b1e001503cf3dc3234 ]

Use the helper fget_task and simplify the code.

As well as simplifying the code this removes one unnecessary increment of struct files_struct. This unnecessary increment of files_struct.count can result in exec unnecessarily unsharing files_struct and breaking posix locks, and it can result in fget_light having to fallback to fget reducing performance.

v1: https://lkml.kernel.org/r/[email protected]

---
 kernel/kcmp.c | 20 ++++----------------
 1 file changed, 4 insertions(+), 16 deletions(-)
kernel/kcmp.c +4 -16
index c0d2ad9b4705d..bd6f9edf98fd3 100644
@@ -107,7 +107,6 @@ static int kcmp_epoll_target(struct task_struct *task1,
 {
 	struct file *filp, *filp_epoll, *filp_tgt;
 	struct kcmp_epoll_slot slot;
-	struct files_struct *files;
 
 	if (copy_from_user(&slot, uslot, sizeof(slot)))
 		return -EFAULT;
@@ -116,23 +115,12 @@ static int kcmp_epoll_target(struct task_struct *task1,
 	if (!filp)
 		return -EBADF;
 
-	files = get_files_struct(task2);
-	if (!files)
+	filp_epoll = fget_task(task2, slot.efd);
+	if (!filp_epoll)
 		return -EBADF;
 
-	spin_lock(&files->file_lock);
-	filp_epoll = fcheck_files(files, slot.efd);
-	if (filp_epoll)
-		get_file(filp_epoll);
-	else
-		filp_tgt = ERR_PTR(-EBADF);
-	spin_unlock(&files->file_lock);
-	put_files_struct(files);
-
-	if (filp_epoll) {
-		filp_tgt = get_epoll_tfile_raw_ptr(filp_epoll, slot.tfd, slot.toff);
-		fput(filp_epoll);
-	}
+	filp_tgt = get_epoll_tfile_raw_ptr(filp_epoll, slot.tfd, slot.toff);
+	fput(filp_epoll);
 
 	if (IS_ERR(filp_tgt))
 		return PTR_ERR(filp_tgt);
Signature · 1 line
2.43.0
author maintainer
#111 lore raw

PATCH 111/770 bpf: In bpf_task_fd_query use fget_task

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric W. Biederman <[email protected]>

[ Upstream commit b48845af0152d790a54b8ab78cc2b7c07485fc98 ]

Use the helper fget_task to simplify bpf_task_fd_query.

As well as simplifying the code this removes one unnecessary increment of struct files_struct. This unnecessary increment of files_struct.count can result in exec unnecessarily unsharing files_struct and breaking posix locks, and it can result in fget_light having to fallback to fget reducing performance.

This simplification comes from the observation that none of the callers of get_files_struct actually need to call get_files_struct that was made when discussing[1] exec and posix file locks.

[1] https://lkml.kernel.org/r/[email protected]

v1: https://lkml.kernel.org/r/[email protected]

---
 kernel/bpf/syscall.c | 20 +++-----------------
 1 file changed, 3 insertions(+), 17 deletions(-)
kernel/bpf/syscall.c +3 -17
index e1bee8cd34044..fbe7f8e2b022c 100644
@@ -3929,7 +3929,6 @@ static int bpf_task_fd_query(const union bpf_attr *attr,
 	pid_t pid = attr->task_fd_query.pid;
 	u32 fd = attr->task_fd_query.fd;
 	const struct perf_event *event;
-	struct files_struct *files;
 	struct task_struct *task;
 	struct file *file;
 	int err;
@@ -3949,23 +3948,11 @@ static int bpf_task_fd_query(const union bpf_attr *attr,
 	if (!task)
 		return -ENOENT;
 
-	files = get_files_struct(task);
-	put_task_struct(task);
-	if (!files)
-		return -ENOENT;
-
 	err = 0;
-	spin_lock(&files->file_lock);
-	file = fcheck_files(files, fd);
+	file = fget_task(task, fd);
+	put_task_struct(task);
 	if (!file)
-		err = -EBADF;
-	else
-		get_file(file);
-	spin_unlock(&files->file_lock);
-	put_files_struct(files);
-
-	if (err)
-		goto out;
+		return -EBADF;
 
 	if (file->f_op == &bpf_link_fops) {
 		struct bpf_link *link = file->private_data;
@@ -4005,7 +3992,6 @@ static int bpf_task_fd_query(const union bpf_attr *attr,
 	err = -ENOTSUPP;
 put_file:
 	fput(file);
-out:
 	return err;
 }
 
Signature · 1 line
2.43.0
author maintainer
#112 lore raw

PATCH 112/770 proc/fd: In proc_fd_link use fget_task

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric W. Biederman <[email protected]>

[ Upstream commit 439be32656035d3239fd56f9b83353ec06cb3b45 ]

When discussing[1] exec and posix file locks it was realized that none of the callers of get_files_struct fundamentally needed to call get_files_struct, and that by switching them to helper functions instead it will both simplify their code and remove unnecessary increments of files_struct.count. Those unnecessary increments can result in exec unnecessarily unsharing files_struct which breaking posix locks, and it can result in fget_light having to fallback to fget reducing system performance.

Simplifying proc_fd_link is a little bit tricky. It is necessary to
know that there is a reference to fd_f ile while path_get is running.
This reference can either be guaranteed to exist either by locking the fdtable as the code currently does or by taking a reference on the file in question.

Use fget_task to remove the need for get_files_struct and to take a reference to file in question.

[1] https://lkml.kernel.org/r/[email protected]

v1: https://lkml.kernel.org/r/[email protected]

---
 fs/proc/fd.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)
fs/proc/fd.c +3 -10
index 81882a13212d3..d58960f6ee524 100644
@@ -146,29 +146,22 @@ static const struct dentry_operations tid_fd_dentry_operations = {
 
 static int proc_fd_link(struct dentry *dentry, struct path *path)
 {
-	struct files_struct *files = NULL;
 	struct task_struct *task;
 	int ret = -ENOENT;
 
 	task = get_proc_task(d_inode(dentry));
 	if (task) {
-		files = get_files_struct(task);
-		put_task_struct(task);
-	}
-
-	if (files) {
 		unsigned int fd = proc_fd(d_inode(dentry));
 		struct file *fd_file;
 
-		spin_lock(&files->file_lock);
-		fd_file = fcheck_files(files, fd);
+		fd_file = fget_task(task, fd);
 		if (fd_file) {
 			*path = fd_file->f_path;
 			path_get(&fd_file->f_path);
 			ret = 0;
+			fput(fd_file);
 		}
-		spin_unlock(&files->file_lock);
-		put_files_struct(files);
+		put_task_struct(task);
 	}
 
 	return ret;
Signature · 1 line
2.43.0
author maintainer
#113 lore raw

PATCH 113/770 Revert "fget: clarify and improve __fget_files() implementation"

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

Temporarily revert commit 0849f83e4782 ("fget: clarify and improve __fget_files() implementation") to enable subsequent upstream commits to apply and build cleanly.

Stable-dep-of: bebf684bf330 ("file: Rename __fcheck_files to files_lookup_fd_raw")

---
 fs/file.c | 72 +++++++++++++------------------------------------------
 1 file changed, 16 insertions(+), 56 deletions(-)
fs/file.c +16 -56
index 5065252bb474e..fea693acc065e 100644
@@ -849,68 +849,28 @@ void do_close_on_exec(struct files_struct *files)
 	spin_unlock(&files->file_lock);
 }
 
-static inline struct file *__fget_files_rcu(struct files_struct *files,
-	unsigned int fd, fmode_t mask, unsigned int refs)
-{
-	for (;;) {
-		struct file *file;
-		struct fdtable *fdt = rcu_dereference_raw(files->fdt);
-		struct file __rcu **fdentry;
-
-		if (unlikely(fd >= fdt->max_fds))
-			return NULL;
-
-		fdentry = fdt->fd + array_index_nospec(fd, fdt->max_fds);
-		file = rcu_dereference_raw(*fdentry);
-		if (unlikely(!file))
-			return NULL;
-
-		if (unlikely(file->f_mode & mask))
-			return NULL;
-
-		/*
-		 * Ok, we have a file pointer. However, because we do
-		 * this all locklessly under RCU, we may be racing with
-		 * that file being closed.
-		 *
-		 * Such a race can take two forms:
-		 *
-		 *  (a) the file ref already went down to zero,
-		 *      and get_file_rcu_many() fails. Just try
-		 *      again:
-		 */
-		if (unlikely(!get_file_rcu_many(file, refs)))
-			continue;
-
-		/*
-		 *  (b) the file table entry has changed under us.
-		 *       Note that we don't need to re-check the 'fdt->fd'
-		 *       pointer having changed, because it always goes
-		 *       hand-in-hand with 'fdt'.
-		 *
-		 * If so, we need to put our refs and try again.
-		 */
-		if (unlikely(rcu_dereference_raw(files->fdt) != fdt) ||
-		    unlikely(rcu_dereference_raw(*fdentry) != file)) {
-			fput_many(file, refs);
-			continue;
-		}
-
-		/*
-		 * Ok, we have a ref to the file, and checked that it
-		 * still exists.
-		 */
-		return file;
-	}
-}
-
 static struct file *__fget_files(struct files_struct *files, unsigned int fd,
 				 fmode_t mask, unsigned int refs)
 {
 	struct file *file;
 
 	rcu_read_lock();
-	file = __fget_files_rcu(files, fd, mask, refs);
+loop:
+	file = fcheck_files(files, fd);
+	if (file) {
+		/* File object ref couldn't be taken.
+		 * dup2() atomicity guarantee is the reason
+		 * we loop to catch the new file (or NULL pointer)
+		 */
+		if (file->f_mode & mask)
+			file = NULL;
+		else if (!get_file_rcu_many(file, refs))
+			goto loop;
+		else if (__fcheck_files(files, fd) != file) {
+			fput_many(file, refs);
+			goto loop;
+		}
+	}
 	rcu_read_unlock();
 
 	return file;
Signature · 1 line
2.43.0
author maintainer
#114 lore raw

PATCH 114/770 file: Rename __fcheck_files to files_lookup_fd_raw

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric W. Biederman <[email protected]>

[ Upstream commit bebf684bf330915e6c96313ad7db89a5480fc9c2 ]

The function fcheck despite it's comment is poorly named as it has no callers that only check it's return value. All of fcheck's callers use the returned file descriptor. The same is true for fcheck_files and __fcheck_files.

A new less confusing name is needed. In addition the names of these functions are confusing as they do not report the kind of locks that are needed to be held when these functions are called making error prone to use them.

To remedy this I am making the base functio name lookup_fd and will and prefixes and sufficies to indicate the rest of the context.

Name the function (previously called __fcheck_files) that proceeds from a struct files_struct, looks up the struct file of a file descriptor, and requires it's callers to verify all of the appropriate locks are held files_lookup_fd_raw.

The need for better names became apparent in the last round of discussion of this set of changes[1].

[1] https://lkml.kernel.org/r/CAHk-=wj8BQbgJFLa+J0e=iT-1qpmCRTbPAJ8gd6MJQ=kbRPqyQ@mail.gmail.com

---
 fs/file.c               | 4 ++--
 include/linux/fdtable.h | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)
fs/file.c +2 -2
index fea693acc065e..eb1e2b7220ac6 100644
@@ -866,7 +866,7 @@ static struct file *__fget_files(struct files_struct *files, unsigned int fd,
 			file = NULL;
 		else if (!get_file_rcu_many(file, refs))
 			goto loop;
-		else if (__fcheck_files(files, fd) != file) {
+		else if (files_lookup_fd_raw(files, fd) != file) {
 			fput_many(file, refs);
 			goto loop;
 		}
@@ -933,7 +933,7 @@ static unsigned long __fget_light(unsigned int fd, fmode_t mask)
 	struct file *file;
 
 	if (atomic_read(&files->count) == 1) {
-		file = __fcheck_files(files, fd);
+		file = files_lookup_fd_raw(files, fd);
 		if (!file || unlikely(file->f_mode & mask))
 			return 0;
 		return (unsigned long)file;
include/linux/fdtable.h +2 -2
index c0ca6fb3f0f95..10e75b4c30a43 100644
@@ -80,7 +80,7 @@ struct dentry;
 /*
  * The caller must ensure that fd table isn't shared or hold rcu or file lock
  */
-static inline struct file *__fcheck_files(struct files_struct *files, unsigned int fd)
+static inline struct file *files_lookup_fd_raw(struct files_struct *files, unsigned int fd)
 {
 	struct fdtable *fdt = rcu_dereference_raw(files->fdt);
 
@@ -96,7 +96,7 @@ static inline struct file *fcheck_files(struct files_struct *files, unsigned int
 	RCU_LOCKDEP_WARN(!rcu_read_lock_held() &&
 			   !lockdep_is_held(&files->file_lock),
 			   "suspicious rcu_dereference_check() usage");
-	return __fcheck_files(files, fd);
+	return files_lookup_fd_raw(files, fd);
 }
 
 /*
Signature · 1 line
2.43.0
author maintainer
#115 lore raw

PATCH 115/770 file: Factor files_lookup_fd_locked out of fcheck_files

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric W. Biederman <[email protected]>

[ Upstream commit 120ce2b0cd52abe73e8b16c23461eb14df5a87d8 ]

To make it easy to tell where files->file_lock protection is being used when looking up a file create files_lookup_fd_locked. Only allow this function to be called with the file_lock held.

Update the callers of fcheck and fcheck_files that are called with the files->file_lock held to call files_lookup_fd_locked instead.

Hopefully this makes it easier to quickly understand what is going on.

The need for better names became apparent in the last round of discussion of this set of changes[1].

[1] https://lkml.kernel.org/r/CAHk-=wj8BQbgJFLa+J0e=iT-1qpmCRTbPAJ8gd6MJQ=kbRPqyQ@mail.gmail.com

---
 fs/file.c               |  2 +-
 fs/locks.c              | 14 ++++++++------
 fs/proc/fd.c            |  2 +-
 include/linux/fdtable.h |  7 +++++++
 4 files changed, 17 insertions(+), 8 deletions(-)
fs/file.c +1 -1
index eb1e2b7220ac6..6a6b03ce4ad69 100644
@@ -1158,7 +1158,7 @@ static int ksys_dup3(unsigned int oldfd, unsigned int newfd, int flags)
 
 	spin_lock(&files->file_lock);
 	err = expand_files(files, newfd);
-	file = fcheck(oldfd);
+	file = files_lookup_fd_locked(files, oldfd);
 	if (unlikely(!file))
 		goto Ebadf;
 	if (unlikely(err < 0)) {
fs/locks.c +8 -6
index cbb5701ce9f37..873f97504bddf 100644
@@ -2536,14 +2536,15 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
 	 */
 	if (!error && file_lock->fl_type != F_UNLCK &&
 	    !(file_lock->fl_flags & FL_OFDLCK)) {
+		struct files_struct *files = current->files;
 		/*
 		 * We need that spin_lock here - it prevents reordering between
 		 * update of i_flctx->flc_posix and check for it done in
 		 * close(). rcu_read_lock() wouldn't do.
 		 */
-		spin_lock(&current->files->file_lock);
-		f = fcheck(fd);
-		spin_unlock(&current->files->file_lock);
+		spin_lock(&files->file_lock);
+		f = files_lookup_fd_locked(files, fd);
+		spin_unlock(&files->file_lock);
 		if (f != filp) {
 			file_lock->fl_type = F_UNLCK;
 			error = do_lock_file_wait(filp, cmd, file_lock);
@@ -2667,14 +2668,15 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
 	 */
 	if (!error && file_lock->fl_type != F_UNLCK &&
 	    !(file_lock->fl_flags & FL_OFDLCK)) {
+		struct files_struct *files = current->files;
 		/*
 		 * We need that spin_lock here - it prevents reordering between
 		 * update of i_flctx->flc_posix and check for it done in
 		 * close(). rcu_read_lock() wouldn't do.
 		 */
-		spin_lock(&current->files->file_lock);
-		f = fcheck(fd);
-		spin_unlock(&current->files->file_lock);
+		spin_lock(&files->file_lock);
+		f = files_lookup_fd_locked(files, fd);
+		spin_unlock(&files->file_lock);
 		if (f != filp) {
 			file_lock->fl_type = F_UNLCK;
 			error = do_lock_file_wait(filp, cmd, file_lock);
fs/proc/fd.c +1 -1
index d58960f6ee524..2cca9bca3b3a3 100644
@@ -35,7 +35,7 @@ static int seq_show(struct seq_file *m, void *v)
 		unsigned int fd = proc_fd(m->private);
 
 		spin_lock(&files->file_lock);
-		file = fcheck_files(files, fd);
+		file = files_lookup_fd_locked(files, fd);
 		if (file) {
 			struct fdtable *fdt = files_fdtable(files);
 
include/linux/fdtable.h +7 -0
index 10e75b4c30a43..87be704268d26 100644
@@ -91,6 +91,13 @@ static inline struct file *files_lookup_fd_raw(struct files_struct *files, unsig
 	return NULL;
 }
 
+static inline struct file *files_lookup_fd_locked(struct files_struct *files, unsigned int fd)
+{
+	RCU_LOCKDEP_WARN(!lockdep_is_held(&files->file_lock),
+			   "suspicious rcu_dereference_check() usage");
+	return files_lookup_fd_raw(files, fd);
+}
+
 static inline struct file *fcheck_files(struct files_struct *files, unsigned int fd)
 {
 	RCU_LOCKDEP_WARN(!rcu_read_lock_held() &&
Signature · 1 line
2.43.0
author maintainer
#116 lore raw

PATCH 116/770 file: Replace fcheck_files with files_lookup_fd_rcu

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric W. Biederman <[email protected]>

[ Upstream commit f36c2943274199cb8aef32ac96531ffb7c4b43d0 ]

This change renames fcheck_files to files_lookup_fd_rcu. All of the remaining callers take the rcu_read_lock before calling this function so the _rcu suffix is appropriate. This change also tightens up the debug check to verify that all callers hold the rcu_read_lock.

All callers that used to call files_check with the files->file_lock held have now been changed to call files_lookup_fd_locked.

This change of name has helped remind me of which locks and which guarantees are in place helping me to catch bugs later in the patchset.

The need for better names became apparent in the last round of discussion of this set of changes[1].

[1] https://lkml.kernel.org/r/CAHk-=wj8BQbgJFLa+J0e=iT-1qpmCRTbPAJ8gd6MJQ=kbRPqyQ@mail.gmail.com

---
 Documentation/filesystems/files.rst | 6 +++---
 fs/file.c                           | 4 ++--
 fs/proc/fd.c                        | 4 ++--
 include/linux/fdtable.h             | 7 +++----
 kernel/bpf/task_iter.c              | 2 +-
 kernel/kcmp.c                       | 2 +-
 6 files changed, 12 insertions(+), 13 deletions(-)
Documentation/filesystems/files.rst +3 -3
index cbf8e57376bf6..ea75acdb632c0 100644
@@ -62,7 +62,7 @@ the fdtable structure -
    be held.
 
 4. To look up the file structure given an fd, a reader
-   must use either fcheck() or fcheck_files() APIs. These
+   must use either fcheck() or files_lookup_fd_rcu() APIs. These
    take care of barrier requirements due to lock-free lookup.
 
    An example::
@@ -84,7 +84,7 @@ the fdtable structure -
    on ->f_count::
 
 	rcu_read_lock();
-	file = fcheck_files(files, fd);
+	file = files_lookup_fd_rcu(files, fd);
 	if (file) {
 		if (atomic_long_inc_not_zero(&file->f_count))
 			*fput_needed = 1;
@@ -104,7 +104,7 @@ the fdtable structure -
    lock-free, they must be installed using rcu_assign_pointer()
    API. If they are looked up lock-free, rcu_dereference()
    must be used. However it is advisable to use files_fdtable()
-   and fcheck()/fcheck_files() which take care of these issues.
+   and fcheck()/files_lookup_fd_rcu() which take care of these issues.
 
 7. While updating, the fdtable pointer must be looked up while
    holding files->file_lock. If ->file_lock is dropped, then
fs/file.c +2 -2
index 6a6b03ce4ad69..6149f75a18a66 100644
@@ -856,7 +856,7 @@ static struct file *__fget_files(struct files_struct *files, unsigned int fd,
 
 	rcu_read_lock();
 loop:
-	file = fcheck_files(files, fd);
+	file = files_lookup_fd_rcu(files, fd);
 	if (file) {
 		/* File object ref couldn't be taken.
 		 * dup2() atomicity guarantee is the reason
@@ -1187,7 +1187,7 @@ SYSCALL_DEFINE2(dup2, unsigned int, oldfd, unsigned int, newfd)
 		int retval = oldfd;
 
 		rcu_read_lock();
-		if (!fcheck_files(files, oldfd))
+		if (!files_lookup_fd_rcu(files, oldfd))
 			retval = -EBADF;
 		rcu_read_unlock();
 		return retval;
fs/proc/fd.c +2 -2
index 2cca9bca3b3a3..3dec44d7c5c5c 100644
@@ -90,7 +90,7 @@ static bool tid_fd_mode(struct task_struct *task, unsigned fd, fmode_t *mode)
 		return false;
 
 	rcu_read_lock();
-	file = fcheck_files(files, fd);
+	file = files_lookup_fd_rcu(files, fd);
 	if (file)
 		*mode = file->f_mode;
 	rcu_read_unlock();
@@ -243,7 +243,7 @@ static int proc_readfd_common(struct file *file, struct dir_context *ctx,
 		char name[10 + 1];
 		unsigned int len;
 
-		f = fcheck_files(files, fd);
+		f = files_lookup_fd_rcu(files, fd);
 		if (!f)
 			continue;
 		data.mode = f->f_mode;
include/linux/fdtable.h +3 -4
index 87be704268d26..a45fa2ef723f5 100644
@@ -98,10 +98,9 @@ static inline struct file *files_lookup_fd_locked(struct files_struct *files, un
 	return files_lookup_fd_raw(files, fd);
 }
 
-static inline struct file *fcheck_files(struct files_struct *files, unsigned int fd)
+static inline struct file *files_lookup_fd_rcu(struct files_struct *files, unsigned int fd)
 {
-	RCU_LOCKDEP_WARN(!rcu_read_lock_held() &&
-			   !lockdep_is_held(&files->file_lock),
+	RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
 			   "suspicious rcu_dereference_check() usage");
 	return files_lookup_fd_raw(files, fd);
 }
@@ -109,7 +108,7 @@ static inline struct file *fcheck_files(struct files_struct *files, unsigned int
 /*
  * Check whether the specified fd has an open file.
  */
-#define fcheck(fd)	fcheck_files(current->files, fd)
+#define fcheck(fd)	files_lookup_fd_rcu(current->files, fd)
 
 struct task_struct;
 
kernel/bpf/task_iter.c +1 -1
index f3d3a562a802a..762b4d7c37795 100644
@@ -185,7 +185,7 @@ task_file_seq_get_next(struct bpf_iter_seq_task_file_info *info)
 	for (; curr_fd < max_fds; curr_fd++) {
 		struct file *f;
 
-		f = fcheck_files(curr_files, curr_fd);
+		f = files_lookup_fd_rcu(curr_files, curr_fd);
 		if (!f)
 			continue;
 		if (!get_file_rcu(f))
kernel/kcmp.c +1 -1
index bd6f9edf98fd3..5b2435e030472 100644
@@ -67,7 +67,7 @@ get_file_raw_ptr(struct task_struct *task, unsigned int idx)
 	rcu_read_lock();
 
 	if (task->files)
-		file = fcheck_files(task->files, idx);
+		file = files_lookup_fd_rcu(task->files, idx);
 
 	rcu_read_unlock();
 	task_unlock(task);
Signature · 1 line
2.43.0
author maintainer
#117 lore raw

PATCH 117/770 file: Rename fcheck lookup_fd_rcu

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric W. Biederman <[email protected]>

[ Upstream commit 460b4f812a9d473d4b39d87d37844f9fc30a9eb3 ]

Also remove the confusing comment about checking if a fd exists. I could not find one instance in the entire kernel that still matches the description or the reason for the name fcheck.

The need for better names became apparent in the last round of discussion of this set of changes[1].

[1] https://lkml.kernel.org/r/CAHk-=wj8BQbgJFLa+J0e=iT-1qpmCRTbPAJ8gd6MJQ=kbRPqyQ@mail.gmail.com

---
 Documentation/filesystems/files.rst          | 6 +++---
 arch/powerpc/platforms/cell/spufs/coredump.c | 2 +-
 fs/notify/dnotify/dnotify.c                  | 2 +-
 include/linux/fdtable.h                      | 8 ++++----
 4 files changed, 9 insertions(+), 9 deletions(-)
Documentation/filesystems/files.rst +3 -3
index ea75acdb632c0..bcf84459917f5 100644
@@ -62,7 +62,7 @@ the fdtable structure -
    be held.
 
 4. To look up the file structure given an fd, a reader
-   must use either fcheck() or files_lookup_fd_rcu() APIs. These
+   must use either lookup_fd_rcu() or files_lookup_fd_rcu() APIs. These
    take care of barrier requirements due to lock-free lookup.
 
    An example::
@@ -70,7 +70,7 @@ the fdtable structure -
 	struct file *file;
 
 	rcu_read_lock();
-	file = fcheck(fd);
+	file = lookup_fd_rcu(fd);
 	if (file) {
 		...
 	}
@@ -104,7 +104,7 @@ the fdtable structure -
    lock-free, they must be installed using rcu_assign_pointer()
    API. If they are looked up lock-free, rcu_dereference()
    must be used. However it is advisable to use files_fdtable()
-   and fcheck()/files_lookup_fd_rcu() which take care of these issues.
+   and lookup_fd_rcu()/files_lookup_fd_rcu() which take care of these issues.
 
 7. While updating, the fdtable pointer must be looked up while
    holding files->file_lock. If ->file_lock is dropped, then
arch/powerpc/platforms/cell/spufs/coredump.c +1 -1
index 026c181a98c5d..60b5583e9eafc 100644
@@ -74,7 +74,7 @@ static struct spu_context *coredump_next_context(int *fd)
 	*fd = n - 1;
 
 	rcu_read_lock();
-	file = fcheck(*fd);
+	file = lookup_fd_rcu(*fd);
 	ctx = SPUFS_I(file_inode(file))->i_ctx;
 	get_spu_context(ctx);
 	rcu_read_unlock();
fs/notify/dnotify/dnotify.c +1 -1
index e45ca6ecba959..e85e13c50d6d4 100644
@@ -327,7 +327,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
 	}
 
 	rcu_read_lock();
-	f = fcheck(fd);
+	f = lookup_fd_rcu(fd);
 	rcu_read_unlock();
 
 	/* if (f != filp) means that we lost a race and another task/thread
include/linux/fdtable.h +4 -4
index a45fa2ef723f5..695306cc5337a 100644
@@ -105,10 +105,10 @@ static inline struct file *files_lookup_fd_rcu(struct files_struct *files, unsig
 	return files_lookup_fd_raw(files, fd);
 }
 
-/*
- * Check whether the specified fd has an open file.
- */
-#define fcheck(fd)	files_lookup_fd_rcu(current->files, fd)
+static inline struct file *lookup_fd_rcu(unsigned int fd)
+{
+	return files_lookup_fd_rcu(current->files, fd);
+}
 
 struct task_struct;
 
Signature · 1 line
2.43.0
author maintainer
#118 lore raw

PATCH 118/770 file: Implement task_lookup_fd_rcu

In reply to Greg Kroah-Hartman

5.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric W. Biederman <[email protected]>

[ Upstream commit 3a879fb38082125cc0d8aa89b70c7f3a7cdf584b ]

As a companion to lookup_fd_rcu implement task_lookup_fd_rcu for querying an arbitrary process about a specific file.

v1: https://lkml.kernel.org/r/20200818103713.aw46m7vprsy4vlve@wittgenstein

---
 fs/file.c               | 15 +++++++++++++++
 include/linux/fdtable.h |  2 ++
 2 files changed, 17 insertions(+)
fs/file.c +15 -0
index 6149f75a18a66..60a3ccba728cd 100644
@@ -911,6 +911,21 @@ struct file *fget_task(struct task_struct *task, unsigned int fd)
 	return file;
 }
 
+struct file *task_lookup_fd_rcu(struct task_struct *task, unsigned int fd)
+{
+	/* Must be called with rcu_read_lock held */
+	struct files_struct *files;
+	struct file *file = NULL;
+
+	task_lock(task);
+	files = task->files;
+	if (files)
+		file = files_lookup_fd_rcu(files, fd);
+	task_unlock(task);
+
+	return file;
+}
+
 /*
  * Lightweight file lookup - no refcnt increment if fd table isn't shared.
  *
include/linux/fdtable.h +2 -0
index 695306cc5337a..a88f68f740677 100644
@@ -110,6 +110,8 @@ static inline struct file *lookup_fd_rcu(unsigned int fd)
 	return files_lookup_fd_rcu(current->files, fd);
 }
 
+struct file *task_lookup_fd_rcu(struct task_struct *task, unsigned int fd);
+
 struct task_struct;
 
 struct files_struct *get_files_struct(struct task_struct *);
Signature · 1 line
2.43.0