patch-2.4.0-test2 linux/fs/coda/cnode.c

Next file: linux/fs/coda/dir.c
Previous file: linux/fs/coda/cache.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test1/linux/fs/coda/cnode.c linux/fs/coda/cnode.c
@@ -50,6 +50,7 @@
         } 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 @@
 	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 @@
 	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 @@
 */
 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 @@
 		   "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 @@
 	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 @@
 {
 	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 @@
 
 
 	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 @@
 		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 @@
 	}
 
 	/* 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 @@
     
     return error;
 }
+

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)