summaryrefslogtreecommitdiffstats
path: root/fs/coda/cnode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/coda/cnode.c')
-rw-r--r--fs/coda/cnode.c100
1 files changed, 52 insertions, 48 deletions
diff --git a/fs/coda/cnode.c b/fs/coda/cnode.c
index 47f853c14..7c5544612 100644
--- a/fs/coda/cnode.c
+++ b/fs/coda/cnode.c
@@ -50,6 +50,7 @@ static void coda_fill_inode(struct inode *inode, struct coda_vattr *attr)
} else if (S_ISLNK(inode->i_mode)) {
inode->i_op = &coda_symlink_inode_operations;
inode->i_data.a_ops = &coda_symlink_aops;
+ inode->i_mapping = &inode->i_data;
} else
init_special_inode(inode, inode->i_mode, attr->va_rdev);
}
@@ -65,13 +66,25 @@ struct inode * coda_iget(struct super_block * sb, ViceFid * fid,
inode = iget(sb, ino);
if ( !inode ) {
CDEBUG(D_CNODE, "coda_iget: no inode\n");
- return NULL;
+ return ERR_PTR(-ENOMEM);
}
/* check if the inode is already initialized */
cii = ITOC(inode);
- if (cii->c_magic == CODA_CNODE_MAGIC)
+ if (cii->c_magic == CODA_CNODE_MAGIC) {
+ /* see if it is the right one (might have an inode collision) */
+ if ( !coda_fideq(fid, &cii->c_fid) ) {
+ printk("coda_iget: initialized inode old %s new %s!\n",
+ coda_f2s(&cii->c_fid), coda_f2s2(fid));
+ iput(inode);
+ return ERR_PTR(-ENOENT);
+ }
+ /* replace the attributes, type might have changed */
+ coda_fill_inode(inode, attr);
goto out;
+ }
+
+ /* new, empty inode found... initializing */
/* Initialize the Coda inode info structure */
memset(cii, 0, (int) sizeof(struct coda_inode_info));
@@ -90,15 +103,17 @@ struct inode * coda_iget(struct super_block * sb, ViceFid * fid,
if ( coda_f2i(fid) == ino )
goto out;
- /* check if we expect this weird fid */
- if ( !coda_fid_is_weird(fid) )
+ /* check if we expected this weird fid */
+ if ( !coda_fid_is_weird(fid) ) {
printk("Coda: unknown weird fid: ino %ld, fid %s."
"Tell Peter.\n", (long)ino, coda_f2s(&cii->c_fid));
+ goto out;
+ }
/* add the inode to a global list so we can find it back later */
list_add(&cii->c_volrootlist, &sbi->sbi_volroothead);
CDEBUG(D_CNODE, "Added %ld, %s to volroothead\n",
- (long)ino, coda_f2s(&cii->c_fid));
+ (long)ino, coda_f2s(&cii->c_fid));
out:
return inode;
}
@@ -111,7 +126,6 @@ out:
*/
int coda_cnode_make(struct inode **inode, ViceFid *fid, struct super_block *sb)
{
- struct coda_inode_info *cnp;
struct coda_vattr attr;
int error;
@@ -125,32 +139,22 @@ int coda_cnode_make(struct inode **inode, ViceFid *fid, struct super_block *sb)
"coda_cnode_make: coda_getvattr returned %d for %s.\n",
error, coda_f2s(fid));
*inode = NULL;
+ EXIT;
return error;
}
*inode = coda_iget(sb, fid, &attr);
- if ( !(*inode) ) {
+ if ( IS_ERR(*inode) ) {
printk("coda_cnode_make: coda_iget failed\n");
- return -ENOMEM;
- }
-
- cnp = ITOC(*inode);
- /* see if it is the right one (we might have an inode collision) */
- if ( coda_fideq(fid, &cnp->c_fid) ) {
- CDEBUG(D_DOWNCALL,
- "Done making inode: ino %ld, count %d with %s\n",
- (*inode)->i_ino, (*inode)->i_count,
- coda_f2s(&cnp->c_fid));
EXIT;
- return 0;
- }
+ return PTR_ERR(*inode);
+ }
- /* collision */
- printk("coda_cnode_make on initialized inode %ld, old %s new %s!\n",
- (*inode)->i_ino, coda_f2s(&cnp->c_fid), coda_f2s2(fid));
- iput(*inode);
+ CDEBUG(D_DOWNCALL, "Done making inode: ino %ld, count %d with %s\n",
+ (*inode)->i_ino, atomic_read(&(*inode)->i_count),
+ coda_f2s(&(*inode)->u.coda_i.c_fid));
EXIT;
- return -ENOENT;
+ return 0;
}
@@ -168,7 +172,8 @@ void coda_replace_fid(struct inode *inode, struct ViceFid *oldfid,
cnp->c_fid = *newfid;
list_del(&cnp->c_volrootlist);
- if ( !coda_fid_is_weird(newfid) )
+ INIT_LIST_HEAD(&cnp->c_volrootlist);
+ if ( coda_fid_is_weird(newfid) )
list_add(&cnp->c_volrootlist, &sbi->sbi_volroothead);
return;
@@ -184,10 +189,9 @@ struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb)
{
ino_t nr;
struct inode *inode;
- struct coda_inode_info *cnp;
+ struct coda_inode_info *cii;
ENTRY;
-
if ( !sb ) {
printk("coda_fid_to_inode: no sb!\n");
return NULL;
@@ -201,7 +205,6 @@ struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb)
if ( coda_fid_is_weird(fid) ) {
- struct coda_inode_info *cii;
struct list_head *lh, *le;
struct coda_sb_info *sbi = coda_sbp(sb);
le = lh = &sbi->sbi_volroothead;
@@ -209,19 +212,19 @@ struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb)
while ( (le = le->next) != lh ) {
cii = list_entry(le, struct coda_inode_info,
c_volrootlist);
- CDEBUG(D_DOWNCALL, "iterating, now doing %s, ino %ld\n",
+ /* paranoia check, should never trigger */
+ if ( cii->c_magic != CODA_CNODE_MAGIC )
+ printk("coda_fid_to_inode: Bad magic in inode %x.\n", cii->c_magic);
+
+ CDEBUG(D_DOWNCALL, "iterating, now doing %s, ino %ld\n",
coda_f2s(&cii->c_fid), cii->c_vnode->i_ino);
+
if ( coda_fideq(&cii->c_fid, fid) ) {
inode = cii->c_vnode;
CDEBUG(D_INODE, "volume root, found %ld\n", inode->i_ino);
- if ( cii->c_magic != CODA_CNODE_MAGIC )
- printk("%s: Bad magic in inode, tell Peter.\n",
- __FUNCTION__);
-
iget(sb, inode->i_ino);
return inode;
}
-
}
return NULL;
}
@@ -236,27 +239,27 @@ struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb)
}
/* check if this inode is linked to a cnode */
- cnp = ITOC(inode);
- if ( cnp->c_magic != CODA_CNODE_MAGIC ) {
+ cii = ITOC(inode);
+ if ( cii->c_magic != CODA_CNODE_MAGIC ) {
CDEBUG(D_INODE, "uninitialized inode. Return.\n");
- iput(inode);
- return NULL;
+ goto bad_inode;
}
- /* make sure fid is the one we want;
- unfortunately Venus will shamelessly send us mount-symlinks.
- These have the same inode as the root of the volume they
- mount, but the fid will be wrong.
- */
- if ( !coda_fideq(fid, &(cnp->c_fid)) ) {
- /* printk("coda_fid2inode: bad cnode (ino %ld, fid %s)"
- "Tell Peter.\n", nr, coda_f2s(fid)); */
- iput(inode);
- return NULL;
+ /* make sure fid is the one we want */
+ if ( !coda_fideq(fid, &(cii->c_fid)) ) {
+#if 0
+ printk("coda_fid2inode: bad cnode (ino %ld, fid %s)", nr,
+ coda_f2s(fid));
+#endif
+ goto bad_inode;
}
CDEBUG(D_INODE, "found %ld\n", inode->i_ino);
return inode;
+
+bad_inode:
+ iput(inode);
+ return NULL;
}
/* the CONTROL inode is made without asking attributes from Venus */
@@ -276,3 +279,4 @@ int coda_cnode_makectl(struct inode **inode, struct super_block *sb)
return error;
}
+