mirror of
https://github.com/torvalds/linux.git
synced 2024-11-12 07:01:57 +00:00
NFS client updates for Linux 3.8
Features include: - Full audit of BUG_ON asserts in the NFS, SUNRPC and lockd client code Remove altogether where possible, and replace with WARN_ON_ONCE and appropriate error returns where not. - NFSv4.1 client adds session dynamic slot table management. There is matching server side code that has been submitted to Bruce for consideration. Together, this code allows the server to dynamically manage the amount of memory it allocates to the duplicate request cache for each client. It will constantly resize those caches to reserve more memory for clients that are hot while shrinking caches for those that are quiescent. In addition, there are assorted bugfixes for the generic NFS write code, fixes to deal with the drop_nlink() warnings, and yet another fix for NFSv4 getacl. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABAgAGBQJQz8VNAAoJEGcL54qWCgDy7iYQAKbr7AAZOcZPoJigzakZ7nMi UKYulGbFais2Llwzw1e+U5RzmorTSbvl7/m8eS7pDf3auYw/t4xtXjKSGZUNxaE1 q2hNKgVwodMbScYdkZXvKKNckS93oPDttrmEyzjKanqey+1E3HSklvOvikN0ihte B/G1OtA7Qpcr92bPrLK+PjDqarCBUI4g42dYbZOBrZnXKTRtzUqsuKPu7WjpPiof SHE5b1Emt7oUxgcijWGcvYCQ8voZdeSCnSksH3DgvORlutwdhUD3Yg8KyEfFZdyc 6C59ozXRLiHkV3c+jMhJzDkQXR9bYHrnK3tlq4G8v1NdJxRktQliZeqecRvip/Wz rAxfE6fnPDEvKsCpZb3+5yTAt+aZwzEhRg1fFC9qfGOp+oRa+CWw5kJCyIFHwJu6 4LOlubQAf6rnIsja1L8D0FdeqHUa1+wy61On5kgVYS5JGtoBsQHpa1zTwdOxPmsR 2XTMYGNCEabvpKpO9+5xQbUzkFExPTesw47ygXiUuDT/snaarpV3/f05SSCaWZkX R8QsGEOXTIh8/S+UxARGpc7H6xi1PdBM5nBziHVzjEdHgZRF4wGFaJe2CirMjSJO Df5GEd5Z/8VCGWs+1w7HD5EaQ2n0wbt5daCE80Y2jRBr7NMYnY+ciF8/GktLpHsn Zq1bXGOdr3UZ92LXuzL9 =G3N9 -----END PGP SIGNATURE----- Merge tag 'nfs-for-3.8-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs Pull NFS client updates from Trond Myklebust: "Features include: - Full audit of BUG_ON asserts in the NFS, SUNRPC and lockd client code. Remove altogether where possible, and replace with WARN_ON_ONCE and appropriate error returns where not. - NFSv4.1 client adds session dynamic slot table management. There is matching server side code that has been submitted to Bruce for consideration. Together, this code allows the server to dynamically manage the amount of memory it allocates to the duplicate request cache for each client. It will constantly resize those caches to reserve more memory for clients that are hot while shrinking caches for those that are quiescent. In addition, there are assorted bugfixes for the generic NFS write code, fixes to deal with the drop_nlink() warnings, and yet another fix for NFSv4 getacl." * tag 'nfs-for-3.8-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (106 commits) SUNRPC: continue run over clients list on PipeFS event instead of break NFS: Don't use SetPageError in the NFS writeback code SUNRPC: variable 'svsk' is unused in function bc_send_request SUNRPC: Handle ECONNREFUSED in xs_local_setup_socket NFSv4.1: Deal effectively with interrupted RPC calls. NFSv4.1: Move the RPC timestamp out of the slot. NFSv4.1: Try to deal with NFS4ERR_SEQ_MISORDERED. NFS: nfs_lookup_revalidate should not trust an inode with i_nlink == 0 NFS: Fix calls to drop_nlink() NFS: Ensure that we always drop inodes that have been marked as stale nfs: Remove unused list nfs4_clientid_list nfs: Remove duplicate function declaration in internal.h NFS: avoid NULL dereference in nfs_destroy_server SUNRPC handle EKEYEXPIRED in call_refreshresult SUNRPC set gss gc_expiry to full lifetime nfs: fix page dirtying in NFS DIO read codepath nfs: don't zero out the rest of the page if we hit the EOF on a DIO READ NFSv4.1: Be conservative about the client highest slotid NFSv4.1: Handle NFS4ERR_BADSLOT errors correctly nfs: don't extend writes to cover entire page if pagecache is invalid ...
This commit is contained in:
commit
2d4dce0070
@ -64,10 +64,6 @@ static void nlm4_compute_offsets(const struct nlm_lock *lock,
|
||||
{
|
||||
const struct file_lock *fl = &lock->fl;
|
||||
|
||||
BUG_ON(fl->fl_start > NLM4_OFFSET_MAX);
|
||||
BUG_ON(fl->fl_end > NLM4_OFFSET_MAX &&
|
||||
fl->fl_end != OFFSET_MAX);
|
||||
|
||||
*l_offset = loff_t_to_s64(fl->fl_start);
|
||||
if (fl->fl_end == OFFSET_MAX)
|
||||
*l_len = 0;
|
||||
@ -122,7 +118,6 @@ static void encode_netobj(struct xdr_stream *xdr,
|
||||
{
|
||||
__be32 *p;
|
||||
|
||||
BUG_ON(length > XDR_MAX_NETOBJ);
|
||||
p = xdr_reserve_space(xdr, 4 + length);
|
||||
xdr_encode_opaque(p, data, length);
|
||||
}
|
||||
@ -156,7 +151,6 @@ out_overflow:
|
||||
static void encode_cookie(struct xdr_stream *xdr,
|
||||
const struct nlm_cookie *cookie)
|
||||
{
|
||||
BUG_ON(cookie->len > NLM_MAXCOOKIELEN);
|
||||
encode_netobj(xdr, (u8 *)&cookie->data, cookie->len);
|
||||
}
|
||||
|
||||
@ -198,7 +192,6 @@ out_overflow:
|
||||
*/
|
||||
static void encode_fh(struct xdr_stream *xdr, const struct nfs_fh *fh)
|
||||
{
|
||||
BUG_ON(fh->size > NFS3_FHSIZE);
|
||||
encode_netobj(xdr, (u8 *)&fh->data, fh->size);
|
||||
}
|
||||
|
||||
@ -336,7 +329,6 @@ static void encode_caller_name(struct xdr_stream *xdr, const char *name)
|
||||
u32 length = strlen(name);
|
||||
__be32 *p;
|
||||
|
||||
BUG_ON(length > NLM_MAXSTRLEN);
|
||||
p = xdr_reserve_space(xdr, 4 + length);
|
||||
xdr_encode_opaque(p, name, length);
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ static void nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl)
|
||||
|
||||
static void nlmclnt_release_lockargs(struct nlm_rqst *req)
|
||||
{
|
||||
BUG_ON(req->a_args.lock.fl.fl_ops != NULL);
|
||||
WARN_ON_ONCE(req->a_args.lock.fl.fl_ops != NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -465,7 +465,6 @@ static const struct file_lock_operations nlmclnt_lock_ops = {
|
||||
|
||||
static void nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *host)
|
||||
{
|
||||
BUG_ON(fl->fl_ops != NULL);
|
||||
fl->fl_u.nfs_fl.state = 0;
|
||||
fl->fl_u.nfs_fl.owner = nlm_find_lockowner(host, fl->fl_owner);
|
||||
INIT_LIST_HEAD(&fl->fl_u.nfs_fl.list);
|
||||
|
@ -60,10 +60,6 @@ static void nlm_compute_offsets(const struct nlm_lock *lock,
|
||||
{
|
||||
const struct file_lock *fl = &lock->fl;
|
||||
|
||||
BUG_ON(fl->fl_start > NLM_OFFSET_MAX);
|
||||
BUG_ON(fl->fl_end > NLM_OFFSET_MAX &&
|
||||
fl->fl_end != OFFSET_MAX);
|
||||
|
||||
*l_offset = loff_t_to_s32(fl->fl_start);
|
||||
if (fl->fl_end == OFFSET_MAX)
|
||||
*l_len = 0;
|
||||
@ -119,7 +115,6 @@ static void encode_netobj(struct xdr_stream *xdr,
|
||||
{
|
||||
__be32 *p;
|
||||
|
||||
BUG_ON(length > XDR_MAX_NETOBJ);
|
||||
p = xdr_reserve_space(xdr, 4 + length);
|
||||
xdr_encode_opaque(p, data, length);
|
||||
}
|
||||
@ -153,7 +148,6 @@ out_overflow:
|
||||
static void encode_cookie(struct xdr_stream *xdr,
|
||||
const struct nlm_cookie *cookie)
|
||||
{
|
||||
BUG_ON(cookie->len > NLM_MAXCOOKIELEN);
|
||||
encode_netobj(xdr, (u8 *)&cookie->data, cookie->len);
|
||||
}
|
||||
|
||||
@ -195,7 +189,6 @@ out_overflow:
|
||||
*/
|
||||
static void encode_fh(struct xdr_stream *xdr, const struct nfs_fh *fh)
|
||||
{
|
||||
BUG_ON(fh->size != NFS2_FHSIZE);
|
||||
encode_netobj(xdr, (u8 *)&fh->data, NFS2_FHSIZE);
|
||||
}
|
||||
|
||||
@ -330,7 +323,6 @@ static void encode_caller_name(struct xdr_stream *xdr, const char *name)
|
||||
u32 length = strlen(name);
|
||||
__be32 *p;
|
||||
|
||||
BUG_ON(length > NLM_MAXSTRLEN);
|
||||
p = xdr_reserve_space(xdr, 4 + length);
|
||||
xdr_encode_opaque(p, name, length);
|
||||
}
|
||||
|
@ -177,9 +177,6 @@ static void nlm_destroy_host_locked(struct nlm_host *host)
|
||||
|
||||
dprintk("lockd: destroy host %s\n", host->h_name);
|
||||
|
||||
BUG_ON(!list_empty(&host->h_lockowners));
|
||||
BUG_ON(atomic_read(&host->h_count));
|
||||
|
||||
hlist_del_init(&host->h_hash);
|
||||
|
||||
nsm_unmonitor(host);
|
||||
@ -289,13 +286,12 @@ void nlmclnt_release_host(struct nlm_host *host)
|
||||
|
||||
dprintk("lockd: release client host %s\n", host->h_name);
|
||||
|
||||
BUG_ON(atomic_read(&host->h_count) < 0);
|
||||
BUG_ON(host->h_server);
|
||||
WARN_ON_ONCE(host->h_server);
|
||||
|
||||
if (atomic_dec_and_test(&host->h_count)) {
|
||||
BUG_ON(!list_empty(&host->h_lockowners));
|
||||
BUG_ON(!list_empty(&host->h_granted));
|
||||
BUG_ON(!list_empty(&host->h_reclaim));
|
||||
WARN_ON_ONCE(!list_empty(&host->h_lockowners));
|
||||
WARN_ON_ONCE(!list_empty(&host->h_granted));
|
||||
WARN_ON_ONCE(!list_empty(&host->h_reclaim));
|
||||
|
||||
mutex_lock(&nlm_host_mutex);
|
||||
nlm_destroy_host_locked(host);
|
||||
@ -412,8 +408,7 @@ void nlmsvc_release_host(struct nlm_host *host)
|
||||
|
||||
dprintk("lockd: release server host %s\n", host->h_name);
|
||||
|
||||
BUG_ON(atomic_read(&host->h_count) < 0);
|
||||
BUG_ON(!host->h_server);
|
||||
WARN_ON_ONCE(!host->h_server);
|
||||
atomic_dec(&host->h_count);
|
||||
}
|
||||
|
||||
|
@ -154,8 +154,6 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
|
||||
.rpc_resp = res,
|
||||
};
|
||||
|
||||
BUG_ON(clnt == NULL);
|
||||
|
||||
memset(res, 0, sizeof(*res));
|
||||
|
||||
msg.rpc_proc = &clnt->cl_procinfo[proc];
|
||||
@ -466,7 +464,6 @@ static void encode_nsm_string(struct xdr_stream *xdr, const char *string)
|
||||
const u32 len = strlen(string);
|
||||
__be32 *p;
|
||||
|
||||
BUG_ON(len > SM_MAXSTRLEN);
|
||||
p = xdr_reserve_space(xdr, 4 + len);
|
||||
xdr_encode_opaque(p, string, len);
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ nfsv4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o
|
||||
delegation.o idmap.o callback.o callback_xdr.o callback_proc.o \
|
||||
nfs4namespace.o nfs4getroot.o nfs4client.o
|
||||
nfsv4-$(CONFIG_SYSCTL) += nfs4sysctl.o
|
||||
nfsv4-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o
|
||||
nfsv4-$(CONFIG_NFS_V4_1) += nfs4session.o pnfs.o pnfs_dev.o
|
||||
|
||||
obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o
|
||||
nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include <linux/pagevec.h>
|
||||
|
||||
#include "../pnfs.h"
|
||||
#include "../nfs4session.h"
|
||||
#include "../internal.h"
|
||||
#include "blocklayout.h"
|
||||
|
||||
|
@ -118,7 +118,6 @@ int nfs_cache_register_sb(struct super_block *sb, struct cache_detail *cd)
|
||||
struct dentry *dir;
|
||||
|
||||
dir = rpc_d_lookup_sb(sb, "cache");
|
||||
BUG_ON(dir == NULL);
|
||||
ret = sunrpc_cache_register_pipefs(dir, cd->name, 0600, cd);
|
||||
dput(dir);
|
||||
return ret;
|
||||
|
@ -142,7 +142,7 @@ extern __be32 nfs4_callback_recallany(struct cb_recallanyargs *args,
|
||||
|
||||
struct cb_recallslotargs {
|
||||
struct sockaddr *crsa_addr;
|
||||
uint32_t crsa_target_max_slots;
|
||||
uint32_t crsa_target_highest_slotid;
|
||||
};
|
||||
extern __be32 nfs4_callback_recallslot(struct cb_recallslotargs *args,
|
||||
void *dummy,
|
||||
@ -167,8 +167,6 @@ extern __be32 nfs4_callback_layoutrecall(
|
||||
struct cb_layoutrecallargs *args,
|
||||
void *dummy, struct cb_process_state *cps);
|
||||
|
||||
extern void nfs4_check_drain_bc_complete(struct nfs4_session *ses);
|
||||
|
||||
struct cb_devicenotifyitem {
|
||||
uint32_t cbd_notify_type;
|
||||
uint32_t cbd_layout_type;
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "delegation.h"
|
||||
#include "internal.h"
|
||||
#include "pnfs.h"
|
||||
#include "nfs4session.h"
|
||||
|
||||
#ifdef NFS_DEBUG
|
||||
#define NFSDBG_FACILITY NFSDBG_CALLBACK
|
||||
@ -216,7 +217,6 @@ static u32 initiate_bulk_draining(struct nfs_client *clp,
|
||||
}
|
||||
pnfs_get_layout_hdr(lo);
|
||||
spin_unlock(&ino->i_lock);
|
||||
BUG_ON(!list_empty(&lo->plh_bulk_recall));
|
||||
list_add(&lo->plh_bulk_recall, &recall_list);
|
||||
}
|
||||
}
|
||||
@ -562,23 +562,16 @@ __be32 nfs4_callback_recallslot(struct cb_recallslotargs *args, void *dummy,
|
||||
if (!cps->clp) /* set in cb_sequence */
|
||||
goto out;
|
||||
|
||||
dprintk_rcu("NFS: CB_RECALL_SLOT request from %s target max slots %d\n",
|
||||
dprintk_rcu("NFS: CB_RECALL_SLOT request from %s target highest slotid %d\n",
|
||||
rpc_peeraddr2str(cps->clp->cl_rpcclient, RPC_DISPLAY_ADDR),
|
||||
args->crsa_target_max_slots);
|
||||
args->crsa_target_highest_slotid);
|
||||
|
||||
fc_tbl = &cps->clp->cl_session->fc_slot_table;
|
||||
|
||||
status = htonl(NFS4ERR_BAD_HIGH_SLOT);
|
||||
if (args->crsa_target_max_slots > fc_tbl->max_slots ||
|
||||
args->crsa_target_max_slots < 1)
|
||||
goto out;
|
||||
|
||||
status = htonl(NFS4_OK);
|
||||
if (args->crsa_target_max_slots == fc_tbl->max_slots)
|
||||
goto out;
|
||||
|
||||
fc_tbl->target_max_slots = args->crsa_target_max_slots;
|
||||
nfs41_handle_recall_slot(cps->clp);
|
||||
nfs41_set_target_slotid(fc_tbl, args->crsa_target_highest_slotid);
|
||||
nfs41_server_notify_target_slotid_update(cps->clp);
|
||||
out:
|
||||
dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
|
||||
return status;
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "nfs4_fs.h"
|
||||
#include "callback.h"
|
||||
#include "internal.h"
|
||||
#include "nfs4session.h"
|
||||
|
||||
#define CB_OP_TAGLEN_MAXSZ (512)
|
||||
#define CB_OP_HDR_RES_MAXSZ (2 + CB_OP_TAGLEN_MAXSZ)
|
||||
@ -520,7 +521,7 @@ static __be32 decode_recallslot_args(struct svc_rqst *rqstp,
|
||||
p = read_buf(xdr, 4);
|
||||
if (unlikely(p == NULL))
|
||||
return htonl(NFS4ERR_BADXDR);
|
||||
args->crsa_target_max_slots = ntohl(*p++);
|
||||
args->crsa_target_highest_slotid = ntohl(*p++);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -762,7 +763,7 @@ static void nfs4_callback_free_slot(struct nfs4_session *session)
|
||||
* A single slot, so highest used slotid is either 0 or -1
|
||||
*/
|
||||
tbl->highest_used_slotid = NFS4_NO_SLOT;
|
||||
nfs4_check_drain_bc_complete(session);
|
||||
nfs4_session_drain_complete(session, tbl);
|
||||
spin_unlock(&tbl->slot_tbl_lock);
|
||||
}
|
||||
|
||||
|
@ -277,7 +277,7 @@ void nfs_put_client(struct nfs_client *clp)
|
||||
nfs_cb_idr_remove_locked(clp);
|
||||
spin_unlock(&nn->nfs_client_lock);
|
||||
|
||||
BUG_ON(!list_empty(&clp->cl_superblocks));
|
||||
WARN_ON_ONCE(!list_empty(&clp->cl_superblocks));
|
||||
|
||||
clp->rpc_ops->free_client(clp);
|
||||
}
|
||||
@ -615,8 +615,7 @@ EXPORT_SYMBOL_GPL(nfs_create_rpc_client);
|
||||
*/
|
||||
static void nfs_destroy_server(struct nfs_server *server)
|
||||
{
|
||||
if (!(server->flags & NFS_MOUNT_LOCAL_FLOCK) ||
|
||||
!(server->flags & NFS_MOUNT_LOCAL_FCNTL))
|
||||
if (server->nlm_host)
|
||||
nlmclnt_done(server->nlm_host);
|
||||
}
|
||||
|
||||
@ -1061,10 +1060,6 @@ struct nfs_server *nfs_create_server(struct nfs_mount_info *mount_info,
|
||||
if (error < 0)
|
||||
goto error;
|
||||
|
||||
BUG_ON(!server->nfs_client);
|
||||
BUG_ON(!server->nfs_client->rpc_ops);
|
||||
BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
|
||||
|
||||
/* Probe the root fh to retrieve its FSID */
|
||||
error = nfs_probe_fsinfo(server, mount_info->mntfh, fattr);
|
||||
if (error < 0)
|
||||
|
22
fs/nfs/dir.c
22
fs/nfs/dir.c
@ -979,10 +979,11 @@ static int nfs_is_exclusive_create(struct inode *dir, unsigned int flags)
|
||||
* particular file and the "nocto" mount flag is not set.
|
||||
*
|
||||
*/
|
||||
static inline
|
||||
static
|
||||
int nfs_lookup_verify_inode(struct inode *inode, unsigned int flags)
|
||||
{
|
||||
struct nfs_server *server = NFS_SERVER(inode);
|
||||
int ret;
|
||||
|
||||
if (IS_AUTOMOUNT(inode))
|
||||
return 0;
|
||||
@ -993,9 +994,13 @@ int nfs_lookup_verify_inode(struct inode *inode, unsigned int flags)
|
||||
if ((flags & LOOKUP_OPEN) && !(server->flags & NFS_MOUNT_NOCTO) &&
|
||||
(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)))
|
||||
goto out_force;
|
||||
return 0;
|
||||
out:
|
||||
return (inode->i_nlink == 0) ? -ENOENT : 0;
|
||||
out_force:
|
||||
return __nfs_revalidate_inode(server, inode);
|
||||
ret = __nfs_revalidate_inode(server, inode);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1156,11 +1161,14 @@ static int nfs_dentry_delete(const struct dentry *dentry)
|
||||
|
||||
}
|
||||
|
||||
/* Ensure that we revalidate inode->i_nlink */
|
||||
static void nfs_drop_nlink(struct inode *inode)
|
||||
{
|
||||
spin_lock(&inode->i_lock);
|
||||
if (inode->i_nlink > 0)
|
||||
drop_nlink(inode);
|
||||
/* drop the inode if we're reasonably sure this is the last link */
|
||||
if (inode->i_nlink == 1)
|
||||
clear_nlink(inode);
|
||||
NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR;
|
||||
spin_unlock(&inode->i_lock);
|
||||
}
|
||||
|
||||
@ -1175,8 +1183,8 @@ static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode)
|
||||
NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA;
|
||||
|
||||
if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
|
||||
drop_nlink(inode);
|
||||
nfs_complete_unlink(dentry, inode);
|
||||
nfs_drop_nlink(inode);
|
||||
}
|
||||
iput(inode);
|
||||
}
|
||||
@ -1647,10 +1655,8 @@ static int nfs_safe_remove(struct dentry *dentry)
|
||||
if (inode != NULL) {
|
||||
NFS_PROTO(inode)->return_delegation(inode);
|
||||
error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
|
||||
/* The VFS may want to delete this inode */
|
||||
if (error == 0)
|
||||
nfs_drop_nlink(inode);
|
||||
nfs_mark_for_revalidate(inode);
|
||||
} else
|
||||
error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
|
||||
if (error == -ENOENT)
|
||||
|
@ -266,21 +266,8 @@ static void nfs_direct_read_completion(struct nfs_pgio_header *hdr)
|
||||
struct nfs_page *req = nfs_list_entry(hdr->pages.next);
|
||||
struct page *page = req->wb_page;
|
||||
|
||||
if (test_bit(NFS_IOHDR_EOF, &hdr->flags)) {
|
||||
if (bytes > hdr->good_bytes)
|
||||
zero_user(page, 0, PAGE_SIZE);
|
||||
else if (hdr->good_bytes - bytes < PAGE_SIZE)
|
||||
zero_user_segment(page,
|
||||
hdr->good_bytes & ~PAGE_MASK,
|
||||
PAGE_SIZE);
|
||||
}
|
||||
if (!PageCompound(page)) {
|
||||
if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) {
|
||||
if (bytes < hdr->good_bytes)
|
||||
set_page_dirty(page);
|
||||
} else
|
||||
set_page_dirty(page);
|
||||
}
|
||||
if (!PageCompound(page) && bytes < hdr->good_bytes)
|
||||
set_page_dirty(page);
|
||||
bytes += req->wb_bytes;
|
||||
nfs_list_remove_request(req);
|
||||
nfs_direct_readpage_release(req);
|
||||
|
@ -107,13 +107,19 @@ u64 nfs_compat_user_ino64(u64 fileid)
|
||||
return ino;
|
||||
}
|
||||
|
||||
int nfs_drop_inode(struct inode *inode)
|
||||
{
|
||||
return NFS_STALE(inode) || generic_drop_inode(inode);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_drop_inode);
|
||||
|
||||
void nfs_clear_inode(struct inode *inode)
|
||||
{
|
||||
/*
|
||||
* The following should never happen...
|
||||
*/
|
||||
BUG_ON(nfs_have_writebacks(inode));
|
||||
BUG_ON(!list_empty(&NFS_I(inode)->open_files));
|
||||
WARN_ON_ONCE(nfs_have_writebacks(inode));
|
||||
WARN_ON_ONCE(!list_empty(&NFS_I(inode)->open_files));
|
||||
nfs_zap_acl_cache(inode);
|
||||
nfs_access_zap_cache(inode);
|
||||
nfs_fscache_release_inode_cookie(inode);
|
||||
|
@ -18,27 +18,6 @@ struct nfs_string;
|
||||
*/
|
||||
#define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1)
|
||||
|
||||
/*
|
||||
* Determine if sessions are in use.
|
||||
*/
|
||||
static inline int nfs4_has_session(const struct nfs_client *clp)
|
||||
{
|
||||
#ifdef CONFIG_NFS_V4_1
|
||||
if (clp->cl_session)
|
||||
return 1;
|
||||
#endif /* CONFIG_NFS_V4_1 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int nfs4_has_persistent_session(const struct nfs_client *clp)
|
||||
{
|
||||
#ifdef CONFIG_NFS_V4_1
|
||||
if (nfs4_has_session(clp))
|
||||
return (clp->cl_session->flags & SESSION4_PERSIST);
|
||||
#endif /* CONFIG_NFS_V4_1 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void nfs_attr_check_mountpoint(struct super_block *parent, struct nfs_fattr *fattr)
|
||||
{
|
||||
if (!nfs_fsid_equal(&NFS_SB(parent)->fsid, &fattr->fsid))
|
||||
@ -276,8 +255,6 @@ extern const u32 nfs41_maxwrite_overhead;
|
||||
extern struct rpc_procinfo nfs4_procedures[];
|
||||
#endif
|
||||
|
||||
extern int nfs4_init_ds_session(struct nfs_client *, unsigned long);
|
||||
|
||||
/* proc.c */
|
||||
void nfs_close_context(struct nfs_open_context *ctx, int is_sync);
|
||||
extern struct nfs_client *nfs_init_client(struct nfs_client *clp,
|
||||
@ -319,6 +296,7 @@ extern struct workqueue_struct *nfsiod_workqueue;
|
||||
extern struct inode *nfs_alloc_inode(struct super_block *sb);
|
||||
extern void nfs_destroy_inode(struct inode *);
|
||||
extern int nfs_write_inode(struct inode *, struct writeback_control *);
|
||||
extern int nfs_drop_inode(struct inode *);
|
||||
extern void nfs_clear_inode(struct inode *);
|
||||
extern void nfs_evict_inode(struct inode *);
|
||||
void nfs_zap_acl_cache(struct inode *inode);
|
||||
@ -386,9 +364,6 @@ extern int nfs_initiate_read(struct rpc_clnt *clnt,
|
||||
extern void nfs_read_prepare(struct rpc_task *task, void *calldata);
|
||||
extern int nfs_generic_pagein(struct nfs_pageio_descriptor *desc,
|
||||
struct nfs_pgio_header *hdr);
|
||||
extern void nfs_pageio_init_read(struct nfs_pageio_descriptor *pgio,
|
||||
struct inode *inode,
|
||||
const struct nfs_pgio_completion_ops *compl_ops);
|
||||
extern void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio);
|
||||
extern void nfs_readdata_release(struct nfs_read_data *rdata);
|
||||
|
||||
@ -411,9 +386,6 @@ extern struct nfs_write_header *nfs_writehdr_alloc(void);
|
||||
extern void nfs_writehdr_free(struct nfs_pgio_header *hdr);
|
||||
extern int nfs_generic_flush(struct nfs_pageio_descriptor *desc,
|
||||
struct nfs_pgio_header *hdr);
|
||||
extern void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
|
||||
struct inode *inode, int ioflags,
|
||||
const struct nfs_pgio_completion_ops *compl_ops);
|
||||
extern void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio);
|
||||
extern void nfs_writedata_release(struct nfs_write_data *wdata);
|
||||
extern void nfs_commit_free(struct nfs_commit_data *p);
|
||||
@ -474,18 +446,6 @@ extern struct nfs_client *nfs4_init_client(struct nfs_client *clp,
|
||||
const struct rpc_timeout *timeparms,
|
||||
const char *ip_addr,
|
||||
rpc_authflavor_t authflavour);
|
||||
extern int _nfs4_call_sync(struct rpc_clnt *clnt,
|
||||
struct nfs_server *server,
|
||||
struct rpc_message *msg,
|
||||
struct nfs4_sequence_args *args,
|
||||
struct nfs4_sequence_res *res,
|
||||
int cache_reply);
|
||||
extern int _nfs4_call_sync_session(struct rpc_clnt *clnt,
|
||||
struct nfs_server *server,
|
||||
struct rpc_message *msg,
|
||||
struct nfs4_sequence_args *args,
|
||||
struct nfs4_sequence_res *res,
|
||||
int cache_reply);
|
||||
extern int nfs40_walk_client_list(struct nfs_client *clp,
|
||||
struct nfs_client **result,
|
||||
struct rpc_cred *cred);
|
||||
|
@ -169,6 +169,9 @@ int nfs_mount(struct nfs_mount_request *info)
|
||||
(info->hostname ? info->hostname : "server"),
|
||||
info->dirpath);
|
||||
|
||||
if (strlen(info->dirpath) > MNTPATHLEN)
|
||||
return -ENAMETOOLONG;
|
||||
|
||||
if (info->noresvport)
|
||||
args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
|
||||
|
||||
@ -242,6 +245,9 @@ void nfs_umount(const struct nfs_mount_request *info)
|
||||
struct rpc_clnt *clnt;
|
||||
int status;
|
||||
|
||||
if (strlen(info->dirpath) > MNTPATHLEN)
|
||||
return;
|
||||
|
||||
if (info->noresvport)
|
||||
args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
|
||||
|
||||
@ -283,7 +289,6 @@ static void encode_mntdirpath(struct xdr_stream *xdr, const char *pathname)
|
||||
const u32 pathname_len = strlen(pathname);
|
||||
__be32 *p;
|
||||
|
||||
BUG_ON(pathname_len > MNTPATHLEN);
|
||||
p = xdr_reserve_space(xdr, 4 + pathname_len);
|
||||
xdr_encode_opaque(p, pathname, pathname_len);
|
||||
}
|
||||
|
@ -195,7 +195,6 @@ static void encode_fhandle(struct xdr_stream *xdr, const struct nfs_fh *fh)
|
||||
{
|
||||
__be32 *p;
|
||||
|
||||
BUG_ON(fh->size != NFS2_FHSIZE);
|
||||
p = xdr_reserve_space(xdr, NFS2_FHSIZE);
|
||||
memcpy(p, fh->data, NFS2_FHSIZE);
|
||||
}
|
||||
@ -388,7 +387,7 @@ static void encode_filename(struct xdr_stream *xdr,
|
||||
{
|
||||
__be32 *p;
|
||||
|
||||
BUG_ON(length > NFS2_MAXNAMLEN);
|
||||
WARN_ON_ONCE(length > NFS2_MAXNAMLEN);
|
||||
p = xdr_reserve_space(xdr, 4 + length);
|
||||
xdr_encode_opaque(p, name, length);
|
||||
}
|
||||
@ -428,7 +427,6 @@ static void encode_path(struct xdr_stream *xdr, struct page **pages, u32 length)
|
||||
{
|
||||
__be32 *p;
|
||||
|
||||
BUG_ON(length > NFS2_MAXPATHLEN);
|
||||
p = xdr_reserve_space(xdr, 4);
|
||||
*p = cpu_to_be32(length);
|
||||
xdr_write_pages(xdr, pages, 0, length);
|
||||
|
@ -24,14 +24,14 @@
|
||||
|
||||
#define NFSDBG_FACILITY NFSDBG_PROC
|
||||
|
||||
/* A wrapper to handle the EJUKEBOX and EKEYEXPIRED error messages */
|
||||
/* A wrapper to handle the EJUKEBOX error messages */
|
||||
static int
|
||||
nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
|
||||
{
|
||||
int res;
|
||||
do {
|
||||
res = rpc_call_sync(clnt, msg, flags);
|
||||
if (res != -EJUKEBOX && res != -EKEYEXPIRED)
|
||||
if (res != -EJUKEBOX)
|
||||
break;
|
||||
freezable_schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
|
||||
res = -ERESTARTSYS;
|
||||
@ -44,7 +44,7 @@ nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
|
||||
static int
|
||||
nfs3_async_handle_jukebox(struct rpc_task *task, struct inode *inode)
|
||||
{
|
||||
if (task->tk_status != -EJUKEBOX && task->tk_status != -EKEYEXPIRED)
|
||||
if (task->tk_status != -EJUKEBOX)
|
||||
return 0;
|
||||
if (task->tk_status == -EJUKEBOX)
|
||||
nfs_inc_stats(inode, NFSIOS_DELAY);
|
||||
|
@ -198,7 +198,7 @@ static void encode_filename3(struct xdr_stream *xdr,
|
||||
{
|
||||
__be32 *p;
|
||||
|
||||
BUG_ON(length > NFS3_MAXNAMLEN);
|
||||
WARN_ON_ONCE(length > NFS3_MAXNAMLEN);
|
||||
p = xdr_reserve_space(xdr, 4 + length);
|
||||
xdr_encode_opaque(p, name, length);
|
||||
}
|
||||
@ -238,7 +238,6 @@ out_overflow:
|
||||
static void encode_nfspath3(struct xdr_stream *xdr, struct page **pages,
|
||||
const u32 length)
|
||||
{
|
||||
BUG_ON(length > NFS3_MAXPATHLEN);
|
||||
encode_uint32(xdr, length);
|
||||
xdr_write_pages(xdr, pages, 0, length);
|
||||
}
|
||||
@ -388,7 +387,6 @@ out_overflow:
|
||||
*/
|
||||
static void encode_ftype3(struct xdr_stream *xdr, const u32 type)
|
||||
{
|
||||
BUG_ON(type > NF3FIFO);
|
||||
encode_uint32(xdr, type);
|
||||
}
|
||||
|
||||
@ -443,7 +441,7 @@ static void encode_nfs_fh3(struct xdr_stream *xdr, const struct nfs_fh *fh)
|
||||
{
|
||||
__be32 *p;
|
||||
|
||||
BUG_ON(fh->size > NFS3_FHSIZE);
|
||||
WARN_ON_ONCE(fh->size > NFS3_FHSIZE);
|
||||
p = xdr_reserve_space(xdr, 4 + fh->size);
|
||||
xdr_encode_opaque(p, fh->data, fh->size);
|
||||
}
|
||||
@ -1339,6 +1337,7 @@ static void nfs3_xdr_enc_setacl3args(struct rpc_rqst *req,
|
||||
error = nfsacl_encode(xdr->buf, base, args->inode,
|
||||
(args->mask & NFS_ACL) ?
|
||||
args->acl_access : NULL, 1, 0);
|
||||
/* FIXME: this is just broken */
|
||||
BUG_ON(error < 0);
|
||||
error = nfsacl_encode(xdr->buf, base + error, args->inode,
|
||||
(args->mask & NFS_DFACL) ?
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
|
||||
#define NFS4_MAX_LOOP_ON_RECOVER (10)
|
||||
|
||||
struct idmap;
|
||||
|
||||
enum nfs4_client_state {
|
||||
@ -21,18 +23,12 @@ enum nfs4_client_state {
|
||||
NFS4CLNT_RECLAIM_NOGRACE,
|
||||
NFS4CLNT_DELEGRETURN,
|
||||
NFS4CLNT_SESSION_RESET,
|
||||
NFS4CLNT_RECALL_SLOT,
|
||||
NFS4CLNT_LEASE_CONFIRM,
|
||||
NFS4CLNT_SERVER_SCOPE_MISMATCH,
|
||||
NFS4CLNT_PURGE_STATE,
|
||||
NFS4CLNT_BIND_CONN_TO_SESSION,
|
||||
};
|
||||
|
||||
enum nfs4_session_state {
|
||||
NFS4_SESSION_INITING,
|
||||
NFS4_SESSION_DRAINING,
|
||||
};
|
||||
|
||||
#define NFS4_RENEW_TIMEOUT 0x01
|
||||
#define NFS4_RENEW_DELEGATION_CB 0x02
|
||||
|
||||
@ -43,8 +39,7 @@ struct nfs4_minor_version_ops {
|
||||
struct nfs_server *server,
|
||||
struct rpc_message *msg,
|
||||
struct nfs4_sequence_args *args,
|
||||
struct nfs4_sequence_res *res,
|
||||
int cache_reply);
|
||||
struct nfs4_sequence_res *res);
|
||||
bool (*match_stateid)(const nfs4_stateid *,
|
||||
const nfs4_stateid *);
|
||||
int (*find_root_sec)(struct nfs_server *, struct nfs_fh *,
|
||||
@ -241,18 +236,14 @@ static inline struct nfs4_session *nfs4_get_session(const struct nfs_server *ser
|
||||
return server->nfs_client->cl_session;
|
||||
}
|
||||
|
||||
extern bool nfs4_set_task_privileged(struct rpc_task *task, void *dummy);
|
||||
extern int nfs4_setup_sequence(const struct nfs_server *server,
|
||||
struct nfs4_sequence_args *args, struct nfs4_sequence_res *res,
|
||||
struct rpc_task *task);
|
||||
extern int nfs41_setup_sequence(struct nfs4_session *session,
|
||||
struct nfs4_sequence_args *args, struct nfs4_sequence_res *res,
|
||||
struct rpc_task *task);
|
||||
extern void nfs4_destroy_session(struct nfs4_session *session);
|
||||
extern struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp);
|
||||
extern int nfs4_proc_create_session(struct nfs_client *, struct rpc_cred *);
|
||||
extern int nfs4_proc_destroy_session(struct nfs4_session *, struct rpc_cred *);
|
||||
extern int nfs4_init_session(struct nfs_server *server);
|
||||
extern int nfs4_proc_get_lease_time(struct nfs_client *clp,
|
||||
struct nfs_fsinfo *fsinfo);
|
||||
extern int nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data,
|
||||
@ -280,11 +271,7 @@ static inline int nfs4_setup_sequence(const struct nfs_server *server,
|
||||
struct nfs4_sequence_args *args, struct nfs4_sequence_res *res,
|
||||
struct rpc_task *task)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int nfs4_init_session(struct nfs_server *server)
|
||||
{
|
||||
rpc_call_start(task);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -321,17 +308,20 @@ extern void nfs4_renew_state(struct work_struct *);
|
||||
|
||||
/* nfs4state.c */
|
||||
struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp);
|
||||
struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp);
|
||||
struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp);
|
||||
int nfs4_discover_server_trunking(struct nfs_client *clp,
|
||||
struct nfs_client **);
|
||||
int nfs40_discover_server_trunking(struct nfs_client *clp,
|
||||
struct nfs_client **, struct rpc_cred *);
|
||||
#if defined(CONFIG_NFS_V4_1)
|
||||
struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp);
|
||||
struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp);
|
||||
int nfs41_discover_server_trunking(struct nfs_client *clp,
|
||||
struct nfs_client **, struct rpc_cred *);
|
||||
extern void nfs4_schedule_session_recovery(struct nfs4_session *, int);
|
||||
extern void nfs41_server_notify_target_slotid_update(struct nfs_client *clp);
|
||||
extern void nfs41_server_notify_highest_slotid_update(struct nfs_client *clp);
|
||||
|
||||
#else
|
||||
static inline void nfs4_schedule_session_recovery(struct nfs4_session *session, int err)
|
||||
{
|
||||
@ -349,11 +339,12 @@ extern void nfs4_state_set_mode_locked(struct nfs4_state *, fmode_t);
|
||||
extern void nfs_inode_find_state_and_recover(struct inode *inode,
|
||||
const nfs4_stateid *stateid);
|
||||
extern void nfs4_schedule_lease_recovery(struct nfs_client *);
|
||||
extern int nfs4_wait_clnt_recover(struct nfs_client *clp);
|
||||
extern int nfs4_client_recover_expired_lease(struct nfs_client *clp);
|
||||
extern void nfs4_schedule_state_manager(struct nfs_client *);
|
||||
extern void nfs4_schedule_path_down_recovery(struct nfs_client *clp);
|
||||
extern void nfs4_schedule_stateid_recovery(const struct nfs_server *, struct nfs4_state *);
|
||||
extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags);
|
||||
extern void nfs41_handle_recall_slot(struct nfs_client *clp);
|
||||
extern void nfs41_handle_server_scope(struct nfs_client *,
|
||||
struct nfs41_server_scope **);
|
||||
extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "internal.h"
|
||||
#include "callback.h"
|
||||
#include "delegation.h"
|
||||
#include "nfs4session.h"
|
||||
#include "pnfs.h"
|
||||
#include "netns.h"
|
||||
|
||||
@ -713,10 +714,6 @@ static int nfs4_server_common_setup(struct nfs_server *server,
|
||||
struct nfs_fattr *fattr;
|
||||
int error;
|
||||
|
||||
BUG_ON(!server->nfs_client);
|
||||
BUG_ON(!server->nfs_client->rpc_ops);
|
||||
BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
|
||||
|
||||
/* data servers support only a subset of NFSv4.1 */
|
||||
if (is_ds_only_client(server->nfs_client))
|
||||
return -EPROTONOSUPPORT;
|
||||
|
@ -20,7 +20,6 @@ nfs4_file_open(struct inode *inode, struct file *filp)
|
||||
struct iattr attr;
|
||||
int err;
|
||||
|
||||
BUG_ON(inode != dentry->d_inode);
|
||||
/*
|
||||
* If no cached dentry exists or if it's negative, NFSv4 handled the
|
||||
* opens in ->lookup() or ->create().
|
||||
|
@ -35,6 +35,7 @@
|
||||
|
||||
#include <linux/sunrpc/metrics.h>
|
||||
|
||||
#include "nfs4session.h"
|
||||
#include "internal.h"
|
||||
#include "delegation.h"
|
||||
#include "nfs4filelayout.h"
|
||||
@ -178,7 +179,6 @@ static int filelayout_async_handle_error(struct rpc_task *task,
|
||||
break;
|
||||
case -NFS4ERR_DELAY:
|
||||
case -NFS4ERR_GRACE:
|
||||
case -EKEYEXPIRED:
|
||||
rpc_delay(task, FILELAYOUT_POLL_RETRY_MAX);
|
||||
break;
|
||||
case -NFS4ERR_RETRY_UNCACHED_REP:
|
||||
@ -306,12 +306,10 @@ static void filelayout_read_prepare(struct rpc_task *task, void *data)
|
||||
}
|
||||
rdata->read_done_cb = filelayout_read_done_cb;
|
||||
|
||||
if (nfs41_setup_sequence(rdata->ds_clp->cl_session,
|
||||
&rdata->args.seq_args, &rdata->res.seq_res,
|
||||
task))
|
||||
return;
|
||||
|
||||
rpc_call_start(task);
|
||||
nfs41_setup_sequence(rdata->ds_clp->cl_session,
|
||||
&rdata->args.seq_args,
|
||||
&rdata->res.seq_res,
|
||||
task);
|
||||
}
|
||||
|
||||
static void filelayout_read_call_done(struct rpc_task *task, void *data)
|
||||
@ -408,12 +406,10 @@ static void filelayout_write_prepare(struct rpc_task *task, void *data)
|
||||
rpc_exit(task, 0);
|
||||
return;
|
||||
}
|
||||
if (nfs41_setup_sequence(wdata->ds_clp->cl_session,
|
||||
&wdata->args.seq_args, &wdata->res.seq_res,
|
||||
task))
|
||||
return;
|
||||
|
||||
rpc_call_start(task);
|
||||
nfs41_setup_sequence(wdata->ds_clp->cl_session,
|
||||
&wdata->args.seq_args,
|
||||
&wdata->res.seq_res,
|
||||
task);
|
||||
}
|
||||
|
||||
static void filelayout_write_call_done(struct rpc_task *task, void *data)
|
||||
@ -449,12 +445,10 @@ static void filelayout_commit_prepare(struct rpc_task *task, void *data)
|
||||
{
|
||||
struct nfs_commit_data *wdata = data;
|
||||
|
||||
if (nfs41_setup_sequence(wdata->ds_clp->cl_session,
|
||||
&wdata->args.seq_args, &wdata->res.seq_res,
|
||||
task))
|
||||
return;
|
||||
|
||||
rpc_call_start(task);
|
||||
nfs41_setup_sequence(wdata->ds_clp->cl_session,
|
||||
&wdata->args.seq_args,
|
||||
&wdata->res.seq_res,
|
||||
task);
|
||||
}
|
||||
|
||||
static void filelayout_write_commit_done(struct rpc_task *task, void *data)
|
||||
@ -512,7 +506,6 @@ filelayout_read_pagelist(struct nfs_read_data *data)
|
||||
loff_t offset = data->args.offset;
|
||||
u32 j, idx;
|
||||
struct nfs_fh *fh;
|
||||
int status;
|
||||
|
||||
dprintk("--> %s ino %lu pgbase %u req %Zu@%llu\n",
|
||||
__func__, hdr->inode->i_ino,
|
||||
@ -538,9 +531,8 @@ filelayout_read_pagelist(struct nfs_read_data *data)
|
||||
data->mds_offset = offset;
|
||||
|
||||
/* Perform an asynchronous read to ds */
|
||||
status = nfs_initiate_read(ds->ds_clp->cl_rpcclient, data,
|
||||
nfs_initiate_read(ds->ds_clp->cl_rpcclient, data,
|
||||
&filelayout_read_call_ops, RPC_TASK_SOFTCONN);
|
||||
BUG_ON(status != 0);
|
||||
return PNFS_ATTEMPTED;
|
||||
}
|
||||
|
||||
@ -554,7 +546,6 @@ filelayout_write_pagelist(struct nfs_write_data *data, int sync)
|
||||
loff_t offset = data->args.offset;
|
||||
u32 j, idx;
|
||||
struct nfs_fh *fh;
|
||||
int status;
|
||||
|
||||
/* Retrieve the correct rpc_client for the byte range */
|
||||
j = nfs4_fl_calc_j_index(lseg, offset);
|
||||
@ -579,10 +570,9 @@ filelayout_write_pagelist(struct nfs_write_data *data, int sync)
|
||||
data->args.offset = filelayout_get_dserver_offset(lseg, offset);
|
||||
|
||||
/* Perform an asynchronous write */
|
||||
status = nfs_initiate_write(ds->ds_clp->cl_rpcclient, data,
|
||||
nfs_initiate_write(ds->ds_clp->cl_rpcclient, data,
|
||||
&filelayout_write_call_ops, sync,
|
||||
RPC_TASK_SOFTCONN);
|
||||
BUG_ON(status != 0);
|
||||
return PNFS_ATTEMPTED;
|
||||
}
|
||||
|
||||
@ -909,7 +899,7 @@ static void
|
||||
filelayout_pg_init_read(struct nfs_pageio_descriptor *pgio,
|
||||
struct nfs_page *req)
|
||||
{
|
||||
BUG_ON(pgio->pg_lseg != NULL);
|
||||
WARN_ON_ONCE(pgio->pg_lseg != NULL);
|
||||
|
||||
if (req->wb_offset != req->wb_pgbase) {
|
||||
/*
|
||||
@ -939,7 +929,7 @@ filelayout_pg_init_write(struct nfs_pageio_descriptor *pgio,
|
||||
struct nfs_commit_info cinfo;
|
||||
int status;
|
||||
|
||||
BUG_ON(pgio->pg_lseg != NULL);
|
||||
WARN_ON_ONCE(pgio->pg_lseg != NULL);
|
||||
|
||||
if (req->wb_offset != req->wb_pgbase)
|
||||
goto out_mds;
|
||||
@ -1187,7 +1177,6 @@ static void filelayout_recover_commit_reqs(struct list_head *dst,
|
||||
*/
|
||||
for (i = 0, b = cinfo->ds->buckets; i < cinfo->ds->nbuckets; i++, b++) {
|
||||
if (transfer_commit_list(&b->written, dst, cinfo, 0)) {
|
||||
BUG_ON(!list_empty(&b->written));
|
||||
pnfs_put_lseg(b->wlseg);
|
||||
b->wlseg = NULL;
|
||||
}
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "nfs4session.h"
|
||||
#include "nfs4filelayout.h"
|
||||
|
||||
#define NFSDBG_FACILITY NFSDBG_PNFS_LD
|
||||
@ -162,8 +163,6 @@ nfs4_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds)
|
||||
dprintk("--> %s DS %s au_flavor %d\n", __func__, ds->ds_remotestr,
|
||||
mds_srv->nfs_client->cl_rpcclient->cl_auth->au_flavor);
|
||||
|
||||
BUG_ON(list_empty(&ds->ds_addrs));
|
||||
|
||||
list_for_each_entry(da, &ds->ds_addrs, da_node) {
|
||||
dprintk("%s: DS %s: trying address %s\n",
|
||||
__func__, ds->ds_remotestr, da->da_remotestr);
|
||||
|
File diff suppressed because it is too large
Load Diff
552
fs/nfs/nfs4session.c
Normal file
552
fs/nfs/nfs4session.c
Normal file
@ -0,0 +1,552 @@
|
||||
/*
|
||||
* fs/nfs/nfs4session.c
|
||||
*
|
||||
* Copyright (c) 2012 Trond Myklebust <Trond.Myklebust@netapp.com>
|
||||
*
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sunrpc/sched.h>
|
||||
#include <linux/sunrpc/bc_xprt.h>
|
||||
#include <linux/nfs.h>
|
||||
#include <linux/nfs4.h>
|
||||
#include <linux/nfs_fs.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "nfs4_fs.h"
|
||||
#include "internal.h"
|
||||
#include "nfs4session.h"
|
||||
#include "callback.h"
|
||||
|
||||
#define NFSDBG_FACILITY NFSDBG_STATE
|
||||
|
||||
/*
|
||||
* nfs4_shrink_slot_table - free retired slots from the slot table
|
||||
*/
|
||||
static void nfs4_shrink_slot_table(struct nfs4_slot_table *tbl, u32 newsize)
|
||||
{
|
||||
struct nfs4_slot **p;
|
||||
if (newsize >= tbl->max_slots)
|
||||
return;
|
||||
|
||||
p = &tbl->slots;
|
||||
while (newsize--)
|
||||
p = &(*p)->next;
|
||||
while (*p) {
|
||||
struct nfs4_slot *slot = *p;
|
||||
|
||||
*p = slot->next;
|
||||
kfree(slot);
|
||||
tbl->max_slots--;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* nfs4_free_slot - free a slot and efficiently update slot table.
|
||||
*
|
||||
* freeing a slot is trivially done by clearing its respective bit
|
||||
* in the bitmap.
|
||||
* If the freed slotid equals highest_used_slotid we want to update it
|
||||
* so that the server would be able to size down the slot table if needed,
|
||||
* otherwise we know that the highest_used_slotid is still in use.
|
||||
* When updating highest_used_slotid there may be "holes" in the bitmap
|
||||
* so we need to scan down from highest_used_slotid to 0 looking for the now
|
||||
* highest slotid in use.
|
||||
* If none found, highest_used_slotid is set to NFS4_NO_SLOT.
|
||||
*
|
||||
* Must be called while holding tbl->slot_tbl_lock
|
||||
*/
|
||||
void nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot)
|
||||
{
|
||||
u32 slotid = slot->slot_nr;
|
||||
|
||||
/* clear used bit in bitmap */
|
||||
__clear_bit(slotid, tbl->used_slots);
|
||||
|
||||
/* update highest_used_slotid when it is freed */
|
||||
if (slotid == tbl->highest_used_slotid) {
|
||||
u32 new_max = find_last_bit(tbl->used_slots, slotid);
|
||||
if (new_max < slotid)
|
||||
tbl->highest_used_slotid = new_max;
|
||||
else {
|
||||
tbl->highest_used_slotid = NFS4_NO_SLOT;
|
||||
nfs4_session_drain_complete(tbl->session, tbl);
|
||||
}
|
||||
}
|
||||
dprintk("%s: slotid %u highest_used_slotid %d\n", __func__,
|
||||
slotid, tbl->highest_used_slotid);
|
||||
}
|
||||
|
||||
static struct nfs4_slot *nfs4_new_slot(struct nfs4_slot_table *tbl,
|
||||
u32 slotid, u32 seq_init, gfp_t gfp_mask)
|
||||
{
|
||||
struct nfs4_slot *slot;
|
||||
|
||||
slot = kzalloc(sizeof(*slot), gfp_mask);
|
||||
if (slot) {
|
||||
slot->table = tbl;
|
||||
slot->slot_nr = slotid;
|
||||
slot->seq_nr = seq_init;
|
||||
}
|
||||
return slot;
|
||||
}
|
||||
|
||||
static struct nfs4_slot *nfs4_find_or_create_slot(struct nfs4_slot_table *tbl,
|
||||
u32 slotid, u32 seq_init, gfp_t gfp_mask)
|
||||
{
|
||||
struct nfs4_slot **p, *slot;
|
||||
|
||||
p = &tbl->slots;
|
||||
for (;;) {
|
||||
if (*p == NULL) {
|
||||
*p = nfs4_new_slot(tbl, tbl->max_slots,
|
||||
seq_init, gfp_mask);
|
||||
if (*p == NULL)
|
||||
break;
|
||||
tbl->max_slots++;
|
||||
}
|
||||
slot = *p;
|
||||
if (slot->slot_nr == slotid)
|
||||
return slot;
|
||||
p = &slot->next;
|
||||
}
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
/*
|
||||
* nfs4_alloc_slot - efficiently look for a free slot
|
||||
*
|
||||
* nfs4_alloc_slot looks for an unset bit in the used_slots bitmap.
|
||||
* If found, we mark the slot as used, update the highest_used_slotid,
|
||||
* and respectively set up the sequence operation args.
|
||||
*
|
||||
* Note: must be called with under the slot_tbl_lock.
|
||||
*/
|
||||
struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl)
|
||||
{
|
||||
struct nfs4_slot *ret = ERR_PTR(-EBUSY);
|
||||
u32 slotid;
|
||||
|
||||
dprintk("--> %s used_slots=%04lx highest_used=%u max_slots=%u\n",
|
||||
__func__, tbl->used_slots[0], tbl->highest_used_slotid,
|
||||
tbl->max_slotid + 1);
|
||||
slotid = find_first_zero_bit(tbl->used_slots, tbl->max_slotid + 1);
|
||||
if (slotid > tbl->max_slotid)
|
||||
goto out;
|
||||
ret = nfs4_find_or_create_slot(tbl, slotid, 1, GFP_NOWAIT);
|
||||
if (IS_ERR(ret))
|
||||
goto out;
|
||||
__set_bit(slotid, tbl->used_slots);
|
||||
if (slotid > tbl->highest_used_slotid ||
|
||||
tbl->highest_used_slotid == NFS4_NO_SLOT)
|
||||
tbl->highest_used_slotid = slotid;
|
||||
ret->generation = tbl->generation;
|
||||
|
||||
out:
|
||||
dprintk("<-- %s used_slots=%04lx highest_used=%d slotid=%d \n",
|
||||
__func__, tbl->used_slots[0], tbl->highest_used_slotid,
|
||||
!IS_ERR(ret) ? ret->slot_nr : -1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nfs4_grow_slot_table(struct nfs4_slot_table *tbl,
|
||||
u32 max_reqs, u32 ivalue)
|
||||
{
|
||||
if (max_reqs <= tbl->max_slots)
|
||||
return 0;
|
||||
if (!IS_ERR(nfs4_find_or_create_slot(tbl, max_reqs - 1, ivalue, GFP_NOFS)))
|
||||
return 0;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void nfs4_reset_slot_table(struct nfs4_slot_table *tbl,
|
||||
u32 server_highest_slotid,
|
||||
u32 ivalue)
|
||||
{
|
||||
struct nfs4_slot **p;
|
||||
|
||||
nfs4_shrink_slot_table(tbl, server_highest_slotid + 1);
|
||||
p = &tbl->slots;
|
||||
while (*p) {
|
||||
(*p)->seq_nr = ivalue;
|
||||
(*p)->interrupted = 0;
|
||||
p = &(*p)->next;
|
||||
}
|
||||
tbl->highest_used_slotid = NFS4_NO_SLOT;
|
||||
tbl->target_highest_slotid = server_highest_slotid;
|
||||
tbl->server_highest_slotid = server_highest_slotid;
|
||||
tbl->d_target_highest_slotid = 0;
|
||||
tbl->d2_target_highest_slotid = 0;
|
||||
tbl->max_slotid = server_highest_slotid;
|
||||
}
|
||||
|
||||
/*
|
||||
* (re)Initialise a slot table
|
||||
*/
|
||||
static int nfs4_realloc_slot_table(struct nfs4_slot_table *tbl,
|
||||
u32 max_reqs, u32 ivalue)
|
||||
{
|
||||
int ret;
|
||||
|
||||
dprintk("--> %s: max_reqs=%u, tbl->max_slots %d\n", __func__,
|
||||
max_reqs, tbl->max_slots);
|
||||
|
||||
if (max_reqs > NFS4_MAX_SLOT_TABLE)
|
||||
max_reqs = NFS4_MAX_SLOT_TABLE;
|
||||
|
||||
ret = nfs4_grow_slot_table(tbl, max_reqs, ivalue);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
spin_lock(&tbl->slot_tbl_lock);
|
||||
nfs4_reset_slot_table(tbl, max_reqs - 1, ivalue);
|
||||
spin_unlock(&tbl->slot_tbl_lock);
|
||||
|
||||
dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
|
||||
tbl, tbl->slots, tbl->max_slots);
|
||||
out:
|
||||
dprintk("<-- %s: return %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Destroy the slot table */
|
||||
static void nfs4_destroy_slot_tables(struct nfs4_session *session)
|
||||
{
|
||||
nfs4_shrink_slot_table(&session->fc_slot_table, 0);
|
||||
nfs4_shrink_slot_table(&session->bc_slot_table, 0);
|
||||
}
|
||||
|
||||
static bool nfs41_assign_slot(struct rpc_task *task, void *pslot)
|
||||
{
|
||||
struct nfs4_sequence_args *args = task->tk_msg.rpc_argp;
|
||||
struct nfs4_sequence_res *res = task->tk_msg.rpc_resp;
|
||||
struct nfs4_slot *slot = pslot;
|
||||
struct nfs4_slot_table *tbl = slot->table;
|
||||
|
||||
if (nfs4_session_draining(tbl->session) && !args->sa_privileged)
|
||||
return false;
|
||||
slot->generation = tbl->generation;
|
||||
args->sa_slot = slot;
|
||||
res->sr_timestamp = jiffies;
|
||||
res->sr_slot = slot;
|
||||
res->sr_status_flags = 0;
|
||||
res->sr_status = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __nfs41_wake_and_assign_slot(struct nfs4_slot_table *tbl,
|
||||
struct nfs4_slot *slot)
|
||||
{
|
||||
if (rpc_wake_up_first(&tbl->slot_tbl_waitq, nfs41_assign_slot, slot))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool nfs41_wake_and_assign_slot(struct nfs4_slot_table *tbl,
|
||||
struct nfs4_slot *slot)
|
||||
{
|
||||
if (slot->slot_nr > tbl->max_slotid)
|
||||
return false;
|
||||
return __nfs41_wake_and_assign_slot(tbl, slot);
|
||||
}
|
||||
|
||||
static bool nfs41_try_wake_next_slot_table_entry(struct nfs4_slot_table *tbl)
|
||||
{
|
||||
struct nfs4_slot *slot = nfs4_alloc_slot(tbl);
|
||||
if (!IS_ERR(slot)) {
|
||||
bool ret = __nfs41_wake_and_assign_slot(tbl, slot);
|
||||
if (ret)
|
||||
return ret;
|
||||
nfs4_free_slot(tbl, slot);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void nfs41_wake_slot_table(struct nfs4_slot_table *tbl)
|
||||
{
|
||||
for (;;) {
|
||||
if (!nfs41_try_wake_next_slot_table_entry(tbl))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void nfs41_set_max_slotid_locked(struct nfs4_slot_table *tbl,
|
||||
u32 target_highest_slotid)
|
||||
{
|
||||
u32 max_slotid;
|
||||
|
||||
max_slotid = min(NFS4_MAX_SLOT_TABLE - 1, target_highest_slotid);
|
||||
if (max_slotid > tbl->server_highest_slotid)
|
||||
max_slotid = tbl->server_highest_slotid;
|
||||
if (max_slotid > tbl->target_highest_slotid)
|
||||
max_slotid = tbl->target_highest_slotid;
|
||||
tbl->max_slotid = max_slotid;
|
||||
nfs41_wake_slot_table(tbl);
|
||||
}
|
||||
|
||||
/* Update the client's idea of target_highest_slotid */
|
||||
static void nfs41_set_target_slotid_locked(struct nfs4_slot_table *tbl,
|
||||
u32 target_highest_slotid)
|
||||
{
|
||||
if (tbl->target_highest_slotid == target_highest_slotid)
|
||||
return;
|
||||
tbl->target_highest_slotid = target_highest_slotid;
|
||||
tbl->generation++;
|
||||
}
|
||||
|
||||
void nfs41_set_target_slotid(struct nfs4_slot_table *tbl,
|
||||
u32 target_highest_slotid)
|
||||
{
|
||||
spin_lock(&tbl->slot_tbl_lock);
|
||||
nfs41_set_target_slotid_locked(tbl, target_highest_slotid);
|
||||
tbl->d_target_highest_slotid = 0;
|
||||
tbl->d2_target_highest_slotid = 0;
|
||||
nfs41_set_max_slotid_locked(tbl, target_highest_slotid);
|
||||
spin_unlock(&tbl->slot_tbl_lock);
|
||||
}
|
||||
|
||||
static void nfs41_set_server_slotid_locked(struct nfs4_slot_table *tbl,
|
||||
u32 highest_slotid)
|
||||
{
|
||||
if (tbl->server_highest_slotid == highest_slotid)
|
||||
return;
|
||||
if (tbl->highest_used_slotid > highest_slotid)
|
||||
return;
|
||||
/* Deallocate slots */
|
||||
nfs4_shrink_slot_table(tbl, highest_slotid + 1);
|
||||
tbl->server_highest_slotid = highest_slotid;
|
||||
}
|
||||
|
||||
static s32 nfs41_derivative_target_slotid(s32 s1, s32 s2)
|
||||
{
|
||||
s1 -= s2;
|
||||
if (s1 == 0)
|
||||
return 0;
|
||||
if (s1 < 0)
|
||||
return (s1 - 1) >> 1;
|
||||
return (s1 + 1) >> 1;
|
||||
}
|
||||
|
||||
static int nfs41_sign_s32(s32 s1)
|
||||
{
|
||||
if (s1 > 0)
|
||||
return 1;
|
||||
if (s1 < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool nfs41_same_sign_or_zero_s32(s32 s1, s32 s2)
|
||||
{
|
||||
if (!s1 || !s2)
|
||||
return true;
|
||||
return nfs41_sign_s32(s1) == nfs41_sign_s32(s2);
|
||||
}
|
||||
|
||||
/* Try to eliminate outliers by checking for sharp changes in the
|
||||
* derivatives and second derivatives
|
||||
*/
|
||||
static bool nfs41_is_outlier_target_slotid(struct nfs4_slot_table *tbl,
|
||||
u32 new_target)
|
||||
{
|
||||
s32 d_target, d2_target;
|
||||
bool ret = true;
|
||||
|
||||
d_target = nfs41_derivative_target_slotid(new_target,
|
||||
tbl->target_highest_slotid);
|
||||
d2_target = nfs41_derivative_target_slotid(d_target,
|
||||
tbl->d_target_highest_slotid);
|
||||
/* Is first derivative same sign? */
|
||||
if (nfs41_same_sign_or_zero_s32(d_target, tbl->d_target_highest_slotid))
|
||||
ret = false;
|
||||
/* Is second derivative same sign? */
|
||||
if (nfs41_same_sign_or_zero_s32(d2_target, tbl->d2_target_highest_slotid))
|
||||
ret = false;
|
||||
tbl->d_target_highest_slotid = d_target;
|
||||
tbl->d2_target_highest_slotid = d2_target;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void nfs41_update_target_slotid(struct nfs4_slot_table *tbl,
|
||||
struct nfs4_slot *slot,
|
||||
struct nfs4_sequence_res *res)
|
||||
{
|
||||
spin_lock(&tbl->slot_tbl_lock);
|
||||
if (!nfs41_is_outlier_target_slotid(tbl, res->sr_target_highest_slotid))
|
||||
nfs41_set_target_slotid_locked(tbl, res->sr_target_highest_slotid);
|
||||
if (tbl->generation == slot->generation)
|
||||
nfs41_set_server_slotid_locked(tbl, res->sr_highest_slotid);
|
||||
nfs41_set_max_slotid_locked(tbl, res->sr_target_highest_slotid);
|
||||
spin_unlock(&tbl->slot_tbl_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize or reset the forechannel and backchannel tables
|
||||
*/
|
||||
int nfs4_setup_session_slot_tables(struct nfs4_session *ses)
|
||||
{
|
||||
struct nfs4_slot_table *tbl;
|
||||
int status;
|
||||
|
||||
dprintk("--> %s\n", __func__);
|
||||
/* Fore channel */
|
||||
tbl = &ses->fc_slot_table;
|
||||
tbl->session = ses;
|
||||
status = nfs4_realloc_slot_table(tbl, ses->fc_attrs.max_reqs, 1);
|
||||
if (status) /* -ENOMEM */
|
||||
return status;
|
||||
/* Back channel */
|
||||
tbl = &ses->bc_slot_table;
|
||||
tbl->session = ses;
|
||||
status = nfs4_realloc_slot_table(tbl, ses->bc_attrs.max_reqs, 0);
|
||||
if (status && tbl->slots == NULL)
|
||||
/* Fore and back channel share a connection so get
|
||||
* both slot tables or neither */
|
||||
nfs4_destroy_slot_tables(ses);
|
||||
return status;
|
||||
}
|
||||
|
||||
struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
|
||||
{
|
||||
struct nfs4_session *session;
|
||||
struct nfs4_slot_table *tbl;
|
||||
|
||||
session = kzalloc(sizeof(struct nfs4_session), GFP_NOFS);
|
||||
if (!session)
|
||||
return NULL;
|
||||
|
||||
tbl = &session->fc_slot_table;
|
||||
tbl->highest_used_slotid = NFS4_NO_SLOT;
|
||||
spin_lock_init(&tbl->slot_tbl_lock);
|
||||
rpc_init_priority_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table");
|
||||
init_completion(&tbl->complete);
|
||||
|
||||
tbl = &session->bc_slot_table;
|
||||
tbl->highest_used_slotid = NFS4_NO_SLOT;
|
||||
spin_lock_init(&tbl->slot_tbl_lock);
|
||||
rpc_init_wait_queue(&tbl->slot_tbl_waitq, "BackChannel Slot table");
|
||||
init_completion(&tbl->complete);
|
||||
|
||||
session->session_state = 1<<NFS4_SESSION_INITING;
|
||||
|
||||
session->clp = clp;
|
||||
return session;
|
||||
}
|
||||
|
||||
void nfs4_destroy_session(struct nfs4_session *session)
|
||||
{
|
||||
struct rpc_xprt *xprt;
|
||||
struct rpc_cred *cred;
|
||||
|
||||
cred = nfs4_get_exchange_id_cred(session->clp);
|
||||
nfs4_proc_destroy_session(session, cred);
|
||||
if (cred)
|
||||
put_rpccred(cred);
|
||||
|
||||
rcu_read_lock();
|
||||
xprt = rcu_dereference(session->clp->cl_rpcclient->cl_xprt);
|
||||
rcu_read_unlock();
|
||||
dprintk("%s Destroy backchannel for xprt %p\n",
|
||||
__func__, xprt);
|
||||
xprt_destroy_backchannel(xprt, NFS41_BC_MIN_CALLBACKS);
|
||||
nfs4_destroy_slot_tables(session);
|
||||
kfree(session);
|
||||
}
|
||||
|
||||
/*
|
||||
* With sessions, the client is not marked ready until after a
|
||||
* successful EXCHANGE_ID and CREATE_SESSION.
|
||||
*
|
||||
* Map errors cl_cons_state errors to EPROTONOSUPPORT to indicate
|
||||
* other versions of NFS can be tried.
|
||||
*/
|
||||
static int nfs41_check_session_ready(struct nfs_client *clp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (clp->cl_cons_state == NFS_CS_SESSION_INITING) {
|
||||
ret = nfs4_client_recover_expired_lease(clp);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
if (clp->cl_cons_state < NFS_CS_READY)
|
||||
return -EPROTONOSUPPORT;
|
||||
smp_rmb();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nfs4_init_session(struct nfs_server *server)
|
||||
{
|
||||
struct nfs_client *clp = server->nfs_client;
|
||||
struct nfs4_session *session;
|
||||
unsigned int target_max_rqst_sz = NFS_MAX_FILE_IO_SIZE;
|
||||
unsigned int target_max_resp_sz = NFS_MAX_FILE_IO_SIZE;
|
||||
|
||||
if (!nfs4_has_session(clp))
|
||||
return 0;
|
||||
|
||||
if (server->rsize != 0)
|
||||
target_max_resp_sz = server->rsize;
|
||||
target_max_resp_sz += nfs41_maxread_overhead;
|
||||
|
||||
if (server->wsize != 0)
|
||||
target_max_rqst_sz = server->wsize;
|
||||
target_max_rqst_sz += nfs41_maxwrite_overhead;
|
||||
|
||||
session = clp->cl_session;
|
||||
spin_lock(&clp->cl_lock);
|
||||
if (test_and_clear_bit(NFS4_SESSION_INITING, &session->session_state)) {
|
||||
/* Initialise targets and channel attributes */
|
||||
session->fc_target_max_rqst_sz = target_max_rqst_sz;
|
||||
session->fc_attrs.max_rqst_sz = target_max_rqst_sz;
|
||||
session->fc_target_max_resp_sz = target_max_resp_sz;
|
||||
session->fc_attrs.max_resp_sz = target_max_resp_sz;
|
||||
} else {
|
||||
/* Just adjust the targets */
|
||||
if (target_max_rqst_sz > session->fc_target_max_rqst_sz) {
|
||||
session->fc_target_max_rqst_sz = target_max_rqst_sz;
|
||||
set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state);
|
||||
}
|
||||
if (target_max_resp_sz > session->fc_target_max_resp_sz) {
|
||||
session->fc_target_max_resp_sz = target_max_resp_sz;
|
||||
set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state);
|
||||
}
|
||||
}
|
||||
spin_unlock(&clp->cl_lock);
|
||||
|
||||
if (test_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state))
|
||||
nfs4_schedule_lease_recovery(clp);
|
||||
|
||||
return nfs41_check_session_ready(clp);
|
||||
}
|
||||
|
||||
int nfs4_init_ds_session(struct nfs_client *clp, unsigned long lease_time)
|
||||
{
|
||||
struct nfs4_session *session = clp->cl_session;
|
||||
int ret;
|
||||
|
||||
spin_lock(&clp->cl_lock);
|
||||
if (test_and_clear_bit(NFS4_SESSION_INITING, &session->session_state)) {
|
||||
/*
|
||||
* Do not set NFS_CS_CHECK_LEASE_TIME instead set the
|
||||
* DS lease to be equal to the MDS lease.
|
||||
*/
|
||||
clp->cl_lease_time = lease_time;
|
||||
clp->cl_last_renewal = jiffies;
|
||||
}
|
||||
spin_unlock(&clp->cl_lock);
|
||||
|
||||
ret = nfs41_check_session_ready(clp);
|
||||
if (ret)
|
||||
return ret;
|
||||
/* Test for the DS role */
|
||||
if (!is_ds_client(clp))
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs4_init_ds_session);
|
||||
|
||||
|
142
fs/nfs/nfs4session.h
Normal file
142
fs/nfs/nfs4session.h
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* fs/nfs/nfs4session.h
|
||||
*
|
||||
* Copyright (c) 2012 Trond Myklebust <Trond.Myklebust@netapp.com>
|
||||
*
|
||||
*/
|
||||
#ifndef __LINUX_FS_NFS_NFS4SESSION_H
|
||||
#define __LINUX_FS_NFS_NFS4SESSION_H
|
||||
|
||||
/* maximum number of slots to use */
|
||||
#define NFS4_DEF_SLOT_TABLE_SIZE (16U)
|
||||
#define NFS4_MAX_SLOT_TABLE (1024U)
|
||||
#define NFS4_NO_SLOT ((u32)-1)
|
||||
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
|
||||
/* Sessions slot seqid */
|
||||
struct nfs4_slot {
|
||||
struct nfs4_slot_table *table;
|
||||
struct nfs4_slot *next;
|
||||
unsigned long generation;
|
||||
u32 slot_nr;
|
||||
u32 seq_nr;
|
||||
unsigned int interrupted : 1;
|
||||
};
|
||||
|
||||
/* Sessions */
|
||||
#define SLOT_TABLE_SZ DIV_ROUND_UP(NFS4_MAX_SLOT_TABLE, 8*sizeof(long))
|
||||
struct nfs4_slot_table {
|
||||
struct nfs4_session *session; /* Parent session */
|
||||
struct nfs4_slot *slots; /* seqid per slot */
|
||||
unsigned long used_slots[SLOT_TABLE_SZ]; /* used/unused bitmap */
|
||||
spinlock_t slot_tbl_lock;
|
||||
struct rpc_wait_queue slot_tbl_waitq; /* allocators may wait here */
|
||||
u32 max_slots; /* # slots in table */
|
||||
u32 max_slotid; /* Max allowed slotid value */
|
||||
u32 highest_used_slotid; /* sent to server on each SEQ.
|
||||
* op for dynamic resizing */
|
||||
u32 target_highest_slotid; /* Server max_slot target */
|
||||
u32 server_highest_slotid; /* Server highest slotid */
|
||||
s32 d_target_highest_slotid; /* Derivative */
|
||||
s32 d2_target_highest_slotid; /* 2nd derivative */
|
||||
unsigned long generation; /* Generation counter for
|
||||
target_highest_slotid */
|
||||
struct completion complete;
|
||||
};
|
||||
|
||||
/*
|
||||
* Session related parameters
|
||||
*/
|
||||
struct nfs4_session {
|
||||
struct nfs4_sessionid sess_id;
|
||||
u32 flags;
|
||||
unsigned long session_state;
|
||||
u32 hash_alg;
|
||||
u32 ssv_len;
|
||||
|
||||
/* The fore and back channel */
|
||||
struct nfs4_channel_attrs fc_attrs;
|
||||
struct nfs4_slot_table fc_slot_table;
|
||||
struct nfs4_channel_attrs bc_attrs;
|
||||
struct nfs4_slot_table bc_slot_table;
|
||||
struct nfs_client *clp;
|
||||
/* Create session arguments */
|
||||
unsigned int fc_target_max_rqst_sz;
|
||||
unsigned int fc_target_max_resp_sz;
|
||||
};
|
||||
|
||||
enum nfs4_session_state {
|
||||
NFS4_SESSION_INITING,
|
||||
NFS4_SESSION_DRAINING,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_NFS_V4_1)
|
||||
extern struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl);
|
||||
extern void nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot);
|
||||
|
||||
extern void nfs41_set_target_slotid(struct nfs4_slot_table *tbl,
|
||||
u32 target_highest_slotid);
|
||||
extern void nfs41_update_target_slotid(struct nfs4_slot_table *tbl,
|
||||
struct nfs4_slot *slot,
|
||||
struct nfs4_sequence_res *res);
|
||||
|
||||
extern int nfs4_setup_session_slot_tables(struct nfs4_session *ses);
|
||||
|
||||
extern struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp);
|
||||
extern void nfs4_destroy_session(struct nfs4_session *session);
|
||||
extern int nfs4_init_session(struct nfs_server *server);
|
||||
extern int nfs4_init_ds_session(struct nfs_client *, unsigned long);
|
||||
|
||||
extern void nfs4_session_drain_complete(struct nfs4_session *session,
|
||||
struct nfs4_slot_table *tbl);
|
||||
|
||||
static inline bool nfs4_session_draining(struct nfs4_session *session)
|
||||
{
|
||||
return !!test_bit(NFS4_SESSION_DRAINING, &session->session_state);
|
||||
}
|
||||
|
||||
bool nfs41_wake_and_assign_slot(struct nfs4_slot_table *tbl,
|
||||
struct nfs4_slot *slot);
|
||||
void nfs41_wake_slot_table(struct nfs4_slot_table *tbl);
|
||||
|
||||
/*
|
||||
* Determine if sessions are in use.
|
||||
*/
|
||||
static inline int nfs4_has_session(const struct nfs_client *clp)
|
||||
{
|
||||
if (clp->cl_session)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int nfs4_has_persistent_session(const struct nfs_client *clp)
|
||||
{
|
||||
if (nfs4_has_session(clp))
|
||||
return (clp->cl_session->flags & SESSION4_PERSIST);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* defined(CONFIG_NFS_V4_1) */
|
||||
|
||||
static inline int nfs4_init_session(struct nfs_server *server)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine if sessions are in use.
|
||||
*/
|
||||
static inline int nfs4_has_session(const struct nfs_client *clp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int nfs4_has_persistent_session(const struct nfs_client *clp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* defined(CONFIG_NFS_V4_1) */
|
||||
#endif /* IS_ENABLED(CONFIG_NFS_V4) */
|
||||
#endif /* __LINUX_FS_NFS_NFS4SESSION_H */
|
@ -57,6 +57,7 @@
|
||||
#include "callback.h"
|
||||
#include "delegation.h"
|
||||
#include "internal.h"
|
||||
#include "nfs4session.h"
|
||||
#include "pnfs.h"
|
||||
#include "netns.h"
|
||||
|
||||
@ -66,7 +67,6 @@
|
||||
|
||||
const nfs4_stateid zero_stateid;
|
||||
static DEFINE_MUTEX(nfs_clid_init_mutex);
|
||||
static LIST_HEAD(nfs4_clientid_list);
|
||||
|
||||
int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
|
||||
{
|
||||
@ -254,24 +254,27 @@ static void nfs4_end_drain_session(struct nfs_client *clp)
|
||||
{
|
||||
struct nfs4_session *ses = clp->cl_session;
|
||||
struct nfs4_slot_table *tbl;
|
||||
int max_slots;
|
||||
|
||||
if (ses == NULL)
|
||||
return;
|
||||
tbl = &ses->fc_slot_table;
|
||||
if (test_and_clear_bit(NFS4_SESSION_DRAINING, &ses->session_state)) {
|
||||
spin_lock(&tbl->slot_tbl_lock);
|
||||
max_slots = tbl->max_slots;
|
||||
while (max_slots--) {
|
||||
if (rpc_wake_up_first(&tbl->slot_tbl_waitq,
|
||||
nfs4_set_task_privileged,
|
||||
NULL) == NULL)
|
||||
break;
|
||||
}
|
||||
nfs41_wake_slot_table(tbl);
|
||||
spin_unlock(&tbl->slot_tbl_lock);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Signal state manager thread if session fore channel is drained
|
||||
*/
|
||||
void nfs4_session_drain_complete(struct nfs4_session *session,
|
||||
struct nfs4_slot_table *tbl)
|
||||
{
|
||||
if (nfs4_session_draining(session))
|
||||
complete(&tbl->complete);
|
||||
}
|
||||
|
||||
static int nfs4_wait_on_slot_tbl(struct nfs4_slot_table *tbl)
|
||||
{
|
||||
spin_lock(&tbl->slot_tbl_lock);
|
||||
@ -303,7 +306,6 @@ static void nfs41_finish_session_reset(struct nfs_client *clp)
|
||||
clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
|
||||
clear_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state);
|
||||
/* create_session negotiated new slot table */
|
||||
clear_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state);
|
||||
clear_bit(NFS4CLNT_BIND_CONN_TO_SESSION, &clp->cl_state);
|
||||
nfs41_setup_state_renewal(clp);
|
||||
}
|
||||
@ -1086,7 +1088,6 @@ void nfs_free_seqid(struct nfs_seqid *seqid)
|
||||
*/
|
||||
static void nfs_increment_seqid(int status, struct nfs_seqid *seqid)
|
||||
{
|
||||
BUG_ON(list_first_entry(&seqid->sequence->list, struct nfs_seqid, list) != seqid);
|
||||
switch (status) {
|
||||
case 0:
|
||||
break;
|
||||
@ -1209,6 +1210,40 @@ void nfs4_schedule_lease_recovery(struct nfs_client *clp)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs4_schedule_lease_recovery);
|
||||
|
||||
int nfs4_wait_clnt_recover(struct nfs_client *clp)
|
||||
{
|
||||
int res;
|
||||
|
||||
might_sleep();
|
||||
|
||||
res = wait_on_bit(&clp->cl_state, NFS4CLNT_MANAGER_RUNNING,
|
||||
nfs_wait_bit_killable, TASK_KILLABLE);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
if (clp->cl_cons_state < 0)
|
||||
return clp->cl_cons_state;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nfs4_client_recover_expired_lease(struct nfs_client *clp)
|
||||
{
|
||||
unsigned int loop;
|
||||
int ret;
|
||||
|
||||
for (loop = NFS4_MAX_LOOP_ON_RECOVER; loop != 0; loop--) {
|
||||
ret = nfs4_wait_clnt_recover(clp);
|
||||
if (ret != 0)
|
||||
break;
|
||||
if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) &&
|
||||
!test_bit(NFS4CLNT_CHECK_LEASE,&clp->cl_state))
|
||||
break;
|
||||
nfs4_schedule_state_manager(clp);
|
||||
ret = -EIO;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* nfs40_handle_cb_pathdown - return all delegations after NFS4ERR_CB_PATH_DOWN
|
||||
* @clp: client to process
|
||||
@ -1401,14 +1436,6 @@ restart:
|
||||
/* Mark the file as being 'closed' */
|
||||
state->state = 0;
|
||||
break;
|
||||
case -EKEYEXPIRED:
|
||||
/*
|
||||
* User RPCSEC_GSS context has expired.
|
||||
* We cannot recover this stateid now, so
|
||||
* skip it and allow recovery thread to
|
||||
* proceed.
|
||||
*/
|
||||
break;
|
||||
case -NFS4ERR_ADMIN_REVOKED:
|
||||
case -NFS4ERR_STALE_STATEID:
|
||||
case -NFS4ERR_BAD_STATEID:
|
||||
@ -1561,14 +1588,6 @@ static void nfs4_state_start_reclaim_nograce(struct nfs_client *clp)
|
||||
nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_nograce);
|
||||
}
|
||||
|
||||
static void nfs4_warn_keyexpired(const char *s)
|
||||
{
|
||||
printk_ratelimited(KERN_WARNING "Error: state manager"
|
||||
" encountered RPCSEC_GSS session"
|
||||
" expired against NFSv4 server %s.\n",
|
||||
s);
|
||||
}
|
||||
|
||||
static int nfs4_recovery_handle_error(struct nfs_client *clp, int error)
|
||||
{
|
||||
switch (error) {
|
||||
@ -1602,10 +1621,6 @@ static int nfs4_recovery_handle_error(struct nfs_client *clp, int error)
|
||||
case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
|
||||
set_bit(NFS4CLNT_BIND_CONN_TO_SESSION, &clp->cl_state);
|
||||
break;
|
||||
case -EKEYEXPIRED:
|
||||
/* Nothing we can do */
|
||||
nfs4_warn_keyexpired(clp->cl_hostname);
|
||||
break;
|
||||
default:
|
||||
dprintk("%s: failed to handle error %d for server %s\n",
|
||||
__func__, error, clp->cl_hostname);
|
||||
@ -1722,8 +1737,6 @@ static int nfs4_handle_reclaim_lease_error(struct nfs_client *clp, int status)
|
||||
dprintk("%s: exit with error %d for server %s\n",
|
||||
__func__, -EPROTONOSUPPORT, clp->cl_hostname);
|
||||
return -EPROTONOSUPPORT;
|
||||
case -EKEYEXPIRED:
|
||||
nfs4_warn_keyexpired(clp->cl_hostname);
|
||||
case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery
|
||||
* in nfs4_exchange_id */
|
||||
default:
|
||||
@ -1876,7 +1889,6 @@ again:
|
||||
break;
|
||||
|
||||
case -EKEYEXPIRED:
|
||||
nfs4_warn_keyexpired(clp->cl_hostname);
|
||||
case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery
|
||||
* in nfs4_exchange_id */
|
||||
status = -EKEYEXPIRED;
|
||||
@ -1907,14 +1919,23 @@ void nfs4_schedule_session_recovery(struct nfs4_session *session, int err)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs4_schedule_session_recovery);
|
||||
|
||||
void nfs41_handle_recall_slot(struct nfs_client *clp)
|
||||
static void nfs41_ping_server(struct nfs_client *clp)
|
||||
{
|
||||
set_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state);
|
||||
dprintk("%s: scheduling slot recall for server %s\n", __func__,
|
||||
clp->cl_hostname);
|
||||
/* Use CHECK_LEASE to ping the server with a SEQUENCE */
|
||||
set_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state);
|
||||
nfs4_schedule_state_manager(clp);
|
||||
}
|
||||
|
||||
void nfs41_server_notify_target_slotid_update(struct nfs_client *clp)
|
||||
{
|
||||
nfs41_ping_server(clp);
|
||||
}
|
||||
|
||||
void nfs41_server_notify_highest_slotid_update(struct nfs_client *clp)
|
||||
{
|
||||
nfs41_ping_server(clp);
|
||||
}
|
||||
|
||||
static void nfs4_reset_all_state(struct nfs_client *clp)
|
||||
{
|
||||
if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) {
|
||||
@ -2024,35 +2045,6 @@ out:
|
||||
return status;
|
||||
}
|
||||
|
||||
static int nfs4_recall_slot(struct nfs_client *clp)
|
||||
{
|
||||
struct nfs4_slot_table *fc_tbl;
|
||||
struct nfs4_slot *new, *old;
|
||||
int i;
|
||||
|
||||
if (!nfs4_has_session(clp))
|
||||
return 0;
|
||||
nfs4_begin_drain_session(clp);
|
||||
fc_tbl = &clp->cl_session->fc_slot_table;
|
||||
new = kmalloc(fc_tbl->target_max_slots * sizeof(struct nfs4_slot),
|
||||
GFP_NOFS);
|
||||
if (!new)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock(&fc_tbl->slot_tbl_lock);
|
||||
for (i = 0; i < fc_tbl->target_max_slots; i++)
|
||||
new[i].seq_nr = fc_tbl->slots[i].seq_nr;
|
||||
old = fc_tbl->slots;
|
||||
fc_tbl->slots = new;
|
||||
fc_tbl->max_slots = fc_tbl->target_max_slots;
|
||||
fc_tbl->target_max_slots = 0;
|
||||
clp->cl_session->fc_attrs.max_reqs = fc_tbl->max_slots;
|
||||
spin_unlock(&fc_tbl->slot_tbl_lock);
|
||||
|
||||
kfree(old);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nfs4_bind_conn_to_session(struct nfs_client *clp)
|
||||
{
|
||||
struct rpc_cred *cred;
|
||||
@ -2083,7 +2075,6 @@ static int nfs4_bind_conn_to_session(struct nfs_client *clp)
|
||||
#else /* CONFIG_NFS_V4_1 */
|
||||
static int nfs4_reset_session(struct nfs_client *clp) { return 0; }
|
||||
static int nfs4_end_drain_session(struct nfs_client *clp) { return 0; }
|
||||
static int nfs4_recall_slot(struct nfs_client *clp) { return 0; }
|
||||
|
||||
static int nfs4_bind_conn_to_session(struct nfs_client *clp)
|
||||
{
|
||||
@ -2115,15 +2106,6 @@ static void nfs4_state_manager(struct nfs_client *clp)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (test_and_clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state)) {
|
||||
section = "check lease";
|
||||
status = nfs4_check_lease(clp);
|
||||
if (status < 0)
|
||||
goto out_error;
|
||||
if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Initialize or reset the session */
|
||||
if (test_and_clear_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state)) {
|
||||
section = "reset session";
|
||||
@ -2144,10 +2126,9 @@ static void nfs4_state_manager(struct nfs_client *clp)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Recall session slots */
|
||||
if (test_and_clear_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state)) {
|
||||
section = "recall slot";
|
||||
status = nfs4_recall_slot(clp);
|
||||
if (test_and_clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state)) {
|
||||
section = "check lease";
|
||||
status = nfs4_check_lease(clp);
|
||||
if (status < 0)
|
||||
goto out_error;
|
||||
continue;
|
||||
|
@ -51,6 +51,7 @@ static const struct super_operations nfs4_sops = {
|
||||
.alloc_inode = nfs_alloc_inode,
|
||||
.destroy_inode = nfs_destroy_inode,
|
||||
.write_inode = nfs4_write_inode,
|
||||
.drop_inode = nfs_drop_inode,
|
||||
.put_super = nfs_put_super,
|
||||
.statfs = nfs_statfs,
|
||||
.evict_inode = nfs4_evict_inode,
|
||||
|
@ -56,6 +56,7 @@
|
||||
|
||||
#include "nfs4_fs.h"
|
||||
#include "internal.h"
|
||||
#include "nfs4session.h"
|
||||
#include "pnfs.h"
|
||||
#include "netns.h"
|
||||
|
||||
@ -270,6 +271,8 @@ static int nfs4_stat_to_errno(int);
|
||||
|
||||
#if defined(CONFIG_NFS_V4_1)
|
||||
#define NFS4_MAX_MACHINE_NAME_LEN (64)
|
||||
#define IMPL_NAME_LIMIT (sizeof(utsname()->sysname) + sizeof(utsname()->release) + \
|
||||
sizeof(utsname()->version) + sizeof(utsname()->machine) + 8)
|
||||
|
||||
#define encode_exchange_id_maxsz (op_encode_hdr_maxsz + \
|
||||
encode_verifier_maxsz + \
|
||||
@ -282,7 +285,7 @@ static int nfs4_stat_to_errno(int);
|
||||
1 /* nii_domain */ + \
|
||||
XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \
|
||||
1 /* nii_name */ + \
|
||||
XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \
|
||||
XDR_QUADLEN(IMPL_NAME_LIMIT) + \
|
||||
3 /* nii_date */)
|
||||
#define decode_exchange_id_maxsz (op_decode_hdr_maxsz + \
|
||||
2 /* eir_clientid */ + \
|
||||
@ -936,7 +939,7 @@ static void encode_compound_hdr(struct xdr_stream *xdr,
|
||||
* but this is not required as a MUST for the server to do so. */
|
||||
hdr->replen = RPC_REPHDRSIZE + auth->au_rslack + 3 + hdr->taglen;
|
||||
|
||||
BUG_ON(hdr->taglen > NFS4_MAXTAGLEN);
|
||||
WARN_ON_ONCE(hdr->taglen > NFS4_MAXTAGLEN);
|
||||
encode_string(xdr, hdr->taglen, hdr->tag);
|
||||
p = reserve_space(xdr, 8);
|
||||
*p++ = cpu_to_be32(hdr->minorversion);
|
||||
@ -955,7 +958,7 @@ static void encode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 op,
|
||||
|
||||
static void encode_nops(struct compound_hdr *hdr)
|
||||
{
|
||||
BUG_ON(hdr->nops > NFS4_MAX_OPS);
|
||||
WARN_ON_ONCE(hdr->nops > NFS4_MAX_OPS);
|
||||
*hdr->nops_p = htonl(hdr->nops);
|
||||
}
|
||||
|
||||
@ -1403,7 +1406,6 @@ static void encode_opentype(struct xdr_stream *xdr, const struct nfs_openargs *a
|
||||
*p = cpu_to_be32(NFS4_OPEN_NOCREATE);
|
||||
break;
|
||||
default:
|
||||
BUG_ON(arg->claim != NFS4_OPEN_CLAIM_NULL);
|
||||
*p = cpu_to_be32(NFS4_OPEN_CREATE);
|
||||
encode_createmode(xdr, arg);
|
||||
}
|
||||
@ -1621,7 +1623,6 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compoun
|
||||
p = reserve_space(xdr, 2*4);
|
||||
*p++ = cpu_to_be32(1);
|
||||
*p = cpu_to_be32(FATTR4_WORD0_ACL);
|
||||
BUG_ON(arg->acl_len % 4);
|
||||
p = reserve_space(xdr, 4);
|
||||
*p = cpu_to_be32(arg->acl_len);
|
||||
xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len);
|
||||
@ -1713,7 +1714,7 @@ static void encode_exchange_id(struct xdr_stream *xdr,
|
||||
struct compound_hdr *hdr)
|
||||
{
|
||||
__be32 *p;
|
||||
char impl_name[NFS4_OPAQUE_LIMIT];
|
||||
char impl_name[IMPL_NAME_LIMIT];
|
||||
int len = 0;
|
||||
|
||||
encode_op_hdr(xdr, OP_EXCHANGE_ID, decode_exchange_id_maxsz, hdr);
|
||||
@ -1728,7 +1729,7 @@ static void encode_exchange_id(struct xdr_stream *xdr,
|
||||
if (send_implementation_id &&
|
||||
sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN) > 1 &&
|
||||
sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN)
|
||||
<= NFS4_OPAQUE_LIMIT + 1)
|
||||
<= sizeof(impl_name) + 1)
|
||||
len = snprintf(impl_name, sizeof(impl_name), "%s %s %s %s",
|
||||
utsname()->sysname, utsname()->release,
|
||||
utsname()->version, utsname()->machine);
|
||||
@ -1835,18 +1836,16 @@ static void encode_sequence(struct xdr_stream *xdr,
|
||||
struct compound_hdr *hdr)
|
||||
{
|
||||
#if defined(CONFIG_NFS_V4_1)
|
||||
struct nfs4_session *session = args->sa_session;
|
||||
struct nfs4_session *session;
|
||||
struct nfs4_slot_table *tp;
|
||||
struct nfs4_slot *slot;
|
||||
struct nfs4_slot *slot = args->sa_slot;
|
||||
__be32 *p;
|
||||
|
||||
if (!session)
|
||||
if (slot == NULL)
|
||||
return;
|
||||
|
||||
tp = &session->fc_slot_table;
|
||||
|
||||
WARN_ON(args->sa_slotid == NFS4_MAX_SLOT_TABLE);
|
||||
slot = tp->slots + args->sa_slotid;
|
||||
tp = slot->table;
|
||||
session = tp->session;
|
||||
|
||||
encode_op_hdr(xdr, OP_SEQUENCE, decode_sequence_maxsz, hdr);
|
||||
|
||||
@ -1860,12 +1859,12 @@ static void encode_sequence(struct xdr_stream *xdr,
|
||||
((u32 *)session->sess_id.data)[1],
|
||||
((u32 *)session->sess_id.data)[2],
|
||||
((u32 *)session->sess_id.data)[3],
|
||||
slot->seq_nr, args->sa_slotid,
|
||||
slot->seq_nr, slot->slot_nr,
|
||||
tp->highest_used_slotid, args->sa_cache_this);
|
||||
p = reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 16);
|
||||
p = xdr_encode_opaque_fixed(p, session->sess_id.data, NFS4_MAX_SESSIONID_LEN);
|
||||
*p++ = cpu_to_be32(slot->seq_nr);
|
||||
*p++ = cpu_to_be32(args->sa_slotid);
|
||||
*p++ = cpu_to_be32(slot->slot_nr);
|
||||
*p++ = cpu_to_be32(tp->highest_used_slotid);
|
||||
*p = cpu_to_be32(args->sa_cache_this);
|
||||
#endif /* CONFIG_NFS_V4_1 */
|
||||
@ -2027,8 +2026,9 @@ static void encode_free_stateid(struct xdr_stream *xdr,
|
||||
static u32 nfs4_xdr_minorversion(const struct nfs4_sequence_args *args)
|
||||
{
|
||||
#if defined(CONFIG_NFS_V4_1)
|
||||
if (args->sa_session)
|
||||
return args->sa_session->clp->cl_mvops->minor_version;
|
||||
|
||||
if (args->sa_slot)
|
||||
return args->sa_slot->table->session->clp->cl_mvops->minor_version;
|
||||
#endif /* CONFIG_NFS_V4_1 */
|
||||
return 0;
|
||||
}
|
||||
@ -5509,12 +5509,13 @@ static int decode_sequence(struct xdr_stream *xdr,
|
||||
struct rpc_rqst *rqstp)
|
||||
{
|
||||
#if defined(CONFIG_NFS_V4_1)
|
||||
struct nfs4_session *session;
|
||||
struct nfs4_sessionid id;
|
||||
u32 dummy;
|
||||
int status;
|
||||
__be32 *p;
|
||||
|
||||
if (!res->sr_session)
|
||||
if (res->sr_slot == NULL)
|
||||
return 0;
|
||||
|
||||
status = decode_op_hdr(xdr, OP_SEQUENCE);
|
||||
@ -5528,8 +5529,9 @@ static int decode_sequence(struct xdr_stream *xdr,
|
||||
* sequence number, the server is looney tunes.
|
||||
*/
|
||||
status = -EREMOTEIO;
|
||||
session = res->sr_slot->table->session;
|
||||
|
||||
if (memcmp(id.data, res->sr_session->sess_id.data,
|
||||
if (memcmp(id.data, session->sess_id.data,
|
||||
NFS4_MAX_SESSIONID_LEN)) {
|
||||
dprintk("%s Invalid session id\n", __func__);
|
||||
goto out_err;
|
||||
@ -5547,14 +5549,14 @@ static int decode_sequence(struct xdr_stream *xdr,
|
||||
}
|
||||
/* slot id */
|
||||
dummy = be32_to_cpup(p++);
|
||||
if (dummy != res->sr_slot - res->sr_session->fc_slot_table.slots) {
|
||||
if (dummy != res->sr_slot->slot_nr) {
|
||||
dprintk("%s Invalid slot id\n", __func__);
|
||||
goto out_err;
|
||||
}
|
||||
/* highest slot id - currently not processed */
|
||||
dummy = be32_to_cpup(p++);
|
||||
/* target highest slot id - currently not processed */
|
||||
dummy = be32_to_cpup(p++);
|
||||
/* highest slot id */
|
||||
res->sr_highest_slotid = be32_to_cpup(p++);
|
||||
/* target highest slot id */
|
||||
res->sr_target_highest_slotid = be32_to_cpup(p++);
|
||||
/* result flags */
|
||||
res->sr_status_flags = be32_to_cpup(p);
|
||||
status = 0;
|
||||
|
@ -148,17 +148,6 @@ end_offset(u64 start, u64 len)
|
||||
return end >= start ? end : NFS4_MAX_UINT64;
|
||||
}
|
||||
|
||||
/* last octet in a range */
|
||||
static inline u64
|
||||
last_byte_offset(u64 start, u64 len)
|
||||
{
|
||||
u64 end;
|
||||
|
||||
BUG_ON(!len);
|
||||
end = start + len;
|
||||
return end > start ? end - 1 : NFS4_MAX_UINT64;
|
||||
}
|
||||
|
||||
static void _fix_verify_io_params(struct pnfs_layout_segment *lseg,
|
||||
struct page ***p_pages, unsigned *p_pgbase,
|
||||
u64 offset, unsigned long count)
|
||||
|
@ -369,17 +369,6 @@ end_offset(u64 start, u64 len)
|
||||
return end >= start ? end : NFS4_MAX_UINT64;
|
||||
}
|
||||
|
||||
/* last octet in a range */
|
||||
static inline u64
|
||||
last_byte_offset(u64 start, u64 len)
|
||||
{
|
||||
u64 end;
|
||||
|
||||
BUG_ON(!len);
|
||||
end = start + len;
|
||||
return end > start ? end - 1 : NFS4_MAX_UINT64;
|
||||
}
|
||||
|
||||
/*
|
||||
* is l2 fully contained in l1?
|
||||
* start1 end1
|
||||
@ -645,7 +634,6 @@ send_layoutget(struct pnfs_layout_hdr *lo,
|
||||
|
||||
dprintk("--> %s\n", __func__);
|
||||
|
||||
BUG_ON(ctx == NULL);
|
||||
lgp = kzalloc(sizeof(*lgp), gfp_flags);
|
||||
if (lgp == NULL)
|
||||
return NULL;
|
||||
@ -1126,7 +1114,6 @@ pnfs_update_layout(struct inode *ino,
|
||||
* chance of a CB_LAYOUTRECALL(FILE) coming in.
|
||||
*/
|
||||
spin_lock(&clp->cl_lock);
|
||||
BUG_ON(!list_empty(&lo->plh_layouts));
|
||||
list_add_tail(&lo->plh_layouts, &server->layouts);
|
||||
spin_unlock(&clp->cl_lock);
|
||||
}
|
||||
@ -1222,7 +1209,7 @@ pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *r
|
||||
{
|
||||
u64 rd_size = req->wb_bytes;
|
||||
|
||||
BUG_ON(pgio->pg_lseg != NULL);
|
||||
WARN_ON_ONCE(pgio->pg_lseg != NULL);
|
||||
|
||||
if (req->wb_offset != req->wb_pgbase) {
|
||||
nfs_pageio_reset_read_mds(pgio);
|
||||
@ -1251,7 +1238,7 @@ void
|
||||
pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio,
|
||||
struct nfs_page *req, u64 wb_size)
|
||||
{
|
||||
BUG_ON(pgio->pg_lseg != NULL);
|
||||
WARN_ON_ONCE(pgio->pg_lseg != NULL);
|
||||
|
||||
if (req->wb_offset != req->wb_pgbase) {
|
||||
nfs_pageio_reset_write_mds(pgio);
|
||||
|
@ -46,39 +46,6 @@
|
||||
|
||||
#define NFSDBG_FACILITY NFSDBG_PROC
|
||||
|
||||
/*
|
||||
* wrapper to handle the -EKEYEXPIRED error message. This should generally
|
||||
* only happen if using krb5 auth and a user's TGT expires. NFSv2 doesn't
|
||||
* support the NFSERR_JUKEBOX error code, but we handle this situation in the
|
||||
* same way that we handle that error with NFSv3.
|
||||
*/
|
||||
static int
|
||||
nfs_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
|
||||
{
|
||||
int res;
|
||||
do {
|
||||
res = rpc_call_sync(clnt, msg, flags);
|
||||
if (res != -EKEYEXPIRED)
|
||||
break;
|
||||
freezable_schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
|
||||
res = -ERESTARTSYS;
|
||||
} while (!fatal_signal_pending(current));
|
||||
return res;
|
||||
}
|
||||
|
||||
#define rpc_call_sync(clnt, msg, flags) nfs_rpc_wrapper(clnt, msg, flags)
|
||||
|
||||
static int
|
||||
nfs_async_handle_expired_key(struct rpc_task *task)
|
||||
{
|
||||
if (task->tk_status != -EKEYEXPIRED)
|
||||
return 0;
|
||||
task->tk_status = 0;
|
||||
rpc_restart_call(task);
|
||||
rpc_delay(task, NFS_JUKEBOX_RETRY_TIME);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Bare-bones access to getattr: this is for nfs_read_super.
|
||||
*/
|
||||
@ -364,8 +331,6 @@ static void nfs_proc_unlink_rpc_prepare(struct rpc_task *task, struct nfs_unlink
|
||||
|
||||
static int nfs_proc_unlink_done(struct rpc_task *task, struct inode *dir)
|
||||
{
|
||||
if (nfs_async_handle_expired_key(task))
|
||||
return 0;
|
||||
nfs_mark_for_revalidate(dir);
|
||||
return 1;
|
||||
}
|
||||
@ -385,8 +350,6 @@ static int
|
||||
nfs_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
|
||||
struct inode *new_dir)
|
||||
{
|
||||
if (nfs_async_handle_expired_key(task))
|
||||
return 0;
|
||||
nfs_mark_for_revalidate(old_dir);
|
||||
nfs_mark_for_revalidate(new_dir);
|
||||
return 1;
|
||||
@ -642,9 +605,6 @@ static int nfs_read_done(struct rpc_task *task, struct nfs_read_data *data)
|
||||
{
|
||||
struct inode *inode = data->header->inode;
|
||||
|
||||
if (nfs_async_handle_expired_key(task))
|
||||
return -EAGAIN;
|
||||
|
||||
nfs_invalidate_atime(inode);
|
||||
if (task->tk_status >= 0) {
|
||||
nfs_refresh_inode(inode, data->res.fattr);
|
||||
@ -671,9 +631,6 @@ static int nfs_write_done(struct rpc_task *task, struct nfs_write_data *data)
|
||||
{
|
||||
struct inode *inode = data->header->inode;
|
||||
|
||||
if (nfs_async_handle_expired_key(task))
|
||||
return -EAGAIN;
|
||||
|
||||
if (task->tk_status >= 0)
|
||||
nfs_post_op_update_inode_force_wcc(inode, data->res.fattr);
|
||||
return 0;
|
||||
|
@ -64,6 +64,7 @@
|
||||
#include "iostat.h"
|
||||
#include "internal.h"
|
||||
#include "fscache.h"
|
||||
#include "nfs4session.h"
|
||||
#include "pnfs.h"
|
||||
#include "nfs.h"
|
||||
|
||||
@ -307,6 +308,7 @@ const struct super_operations nfs_sops = {
|
||||
.alloc_inode = nfs_alloc_inode,
|
||||
.destroy_inode = nfs_destroy_inode,
|
||||
.write_inode = nfs_write_inode,
|
||||
.drop_inode = nfs_drop_inode,
|
||||
.put_super = nfs_put_super,
|
||||
.statfs = nfs_statfs,
|
||||
.evict_inode = nfs_evict_inode,
|
||||
|
@ -202,7 +202,6 @@ out:
|
||||
/* A writeback failed: mark the page as bad, and invalidate the page cache */
|
||||
static void nfs_set_pageerror(struct page *page)
|
||||
{
|
||||
SetPageError(page);
|
||||
nfs_zap_mapping(page_file_mapping(page)->host, page_file_mapping(page));
|
||||
}
|
||||
|
||||
@ -239,21 +238,18 @@ int nfs_congestion_kb;
|
||||
#define NFS_CONGESTION_OFF_THRESH \
|
||||
(NFS_CONGESTION_ON_THRESH - (NFS_CONGESTION_ON_THRESH >> 2))
|
||||
|
||||
static int nfs_set_page_writeback(struct page *page)
|
||||
static void nfs_set_page_writeback(struct page *page)
|
||||
{
|
||||
struct nfs_server *nfss = NFS_SERVER(page_file_mapping(page)->host);
|
||||
int ret = test_set_page_writeback(page);
|
||||
|
||||
if (!ret) {
|
||||
struct inode *inode = page_file_mapping(page)->host;
|
||||
struct nfs_server *nfss = NFS_SERVER(inode);
|
||||
WARN_ON_ONCE(ret != 0);
|
||||
|
||||
if (atomic_long_inc_return(&nfss->writeback) >
|
||||
NFS_CONGESTION_ON_THRESH) {
|
||||
set_bdi_congested(&nfss->backing_dev_info,
|
||||
BLK_RW_ASYNC);
|
||||
}
|
||||
if (atomic_long_inc_return(&nfss->writeback) >
|
||||
NFS_CONGESTION_ON_THRESH) {
|
||||
set_bdi_congested(&nfss->backing_dev_info,
|
||||
BLK_RW_ASYNC);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void nfs_end_page_writeback(struct page *page)
|
||||
@ -315,10 +311,10 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
|
||||
if (IS_ERR(req))
|
||||
goto out;
|
||||
|
||||
ret = nfs_set_page_writeback(page);
|
||||
BUG_ON(ret != 0);
|
||||
BUG_ON(test_bit(PG_CLEAN, &req->wb_flags));
|
||||
nfs_set_page_writeback(page);
|
||||
WARN_ON_ONCE(test_bit(PG_CLEAN, &req->wb_flags));
|
||||
|
||||
ret = 0;
|
||||
if (!nfs_pageio_add_request(pgio, req)) {
|
||||
nfs_redirty_request(req);
|
||||
ret = pgio->pg_error;
|
||||
@ -451,8 +447,6 @@ static void nfs_inode_remove_request(struct nfs_page *req)
|
||||
struct inode *inode = req->wb_context->dentry->d_inode;
|
||||
struct nfs_inode *nfsi = NFS_I(inode);
|
||||
|
||||
BUG_ON (!NFS_WBACK_BUSY(req));
|
||||
|
||||
spin_lock(&inode->i_lock);
|
||||
if (likely(!PageSwapCache(req->wb_page))) {
|
||||
set_page_private(req->wb_page, 0);
|
||||
@ -884,7 +878,7 @@ static bool nfs_write_pageuptodate(struct page *page, struct inode *inode)
|
||||
{
|
||||
if (nfs_have_delegated_attributes(inode))
|
||||
goto out;
|
||||
if (NFS_I(inode)->cache_validity & NFS_INO_REVAL_PAGECACHE)
|
||||
if (NFS_I(inode)->cache_validity & (NFS_INO_INVALID_DATA|NFS_INO_REVAL_PAGECACHE))
|
||||
return false;
|
||||
out:
|
||||
return PageUptodate(page) != 0;
|
||||
@ -1727,7 +1721,6 @@ int nfs_wb_page_cancel(struct inode *inode, struct page *page)
|
||||
struct nfs_page *req;
|
||||
int ret = 0;
|
||||
|
||||
BUG_ON(!PageLocked(page));
|
||||
for (;;) {
|
||||
wait_on_page_writeback(page);
|
||||
req = nfs_page_find_request(page);
|
||||
@ -1829,7 +1822,7 @@ int __init nfs_init_writepagecache(void)
|
||||
goto out_destroy_write_mempool;
|
||||
|
||||
nfs_commit_mempool = mempool_create_slab_pool(MIN_POOL_COMMIT,
|
||||
nfs_wdata_cachep);
|
||||
nfs_cdata_cachep);
|
||||
if (nfs_commit_mempool == NULL)
|
||||
goto out_destroy_commit_cache;
|
||||
|
||||
|
@ -198,51 +198,4 @@ struct nfs_server {
|
||||
#define NFS_CAP_POSIX_LOCK (1U << 14)
|
||||
#define NFS_CAP_UIDGID_NOMAP (1U << 15)
|
||||
|
||||
|
||||
/* maximum number of slots to use */
|
||||
#define NFS4_DEF_SLOT_TABLE_SIZE (16U)
|
||||
#define NFS4_MAX_SLOT_TABLE (256U)
|
||||
#define NFS4_NO_SLOT ((u32)-1)
|
||||
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
|
||||
/* Sessions */
|
||||
#define SLOT_TABLE_SZ DIV_ROUND_UP(NFS4_MAX_SLOT_TABLE, 8*sizeof(long))
|
||||
struct nfs4_slot_table {
|
||||
struct nfs4_slot *slots; /* seqid per slot */
|
||||
unsigned long used_slots[SLOT_TABLE_SZ]; /* used/unused bitmap */
|
||||
spinlock_t slot_tbl_lock;
|
||||
struct rpc_wait_queue slot_tbl_waitq; /* allocators may wait here */
|
||||
u32 max_slots; /* # slots in table */
|
||||
u32 highest_used_slotid; /* sent to server on each SEQ.
|
||||
* op for dynamic resizing */
|
||||
u32 target_max_slots; /* Set by CB_RECALL_SLOT as
|
||||
* the new max_slots */
|
||||
struct completion complete;
|
||||
};
|
||||
|
||||
static inline int slot_idx(struct nfs4_slot_table *tbl, struct nfs4_slot *sp)
|
||||
{
|
||||
return sp - tbl->slots;
|
||||
}
|
||||
|
||||
/*
|
||||
* Session related parameters
|
||||
*/
|
||||
struct nfs4_session {
|
||||
struct nfs4_sessionid sess_id;
|
||||
u32 flags;
|
||||
unsigned long session_state;
|
||||
u32 hash_alg;
|
||||
u32 ssv_len;
|
||||
|
||||
/* The fore and back channel */
|
||||
struct nfs4_channel_attrs fc_attrs;
|
||||
struct nfs4_slot_table fc_slot_table;
|
||||
struct nfs4_channel_attrs bc_attrs;
|
||||
struct nfs4_slot_table bc_slot_table;
|
||||
struct nfs_client *clp;
|
||||
};
|
||||
|
||||
#endif /* CONFIG_NFS_V4 */
|
||||
#endif
|
||||
|
@ -185,23 +185,20 @@ struct nfs4_channel_attrs {
|
||||
u32 max_reqs;
|
||||
};
|
||||
|
||||
/* nfs41 sessions slot seqid */
|
||||
struct nfs4_slot {
|
||||
u32 seq_nr;
|
||||
};
|
||||
|
||||
struct nfs4_slot;
|
||||
struct nfs4_sequence_args {
|
||||
struct nfs4_session *sa_session;
|
||||
u32 sa_slotid;
|
||||
u8 sa_cache_this;
|
||||
struct nfs4_slot *sa_slot;
|
||||
u8 sa_cache_this : 1,
|
||||
sa_privileged : 1;
|
||||
};
|
||||
|
||||
struct nfs4_sequence_res {
|
||||
struct nfs4_session *sr_session;
|
||||
struct nfs4_slot *sr_slot; /* slot used to send request */
|
||||
unsigned long sr_timestamp;
|
||||
int sr_status; /* sequence operation status */
|
||||
unsigned long sr_renewal_time;
|
||||
u32 sr_status_flags;
|
||||
u32 sr_highest_slotid;
|
||||
u32 sr_target_highest_slotid;
|
||||
};
|
||||
|
||||
struct nfs4_get_lease_time_args {
|
||||
@ -209,8 +206,8 @@ struct nfs4_get_lease_time_args {
|
||||
};
|
||||
|
||||
struct nfs4_get_lease_time_res {
|
||||
struct nfs_fsinfo *lr_fsinfo;
|
||||
struct nfs4_sequence_res lr_seq_res;
|
||||
struct nfs_fsinfo *lr_fsinfo;
|
||||
};
|
||||
|
||||
#define PNFS_LAYOUT_MAXSIZE 4096
|
||||
@ -228,23 +225,23 @@ struct pnfs_layout_range {
|
||||
};
|
||||
|
||||
struct nfs4_layoutget_args {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
__u32 type;
|
||||
struct pnfs_layout_range range;
|
||||
__u64 minlength;
|
||||
__u32 maxcount;
|
||||
struct inode *inode;
|
||||
struct nfs_open_context *ctx;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
nfs4_stateid stateid;
|
||||
struct nfs4_layoutdriver_data layout;
|
||||
};
|
||||
|
||||
struct nfs4_layoutget_res {
|
||||
struct nfs4_sequence_res seq_res;
|
||||
__u32 return_on_close;
|
||||
struct pnfs_layout_range range;
|
||||
__u32 type;
|
||||
nfs4_stateid stateid;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
struct nfs4_layoutdriver_data *layoutp;
|
||||
};
|
||||
|
||||
@ -255,38 +252,38 @@ struct nfs4_layoutget {
|
||||
};
|
||||
|
||||
struct nfs4_getdevicelist_args {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
const struct nfs_fh *fh;
|
||||
u32 layoutclass;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs4_getdevicelist_res {
|
||||
struct pnfs_devicelist *devlist;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
struct pnfs_devicelist *devlist;
|
||||
};
|
||||
|
||||
struct nfs4_getdeviceinfo_args {
|
||||
struct pnfs_device *pdev;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
struct pnfs_device *pdev;
|
||||
};
|
||||
|
||||
struct nfs4_getdeviceinfo_res {
|
||||
struct pnfs_device *pdev;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
struct pnfs_device *pdev;
|
||||
};
|
||||
|
||||
struct nfs4_layoutcommit_args {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
nfs4_stateid stateid;
|
||||
__u64 lastbytewritten;
|
||||
struct inode *inode;
|
||||
const u32 *bitmask;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs4_layoutcommit_res {
|
||||
struct nfs4_sequence_res seq_res;
|
||||
struct nfs_fattr *fattr;
|
||||
const struct nfs_server *server;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
int status;
|
||||
};
|
||||
|
||||
@ -300,11 +297,11 @@ struct nfs4_layoutcommit_data {
|
||||
};
|
||||
|
||||
struct nfs4_layoutreturn_args {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
struct pnfs_layout_hdr *layout;
|
||||
struct inode *inode;
|
||||
nfs4_stateid stateid;
|
||||
__u32 layout_type;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs4_layoutreturn_res {
|
||||
@ -330,6 +327,7 @@ struct stateowner_id {
|
||||
* Arguments to the open call.
|
||||
*/
|
||||
struct nfs_openargs {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
const struct nfs_fh * fh;
|
||||
struct nfs_seqid * seqid;
|
||||
int open_flags;
|
||||
@ -350,10 +348,10 @@ struct nfs_openargs {
|
||||
const u32 * bitmask;
|
||||
const u32 * open_bitmap;
|
||||
__u32 claim;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs_openres {
|
||||
struct nfs4_sequence_res seq_res;
|
||||
nfs4_stateid stateid;
|
||||
struct nfs_fh fh;
|
||||
struct nfs4_change_info cinfo;
|
||||
@ -368,7 +366,6 @@ struct nfs_openres {
|
||||
__u32 attrset[NFS4_BITMAP_SIZE];
|
||||
struct nfs4_string *owner;
|
||||
struct nfs4_string *group_owner;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
__u32 access_request;
|
||||
__u32 access_supported;
|
||||
__u32 access_result;
|
||||
@ -392,20 +389,20 @@ struct nfs_open_confirmres {
|
||||
* Arguments to the close call.
|
||||
*/
|
||||
struct nfs_closeargs {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
struct nfs_fh * fh;
|
||||
nfs4_stateid * stateid;
|
||||
struct nfs_seqid * seqid;
|
||||
fmode_t fmode;
|
||||
const u32 * bitmask;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs_closeres {
|
||||
struct nfs4_sequence_res seq_res;
|
||||
nfs4_stateid stateid;
|
||||
struct nfs_fattr * fattr;
|
||||
struct nfs_seqid * seqid;
|
||||
const struct nfs_server *server;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
};
|
||||
/*
|
||||
* * Arguments to the lock,lockt, and locku call.
|
||||
@ -417,6 +414,7 @@ struct nfs_lowner {
|
||||
};
|
||||
|
||||
struct nfs_lock_args {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
struct nfs_fh * fh;
|
||||
struct file_lock * fl;
|
||||
struct nfs_seqid * lock_seqid;
|
||||
@ -427,40 +425,39 @@ struct nfs_lock_args {
|
||||
unsigned char block : 1;
|
||||
unsigned char reclaim : 1;
|
||||
unsigned char new_lock_owner : 1;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs_lock_res {
|
||||
struct nfs4_sequence_res seq_res;
|
||||
nfs4_stateid stateid;
|
||||
struct nfs_seqid * lock_seqid;
|
||||
struct nfs_seqid * open_seqid;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
};
|
||||
|
||||
struct nfs_locku_args {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
struct nfs_fh * fh;
|
||||
struct file_lock * fl;
|
||||
struct nfs_seqid * seqid;
|
||||
nfs4_stateid * stateid;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs_locku_res {
|
||||
struct nfs4_sequence_res seq_res;
|
||||
nfs4_stateid stateid;
|
||||
struct nfs_seqid * seqid;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
};
|
||||
|
||||
struct nfs_lockt_args {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
struct nfs_fh * fh;
|
||||
struct file_lock * fl;
|
||||
struct nfs_lowner lock_owner;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs_lockt_res {
|
||||
struct file_lock * denied; /* LOCK, LOCKT failed */
|
||||
struct nfs4_sequence_res seq_res;
|
||||
struct file_lock * denied; /* LOCK, LOCKT failed */
|
||||
};
|
||||
|
||||
struct nfs_release_lockowner_args {
|
||||
@ -468,22 +465,23 @@ struct nfs_release_lockowner_args {
|
||||
};
|
||||
|
||||
struct nfs4_delegreturnargs {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
const struct nfs_fh *fhandle;
|
||||
const nfs4_stateid *stateid;
|
||||
const u32 * bitmask;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs4_delegreturnres {
|
||||
struct nfs4_sequence_res seq_res;
|
||||
struct nfs_fattr * fattr;
|
||||
const struct nfs_server *server;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
};
|
||||
|
||||
/*
|
||||
* Arguments to the read call.
|
||||
*/
|
||||
struct nfs_readargs {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
struct nfs_fh * fh;
|
||||
struct nfs_open_context *context;
|
||||
struct nfs_lock_context *lock_context;
|
||||
@ -491,20 +489,20 @@ struct nfs_readargs {
|
||||
__u32 count;
|
||||
unsigned int pgbase;
|
||||
struct page ** pages;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs_readres {
|
||||
struct nfs4_sequence_res seq_res;
|
||||
struct nfs_fattr * fattr;
|
||||
__u32 count;
|
||||
int eof;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
};
|
||||
|
||||
/*
|
||||
* Arguments to the write call.
|
||||
*/
|
||||
struct nfs_writeargs {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
struct nfs_fh * fh;
|
||||
struct nfs_open_context *context;
|
||||
struct nfs_lock_context *lock_context;
|
||||
@ -514,7 +512,6 @@ struct nfs_writeargs {
|
||||
unsigned int pgbase;
|
||||
struct page ** pages;
|
||||
const u32 * bitmask;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs_write_verifier {
|
||||
@ -527,65 +524,65 @@ struct nfs_writeverf {
|
||||
};
|
||||
|
||||
struct nfs_writeres {
|
||||
struct nfs4_sequence_res seq_res;
|
||||
struct nfs_fattr * fattr;
|
||||
struct nfs_writeverf * verf;
|
||||
__u32 count;
|
||||
const struct nfs_server *server;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
};
|
||||
|
||||
/*
|
||||
* Arguments to the commit call.
|
||||
*/
|
||||
struct nfs_commitargs {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
struct nfs_fh *fh;
|
||||
__u64 offset;
|
||||
__u32 count;
|
||||
const u32 *bitmask;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs_commitres {
|
||||
struct nfs4_sequence_res seq_res;
|
||||
struct nfs_fattr *fattr;
|
||||
struct nfs_writeverf *verf;
|
||||
const struct nfs_server *server;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
};
|
||||
|
||||
/*
|
||||
* Common arguments to the unlink call
|
||||
*/
|
||||
struct nfs_removeargs {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
const struct nfs_fh *fh;
|
||||
struct qstr name;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs_removeres {
|
||||
struct nfs4_sequence_res seq_res;
|
||||
const struct nfs_server *server;
|
||||
struct nfs_fattr *dir_attr;
|
||||
struct nfs4_change_info cinfo;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
};
|
||||
|
||||
/*
|
||||
* Common arguments to the rename call
|
||||
*/
|
||||
struct nfs_renameargs {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
const struct nfs_fh *old_dir;
|
||||
const struct nfs_fh *new_dir;
|
||||
const struct qstr *old_name;
|
||||
const struct qstr *new_name;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs_renameres {
|
||||
struct nfs4_sequence_res seq_res;
|
||||
const struct nfs_server *server;
|
||||
struct nfs4_change_info old_cinfo;
|
||||
struct nfs_fattr *old_fattr;
|
||||
struct nfs4_change_info new_cinfo;
|
||||
struct nfs_fattr *new_fattr;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -626,20 +623,20 @@ struct nfs_createargs {
|
||||
};
|
||||
|
||||
struct nfs_setattrargs {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
struct nfs_fh * fh;
|
||||
nfs4_stateid stateid;
|
||||
struct iattr * iap;
|
||||
const struct nfs_server * server; /* Needed for name mapping */
|
||||
const u32 * bitmask;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs_setaclargs {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
struct nfs_fh * fh;
|
||||
size_t acl_len;
|
||||
unsigned int acl_pgbase;
|
||||
struct page ** acl_pages;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs_setaclres {
|
||||
@ -647,27 +644,27 @@ struct nfs_setaclres {
|
||||
};
|
||||
|
||||
struct nfs_getaclargs {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
struct nfs_fh * fh;
|
||||
size_t acl_len;
|
||||
unsigned int acl_pgbase;
|
||||
struct page ** acl_pages;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
/* getxattr ACL interface flags */
|
||||
#define NFS4_ACL_TRUNC 0x0001 /* ACL was truncated */
|
||||
struct nfs_getaclres {
|
||||
struct nfs4_sequence_res seq_res;
|
||||
size_t acl_len;
|
||||
size_t acl_data_offset;
|
||||
int acl_flags;
|
||||
struct page * acl_scratch;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
};
|
||||
|
||||
struct nfs_setattrres {
|
||||
struct nfs4_sequence_res seq_res;
|
||||
struct nfs_fattr * fattr;
|
||||
const struct nfs_server * server;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
};
|
||||
|
||||
struct nfs_linkargs {
|
||||
@ -832,21 +829,22 @@ struct nfs3_getaclres {
|
||||
typedef u64 clientid4;
|
||||
|
||||
struct nfs4_accessargs {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
const struct nfs_fh * fh;
|
||||
const u32 * bitmask;
|
||||
u32 access;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs4_accessres {
|
||||
struct nfs4_sequence_res seq_res;
|
||||
const struct nfs_server * server;
|
||||
struct nfs_fattr * fattr;
|
||||
u32 supported;
|
||||
u32 access;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
};
|
||||
|
||||
struct nfs4_create_arg {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
u32 ftype;
|
||||
union {
|
||||
struct {
|
||||
@ -863,88 +861,88 @@ struct nfs4_create_arg {
|
||||
const struct iattr * attrs;
|
||||
const struct nfs_fh * dir_fh;
|
||||
const u32 * bitmask;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs4_create_res {
|
||||
struct nfs4_sequence_res seq_res;
|
||||
const struct nfs_server * server;
|
||||
struct nfs_fh * fh;
|
||||
struct nfs_fattr * fattr;
|
||||
struct nfs4_change_info dir_cinfo;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
};
|
||||
|
||||
struct nfs4_fsinfo_arg {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
const struct nfs_fh * fh;
|
||||
const u32 * bitmask;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs4_fsinfo_res {
|
||||
struct nfs_fsinfo *fsinfo;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
struct nfs_fsinfo *fsinfo;
|
||||
};
|
||||
|
||||
struct nfs4_getattr_arg {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
const struct nfs_fh * fh;
|
||||
const u32 * bitmask;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs4_getattr_res {
|
||||
struct nfs4_sequence_res seq_res;
|
||||
const struct nfs_server * server;
|
||||
struct nfs_fattr * fattr;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
};
|
||||
|
||||
struct nfs4_link_arg {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
const struct nfs_fh * fh;
|
||||
const struct nfs_fh * dir_fh;
|
||||
const struct qstr * name;
|
||||
const u32 * bitmask;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs4_link_res {
|
||||
struct nfs4_sequence_res seq_res;
|
||||
const struct nfs_server * server;
|
||||
struct nfs_fattr * fattr;
|
||||
struct nfs4_change_info cinfo;
|
||||
struct nfs_fattr * dir_attr;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
};
|
||||
|
||||
|
||||
struct nfs4_lookup_arg {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
const struct nfs_fh * dir_fh;
|
||||
const struct qstr * name;
|
||||
const u32 * bitmask;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs4_lookup_res {
|
||||
struct nfs4_sequence_res seq_res;
|
||||
const struct nfs_server * server;
|
||||
struct nfs_fattr * fattr;
|
||||
struct nfs_fh * fh;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
};
|
||||
|
||||
struct nfs4_lookup_root_arg {
|
||||
const u32 * bitmask;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
const u32 * bitmask;
|
||||
};
|
||||
|
||||
struct nfs4_pathconf_arg {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
const struct nfs_fh * fh;
|
||||
const u32 * bitmask;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs4_pathconf_res {
|
||||
struct nfs_pathconf *pathconf;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
struct nfs_pathconf *pathconf;
|
||||
};
|
||||
|
||||
struct nfs4_readdir_arg {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
const struct nfs_fh * fh;
|
||||
u64 cookie;
|
||||
nfs4_verifier verifier;
|
||||
@ -953,21 +951,20 @@ struct nfs4_readdir_arg {
|
||||
unsigned int pgbase; /* zero-copy data */
|
||||
const u32 * bitmask;
|
||||
int plus;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs4_readdir_res {
|
||||
struct nfs4_sequence_res seq_res;
|
||||
nfs4_verifier verifier;
|
||||
unsigned int pgbase;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
};
|
||||
|
||||
struct nfs4_readlink {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
const struct nfs_fh * fh;
|
||||
unsigned int pgbase;
|
||||
unsigned int pglen; /* zero-copy data */
|
||||
struct page ** pages; /* zero-copy data */
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs4_readlink_res {
|
||||
@ -993,28 +990,28 @@ struct nfs4_setclientid_res {
|
||||
};
|
||||
|
||||
struct nfs4_statfs_arg {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
const struct nfs_fh * fh;
|
||||
const u32 * bitmask;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs4_statfs_res {
|
||||
struct nfs_fsstat *fsstat;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
struct nfs_fsstat *fsstat;
|
||||
};
|
||||
|
||||
struct nfs4_server_caps_arg {
|
||||
struct nfs_fh *fhandle;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
struct nfs_fh *fhandle;
|
||||
};
|
||||
|
||||
struct nfs4_server_caps_res {
|
||||
struct nfs4_sequence_res seq_res;
|
||||
u32 attr_bitmask[3];
|
||||
u32 acl_bitmask;
|
||||
u32 has_links;
|
||||
u32 has_symlinks;
|
||||
u32 fh_expire_type;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
};
|
||||
|
||||
#define NFS4_PATHNAME_MAXCOMPONENTS 512
|
||||
@ -1040,16 +1037,16 @@ struct nfs4_fs_locations {
|
||||
};
|
||||
|
||||
struct nfs4_fs_locations_arg {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
const struct nfs_fh *dir_fh;
|
||||
const struct qstr *name;
|
||||
struct page *page;
|
||||
const u32 *bitmask;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs4_fs_locations_res {
|
||||
struct nfs4_fs_locations *fs_locations;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
struct nfs4_fs_locations *fs_locations;
|
||||
};
|
||||
|
||||
struct nfs4_secinfo_oid {
|
||||
@ -1074,14 +1071,14 @@ struct nfs4_secinfo_flavors {
|
||||
};
|
||||
|
||||
struct nfs4_secinfo_arg {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
const struct nfs_fh *dir_fh;
|
||||
const struct qstr *name;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs4_secinfo_res {
|
||||
struct nfs4_secinfo_flavors *flavors;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
struct nfs4_secinfo_flavors *flavors;
|
||||
};
|
||||
|
||||
#endif /* CONFIG_NFS_V4 */
|
||||
@ -1161,9 +1158,9 @@ struct nfs41_create_session_res {
|
||||
};
|
||||
|
||||
struct nfs41_reclaim_complete_args {
|
||||
struct nfs4_sequence_args seq_args;
|
||||
/* In the future extend to include curr_fh for use with migration */
|
||||
unsigned char one_fs:1;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
struct nfs41_reclaim_complete_res {
|
||||
@ -1173,28 +1170,28 @@ struct nfs41_reclaim_complete_res {
|
||||
#define SECINFO_STYLE_CURRENT_FH 0
|
||||
#define SECINFO_STYLE_PARENT 1
|
||||
struct nfs41_secinfo_no_name_args {
|
||||
int style;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
int style;
|
||||
};
|
||||
|
||||
struct nfs41_test_stateid_args {
|
||||
nfs4_stateid *stateid;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
nfs4_stateid *stateid;
|
||||
};
|
||||
|
||||
struct nfs41_test_stateid_res {
|
||||
unsigned int status;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
unsigned int status;
|
||||
};
|
||||
|
||||
struct nfs41_free_stateid_args {
|
||||
nfs4_stateid *stateid;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
nfs4_stateid *stateid;
|
||||
};
|
||||
|
||||
struct nfs41_free_stateid_res {
|
||||
unsigned int status;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
unsigned int status;
|
||||
};
|
||||
|
||||
#else
|
||||
|
@ -192,7 +192,6 @@ struct rpc_wait_queue {
|
||||
pid_t owner; /* process id of last task serviced */
|
||||
unsigned char maxpriority; /* maximum priority (0 if queue is not a priority queue) */
|
||||
unsigned char priority; /* current priority */
|
||||
unsigned char count; /* # task groups remaining serviced so far */
|
||||
unsigned char nr; /* # tasks remaining for cookie */
|
||||
unsigned short qlen; /* total # tasks waiting in queue */
|
||||
struct rpc_timer timer_list;
|
||||
|
@ -192,17 +192,23 @@ gss_fill_context(const void *p, const void *end, struct gss_cl_ctx *ctx, struct
|
||||
const void *q;
|
||||
unsigned int seclen;
|
||||
unsigned int timeout;
|
||||
unsigned long now = jiffies;
|
||||
u32 window_size;
|
||||
int ret;
|
||||
|
||||
/* First unsigned int gives the lifetime (in seconds) of the cred */
|
||||
/* First unsigned int gives the remaining lifetime in seconds of the
|
||||
* credential - e.g. the remaining TGT lifetime for Kerberos or
|
||||
* the -t value passed to GSSD.
|
||||
*/
|
||||
p = simple_get_bytes(p, end, &timeout, sizeof(timeout));
|
||||
if (IS_ERR(p))
|
||||
goto err;
|
||||
if (timeout == 0)
|
||||
timeout = GSSD_MIN_TIMEOUT;
|
||||
ctx->gc_expiry = jiffies + (unsigned long)timeout * HZ * 3 / 4;
|
||||
/* Sequence number window. Determines the maximum number of simultaneous requests */
|
||||
ctx->gc_expiry = now + ((unsigned long)timeout * HZ);
|
||||
/* Sequence number window. Determines the maximum number of
|
||||
* simultaneous requests
|
||||
*/
|
||||
p = simple_get_bytes(p, end, &window_size, sizeof(window_size));
|
||||
if (IS_ERR(p))
|
||||
goto err;
|
||||
@ -237,9 +243,12 @@ gss_fill_context(const void *p, const void *end, struct gss_cl_ctx *ctx, struct
|
||||
p = ERR_PTR(ret);
|
||||
goto err;
|
||||
}
|
||||
dprintk("RPC: %s Success. gc_expiry %lu now %lu timeout %u\n",
|
||||
__func__, ctx->gc_expiry, now, timeout);
|
||||
return q;
|
||||
err:
|
||||
dprintk("RPC: %s returning %ld\n", __func__, -PTR_ERR(p));
|
||||
dprintk("RPC: %s returns %ld gc_expiry %lu now %lu timeout %u\n",
|
||||
__func__, -PTR_ERR(p), ctx->gc_expiry, now, timeout);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ static void xprt_free_allocation(struct rpc_rqst *req)
|
||||
struct xdr_buf *xbufp;
|
||||
|
||||
dprintk("RPC: free allocations for req= %p\n", req);
|
||||
BUG_ON(test_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state));
|
||||
WARN_ON_ONCE(test_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state));
|
||||
xbufp = &req->rq_private_buf;
|
||||
free_page((unsigned long)xbufp->head[0].iov_base);
|
||||
xbufp = &req->rq_snd_buf;
|
||||
@ -191,7 +191,9 @@ void xprt_destroy_backchannel(struct rpc_xprt *xprt, unsigned int max_reqs)
|
||||
|
||||
dprintk("RPC: destroy backchannel transport\n");
|
||||
|
||||
BUG_ON(max_reqs == 0);
|
||||
if (max_reqs == 0)
|
||||
goto out;
|
||||
|
||||
spin_lock_bh(&xprt->bc_pa_lock);
|
||||
xprt_dec_alloc_count(xprt, max_reqs);
|
||||
list_for_each_entry_safe(req, tmp, &xprt->bc_pa_list, rq_bc_pa_list) {
|
||||
@ -202,6 +204,7 @@ void xprt_destroy_backchannel(struct rpc_xprt *xprt, unsigned int max_reqs)
|
||||
}
|
||||
spin_unlock_bh(&xprt->bc_pa_lock);
|
||||
|
||||
out:
|
||||
dprintk("RPC: backchannel list empty= %s\n",
|
||||
list_empty(&xprt->bc_pa_list) ? "true" : "false");
|
||||
}
|
||||
@ -255,7 +258,7 @@ void xprt_free_bc_request(struct rpc_rqst *req)
|
||||
dprintk("RPC: free backchannel req=%p\n", req);
|
||||
|
||||
smp_mb__before_clear_bit();
|
||||
BUG_ON(!test_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state));
|
||||
WARN_ON_ONCE(!test_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state));
|
||||
clear_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state);
|
||||
smp_mb__after_clear_bit();
|
||||
|
||||
|
@ -53,7 +53,7 @@ int bc_send(struct rpc_rqst *req)
|
||||
if (IS_ERR(task))
|
||||
ret = PTR_ERR(task);
|
||||
else {
|
||||
BUG_ON(atomic_read(&task->tk_count) != 1);
|
||||
WARN_ON_ONCE(atomic_read(&task->tk_count) != 1);
|
||||
ret = task->tk_status;
|
||||
rpc_put_task(task);
|
||||
}
|
||||
|
@ -775,11 +775,11 @@ static ssize_t cache_read(struct file *filp, char __user *buf, size_t count,
|
||||
if (rp->q.list.next == &cd->queue) {
|
||||
spin_unlock(&queue_lock);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
BUG_ON(rp->offset);
|
||||
WARN_ON_ONCE(rp->offset);
|
||||
return 0;
|
||||
}
|
||||
rq = container_of(rp->q.list.next, struct cache_request, q.list);
|
||||
BUG_ON(rq->q.reader);
|
||||
WARN_ON_ONCE(rq->q.reader);
|
||||
if (rp->offset == 0)
|
||||
rq->readers++;
|
||||
spin_unlock(&queue_lock);
|
||||
|
@ -132,8 +132,10 @@ static struct dentry *rpc_setup_pipedir_sb(struct super_block *sb,
|
||||
int error;
|
||||
|
||||
dir = rpc_d_lookup_sb(sb, dir_name);
|
||||
if (dir == NULL)
|
||||
if (dir == NULL) {
|
||||
pr_info("RPC: pipefs directory doesn't exist: %s\n", dir_name);
|
||||
return dir;
|
||||
}
|
||||
for (;;) {
|
||||
q.len = snprintf(name, sizeof(name), "clnt%x", (unsigned int)clntid++);
|
||||
name[sizeof(name) - 1] = '\0';
|
||||
@ -192,7 +194,8 @@ static int __rpc_clnt_handle_event(struct rpc_clnt *clnt, unsigned long event,
|
||||
case RPC_PIPEFS_MOUNT:
|
||||
dentry = rpc_setup_pipedir_sb(sb, clnt,
|
||||
clnt->cl_program->pipe_dir_name);
|
||||
BUG_ON(dentry == NULL);
|
||||
if (!dentry)
|
||||
return -ENOENT;
|
||||
if (IS_ERR(dentry))
|
||||
return PTR_ERR(dentry);
|
||||
clnt->cl_dentry = dentry;
|
||||
@ -234,7 +237,7 @@ static struct rpc_clnt *rpc_get_client_for_event(struct net *net, int event)
|
||||
spin_lock(&sn->rpc_client_lock);
|
||||
list_for_each_entry(clnt, &sn->all_clients, cl_clients) {
|
||||
if (clnt->cl_program->pipe_dir_name == NULL)
|
||||
break;
|
||||
continue;
|
||||
if (rpc_clnt_skip_event(clnt, event))
|
||||
continue;
|
||||
if (atomic_inc_not_zero(&clnt->cl_count) == 0)
|
||||
@ -607,6 +610,13 @@ EXPORT_SYMBOL_GPL(rpc_killall_tasks);
|
||||
*/
|
||||
void rpc_shutdown_client(struct rpc_clnt *clnt)
|
||||
{
|
||||
/*
|
||||
* To avoid deadlock, never call rpc_shutdown_client from a
|
||||
* workqueue context!
|
||||
*/
|
||||
WARN_ON_ONCE(current->flags & PF_WQ_WORKER);
|
||||
might_sleep();
|
||||
|
||||
dprintk_rcu("RPC: shutting down %s client for %s\n",
|
||||
clnt->cl_protname,
|
||||
rcu_dereference(clnt->cl_xprt)->servername);
|
||||
@ -693,21 +703,19 @@ struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old,
|
||||
const struct rpc_program *program,
|
||||
u32 vers)
|
||||
{
|
||||
struct rpc_create_args args = {
|
||||
.program = program,
|
||||
.prognumber = program->number,
|
||||
.version = vers,
|
||||
.authflavor = old->cl_auth->au_flavor,
|
||||
.client_name = old->cl_principal,
|
||||
};
|
||||
struct rpc_clnt *clnt;
|
||||
const struct rpc_version *version;
|
||||
int err;
|
||||
|
||||
BUG_ON(vers >= program->nrvers || !program->version[vers]);
|
||||
version = program->version[vers];
|
||||
clnt = rpc_clone_client(old);
|
||||
clnt = __rpc_clone_client(&args, old);
|
||||
if (IS_ERR(clnt))
|
||||
goto out;
|
||||
clnt->cl_procinfo = version->procs;
|
||||
clnt->cl_maxproc = version->nrprocs;
|
||||
clnt->cl_protname = program->name;
|
||||
clnt->cl_prog = program->number;
|
||||
clnt->cl_vers = version->number;
|
||||
clnt->cl_stats = program->stats;
|
||||
err = rpc_ping(clnt);
|
||||
if (err != 0) {
|
||||
rpc_shutdown_client(clnt);
|
||||
@ -832,7 +840,12 @@ int rpc_call_sync(struct rpc_clnt *clnt, const struct rpc_message *msg, int flag
|
||||
};
|
||||
int status;
|
||||
|
||||
BUG_ON(flags & RPC_TASK_ASYNC);
|
||||
WARN_ON_ONCE(flags & RPC_TASK_ASYNC);
|
||||
if (flags & RPC_TASK_ASYNC) {
|
||||
rpc_release_calldata(task_setup_data.callback_ops,
|
||||
task_setup_data.callback_data);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
task = rpc_run_task(&task_setup_data);
|
||||
if (IS_ERR(task))
|
||||
@ -908,7 +921,7 @@ struct rpc_task *rpc_run_bc_task(struct rpc_rqst *req,
|
||||
|
||||
task->tk_action = call_bc_transmit;
|
||||
atomic_inc(&task->tk_count);
|
||||
BUG_ON(atomic_read(&task->tk_count) != 2);
|
||||
WARN_ON_ONCE(atomic_read(&task->tk_count) != 2);
|
||||
rpc_execute(task);
|
||||
|
||||
out:
|
||||
@ -1368,6 +1381,7 @@ call_refreshresult(struct rpc_task *task)
|
||||
return;
|
||||
case -ETIMEDOUT:
|
||||
rpc_delay(task, 3*HZ);
|
||||
case -EKEYEXPIRED:
|
||||
case -EAGAIN:
|
||||
status = -EACCES;
|
||||
if (!task->tk_cred_retry)
|
||||
@ -1654,7 +1668,6 @@ call_transmit(struct rpc_task *task)
|
||||
task->tk_action = call_transmit_status;
|
||||
/* Encode here so that rpcsec_gss can use correct sequence number. */
|
||||
if (rpc_task_need_encode(task)) {
|
||||
BUG_ON(task->tk_rqstp->rq_bytes_sent != 0);
|
||||
rpc_xdr_encode(task);
|
||||
/* Did the encode result in an error condition? */
|
||||
if (task->tk_status != 0) {
|
||||
@ -1738,7 +1751,6 @@ call_bc_transmit(struct rpc_task *task)
|
||||
{
|
||||
struct rpc_rqst *req = task->tk_rqstp;
|
||||
|
||||
BUG_ON(task->tk_status != 0);
|
||||
task->tk_status = xprt_prepare_transmit(task);
|
||||
if (task->tk_status == -EAGAIN) {
|
||||
/*
|
||||
@ -1785,7 +1797,7 @@ call_bc_transmit(struct rpc_task *task)
|
||||
* We were unable to reply and will have to drop the
|
||||
* request. The server should reconnect and retransmit.
|
||||
*/
|
||||
BUG_ON(task->tk_status == -EAGAIN);
|
||||
WARN_ON_ONCE(task->tk_status == -EAGAIN);
|
||||
printk(KERN_NOTICE "RPC: Could not send backchannel reply "
|
||||
"error: %d\n", task->tk_status);
|
||||
break;
|
||||
|
@ -1093,7 +1093,7 @@ void rpc_put_sb_net(const struct net *net)
|
||||
{
|
||||
struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
|
||||
|
||||
BUG_ON(sn->pipefs_sb == NULL);
|
||||
WARN_ON(sn->pipefs_sb == NULL);
|
||||
mutex_unlock(&sn->pipefs_sb_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rpc_put_sb_net);
|
||||
@ -1152,14 +1152,19 @@ static void rpc_kill_sb(struct super_block *sb)
|
||||
struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
|
||||
|
||||
mutex_lock(&sn->pipefs_sb_lock);
|
||||
if (sn->pipefs_sb != sb) {
|
||||
mutex_unlock(&sn->pipefs_sb_lock);
|
||||
goto out;
|
||||
}
|
||||
sn->pipefs_sb = NULL;
|
||||
mutex_unlock(&sn->pipefs_sb_lock);
|
||||
put_net(net);
|
||||
dprintk("RPC: sending pipefs UMOUNT notification for net %p%s\n",
|
||||
net, NET_NAME(net));
|
||||
blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
|
||||
RPC_PIPEFS_UMOUNT,
|
||||
sb);
|
||||
put_net(net);
|
||||
out:
|
||||
kill_litter_super(sb);
|
||||
}
|
||||
|
||||
|
@ -884,7 +884,10 @@ static void encode_rpcb_string(struct xdr_stream *xdr, const char *string,
|
||||
u32 len;
|
||||
|
||||
len = strlen(string);
|
||||
BUG_ON(len > maxstrlen);
|
||||
WARN_ON_ONCE(len > maxstrlen);
|
||||
if (len > maxstrlen)
|
||||
/* truncate and hope for the best */
|
||||
len = maxstrlen;
|
||||
p = xdr_reserve_space(xdr, 4 + len);
|
||||
xdr_encode_opaque(p, string, len);
|
||||
}
|
||||
|
@ -98,6 +98,23 @@ __rpc_add_timer(struct rpc_wait_queue *queue, struct rpc_task *task)
|
||||
list_add(&task->u.tk_wait.timer_list, &queue->timer_list.list);
|
||||
}
|
||||
|
||||
static void rpc_set_waitqueue_priority(struct rpc_wait_queue *queue, int priority)
|
||||
{
|
||||
queue->priority = priority;
|
||||
}
|
||||
|
||||
static void rpc_set_waitqueue_owner(struct rpc_wait_queue *queue, pid_t pid)
|
||||
{
|
||||
queue->owner = pid;
|
||||
queue->nr = RPC_BATCH_COUNT;
|
||||
}
|
||||
|
||||
static void rpc_reset_waitqueue_priority(struct rpc_wait_queue *queue)
|
||||
{
|
||||
rpc_set_waitqueue_priority(queue, queue->maxpriority);
|
||||
rpc_set_waitqueue_owner(queue, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add new request to a priority queue.
|
||||
*/
|
||||
@ -109,9 +126,11 @@ static void __rpc_add_wait_queue_priority(struct rpc_wait_queue *queue,
|
||||
struct rpc_task *t;
|
||||
|
||||
INIT_LIST_HEAD(&task->u.tk_wait.links);
|
||||
q = &queue->tasks[queue_priority];
|
||||
if (unlikely(queue_priority > queue->maxpriority))
|
||||
q = &queue->tasks[queue->maxpriority];
|
||||
queue_priority = queue->maxpriority;
|
||||
if (queue_priority > queue->priority)
|
||||
rpc_set_waitqueue_priority(queue, queue_priority);
|
||||
q = &queue->tasks[queue_priority];
|
||||
list_for_each_entry(t, q, u.tk_wait.list) {
|
||||
if (t->tk_owner == task->tk_owner) {
|
||||
list_add_tail(&task->u.tk_wait.list, &t->u.tk_wait.links);
|
||||
@ -133,7 +152,9 @@ static void __rpc_add_wait_queue(struct rpc_wait_queue *queue,
|
||||
struct rpc_task *task,
|
||||
unsigned char queue_priority)
|
||||
{
|
||||
BUG_ON (RPC_IS_QUEUED(task));
|
||||
WARN_ON_ONCE(RPC_IS_QUEUED(task));
|
||||
if (RPC_IS_QUEUED(task))
|
||||
return;
|
||||
|
||||
if (RPC_IS_PRIORITY(queue))
|
||||
__rpc_add_wait_queue_priority(queue, task, queue_priority);
|
||||
@ -178,24 +199,6 @@ static void __rpc_remove_wait_queue(struct rpc_wait_queue *queue, struct rpc_tas
|
||||
task->tk_pid, queue, rpc_qname(queue));
|
||||
}
|
||||
|
||||
static inline void rpc_set_waitqueue_priority(struct rpc_wait_queue *queue, int priority)
|
||||
{
|
||||
queue->priority = priority;
|
||||
queue->count = 1 << (priority * 2);
|
||||
}
|
||||
|
||||
static inline void rpc_set_waitqueue_owner(struct rpc_wait_queue *queue, pid_t pid)
|
||||
{
|
||||
queue->owner = pid;
|
||||
queue->nr = RPC_BATCH_COUNT;
|
||||
}
|
||||
|
||||
static inline void rpc_reset_waitqueue_priority(struct rpc_wait_queue *queue)
|
||||
{
|
||||
rpc_set_waitqueue_priority(queue, queue->maxpriority);
|
||||
rpc_set_waitqueue_owner(queue, 0);
|
||||
}
|
||||
|
||||
static void __rpc_init_priority_wait_queue(struct rpc_wait_queue *queue, const char *qname, unsigned char nr_queues)
|
||||
{
|
||||
int i;
|
||||
@ -334,7 +337,7 @@ static void __rpc_sleep_on_priority(struct rpc_wait_queue *q,
|
||||
|
||||
__rpc_add_wait_queue(q, task, queue_priority);
|
||||
|
||||
BUG_ON(task->tk_callback != NULL);
|
||||
WARN_ON_ONCE(task->tk_callback != NULL);
|
||||
task->tk_callback = action;
|
||||
__rpc_add_timer(q, task);
|
||||
}
|
||||
@ -343,7 +346,12 @@ void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
|
||||
rpc_action action)
|
||||
{
|
||||
/* We shouldn't ever put an inactive task to sleep */
|
||||
BUG_ON(!RPC_IS_ACTIVATED(task));
|
||||
WARN_ON_ONCE(!RPC_IS_ACTIVATED(task));
|
||||
if (!RPC_IS_ACTIVATED(task)) {
|
||||
task->tk_status = -EIO;
|
||||
rpc_put_task_async(task);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Protect the queue operations.
|
||||
@ -358,7 +366,12 @@ void rpc_sleep_on_priority(struct rpc_wait_queue *q, struct rpc_task *task,
|
||||
rpc_action action, int priority)
|
||||
{
|
||||
/* We shouldn't ever put an inactive task to sleep */
|
||||
BUG_ON(!RPC_IS_ACTIVATED(task));
|
||||
WARN_ON_ONCE(!RPC_IS_ACTIVATED(task));
|
||||
if (!RPC_IS_ACTIVATED(task)) {
|
||||
task->tk_status = -EIO;
|
||||
rpc_put_task_async(task);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Protect the queue operations.
|
||||
@ -367,6 +380,7 @@ void rpc_sleep_on_priority(struct rpc_wait_queue *q, struct rpc_task *task,
|
||||
__rpc_sleep_on_priority(q, task, action, priority - RPC_PRIORITY_LOW);
|
||||
spin_unlock_bh(&q->lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rpc_sleep_on_priority);
|
||||
|
||||
/**
|
||||
* __rpc_do_wake_up_task - wake up a single rpc_task
|
||||
@ -451,8 +465,7 @@ static struct rpc_task *__rpc_find_next_queued_priority(struct rpc_wait_queue *q
|
||||
/*
|
||||
* Check if we need to switch queues.
|
||||
*/
|
||||
if (--queue->count)
|
||||
goto new_owner;
|
||||
goto new_owner;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -697,7 +710,9 @@ static void __rpc_execute(struct rpc_task *task)
|
||||
dprintk("RPC: %5u __rpc_execute flags=0x%x\n",
|
||||
task->tk_pid, task->tk_flags);
|
||||
|
||||
BUG_ON(RPC_IS_QUEUED(task));
|
||||
WARN_ON_ONCE(RPC_IS_QUEUED(task));
|
||||
if (RPC_IS_QUEUED(task))
|
||||
return;
|
||||
|
||||
for (;;) {
|
||||
void (*do_action)(struct rpc_task *);
|
||||
@ -981,7 +996,7 @@ static void rpc_release_task(struct rpc_task *task)
|
||||
{
|
||||
dprintk("RPC: %5u release task\n", task->tk_pid);
|
||||
|
||||
BUG_ON (RPC_IS_QUEUED(task));
|
||||
WARN_ON_ONCE(RPC_IS_QUEUED(task));
|
||||
|
||||
rpc_release_resources_task(task);
|
||||
|
||||
|
@ -324,7 +324,9 @@ svc_pool_map_set_cpumask(struct task_struct *task, unsigned int pidx)
|
||||
* The caller checks for sv_nrpools > 1, which
|
||||
* implies that we've been initialized.
|
||||
*/
|
||||
BUG_ON(m->count == 0);
|
||||
WARN_ON_ONCE(m->count == 0);
|
||||
if (m->count == 0)
|
||||
return;
|
||||
|
||||
switch (m->mode) {
|
||||
case SVC_POOL_PERCPU:
|
||||
@ -585,7 +587,9 @@ svc_init_buffer(struct svc_rqst *rqstp, unsigned int size, int node)
|
||||
* We assume one is at most one page
|
||||
*/
|
||||
arghi = 0;
|
||||
BUG_ON(pages > RPCSVC_MAXPAGES);
|
||||
WARN_ON_ONCE(pages > RPCSVC_MAXPAGES);
|
||||
if (pages > RPCSVC_MAXPAGES)
|
||||
pages = RPCSVC_MAXPAGES;
|
||||
while (pages) {
|
||||
struct page *p = alloc_pages_node(node, GFP_KERNEL, 0);
|
||||
if (!p)
|
||||
@ -946,7 +950,9 @@ int svc_register(const struct svc_serv *serv, struct net *net,
|
||||
unsigned int i;
|
||||
int error = 0;
|
||||
|
||||
BUG_ON(proto == 0 && port == 0);
|
||||
WARN_ON_ONCE(proto == 0 && port == 0);
|
||||
if (proto == 0 && port == 0)
|
||||
return -EINVAL;
|
||||
|
||||
for (progp = serv->sv_program; progp; progp = progp->pg_next) {
|
||||
for (i = 0; i < progp->pg_nvers; i++) {
|
||||
|
@ -218,7 +218,9 @@ static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl,
|
||||
*/
|
||||
static void svc_xprt_received(struct svc_xprt *xprt)
|
||||
{
|
||||
BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags));
|
||||
WARN_ON_ONCE(!test_bit(XPT_BUSY, &xprt->xpt_flags));
|
||||
if (!test_bit(XPT_BUSY, &xprt->xpt_flags))
|
||||
return;
|
||||
/* As soon as we clear busy, the xprt could be closed and
|
||||
* 'put', so we need a reference to call svc_xprt_enqueue with:
|
||||
*/
|
||||
@ -577,7 +579,10 @@ int svc_alloc_arg(struct svc_rqst *rqstp)
|
||||
|
||||
/* now allocate needed pages. If we get a failure, sleep briefly */
|
||||
pages = (serv->sv_max_mesg + PAGE_SIZE) / PAGE_SIZE;
|
||||
BUG_ON(pages >= RPCSVC_MAXPAGES);
|
||||
WARN_ON_ONCE(pages >= RPCSVC_MAXPAGES);
|
||||
if (pages >= RPCSVC_MAXPAGES)
|
||||
/* use as many pages as possible */
|
||||
pages = RPCSVC_MAXPAGES - 1;
|
||||
for (i = 0; i < pages ; i++)
|
||||
while (rqstp->rq_pages[i] == NULL) {
|
||||
struct page *p = alloc_page(GFP_KERNEL);
|
||||
@ -926,7 +931,7 @@ static void svc_delete_xprt(struct svc_xprt *xprt)
|
||||
spin_lock_bh(&serv->sv_lock);
|
||||
if (!test_and_set_bit(XPT_DETACHED, &xprt->xpt_flags))
|
||||
list_del_init(&xprt->xpt_list);
|
||||
BUG_ON(!list_empty(&xprt->xpt_ready));
|
||||
WARN_ON_ONCE(!list_empty(&xprt->xpt_ready));
|
||||
if (test_bit(XPT_TEMP, &xprt->xpt_flags))
|
||||
serv->sv_tmpcnt--;
|
||||
spin_unlock_bh(&serv->sv_lock);
|
||||
|
@ -84,7 +84,11 @@ static struct lock_class_key svc_slock_key[2];
|
||||
static void svc_reclassify_socket(struct socket *sock)
|
||||
{
|
||||
struct sock *sk = sock->sk;
|
||||
BUG_ON(sock_owned_by_user(sk));
|
||||
|
||||
WARN_ON_ONCE(sock_owned_by_user(sk));
|
||||
if (sock_owned_by_user(sk))
|
||||
return;
|
||||
|
||||
switch (sk->sk_family) {
|
||||
case AF_INET:
|
||||
sock_lock_init_class_and_name(sk, "slock-AF_INET-NFSD",
|
||||
|
@ -318,7 +318,10 @@ xdr_shrink_bufhead(struct xdr_buf *buf, size_t len)
|
||||
|
||||
tail = buf->tail;
|
||||
head = buf->head;
|
||||
BUG_ON (len > head->iov_len);
|
||||
|
||||
WARN_ON_ONCE(len > head->iov_len);
|
||||
if (len > head->iov_len)
|
||||
len = head->iov_len;
|
||||
|
||||
/* Shift the tail first */
|
||||
if (tail->iov_len != 0) {
|
||||
|
@ -1746,7 +1746,6 @@ static inline void xs_reclassify_socketu(struct socket *sock)
|
||||
{
|
||||
struct sock *sk = sock->sk;
|
||||
|
||||
BUG_ON(sock_owned_by_user(sk));
|
||||
sock_lock_init_class_and_name(sk, "slock-AF_LOCAL-RPC",
|
||||
&xs_slock_key[1], "sk_lock-AF_LOCAL-RPC", &xs_key[1]);
|
||||
}
|
||||
@ -1755,7 +1754,6 @@ static inline void xs_reclassify_socket4(struct socket *sock)
|
||||
{
|
||||
struct sock *sk = sock->sk;
|
||||
|
||||
BUG_ON(sock_owned_by_user(sk));
|
||||
sock_lock_init_class_and_name(sk, "slock-AF_INET-RPC",
|
||||
&xs_slock_key[0], "sk_lock-AF_INET-RPC", &xs_key[0]);
|
||||
}
|
||||
@ -1764,13 +1762,16 @@ static inline void xs_reclassify_socket6(struct socket *sock)
|
||||
{
|
||||
struct sock *sk = sock->sk;
|
||||
|
||||
BUG_ON(sock_owned_by_user(sk));
|
||||
sock_lock_init_class_and_name(sk, "slock-AF_INET6-RPC",
|
||||
&xs_slock_key[1], "sk_lock-AF_INET6-RPC", &xs_key[1]);
|
||||
}
|
||||
|
||||
static inline void xs_reclassify_socket(int family, struct socket *sock)
|
||||
{
|
||||
WARN_ON_ONCE(sock_owned_by_user(sock->sk));
|
||||
if (sock_owned_by_user(sock->sk))
|
||||
return;
|
||||
|
||||
switch (family) {
|
||||
case AF_LOCAL:
|
||||
xs_reclassify_socketu(sock);
|
||||
@ -1901,6 +1902,10 @@ static void xs_local_setup_socket(struct work_struct *work)
|
||||
dprintk("RPC: xprt %p: socket %s does not exist\n",
|
||||
xprt, xprt->address_strings[RPC_DISPLAY_ADDR]);
|
||||
break;
|
||||
case -ECONNREFUSED:
|
||||
dprintk("RPC: xprt %p: connection refused for %s\n",
|
||||
xprt, xprt->address_strings[RPC_DISPLAY_ADDR]);
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "%s: unhandled error (%d) connecting to %s\n",
|
||||
__func__, -status,
|
||||
@ -2329,9 +2334,11 @@ static void *bc_malloc(struct rpc_task *task, size_t size)
|
||||
struct page *page;
|
||||
struct rpc_buffer *buf;
|
||||
|
||||
BUG_ON(size > PAGE_SIZE - sizeof(struct rpc_buffer));
|
||||
page = alloc_page(GFP_KERNEL);
|
||||
WARN_ON_ONCE(size > PAGE_SIZE - sizeof(struct rpc_buffer));
|
||||
if (size > PAGE_SIZE - sizeof(struct rpc_buffer))
|
||||
return NULL;
|
||||
|
||||
page = alloc_page(GFP_KERNEL);
|
||||
if (!page)
|
||||
return NULL;
|
||||
|
||||
@ -2393,7 +2400,6 @@ static int bc_send_request(struct rpc_task *task)
|
||||
{
|
||||
struct rpc_rqst *req = task->tk_rqstp;
|
||||
struct svc_xprt *xprt;
|
||||
struct svc_sock *svsk;
|
||||
u32 len;
|
||||
|
||||
dprintk("sending request with xid: %08x\n", ntohl(req->rq_xid));
|
||||
@ -2401,7 +2407,6 @@ static int bc_send_request(struct rpc_task *task)
|
||||
* Get the server socket associated with this callback xprt
|
||||
*/
|
||||
xprt = req->rq_xprt->bc_xprt;
|
||||
svsk = container_of(xprt, struct svc_sock, sk_xprt);
|
||||
|
||||
/*
|
||||
* Grab the mutex to serialize data as the connection is shared
|
||||
|
Loading…
Reference in New Issue
Block a user