@@ -1158,37 +1158,48 @@ nfs4_dec_nlink_locked(struct inode *inode)
1158
1158
}
1159
1159
1160
1160
static void
1161
- update_changeattr_locked (struct inode * dir , struct nfs4_change_info * cinfo ,
1161
+ nfs4_update_changeattr_locked (struct inode * inode ,
1162
+ struct nfs4_change_info * cinfo ,
1162
1163
unsigned long timestamp , unsigned long cache_validity )
1163
1164
{
1164
- struct nfs_inode * nfsi = NFS_I (dir );
1165
+ struct nfs_inode * nfsi = NFS_I (inode );
1165
1166
1166
1167
nfsi -> cache_validity |= NFS_INO_INVALID_CTIME
1167
1168
| NFS_INO_INVALID_MTIME
1168
- | NFS_INO_INVALID_DATA
1169
1169
| cache_validity ;
1170
- if (cinfo -> atomic && cinfo -> before == inode_peek_iversion_raw (dir )) {
1170
+
1171
+ if (cinfo -> atomic && cinfo -> before == inode_peek_iversion_raw (inode )) {
1171
1172
nfsi -> cache_validity &= ~NFS_INO_REVAL_PAGECACHE ;
1172
1173
nfsi -> attrtimeo_timestamp = jiffies ;
1173
1174
} else {
1174
- nfs_force_lookup_revalidate (dir );
1175
- if (cinfo -> before != inode_peek_iversion_raw (dir ))
1175
+ if (S_ISDIR (inode -> i_mode )) {
1176
+ nfsi -> cache_validity |= NFS_INO_INVALID_DATA ;
1177
+ nfs_force_lookup_revalidate (inode );
1178
+ } else {
1179
+ if (!NFS_PROTO (inode )-> have_delegation (inode ,
1180
+ FMODE_READ ))
1181
+ nfsi -> cache_validity |= NFS_INO_REVAL_PAGECACHE ;
1182
+ }
1183
+
1184
+ if (cinfo -> before != inode_peek_iversion_raw (inode ))
1176
1185
nfsi -> cache_validity |= NFS_INO_INVALID_ACCESS |
1177
- NFS_INO_INVALID_ACL ;
1186
+ NFS_INO_INVALID_ACL ;
1178
1187
}
1179
- inode_set_iversion_raw (dir , cinfo -> after );
1188
+ inode_set_iversion_raw (inode , cinfo -> after );
1180
1189
nfsi -> read_cache_jiffies = timestamp ;
1181
1190
nfsi -> attr_gencount = nfs_inc_attr_generation_counter ();
1182
1191
nfsi -> cache_validity &= ~NFS_INO_INVALID_CHANGE ;
1183
- nfs_fscache_invalidate (dir );
1192
+
1193
+ if (nfsi -> cache_validity & NFS_INO_INVALID_DATA )
1194
+ nfs_fscache_invalidate (inode );
1184
1195
}
1185
1196
1186
- static void
1187
- update_changeattr (struct inode * dir , struct nfs4_change_info * cinfo ,
1197
+ void
1198
+ nfs4_update_changeattr (struct inode * dir , struct nfs4_change_info * cinfo ,
1188
1199
unsigned long timestamp , unsigned long cache_validity )
1189
1200
{
1190
1201
spin_lock (& dir -> i_lock );
1191
- update_changeattr_locked (dir , cinfo , timestamp , cache_validity );
1202
+ nfs4_update_changeattr_locked (dir , cinfo , timestamp , cache_validity );
1192
1203
spin_unlock (& dir -> i_lock );
1193
1204
}
1194
1205
@@ -2644,8 +2655,9 @@ static int _nfs4_proc_open(struct nfs4_opendata *data,
2644
2655
data -> file_created = true;
2645
2656
if (data -> file_created ||
2646
2657
inode_peek_iversion_raw (dir ) != o_res -> cinfo .after )
2647
- update_changeattr (dir , & o_res -> cinfo ,
2648
- o_res -> f_attr -> time_start , 0 );
2658
+ nfs4_update_changeattr (dir , & o_res -> cinfo ,
2659
+ o_res -> f_attr -> time_start ,
2660
+ NFS_INO_INVALID_DATA );
2649
2661
}
2650
2662
if ((o_res -> rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX ) == 0 )
2651
2663
server -> caps &= ~NFS_CAP_POSIX_LOCK ;
@@ -4531,7 +4543,8 @@ _nfs4_proc_remove(struct inode *dir, const struct qstr *name, u32 ftype)
4531
4543
status = nfs4_call_sync (server -> client , server , & msg , & args .seq_args , & res .seq_res , 1 );
4532
4544
if (status == 0 ) {
4533
4545
spin_lock (& dir -> i_lock );
4534
- update_changeattr_locked (dir , & res .cinfo , timestamp , 0 );
4546
+ nfs4_update_changeattr_locked (dir , & res .cinfo , timestamp ,
4547
+ NFS_INO_INVALID_DATA );
4535
4548
/* Removing a directory decrements nlink in the parent */
4536
4549
if (ftype == NF4DIR && dir -> i_nlink > 2 )
4537
4550
nfs4_dec_nlink_locked (dir );
@@ -4615,8 +4628,9 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
4615
4628
& data -> timeout ) == - EAGAIN )
4616
4629
return 0 ;
4617
4630
if (task -> tk_status == 0 )
4618
- update_changeattr (dir , & res -> cinfo ,
4619
- res -> dir_attr -> time_start , 0 );
4631
+ nfs4_update_changeattr (dir , & res -> cinfo ,
4632
+ res -> dir_attr -> time_start ,
4633
+ NFS_INO_INVALID_DATA );
4620
4634
return 1 ;
4621
4635
}
4622
4636
@@ -4660,16 +4674,18 @@ static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
4660
4674
if (task -> tk_status == 0 ) {
4661
4675
if (new_dir != old_dir ) {
4662
4676
/* Note: If we moved a directory, nlink will change */
4663
- update_changeattr (old_dir , & res -> old_cinfo ,
4677
+ nfs4_update_changeattr (old_dir , & res -> old_cinfo ,
4664
4678
res -> old_fattr -> time_start ,
4665
- NFS_INO_INVALID_OTHER );
4666
- update_changeattr (new_dir , & res -> new_cinfo ,
4679
+ NFS_INO_INVALID_OTHER |
4680
+ NFS_INO_INVALID_DATA );
4681
+ nfs4_update_changeattr (new_dir , & res -> new_cinfo ,
4667
4682
res -> new_fattr -> time_start ,
4668
- NFS_INO_INVALID_OTHER );
4683
+ NFS_INO_INVALID_OTHER |
4684
+ NFS_INO_INVALID_DATA );
4669
4685
} else
4670
- update_changeattr (old_dir , & res -> old_cinfo ,
4686
+ nfs4_update_changeattr (old_dir , & res -> old_cinfo ,
4671
4687
res -> old_fattr -> time_start ,
4672
- 0 );
4688
+ NFS_INO_INVALID_DATA );
4673
4689
}
4674
4690
return 1 ;
4675
4691
}
@@ -4710,7 +4726,8 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, const struct
4710
4726
4711
4727
status = nfs4_call_sync (server -> client , server , & msg , & arg .seq_args , & res .seq_res , 1 );
4712
4728
if (!status ) {
4713
- update_changeattr (dir , & res .cinfo , res .fattr -> time_start , 0 );
4729
+ nfs4_update_changeattr (dir , & res .cinfo , res .fattr -> time_start ,
4730
+ NFS_INO_INVALID_DATA );
4714
4731
status = nfs_post_op_update_inode (inode , res .fattr );
4715
4732
if (!status )
4716
4733
nfs_setsecurity (inode , res .fattr , res .label );
@@ -4788,8 +4805,9 @@ static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_
4788
4805
& data -> arg .seq_args , & data -> res .seq_res , 1 );
4789
4806
if (status == 0 ) {
4790
4807
spin_lock (& dir -> i_lock );
4791
- update_changeattr_locked (dir , & data -> res .dir_cinfo ,
4792
- data -> res .fattr -> time_start , 0 );
4808
+ nfs4_update_changeattr_locked (dir , & data -> res .dir_cinfo ,
4809
+ data -> res .fattr -> time_start ,
4810
+ NFS_INO_INVALID_DATA );
4793
4811
/* Creating a directory bumps nlink in the parent */
4794
4812
if (data -> arg .ftype == NF4DIR )
4795
4813
nfs4_inc_nlink_locked (dir );
0 commit comments