mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	Stable bugfixes:
 - Revalidate "." and ".." correctly on open
 - Avoid RCU usage in tracepoints
 - Fix ugly referral attributes
 - Fix a typo in nomigration mount option
 - Revert "NFS: Move the flock open mode check into nfs_flock()"
 
 Features:
 - Implement a stronger send queue accounting system for NFS over RDMA
 - Switch some atomics to the new refcount_t type
 
 Other bugfixes and cleanups:
 - Clean up access mode bits
 - Remove special-case revalidations in nfs_opendir()
 - Improve invalidating NFS over RDMA memory for async operations that time out
 - Handle NFS over RDMA replies with a worqueue
 - Handle NFS over RDMA sends with a workqueue
 - Fix up replaying interrupted requests
 - Remove dead NFS over RDMA definitions
 - Update NFS over RDMA copyright information
 - Be more consistent with bool initialization and comparisons
 - Mark expected switch fall throughs
 - Various sunrpc tracepoint cleanups
 - Fix various OPEN races
 - Fix a typo in nfs_rename()
 - Use common error handling code in nfs_lock_and_join_request()
 - Check that some structures are properly cleaned up during net_exit()
 - Remove net pointer from dprintk()s
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEnZ5MQTpR7cLU7KEp18tUv7ClQOsFAloPWGwACgkQ18tUv7Cl
 QOtMVhAAufCkDxqO2lmDH+0JyYUKMcoOMYtI8s2J1HrbEzTW/dVtI28fPAKEEd4m
 2JjNqnO516Jiv+g3E6eO4uunZRb4IB3AYT6YaTwmBFE+l7tpMdPb1xybOBP02Hji
 Y29kzLXwxxvnoxEqFalzCzV2BeRb2kAw6mayY9FxH6AfiEEQZfmxLCYgVuYa2jTC
 Z/B5E0GxAf28Aj0bIP8lLKbOkFijo851DB88UffEOZQGKUDlAd3GNUSSHb81Rj0N
 4ef7bKoGylkIpZ1PdTChdG1+RKqud02zrmQfmEwXui3eUwhOWy8hrKloNykqR5sj
 pgoDz79euAq4TDVyQKtutnbvVxfCcBeMYAXZhXkZLVcl+39in0kuLj4SxU5AmDhf
 ErnthG4W7jsLMM96kMvSTaoh4uwioviG1KmZfvuvUoMBSwtiX18hFTWtFKRD6x9e
 PNOqBdh8nkKYEFbEO4ksfYaWZJ5AuyFIQiIpj1gm+7sf039oN/zEuPV+jaEJG0oa
 Ef9IqHrQbbCUFYFjpBENr3HjU3igTTaxQ5iq+VYl4zg1pw6m6JTojqZ6qtQzqOYS
 O3N1ygeShsW934z8QcWjtEyeUXIB3JF9vUS3gEBgWPDyCltGXyq4Cq6Lod4s4JCb
 pWGI6wJLX1Fg6nq7cj0S4Or3QBgz2q8ZyBxssamhdvON/Ef5ccI=
 =2Zc1
 -----END PGP SIGNATURE-----
Merge tag 'nfs-for-4.15-1' of git://git.linux-nfs.org/projects/anna/linux-nfs
Pull NFS client updates from Anna Schumaker:
 "Stable bugfixes:
   - Revalidate "." and ".." correctly on open
   - Avoid RCU usage in tracepoints
   - Fix ugly referral attributes
   - Fix a typo in nomigration mount option
   - Revert "NFS: Move the flock open mode check into nfs_flock()"
  Features:
   - Implement a stronger send queue accounting system for NFS over RDMA
   - Switch some atomics to the new refcount_t type
  Other bugfixes and cleanups:
   - Clean up access mode bits
   - Remove special-case revalidations in nfs_opendir()
   - Improve invalidating NFS over RDMA memory for async operations that
     time out
   - Handle NFS over RDMA replies with a worqueue
   - Handle NFS over RDMA sends with a workqueue
   - Fix up replaying interrupted requests
   - Remove dead NFS over RDMA definitions
   - Update NFS over RDMA copyright information
   - Be more consistent with bool initialization and comparisons
   - Mark expected switch fall throughs
   - Various sunrpc tracepoint cleanups
   - Fix various OPEN races
   - Fix a typo in nfs_rename()
   - Use common error handling code in nfs_lock_and_join_request()
   - Check that some structures are properly cleaned up during
     net_exit()
   - Remove net pointer from dprintk()s"
