@@ -878,7 +878,10 @@ void nfs_inode_attach_open_context(struct nfs_open_context *ctx)
878
878
struct nfs_inode * nfsi = NFS_I (inode );
879
879
880
880
spin_lock (& inode -> i_lock );
881
- list_add (& ctx -> list , & nfsi -> open_files );
881
+ if (ctx -> mode & FMODE_WRITE )
882
+ list_add (& ctx -> list , & nfsi -> open_files );
883
+ else
884
+ list_add_tail (& ctx -> list , & nfsi -> open_files );
882
885
spin_unlock (& inode -> i_lock );
883
886
}
884
887
EXPORT_SYMBOL_GPL (nfs_inode_attach_open_context );
@@ -1215,6 +1218,25 @@ int nfs_revalidate_mapping_protected(struct inode *inode, struct address_space *
1215
1218
return __nfs_revalidate_mapping (inode , mapping , true);
1216
1219
}
1217
1220
1221
+ static bool nfs_file_has_writers (struct nfs_inode * nfsi )
1222
+ {
1223
+ struct inode * inode = & nfsi -> vfs_inode ;
1224
+
1225
+ assert_spin_locked (& inode -> i_lock );
1226
+
1227
+ if (!S_ISREG (inode -> i_mode ))
1228
+ return false;
1229
+ if (list_empty (& nfsi -> open_files ))
1230
+ return false;
1231
+ /* Note: This relies on nfsi->open_files being ordered with writers
1232
+ * being placed at the head of the list.
1233
+ * See nfs_inode_attach_open_context()
1234
+ */
1235
+ return (list_first_entry (& nfsi -> open_files ,
1236
+ struct nfs_open_context ,
1237
+ list )-> mode & FMODE_WRITE ) == FMODE_WRITE ;
1238
+ }
1239
+
1218
1240
static unsigned long nfs_wcc_update_inode (struct inode * inode , struct nfs_fattr * fattr )
1219
1241
{
1220
1242
struct nfs_inode * nfsi = NFS_I (inode );
@@ -1279,22 +1301,24 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
1279
1301
if ((fattr -> valid & NFS_ATTR_FATTR_TYPE ) && (inode -> i_mode & S_IFMT ) != (fattr -> mode & S_IFMT ))
1280
1302
return - EIO ;
1281
1303
1282
- if ((fattr -> valid & NFS_ATTR_FATTR_CHANGE ) != 0 &&
1283
- inode -> i_version != fattr -> change_attr )
1284
- invalid |= NFS_INO_INVALID_ATTR |NFS_INO_REVAL_PAGECACHE ;
1304
+ if (!nfs_file_has_writers (nfsi )) {
1305
+ /* Verify a few of the more important attributes */
1306
+ if ((fattr -> valid & NFS_ATTR_FATTR_CHANGE ) != 0 && inode -> i_version != fattr -> change_attr )
1307
+ invalid |= NFS_INO_INVALID_ATTR | NFS_INO_REVAL_PAGECACHE ;
1285
1308
1286
- /* Verify a few of the more important attributes */
1287
- if ((fattr -> valid & NFS_ATTR_FATTR_MTIME ) && !timespec_equal (& inode -> i_mtime , & fattr -> mtime ))
1288
- invalid |= NFS_INO_INVALID_ATTR ;
1309
+ if ((fattr -> valid & NFS_ATTR_FATTR_MTIME ) && !timespec_equal (& inode -> i_mtime , & fattr -> mtime ))
1310
+ invalid |= NFS_INO_INVALID_ATTR ;
1289
1311
1290
- if (fattr -> valid & NFS_ATTR_FATTR_SIZE ) {
1291
- cur_size = i_size_read (inode );
1292
- new_isize = nfs_size_to_loff_t (fattr -> size );
1293
- if (cur_size != new_isize )
1294
- invalid |= NFS_INO_INVALID_ATTR |NFS_INO_REVAL_PAGECACHE ;
1312
+ if ((fattr -> valid & NFS_ATTR_FATTR_CTIME ) && !timespec_equal (& inode -> i_ctime , & fattr -> ctime ))
1313
+ invalid |= NFS_INO_INVALID_ATTR ;
1314
+
1315
+ if (fattr -> valid & NFS_ATTR_FATTR_SIZE ) {
1316
+ cur_size = i_size_read (inode );
1317
+ new_isize = nfs_size_to_loff_t (fattr -> size );
1318
+ if (cur_size != new_isize )
1319
+ invalid |= NFS_INO_INVALID_ATTR |NFS_INO_REVAL_PAGECACHE ;
1320
+ }
1295
1321
}
1296
- if (nfsi -> nrequests != 0 )
1297
- invalid &= ~NFS_INO_REVAL_PAGECACHE ;
1298
1322
1299
1323
/* Have any file permissions changed? */
1300
1324
if ((fattr -> valid & NFS_ATTR_FATTR_MODE ) && (inode -> i_mode & S_IALLUGO ) != (fattr -> mode & S_IALLUGO ))
@@ -1526,7 +1550,7 @@ EXPORT_SYMBOL_GPL(nfs_refresh_inode);
1526
1550
1527
1551
static int nfs_post_op_update_inode_locked (struct inode * inode , struct nfs_fattr * fattr )
1528
1552
{
1529
- unsigned long invalid = NFS_INO_INVALID_ATTR | NFS_INO_REVAL_PAGECACHE ;
1553
+ unsigned long invalid = NFS_INO_INVALID_ATTR ;
1530
1554
1531
1555
/*
1532
1556
* Don't revalidate the pagecache if we hold a delegation, but do
@@ -1675,6 +1699,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1675
1699
unsigned long invalid = 0 ;
1676
1700
unsigned long now = jiffies ;
1677
1701
unsigned long save_cache_validity ;
1702
+ bool have_writers = nfs_file_has_writers (nfsi );
1678
1703
bool cache_revalidated = true;
1679
1704
1680
1705
dfprintk (VFS , "NFS: %s(%s/%lu fh_crc=0x%08x ct=%d info=0x%x)\n" ,
@@ -1730,7 +1755,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1730
1755
dprintk ("NFS: change_attr change on server for file %s/%ld\n" ,
1731
1756
inode -> i_sb -> s_id , inode -> i_ino );
1732
1757
/* Could it be a race with writeback? */
1733
- if (nfsi -> nrequests == 0 ) {
1758
+ if (! have_writers ) {
1734
1759
invalid |= NFS_INO_INVALID_ATTR
1735
1760
| NFS_INO_INVALID_DATA
1736
1761
| NFS_INO_INVALID_ACCESS
@@ -1770,9 +1795,10 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1770
1795
if (new_isize != cur_isize ) {
1771
1796
/* Do we perhaps have any outstanding writes, or has
1772
1797
* the file grown beyond our last write? */
1773
- if (( nfsi -> nrequests == 0 ) || new_isize > cur_isize ) {
1798
+ if (nfsi -> nrequests == 0 || new_isize > cur_isize ) {
1774
1799
i_size_write (inode , new_isize );
1775
- invalid |= NFS_INO_INVALID_ATTR |NFS_INO_INVALID_DATA ;
1800
+ if (!have_writers )
1801
+ invalid |= NFS_INO_INVALID_ATTR |NFS_INO_INVALID_DATA ;
1776
1802
}
1777
1803
dprintk ("NFS: isize change on server for file %s/%ld "
1778
1804
"(%Ld to %Ld)\n" ,
0 commit comments