mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-04 20:19:47 +08: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
...
234 lines
6.4 KiB
C
234 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 */
|