@@ -147,6 +147,17 @@ int nfs_sync_mapping(struct address_space *mapping)
147
147
return ret ;
148
148
}
149
149
150
+ static void nfs_set_cache_invalid (struct inode * inode , unsigned long flags )
151
+ {
152
+ struct nfs_inode * nfsi = NFS_I (inode );
153
+
154
+ if (inode -> i_mapping -> nrpages == 0 )
155
+ flags &= ~NFS_INO_INVALID_DATA ;
156
+ nfsi -> cache_validity |= flags ;
157
+ if (flags & NFS_INO_INVALID_DATA )
158
+ nfs_fscache_invalidate (inode );
159
+ }
160
+
150
161
/*
151
162
* Invalidate the local caches
152
163
*/
@@ -162,17 +173,16 @@ static void nfs_zap_caches_locked(struct inode *inode)
162
173
163
174
memset (NFS_I (inode )-> cookieverf , 0 , sizeof (NFS_I (inode )-> cookieverf ));
164
175
if (S_ISREG (mode ) || S_ISDIR (mode ) || S_ISLNK (mode )) {
165
- nfs_fscache_invalidate (inode );
166
- nfsi -> cache_validity |= NFS_INO_INVALID_ATTR
176
+ nfs_set_cache_invalid (inode , NFS_INO_INVALID_ATTR
167
177
| NFS_INO_INVALID_DATA
168
178
| NFS_INO_INVALID_ACCESS
169
179
| NFS_INO_INVALID_ACL
170
- | NFS_INO_REVAL_PAGECACHE ;
180
+ | NFS_INO_REVAL_PAGECACHE ) ;
171
181
} else
172
- nfsi -> cache_validity |= NFS_INO_INVALID_ATTR
182
+ nfs_set_cache_invalid ( inode , NFS_INO_INVALID_ATTR
173
183
| NFS_INO_INVALID_ACCESS
174
184
| NFS_INO_INVALID_ACL
175
- | NFS_INO_REVAL_PAGECACHE ;
185
+ | NFS_INO_REVAL_PAGECACHE ) ;
176
186
nfs_zap_label_cache_locked (nfsi );
177
187
}
178
188
@@ -187,8 +197,7 @@ void nfs_zap_mapping(struct inode *inode, struct address_space *mapping)
187
197
{
188
198
if (mapping -> nrpages != 0 ) {
189
199
spin_lock (& inode -> i_lock );
190
- NFS_I (inode )-> cache_validity |= NFS_INO_INVALID_DATA ;
191
- nfs_fscache_invalidate (inode );
200
+ nfs_set_cache_invalid (inode , NFS_INO_INVALID_DATA );
192
201
spin_unlock (& inode -> i_lock );
193
202
}
194
203
}
@@ -209,7 +218,7 @@ EXPORT_SYMBOL_GPL(nfs_zap_acl_cache);
209
218
void nfs_invalidate_atime (struct inode * inode )
210
219
{
211
220
spin_lock (& inode -> i_lock );
212
- NFS_I (inode ) -> cache_validity |= NFS_INO_INVALID_ATIME ;
221
+ nfs_set_cache_invalid (inode , NFS_INO_INVALID_ATIME ) ;
213
222
spin_unlock (& inode -> i_lock );
214
223
}
215
224
EXPORT_SYMBOL_GPL (nfs_invalidate_atime );
@@ -369,7 +378,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
369
378
inode -> i_mode = fattr -> mode ;
370
379
if ((fattr -> valid & NFS_ATTR_FATTR_MODE ) == 0
371
380
&& nfs_server_capable (inode , NFS_CAP_MODE ))
372
- nfsi -> cache_validity |= NFS_INO_INVALID_ATTR ;
381
+ nfs_set_cache_invalid ( inode , NFS_INO_INVALID_ATTR ) ;
373
382
/* Why so? Because we want revalidate for devices/FIFOs, and
374
383
* that's precisely what we have in nfs_file_inode_operations.
375
384
*/
@@ -415,36 +424,36 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
415
424
if (fattr -> valid & NFS_ATTR_FATTR_ATIME )
416
425
inode -> i_atime = fattr -> atime ;
417
426
else if (nfs_server_capable (inode , NFS_CAP_ATIME ))
418
- nfsi -> cache_validity |= NFS_INO_INVALID_ATTR ;
427
+ nfs_set_cache_invalid ( inode , NFS_INO_INVALID_ATTR ) ;
419
428
if (fattr -> valid & NFS_ATTR_FATTR_MTIME )
420
429
inode -> i_mtime = fattr -> mtime ;
421
430
else if (nfs_server_capable (inode , NFS_CAP_MTIME ))
422
- nfsi -> cache_validity |= NFS_INO_INVALID_ATTR ;
431
+ nfs_set_cache_invalid ( inode , NFS_INO_INVALID_ATTR ) ;
423
432
if (fattr -> valid & NFS_ATTR_FATTR_CTIME )
424
433
inode -> i_ctime = fattr -> ctime ;
425
434
else if (nfs_server_capable (inode , NFS_CAP_CTIME ))
426
- nfsi -> cache_validity |= NFS_INO_INVALID_ATTR ;
435
+ nfs_set_cache_invalid ( inode , NFS_INO_INVALID_ATTR ) ;
427
436
if (fattr -> valid & NFS_ATTR_FATTR_CHANGE )
428
437
inode -> i_version = fattr -> change_attr ;
429
438
else if (nfs_server_capable (inode , NFS_CAP_CHANGE_ATTR ))
430
- nfsi -> cache_validity |= NFS_INO_INVALID_ATTR ;
439
+ nfs_set_cache_invalid ( inode , NFS_INO_INVALID_ATTR ) ;
431
440
if (fattr -> valid & NFS_ATTR_FATTR_SIZE )
432
441
inode -> i_size = nfs_size_to_loff_t (fattr -> size );
433
442
else
434
- nfsi -> cache_validity |= NFS_INO_INVALID_ATTR
435
- | NFS_INO_REVAL_PAGECACHE ;
443
+ nfs_set_cache_invalid ( inode , NFS_INO_INVALID_ATTR
444
+ | NFS_INO_REVAL_PAGECACHE ) ;
436
445
if (fattr -> valid & NFS_ATTR_FATTR_NLINK )
437
446
set_nlink (inode , fattr -> nlink );
438
447
else if (nfs_server_capable (inode , NFS_CAP_NLINK ))
439
- nfsi -> cache_validity |= NFS_INO_INVALID_ATTR ;
448
+ nfs_set_cache_invalid ( inode , NFS_INO_INVALID_ATTR ) ;
440
449
if (fattr -> valid & NFS_ATTR_FATTR_OWNER )
441
450
inode -> i_uid = fattr -> uid ;
442
451
else if (nfs_server_capable (inode , NFS_CAP_OWNER ))
443
- nfsi -> cache_validity |= NFS_INO_INVALID_ATTR ;
452
+ nfs_set_cache_invalid ( inode , NFS_INO_INVALID_ATTR ) ;
444
453
if (fattr -> valid & NFS_ATTR_FATTR_GROUP )
445
454
inode -> i_gid = fattr -> gid ;
446
455
else if (nfs_server_capable (inode , NFS_CAP_OWNER_GROUP ))
447
- nfsi -> cache_validity |= NFS_INO_INVALID_ATTR ;
456
+ nfs_set_cache_invalid ( inode , NFS_INO_INVALID_ATTR ) ;
448
457
if (fattr -> valid & NFS_ATTR_FATTR_BLOCKS_USED )
449
458
inode -> i_blocks = fattr -> du .nfs2 .blocks ;
450
459
if (fattr -> valid & NFS_ATTR_FATTR_SPACE_USED ) {
@@ -550,6 +559,9 @@ static int nfs_vmtruncate(struct inode * inode, loff_t offset)
550
559
551
560
spin_lock (& inode -> i_lock );
552
561
i_size_write (inode , offset );
562
+ /* Optimisation */
563
+ if (offset == 0 )
564
+ NFS_I (inode )-> cache_validity &= ~NFS_INO_INVALID_DATA ;
553
565
spin_unlock (& inode -> i_lock );
554
566
555
567
truncate_pagecache (inode , offset );
@@ -578,7 +590,8 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr)
578
590
inode -> i_uid = attr -> ia_uid ;
579
591
if ((attr -> ia_valid & ATTR_GID ) != 0 )
580
592
inode -> i_gid = attr -> ia_gid ;
581
- NFS_I (inode )-> cache_validity |= NFS_INO_INVALID_ACCESS |NFS_INO_INVALID_ACL ;
593
+ nfs_set_cache_invalid (inode , NFS_INO_INVALID_ACCESS
594
+ | NFS_INO_INVALID_ACL );
582
595
spin_unlock (& inode -> i_lock );
583
596
}
584
597
if ((attr -> ia_valid & ATTR_SIZE ) != 0 ) {
@@ -1101,7 +1114,7 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr
1101
1114
&& inode -> i_version == fattr -> pre_change_attr ) {
1102
1115
inode -> i_version = fattr -> change_attr ;
1103
1116
if (S_ISDIR (inode -> i_mode ))
1104
- nfsi -> cache_validity |= NFS_INO_INVALID_DATA ;
1117
+ nfs_set_cache_invalid ( inode , NFS_INO_INVALID_DATA ) ;
1105
1118
ret |= NFS_INO_INVALID_ATTR ;
1106
1119
}
1107
1120
/* If we have atomic WCC data, we may update some attributes */
@@ -1117,7 +1130,7 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr
1117
1130
&& timespec_equal (& inode -> i_mtime , & fattr -> pre_mtime )) {
1118
1131
memcpy (& inode -> i_mtime , & fattr -> mtime , sizeof (inode -> i_mtime ));
1119
1132
if (S_ISDIR (inode -> i_mode ))
1120
- nfsi -> cache_validity |= NFS_INO_INVALID_DATA ;
1133
+ nfs_set_cache_invalid ( inode , NFS_INO_INVALID_DATA ) ;
1121
1134
ret |= NFS_INO_INVALID_ATTR ;
1122
1135
}
1123
1136
if ((fattr -> valid & NFS_ATTR_FATTR_PRESIZE )
@@ -1128,9 +1141,6 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr
1128
1141
ret |= NFS_INO_INVALID_ATTR ;
1129
1142
}
1130
1143
1131
- if (nfsi -> cache_validity & NFS_INO_INVALID_DATA )
1132
- nfs_fscache_invalidate (inode );
1133
-
1134
1144
return ret ;
1135
1145
}
1136
1146
@@ -1189,7 +1199,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
1189
1199
invalid |= NFS_INO_INVALID_ATIME ;
1190
1200
1191
1201
if (invalid != 0 )
1192
- nfsi -> cache_validity |= invalid ;
1202
+ nfs_set_cache_invalid ( inode , invalid ) ;
1193
1203
1194
1204
nfsi -> read_cache_jiffies = fattr -> time_start ;
1195
1205
return 0 ;
@@ -1402,13 +1412,11 @@ EXPORT_SYMBOL_GPL(nfs_refresh_inode);
1402
1412
1403
1413
static int nfs_post_op_update_inode_locked (struct inode * inode , struct nfs_fattr * fattr )
1404
1414
{
1405
- struct nfs_inode * nfsi = NFS_I ( inode ) ;
1415
+ unsigned long invalid = NFS_INO_INVALID_ATTR | NFS_INO_REVAL_PAGECACHE ;
1406
1416
1407
- nfsi -> cache_validity |= NFS_INO_INVALID_ATTR |NFS_INO_REVAL_PAGECACHE ;
1408
- if (S_ISDIR (inode -> i_mode )) {
1409
- nfsi -> cache_validity |= NFS_INO_INVALID_DATA ;
1410
- nfs_fscache_invalidate (inode );
1411
- }
1417
+ if (S_ISDIR (inode -> i_mode ))
1418
+ invalid |= NFS_INO_INVALID_DATA ;
1419
+ nfs_set_cache_invalid (inode , invalid );
1412
1420
if ((fattr -> valid & NFS_ATTR_FATTR ) == 0 )
1413
1421
return 0 ;
1414
1422
return nfs_refresh_inode_locked (inode , fattr );
@@ -1601,6 +1609,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1601
1609
if ((nfsi -> npages == 0 ) || new_isize > cur_isize ) {
1602
1610
i_size_write (inode , new_isize );
1603
1611
invalid |= NFS_INO_INVALID_ATTR |NFS_INO_INVALID_DATA ;
1612
+ invalid &= ~NFS_INO_REVAL_PAGECACHE ;
1604
1613
}
1605
1614
dprintk ("NFS: isize change on server for file %s/%ld "
1606
1615
"(%Ld to %Ld)\n" ,
@@ -1702,10 +1711,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1702
1711
invalid &= ~NFS_INO_INVALID_DATA ;
1703
1712
if (!NFS_PROTO (inode )-> have_delegation (inode , FMODE_READ ) ||
1704
1713
(save_cache_validity & NFS_INO_REVAL_FORCED ))
1705
- nfsi -> cache_validity |= invalid ;
1706
-
1707
- if (invalid & NFS_INO_INVALID_DATA )
1708
- nfs_fscache_invalidate (inode );
1714
+ nfs_set_cache_invalid (inode , invalid );
1709
1715
1710
1716
return 0 ;
1711
1717
out_err :
0 commit comments