Commit 0cfcd405 authored by Dai Ngo's avatar Dai Ngo Committed by J. Bruce Fields
Browse files

NFSv4.2: Fix NFS4ERR_STALE error when doing inter server copy



NFS_FS=y as dependency of CONFIG_NFSD_V4_2_INTER_SSC still have
build errors and some configs with NFSD=m to get NFS4ERR_STALE
error when doing inter server copy.

Added ops table in nfs_common for knfsd to access NFS client modules.

Fixes: 3ac3711a ("NFSD: Fix NFS server build errors")
Signed-off-by: default avatarDai Ngo <dai.ngo@oracle.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent d48c8124
Loading
Loading
Loading
Loading
+32 −6
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#include <linux/falloc.h>
#include <linux/mount.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_ssc.h>
#include "delegation.h"
#include "internal.h"
#include "iostat.h"
@@ -314,9 +315,8 @@ out:
static int read_name_gen = 1;
#define SSC_READ_NAME_BODY "ssc_read_%d"

struct file *
nfs42_ssc_open(struct vfsmount *ss_mnt, struct nfs_fh *src_fh,
		nfs4_stateid *stateid)
static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt,
		struct nfs_fh *src_fh, nfs4_stateid *stateid)
{
	struct nfs_fattr fattr;
	struct file *filep, *res;
@@ -398,14 +398,40 @@ out_filep:
	fput(filep);
	goto out_free_name;
}
EXPORT_SYMBOL_GPL(nfs42_ssc_open);
void nfs42_ssc_close(struct file *filep)

static void __nfs42_ssc_close(struct file *filep)
{
	struct nfs_open_context *ctx = nfs_file_open_context(filep);

	ctx->state->flags = 0;
}
EXPORT_SYMBOL_GPL(nfs42_ssc_close);

static const struct nfs4_ssc_client_ops nfs4_ssc_clnt_ops_tbl = {
	.sco_open = __nfs42_ssc_open,
	.sco_close = __nfs42_ssc_close,
};

/**
 * nfs42_ssc_register_ops - Wrapper to register NFS_V4 ops in nfs_common
 *
 * Return values:
 *   None
 */
void nfs42_ssc_register_ops(void)
{
	nfs42_ssc_register(&nfs4_ssc_clnt_ops_tbl);
}

/**
 * nfs42_ssc_unregister_ops - wrapper to un-register NFS_V4 ops in nfs_common
 *
 * Return values:
 *   None.
 */
void nfs42_ssc_unregister_ops(void)
{
	nfs42_ssc_unregister(&nfs4_ssc_clnt_ops_tbl);
}
#endif /* CONFIG_NFS_V4_2 */

