annotate yaffs_fs.c @ 67:cb8afec5ad31

Fix an error in writepage when a file is extended. When a file is extended with truncate(), the call to inode_setattr() in yaffs_setattr() call vmtruncate() which itself call a bunches of yaffs_writepage(). There we must NOT fill page whit index greater that the one given by the inode 'cos these pages refers to parts of the file which doesn't physically exists.
author luc <luc>
date Thu, 04 Aug 2005 22:47:36 +0000
parents 49f66fca0b09
children ddb4fe818ca3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1 /*
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
2 * YAFFS: Yet another FFS. A NAND-flash specific file system.
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
3 * yaffs_fs.c
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
4 *
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
5 * Copyright (C) 2002 Aleph One Ltd.
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
6 * for Toby Churchill Ltd and Brightstar Engineering
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
7 *
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
8 * Created by Charles Manning <charles@aleph1.co.uk>
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
9 *
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
10 * This program is free software; you can redistribute it and/or modify
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
11 * it under the terms of the GNU General Public License version 2 as
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
12 * published by the Free Software Foundation.
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
13 *
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
14 * This is the file system front-end to YAFFS that hooks it up to
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
15 * the VFS.
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
16 *
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
17 * Special notes:
22
0b57027b96fe Some improvements to garbage collection and st_xxx to yst_xxx changes
charles <charles>
parents: 19
diff changeset
18 * >> 2.4: sb->u.generic_sbp points to the yaffs_Device associated with this superblock
0b57027b96fe Some improvements to garbage collection and st_xxx to yst_xxx changes
charles <charles>
parents: 19
diff changeset
19 * >> 2.6: sb->s_fs_info points to the yaffs_Device associated with this superblock
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
20 * >> inode->u.generic_ip points to the associated yaffs_Object.
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
21 *
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
22 *
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
23 * Acknowledgements:
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
24 * * Luc van OostenRyck for numerous patches.
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
25 * * Nick Bane for numerous patches.
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
26 * * Nick Bane for 2.5/2.6 integration.
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
27 * * Andras Toth for mknod rdev issue.
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
28 * * Michael Fischer for finding the problem with inode inconsistency.
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
29 * * Some code bodily lifted from JFFS2.
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
30 */
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
31
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
32
67
cb8afec5ad31 Fix an error in writepage when a file is extended.
luc <luc>
parents: 61
diff changeset
33 const char *yaffs_fs_c_version = "$Id: yaffs_fs.c,v 1.27 2005-08-04 22:47:36 luc Exp $";
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
34 extern const char *yaffs_guts_c_version;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
35
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
36
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
37 #include <linux/config.h>
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
38 #include <linux/kernel.h>
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
39 #include <linux/module.h>
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
40 #include <linux/version.h>
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
41 #include <linux/slab.h>
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
42 #include <linux/init.h>
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
43 #include <linux/list.h>
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
44 #include <linux/fs.h>
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
45 #include <linux/proc_fs.h>
27
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
46 #include <linux/smp_lock.h>
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
47 #include <linux/pagemap.h>
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
48 #include <linux/mtd/mtd.h>
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
49 #include <linux/interrupt.h>
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
50 #include <linux/string.h>
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
51
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
52
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
53 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
54
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
55 #include <linux/statfs.h> /* Added NCB 15-8-2003 */
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
56 #include <asm/statfs.h>
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
57 #define UnlockPage(p) unlock_page(p)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
58 #define Page_Uptodate(page) test_bit(PG_uptodate, &(page)->flags)
37
843d9d0add74 Fix devname which was faked by always using "(unavailable)".
luc <luc>
parents: 36
diff changeset
59 #define yaffs_devname(sb, buf) bdevname(sb->s_bdev, buf) // FIXME: use sb->s_id instead ?
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
60
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
61 #else
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
62
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
63 #include <linux/locks.h>
37
843d9d0add74 Fix devname which was faked by always using "(unavailable)".
luc <luc>
parents: 36
diff changeset
64 #define BDEVNAME_SIZE 0
843d9d0add74 Fix devname which was faked by always using "(unavailable)".
luc <luc>
parents: 36
diff changeset
65 #define yaffs_devname(sb, buf) kdevname(sb->s_dev)
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
66
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
67 #endif
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
68
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
69 #include <asm/uaccess.h>
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
70
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
71 #include "yportenv.h"
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
72 #include "yaffs_guts.h"
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
73
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
74
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
75
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
76
9
09ae5ca61698 Add patches from Nick Banes for compatability
charles <charles>
parents: 7
diff changeset
77 unsigned yaffs_traceMask = YAFFS_TRACE_ALWAYS | YAFFS_TRACE_BAD_BLOCKS;
09ae5ca61698 Add patches from Nick Banes for compatability
charles <charles>
parents: 7
diff changeset
78 //unsigned yaffs_traceMask = 0xFFFFFFFF;
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
79
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
80
49
05fb5e11130f Remove CONFIG_YAFFS_USE_CHUNK_SIZE
marty <marty>
parents: 45
diff changeset
81 #ifdef CONFIG_YAFFS_YAFFS1
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
82 #include <linux/mtd/mtd.h>
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
83 #include "yaffs_mtdif.h"
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
84 #include "yaffs_mtdif2.h"
49
05fb5e11130f Remove CONFIG_YAFFS_USE_CHUNK_SIZE
marty <marty>
parents: 45
diff changeset
85 #endif //CONFIG_YAFFS_YAFFS1
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
86
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
87 //#define T(x) printk x
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
88
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
89
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
90
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
91 #define yaffs_InodeToObject(iptr) ((yaffs_Object *)((iptr)->u.generic_ip))
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
92 #define yaffs_DentryToObject(dptr) yaffs_InodeToObject((dptr)->d_inode)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
93
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
94 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
95 #define yaffs_SuperToDevice(sb) ((yaffs_Device *)sb->s_fs_info)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
96 #else
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
97 #define yaffs_SuperToDevice(sb) ((yaffs_Device *)sb->u.generic_sbp)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
98 #endif
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
99
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
100
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
101 static void yaffs_put_super(struct super_block *sb);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
102
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
103 static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, loff_t *pos);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
104
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
105 static int yaffs_file_flush(struct file* file);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
106
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
107 static int yaffs_sync_object(struct file * file, struct dentry *dentry, int datasync);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
108
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
109 static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
110
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
111 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
112 static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *n);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
113 static struct dentry * yaffs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *n);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
114 #else
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
115 static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
116 static struct dentry * yaffs_lookup(struct inode *dir, struct dentry *dentry);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
117 #endif
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
118 static int yaffs_link(struct dentry *old_dentry, struct inode * dir, struct dentry * dentry);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
119 static int yaffs_unlink(struct inode * dir, struct dentry *dentry);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
120 static int yaffs_symlink(struct inode * dir, struct dentry *dentry, const char * symname);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
121 static int yaffs_mkdir(struct inode * dir, struct dentry * dentry, int mode);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
122
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
123 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
124 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
125 #else
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
126 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
127 #endif
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
128 static int yaffs_rename(struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir,struct dentry *new_dentry);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
129 static int yaffs_setattr(struct dentry *dentry, struct iattr *attr);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
130
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
131 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
132 static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
133 #else
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
134 static int yaffs_statfs(struct super_block *sb, struct statfs *buf);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
135 #endif
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
136 static void yaffs_read_inode (struct inode *inode);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
137
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
138 static void yaffs_put_inode (struct inode *inode);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
139 static void yaffs_delete_inode(struct inode *);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
140 static void yaffs_clear_inode(struct inode *);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
141
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
142 static int yaffs_readpage(struct file *file, struct page * page);
23
7942535c12c6 Apply Luc's patches
charles <charles>
parents: 22
diff changeset
143 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
7942535c12c6 Apply Luc's patches
charles <charles>
parents: 22
diff changeset
144 static int yaffs_writepage(struct page *page, struct writeback_control *wbc);
7942535c12c6 Apply Luc's patches
charles <charles>
parents: 22
diff changeset
145 #else
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
146 static int yaffs_writepage(struct page *page);
23
7942535c12c6 Apply Luc's patches
charles <charles>
parents: 22
diff changeset
147 #endif
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
148 static int yaffs_prepare_write(struct file *f, struct page *pg, unsigned offset, unsigned to);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
149 static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset, unsigned to);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
150
23
7942535c12c6 Apply Luc's patches
charles <charles>
parents: 22
diff changeset
151 static int yaffs_readlink(struct dentry *dentry, char __user *buffer, int buflen);
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
152 static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
153
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
154
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
155
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
156 static struct address_space_operations yaffs_file_address_operations = {
29
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
157 .readpage = yaffs_readpage,
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
158 .writepage = yaffs_writepage,
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
159 .prepare_write = yaffs_prepare_write,
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
160 .commit_write = yaffs_commit_write,
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
161 };
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
162
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
163 static struct file_operations yaffs_file_operations = {
29
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
164 .read = generic_file_read,
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
165 .write = generic_file_write,
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
166 .mmap = generic_file_mmap,
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
167 .flush = yaffs_file_flush,
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
168 .fsync = yaffs_sync_object,
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
169 };
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
170
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
171 static struct inode_operations yaffs_file_inode_operations = {
29
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
172 .setattr = yaffs_setattr,
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
173 };
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
174
43
ea3f08fe855b applied patch 13-sparse-fix--make-some-symbol-static.diff
marty <marty>
parents: 41
diff changeset
175 static struct inode_operations yaffs_symlink_inode_operations = {
29
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
176 .readlink = yaffs_readlink,
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
177 .follow_link = yaffs_follow_link,
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
178 .setattr = yaffs_setattr,
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
179 };
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
180
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
181 static struct inode_operations yaffs_dir_inode_operations = {
29
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
182 .create = yaffs_create,
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
183 .lookup = yaffs_lookup,
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
184 .link = yaffs_link,
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
185 .unlink = yaffs_unlink,
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
186 .symlink = yaffs_symlink,
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
187 .mkdir = yaffs_mkdir,
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
188 .rmdir = yaffs_unlink,
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
189 .mknod = yaffs_mknod,
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
190 .rename = yaffs_rename,
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
191 .setattr = yaffs_setattr,
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
192 };
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
193
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
194 static struct file_operations yaffs_dir_operations = {
29
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
195 .read = generic_read_dir,
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
196 .readdir = yaffs_readdir,
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
197 .fsync = yaffs_sync_object,
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
198 };
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
199
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
200 static struct super_operations yaffs_super_ops = {
29
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
201 .statfs = yaffs_statfs,
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
202 .read_inode = yaffs_read_inode,
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
203 .put_inode = yaffs_put_inode,
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
204 .put_super = yaffs_put_super,
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
205 .delete_inode = yaffs_delete_inode,
28edf97b9d9a Clean up field assignments
charles <charles>
parents: 27
diff changeset
206 .clear_inode = yaffs_clear_inode,
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
207 };
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
208
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
209
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
210
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
211 static void yaffs_GrossLock(yaffs_Device *dev)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
212 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
213 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs locking\n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
214
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
215 down(&dev->grossLock);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
216 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
217
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
218 static void yaffs_GrossUnlock(yaffs_Device *dev)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
219 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
220 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs unlocking\n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
221 up(&dev->grossLock);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
222
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
223 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
224
23
7942535c12c6 Apply Luc's patches
charles <charles>
parents: 22
diff changeset
225 static int yaffs_readlink(struct dentry *dentry, char __user *buffer, int buflen)
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
226 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
227 unsigned char *alias;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
228 int ret;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
229
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
230 yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
231
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
232
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
233 yaffs_GrossLock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
234
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
235 alias = yaffs_GetSymlinkAlias(yaffs_DentryToObject(dentry));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
236
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
237 yaffs_GrossUnlock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
238
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
239 if(!alias)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
240 return -ENOMEM;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
241
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
242 ret = vfs_readlink(dentry, buffer, buflen, alias);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
243 kfree(alias);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
244 return ret;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
245 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
246
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
247 static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
248 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
249 unsigned char *alias;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
250 int ret;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
251 yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
252
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
253
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
254 yaffs_GrossLock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
255
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
256 alias = yaffs_GetSymlinkAlias(yaffs_DentryToObject(dentry));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
257
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
258 yaffs_GrossUnlock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
259
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
260 if(!alias)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
261 return -ENOMEM;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
262
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
263 ret = vfs_follow_link(nd,alias);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
264 kfree(alias);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
265 return ret;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
266 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
267
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
268
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
269 struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,yaffs_Object *obj);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
270
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
271 /*
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
272 * Lookup is used to find objects in the fs
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
273 */
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
274 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
275
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
276 static struct dentry * yaffs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *n)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
277 #else
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
278 static struct dentry * yaffs_lookup(struct inode *dir, struct dentry *dentry)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
279 #endif
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
280 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
281 yaffs_Object *obj;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
282 struct inode *inode = NULL; // NCB 2.5/2.6 needs NULL here
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
283
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
284 yaffs_Device *dev = yaffs_InodeToObject(dir)->myDev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
285
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
286
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
287 yaffs_GrossLock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
288
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
289
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
290 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_lookup for %d:%s\n",yaffs_InodeToObject(dir)->objectId,dentry->d_name.name));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
291
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
292 obj = yaffs_FindObjectByName(yaffs_InodeToObject(dir),dentry->d_name.name);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
293
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
294 obj = yaffs_GetEquivalentObject(obj); // in case it was a hardlink
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
295
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
296
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
297
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
298 if(obj)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
299 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
300 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_lookup found %d\n",obj->objectId));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
301
22
0b57027b96fe Some improvements to garbage collection and st_xxx to yst_xxx changes
charles <charles>
parents: 19
diff changeset
302 inode = yaffs_get_inode(dir->i_sb, obj->yst_mode,0,obj);
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
303
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
304 if(inode)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
305 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
306 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_loookup dentry \n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
307 /* #if 0 asserted by NCB for 2.5/6 compatability - falls through to d_add even if NULL inode */
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
308 #if 0
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
309 //dget(dentry); // try to solve directory bug
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
310 d_add(dentry,inode);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
311
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
312 yaffs_GrossUnlock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
313
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
314 // return dentry;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
315 return NULL;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
316 #endif
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
317 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
318
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
319 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
320 else
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
321 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
322 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_lookup not found\n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
323
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
324 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
325 yaffs_GrossUnlock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
326
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
327 /* added NCB for 2.5/6 compatability - forces add even if inode is NULL which creates dentry hash*/
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
328 d_add(dentry,inode);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
329
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
330 return NULL;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
331 // return (ERR_PTR(-EIO));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
332
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
333 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
334
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
335 // For now put inode is just for debugging
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
336 // Put inode is called when the inode **structure** is put.
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
337 static void yaffs_put_inode(struct inode *inode)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
338 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
339 T(YAFFS_TRACE_OS,("yaffs_put_inode: ino %d, count %d\n",(int)inode->i_ino, atomic_read(&inode->i_count)));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
340
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
341 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
342
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
343 // clear is called to tell the fs to release any per-inode data it holds
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
344 static void yaffs_clear_inode(struct inode *inode)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
345 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
346 yaffs_Object *obj;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
347 yaffs_Device *dev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
348
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
349 obj = yaffs_InodeToObject(inode);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
350
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
351 T(YAFFS_TRACE_OS,("yaffs_clear_inode: ino %d, count %d %s\n",(int)inode->i_ino, atomic_read(&inode->i_count),
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
352 obj ? "object exists" : "null object"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
353
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
354 if(obj)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
355 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
356 dev = obj->myDev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
357 yaffs_GrossLock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
358
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
359 // Clear the association between the inode ant the yaffs_Object.
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
360 obj->myInode = NULL;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
361 inode->u.generic_ip = NULL;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
362
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
363 // If the object freeing was deferred, then the real free happens now.
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
364 // This should fix the inode inconsistency problem.
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
365
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
366 yaffs_HandleDeferedFree(obj);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
367
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
368 yaffs_GrossUnlock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
369 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
370
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
371
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
372 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
373
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
374 // delete is called when the link count is zero and the inode
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
375 // is put (ie. nobody wants to know about it anymore, time to
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
376 // delete the file).
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
377 // NB Must call clear_inode()
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
378 static void yaffs_delete_inode(struct inode *inode)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
379 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
380 yaffs_Object *obj = yaffs_InodeToObject(inode);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
381 yaffs_Device *dev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
382
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
383 T(YAFFS_TRACE_OS,("yaffs_delete_inode: ino %d, count %d %s\n",(int)inode->i_ino, atomic_read(&inode->i_count),
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
384 obj ? "object exists" : "null object"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
385
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
386 if(obj)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
387 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
388 dev = obj->myDev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
389 yaffs_GrossLock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
390 yaffs_DeleteFile(obj);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
391 yaffs_GrossUnlock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
392 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
393 clear_inode(inode);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
394 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
395
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
396
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
397 static int yaffs_file_flush(struct file* file)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
398 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
399 yaffs_Object *obj = yaffs_DentryToObject(file->f_dentry);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
400
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
401 yaffs_Device *dev = obj->myDev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
402
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
403 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_file_flush object %d (%s)\n",obj->objectId,
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
404 obj->dirty ? "dirty" : "clean"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
405
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
406 yaffs_GrossLock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
407
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
408 yaffs_FlushFile(obj,1);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
409
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
410 yaffs_GrossUnlock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
411
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
412 return 0;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
413 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
414
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
415
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
416
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
417 static int yaffs_readpage_nolock(struct file *f, struct page * pg)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
418 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
419 // Lifted from jffs2
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
420
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
421 yaffs_Object *obj;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
422 unsigned char *pg_buf;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
423 int ret;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
424
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
425 yaffs_Device *dev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
426
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
427 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_readpage at %08x, size %08x\n",
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
428 (unsigned)(pg->index << PAGE_CACHE_SHIFT), (unsigned)PAGE_CACHE_SIZE));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
429
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
430 obj = yaffs_DentryToObject(f->f_dentry);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
431
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
432 dev = obj->myDev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
433
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
434
23
7942535c12c6 Apply Luc's patches
charles <charles>
parents: 22
diff changeset
435 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
7942535c12c6 Apply Luc's patches
charles <charles>
parents: 22
diff changeset
436 BUG_ON(!PageLocked(pg));
7942535c12c6 Apply Luc's patches
charles <charles>
parents: 22
diff changeset
437 #else
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
438 if (!PageLocked(pg))
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
439 PAGE_BUG(pg);
23
7942535c12c6 Apply Luc's patches
charles <charles>
parents: 22
diff changeset
440 #endif
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
441
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
442 pg_buf = kmap(pg);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
443 /* FIXME: Can kmap fail? */
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
444
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
445 yaffs_GrossLock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
446
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
447 ret = yaffs_ReadDataFromFile(obj, pg_buf, pg->index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
448
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
449 yaffs_GrossUnlock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
450
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
451 if(ret >= 0) ret = 0;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
452
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
453 if (ret) {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
454 ClearPageUptodate(pg);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
455 SetPageError(pg);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
456 } else {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
457 SetPageUptodate(pg);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
458 ClearPageError(pg);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
459 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
460
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
461 flush_dcache_page(pg);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
462 kunmap(pg);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
463
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
464
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
465 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_readpage done\n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
466 return ret;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
467 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
468
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
469 static int yaffs_readpage_unlock(struct file *f, struct page *pg)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
470 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
471 int ret = yaffs_readpage_nolock(f,pg);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
472 UnlockPage(pg);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
473 return ret;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
474 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
475
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
476 static int yaffs_readpage(struct file *f, struct page * pg)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
477 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
478 return yaffs_readpage_unlock(f,pg);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
479 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
480
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
481 // writepage inspired by/stolen from smbfs
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
482 //
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
483
23
7942535c12c6 Apply Luc's patches
charles <charles>
parents: 22
diff changeset
484 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
7942535c12c6 Apply Luc's patches
charles <charles>
parents: 22
diff changeset
485 static int yaffs_writepage(struct page *page, struct writeback_control *wbc)
7942535c12c6 Apply Luc's patches
charles <charles>
parents: 22
diff changeset
486 #else
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
487 static int yaffs_writepage(struct page *page)
23
7942535c12c6 Apply Luc's patches
charles <charles>
parents: 22
diff changeset
488 #endif
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
489 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
490 struct address_space *mapping = page->mapping;
67
cb8afec5ad31 Fix an error in writepage when a file is extended.
luc <luc>
parents: 61
diff changeset
491 loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
492 struct inode *inode;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
493 unsigned long end_index;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
494 char *buffer;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
495 yaffs_Object *obj;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
496 int nWritten = 0;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
497 unsigned nBytes;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
498
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
499 if (!mapping)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
500 BUG();
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
501 inode = mapping->host;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
502 if (!inode)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
503 BUG();
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
504
67
cb8afec5ad31 Fix an error in writepage when a file is extended.
luc <luc>
parents: 61
diff changeset
505 if (offset > inode->i_size)
cb8afec5ad31 Fix an error in writepage when a file is extended.
luc <luc>
parents: 61
diff changeset
506 {
cb8afec5ad31 Fix an error in writepage when a file is extended.
luc <luc>
parents: 61
diff changeset
507 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_writepage at %08x, inode size = %08x!!!\n", (unsigned)(page->index << PAGE_CACHE_SHIFT), (unsigned) inode->i_size));
cb8afec5ad31 Fix an error in writepage when a file is extended.
luc <luc>
parents: 61
diff changeset
508 T(YAFFS_TRACE_OS,(KERN_DEBUG" -> don't care!!\n"));
cb8afec5ad31 Fix an error in writepage when a file is extended.
luc <luc>
parents: 61
diff changeset
509 unlock_page(page);
cb8afec5ad31 Fix an error in writepage when a file is extended.
luc <luc>
parents: 61
diff changeset
510 return 0;
cb8afec5ad31 Fix an error in writepage when a file is extended.
luc <luc>
parents: 61
diff changeset
511 }
cb8afec5ad31 Fix an error in writepage when a file is extended.
luc <luc>
parents: 61
diff changeset
512
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
513 end_index = inode->i_size >> PAGE_CACHE_SHIFT;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
514
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
515 /* easy case */
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
516 if (page->index < end_index)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
517 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
518 nBytes = PAGE_CACHE_SIZE;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
519 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
520 else
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
521 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
522 nBytes = inode->i_size & (PAGE_CACHE_SIZE-1);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
523 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
524 // What's happening here?
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
525 ///* OK, are we completely out? */
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
526 //if (page->index >= end_index+1 || !offset)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
527 // return -EIO;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
528
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
529 get_page(page);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
530
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
531
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
532 buffer = kmap(page);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
533
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
534 obj = yaffs_InodeToObject(inode);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
535 yaffs_GrossLock(obj->myDev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
536
67
cb8afec5ad31 Fix an error in writepage when a file is extended.
luc <luc>
parents: 61
diff changeset
537 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_writepage at %08x, size %08x\n", (unsigned)(page->index << PAGE_CACHE_SHIFT), nBytes));
cb8afec5ad31 Fix an error in writepage when a file is extended.
luc <luc>
parents: 61
diff changeset
538 T(YAFFS_TRACE_OS,(KERN_DEBUG"writepag0: obj = %05x, ino = %05x\n", (int) obj->variant.fileVariant.fileSize, (int) inode->i_size));
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
539
18
47d3aadf185a Add cache write through and some benign fixes
charles <charles>
parents: 15
diff changeset
540 nWritten = yaffs_WriteDataToFile(obj,buffer,page->index << PAGE_CACHE_SHIFT,nBytes,0);
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
541
67
cb8afec5ad31 Fix an error in writepage when a file is extended.
luc <luc>
parents: 61
diff changeset
542 T(YAFFS_TRACE_OS,(KERN_DEBUG"writepag1: obj = %05x, ino = %05x\n", (int) obj->variant.fileVariant.fileSize, (int) inode->i_size));
cb8afec5ad31 Fix an error in writepage when a file is extended.
luc <luc>
parents: 61
diff changeset
543
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
544 yaffs_GrossUnlock(obj->myDev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
545
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
546 kunmap(page);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
547 SetPageUptodate(page);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
548 UnlockPage(page);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
549 put_page(page);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
550
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
551 return (nWritten == nBytes) ? 0 : -ENOSPC;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
552 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
553
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
554
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
555
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
556 static int yaffs_prepare_write(struct file *f, struct page *pg, unsigned offset, unsigned to)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
557 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
558
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
559 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_prepair_write\n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
560 if(!Page_Uptodate(pg) && (offset || to < PAGE_CACHE_SIZE))
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
561 return yaffs_readpage_nolock(f,pg);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
562
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
563 return 0;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
564
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
565 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
566
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
567 static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset, unsigned to)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
568 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
569
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
570 void *addr = page_address(pg) + offset;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
571 loff_t pos = (((loff_t)pg->index) << PAGE_CACHE_SHIFT) + offset;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
572 int nBytes = to - offset;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
573 int nWritten;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
574
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
575 unsigned spos = pos;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
576 unsigned saddr = (unsigned)addr;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
577
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
578 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_commit_write addr %x pos %x nBytes %d\n",saddr,spos,nBytes));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
579
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
580 nWritten = yaffs_file_write(f,addr, nBytes, &pos);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
581
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
582 if(nWritten != nBytes)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
583 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
584 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_commit_write not same size nWritten %d nBytes %d\n",nWritten,nBytes));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
585 SetPageError(pg);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
586 ClearPageUptodate(pg);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
587 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
588 else
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
589 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
590 SetPageUptodate(pg);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
591 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
592
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
593 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_commit_write returning %d\n",nWritten));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
594
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
595 return nWritten;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
596
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
597 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
598
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
599
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
600
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
601 static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object *obj)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
602 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
603 if (inode && obj)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
604 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
605 inode->i_ino = obj->objectId;
22
0b57027b96fe Some improvements to garbage collection and st_xxx to yst_xxx changes
charles <charles>
parents: 19
diff changeset
606 inode->i_mode = obj->yst_mode;
0b57027b96fe Some improvements to garbage collection and st_xxx to yst_xxx changes
charles <charles>
parents: 19
diff changeset
607 inode->i_uid = obj->yst_uid;
0b57027b96fe Some improvements to garbage collection and st_xxx to yst_xxx changes
charles <charles>
parents: 19
diff changeset
608 inode->i_gid = obj->yst_gid;
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
609 inode->i_blksize = inode->i_sb->s_blocksize;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
610 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
611
22
0b57027b96fe Some improvements to garbage collection and st_xxx to yst_xxx changes
charles <charles>
parents: 19
diff changeset
612 inode->i_rdev = old_decode_dev(obj->yst_rdev);
0b57027b96fe Some improvements to garbage collection and st_xxx to yst_xxx changes
charles <charles>
parents: 19
diff changeset
613 inode->i_atime.tv_sec = (time_t)(obj->yst_atime);
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
614 inode->i_atime.tv_nsec = 0;
22
0b57027b96fe Some improvements to garbage collection and st_xxx to yst_xxx changes
charles <charles>
parents: 19
diff changeset
615 inode->i_mtime.tv_sec = (time_t)obj->yst_mtime;
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
616 inode->i_mtime.tv_nsec =0;
22
0b57027b96fe Some improvements to garbage collection and st_xxx to yst_xxx changes
charles <charles>
parents: 19
diff changeset
617 inode->i_ctime.tv_sec = (time_t)obj->yst_ctime;
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
618 inode->i_ctime.tv_nsec = 0;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
619 #else
22
0b57027b96fe Some improvements to garbage collection and st_xxx to yst_xxx changes
charles <charles>
parents: 19
diff changeset
620 inode->i_rdev = obj->yst_rdev;
0b57027b96fe Some improvements to garbage collection and st_xxx to yst_xxx changes
charles <charles>
parents: 19
diff changeset
621 inode->i_atime = obj->yst_atime;
0b57027b96fe Some improvements to garbage collection and st_xxx to yst_xxx changes
charles <charles>
parents: 19
diff changeset
622 inode->i_mtime = obj->yst_mtime;
0b57027b96fe Some improvements to garbage collection and st_xxx to yst_xxx changes
charles <charles>
parents: 19
diff changeset
623 inode->i_ctime = obj->yst_ctime;
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
624 #endif
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
625 inode->i_size = yaffs_GetObjectFileLength(obj);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
626 inode->i_blocks = (inode->i_size + 511) >> 9;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
627
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
628 inode->i_nlink = yaffs_GetObjectLinkCount(obj);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
629
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
630 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_FillInode mode %x uid %d gid %d size %d count %d\n",
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
631 inode->i_mode, inode->i_uid, inode->i_gid, (int)inode->i_size, atomic_read(&inode->i_count)));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
632
22
0b57027b96fe Some improvements to garbage collection and st_xxx to yst_xxx changes
charles <charles>
parents: 19
diff changeset
633 switch (obj->yst_mode & S_IFMT)
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
634 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
635 default: // fifo, device or socket
12
e0fa36dd109b Fix 2.6 special inodes
charles <charles>
parents: 10
diff changeset
636 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
22
0b57027b96fe Some improvements to garbage collection and st_xxx to yst_xxx changes
charles <charles>
parents: 19
diff changeset
637 init_special_inode(inode, obj->yst_mode,old_decode_dev(obj->yst_rdev));
12
e0fa36dd109b Fix 2.6 special inodes
charles <charles>
parents: 10
diff changeset
638 #else
22
0b57027b96fe Some improvements to garbage collection and st_xxx to yst_xxx changes
charles <charles>
parents: 19
diff changeset
639 init_special_inode(inode, obj->yst_mode,(dev_t)(obj->yst_rdev));
23
7942535c12c6 Apply Luc's patches
charles <charles>
parents: 22
diff changeset
640 #endif
7942535c12c6 Apply Luc's patches
charles <charles>
parents: 22
diff changeset
641 break;
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
642 case S_IFREG: // file
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
643 inode->i_op = &yaffs_file_inode_operations;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
644 inode->i_fop = &yaffs_file_operations;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
645 inode->i_mapping->a_ops = &yaffs_file_address_operations;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
646 break;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
647 case S_IFDIR: // directory
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
648 inode->i_op = &yaffs_dir_inode_operations;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
649 inode->i_fop = &yaffs_dir_operations;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
650 break;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
651 case S_IFLNK: // symlink
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
652 inode->i_op = &yaffs_symlink_inode_operations;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
653 break;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
654 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
655
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
656
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
657 inode->u.generic_ip = obj;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
658 obj->myInode = inode;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
659
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
660 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
661 else
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
662 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
663 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_FileInode invalid parameters\n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
664 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
665
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
666 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
667
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
668 struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,yaffs_Object *obj)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
669 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
670 struct inode * inode;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
671
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
672 if(!sb)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
673 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
674 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_get_inode for NULL super_block!!\n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
675 return NULL;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
676
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
677 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
678
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
679 if(!obj)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
680 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
681 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_get_inode for NULL object!!\n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
682 return NULL;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
683
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
684 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
685
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
686 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_get_inode for object %d\n",obj->objectId));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
687
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
688 inode = iget(sb,obj->objectId);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
689
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
690 // NB Side effect: iget calls back to yaffs_read_inode().
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
691 // iget also increments the inode's i_count
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
692
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
693 return inode;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
694 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
695
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
696 static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, loff_t *pos)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
697 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
698 yaffs_Object *obj;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
699 int nWritten,ipos;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
700 struct inode *inode;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
701 yaffs_Device *dev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
702
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
703
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
704 obj = yaffs_DentryToObject(f->f_dentry);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
705
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
706 dev = obj->myDev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
707
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
708 yaffs_GrossLock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
709
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
710 inode = f->f_dentry->d_inode;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
711
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
712 if(!S_ISBLK(inode->i_mode) && f->f_flags & O_APPEND)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
713 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
714 ipos = inode->i_size;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
715 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
716 else
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
717 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
718 ipos = *pos;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
719 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
720
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
721
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
722 if(!obj)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
723 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
724 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_file_write: hey obj is null!\n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
725 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
726 else
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
727 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
728 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_file_write about to write writing %d bytes to object %d at %d\n",n,obj->objectId,ipos));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
729 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
730
18
47d3aadf185a Add cache write through and some benign fixes
charles <charles>
parents: 15
diff changeset
731 nWritten = yaffs_WriteDataToFile(obj,buf,ipos,n,0);
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
732
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
733 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_file_write writing %d bytes, %d written at %d\n",n,nWritten,ipos));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
734 if(nWritten > 0)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
735 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
736 ipos += nWritten;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
737 *pos = ipos;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
738 if(ipos > inode->i_size)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
739 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
740 inode->i_size = ipos;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
741 inode->i_blocks = (ipos + 511)>>9;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
742
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
743 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_file_write size updated to %d bytes, %d blocks\n",ipos,(int)(inode->i_blocks)));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
744 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
745
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
746 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
747 yaffs_GrossUnlock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
748
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
749 return nWritten != n ? -ENOSPC : nWritten;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
750 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
751
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
752
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
753
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
754 static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
755 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
756 yaffs_Object *obj;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
757 yaffs_Device *dev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
758 struct inode *inode = f->f_dentry->d_inode;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
759 unsigned long offset, curoffs;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
760 struct list_head *i;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
761 yaffs_Object *l;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
762
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
763 char name[YAFFS_MAX_NAME_LENGTH +1];
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
764
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
765 obj = yaffs_DentryToObject(f->f_dentry);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
766 dev = obj->myDev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
767
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
768 yaffs_GrossLock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
769
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
770 offset = f->f_pos;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
771
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
772 T(YAFFS_TRACE_OS,("yaffs_readdir: starting at %d\n",(int)offset));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
773
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
774 if(offset == 0)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
775 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
776 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_readdir: entry . ino %d \n",(int)inode->i_ino));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
777 if(filldir(dirent,".",1,offset,inode->i_ino,DT_DIR) < 0)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
778 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
779 goto out;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
780 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
781 offset++;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
782 f->f_pos++;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
783 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
784 if(offset == 1)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
785 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
786 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_readdir: entry .. ino %d \n",(int)f->f_dentry->d_parent->d_inode->i_ino));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
787 if(filldir(dirent,"..",2,offset,f->f_dentry->d_parent->d_inode->i_ino,DT_DIR) < 0)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
788 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
789 goto out;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
790 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
791 offset++;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
792 f->f_pos++;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
793 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
794
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
795 curoffs = 1;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
796
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
797 list_for_each(i,&obj->variant.directoryVariant.children)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
798 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
799 curoffs++;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
800 if(curoffs >= offset)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
801 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
802 l = list_entry(i, yaffs_Object,siblings);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
803
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
804 yaffs_GetObjectName(l,name,YAFFS_MAX_NAME_LENGTH+1);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
805 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_readdir: %s inode %d\n",name,yaffs_GetObjectInode(l)));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
806
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
807 if(filldir(dirent,
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
808 name,
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
809 strlen(name),
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
810 offset,
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
811 yaffs_GetObjectInode(l),
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
812 yaffs_GetObjectType(l))
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
813 < 0)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
814 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
815 goto up_and_out;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
816 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
817
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
818 offset++;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
819 f->f_pos++;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
820 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
821 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
822
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
823 up_and_out:
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
824 out:
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
825
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
826 yaffs_GrossUnlock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
827
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
828 return 0;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
829 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
830
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
831
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
832 /*
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
833 * File creation. Allocate an inode, and we're done..
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
834 */
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
835 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
836 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
837 #else
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
838 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
839 #endif
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
840 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
841 struct inode *inode;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
842
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
843 yaffs_Object *obj = NULL;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
844 yaffs_Device *dev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
845
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
846 yaffs_Object *parent = yaffs_InodeToObject(dir);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
847
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
848 int error = -ENOSPC;
36
e98ab6dcd6b7 Set the correct uid/gid of newly created files when: use fsuid & fsgid and take care when the SGID bit is set on the parent directory.
luc <luc>
parents: 32
diff changeset
849 uid_t uid = current->fsuid;
e98ab6dcd6b7 Set the correct uid/gid of newly created files when: use fsuid & fsgid and take care when the SGID bit is set on the parent directory.
luc <luc>
parents: 32
diff changeset
850 gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
851
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
852 if(parent)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
853 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
854 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod: parent object %d type %d\n",
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
855 parent->objectId,parent->variantType));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
856 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
857 else
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
858 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
859 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod: could not get parent object\n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
860 return -EPERM;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
861 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
862
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
863 T(YAFFS_TRACE_OS,("yaffs_mknod: making oject for %s, mode %x dev %x\n",
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
864 dentry->d_name.name, mode,rdev));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
865
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
866 dev = parent->myDev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
867
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
868 yaffs_GrossLock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
869
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
870 switch (mode & S_IFMT)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
871 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
872 default:
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
873 // Special (socket, fifo, device...)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
874 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod: making special\n"));
12
e0fa36dd109b Fix 2.6 special inodes
charles <charles>
parents: 10
diff changeset
875 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
36
e98ab6dcd6b7 Set the correct uid/gid of newly created files when: use fsuid & fsgid and take care when the SGID bit is set on the parent directory.
luc <luc>
parents: 32
diff changeset
876 obj = yaffs_MknodSpecial(parent,dentry->d_name.name,mode,uid, gid,old_encode_dev(rdev));
12
e0fa36dd109b Fix 2.6 special inodes
charles <charles>
parents: 10
diff changeset
877 #else
36
e98ab6dcd6b7 Set the correct uid/gid of newly created files when: use fsuid & fsgid and take care when the SGID bit is set on the parent directory.
luc <luc>
parents: 32
diff changeset
878 obj = yaffs_MknodSpecial(parent,dentry->d_name.name,mode,uid, gid,rdev);
23
7942535c12c6 Apply Luc's patches
charles <charles>
parents: 22
diff changeset
879 #endif
7942535c12c6 Apply Luc's patches
charles <charles>
parents: 22
diff changeset
880 break;
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
881 case S_IFREG: // file
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
882 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod: making file\n"));
36
e98ab6dcd6b7 Set the correct uid/gid of newly created files when: use fsuid & fsgid and take care when the SGID bit is set on the parent directory.
luc <luc>
parents: 32
diff changeset
883 obj = yaffs_MknodFile(parent,dentry->d_name.name,mode,uid, gid);
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
884 break;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
885 case S_IFDIR: // directory
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
886 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod: making directory\n"));
36
e98ab6dcd6b7 Set the correct uid/gid of newly created files when: use fsuid & fsgid and take care when the SGID bit is set on the parent directory.
luc <luc>
parents: 32
diff changeset
887 obj = yaffs_MknodDirectory(parent,dentry->d_name.name,mode,uid, gid);
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
888 break;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
889 case S_IFLNK: // symlink
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
890 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod: making file\n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
891 obj = NULL; // Do we ever get here?
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
892 break;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
893 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
894
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
895 if(obj)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
896 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
897 inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
898 d_instantiate(dentry, inode);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
899 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod created object %d count = %d\n",obj->objectId,atomic_read(&inode->i_count)));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
900 error = 0;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
901 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
902 else
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
903 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
904 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod failed making object\n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
905 error = -ENOMEM;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
906 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
907
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
908 yaffs_GrossUnlock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
909
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
910 return error;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
911 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
912
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
913 static int yaffs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
914 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
915 int retVal;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
916 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mkdir\n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
917 retVal = yaffs_mknod(dir, dentry, mode | S_IFDIR, 0);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
918 #if 0
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
919 // attempt to fix dir bug - didn't work
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
920 if(!retVal)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
921 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
922 dget(dentry);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
923 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
924 #endif
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
925 return retVal;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
926 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
927
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
928 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
929 static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *n)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
930 #else
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
931 static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
932 #endif
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
933 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
934 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_create\n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
935 return yaffs_mknod(dir, dentry, mode | S_IFREG, 0);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
936 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
937
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
938
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
939 static int yaffs_unlink(struct inode * dir, struct dentry *dentry)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
940 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
941 int retVal;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
942
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
943 yaffs_Device *dev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
944
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
945
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
946 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_unlink %d:%s\n",(int)(dir->i_ino),dentry->d_name.name));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
947
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
948 dev = yaffs_InodeToObject(dir)->myDev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
949
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
950 yaffs_GrossLock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
951
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
952
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
953 retVal = yaffs_Unlink(yaffs_InodeToObject(dir),dentry->d_name.name);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
954
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
955
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
956 yaffs_GrossUnlock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
957
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
958 if( retVal == YAFFS_OK)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
959 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
960 dentry->d_inode->i_nlink--;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
961 mark_inode_dirty(dentry->d_inode);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
962 return 0;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
963 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
964 else
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
965 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
966 return -ENOTEMPTY;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
967 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
968 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
969
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
970
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
971 /*
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
972 * Create a link...
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
973 */
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
974 static int yaffs_link(struct dentry *old_dentry, struct inode * dir, struct dentry * dentry)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
975 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
976 struct inode *inode = old_dentry->d_inode;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
977 yaffs_Object *obj = NULL;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
978 yaffs_Object *link=NULL;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
979 yaffs_Device *dev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
980
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
981 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_link\n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
982
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
983 obj = yaffs_InodeToObject(inode);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
984 dev = obj->myDev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
985
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
986 yaffs_GrossLock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
987
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
988 if (!S_ISDIR(inode->i_mode)) // Don't link directories
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
989 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
990 link = yaffs_Link(yaffs_InodeToObject(dir),dentry->d_name.name,obj);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
991 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
992
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
993
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
994 if(link)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
995 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
996 old_dentry->d_inode->i_nlink = yaffs_GetObjectLinkCount(obj);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
997 d_instantiate(dentry, old_dentry->d_inode);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
998 atomic_inc(&old_dentry->d_inode->i_count);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
999 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_link link count %d i_count %d\n",
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1000 old_dentry->d_inode->i_nlink,atomic_read(&old_dentry->d_inode->i_count)));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1001
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1002 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1003
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1004 yaffs_GrossUnlock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1005
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1006
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1007 if(link)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1008 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1009
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1010 return 0;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1011 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1012
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1013
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1014 return -EPERM;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1015 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1016
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1017
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1018 static int yaffs_symlink(struct inode * dir, struct dentry *dentry, const char * symname)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1019 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1020 yaffs_Object *obj;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1021 yaffs_Device *dev;
36
e98ab6dcd6b7 Set the correct uid/gid of newly created files when: use fsuid & fsgid and take care when the SGID bit is set on the parent directory.
luc <luc>
parents: 32
diff changeset
1022 uid_t uid = current->fsuid;
e98ab6dcd6b7 Set the correct uid/gid of newly created files when: use fsuid & fsgid and take care when the SGID bit is set on the parent directory.
luc <luc>
parents: 32
diff changeset
1023 gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1024
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1025 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_symlink\n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1026
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1027 dev = yaffs_InodeToObject(dir)->myDev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1028 yaffs_GrossLock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1029 obj = yaffs_MknodSymLink(yaffs_InodeToObject(dir), dentry->d_name.name,
36
e98ab6dcd6b7 Set the correct uid/gid of newly created files when: use fsuid & fsgid and take care when the SGID bit is set on the parent directory.
luc <luc>
parents: 32
diff changeset
1030 S_IFLNK | S_IRWXUGO, uid, gid,
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1031 symname);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1032 yaffs_GrossUnlock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1033
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1034 if(obj)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1035 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1036
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1037 struct inode* inode;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1038
22
0b57027b96fe Some improvements to garbage collection and st_xxx to yst_xxx changes
charles <charles>
parents: 19
diff changeset
1039 inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj);
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1040 d_instantiate(dentry, inode);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1041 T(YAFFS_TRACE_OS,(KERN_DEBUG"symlink created OK\n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1042 return 0;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1043 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1044 else
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1045 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1046 T(YAFFS_TRACE_OS,(KERN_DEBUG"symlink not created\n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1047
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1048 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1049
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1050 return -ENOMEM;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1051 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1052
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1053 static int yaffs_sync_object(struct file * file, struct dentry *dentry, int datasync)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1054 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1055
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1056 yaffs_Object *obj;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1057 yaffs_Device *dev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1058
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1059 obj = yaffs_DentryToObject(dentry);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1060
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1061 dev = obj->myDev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1062
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1063 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_sync_object\n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1064 yaffs_GrossLock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1065 yaffs_FlushFile(obj,1);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1066 yaffs_GrossUnlock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1067 return 0;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1068 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1069
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1070 /*
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1071 * The VFS layer already does all the dentry stuff for rename.
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1072 *
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1073 * NB: POSIX says you can rename an object over an old object of the same name
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1074 */
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1075 static int yaffs_rename(struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir,struct dentry *new_dentry)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1076 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1077 yaffs_Device *dev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1078 int retVal = YAFFS_FAIL;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1079 int removed = 0;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1080 yaffs_Object *target;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1081
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1082 dev = yaffs_InodeToObject(old_dir)->myDev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1083
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1084 yaffs_GrossLock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1085
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1086 // Check if the target is an existing directory that is not empty.
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1087 target = yaffs_FindObjectByName(yaffs_InodeToObject(new_dir),new_dentry->d_name.name);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1088
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1089 if(target &&
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1090 target->variantType == YAFFS_OBJECT_TYPE_DIRECTORY &&
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1091 !list_empty(&target->variant.directoryVariant.children))
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1092 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1093 retVal = YAFFS_FAIL;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1094 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1095 else
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1096 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1097
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1098 // Unlink the target if it exists
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1099 removed = yaffs_Unlink(yaffs_InodeToObject(new_dir),new_dentry->d_name.name);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1100
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1101
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1102 retVal = yaffs_RenameObject(yaffs_InodeToObject(old_dir),old_dentry->d_name.name,
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1103 yaffs_InodeToObject(new_dir),new_dentry->d_name.name);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1104
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1105 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1106 yaffs_GrossUnlock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1107
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1108 if(retVal == YAFFS_OK)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1109 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1110 if(removed == YAFFS_OK)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1111 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1112 new_dentry->d_inode->i_nlink--;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1113 mark_inode_dirty(new_dentry->d_inode);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1114 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1115
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1116 return 0;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1117 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1118 else
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1119 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1120 return -ENOTEMPTY;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1121 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1122
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1123
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1124 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1125
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1126 static int yaffs_setattr(struct dentry *dentry, struct iattr *attr)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1127 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1128 struct inode *inode = dentry->d_inode;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1129 int error;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1130 yaffs_Device *dev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1131
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1132 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_setattr of object %d\n",yaffs_InodeToObject(inode)->objectId));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1133
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1134 if((error = inode_change_ok(inode,attr)) == 0)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1135 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1136
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1137 dev = yaffs_InodeToObject(inode)->myDev;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1138 yaffs_GrossLock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1139 if(yaffs_SetAttributes(yaffs_InodeToObject(inode),attr) == YAFFS_OK)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1140 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1141 error = 0;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1142 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1143 else
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1144 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1145 error = -EPERM;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1146 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1147 yaffs_GrossUnlock(dev);
23
7942535c12c6 Apply Luc's patches
charles <charles>
parents: 22
diff changeset
1148 if (!error)
7942535c12c6 Apply Luc's patches
charles <charles>
parents: 22
diff changeset
1149 error = inode_setattr(inode,attr);
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1150 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1151 return error;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1152 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1153
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1154 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1155 static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1156 #else
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1157 static int yaffs_statfs(struct super_block *sb, struct statfs *buf)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1158 #endif
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1159 {
15
f422dc67a33c Fix df size problem
charles <charles>
parents: 12
diff changeset
1160
f422dc67a33c Fix df size problem
charles <charles>
parents: 12
diff changeset
1161
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1162 yaffs_Device *dev = yaffs_SuperToDevice(sb);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1163 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_statfs\n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1164
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1165 yaffs_GrossLock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1166
15
f422dc67a33c Fix df size problem
charles <charles>
parents: 12
diff changeset
1167
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1168 buf->f_type = YAFFS_MAGIC;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1169 buf->f_bsize = sb->s_blocksize;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1170 buf->f_namelen = 255;
15
f422dc67a33c Fix df size problem
charles <charles>
parents: 12
diff changeset
1171 if(sb->s_blocksize > dev->nBytesPerChunk)
f422dc67a33c Fix df size problem
charles <charles>
parents: 12
diff changeset
1172 {
f422dc67a33c Fix df size problem
charles <charles>
parents: 12
diff changeset
1173
f422dc67a33c Fix df size problem
charles <charles>
parents: 12
diff changeset
1174 buf->f_blocks = (dev->endBlock - dev->startBlock + 1) * dev->nChunksPerBlock/
f422dc67a33c Fix df size problem
charles <charles>
parents: 12
diff changeset
1175 (sb->s_blocksize/dev->nBytesPerChunk);
f422dc67a33c Fix df size problem
charles <charles>
parents: 12
diff changeset
1176 buf->f_bfree = yaffs_GetNumberOfFreeChunks(dev)/
f422dc67a33c Fix df size problem
charles <charles>
parents: 12
diff changeset
1177 (sb->s_blocksize/dev->nBytesPerChunk);
f422dc67a33c Fix df size problem
charles <charles>
parents: 12
diff changeset
1178 }
f422dc67a33c Fix df size problem
charles <charles>
parents: 12
diff changeset
1179 else
f422dc67a33c Fix df size problem
charles <charles>
parents: 12
diff changeset
1180 {
f422dc67a33c Fix df size problem
charles <charles>
parents: 12
diff changeset
1181
f422dc67a33c Fix df size problem
charles <charles>
parents: 12
diff changeset
1182 buf->f_blocks = (dev->endBlock - dev->startBlock + 1) * dev->nChunksPerBlock *
f422dc67a33c Fix df size problem
charles <charles>
parents: 12
diff changeset
1183 (dev->nBytesPerChunk/sb->s_blocksize);
f422dc67a33c Fix df size problem
charles <charles>
parents: 12
diff changeset
1184 buf->f_bfree = yaffs_GetNumberOfFreeChunks(dev) *
f422dc67a33c Fix df size problem
charles <charles>
parents: 12
diff changeset
1185 (dev->nBytesPerChunk/sb->s_blocksize);
f422dc67a33c Fix df size problem
charles <charles>
parents: 12
diff changeset
1186 }
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1187 buf->f_files = 0;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1188 buf->f_ffree = 0;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1189 buf->f_bavail = buf->f_bfree;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1190
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1191 yaffs_GrossUnlock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1192 return 0;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1193 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1194
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1195 static void yaffs_read_inode (struct inode *inode)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1196 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1197 // NB This is called as a side effect of other functions and
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1198 // thus gross locking should always be in place already.
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1199
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1200 yaffs_Object *obj ;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1201 yaffs_Device *dev = yaffs_SuperToDevice(inode->i_sb);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1202
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1203 T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_read_inode for %d\n",(int)inode->i_ino));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1204
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1205 obj = yaffs_FindObjectByNumber(dev,inode->i_ino);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1206
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1207 yaffs_FillInodeFromObject(inode,obj);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1208
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1209 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1210
27
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1211 static LIST_HEAD(yaffs_dev_list);
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1212
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1213 static void yaffs_put_super(struct super_block *sb)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1214 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1215 yaffs_Device *dev = yaffs_SuperToDevice(sb);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1216
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1217 yaffs_GrossLock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1218 if(dev->putSuperFunc)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1219 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1220 dev->putSuperFunc(sb);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1221 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1222 yaffs_Deinitialise(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1223 yaffs_GrossUnlock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1224
27
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1225 /* we assume this is protected by lock_kernel() in mount/umount */
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1226 list_del(&dev->devList);
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1227
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1228 kfree(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1229 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1230
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1231
49
05fb5e11130f Remove CONFIG_YAFFS_USE_CHUNK_SIZE
marty <marty>
parents: 45
diff changeset
1232 #ifdef CONFIG_YAFFS_YAFFS1
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1233
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1234 static void yaffs_MTDPutSuper(struct super_block *sb)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1235 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1236
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1237 struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1238
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1239 if(mtd->sync)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1240 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1241 mtd->sync(mtd);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1242 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1243
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1244 put_mtd_device(mtd);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1245 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1246
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1247 #endif
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1248
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1249
58
166bb4951954 Remove the support for yaffsram.
luc <luc>
parents: 57
diff changeset
1250 static struct super_block *yaffs_internal_read_super(int yaffsVersion, struct super_block * sb, void * data, int silent)
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1251 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1252 int nBlocks;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1253 struct inode * inode = NULL;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1254 struct dentry * root;
27
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1255 yaffs_Device *dev = 0;
37
843d9d0add74 Fix devname which was faked by always using "(unavailable)".
luc <luc>
parents: 36
diff changeset
1256 char devname_buf[BDEVNAME_SIZE+1];
59
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1257 struct mtd_info *mtd;
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1258 int err;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1259
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1260 sb->s_magic = YAFFS_MAGIC;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1261 sb->s_op = &yaffs_super_ops;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1262
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1263 if(!sb)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1264 printk(KERN_INFO"yaffs: sb is NULL\n");
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1265 else if(!sb->s_dev)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1266 printk(KERN_INFO"yaffs: sb->s_dev is NULL\n");
37
843d9d0add74 Fix devname which was faked by always using "(unavailable)".
luc <luc>
parents: 36
diff changeset
1267 else if(!yaffs_devname(sb, devname_buf))
843d9d0add74 Fix devname which was faked by always using "(unavailable)".
luc <luc>
parents: 36
diff changeset
1268 printk(KERN_INFO"yaffs: devname is NULL\n");
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1269 else
37
843d9d0add74 Fix devname which was faked by always using "(unavailable)".
luc <luc>
parents: 36
diff changeset
1270 printk(KERN_INFO"yaffs: dev is %d name is \"%s\"\n", sb->s_dev, yaffs_devname(sb, devname_buf));
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1271
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1272
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1273
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1274 sb->s_blocksize = PAGE_CACHE_SIZE;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1275 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1276 T(YAFFS_TRACE_OS,("yaffs_read_super: Using yaffs%d\n",yaffsVersion));
58
166bb4951954 Remove the support for yaffsram.
luc <luc>
parents: 57
diff changeset
1277 T(YAFFS_TRACE_OS,("yaffs_read_super: block size %d\n", (int)(sb->s_blocksize)));
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1278
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1279 #ifdef CONFIG_YAFFS_DISABLE_WRITE_VERIFY
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1280 T(YAFFS_TRACE_OS,("yaffs: Write verification disabled. All guarantees null and void\n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1281 #endif
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1282
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1283
59
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1284 T(YAFFS_TRACE_ALWAYS,("yaffs: Attempting MTD mount on %u.%u, \"%s\"\n",
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1285 MAJOR(sb->s_dev),MINOR(sb->s_dev), yaffs_devname(sb, devname_buf)));
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1286
59
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1287 // Check it's an mtd device.....
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1288 if(MAJOR(sb->s_dev) != MTD_BLOCK_MAJOR)
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1289 {
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1290 return NULL; // This isn't an mtd device
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1291 }
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1292
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1293 // Get the device
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1294 mtd = get_mtd_device(NULL, MINOR(sb->s_dev));
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1295 if (!mtd)
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1296 {
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1297 T(YAFFS_TRACE_ALWAYS,("yaffs: MTD device #%u doesn't appear to exist\n", MINOR(sb->s_dev)));
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1298 return NULL;
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1299 }
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1300
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1301 // Check it's NAND
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1302 if(mtd->type != MTD_NANDFLASH)
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1303 {
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1304 T(YAFFS_TRACE_ALWAYS,("yaffs: MTD device is not NAND it's type %d\n", mtd->type));
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1305 return NULL;
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1306 }
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1307
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1308 T(YAFFS_TRACE_OS,(" erase %p\n",mtd->erase));
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1309 T(YAFFS_TRACE_OS,(" read %p\n",mtd->read));
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1310 T(YAFFS_TRACE_OS,(" write %p\n",mtd->write));
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1311 T(YAFFS_TRACE_OS,(" readoob %p\n",mtd->read_oob));
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1312 T(YAFFS_TRACE_OS,(" writeoob %p\n",mtd->write_oob));
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1313 T(YAFFS_TRACE_OS,(" block_isbad %p\n",mtd->block_isbad));
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1314 T(YAFFS_TRACE_OS,(" block_markbad %p\n",mtd->block_markbad));
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1315 T(YAFFS_TRACE_OS,(" oobblock %d\n",mtd->oobblock));
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1316 T(YAFFS_TRACE_OS,(" oobsize %d\n",mtd->oobsize));
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1317 T(YAFFS_TRACE_OS,(" erasesize %d\n",mtd->erasesize));
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1318 T(YAFFS_TRACE_OS,(" size %d\n",mtd->size));
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1319
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1320 if(yaffsVersion == 2)
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1321 {
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1322 // Check for version 2 style functions
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1323 if(!mtd->erase ||
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1324 !mtd->block_isbad ||
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1325 !mtd->block_markbad ||
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1326 !mtd->read ||
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1327 !mtd->write ||
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1328 !mtd->write_ecc ||
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1329 !mtd->read_ecc ||
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1330 !mtd->read_oob ||
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1331 !mtd->write_oob )
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1332 {
59
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1333 T(YAFFS_TRACE_ALWAYS,("yaffs: MTD device does not support required functions\n"));;
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1334 return NULL;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1335 }
59
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1336
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1337 if(mtd->oobblock < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1338 mtd->oobsize < YAFFS_MIN_YAFFS2_SPARE_SIZE)
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1339 {
59
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1340 T(YAFFS_TRACE_ALWAYS,("yaffs: MTD device does not support have the right page sizes\n"));
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1341 return NULL;
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1342 } }
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1343 else
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1344 {
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1345 // Check for V1 style functions
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1346 if(!mtd->erase ||
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1347 !mtd->read ||
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1348 !mtd->write ||
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1349 !mtd->write_ecc ||
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1350 !mtd->read_ecc ||
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1351 !mtd->read_oob ||
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1352 !mtd->write_oob )
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1353 {
59
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1354 T(YAFFS_TRACE_ALWAYS,("yaffs: MTD device does not support required functions\n"));;
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1355 return NULL;
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1356 }
59
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1357
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1358 if(mtd->oobblock != YAFFS_BYTES_PER_CHUNK ||
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1359 mtd->oobsize != YAFFS_BYTES_PER_SPARE)
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1360 {
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1361 T(YAFFS_TRACE_ALWAYS,("yaffs: MTD device does not support have the right page sizes\n"));
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1362 return NULL;
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1363 }
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1364 }
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1365
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1366
59
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1367 // OK, so if we got here, we have an MTD that's NAND and looks
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1368 // like it has the right capabilities
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1369 // Set the yaffs_Device up for mtd
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1370
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1371 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
59
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1372 sb->s_fs_info = dev = kmalloc(sizeof(yaffs_Device),GFP_KERNEL);
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1373 #else
59
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1374 sb->u.generic_sbp = dev = kmalloc(sizeof(yaffs_Device),GFP_KERNEL);
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1375 #endif
59
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1376 if(!dev)
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1377 {
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1378 // Deep shit could not allocate device structure
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1379 T(YAFFS_TRACE_ALWAYS,("yaffs_read_super: Failed trying to allocate yaffs_Device. \n"));
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1380 return NULL;
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1381 }
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1382
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1383 memset(dev,0,sizeof(yaffs_Device));
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1384 dev->genericDevice = mtd;
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1385 dev->name = mtd->name;
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1386
59
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1387 // Set up the memory size parameters....
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1388
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1389 nBlocks = mtd->size / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1390 dev->startBlock = 0;
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1391 dev->endBlock = nBlocks - 1;
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1392 dev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1393 dev->nBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1394 dev->nReservedBlocks = 5;
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1395 dev->nShortOpCaches = 10; // Enable short op caching
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1396
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1397
59
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1398 // ... and the functions.
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1399 if(yaffsVersion == 2)
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1400 {
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1401 dev->writeChunkWithTagsToNAND = nandmtd2_WriteChunkWithTagsToNAND;
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1402 dev->readChunkWithTagsFromNAND = nandmtd2_ReadChunkWithTagsFromNAND;
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1403 dev->markNANDBlockBad = nandmtd2_MarkNANDBlockBad;
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1404 dev->queryNANDBlock = nandmtd2_QueryNANDBlock;
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1405 dev->spareBuffer = YMALLOC(mtd->oobsize);
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1406 dev->isYaffs2 = 1;
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1407 dev->nBytesPerChunk = mtd->oobblock;
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1408 dev->nChunksPerBlock = mtd->erasesize / mtd->oobblock;
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1409 nBlocks = mtd->size / mtd->erasesize;
19
2f9c52f2060c Allow use of page zero
charles <charles>
parents: 18
diff changeset
1410 dev->startBlock = 0;
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1411 dev->endBlock = nBlocks - 1;
59
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1412 }
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1413 else
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1414 {
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1415 dev->writeChunkToNAND = nandmtd_WriteChunkToNAND;
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1416 dev->readChunkFromNAND = nandmtd_ReadChunkFromNAND;
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1417 dev->isYaffs2 = 0;
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1418 }
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1419 // ... and common functions
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1420 dev->eraseBlockInNAND = nandmtd_EraseBlockInNAND;
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1421 dev->initialiseNAND = nandmtd_InitialiseNAND;
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1422
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1423 dev->putSuperFunc = yaffs_MTDPutSuper;
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1424
61
49f66fca0b09 newconfig: use YAFFS_DOES_ECC instead of USE_NANDECC
luc <luc>
parents: 59
diff changeset
1425 #ifndef CONFIG_YAFFS_DOES_ECC
59
d6ff669317b8 Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents: 58
diff changeset
1426 dev->useNANDECC = 1;
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1427 #endif
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1428
27
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1429 /* we assume this is protected by lock_kernel() in mount/umount */
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1430 list_add_tail(&dev->devList, &yaffs_dev_list);
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1431
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1432 init_MUTEX(&dev->grossLock);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1433
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1434
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1435 yaffs_GrossLock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1436
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1437 err = yaffs_GutsInitialise(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1438
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1439 T(YAFFS_TRACE_OS,("yaffs_read_super: guts initialised %s\n", (err == YAFFS_OK) ? "OK" : "FAILED"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1440
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1441 // Create root inode
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1442 if(err == YAFFS_OK)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1443 inode = yaffs_get_inode(sb, S_IFDIR | 0755, 0,yaffs_Root(dev));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1444
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1445 yaffs_GrossUnlock(dev);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1446
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1447 if (!inode)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1448 return NULL;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1449
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1450 // added NCB
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1451 inode->i_op = & yaffs_dir_inode_operations;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1452 inode->i_fop = & yaffs_dir_operations;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1453
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1454 T(YAFFS_TRACE_OS,("yaffs_read_super: got root inode\n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1455
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1456
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1457 root = d_alloc_root(inode);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1458
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1459 T(YAFFS_TRACE_OS,("yaffs_read_super: d_alloc_root done\n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1460
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1461 if (!root) {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1462 iput(inode);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1463 return NULL;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1464 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1465 sb->s_root = root;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1466
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1467 T(YAFFS_TRACE_OS,("yaffs_read_super: done\n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1468 return sb;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1469 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1470
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1471
32
e344a10a3a1e Move the internals read_super() functions near the declaration of
luc <luc>
parents: 29
diff changeset
1472
49
05fb5e11130f Remove CONFIG_YAFFS_USE_CHUNK_SIZE
marty <marty>
parents: 45
diff changeset
1473 #ifdef CONFIG_YAFFS_YAFFS1
32
e344a10a3a1e Move the internals read_super() functions near the declaration of
luc <luc>
parents: 29
diff changeset
1474
e344a10a3a1e Move the internals read_super() functions near the declaration of
luc <luc>
parents: 29
diff changeset
1475 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1476 static int yaffs_internal_read_super_mtd(struct super_block * sb, void * data, int silent)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1477 {
58
166bb4951954 Remove the support for yaffsram.
luc <luc>
parents: 57
diff changeset
1478 return yaffs_internal_read_super(1,sb,data,silent) ? 0 : -1;
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1479 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1480
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1481 static struct super_block *yaffs_read_super(struct file_system_type * fs, int flags, const char *dev_name, void *data)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1482 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1483
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1484 return get_sb_bdev(fs, flags, dev_name, data, yaffs_internal_read_super_mtd);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1485 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1486
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1487 static struct file_system_type yaffs_fs_type = {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1488 .owner = THIS_MODULE,
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1489 .name = "yaffs",
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1490 .get_sb = yaffs_read_super,
10
33edc774d5c4 Change to kill_block_super
charles <charles>
parents: 9
diff changeset
1491 .kill_sb = kill_block_super,
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1492 .fs_flags = FS_REQUIRES_DEV,
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1493 };
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1494 #else
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1495 static struct super_block *yaffs_read_super(struct super_block * sb, void * data, int silent)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1496 {
58
166bb4951954 Remove the support for yaffsram.
luc <luc>
parents: 57
diff changeset
1497 return yaffs_internal_read_super(1,sb,data,silent);
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1498 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1499
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1500 static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super, FS_REQUIRES_DEV);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1501 #endif
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1502
49
05fb5e11130f Remove CONFIG_YAFFS_USE_CHUNK_SIZE
marty <marty>
parents: 45
diff changeset
1503 #endif // CONFIG_YAFFS_YAFFS1
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1504
49
05fb5e11130f Remove CONFIG_YAFFS_USE_CHUNK_SIZE
marty <marty>
parents: 45
diff changeset
1505 #ifdef CONFIG_YAFFS_YAFFS2
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1506
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1507 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
32
e344a10a3a1e Move the internals read_super() functions near the declaration of
luc <luc>
parents: 29
diff changeset
1508 static int yaffs2_internal_read_super_mtd(struct super_block * sb, void * data, int silent)
e344a10a3a1e Move the internals read_super() functions near the declaration of
luc <luc>
parents: 29
diff changeset
1509 {
58
166bb4951954 Remove the support for yaffsram.
luc <luc>
parents: 57
diff changeset
1510 return yaffs_internal_read_super(2,sb,data,silent) ? 0 : -1;
32
e344a10a3a1e Move the internals read_super() functions near the declaration of
luc <luc>
parents: 29
diff changeset
1511 }
e344a10a3a1e Move the internals read_super() functions near the declaration of
luc <luc>
parents: 29
diff changeset
1512
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1513 static struct super_block *yaffs2_read_super(struct file_system_type * fs, int flags, const char *dev_name, void *data)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1514 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1515
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1516 return get_sb_bdev(fs, flags, dev_name, data, yaffs2_internal_read_super_mtd);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1517 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1518
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1519 static struct file_system_type yaffs2_fs_type = {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1520 .owner = THIS_MODULE,
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1521 .name = "yaffs2",
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1522 .get_sb = yaffs2_read_super,
10
33edc774d5c4 Change to kill_block_super
charles <charles>
parents: 9
diff changeset
1523 .kill_sb = kill_block_super,
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1524 .fs_flags = FS_REQUIRES_DEV,
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1525 };
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1526 #else
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1527 static struct super_block *yaffs2_read_super(struct super_block * sb, void * data, int silent)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1528 {
58
166bb4951954 Remove the support for yaffsram.
luc <luc>
parents: 57
diff changeset
1529 return yaffs_internal_read_super(2,sb,data,silent);
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1530 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1531
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1532 static DECLARE_FSTYPE(yaffs2_fs_type, "yaffs2", yaffs2_read_super, FS_REQUIRES_DEV);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1533 #endif
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1534
49
05fb5e11130f Remove CONFIG_YAFFS_USE_CHUNK_SIZE
marty <marty>
parents: 45
diff changeset
1535 #endif // CONFIG_YAFFS_YAFFS2
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1536
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1537
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1538
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1539
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1540 static struct proc_dir_entry *my_proc_entry;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1541
27
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1542 static char * yaffs_dump_dev(char *buf,yaffs_Device *dev)
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1543 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1544 buf +=sprintf(buf,"startBlock......... %d\n",dev->startBlock);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1545 buf +=sprintf(buf,"endBlock........... %d\n",dev->endBlock);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1546 buf +=sprintf(buf,"chunkGroupBits..... %d\n",dev->chunkGroupBits);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1547 buf +=sprintf(buf,"chunkGroupSize..... %d\n",dev->chunkGroupSize);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1548 buf +=sprintf(buf,"nErasedBlocks...... %d\n",dev->nErasedBlocks);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1549 buf +=sprintf(buf,"nTnodesCreated..... %d\n",dev->nTnodesCreated);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1550 buf +=sprintf(buf,"nFreeTnodes........ %d\n",dev->nFreeTnodes);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1551 buf +=sprintf(buf,"nObjectsCreated.... %d\n",dev->nObjectsCreated);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1552 buf +=sprintf(buf,"nFreeObjects....... %d\n",dev->nFreeObjects);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1553 buf +=sprintf(buf,"nFreeChunks........ %d\n",dev->nFreeChunks);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1554 buf +=sprintf(buf,"nPageWrites........ %d\n",dev->nPageWrites);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1555 buf +=sprintf(buf,"nPageReads......... %d\n",dev->nPageReads);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1556 buf +=sprintf(buf,"nBlockErasures..... %d\n",dev->nBlockErasures);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1557 buf +=sprintf(buf,"nGCCopies.......... %d\n",dev->nGCCopies);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1558 buf +=sprintf(buf,"garbageCollections. %d\n",dev->garbageCollections);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1559 buf +=sprintf(buf,"passiveGCs......... %d\n",dev->passiveGarbageCollections);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1560 buf +=sprintf(buf,"nRetriedWrites..... %d\n",dev->nRetriedWrites);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1561 buf +=sprintf(buf,"nRetireBlocks...... %d\n",dev->nRetiredBlocks);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1562 buf +=sprintf(buf,"eccFixed........... %d\n",dev->eccFixed);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1563 buf +=sprintf(buf,"eccUnfixed......... %d\n",dev->eccUnfixed);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1564 buf +=sprintf(buf,"tagsEccFixed....... %d\n",dev->tagsEccFixed);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1565 buf +=sprintf(buf,"tagsEccUnfixed..... %d\n",dev->tagsEccUnfixed);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1566 buf +=sprintf(buf,"cacheHits.......... %d\n",dev->cacheHits);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1567 buf +=sprintf(buf,"nDeletedFiles...... %d\n",dev->nDeletedFiles);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1568 buf +=sprintf(buf,"nUnlinkedFiles..... %d\n",dev->nUnlinkedFiles);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1569 buf +=sprintf(buf,"nBackgroudDeletions %d\n",dev->nBackgroundDeletions);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1570 buf +=sprintf(buf,"useNANDECC......... %d\n",dev->useNANDECC);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1571 buf +=sprintf(buf,"isYaffs2........... %d\n",dev->isYaffs2);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1572
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1573 return buf;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1574 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1575
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1576 static int yaffs_proc_read(
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1577 char *page,
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1578 char **start,
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1579 off_t offset,
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1580 int count,
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1581 int *eof,
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1582 void *data
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1583 )
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1584 {
27
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1585 struct list_head *item;
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1586 char *buf = page;
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1587 int step = offset;
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1588 int n = 0;
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1589
27
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1590 /* Get proc_file_read() to step 'offset' by one on each sucessive call.
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1591 * We use 'offset' (*ppos) to indicate where we are in devList.
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1592 * This also assumes the user has posted a read buffer large
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1593 * enough to hold the complete output; but that's life in /proc.
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1594 */
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1595
27
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1596 *(int *)start = 1;
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1597
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1598 /* Print header first */
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1599 if (step == 0) {
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1600 buf += sprintf(buf, "YAFFS built:" __DATE__ " "__TIME__
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1601 "\n%s\n%s\n", yaffs_fs_c_version, yaffs_guts_c_version);
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1602 }
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1603
27
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1604 /* hold lock_kernel while traversing yaffs_dev_list */
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1605 lock_kernel();
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1606
27
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1607 /* Locate and print the Nth entry. Order N-squared but N is small. */
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1608 list_for_each(item, &yaffs_dev_list) {
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1609 yaffs_Device *dev = list_entry(item, yaffs_Device, devList);
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1610 if (n < step) {
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1611 n++;
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1612 continue;
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1613 }
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1614 buf += sprintf(buf,"\nDevice %d \"%s\"\n", n, dev->name);
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1615 buf = yaffs_dump_dev(buf, dev);
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1616 break;
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1617 }
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1618 unlock_kernel();
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1619
d77d5c2ba9cc Allow /proc/yaffs to handle multiple fs
charles <charles>
parents: 26
diff changeset
1620 return buf-page < count ? buf-page : count;
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1621 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1622
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1623 // Stuff to handle installation of file systems
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1624 struct file_system_to_install
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1625 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1626 struct file_system_type *fst;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1627 int installed;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1628 };
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1629
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1630 static struct file_system_to_install fs_to_install[] =
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1631 {
49
05fb5e11130f Remove CONFIG_YAFFS_USE_CHUNK_SIZE
marty <marty>
parents: 45
diff changeset
1632 #ifdef CONFIG_YAFFS_YAFFS1
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1633 { &yaffs_fs_type,0},
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1634 #endif
49
05fb5e11130f Remove CONFIG_YAFFS_USE_CHUNK_SIZE
marty <marty>
parents: 45
diff changeset
1635 #ifdef CONFIG_YAFFS_YAFFS2
7
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1636 { &yaffs2_fs_type,0},
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1637 #endif
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1638 { NULL,0}
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1639 };
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1640
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1641 static int __init init_yaffs_fs(void)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1642 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1643 int error = 0;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1644 struct file_system_to_install *fsinst;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1645
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1646 T(YAFFS_TRACE_ALWAYS,("yaffs " __DATE__ " " __TIME__ " Installing. \n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1647
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1648
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1649
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1650 /* Install the proc_fs entry */
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1651 my_proc_entry = create_proc_read_entry("yaffs",
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1652 S_IRUGO | S_IFREG,
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1653 &proc_root,
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1654 yaffs_proc_read,
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1655 NULL);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1656 if(!my_proc_entry)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1657 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1658 return -ENOMEM;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1659 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1660
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1661
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1662
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1663 // Now add the file system entries
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1664
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1665 fsinst = fs_to_install;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1666
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1667 while(fsinst->fst && !error)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1668 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1669 error = register_filesystem(fsinst->fst);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1670 if(!error)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1671 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1672 fsinst->installed = 1;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1673 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1674 fsinst++;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1675 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1676
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1677 // Any errors? uninstall
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1678 if(error)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1679 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1680 fsinst = fs_to_install;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1681
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1682 while(fsinst->fst)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1683 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1684 if(fsinst->installed)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1685 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1686 unregister_filesystem(fsinst->fst);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1687 fsinst->installed = 0;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1688 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1689 fsinst++;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1690 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1691 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1692
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1693 return error;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1694 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1695
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1696 static void __exit exit_yaffs_fs(void)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1697 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1698
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1699 struct file_system_to_install *fsinst;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1700
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1701 T(YAFFS_TRACE_ALWAYS,("yaffs " __DATE__ " " __TIME__ " removing. \n"));
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1702
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1703 remove_proc_entry("yaffs",&proc_root);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1704
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1705 fsinst = fs_to_install;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1706
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1707 while(fsinst->fst)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1708 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1709 if(fsinst->installed)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1710 {
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1711 unregister_filesystem(fsinst->fst);
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1712 fsinst->installed = 0;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1713 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1714 fsinst++;
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1715 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1716
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1717 }
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1718
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1719 module_init(init_yaffs_fs)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1720 module_exit(exit_yaffs_fs)
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1721
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1722 MODULE_DESCRIPTION("YAFFS2 - a NAND specific flash file system");
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1723 MODULE_AUTHOR("Charles Manning, Aleph One Ltd., 2002,2003,2004");
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1724 MODULE_LICENSE("GPL");
9fd733a84a74 *** empty log message ***
charles <charles>
parents:
diff changeset
1725
12
e0fa36dd109b Fix 2.6 special inodes
charles <charles>
parents: 10
diff changeset
1726