Mercurial > yaffs-ecoscentric-gpl
annotate yaffs_fs.c @ 266:1fc8a6a2271f
Add Linux 2.6.29 support
| author | charles <charles> |
|---|---|
| date | Sun, 01 Mar 2009 23:52:28 +0000 |
| parents | 3d3cda524900 |
| children | b14e2b98b91b |
| rev | line source |
|---|---|
| 7 | 1 /* |
| 168 | 2 * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. |
| 7 | 3 * |
| 168 | 4 * Copyright (C) 2002-2007 Aleph One Ltd. |
| 7 | 5 * for Toby Churchill Ltd and Brightstar Engineering |
| 6 * | |
| 7 * Created by Charles Manning <charles@aleph1.co.uk> | |
| 168 | 8 * Acknowledgements: |
| 9 * Luc van OostenRyck for numerous patches. | |
| 10 * Nick Bane for numerous patches. | |
| 11 * Nick Bane for 2.5/2.6 integration. | |
| 12 * Andras Toth for mknod rdev issue. | |
| 13 * Michael Fischer for finding the problem with inode inconsistency. | |
| 14 * Some code bodily lifted from JFFS | |
| 7 | 15 * |
| 16 * This program is free software; you can redistribute it and/or modify | |
| 17 * it under the terms of the GNU General Public License version 2 as | |
| 18 * published by the Free Software Foundation. | |
| 168 | 19 */ |
| 20 | |
| 21 /* | |
| 22 * | |
| 7 | 23 * This is the file system front-end to YAFFS that hooks it up to |
| 24 * the VFS. | |
| 25 * | |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
26 * Special notes: |
| 76 | 27 * >> 2.4: sb->u.generic_sbp points to the yaffs_Device associated with |
| 28 * this superblock | |
| 29 * >> 2.6: sb->s_fs_info points to the yaffs_Device associated with this | |
| 30 * superblock | |
| 7 | 31 * >> inode->u.generic_ip points to the associated yaffs_Object. |
| 32 */ | |
| 33 | |
| 76 | 34 const char *yaffs_fs_c_version = |
| 266 | 35 "$Id: yaffs_fs.c,v 1.73 2009-03-01 23:52:28 charles Exp $"; |
| 7 | 36 extern const char *yaffs_guts_c_version; |
| 37 | |
| 166 | 38 #include <linux/version.h> |
| 39 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) | |
| 7 | 40 #include <linux/config.h> |
| 166 | 41 #endif |
| 7 | 42 #include <linux/kernel.h> |
| 43 #include <linux/module.h> | |
| 44 #include <linux/slab.h> | |
| 45 #include <linux/init.h> | |
| 46 #include <linux/fs.h> | |
| 47 #include <linux/proc_fs.h> | |
| 27 | 48 #include <linux/smp_lock.h> |
| 7 | 49 #include <linux/pagemap.h> |
| 50 #include <linux/mtd/mtd.h> | |
| 51 #include <linux/interrupt.h> | |
| 52 #include <linux/string.h> | |
|
115
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
53 #include <linux/ctype.h> |
| 7 | 54 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
55 #include "asm/div64.h" |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
56 |
| 7 | 57 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) |
| 58 | |
| 59 #include <linux/statfs.h> /* Added NCB 15-8-2003 */ | |
| 60 #include <asm/statfs.h> | |
| 61 #define UnlockPage(p) unlock_page(p) | |
| 62 #define Page_Uptodate(page) test_bit(PG_uptodate, &(page)->flags) | |
| 76 | 63 |
| 64 /* FIXME: use sb->s_id instead ? */ | |
| 65 #define yaffs_devname(sb, buf) bdevname(sb->s_bdev, buf) | |
| 7 | 66 |
| 67 #else | |
| 68 | |
| 69 #include <linux/locks.h> | |
|
37
843d9d0add74
Fix devname which was faked by always using "(unavailable)".
luc <luc>
parents:
36
diff
changeset
|
70 #define BDEVNAME_SIZE 0 |
|
843d9d0add74
Fix devname which was faked by always using "(unavailable)".
luc <luc>
parents:
36
diff
changeset
|
71 #define yaffs_devname(sb, buf) kdevname(sb->s_dev) |
| 7 | 72 |
| 137 | 73 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) |
| 74 /* added NCB 26/5/2006 for 2.4.25-vrs2-tcl1 kernel */ | |
| 75 #define __user | |
| 76 #endif | |
| 77 | |
| 7 | 78 #endif |
| 79 | |
|
212
0107f21a03fb
Fix compilation on Linux 2.6.26, fix compilation warnings
charles <charles>
parents:
210
diff
changeset
|
80 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) |
|
0107f21a03fb
Fix compilation on Linux 2.6.26, fix compilation warnings
charles <charles>
parents:
210
diff
changeset
|
81 #define YPROC_ROOT &proc_root |
|
0107f21a03fb
Fix compilation on Linux 2.6.26, fix compilation warnings
charles <charles>
parents:
210
diff
changeset
|
82 #else |
|
0107f21a03fb
Fix compilation on Linux 2.6.26, fix compilation warnings
charles <charles>
parents:
210
diff
changeset
|
83 #define YPROC_ROOT NULL |
|
0107f21a03fb
Fix compilation on Linux 2.6.26, fix compilation warnings
charles <charles>
parents:
210
diff
changeset
|
84 #endif |
|
0107f21a03fb
Fix compilation on Linux 2.6.26, fix compilation warnings
charles <charles>
parents:
210
diff
changeset
|
85 |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
86 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
87 #define WRITE_SIZE_STR "writesize" |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
88 #define WRITE_SIZE(mtd) (mtd)->writesize |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
89 #else |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
90 #define WRITE_SIZE_STR "oobblock" |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
91 #define WRITE_SIZE(mtd) (mtd)->oobblock |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
92 #endif |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
93 |
|
253
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
94 #if(LINUX_VERSION_CODE > KERNEL_VERSION(2,6,27)) |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
95 #define YAFFS_USE_WRITE_BEGIN_END 1 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
96 #else |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
97 #define YAFFS_USE_WRITE_BEGIN_END 0 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
98 #endif |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
99 |
| 266 | 100 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,28)) |
| 101 static uint32_t YCALCBLOCKS(uint64_t partition_size, uint32_t block_size) | |
| 102 { | |
| 103 uint64_t result = partition_size; | |
| 104 do_div(result,block_size); | |
| 105 return (uint32_t)result; | |
| 106 } | |
| 107 #else | |
| 108 #define YCALCBLOCKS(s,b) ((s)/(b)) | |
| 109 #endif | |
|
253
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
110 |
| 7 | 111 #include <asm/uaccess.h> |
| 112 | |
| 113 #include "yportenv.h" | |
| 114 #include "yaffs_guts.h" | |
| 115 | |
| 116 #include <linux/mtd/mtd.h> | |
| 117 #include "yaffs_mtdif.h" | |
| 179 | 118 #include "yaffs_mtdif1.h" |
| 7 | 119 #include "yaffs_mtdif2.h" |
| 120 | |
| 179 | 121 unsigned int yaffs_traceMask = YAFFS_TRACE_BAD_BLOCKS; |
| 122 unsigned int yaffs_wr_attempts = YAFFS_WR_ATTEMPTS; | |
| 249 | 123 unsigned int yaffs_auto_checkpoint = 1; |
| 179 | 124 |
| 125 /* Module Parameters */ | |
| 126 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) | |
| 127 module_param(yaffs_traceMask,uint,0644); | |
| 128 module_param(yaffs_wr_attempts,uint,0644); | |
| 249 | 129 module_param(yaffs_auto_checkpoint,uint,0644); |
| 179 | 130 #else |
| 131 MODULE_PARM(yaffs_traceMask,"i"); | |
| 132 MODULE_PARM(yaffs_wr_attempts,"i"); | |
| 249 | 133 MODULE_PARM(yaffs_auto_checkpoint,"i"); |
| 179 | 134 #endif |
| 135 | |
|
210
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
136 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)) |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
137 /* use iget and read_inode */ |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
138 #define Y_IGET(sb,inum) iget((sb),(inum)) |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
139 static void yaffs_read_inode(struct inode *inode); |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
140 |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
141 #else |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
142 /* Call local equivalent */ |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
143 #define YAFFS_USE_OWN_IGET |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
144 #define Y_IGET(sb,inum) yaffs_iget((sb),(inum)) |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
145 |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
146 static struct inode * yaffs_iget(struct super_block *sb, unsigned long ino); |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
147 #endif |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
148 |
| 76 | 149 /*#define T(x) printk x */ |
| 7 | 150 |
| 166 | 151 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)) |
| 152 #define yaffs_InodeToObjectLV(iptr) (iptr)->i_private | |
| 153 #else | |
| 154 #define yaffs_InodeToObjectLV(iptr) (iptr)->u.generic_ip | |
| 155 #endif | |
| 156 | |
| 157 #define yaffs_InodeToObject(iptr) ((yaffs_Object *)(yaffs_InodeToObjectLV(iptr))) | |
| 7 | 158 #define yaffs_DentryToObject(dptr) yaffs_InodeToObject((dptr)->d_inode) |
| 159 | |
| 160 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) | |
| 161 #define yaffs_SuperToDevice(sb) ((yaffs_Device *)sb->s_fs_info) | |
| 162 #else | |
| 163 #define yaffs_SuperToDevice(sb) ((yaffs_Device *)sb->u.generic_sbp) | |
| 164 #endif | |
| 165 | |
| 166 static void yaffs_put_super(struct super_block *sb); | |
| 167 | |
| 76 | 168 static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, |
| 169 loff_t * pos); | |
|
253
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
170 static ssize_t yaffs_hold_space(struct file *f); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
171 static void yaffs_release_space(struct file *f); |
| 7 | 172 |
| 143 | 173 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) |
| 174 static int yaffs_file_flush(struct file *file, fl_owner_t id); | |
| 175 #else | |
| 76 | 176 static int yaffs_file_flush(struct file *file); |
| 143 | 177 #endif |
| 7 | 178 |
| 76 | 179 static int yaffs_sync_object(struct file *file, struct dentry *dentry, |
| 180 int datasync); | |
| 7 | 181 |
| 182 static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir); | |
| 183 | |
| 184 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) | |
| 76 | 185 static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode, |
| 186 struct nameidata *n); | |
| 187 static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry, | |
| 188 struct nameidata *n); | |
| 7 | 189 #else |
| 190 static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode); | |
| 76 | 191 static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry); |
| 7 | 192 #endif |
| 76 | 193 static int yaffs_link(struct dentry *old_dentry, struct inode *dir, |
| 194 struct dentry *dentry); | |
| 195 static int yaffs_unlink(struct inode *dir, struct dentry *dentry); | |
| 196 static int yaffs_symlink(struct inode *dir, struct dentry *dentry, | |
| 197 const char *symname); | |
| 198 static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, int mode); | |
| 7 | 199 |
| 200 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) | |
| 76 | 201 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, |
| 202 dev_t dev); | |
| 7 | 203 #else |
| 76 | 204 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, |
| 205 int dev); | |
| 7 | 206 #endif |
| 76 | 207 static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry, |
| 208 struct inode *new_dir, struct dentry *new_dentry); | |
| 7 | 209 static int yaffs_setattr(struct dentry *dentry, struct iattr *attr); |
| 210 | |
| 143 | 211 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) |
| 212 static int yaffs_sync_fs(struct super_block *sb, int wait); | |
| 213 static void yaffs_write_super(struct super_block *sb); | |
| 214 #else | |
| 129 | 215 static int yaffs_sync_fs(struct super_block *sb); |
| 216 static int yaffs_write_super(struct super_block *sb); | |
| 143 | 217 #endif |
| 129 | 218 |
| 143 | 219 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) |
| 220 static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf); | |
| 221 #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) | |
| 7 | 222 static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf); |
| 223 #else | |
| 224 static int yaffs_statfs(struct super_block *sb, struct statfs *buf); | |
| 225 #endif | |
| 226 | |
|
212
0107f21a03fb
Fix compilation on Linux 2.6.26, fix compilation warnings
charles <charles>
parents:
210
diff
changeset
|
227 #ifdef YAFFS_HAS_PUT_INODE |
| 76 | 228 static void yaffs_put_inode(struct inode *inode); |
|
212
0107f21a03fb
Fix compilation on Linux 2.6.26, fix compilation warnings
charles <charles>
parents:
210
diff
changeset
|
229 #endif |
|
0107f21a03fb
Fix compilation on Linux 2.6.26, fix compilation warnings
charles <charles>
parents:
210
diff
changeset
|
230 |
| 7 | 231 static void yaffs_delete_inode(struct inode *); |
| 232 static void yaffs_clear_inode(struct inode *); | |
| 233 | |
| 76 | 234 static int yaffs_readpage(struct file *file, struct page *page); |
| 23 | 235 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) |
| 236 static int yaffs_writepage(struct page *page, struct writeback_control *wbc); | |
| 237 #else | |
| 7 | 238 static int yaffs_writepage(struct page *page); |
| 23 | 239 #endif |
|
253
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
240 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
241 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
242 #if (YAFFS_USE_WRITE_BEGIN_END != 0) |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
243 static int yaffs_write_begin(struct file *filp, struct address_space *mapping, |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
244 loff_t pos, unsigned len, unsigned flags, |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
245 struct page **pagep, void **fsdata); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
246 static int yaffs_write_end(struct file *filp, struct address_space *mapping, |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
247 loff_t pos, unsigned len, unsigned copied, |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
248 struct page *pg, void *fsdadata); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
249 #else |
| 76 | 250 static int yaffs_prepare_write(struct file *f, struct page *pg, |
| 251 unsigned offset, unsigned to); | |
| 252 static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset, | |
| 253 unsigned to); | |
|
253
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
254 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
255 #endif |
| 7 | 256 |
| 76 | 257 static int yaffs_readlink(struct dentry *dentry, char __user * buffer, |
| 258 int buflen); | |
| 99 | 259 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)) |
| 260 static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd); | |
| 261 #else | |
| 7 | 262 static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd); |
| 99 | 263 #endif |
| 7 | 264 |
| 265 static struct address_space_operations yaffs_file_address_operations = { | |
| 76 | 266 .readpage = yaffs_readpage, |
| 267 .writepage = yaffs_writepage, | |
|
253
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
268 #if (YAFFS_USE_WRITE_BEGIN_END > 0) |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
269 .write_begin = yaffs_write_begin, |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
270 .write_end = yaffs_write_end, |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
271 #else |
| 76 | 272 .prepare_write = yaffs_prepare_write, |
| 273 .commit_write = yaffs_commit_write, | |
|
253
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
274 #endif |
| 7 | 275 }; |
| 276 | |
| 189 | 277 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) |
| 7 | 278 static struct file_operations yaffs_file_operations = { |
| 166 | 279 .read = do_sync_read, |
| 280 .write = do_sync_write, | |
| 281 .aio_read = generic_file_aio_read, | |
| 282 .aio_write = generic_file_aio_write, | |
| 189 | 283 .mmap = generic_file_mmap, |
| 284 .flush = yaffs_file_flush, | |
| 285 .fsync = yaffs_sync_object, | |
| 286 .splice_read = generic_file_splice_read, | |
| 287 .splice_write = generic_file_splice_write, | |
|
253
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
288 .llseek = generic_file_llseek, |
| 189 | 289 }; |
| 290 | |
| 291 #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)) | |
| 292 | |
| 293 static struct file_operations yaffs_file_operations = { | |
| 294 .read = do_sync_read, | |
| 295 .write = do_sync_write, | |
| 296 .aio_read = generic_file_aio_read, | |
| 297 .aio_write = generic_file_aio_write, | |
| 298 .mmap = generic_file_mmap, | |
| 299 .flush = yaffs_file_flush, | |
| 300 .fsync = yaffs_sync_object, | |
| 301 .sendfile = generic_file_sendfile, | |
| 302 }; | |
| 303 | |
| 166 | 304 #else |
| 189 | 305 |
| 306 static struct file_operations yaffs_file_operations = { | |
| 76 | 307 .read = generic_file_read, |
| 308 .write = generic_file_write, | |
| 309 .mmap = generic_file_mmap, | |
| 310 .flush = yaffs_file_flush, | |
| 311 .fsync = yaffs_sync_object, | |
|
112
0f8838615001
Add generic sendfile method for yaffs2, also thereby allowing loopback mount.
tpoynor <tpoynor>
parents:
109
diff
changeset
|
312 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) |
|
0f8838615001
Add generic sendfile method for yaffs2, also thereby allowing loopback mount.
tpoynor <tpoynor>
parents:
109
diff
changeset
|
313 .sendfile = generic_file_sendfile, |
|
0f8838615001
Add generic sendfile method for yaffs2, also thereby allowing loopback mount.
tpoynor <tpoynor>
parents:
109
diff
changeset
|
314 #endif |
| 7 | 315 }; |
| 189 | 316 #endif |
| 7 | 317 |
| 318 static struct inode_operations yaffs_file_inode_operations = { | |
| 76 | 319 .setattr = yaffs_setattr, |
| 7 | 320 }; |
| 321 | |
| 76 | 322 static struct inode_operations yaffs_symlink_inode_operations = { |
| 323 .readlink = yaffs_readlink, | |
| 324 .follow_link = yaffs_follow_link, | |
| 325 .setattr = yaffs_setattr, | |
| 7 | 326 }; |
| 327 | |
| 328 static struct inode_operations yaffs_dir_inode_operations = { | |
| 76 | 329 .create = yaffs_create, |
| 330 .lookup = yaffs_lookup, | |
| 331 .link = yaffs_link, | |
| 332 .unlink = yaffs_unlink, | |
| 333 .symlink = yaffs_symlink, | |
| 334 .mkdir = yaffs_mkdir, | |
| 335 .rmdir = yaffs_unlink, | |
| 336 .mknod = yaffs_mknod, | |
| 337 .rename = yaffs_rename, | |
| 338 .setattr = yaffs_setattr, | |
| 7 | 339 }; |
| 340 | |
| 341 static struct file_operations yaffs_dir_operations = { | |
| 76 | 342 .read = generic_read_dir, |
| 343 .readdir = yaffs_readdir, | |
| 344 .fsync = yaffs_sync_object, | |
| 7 | 345 }; |
| 346 | |
| 347 static struct super_operations yaffs_super_ops = { | |
| 76 | 348 .statfs = yaffs_statfs, |
|
210
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
349 |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
350 #ifndef YAFFS_USE_OWN_IGET |
| 76 | 351 .read_inode = yaffs_read_inode, |
|
210
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
352 #endif |
|
212
0107f21a03fb
Fix compilation on Linux 2.6.26, fix compilation warnings
charles <charles>
parents:
210
diff
changeset
|
353 #ifdef YAFFS_HAS_PUT_INODE |
| 76 | 354 .put_inode = yaffs_put_inode, |
|
212
0107f21a03fb
Fix compilation on Linux 2.6.26, fix compilation warnings
charles <charles>
parents:
210
diff
changeset
|
355 #endif |
| 76 | 356 .put_super = yaffs_put_super, |
| 357 .delete_inode = yaffs_delete_inode, | |
| 358 .clear_inode = yaffs_clear_inode, | |
| 129 | 359 .sync_fs = yaffs_sync_fs, |
| 360 .write_super = yaffs_write_super, | |
| 7 | 361 }; |
| 362 | |
| 76 | 363 static void yaffs_GrossLock(yaffs_Device * dev) |
| 7 | 364 { |
| 266 | 365 T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs locking %p\n",current)); |
| 7 | 366 |
| 367 down(&dev->grossLock); | |
| 266 | 368 T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs locked %p\n",current)); |
| 369 | |
| 7 | 370 } |
| 371 | |
| 76 | 372 static void yaffs_GrossUnlock(yaffs_Device * dev) |
| 7 | 373 { |
| 266 | 374 T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs unlocking %p\n",current)); |
| 7 | 375 up(&dev->grossLock); |
| 376 | |
| 377 } | |
| 378 | |
| 76 | 379 static int yaffs_readlink(struct dentry *dentry, char __user * buffer, |
| 380 int buflen) | |
| 7 | 381 { |
| 382 unsigned char *alias; | |
| 383 int ret; | |
| 384 | |
| 385 yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev; | |
| 386 | |
| 76 | 387 yaffs_GrossLock(dev); |
| 7 | 388 |
| 389 alias = yaffs_GetSymlinkAlias(yaffs_DentryToObject(dentry)); | |
| 76 | 390 |
| 7 | 391 yaffs_GrossUnlock(dev); |
| 76 | 392 |
| 393 if (!alias) | |
| 7 | 394 return -ENOMEM; |
| 395 | |
| 396 ret = vfs_readlink(dentry, buffer, buflen, alias); | |
| 397 kfree(alias); | |
| 398 return ret; | |
| 399 } | |
| 400 | |
| 99 | 401 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)) |
| 402 static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd) | |
| 403 #else | |
| 7 | 404 static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd) |
| 99 | 405 #endif |
| 7 | 406 { |
| 407 unsigned char *alias; | |
| 408 int ret; | |
| 409 yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev; | |
| 410 | |
| 411 yaffs_GrossLock(dev); | |
| 412 | |
| 413 alias = yaffs_GetSymlinkAlias(yaffs_DentryToObject(dentry)); | |
| 76 | 414 |
| 7 | 415 yaffs_GrossUnlock(dev); |
| 76 | 416 |
| 417 if (!alias) | |
| 99 | 418 { |
| 419 ret = -ENOMEM; | |
| 420 goto out; | |
| 421 } | |
| 7 | 422 |
| 76 | 423 ret = vfs_follow_link(nd, alias); |
| 7 | 424 kfree(alias); |
| 99 | 425 out: |
| 426 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)) | |
| 427 return ERR_PTR (ret); | |
| 428 #else | |
| 7 | 429 return ret; |
| 99 | 430 #endif |
| 7 | 431 } |
| 432 | |
| 76 | 433 struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev, |
| 434 yaffs_Object * obj); | |
| 7 | 435 |
| 436 /* | |
| 437 * Lookup is used to find objects in the fs | |
| 438 */ | |
| 439 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) | |
| 440 | |
| 76 | 441 static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry, |
| 442 struct nameidata *n) | |
| 7 | 443 #else |
| 76 | 444 static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry) |
| 7 | 445 #endif |
| 446 { | |
| 447 yaffs_Object *obj; | |
| 76 | 448 struct inode *inode = NULL; /* NCB 2.5/2.6 needs NULL here */ |
| 449 | |
| 7 | 450 yaffs_Device *dev = yaffs_InodeToObject(dir)->myDev; |
| 451 | |
| 452 yaffs_GrossLock(dev); | |
| 453 | |
| 76 | 454 T(YAFFS_TRACE_OS, |
| 455 (KERN_DEBUG "yaffs_lookup for %d:%s\n", | |
| 456 yaffs_InodeToObject(dir)->objectId, dentry->d_name.name)); | |
| 457 | |
| 458 obj = | |
| 459 yaffs_FindObjectByName(yaffs_InodeToObject(dir), | |
| 460 dentry->d_name.name); | |
| 461 | |
| 462 obj = yaffs_GetEquivalentObject(obj); /* in case it was a hardlink */ | |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
463 |
|
106
5b8f68c30468
Apply Reed's deadlocking fix (manually applied)
charles <charles>
parents:
104
diff
changeset
|
464 /* Can't hold gross lock when calling yaffs_get_inode() */ |
|
5b8f68c30468
Apply Reed's deadlocking fix (manually applied)
charles <charles>
parents:
104
diff
changeset
|
465 yaffs_GrossUnlock(dev); |
| 7 | 466 |
| 76 | 467 if (obj) { |
| 468 T(YAFFS_TRACE_OS, | |
| 469 (KERN_DEBUG "yaffs_lookup found %d\n", obj->objectId)); | |
| 470 | |
| 471 inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj); | |
| 472 | |
| 473 if (inode) { | |
| 474 T(YAFFS_TRACE_OS, | |
| 475 (KERN_DEBUG "yaffs_loookup dentry \n")); | |
| 476 /* #if 0 asserted by NCB for 2.5/6 compatability - falls through to | |
| 477 * d_add even if NULL inode */ | |
| 7 | 478 #if 0 |
| 76 | 479 /*dget(dentry); // try to solve directory bug */ |
| 480 d_add(dentry, inode); | |
| 481 | |
| 482 /* return dentry; */ | |
| 7 | 483 return NULL; |
| 484 #endif | |
| 485 } | |
| 486 | |
| 76 | 487 } else { |
| 488 T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_lookup not found\n")); | |
| 489 | |
| 7 | 490 } |
| 491 | |
| 76 | 492 /* added NCB for 2.5/6 compatability - forces add even if inode is |
| 493 * NULL which creates dentry hash */ | |
| 494 d_add(dentry, inode); | |
| 495 | |
| 7 | 496 return NULL; |
| 76 | 497 /* return (ERR_PTR(-EIO)); */ |
| 498 | |
| 7 | 499 } |
| 500 | |
|
212
0107f21a03fb
Fix compilation on Linux 2.6.26, fix compilation warnings
charles <charles>
parents:
210
diff
changeset
|
501 |
|
0107f21a03fb
Fix compilation on Linux 2.6.26, fix compilation warnings
charles <charles>
parents:
210
diff
changeset
|
502 #ifdef YAFFS_HAS_PUT_INODE |
|
0107f21a03fb
Fix compilation on Linux 2.6.26, fix compilation warnings
charles <charles>
parents:
210
diff
changeset
|
503 |
| 76 | 504 /* For now put inode is just for debugging |
| 505 * Put inode is called when the inode **structure** is put. | |
| 506 */ | |
| 7 | 507 static void yaffs_put_inode(struct inode *inode) |
| 508 { | |
| 76 | 509 T(YAFFS_TRACE_OS, |
| 510 ("yaffs_put_inode: ino %d, count %d\n", (int)inode->i_ino, | |
| 511 atomic_read(&inode->i_count))); | |
| 512 | |
| 7 | 513 } |
|
212
0107f21a03fb
Fix compilation on Linux 2.6.26, fix compilation warnings
charles <charles>
parents:
210
diff
changeset
|
514 #endif |
| 7 | 515 |
| 76 | 516 /* clear is called to tell the fs to release any per-inode data it holds */ |
| 7 | 517 static void yaffs_clear_inode(struct inode *inode) |
| 518 { | |
| 519 yaffs_Object *obj; | |
| 520 yaffs_Device *dev; | |
| 76 | 521 |
| 7 | 522 obj = yaffs_InodeToObject(inode); |
| 523 | |
| 76 | 524 T(YAFFS_TRACE_OS, |
| 525 ("yaffs_clear_inode: ino %d, count %d %s\n", (int)inode->i_ino, | |
| 526 atomic_read(&inode->i_count), | |
| 527 obj ? "object exists" : "null object")); | |
| 528 | |
| 529 if (obj) { | |
| 7 | 530 dev = obj->myDev; |
| 531 yaffs_GrossLock(dev); | |
| 76 | 532 |
| 533 /* Clear the association between the inode and | |
| 534 * the yaffs_Object. | |
| 535 */ | |
| 7 | 536 obj->myInode = NULL; |
| 166 | 537 yaffs_InodeToObjectLV(inode) = NULL; |
| 76 | 538 |
| 539 /* If the object freeing was deferred, then the real | |
| 540 * free happens now. | |
| 541 * This should fix the inode inconsistency problem. | |
| 542 */ | |
| 543 | |
| 7 | 544 yaffs_HandleDeferedFree(obj); |
| 76 | 545 |
| 7 | 546 yaffs_GrossUnlock(dev); |
| 547 } | |
| 76 | 548 |
| 7 | 549 } |
| 550 | |
| 76 | 551 /* delete is called when the link count is zero and the inode |
| 552 * is put (ie. nobody wants to know about it anymore, time to | |
| 553 * delete the file). | |
| 554 * NB Must call clear_inode() | |
| 555 */ | |
| 7 | 556 static void yaffs_delete_inode(struct inode *inode) |
| 557 { | |
| 558 yaffs_Object *obj = yaffs_InodeToObject(inode); | |
| 559 yaffs_Device *dev; | |
| 560 | |
| 76 | 561 T(YAFFS_TRACE_OS, |
| 562 ("yaffs_delete_inode: ino %d, count %d %s\n", (int)inode->i_ino, | |
| 563 atomic_read(&inode->i_count), | |
| 564 obj ? "object exists" : "null object")); | |
| 565 | |
| 566 if (obj) { | |
| 567 dev = obj->myDev; | |
| 7 | 568 yaffs_GrossLock(dev); |
| 569 yaffs_DeleteFile(obj); | |
| 570 yaffs_GrossUnlock(dev); | |
| 571 } | |
| 99 | 572 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)) |
| 573 truncate_inode_pages (&inode->i_data, 0); | |
| 574 #endif | |
| 7 | 575 clear_inode(inode); |
| 576 } | |
| 577 | |
| 143 | 578 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) |
| 579 static int yaffs_file_flush(struct file *file, fl_owner_t id) | |
| 580 #else | |
| 76 | 581 static int yaffs_file_flush(struct file *file) |
| 143 | 582 #endif |
| 7 | 583 { |
| 584 yaffs_Object *obj = yaffs_DentryToObject(file->f_dentry); | |
| 76 | 585 |
| 7 | 586 yaffs_Device *dev = obj->myDev; |
| 76 | 587 |
| 588 T(YAFFS_TRACE_OS, | |
| 589 (KERN_DEBUG "yaffs_file_flush object %d (%s)\n", obj->objectId, | |
| 590 obj->dirty ? "dirty" : "clean")); | |
| 7 | 591 |
| 592 yaffs_GrossLock(dev); | |
| 76 | 593 |
| 594 yaffs_FlushFile(obj, 1); | |
| 7 | 595 |
| 596 yaffs_GrossUnlock(dev); | |
| 597 | |
| 76 | 598 return 0; |
| 7 | 599 } |
| 600 | |
| 76 | 601 static int yaffs_readpage_nolock(struct file *f, struct page *pg) |
| 602 { | |
| 603 /* Lifted from jffs2 */ | |
| 7 | 604 |
| 605 yaffs_Object *obj; | |
| 606 unsigned char *pg_buf; | |
| 607 int ret; | |
| 608 | |
| 609 yaffs_Device *dev; | |
| 610 | |
| 76 | 611 T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_readpage at %08x, size %08x\n", |
| 612 (unsigned)(pg->index << PAGE_CACHE_SHIFT), | |
| 613 (unsigned)PAGE_CACHE_SIZE)); | |
| 7 | 614 |
| 76 | 615 obj = yaffs_DentryToObject(f->f_dentry); |
| 7 | 616 |
| 617 dev = obj->myDev; | |
| 76 | 618 |
| 23 | 619 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) |
| 76 | 620 BUG_ON(!PageLocked(pg)); |
| 23 | 621 #else |
| 7 | 622 if (!PageLocked(pg)) |
| 76 | 623 PAGE_BUG(pg); |
| 23 | 624 #endif |
| 7 | 625 |
| 626 pg_buf = kmap(pg); | |
| 627 /* FIXME: Can kmap fail? */ | |
| 628 | |
| 629 yaffs_GrossLock(dev); | |
| 76 | 630 |
| 631 ret = | |
| 632 yaffs_ReadDataFromFile(obj, pg_buf, pg->index << PAGE_CACHE_SHIFT, | |
| 633 PAGE_CACHE_SIZE); | |
| 7 | 634 |
| 635 yaffs_GrossUnlock(dev); | |
| 76 | 636 |
| 637 if (ret >= 0) | |
| 638 ret = 0; | |
| 7 | 639 |
| 640 if (ret) { | |
| 641 ClearPageUptodate(pg); | |
| 642 SetPageError(pg); | |
| 643 } else { | |
| 644 SetPageUptodate(pg); | |
| 645 ClearPageError(pg); | |
| 646 } | |
| 647 | |
| 648 flush_dcache_page(pg); | |
| 649 kunmap(pg); | |
| 650 | |
| 76 | 651 T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_readpage done\n")); |
| 7 | 652 return ret; |
| 653 } | |
| 654 | |
| 655 static int yaffs_readpage_unlock(struct file *f, struct page *pg) | |
| 656 { | |
| 76 | 657 int ret = yaffs_readpage_nolock(f, pg); |
| 7 | 658 UnlockPage(pg); |
| 659 return ret; | |
| 660 } | |
| 661 | |
| 76 | 662 static int yaffs_readpage(struct file *f, struct page *pg) |
| 7 | 663 { |
| 76 | 664 return yaffs_readpage_unlock(f, pg); |
| 7 | 665 } |
| 666 | |
| 76 | 667 /* writepage inspired by/stolen from smbfs */ |
| 7 | 668 |
| 23 | 669 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) |
| 670 static int yaffs_writepage(struct page *page, struct writeback_control *wbc) | |
| 671 #else | |
| 7 | 672 static int yaffs_writepage(struct page *page) |
| 23 | 673 #endif |
| 7 | 674 { |
| 675 struct address_space *mapping = page->mapping; | |
| 76 | 676 loff_t offset = (loff_t) page->index << PAGE_CACHE_SHIFT; |
| 7 | 677 struct inode *inode; |
| 678 unsigned long end_index; | |
| 679 char *buffer; | |
| 680 yaffs_Object *obj; | |
| 681 int nWritten = 0; | |
| 682 unsigned nBytes; | |
| 683 | |
| 684 if (!mapping) | |
| 685 BUG(); | |
| 686 inode = mapping->host; | |
| 687 if (!inode) | |
| 688 BUG(); | |
| 689 | |
| 76 | 690 if (offset > inode->i_size) { |
| 691 T(YAFFS_TRACE_OS, | |
| 692 (KERN_DEBUG | |
| 693 "yaffs_writepage at %08x, inode size = %08x!!!\n", | |
| 694 (unsigned)(page->index << PAGE_CACHE_SHIFT), | |
| 695 (unsigned)inode->i_size)); | |
| 696 T(YAFFS_TRACE_OS, | |
| 697 (KERN_DEBUG " -> don't care!!\n")); | |
|
67
cb8afec5ad31
Fix an error in writepage when a file is extended.
luc <luc>
parents:
61
diff
changeset
|
698 unlock_page(page); |
|
cb8afec5ad31
Fix an error in writepage when a file is extended.
luc <luc>
parents:
61
diff
changeset
|
699 return 0; |
|
cb8afec5ad31
Fix an error in writepage when a file is extended.
luc <luc>
parents:
61
diff
changeset
|
700 } |
|
cb8afec5ad31
Fix an error in writepage when a file is extended.
luc <luc>
parents:
61
diff
changeset
|
701 |
| 7 | 702 end_index = inode->i_size >> PAGE_CACHE_SHIFT; |
| 703 | |
| 704 /* easy case */ | |
| 76 | 705 if (page->index < end_index) { |
| 7 | 706 nBytes = PAGE_CACHE_SIZE; |
| 76 | 707 } else { |
| 708 nBytes = inode->i_size & (PAGE_CACHE_SIZE - 1); | |
| 7 | 709 } |
| 710 | |
| 711 get_page(page); | |
| 712 | |
| 713 buffer = kmap(page); | |
| 714 | |
| 715 obj = yaffs_InodeToObject(inode); | |
| 716 yaffs_GrossLock(obj->myDev); | |
| 717 | |
| 76 | 718 T(YAFFS_TRACE_OS, |
| 719 (KERN_DEBUG "yaffs_writepage at %08x, size %08x\n", | |
| 720 (unsigned)(page->index << PAGE_CACHE_SHIFT), nBytes)); | |
| 721 T(YAFFS_TRACE_OS, | |
| 722 (KERN_DEBUG "writepag0: obj = %05x, ino = %05x\n", | |
| 723 (int)obj->variant.fileVariant.fileSize, (int)inode->i_size)); | |
| 7 | 724 |
| 76 | 725 nWritten = |
| 726 yaffs_WriteDataToFile(obj, buffer, page->index << PAGE_CACHE_SHIFT, | |
| 727 nBytes, 0); | |
| 7 | 728 |
| 76 | 729 T(YAFFS_TRACE_OS, |
| 730 (KERN_DEBUG "writepag1: obj = %05x, ino = %05x\n", | |
| 731 (int)obj->variant.fileVariant.fileSize, (int)inode->i_size)); | |
|
67
cb8afec5ad31
Fix an error in writepage when a file is extended.
luc <luc>
parents:
61
diff
changeset
|
732 |
| 7 | 733 yaffs_GrossUnlock(obj->myDev); |
| 76 | 734 |
| 7 | 735 kunmap(page); |
| 736 SetPageUptodate(page); | |
| 737 UnlockPage(page); | |
| 738 put_page(page); | |
| 739 | |
| 76 | 740 return (nWritten == nBytes) ? 0 : -ENOSPC; |
| 7 | 741 } |
| 742 | |
|
253
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
743 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
744 #if (YAFFS_USE_WRITE_BEGIN_END > 0) |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
745 static int yaffs_write_begin(struct file *filp, struct address_space *mapping, |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
746 loff_t pos, unsigned len, unsigned flags, |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
747 struct page **pagep, void **fsdata) |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
748 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
749 { |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
750 struct page *pg = NULL; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
751 pgoff_t index = pos >> PAGE_CACHE_SHIFT; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
752 uint32_t offset = pos & (PAGE_CACHE_SIZE - 1); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
753 uint32_t to = offset + len; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
754 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
755 int ret = 0; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
756 int space_held = 0; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
757 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
758 T(YAFFS_TRACE_OS, (KERN_DEBUG "start yaffs_write_begin\n")); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
759 /* Get a page */ |
| 266 | 760 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,28) |
| 761 pg = grab_cache_page_write_begin(mapping,index,flags); | |
| 762 #else | |
|
253
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
763 pg = __grab_cache_page(mapping,index); |
| 266 | 764 #endif |
| 765 | |
|
253
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
766 *pagep = pg; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
767 if(!pg){ |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
768 ret = -ENOMEM; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
769 goto out; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
770 } |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
771 /* Get fs space */ |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
772 space_held = yaffs_hold_space(filp); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
773 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
774 if(!space_held){ |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
775 ret = -ENOSPC; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
776 goto out; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
777 } |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
778 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
779 /* Update page if required */ |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
780 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
781 if (!Page_Uptodate(pg) && (offset || to < PAGE_CACHE_SIZE)) |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
782 ret = yaffs_readpage_nolock(filp, pg); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
783 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
784 if(ret) |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
785 goto out; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
786 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
787 /* Happy path return */ |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
788 T(YAFFS_TRACE_OS, (KERN_DEBUG "end yaffs_write_begin - ok\n")); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
789 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
790 return 0; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
791 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
792 out: |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
793 T(YAFFS_TRACE_OS, (KERN_DEBUG "end yaffs_write_begin fail returning %d\n",ret)); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
794 if(space_held){ |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
795 yaffs_release_space(filp); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
796 } |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
797 if(pg) { |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
798 unlock_page(pg); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
799 page_cache_release(pg); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
800 } |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
801 return ret; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
802 } |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
803 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
804 #else |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
805 |
| 76 | 806 static int yaffs_prepare_write(struct file *f, struct page *pg, |
| 807 unsigned offset, unsigned to) | |
| 7 | 808 { |
| 809 | |
| 76 | 810 T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_prepair_write\n")); |
| 811 if (!Page_Uptodate(pg) && (offset || to < PAGE_CACHE_SIZE)) | |
| 812 return yaffs_readpage_nolock(f, pg); | |
| 7 | 813 return 0; |
| 76 | 814 |
| 7 | 815 } |
|
253
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
816 #endif |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
817 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
818 #if (YAFFS_USE_WRITE_BEGIN_END > 0) |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
819 static int yaffs_write_end(struct file *filp, struct address_space *mapping, |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
820 loff_t pos, unsigned len, unsigned copied, |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
821 struct page *pg, void *fsdadata) |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
822 { |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
823 int ret = 0; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
824 void *addr, *kva; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
825 uint32_t offset_into_page = pos & (PAGE_CACHE_SIZE -1); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
826 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
827 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
828 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
829 kva=kmap(pg); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
830 addr = kva + offset_into_page; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
831 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
832 T(YAFFS_TRACE_OS, |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
833 (KERN_DEBUG "yaffs_write_end addr %x pos %x nBytes %d\n", (unsigned) addr, |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
834 (int)pos, copied)); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
835 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
836 ret = yaffs_file_write(filp, addr, copied, &pos); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
837 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
838 if (ret != copied) { |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
839 T(YAFFS_TRACE_OS, |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
840 (KERN_DEBUG |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
841 "yaffs_write_end not same size ret %d copied %d\n", |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
842 ret, copied )); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
843 SetPageError(pg); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
844 ClearPageUptodate(pg); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
845 } else { |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
846 SetPageUptodate(pg); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
847 } |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
848 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
849 kunmap(pg); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
850 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
851 yaffs_release_space(filp); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
852 unlock_page(pg); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
853 page_cache_release(pg); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
854 return ret; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
855 } |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
856 #else |
| 7 | 857 |
| 76 | 858 static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset, |
| 859 unsigned to) | |
| 7 | 860 { |
| 861 | |
| 218 | 862 void *addr, *kva; |
| 863 | |
| 76 | 864 loff_t pos = (((loff_t) pg->index) << PAGE_CACHE_SHIFT) + offset; |
| 7 | 865 int nBytes = to - offset; |
| 866 int nWritten; | |
| 76 | 867 |
| 7 | 868 unsigned spos = pos; |
|
253
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
869 unsigned saddr; |
| 218 | 870 |
| 871 kva=kmap(pg); | |
| 872 addr = kva + offset; | |
| 7 | 873 |
|
253
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
874 saddr = (unsigned) addr; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
875 |
| 76 | 876 T(YAFFS_TRACE_OS, |
| 877 (KERN_DEBUG "yaffs_commit_write addr %x pos %x nBytes %d\n", saddr, | |
| 878 spos, nBytes)); | |
| 879 | |
| 880 nWritten = yaffs_file_write(f, addr, nBytes, &pos); | |
| 881 | |
| 882 if (nWritten != nBytes) { | |
| 883 T(YAFFS_TRACE_OS, | |
| 884 (KERN_DEBUG | |
| 885 "yaffs_commit_write not same size nWritten %d nBytes %d\n", | |
| 886 nWritten, nBytes)); | |
| 7 | 887 SetPageError(pg); |
| 888 ClearPageUptodate(pg); | |
| 76 | 889 } else { |
| 7 | 890 SetPageUptodate(pg); |
| 891 } | |
| 892 | |
| 218 | 893 kunmap(pg); |
| 894 | |
| 76 | 895 T(YAFFS_TRACE_OS, |
| 94 | 896 (KERN_DEBUG "yaffs_commit_write returning %d\n", |
|
113
325f5d3a757c
Handle partial writes more gracefully: return partial byte counts, return
tpoynor <tpoynor>
parents:
112
diff
changeset
|
897 nWritten == nBytes ? 0 : nWritten)); |
| 76 | 898 |
|
113
325f5d3a757c
Handle partial writes more gracefully: return partial byte counts, return
tpoynor <tpoynor>
parents:
112
diff
changeset
|
899 return nWritten == nBytes ? 0 : nWritten; |
| 7 | 900 |
| 901 } | |
|
253
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
902 #endif |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
903 |
| 7 | 904 |
| 76 | 905 static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object * obj) |
| 7 | 906 { |
| 76 | 907 if (inode && obj) { |
| 139 | 908 |
| 909 | |
| 910 /* Check mode against the variant type and attempt to repair if broken. */ | |
| 911 __u32 mode = obj->yst_mode; | |
| 912 switch( obj->variantType ){ | |
| 913 case YAFFS_OBJECT_TYPE_FILE : | |
| 914 if( ! S_ISREG(mode) ){ | |
| 915 obj->yst_mode &= ~S_IFMT; | |
| 916 obj->yst_mode |= S_IFREG; | |
| 917 } | |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
918 |
| 139 | 919 break; |
| 920 case YAFFS_OBJECT_TYPE_SYMLINK : | |
| 921 if( ! S_ISLNK(mode) ){ | |
| 922 obj->yst_mode &= ~S_IFMT; | |
| 923 obj->yst_mode |= S_IFLNK; | |
| 924 } | |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
925 |
| 139 | 926 break; |
| 927 case YAFFS_OBJECT_TYPE_DIRECTORY : | |
| 928 if( ! S_ISDIR(mode) ){ | |
| 929 obj->yst_mode &= ~S_IFMT; | |
| 930 obj->yst_mode |= S_IFDIR; | |
| 931 } | |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
932 |
| 139 | 933 break; |
| 934 case YAFFS_OBJECT_TYPE_UNKNOWN : | |
| 935 case YAFFS_OBJECT_TYPE_HARDLINK : | |
| 936 case YAFFS_OBJECT_TYPE_SPECIAL : | |
| 937 default: | |
| 938 /* TODO? */ | |
| 939 break; | |
| 940 } | |
| 941 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
942 inode->i_flags |= S_NOATIME; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
943 |
| 7 | 944 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
|
945 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
|
946 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
|
947 inode->i_gid = obj->yst_gid; |
| 166 | 948 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) |
| 7 | 949 inode->i_blksize = inode->i_sb->s_blocksize; |
| 166 | 950 #endif |
| 7 | 951 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) |
| 952 | |
|
22
0b57027b96fe
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles <charles>
parents:
19
diff
changeset
|
953 inode->i_rdev = old_decode_dev(obj->yst_rdev); |
| 76 | 954 inode->i_atime.tv_sec = (time_t) (obj->yst_atime); |
| 7 | 955 inode->i_atime.tv_nsec = 0; |
| 76 | 956 inode->i_mtime.tv_sec = (time_t) obj->yst_mtime; |
| 957 inode->i_mtime.tv_nsec = 0; | |
| 958 inode->i_ctime.tv_sec = (time_t) obj->yst_ctime; | |
| 7 | 959 inode->i_ctime.tv_nsec = 0; |
| 960 #else | |
|
22
0b57027b96fe
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles <charles>
parents:
19
diff
changeset
|
961 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
|
962 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
|
963 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
|
964 inode->i_ctime = obj->yst_ctime; |
| 7 | 965 #endif |
| 966 inode->i_size = yaffs_GetObjectFileLength(obj); | |
| 967 inode->i_blocks = (inode->i_size + 511) >> 9; | |
| 968 | |
| 969 inode->i_nlink = yaffs_GetObjectLinkCount(obj); | |
| 76 | 970 |
| 971 T(YAFFS_TRACE_OS, | |
| 972 (KERN_DEBUG | |
| 973 "yaffs_FillInode mode %x uid %d gid %d size %d count %d\n", | |
| 974 inode->i_mode, inode->i_uid, inode->i_gid, | |
| 975 (int)inode->i_size, atomic_read(&inode->i_count))); | |
| 976 | |
| 977 switch (obj->yst_mode & S_IFMT) { | |
| 978 default: /* fifo, device or socket */ | |
| 12 | 979 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) |
| 76 | 980 init_special_inode(inode, obj->yst_mode, |
| 981 old_decode_dev(obj->yst_rdev)); | |
| 12 | 982 #else |
| 76 | 983 init_special_inode(inode, obj->yst_mode, |
| 984 (dev_t) (obj->yst_rdev)); | |
| 985 #endif | |
| 986 break; | |
| 987 case S_IFREG: /* file */ | |
| 988 inode->i_op = &yaffs_file_inode_operations; | |
| 989 inode->i_fop = &yaffs_file_operations; | |
| 990 inode->i_mapping->a_ops = | |
| 991 &yaffs_file_address_operations; | |
| 992 break; | |
| 993 case S_IFDIR: /* directory */ | |
| 994 inode->i_op = &yaffs_dir_inode_operations; | |
| 995 inode->i_fop = &yaffs_dir_operations; | |
| 996 break; | |
| 997 case S_IFLNK: /* symlink */ | |
| 998 inode->i_op = &yaffs_symlink_inode_operations; | |
| 999 break; | |
| 7 | 1000 } |
| 76 | 1001 |
| 166 | 1002 yaffs_InodeToObjectLV(inode) = obj; |
| 1003 | |
| 7 | 1004 obj->myInode = inode; |
| 76 | 1005 |
| 1006 } else { | |
| 1007 T(YAFFS_TRACE_OS, | |
| 1008 (KERN_DEBUG "yaffs_FileInode invalid parameters\n")); | |
| 7 | 1009 } |
| 1010 | |
| 1011 } | |
| 1012 | |
| 76 | 1013 struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev, |
| 1014 yaffs_Object * obj) | |
| 7 | 1015 { |
| 76 | 1016 struct inode *inode; |
| 1017 | |
| 1018 if (!sb) { | |
| 1019 T(YAFFS_TRACE_OS, | |
| 1020 (KERN_DEBUG "yaffs_get_inode for NULL super_block!!\n")); | |
| 1021 return NULL; | |
| 1022 | |
| 7 | 1023 } |
| 76 | 1024 |
| 1025 if (!obj) { | |
| 1026 T(YAFFS_TRACE_OS, | |
| 1027 (KERN_DEBUG "yaffs_get_inode for NULL object!!\n")); | |
| 1028 return NULL; | |
| 1029 | |
| 7 | 1030 } |
| 76 | 1031 |
| 1032 T(YAFFS_TRACE_OS, | |
| 1033 (KERN_DEBUG "yaffs_get_inode for object %d\n", obj->objectId)); | |
| 7 | 1034 |
|
210
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1035 inode = Y_IGET(sb, obj->objectId); |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1036 if(IS_ERR(inode)) |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1037 return NULL; |
| 7 | 1038 |
| 76 | 1039 /* NB Side effect: iget calls back to yaffs_read_inode(). */ |
| 1040 /* iget also increments the inode's i_count */ | |
|
106
5b8f68c30468
Apply Reed's deadlocking fix (manually applied)
charles <charles>
parents:
104
diff
changeset
|
1041 /* NB You can't be holding grossLock or deadlock will happen! */ |
| 76 | 1042 |
| 7 | 1043 return inode; |
| 1044 } | |
| 1045 | |
| 76 | 1046 static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, |
| 1047 loff_t * pos) | |
| 7 | 1048 { |
| 1049 yaffs_Object *obj; | |
| 76 | 1050 int nWritten, ipos; |
| 7 | 1051 struct inode *inode; |
| 1052 yaffs_Device *dev; | |
| 76 | 1053 |
| 1054 obj = yaffs_DentryToObject(f->f_dentry); | |
| 1055 | |
| 7 | 1056 dev = obj->myDev; |
| 76 | 1057 |
| 7 | 1058 yaffs_GrossLock(dev); |
| 1059 | |
| 1060 inode = f->f_dentry->d_inode; | |
| 1061 | |
| 76 | 1062 if (!S_ISBLK(inode->i_mode) && f->f_flags & O_APPEND) { |
| 7 | 1063 ipos = inode->i_size; |
| 76 | 1064 } else { |
| 7 | 1065 ipos = *pos; |
| 1066 } | |
| 76 | 1067 |
| 1068 if (!obj) { | |
| 1069 T(YAFFS_TRACE_OS, | |
| 1070 (KERN_DEBUG "yaffs_file_write: hey obj is null!\n")); | |
| 1071 } else { | |
| 1072 T(YAFFS_TRACE_OS, | |
| 1073 (KERN_DEBUG | |
| 264 | 1074 "yaffs_file_write about to write writing %zu bytes" |
| 76 | 1075 "to object %d at %d\n", |
| 1076 n, obj->objectId, ipos)); | |
| 7 | 1077 } |
| 1078 | |
| 76 | 1079 nWritten = yaffs_WriteDataToFile(obj, buf, ipos, n, 0); |
| 7 | 1080 |
| 76 | 1081 T(YAFFS_TRACE_OS, |
| 264 | 1082 (KERN_DEBUG "yaffs_file_write writing %zu bytes, %d written at %d\n", |
| 76 | 1083 n, nWritten, ipos)); |
| 1084 if (nWritten > 0) { | |
| 7 | 1085 ipos += nWritten; |
| 1086 *pos = ipos; | |
| 76 | 1087 if (ipos > inode->i_size) { |
| 7 | 1088 inode->i_size = ipos; |
| 76 | 1089 inode->i_blocks = (ipos + 511) >> 9; |
| 1090 | |
| 1091 T(YAFFS_TRACE_OS, | |
| 1092 (KERN_DEBUG | |
| 1093 "yaffs_file_write size updated to %d bytes, " | |
| 1094 "%d blocks\n", | |
| 1095 ipos, (int)(inode->i_blocks))); | |
| 7 | 1096 } |
| 76 | 1097 |
| 7 | 1098 } |
| 1099 yaffs_GrossUnlock(dev); | |
|
113
325f5d3a757c
Handle partial writes more gracefully: return partial byte counts, return
tpoynor <tpoynor>
parents:
112
diff
changeset
|
1100 return nWritten == 0 ? -ENOSPC : nWritten; |
| 7 | 1101 } |
| 1102 | |
|
253
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1103 /* Space holding and freeing is done to ensure we have space available for write_begin/end */ |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1104 /* For now we just assume few parallel writes and check against a small number. */ |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1105 /* Todo: need to do this with a counter to handle parallel reads better */ |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1106 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1107 static ssize_t yaffs_hold_space(struct file *f) |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1108 { |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1109 yaffs_Object *obj; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1110 yaffs_Device *dev; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1111 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1112 int nFreeChunks; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1113 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1114 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1115 obj = yaffs_DentryToObject(f->f_dentry); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1116 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1117 dev = obj->myDev; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1118 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1119 yaffs_GrossLock(dev); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1120 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1121 nFreeChunks = yaffs_GetNumberOfFreeChunks(dev); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1122 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1123 yaffs_GrossUnlock(dev); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1124 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1125 return (nFreeChunks > 20) ? 1 : 0; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1126 } |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1127 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1128 static void yaffs_release_space(struct file *f) |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1129 { |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1130 yaffs_Object *obj; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1131 yaffs_Device *dev; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1132 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1133 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1134 obj = yaffs_DentryToObject(f->f_dentry); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1135 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1136 dev = obj->myDev; |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1137 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1138 yaffs_GrossLock(dev); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1139 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1140 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1141 yaffs_GrossUnlock(dev); |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1142 |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1143 } |
|
6dd9ed6bed42
Change Linux glue code to work with 2.6.28
charles <charles>
parents:
249
diff
changeset
|
1144 |
| 7 | 1145 static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir) |
| 1146 { | |
| 1147 yaffs_Object *obj; | |
| 1148 yaffs_Device *dev; | |
| 1149 struct inode *inode = f->f_dentry->d_inode; | |
| 1150 unsigned long offset, curoffs; | |
|
210
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1151 struct ylist_head *i; |
| 7 | 1152 yaffs_Object *l; |
| 76 | 1153 |
| 1154 char name[YAFFS_MAX_NAME_LENGTH + 1]; | |
| 1155 | |
| 1156 obj = yaffs_DentryToObject(f->f_dentry); | |
| 7 | 1157 dev = obj->myDev; |
| 76 | 1158 |
| 7 | 1159 yaffs_GrossLock(dev); |
| 76 | 1160 |
| 7 | 1161 offset = f->f_pos; |
| 76 | 1162 |
| 1163 T(YAFFS_TRACE_OS, ("yaffs_readdir: starting at %d\n", (int)offset)); | |
| 1164 | |
| 1165 if (offset == 0) { | |
| 1166 T(YAFFS_TRACE_OS, | |
| 1167 (KERN_DEBUG "yaffs_readdir: entry . ino %d \n", | |
| 1168 (int)inode->i_ino)); | |
| 1169 if (filldir(dirent, ".", 1, offset, inode->i_ino, DT_DIR) | |
| 1170 < 0) { | |
| 7 | 1171 goto out; |
| 1172 } | |
| 1173 offset++; | |
| 1174 f->f_pos++; | |
| 1175 } | |
| 76 | 1176 if (offset == 1) { |
| 1177 T(YAFFS_TRACE_OS, | |
| 1178 (KERN_DEBUG "yaffs_readdir: entry .. ino %d \n", | |
| 1179 (int)f->f_dentry->d_parent->d_inode->i_ino)); | |
| 1180 if (filldir | |
| 1181 (dirent, "..", 2, offset, | |
| 1182 f->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) { | |
| 7 | 1183 goto out; |
| 1184 } | |
| 1185 offset++; | |
| 1186 f->f_pos++; | |
| 1187 } | |
| 76 | 1188 |
| 7 | 1189 curoffs = 1; |
| 76 | 1190 |
| 117 | 1191 /* If the directory has changed since the open or last call to |
| 1192 readdir, rewind to after the 2 canned entries. */ | |
| 1193 | |
| 1194 if (f->f_version != inode->i_version) { | |
| 1195 offset = 2; | |
| 1196 f->f_pos = offset; | |
| 1197 f->f_version = inode->i_version; | |
| 1198 } | |
| 1199 | |
|
210
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1200 ylist_for_each(i, &obj->variant.directoryVariant.children) { |
| 7 | 1201 curoffs++; |
| 76 | 1202 if (curoffs >= offset) { |
|
210
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1203 l = ylist_entry(i, yaffs_Object, siblings); |
| 76 | 1204 |
| 1205 yaffs_GetObjectName(l, name, | |
| 1206 YAFFS_MAX_NAME_LENGTH + 1); | |
| 1207 T(YAFFS_TRACE_OS, | |
| 1208 (KERN_DEBUG "yaffs_readdir: %s inode %d\n", name, | |
| 1209 yaffs_GetObjectInode(l))); | |
| 1210 | |
| 1211 if (filldir(dirent, | |
| 1212 name, | |
| 1213 strlen(name), | |
| 1214 offset, | |
| 1215 yaffs_GetObjectInode(l), | |
| 1216 yaffs_GetObjectType(l)) | |
| 1217 < 0) { | |
| 7 | 1218 goto up_and_out; |
| 1219 } | |
| 76 | 1220 |
| 7 | 1221 offset++; |
| 76 | 1222 f->f_pos++; |
| 7 | 1223 } |
| 1224 } | |
| 1225 | |
| 76 | 1226 up_and_out: |
| 1227 out: | |
| 1228 | |
| 1229 yaffs_GrossUnlock(dev); | |
| 1230 | |
| 7 | 1231 return 0; |
| 1232 } | |
| 1233 | |
| 1234 /* | |
| 1235 * File creation. Allocate an inode, and we're done.. | |
| 1236 */ | |
| 266 | 1237 |
| 1238 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) | |
| 1239 #define YCRED(x) x | |
| 1240 #else | |
| 1241 #define YCRED(x) x->cred | |
| 1242 #endif | |
| 1243 | |
| 7 | 1244 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) |
| 76 | 1245 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, |
| 1246 dev_t rdev) | |
| 7 | 1247 #else |
| 76 | 1248 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, |
| 1249 int rdev) | |
| 7 | 1250 #endif |
| 1251 { | |
| 1252 struct inode *inode; | |
| 76 | 1253 |
| 7 | 1254 yaffs_Object *obj = NULL; |
| 1255 yaffs_Device *dev; | |
| 76 | 1256 |
| 7 | 1257 yaffs_Object *parent = yaffs_InodeToObject(dir); |
| 76 | 1258 |
| 7 | 1259 int error = -ENOSPC; |
| 266 | 1260 uid_t uid = YCRED(current)->fsuid; |
| 1261 gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid; | |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1262 |
| 133 | 1263 if((dir->i_mode & S_ISGID) && S_ISDIR(mode)) |
| 1264 mode |= S_ISGID; | |
| 7 | 1265 |
| 76 | 1266 if (parent) { |
| 1267 T(YAFFS_TRACE_OS, | |
| 1268 (KERN_DEBUG "yaffs_mknod: parent object %d type %d\n", | |
| 1269 parent->objectId, parent->variantType)); | |
| 1270 } else { | |
| 1271 T(YAFFS_TRACE_OS, | |
| 1272 (KERN_DEBUG "yaffs_mknod: could not get parent object\n")); | |
| 7 | 1273 return -EPERM; |
| 1274 } | |
| 76 | 1275 |
| 1276 T(YAFFS_TRACE_OS, ("yaffs_mknod: making oject for %s, " | |
| 1277 "mode %x dev %x\n", | |
| 1278 dentry->d_name.name, mode, rdev)); | |
| 7 | 1279 |
| 1280 dev = parent->myDev; | |
| 76 | 1281 |
| 7 | 1282 yaffs_GrossLock(dev); |
| 1283 | |
| 76 | 1284 switch (mode & S_IFMT) { |
| 1285 default: | |
| 1286 /* Special (socket, fifo, device...) */ | |
| 1287 T(YAFFS_TRACE_OS, (KERN_DEBUG | |
| 1288 "yaffs_mknod: making special\n")); | |
| 12 | 1289 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) |
| 76 | 1290 obj = |
| 1291 yaffs_MknodSpecial(parent, dentry->d_name.name, mode, uid, | |
| 1292 gid, old_encode_dev(rdev)); | |
| 12 | 1293 #else |
| 76 | 1294 obj = |
| 1295 yaffs_MknodSpecial(parent, dentry->d_name.name, mode, uid, | |
| 1296 gid, rdev); | |
| 1297 #endif | |
| 1298 break; | |
| 1299 case S_IFREG: /* file */ | |
| 1300 T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_mknod: making file\n")); | |
| 1301 obj = | |
| 1302 yaffs_MknodFile(parent, dentry->d_name.name, mode, uid, | |
| 1303 gid); | |
| 1304 break; | |
| 1305 case S_IFDIR: /* directory */ | |
| 1306 T(YAFFS_TRACE_OS, | |
| 1307 (KERN_DEBUG "yaffs_mknod: making directory\n")); | |
| 1308 obj = | |
| 1309 yaffs_MknodDirectory(parent, dentry->d_name.name, mode, | |
| 1310 uid, gid); | |
| 1311 break; | |
| 1312 case S_IFLNK: /* symlink */ | |
| 266 | 1313 T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_mknod: making symlink\n")); |
| 76 | 1314 obj = NULL; /* Do we ever get here? */ |
| 1315 break; | |
| 7 | 1316 } |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1317 |
|
106
5b8f68c30468
Apply Reed's deadlocking fix (manually applied)
charles <charles>
parents:
104
diff
changeset
|
1318 /* Can not call yaffs_get_inode() with gross lock held */ |
|
5b8f68c30468
Apply Reed's deadlocking fix (manually applied)
charles <charles>
parents:
104
diff
changeset
|
1319 yaffs_GrossUnlock(dev); |
| 76 | 1320 |
| 1321 if (obj) { | |
| 7 | 1322 inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj); |
| 1323 d_instantiate(dentry, inode); | |
| 76 | 1324 T(YAFFS_TRACE_OS, |
| 1325 (KERN_DEBUG "yaffs_mknod created object %d count = %d\n", | |
| 1326 obj->objectId, atomic_read(&inode->i_count))); | |
| 7 | 1327 error = 0; |
| 76 | 1328 } else { |
| 1329 T(YAFFS_TRACE_OS, | |
| 1330 (KERN_DEBUG "yaffs_mknod failed making object\n")); | |
| 7 | 1331 error = -ENOMEM; |
| 1332 } | |
| 1333 | |
| 1334 return error; | |
| 1335 } | |
| 1336 | |
| 76 | 1337 static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, int mode) |
| 7 | 1338 { |
| 1339 int retVal; | |
| 76 | 1340 T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_mkdir\n")); |
| 1341 retVal = yaffs_mknod(dir, dentry, mode | S_IFDIR, 0); | |
| 7 | 1342 #if 0 |
| 76 | 1343 /* attempt to fix dir bug - didn't work */ |
| 1344 if (!retVal) { | |
| 7 | 1345 dget(dentry); |
| 1346 } | |
| 1347 #endif | |
| 1348 return retVal; | |
| 1349 } | |
| 1350 | |
| 1351 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) | |
| 76 | 1352 static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode, |
| 1353 struct nameidata *n) | |
| 7 | 1354 #else |
| 1355 static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode) | |
| 1356 #endif | |
| 1357 { | |
| 76 | 1358 T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_create\n")); |
| 7 | 1359 return yaffs_mknod(dir, dentry, mode | S_IFREG, 0); |
| 1360 } | |
| 1361 | |
| 76 | 1362 static int yaffs_unlink(struct inode *dir, struct dentry *dentry) |
| 7 | 1363 { |
| 1364 int retVal; | |
| 76 | 1365 |
| 7 | 1366 yaffs_Device *dev; |
| 76 | 1367 |
| 1368 T(YAFFS_TRACE_OS, | |
| 1369 (KERN_DEBUG "yaffs_unlink %d:%s\n", (int)(dir->i_ino), | |
| 1370 dentry->d_name.name)); | |
| 1371 | |
| 7 | 1372 dev = yaffs_InodeToObject(dir)->myDev; |
| 76 | 1373 |
| 7 | 1374 yaffs_GrossLock(dev); |
| 76 | 1375 |
| 1376 retVal = yaffs_Unlink(yaffs_InodeToObject(dir), dentry->d_name.name); | |
| 1377 | |
| 1378 if (retVal == YAFFS_OK) { | |
| 7 | 1379 dentry->d_inode->i_nlink--; |
| 117 | 1380 dir->i_version++; |
| 1381 yaffs_GrossUnlock(dev); | |
| 7 | 1382 mark_inode_dirty(dentry->d_inode); |
| 1383 return 0; | |
| 1384 } | |
| 117 | 1385 yaffs_GrossUnlock(dev); |
| 1386 return -ENOTEMPTY; | |
| 7 | 1387 } |
| 1388 | |
| 1389 /* | |
| 1390 * Create a link... | |
| 1391 */ | |
| 76 | 1392 static int yaffs_link(struct dentry *old_dentry, struct inode *dir, |
| 1393 struct dentry *dentry) | |
| 7 | 1394 { |
| 1395 struct inode *inode = old_dentry->d_inode; | |
| 1396 yaffs_Object *obj = NULL; | |
| 76 | 1397 yaffs_Object *link = NULL; |
| 7 | 1398 yaffs_Device *dev; |
| 76 | 1399 |
| 1400 T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_link\n")); | |
| 1401 | |
| 7 | 1402 obj = yaffs_InodeToObject(inode); |
| 1403 dev = obj->myDev; | |
| 76 | 1404 |
| 7 | 1405 yaffs_GrossLock(dev); |
| 1406 | |
| 76 | 1407 if (!S_ISDIR(inode->i_mode)) /* Don't link directories */ |
| 7 | 1408 { |
| 76 | 1409 link = |
| 1410 yaffs_Link(yaffs_InodeToObject(dir), dentry->d_name.name, | |
| 1411 obj); | |
| 7 | 1412 } |
| 1413 | |
| 76 | 1414 if (link) { |
| 1415 old_dentry->d_inode->i_nlink = yaffs_GetObjectLinkCount(obj); | |
| 7 | 1416 d_instantiate(dentry, old_dentry->d_inode); |
| 1417 atomic_inc(&old_dentry->d_inode->i_count); | |
| 76 | 1418 T(YAFFS_TRACE_OS, |
| 1419 (KERN_DEBUG "yaffs_link link count %d i_count %d\n", | |
| 1420 old_dentry->d_inode->i_nlink, | |
| 1421 atomic_read(&old_dentry->d_inode->i_count))); | |
| 1422 | |
| 7 | 1423 } |
| 76 | 1424 |
| 7 | 1425 yaffs_GrossUnlock(dev); |
| 1426 | |
| 76 | 1427 if (link) { |
| 1428 | |
| 7 | 1429 return 0; |
| 1430 } | |
| 76 | 1431 |
| 1432 return -EPERM; | |
| 7 | 1433 } |
| 1434 | |
| 76 | 1435 static int yaffs_symlink(struct inode *dir, struct dentry *dentry, |
| 1436 const char *symname) | |
| 7 | 1437 { |
| 1438 yaffs_Object *obj; | |
| 1439 yaffs_Device *dev; | |
| 266 | 1440 uid_t uid = YCRED(current)->fsuid; |
| 1441 gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid; | |
| 76 | 1442 |
| 1443 T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_symlink\n")); | |
| 1444 | |
| 7 | 1445 dev = yaffs_InodeToObject(dir)->myDev; |
| 1446 yaffs_GrossLock(dev); | |
| 76 | 1447 obj = yaffs_MknodSymLink(yaffs_InodeToObject(dir), dentry->d_name.name, |
| 1448 S_IFLNK | S_IRWXUGO, uid, gid, symname); | |
| 7 | 1449 yaffs_GrossUnlock(dev); |
| 1450 | |
| 76 | 1451 if (obj) { |
| 7 | 1452 |
| 76 | 1453 struct inode *inode; |
| 1454 | |
|
22
0b57027b96fe
Some improvements to garbage collection and st_xxx to yst_xxx changes
charles <charles>
parents:
19
diff
changeset
|
1455 inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj); |
| 7 | 1456 d_instantiate(dentry, inode); |
| 76 | 1457 T(YAFFS_TRACE_OS, (KERN_DEBUG "symlink created OK\n")); |
| 7 | 1458 return 0; |
| 76 | 1459 } else { |
| 1460 T(YAFFS_TRACE_OS, (KERN_DEBUG "symlink not created\n")); | |
| 7 | 1461 |
| 1462 } | |
| 76 | 1463 |
| 7 | 1464 return -ENOMEM; |
| 1465 } | |
| 1466 | |
| 76 | 1467 static int yaffs_sync_object(struct file *file, struct dentry *dentry, |
| 1468 int datasync) | |
| 7 | 1469 { |
| 1470 | |
| 1471 yaffs_Object *obj; | |
| 1472 yaffs_Device *dev; | |
| 76 | 1473 |
| 7 | 1474 obj = yaffs_DentryToObject(dentry); |
| 1475 | |
| 1476 dev = obj->myDev; | |
| 76 | 1477 |
| 1478 T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_sync_object\n")); | |
| 7 | 1479 yaffs_GrossLock(dev); |
| 76 | 1480 yaffs_FlushFile(obj, 1); |
| 7 | 1481 yaffs_GrossUnlock(dev); |
| 1482 return 0; | |
| 1483 } | |
| 1484 | |
| 1485 /* | |
| 1486 * The VFS layer already does all the dentry stuff for rename. | |
| 1487 * | |
| 1488 * NB: POSIX says you can rename an object over an old object of the same name | |
| 1489 */ | |
| 76 | 1490 static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry, |
| 1491 struct inode *new_dir, struct dentry *new_dentry) | |
| 7 | 1492 { |
| 1493 yaffs_Device *dev; | |
| 1494 int retVal = YAFFS_FAIL; | |
| 1495 yaffs_Object *target; | |
| 76 | 1496 |
| 83 | 1497 T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_rename\n")); |
| 7 | 1498 dev = yaffs_InodeToObject(old_dir)->myDev; |
| 1499 | |
| 1500 yaffs_GrossLock(dev); | |
| 76 | 1501 |
| 1502 /* Check if the target is an existing directory that is not empty. */ | |
| 1503 target = | |
| 1504 yaffs_FindObjectByName(yaffs_InodeToObject(new_dir), | |
| 1505 new_dentry->d_name.name); | |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1506 |
|
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1507 |
| 76 | 1508 |
| 1509 if (target && | |
| 1510 target->variantType == YAFFS_OBJECT_TYPE_DIRECTORY && | |
|
210
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1511 !ylist_empty(&target->variant.directoryVariant.children)) { |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1512 |
| 83 | 1513 T(YAFFS_TRACE_OS, (KERN_DEBUG "target is non-empty dir\n")); |
| 1514 | |
| 7 | 1515 retVal = YAFFS_FAIL; |
| 76 | 1516 } else { |
| 1517 | |
| 1518 /* Now does unlinking internally using shadowing mechanism */ | |
| 83 | 1519 T(YAFFS_TRACE_OS, (KERN_DEBUG "calling yaffs_RenameObject\n")); |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1520 |
| 76 | 1521 retVal = |
| 1522 yaffs_RenameObject(yaffs_InodeToObject(old_dir), | |
| 1523 old_dentry->d_name.name, | |
| 1524 yaffs_InodeToObject(new_dir), | |
| 1525 new_dentry->d_name.name); | |
| 1526 | |
| 7 | 1527 } |
| 1528 yaffs_GrossUnlock(dev); | |
| 76 | 1529 |
| 1530 if (retVal == YAFFS_OK) { | |
| 88 | 1531 if(target) { |
| 1532 new_dentry->d_inode->i_nlink--; | |
| 1533 mark_inode_dirty(new_dentry->d_inode); | |
| 1534 } | |
| 76 | 1535 |
| 7 | 1536 return 0; |
| 76 | 1537 } else { |
| 7 | 1538 return -ENOTEMPTY; |
| 1539 } | |
| 1540 | |
| 1541 } | |
| 1542 | |
| 1543 static int yaffs_setattr(struct dentry *dentry, struct iattr *attr) | |
| 1544 { | |
| 1545 struct inode *inode = dentry->d_inode; | |
| 1546 int error; | |
| 1547 yaffs_Device *dev; | |
| 76 | 1548 |
| 1549 T(YAFFS_TRACE_OS, | |
| 1550 (KERN_DEBUG "yaffs_setattr of object %d\n", | |
| 1551 yaffs_InodeToObject(inode)->objectId)); | |
| 1552 | |
| 1553 if ((error = inode_change_ok(inode, attr)) == 0) { | |
| 1554 | |
| 7 | 1555 dev = yaffs_InodeToObject(inode)->myDev; |
| 1556 yaffs_GrossLock(dev); | |
| 76 | 1557 if (yaffs_SetAttributes(yaffs_InodeToObject(inode), attr) == |
| 1558 YAFFS_OK) { | |
| 7 | 1559 error = 0; |
| 76 | 1560 } else { |
| 7 | 1561 error = -EPERM; |
| 1562 } | |
| 1563 yaffs_GrossUnlock(dev); | |
| 23 | 1564 if (!error) |
| 76 | 1565 error = inode_setattr(inode, attr); |
| 7 | 1566 } |
| 1567 return error; | |
| 1568 } | |
| 1569 | |
| 143 | 1570 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) |
| 1571 static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf) | |
| 1572 { | |
| 1573 yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev; | |
| 1574 struct super_block *sb = dentry->d_sb; | |
| 1575 #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) | |
| 7 | 1576 static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf) |
| 143 | 1577 { |
| 1578 yaffs_Device *dev = yaffs_SuperToDevice(sb); | |
| 7 | 1579 #else |
| 1580 static int yaffs_statfs(struct super_block *sb, struct statfs *buf) | |
| 143 | 1581 { |
| 1582 yaffs_Device *dev = yaffs_SuperToDevice(sb); | |
| 7 | 1583 #endif |
| 15 | 1584 |
| 76 | 1585 T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_statfs\n")); |
| 7 | 1586 |
| 1587 yaffs_GrossLock(dev); | |
| 76 | 1588 |
| 7 | 1589 buf->f_type = YAFFS_MAGIC; |
| 1590 buf->f_bsize = sb->s_blocksize; | |
| 1591 buf->f_namelen = 255; | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1592 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1593 if(dev->nDataBytesPerChunk & (dev->nDataBytesPerChunk - 1)){ |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1594 /* Do this if chunk size is not a power of 2 */ |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1595 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1596 uint64_t bytesInDev; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1597 uint64_t bytesFree; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1598 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1599 bytesInDev = ((uint64_t)((dev->endBlock - dev->startBlock +1))) * |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1600 ((uint64_t)(dev->nChunksPerBlock * dev->nDataBytesPerChunk)); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1601 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1602 do_div(bytesInDev,sb->s_blocksize); /* bytesInDev becomes the number of blocks */ |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1603 buf->f_blocks = bytesInDev; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1604 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1605 bytesFree = ((uint64_t)(yaffs_GetNumberOfFreeChunks(dev))) * |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1606 ((uint64_t)(dev->nDataBytesPerChunk)); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1607 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1608 do_div(bytesFree,sb->s_blocksize); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1609 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1610 buf->f_bfree = bytesFree; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1611 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1612 } else if (sb->s_blocksize > dev->nDataBytesPerChunk) { |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1613 |
| 76 | 1614 buf->f_blocks = |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1615 (dev->endBlock - dev->startBlock + 1) * |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1616 dev->nChunksPerBlock / |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1617 (sb->s_blocksize / dev->nDataBytesPerChunk); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1618 buf->f_bfree = |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1619 yaffs_GetNumberOfFreeChunks(dev) / |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1620 (sb->s_blocksize / dev->nDataBytesPerChunk); |
| 76 | 1621 } else { |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1622 buf->f_blocks = |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1623 (dev->endBlock - dev->startBlock + 1) * |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1624 dev->nChunksPerBlock * |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1625 (dev->nDataBytesPerChunk / sb->s_blocksize); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1626 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1627 buf->f_bfree = |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1628 yaffs_GetNumberOfFreeChunks(dev) * |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1629 (dev->nDataBytesPerChunk / sb->s_blocksize); |
| 15 | 1630 } |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1631 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1632 |
| 7 | 1633 buf->f_files = 0; |
| 1634 buf->f_ffree = 0; | |
| 76 | 1635 buf->f_bavail = buf->f_bfree; |
| 1636 | |
| 7 | 1637 yaffs_GrossUnlock(dev); |
| 1638 return 0; | |
| 1639 } | |
| 1640 | |
| 129 | 1641 |
| 1642 static int yaffs_do_sync_fs(struct super_block *sb) | |
| 1643 { | |
| 1644 | |
| 1645 yaffs_Device *dev = yaffs_SuperToDevice(sb); | |
| 1646 T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_do_sync_fs\n")); | |
| 1647 | |
| 1648 if(sb->s_dirt) { | |
| 1649 yaffs_GrossLock(dev); | |
| 1650 | |
|
210
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1651 if(dev){ |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1652 yaffs_FlushEntireDeviceCache(dev); |
| 129 | 1653 yaffs_CheckpointSave(dev); |
|
210
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1654 } |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1655 |
| 129 | 1656 yaffs_GrossUnlock(dev); |
| 1657 | |
| 1658 sb->s_dirt = 0; | |
| 1659 } | |
| 1660 return 0; | |
| 1661 } | |
|
210
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1662 |
| 129 | 1663 |
| 143 | 1664 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) |
| 1665 static void yaffs_write_super(struct super_block *sb) | |
| 1666 #else | |
| 129 | 1667 static int yaffs_write_super(struct super_block *sb) |
| 143 | 1668 #endif |
| 129 | 1669 { |
| 1670 | |
| 1671 T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_write_super\n")); | |
| 249 | 1672 if (yaffs_auto_checkpoint >= 2) |
| 1673 yaffs_do_sync_fs(sb); | |
| 143 | 1674 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) |
|
210
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1675 return 0; |
| 143 | 1676 #endif |
| 129 | 1677 } |
| 1678 | |
| 1679 | |
| 143 | 1680 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) |
| 1681 static int yaffs_sync_fs(struct super_block *sb, int wait) | |
| 1682 #else | |
| 129 | 1683 static int yaffs_sync_fs(struct super_block *sb) |
| 143 | 1684 #endif |
| 129 | 1685 { |
| 1686 | |
| 1687 T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_sync_fs\n")); | |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1688 |
| 249 | 1689 if (yaffs_auto_checkpoint >= 1) |
| 1690 yaffs_do_sync_fs(sb); | |
|
210
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1691 |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1692 return 0; |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1693 |
| 129 | 1694 } |
| 1695 | |
|
210
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1696 #ifdef YAFFS_USE_OWN_IGET |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1697 |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1698 static struct inode * yaffs_iget(struct super_block *sb, unsigned long ino) |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1699 { |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1700 struct inode *inode; |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1701 yaffs_Object *obj; |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1702 yaffs_Device *dev = yaffs_SuperToDevice(sb); |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1703 |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1704 T(YAFFS_TRACE_OS, |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1705 (KERN_DEBUG "yaffs_iget for %lu\n", ino)); |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1706 |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1707 inode = iget_locked(sb, ino); |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1708 if (!inode) |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1709 return ERR_PTR(-ENOMEM); |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1710 if (!(inode->i_state & I_NEW)) |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1711 return inode; |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1712 |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1713 /* NB This is called as a side effect of other functions, but |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1714 * we had to release the lock to prevent deadlocks, so |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1715 * need to lock again. |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1716 */ |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1717 |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1718 yaffs_GrossLock(dev); |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1719 |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1720 obj = yaffs_FindObjectByNumber(dev, inode->i_ino); |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1721 |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1722 yaffs_FillInodeFromObject(inode, obj); |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1723 |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1724 yaffs_GrossUnlock(dev); |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1725 |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1726 unlock_new_inode(inode); |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1727 return inode; |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1728 } |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1729 |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1730 #else |
| 129 | 1731 |
| 76 | 1732 static void yaffs_read_inode(struct inode *inode) |
| 7 | 1733 { |
|
106
5b8f68c30468
Apply Reed's deadlocking fix (manually applied)
charles <charles>
parents:
104
diff
changeset
|
1734 /* NB This is called as a side effect of other functions, but |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1735 * we had to release the lock to prevent deadlocks, so |
|
106
5b8f68c30468
Apply Reed's deadlocking fix (manually applied)
charles <charles>
parents:
104
diff
changeset
|
1736 * need to lock again. |
| 76 | 1737 */ |
| 1738 | |
| 1739 yaffs_Object *obj; | |
| 7 | 1740 yaffs_Device *dev = yaffs_SuperToDevice(inode->i_sb); |
| 76 | 1741 |
| 1742 T(YAFFS_TRACE_OS, | |
| 1743 (KERN_DEBUG "yaffs_read_inode for %d\n", (int)inode->i_ino)); | |
| 7 | 1744 |
|
106
5b8f68c30468
Apply Reed's deadlocking fix (manually applied)
charles <charles>
parents:
104
diff
changeset
|
1745 yaffs_GrossLock(dev); |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1746 |
| 76 | 1747 obj = yaffs_FindObjectByNumber(dev, inode->i_ino); |
| 1748 | |
| 1749 yaffs_FillInodeFromObject(inode, obj); | |
| 7 | 1750 |
|
106
5b8f68c30468
Apply Reed's deadlocking fix (manually applied)
charles <charles>
parents:
104
diff
changeset
|
1751 yaffs_GrossUnlock(dev); |
| 7 | 1752 } |
| 1753 | |
|
210
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1754 #endif |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1755 |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1756 static YLIST_HEAD(yaffs_dev_list); |
| 7 | 1757 |
| 189 | 1758 #if 0 // not used |
| 175 | 1759 static int yaffs_remount_fs(struct super_block *sb, int *flags, char *data) |
| 1760 { | |
| 1761 yaffs_Device *dev = yaffs_SuperToDevice(sb); | |
| 1762 | |
| 1763 if( *flags & MS_RDONLY ) { | |
| 1764 struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice; | |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1765 |
| 175 | 1766 T(YAFFS_TRACE_OS, |
| 1767 (KERN_DEBUG "yaffs_remount_fs: %s: RO\n", dev->name )); | |
| 1768 | |
| 1769 yaffs_GrossLock(dev); | |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1770 |
| 175 | 1771 yaffs_FlushEntireDeviceCache(dev); |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1772 |
| 175 | 1773 yaffs_CheckpointSave(dev); |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1774 |
| 175 | 1775 if (mtd->sync) |
| 1776 mtd->sync(mtd); | |
| 1777 | |
| 1778 yaffs_GrossUnlock(dev); | |
| 1779 } | |
| 1780 else { | |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1781 T(YAFFS_TRACE_OS, |
| 175 | 1782 (KERN_DEBUG "yaffs_remount_fs: %s: RW\n", dev->name )); |
| 1783 } | |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1784 |
| 175 | 1785 return 0; |
| 1786 } | |
| 189 | 1787 #endif |
| 175 | 1788 |
| 7 | 1789 static void yaffs_put_super(struct super_block *sb) |
| 1790 { | |
| 1791 yaffs_Device *dev = yaffs_SuperToDevice(sb); | |
| 76 | 1792 |
| 129 | 1793 T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_put_super\n")); |
| 1794 | |
| 7 | 1795 yaffs_GrossLock(dev); |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1796 |
| 123 | 1797 yaffs_FlushEntireDeviceCache(dev); |
| 175 | 1798 |
| 1799 yaffs_CheckpointSave(dev); | |
| 1800 | |
| 76 | 1801 if (dev->putSuperFunc) { |
| 1802 dev->putSuperFunc(sb); | |
| 7 | 1803 } |
| 175 | 1804 |
| 7 | 1805 yaffs_Deinitialise(dev); |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1806 |
| 7 | 1807 yaffs_GrossUnlock(dev); |
| 1808 | |
| 27 | 1809 /* we assume this is protected by lock_kernel() in mount/umount */ |
|
210
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
1810 ylist_del(&dev->devList); |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1811 |
| 124 | 1812 if(dev->spareBuffer){ |
| 1813 YFREE(dev->spareBuffer); | |
| 1814 dev->spareBuffer = NULL; | |
| 1815 } | |
| 27 | 1816 |
| 7 | 1817 kfree(dev); |
| 1818 } | |
| 1819 | |
| 1820 | |
| 76 | 1821 static void yaffs_MTDPutSuper(struct super_block *sb) |
| 7 | 1822 { |
| 76 | 1823 |
| 7 | 1824 struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice; |
| 76 | 1825 |
| 1826 if (mtd->sync) { | |
| 7 | 1827 mtd->sync(mtd); |
| 1828 } | |
| 76 | 1829 |
| 7 | 1830 put_mtd_device(mtd); |
| 1831 } | |
| 1832 | |
| 1833 | |
| 129 | 1834 static void yaffs_MarkSuperBlockDirty(void *vsb) |
| 1835 { | |
| 1836 struct super_block *sb = (struct super_block *)vsb; | |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1837 |
| 129 | 1838 T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_MarkSuperBlockDirty() sb = %p\n",sb)); |
| 249 | 1839 if(sb) |
| 1840 sb->s_dirt = 1; | |
| 129 | 1841 } |
| 1842 | |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1843 typedef struct { |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1844 int inband_tags; |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1845 int skip_checkpoint_read; |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1846 int skip_checkpoint_write; |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1847 int no_cache; |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1848 } yaffs_options; |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1849 |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1850 #define MAX_OPT_LEN 20 |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1851 static int yaffs_parse_options(yaffs_options *options, const char *options_str) |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1852 { |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1853 char cur_opt[MAX_OPT_LEN+1]; |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1854 int p; |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1855 int error = 0; |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1856 |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1857 /* Parse through the options which is a comma seperated list */ |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1858 |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1859 while(options_str && *options_str && !error){ |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1860 memset(cur_opt,0,MAX_OPT_LEN+1); |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1861 p = 0; |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1862 |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1863 while(*options_str && *options_str != ','){ |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1864 if(p < MAX_OPT_LEN){ |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1865 cur_opt[p] = *options_str; |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1866 p++; |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1867 } |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1868 options_str++; |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1869 } |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1870 |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1871 if(!strcmp(cur_opt,"inband-tags")) |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1872 options->inband_tags = 1; |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1873 else if(!strcmp(cur_opt,"no-cache")) |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1874 options->no_cache = 1; |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1875 else if(!strcmp(cur_opt,"no-checkpoint-read")) |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1876 options->skip_checkpoint_read = 1; |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1877 else if(!strcmp(cur_opt,"no-checkpoint-write")) |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1878 options->skip_checkpoint_write = 1; |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1879 else if(!strcmp(cur_opt,"no-checkpoint")){ |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1880 options->skip_checkpoint_read = 1; |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1881 options->skip_checkpoint_write = 1; |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1882 } else { |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1883 printk(KERN_INFO "yaffs: Bad mount option \"%s\"\n",cur_opt); |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1884 error = 1; |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1885 } |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1886 |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1887 } |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1888 |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1889 return error; |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1890 } |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1891 |
| 76 | 1892 static struct super_block *yaffs_internal_read_super(int yaffsVersion, |
| 1893 struct super_block *sb, | |
| 1894 void *data, int silent) | |
| 7 | 1895 { |
| 1896 int nBlocks; | |
| 76 | 1897 struct inode *inode = NULL; |
| 1898 struct dentry *root; | |
| 27 | 1899 yaffs_Device *dev = 0; |
| 76 | 1900 char devname_buf[BDEVNAME_SIZE + 1]; |
|
59
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
1901 struct mtd_info *mtd; |
| 7 | 1902 int err; |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1903 char *data_str = (char *)data; |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1904 |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1905 yaffs_options options; |
| 76 | 1906 |
| 7 | 1907 sb->s_magic = YAFFS_MAGIC; |
| 1908 sb->s_op = &yaffs_super_ops; | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1909 sb->s_flags |= MS_NOATIME; |
| 76 | 1910 |
| 1911 if (!sb) | |
| 1912 printk(KERN_INFO "yaffs: sb is NULL\n"); | |
| 1913 else if (!sb->s_dev) | |
| 1914 printk(KERN_INFO "yaffs: sb->s_dev is NULL\n"); | |
| 1915 else if (!yaffs_devname(sb, devname_buf)) | |
| 1916 printk(KERN_INFO "yaffs: devname is NULL\n"); | |
| 7 | 1917 else |
| 76 | 1918 printk(KERN_INFO "yaffs: dev is %d name is \"%s\"\n", |
| 1919 sb->s_dev, | |
| 1920 yaffs_devname(sb, devname_buf)); | |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1921 |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1922 if(!data_str) |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1923 data_str = ""; |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1924 |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1925 printk(KERN_INFO "yaffs: passed flags \"%s\"\n",data_str); |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1926 |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1927 memset(&options,0,sizeof(options)); |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1928 |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1929 if(yaffs_parse_options(&options,data_str)){ |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1930 /* Option parsing failed */ |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1931 return NULL; |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1932 } |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1933 |
| 7 | 1934 |
| 1935 sb->s_blocksize = PAGE_CACHE_SIZE; | |
| 1936 sb->s_blocksize_bits = PAGE_CACHE_SHIFT; | |
| 76 | 1937 T(YAFFS_TRACE_OS, ("yaffs_read_super: Using yaffs%d\n", yaffsVersion)); |
| 1938 T(YAFFS_TRACE_OS, | |
| 1939 ("yaffs_read_super: block size %d\n", (int)(sb->s_blocksize))); | |
| 7 | 1940 |
| 1941 #ifdef CONFIG_YAFFS_DISABLE_WRITE_VERIFY | |
| 76 | 1942 T(YAFFS_TRACE_OS, |
| 1943 ("yaffs: Write verification disabled. All guarantees " | |
| 1944 "null and void\n")); | |
| 7 | 1945 #endif |
| 1946 | |
| 76 | 1947 T(YAFFS_TRACE_ALWAYS, ("yaffs: Attempting MTD mount on %u.%u, " |
| 1948 "\"%s\"\n", | |
| 1949 MAJOR(sb->s_dev), MINOR(sb->s_dev), | |
| 1950 yaffs_devname(sb, devname_buf))); | |
| 7 | 1951 |
| 76 | 1952 /* Check it's an mtd device..... */ |
| 1953 if (MAJOR(sb->s_dev) != MTD_BLOCK_MAJOR) { | |
| 1954 return NULL; /* This isn't an mtd device */ | |
| 1955 } | |
| 1956 /* Get the device */ | |
|
59
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
1957 mtd = get_mtd_device(NULL, MINOR(sb->s_dev)); |
| 76 | 1958 if (!mtd) { |
| 1959 T(YAFFS_TRACE_ALWAYS, | |
| 1960 ("yaffs: MTD device #%u doesn't appear to exist\n", | |
| 1961 MINOR(sb->s_dev))); | |
|
59
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
1962 return NULL; |
|
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
1963 } |
| 76 | 1964 /* Check it's NAND */ |
| 1965 if (mtd->type != MTD_NANDFLASH) { | |
| 1966 T(YAFFS_TRACE_ALWAYS, | |
| 1967 ("yaffs: MTD device is not NAND it's type %d\n", mtd->type)); | |
|
59
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
1968 return NULL; |
|
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
1969 } |
|
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
1970 |
| 76 | 1971 T(YAFFS_TRACE_OS, (" erase %p\n", mtd->erase)); |
| 1972 T(YAFFS_TRACE_OS, (" read %p\n", mtd->read)); | |
| 1973 T(YAFFS_TRACE_OS, (" write %p\n", mtd->write)); | |
| 1974 T(YAFFS_TRACE_OS, (" readoob %p\n", mtd->read_oob)); | |
| 1975 T(YAFFS_TRACE_OS, (" writeoob %p\n", mtd->write_oob)); | |
| 1976 T(YAFFS_TRACE_OS, (" block_isbad %p\n", mtd->block_isbad)); | |
| 1977 T(YAFFS_TRACE_OS, (" block_markbad %p\n", mtd->block_markbad)); | |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
1978 T(YAFFS_TRACE_OS, (" %s %d\n", WRITE_SIZE_STR, WRITE_SIZE(mtd))); |
| 76 | 1979 T(YAFFS_TRACE_OS, (" oobsize %d\n", mtd->oobsize)); |
| 1980 T(YAFFS_TRACE_OS, (" erasesize %d\n", mtd->erasesize)); | |
| 266 | 1981 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) |
| 1982 T(YAFFS_TRACE_OS, (" size %u\n", mtd->size)); | |
| 1983 #else | |
| 1984 T(YAFFS_TRACE_OS, (" size %lld\n", mtd->size)); | |
| 1985 #endif | |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1986 |
| 109 | 1987 #ifdef CONFIG_YAFFS_AUTO_YAFFS2 |
| 108 | 1988 |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1989 if (yaffsVersion == 1 && |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1990 WRITE_SIZE(mtd) >= 2048) { |
| 108 | 1991 T(YAFFS_TRACE_ALWAYS,("yaffs: auto selecting yaffs2\n")); |
| 1992 yaffsVersion = 2; | |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1993 } |
|
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
1994 |
| 137 | 1995 /* Added NCB 26/5/2006 for completeness */ |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1996 if (yaffsVersion == 2 && |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1997 !options.inband_tags && |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
1998 WRITE_SIZE(mtd) == 512){ |
| 137 | 1999 T(YAFFS_TRACE_ALWAYS,("yaffs: auto selecting yaffs1\n")); |
| 2000 yaffsVersion = 1; | |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
2001 } |
| 137 | 2002 |
| 108 | 2003 #endif |
|
59
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2004 |
| 76 | 2005 if (yaffsVersion == 2) { |
| 2006 /* Check for version 2 style functions */ | |
| 2007 if (!mtd->erase || | |
| 2008 !mtd->block_isbad || | |
| 2009 !mtd->block_markbad || | |
| 2010 !mtd->read || | |
| 2011 !mtd->write || | |
| 143 | 2012 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) |
| 2013 !mtd->read_oob || !mtd->write_oob) { | |
| 2014 #else | |
| 76 | 2015 !mtd->write_ecc || |
| 2016 !mtd->read_ecc || !mtd->read_oob || !mtd->write_oob) { | |
| 143 | 2017 #endif |
| 76 | 2018 T(YAFFS_TRACE_ALWAYS, |
| 2019 ("yaffs: MTD device does not support required " | |
| 2020 "functions\n"));; | |
| 7 | 2021 return NULL; |
| 2022 } | |
| 76 | 2023 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
2024 if ((WRITE_SIZE(mtd) < YAFFS_MIN_YAFFS2_CHUNK_SIZE || |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
2025 mtd->oobsize < YAFFS_MIN_YAFFS2_SPARE_SIZE) && |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
2026 !options.inband_tags) { |
| 76 | 2027 T(YAFFS_TRACE_ALWAYS, |
|
126
2e7fd6d40037
Fix a couple of mistakes in TRACE/Error messages. Update copyright date.
wookey <wookey>
parents:
124
diff
changeset
|
2028 ("yaffs: MTD device does not have the " |
| 76 | 2029 "right page sizes\n")); |
|
59
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2030 return NULL; |
| 7 | 2031 } |
| 76 | 2032 } else { |
| 2033 /* Check for V1 style functions */ | |
| 2034 if (!mtd->erase || | |
| 2035 !mtd->read || | |
| 2036 !mtd->write || | |
| 143 | 2037 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) |
| 2038 !mtd->read_oob || !mtd->write_oob) { | |
| 2039 #else | |
| 76 | 2040 !mtd->write_ecc || |
| 2041 !mtd->read_ecc || !mtd->read_oob || !mtd->write_oob) { | |
| 143 | 2042 #endif |
| 76 | 2043 T(YAFFS_TRACE_ALWAYS, |
| 2044 ("yaffs: MTD device does not support required " | |
| 2045 "functions\n"));; | |
| 2046 return NULL; | |
| 2047 } | |
| 2048 | |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2049 if (WRITE_SIZE(mtd) < YAFFS_BYTES_PER_CHUNK || |
| 76 | 2050 mtd->oobsize != YAFFS_BYTES_PER_SPARE) { |
| 2051 T(YAFFS_TRACE_ALWAYS, | |
| 2052 ("yaffs: MTD device does not support have the " | |
| 2053 "right page sizes\n")); | |
|
59
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2054 return NULL; |
|
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2055 } |
|
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2056 } |
| 7 | 2057 |
| 76 | 2058 /* OK, so if we got here, we have an MTD that's NAND and looks |
| 2059 * like it has the right capabilities | |
| 2060 * Set the yaffs_Device up for mtd | |
| 2061 */ | |
| 7 | 2062 |
| 2063 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) | |
| 76 | 2064 sb->s_fs_info = dev = kmalloc(sizeof(yaffs_Device), GFP_KERNEL); |
| 7 | 2065 #else |
| 76 | 2066 sb->u.generic_sbp = dev = kmalloc(sizeof(yaffs_Device), GFP_KERNEL); |
| 7 | 2067 #endif |
| 76 | 2068 if (!dev) { |
| 2069 /* Deep shit could not allocate device structure */ | |
| 2070 T(YAFFS_TRACE_ALWAYS, | |
| 2071 ("yaffs_read_super: Failed trying to allocate " | |
| 2072 "yaffs_Device. \n")); | |
|
59
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2073 return NULL; |
|
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2074 } |
|
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2075 |
| 76 | 2076 memset(dev, 0, sizeof(yaffs_Device)); |
| 2077 dev->genericDevice = mtd; | |
|
59
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2078 dev->name = mtd->name; |
| 7 | 2079 |
| 76 | 2080 /* Set up the memory size parameters.... */ |
| 2081 | |
| 266 | 2082 nBlocks = YCALCBLOCKS(mtd->size ,(YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK)); |
| 2083 | |
|
59
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2084 dev->startBlock = 0; |
|
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2085 dev->endBlock = nBlocks - 1; |
|
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2086 dev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK; |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
2087 dev->totalBytesPerChunk = YAFFS_BYTES_PER_CHUNK; |
|
59
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2088 dev->nReservedBlocks = 5; |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2089 dev->nShortOpCaches = (options.no_cache) ? 0 : 10; |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
2090 dev->inbandTags = options.inband_tags; |
| 7 | 2091 |
| 76 | 2092 /* ... and the functions. */ |
| 2093 if (yaffsVersion == 2) { | |
| 2094 dev->writeChunkWithTagsToNAND = | |
| 2095 nandmtd2_WriteChunkWithTagsToNAND; | |
| 2096 dev->readChunkWithTagsFromNAND = | |
| 2097 nandmtd2_ReadChunkWithTagsFromNAND; | |
|
59
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2098 dev->markNANDBlockBad = nandmtd2_MarkNANDBlockBad; |
|
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2099 dev->queryNANDBlock = nandmtd2_QueryNANDBlock; |
|
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2100 dev->spareBuffer = YMALLOC(mtd->oobsize); |
|
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2101 dev->isYaffs2 = 1; |
| 143 | 2102 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
2103 dev->totalBytesPerChunk = mtd->writesize; |
| 143 | 2104 dev->nChunksPerBlock = mtd->erasesize / mtd->writesize; |
| 2105 #else | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
2106 dev->totalBytesPerChunk = mtd->oobblock; |
|
59
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2107 dev->nChunksPerBlock = mtd->erasesize / mtd->oobblock; |
| 143 | 2108 #endif |
| 266 | 2109 nBlocks = YCALCBLOCKS(mtd->size,mtd->erasesize); |
| 131 | 2110 |
| 129 | 2111 dev->startBlock = 0; |
| 7 | 2112 dev->endBlock = nBlocks - 1; |
| 76 | 2113 } else { |
| 179 | 2114 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) |
| 2115 /* use the MTD interface in yaffs_mtdif1.c */ | |
| 2116 dev->writeChunkWithTagsToNAND = | |
| 2117 nandmtd1_WriteChunkWithTagsToNAND; | |
| 2118 dev->readChunkWithTagsFromNAND = | |
| 2119 nandmtd1_ReadChunkWithTagsFromNAND; | |
| 2120 dev->markNANDBlockBad = nandmtd1_MarkNANDBlockBad; | |
| 2121 dev->queryNANDBlock = nandmtd1_QueryNANDBlock; | |
| 2122 #else | |
|
59
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2123 dev->writeChunkToNAND = nandmtd_WriteChunkToNAND; |
|
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2124 dev->readChunkFromNAND = nandmtd_ReadChunkFromNAND; |
| 179 | 2125 #endif |
|
59
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2126 dev->isYaffs2 = 0; |
|
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2127 } |
| 76 | 2128 /* ... and common functions */ |
|
59
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2129 dev->eraseBlockInNAND = nandmtd_EraseBlockInNAND; |
|
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2130 dev->initialiseNAND = nandmtd_InitialiseNAND; |
| 76 | 2131 |
|
59
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2132 dev->putSuperFunc = yaffs_MTDPutSuper; |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
2133 |
| 129 | 2134 dev->superBlock = (void *)sb; |
| 2135 dev->markSuperBlockDirty = yaffs_MarkSuperBlockDirty; | |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
2136 |
| 76 | 2137 |
|
61
49f66fca0b09
newconfig: use YAFFS_DOES_ECC instead of USE_NANDECC
luc <luc>
parents:
59
diff
changeset
|
2138 #ifndef CONFIG_YAFFS_DOES_ECC |
|
59
d6ff669317b8
Adapt the code structure after removing of the yaffsram support.
luc <luc>
parents:
58
diff
changeset
|
2139 dev->useNANDECC = 1; |
| 7 | 2140 #endif |
| 2141 | |
| 104 | 2142 #ifdef CONFIG_YAFFS_DISABLE_WIDE_TNODES |
| 2143 dev->wideTnodesDisabled = 1; | |
| 2144 #endif | |
| 2145 | |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2146 dev->skipCheckpointRead = options.skip_checkpoint_read; |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2147 dev->skipCheckpointWrite = options.skip_checkpoint_write; |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
2148 |
| 27 | 2149 /* we assume this is protected by lock_kernel() in mount/umount */ |
|
210
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
2150 ylist_add_tail(&dev->devList, &yaffs_dev_list); |
| 27 | 2151 |
| 7 | 2152 init_MUTEX(&dev->grossLock); |
| 76 | 2153 |
| 7 | 2154 yaffs_GrossLock(dev); |
| 76 | 2155 |
| 7 | 2156 err = yaffs_GutsInitialise(dev); |
| 2157 | |
| 76 | 2158 T(YAFFS_TRACE_OS, |
| 2159 ("yaffs_read_super: guts initialised %s\n", | |
| 2160 (err == YAFFS_OK) ? "OK" : "FAILED")); | |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
2161 |
|
106
5b8f68c30468
Apply Reed's deadlocking fix (manually applied)
charles <charles>
parents:
104
diff
changeset
|
2162 /* Release lock before yaffs_get_inode() */ |
|
5b8f68c30468
Apply Reed's deadlocking fix (manually applied)
charles <charles>
parents:
104
diff
changeset
|
2163 yaffs_GrossUnlock(dev); |
| 7 | 2164 |
| 76 | 2165 /* Create root inode */ |
| 2166 if (err == YAFFS_OK) | |
| 2167 inode = yaffs_get_inode(sb, S_IFDIR | 0755, 0, | |
| 2168 yaffs_Root(dev)); | |
| 7 | 2169 |
| 2170 if (!inode) | |
| 2171 return NULL; | |
| 2172 | |
| 76 | 2173 inode->i_op = &yaffs_dir_inode_operations; |
| 2174 inode->i_fop = &yaffs_dir_operations; | |
| 2175 | |
| 2176 T(YAFFS_TRACE_OS, ("yaffs_read_super: got root inode\n")); | |
| 7 | 2177 |
| 2178 root = d_alloc_root(inode); | |
| 2179 | |
| 76 | 2180 T(YAFFS_TRACE_OS, ("yaffs_read_super: d_alloc_root done\n")); |
| 7 | 2181 |
| 2182 if (!root) { | |
| 2183 iput(inode); | |
| 2184 return NULL; | |
| 2185 } | |
| 2186 sb->s_root = root; | |
| 249 | 2187 sb->s_dirt = !dev->isCheckpointed; |
| 2188 T(YAFFS_TRACE_ALWAYS, | |
| 2189 ("yaffs_read_super: isCheckpointed %d\n", dev->isCheckpointed)); | |
| 7 | 2190 |
| 76 | 2191 T(YAFFS_TRACE_OS, ("yaffs_read_super: done\n")); |
| 7 | 2192 return sb; |
| 2193 } | |
| 2194 | |
|
32
e344a10a3a1e
Move the internals read_super() functions near the declaration of
luc <luc>
parents:
29
diff
changeset
|
2195 |
|
e344a10a3a1e
Move the internals read_super() functions near the declaration of
luc <luc>
parents:
29
diff
changeset
|
2196 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) |
| 76 | 2197 static int yaffs_internal_read_super_mtd(struct super_block *sb, void *data, |
| 2198 int silent) | |
| 7 | 2199 { |
| 95 | 2200 return yaffs_internal_read_super(1, sb, data, silent) ? 0 : -EINVAL; |
| 7 | 2201 } |
| 2202 | |
| 143 | 2203 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) |
| 2204 static int yaffs_read_super(struct file_system_type *fs, | |
| 2205 int flags, const char *dev_name, | |
| 2206 void *data, struct vfsmount *mnt) | |
| 2207 { | |
| 2208 | |
| 2209 return get_sb_bdev(fs, flags, dev_name, data, | |
| 2210 yaffs_internal_read_super_mtd, mnt); | |
| 2211 } | |
| 2212 #else | |
| 76 | 2213 static struct super_block *yaffs_read_super(struct file_system_type *fs, |
| 2214 int flags, const char *dev_name, | |
| 2215 void *data) | |
| 7 | 2216 { |
| 2217 | |
| 76 | 2218 return get_sb_bdev(fs, flags, dev_name, data, |
| 2219 yaffs_internal_read_super_mtd); | |
| 7 | 2220 } |
| 143 | 2221 #endif |
| 7 | 2222 |
| 2223 static struct file_system_type yaffs_fs_type = { | |
| 76 | 2224 .owner = THIS_MODULE, |
| 2225 .name = "yaffs", | |
| 2226 .get_sb = yaffs_read_super, | |
| 2227 .kill_sb = kill_block_super, | |
| 2228 .fs_flags = FS_REQUIRES_DEV, | |
| 7 | 2229 }; |
| 2230 #else | |
| 76 | 2231 static struct super_block *yaffs_read_super(struct super_block *sb, void *data, |
| 2232 int silent) | |
| 7 | 2233 { |
| 76 | 2234 return yaffs_internal_read_super(1, sb, data, silent); |
| 7 | 2235 } |
| 2236 | |
| 76 | 2237 static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super, |
| 2238 FS_REQUIRES_DEV); | |
| 7 | 2239 #endif |
| 2240 | |
| 2241 | |
| 49 | 2242 #ifdef CONFIG_YAFFS_YAFFS2 |
| 7 | 2243 |
| 2244 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) | |
| 76 | 2245 static int yaffs2_internal_read_super_mtd(struct super_block *sb, void *data, |
| 2246 int silent) | |
|
32
e344a10a3a1e
Move the internals read_super() functions near the declaration of
luc <luc>
parents:
29
diff
changeset
|
2247 { |
| 95 | 2248 return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL; |
|
32
e344a10a3a1e
Move the internals read_super() functions near the declaration of
luc <luc>
parents:
29
diff
changeset
|
2249 } |
|
e344a10a3a1e
Move the internals read_super() functions near the declaration of
luc <luc>
parents:
29
diff
changeset
|
2250 |
| 143 | 2251 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) |
| 2252 static int yaffs2_read_super(struct file_system_type *fs, | |
| 2253 int flags, const char *dev_name, void *data, | |
| 2254 struct vfsmount *mnt) | |
| 2255 { | |
| 2256 return get_sb_bdev(fs, flags, dev_name, data, | |
| 2257 yaffs2_internal_read_super_mtd, mnt); | |
| 2258 } | |
| 2259 #else | |
| 76 | 2260 static struct super_block *yaffs2_read_super(struct file_system_type *fs, |
| 2261 int flags, const char *dev_name, | |
| 2262 void *data) | |
| 7 | 2263 { |
| 2264 | |
| 76 | 2265 return get_sb_bdev(fs, flags, dev_name, data, |
| 2266 yaffs2_internal_read_super_mtd); | |
| 7 | 2267 } |
| 143 | 2268 #endif |
| 7 | 2269 |
| 2270 static struct file_system_type yaffs2_fs_type = { | |
| 76 | 2271 .owner = THIS_MODULE, |
| 2272 .name = "yaffs2", | |
| 2273 .get_sb = yaffs2_read_super, | |
| 2274 .kill_sb = kill_block_super, | |
| 2275 .fs_flags = FS_REQUIRES_DEV, | |
| 7 | 2276 }; |
| 2277 #else | |
| 76 | 2278 static struct super_block *yaffs2_read_super(struct super_block *sb, |
| 2279 void *data, int silent) | |
| 7 | 2280 { |
| 76 | 2281 return yaffs_internal_read_super(2, sb, data, silent); |
| 7 | 2282 } |
| 2283 | |
| 76 | 2284 static DECLARE_FSTYPE(yaffs2_fs_type, "yaffs2", yaffs2_read_super, |
| 2285 FS_REQUIRES_DEV); | |
| 7 | 2286 #endif |
| 2287 | |
| 76 | 2288 #endif /* CONFIG_YAFFS_YAFFS2 */ |
| 7 | 2289 |
| 2290 static struct proc_dir_entry *my_proc_entry; | |
| 2291 | |
| 76 | 2292 static char *yaffs_dump_dev(char *buf, yaffs_Device * dev) |
| 7 | 2293 { |
| 76 | 2294 buf += sprintf(buf, "startBlock......... %d\n", dev->startBlock); |
| 2295 buf += sprintf(buf, "endBlock........... %d\n", dev->endBlock); | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
2296 buf += sprintf(buf, "totalBytesPerChunk. %d\n", dev->totalBytesPerChunk); |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2297 buf += sprintf(buf, "nDataBytesPerChunk. %d\n", dev->nDataBytesPerChunk); |
| 76 | 2298 buf += sprintf(buf, "chunkGroupBits..... %d\n", dev->chunkGroupBits); |
| 2299 buf += sprintf(buf, "chunkGroupSize..... %d\n", dev->chunkGroupSize); | |
| 2300 buf += sprintf(buf, "nErasedBlocks...... %d\n", dev->nErasedBlocks); | |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2301 buf += sprintf(buf, "nReservedBlocks.... %d\n", dev->nReservedBlocks); |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2302 buf += sprintf(buf, "blocksInCheckpoint. %d\n", dev->blocksInCheckpoint); |
| 76 | 2303 buf += sprintf(buf, "nTnodesCreated..... %d\n", dev->nTnodesCreated); |
| 2304 buf += sprintf(buf, "nFreeTnodes........ %d\n", dev->nFreeTnodes); | |
| 2305 buf += sprintf(buf, "nObjectsCreated.... %d\n", dev->nObjectsCreated); | |
| 2306 buf += sprintf(buf, "nFreeObjects....... %d\n", dev->nFreeObjects); | |
| 2307 buf += sprintf(buf, "nFreeChunks........ %d\n", dev->nFreeChunks); | |
| 2308 buf += sprintf(buf, "nPageWrites........ %d\n", dev->nPageWrites); | |
| 2309 buf += sprintf(buf, "nPageReads......... %d\n", dev->nPageReads); | |
| 2310 buf += sprintf(buf, "nBlockErasures..... %d\n", dev->nBlockErasures); | |
| 2311 buf += sprintf(buf, "nGCCopies.......... %d\n", dev->nGCCopies); | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
2312 buf += sprintf(buf, "garbageCollections. %d\n", dev->garbageCollections); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
2313 buf += sprintf(buf, "passiveGCs......... %d\n", |
| 76 | 2314 dev->passiveGarbageCollections); |
| 2315 buf += sprintf(buf, "nRetriedWrites..... %d\n", dev->nRetriedWrites); | |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2316 buf += sprintf(buf, "nShortOpCaches..... %d\n", dev->nShortOpCaches); |
| 76 | 2317 buf += sprintf(buf, "nRetireBlocks...... %d\n", dev->nRetiredBlocks); |
| 2318 buf += sprintf(buf, "eccFixed........... %d\n", dev->eccFixed); | |
| 2319 buf += sprintf(buf, "eccUnfixed......... %d\n", dev->eccUnfixed); | |
| 2320 buf += sprintf(buf, "tagsEccFixed....... %d\n", dev->tagsEccFixed); | |
| 2321 buf += sprintf(buf, "tagsEccUnfixed..... %d\n", dev->tagsEccUnfixed); | |
| 2322 buf += sprintf(buf, "cacheHits.......... %d\n", dev->cacheHits); | |
| 2323 buf += sprintf(buf, "nDeletedFiles...... %d\n", dev->nDeletedFiles); | |
| 2324 buf += sprintf(buf, "nUnlinkedFiles..... %d\n", dev->nUnlinkedFiles); | |
| 2325 buf += | |
| 2326 sprintf(buf, "nBackgroudDeletions %d\n", dev->nBackgroundDeletions); | |
| 2327 buf += sprintf(buf, "useNANDECC......... %d\n", dev->useNANDECC); | |
| 2328 buf += sprintf(buf, "isYaffs2........... %d\n", dev->isYaffs2); | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
198
diff
changeset
|
2329 buf += sprintf(buf, "inbandTags......... %d\n", dev->inbandTags); |
| 7 | 2330 |
| 76 | 2331 return buf; |
| 7 | 2332 } |
| 2333 | |
| 76 | 2334 static int yaffs_proc_read(char *page, |
| 2335 char **start, | |
| 2336 off_t offset, int count, int *eof, void *data) | |
| 7 | 2337 { |
|
210
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
2338 struct ylist_head *item; |
| 27 | 2339 char *buf = page; |
| 2340 int step = offset; | |
| 2341 int n = 0; | |
| 7 | 2342 |
| 27 | 2343 /* Get proc_file_read() to step 'offset' by one on each sucessive call. |
| 2344 * We use 'offset' (*ppos) to indicate where we are in devList. | |
| 2345 * This also assumes the user has posted a read buffer large | |
| 2346 * enough to hold the complete output; but that's life in /proc. | |
| 2347 */ | |
| 7 | 2348 |
| 27 | 2349 *(int *)start = 1; |
| 2350 | |
| 2351 /* Print header first */ | |
| 2352 if (step == 0) { | |
| 76 | 2353 buf += sprintf(buf, "YAFFS built:" __DATE__ " " __TIME__ |
| 2354 "\n%s\n%s\n", yaffs_fs_c_version, | |
| 2355 yaffs_guts_c_version); | |
| 27 | 2356 } |
| 7 | 2357 |
| 27 | 2358 /* hold lock_kernel while traversing yaffs_dev_list */ |
| 2359 lock_kernel(); | |
| 7 | 2360 |
| 27 | 2361 /* Locate and print the Nth entry. Order N-squared but N is small. */ |
|
210
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
2362 ylist_for_each(item, &yaffs_dev_list) { |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
204
diff
changeset
|
2363 yaffs_Device *dev = ylist_entry(item, yaffs_Device, devList); |
| 27 | 2364 if (n < step) { |
| 2365 n++; | |
| 2366 continue; | |
| 2367 } | |
| 76 | 2368 buf += sprintf(buf, "\nDevice %d \"%s\"\n", n, dev->name); |
| 27 | 2369 buf = yaffs_dump_dev(buf, dev); |
| 2370 break; | |
| 2371 } | |
| 2372 unlock_kernel(); | |
| 2373 | |
| 76 | 2374 return buf - page < count ? buf - page : count; |
| 7 | 2375 } |
| 2376 | |
|
115
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2377 /** |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2378 * Set the verbosity of the warnings and error messages. |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2379 * |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2380 * Note that the names can only be a..z or _ with the current code. |
|
115
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2381 */ |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2382 |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2383 static struct { |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2384 char *mask_name; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2385 unsigned mask_bitfield; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2386 } mask_flags[] = { |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2387 {"allocate", YAFFS_TRACE_ALLOCATE}, |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2388 {"always", YAFFS_TRACE_ALWAYS}, |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2389 {"bad_blocks", YAFFS_TRACE_BAD_BLOCKS}, |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2390 {"buffers", YAFFS_TRACE_BUFFERS}, |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2391 {"bug", YAFFS_TRACE_BUG}, |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2392 {"checkpt", YAFFS_TRACE_CHECKPOINT}, |
|
115
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2393 {"deletion", YAFFS_TRACE_DELETION}, |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2394 {"erase", YAFFS_TRACE_ERASE}, |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2395 {"error", YAFFS_TRACE_ERROR}, |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2396 {"gc_detail", YAFFS_TRACE_GC_DETAIL}, |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2397 {"gc", YAFFS_TRACE_GC}, |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2398 {"mtd", YAFFS_TRACE_MTD}, |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2399 {"nandaccess", YAFFS_TRACE_NANDACCESS}, |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2400 {"os", YAFFS_TRACE_OS}, |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2401 {"scan_debug", YAFFS_TRACE_SCAN_DEBUG}, |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2402 {"scan", YAFFS_TRACE_SCAN}, |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2403 {"tracing", YAFFS_TRACE_TRACING}, |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2404 |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2405 {"verify", YAFFS_TRACE_VERIFY}, |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2406 {"verify_nand", YAFFS_TRACE_VERIFY_NAND}, |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2407 {"verify_full", YAFFS_TRACE_VERIFY_FULL}, |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2408 {"verify_all", YAFFS_TRACE_VERIFY_ALL}, |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2409 |
|
115
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2410 {"write", YAFFS_TRACE_WRITE}, |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2411 {"all", 0xffffffff}, |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2412 {"none", 0}, |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2413 {NULL, 0}, |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2414 }; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2415 |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2416 #define MAX_MASK_NAME_LENGTH 40 |
|
115
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2417 static int yaffs_proc_write(struct file *file, const char *buf, |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2418 unsigned long count, void *data) |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2419 { |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2420 unsigned rg = 0, mask_bitfield; |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2421 char *end; |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2422 char *mask_name; |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
2423 const char *x; |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2424 char substring[MAX_MASK_NAME_LENGTH+1]; |
|
115
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2425 int i; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2426 int done = 0; |
| 166 | 2427 int add, len = 0; |
|
115
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2428 int pos = 0; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2429 |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2430 rg = yaffs_traceMask; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2431 |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2432 while (!done && (pos < count)) { |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2433 done = 1; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2434 while ((pos < count) && isspace(buf[pos])) { |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2435 pos++; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2436 } |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2437 |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2438 switch (buf[pos]) { |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2439 case '+': |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2440 case '-': |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2441 case '=': |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2442 add = buf[pos]; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2443 pos++; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2444 break; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2445 |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2446 default: |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2447 add = ' '; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2448 break; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2449 } |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2450 mask_name = NULL; |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
2451 |
|
115
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2452 mask_bitfield = simple_strtoul(buf + pos, &end, 0); |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2453 if (end > buf + pos) { |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2454 mask_name = "numeral"; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2455 len = end - (buf + pos); |
|
188
62921764ba1b
Fix infinite loop when parsing numeric trace flags written to /proc/yaffs.
imcd <imcd>
parents:
179
diff
changeset
|
2456 pos += len; |
|
115
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2457 done = 0; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2458 } else { |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
2459 for(x = buf + pos, i = 0; |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2460 (*x == '_' || (*x >='a' && *x <= 'z')) && |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2461 i <MAX_MASK_NAME_LENGTH; x++, i++, pos++) |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2462 substring[i] = *x; |
|
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2463 substring[i] = '\0'; |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
2464 |
|
115
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2465 for (i = 0; mask_flags[i].mask_name != NULL; i++) { |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2466 if(strcmp(substring,mask_flags[i].mask_name) == 0){ |
|
115
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2467 mask_name = mask_flags[i].mask_name; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2468 mask_bitfield = mask_flags[i].mask_bitfield; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2469 done = 0; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2470 break; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2471 } |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2472 } |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2473 } |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2474 |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2475 if (mask_name != NULL) { |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2476 done = 0; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2477 switch(add) { |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2478 case '-': |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2479 rg &= ~mask_bitfield; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2480 break; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2481 case '+': |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2482 rg |= mask_bitfield; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2483 break; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2484 case '=': |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2485 rg = mask_bitfield; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2486 break; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2487 default: |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2488 rg |= mask_bitfield; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2489 break; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2490 } |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2491 } |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2492 } |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2493 |
| 165 | 2494 yaffs_traceMask = rg | YAFFS_TRACE_ALWAYS; |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
2495 |
|
176
570d9d4cac30
Adding checkpoint and robustness improvements
charles <charles>
parents:
175
diff
changeset
|
2496 printk("new trace = 0x%08X\n",yaffs_traceMask); |
|
198
b7f785925166
Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents:
196
diff
changeset
|
2497 |
|
115
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2498 if (rg & YAFFS_TRACE_ALWAYS) { |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2499 for (i = 0; mask_flags[i].mask_name != NULL; i++) { |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2500 char flag; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2501 flag = ((rg & mask_flags[i].mask_bitfield) == mask_flags[i].mask_bitfield) ? '+' : '-'; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2502 printk("%c%s\n", flag, mask_flags[i].mask_name); |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2503 } |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2504 } |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2505 |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2506 return count; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2507 } |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2508 |
| 76 | 2509 /* Stuff to handle installation of file systems */ |
| 2510 struct file_system_to_install { | |
| 2511 struct file_system_type *fst; | |
| 2512 int installed; | |
| 7 | 2513 }; |
| 2514 | |
| 76 | 2515 static struct file_system_to_install fs_to_install[] = { |
| 83 | 2516 //#ifdef CONFIG_YAFFS_YAFFS1 |
| 76 | 2517 {&yaffs_fs_type, 0}, |
| 83 | 2518 //#endif |
| 2519 //#ifdef CONFIG_YAFFS_YAFFS2 | |
| 76 | 2520 {&yaffs2_fs_type, 0}, |
| 83 | 2521 //#endif |
| 76 | 2522 {NULL, 0} |
| 7 | 2523 }; |
| 2524 | |
| 2525 static int __init init_yaffs_fs(void) | |
| 2526 { | |
| 2527 int error = 0; | |
| 76 | 2528 struct file_system_to_install *fsinst; |
| 7 | 2529 |
| 76 | 2530 T(YAFFS_TRACE_ALWAYS, |
| 2531 ("yaffs " __DATE__ " " __TIME__ " Installing. \n")); | |
| 7 | 2532 |
| 76 | 2533 /* Install the proc_fs entry */ |
|
115
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2534 my_proc_entry = create_proc_entry("yaffs", |
| 76 | 2535 S_IRUGO | S_IFREG, |
|
212
0107f21a03fb
Fix compilation on Linux 2.6.26, fix compilation warnings
charles <charles>
parents:
210
diff
changeset
|
2536 YPROC_ROOT); |
|
115
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2537 |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2538 if (my_proc_entry) { |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2539 my_proc_entry->write_proc = yaffs_proc_write; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2540 my_proc_entry->read_proc = yaffs_proc_read; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2541 my_proc_entry->data = NULL; |
|
06a072660af9
Add /proc interface for modifying debugging trace flags, from John M Cavallo.
tpoynor <tpoynor>
parents:
113
diff
changeset
|
2542 } else { |
| 76 | 2543 return -ENOMEM; |
| 2544 } | |
| 2545 | |
| 2546 /* Now add the file system entries */ | |
| 2547 | |
| 2548 fsinst = fs_to_install; | |
| 7 | 2549 |
| 76 | 2550 while (fsinst->fst && !error) { |
| 2551 error = register_filesystem(fsinst->fst); | |
| 2552 if (!error) { | |
| 2553 fsinst->installed = 1; | |
| 2554 } | |
| 2555 fsinst++; | |
| 2556 } | |
| 2557 | |
| 2558 /* Any errors? uninstall */ | |
| 2559 if (error) { | |
| 2560 fsinst = fs_to_install; | |
| 2561 | |
| 2562 while (fsinst->fst) { | |
| 2563 if (fsinst->installed) { | |
| 2564 unregister_filesystem(fsinst->fst); | |
| 2565 fsinst->installed = 0; | |
| 2566 } | |
| 2567 fsinst++; | |
| 2568 } | |
| 2569 } | |
| 2570 | |
| 2571 return error; | |
| 7 | 2572 } |
| 2573 | |
| 2574 static void __exit exit_yaffs_fs(void) | |
| 2575 { | |
| 2576 | |
| 76 | 2577 struct file_system_to_install *fsinst; |
| 2578 | |
| 2579 T(YAFFS_TRACE_ALWAYS, ("yaffs " __DATE__ " " __TIME__ | |
| 2580 " removing. \n")); | |
| 2581 | |
|
212
0107f21a03fb
Fix compilation on Linux 2.6.26, fix compilation warnings
charles <charles>
parents:
210
diff
changeset
|
2582 remove_proc_entry("yaffs", YPROC_ROOT); |
| 7 | 2583 |
| 76 | 2584 fsinst = fs_to_install; |
| 2585 | |
| 2586 while (fsinst->fst) { | |
| 2587 if (fsinst->installed) { | |
| 2588 unregister_filesystem(fsinst->fst); | |
| 2589 fsinst->installed = 0; | |
| 2590 } | |
| 2591 fsinst++; | |
| 2592 } | |
| 7 | 2593 |
| 2594 } | |
| 2595 | |
| 2596 module_init(init_yaffs_fs) | |
| 2597 module_exit(exit_yaffs_fs) | |
| 2598 | |
| 2599 MODULE_DESCRIPTION("YAFFS2 - a NAND specific flash file system"); | |
|
126
2e7fd6d40037
Fix a couple of mistakes in TRACE/Error messages. Update copyright date.
wookey <wookey>
parents:
124
diff
changeset
|
2600 MODULE_AUTHOR("Charles Manning, Aleph One Ltd., 2002-2006"); |
| 7 | 2601 MODULE_LICENSE("GPL"); |
