*** empty log message ***
[yaffs/.git] / yaffs_fs.c
1 /*
2  * YAFFS: Yet another FFS. A NAND-flash specific file system.
3  * yaffs_fs.c
4  *
5  * Copyright (C) 2002 Aleph One Ltd.
6  *   for Toby Churchill Ltd and Brightstar Engineering
7  *
8  * Created by Charles Manning <charles@aleph1.co.uk>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  *
14  * This is the file system front-end to YAFFS that hooks it up to
15  * the VFS.
16  *
17  * Special notes: 
18  * >> sb->u.generic_sbp points to the yaffs_Device associated with this superblock
19  * >> inode->u.generic_ip points to the associated yaffs_Object.
20  *
21  *
22  * Acknowledgements:
23  * * Luc van OostenRyck for numerous patches.
24  * * Nick Bane for numerous patches.
25  * * Some code bodily lifted from JFFS2.
26  */
27
28
29 #include <linux/config.h>
30 #include <linux/kernel.h>
31 #include <linux/module.h>
32 #include <linux/version.h>
33 #include <linux/slab.h>
34 #include <linux/init.h>
35 #include <linux/list.h>
36 #include <linux/fs.h>
37 #include <linux/proc_fs.h>
38 #include <linux/pagemap.h>
39 #include <linux/mtd/mtd.h>
40 #include <linux/interrupt.h>
41 #include <linux/string.h>
42 #include <linux/locks.h>
43
44 #include <asm/uaccess.h>
45
46 #include "yaffs_guts.h"
47
48 #ifdef CONFIG_YAFFS_RAM_ENABLED
49 #include "yaffs_nandemul.h" 
50 // 2 MB of RAM for emulation
51 #define YAFFS_RAM_EMULATION_SIZE  0x200000
52 #endif //CONFIG_YAFFS_RAM_ENABLED
53
54 #ifdef CONFIG_YAFFS_MTD_ENABLED
55 #include <linux/mtd/mtd.h>
56 #include "yaffs_mtdif.h"
57 #endif //CONFIG_YAFFS_MTD_ENABLED
58
59 #define T(x) printk x
60
61
62
63 #define yaffs_InodeToObject(iptr) ((yaffs_Object *)((iptr)->u.generic_ip))
64 #define yaffs_DentryToObject(dptr) yaffs_InodeToObject((dptr)->d_inode)
65 #define yaffs_SuperToDevice(sb) ((yaffs_Device *)sb->u.generic_sbp)
66
67
68
69 static void yaffs_put_super(struct super_block *sb);
70
71 static ssize_t yaffs_file_read(struct file *f, char *buf, size_t n, loff_t *pos);
72 static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, loff_t *pos);
73 static int yaffs_file_flush(struct file* file);
74
75 static int yaffs_sync_object(struct file * file, struct dentry *dentry, int datasync);
76
77 static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir);
78
79 static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode);
80 static struct dentry * yaffs_lookup(struct inode *dir, struct dentry *dentry);
81 static int yaffs_link(struct dentry *old_dentry, struct inode * dir, struct dentry * dentry);
82 static int yaffs_unlink(struct inode * dir, struct dentry *dentry);
83 static int yaffs_symlink(struct inode * dir, struct dentry *dentry, const char * symname);
84 static int yaffs_mkdir(struct inode * dir, struct dentry * dentry, int mode);
85 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev);
86 static int yaffs_rename(struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir,struct dentry *new_dentry);
87 static int yaffs_setattr(struct dentry *dentry, struct iattr *attr);
88
89 static int yaffs_statfs(struct super_block *sb, struct statfs *buf);
90 static void yaffs_read_inode (struct inode *inode);
91 static struct super_block *yaffs_read_super(struct super_block * sb, void * data, int silent);
92 static void yaffs_put_inode (struct inode *inode);
93 static void yaffs_delete_inode(struct inode *);
94 static void yaffs_clear_inode(struct inode *);
95
96 static int yaffs_readpage(struct file *file, struct page * page);
97
98 static int yaffs_prepare_write(struct file *f, struct page *pg, unsigned offset, unsigned to);
99 static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset, unsigned to);
100
101 static int yaffs_readlink(struct dentry *dentry, char *buffer, int buflen);
102 static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd);
103
104
105
106
107 static struct address_space_operations yaffs_file_address_operations = {
108         readpage:               yaffs_readpage,
109         prepare_write:  yaffs_prepare_write,
110         commit_write:   yaffs_commit_write
111 };
112
113
114 static struct file_operations yaffs_file_operations = {
115 #ifdef CONFIG_YAFFS_USE_GENERIC_RW
116         read:           generic_file_read,
117         write:          generic_file_write,
118 #else
119         read:           yaffs_file_read,
120         write:          yaffs_file_write,
121 #endif
122         mmap:           generic_file_mmap,
123         flush:          yaffs_file_flush,
124         fsync:          yaffs_sync_object,
125 };
126
127
128 static struct inode_operations yaffs_file_inode_operations = {
129         setattr:        yaffs_setattr,
130 };
131
132
133 struct inode_operations yaffs_symlink_inode_operations =
134 {       
135         readlink:       yaffs_readlink,
136         follow_link:    yaffs_follow_link,
137         setattr:        yaffs_setattr
138 };
139
140 static struct inode_operations yaffs_dir_inode_operations = {
141         create:         yaffs_create,
142         lookup:         yaffs_lookup,
143         link:           yaffs_link,
144         unlink:         yaffs_unlink,   
145         symlink:        yaffs_symlink,
146         mkdir:          yaffs_mkdir,
147         rmdir:          yaffs_unlink,
148         mknod:          yaffs_mknod,
149         rename:         yaffs_rename,
150         setattr:        yaffs_setattr,
151 };
152
153 static struct file_operations yaffs_dir_operations = {
154         read:           generic_read_dir,
155         readdir:        yaffs_readdir,
156         fsync:          yaffs_sync_object,
157 };
158
159
160 static struct super_operations yaffs_super_ops = {
161         statfs:                 yaffs_statfs,
162         read_inode:             yaffs_read_inode,
163         put_inode:              yaffs_put_inode,
164         put_super:              yaffs_put_super,
165 //      remount_fs:
166         delete_inode:           yaffs_delete_inode,
167         clear_inode:            yaffs_clear_inode,
168 };
169
170
171
172 static void yaffs_GrossLock(yaffs_Device *dev)
173 {
174         T((KERN_DEBUG"yaffs locking\n"));
175
176         down(&dev->grossLock);
177 }
178
179 static void yaffs_GrossUnlock(yaffs_Device *dev)
180 {
181         T((KERN_DEBUG"yaffs unlocking\n"));
182         up(&dev->grossLock);
183
184 }
185
186 static int yaffs_readlink(struct dentry *dentry, char *buffer, int buflen)
187 {
188         unsigned char *alias;
189         int ret;
190
191         yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev;
192
193
194         yaffs_GrossLock(dev);
195         
196         alias = yaffs_GetSymlinkAlias(yaffs_DentryToObject(dentry));
197         
198         yaffs_GrossUnlock(dev);
199         
200         if(!alias)
201                 return -ENOMEM;
202
203         ret = vfs_readlink(dentry, buffer, buflen, alias);
204         kfree(alias);
205         return ret;
206 }
207
208 static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd)
209 {
210         unsigned char *alias;
211         int ret;
212         yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev;
213
214
215         yaffs_GrossLock(dev);
216
217         alias = yaffs_GetSymlinkAlias(yaffs_DentryToObject(dentry));
218         
219         yaffs_GrossUnlock(dev);
220         
221         if(!alias)
222                 return -ENOMEM;
223
224         ret = vfs_follow_link(nd,alias);
225         kfree(alias);
226         return ret;
227 }
228
229
230 struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,yaffs_Object *obj);
231
232 /*
233  * Lookup is used to find objects in the fs
234  */
235 static struct dentry * yaffs_lookup(struct inode *dir, struct dentry *dentry)
236 {
237         yaffs_Object *obj;
238         struct inode *inode;
239         
240         yaffs_Device *dev = yaffs_InodeToObject(dir)->myDev;
241
242
243         yaffs_GrossLock(dev);
244
245         
246         T((KERN_DEBUG"yaffs_lookup for %d:%s\n",yaffs_InodeToObject(dir)->objectId,dentry->d_name.name));
247         
248         obj = yaffs_FindObjectByName(yaffs_InodeToObject(dir),dentry->d_name.name);
249         
250         obj = yaffs_GetEquivalentObject(obj); // in case it was a hardlink
251         
252
253         
254         if(obj)
255         {
256                 T((KERN_DEBUG"yaffs_lookup found %d\n",obj->objectId));
257                 
258                 inode = yaffs_get_inode(dir->i_sb, obj->st_mode,0,obj);
259                 
260                 if(inode)
261                 {
262                         T((KERN_DEBUG"yaffs_loookup dentry \n"));
263                         //dget(dentry); // try to solve directory bug
264                         d_add(dentry,inode);
265                         
266                         yaffs_GrossUnlock(dev);
267
268                         // return dentry;
269                         return NULL;
270                 }
271
272         }
273         else
274         {
275                 T((KERN_DEBUG"yaffs_lookup not found\n"));
276                 
277         }
278         yaffs_GrossUnlock(dev);
279         
280         return NULL;
281         //      return (ERR_PTR(-EIO));
282         
283 }
284
285 // For now put inode is just for debugging
286 // Put inode is called when the inode **structure** is put.
287 static void yaffs_put_inode(struct inode *inode)
288 {
289         T(("yaffs_put_inode: ino %d, count %d\n",(int)inode->i_ino, atomic_read(&inode->i_count)));
290         
291 }
292
293 // clear is called to tell the fs to release any per-inode data it holds
294 static void yaffs_clear_inode(struct inode *inode)
295 {
296         yaffs_Object *obj = yaffs_InodeToObject(inode);
297         
298         T(("yaffs_clear_inode: ino %d, count %d %s\n",(int)inode->i_ino, atomic_read(&inode->i_count),
299                 obj ? "object exists" : "null object"));        
300
301         if(obj)
302         {
303                 obj->myInode = NULL;
304                 inode->u.generic_ip = NULL;     
305         }
306         
307         
308 }
309
310 // delete is called when the link count is zero and the inode
311 // is put (ie. nobody wants to know about it anymore, time to
312 // delete the file).
313 // NB Must call clear_inode()
314 static void yaffs_delete_inode(struct inode *inode)
315 {
316         yaffs_Object *obj = yaffs_InodeToObject(inode);
317         yaffs_Device *dev;
318
319         T(("yaffs_delete_inode: ino %d, count %d %s\n",(int)inode->i_ino, atomic_read(&inode->i_count),
320                 obj ? "object exists" : "null object"));
321         
322         if(obj)
323         {
324                 dev = obj->myDev;
325                 yaffs_GrossLock(dev);
326                 yaffs_DeleteFile(obj);
327                 yaffs_GrossUnlock(dev);
328         }
329         clear_inode(inode);
330 }
331
332
333 static int yaffs_file_flush(struct file* file)
334 {
335         yaffs_Object *obj = yaffs_DentryToObject(file->f_dentry);
336         
337         yaffs_Device *dev = obj->myDev;
338         
339         T((KERN_DEBUG"yaffs_file_flush object %d (%s)\n",obj->objectId,
340                                 obj->dirty ? "dirty" : "clean"));
341
342         yaffs_GrossLock(dev);
343         
344     yaffs_FlushFile(obj);
345
346         yaffs_GrossUnlock(dev);
347
348     return 0;
349 }
350
351
352
353 static int yaffs_readpage_nolock(struct file *f, struct page * pg)
354 {
355         // Lifted from jffs2
356         
357         yaffs_Object *obj;
358         unsigned char *pg_buf;  
359         int ret;
360         
361         yaffs_Device *dev;
362         
363         T((KERN_DEBUG"yaffs_readpage at %08x, size %08x\n", 
364                       pg->index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE));
365
366         obj  = yaffs_DentryToObject(f->f_dentry);
367
368         dev = obj->myDev;
369         
370         
371         if (!PageLocked(pg))
372                 PAGE_BUG(pg);
373
374         pg_buf = kmap(pg);
375         /* FIXME: Can kmap fail? */
376
377         yaffs_GrossLock(dev);
378         
379         ret = yaffs_ReadDataFromFile(obj, pg_buf, pg->index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE);
380
381         yaffs_GrossUnlock(dev);
382         
383         if(ret >= 0) ret = 0;
384
385         if (ret) {
386                 ClearPageUptodate(pg);
387                 SetPageError(pg);
388         } else {
389                 SetPageUptodate(pg);
390                 ClearPageError(pg);
391         }
392
393         flush_dcache_page(pg);
394         kunmap(pg);
395
396
397         T((KERN_DEBUG"yaffs_readpage done\n"));
398         return ret;
399 }
400
401 static int yaffs_readpage_unlock(struct file *f, struct page *pg)
402 {
403         int ret = yaffs_readpage_nolock(f,pg);
404         UnlockPage(pg);
405         return ret;
406 }
407
408 static int yaffs_readpage(struct file *f, struct page * pg)
409 {
410         return yaffs_readpage_unlock(f,pg);
411 }
412
413
414 static int yaffs_prepare_write(struct file *f, struct page *pg, unsigned offset, unsigned to)
415 {
416
417         T((KERN_DEBUG"yaffs_prepair_write\n"));
418         if(!Page_Uptodate(pg) && (offset || to < PAGE_CACHE_SIZE))
419                 return  yaffs_readpage_nolock(f,pg);    
420
421         return 0;
422         
423 }
424
425 static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset, unsigned to)
426 {
427
428         void *addr = page_address(pg) + offset;
429         loff_t pos = (((loff_t)pg->index) << PAGE_CACHE_SHIFT) + offset;
430         int nBytes = to - offset;
431         int nWritten;
432         
433         unsigned spos = pos;
434         unsigned saddr = addr;
435
436         T((KERN_DEBUG"yaffs_commit_write addr %x pos %x nBytes %d\n",saddr,spos,nBytes));
437         
438         nWritten = yaffs_file_write(f,addr, nBytes, &pos);
439         
440         if(nWritten != nBytes)
441         {
442                 T((KERN_DEBUG"yaffs_commit_write not same size nWritten %d  nBytes %d\n",nWritten,nBytes));
443                 SetPageError(pg);
444                 ClearPageUptodate(pg);
445         }
446         else
447         {
448                 SetPageUptodate(pg);
449         }
450
451         T((KERN_DEBUG"yaffs_commit_write returning %d\n",nWritten));
452         
453         return nWritten;
454
455 }
456
457
458
459 static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object *obj)
460 {
461         if (inode && obj) 
462         {
463                 inode->i_ino = obj->objectId;
464                 inode->i_mode = obj->st_mode;
465                 inode->i_uid = obj->st_uid;
466                 inode->i_gid = obj->st_gid;
467                 inode->i_blksize = inode->i_sb->s_blocksize;
468                 inode->i_blocks = 0;
469                 inode->i_rdev = obj->st_rdev;;
470                 inode->i_atime = obj->st_atime;
471                 inode->i_mtime = obj->st_mtime;
472                 inode->i_ctime = obj->st_ctime;
473                 inode->i_size = yaffs_GetObjectFileLength(obj);
474                 inode->i_nlink = yaffs_GetObjectLinkCount(obj);
475                 
476                 T((KERN_DEBUG"yaffs_FillInode mode %x uid %d gid %d size %d count %d\n",
477                                 inode->i_mode, inode->i_uid, inode->i_gid, (int)inode->i_size, atomic_read(&inode->i_count)));
478                 
479                 switch (obj->st_mode & S_IFMT) 
480                 {
481                         default: // fifo, device or socket
482                                 init_special_inode(inode, obj->st_mode, obj->st_rdev);
483                                 break;
484                         case S_IFREG:   // file         
485                                 inode->i_op = &yaffs_file_inode_operations;
486                                 inode->i_fop = &yaffs_file_operations;
487                                 inode->i_mapping->a_ops = &yaffs_file_address_operations;
488                                 break;
489                         case S_IFDIR:   // directory
490                                 inode->i_op = &yaffs_dir_inode_operations;
491                                 inode->i_fop = &yaffs_dir_operations;
492                                 break;
493                         case S_IFLNK:   // symlink
494                                 inode->i_op = &yaffs_symlink_inode_operations;
495                                 break;
496                 }
497                 
498                 
499                 inode->u.generic_ip = obj;
500                 obj->myInode = inode;
501                 
502         }
503         else
504         {
505                 T((KERN_DEBUG"yaffs_FileInode invalid parameters\n"));
506         }
507
508 }
509
510 struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,yaffs_Object *obj)
511 {
512         struct inode * inode;
513         
514         T((KERN_DEBUG"yaffs_get_inode for object %d\n",obj->objectId));
515
516         inode = iget(sb,obj->objectId);
517
518         // NB Side effect: iget calls back to yaffs_read_inode().
519         // iget also increments the inode's i_count
520         
521         return inode;
522 }
523
524 static ssize_t yaffs_file_read(struct file *f, char *buf, size_t n, loff_t *pos)
525 {
526         yaffs_Object *obj;
527         int nRead,ipos;
528         struct inode *inode;
529         yaffs_Device *dev;
530         
531         T((KERN_DEBUG"yaffs_file_read\n"));
532
533         obj  = yaffs_DentryToObject(f->f_dentry);
534         
535         dev = obj->myDev;
536         
537         yaffs_GrossLock(dev);
538         
539         inode = f->f_dentry->d_inode;
540         
541         if (*pos < inode->i_size) 
542         {
543                         if (*pos + n > inode->i_size)
544                         {
545                                 n = inode->i_size - *pos;
546                         }
547         }
548         else
549         {
550                 n = 0;
551         }
552         
553         nRead = yaffs_ReadDataFromFile(obj,buf,*pos,n);
554         if(nRead > 0)
555         {
556                 f->f_pos += nRead;
557         }
558         
559         yaffs_GrossUnlock(dev);
560         
561         ipos = *pos;
562         
563         T((KERN_DEBUG"yaffs_file_read read %d bytes, %d read at %d\n",n,nRead,ipos));
564         return nRead;
565         
566 }
567
568
569 static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, loff_t *pos)
570 {
571         yaffs_Object *obj;
572         int nWritten,ipos;
573         struct inode *inode;
574         yaffs_Device *dev;
575         
576         
577         obj  = yaffs_DentryToObject(f->f_dentry);
578         
579         dev = obj->myDev;
580         
581         yaffs_GrossLock(dev);
582         
583         inode = f->f_dentry->d_inode;
584
585         if(!S_ISBLK(inode->i_mode) && f->f_flags & O_APPEND)
586         {
587                 ipos = inode->i_size;
588         }
589         else
590         {
591                 ipos = *pos;
592         }
593         
594         
595         if(!obj)
596         {
597                 T((KERN_DEBUG"yaffs_file_write: hey obj is null!\n"));
598         }
599         else
600         {
601                 T((KERN_DEBUG"yaffs_file_write about to write writing %d bytes to object %d at %d\n",n,obj->objectId,ipos));
602         }
603
604         nWritten = yaffs_WriteDataToFile(obj,buf,ipos,n);
605
606         T((KERN_DEBUG"yaffs_file_write writing %d bytes, %d written at %d\n",n,nWritten,ipos));
607         if(nWritten > 0)
608         {
609                 ipos += nWritten;
610                 *pos = ipos;
611                 if(ipos > inode->i_size)
612                 {
613                         inode->i_size = ipos;
614                         inode->i_blocks = (ipos + inode->i_blksize - 1)/ inode->i_blksize;
615                         
616                         T((KERN_DEBUG"yaffs_file_write size updated to %d bytes, %d blocks\n",ipos,inode->i_blocks));
617                 }
618                 
619         }
620         yaffs_GrossUnlock(dev);
621         
622         return nWritten != n ? -ENOSPC : nWritten;      
623 }
624
625
626 static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
627 {
628         yaffs_Object *obj;
629         yaffs_Device *dev;
630         struct inode *inode = f->f_dentry->d_inode;
631         unsigned long offset, curoffs;
632         struct list_head *i;    
633         yaffs_Object *l;
634         
635         char name[YAFFS_MAX_NAME_LENGTH +1];
636                 
637         obj =  yaffs_DentryToObject(f->f_dentry);
638         dev = obj->myDev;
639         
640         yaffs_GrossLock(dev);
641         
642         offset = f->f_pos;
643         
644         T(("yaffs_readdir: starting at %d\n",(int)offset));
645         
646         if(offset == 0)
647         {
648         T((KERN_DEBUG"yaffs_readdir: entry . ino %d \n",(int)inode->i_ino));
649                 if(filldir(dirent,".",1,offset,inode->i_ino,DT_DIR) < 0)
650                 {
651                         goto out;
652                 }
653                 offset++;
654                 f->f_pos++;
655         }
656         if(offset == 1)
657         {
658                 T((KERN_DEBUG"yaffs_readdir: entry .. ino %d \n",(int)f->f_dentry->d_parent->d_inode->i_ino));
659                 if(filldir(dirent,"..",2,offset,f->f_dentry->d_parent->d_inode->i_ino,DT_DIR) < 0)
660                 {
661                         goto out;
662                 }
663                 offset++;
664                 f->f_pos++;
665         }
666         
667         curoffs = 1;
668         
669         list_for_each(i,&obj->variant.directoryVariant.children)
670         {
671                 curoffs++;
672                 if(curoffs >= offset)
673                 {               
674                         l = list_entry(i, yaffs_Object,siblings);
675                         
676                         yaffs_GetObjectName(l,name,YAFFS_MAX_NAME_LENGTH+1); 
677                         T((KERN_DEBUG"yaffs_readdir: %s inode %d\n",name,yaffs_GetObjectInode(l)));
678                         
679                         if(filldir(dirent,
680                                            name,
681                                            strlen(name),
682                                            offset,
683                                            yaffs_GetObjectInode(l),
684                                            yaffs_GetObjectType(l))
685                                            < 0)
686                         {
687                                 goto up_and_out;
688                         }
689                         
690                         offset++;
691                         f->f_pos++;        
692                 }
693         }
694
695   up_and_out:
696   out:
697   
698     yaffs_GrossUnlock(dev);
699     
700         return 0;
701 }
702
703
704 /*
705  * File creation. Allocate an inode, and we're done..
706  */
707 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev)
708 {
709         struct inode *inode;
710         
711         yaffs_Object *obj = NULL;
712         yaffs_Device *dev;
713         
714         yaffs_Object *parent = yaffs_InodeToObject(dir);
715         
716         int error = -ENOSPC;
717
718         if(parent)
719         {
720                 T((KERN_DEBUG"yaffs_mknod: parent object %d type %d\n",
721                                          parent->objectId,parent->variantType));
722         }
723         else
724         {
725                 T((KERN_DEBUG"yaffs_mknod: could not get parent object\n"));
726                 return -EPERM;
727         }
728         
729         T(("yaffs_mknod: making oject for %s, mode %x dev %x\n",
730                                         dentry->d_name.name, mode,dev));
731
732         dev = parent->myDev;
733         
734         yaffs_GrossLock(dev);
735
736         switch (mode & S_IFMT) 
737         {
738                 default:
739                         // Special (socket, fifo, device...)
740                         T((KERN_DEBUG"yaffs_mknod: making special\n"));
741                         obj = yaffs_MknodSpecial(parent,dentry->d_name.name,mode,current->uid, current->gid,dev);
742                         break;
743                 case S_IFREG:   // file         
744                         T((KERN_DEBUG"yaffs_mknod: making file\n"));
745                         obj = yaffs_MknodFile(parent,dentry->d_name.name,mode,current->uid, current->gid);
746                         break;
747                 case S_IFDIR:   // directory
748                         T((KERN_DEBUG"yaffs_mknod: making directory\n"));
749                         obj = yaffs_MknodDirectory(parent,dentry->d_name.name,mode,current->uid, current->gid);
750                         break;
751                 case S_IFLNK:   // symlink
752                         T((KERN_DEBUG"yaffs_mknod: making file\n"));
753                         obj = NULL; // Do we ever get here?
754                         break;
755         }
756         
757         if(obj)
758         {
759                 inode = yaffs_get_inode(dir->i_sb, mode, dev, obj);
760                 d_instantiate(dentry, inode);
761                 T((KERN_DEBUG"yaffs_mknod created object %d count = %d\n",obj->objectId,atomic_read(&inode->i_count)));
762                 error = 0;
763         }
764         else
765         {
766                 T((KERN_DEBUG"yaffs_mknod failed making object\n"));
767                 error = -ENOMEM;
768         }
769
770         yaffs_GrossUnlock(dev);
771
772         return error;
773 }
774
775 static int yaffs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
776 {
777         int retVal;
778         T((KERN_DEBUG"yaffs_mkdir\n"));
779         retVal =  yaffs_mknod(dir, dentry, mode | S_IFDIR, 0);
780 #if 0
781  // attempt to fix dir bug - didn't work
782         if(!retVal)
783         {
784                 dget(dentry);
785         }
786 #endif
787         return retVal;
788 }
789
790 static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode)
791 {
792         T((KERN_DEBUG"yaffs_create\n"));
793         return yaffs_mknod(dir, dentry, mode | S_IFREG, 0);
794 }
795
796
797 static int yaffs_unlink(struct inode * dir, struct dentry *dentry)
798 {
799         int retVal;
800         int nlinks;
801         
802         yaffs_Device *dev;
803         
804         
805         T((KERN_DEBUG"yaffs_unlink %d:%s\n",dir->i_ino,dentry->d_name.name));
806         
807         dev = yaffs_InodeToObject(dir)->myDev;
808         
809         yaffs_GrossLock(dev);
810         
811         nlinks = 
812         
813         retVal = yaffs_Unlink(yaffs_InodeToObject(dir),dentry->d_name.name);
814         
815         
816         yaffs_GrossUnlock(dev);
817         
818         if( retVal == YAFFS_OK)
819         {
820                 dentry->d_inode->i_nlink--;
821                 return 0;
822         }
823         else
824         {
825                 return -ENOTEMPTY;
826         }
827 }
828
829
830 /*
831  * Create a link...
832  */
833 static int yaffs_link(struct dentry *old_dentry, struct inode * dir, struct dentry * dentry)
834 {
835         struct inode *inode = old_dentry->d_inode;
836         yaffs_Object *obj = NULL;
837         yaffs_Object *link=NULL;
838         yaffs_Device *dev;
839         
840         T((KERN_DEBUG"yaffs_link\n"));
841         
842         obj = yaffs_InodeToObject(inode);
843         dev = obj->myDev;
844         
845         yaffs_GrossLock(dev);
846         
847         link = yaffs_Link(yaffs_InodeToObject(dir),dentry->d_name.name,obj);
848         
849
850         if(link)
851         {
852                 old_dentry->d_inode->i_nlink =  yaffs_GetObjectLinkCount(obj);
853                 d_instantiate(dentry, old_dentry->d_inode);
854                 atomic_inc(&old_dentry->d_inode->i_count);
855                 T((KERN_DEBUG"yaffs_link link count %d i_count %d\n",   
856                         old_dentry->d_inode->i_nlink,atomic_read(&old_dentry->d_inode->i_count)));
857         
858         }
859         
860         yaffs_GrossUnlock(dev);
861         
862
863         if(link)
864         {
865         
866                 return 0;
867         }
868         
869         
870         return -EPERM; 
871 }
872
873
874 static int yaffs_symlink(struct inode * dir, struct dentry *dentry, const char * symname)
875 {
876         yaffs_Object *obj;
877         yaffs_Device *dev;
878         
879         T((KERN_DEBUG"yaffs_symlink\n"));
880         
881         dev = yaffs_InodeToObject(dir)->myDev;
882         yaffs_GrossLock(dev);
883         obj = yaffs_MknodSymLink(yaffs_InodeToObject(dir), dentry->d_name.name, 
884                                                          S_IFLNK | S_IRWXUGO, current->uid, current->gid,
885                                                          symname);
886         yaffs_GrossUnlock(dev);
887
888         if(obj)
889         {
890                 T((KERN_DEBUG"symlink created OK\n"));
891                 return 0;
892         }
893         else
894         {
895                 T((KERN_DEBUG"symlink not created\n"));
896
897         }
898         
899         return -ENOMEM;
900 }
901
902 static int yaffs_sync_object(struct file * file, struct dentry *dentry, int datasync)
903 {
904
905         yaffs_Object *obj;
906         yaffs_Device *dev;
907         
908         obj = yaffs_DentryToObject(dentry);
909
910         dev = obj->myDev;
911         
912         T((KERN_DEBUG"yaffs_sync_object\n"));
913         yaffs_GrossLock(dev);
914         yaffs_FlushFile(obj);
915         yaffs_GrossUnlock(dev);
916         return 0;
917 }
918
919 /*
920  * The VFS layer already does all the dentry stuff for rename.
921  *
922  * NB: POSIX says you can rename an object over an old object of the same name
923  */
924 static int yaffs_rename(struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir,struct dentry *new_dentry)
925 {
926         yaffs_Device *dev;
927         int retVal;
928         
929         dev = yaffs_InodeToObject(old_dir)->myDev;
930
931         yaffs_GrossLock(dev);
932         
933         retVal =  yaffs_RenameObject(yaffs_InodeToObject(old_dir),old_dentry->d_name.name,
934                                          yaffs_InodeToObject(new_dir),new_dentry->d_name.name);
935         yaffs_GrossUnlock(dev);
936         
937         if(retVal == YAFFS_OK)
938         {
939                 return 0;
940         }
941         else
942         {
943                 return -ENOTEMPTY;
944         }
945         
946
947 }
948
949 static int yaffs_setattr(struct dentry *dentry, struct iattr *attr)
950 {
951         struct inode *inode = dentry->d_inode;
952         int error;
953         yaffs_Device *dev;
954         
955         T((KERN_DEBUG"yaffs_setattr of object %d\n",yaffs_InodeToObject(inode)->objectId));
956         
957         if((error = inode_change_ok(inode,attr)) == 0)
958         {
959         
960                 dev = yaffs_InodeToObject(inode)->myDev;
961                 yaffs_GrossLock(dev);
962                 if(yaffs_SetAttributes(yaffs_InodeToObject(inode),attr) == YAFFS_OK)
963                 {
964                         error = 0;
965                 }
966                 else
967                 {
968                         error = -EPERM;
969                 }
970                 yaffs_GrossUnlock(dev);
971                 inode_setattr(inode,attr);
972         }
973         return error;
974 }
975
976 static int yaffs_statfs(struct super_block *sb, struct statfs *buf)
977 {
978         yaffs_Device *dev = yaffs_SuperToDevice(sb);
979         T((KERN_DEBUG"yaffs_statfs\n"));
980
981         yaffs_GrossLock(dev);
982         
983         buf->f_type = YAFFS_MAGIC;
984         buf->f_bsize = sb->s_blocksize;
985         buf->f_namelen = 255;
986         buf->f_blocks = (dev->endBlock - dev->startBlock + 1) * YAFFS_CHUNKS_PER_BLOCK/
987                                                 (sb->s_blocksize/YAFFS_BYTES_PER_CHUNK);
988         buf->f_files = 0;
989         buf->f_ffree = 0;
990         buf->f_bfree = yaffs_GetNumberOfFreeChunks(dev)/
991                                                 (sb->s_blocksize/YAFFS_BYTES_PER_CHUNK);
992         buf->f_bavail =  buf->f_bfree;
993         
994         yaffs_GrossUnlock(dev);
995         return 0;
996 }
997
998 static void yaffs_read_inode (struct inode *inode)
999 {
1000         // NB This is called as a side effect of other functions and
1001         // thus gross locking should always be in place already.
1002         
1003         yaffs_Object *obj ; 
1004         yaffs_Device *dev = yaffs_SuperToDevice(inode->i_sb);
1005         
1006         T((KERN_DEBUG"yaffs_read_inode for %d\n",(int)inode->i_ino));
1007
1008         obj  = yaffs_FindObjectByNumber(dev,inode->i_ino);
1009         
1010         yaffs_FillInodeFromObject(inode,obj);
1011
1012 }
1013
1014
1015 static void yaffs_put_super(struct super_block *sb)
1016 {
1017         yaffs_Device *dev = yaffs_SuperToDevice(sb);
1018         
1019         yaffs_GrossLock(dev);
1020         if(dev->putSuperFunc)
1021         {
1022                  dev->putSuperFunc(sb);
1023         }
1024         yaffs_Deinitialise(dev);
1025         yaffs_GrossUnlock(dev);
1026         
1027         kfree(dev);
1028 }
1029
1030
1031 #ifdef CONFIG_YAFFS_MTD_ENABLED
1032
1033 static void  yaffs_MTDPutSuper(struct super_block *sb)
1034 {
1035         
1036         struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice;
1037         
1038         if(mtd->sync)
1039         {
1040                 mtd->sync(mtd);
1041         }
1042         
1043         put_mtd_device(mtd);
1044 }
1045
1046 #endif
1047
1048 static struct super_block *yaffs_internal_read_super(int useRam, struct super_block * sb, void * data, int silent)
1049 {
1050         int nBlocks;
1051         struct inode * inode;
1052         struct dentry * root;
1053         yaffs_Device *dev;
1054         
1055         sb->s_magic = YAFFS_MAGIC;
1056         sb->s_op = &yaffs_super_ops;
1057         
1058         if(!sb)
1059                 printk(KERN_INFO"yaffs: sb is NULL\n");
1060         else if(!sb->s_dev)
1061                 printk(KERN_INFO"yaffs: sb->s_dev is NULL\n");
1062         else if(! kdevname(sb->s_dev))
1063                 printk(KERN_INFO"yaffs: kdevname is NULL\n");
1064         else
1065                 printk(KERN_INFO"yaffs: dev is %d name is \"%s\"\n", sb->s_dev, kdevname(sb->s_dev));
1066
1067         
1068
1069 #ifdef CONFIG_YAFFS_USE_CHUNK_SIZE
1070         sb->s_blocksize = YAFFS_BYTES_PER_CHUNK;
1071         sb->s_blocksize_bits = YAFFS_CHUNK_SIZE_SHIFT;
1072 #else
1073         sb->s_blocksize = PAGE_CACHE_SIZE;
1074         sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
1075 #endif
1076         T(("yaffs_read_super: %s block size %d\n", useRam ? "RAM" : "MTD",sb->s_blocksize));
1077
1078 #ifdef CONFIG_YAFFS_DISABLE_WRITE_VERIFY
1079         T(("yaffs: Write verification disabled. All guarantees null and void\n");
1080 #endif
1081
1082
1083         
1084         if(useRam)
1085         {
1086
1087 #ifdef CONFIG_YAFFS_RAM_ENABLED
1088                 // Set the yaffs_Device up for ram emulation
1089
1090                 sb->u.generic_sbp =     dev = kmalloc(sizeof(yaffs_Device),GFP_KERNEL);
1091                 if(!dev)
1092                 {
1093                         // Deep shit could not allocate device structure
1094                         printk(KERN_DEBUG"yaffs_read_super: Failed trying to allocate yaffs_Device. Terminating debug.\n");
1095                         return NULL;
1096                 }
1097
1098                 memset(dev,0,sizeof(yaffs_Device));
1099                 dev->genericDevice = NULL; // Not used for RAM emulation.
1100
1101                 nBlocks = YAFFS_RAM_EMULATION_SIZE / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
1102                 dev->startBlock = 1;  // Don't use block 0
1103                 dev->endBlock = nBlocks - 1;
1104
1105                 dev->writeChunkToNAND = nandemul_WriteChunkToNAND;
1106                 dev->readChunkFromNAND = nandemul_ReadChunkFromNAND;
1107                 dev->eraseBlockInNAND = nandemul_EraseBlockInNAND;
1108                 dev->initialiseNAND = nandemul_InitialiseNAND;
1109                 
1110 #endif
1111
1112         }
1113         else
1114         {       
1115 #ifdef CONFIG_YAFFS_MTD_ENABLED
1116                 struct mtd_info *mtd;
1117                 
1118                 printk(KERN_DEBUG "yaffs: Attempting MTD mount on %u.%u, \"%s\"\n",
1119                  MAJOR(sb->s_dev),MINOR(sb->s_dev),kdevname(sb->s_dev));
1120                         
1121                 // Hope it's a NAND mtd
1122                 mtd = get_mtd_device(NULL, MINOR(sb->s_dev));
1123                 if (!mtd) 
1124                 {
1125                         printk(KERN_DEBUG "yaffs: MTD device #%u doesn't appear to exist\n", MINOR(sb->s_dev));
1126                         return NULL;
1127                 }
1128                 
1129                 if(mtd->type != MTD_NANDFLASH)
1130                 {
1131                         printk(KERN_DEBUG "yaffs: MTD device is not NAND it's type %d\n", mtd->type);
1132                         return NULL;
1133                 }
1134
1135                 printk(KERN_DEBUG" erase %x\n",mtd->erase);
1136                 printk(KERN_DEBUG" read %x\n",mtd->read);
1137                 printk(KERN_DEBUG" write %x\n",mtd->write);
1138                 printk(KERN_DEBUG" readoob %x\n",mtd->read_oob);
1139                 printk(KERN_DEBUG" writeoob %x\n",mtd->write_oob);
1140                 printk(KERN_DEBUG" oobblock %x\n",mtd->oobblock);
1141                 printk(KERN_DEBUG" oobsize %x\n",mtd->oobsize);
1142
1143
1144                 if(!mtd->erase ||
1145                    !mtd->read  ||
1146                    !mtd->write ||
1147                    !mtd->read_oob ||
1148                    !mtd->write_oob)
1149                 {
1150                         printk(KERN_DEBUG "yaffs: MTD device does not support required functions\n");
1151                         return NULL;
1152                 }
1153                 
1154                 if(mtd->oobblock != YAFFS_BYTES_PER_CHUNK ||
1155                    mtd->oobsize != YAFFS_BYTES_PER_SPARE)
1156                 {
1157                         printk(KERN_DEBUG "yaffs: MTD device does not support have the right page sizes\n");
1158                         return NULL;
1159                 }
1160                    
1161
1162                 // OK, so if we got here, we have an MTD that's NAND and looks 
1163                 // like it has the right capabilities
1164                 // Set the yaffs_Device up for ram emulation
1165
1166                 sb->u.generic_sbp =     dev = kmalloc(sizeof(yaffs_Device),GFP_KERNEL);
1167                 if(!dev)
1168                 {
1169                         // Deep shit could not allocate device structure
1170                         printk(KERN_DEBUG"yaffs_read_super: Failed trying to allocate yaffs_Device. Terminating debug.\n");
1171                         return NULL;
1172                 }
1173
1174                 memset(dev,0,sizeof(yaffs_Device));
1175                 dev->genericDevice = mtd; 
1176
1177                 // Set up the memory size parameters....
1178                 
1179                 nBlocks = mtd->size / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
1180                 dev->startBlock = 1;  // Don't use block 0
1181                 dev->endBlock = nBlocks - 1;
1182
1183                 // ... and the functions.
1184                 dev->writeChunkToNAND = nandmtd_WriteChunkToNAND;
1185                 dev->readChunkFromNAND = nandmtd_ReadChunkFromNAND;
1186                 dev->eraseBlockInNAND = nandmtd_EraseBlockInNAND;
1187                 dev->initialiseNAND = nandmtd_InitialiseNAND;
1188                 
1189                 dev->putSuperFunc = yaffs_MTDPutSuper;
1190 #endif
1191         }
1192
1193         init_MUTEX(&dev->grossLock);
1194         
1195         
1196         yaffs_GrossLock(dev);
1197         yaffs_GutsInitialise(yaffs_SuperToDevice(sb));
1198
1199         T(("yaffs_read_super: guts initialised\n"));
1200
1201         // Create root inode
1202         inode = yaffs_get_inode(sb, S_IFDIR | 0755, 0,yaffs_Root(yaffs_SuperToDevice(sb)));
1203
1204         yaffs_GrossUnlock(dev);
1205
1206         if (!inode)
1207                 return NULL;
1208
1209         T(("yaffs_read_super: got root inode\n"));
1210                 
1211
1212         root = d_alloc_root(inode);
1213
1214         T(("yaffs_read_super: d_alloc_root done\n"));
1215
1216         if (!root) {
1217                 iput(inode);
1218                 return NULL;
1219         }
1220         sb->s_root = root;
1221
1222         T(("yaffs_read_super: done\n"));
1223         return sb;
1224 }
1225
1226 #ifdef CONFIG_YAFFS_MTD_ENABLED
1227 static struct super_block *yaffs_read_super(struct super_block * sb, void * data, int silent)
1228 {
1229         return yaffs_internal_read_super(0,sb,data,silent);
1230 }
1231
1232 static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super, FS_REQUIRES_DEV);
1233 #endif
1234
1235 #ifdef CONFIG_YAFFS_RAM_ENABLED
1236
1237 static struct super_block *yaffs_ram_read_super(struct super_block * sb, void * data, int silent)
1238 {
1239         return yaffs_internal_read_super(1,sb,data,silent);
1240 }
1241
1242 static DECLARE_FSTYPE(yaffs_ram_fs_type, "yaffsram", yaffs_ram_read_super, FS_SINGLE);
1243 #endif // CONFIG_YAFFS_RAM_ENABLED
1244
1245
1246 static struct proc_dir_entry *my_proc_entry;
1247 static struct proc_dir_entry *my_proc_ram_write_entry;
1248
1249
1250 static int  yaffs_proc_read(
1251         char *page,
1252         char **start,
1253         off_t offset,
1254         int count,
1255         int *eof,
1256         void *data
1257         )
1258 {
1259
1260         static char my_buffer[1000];
1261
1262         if (offset > 0) return 0;
1263
1264         /* Fill the buffer and get its length */
1265         sprintf( my_buffer, 
1266                 "YAFFS built:"__DATE__ " "__TIME__"\n"
1267                 
1268         );
1269
1270         strcpy(page,my_buffer);
1271         return strlen(my_buffer);
1272 }
1273
1274
1275 static int  yaffs_proc_ram_write(
1276         char *page,
1277         char **start,
1278         off_t offset,
1279         int count,
1280         int *eof,
1281         void *data
1282         )
1283 {
1284
1285         printk(KERN_DEBUG "yaffs write size %d\n",count);
1286         return count;
1287 }
1288
1289 static int __init init_yaffs_fs(void)
1290 {
1291         int error = 0;
1292         
1293         printk(KERN_DEBUG "yaffs " __DATE__ " " __TIME__ " Initialisation\n");
1294 #ifdef CONFIG_YAFFS_USE_GENERIC_RW
1295         printk(KERN_DEBUG "yaffs is using generic read/write (caching)\n");
1296 #else
1297         printk(KERN_DEBUG "yaffs is using direct read/write (uncached)\n");
1298 #endif
1299
1300
1301     /* Install the proc_fs entry */
1302     my_proc_entry = create_proc_read_entry("yaffs",
1303                                            S_IRUGO | S_IFREG,
1304                                            &proc_root,
1305                                            yaffs_proc_read,
1306                                            NULL);
1307     if(!my_proc_entry)
1308     {
1309        return -ENOMEM;
1310     }
1311
1312 #ifdef CONFIG_YAFFS_RAM_ENABLED
1313
1314     my_proc_ram_write_entry = create_proc_entry("yaffs_ram",
1315                                            S_IRUGO | S_IFREG,
1316                                            &proc_root);
1317  
1318     if(!my_proc_ram_write_entry)
1319     {
1320        return -ENOMEM;
1321     }
1322     else
1323     {
1324         my_proc_ram_write_entry->write_proc = yaffs_proc_ram_write;
1325     }
1326     error = register_filesystem(&yaffs_ram_fs_type);
1327     if(error)
1328     {
1329         return error;
1330     }
1331 #endif //CONFIG_YAFFS_RAM_ENABLED
1332
1333 #ifdef CONFIG_YAFFS_MTD_ENABLED
1334         error = register_filesystem(&yaffs_fs_type);
1335         if(error)
1336         {
1337 #ifdef CONFIG_YAFFS_RAM_ENABLED
1338                 unregister_filesystem(&yaffs_ram_fs_type);
1339 #endif //CONFIG_YAFFS_RAM_ENABLED
1340         }
1341 #endif // CONFIG_YAFFS_MTD_ENABLED
1342
1343         return error;
1344 }
1345
1346 static void __exit exit_yaffs_fs(void)
1347 {
1348         printk(KERN_DEBUG "yaffs " __DATE__ " " __TIME__ " Clean up\n");
1349
1350     remove_proc_entry("yaffs",&proc_root);
1351     
1352 #ifdef CONFIG_YAFFS_RAM_ENABLED
1353         unregister_filesystem(&yaffs_ram_fs_type);
1354 #endif
1355 #ifdef CONFIG_YAFFS_MTD_ENABLED
1356         unregister_filesystem(&yaffs_fs_type);
1357 #endif
1358
1359 }
1360
1361 module_init(init_yaffs_fs)
1362 module_exit(exit_yaffs_fs)
1363
1364 MODULE_DESCRIPTION("YAFFS - a NAND specific flash file system");
1365 MODULE_AUTHOR("Charles Manning, Aleph One Ltd., 2002");
1366 MODULE_LICENSE("GPL");
1367