* tag 'nfs-for-4.15-1' of git://git.linux-nfs.org/projects/anna/linux-nfs: (62 commits)
  NFS: Revert "NFS: Move the flock open mode check into nfs_flock()"
  NFS: Fix typo in nomigration mount option
  nfs: Fix ugly referral attributes
  NFS: super: mark expected switch fall-throughs
  sunrpc: remove net pointer from messages
  nfs: remove net pointer from messages
  sunrpc: exit_net cleanup check added
  nfs client: exit_net cleanup check added
  nfs/write: Use common error handling code in nfs_lock_and_join_requests()
  NFSv4: Replace closed stateids with the "invalid special stateid"
  NFSv4: nfs_set_open_stateid must not trigger state recovery for closed state
  NFSv4: Check the open stateid when searching for expired state
  NFSv4: Clean up nfs4_delegreturn_done
  NFSv4: cleanup nfs4_close_done
  NFSv4: Retry NFS4ERR_OLD_STATEID errors in layoutreturn
  pNFS: Retry NFS4ERR_OLD_STATEID errors in layoutreturn-on-close
  NFSv4: Don't try to CLOSE if the stateid 'other' field has changed
  NFSv4: Retry CLOSE and DELEGRETURN on NFS4ERR_OLD_STATEID.
  NFS: Fix a typo in nfs_rename()
  NFSv4: Fix open create exclusive when the server reboots
  ...
		
	
			
		
			
				
	
	
		
			233 lines
		
	
	
	
		
			6.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			233 lines
		
	
	
	
		
			6.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* SPDX-License-Identifier: GPL-2.0 */
 | 
						|
/*
 | 
						|
 * NFSv4 flexfile layout driver data structures.
 | 
						|
 *
 | 
						|
 * Copyright (c) 2014, Primary Data, Inc. All rights reserved.
 | 
						|
 *
 | 
						|
 * Tao Peng <bergwolf@primarydata.com>
 | 
						|
 */
 | 
						|
 | 
						|
#ifndef FS_NFS_NFS4FLEXFILELAYOUT_H
 | 
						|
#define FS_NFS_NFS4FLEXFILELAYOUT_H
 | 
						|
 | 
						|
#define FF_FLAGS_NO_LAYOUTCOMMIT 1
 | 
						|
#define FF_FLAGS_NO_IO_THRU_MDS  2
 | 
						|
#define FF_FLAGS_NO_READ_IO      4
 | 
						|
 | 
						|
#include <linux/refcount.h>
 | 
						|
#include "../pnfs.h"
 | 
						|
 | 
						|
/* XXX: Let's filter out insanely large mirror count for now to avoid oom
 | 
						|
 * due to network error etc. */
 | 
						|
#define NFS4_FLEXFILE_LAYOUT_MAX_MIRROR_CNT 4096
 | 
						|
 | 
						|
/* LAYOUTSTATS report interval in ms */
 | 
						|
#define FF_LAYOUTSTATS_REPORT_INTERVAL (60000L)
 | 
						|
#define FF_LAYOUTSTATS_MAXDEV 4
 | 
						|
 | 
						|
struct nfs4_ff_ds_version {
 | 
						|
	u32				version;
 | 
						|
	u32				minor_version;
 | 
						|
	u32				rsize;
 | 
						|
	u32				wsize;
 | 
						|
	bool				tightly_coupled;
 | 
						|
};
 | 
						|
 | 
						|
/* chained in global deviceid hlist */
 | 
						|
struct nfs4_ff_layout_ds {
 | 
						|
	struct nfs4_deviceid_node	id_node;
 | 
						|
	u32				ds_versions_cnt;
 | 
						|
	struct nfs4_ff_ds_version	*ds_versions;
 | 
						|
	struct nfs4_pnfs_ds		*ds;
 | 
						|
};
 | 
						|
 | 
						|
struct nfs4_ff_layout_ds_err {
 | 
						|
	struct list_head		list; /* linked in mirror error_list */
 | 
						|
	u64				offset;
 | 
						|
	u64				length;
 | 
						|
	int				status;
 | 
						|
	enum nfs_opnum4			opnum;
 | 
						|
	nfs4_stateid			stateid;
 | 
						|
	struct nfs4_deviceid		deviceid;
 | 
						|
};
 | 
						|
 | 
						|
struct nfs4_ff_io_stat {
 | 
						|
	__u64				ops_requested;
 | 
						|
	__u64				bytes_requested;
 | 
						|
	__u64				ops_completed;
 | 
						|
	__u64				bytes_completed;
 | 
						|
	__u64				bytes_not_delivered;
 | 
						|
	ktime_t				total_busy_time;
 | 
						|
	ktime_t				aggregate_completion_time;
 | 
						|
};
 | 
						|
 | 
						|
struct nfs4_ff_busy_timer {
 | 
						|
	ktime_t start_time;
 | 
						|
	atomic_t n_ops;
 | 
						|
};
 | 
						|
 | 
						|
struct nfs4_ff_layoutstat {
 | 
						|
	struct nfs4_ff_io_stat io_stat;
 | 
						|
	struct nfs4_ff_busy_timer busy_timer;
 | 
						|
};
 | 
						|
 | 
						|
