patch-2.1.81 linux/fs/smbfs/inode.c

Next file: linux/fs/smbfs/proc.c
Previous file: linux/fs/smbfs/file.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.80/linux/fs/smbfs/inode.c linux/fs/smbfs/inode.c
@@ -181,6 +181,59 @@
 }
 
 /*
+ * This is called to update the inode attributes after
+ * we've made changes to a file or directory.
+ */
+static int
+smb_refresh_inode(struct dentry *dentry)
+{
+	struct inode *inode = dentry->d_inode;
+	int error;
+	struct smb_fattr fattr;
+
+	error = smb_proc_getattr(dentry, &fattr);
+	if (!error)
+	{
+		smb_renew_times(dentry);
+		/*
+		 * Check whether the type part of the mode changed,
+		 * and don't update the attributes if it did.
+		 */
+		if ((inode->i_mode & S_IFMT) == (fattr.f_mode & S_IFMT))
+			smb_set_inode_attr(inode, &fattr);
+		else
+		{
+			/*
+			 * Big trouble! The inode has become a new object,
+			 * so any operations attempted on it are invalid.
+			 *
+			 * To limit damage, mark the inode as bad so that
+			 * subsequent lookup validations will fail.
+			 */
+#ifdef SMBFS_PARANOIA
+printk("smb_refresh_inode: %s/%s changed mode, %07o to %07o\n",
+dentry->d_parent->d_name.name, dentry->d_name.name,
+inode->i_mode, fattr.f_mode);
+#endif
+			fattr.f_mode = inode->i_mode; /* save mode */
+			make_bad_inode(inode);
+			inode->i_mode = fattr.f_mode; /* restore mode */
+			/*
+			 * No need to worry about unhashing the dentry: the
+			 * lookup validation will see that the inode is bad.
+			 * But we do want to invalidate the caches ...
+			 */
+			if (!S_ISDIR(inode->i_mode))
+				invalidate_inode_pages(inode);
+			else
+				smb_invalid_dir_cache(inode);
+			error = -EIO;
+		}
+	}
+	return error;
+}
+
+/*
  * This is called when we want to check whether the inode
  * has changed on the server.  If it has changed, we must
  * invalidate our local caches.
@@ -220,7 +273,7 @@
 	 * (Note: a size change should have a different mtime.)
 	 */
 	last_time = inode->i_mtime;
-	error = smb_refresh_inode(inode);
+	error = smb_refresh_inode(dentry);
 	if (error || inode->i_mtime != last_time)
 	{
 #ifdef SMBFS_DEBUG_VERBOSE
@@ -238,99 +291,15 @@
 }
 
 /*
- * This is called to update the inode attributes after
- * we've made changes to a file or directory.
- */
-int
-smb_refresh_inode(struct inode *inode)
-{
-	struct dentry * dentry = inode->u.smbfs_i.dentry;
-	struct smb_fattr fattr;
-	int error;
-
-	pr_debug("smb_refresh_inode\n");
-	if (!dentry)
-	{
-		printk("smb_refresh_inode: no dentry, can't refresh\n");
-		error = -EIO;
-		goto out;
-	}
-
-	error = smb_proc_getattr(dentry, &fattr);
-	if (!error)
-	{
-		smb_renew_times(dentry);
-		/*
-		 * Check whether the type part of the mode changed,
-		 * and don't update the attributes if it did.
-		 */
-		if ((inode->i_mode & S_IFMT) == (fattr.f_mode & S_IFMT))
-			smb_set_inode_attr(inode, &fattr);
-		else
-		{
-			/*
-			 * Big trouble! The inode has become a new object,
-			 * so any operations attempted on it are invalid.
-			 *
-			 * To limit damage, mark the inode as bad so that
-			 * subsequent lookup validations will fail.
-			 */
-#ifdef SMBFS_PARANOIA
-printk("smb_refresh_inode: %s/%s changed mode, %07o to %07o\n",
-dentry->d_parent->d_name.name, dentry->d_name.name,
-inode->i_mode, fattr.f_mode);
-#endif
-			fattr.f_mode = inode->i_mode; /* save mode */
-			make_bad_inode(inode);
-			inode->i_mode = fattr.f_mode; /* restore mode */
-			/*
-			 * No need to worry about unhashing the dentry: the
-			 * lookup validation will see that the inode is bad.
-			 * But we do want to invalidate the caches ...
-			 */
-			if (!S_ISDIR(inode->i_mode))
-				invalidate_inode_pages(inode);
-			else
-				smb_invalid_dir_cache(inode);
-			error = -EIO;
-		}
-	}
-out:
-	return error;
-
-}
-
-/*
- * This routine is called for every iput().
+ * This routine is called for every iput(). We clear i_nlink
+ * on the last use to force a call to delete_inode.
  */
 static void
 smb_put_inode(struct inode *ino)
 {
 	pr_debug("smb_put_inode: count = %d\n", ino->i_count);
-
-	if (ino->i_count > 1) {
-		struct dentry * dentry;
-		/*
-		 * Check whether the dentry still holds this inode. 
-		 * This looks scary, but should work ... if this is
-		 * the last use, d_inode == NULL or d_count == 0. 
-		 */
-		dentry = (struct dentry *) ino->u.smbfs_i.dentry;
-		if (dentry && (dentry->d_inode != ino || dentry->d_count == 0))
-		{
-			ino->u.smbfs_i.dentry = NULL;
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_put_inode: cleared dentry for %s/%s (%ld), count=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, ino->i_ino, ino->i_count);
-#endif
-		}
-	} else {
-		/*
-		 * Last use ... clear i_nlink to force
-		 * smb_delete_inode to be called.
-	 	*/
+	if (ino->i_count == 1)
 		ino->i_nlink = 0;
-	}
 }
 
 /*
@@ -379,7 +348,6 @@
 {
 	struct smb_mount_data *mnt;
 	struct inode *root_inode;
-	struct dentry *dentry;
 	struct smb_fattr root;
 
 	MOD_INC_USE_COUNT;
@@ -435,6 +403,8 @@
 		printk("SMBFS: Win 95 bug fixes enabled\n");
 	if (mnt->version & SMB_FIX_OLDATTR)
 		printk("SMBFS: Using core getattr (Win 95 speedup)\n");
+	else if (mnt->version & SMB_FIX_DIRATTR)
+		printk("SMBFS: Using dir ff getattr\n");
 
 	/*
 	 * Keep the super block locked while we get the root inode.
@@ -444,11 +414,9 @@
 	if (!root_inode)
 		goto out_no_root;
 
-	dentry = d_alloc_root(root_inode, NULL);
-	if (!dentry)
+	sb->s_root = d_alloc_root(root_inode, NULL);
+	if (!sb->s_root)
 		goto out_no_root;
-	root_inode->u.smbfs_i.dentry = dentry;
-	sb->s_root = dentry;
 
 	unlock_super(sb);
 	return sb;
@@ -465,7 +433,7 @@
 	unlock_super(sb);
 	goto out_fail;
 out_wrong_data:
-	printk("smb_read_super: need mount version %d\n", SMB_MOUNT_VERSION);
+	printk(KERN_ERR "SMBFS: need mount version %d\n", SMB_MOUNT_VERSION);
 	goto out_fail;
 out_no_data:
 	printk("smb_read_super: missing data argument\n");
@@ -609,7 +577,7 @@
 
 out:
 	if (refresh)
-		smb_refresh_inode(inode);
+		smb_refresh_inode(dentry);
 	return error;
 }
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov