Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Mike Snitzer and committed by
Anna Schumaker
d11f6cd1 ffe38192

+91
+34
fs/nfsd/filecache.c
··· 231 231 refcount_set(&nf->nf_ref, 1); 232 232 nf->nf_may = need; 233 233 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; 234 237 return nf; 235 238 } 236 239 ··· 1073 1070 } 1074 1071 1075 1072 static __be32 1073 + nfsd_file_get_dio_attrs(const struct svc_fh *fhp, struct nfsd_file *nf) 1074 + { 1075 + struct inode *inode = file_inode(nf->nf_file); 1076 + struct kstat stat; 1077 + __be32 status; 1078 + 1079 + /* Currently only need to get DIO alignment info for regular files */ 1080 + if (!S_ISREG(inode->i_mode)) 1081 + return nfs_ok; 1082 + 1083 + status = fh_getattr(fhp, &stat); 1084 + if (status != nfs_ok) 1085 + return status; 1086 + 1087 + trace_nfsd_file_get_dio_attrs(inode, &stat); 1088 + 1089 + if (stat.result_mask & STATX_DIOALIGN) { 1090 + nf->nf_dio_mem_align = stat.dio_mem_align; 1091 + nf->nf_dio_offset_align = stat.dio_offset_align; 1092 + } 1093 + if (stat.result_mask & STATX_DIO_READ_ALIGN) 1094 + nf->nf_dio_read_offset_align = stat.dio_read_offset_align; 1095 + else 1096 + nf->nf_dio_read_offset_align = nf->nf_dio_offset_align; 1097 + 1098 + return nfs_ok; 1099 + } 1100 + 1101 + static __be32 1076 1102 nfsd_file_do_acquire(struct svc_rqst *rqstp, struct net *net, 1077 1103 struct svc_cred *cred, 1078 1104 struct auth_domain *client, ··· 1219 1187 } 1220 1188 status = nfserrno(ret); 1221 1189 trace_nfsd_file_open(nf, status); 1190 + if (status == nfs_ok) 1191 + status = nfsd_file_get_dio_attrs(fhp, nf); 1222 1192 } 1223 1193 } else 1224 1194 status = nfserr_jukebox;
+4
fs/nfsd/filecache.h
··· 54 54 struct list_head nf_gc; 55 55 struct rcu_head nf_rcu; 56 56 ktime_t nf_birthtime; 57 + 58 + u32 nf_dio_mem_align; 59 + u32 nf_dio_offset_align; 60 + u32 nf_dio_read_offset_align; 57 61 }; 58 62 59 63 int nfsd_file_cache_init(void);
+27
fs/nfsd/trace.h
··· 1133 1133 ) 1134 1134 ); 1135 1135 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 + 1136 1163 TRACE_EVENT(nfsd_file_acquire, 1137 1164 TP_PROTO( 1138 1165 const struct svc_rqst *rqstp,
+4
fs/nfsd/vfs.h
··· 185 185 u32 request_mask = STATX_BASIC_STATS; 186 186 struct path p = {.mnt = fh->fh_export->ex_path.mnt, 187 187 .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); 188 192 189 193 if (fh->fh_maxsize == NFS4_FHSIZE) 190 194 request_mask |= (STATX_BTIME | STATX_CHANGE_COOKIE);
+22
include/trace/misc/fs.h
··· 141 141 { ATTR_TIMES_SET, "TIMES_SET" }, \ 142 142 { ATTR_TOUCH, "TOUCH"}, \ 143 143 { 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" })