diff options
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r-- | fs/nfs/inode.c | 117 |
1 files changed, 85 insertions, 32 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 00ad1c2b217d..360114ae8b82 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -164,17 +164,16 @@ static void nfs_zap_caches_locked(struct inode *inode) | |||
164 | if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) { | 164 | if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) { |
165 | nfs_fscache_invalidate(inode); | 165 | nfs_fscache_invalidate(inode); |
166 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR | 166 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR |
167 | | NFS_INO_INVALID_LABEL | ||
168 | | NFS_INO_INVALID_DATA | 167 | | NFS_INO_INVALID_DATA |
169 | | NFS_INO_INVALID_ACCESS | 168 | | NFS_INO_INVALID_ACCESS |
170 | | NFS_INO_INVALID_ACL | 169 | | NFS_INO_INVALID_ACL |
171 | | NFS_INO_REVAL_PAGECACHE; | 170 | | NFS_INO_REVAL_PAGECACHE; |
172 | } else | 171 | } else |
173 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR | 172 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR |
174 | | NFS_INO_INVALID_LABEL | ||
175 | | NFS_INO_INVALID_ACCESS | 173 | | NFS_INO_INVALID_ACCESS |
176 | | NFS_INO_INVALID_ACL | 174 | | NFS_INO_INVALID_ACL |
177 | | NFS_INO_REVAL_PAGECACHE; | 175 | | NFS_INO_REVAL_PAGECACHE; |
176 | nfs_zap_label_cache_locked(nfsi); | ||
178 | } | 177 | } |
179 | 178 | ||
180 | void nfs_zap_caches(struct inode *inode) | 179 | void nfs_zap_caches(struct inode *inode) |
@@ -266,6 +265,13 @@ nfs_init_locked(struct inode *inode, void *opaque) | |||
266 | } | 265 | } |
267 | 266 | ||
268 | #ifdef CONFIG_NFS_V4_SECURITY_LABEL | 267 | #ifdef CONFIG_NFS_V4_SECURITY_LABEL |
268 | static void nfs_clear_label_invalid(struct inode *inode) | ||
269 | { | ||
270 | spin_lock(&inode->i_lock); | ||
271 | NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_LABEL; | ||
272 | spin_unlock(&inode->i_lock); | ||
273 | } | ||
274 | |||
269 | void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr, | 275 | void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr, |
270 | struct nfs4_label *label) | 276 | struct nfs4_label *label) |
271 | { | 277 | { |
@@ -283,6 +289,7 @@ void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr, | |||
283 | __func__, | 289 | __func__, |
284 | (char *)label->label, | 290 | (char *)label->label, |
285 | label->len, error); | 291 | label->len, error); |
292 | nfs_clear_label_invalid(inode); | ||
286 | } | 293 | } |
287 | } | 294 | } |
288 | 295 | ||
@@ -458,9 +465,9 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st | |||
458 | unlock_new_inode(inode); | 465 | unlock_new_inode(inode); |
459 | } else | 466 | } else |
460 | nfs_refresh_inode(inode, fattr); | 467 | nfs_refresh_inode(inode, fattr); |
461 | dprintk("NFS: nfs_fhget(%s/%Ld fh_crc=0x%08x ct=%d)\n", | 468 | dprintk("NFS: nfs_fhget(%s/%Lu fh_crc=0x%08x ct=%d)\n", |
462 | inode->i_sb->s_id, | 469 | inode->i_sb->s_id, |
463 | (long long)NFS_FILEID(inode), | 470 | (unsigned long long)NFS_FILEID(inode), |
464 | nfs_display_fhandle_hash(fh), | 471 | nfs_display_fhandle_hash(fh), |
465 | atomic_read(&inode->i_count)); | 472 | atomic_read(&inode->i_count)); |
466 | 473 | ||
@@ -870,8 +877,8 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
870 | struct nfs_fattr *fattr = NULL; | 877 | struct nfs_fattr *fattr = NULL; |
871 | struct nfs_inode *nfsi = NFS_I(inode); | 878 | struct nfs_inode *nfsi = NFS_I(inode); |
872 | 879 | ||
873 | dfprintk(PAGECACHE, "NFS: revalidating (%s/%Ld)\n", | 880 | dfprintk(PAGECACHE, "NFS: revalidating (%s/%Lu)\n", |
874 | inode->i_sb->s_id, (long long)NFS_FILEID(inode)); | 881 | inode->i_sb->s_id, (unsigned long long)NFS_FILEID(inode)); |
875 | 882 | ||
876 | trace_nfs_revalidate_inode_enter(inode); | 883 | trace_nfs_revalidate_inode_enter(inode); |
877 | 884 | ||
@@ -895,9 +902,9 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
895 | 902 | ||
896 | status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), fattr, label); | 903 | status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), fattr, label); |
897 | if (status != 0) { | 904 | if (status != 0) { |
898 | dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n", | 905 | dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Lu) getattr failed, error=%d\n", |
899 | inode->i_sb->s_id, | 906 | inode->i_sb->s_id, |
900 | (long long)NFS_FILEID(inode), status); | 907 | (unsigned long long)NFS_FILEID(inode), status); |
901 | if (status == -ESTALE) { | 908 | if (status == -ESTALE) { |
902 | nfs_zap_caches(inode); | 909 | nfs_zap_caches(inode); |
903 | if (!S_ISDIR(inode->i_mode)) | 910 | if (!S_ISDIR(inode->i_mode)) |
@@ -908,9 +915,9 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
908 | 915 | ||
909 | status = nfs_refresh_inode(inode, fattr); | 916 | status = nfs_refresh_inode(inode, fattr); |
910 | if (status) { | 917 | if (status) { |
911 | dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n", | 918 | dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Lu) refresh failed, error=%d\n", |
912 | inode->i_sb->s_id, | 919 | inode->i_sb->s_id, |
913 | (long long)NFS_FILEID(inode), status); | 920 | (unsigned long long)NFS_FILEID(inode), status); |
914 | goto err_out; | 921 | goto err_out; |
915 | } | 922 | } |
916 | 923 | ||
@@ -919,9 +926,9 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
919 | 926 | ||
920 | nfs_setsecurity(inode, fattr, label); | 927 | nfs_setsecurity(inode, fattr, label); |
921 | 928 | ||
922 | dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n", | 929 | dfprintk(PAGECACHE, "NFS: (%s/%Lu) revalidation complete\n", |
923 | inode->i_sb->s_id, | 930 | inode->i_sb->s_id, |
924 | (long long)NFS_FILEID(inode)); | 931 | (unsigned long long)NFS_FILEID(inode)); |
925 | 932 | ||
926 | err_out: | 933 | err_out: |
927 | nfs4_label_free(label); | 934 | nfs4_label_free(label); |
@@ -977,16 +984,17 @@ static int nfs_invalidate_mapping(struct inode *inode, struct address_space *map | |||
977 | if (ret < 0) | 984 | if (ret < 0) |
978 | return ret; | 985 | return ret; |
979 | } | 986 | } |
980 | spin_lock(&inode->i_lock); | 987 | if (S_ISDIR(inode->i_mode)) { |
981 | nfsi->cache_validity &= ~NFS_INO_INVALID_DATA; | 988 | spin_lock(&inode->i_lock); |
982 | if (S_ISDIR(inode->i_mode)) | ||
983 | memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf)); | 989 | memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf)); |
984 | spin_unlock(&inode->i_lock); | 990 | spin_unlock(&inode->i_lock); |
991 | } | ||
985 | nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE); | 992 | nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE); |
986 | nfs_fscache_wait_on_invalidate(inode); | 993 | nfs_fscache_wait_on_invalidate(inode); |
987 | 994 | ||
988 | dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n", | 995 | dfprintk(PAGECACHE, "NFS: (%s/%Lu) data cache invalidated\n", |
989 | inode->i_sb->s_id, (long long)NFS_FILEID(inode)); | 996 | inode->i_sb->s_id, |
997 | (unsigned long long)NFS_FILEID(inode)); | ||
990 | return 0; | 998 | return 0; |
991 | } | 999 | } |
992 | 1000 | ||
@@ -1007,6 +1015,7 @@ static bool nfs_mapping_need_revalidate_inode(struct inode *inode) | |||
1007 | int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) | 1015 | int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) |
1008 | { | 1016 | { |
1009 | struct nfs_inode *nfsi = NFS_I(inode); | 1017 | struct nfs_inode *nfsi = NFS_I(inode); |
1018 | unsigned long *bitlock = &nfsi->flags; | ||
1010 | int ret = 0; | 1019 | int ret = 0; |
1011 | 1020 | ||
1012 | /* swapfiles are not supposed to be shared. */ | 1021 | /* swapfiles are not supposed to be shared. */ |
@@ -1018,12 +1027,46 @@ int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) | |||
1018 | if (ret < 0) | 1027 | if (ret < 0) |
1019 | goto out; | 1028 | goto out; |
1020 | } | 1029 | } |
1021 | if (nfsi->cache_validity & NFS_INO_INVALID_DATA) { | 1030 | |
1022 | trace_nfs_invalidate_mapping_enter(inode); | 1031 | /* |
1023 | ret = nfs_invalidate_mapping(inode, mapping); | 1032 | * We must clear NFS_INO_INVALID_DATA first to ensure that |
1024 | trace_nfs_invalidate_mapping_exit(inode, ret); | 1033 | * invalidations that come in while we're shooting down the mappings |
1034 | * are respected. But, that leaves a race window where one revalidator | ||
1035 | * can clear the flag, and then another checks it before the mapping | ||
1036 | * gets invalidated. Fix that by serializing access to this part of | ||
1037 | * the function. | ||
1038 | * | ||
1039 | * At the same time, we need to allow other tasks to see whether we | ||
1040 | * might be in the middle of invalidating the pages, so we only set | ||
1041 | * the bit lock here if it looks like we're going to be doing that. | ||
1042 | */ | ||
1043 | for (;;) { | ||
1044 | ret = wait_on_bit(bitlock, NFS_INO_INVALIDATING, | ||
1045 | nfs_wait_bit_killable, TASK_KILLABLE); | ||
1046 | if (ret) | ||
1047 | goto out; | ||
1048 | spin_lock(&inode->i_lock); | ||
1049 | if (test_bit(NFS_INO_INVALIDATING, bitlock)) { | ||
1050 | spin_unlock(&inode->i_lock); | ||
1051 | continue; | ||
1052 | } | ||
1053 | if (nfsi->cache_validity & NFS_INO_INVALID_DATA) | ||
1054 | break; | ||
1055 | spin_unlock(&inode->i_lock); | ||
1056 | goto out; | ||
1025 | } | 1057 | } |
1026 | 1058 | ||
1059 | set_bit(NFS_INO_INVALIDATING, bitlock); | ||
1060 | smp_wmb(); | ||
1061 | nfsi->cache_validity &= ~NFS_INO_INVALID_DATA; | ||
1062 | spin_unlock(&inode->i_lock); | ||
1063 | trace_nfs_invalidate_mapping_enter(inode); | ||
1064 | ret = nfs_invalidate_mapping(inode, mapping); | ||
1065 | trace_nfs_invalidate_mapping_exit(inode, ret); | ||
1066 | |||
1067 | clear_bit_unlock(NFS_INO_INVALIDATING, bitlock); | ||
1068 | smp_mb__after_clear_bit(); | ||
1069 | wake_up_bit(bitlock, NFS_INO_INVALIDATING); | ||
1027 | out: | 1070 | out: |
1028 | return ret; | 1071 | return ret; |
1029 | } | 1072 | } |
@@ -1282,12 +1325,28 @@ static int nfs_inode_attrs_need_update(const struct inode *inode, const struct n | |||
1282 | ((long)nfsi->attr_gencount - (long)nfs_read_attr_generation_counter() > 0); | 1325 | ((long)nfsi->attr_gencount - (long)nfs_read_attr_generation_counter() > 0); |
1283 | } | 1326 | } |
1284 | 1327 | ||
1328 | /* | ||
1329 | * Don't trust the change_attribute, mtime, ctime or size if | ||
1330 | * a pnfs LAYOUTCOMMIT is outstanding | ||
1331 | */ | ||
1332 | static void nfs_inode_attrs_handle_layoutcommit(struct inode *inode, | ||
1333 | struct nfs_fattr *fattr) | ||
1334 | { | ||
1335 | if (pnfs_layoutcommit_outstanding(inode)) | ||
1336 | fattr->valid &= ~(NFS_ATTR_FATTR_CHANGE | | ||
1337 | NFS_ATTR_FATTR_MTIME | | ||
1338 | NFS_ATTR_FATTR_CTIME | | ||
1339 | NFS_ATTR_FATTR_SIZE); | ||
1340 | } | ||
1341 | |||
1285 | static int nfs_refresh_inode_locked(struct inode *inode, struct nfs_fattr *fattr) | 1342 | static int nfs_refresh_inode_locked(struct inode *inode, struct nfs_fattr *fattr) |
1286 | { | 1343 | { |
1287 | int ret; | 1344 | int ret; |
1288 | 1345 | ||
1289 | trace_nfs_refresh_inode_enter(inode); | 1346 | trace_nfs_refresh_inode_enter(inode); |
1290 | 1347 | ||
1348 | nfs_inode_attrs_handle_layoutcommit(inode, fattr); | ||
1349 | |||
1291 | if (nfs_inode_attrs_need_update(inode, fattr)) | 1350 | if (nfs_inode_attrs_need_update(inode, fattr)) |
1292 | ret = nfs_update_inode(inode, fattr); | 1351 | ret = nfs_update_inode(inode, fattr); |
1293 | else | 1352 | else |
@@ -1434,7 +1493,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1434 | unsigned long now = jiffies; | 1493 | unsigned long now = jiffies; |
1435 | unsigned long save_cache_validity; | 1494 | unsigned long save_cache_validity; |
1436 | 1495 | ||
1437 | dfprintk(VFS, "NFS: %s(%s/%ld fh_crc=0x%08x ct=%d info=0x%x)\n", | 1496 | dfprintk(VFS, "NFS: %s(%s/%lu fh_crc=0x%08x ct=%d info=0x%x)\n", |
1438 | __func__, inode->i_sb->s_id, inode->i_ino, | 1497 | __func__, inode->i_sb->s_id, inode->i_ino, |
1439 | nfs_display_fhandle_hash(NFS_FH(inode)), | 1498 | nfs_display_fhandle_hash(NFS_FH(inode)), |
1440 | atomic_read(&inode->i_count), fattr->valid); | 1499 | atomic_read(&inode->i_count), fattr->valid); |
@@ -1455,7 +1514,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1455 | /* | 1514 | /* |
1456 | * Big trouble! The inode has become a different object. | 1515 | * Big trouble! The inode has become a different object. |
1457 | */ | 1516 | */ |
1458 | printk(KERN_DEBUG "NFS: %s: inode %ld mode changed, %07o to %07o\n", | 1517 | printk(KERN_DEBUG "NFS: %s: inode %lu mode changed, %07o to %07o\n", |
1459 | __func__, inode->i_ino, inode->i_mode, fattr->mode); | 1518 | __func__, inode->i_ino, inode->i_mode, fattr->mode); |
1460 | goto out_err; | 1519 | goto out_err; |
1461 | } | 1520 | } |
@@ -1517,8 +1576,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1517 | if (new_isize != cur_isize) { | 1576 | if (new_isize != cur_isize) { |
1518 | /* Do we perhaps have any outstanding writes, or has | 1577 | /* Do we perhaps have any outstanding writes, or has |
1519 | * the file grown beyond our last write? */ | 1578 | * the file grown beyond our last write? */ |
1520 | if ((nfsi->npages == 0 && !test_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) || | 1579 | if ((nfsi->npages == 0) || new_isize > cur_isize) { |
1521 | new_isize > cur_isize) { | ||
1522 | i_size_write(inode, new_isize); | 1580 | i_size_write(inode, new_isize); |
1523 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; | 1581 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; |
1524 | } | 1582 | } |
@@ -1597,7 +1655,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1597 | inode->i_blocks = fattr->du.nfs2.blocks; | 1655 | inode->i_blocks = fattr->du.nfs2.blocks; |
1598 | 1656 | ||
1599 | /* Update attrtimeo value if we're out of the unstable period */ | 1657 | /* Update attrtimeo value if we're out of the unstable period */ |
1600 | if (invalid & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL)) { | 1658 | if (invalid & NFS_INO_INVALID_ATTR) { |
1601 | nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE); | 1659 | nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE); |
1602 | nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); | 1660 | nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); |
1603 | nfsi->attrtimeo_timestamp = now; | 1661 | nfsi->attrtimeo_timestamp = now; |
@@ -1610,7 +1668,6 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1610 | } | 1668 | } |
1611 | } | 1669 | } |
1612 | invalid &= ~NFS_INO_INVALID_ATTR; | 1670 | invalid &= ~NFS_INO_INVALID_ATTR; |
1613 | invalid &= ~NFS_INO_INVALID_LABEL; | ||
1614 | /* Don't invalidate the data if we were to blame */ | 1671 | /* Don't invalidate the data if we were to blame */ |
1615 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) | 1672 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) |
1616 | || S_ISLNK(inode->i_mode))) | 1673 | || S_ISLNK(inode->i_mode))) |
@@ -1641,10 +1698,6 @@ struct inode *nfs_alloc_inode(struct super_block *sb) | |||
1641 | return NULL; | 1698 | return NULL; |
1642 | nfsi->flags = 0UL; | 1699 | nfsi->flags = 0UL; |
1643 | nfsi->cache_validity = 0UL; | 1700 | nfsi->cache_validity = 0UL; |
1644 | #ifdef CONFIG_NFS_V3_ACL | ||
1645 | nfsi->acl_access = ERR_PTR(-EAGAIN); | ||
1646 | nfsi->acl_default = ERR_PTR(-EAGAIN); | ||
1647 | #endif | ||
1648 | #if IS_ENABLED(CONFIG_NFS_V4) | 1701 | #if IS_ENABLED(CONFIG_NFS_V4) |
1649 | nfsi->nfs4_acl = NULL; | 1702 | nfsi->nfs4_acl = NULL; |
1650 | #endif /* CONFIG_NFS_V4 */ | 1703 | #endif /* CONFIG_NFS_V4 */ |