struct nfs4_ff_layout_mirror {
 | 
						|
	struct pnfs_layout_hdr		*layout;
 | 
						|
	struct list_head		mirrors;
 | 
						|
	u32				ds_count;
 | 
						|
	u32				efficiency;
 | 
						|
	struct nfs4_deviceid		devid;
 | 
						|
	struct nfs4_ff_layout_ds	*mirror_ds;
 | 
						|
	u32				fh_versions_cnt;
 | 
						|
	struct nfs_fh			*fh_versions;
 | 
						|
	nfs4_stateid			stateid;
 | 
						|
	struct rpc_cred	__rcu		*ro_cred;
 | 
						|
	struct rpc_cred	__rcu		*rw_cred;
 | 
						|
	refcount_t			ref;
 | 
						|
	spinlock_t			lock;
 | 
						|
	unsigned long			flags;
 | 
						|
	struct nfs4_ff_layoutstat	read_stat;
 | 
						|
	struct nfs4_ff_layoutstat	write_stat;
 | 
						|
	ktime_t				start_time;
 | 
						|
	u32				report_interval;
 | 
						|
};
 | 
						|
 | 
						|
#define NFS4_FF_MIRROR_STAT_AVAIL	(0)
 | 
						|
 | 
						|
struct nfs4_ff_layout_segment {
 | 
						|
	struct pnfs_layout_segment	generic_hdr;
 | 
						|
	u64				stripe_unit;
 | 
						|
	u32				flags;
 | 
						|
	u32				mirror_array_cnt;
 | 
						|
	struct nfs4_ff_layout_mirror	**mirror_array;
 | 
						|
};
 | 
						|
 | 
						|
struct nfs4_flexfile_layout {
 | 
						|
	struct pnfs_layout_hdr generic_hdr;
 | 
						|
	struct pnfs_ds_commit_info commit_info;
 | 
						|
	struct list_head	mirrors;
 | 
						|
	struct list_head	error_list; /* nfs4_ff_layout_ds_err */
 | 
						|
	ktime_t			last_report_time; /* Layoutstat report times */
 | 
						|
};
 | 
						|
 | 
						|
struct nfs4_flexfile_layoutreturn_args {
 | 
						|
	struct list_head errors;
 | 
						|
	struct nfs42_layoutstat_devinfo devinfo[FF_LAYOUTSTATS_MAXDEV];
 | 
						|
	unsigned int num_errors;
 | 
						|
	unsigned int num_dev;
 | 
						|
	struct page *pages[1];
 | 
						|
};
 | 
						|
 | 
						|
static inline struct nfs4_flexfile_layout *
 | 
						|
FF_LAYOUT_FROM_HDR(struct pnfs_layout_hdr *lo)
 | 
						|
{
 | 
						|
	return container_of(lo, struct nfs4_flexfile_layout, generic_hdr);
 | 
						|
}
 | 
						|
 | 
						|
static inline struct nfs4_ff_layout_segment *
 | 
						|
FF_LAYOUT_LSEG(struct pnfs_layout_segment *lseg)
 | 
						|
{
 | 
						|
	return container_of(lseg,
 | 
						|
			    struct nfs4_ff_layout_segment,
 | 
						|
			    generic_hdr);
 | 
						|
}
 | 
						|
 | 
						|
static inline struct nfs4_deviceid_node *
 | 
						|
FF_LAYOUT_DEVID_NODE(struct pnfs_layout_segment *lseg, u32 idx)
 | 
						|
{
 | 
						|
	if (idx >= FF_LAYOUT_LSEG(lseg)->mirror_array_cnt ||
 | 
						|
	    FF_LAYOUT_LSEG(lseg)->mirror_array[idx] == NULL ||
 | 
						|
	    FF_LAYOUT_LSEG(lseg)->mirror_array[idx]->mirror_ds == NULL)
 | 
						|
		return NULL;
 | 
						|
	return &FF_LAYOUT_LSEG(lseg)->mirror_array[idx]->mirror_ds->id_node;
 | 
						|
}
 | 
						|
 | 
						|
static inline struct nfs4_ff_layout_ds *
 | 
						|
FF_LAYOUT_MIRROR_DS(struct nfs4_deviceid_node *node)
 | 
						|
{
 | 
						|
	return container_of(node, struct nfs4_ff_layout_ds, id_node);
 | 
						|
}
 | 
						|
 | 
						|
static inline struct nfs4_ff_layout_mirror *
 | 
						|
FF_LAYOUT_COMP(struct pnfs_layout_segment *lseg, u32 idx)
 | 
						|
{
 | 
						|
	if (idx >= FF_LAYOUT_LSEG(lseg)->mirror_array_cnt)
 | 
						|
		return NULL;
 | 
						|
	return FF_LAYOUT_LSEG(lseg)->mirror_array[idx];
 | 
						|
}
 | 
						|
 | 
						|
