changeset 320:37b5b3fda7c0

Revert readdir locking fix that doesn't work properly
author charles <charles>
date Sun, 29 Nov 2009 21:42:47 +0000
parents b22d1f927037
children be04ef15b604
files yaffs_fs.c yaffs_guts.h
diffstat 2 files changed, 23 insertions(+), 131 deletions(-) [+]
line wrap: on
line diff
--- a/yaffs_fs.c
+++ b/yaffs_fs.c
@@ -32,7 +32,7 @@
  */
 
 const char *yaffs_fs_c_version =
-    "$Id: yaffs_fs.c,v 1.87 2009-11-11 02:11:13 charles Exp $";
+    "$Id: yaffs_fs.c,v 1.88 2009-11-29 21:42:47 charles Exp $";
 extern const char *yaffs_guts_c_version;
 
 #include <linux/version.h>
@@ -365,54 +365,6 @@ static const struct super_operations yaf
 	.write_super = yaffs_write_super,
 };
 
-/* YAFFS uses two locks per yaffs_Device.
- * dirLock: r/w lock Must be held when accessing directory structure.
- * grossLock: Lock when accessing yaffs internals.
- *
- * Locking rules:
- *  If you're going to take dirLock then you must take if before
- *  taking grossLock.
- *  ie. Don't call yaffs_DirLockxxx()  while holding grossLock.
- *
- * Todo:
- *   Investigate changing to mutexes etc and improve debugging.
- */
-static void yaffs_DirLockInitialise(yaffs_Device *dev)
-{
-	init_rwsem(&dev->dirLock);
-}
-
-static void yaffs_DirLockRead(yaffs_Device *dev)
-{
-	T(YAFFS_TRACE_OS, ("yaffs locking dir read %p\n", current));
-	down_read(&dev->dirLock);
-	T(YAFFS_TRACE_OS, ("yaffs locked dir read %p\n", current));
-}
-
-static void yaffs_DirUnlockRead(yaffs_Device *dev)
-{
-	T(YAFFS_TRACE_OS, ("yaffs unlocking dir read %p\n", current));
-	up_read(&dev->dirLock);
-}
-
-static void yaffs_DirLockWrite(yaffs_Device *dev)
-{
-	T(YAFFS_TRACE_OS, ("yaffs locking dir write %p\n", current));
-	down_write(&dev->dirLock);
-	T(YAFFS_TRACE_OS, ("yaffs locked dir write %p\n", current));
-}
-
-static void yaffs_DirUnlockWrite(yaffs_Device *dev)
-{
-	T(YAFFS_TRACE_OS, ("yaffs unlocking dir write %p\n", current));
-	up_write(&dev->dirLock);
-}
-
-static void yaffs_GrossLockInitialise(yaffs_Device *dev)
-{
-	init_MUTEX(&dev->grossLock);
-}
-
 static void yaffs_GrossLock(yaffs_Device *dev)
 {
 	T(YAFFS_TRACE_OS, ("yaffs locking %p\n", current));
@@ -426,7 +378,6 @@ static void yaffs_GrossUnlock(yaffs_Devi
 	up(&dev->grossLock);
 }
 
-
 static int yaffs_readlink(struct dentry *dentry, char __user *buffer,
 			int buflen)
 {
@@ -434,14 +385,12 @@ static int yaffs_readlink(struct dentry 
 	int ret;
 
 	yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev;
-	
-	yaffs_DirLockRead(dev);
+
 	yaffs_GrossLock(dev);
 
 	alias = yaffs_GetSymlinkAlias(yaffs_DentryToObject(dentry));
 
 	yaffs_GrossUnlock(dev);
-	yaffs_DirUnlockRead(dev);
 
 	if (!alias)
 		return -ENOMEM;
@@ -461,13 +410,11 @@ static int yaffs_follow_link(struct dent
 	int ret;
 	yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev;
 
-	yaffs_DirLockRead(dev);
 	yaffs_GrossLock(dev);
 
 	alias = yaffs_GetSymlinkAlias(yaffs_DentryToObject(dentry));
 
 	yaffs_GrossUnlock(dev);
-	yaffs_DirUnlockRead(dev);
 
 	if (!alias) {
 		ret = -ENOMEM;
@@ -503,7 +450,6 @@ static struct dentry *yaffs_lookup(struc
 
 	yaffs_Device *dev = yaffs_InodeToObject(dir)->myDev;
 
-	yaffs_DirLockRead(dev);
 	yaffs_GrossLock(dev);
 
 	T(YAFFS_TRACE_OS,
@@ -517,7 +463,6 @@ static struct dentry *yaffs_lookup(struc
 
 	/* Can't hold gross lock when calling yaffs_get_inode() */
 	yaffs_GrossUnlock(dev);
-	yaffs_DirUnlockRead(dev);
 
 	if (obj) {
 		T(YAFFS_TRACE_OS,
@@ -581,7 +526,6 @@ static void yaffs_clear_inode(struct ino
 
 	if (obj) {
 		dev = obj->myDev;
-		yaffs_DirLockRead(dev);
 		yaffs_GrossLock(dev);
 
 		/* Clear the association between the inode and
@@ -598,7 +542,6 @@ static void yaffs_clear_inode(struct ino
 		yaffs_HandleDeferedFree(obj);
 
 		yaffs_GrossUnlock(dev);
-		yaffs_DirUnlockRead(dev);
 	}
 
 }
@@ -620,11 +563,9 @@ static void yaffs_delete_inode(struct in
 
 	if (obj) {
 		dev = obj->myDev;
-		yaffs_DirLockWrite(dev);
 		yaffs_GrossLock(dev);
 		yaffs_DeleteObject(obj);
 		yaffs_GrossUnlock(dev);
-		yaffs_DirUnlockWrite(dev);
 	}
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
 	truncate_inode_pages(&inode->i_data, 0);
@@ -646,13 +587,11 @@ static int yaffs_file_flush(struct file 
 		("yaffs_file_flush object %d (%s)\n", obj->objectId,
 		obj->dirty ? "dirty" : "clean"));
 
-	yaffs_DirLockRead(dev);
 	yaffs_GrossLock(dev);
 
 	yaffs_FlushFile(obj, 1,0);
 
 	yaffs_GrossUnlock(dev);
-	yaffs_DirUnlockRead(dev);
 
 	return 0;
 }
@@ -685,7 +624,6 @@ static int yaffs_readpage_nolock(struct 
 	pg_buf = kmap(pg);
 	/* FIXME: Can kmap fail? */
 
-	yaffs_DirLockRead(dev);
 	yaffs_GrossLock(dev);
 
 	ret = yaffs_ReadDataFromFile(obj, pg_buf,
@@ -693,7 +631,6 @@ static int yaffs_readpage_nolock(struct 
 				PAGE_CACHE_SIZE);
 
 	yaffs_GrossUnlock(dev);
-	yaffs_DirUnlockRead(dev);
 
 	if (ret >= 0)
 		ret = 0;
@@ -772,7 +709,6 @@ static int yaffs_writepage(struct page *
 	buffer = kmap(page);
 
 	obj = yaffs_InodeToObject(inode);
-	yaffs_DirLockRead(obj->myDev);
 	yaffs_GrossLock(obj->myDev);
 
 	T(YAFFS_TRACE_OS,
@@ -790,7 +726,6 @@ static int yaffs_writepage(struct page *
 		(int)obj->variant.fileVariant.fileSize, (int)inode->i_size));
 
 	yaffs_GrossUnlock(obj->myDev);
-	yaffs_DirUnlockRead(obj->myDev);
 
 	kunmap(page);
 	SetPageUptodate(page);
@@ -1106,7 +1041,6 @@ static ssize_t yaffs_file_write(struct f
 
 	dev = obj->myDev;
 
-	yaffs_DirLockRead(dev);
 	yaffs_GrossLock(dev);
 
 	inode = f->f_dentry->d_inode;
@@ -1146,8 +1080,6 @@ static ssize_t yaffs_file_write(struct f
 
 	}
 	yaffs_GrossUnlock(dev);
-	yaffs_DirUnlockRead(dev);
-
 	return (nWritten == 0) && (n > 0) ? -ENOSPC : nWritten;
 }
 
@@ -1167,19 +1099,29 @@ static ssize_t yaffs_hold_space(struct f
 
 	dev = obj->myDev;
 
-	yaffs_DirLockRead(dev);
 	yaffs_GrossLock(dev);
 
 	nFreeChunks = yaffs_GetNumberOfFreeChunks(dev);
 
 	yaffs_GrossUnlock(dev);
-	yaffs_DirUnlockRead(dev);
 
 	return (nFreeChunks > 20) ? 1 : 0;
 }
 
 static void yaffs_release_space(struct file *f)
 {
+	yaffs_Object *obj;
+	yaffs_Device *dev;
+
+
+	obj = yaffs_DentryToObject(f->f_dentry);
+
+	dev = obj->myDev;
+
+	yaffs_GrossLock(dev);
+
+
+	yaffs_GrossUnlock(dev);
 }
 
 static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
@@ -1196,7 +1138,6 @@ static int yaffs_readdir(struct file *f,
 	obj = yaffs_DentryToObject(f->f_dentry);
 	dev = obj->myDev;
 
-	yaffs_DirLockRead(dev);
 	yaffs_GrossLock(dev);
 
 	offset = f->f_pos;
@@ -1207,14 +1148,8 @@ static int yaffs_readdir(struct file *f,
 		T(YAFFS_TRACE_OS,
 			("yaffs_readdir: entry . ino %d \n",
 			(int)inode->i_ino));
-
-		yaffs_GrossUnlock(dev);
-		
 		if (filldir(dirent, ".", 1, offset, inode->i_ino, DT_DIR) < 0)
 			goto out;
-
-		yaffs_GrossLock(dev);
-
 		offset++;
 		f->f_pos++;
 	}
@@ -1222,15 +1157,9 @@ static int yaffs_readdir(struct file *f,
 		T(YAFFS_TRACE_OS,
 			("yaffs_readdir: entry .. ino %d \n",
 			(int)f->f_dentry->d_parent->d_inode->i_ino));
-
-		yaffs_GrossUnlock(dev);
-
 		if (filldir(dirent, "..", 2, offset,
 			f->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0)
 			goto out;
-
-		yaffs_GrossLock(dev);
-
 		offset++;
 		f->f_pos++;
 	}
@@ -1257,26 +1186,22 @@ static int yaffs_readdir(struct file *f,
 			  ("yaffs_readdir: %s inode %d\n", name,
 			   yaffs_GetObjectInode(l)));
 
-			yaffs_GrossUnlock(dev);
-
 			if (filldir(dirent,
 					name,
 					strlen(name),
 					offset,
 					yaffs_GetObjectInode(l),
 					yaffs_GetObjectType(l)) < 0)
-				goto out;
-
-			yaffs_GrossLock(dev);
+				goto up_and_out;
 
 			offset++;
 			f->f_pos++;
 		}
 	}
 
-	yaffs_GrossUnlock(dev);
+up_and_out:
 out:
-	yaffs_DirUnlockRead(dev);
+	yaffs_GrossUnlock(dev);
 
 	return 0;
 }
@@ -1329,7 +1254,6 @@ static int yaffs_mknod(struct inode *dir
 
 	dev = parent->myDev;
 
-	yaffs_DirLockWrite(dev);
 	yaffs_GrossLock(dev);
 
 	switch (mode & S_IFMT) {
@@ -1363,7 +1287,6 @@ static int yaffs_mknod(struct inode *dir
 
 	/* Can not call yaffs_get_inode() with gross lock held */
 	yaffs_GrossUnlock(dev);
-	yaffs_DirUnlockWrite(dev);
 
 	if (obj) {
 		inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj);
@@ -1413,7 +1336,6 @@ static int yaffs_unlink(struct inode *di
 
 	dev = yaffs_InodeToObject(dir)->myDev;
 
-	yaffs_DirLockWrite(dev); 
 	yaffs_GrossLock(dev);
 
 	retVal = yaffs_Unlink(yaffs_InodeToObject(dir), dentry->d_name.name);
@@ -1421,17 +1343,12 @@ static int yaffs_unlink(struct inode *di
 	if (retVal == YAFFS_OK) {
 		dentry->d_inode->i_nlink--;
 		dir->i_version++;
-	}
-
-	yaffs_GrossUnlock(dev);
-	yaffs_DirUnlockWrite(dev);
-
-	if( retVal == YAFFS_OK){
+		yaffs_GrossUnlock(dev);
 		mark_inode_dirty(dentry->d_inode);
 		update_dir_time(dir);
 		return 0;
 	}
-
+	yaffs_GrossUnlock(dev);
 	return -ENOTEMPTY;
 }
 
@@ -1451,7 +1368,6 @@ static int yaffs_link(struct dentry *old
 	obj = yaffs_InodeToObject(inode);
 	dev = obj->myDev;
 
-	yaffs_DirLockWrite(dev);
 	yaffs_GrossLock(dev);
 
 	if (!S_ISDIR(inode->i_mode))		/* Don't link directories */
@@ -1469,7 +1385,6 @@ static int yaffs_link(struct dentry *old
 	}
 
 	yaffs_GrossUnlock(dev);
-	yaffs_DirUnlockWrite(dev);
 
 	if (link){
 		update_dir_time(dir);
@@ -1490,12 +1405,10 @@ static int yaffs_symlink(struct inode *d
 	T(YAFFS_TRACE_OS, ("yaffs_symlink\n"));
 
 	dev = yaffs_InodeToObject(dir)->myDev;
-	yaffs_DirLockWrite(dev);
 	yaffs_GrossLock(dev);
 	obj = yaffs_MknodSymLink(yaffs_InodeToObject(dir), dentry->d_name.name,
 				S_IFLNK | S_IRWXUGO, uid, gid, symname);
 	yaffs_GrossUnlock(dev);
-	yaffs_DirUnlockWrite(dev);
 
 	if (obj) {
 		struct inode *inode;
@@ -1524,11 +1437,9 @@ static int yaffs_sync_object(struct file
 	dev = obj->myDev;
 
 	T(YAFFS_TRACE_OS, ("yaffs_sync_object\n"));
-	yaffs_DirLockRead(dev);
 	yaffs_GrossLock(dev);
 	yaffs_FlushFile(obj, 1, datasync);
 	yaffs_GrossUnlock(dev);
-	yaffs_DirUnlockRead(dev);
 	return 0;
 }
 
@@ -1547,7 +1458,6 @@ static int yaffs_rename(struct inode *ol
 	T(YAFFS_TRACE_OS, ("yaffs_rename\n"));
 	dev = yaffs_InodeToObject(old_dir)->myDev;
 
-	yaffs_DirLockWrite(dev);
 	yaffs_GrossLock(dev);
 
 	/* Check if the target is an existing directory that is not empty. */
@@ -1572,7 +1482,6 @@ static int yaffs_rename(struct inode *ol
 				new_dentry->d_name.name);
 	}
 	yaffs_GrossUnlock(dev);
-	yaffs_DirUnlockWrite(dev);
 
 	if (retVal == YAFFS_OK) {
 		if (target) {
@@ -1602,7 +1511,6 @@ static int yaffs_setattr(struct dentry *
 	error = inode_change_ok(inode, attr);
 	if (error == 0) {
 		dev = yaffs_InodeToObject(inode)->myDev;
-		yaffs_DirLockRead(dev);
 		yaffs_GrossLock(dev);
 		if (yaffs_SetAttributes(yaffs_InodeToObject(inode), attr) ==
 				YAFFS_OK) {
@@ -1611,7 +1519,6 @@ static int yaffs_setattr(struct dentry *
 			error = -EPERM;
 		}
 		yaffs_GrossUnlock(dev);
-		yaffs_DirUnlockRead(dev);
 		if (!error)
 			error = inode_setattr(inode, attr);
 	}
@@ -1635,7 +1542,6 @@ static int yaffs_statfs(struct super_blo
 
 	T(YAFFS_TRACE_OS, ("yaffs_statfs\n"));
 
-	yaffs_DirLockRead(dev);
 	yaffs_GrossLock(dev);
 
 	buf->f_type = YAFFS_MAGIC;
@@ -1686,7 +1592,6 @@ static int yaffs_statfs(struct super_blo
 	buf->f_bavail = buf->f_bfree;
 
 	yaffs_GrossUnlock(dev);
-	yaffs_DirUnlockRead(dev);
 	return 0;
 }
 
@@ -1713,7 +1618,6 @@ static int yaffs_do_sync_fs(struct super
 	T(YAFFS_TRACE_OS, ("yaffs_do_sync_fs\n"));
 
 	if (sb->s_dirt) {
-		yaffs_DirLockRead(dev);
 		yaffs_GrossLock(dev);
 
 		if (dev) {
@@ -1723,7 +1627,6 @@ static int yaffs_do_sync_fs(struct super
 		}
 
 		yaffs_GrossUnlock(dev);
-		yaffs_DirUnlockRead(dev);
 
 		sb->s_dirt = 0;
 	}
@@ -1783,7 +1686,6 @@ static struct inode *yaffs_iget(struct s
 	 * need to lock again.
 	 */
 
-	yaffs_DirLockRead(dev);
 	yaffs_GrossLock(dev);
 
 	obj = yaffs_FindObjectByNumber(dev, inode->i_ino);
@@ -1791,7 +1693,6 @@ static struct inode *yaffs_iget(struct s
 	yaffs_FillInodeFromObject(inode, obj);
 
 	yaffs_GrossUnlock(dev);
-	yaffs_DirUnlockRead(dev);
 
 	unlock_new_inode(inode);
 	return inode;
@@ -1812,7 +1713,6 @@ static void yaffs_read_inode(struct inod
 	T(YAFFS_TRACE_OS,
 		("yaffs_read_inode for %d\n", (int)inode->i_ino));
 
-	yaffs_DirLockRead(dev);
 	yaffs_GrossLock(dev);
 
 	obj = yaffs_FindObjectByNumber(dev, inode->i_ino);
@@ -1820,7 +1720,6 @@ static void yaffs_read_inode(struct inod
 	yaffs_FillInodeFromObject(inode, obj);
 
 	yaffs_GrossUnlock(dev);
-	yaffs_DirUnlockRead(dev);
 }
 
 #endif
@@ -1837,7 +1736,7 @@ static int yaffs_remount_fs(struct super
 
 		T(YAFFS_TRACE_OS,
 			("yaffs_remount_fs: %s: RO\n", dev->name));
-		yaffs_DirLockWrite(dev);
+
 		yaffs_GrossLock(dev);
 
 		yaffs_FlushEntireDeviceCache(dev);
@@ -1848,7 +1747,6 @@ static int yaffs_remount_fs(struct super
 			mtd->sync(mtd);
 
 		yaffs_GrossUnlock(dev);
-		yaffs_DirUnlockWrite(dev);
 	} else {
 		T(YAFFS_TRACE_OS,
 			("yaffs_remount_fs: %s: RW\n", dev->name));
@@ -1864,7 +1762,6 @@ static void yaffs_put_super(struct super
 
 	T(YAFFS_TRACE_OS, ("yaffs_put_super\n"));
 
-	yaffs_DirLockWrite(dev);
 	yaffs_GrossLock(dev);
 
 	yaffs_FlushEntireDeviceCache(dev);
@@ -1877,7 +1774,6 @@ static void yaffs_put_super(struct super
 	yaffs_Deinitialise(dev);
 
 	yaffs_GrossUnlock(dev);
-	yaffs_DirUnlockWrite(dev);
 
 	/* we assume this is protected by lock_kernel() in mount/umount */
 	ylist_del(&dev->devList);
@@ -2261,11 +2157,9 @@ static struct super_block *yaffs_interna
 
 	/* we assume this is protected by lock_kernel() in mount/umount */
 	ylist_add_tail(&dev->devList, &yaffs_dev_list);
-	
-	yaffs_DirLockInitialise(dev);
-	yaffs_GrossLockInitialise(dev);
-
-	yaffs_DirLockWrite(dev);
+
+	init_MUTEX(&dev->grossLock);
+
 	yaffs_GrossLock(dev);
 
 	err = yaffs_GutsInitialise(dev);
@@ -2276,7 +2170,6 @@ static struct super_block *yaffs_interna
 
 	/* Release lock before yaffs_get_inode() */
 	yaffs_GrossUnlock(dev);
-	yaffs_DirUnlockWrite(dev);
 
 	/* Create root inode */
 	if (err == YAFFS_OK)
--- a/yaffs_guts.h
+++ b/yaffs_guts.h
@@ -640,7 +640,6 @@ struct yaffs_DeviceStruct {
 
 	struct semaphore sem;	/* Semaphore for waiting on erasure.*/
 	struct semaphore grossLock;	/* Gross locking semaphore */
-	struct rw_semaphore dirLock; /* Lock the directory structure */
 	__u8 *spareBuffer;	/* For mtdif2 use. Don't know the size of the buffer
 				 * at compile time so we have to allocate it.
 				 */