diff options
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/dir.c | 3 | ||||
-rw-r--r-- | fs/nfs/inode.c | 81 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 17 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 20 | ||||
-rw-r--r-- | fs/nfs/proc.c | 1 | ||||
-rw-r--r-- | fs/nfs/write.c | 6 |
6 files changed, 64 insertions, 64 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 7370583b61e5..c0d1a214572c 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -1287,6 +1287,7 @@ dentry->d_parent->d_name.name, dentry->d_name.name); | |||
1287 | nfs_begin_data_update(dentry->d_inode); | 1287 | nfs_begin_data_update(dentry->d_inode); |
1288 | error = NFS_PROTO(dir)->rename(dir, &dentry->d_name, | 1288 | error = NFS_PROTO(dir)->rename(dir, &dentry->d_name, |
1289 | dir, &qsilly); | 1289 | dir, &qsilly); |
1290 | nfs_mark_for_revalidate(dentry->d_inode); | ||
1290 | nfs_end_data_update(dentry->d_inode); | 1291 | nfs_end_data_update(dentry->d_inode); |
1291 | } else | 1292 | } else |
1292 | error = NFS_PROTO(dir)->rename(dir, &dentry->d_name, | 1293 | error = NFS_PROTO(dir)->rename(dir, &dentry->d_name, |
@@ -1334,6 +1335,7 @@ static int nfs_safe_remove(struct dentry *dentry) | |||
1334 | /* The VFS may want to delete this inode */ | 1335 | /* The VFS may want to delete this inode */ |
1335 | if (error == 0) | 1336 | if (error == 0) |
1336 | inode->i_nlink--; | 1337 | inode->i_nlink--; |
1338 | nfs_mark_for_revalidate(inode); | ||
1337 | nfs_end_data_update(inode); | 1339 | nfs_end_data_update(inode); |
1338 | } else | 1340 | } else |
1339 | error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); | 1341 | error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); |
@@ -1556,6 +1558,7 @@ go_ahead: | |||
1556 | nfs_begin_data_update(old_inode); | 1558 | nfs_begin_data_update(old_inode); |
1557 | error = NFS_PROTO(old_dir)->rename(old_dir, &old_dentry->d_name, | 1559 | error = NFS_PROTO(old_dir)->rename(old_dir, &old_dentry->d_name, |
1558 | new_dir, &new_dentry->d_name); | 1560 | new_dir, &new_dentry->d_name); |
1561 | nfs_mark_for_revalidate(old_inode); | ||
1559 | nfs_end_data_update(old_inode); | 1562 | nfs_end_data_update(old_inode); |
1560 | nfs_end_data_update(new_dir); | 1563 | nfs_end_data_update(new_dir); |
1561 | nfs_end_data_update(old_dir); | 1564 | nfs_end_data_update(old_dir); |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 6391d8964214..afd75d0463fd 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -54,7 +54,7 @@ | |||
54 | #define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1) | 54 | #define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1) |
55 | 55 | ||
56 | static void nfs_invalidate_inode(struct inode *); | 56 | static void nfs_invalidate_inode(struct inode *); |
57 | static int nfs_update_inode(struct inode *, struct nfs_fattr *, unsigned long); | 57 | static int nfs_update_inode(struct inode *, struct nfs_fattr *); |
58 | 58 | ||
59 | static struct inode *nfs_alloc_inode(struct super_block *sb); | 59 | static struct inode *nfs_alloc_inode(struct super_block *sb); |
60 | static void nfs_destroy_inode(struct inode *); | 60 | static void nfs_destroy_inode(struct inode *); |
@@ -643,14 +643,11 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt) | |||
643 | /* | 643 | /* |
644 | * Invalidate the local caches | 644 | * Invalidate the local caches |
645 | */ | 645 | */ |
646 | void | 646 | static void nfs_zap_caches_locked(struct inode *inode) |
647 | nfs_zap_caches(struct inode *inode) | ||
648 | { | 647 | { |
649 | struct nfs_inode *nfsi = NFS_I(inode); | 648 | struct nfs_inode *nfsi = NFS_I(inode); |
650 | int mode = inode->i_mode; | 649 | int mode = inode->i_mode; |
651 | 650 | ||
652 | spin_lock(&inode->i_lock); | ||
653 | |||
654 | NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode); | 651 | NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode); |
655 | NFS_ATTRTIMEO_UPDATE(inode) = jiffies; | 652 | NFS_ATTRTIMEO_UPDATE(inode) = jiffies; |
656 | 653 | ||
@@ -659,7 +656,12 @@ nfs_zap_caches(struct inode *inode) | |||
659 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; | 656 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; |
660 | else | 657 | else |
661 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; | 658 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; |
659 | } | ||
662 | 660 | ||
661 | void nfs_zap_caches(struct inode *inode) | ||
662 | { | ||
663 | spin_lock(&inode->i_lock); | ||
664 | nfs_zap_caches_locked(inode); | ||
663 | spin_unlock(&inode->i_lock); | 665 | spin_unlock(&inode->i_lock); |
664 | } | 666 | } |
665 | 667 | ||
@@ -676,16 +678,13 @@ static void nfs_zap_acl_cache(struct inode *inode) | |||
676 | } | 678 | } |
677 | 679 | ||
678 | /* | 680 | /* |
679 | * Invalidate, but do not unhash, the inode | 681 | * Invalidate, but do not unhash, the inode. |
682 | * NB: must be called with inode->i_lock held! | ||
680 | */ | 683 | */ |
681 | static void | 684 | static void nfs_invalidate_inode(struct inode *inode) |
682 | nfs_invalidate_inode(struct inode *inode) | ||
683 | { | 685 | { |
684 | umode_t save_mode = inode->i_mode; | 686 | set_bit(NFS_INO_STALE, &NFS_FLAGS(inode)); |
685 | 687 | nfs_zap_caches_locked(inode); | |
686 | make_bad_inode(inode); | ||
687 | inode->i_mode = save_mode; | ||
688 | nfs_zap_caches(inode); | ||
689 | } | 688 | } |
690 | 689 | ||
691 | struct nfs_find_desc { | 690 | struct nfs_find_desc { |
@@ -1081,8 +1080,6 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
1081 | int status = -ESTALE; | 1080 | int status = -ESTALE; |
1082 | struct nfs_fattr fattr; | 1081 | struct nfs_fattr fattr; |
1083 | struct nfs_inode *nfsi = NFS_I(inode); | 1082 | struct nfs_inode *nfsi = NFS_I(inode); |
1084 | unsigned long verifier; | ||
1085 | unsigned long cache_validity; | ||
1086 | 1083 | ||
1087 | dfprintk(PAGECACHE, "NFS: revalidating (%s/%Ld)\n", | 1084 | dfprintk(PAGECACHE, "NFS: revalidating (%s/%Ld)\n", |
1088 | inode->i_sb->s_id, (long long)NFS_FILEID(inode)); | 1085 | inode->i_sb->s_id, (long long)NFS_FILEID(inode)); |
@@ -1107,8 +1104,6 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
1107 | } | 1104 | } |
1108 | } | 1105 | } |
1109 | 1106 | ||
1110 | /* Protect against RPC races by saving the change attribute */ | ||
1111 | verifier = nfs_save_change_attribute(inode); | ||
1112 | status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), &fattr); | 1107 | status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), &fattr); |
1113 | if (status != 0) { | 1108 | if (status != 0) { |
1114 | dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n", | 1109 | dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n", |
@@ -1123,7 +1118,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
1123 | } | 1118 | } |
1124 | 1119 | ||
1125 | spin_lock(&inode->i_lock); | 1120 | spin_lock(&inode->i_lock); |
1126 | status = nfs_update_inode(inode, &fattr, verifier); | 1121 | status = nfs_update_inode(inode, &fattr); |
1127 | if (status) { | 1122 | if (status) { |
1128 | spin_unlock(&inode->i_lock); | 1123 | spin_unlock(&inode->i_lock); |
1129 | dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n", | 1124 | dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n", |
@@ -1131,20 +1126,11 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
1131 | (long long)NFS_FILEID(inode), status); | 1126 | (long long)NFS_FILEID(inode), status); |
1132 | goto out; | 1127 | goto out; |
1133 | } | 1128 | } |
1134 | cache_validity = nfsi->cache_validity; | ||
1135 | nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE; | ||
1136 | |||
1137 | /* | ||
1138 | * We may need to keep the attributes marked as invalid if | ||
1139 | * we raced with nfs_end_attr_update(). | ||
1140 | */ | ||
1141 | if (time_after_eq(verifier, nfsi->cache_change_attribute)) | ||
1142 | nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME); | ||
1143 | spin_unlock(&inode->i_lock); | 1129 | spin_unlock(&inode->i_lock); |
1144 | 1130 | ||
1145 | nfs_revalidate_mapping(inode, inode->i_mapping); | 1131 | nfs_revalidate_mapping(inode, inode->i_mapping); |
1146 | 1132 | ||
1147 | if (cache_validity & NFS_INO_INVALID_ACL) | 1133 | if (nfsi->cache_validity & NFS_INO_INVALID_ACL) |
1148 | nfs_zap_acl_cache(inode); | 1134 | nfs_zap_acl_cache(inode); |
1149 | 1135 | ||
1150 | dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n", | 1136 | dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n", |
@@ -1347,10 +1333,8 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1347 | return 0; | 1333 | return 0; |
1348 | spin_lock(&inode->i_lock); | 1334 | spin_lock(&inode->i_lock); |
1349 | nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE; | 1335 | nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE; |
1350 | if (nfs_verify_change_attribute(inode, fattr->time_start)) | ||
1351 | nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME); | ||
1352 | if (time_after(fattr->time_start, nfsi->last_updated)) | 1336 | if (time_after(fattr->time_start, nfsi->last_updated)) |
1353 | status = nfs_update_inode(inode, fattr, fattr->time_start); | 1337 | status = nfs_update_inode(inode, fattr); |
1354 | else | 1338 | else |
1355 | status = nfs_check_inode_attributes(inode, fattr); | 1339 | status = nfs_check_inode_attributes(inode, fattr); |
1356 | 1340 | ||
@@ -1376,10 +1360,7 @@ int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1376 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS; | 1360 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS; |
1377 | goto out; | 1361 | goto out; |
1378 | } | 1362 | } |
1379 | status = nfs_update_inode(inode, fattr, fattr->time_start); | 1363 | status = nfs_update_inode(inode, fattr); |
1380 | if (time_after_eq(fattr->time_start, nfsi->cache_change_attribute)) | ||
1381 | nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME|NFS_INO_REVAL_PAGECACHE); | ||
1382 | nfsi->cache_change_attribute = jiffies; | ||
1383 | out: | 1364 | out: |
1384 | spin_unlock(&inode->i_lock); | 1365 | spin_unlock(&inode->i_lock); |
1385 | return status; | 1366 | return status; |
@@ -1397,12 +1378,12 @@ out: | |||
1397 | * | 1378 | * |
1398 | * A very similar scenario holds for the dir cache. | 1379 | * A very similar scenario holds for the dir cache. |
1399 | */ | 1380 | */ |
1400 | static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsigned long verifier) | 1381 | static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) |
1401 | { | 1382 | { |
1402 | struct nfs_inode *nfsi = NFS_I(inode); | 1383 | struct nfs_inode *nfsi = NFS_I(inode); |
1403 | loff_t cur_isize, new_isize; | 1384 | loff_t cur_isize, new_isize; |
1404 | unsigned int invalid = 0; | 1385 | unsigned int invalid = 0; |
1405 | int data_unstable; | 1386 | int data_stable; |
1406 | 1387 | ||
1407 | dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", | 1388 | dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", |
1408 | __FUNCTION__, inode->i_sb->s_id, inode->i_ino, | 1389 | __FUNCTION__, inode->i_sb->s_id, inode->i_ino, |
@@ -1433,8 +1414,9 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign | |||
1433 | nfsi->last_updated = jiffies; | 1414 | nfsi->last_updated = jiffies; |
1434 | 1415 | ||
1435 | /* Are we racing with known updates of the metadata on the server? */ | 1416 | /* Are we racing with known updates of the metadata on the server? */ |
1436 | data_unstable = ! (nfs_verify_change_attribute(inode, verifier) || | 1417 | data_stable = nfs_verify_change_attribute(inode, fattr->time_start); |
1437 | (nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)); | 1418 | if (data_stable) |
1419 | nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME); | ||
1438 | 1420 | ||
1439 | /* Check if our cached file size is stale */ | 1421 | /* Check if our cached file size is stale */ |
1440 | new_isize = nfs_size_to_loff_t(fattr->size); | 1422 | new_isize = nfs_size_to_loff_t(fattr->size); |
@@ -1443,7 +1425,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign | |||
1443 | /* Do we perhaps have any outstanding writes? */ | 1425 | /* Do we perhaps have any outstanding writes? */ |
1444 | if (nfsi->npages == 0) { | 1426 | if (nfsi->npages == 0) { |
1445 | /* No, but did we race with nfs_end_data_update()? */ | 1427 | /* No, but did we race with nfs_end_data_update()? */ |
1446 | if (time_after_eq(verifier, nfsi->cache_change_attribute)) { | 1428 | if (data_stable) { |
1447 | inode->i_size = new_isize; | 1429 | inode->i_size = new_isize; |
1448 | invalid |= NFS_INO_INVALID_DATA; | 1430 | invalid |= NFS_INO_INVALID_DATA; |
1449 | } | 1431 | } |
@@ -1452,6 +1434,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign | |||
1452 | inode->i_size = new_isize; | 1434 | inode->i_size = new_isize; |
1453 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; | 1435 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; |
1454 | } | 1436 | } |
1437 | nfsi->cache_change_attribute = jiffies; | ||
1455 | dprintk("NFS: isize change on server for file %s/%ld\n", | 1438 | dprintk("NFS: isize change on server for file %s/%ld\n", |
1456 | inode->i_sb->s_id, inode->i_ino); | 1439 | inode->i_sb->s_id, inode->i_ino); |
1457 | } | 1440 | } |
@@ -1461,8 +1444,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign | |||
1461 | memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); | 1444 | memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); |
1462 | dprintk("NFS: mtime change on server for file %s/%ld\n", | 1445 | dprintk("NFS: mtime change on server for file %s/%ld\n", |
1463 | inode->i_sb->s_id, inode->i_ino); | 1446 | inode->i_sb->s_id, inode->i_ino); |
1464 | if (!data_unstable) | 1447 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; |
1465 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; | 1448 | nfsi->cache_change_attribute = jiffies; |
1466 | } | 1449 | } |
1467 | 1450 | ||
1468 | if ((fattr->valid & NFS_ATTR_FATTR_V4) | 1451 | if ((fattr->valid & NFS_ATTR_FATTR_V4) |
@@ -1470,15 +1453,15 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign | |||
1470 | dprintk("NFS: change_attr change on server for file %s/%ld\n", | 1453 | dprintk("NFS: change_attr change on server for file %s/%ld\n", |
1471 | inode->i_sb->s_id, inode->i_ino); | 1454 | inode->i_sb->s_id, inode->i_ino); |
1472 | nfsi->change_attr = fattr->change_attr; | 1455 | nfsi->change_attr = fattr->change_attr; |
1473 | if (!data_unstable) | 1456 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
1474 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; | 1457 | nfsi->cache_change_attribute = jiffies; |
1475 | } | 1458 | } |
1476 | 1459 | ||
1477 | /* If ctime has changed we should definitely clear access+acl caches */ | 1460 | /* If ctime has changed we should definitely clear access+acl caches */ |
1478 | if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) { | 1461 | if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) { |
1479 | if (!data_unstable) | 1462 | invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
1480 | invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; | ||
1481 | memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); | 1463 | memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); |
1464 | nfsi->cache_change_attribute = jiffies; | ||
1482 | } | 1465 | } |
1483 | memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); | 1466 | memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); |
1484 | 1467 | ||
@@ -1516,6 +1499,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign | |||
1516 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) | 1499 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) |
1517 | || S_ISLNK(inode->i_mode))) | 1500 | || S_ISLNK(inode->i_mode))) |
1518 | invalid &= ~NFS_INO_INVALID_DATA; | 1501 | invalid &= ~NFS_INO_INVALID_DATA; |
1502 | if (data_stable) | ||
1503 | invalid &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME|NFS_INO_REVAL_PAGECACHE); | ||
1519 | if (!nfs_have_delegation(inode, FMODE_READ)) | 1504 | if (!nfs_have_delegation(inode, FMODE_READ)) |
1520 | nfsi->cache_validity |= invalid; | 1505 | nfsi->cache_validity |= invalid; |
1521 | 1506 | ||
@@ -1528,14 +1513,13 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign | |||
1528 | printk(KERN_DEBUG "%s: inode %ld mode changed, %07o to %07o\n", | 1513 | printk(KERN_DEBUG "%s: inode %ld mode changed, %07o to %07o\n", |
1529 | __FUNCTION__, inode->i_ino, inode->i_mode, fattr->mode); | 1514 | __FUNCTION__, inode->i_ino, inode->i_mode, fattr->mode); |
1530 | #endif | 1515 | #endif |
1516 | out_err: | ||
1531 | /* | 1517 | /* |
1532 | * No need to worry about unhashing the dentry, as the | 1518 | * No need to worry about unhashing the dentry, as the |
1533 | * lookup validation will know that the inode is bad. | 1519 | * lookup validation will know that the inode is bad. |
1534 | * (But we fall through to invalidate the caches.) | 1520 | * (But we fall through to invalidate the caches.) |
1535 | */ | 1521 | */ |
1536 | nfs_invalidate_inode(inode); | 1522 | nfs_invalidate_inode(inode); |
1537 | out_err: | ||
1538 | set_bit(NFS_INO_STALE, &NFS_FLAGS(inode)); | ||
1539 | return -ESTALE; | 1523 | return -ESTALE; |
1540 | } | 1524 | } |
1541 | 1525 | ||
@@ -2068,6 +2052,7 @@ static struct inode *nfs_alloc_inode(struct super_block *sb) | |||
2068 | return NULL; | 2052 | return NULL; |
2069 | nfsi->flags = 0UL; | 2053 | nfsi->flags = 0UL; |
2070 | nfsi->cache_validity = 0UL; | 2054 | nfsi->cache_validity = 0UL; |
2055 | nfsi->cache_change_attribute = jiffies; | ||
2071 | #ifdef CONFIG_NFS_V3_ACL | 2056 | #ifdef CONFIG_NFS_V3_ACL |
2072 | nfsi->acl_access = ERR_PTR(-EAGAIN); | 2057 | nfsi->acl_access = ERR_PTR(-EAGAIN); |
2073 | nfsi->acl_default = ERR_PTR(-EAGAIN); | 2058 | nfsi->acl_default = ERR_PTR(-EAGAIN); |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 21482b2518f6..f988a9417b13 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -1506,10 +1506,15 @@ static int _nfs4_proc_write(struct nfs_write_data *wdata) | |||
1506 | dprintk("NFS call write %d @ %Ld\n", wdata->args.count, | 1506 | dprintk("NFS call write %d @ %Ld\n", wdata->args.count, |
1507 | (long long) wdata->args.offset); | 1507 | (long long) wdata->args.offset); |
1508 | 1508 | ||
1509 | wdata->args.bitmask = server->attr_bitmask; | ||
1510 | wdata->res.server = server; | ||
1509 | nfs_fattr_init(fattr); | 1511 | nfs_fattr_init(fattr); |
1510 | status = rpc_call_sync(server->client, &msg, rpcflags); | 1512 | status = rpc_call_sync(server->client, &msg, rpcflags); |
1511 | dprintk("NFS reply write: %d\n", status); | 1513 | dprintk("NFS reply write: %d\n", status); |
1512 | return status; | 1514 | if (status < 0) |
1515 | return status; | ||
1516 | nfs_post_op_update_inode(inode, fattr); | ||
1517 | return wdata->res.count; | ||
1513 | } | 1518 | } |
1514 | 1519 | ||
1515 | static int nfs4_proc_write(struct nfs_write_data *wdata) | 1520 | static int nfs4_proc_write(struct nfs_write_data *wdata) |
@@ -1540,9 +1545,13 @@ static int _nfs4_proc_commit(struct nfs_write_data *cdata) | |||
1540 | dprintk("NFS call commit %d @ %Ld\n", cdata->args.count, | 1545 | dprintk("NFS call commit %d @ %Ld\n", cdata->args.count, |
1541 | (long long) cdata->args.offset); | 1546 | (long long) cdata->args.offset); |
1542 | 1547 | ||
1548 | cdata->args.bitmask = server->attr_bitmask; | ||
1549 | cdata->res.server = server; | ||
1543 | nfs_fattr_init(fattr); | 1550 | nfs_fattr_init(fattr); |
1544 | status = rpc_call_sync(server->client, &msg, 0); | 1551 | status = rpc_call_sync(server->client, &msg, 0); |
1545 | dprintk("NFS reply commit: %d\n", status); | 1552 | dprintk("NFS reply commit: %d\n", status); |
1553 | if (status >= 0) | ||
1554 | nfs_post_op_update_inode(inode, fattr); | ||
1546 | return status; | 1555 | return status; |
1547 | } | 1556 | } |
1548 | 1557 | ||
@@ -3071,15 +3080,15 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock | |||
3071 | struct nfs4_client *clp = state->owner->so_client; | 3080 | struct nfs4_client *clp = state->owner->so_client; |
3072 | int status; | 3081 | int status; |
3073 | 3082 | ||
3074 | down_read(&clp->cl_sem); | ||
3075 | /* Is this a delegated open? */ | 3083 | /* Is this a delegated open? */ |
3076 | if (test_bit(NFS_DELEGATED_STATE, &state->flags)) { | 3084 | if (NFS_I(state->inode)->delegation_state != 0) { |
3077 | /* Yes: cache locks! */ | 3085 | /* Yes: cache locks! */ |
3078 | status = do_vfs_lock(request->fl_file, request); | 3086 | status = do_vfs_lock(request->fl_file, request); |
3079 | /* ...but avoid races with delegation recall... */ | 3087 | /* ...but avoid races with delegation recall... */ |
3080 | if (status < 0 || test_bit(NFS_DELEGATED_STATE, &state->flags)) | 3088 | if (status < 0 || test_bit(NFS_DELEGATED_STATE, &state->flags)) |
3081 | goto out; | 3089 | return status; |
3082 | } | 3090 | } |
3091 | down_read(&clp->cl_sem); | ||
3083 | status = nfs4_set_lock_state(state, request); | 3092 | status = nfs4_set_lock_state(state, request); |
3084 | if (status != 0) | 3093 | if (status != 0) |
3085 | goto out; | 3094 | goto out; |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 0675f3215e0a..5ef4c57618fe 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -644,12 +644,15 @@ void nfs4_copy_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t f | |||
644 | 644 | ||
645 | struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter) | 645 | struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter) |
646 | { | 646 | { |
647 | struct rpc_sequence *sequence = counter->sequence; | ||
647 | struct nfs_seqid *new; | 648 | struct nfs_seqid *new; |
648 | 649 | ||
649 | new = kmalloc(sizeof(*new), GFP_KERNEL); | 650 | new = kmalloc(sizeof(*new), GFP_KERNEL); |
650 | if (new != NULL) { | 651 | if (new != NULL) { |
651 | new->sequence = counter; | 652 | new->sequence = counter; |
652 | INIT_LIST_HEAD(&new->list); | 653 | spin_lock(&sequence->lock); |
654 | list_add_tail(&new->list, &sequence->list); | ||
655 | spin_unlock(&sequence->lock); | ||
653 | } | 656 | } |
654 | return new; | 657 | return new; |
655 | } | 658 | } |
@@ -658,12 +661,10 @@ void nfs_free_seqid(struct nfs_seqid *seqid) | |||
658 | { | 661 | { |
659 | struct rpc_sequence *sequence = seqid->sequence->sequence; | 662 | struct rpc_sequence *sequence = seqid->sequence->sequence; |
660 | 663 | ||
661 | if (!list_empty(&seqid->list)) { | 664 | spin_lock(&sequence->lock); |
662 | spin_lock(&sequence->lock); | 665 | list_del(&seqid->list); |
663 | list_del(&seqid->list); | 666 | spin_unlock(&sequence->lock); |
664 | spin_unlock(&sequence->lock); | 667 | rpc_wake_up(&sequence->wait); |
665 | } | ||
666 | rpc_wake_up_next(&sequence->wait); | ||
667 | kfree(seqid); | 668 | kfree(seqid); |
668 | } | 669 | } |
669 | 670 | ||
@@ -722,11 +723,10 @@ int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task) | |||
722 | if (sequence->list.next == &seqid->list) | 723 | if (sequence->list.next == &seqid->list) |
723 | goto out; | 724 | goto out; |
724 | spin_lock(&sequence->lock); | 725 | spin_lock(&sequence->lock); |
725 | if (!list_empty(&sequence->list)) { | 726 | if (sequence->list.next != &seqid->list) { |
726 | rpc_sleep_on(&sequence->wait, task, NULL, NULL); | 727 | rpc_sleep_on(&sequence->wait, task, NULL, NULL); |
727 | status = -EAGAIN; | 728 | status = -EAGAIN; |
728 | } else | 729 | } |
729 | list_add(&seqid->list, &sequence->list); | ||
730 | spin_unlock(&sequence->lock); | 730 | spin_unlock(&sequence->lock); |
731 | out: | 731 | out: |
732 | return status; | 732 | return status; |
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index a48a003242c0..e1e3ca5d746b 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c | |||
@@ -375,6 +375,7 @@ nfs_proc_link(struct inode *inode, struct inode *dir, struct qstr *name) | |||
375 | 375 | ||
376 | dprintk("NFS call link %s\n", name->name); | 376 | dprintk("NFS call link %s\n", name->name); |
377 | status = rpc_call(NFS_CLIENT(inode), NFSPROC_LINK, &arg, NULL, 0); | 377 | status = rpc_call(NFS_CLIENT(inode), NFSPROC_LINK, &arg, NULL, 0); |
378 | nfs_mark_for_revalidate(inode); | ||
378 | nfs_mark_for_revalidate(dir); | 379 | nfs_mark_for_revalidate(dir); |
379 | dprintk("NFS reply link: %d\n", status); | 380 | dprintk("NFS reply link: %d\n", status); |
380 | return status; | 381 | return status; |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 8f71e766cc5d..3107908e5f3f 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -189,6 +189,7 @@ static int nfs_writepage_sync(struct nfs_open_context *ctx, struct inode *inode, | |||
189 | (long long)NFS_FILEID(inode), | 189 | (long long)NFS_FILEID(inode), |
190 | count, (long long)(page_offset(page) + offset)); | 190 | count, (long long)(page_offset(page) + offset)); |
191 | 191 | ||
192 | set_page_writeback(page); | ||
192 | nfs_begin_data_update(inode); | 193 | nfs_begin_data_update(inode); |
193 | do { | 194 | do { |
194 | if (count < wsize) | 195 | if (count < wsize) |
@@ -221,6 +222,7 @@ static int nfs_writepage_sync(struct nfs_open_context *ctx, struct inode *inode, | |||
221 | 222 | ||
222 | io_error: | 223 | io_error: |
223 | nfs_end_data_update(inode); | 224 | nfs_end_data_update(inode); |
225 | end_page_writeback(page); | ||
224 | nfs_writedata_free(wdata); | 226 | nfs_writedata_free(wdata); |
225 | return written ? written : result; | 227 | return written ? written : result; |
226 | } | 228 | } |
@@ -929,7 +931,7 @@ static int nfs_flush_multi(struct list_head *head, struct inode *inode, int how) | |||
929 | atomic_set(&req->wb_complete, requests); | 931 | atomic_set(&req->wb_complete, requests); |
930 | 932 | ||
931 | ClearPageError(page); | 933 | ClearPageError(page); |
932 | SetPageWriteback(page); | 934 | set_page_writeback(page); |
933 | offset = 0; | 935 | offset = 0; |
934 | nbytes = req->wb_bytes; | 936 | nbytes = req->wb_bytes; |
935 | do { | 937 | do { |
@@ -992,7 +994,7 @@ static int nfs_flush_one(struct list_head *head, struct inode *inode, int how) | |||
992 | nfs_list_remove_request(req); | 994 | nfs_list_remove_request(req); |
993 | nfs_list_add_request(req, &data->pages); | 995 | nfs_list_add_request(req, &data->pages); |
994 | ClearPageError(req->wb_page); | 996 | ClearPageError(req->wb_page); |
995 | SetPageWriteback(req->wb_page); | 997 | set_page_writeback(req->wb_page); |
996 | *pages++ = req->wb_page; | 998 | *pages++ = req->wb_page; |
997 | count += req->wb_bytes; | 999 | count += req->wb_bytes; |
998 | } | 1000 | } |