const struct file_operations nfs4_file_operations = {
+5 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
#include <linux/mount.h>
#include <linux/nfs4_mount.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_ssc.h>
#include "delegation.h"
#include "internal.h"
#include "nfs4_fs.h"
@@ -279,6 +280,9 @@ static int __init init_nfs_v4(void)
	if (err)
		goto out2;

#ifdef CONFIG_NFS_V4_2
	nfs42_ssc_register_ops();
#endif
	register_nfs_version(&nfs_v4);
	return 0;
out2:
@@ -297,6 +301,7 @@ static void __exit exit_nfs_v4(void)
	unregister_nfs_version(&nfs_v4);
#ifdef CONFIG_NFS_V4_2
	nfs4_xattr_cache_exit();
	nfs42_ssc_unregister_ops();
#endif
	nfs4_unregister_sysctl();
	nfs_idmap_quit();
+17 −0
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@
#include <linux/rcupdate.h>

#include <linux/uaccess.h>
#include <linux/nfs_ssc.h>

#include "nfs4_fs.h"
#include "callback.h"
@@ -85,6 +86,10 @@ const struct super_operations nfs_sops = {
};
EXPORT_SYMBOL_GPL(nfs_sops);

static const struct nfs_ssc_client_ops nfs_ssc_clnt_ops_tbl = {
	.sco_sb_deactive = nfs_sb_deactive,
};

#if IS_ENABLED(CONFIG_NFS_V4)
static int __init register_nfs4_fs(void)
{
@@ -106,6 +111,16 @@ static void unregister_nfs4_fs(void)
}
#endif

static void nfs_ssc_register_ops(void)
{
	nfs_ssc_register(&nfs_ssc_clnt_ops_tbl);
}

static void nfs_ssc_unregister_ops(void)
{
	nfs_ssc_unregister(&nfs_ssc_clnt_ops_tbl);
}

static struct shrinker acl_shrinker = {
	.count_objects	= nfs_access_cache_count,
	.scan_objects	= nfs_access_cache_scan,
@@ -133,6 +148,7 @@ int __init register_nfs_fs(void)
	ret = register_shrinker(&acl_shrinker);
	if (ret < 0)
		goto error_3;
	nfs_ssc_register_ops();
	return 0;
error_3:
	nfs_unregister_sysctl();
@@ -152,6 +168,7 @@ void __exit unregister_nfs_fs(void)
	unregister_shrinker(&acl_shrinker);
	nfs_unregister_sysctl();
	unregister_nfs4_fs();
	nfs_ssc_unregister_ops();
	unregister_filesystem(&nfs_fs_type);
}

+1 −0
Original line number Diff line number Diff line
@@ -7,3 +7,4 @@ obj-$(CONFIG_NFS_ACL_SUPPORT) += nfs_acl.o
nfs_acl-objs := nfsacl.o

obj-$(CONFIG_GRACE_PERIOD) += grace.o
obj-$(CONFIG_GRACE_PERIOD) += nfs_ssc.o
+94 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * fs/nfs_common/nfs_ssc_comm.c
 *
 * Helper for knfsd's SSC to access ops in NFS client modules
 *
 * Author: Dai Ngo <dai.ngo@oracle.com>
 *
 * Copyright (c) 2020, Oracle and/or its affiliates.
 */

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/nfs_ssc.h>
#include "../nfs/nfs4_fs.h"

MODULE_LICENSE("GPL");

struct nfs_ssc_client_ops_tbl nfs_ssc_client_tbl;
EXPORT_SYMBOL_GPL(nfs_ssc_client_tbl);

#ifdef CONFIG_NFS_V4_2
/**
 * nfs42_ssc_register - install the NFS_V4 client ops in the nfs_ssc_client_tbl
 * @ops: NFS_V4 ops to be installed
 *
 * Return values:
 *   None
 */
void nfs42_ssc_register(const struct nfs4_ssc_client_ops *ops)
{
	nfs_ssc_client_tbl.ssc_nfs4_ops = ops;
}
EXPORT_SYMBOL_GPL(nfs42_ssc_register);

/**
 * nfs42_ssc_unregister - uninstall the NFS_V4 client ops from
 *				the nfs_ssc_client_tbl
 * @ops: ops to be uninstalled
 *
 * Return values:
 *   None
 */
void nfs42_ssc_unregister(const struct nfs4_ssc_client_ops *ops)
{
	if (nfs_ssc_client_tbl.ssc_nfs4_ops != ops)
		return;

	nfs_ssc_client_tbl.ssc_nfs4_ops = NULL;
}
EXPORT_SYMBOL_GPL(nfs42_ssc_unregister);
#endif /* CONFIG_NFS_V4_2 */

#ifdef CONFIG_NFS_V4_2
/**
 * nfs_ssc_register - install the NFS_FS client ops in the nfs_ssc_client_tbl
 * @ops: NFS_FS ops to be installed
 *
 * Return values:
 *   None
 */
void nfs_ssc_register(const struct nfs_ssc_client_ops *ops)
{
	nfs_ssc_client_tbl.ssc_nfs_ops = ops;
}
EXPORT_SYMBOL_GPL(nfs_ssc_register);

/**
 * nfs_ssc_unregister - uninstall the NFS_FS client ops from
 *				the nfs_ssc_client_tbl
 * @ops: ops to be uninstalled
 *
 * Return values:
 *   None
 */
void nfs_ssc_unregister(const struct nfs_ssc_client_ops *ops)
{
	if (nfs_ssc_client_tbl.ssc_nfs_ops != ops)
		return;
	nfs_ssc_client_tbl.ssc_nfs_ops = NULL;
}
EXPORT_SYMBOL_GPL(nfs_ssc_unregister);

#else
void nfs_ssc_register(const struct nfs_ssc_client_ops *ops)
{
}
EXPORT_SYMBOL_GPL(nfs_ssc_register);

void nfs_ssc_unregister(const struct nfs_ssc_client_ops *ops)
{
}
EXPORT_SYMBOL_GPL(nfs_ssc_unregister);
#endif /* CONFIG_NFS_V4_2 */
Loading