@@ -31,6 +31,9 @@ xchk_xattr_buf_cleanup(
3131 ab -> freemap = NULL ;
3232 kvfree (ab -> usedmap );
3333 ab -> usedmap = NULL ;
34+ kvfree (ab -> value );
35+ ab -> value = NULL ;
36+ ab -> value_sz = 0 ;
3437}
3538
3639/*
@@ -44,54 +47,45 @@ xchk_setup_xattr_buf(
4447 size_t value_size ,
4548 gfp_t flags )
4649{
47- size_t sz = value_size ;
4850 size_t bmp_sz ;
4951 struct xchk_xattr_buf * ab = sc -> buf ;
50- unsigned long * old_usedmap = NULL ;
51- unsigned long * old_freemap = NULL ;
52+ void * new_val ;
5253
5354 bmp_sz = sizeof (long ) * BITS_TO_LONGS (sc -> mp -> m_attr_geo -> blksize );
5455
55- /*
56- * If there's already a buffer, figure out if we need to reallocate it
57- * to accommodate a larger size.
58- */
59- if (ab ) {
60- if (sz <= ab -> sz )
61- return 0 ;
62- old_freemap = ab -> freemap ;
63- old_usedmap = ab -> usedmap ;
64- kvfree (ab );
65- sc -> buf = NULL ;
66- }
56+ if (ab )
57+ goto resize_value ;
6758
68- /*
69- * Don't zero the buffer upon allocation to avoid runtime overhead.
70- * All users must be careful never to read uninitialized contents.
71- */
72- ab = kvmalloc (sizeof (* ab ) + sz , flags );
59+ ab = kvzalloc (sizeof (struct xchk_xattr_buf ), flags );
7360 if (!ab )
7461 return - ENOMEM ;
75- ab -> sz = sz ;
7662 sc -> buf = ab ;
7763 sc -> buf_cleanup = xchk_xattr_buf_cleanup ;
7864
79- if (old_usedmap ) {
80- ab -> usedmap = old_usedmap ;
81- } else {
82- ab -> usedmap = kvmalloc (bmp_sz , flags );
83- if (!ab -> usedmap )
84- return - ENOMEM ;
85- }
65+ ab -> usedmap = kvmalloc (bmp_sz , flags );
66+ if (!ab -> usedmap )
67+ return - ENOMEM ;
8668
87- if (old_freemap ) {
88- ab -> freemap = old_freemap ;
89- } else {
90- ab -> freemap = kvmalloc (bmp_sz , flags );
91- if (!ab -> freemap )
92- return - ENOMEM ;
69+ ab -> freemap = kvmalloc (bmp_sz , flags );
70+ if (!ab -> freemap )
71+ return - ENOMEM ;
72+
73+ resize_value :
74+ if (ab -> value_sz >= value_size )
75+ return 0 ;
76+
77+ if (ab -> value ) {
78+ kvfree (ab -> value );
79+ ab -> value = NULL ;
80+ ab -> value_sz = 0 ;
9381 }
9482
83+ new_val = kvmalloc (value_size , flags );
84+ if (!new_val )
85+ return - ENOMEM ;
86+
87+ ab -> value = new_val ;
88+ ab -> value_sz = value_size ;
9589 return 0 ;
9690}
9791
@@ -140,11 +134,24 @@ xchk_xattr_listent(
140134 int namelen ,
141135 int valuelen )
142136{
137+ struct xfs_da_args args = {
138+ .op_flags = XFS_DA_OP_NOTIME ,
139+ .attr_filter = flags & XFS_ATTR_NSP_ONDISK_MASK ,
140+ .geo = context -> dp -> i_mount -> m_attr_geo ,
141+ .whichfork = XFS_ATTR_FORK ,
142+ .dp = context -> dp ,
143+ .name = name ,
144+ .namelen = namelen ,
145+ .hashval = xfs_da_hashname (name , namelen ),
146+ .trans = context -> tp ,
147+ .valuelen = valuelen ,
148+ };
149+ struct xchk_xattr_buf * ab ;
143150 struct xchk_xattr * sx ;
144- struct xfs_da_args args = { NULL };
145151 int error = 0 ;
146152
147153 sx = container_of (context , struct xchk_xattr , context );
154+ ab = sx -> sc -> buf ;
148155
149156 if (xchk_should_terminate (sx -> sc , & error )) {
150157 context -> seen_enough = error ;
@@ -182,17 +189,7 @@ xchk_xattr_listent(
182189 return ;
183190 }
184191
185- args .op_flags = XFS_DA_OP_NOTIME ;
186- args .attr_filter = flags & XFS_ATTR_NSP_ONDISK_MASK ;
187- args .geo = context -> dp -> i_mount -> m_attr_geo ;
188- args .whichfork = XFS_ATTR_FORK ;
189- args .dp = context -> dp ;
190- args .name = name ;
191- args .namelen = namelen ;
192- args .hashval = xfs_da_hashname (args .name , args .namelen );
193- args .trans = context -> tp ;
194- args .value = xchk_xattr_valuebuf (sx -> sc );
195- args .valuelen = valuelen ;
192+ args .value = ab -> value ;
196193
197194 error = xfs_attr_get_ilocked (& args );
198195 /* ENODATA means the hash lookup failed and the attr is bad */
0 commit comments