static inline u32
 | 
						|
FF_LAYOUT_MIRROR_COUNT(struct pnfs_layout_segment *lseg)
 | 
						|
{
 | 
						|
	return FF_LAYOUT_LSEG(lseg)->mirror_array_cnt;
 | 
						|
}
 | 
						|
 | 
						|
static inline bool
 | 
						|
ff_layout_no_fallback_to_mds(struct pnfs_layout_segment *lseg)
 | 
						|
{
 | 
						|
	return FF_LAYOUT_LSEG(lseg)->flags & FF_FLAGS_NO_IO_THRU_MDS;
 | 
						|
}
 | 
						|
 | 
						|
static inline bool
 | 
						|
ff_layout_no_read_on_rw(struct pnfs_layout_segment *lseg)
 | 
						|
{
 | 
						|
	return FF_LAYOUT_LSEG(lseg)->flags & FF_FLAGS_NO_READ_IO;
 | 
						|
}
 | 
						|
 | 
						|
static inline bool
 | 
						|
ff_layout_test_devid_unavailable(struct nfs4_deviceid_node *node)
 | 
						|
{
 | 
						|
	/*
 | 
						|
	 * Flexfiles should never mark a DS unavailable, but if it does
 | 
						|
	 * print a (ratelimited) warning as this can affect performance.
 | 
						|
	 */
 | 
						|
	if (nfs4_test_deviceid_unavailable(node)) {
 | 
						|
		u32 *p = (u32 *)node->deviceid.data;
 | 
						|
 | 
						|
		pr_warn_ratelimited("NFS: flexfiles layout referencing an "
 | 
						|
				"unavailable device [%x%x%x%x]\n",
 | 
						|
				p[0], p[1], p[2], p[3]);
 | 
						|
		return true;
 | 
						|
	}
 | 
						|
	return false;
 | 
						|
}
 | 
						|
 | 
						|
static inline int
 | 
						|
nfs4_ff_layout_ds_version(struct pnfs_layout_segment *lseg, u32 ds_idx)
 | 
						|
{
 | 
						|
	return FF_LAYOUT_COMP(lseg, ds_idx)->mirror_ds->ds_versions[0].version;
 | 
						|
}
 | 
						|
 | 
						|
struct nfs4_ff_layout_ds *
 | 
						|
nfs4_ff_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev,
 | 
						|
			    gfp_t gfp_flags);
 | 
						|
void nfs4_ff_layout_put_deviceid(struct nfs4_ff_layout_ds *mirror_ds);
 | 
						|
void nfs4_ff_layout_free_deviceid(struct nfs4_ff_layout_ds *mirror_ds);
 | 
						|
int ff_layout_track_ds_error(struct nfs4_flexfile_layout *flo,
 | 
						|
			     struct nfs4_ff_layout_mirror *mirror, u64 offset,
 | 
						|
			     u64 length, int status, enum nfs_opnum4 opnum,
 | 
						|
			     gfp_t gfp_flags);
 | 
						|
int ff_layout_encode_ds_ioerr(struct xdr_stream *xdr, const struct list_head *head);
 | 
						|
void ff_layout_free_ds_ioerr(struct list_head *head);
 | 
						|
unsigned int ff_layout_fetch_ds_ioerr(struct pnfs_layout_hdr *lo,
 | 
						|
		const struct pnfs_layout_range *range,
 | 
						|
		struct list_head *head,
 | 
						|
		unsigned int maxnum);
 | 
						|
struct nfs_fh *
 | 
						|
nfs4_ff_layout_select_ds_fh(struct pnfs_layout_segment *lseg, u32 mirror_idx);
 | 
						|
 | 
						|
struct nfs4_pnfs_ds *
 | 
						|
nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx,
 | 
						|
			  bool fail_return);
 | 
						|
 | 
						|
struct rpc_clnt *
 | 
						|
nfs4_ff_find_or_create_ds_client(struct pnfs_layout_segment *lseg,
 | 
						|
				 u32 ds_idx,
 | 
						|
				 struct nfs_client *ds_clp,
 | 
						|
				 struct inode *inode);
 | 
						|
struct rpc_cred *ff_layout_get_ds_cred(struct pnfs_layout_segment *lseg,
 | 
						|
				       u32 ds_idx, struct rpc_cred *mdscred);
 | 
						|
bool ff_layout_avoid_mds_available_ds(struct pnfs_layout_segment *lseg);
 | 
						|
bool ff_layout_avoid_read_on_rw(struct pnfs_layout_segment *lseg);
 | 
						|
 | 
						|
#endif /* FS_NFS_NFS4FLEXFILELAYOUT_H */
 |