aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c153
1 files changed, 153 insertions, 0 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 2aacd1357dc5..c71c16e0ac22 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -5984,6 +5984,157 @@ int nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir,
5984 return err; 5984 return err;
5985} 5985}
5986 5986
5987/*
5988 * This operation also signals the server that this client is
5989 * performing migration recovery. The server can stop returning
5990 * NFS4ERR_LEASE_MOVED to this client. A RENEW operation is
5991 * appended to this compound to identify the client ID which is
5992 * performing recovery.
5993 */
5994static int _nfs40_proc_get_locations(struct inode *inode,
5995 struct nfs4_fs_locations *locations,
5996 struct page *page, struct rpc_cred *cred)
5997{
5998 struct nfs_server *server = NFS_SERVER(inode);
5999 struct rpc_clnt *clnt = server->client;
6000 u32 bitmask[2] = {
6001 [0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS,
6002 };
6003 struct nfs4_fs_locations_arg args = {
6004 .clientid = server->nfs_client->cl_clientid,
6005 .fh = NFS_FH(inode),
6006 .page = page,
6007 .bitmask = bitmask,
6008 .migration = 1, /* skip LOOKUP */
6009 .renew = 1, /* append RENEW */
6010 };
6011 struct nfs4_fs_locations_res res = {
6012 .fs_locations = locations,
6013 .migration = 1,
6014 .renew = 1,
6015 };
6016 struct rpc_message msg = {
6017 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FS_LOCATIONS],
6018 .rpc_argp = &args,
6019 .rpc_resp = &res,
6020 .rpc_cred = cred,
6021 };
6022 unsigned long now = jiffies;
6023 int status;
6024
6025 nfs_fattr_init(&locations->fattr);
6026 locations->server = server;
6027 locations->nlocations = 0;
6028
6029 nfs4_init_sequence(&args.seq_args, &res.seq_res, 0);
6030 nfs4_set_sequence_privileged(&args.seq_args);
6031 status = nfs4_call_sync_sequence(clnt, server, &msg,
6032 &args.seq_args, &res.seq_res);
6033 if (status)
6034 return status;
6035
6036 renew_lease(server, now);
6037 return 0;
6038}
6039
6040#ifdef CONFIG_NFS_V4_1
6041
6042/*
6043 * This operation also signals the server that this client is
6044 * performing migration recovery. The server can stop asserting
6045 * SEQ4_STATUS_LEASE_MOVED for this client. The client ID
6046 * performing this operation is identified in the SEQUENCE
6047 * operation in this compound.
6048 *
6049 * When the client supports GETATTR(fs_locations_info), it can
6050 * be plumbed in here.
6051 */
6052static int _nfs41_proc_get_locations(struct inode *inode,
6053 struct nfs4_fs_locations *locations,
6054 struct page *page, struct rpc_cred *cred)
6055{
6056 struct nfs_server *server = NFS_SERVER(inode);
6057 struct rpc_clnt *clnt = server->client;
6058 u32 bitmask[2] = {
6059 [0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS,
6060 };
6061 struct nfs4_fs_locations_arg args = {
6062 .fh = NFS_FH(inode),
6063 .page = page,
6064 .bitmask = bitmask,
6065 .migration = 1, /* skip LOOKUP */
6066 };
6067 struct nfs4_fs_locations_res res = {
6068 .fs_locations = locations,
6069 .migration = 1,
6070 };
6071 struct rpc_message msg = {
6072 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FS_LOCATIONS],
6073 .rpc_argp = &args,
6074 .rpc_resp = &res,
6075 .rpc_cred = cred,
6076 };
6077 int status;
6078
6079 nfs_fattr_init(&locations->fattr);
6080 locations->server = server;
6081 locations->nlocations = 0;
6082
6083 nfs4_init_sequence(&args.seq_args, &res.seq_res, 0);
6084 nfs4_set_sequence_privileged(&args.seq_args);
6085 status = nfs4_call_sync_sequence(clnt, server, &msg,
6086 &args.seq_args, &res.seq_res);
6087 if (status == NFS4_OK &&
6088 res.seq_res.sr_status_flags & SEQ4_STATUS_LEASE_MOVED)
6089 status = -NFS4ERR_LEASE_MOVED;
6090 return status;
6091}
6092
6093#endif /* CONFIG_NFS_V4_1 */
6094
6095/**
6096 * nfs4_proc_get_locations - discover locations for a migrated FSID
6097 * @inode: inode on FSID that is migrating
6098 * @locations: result of query
6099 * @page: buffer
6100 * @cred: credential to use for this operation
6101 *
6102 * Returns NFS4_OK on success, a negative NFS4ERR status code if the
6103 * operation failed, or a negative errno if a local error occurred.
6104 *
6105 * On success, "locations" is filled in, but if the server has
6106 * no locations information, NFS_ATTR_FATTR_V4_LOCATIONS is not
6107 * asserted.
6108 *
6109 * -NFS4ERR_LEASE_MOVED is returned if the server still has leases
6110 * from this client that require migration recovery.
6111 */
6112int nfs4_proc_get_locations(struct inode *inode,
6113 struct nfs4_fs_locations *locations,
6114 struct page *page, struct rpc_cred *cred)
6115{
6116 struct nfs_server *server = NFS_SERVER(inode);
6117 struct nfs_client *clp = server->nfs_client;
6118 const struct nfs4_mig_recovery_ops *ops =
6119 clp->cl_mvops->mig_recovery_ops;
6120 struct nfs4_exception exception = { };
6121 int status;
6122
6123 dprintk("%s: FSID %llx:%llx on \"%s\"\n", __func__,
6124 (unsigned long long)server->fsid.major,
6125 (unsigned long long)server->fsid.minor,
6126 clp->cl_hostname);
6127 nfs_display_fhandle(NFS_FH(inode), __func__);
6128
6129 do {
6130 status = ops->get_locations(inode, locations, page, cred);
6131 if (status != -NFS4ERR_DELAY)
6132 break;
6133 nfs4_handle_exception(server, status, &exception);
6134 } while (exception.retry);
6135 return status;
6136}
6137
5987/** 6138/**
5988 * If 'use_integrity' is true and the state managment nfs_client 6139 * If 'use_integrity' is true and the state managment nfs_client
5989 * cl_rpcclient is using krb5i/p, use the integrity protected cl_rpcclient 6140 * cl_rpcclient is using krb5i/p, use the integrity protected cl_rpcclient
@@ -7882,10 +8033,12 @@ static const struct nfs4_state_maintenance_ops nfs41_state_renewal_ops = {
7882#endif 8033#endif
7883 8034
7884static const struct nfs4_mig_recovery_ops nfs40_mig_recovery_ops = { 8035static const struct nfs4_mig_recovery_ops nfs40_mig_recovery_ops = {
8036 .get_locations = _nfs40_proc_get_locations,
7885}; 8037};
7886 8038
7887#if defined(CONFIG_NFS_V4_1) 8039#if defined(CONFIG_NFS_V4_1)
7888static const struct nfs4_mig_recovery_ops nfs41_mig_recovery_ops = { 8040static const struct nfs4_mig_recovery_ops nfs41_mig_recovery_ops = {
8041 .get_locations = _nfs41_proc_get_locations,
7889}; 8042};
7890#endif /* CONFIG_NFS_V4_1 */ 8043#endif /* CONFIG_NFS_V4_1 */
7891 8044