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