summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/afs/dir.c84
1 files changed, 70 insertions, 14 deletions
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index 618e26cea887..81207dc3c997 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -440,7 +440,7 @@ static int afs_dir_iterate_block(struct afs_vnode *dvnode,
440 * iterate through the data blob that lists the contents of an AFS directory 440 * iterate through the data blob that lists the contents of an AFS directory
441 */ 441 */
442static int afs_dir_iterate(struct inode *dir, struct dir_context *ctx, 442static int afs_dir_iterate(struct inode *dir, struct dir_context *ctx,
443 struct key *key) 443 struct key *key, afs_dataversion_t *_dir_version)
444{ 444{
445 struct afs_vnode *dvnode = AFS_FS_I(dir); 445 struct afs_vnode *dvnode = AFS_FS_I(dir);
446 struct afs_xdr_dir_page *dbuf; 446 struct afs_xdr_dir_page *dbuf;
@@ -460,6 +460,7 @@ static int afs_dir_iterate(struct inode *dir, struct dir_context *ctx,
460 req = afs_read_dir(dvnode, key); 460 req = afs_read_dir(dvnode, key);
461 if (IS_ERR(req)) 461 if (IS_ERR(req))
462 return PTR_ERR(req); 462 return PTR_ERR(req);
463 *_dir_version = req->data_version;
463 464
464 /* round the file position up to the next entry boundary */ 465 /* round the file position up to the next entry boundary */
465 ctx->pos += sizeof(union afs_xdr_dirent) - 1; 466 ctx->pos += sizeof(union afs_xdr_dirent) - 1;
@@ -514,7 +515,10 @@ out:
514 */ 515 */
515static int afs_readdir(struct file *file, struct dir_context *ctx) 516static int afs_readdir(struct file *file, struct dir_context *ctx)
516{ 517{
517 return afs_dir_iterate(file_inode(file), ctx, afs_file_key(file)); 518 afs_dataversion_t dir_version;
519
520 return afs_dir_iterate(file_inode(file), ctx, afs_file_key(file),
521 &dir_version);
518} 522}
519 523
520/* 524/*
@@ -555,7 +559,8 @@ static int afs_lookup_one_filldir(struct dir_context *ctx, const char *name,
555 * - just returns the FID the dentry name maps to if found 559 * - just returns the FID the dentry name maps to if found
556 */ 560 */
557static int afs_do_lookup_one(struct inode *dir, struct dentry *dentry, 561static int afs_do_lookup_one(struct inode *dir, struct dentry *dentry,
558 struct afs_fid *fid, struct key *key) 562 struct afs_fid *fid, struct key *key,
563 afs_dataversion_t *_dir_version)
559{ 564{
560 struct afs_super_info *as = dir->i_sb->s_fs_info; 565 struct afs_super_info *as = dir->i_sb->s_fs_info;
561 struct afs_lookup_one_cookie cookie = { 566 struct afs_lookup_one_cookie cookie = {
@@ -568,7 +573,7 @@ static int afs_do_lookup_one(struct inode *dir, struct dentry *dentry,
568 _enter("{%lu},%p{%pd},", dir->i_ino, dentry, dentry); 573 _enter("{%lu},%p{%pd},", dir->i_ino, dentry, dentry);
569 574
570 /* search the directory */ 575 /* search the directory */
571 ret = afs_dir_iterate(dir, &cookie.ctx, key); 576 ret = afs_dir_iterate(dir, &cookie.ctx, key, _dir_version);
572 if (ret < 0) { 577 if (ret < 0) {
573 _leave(" = %d [iter]", ret); 578 _leave(" = %d [iter]", ret);
574 return ret; 579 return ret;
@@ -642,6 +647,7 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry,
642 struct afs_server *server; 647 struct afs_server *server;
643 struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode; 648 struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode;
644 struct inode *inode = NULL, *ti; 649 struct inode *inode = NULL, *ti;
650 afs_dataversion_t data_version = READ_ONCE(dvnode->status.data_version);
645 int ret, i; 651 int ret, i;
646 652
647 _enter("{%lu},%p{%pd},", dir->i_ino, dentry, dentry); 653 _enter("{%lu},%p{%pd},", dir->i_ino, dentry, dentry);
@@ -669,12 +675,14 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry,
669 cookie->fids[i].vid = as->volume->vid; 675 cookie->fids[i].vid = as->volume->vid;
670 676
671 /* search the directory */ 677 /* search the directory */
672 ret = afs_dir_iterate(dir, &cookie->ctx, key); 678 ret = afs_dir_iterate(dir, &cookie->ctx, key, &data_version);
673 if (ret < 0) { 679 if (ret < 0) {
674 inode = ERR_PTR(ret); 680 inode = ERR_PTR(ret);
675 goto out; 681 goto out;
676 } 682 }
677 683
684 dentry->d_fsdata = (void *)(unsigned long)data_version;
685
678 inode = ERR_PTR(-ENOENT); 686 inode = ERR_PTR(-ENOENT);
679 if (!cookie->found) 687 if (!cookie->found)
680 goto out; 688 goto out;
@@ -968,7 +976,8 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags)
968 struct dentry *parent; 976 struct dentry *parent;
969 struct inode *inode; 977 struct inode *inode;
970 struct key *key; 978 struct key *key;
971 long dir_version, de_version; 979 afs_dataversion_t dir_version;
980 long de_version;
972 int ret; 981 int ret;
973 982
974 if (flags & LOOKUP_RCU) 983 if (flags & LOOKUP_RCU)
@@ -1014,20 +1023,20 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags)
1014 * on a 32-bit system, we only have 32 bits in the dentry to store the 1023 * on a 32-bit system, we only have 32 bits in the dentry to store the
1015 * version. 1024 * version.
1016 */ 1025 */
1017 dir_version = (long)dir->status.data_version; 1026 dir_version = dir->status.data_version;
1018 de_version = (long)dentry->d_fsdata; 1027 de_version = (long)dentry->d_fsdata;
1019 if (de_version == dir_version) 1028 if (de_version == (long)dir_version)
1020 goto out_valid_noupdate; 1029 goto out_valid_noupdate;
1021 1030
1022 dir_version = (long)dir->invalid_before; 1031 dir_version = dir->invalid_before;
1023 if (de_version - dir_version >= 0) 1032 if (de_version - (long)dir_version >= 0)
1024 goto out_valid; 1033 goto out_valid;
1025 1034
1026 _debug("dir modified"); 1035 _debug("dir modified");
1027 afs_stat_v(dir, n_reval); 1036 afs_stat_v(dir, n_reval);
1028 1037
1029 /* search the directory for this vnode */ 1038 /* search the directory for this vnode */
1030 ret = afs_do_lookup_one(&dir->vfs_inode, dentry, &fid, key); 1039 ret = afs_do_lookup_one(&dir->vfs_inode, dentry, &fid, key, &dir_version);
1031 switch (ret) { 1040 switch (ret) {
1032 case 0: 1041 case 0:
1033 /* the filename maps to something */ 1042 /* the filename maps to something */
@@ -1080,7 +1089,7 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags)
1080 } 1089 }
1081 1090
1082out_valid: 1091out_valid:
1083 dentry->d_fsdata = (void *)dir_version; 1092 dentry->d_fsdata = (void *)(unsigned long)dir_version;
1084out_valid_noupdate: 1093out_valid_noupdate:
1085 dput(parent); 1094 dput(parent);
1086 key_put(key); 1095 key_put(key);
@@ -1187,6 +1196,20 @@ static void afs_prep_for_new_inode(struct afs_fs_cursor *fc,
1187} 1196}
1188 1197
1189/* 1198/*
1199 * Note that a dentry got changed. We need to set d_fsdata to the data version
1200 * number derived from the result of the operation. It doesn't matter if
1201 * d_fsdata goes backwards as we'll just revalidate.
1202 */
1203static void afs_update_dentry_version(struct afs_fs_cursor *fc,
1204 struct dentry *dentry,
1205 struct afs_status_cb *scb)
1206{
1207 if (fc->ac.error == 0)
1208 dentry->d_fsdata =
1209 (void *)(unsigned long)scb->status.data_version;
1210}
1211
1212/*
1190 * create a directory on an AFS filesystem 1213 * create a directory on an AFS filesystem
1191 */ 1214 */
1192static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) 1215static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
@@ -1228,6 +1251,7 @@ static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
1228 afs_check_for_remote_deletion(&fc, dvnode); 1251 afs_check_for_remote_deletion(&fc, dvnode);
1229 afs_vnode_commit_status(&fc, dvnode, fc.cb_break, 1252 afs_vnode_commit_status(&fc, dvnode, fc.cb_break,
1230 &data_version, &scb[0]); 1253 &data_version, &scb[0]);
1254 afs_update_dentry_version(&fc, dentry, &scb[0]);
1231 afs_vnode_new_inode(&fc, dentry, &iget_data, &scb[1]); 1255 afs_vnode_new_inode(&fc, dentry, &iget_data, &scb[1]);
1232 ret = afs_end_vnode_operation(&fc); 1256 ret = afs_end_vnode_operation(&fc);
1233 if (ret < 0) 1257 if (ret < 0)
@@ -1320,6 +1344,7 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry)
1320 1344
1321 afs_vnode_commit_status(&fc, dvnode, fc.cb_break, 1345 afs_vnode_commit_status(&fc, dvnode, fc.cb_break,
1322 &data_version, scb); 1346 &data_version, scb);
1347 afs_update_dentry_version(&fc, dentry, scb);
1323 ret = afs_end_vnode_operation(&fc); 1348 ret = afs_end_vnode_operation(&fc);
1324 if (ret == 0) { 1349 if (ret == 0) {
1325 afs_dir_remove_subdir(dentry); 1350 afs_dir_remove_subdir(dentry);
@@ -1459,6 +1484,7 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry)
1459 &data_version, &scb[0]); 1484 &data_version, &scb[0]);
1460 afs_vnode_commit_status(&fc, vnode, fc.cb_break_2, 1485 afs_vnode_commit_status(&fc, vnode, fc.cb_break_2,
1461 &data_version_2, &scb[1]); 1486 &data_version_2, &scb[1]);
1487 afs_update_dentry_version(&fc, dentry, &scb[0]);
1462 ret = afs_end_vnode_operation(&fc); 1488 ret = afs_end_vnode_operation(&fc);
1463 if (ret == 0 && !(scb[1].have_status || scb[1].have_error)) 1489 if (ret == 0 && !(scb[1].have_status || scb[1].have_error))
1464 ret = afs_dir_remove_link(dvnode, dentry, key); 1490 ret = afs_dir_remove_link(dvnode, dentry, key);
@@ -1527,6 +1553,7 @@ static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
1527 afs_check_for_remote_deletion(&fc, dvnode); 1553 afs_check_for_remote_deletion(&fc, dvnode);
1528 afs_vnode_commit_status(&fc, dvnode, fc.cb_break, 1554 afs_vnode_commit_status(&fc, dvnode, fc.cb_break,
1529 &data_version, &scb[0]); 1555 &data_version, &scb[0]);
1556 afs_update_dentry_version(&fc, dentry, &scb[0]);
1530 afs_vnode_new_inode(&fc, dentry, &iget_data, &scb[1]); 1557 afs_vnode_new_inode(&fc, dentry, &iget_data, &scb[1]);
1531 ret = afs_end_vnode_operation(&fc); 1558 ret = afs_end_vnode_operation(&fc);
1532 if (ret < 0) 1559 if (ret < 0)
@@ -1608,6 +1635,7 @@ static int afs_link(struct dentry *from, struct inode *dir,
1608 afs_vnode_commit_status(&fc, vnode, fc.cb_break_2, 1635 afs_vnode_commit_status(&fc, vnode, fc.cb_break_2,
1609 NULL, &scb[1]); 1636 NULL, &scb[1]);
1610 ihold(&vnode->vfs_inode); 1637 ihold(&vnode->vfs_inode);
1638 afs_update_dentry_version(&fc, dentry, &scb[0]);
1611 d_instantiate(dentry, &vnode->vfs_inode); 1639 d_instantiate(dentry, &vnode->vfs_inode);
1612 1640
1613 mutex_unlock(&vnode->io_lock); 1641 mutex_unlock(&vnode->io_lock);
@@ -1687,6 +1715,7 @@ static int afs_symlink(struct inode *dir, struct dentry *dentry,
1687 afs_check_for_remote_deletion(&fc, dvnode); 1715 afs_check_for_remote_deletion(&fc, dvnode);
1688 afs_vnode_commit_status(&fc, dvnode, fc.cb_break, 1716 afs_vnode_commit_status(&fc, dvnode, fc.cb_break,
1689 &data_version, &scb[0]); 1717 &data_version, &scb[0]);
1718 afs_update_dentry_version(&fc, dentry, &scb[0]);
1690 afs_vnode_new_inode(&fc, dentry, &iget_data, &scb[1]); 1719 afs_vnode_new_inode(&fc, dentry, &iget_data, &scb[1]);
1691 ret = afs_end_vnode_operation(&fc); 1720 ret = afs_end_vnode_operation(&fc);
1692 if (ret < 0) 1721 if (ret < 0)
@@ -1792,6 +1821,17 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
1792 } 1821 }
1793 } 1822 }
1794 1823
1824 /* This bit is potentially nasty as there's a potential race with
1825 * afs_d_revalidate{,_rcu}(). We have to change d_fsdata on the dentry
1826 * to reflect it's new parent's new data_version after the op, but
1827 * d_revalidate may see old_dentry between the op having taken place
1828 * and the version being updated.
1829 *
1830 * So drop the old_dentry for now to make other threads go through
1831 * lookup instead - which we hold a lock against.
1832 */
1833 d_drop(old_dentry);
1834
1795 ret = -ERESTARTSYS; 1835 ret = -ERESTARTSYS;
1796 if (afs_begin_vnode_operation(&fc, orig_dvnode, key, true)) { 1836 if (afs_begin_vnode_operation(&fc, orig_dvnode, key, true)) {
1797 afs_dataversion_t orig_data_version; 1837 afs_dataversion_t orig_data_version;
@@ -1803,7 +1843,7 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
1803 if (orig_dvnode != new_dvnode) { 1843 if (orig_dvnode != new_dvnode) {
1804 if (mutex_lock_interruptible_nested(&new_dvnode->io_lock, 1) < 0) { 1844 if (mutex_lock_interruptible_nested(&new_dvnode->io_lock, 1) < 0) {
1805 afs_end_vnode_operation(&fc); 1845 afs_end_vnode_operation(&fc);
1806 goto error_rehash; 1846 goto error_rehash_old;
1807 } 1847 }
1808 new_data_version = new_dvnode->status.data_version + 1; 1848 new_data_version = new_dvnode->status.data_version + 1;
1809 } else { 1849 } else {
@@ -1828,7 +1868,7 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
1828 } 1868 }
1829 ret = afs_end_vnode_operation(&fc); 1869 ret = afs_end_vnode_operation(&fc);
1830 if (ret < 0) 1870 if (ret < 0)
1831 goto error_rehash; 1871 goto error_rehash_old;
1832 } 1872 }
1833 1873
1834 if (ret == 0) { 1874 if (ret == 0) {
@@ -1854,10 +1894,26 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
1854 drop_nlink(new_inode); 1894 drop_nlink(new_inode);
1855 spin_unlock(&new_inode->i_lock); 1895 spin_unlock(&new_inode->i_lock);
1856 } 1896 }
1897
1898 /* Now we can update d_fsdata on the dentries to reflect their
1899 * new parent's data_version.
1900 *
1901 * Note that if we ever implement RENAME_EXCHANGE, we'll have
1902 * to update both dentries with opposing dir versions.
1903 */
1904 if (new_dvnode != orig_dvnode) {
1905 afs_update_dentry_version(&fc, old_dentry, &scb[1]);
1906 afs_update_dentry_version(&fc, new_dentry, &scb[1]);
1907 } else {
1908 afs_update_dentry_version(&fc, old_dentry, &scb[0]);
1909 afs_update_dentry_version(&fc, new_dentry, &scb[0]);
1910 }
1857 d_move(old_dentry, new_dentry); 1911 d_move(old_dentry, new_dentry);
1858 goto error_tmp; 1912 goto error_tmp;
1859 } 1913 }
1860 1914
1915error_rehash_old:
1916 d_rehash(new_dentry);
1861error_rehash: 1917error_rehash:
1862 if (rehash) 1918 if (rehash)
1863 d_rehash(rehash); 1919 d_rehash(rehash);