Skip to content

Commit

Permalink
nfs4.1: Add SP4_MACH_CRED write and commit support
Browse files Browse the repository at this point in the history
WRITE and COMMIT can use the machine credential.

If WRITE is supported and COMMIT is not, make all (mach cred) writes FILE_SYNC4.

Signed-off-by: Weston Andros Adamson <dros@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
  • Loading branch information
Weston Andros Adamson authored and Trond Myklebust committed Sep 5, 2013
1 parent 3787d50 commit 8c21c62
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 9 deletions.
50 changes: 41 additions & 9 deletions fs/nfs/nfs4_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,15 +269,9 @@ is_ds_client(struct nfs_client *clp)
return clp->cl_exchange_flags & EXCHGID4_FLAG_USE_PNFS_DS;
}

/*
* Function responsible for determining if an rpc_message should use the
* machine cred under SP4_MACH_CRED and if so switching the credential and
* authflavor (using the nfs_client's rpc_clnt which will be krb5i/p).
* Should be called before rpc_call_sync/rpc_call_async.
*/
static inline void
nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_mode,
struct rpc_clnt **clntp, struct rpc_message *msg)
static inline bool
_nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_mode,
struct rpc_clnt **clntp, struct rpc_message *msg)
{
struct rpc_cred *newcred = NULL;
rpc_authflavor_t flavor;
Expand All @@ -295,7 +289,37 @@ nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_mode,
WARN_ON(flavor != RPC_AUTH_GSS_KRB5I &&
flavor != RPC_AUTH_GSS_KRB5P);
*clntp = clp->cl_rpcclient;

return true;
}
return false;
}

/*
* Function responsible for determining if an rpc_message should use the
* machine cred under SP4_MACH_CRED and if so switching the credential and
* authflavor (using the nfs_client's rpc_clnt which will be krb5i/p).
* Should be called before rpc_call_sync/rpc_call_async.
*/
static inline void
nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_mode,
struct rpc_clnt **clntp, struct rpc_message *msg)
{
_nfs4_state_protect(clp, sp4_mode, clntp, msg);
}

/*
* Special wrapper to nfs4_state_protect for write.
* If WRITE can use machine cred but COMMIT cannot, make sure all writes
* that use machine cred use NFS_FILE_SYNC.
*/
static inline void
nfs4_state_protect_write(struct nfs_client *clp, struct rpc_clnt **clntp,
struct rpc_message *msg, struct nfs_write_data *wdata)
{
if (_nfs4_state_protect(clp, NFS_SP4_MACH_CRED_WRITE, clntp, msg) &&
!test_bit(NFS_SP4_MACH_CRED_COMMIT, &clp->cl_sp4_flags))
wdata->args.stable = NFS_FILE_SYNC;
}
#else /* CONFIG_NFS_v4_1 */
static inline struct nfs4_session *nfs4_get_session(const struct nfs_server *server)
Expand All @@ -320,6 +344,12 @@ nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_flags,
struct rpc_clnt **clntp, struct rpc_message *msg)
{
}

static inline void
nfs4_state_protect_write(struct nfs_client *clp, struct rpc_clnt **clntp,
struct rpc_message *msg, struct nfs_write_data *wdata)
{
}
#endif /* CONFIG_NFS_V4_1 */

extern const struct nfs4_minor_version_ops *nfs_v4_minor_ops[];
Expand Down Expand Up @@ -455,6 +485,8 @@ static inline bool nfs4_valid_open_stateid(const struct nfs4_state *state)

#define nfs4_close_state(a, b) do { } while (0)
#define nfs4_close_sync(a, b) do { } while (0)
#define nfs4_state_protect(a, b, c, d) do { } while (0)
#define nfs4_state_protect_write(a, b, c, d) do { } while (0)

#endif /* CONFIG_NFS_V4 */
#endif /* __LINUX_FS_NFS_NFS4_FS.H */
10 changes: 10 additions & 0 deletions fs/nfs/nfs4proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -6223,6 +6223,16 @@ static int nfs4_sp4_select_mode(struct nfs_client *clp,
dfprintk(MOUNT, " stateid mode enabled\n");
set_bit(NFS_SP4_MACH_CRED_STATEID, &clp->cl_sp4_flags);
}

if (test_bit(OP_WRITE, sp->allow.u.longs)) {
dfprintk(MOUNT, " write mode enabled\n");
set_bit(NFS_SP4_MACH_CRED_WRITE, &clp->cl_sp4_flags);
}

if (test_bit(OP_COMMIT, sp->allow.u.longs)) {
dfprintk(MOUNT, " commit mode enabled\n");
set_bit(NFS_SP4_MACH_CRED_COMMIT, &clp->cl_sp4_flags);
}
}

return 0;
Expand Down
6 changes: 6 additions & 0 deletions fs/nfs/write.c
Original file line number Diff line number Diff line change
Expand Up @@ -1022,6 +1022,9 @@ int nfs_initiate_write(struct rpc_clnt *clnt,
data->args.count,
(unsigned long long)data->args.offset);

nfs4_state_protect_write(NFS_SERVER(inode)->nfs_client,
&task_setup_data.rpc_client, &msg, data);

task = rpc_run_task(&task_setup_data);
if (IS_ERR(task)) {
ret = PTR_ERR(task);
Expand Down Expand Up @@ -1488,6 +1491,9 @@ int nfs_initiate_commit(struct rpc_clnt *clnt, struct nfs_commit_data *data,

dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid);

nfs4_state_protect(NFS_SERVER(data->inode)->nfs_client,
NFS_SP4_MACH_CRED_COMMIT, &task_setup_data.rpc_client, &msg);

task = rpc_run_task(&task_setup_data);
if (IS_ERR(task))
return PTR_ERR(task);
Expand Down
2 changes: 2 additions & 0 deletions include/linux/nfs_fs_sb.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ struct nfs_client {
#define NFS_SP4_MACH_CRED_CLEANUP 2 /* CLOSE and LOCKU */
#define NFS_SP4_MACH_CRED_SECINFO 3 /* SECINFO and SECINFO_NO_NAME */
#define NFS_SP4_MACH_CRED_STATEID 4 /* TEST_STATEID and FREE_STATEID */
#define NFS_SP4_MACH_CRED_WRITE 5 /* WRITE */
#define NFS_SP4_MACH_CRED_COMMIT 6 /* COMMIT */
#endif /* CONFIG_NFS_V4 */

#ifdef CONFIG_NFS_FSCACHE
Expand Down

0 comments on commit 8c21c62

Please sign in to comment.