.listxattr = afs_listxattr,
};
+static noinline void dump_vnode(struct afs_vnode *vnode, struct afs_vnode *parent_vnode)
+{
+ static unsigned long once_only;
+
+ pr_warn("kAFS: AFS vnode with undefined type %u\n",
+ vnode->status.type);
+ pr_warn("kAFS: A=%d m=%o s=%llx v=%llx\n",
+ vnode->status.abort_code,
+ vnode->status.mode,
+ vnode->status.size,
+ vnode->status.data_version);
+ pr_warn("kAFS: vnode %llx:%llx:%x\n",
+ vnode->fid.vid,
+ vnode->fid.vnode,
+ vnode->fid.unique);
+ if (parent_vnode)
+ pr_warn("kAFS: dir %llx:%llx:%x\n",
+ parent_vnode->fid.vid,
+ parent_vnode->fid.vnode,
+ parent_vnode->fid.unique);
+
+ if (!test_and_set_bit(0, &once_only))
+ dump_stack();
+}
+
/*
* Initialise an inode from the vnode status.
*/
-static int afs_inode_init_from_status(struct afs_vnode *vnode, struct key *key)
+static int afs_inode_init_from_status(struct afs_vnode *vnode, struct key *key,
+ struct afs_vnode *parent_vnode)
{
struct inode *inode = AFS_VNODE_TO_I(vnode);
inode_nohighmem(inode);
break;
default:
- printk("kAFS: AFS vnode with undefined type\n");
+ dump_vnode(vnode, parent_vnode);
read_sequnlock_excl(&vnode->cb_lock);
return afs_protocol_error(NULL, -EBADMSG, afs_eproto_file_type);
}
- inode->i_blocks = 0;
+ /*
+ * Estimate 512 bytes blocks used, rounded up to nearest 1K
+ * for consistency with other AFS clients.
+ */
+ inode->i_blocks = ((i_size_read(inode) + 1023) >> 10) << 1;
vnode->invalid_before = vnode->status.data_version;
read_sequnlock_excl(&vnode->cb_lock);
vnode->flags);
ret = -ERESTARTSYS;
- if (afs_begin_vnode_operation(&fc, vnode, key)) {
+ if (afs_begin_vnode_operation(&fc, vnode, key, true)) {
while (afs_select_fileserver(&fc)) {
fc.cb_break = afs_calc_vnode_cb_break(vnode);
afs_fs_fetch_file_status(&fc, NULL, new_inode);
*/
struct inode *afs_iget(struct super_block *sb, struct key *key,
struct afs_fid *fid, struct afs_file_status *status,
- struct afs_callback *cb, struct afs_cb_interest *cbi)
+ struct afs_callback *cb, struct afs_cb_interest *cbi,
+ struct afs_vnode *parent_vnode)
{
struct afs_iget_data data = { .fid = *fid };
struct afs_super_info *as;
vnode->cb_expires_at += ktime_get_real_seconds();
}
- ret = afs_inode_init_from_status(vnode, key);
+ ret = afs_inode_init_from_status(vnode, key, parent_vnode);
if (ret < 0)
goto bad_inode;
vnode->cb_s_break = vnode->cb_interest->server->cb_s_break;
vnode->cb_v_break = vnode->volume->cb_v_break;
valid = false;
- } else if (vnode->status.type == AFS_FTYPE_DIR &&
- (!test_bit(AFS_VNODE_DIR_VALID, &vnode->flags) ||
- vnode->cb_expires_at - 10 <= now)) {
+ } else if (test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) {
valid = false;
- } else if (test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags) ||
- vnode->cb_expires_at - 10 <= now) {
+ } else if (vnode->cb_expires_at - 10 <= now) {
valid = false;
} else {
valid = true;
}
#endif
+ afs_prune_wb_keys(vnode);
afs_put_permits(rcu_access_pointer(vnode->permit_cache));
+ key_put(vnode->silly_key);
+ vnode->silly_key = NULL;
key_put(vnode->lock_key);
vnode->lock_key = NULL;
_leave("");
}
ret = -ERESTARTSYS;
- if (afs_begin_vnode_operation(&fc, vnode, key)) {
+ if (afs_begin_vnode_operation(&fc, vnode, key, false)) {
while (afs_select_fileserver(&fc)) {
fc.cb_break = afs_calc_vnode_cb_break(vnode);
afs_fs_setattr(&fc, attr);