+static void yaffs_GrossLock(yaffs_Device *dev)
+{
+ T((KERN_DEBUG"yaffs locking\n"));
+
+ down(&dev->grossLock);
+}
+static void yaffs_GrossUnlock(yaffs_Device *dev)
+{
+ T((KERN_DEBUG"yaffs unlocking\n"));
+ up(&dev->grossLock);
+
+}
static int yaffs_readlink(struct dentry *dentry, char *buffer, int buflen)
{
unsigned char *alias;
int ret;
+ yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev;
+
+
+ yaffs_GrossLock(dev);
+
alias = yaffs_GetSymlinkAlias(yaffs_DentryToObject(dentry));
+ yaffs_GrossUnlock(dev);
+
if(!alias)
return -ENOMEM;
{
unsigned char *alias;
int ret;
+ yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev;
+
+
+ yaffs_GrossLock(dev);
+
alias = yaffs_GetSymlinkAlias(yaffs_DentryToObject(dentry));
+ yaffs_GrossUnlock(dev);
+
if(!alias)
return -ENOMEM;
yaffs_Object *obj;
struct inode *inode;
+ yaffs_Device *dev = yaffs_InodeToObject(dir)->myDev;
+
+
+ yaffs_GrossLock(dev);
+
T((KERN_DEBUG"yaffs_lookup for %d:%s\n",yaffs_InodeToObject(dir)->objectId,dentry->d_name.name));
obj = yaffs_GetEquivalentObject(obj); // in case it was a hardlink
+
+
if(obj)
{
T((KERN_DEBUG"yaffs_lookup found %d\n",obj->objectId));
if(inode)
{
T((KERN_DEBUG"yaffs_loookup looks good\n"));
- dget(dentry); // try to solve directory bug
+ // try to fix ln -s prob dget(dentry); // try to solve directory bug
d_add(dentry,inode);
+
+ yaffs_GrossUnlock(dev);
+
return dentry;
}
T((KERN_DEBUG"yaffs_lookup not found\n"));
}
+ yaffs_GrossUnlock(dev);
+
return NULL;
}
{
yaffs_Object *obj = yaffs_DentryToObject(file->f_dentry);
+ yaffs_Device *dev = obj->myDev;
+
T((KERN_DEBUG"yaffs_file_flush object %d (%s)\n",obj->objectId,
obj->dirty ? "dirty" : "clean"));
+ yaffs_GrossLock(dev);
+
yaffs_FlushFile(obj);
+ yaffs_GrossUnlock(dev);
+
return 0;
}
unsigned char *pg_buf;
int ret;
+ yaffs_Device *dev;
+
T((KERN_DEBUG"yaffs_readpage at %08x, size %08x\n",
pg->index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE));
obj = yaffs_DentryToObject(f->f_dentry);
- //down(obj->sem);
+ dev = obj->myDev;
+
if (!PageLocked(pg))
PAGE_BUG(pg);
pg_buf = kmap(pg);
/* FIXME: Can kmap fail? */
+ yaffs_GrossLock(dev);
+
ret = yaffs_ReadDataFromFile(obj, pg_buf, pg->index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE);
+ yaffs_GrossUnlock(dev);
+
if(ret >= 0) ret = 0;
if (ret) {
kunmap(pg);
-
- //up(&obj->sem);
-
T((KERN_DEBUG"yaffs_readpage done\n"));
return ret;
}
inode = iget(sb,obj->objectId);
- // No need to call this since iget calls it via the read_inode callback
- // yaffs_FillInodeFromObject(inode,obj);
+ // NB Side effect: iget calls back to yaffs_read_inode().
return inode;
}
yaffs_Object *obj;
int nRead,ipos;
struct inode *inode;
+ yaffs_Device *dev;
T((KERN_DEBUG"yaffs_file_read\n"));
obj = yaffs_DentryToObject(f->f_dentry);
+
+ dev = obj->myDev;
+
+ yaffs_GrossLock(dev);
+
inode = f->f_dentry->d_inode;
if (*pos < inode->i_size)
{
f->f_pos += nRead;
}
+
+ yaffs_GrossUnlock(dev);
+
ipos = *pos;
+
T((KERN_DEBUG"yaffs_file_read read %d bytes, %d read at %d\n",n,nRead,ipos));
return nRead;
yaffs_Object *obj;
int nWritten,ipos;
struct inode *inode;
+ yaffs_Device *dev;
+
obj = yaffs_DentryToObject(f->f_dentry);
+
+ dev = obj->myDev;
+
+ yaffs_GrossLock(dev);
+
inode = f->f_dentry->d_inode;
if(!S_ISBLK(inode->i_mode) && f->f_flags & O_APPEND)
}
}
+ yaffs_GrossUnlock(dev);
+
return nWritten != n ? -ENOSPC : nWritten;
}
static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
{
yaffs_Object *obj;
+ yaffs_Device *dev;
struct inode *inode = f->f_dentry->d_inode;
unsigned long offset, curoffs;
struct list_head *i;
char name[YAFFS_MAX_NAME_LENGTH +1];
obj = yaffs_DentryToObject(f->f_dentry);
+ dev = obj->myDev;
+
+ yaffs_GrossLock(dev);
offset = f->f_pos;
curoffs = 1;
- //down(&obj->sem);
-
-
list_for_each(i,&obj->variant.directoryVariant.children)
{
curoffs++;
}
up_and_out:
-
- //up(&obj->sem);
-
out:
+
+ yaffs_GrossUnlock(dev);
+
return 0;
}
struct inode *inode;
yaffs_Object *obj = NULL;
+ yaffs_Device *dev;
+
yaffs_Object *parent = yaffs_InodeToObject(dir);
int error = -ENOSPC;
}
T(("yaffs_mknod: making oject for %s, mode %x dev %x\n",
- dentry->d_name.name, mode,dev));
+ dentry->d_name.name, mode,dev));
+
+ dev = parent->myDev;
+
+ yaffs_GrossLock(dev);
switch (mode & S_IFMT)
{
T((KERN_DEBUG"yaffs_mknod failed making object\n"));
error = -ENOMEM;
}
-
+
+ yaffs_GrossUnlock(dev);
return error;
}
static int yaffs_unlink(struct inode * dir, struct dentry *dentry)
{
+ int retVal;
+ yaffs_Device *dev;
+
T((KERN_DEBUG"yaffs_unlink %d:%s\n",dir->i_ino,dentry->d_name.name));
- if(yaffs_Unlink(yaffs_InodeToObject(dir),dentry->d_name.name) == YAFFS_OK)
+ dev = yaffs_InodeToObject(dir)->myDev;
+
+ yaffs_GrossLock(dev);
+ retVal = yaffs_Unlink(yaffs_InodeToObject(dir),dentry->d_name.name);
+ yaffs_GrossUnlock(dev);
+
+ if( retVal == YAFFS_OK)
{
return 0;
}
struct inode *inode = old_dentry->d_inode;
yaffs_Object *obj = NULL;
yaffs_Object *link=NULL;
+ yaffs_Device *dev;
T((KERN_DEBUG"yaffs_link\n"));
obj = yaffs_InodeToObject(inode);
+ dev = obj->myDev;
+
+ yaffs_GrossLock(dev);
link = yaffs_Link(yaffs_InodeToObject(dir),dentry->d_name.name,obj);
+ yaffs_GrossUnlock(dev);
+
if(link)
{
return 0;
static int yaffs_symlink(struct inode * dir, struct dentry *dentry, const char * symname)
{
yaffs_Object *obj;
+ yaffs_Device *dev;
T((KERN_DEBUG"yaffs_symlink\n"));
+ dev = yaffs_InodeToObject(dir)->myDev;
+ yaffs_GrossLock(dev);
obj = yaffs_MknodSymLink(yaffs_InodeToObject(dir), dentry->d_name.name,
S_IFLNK | S_IRWXUGO, current->uid, current->gid,
symname);
+ yaffs_GrossUnlock(dev);
if(obj)
{
static int yaffs_sync_object(struct file * file, struct dentry *dentry, int datasync)
{
+ yaffs_Object *obj;
+ yaffs_Device *dev;
+
+ obj = yaffs_DentryToObject(dentry);
+
+ dev = obj->myDev;
+
T((KERN_DEBUG"yaffs_sync_object\n"));
- yaffs_FlushFile(yaffs_DentryToObject(dentry));
+ yaffs_GrossLock(dev);
+ yaffs_FlushFile(obj);
+ yaffs_GrossUnlock(dev);
return 0;
}
*/
static int yaffs_rename(struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir,struct dentry *new_dentry)
{
+ yaffs_Device *dev;
+ int retVal;
+
+ dev = yaffs_InodeToObject(old_dir)->myDev;
+
+ yaffs_GrossLock(dev);
+ retVal = yaffs_RenameObject(yaffs_InodeToObject(old_dir),old_dentry->d_name.name,
+ yaffs_InodeToObject(new_dir),new_dentry->d_name.name);
+ yaffs_GrossUnlock(dev);
- if( yaffs_RenameObject(yaffs_InodeToObject(old_dir),old_dentry->d_name.name,
- yaffs_InodeToObject(new_dir),new_dentry->d_name.name) == YAFFS_OK)
+ if(retVal == YAFFS_OK)
{
return 0;
}
{
struct inode *inode = dentry->d_inode;
int error;
+ yaffs_Device *dev;
T((KERN_DEBUG"yaffs_setattr of object %d\n",yaffs_InodeToObject(inode)->objectId));
if((error = inode_change_ok(inode,attr)) == 0)
{
+ dev = yaffs_InodeToObject(inode)->myDev;
+ yaffs_GrossLock(dev);
if(yaffs_SetAttributes(yaffs_InodeToObject(inode),attr) == YAFFS_OK)
{
error = 0;
{
error = -EPERM;
}
-
+ yaffs_GrossUnlock(dev);
inode_setattr(inode,attr);
}
return error;
static int yaffs_statfs(struct super_block *sb, struct statfs *buf)
{
+ yaffs_Device *dev = yaffs_SuperToDevice(sb);
T((KERN_DEBUG"yaffs_statfs\n"));
+ yaffs_GrossLock(dev);
+
buf->f_type = YAFFS_MAGIC;
buf->f_bsize = sb->s_blocksize;
buf->f_namelen = 255;
- buf->f_blocks = yaffs_SuperToDevice(sb)->nBlocks * YAFFS_CHUNKS_PER_BLOCK/
+ buf->f_blocks = dev->nBlocks * YAFFS_CHUNKS_PER_BLOCK/
(sb->s_blocksize/YAFFS_BYTES_PER_CHUNK);
buf->f_files = 0;
buf->f_ffree = 0;
- buf->f_bfree = yaffs_GetNumberOfFreeChunks(yaffs_SuperToDevice(sb))/
+ buf->f_bfree = yaffs_GetNumberOfFreeChunks(dev)/
(sb->s_blocksize/YAFFS_BYTES_PER_CHUNK);
buf->f_bavail = buf->f_bfree;
+
+ yaffs_GrossUnlock(dev);
return 0;
}
static void yaffs_read_inode (struct inode *inode)
{
-
+ // NB This is called as a side effect of other functions and
+ // thus gross locking should always be in place already.
+
yaffs_Object *obj ;
+ yaffs_Device *dev = yaffs_SuperToDevice(inode->i_sb);
T((KERN_DEBUG"yaffs_read_inode for %d\n",(int)inode->i_ino));
- obj = yaffs_FindObjectByNumber(yaffs_SuperToDevice(inode->i_sb),inode->i_ino);
+ obj = yaffs_FindObjectByNumber(dev,inode->i_ino);
yaffs_FillInodeFromObject(inode,obj);
+
}
{
yaffs_Device *dev = yaffs_SuperToDevice(sb);
+ yaffs_GrossLock(dev);
if(dev->putSuperFunc)
{
dev->putSuperFunc(sb);
}
yaffs_Deinitialise(dev);
+ yaffs_GrossUnlock(dev);
+
kfree(dev);
}
#endif
}
-
-
+ init_MUTEX(&dev->grossLock);
+
+
+ yaffs_GrossLock(dev);
yaffs_GutsInitialise(yaffs_SuperToDevice(sb));
+
T(("yaffs_read_super: guts initialised\n"));
// Create root inode
inode = yaffs_get_inode(sb, S_IFDIR | 0755, 0,yaffs_Root(yaffs_SuperToDevice(sb)));
+
+ yaffs_GrossUnlock(dev);
+
if (!inode)
return NULL;