Commit d11f6cd1 authored by Mike Snitzer's avatar Mike Snitzer Committed by Anna Schumaker
Browse files

NFSD: filecache: add STATX_DIOALIGN and STATX_DIO_READ_ALIGN support



Use STATX_DIOALIGN and STATX_DIO_READ_ALIGN to get DIO alignment
attributes from the underlying filesystem and store them in the
associated nfsd_file. This is done when the nfsd_file is first
opened for each regular file.

Signed-off-by: default avatarMike Snitzer <snitzer@kernel.org>
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Reviewed-by: default avatarNeilBrown <neil@brown.name>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Acked-by: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarAnna Schumaker <anna.schumaker@oracle.com>
parent ffe38192
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -231,6 +231,9 @@ nfsd_file_alloc(struct net *net, struct inode *inode, unsigned char need,
	refcount_set(&nf->nf_ref, 1);
	nf->nf_may = need;
	nf->nf_mark = NULL;
	nf->nf_dio_mem_align = 0;
	nf->nf_dio_offset_align = 0;
	nf->nf_dio_read_offset_align = 0;
	return nf;
}

@@ -1069,6 +1072,35 @@ nfsd_file_is_cached(struct inode *inode)
	return ret;
}

static __be32
nfsd_file_get_dio_attrs(const struct svc_fh *fhp, struct nfsd_file *nf)
{
	struct inode *inode = file_inode(nf->nf_file);
	struct kstat stat;
	__be32 status;

	/* Currently only need to get DIO alignment info for regular files */
	if (!S_ISREG(inode->i_mode))
		return nfs_ok;

	status = fh_getattr(fhp, &stat);
	if (status != nfs_ok)
		return status;

	trace_nfsd_file_get_dio_attrs(inode, &stat);

	if (stat.result_mask & STATX_DIOALIGN) {
		nf->nf_dio_mem_align = stat.dio_mem_align;
		nf->nf_dio_offset_align = stat.dio_offset_align;
	}
	if (stat.result_mask & STATX_DIO_READ_ALIGN)
		nf->nf_dio_read_offset_align = stat.dio_read_offset_align;
	else
		nf->nf_dio_read_offset_align = nf->nf_dio_offset_align;

	return nfs_ok;
}

static __be32
nfsd_file_do_acquire(struct svc_rqst *rqstp, struct net *net,
		     struct svc_cred *cred,
@@ -1187,6 +1219,8 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct net *net,
			}
			status = nfserrno(ret);
			trace_nfsd_file_open(nf, status);
			if (status == nfs_ok)
				status = nfsd_file_get_dio_attrs(fhp, nf);
		}
	} else
		status = nfserr_jukebox;
+4 −0
Original line number Diff line number Diff line
@@ -54,6 +54,10 @@ struct nfsd_file {
	struct list_head	nf_gc;
	struct rcu_head		nf_rcu;
	ktime_t			nf_birthtime;

	u32			nf_dio_mem_align;
	u32			nf_dio_offset_align;
	u32			nf_dio_read_offset_align;
};

int nfsd_file_cache_init(void);
+27 −0
Original line number Diff line number Diff line
@@ -1133,6 +1133,33 @@ TRACE_EVENT(nfsd_file_alloc,
	)
);

TRACE_EVENT(nfsd_file_get_dio_attrs,
	TP_PROTO(
		const struct inode *inode,
		const struct kstat *stat
	),
	TP_ARGS(inode, stat),
	TP_STRUCT__entry(
		__field(const void *, inode)
		__field(unsigned long, mask)
		__field(u32, mem_align)
		__field(u32, offset_align)
		__field(u32, read_offset_align)
	),
	TP_fast_assign(
		__entry->inode = inode;
		__entry->mask = stat->result_mask;
		__entry->mem_align = stat->dio_mem_align;
		__entry->offset_align = stat->dio_offset_align;
		__entry->read_offset_align = stat->dio_read_offset_align;
	),
	TP_printk("inode=%p flags=%s mem_align=%u offset_align=%u read_offset_align=%u",
		__entry->inode, show_statx_mask(__entry->mask),
		__entry->mem_align, __entry->offset_align,
		__entry->read_offset_align
	)
);

TRACE_EVENT(nfsd_file_acquire,
	TP_PROTO(
		const struct svc_rqst *rqstp,
+4 −0
Original line number Diff line number Diff line
@@ -185,6 +185,10 @@ static inline __be32 fh_getattr(const struct svc_fh *fh, struct kstat *stat)
	u32 request_mask = STATX_BASIC_STATS;
	struct path p = {.mnt = fh->fh_export->ex_path.mnt,
			 .dentry = fh->fh_dentry};
	struct inode *inode = d_inode(p.dentry);

	if (S_ISREG(inode->i_mode))
		request_mask |= (STATX_DIOALIGN | STATX_DIO_READ_ALIGN);

	if (fh->fh_maxsize == NFS4_FHSIZE)
		request_mask |= (STATX_BTIME | STATX_CHANGE_COOKIE);
+22 −0
Original line number Diff line number Diff line
@@ -141,3 +141,25 @@
		{ ATTR_TIMES_SET,	"TIMES_SET" },	\
		{ ATTR_TOUCH,		"TOUCH"},	\
		{ ATTR_DELEG,		"DELEG"})

#define show_statx_mask(flags)					\
	__print_flags(flags, "|",				\
		{ STATX_TYPE,		"TYPE" },		\
		{ STATX_MODE,		"MODE" },		\
		{ STATX_NLINK,		"NLINK" },		\
		{ STATX_UID,		"UID" },		\
		{ STATX_GID,		"GID" },		\
		{ STATX_ATIME,		"ATIME" },		\
		{ STATX_MTIME,		"MTIME" },		\
		{ STATX_CTIME,		"CTIME" },		\
		{ STATX_INO,		"INO" },		\
		{ STATX_SIZE,		"SIZE" },		\
		{ STATX_BLOCKS,		"BLOCKS" },		\
		{ STATX_BASIC_STATS,	"BASIC_STATS" },	\
		{ STATX_BTIME,		"BTIME" },		\
		{ STATX_MNT_ID,		"MNT_ID" },		\
		{ STATX_DIOALIGN,	"DIOALIGN" },		\
		{ STATX_MNT_ID_UNIQUE,	"MNT_ID_UNIQUE" },	\
		{ STATX_SUBVOL,		"SUBVOL" },		\
		{ STATX_WRITE_ATOMIC,	"WRITE_ATOMIC" },	\
		{ STATX_DIO_READ_ALIGN,	"DIO_READ_ALIGN" })