Skip to content

Commit d11f6cd

Browse files
Mike SnitzerAnna Schumaker
authored andcommitted
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: Mike Snitzer <snitzer@kernel.org> Reviewed-by: Jeff Layton <jlayton@kernel.org> Reviewed-by: NeilBrown <neil@brown.name> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Acked-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
1 parent ffe3819 commit d11f6cd

5 files changed

Lines changed: 91 additions & 0 deletions

File tree

fs/nfsd/filecache.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,9 @@ nfsd_file_alloc(struct net *net, struct inode *inode, unsigned char need,
231231
refcount_set(&nf->nf_ref, 1);
232232
nf->nf_may = need;
233233
nf->nf_mark = NULL;
234+
nf->nf_dio_mem_align = 0;
235+
nf->nf_dio_offset_align = 0;
236+
nf->nf_dio_read_offset_align = 0;
234237
return nf;
235238
}
236239

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

1075+
static __be32
1076+
nfsd_file_get_dio_attrs(const struct svc_fh *fhp, struct nfsd_file *nf)
1077+
{
1078+
struct inode *inode = file_inode(nf->nf_file);
1079+
struct kstat stat;
1080+
__be32 status;
1081+
1082+
/* Currently only need to get DIO alignment info for regular files */
1083+
if (!S_ISREG(inode->i_mode))
1084+
return nfs_ok;
1085+
1086+
status = fh_getattr(fhp, &stat);
1087+
if (status != nfs_ok)
1088+
return status;
1089+
1090+
trace_nfsd_file_get_dio_attrs(inode, &stat);
1091+
1092+
if (stat.result_mask & STATX_DIOALIGN) {
1093+
nf->nf_dio_mem_align = stat.dio_mem_align;
1094+
nf->nf_dio_offset_align = stat.dio_offset_align;
1095+
}
1096+
if (stat.result_mask & STATX_DIO_READ_ALIGN)
1097+
nf->nf_dio_read_offset_align = stat.dio_read_offset_align;
1098+
else
1099+
nf->nf_dio_read_offset_align = nf->nf_dio_offset_align;
1100+
1101+
return nfs_ok;
1102+
}
1103+
10721104
static __be32
10731105
nfsd_file_do_acquire(struct svc_rqst *rqstp, struct net *net,
10741106
struct svc_cred *cred,
@@ -1187,6 +1219,8 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct net *net,
11871219
}
11881220
status = nfserrno(ret);
11891221
trace_nfsd_file_open(nf, status);
1222+
if (status == nfs_ok)
1223+
status = nfsd_file_get_dio_attrs(fhp, nf);
11901224
}
11911225
} else
11921226
status = nfserr_jukebox;

fs/nfsd/filecache.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ struct nfsd_file {
5454
struct list_head nf_gc;
5555
struct rcu_head nf_rcu;
5656
ktime_t nf_birthtime;
57+
58+
u32 nf_dio_mem_align;
59+
u32 nf_dio_offset_align;
60+
u32 nf_dio_read_offset_align;
5761
};
5862

5963
int nfsd_file_cache_init(void);

fs/nfsd/trace.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,6 +1133,33 @@ TRACE_EVENT(nfsd_file_alloc,
11331133
)
11341134
);
11351135

1136+
TRACE_EVENT(nfsd_file_get_dio_attrs,
1137+
TP_PROTO(
1138+
const struct inode *inode,
1139+
const struct kstat *stat
1140+
),
1141+
TP_ARGS(inode, stat),
1142+
TP_STRUCT__entry(
1143+
__field(const void *, inode)
1144+
__field(unsigned long, mask)
1145+
__field(u32, mem_align)
1146+
__field(u32, offset_align)
1147+
__field(u32, read_offset_align)
1148+
),
1149+
TP_fast_assign(
1150+
__entry->inode = inode;
1151+
__entry->mask = stat->result_mask;
1152+
__entry->mem_align = stat->dio_mem_align;
1153+
__entry->offset_align = stat->dio_offset_align;
1154+
__entry->read_offset_align = stat->dio_read_offset_align;
1155+
),
1156+
TP_printk("inode=%p flags=%s mem_align=%u offset_align=%u read_offset_align=%u",
1157+
__entry->inode, show_statx_mask(__entry->mask),
1158+
__entry->mem_align, __entry->offset_align,
1159+
__entry->read_offset_align
1160+
)
1161+
);
1162+
11361163
TRACE_EVENT(nfsd_file_acquire,
11371164
TP_PROTO(
11381165
const struct svc_rqst *rqstp,

fs/nfsd/vfs.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ static inline __be32 fh_getattr(const struct svc_fh *fh, struct kstat *stat)
185185
u32 request_mask = STATX_BASIC_STATS;
186186
struct path p = {.mnt = fh->fh_export->ex_path.mnt,
187187
.dentry = fh->fh_dentry};
188+
struct inode *inode = d_inode(p.dentry);
189+
190+
if (S_ISREG(inode->i_mode))
191+
request_mask |= (STATX_DIOALIGN | STATX_DIO_READ_ALIGN);
188192

189193
if (fh->fh_maxsize == NFS4_FHSIZE)
190194
request_mask |= (STATX_BTIME | STATX_CHANGE_COOKIE);

include/trace/misc/fs.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,25 @@
141141
{ ATTR_TIMES_SET, "TIMES_SET" }, \
142142
{ ATTR_TOUCH, "TOUCH"}, \
143143
{ ATTR_DELEG, "DELEG"})
144+
145+
#define show_statx_mask(flags) \
146+
__print_flags(flags, "|", \
147+
{ STATX_TYPE, "TYPE" }, \
148+
{ STATX_MODE, "MODE" }, \
149+
{ STATX_NLINK, "NLINK" }, \
150+
{ STATX_UID, "UID" }, \
151+
{ STATX_GID, "GID" }, \
152+
{ STATX_ATIME, "ATIME" }, \
153+
{ STATX_MTIME, "MTIME" }, \
154+
{ STATX_CTIME, "CTIME" }, \
155+
{ STATX_INO, "INO" }, \
156+
{ STATX_SIZE, "SIZE" }, \
157+
{ STATX_BLOCKS, "BLOCKS" }, \
158+
{ STATX_BASIC_STATS, "BASIC_STATS" }, \
159+
{ STATX_BTIME, "BTIME" }, \
160+
{ STATX_MNT_ID, "MNT_ID" }, \
161+
{ STATX_DIOALIGN, "DIOALIGN" }, \
162+
{ STATX_MNT_ID_UNIQUE, "MNT_ID_UNIQUE" }, \
163+
{ STATX_SUBVOL, "SUBVOL" }, \
164+
{ STATX_WRITE_ATOMIC, "WRITE_ATOMIC" }, \
165+
{ STATX_DIO_READ_ALIGN, "DIO_READ_ALIGN" })

0 commit comments

Comments
 (0)