From cacf6da20462fa436de86a66dcb6e5aa11ba76b1 Mon Sep 17 00:00:00 2001 From: charles Date: Thu, 29 Aug 2002 08:46:50 +0000 Subject: [PATCH] *** empty log message *** --- yaffs_fs.c | 183 +++++++++++++++++++++++++++++++++++++++++++------- yaffs_guts.h | 1 + yaffs_ramem.c | 15 +++++ yaffsdev.proj | Bin 53248 -> 53248 bytes 4 files changed, 173 insertions(+), 26 deletions(-) diff --git a/yaffs_fs.c b/yaffs_fs.c index d669793..d494e83 100644 --- a/yaffs_fs.c +++ b/yaffs_fs.c @@ -167,15 +167,34 @@ static struct super_operations yaffs_super_ops = { +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; @@ -188,8 +207,15 @@ static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd) { 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; @@ -209,6 +235,11 @@ static struct dentry * yaffs_lookup(struct inode *dir, struct dentry *dentry) 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)); @@ -216,6 +247,8 @@ static struct dentry * yaffs_lookup(struct inode *dir, struct dentry *dentry) obj = yaffs_GetEquivalentObject(obj); // in case it was a hardlink + + if(obj) { T((KERN_DEBUG"yaffs_lookup found %d\n",obj->objectId)); @@ -225,8 +258,11 @@ static struct dentry * yaffs_lookup(struct inode *dir, struct dentry *dentry) 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; } @@ -236,6 +272,8 @@ static struct dentry * yaffs_lookup(struct inode *dir, struct dentry *dentry) T((KERN_DEBUG"yaffs_lookup not found\n")); } + yaffs_GrossUnlock(dev); + return NULL; } @@ -254,11 +292,17 @@ static int yaffs_file_flush(struct file* file) { 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; } @@ -272,12 +316,15 @@ static int yaffs_readpage_nolock(struct file *f, struct page * pg) 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); @@ -285,8 +332,12 @@ static int yaffs_readpage_nolock(struct file *f, struct page * 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) { @@ -301,9 +352,6 @@ static int yaffs_readpage_nolock(struct file *f, struct page * pg) kunmap(pg); - - //up(&obj->sem); - T((KERN_DEBUG"yaffs_readpage done\n")); return ret; } @@ -424,8 +472,7 @@ struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,yaffs_Ob 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; } @@ -435,10 +482,16 @@ static ssize_t yaffs_file_read(struct file *f, char *buf, size_t n, loff_t *pos) 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) @@ -458,7 +511,11 @@ static ssize_t yaffs_file_read(struct file *f, char *buf, size_t n, loff_t *pos) { 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; @@ -470,8 +527,15 @@ static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, loff_ 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) @@ -509,6 +573,8 @@ static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, loff_ } } + yaffs_GrossUnlock(dev); + return nWritten != n ? -ENOSPC : nWritten; } @@ -516,6 +582,7 @@ static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, loff_ 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; @@ -524,6 +591,9 @@ static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir) char name[YAFFS_MAX_NAME_LENGTH +1]; obj = yaffs_DentryToObject(f->f_dentry); + dev = obj->myDev; + + yaffs_GrossLock(dev); offset = f->f_pos; @@ -552,9 +622,6 @@ static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir) curoffs = 1; - //down(&obj->sem); - - list_for_each(i,&obj->variant.directoryVariant.children) { curoffs++; @@ -582,10 +649,10 @@ static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir) } up_and_out: - - //up(&obj->sem); - out: + + yaffs_GrossUnlock(dev); + return 0; } @@ -598,6 +665,8 @@ static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, int d struct inode *inode; yaffs_Object *obj = NULL; + yaffs_Device *dev; + yaffs_Object *parent = yaffs_InodeToObject(dir); int error = -ENOSPC; @@ -614,7 +683,11 @@ static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, int d } 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) { @@ -649,7 +722,8 @@ static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, int d T((KERN_DEBUG"yaffs_mknod failed making object\n")); error = -ENOMEM; } - + + yaffs_GrossUnlock(dev); return error; } @@ -678,10 +752,19 @@ static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode) 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; } @@ -700,13 +783,19 @@ static int yaffs_link(struct dentry *old_dentry, struct inode * dir, struct dent 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; @@ -720,12 +809,16 @@ static int yaffs_link(struct dentry *old_dentry, struct inode * dir, struct dent 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) { @@ -744,8 +837,17 @@ static int yaffs_symlink(struct inode * dir, struct dentry *dentry, const char * 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; } @@ -754,10 +856,18 @@ static int yaffs_sync_object(struct file * file, struct dentry *dentry, int data */ 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; } @@ -773,12 +883,15 @@ static int yaffs_setattr(struct dentry *dentry, struct iattr *attr) { 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; @@ -787,7 +900,7 @@ static int yaffs_setattr(struct dentry *dentry, struct iattr *attr) { error = -EPERM; } - + yaffs_GrossUnlock(dev); inode_setattr(inode,attr); } return error; @@ -795,31 +908,40 @@ static int yaffs_setattr(struct dentry *dentry, struct iattr *attr) 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); + } @@ -827,11 +949,14 @@ static void yaffs_put_super(struct super_block *sb) { yaffs_Device *dev = yaffs_SuperToDevice(sb); + yaffs_GrossLock(dev); if(dev->putSuperFunc) { dev->putSuperFunc(sb); } yaffs_Deinitialise(dev); + yaffs_GrossUnlock(dev); + kfree(dev); } @@ -998,13 +1123,19 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl #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; diff --git a/yaffs_guts.h b/yaffs_guts.h index 23aeefc..aadfa3f 100644 --- a/yaffs_guts.h +++ b/yaffs_guts.h @@ -340,6 +340,7 @@ struct yaffs_DeviceStruct #ifdef __KERNEL__ struct semaphore sem;// Semaphore for waiting on erasure. + struct semaphore grossLock; // Gross locking semaphore #endif diff --git a/yaffs_ramem.c b/yaffs_ramem.c index 2aebfe9..09e49c3 100644 --- a/yaffs_ramem.c +++ b/yaffs_ramem.c @@ -68,6 +68,15 @@ static nandemul_Device ned; int sizeInMB = DEFAULT_SIZE_IN_MB; +static void nandemul_yield(int n) +{ +#ifdef __KERNEL__ + if(n > 0) schedule_timeout(n); +#endif + +} + + static void nandemul_ReallyEraseBlock(int blockNumber) { int i; @@ -81,6 +90,7 @@ static void nandemul_ReallyEraseBlock(int blockNumber) theBlock->page[i].count[1] = 0; theBlock->page[i].count[2] = 0; theBlock->page[i].empty = 1; + nandemul_yield(2); } } @@ -208,6 +218,11 @@ int nandemul_WriteChunkToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data } ned.block[blk]->page[pg].count[2]++; } + + if(spare || data) + { + nandemul_yield(1); + } return YAFFS_OK; } diff --git a/yaffsdev.proj b/yaffsdev.proj index c0bc23340855fb929289433cbb566494900fe0ae..116b3a99258e5b7bde62d6261cb07fd3cef01b6c 100644 GIT binary patch delta 1124 zcmbVKT}TvB6yEjTD{HkX{Xm)2O>47t-DbvF*Fl2{Nmn8xH4KVvc4k(mo!yn$T~pR2 zgB~L2$4(R#hCvZT2{J+@K@a^vP`&g+4?Y+@6g@;lKM%ch_lL@a9(p*Od(V9LeBXD@ zjEtj^adfK5eq^%wMThi_yd~4*2DwfylS||{X(Bw?NNR|TyKn$+!cEwNEAc{Hg1@7$ z=skLeiX1lE7tRb^89eUh zSY84z_f^B}9*1?e`2@7})UWFaF z7=J@w&|CBdJx9;bBlG~>L6gY7+-6&iCaux^ABy1P{stBu&>UK9Jy!bcrKy5kBOZ^W z`r&-v%HqOtv%7}mtYwRZ6RRySHCZjV$fEOCXm)#;{H1WAuOerIgsa4u98|O0q^V zfOoBP>M^#am}~^IqTq?X=C8^p-37PSwLnm*gpnEo_ttt~s(Y#RO1pv}W0b;pMTK?S z*pA2qx`HOGlK!g*hTAt33H5NTeJv9F5k4HLfsywF&Fv2q$6}dQ<7Pj=x_A$83rFTwQ!*+f+nt+GNA zm@QtQInBSPD%JboM_UAmTqEd#Y9#s^;AEf!A_rYoPvV%v`h2Lg-0lMVsn!LjokyKL z&SDm$a+P)CjKgjXkIpPCOT<&AqQ&HaI*v+g#g{y_Rq4b~G-Ogn*yyMAB2Pt0%H~0q OYk8s8Ct6cu+l8N*TZ1A1 delta 1150 zcmbtTUu;uV7;o=)t`_K;xpp!uWT$Srt%GI#lhMWn+1j-b2ZMG(V48BdJ>9PD+Io90 zwANb|6BC%mRKG>R#AGjq1pngofyBtdlP}C*q5&f@#wS>Om_}dKd)tB|@@8_9lkaza z-|zd*_d91{85WkI{OWnqRsGbgniH5(r+LB)Q0Ob4vg2F&(dl}rSp`{_ir=2cnoi3-6rIW3-SqJmPHD=921rCTtUp@-+kNhjp$uY z+n$&p%tpy@K7yijI*Ef`Aj+l zd;uJ(O*Nt67UXY0#R!k9GdA4vd^;{iIv^AZ;&0JMIqJnPBW{=Zur=xn4~PD(hgWA@ z2H$}(Z4jIJ4!rh?i}U+&JxX_qg?ve&sgxQrK1S1wWKob=^P6bYzbky7n7bkLNBIe} z-LA?3E)c}I$}au)(~fp)FIwwyeyJ_iwuFc3J$kWz+m7^nsP|l(#ZoO*=1<5pL`T9j X5cJVtxUrXweK0f_7}39Yf71UCqePFo -- 2.30.2