diff options
author | David Howells <dhowells@redhat.com> | 2019-05-14 07:23:43 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2019-05-16 17:23:21 -0400 |
commit | b8359153252d4465cb74f8de6c50e8c6295cbe2e (patch) | |
tree | 5ec539b6936cde10dc725cbc90acff2220c0f814 | |
parent | a38a75581e6e2f783e7b8658e9ca5d4243279f55 (diff) |
afs: Pass pre-fetch server and volume break counts into afs_iget5_set()
Pass the server and volume break counts from before the status fetch
operation that queried the attributes of a file into afs_iget5_set() so
that the new vnode's break counters can be initialised appropriately.
This allows detection of a volume or server break that happened whilst we
were fetching the status or setting up the vnode.
Fixes: c435ee34551e ("afs: Overhaul the callback handling")
Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r-- | fs/afs/dir.c | 58 | ||||
-rw-r--r-- | fs/afs/inode.c | 51 | ||||
-rw-r--r-- | fs/afs/internal.h | 4 | ||||
-rw-r--r-- | fs/afs/super.c | 14 |
4 files changed, 78 insertions, 49 deletions
diff --git a/fs/afs/dir.c b/fs/afs/dir.c index d1b3736a3bbd..9e42f6c75747 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c | |||
@@ -641,7 +641,7 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry, | |||
641 | struct afs_cb_interest *dcbi, *cbi = NULL; | 641 | struct afs_cb_interest *dcbi, *cbi = NULL; |
642 | struct afs_super_info *as = dir->i_sb->s_fs_info; | 642 | struct afs_super_info *as = dir->i_sb->s_fs_info; |
643 | struct afs_status_cb *scb; | 643 | struct afs_status_cb *scb; |
644 | struct afs_iget_data data; | 644 | struct afs_iget_data iget_data; |
645 | struct afs_fs_cursor fc; | 645 | struct afs_fs_cursor fc; |
646 | struct afs_server *server; | 646 | struct afs_server *server; |
647 | struct afs_vnode *dvnode = AFS_FS_I(dir); | 647 | struct afs_vnode *dvnode = AFS_FS_I(dir); |
@@ -684,9 +684,12 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry, | |||
684 | goto out; | 684 | goto out; |
685 | 685 | ||
686 | /* Check to see if we already have an inode for the primary fid. */ | 686 | /* Check to see if we already have an inode for the primary fid. */ |
687 | data.volume = dvnode->volume; | 687 | iget_data.fid = cookie->fids[0]; |
688 | data.fid = cookie->fids[0]; | 688 | iget_data.volume = dvnode->volume; |
689 | inode = ilookup5(dir->i_sb, cookie->fids[0].vnode, afs_iget5_test, &data); | 689 | iget_data.cb_v_break = dvnode->volume->cb_v_break; |
690 | iget_data.cb_s_break = 0; | ||
691 | inode = ilookup5(dir->i_sb, cookie->fids[0].vnode, | ||
692 | afs_iget5_test, &iget_data); | ||
690 | if (inode) | 693 | if (inode) |
691 | goto out; | 694 | goto out; |
692 | 695 | ||
@@ -713,6 +716,8 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry, | |||
713 | fc.ac.error = -ECONNABORTED; | 716 | fc.ac.error = -ECONNABORTED; |
714 | break; | 717 | break; |
715 | } | 718 | } |
719 | iget_data.cb_v_break = dvnode->volume->cb_v_break; | ||
720 | iget_data.cb_s_break = fc.cbi->server->cb_s_break; | ||
716 | afs_fs_inline_bulk_status(&fc, | 721 | afs_fs_inline_bulk_status(&fc, |
717 | afs_v2net(dvnode), | 722 | afs_v2net(dvnode), |
718 | cookie->fids, | 723 | cookie->fids, |
@@ -741,6 +746,8 @@ no_inline_bulk_status: | |||
741 | inode = ERR_PTR(-ERESTARTSYS); | 746 | inode = ERR_PTR(-ERESTARTSYS); |
742 | if (afs_begin_vnode_operation(&fc, dvnode, key, true)) { | 747 | if (afs_begin_vnode_operation(&fc, dvnode, key, true)) { |
743 | while (afs_select_fileserver(&fc)) { | 748 | while (afs_select_fileserver(&fc)) { |
749 | iget_data.cb_v_break = dvnode->volume->cb_v_break; | ||
750 | iget_data.cb_s_break = fc.cbi->server->cb_s_break; | ||
744 | scb = &cookie->statuses[0]; | 751 | scb = &cookie->statuses[0]; |
745 | afs_fs_fetch_status(&fc, | 752 | afs_fs_fetch_status(&fc, |
746 | afs_v2net(dvnode), | 753 | afs_v2net(dvnode), |
@@ -775,8 +782,8 @@ success: | |||
775 | if (scb->status.abort_code != 0) | 782 | if (scb->status.abort_code != 0) |
776 | continue; | 783 | continue; |
777 | 784 | ||
778 | ti = afs_iget(dir->i_sb, key, &cookie->fids[i], | 785 | iget_data.fid = cookie->fids[i]; |
779 | scb, cbi, dvnode); | 786 | ti = afs_iget(dir->i_sb, key, &iget_data, scb, cbi, dvnode); |
780 | if (i == 0) { | 787 | if (i == 0) { |
781 | inode = ti; | 788 | inode = ti; |
782 | } else { | 789 | } else { |
@@ -1112,7 +1119,7 @@ void afs_d_release(struct dentry *dentry) | |||
1112 | */ | 1119 | */ |
1113 | static void afs_vnode_new_inode(struct afs_fs_cursor *fc, | 1120 | static void afs_vnode_new_inode(struct afs_fs_cursor *fc, |
1114 | struct dentry *new_dentry, | 1121 | struct dentry *new_dentry, |
1115 | struct afs_fid *newfid, | 1122 | struct afs_iget_data *new_data, |
1116 | struct afs_status_cb *new_scb) | 1123 | struct afs_status_cb *new_scb) |
1117 | { | 1124 | { |
1118 | struct afs_vnode *vnode; | 1125 | struct afs_vnode *vnode; |
@@ -1122,7 +1129,7 @@ static void afs_vnode_new_inode(struct afs_fs_cursor *fc, | |||
1122 | return; | 1129 | return; |
1123 | 1130 | ||
1124 | inode = afs_iget(fc->vnode->vfs_inode.i_sb, fc->key, | 1131 | inode = afs_iget(fc->vnode->vfs_inode.i_sb, fc->key, |
1125 | newfid, new_scb, fc->cbi, fc->vnode); | 1132 | new_data, new_scb, fc->cbi, fc->vnode); |
1126 | if (IS_ERR(inode)) { | 1133 | if (IS_ERR(inode)) { |
1127 | /* ENOMEM or EINTR at a really inconvenient time - just abandon | 1134 | /* ENOMEM or EINTR at a really inconvenient time - just abandon |
1128 | * the new directory on the server. | 1135 | * the new directory on the server. |
@@ -1138,15 +1145,23 @@ static void afs_vnode_new_inode(struct afs_fs_cursor *fc, | |||
1138 | d_instantiate(new_dentry, inode); | 1145 | d_instantiate(new_dentry, inode); |
1139 | } | 1146 | } |
1140 | 1147 | ||
1148 | static void afs_prep_for_new_inode(struct afs_fs_cursor *fc, | ||
1149 | struct afs_iget_data *iget_data) | ||
1150 | { | ||
1151 | iget_data->volume = fc->vnode->volume; | ||
1152 | iget_data->cb_v_break = fc->vnode->volume->cb_v_break; | ||
1153 | iget_data->cb_s_break = fc->cbi->server->cb_s_break; | ||
1154 | } | ||
1155 | |||
1141 | /* | 1156 | /* |
1142 | * create a directory on an AFS filesystem | 1157 | * create a directory on an AFS filesystem |
1143 | */ | 1158 | */ |
1144 | static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | 1159 | static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) |
1145 | { | 1160 | { |
1161 | struct afs_iget_data iget_data; | ||
1146 | struct afs_status_cb *scb; | 1162 | struct afs_status_cb *scb; |
1147 | struct afs_fs_cursor fc; | 1163 | struct afs_fs_cursor fc; |
1148 | struct afs_vnode *dvnode = AFS_FS_I(dir); | 1164 | struct afs_vnode *dvnode = AFS_FS_I(dir); |
1149 | struct afs_fid newfid; | ||
1150 | struct key *key; | 1165 | struct key *key; |
1151 | int ret; | 1166 | int ret; |
1152 | 1167 | ||
@@ -1172,14 +1187,15 @@ static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
1172 | 1187 | ||
1173 | while (afs_select_fileserver(&fc)) { | 1188 | while (afs_select_fileserver(&fc)) { |
1174 | fc.cb_break = afs_calc_vnode_cb_break(dvnode); | 1189 | fc.cb_break = afs_calc_vnode_cb_break(dvnode); |
1190 | afs_prep_for_new_inode(&fc, &iget_data); | ||
1175 | afs_fs_create(&fc, dentry->d_name.name, mode, | 1191 | afs_fs_create(&fc, dentry->d_name.name, mode, |
1176 | &scb[0], &newfid, &scb[1]); | 1192 | &scb[0], &iget_data.fid, &scb[1]); |
1177 | } | 1193 | } |
1178 | 1194 | ||
1179 | afs_check_for_remote_deletion(&fc, dvnode); | 1195 | afs_check_for_remote_deletion(&fc, dvnode); |
1180 | afs_vnode_commit_status(&fc, dvnode, fc.cb_break, | 1196 | afs_vnode_commit_status(&fc, dvnode, fc.cb_break, |
1181 | &data_version, &scb[0]); | 1197 | &data_version, &scb[0]); |
1182 | afs_vnode_new_inode(&fc, dentry, &newfid, &scb[1]); | 1198 | afs_vnode_new_inode(&fc, dentry, &iget_data, &scb[1]); |
1183 | ret = afs_end_vnode_operation(&fc); | 1199 | ret = afs_end_vnode_operation(&fc); |
1184 | if (ret < 0) | 1200 | if (ret < 0) |
1185 | goto error_key; | 1201 | goto error_key; |
@@ -1189,7 +1205,7 @@ static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
1189 | 1205 | ||
1190 | if (ret == 0 && | 1206 | if (ret == 0 && |
1191 | test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) | 1207 | test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) |
1192 | afs_edit_dir_add(dvnode, &dentry->d_name, &newfid, | 1208 | afs_edit_dir_add(dvnode, &dentry->d_name, &iget_data.fid, |
1193 | afs_edit_dir_for_create); | 1209 | afs_edit_dir_for_create); |
1194 | 1210 | ||
1195 | key_put(key); | 1211 | key_put(key); |
@@ -1439,10 +1455,10 @@ error: | |||
1439 | static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 1455 | static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
1440 | bool excl) | 1456 | bool excl) |
1441 | { | 1457 | { |
1458 | struct afs_iget_data iget_data; | ||
1442 | struct afs_fs_cursor fc; | 1459 | struct afs_fs_cursor fc; |
1443 | struct afs_status_cb *scb; | 1460 | struct afs_status_cb *scb; |
1444 | struct afs_vnode *dvnode = AFS_FS_I(dir); | 1461 | struct afs_vnode *dvnode = AFS_FS_I(dir); |
1445 | struct afs_fid newfid; | ||
1446 | struct key *key; | 1462 | struct key *key; |
1447 | int ret; | 1463 | int ret; |
1448 | 1464 | ||
@@ -1472,14 +1488,15 @@ static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
1472 | 1488 | ||
1473 | while (afs_select_fileserver(&fc)) { | 1489 | while (afs_select_fileserver(&fc)) { |
1474 | fc.cb_break = afs_calc_vnode_cb_break(dvnode); | 1490 | fc.cb_break = afs_calc_vnode_cb_break(dvnode); |
1491 | afs_prep_for_new_inode(&fc, &iget_data); | ||
1475 | afs_fs_create(&fc, dentry->d_name.name, mode, | 1492 | afs_fs_create(&fc, dentry->d_name.name, mode, |
1476 | &scb[0], &newfid, &scb[1]); | 1493 | &scb[0], &iget_data.fid, &scb[1]); |
1477 | } | 1494 | } |
1478 | 1495 | ||
1479 | afs_check_for_remote_deletion(&fc, dvnode); | 1496 | afs_check_for_remote_deletion(&fc, dvnode); |
1480 | afs_vnode_commit_status(&fc, dvnode, fc.cb_break, | 1497 | afs_vnode_commit_status(&fc, dvnode, fc.cb_break, |
1481 | &data_version, &scb[0]); | 1498 | &data_version, &scb[0]); |
1482 | afs_vnode_new_inode(&fc, dentry, &newfid, &scb[1]); | 1499 | afs_vnode_new_inode(&fc, dentry, &iget_data, &scb[1]); |
1483 | ret = afs_end_vnode_operation(&fc); | 1500 | ret = afs_end_vnode_operation(&fc); |
1484 | if (ret < 0) | 1501 | if (ret < 0) |
1485 | goto error_key; | 1502 | goto error_key; |
@@ -1488,7 +1505,7 @@ static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
1488 | } | 1505 | } |
1489 | 1506 | ||
1490 | if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) | 1507 | if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) |
1491 | afs_edit_dir_add(dvnode, &dentry->d_name, &newfid, | 1508 | afs_edit_dir_add(dvnode, &dentry->d_name, &iget_data.fid, |
1492 | afs_edit_dir_for_create); | 1509 | afs_edit_dir_for_create); |
1493 | 1510 | ||
1494 | kfree(scb); | 1511 | kfree(scb); |
@@ -1595,10 +1612,10 @@ error: | |||
1595 | static int afs_symlink(struct inode *dir, struct dentry *dentry, | 1612 | static int afs_symlink(struct inode *dir, struct dentry *dentry, |
1596 | const char *content) | 1613 | const char *content) |
1597 | { | 1614 | { |
1615 | struct afs_iget_data iget_data; | ||
1598 | struct afs_fs_cursor fc; | 1616 | struct afs_fs_cursor fc; |
1599 | struct afs_status_cb *scb; | 1617 | struct afs_status_cb *scb; |
1600 | struct afs_vnode *dvnode = AFS_FS_I(dir); | 1618 | struct afs_vnode *dvnode = AFS_FS_I(dir); |
1601 | struct afs_fid newfid; | ||
1602 | struct key *key; | 1619 | struct key *key; |
1603 | int ret; | 1620 | int ret; |
1604 | 1621 | ||
@@ -1631,14 +1648,15 @@ static int afs_symlink(struct inode *dir, struct dentry *dentry, | |||
1631 | 1648 | ||
1632 | while (afs_select_fileserver(&fc)) { | 1649 | while (afs_select_fileserver(&fc)) { |
1633 | fc.cb_break = afs_calc_vnode_cb_break(dvnode); | 1650 | fc.cb_break = afs_calc_vnode_cb_break(dvnode); |
1651 | afs_prep_for_new_inode(&fc, &iget_data); | ||
1634 | afs_fs_symlink(&fc, dentry->d_name.name, content, | 1652 | afs_fs_symlink(&fc, dentry->d_name.name, content, |
1635 | &scb[0], &newfid, &scb[1]); | 1653 | &scb[0], &iget_data.fid, &scb[1]); |
1636 | } | 1654 | } |
1637 | 1655 | ||
1638 | afs_check_for_remote_deletion(&fc, dvnode); | 1656 | afs_check_for_remote_deletion(&fc, dvnode); |
1639 | afs_vnode_commit_status(&fc, dvnode, fc.cb_break, | 1657 | afs_vnode_commit_status(&fc, dvnode, fc.cb_break, |
1640 | &data_version, &scb[0]); | 1658 | &data_version, &scb[0]); |
1641 | afs_vnode_new_inode(&fc, dentry, &newfid, &scb[1]); | 1659 | afs_vnode_new_inode(&fc, dentry, &iget_data, &scb[1]); |
1642 | ret = afs_end_vnode_operation(&fc); | 1660 | ret = afs_end_vnode_operation(&fc); |
1643 | if (ret < 0) | 1661 | if (ret < 0) |
1644 | goto error_key; | 1662 | goto error_key; |
@@ -1647,7 +1665,7 @@ static int afs_symlink(struct inode *dir, struct dentry *dentry, | |||
1647 | } | 1665 | } |
1648 | 1666 | ||
1649 | if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) | 1667 | if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) |
1650 | afs_edit_dir_add(dvnode, &dentry->d_name, &newfid, | 1668 | afs_edit_dir_add(dvnode, &dentry->d_name, &iget_data.fid, |
1651 | afs_edit_dir_for_symlink); | 1669 | afs_edit_dir_for_symlink); |
1652 | 1670 | ||
1653 | key_put(key); | 1671 | key_put(key); |
diff --git a/fs/afs/inode.c b/fs/afs/inode.c index e1a523d2e378..b42d9d09669c 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c | |||
@@ -347,10 +347,10 @@ int afs_fetch_status(struct afs_vnode *vnode, struct key *key, bool is_new, | |||
347 | */ | 347 | */ |
348 | int afs_iget5_test(struct inode *inode, void *opaque) | 348 | int afs_iget5_test(struct inode *inode, void *opaque) |
349 | { | 349 | { |
350 | struct afs_iget_data *data = opaque; | 350 | struct afs_iget_data *iget_data = opaque; |
351 | struct afs_vnode *vnode = AFS_FS_I(inode); | 351 | struct afs_vnode *vnode = AFS_FS_I(inode); |
352 | 352 | ||
353 | return memcmp(&vnode->fid, &data->fid, sizeof(data->fid)) == 0; | 353 | return memcmp(&vnode->fid, &iget_data->fid, sizeof(iget_data->fid)) == 0; |
354 | } | 354 | } |
355 | 355 | ||
356 | /* | 356 | /* |
@@ -368,17 +368,19 @@ static int afs_iget5_pseudo_dir_test(struct inode *inode, void *opaque) | |||
368 | */ | 368 | */ |
369 | static int afs_iget5_set(struct inode *inode, void *opaque) | 369 | static int afs_iget5_set(struct inode *inode, void *opaque) |
370 | { | 370 | { |
371 | struct afs_iget_data *data = opaque; | 371 | struct afs_iget_data *iget_data = opaque; |
372 | struct afs_vnode *vnode = AFS_FS_I(inode); | 372 | struct afs_vnode *vnode = AFS_FS_I(inode); |
373 | 373 | ||
374 | vnode->fid = data->fid; | 374 | vnode->fid = iget_data->fid; |
375 | vnode->volume = data->volume; | 375 | vnode->volume = iget_data->volume; |
376 | vnode->cb_v_break = iget_data->cb_v_break; | ||
377 | vnode->cb_s_break = iget_data->cb_s_break; | ||
376 | 378 | ||
377 | /* YFS supports 96-bit vnode IDs, but Linux only supports | 379 | /* YFS supports 96-bit vnode IDs, but Linux only supports |
378 | * 64-bit inode numbers. | 380 | * 64-bit inode numbers. |
379 | */ | 381 | */ |
380 | inode->i_ino = data->fid.vnode; | 382 | inode->i_ino = iget_data->fid.vnode; |
381 | inode->i_generation = data->fid.unique; | 383 | inode->i_generation = iget_data->fid.unique; |
382 | return 0; | 384 | return 0; |
383 | } | 385 | } |
384 | 386 | ||
@@ -388,38 +390,42 @@ static int afs_iget5_set(struct inode *inode, void *opaque) | |||
388 | */ | 390 | */ |
389 | struct inode *afs_iget_pseudo_dir(struct super_block *sb, bool root) | 391 | struct inode *afs_iget_pseudo_dir(struct super_block *sb, bool root) |
390 | { | 392 | { |
391 | struct afs_iget_data data; | ||
392 | struct afs_super_info *as; | 393 | struct afs_super_info *as; |
393 | struct afs_vnode *vnode; | 394 | struct afs_vnode *vnode; |
394 | struct inode *inode; | 395 | struct inode *inode; |
395 | static atomic_t afs_autocell_ino; | 396 | static atomic_t afs_autocell_ino; |
396 | 397 | ||
398 | struct afs_iget_data iget_data = { | ||
399 | .cb_v_break = 0, | ||
400 | .cb_s_break = 0, | ||
401 | }; | ||
402 | |||
397 | _enter(""); | 403 | _enter(""); |
398 | 404 | ||
399 | as = sb->s_fs_info; | 405 | as = sb->s_fs_info; |
400 | if (as->volume) { | 406 | if (as->volume) { |
401 | data.volume = as->volume; | 407 | iget_data.volume = as->volume; |
402 | data.fid.vid = as->volume->vid; | 408 | iget_data.fid.vid = as->volume->vid; |
403 | } | 409 | } |
404 | if (root) { | 410 | if (root) { |
405 | data.fid.vnode = 1; | 411 | iget_data.fid.vnode = 1; |
406 | data.fid.unique = 1; | 412 | iget_data.fid.unique = 1; |
407 | } else { | 413 | } else { |
408 | data.fid.vnode = atomic_inc_return(&afs_autocell_ino); | 414 | iget_data.fid.vnode = atomic_inc_return(&afs_autocell_ino); |
409 | data.fid.unique = 0; | 415 | iget_data.fid.unique = 0; |
410 | } | 416 | } |
411 | 417 | ||
412 | inode = iget5_locked(sb, data.fid.vnode, | 418 | inode = iget5_locked(sb, iget_data.fid.vnode, |
413 | afs_iget5_pseudo_dir_test, afs_iget5_set, | 419 | afs_iget5_pseudo_dir_test, afs_iget5_set, |
414 | &data); | 420 | &iget_data); |
415 | if (!inode) { | 421 | if (!inode) { |
416 | _leave(" = -ENOMEM"); | 422 | _leave(" = -ENOMEM"); |
417 | return ERR_PTR(-ENOMEM); | 423 | return ERR_PTR(-ENOMEM); |
418 | } | 424 | } |
419 | 425 | ||
420 | _debug("GOT INODE %p { ino=%lu, vl=%llx, vn=%llx, u=%x }", | 426 | _debug("GOT INODE %p { ino=%lu, vl=%llx, vn=%llx, u=%x }", |
421 | inode, inode->i_ino, data.fid.vid, data.fid.vnode, | 427 | inode, inode->i_ino, iget_data.fid.vid, iget_data.fid.vnode, |
422 | data.fid.unique); | 428 | iget_data.fid.unique); |
423 | 429 | ||
424 | vnode = AFS_FS_I(inode); | 430 | vnode = AFS_FS_I(inode); |
425 | 431 | ||
@@ -490,23 +496,24 @@ static void afs_get_inode_cache(struct afs_vnode *vnode) | |||
490 | * inode retrieval | 496 | * inode retrieval |
491 | */ | 497 | */ |
492 | struct inode *afs_iget(struct super_block *sb, struct key *key, | 498 | struct inode *afs_iget(struct super_block *sb, struct key *key, |
493 | struct afs_fid *fid, struct afs_status_cb *scb, | 499 | struct afs_iget_data *iget_data, |
500 | struct afs_status_cb *scb, | ||
494 | struct afs_cb_interest *cbi, | 501 | struct afs_cb_interest *cbi, |
495 | struct afs_vnode *parent_vnode) | 502 | struct afs_vnode *parent_vnode) |
496 | { | 503 | { |
497 | struct afs_iget_data data = { .fid = *fid }; | ||
498 | struct afs_super_info *as; | 504 | struct afs_super_info *as; |
499 | struct afs_vnode *vnode; | 505 | struct afs_vnode *vnode; |
506 | struct afs_fid *fid = &iget_data->fid; | ||
500 | struct inode *inode; | 507 | struct inode *inode; |
501 | int ret; | 508 | int ret; |
502 | 509 | ||
503 | _enter(",{%llx:%llu.%u},,", fid->vid, fid->vnode, fid->unique); | 510 | _enter(",{%llx:%llu.%u},,", fid->vid, fid->vnode, fid->unique); |
504 | 511 | ||
505 | as = sb->s_fs_info; | 512 | as = sb->s_fs_info; |
506 | data.volume = as->volume; | 513 | iget_data->volume = as->volume; |
507 | 514 | ||
508 | inode = iget5_locked(sb, fid->vnode, afs_iget5_test, afs_iget5_set, | 515 | inode = iget5_locked(sb, fid->vnode, afs_iget5_test, afs_iget5_set, |
509 | &data); | 516 | iget_data); |
510 | if (!inode) { | 517 | if (!inode) { |
511 | _leave(" = -ENOMEM"); | 518 | _leave(" = -ENOMEM"); |
512 | return ERR_PTR(-ENOMEM); | 519 | return ERR_PTR(-ENOMEM); |
diff --git a/fs/afs/internal.h b/fs/afs/internal.h index f80ca638e70f..2073c1a3ab4b 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h | |||
@@ -66,6 +66,8 @@ struct afs_fs_context { | |||
66 | struct afs_iget_data { | 66 | struct afs_iget_data { |
67 | struct afs_fid fid; | 67 | struct afs_fid fid; |
68 | struct afs_volume *volume; /* volume on which resides */ | 68 | struct afs_volume *volume; /* volume on which resides */ |
69 | unsigned int cb_v_break; /* Pre-fetch volume break count */ | ||
70 | unsigned int cb_s_break; /* Pre-fetch server break count */ | ||
69 | }; | 71 | }; |
70 | 72 | ||
71 | enum afs_call_state { | 73 | enum afs_call_state { |
@@ -1023,7 +1025,7 @@ extern int afs_fetch_status(struct afs_vnode *, struct key *, bool, afs_access_t | |||
1023 | extern int afs_iget5_test(struct inode *, void *); | 1025 | extern int afs_iget5_test(struct inode *, void *); |
1024 | extern struct inode *afs_iget_pseudo_dir(struct super_block *, bool); | 1026 | extern struct inode *afs_iget_pseudo_dir(struct super_block *, bool); |
1025 | extern struct inode *afs_iget(struct super_block *, struct key *, | 1027 | extern struct inode *afs_iget(struct super_block *, struct key *, |
1026 | struct afs_fid *, struct afs_status_cb *, | 1028 | struct afs_iget_data *, struct afs_status_cb *, |
1027 | struct afs_cb_interest *, | 1029 | struct afs_cb_interest *, |
1028 | struct afs_vnode *); | 1030 | struct afs_vnode *); |
1029 | extern void afs_zap_data(struct afs_vnode *); | 1031 | extern void afs_zap_data(struct afs_vnode *); |
diff --git a/fs/afs/super.c b/fs/afs/super.c index f76473ad7bbb..f18911e8d770 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c | |||
@@ -426,7 +426,7 @@ static int afs_set_super(struct super_block *sb, struct fs_context *fc) | |||
426 | static int afs_fill_super(struct super_block *sb, struct afs_fs_context *ctx) | 426 | static int afs_fill_super(struct super_block *sb, struct afs_fs_context *ctx) |
427 | { | 427 | { |
428 | struct afs_super_info *as = AFS_FS_S(sb); | 428 | struct afs_super_info *as = AFS_FS_S(sb); |
429 | struct afs_fid fid; | 429 | struct afs_iget_data iget_data; |
430 | struct inode *inode = NULL; | 430 | struct inode *inode = NULL; |
431 | int ret; | 431 | int ret; |
432 | 432 | ||
@@ -451,11 +451,13 @@ static int afs_fill_super(struct super_block *sb, struct afs_fs_context *ctx) | |||
451 | } else { | 451 | } else { |
452 | sprintf(sb->s_id, "%llu", as->volume->vid); | 452 | sprintf(sb->s_id, "%llu", as->volume->vid); |
453 | afs_activate_volume(as->volume); | 453 | afs_activate_volume(as->volume); |
454 | fid.vid = as->volume->vid; | 454 | iget_data.fid.vid = as->volume->vid; |
455 | fid.vnode = 1; | 455 | iget_data.fid.vnode = 1; |
456 | fid.vnode_hi = 0; | 456 | iget_data.fid.vnode_hi = 0; |
457 | fid.unique = 1; | 457 | iget_data.fid.unique = 1; |
458 | inode = afs_iget(sb, ctx->key, &fid, NULL, NULL, NULL); | 458 | iget_data.cb_v_break = as->volume->cb_v_break; |
459 | iget_data.cb_s_break = 0; | ||
460 | inode = afs_iget(sb, ctx->key, &iget_data, NULL, NULL, NULL); | ||
459 | } | 461 | } |
460 | 462 | ||
461 | if (IS_ERR(inode)) | 463 | if (IS_ERR(inode)) |