Skip to content

Commit

Permalink
nfs: use change attribute for NFS re-exports
Browse files Browse the repository at this point in the history
When exporting NFS, we may as well use the real change attribute
returned by the original server instead of faking up a change attribute
from the ctime.

Note we can't do that by setting I_VERSION--that would also turn on the
logic in iversion.h which treats the lower bit specially, and that
doesn't make sense for NFS.

So instead we define a new export operation for filesystems like NFS
that want to manage the change attribute themselves.

Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
  • Loading branch information
J. Bruce Fields authored and Chuck Lever committed Jan 30, 2021
1 parent 02591f9 commit 3cc55f4
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 1 deletion.
18 changes: 18 additions & 0 deletions fs/nfs/export.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,28 @@ nfs_get_parent(struct dentry *dentry)
return parent;
}

static u64 nfs_fetch_iversion(struct inode *inode)
{
struct nfs_server *server = NFS_SERVER(inode);

/* Is this the right call?: */
nfs_revalidate_inode(server, inode);
/*
* Also, note we're ignoring any returned error. That seems to be
* the practice for cache consistency information elsewhere in
* the server, but I'm not sure why.
*/
if (server->nfs_client->rpc_ops->version >= 4)
return inode_peek_iversion_raw(inode);
else
return time_to_chattr(&inode->i_ctime);
}

const struct export_operations nfs_export_ops = {
.encode_fh = nfs_encode_fh,
.fh_to_dentry = nfs_fh_to_dentry,
.get_parent = nfs_get_parent,
.fetch_iversion = nfs_fetch_iversion,
.flags = EXPORT_OP_NOWCC|EXPORT_OP_NOSUBTREECHK|
EXPORT_OP_CLOSE_BEFORE_UNLINK|EXPORT_OP_REMOTE_FS|
EXPORT_OP_NOATOMIC_ATTR,
Expand Down
5 changes: 4 additions & 1 deletion fs/nfsd/nfsfh.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <linux/sunrpc/svc.h>
#include <uapi/linux/nfsd/nfsfh.h>
#include <linux/iversion.h>
#include <linux/exportfs.h>

static inline __u32 ino_t_to_u32(ino_t ino)
{
Expand Down Expand Up @@ -264,7 +265,9 @@ fh_clear_wcc(struct svc_fh *fhp)
static inline u64 nfsd4_change_attribute(struct kstat *stat,
struct inode *inode)
{
if (IS_I_VERSION(inode)) {
if (inode->i_sb->s_export_op->fetch_iversion)
return inode->i_sb->s_export_op->fetch_iversion(inode);
else if (IS_I_VERSION(inode)) {
u64 chattr;

chattr = stat->ctime.tv_sec;
Expand Down
1 change: 1 addition & 0 deletions include/linux/exportfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ struct export_operations {
bool write, u32 *device_generation);
int (*commit_blocks)(struct inode *inode, struct iomap *iomaps,
int nr_iomaps, struct iattr *iattr);
u64 (*fetch_iversion)(struct inode *);
#define EXPORT_OP_NOWCC (0x1) /* don't collect v3 wcc data */
#define EXPORT_OP_NOSUBTREECHK (0x2) /* no subtree checking */
#define EXPORT_OP_CLOSE_BEFORE_UNLINK (0x4) /* close files before unlink */
Expand Down

0 comments on commit 3cc55f4

Please sign in to comment.