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: c435ee3455
("afs: Overhaul the callback handling")
Signed-off-by: David Howells <dhowells@redhat.com>
This commit is contained in:
parent
a38a75581e
commit
b835915325
58
fs/afs/dir.c
58
fs/afs/dir.c
|
@ -641,7 +641,7 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry,
|
||||||
struct afs_cb_interest *dcbi, *cbi = NULL;
|
struct afs_cb_interest *dcbi, *cbi = NULL;
|
||||||
struct afs_super_info *as = dir->i_sb->s_fs_info;
|
struct afs_super_info *as = dir->i_sb->s_fs_info;
|
||||||
struct afs_status_cb *scb;
|
struct afs_status_cb *scb;
|
||||||
struct afs_iget_data data;
|
struct afs_iget_data iget_data;
|
||||||
struct afs_fs_cursor fc;
|
struct afs_fs_cursor fc;
|
||||||
struct afs_server *server;
|
struct afs_server *server;
|
||||||
struct afs_vnode *dvnode = AFS_FS_I(dir);
|
struct afs_vnode *dvnode = AFS_FS_I(dir);
|
||||||
|
@ -684,9 +684,12 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry,
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* Check to see if we already have an inode for the primary fid. */
|
/* Check to see if we already have an inode for the primary fid. */
|
||||||
data.volume = dvnode->volume;
|
iget_data.fid = cookie->fids[0];
|
||||||
data.fid = cookie->fids[0];
|
iget_data.volume = dvnode->volume;
|
||||||
inode = ilookup5(dir->i_sb, cookie->fids[0].vnode, afs_iget5_test, &data);
|
iget_data.cb_v_break = dvnode->volume->cb_v_break;
|
||||||
|
iget_data.cb_s_break = 0;
|
||||||
|
inode = ilookup5(dir->i_sb, cookie->fids[0].vnode,
|
||||||
|
afs_iget5_test, &iget_data);
|
||||||
if (inode)
|
if (inode)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -713,6 +716,8 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry,
|
||||||
fc.ac.error = -ECONNABORTED;
|
fc.ac.error = -ECONNABORTED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
iget_data.cb_v_break = dvnode->volume->cb_v_break;
|
||||||
|
iget_data.cb_s_break = fc.cbi->server->cb_s_break;
|
||||||
afs_fs_inline_bulk_status(&fc,
|
afs_fs_inline_bulk_status(&fc,
|
||||||
afs_v2net(dvnode),
|
afs_v2net(dvnode),
|
||||||
cookie->fids,
|
cookie->fids,
|
||||||
|
@ -741,6 +746,8 @@ no_inline_bulk_status:
|
||||||
inode = ERR_PTR(-ERESTARTSYS);
|
inode = ERR_PTR(-ERESTARTSYS);
|
||||||
if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {
|
if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {
|
||||||
while (afs_select_fileserver(&fc)) {
|
while (afs_select_fileserver(&fc)) {
|
||||||
|
iget_data.cb_v_break = dvnode->volume->cb_v_break;
|
||||||
|
iget_data.cb_s_break = fc.cbi->server->cb_s_break;
|
||||||
scb = &cookie->statuses[0];
|
scb = &cookie->statuses[0];
|
||||||
afs_fs_fetch_status(&fc,
|
afs_fs_fetch_status(&fc,
|
||||||
afs_v2net(dvnode),
|
afs_v2net(dvnode),
|
||||||
|
@ -775,8 +782,8 @@ success:
|
||||||
if (scb->status.abort_code != 0)
|
if (scb->status.abort_code != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ti = afs_iget(dir->i_sb, key, &cookie->fids[i],
|
iget_data.fid = cookie->fids[i];
|
||||||
scb, cbi, dvnode);
|
ti = afs_iget(dir->i_sb, key, &iget_data, scb, cbi, dvnode);
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
inode = ti;
|
inode = ti;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1112,7 +1119,7 @@ void afs_d_release(struct dentry *dentry)
|
||||||
*/
|
*/
|
||||||
static void afs_vnode_new_inode(struct afs_fs_cursor *fc,
|
static void afs_vnode_new_inode(struct afs_fs_cursor *fc,
|
||||||
struct dentry *new_dentry,
|
struct dentry *new_dentry,
|
||||||
struct afs_fid *newfid,
|
struct afs_iget_data *new_data,
|
||||||
struct afs_status_cb *new_scb)
|
struct afs_status_cb *new_scb)
|
||||||
{
|
{
|
||||||
struct afs_vnode *vnode;
|
struct afs_vnode *vnode;
|
||||||
|
@ -1122,7 +1129,7 @@ static void afs_vnode_new_inode(struct afs_fs_cursor *fc,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
inode = afs_iget(fc->vnode->vfs_inode.i_sb, fc->key,
|
inode = afs_iget(fc->vnode->vfs_inode.i_sb, fc->key,
|
||||||
newfid, new_scb, fc->cbi, fc->vnode);
|
new_data, new_scb, fc->cbi, fc->vnode);
|
||||||
if (IS_ERR(inode)) {
|
if (IS_ERR(inode)) {
|
||||||
/* ENOMEM or EINTR at a really inconvenient time - just abandon
|
/* ENOMEM or EINTR at a really inconvenient time - just abandon
|
||||||
* the new directory on the server.
|
* the new directory on the server.
|
||||||
|
@ -1138,15 +1145,23 @@ static void afs_vnode_new_inode(struct afs_fs_cursor *fc,
|
||||||
d_instantiate(new_dentry, inode);
|
d_instantiate(new_dentry, inode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void afs_prep_for_new_inode(struct afs_fs_cursor *fc,
|
||||||
|
struct afs_iget_data *iget_data)
|
||||||
|
{
|
||||||
|
iget_data->volume = fc->vnode->volume;
|
||||||
|
iget_data->cb_v_break = fc->vnode->volume->cb_v_break;
|
||||||
|
iget_data->cb_s_break = fc->cbi->server->cb_s_break;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* create a directory on an AFS filesystem
|
* create a directory on an AFS filesystem
|
||||||
*/
|
*/
|
||||||
static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
||||||
{
|
{
|
||||||
|
struct afs_iget_data iget_data;
|
||||||
struct afs_status_cb *scb;
|
struct afs_status_cb *scb;
|
||||||
struct afs_fs_cursor fc;
|
struct afs_fs_cursor fc;
|
||||||
struct afs_vnode *dvnode = AFS_FS_I(dir);
|
struct afs_vnode *dvnode = AFS_FS_I(dir);
|
||||||
struct afs_fid newfid;
|
|
||||||
struct key *key;
|
struct key *key;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -1172,14 +1187,15 @@ static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
||||||
|
|
||||||
while (afs_select_fileserver(&fc)) {
|
while (afs_select_fileserver(&fc)) {
|
||||||
fc.cb_break = afs_calc_vnode_cb_break(dvnode);
|
fc.cb_break = afs_calc_vnode_cb_break(dvnode);
|
||||||
|
afs_prep_for_new_inode(&fc, &iget_data);
|
||||||
afs_fs_create(&fc, dentry->d_name.name, mode,
|
afs_fs_create(&fc, dentry->d_name.name, mode,
|
||||||
&scb[0], &newfid, &scb[1]);
|
&scb[0], &iget_data.fid, &scb[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
afs_check_for_remote_deletion(&fc, dvnode);
|
afs_check_for_remote_deletion(&fc, dvnode);
|
||||||
afs_vnode_commit_status(&fc, dvnode, fc.cb_break,
|
afs_vnode_commit_status(&fc, dvnode, fc.cb_break,
|
||||||
&data_version, &scb[0]);
|
&data_version, &scb[0]);
|
||||||
afs_vnode_new_inode(&fc, dentry, &newfid, &scb[1]);
|
afs_vnode_new_inode(&fc, dentry, &iget_data, &scb[1]);
|
||||||
ret = afs_end_vnode_operation(&fc);
|
ret = afs_end_vnode_operation(&fc);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto error_key;
|
goto error_key;
|
||||||
|
@ -1189,7 +1205,7 @@ static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
||||||
|
|
||||||
if (ret == 0 &&
|
if (ret == 0 &&
|
||||||
test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
|
test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
|
||||||
afs_edit_dir_add(dvnode, &dentry->d_name, &newfid,
|
afs_edit_dir_add(dvnode, &dentry->d_name, &iget_data.fid,
|
||||||
afs_edit_dir_for_create);
|
afs_edit_dir_for_create);
|
||||||
|
|
||||||
key_put(key);
|
key_put(key);
|
||||||
|
@ -1439,10 +1455,10 @@ error:
|
||||||
static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
|
static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
|
||||||
bool excl)
|
bool excl)
|
||||||
{
|
{
|
||||||
|
struct afs_iget_data iget_data;
|
||||||
struct afs_fs_cursor fc;
|
struct afs_fs_cursor fc;
|
||||||
struct afs_status_cb *scb;
|
struct afs_status_cb *scb;
|
||||||
struct afs_vnode *dvnode = AFS_FS_I(dir);
|
struct afs_vnode *dvnode = AFS_FS_I(dir);
|
||||||
struct afs_fid newfid;
|
|
||||||
struct key *key;
|
struct key *key;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -1472,14 +1488,15 @@ static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
|
||||||
|
|
||||||
while (afs_select_fileserver(&fc)) {
|
while (afs_select_fileserver(&fc)) {
|
||||||
fc.cb_break = afs_calc_vnode_cb_break(dvnode);
|
fc.cb_break = afs_calc_vnode_cb_break(dvnode);
|
||||||
|
afs_prep_for_new_inode(&fc, &iget_data);
|
||||||
afs_fs_create(&fc, dentry->d_name.name, mode,
|
afs_fs_create(&fc, dentry->d_name.name, mode,
|
||||||
&scb[0], &newfid, &scb[1]);
|
&scb[0], &iget_data.fid, &scb[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
afs_check_for_remote_deletion(&fc, dvnode);
|
afs_check_for_remote_deletion(&fc, dvnode);
|
||||||
afs_vnode_commit_status(&fc, dvnode, fc.cb_break,
|
afs_vnode_commit_status(&fc, dvnode, fc.cb_break,
|
||||||
&data_version, &scb[0]);
|
&data_version, &scb[0]);
|
||||||
afs_vnode_new_inode(&fc, dentry, &newfid, &scb[1]);
|
afs_vnode_new_inode(&fc, dentry, &iget_data, &scb[1]);
|
||||||
ret = afs_end_vnode_operation(&fc);
|
ret = afs_end_vnode_operation(&fc);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto error_key;
|
goto error_key;
|
||||||
|
@ -1488,7 +1505,7 @@ static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
|
if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
|
||||||
afs_edit_dir_add(dvnode, &dentry->d_name, &newfid,
|
afs_edit_dir_add(dvnode, &dentry->d_name, &iget_data.fid,
|
||||||
afs_edit_dir_for_create);
|
afs_edit_dir_for_create);
|
||||||
|
|
||||||
kfree(scb);
|
kfree(scb);
|
||||||
|
@ -1595,10 +1612,10 @@ error:
|
||||||
static int afs_symlink(struct inode *dir, struct dentry *dentry,
|
static int afs_symlink(struct inode *dir, struct dentry *dentry,
|
||||||
const char *content)
|
const char *content)
|
||||||
{
|
{
|
||||||
|
struct afs_iget_data iget_data;
|
||||||
struct afs_fs_cursor fc;
|
struct afs_fs_cursor fc;
|
||||||
struct afs_status_cb *scb;
|
struct afs_status_cb *scb;
|
||||||
struct afs_vnode *dvnode = AFS_FS_I(dir);
|
struct afs_vnode *dvnode = AFS_FS_I(dir);
|
||||||
struct afs_fid newfid;
|
|
||||||
struct key *key;
|
struct key *key;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -1631,14 +1648,15 @@ static int afs_symlink(struct inode *dir, struct dentry *dentry,
|
||||||
|
|
||||||
while (afs_select_fileserver(&fc)) {
|
while (afs_select_fileserver(&fc)) {
|
||||||
fc.cb_break = afs_calc_vnode_cb_break(dvnode);
|
fc.cb_break = afs_calc_vnode_cb_break(dvnode);
|
||||||
|
afs_prep_for_new_inode(&fc, &iget_data);
|
||||||
afs_fs_symlink(&fc, dentry->d_name.name, content,
|
afs_fs_symlink(&fc, dentry->d_name.name, content,
|
||||||
&scb[0], &newfid, &scb[1]);
|
&scb[0], &iget_data.fid, &scb[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
afs_check_for_remote_deletion(&fc, dvnode);
|
afs_check_for_remote_deletion(&fc, dvnode);
|
||||||
afs_vnode_commit_status(&fc, dvnode, fc.cb_break,
|
afs_vnode_commit_status(&fc, dvnode, fc.cb_break,
|
||||||
&data_version, &scb[0]);
|
&data_version, &scb[0]);
|
||||||
afs_vnode_new_inode(&fc, dentry, &newfid, &scb[1]);
|
afs_vnode_new_inode(&fc, dentry, &iget_data, &scb[1]);
|
||||||
ret = afs_end_vnode_operation(&fc);
|
ret = afs_end_vnode_operation(&fc);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto error_key;
|
goto error_key;
|
||||||
|
@ -1647,7 +1665,7 @@ static int afs_symlink(struct inode *dir, struct dentry *dentry,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
|
if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
|
||||||
afs_edit_dir_add(dvnode, &dentry->d_name, &newfid,
|
afs_edit_dir_add(dvnode, &dentry->d_name, &iget_data.fid,
|
||||||
afs_edit_dir_for_symlink);
|
afs_edit_dir_for_symlink);
|
||||||
|
|
||||||
key_put(key);
|
key_put(key);
|
||||||
|
|
|
@ -347,10 +347,10 @@ int afs_fetch_status(struct afs_vnode *vnode, struct key *key, bool is_new,
|
||||||
*/
|
*/
|
||||||
int afs_iget5_test(struct inode *inode, void *opaque)
|
int afs_iget5_test(struct inode *inode, void *opaque)
|
||||||
{
|
{
|
||||||
struct afs_iget_data *data = opaque;
|
struct afs_iget_data *iget_data = opaque;
|
||||||
struct afs_vnode *vnode = AFS_FS_I(inode);
|
struct afs_vnode *vnode = AFS_FS_I(inode);
|
||||||
|
|
||||||
return memcmp(&vnode->fid, &data->fid, sizeof(data->fid)) == 0;
|
return memcmp(&vnode->fid, &iget_data->fid, sizeof(iget_data->fid)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -368,17 +368,19 @@ static int afs_iget5_pseudo_dir_test(struct inode *inode, void *opaque)
|
||||||
*/
|
*/
|
||||||
static int afs_iget5_set(struct inode *inode, void *opaque)
|
static int afs_iget5_set(struct inode *inode, void *opaque)
|
||||||
{
|
{
|
||||||
struct afs_iget_data *data = opaque;
|
struct afs_iget_data *iget_data = opaque;
|
||||||
struct afs_vnode *vnode = AFS_FS_I(inode);
|
struct afs_vnode *vnode = AFS_FS_I(inode);
|
||||||
|
|
||||||
vnode->fid = data->fid;
|
vnode->fid = iget_data->fid;
|
||||||
vnode->volume = data->volume;
|
vnode->volume = iget_data->volume;
|
||||||
|
vnode->cb_v_break = iget_data->cb_v_break;
|
||||||
|
vnode->cb_s_break = iget_data->cb_s_break;
|
||||||
|
|
||||||
/* YFS supports 96-bit vnode IDs, but Linux only supports
|
/* YFS supports 96-bit vnode IDs, but Linux only supports
|
||||||
* 64-bit inode numbers.
|
* 64-bit inode numbers.
|
||||||
*/
|
*/
|
||||||
inode->i_ino = data->fid.vnode;
|
inode->i_ino = iget_data->fid.vnode;
|
||||||
inode->i_generation = data->fid.unique;
|
inode->i_generation = iget_data->fid.unique;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,38 +390,42 @@ static int afs_iget5_set(struct inode *inode, void *opaque)
|
||||||
*/
|
*/
|
||||||
struct inode *afs_iget_pseudo_dir(struct super_block *sb, bool root)
|
struct inode *afs_iget_pseudo_dir(struct super_block *sb, bool root)
|
||||||
{
|
{
|
||||||
struct afs_iget_data data;
|
|
||||||
struct afs_super_info *as;
|
struct afs_super_info *as;
|
||||||
struct afs_vnode *vnode;
|
struct afs_vnode *vnode;
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
static atomic_t afs_autocell_ino;
|
static atomic_t afs_autocell_ino;
|
||||||
|
|
||||||
|
struct afs_iget_data iget_data = {
|
||||||
|
.cb_v_break = 0,
|
||||||
|
.cb_s_break = 0,
|
||||||
|
};
|
||||||
|
|
||||||
_enter("");
|
_enter("");
|
||||||
|
|
||||||
as = sb->s_fs_info;
|
as = sb->s_fs_info;
|
||||||
if (as->volume) {
|
if (as->volume) {
|
||||||
data.volume = as->volume;
|
iget_data.volume = as->volume;
|
||||||
data.fid.vid = as->volume->vid;
|
iget_data.fid.vid = as->volume->vid;
|
||||||
}
|
}
|
||||||
if (root) {
|
if (root) {
|
||||||
data.fid.vnode = 1;
|
iget_data.fid.vnode = 1;
|
||||||
data.fid.unique = 1;
|
iget_data.fid.unique = 1;
|
||||||
} else {
|
} else {
|
||||||
data.fid.vnode = atomic_inc_return(&afs_autocell_ino);
|
iget_data.fid.vnode = atomic_inc_return(&afs_autocell_ino);
|
||||||
data.fid.unique = 0;
|
iget_data.fid.unique = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inode = iget5_locked(sb, data.fid.vnode,
|
inode = iget5_locked(sb, iget_data.fid.vnode,
|
||||||
afs_iget5_pseudo_dir_test, afs_iget5_set,
|
afs_iget5_pseudo_dir_test, afs_iget5_set,
|
||||||
&data);
|
&iget_data);
|
||||||
if (!inode) {
|
if (!inode) {
|
||||||
_leave(" = -ENOMEM");
|
_leave(" = -ENOMEM");
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
_debug("GOT INODE %p { ino=%lu, vl=%llx, vn=%llx, u=%x }",
|
_debug("GOT INODE %p { ino=%lu, vl=%llx, vn=%llx, u=%x }",
|
||||||
inode, inode->i_ino, data.fid.vid, data.fid.vnode,
|
inode, inode->i_ino, iget_data.fid.vid, iget_data.fid.vnode,
|
||||||
data.fid.unique);
|
iget_data.fid.unique);
|
||||||
|
|
||||||
vnode = AFS_FS_I(inode);
|
vnode = AFS_FS_I(inode);
|
||||||
|
|
||||||
|
@ -490,23 +496,24 @@ static void afs_get_inode_cache(struct afs_vnode *vnode)
|
||||||
* inode retrieval
|
* inode retrieval
|
||||||
*/
|
*/
|
||||||
struct inode *afs_iget(struct super_block *sb, struct key *key,
|
struct inode *afs_iget(struct super_block *sb, struct key *key,
|
||||||
struct afs_fid *fid, struct afs_status_cb *scb,
|
struct afs_iget_data *iget_data,
|
||||||
|
struct afs_status_cb *scb,
|
||||||
struct afs_cb_interest *cbi,
|
struct afs_cb_interest *cbi,
|
||||||
struct afs_vnode *parent_vnode)
|
struct afs_vnode *parent_vnode)
|
||||||
{
|
{
|
||||||
struct afs_iget_data data = { .fid = *fid };
|
|
||||||
struct afs_super_info *as;
|
struct afs_super_info *as;
|
||||||
struct afs_vnode *vnode;
|
struct afs_vnode *vnode;
|
||||||
|
struct afs_fid *fid = &iget_data->fid;
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_enter(",{%llx:%llu.%u},,", fid->vid, fid->vnode, fid->unique);
|
_enter(",{%llx:%llu.%u},,", fid->vid, fid->vnode, fid->unique);
|
||||||
|
|
||||||
as = sb->s_fs_info;
|
as = sb->s_fs_info;
|
||||||
data.volume = as->volume;
|
iget_data->volume = as->volume;
|
||||||
|
|
||||||
inode = iget5_locked(sb, fid->vnode, afs_iget5_test, afs_iget5_set,
|
inode = iget5_locked(sb, fid->vnode, afs_iget5_test, afs_iget5_set,
|
||||||
&data);
|
iget_data);
|
||||||
if (!inode) {
|
if (!inode) {
|
||||||
_leave(" = -ENOMEM");
|
_leave(" = -ENOMEM");
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
|
@ -66,6 +66,8 @@ struct afs_fs_context {
|
||||||
struct afs_iget_data {
|
struct afs_iget_data {
|
||||||
struct afs_fid fid;
|
struct afs_fid fid;
|
||||||
struct afs_volume *volume; /* volume on which resides */
|
struct afs_volume *volume; /* volume on which resides */
|
||||||
|
unsigned int cb_v_break; /* Pre-fetch volume break count */
|
||||||
|
unsigned int cb_s_break; /* Pre-fetch server break count */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum afs_call_state {
|
enum afs_call_state {
|
||||||
|
@ -1023,7 +1025,7 @@ extern int afs_fetch_status(struct afs_vnode *, struct key *, bool, afs_access_t
|
||||||
extern int afs_iget5_test(struct inode *, void *);
|
extern int afs_iget5_test(struct inode *, void *);
|
||||||
extern struct inode *afs_iget_pseudo_dir(struct super_block *, bool);
|
extern struct inode *afs_iget_pseudo_dir(struct super_block *, bool);
|
||||||
extern struct inode *afs_iget(struct super_block *, struct key *,
|
extern struct inode *afs_iget(struct super_block *, struct key *,
|
||||||
struct afs_fid *, struct afs_status_cb *,
|
struct afs_iget_data *, struct afs_status_cb *,
|
||||||
struct afs_cb_interest *,
|
struct afs_cb_interest *,
|
||||||
struct afs_vnode *);
|
struct afs_vnode *);
|
||||||
extern void afs_zap_data(struct afs_vnode *);
|
extern void afs_zap_data(struct afs_vnode *);
|
||||||
|
|
|
@ -426,7 +426,7 @@ static int afs_set_super(struct super_block *sb, struct fs_context *fc)
|
||||||
static int afs_fill_super(struct super_block *sb, struct afs_fs_context *ctx)
|
static int afs_fill_super(struct super_block *sb, struct afs_fs_context *ctx)
|
||||||
{
|
{
|
||||||
struct afs_super_info *as = AFS_FS_S(sb);
|
struct afs_super_info *as = AFS_FS_S(sb);
|
||||||
struct afs_fid fid;
|
struct afs_iget_data iget_data;
|
||||||
struct inode *inode = NULL;
|
struct inode *inode = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -451,11 +451,13 @@ static int afs_fill_super(struct super_block *sb, struct afs_fs_context *ctx)
|
||||||
} else {
|
} else {
|
||||||
sprintf(sb->s_id, "%llu", as->volume->vid);
|
sprintf(sb->s_id, "%llu", as->volume->vid);
|
||||||
afs_activate_volume(as->volume);
|
afs_activate_volume(as->volume);
|
||||||
fid.vid = as->volume->vid;
|
iget_data.fid.vid = as->volume->vid;
|
||||||
fid.vnode = 1;
|
iget_data.fid.vnode = 1;
|
||||||
fid.vnode_hi = 0;
|
iget_data.fid.vnode_hi = 0;
|
||||||
fid.unique = 1;
|
iget_data.fid.unique = 1;
|
||||||
inode = afs_iget(sb, ctx->key, &fid, NULL, NULL, NULL);
|
iget_data.cb_v_break = as->volume->cb_v_break;
|
||||||
|
iget_data.cb_s_break = 0;
|
||||||
|
inode = afs_iget(sb, ctx->key, &iget_data, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_ERR(inode))
|
if (IS_ERR(inode))
|
||||||
|
|
Loading…
Reference in New Issue