annotate packages/fs/jffs2/current/src/fs-ecos.c @ 875:b17faf385ee0

* src/fs-ecos.c Fixed segmentation fault when unmounting file system.
author jlarmour
date Thu, 27 Mar 2003 08:46:29 +0000
parents a7947d436e85
children 47dcd8174e3a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
570
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1 /*
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2 * JFFS2 -- Journalling Flash File System, Version 2.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
3 *
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
4 * Copyright (C) 2001, 2002 Red Hat, Inc.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
5 *
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
6 * Created by Dominic Ostrowski <dominic.ostrowski@3glab.com>
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
7 * Contributors: David Woodhouse, Nick Garnett, Richard Panton.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
8 *
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
9 * For licensing information, see the file 'LICENCE' in this directory.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
10 *
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
11 * $Id: fs-ecos.c,v 1.8 2003/01/21 18:13:01 dwmw2 Exp $
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
12 *
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
13 */
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
14
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
15 #include <linux/types.h>
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
16 #include <linux/stat.h>
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
17 #include <linux/kernel.h>
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
18 #include "jffs2port.h"
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
19 #include <linux/jffs2.h>
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
20 #include <linux/jffs2_fs_sb.h>
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
21 #include <linux/jffs2_fs_i.h>
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
22 #include <linux/pagemap.h>
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
23 #include "nodelist.h"
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
24
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
25 #include <errno.h>
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
26 #include <string.h>
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
27 #include <cyg/io/io.h>
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
28 #include <cyg/io/config_keys.h>
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
29 #include <cyg/io/flash.h>
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
30
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
31 //==========================================================================
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
32 // Forward definitions
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
33
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
34 // Filesystem operations
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
35 static int jffs2_mount(cyg_fstab_entry * fste, cyg_mtab_entry * mte);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
36 static int jffs2_umount(cyg_mtab_entry * mte);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
37 static int jffs2_open(cyg_mtab_entry * mte, cyg_dir dir, const char *name,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
38 int mode, cyg_file * fte);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
39 static int jffs2_ops_unlink(cyg_mtab_entry * mte, cyg_dir dir,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
40 const char *name);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
41 static int jffs2_ops_mkdir(cyg_mtab_entry * mte, cyg_dir dir, const char *name);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
42 static int jffs2_ops_rmdir(cyg_mtab_entry * mte, cyg_dir dir, const char *name);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
43 static int jffs2_ops_rename(cyg_mtab_entry * mte, cyg_dir dir1,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
44 const char *name1, cyg_dir dir2, const char *name2);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
45 static int jffs2_ops_link(cyg_mtab_entry * mte, cyg_dir dir1, const char *name1,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
46 cyg_dir dir2, const char *name2, int type);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
47 static int jffs2_opendir(cyg_mtab_entry * mte, cyg_dir dir, const char *name,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
48 cyg_file * fte);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
49 static int jffs2_chdir(cyg_mtab_entry * mte, cyg_dir dir, const char *name,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
50 cyg_dir * dir_out);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
51 static int jffs2_stat(cyg_mtab_entry * mte, cyg_dir dir, const char *name,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
52 struct stat *buf);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
53 static int jffs2_getinfo(cyg_mtab_entry * mte, cyg_dir dir, const char *name,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
54 int key, void *buf, int len);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
55 static int jffs2_setinfo(cyg_mtab_entry * mte, cyg_dir dir, const char *name,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
56 int key, void *buf, int len);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
57
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
58 // File operations
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
59 static int jffs2_fo_read(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
60 static int jffs2_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
61 static int jffs2_fo_lseek(struct CYG_FILE_TAG *fp, off_t * pos, int whence);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
62 static int jffs2_fo_ioctl(struct CYG_FILE_TAG *fp, CYG_ADDRWORD com,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
63 CYG_ADDRWORD data);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
64 static int jffs2_fo_fsync(struct CYG_FILE_TAG *fp, int mode);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
65 static int jffs2_fo_close(struct CYG_FILE_TAG *fp);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
66 static int jffs2_fo_fstat(struct CYG_FILE_TAG *fp, struct stat *buf);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
67 static int jffs2_fo_getinfo(struct CYG_FILE_TAG *fp, int key, void *buf,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
68 int len);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
69 static int jffs2_fo_setinfo(struct CYG_FILE_TAG *fp, int key, void *buf,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
70 int len);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
71
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
72 // Directory operations
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
73 static int jffs2_fo_dirread(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
74 static int jffs2_fo_dirlseek(struct CYG_FILE_TAG *fp, off_t * pos, int whence);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
75
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
76 //==========================================================================
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
77 // Filesystem table entries
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
78
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
79 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
80 // Fstab entry.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
81 // This defines the entry in the filesystem table.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
82 // For simplicity we use _FILESYSTEM synchronization for all accesses since
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
83 // we should never block in any filesystem operations.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
84
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
85 FSTAB_ENTRY(jffs2_fste, "jffs2", 0,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
86 CYG_SYNCMODE_FILE_FILESYSTEM | CYG_SYNCMODE_IO_FILESYSTEM,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
87 jffs2_mount,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
88 jffs2_umount,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
89 jffs2_open,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
90 jffs2_ops_unlink,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
91 jffs2_ops_mkdir,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
92 jffs2_ops_rmdir,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
93 jffs2_ops_rename,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
94 jffs2_ops_link,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
95 jffs2_opendir,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
96 jffs2_chdir, jffs2_stat, jffs2_getinfo, jffs2_setinfo);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
97
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
98 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
99 // File operations.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
100 // This set of file operations are used for normal open files.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
101
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
102 static cyg_fileops jffs2_fileops = {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
103 jffs2_fo_read,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
104 jffs2_fo_write,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
105 jffs2_fo_lseek,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
106 jffs2_fo_ioctl,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
107 cyg_fileio_seltrue,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
108 jffs2_fo_fsync,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
109 jffs2_fo_close,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
110 jffs2_fo_fstat,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
111 jffs2_fo_getinfo,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
112 jffs2_fo_setinfo
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
113 };
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
114
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
115 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
116 // Directory file operations.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
117 // This set of operations are used for open directories. Most entries
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
118 // point to error-returning stub functions. Only the read, lseek and
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
119 // close entries are functional.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
120
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
121 static cyg_fileops jffs2_dirops = {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
122 jffs2_fo_dirread,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
123 (cyg_fileop_write *) cyg_fileio_enosys,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
124 jffs2_fo_dirlseek,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
125 (cyg_fileop_ioctl *) cyg_fileio_enosys,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
126 cyg_fileio_seltrue,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
127 (cyg_fileop_fsync *) cyg_fileio_enosys,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
128 jffs2_fo_close,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
129 (cyg_fileop_fstat *) cyg_fileio_enosys,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
130 (cyg_fileop_getinfo *) cyg_fileio_enosys,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
131 (cyg_fileop_setinfo *) cyg_fileio_enosys
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
132 };
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
133
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
134 //==========================================================================
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
135 // STATIC VARIABLES !!!
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
136
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
137 static char read_write_buffer[PAGE_CACHE_SIZE]; //avoids malloc when user may be under memory pressure
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
138 static char gc_buffer[PAGE_CACHE_SIZE]; //avoids malloc when user may be under memory pressure
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
139
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
140 //==========================================================================
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
141 // Directory operations
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
142
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
143 struct jffs2_dirsearch {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
144 struct inode *dir; // directory to search
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
145 const char *path; // path to follow
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
146 struct inode *node; // Node found
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
147 const char *name; // last name fragment used
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
148 int namelen; // name fragment length
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
149 cyg_bool last; // last name in path?
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
150 };
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
151
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
152 typedef struct jffs2_dirsearch jffs2_dirsearch;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
153
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
154 //==========================================================================
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
155 // Ref count and nlink management
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
156
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
157 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
158 // dec_refcnt()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
159 // Decrment the reference count on an inode. If this makes the ref count
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
160 // zero, then this inode can be freed.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
161
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
162 static int dec_refcnt(struct inode *node)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
163 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
164 int err = ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
165 node->i_count--;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
166
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
167 // In JFFS2 inode's are temporary in ram structures that are free'd when the usage i_count drops to 0
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
168 // The i_nlink however is managed by JFFS2 and is unrelated to usage
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
169 if (node->i_count == 0) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
170 // This inode is not in use, so delete it.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
171 iput(node);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
172 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
173
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
174 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
175 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
176
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
177 // FIXME: This seems like real cruft. Wouldn't it be better just to do the
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
178 // right thing?
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
179 static void icache_evict(struct inode *root_i, struct inode *i)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
180 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
181 struct inode *cached_inode;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
182 struct inode *next_inode;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
183
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
184 D2(printf("icache_evict\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
185 // If this is an absolute search path from the root,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
186 // remove all cached inodes with i_count of zero (these are only
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
187 // held where needed for dotdot filepaths)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
188 if (i == root_i) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
189 for (cached_inode = root_i; cached_inode != NULL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
190 cached_inode = next_inode) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
191 next_inode = cached_inode->i_cache_next;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
192 if (cached_inode->i_count == 0) {
875
b17faf385ee0 * src/fs-ecos.c
jlarmour
parents: 570
diff changeset
193 cached_inode->i_cache_prev->i_cache_next = cached_inode->i_cache_next; // Previous entry points ahead of us
570
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
194 if (cached_inode->i_cache_next != NULL)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
195 cached_inode->i_cache_next->i_cache_prev = cached_inode->i_cache_prev; // Next entry points behind us
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
196 jffs2_clear_inode(cached_inode);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
197 D2(printf
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
198 ("free icache_evict inode %x $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n",
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
199 cached_inode));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
200 free(cached_inode);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
201 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
202 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
203 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
204 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
205
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
206 //==========================================================================
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
207 // Directory search
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
208
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
209 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
210 // init_dirsearch()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
211 // Initialize a dirsearch object to start a search
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
212
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
213 static void init_dirsearch(jffs2_dirsearch * ds,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
214 struct inode *dir, const char *name)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
215 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
216 D2(printf("init_dirsearch name = %s\n", name));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
217 D2(printf("init_dirsearch dir = %x\n", dir));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
218 ds->dir = dir;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
219 ds->path = name;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
220 ds->node = dir;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
221 ds->name = name;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
222 ds->namelen = 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
223 ds->last = false;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
224 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
225
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
226 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
227 // find_entry()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
228 // Search a single directory for the next name in a path and update the
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
229 // dirsearch object appropriately.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
230
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
231 static int find_entry(jffs2_dirsearch * ds)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
232 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
233 unsigned long hash;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
234 struct qstr this;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
235 unsigned int c;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
236 const char *hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
237
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
238 struct inode *dir = ds->dir;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
239 const char *name = ds->path;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
240 const char *n = name;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
241 char namelen = 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
242 struct inode *d;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
243
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
244 D2(printf("find_entry\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
245
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
246 // check that we really have a directory
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
247 if (!S_ISDIR(dir->i_mode))
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
248 return ENOTDIR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
249
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
250 // Isolate the next element of the path name.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
251 while (*n != '\0' && *n != '/')
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
252 n++, namelen++;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
253
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
254 // If we terminated on a NUL, set last flag.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
255 if (*n == '\0')
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
256 ds->last = true;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
257
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
258 // update name in dirsearch object
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
259 ds->name = name;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
260 ds->namelen = namelen;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
261
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
262 if (name[0] == '.')
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
263 switch (namelen) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
264 default:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
265 break;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
266 case 2:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
267 // Dot followed by not Dot, treat as any other name
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
268 if (name[1] != '.')
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
269 break;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
270 // Dot Dot
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
271 // Move back up the search path
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
272 D2(printf("find_entry found ..\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
273 ds->node = ds->dir->i_parent;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
274 if (ds->dir->i_count == 0) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
275 iput(ds->dir); // This inode may be evicted
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
276 ds->dir = NULL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
277 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
278 return ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
279 case 1:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
280 // Dot is consumed
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
281 D2(printf("find_entry found .\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
282 ds->node = ds->dir;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
283 return ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
284 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
285 // Here we have the name and its length set up.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
286 // Search the directory for a matching entry
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
287
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
288 hashname = name;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
289 this.name = hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
290 c = *(const unsigned char *) hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
291
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
292 hash = init_name_hash();
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
293 do {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
294 hashname++;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
295 hash = partial_name_hash(c, hash);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
296 c = *(const unsigned char *) hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
297 } while (c && (c != '/'));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
298 this.len = hashname - (const char *) this.name;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
299 this.hash = end_name_hash(hash);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
300
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
301 D2(printf("find_entry for name = %s\n", ds->path));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
302 d = jffs2_lookup(dir, &this);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
303 D2(printf("find_entry got dir = %x\n", d));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
304
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
305 if (d == NULL)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
306 return ENOENT;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
307
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
308 // The back path for dotdot to follow
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
309 d->i_parent = dir;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
310 // pass back the node we have found
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
311 ds->node = d;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
312
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
313 return ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
314
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
315 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
316
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
317 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
318 // jffs2_find()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
319 // Main interface to directory search code. This is used in all file
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
320 // level operations to locate the object named by the pathname.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
321
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
322 static int jffs2_find(jffs2_dirsearch * d)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
323 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
324 int err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
325
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
326 D2(printf("jffs2_find for path =%s\n", d->path));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
327 // Short circuit empty paths
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
328 if (*(d->path) == '\0')
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
329 return ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
330
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
331 // iterate down directory tree until we find the object
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
332 // we want.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
333 for (;;) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
334 err = find_entry(d);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
335
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
336 if (err != ENOERR)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
337 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
338
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
339 if (d->last)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
340 return ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
341
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
342 // every inode traversed in the find is temporary and should be free'd
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
343 //iput(d->dir);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
344
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
345 // Update dirsearch object to search next directory.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
346 d->dir = d->node;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
347 d->path += d->namelen;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
348 if (*(d->path) == '/')
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
349 d->path++; // skip dirname separators
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
350 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
351 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
352
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
353 //==========================================================================
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
354 // Pathconf support
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
355 // This function provides support for pathconf() and fpathconf().
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
356
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
357 static int jffs2_pathconf(struct inode *node, struct cyg_pathconf_info *info)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
358 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
359 int err = ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
360 D2(printf("jffs2_pathconf\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
361
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
362 switch (info->name) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
363 case _PC_LINK_MAX:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
364 info->value = LINK_MAX;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
365 break;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
366
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
367 case _PC_MAX_CANON:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
368 info->value = -1; // not supported
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
369 err = EINVAL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
370 break;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
371
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
372 case _PC_MAX_INPUT:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
373 info->value = -1; // not supported
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
374 err = EINVAL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
375 break;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
376
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
377 case _PC_NAME_MAX:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
378 info->value = NAME_MAX;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
379 break;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
380
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
381 case _PC_PATH_MAX:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
382 info->value = PATH_MAX;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
383 break;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
384
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
385 case _PC_PIPE_BUF:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
386 info->value = -1; // not supported
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
387 err = EINVAL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
388 break;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
389
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
390 case _PC_ASYNC_IO:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
391 info->value = -1; // not supported
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
392 err = EINVAL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
393 break;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
394
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
395 case _PC_CHOWN_RESTRICTED:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
396 info->value = -1; // not supported
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
397 err = EINVAL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
398 break;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
399
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
400 case _PC_NO_TRUNC:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
401 info->value = 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
402 break;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
403
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
404 case _PC_PRIO_IO:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
405 info->value = 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
406 break;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
407
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
408 case _PC_SYNC_IO:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
409 info->value = 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
410 break;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
411
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
412 case _PC_VDISABLE:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
413 info->value = -1; // not supported
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
414 err = EINVAL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
415 break;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
416
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
417 default:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
418 err = EINVAL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
419 break;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
420 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
421
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
422 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
423 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
424
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
425 //==========================================================================
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
426 // Filesystem operations
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
427
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
428 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
429 // jffs2_mount()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
430 // Process a mount request. This mainly creates a root for the
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
431 // filesystem.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
432 static int jffs2_read_super(struct super_block *sb)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
433 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
434 struct jffs2_sb_info *c;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
435 struct inode *root_i;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
436 Cyg_ErrNo err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
437 cyg_uint32 len;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
438 cyg_io_flash_getconfig_devsize_t ds;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
439 cyg_io_flash_getconfig_blocksize_t bs;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
440
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
441 D1(printk(KERN_DEBUG "jffs2: read_super\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
442
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
443 c = JFFS2_SB_INFO(sb);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
444
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
445 len = sizeof (ds);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
446 err = cyg_io_get_config(sb->s_dev,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
447 CYG_IO_GET_CONFIG_FLASH_DEVSIZE, &ds, &len);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
448 if (err != ENOERR) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
449 D1(printf
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
450 ("jffs2: cyg_io_get_config failed to get dev size: %d\n",
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
451 err));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
452 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
453 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
454 len = sizeof (bs);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
455 bs.offset = 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
456 err = cyg_io_get_config(sb->s_dev,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
457 CYG_IO_GET_CONFIG_FLASH_BLOCKSIZE, &bs, &len);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
458 if (err != ENOERR) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
459 D1(printf
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
460 ("jffs2: cyg_io_get_config failed to get block size: %d\n",
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
461 err));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
462 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
463 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
464
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
465 c->sector_size = bs.block_size;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
466 c->flash_size = ds.dev_size;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
467 c->cleanmarker_size = sizeof(struct jffs2_unknown_node);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
468
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
469 err = jffs2_do_mount_fs(c);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
470 if (err)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
471 return -err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
472
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
473 D1(printk(KERN_DEBUG "jffs2_read_super(): Getting root inode\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
474 root_i = iget(sb, 1);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
475 if (is_bad_inode(root_i)) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
476 D1(printk(KERN_WARNING "get root inode failed\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
477 err = EIO;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
478 goto out_nodes;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
479 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
480
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
481 D1(printk(KERN_DEBUG "jffs2_read_super(): d_alloc_root()\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
482 sb->s_root = d_alloc_root(root_i);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
483 if (!sb->s_root) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
484 err = ENOMEM;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
485 goto out_root_i;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
486 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
487 sb->s_blocksize = PAGE_CACHE_SIZE;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
488 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
489 sb->s_magic = JFFS2_SUPER_MAGIC;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
490
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
491 return 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
492
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
493 out_root_i:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
494 iput(root_i);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
495 out_nodes:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
496 jffs2_free_ino_caches(c);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
497 jffs2_free_raw_node_refs(c);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
498 free(c->blocks);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
499
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
500 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
501 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
502
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
503 static int jffs2_mount(cyg_fstab_entry * fste, cyg_mtab_entry * mte)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
504 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
505 extern cyg_mtab_entry mtab[], mtab_end;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
506 struct super_block *jffs2_sb = NULL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
507 struct jffs2_sb_info *c;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
508 cyg_mtab_entry *m;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
509 cyg_io_handle_t t;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
510 Cyg_ErrNo err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
511
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
512 D2(printf("jffs2_mount\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
513
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
514 err = cyg_io_lookup(mte->devname, &t);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
515 if (err != ENOERR)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
516 return -err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
517
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
518 // Iterate through the mount table to see if we're mounted
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
519 // FIXME: this should be done better - perhaps if the superblock
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
520 // can be stored as an inode in the icache.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
521 for (m = &mtab[0]; m != &mtab_end; m++) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
522 // stop if there are more than the configured maximum
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
523 if (m - &mtab[0] >= CYGNUM_FILEIO_MTAB_MAX) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
524 m = &mtab_end;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
525 break;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
526 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
527 if (m->valid && strcmp(m->fsname, "jffs2") == 0 &&
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
528 strcmp(m->devname, mte->devname) == 0) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
529 jffs2_sb = (struct super_block *) m->data;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
530 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
531 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
532
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
533 if (jffs2_sb == NULL) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
534 jffs2_sb = malloc(sizeof (struct super_block));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
535
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
536 if (jffs2_sb == NULL)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
537 return ENOMEM;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
538
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
539 c = JFFS2_SB_INFO(jffs2_sb);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
540 memset(jffs2_sb, 0, sizeof (struct super_block));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
541 jffs2_sb->s_dev = t;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
542
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
543 c->inocache_list = malloc(sizeof(struct jffs2_inode_cache *) * INOCACHE_HASHSIZE);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
544 if (!c->inocache_list) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
545 free(jffs2_sb);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
546 return ENOMEM;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
547 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
548 memset(c->inocache_list, 0, sizeof(struct jffs2_inode_cache *) * INOCACHE_HASHSIZE);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
549
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
550 err = jffs2_read_super(jffs2_sb);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
551
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
552 if (err) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
553 free(jffs2_sb);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
554 free(c->inocache_list);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
555 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
556 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
557
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
558 jffs2_sb->s_root->i_parent = jffs2_sb->s_root; // points to itself, no dotdot paths above mountpoint
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
559 jffs2_sb->s_root->i_cache_prev = NULL; // root inode, so always null
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
560 jffs2_sb->s_root->i_cache_next = NULL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
561 jffs2_sb->s_root->i_count = 1; // Ensures the root inode is always in ram until umount
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
562
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
563 D2(printf("jffs2_mount erasing pending blocks\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
564 jffs2_erase_pending_blocks(c);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
565 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
566 mte->data = (CYG_ADDRWORD) jffs2_sb;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
567
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
568 jffs2_sb->s_mount_count++;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
569 mte->root = (cyg_dir) jffs2_sb->s_root;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
570 D2(printf("jffs2_mounted superblock at %x\n", mte->root));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
571
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
572 return ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
573 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
574
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
575 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
576 // jffs2_umount()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
577 // Unmount the filesystem.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
578
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
579 static int jffs2_umount(cyg_mtab_entry * mte)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
580 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
581 struct inode *root = (struct inode *) mte->root;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
582 struct super_block *jffs2_sb = root->i_sb;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
583 struct jffs2_sb_info *c = JFFS2_SB_INFO(jffs2_sb);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
584
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
585 D2(printf("jffs2_umount\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
586
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
587 // Decrement the mount count
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
588 jffs2_sb->s_mount_count--;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
589
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
590 // Only really umount if this is the only mount
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
591 if (jffs2_sb->s_mount_count == 0) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
592
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
593 // Check for open/inuse root or any cached inodes
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
594 //if( root->i_count != 1 || root->i_cache_next != NULL) // root icount was set to 1 on mount
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
595 if (root->i_cache_next != NULL) // root icount was set to 1 on mount
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
596 return EBUSY;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
597
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
598 dec_refcnt(root); // Time to free the root inode
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
599
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
600 //Clear root inode
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
601 //root_i = NULL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
602
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
603 // Clean up the super block and root inode
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
604 jffs2_free_ino_caches(c);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
605 jffs2_free_raw_node_refs(c);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
606 free(c->blocks);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
607 free(c->inocache_list);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
608 free(jffs2_sb);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
609 // Clear root pointer
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
610 mte->root = CYG_DIR_NULL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
611 mte->fs->data = 0; // fstab entry, visible to all mounts. No current mount
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
612 // That's all folks.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
613 D2(printf("jffs2_umount No current mounts\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
614 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
615
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
616 return ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
617 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
618
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
619 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
620 // jffs2_open()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
621 // Open a file for reading or writing.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
622
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
623 static int jffs2_open(cyg_mtab_entry * mte, cyg_dir dir, const char *name,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
624 int mode, cyg_file * file)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
625 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
626
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
627 jffs2_dirsearch ds;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
628 struct inode *node = NULL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
629 int err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
630
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
631 D2(printf("jffs2_open\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
632
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
633 icache_evict((struct inode *) mte->root, (struct inode *) dir);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
634
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
635 init_dirsearch(&ds, (struct inode *) dir, name);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
636
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
637 err = jffs2_find(&ds);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
638
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
639 if (err == ENOENT) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
640 if (ds.last && (mode & O_CREAT)) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
641 unsigned long hash;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
642 struct qstr this;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
643 unsigned int c;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
644 const char *hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
645
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
646 // No node there, if the O_CREAT bit is set then we must
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
647 // create a new one. The dir and name fields of the dirsearch
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
648 // object will have been updated so we know where to put it.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
649
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
650 hashname = ds.name;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
651 this.name = hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
652 c = *(const unsigned char *) hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
653
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
654 hash = init_name_hash();
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
655 do {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
656 hashname++;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
657 hash = partial_name_hash(c, hash);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
658 c = *(const unsigned char *) hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
659 } while (c && (c != '/'));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
660 this.len = hashname - (const char *) this.name;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
661 this.hash = end_name_hash(hash);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
662
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
663 err = jffs2_create(ds.dir, &this, S_IRUGO|S_IXUGO|S_IWUSR|S_IFREG, &node);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
664
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
665 if (err != 0) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
666 //Possible orphaned inode on the flash - but will be gc'd
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
667 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
668 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
669
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
670 err = ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
671 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
672 } else if (err == ENOERR) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
673 // The node exists. If the O_CREAT and O_EXCL bits are set, we
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
674 // must fail the open.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
675
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
676 if ((mode & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
677 err = EEXIST;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
678 else
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
679 node = ds.node;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
680 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
681
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
682 if (err == ENOERR && (mode & O_TRUNC)) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
683 struct jffs2_inode_info *f = JFFS2_INODE_INFO(node);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
684 struct jffs2_sb_info *c = JFFS2_SB_INFO(node->i_sb);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
685 // If the O_TRUNC bit is set we must clean out the file data.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
686
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
687 node->i_size = 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
688 jffs2_truncate_fraglist(c, &f->fragtree, 0);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
689 // Update file times
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
690 node->i_ctime = node->i_mtime = cyg_timestamp();
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
691 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
692
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
693 if (err != ENOERR)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
694 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
695
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
696 // Check that we actually have a file here
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
697 if (S_ISDIR(node->i_mode))
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
698 return EISDIR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
699
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
700 node->i_count++; // Count successful open
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
701
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
702 // Initialize the file object
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
703
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
704 file->f_flag |= mode & CYG_FILE_MODE_MASK;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
705 file->f_type = CYG_FILE_TYPE_FILE;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
706 file->f_ops = &jffs2_fileops;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
707 file->f_offset = (mode & O_APPEND) ? node->i_size : 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
708 file->f_data = (CYG_ADDRWORD) node;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
709 file->f_xops = 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
710
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
711 return ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
712 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
713
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
714 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
715 // jffs2_ops_unlink()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
716 // Remove a file link from its directory.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
717
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
718 static int jffs2_ops_unlink(cyg_mtab_entry * mte, cyg_dir dir, const char *name)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
719 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
720 unsigned long hash;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
721 struct qstr this;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
722 unsigned int c;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
723 const char *hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
724 jffs2_dirsearch ds;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
725 int err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
726
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
727 D2(printf("jffs2_ops_unlink\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
728
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
729 icache_evict((struct inode *) mte->root, (struct inode *) dir);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
730
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
731 init_dirsearch(&ds, (struct inode *) dir, name);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
732
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
733 err = jffs2_find(&ds);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
734
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
735 if (err != ENOERR)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
736 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
737
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
738 // Cannot unlink directories, use rmdir() instead
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
739 if (S_ISDIR(ds.node->i_mode))
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
740 return EPERM;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
741
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
742 // Delete it from its directory
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
743
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
744 hashname = ds.name;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
745 this.name = hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
746 c = *(const unsigned char *) hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
747
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
748 hash = init_name_hash();
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
749 do {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
750 hashname++;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
751 hash = partial_name_hash(c, hash);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
752 c = *(const unsigned char *) hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
753 } while (c && (c != '/'));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
754 this.len = hashname - (const char *) this.name;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
755 this.hash = end_name_hash(hash);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
756
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
757 err = jffs2_unlink(ds.dir, ds.node, &this);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
758
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
759 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
760 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
761
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
762 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
763 // jffs2_ops_mkdir()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
764 // Create a new directory.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
765
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
766 static int jffs2_ops_mkdir(cyg_mtab_entry * mte, cyg_dir dir, const char *name)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
767 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
768 jffs2_dirsearch ds;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
769 struct inode *node = NULL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
770 int err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
771
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
772 D2(printf("jffs2_ops_mkdir\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
773
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
774 icache_evict((struct inode *) mte->root, (struct inode *) dir);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
775
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
776 init_dirsearch(&ds, (struct inode *) dir, name);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
777
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
778 err = jffs2_find(&ds);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
779
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
780 if (err == ENOENT) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
781 if (ds.last) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
782 unsigned long hash;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
783 struct qstr this;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
784 unsigned int c;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
785 const char *hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
786 // The entry does not exist, and it is the last element in
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
787 // the pathname, so we can create it here.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
788
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
789 hashname = ds.name;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
790 this.name = hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
791 c = *(const unsigned char *) hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
792
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
793 hash = init_name_hash();
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
794 do {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
795 hashname++;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
796 hash = partial_name_hash(c, hash);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
797 c = *(const unsigned char *) hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
798 } while (c && (c != '/'));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
799 this.len = hashname - (const char *) this.name;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
800 this.hash = end_name_hash(hash);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
801
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
802 err = jffs2_mkdir(ds.dir, &this, 0, &node);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
803
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
804 if (err != 0)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
805 return ENOSPC;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
806
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
807 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
808 // If this was not the last element, then and intermediate
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
809 // directory does not exist.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
810 } else {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
811 // If there we no error, something already exists with that
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
812 // name, so we cannot create another one.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
813
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
814 if (err == ENOERR)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
815 err = EEXIST;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
816 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
817
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
818 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
819 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
820
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
821 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
822 // jffs2_ops_rmdir()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
823 // Remove a directory.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
824
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
825 static int jffs2_ops_rmdir(cyg_mtab_entry * mte, cyg_dir dir, const char *name)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
826 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
827 unsigned long hash;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
828 struct qstr this;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
829 unsigned int c;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
830 const char *hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
831 jffs2_dirsearch ds;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
832 int err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
833
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
834 D2(printf("jffs2_ops_rmdir\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
835
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
836 icache_evict((struct inode *) mte->root, (struct inode *) dir);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
837
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
838 init_dirsearch(&ds, (struct inode *) dir, name);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
839
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
840 err = jffs2_find(&ds);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
841
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
842 if (err != ENOERR)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
843 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
844
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
845 // Check that this is actually a directory.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
846 if (!S_ISDIR(ds.node->i_mode))
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
847 return EPERM;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
848
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
849 // Delete the entry.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
850 hashname = ds.name;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
851 this.name = hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
852 c = *(const unsigned char *) hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
853
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
854 hash = init_name_hash();
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
855 do {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
856 hashname++;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
857 hash = partial_name_hash(c, hash);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
858 c = *(const unsigned char *) hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
859 } while (c && (c != '/'));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
860 this.len = hashname - (const char *) this.name;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
861 this.hash = end_name_hash(hash);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
862
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
863 err = jffs2_rmdir(ds.dir, ds.node, &this);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
864
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
865 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
866
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
867 return ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
868 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
869
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
870 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
871 // jffs2_ops_rename()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
872 // Rename a file/dir.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
873
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
874 static int jffs2_ops_rename(cyg_mtab_entry * mte, cyg_dir dir1,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
875 const char *name1, cyg_dir dir2, const char *name2)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
876 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
877 unsigned long hash;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
878 struct qstr this1, this2;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
879 unsigned int c;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
880 const char *hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
881 jffs2_dirsearch ds1, ds2;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
882 int err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
883
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
884 D2(printf("jffs2_ops_rename\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
885
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
886 init_dirsearch(&ds1, (struct inode *) dir1, name1);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
887
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
888 err = jffs2_find(&ds1);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
889
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
890 if (err != ENOERR)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
891 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
892
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
893 init_dirsearch(&ds2, (struct inode *) dir2, name2);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
894
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
895 err = jffs2_find(&ds2);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
896
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
897 // Allow through renames to non-existent objects.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
898 if (ds2.last && err == ENOENT)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
899 ds2.node = NULL, err = ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
900
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
901 if (err != ENOERR)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
902 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
903
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
904 // Null rename, just return
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
905 if (ds1.node == ds2.node)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
906 return ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
907
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
908 hashname = ds1.name;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
909 this1.name = hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
910 c = *(const unsigned char *) hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
911
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
912 hash = init_name_hash();
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
913 do {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
914 hashname++;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
915 hash = partial_name_hash(c, hash);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
916 c = *(const unsigned char *) hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
917 } while (c && (c != '/'));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
918 this1.len = hashname - (const char *) this1.name;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
919 this1.hash = end_name_hash(hash);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
920
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
921 hashname = ds2.name;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
922 this2.name = hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
923 c = *(const unsigned char *) hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
924
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
925 hash = init_name_hash();
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
926 do {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
927 hashname++;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
928 hash = partial_name_hash(c, hash);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
929 c = *(const unsigned char *) hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
930 } while (c && (c != '/'));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
931 this2.len = hashname - (const char *) this2.name;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
932 this2.hash = end_name_hash(hash);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
933
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
934 // First deal with any entry that is at the destination
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
935 if (ds2.node) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
936 // Check that we are renaming like-for-like
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
937
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
938 if (!S_ISDIR(ds1.node->i_mode) && S_ISDIR(ds2.node->i_mode))
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
939 return EISDIR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
940
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
941 if (S_ISDIR(ds1.node->i_mode) && !S_ISDIR(ds2.node->i_mode))
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
942 return ENOTDIR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
943
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
944 // Now delete the destination directory entry
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
945
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
946 err = jffs2_unlink(ds2.dir, ds2.node, &this2);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
947
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
948 if (err != 0)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
949 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
950
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
951 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
952 // Now we know that there is no clashing node at the destination,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
953 // make a new direntry at the destination and delete the old entry
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
954 // at the source.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
955
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
956 err = jffs2_rename(ds1.dir, ds1.node, &this1, ds2.dir, &this2);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
957
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
958 // Update directory times
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
959 if (err == 0)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
960 ds1.dir->i_ctime =
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
961 ds1.dir->i_mtime =
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
962 ds2.dir->i_ctime = ds2.dir->i_mtime = cyg_timestamp();
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
963
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
964 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
965 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
966
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
967 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
968 // jffs2_ops_link()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
969 // Make a new directory entry for a file.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
970
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
971 static int jffs2_ops_link(cyg_mtab_entry * mte, cyg_dir dir1, const char *name1,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
972 cyg_dir dir2, const char *name2, int type)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
973 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
974 unsigned long hash;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
975 struct qstr this;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
976 unsigned int c;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
977 const char *hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
978 jffs2_dirsearch ds1, ds2;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
979 int err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
980
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
981 D2(printf("jffs2_ops_link\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
982
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
983 // Only do hard links for now in this filesystem
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
984 if (type != CYG_FSLINK_HARD)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
985 return EINVAL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
986
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
987 init_dirsearch(&ds1, (struct inode *) dir1, name1);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
988
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
989 err = jffs2_find(&ds1);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
990
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
991 if (err != ENOERR)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
992 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
993
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
994 init_dirsearch(&ds2, (struct inode *) dir2, name2);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
995
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
996 err = jffs2_find(&ds2);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
997
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
998 // Don't allow links to existing objects
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
999 if (err == ENOERR)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1000 return EEXIST;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1001
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1002 // Allow through links to non-existing terminal objects
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1003 if (ds2.last && err == ENOENT)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1004 ds2.node = NULL, err = ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1005
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1006 if (err != ENOERR)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1007 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1008
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1009 // Now we know that there is no existing node at the destination,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1010 // make a new direntry at the destination.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1011
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1012 hashname = ds2.name;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1013 this.name = hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1014 c = *(const unsigned char *) hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1015
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1016 hash = init_name_hash();
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1017 do {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1018 hashname++;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1019 hash = partial_name_hash(c, hash);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1020 c = *(const unsigned char *) hashname;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1021 } while (c && (c != '/'));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1022 this.len = hashname - (const char *) this.name;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1023 this.hash = end_name_hash(hash);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1024
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1025 err = jffs2_link(ds2.dir, ds1.node, &this);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1026
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1027 if (err == 0)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1028 ds1.node->i_ctime =
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1029 ds2.dir->i_ctime = ds2.dir->i_mtime = cyg_timestamp();
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1030
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1031 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1032 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1033
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1034 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1035 // jffs2_opendir()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1036 // Open a directory for reading.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1037
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1038 static int jffs2_opendir(cyg_mtab_entry * mte, cyg_dir dir, const char *name,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1039 cyg_file * file)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1040 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1041 jffs2_dirsearch ds;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1042 int err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1043
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1044 D2(printf("jffs2_opendir\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1045
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1046 icache_evict((struct inode *) mte->root, (struct inode *) dir);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1047
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1048 init_dirsearch(&ds, (struct inode *) dir, name);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1049
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1050 err = jffs2_find(&ds);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1051
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1052 if (err != ENOERR)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1053 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1054
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1055 // check it is really a directory.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1056 if (!S_ISDIR(ds.node->i_mode))
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1057 return ENOTDIR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1058
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1059 ds.node->i_count++; // Count successful open
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1060
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1061 // Initialize the file object, setting the f_ops field to a
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1062 // special set of file ops.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1063
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1064 file->f_type = CYG_FILE_TYPE_FILE;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1065 file->f_ops = &jffs2_dirops;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1066 file->f_offset = 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1067 file->f_data = (CYG_ADDRWORD) ds.node;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1068 file->f_xops = 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1069
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1070 return ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1071
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1072 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1073
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1074 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1075 // jffs2_chdir()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1076 // Change directory support.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1077
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1078 static int jffs2_chdir(cyg_mtab_entry * mte, cyg_dir dir, const char *name,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1079 cyg_dir * dir_out)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1080 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1081 D2(printf("jffs2_chdir\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1082
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1083 if (dir_out != NULL) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1084 // This is a request to get a new directory pointer in
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1085 // *dir_out.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1086
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1087 jffs2_dirsearch ds;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1088 int err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1089
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1090 icache_evict((struct inode *) mte->root, (struct inode *) dir);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1091
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1092 init_dirsearch(&ds, (struct inode *) dir, name);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1093
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1094 err = jffs2_find(&ds);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1095
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1096 if (err != ENOERR)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1097 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1098
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1099 // check it is a directory
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1100 if (!S_ISDIR(ds.node->i_mode))
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1101 return ENOTDIR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1102
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1103 // Increment ref count to keep this directory in existance
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1104 // while it is the current cdir.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1105 ds.node->i_count++;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1106
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1107 // Pass it out
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1108 *dir_out = (cyg_dir) ds.node;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1109 } else {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1110 // If no output dir is required, this means that the mte and
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1111 // dir arguments are the current cdir setting and we should
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1112 // forget this fact.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1113
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1114 struct inode *node = (struct inode *) dir;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1115
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1116 // Just decrement directory reference count.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1117 dec_refcnt(node);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1118 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1119
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1120 return ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1121 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1122
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1123 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1124 // jffs2_stat()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1125 // Get struct stat info for named object.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1126
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1127 static int jffs2_stat(cyg_mtab_entry * mte, cyg_dir dir, const char *name,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1128 struct stat *buf)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1129 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1130 jffs2_dirsearch ds;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1131 int err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1132
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1133 D2(printf("jffs2_stat\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1134
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1135 icache_evict((struct inode *) mte->root, (struct inode *) dir);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1136
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1137 init_dirsearch(&ds, (struct inode *) dir, name);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1138
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1139 err = jffs2_find(&ds);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1140
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1141 if (err != ENOERR)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1142 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1143
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1144 // Fill in the status
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1145 buf->st_mode = ds.node->i_mode;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1146 buf->st_ino = (ino_t) ds.node;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1147 buf->st_dev = 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1148 buf->st_nlink = ds.node->i_nlink;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1149 buf->st_uid = 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1150 buf->st_gid = 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1151 buf->st_size = ds.node->i_size;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1152 buf->st_atime = ds.node->i_atime;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1153 buf->st_mtime = ds.node->i_mtime;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1154 buf->st_ctime = ds.node->i_ctime;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1155
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1156 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1157
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1158 return ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1159 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1160
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1161 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1162 // jffs2_getinfo()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1163 // Getinfo. Currently only support pathconf().
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1164
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1165 static int jffs2_getinfo(cyg_mtab_entry * mte, cyg_dir dir, const char *name,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1166 int key, void *buf, int len)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1167 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1168 jffs2_dirsearch ds;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1169 int err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1170
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1171 D2(printf("jffs2_getinfo\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1172
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1173 icache_evict((struct inode *) mte->root, (struct inode *) dir);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1174
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1175 init_dirsearch(&ds, (struct inode *) dir, name);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1176
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1177 err = jffs2_find(&ds);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1178
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1179 if (err != ENOERR)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1180 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1181
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1182 switch (key) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1183 case FS_INFO_CONF:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1184 err = jffs2_pathconf(ds.node, (struct cyg_pathconf_info *) buf);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1185 break;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1186
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1187 default:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1188 err = EINVAL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1189 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1190 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1191
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1192 return ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1193 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1194
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1195 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1196 // jffs2_setinfo()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1197 // Setinfo. Nothing to support here at present.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1198
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1199 static int jffs2_setinfo(cyg_mtab_entry * mte, cyg_dir dir, const char *name,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1200 int key, void *buf, int len)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1201 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1202 // No setinfo keys supported at present
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1203
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1204 D2(printf("jffs2_setinfo\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1205
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1206 return EINVAL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1207 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1208
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1209 //==========================================================================
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1210 // File operations
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1211
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1212 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1213 // jffs2_fo_read()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1214 // Read data from the file.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1215
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1216 static int jffs2_fo_read(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1217 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1218 struct inode *inode = (struct inode *) fp->f_data;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1219 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1220 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1221 int i;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1222 ssize_t resid = uio->uio_resid;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1223 off_t pos = fp->f_offset;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1224
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1225 down(&f->sem);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1226
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1227 // Loop over the io vectors until there are none left
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1228 for (i = 0; i < uio->uio_iovcnt && pos < inode->i_size; i++) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1229 int ret;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1230 cyg_iovec *iov = &uio->uio_iov[i];
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1231 off_t len = min(iov->iov_len, inode->i_size - pos);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1232
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1233 D2(printf("jffs2_fo_read inode size %d\n", inode->i_size));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1234
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1235 ret =
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1236 jffs2_read_inode_range(c, f,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1237 (unsigned char *) iov->iov_base, pos,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1238 len);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1239 if (ret) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1240 D1(printf
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1241 ("jffs2_fo_read(): read_inode_range failed %d\n",
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1242 ret));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1243 uio->uio_resid = resid;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1244 up(&f->sem);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1245 return -ret;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1246 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1247 resid -= len;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1248 pos += len;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1249 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1250
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1251 // We successfully read some data, update the node's access time
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1252 // and update the file offset and transfer residue.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1253
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1254 inode->i_atime = cyg_timestamp();
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1255
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1256 uio->uio_resid = resid;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1257 fp->f_offset = pos;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1258
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1259 up(&f->sem);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1260
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1261 return ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1262 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1263
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1264 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1265 // jffs2_fo_write()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1266 // Write data to file.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1267
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1268 static int jffs2_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1269 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1270 struct page write_page;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1271 off_t page_start_pos;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1272 struct inode *node = (struct inode *) fp->f_data;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1273 off_t pos = fp->f_offset;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1274 ssize_t resid = uio->uio_resid;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1275 int i;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1276
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1277 memset(&read_write_buffer, 0, PAGE_CACHE_SIZE);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1278 write_page.virtual = &read_write_buffer;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1279
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1280 // If the APPEND mode bit was supplied, force all writes to
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1281 // the end of the file.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1282 if (fp->f_flag & CYG_FAPPEND)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1283 pos = fp->f_offset = node->i_size;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1284
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1285 // Check that pos is within current file size, or at the very end.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1286 if (pos < 0 || pos > node->i_size)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1287 return EINVAL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1288
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1289 // Now loop over the iovecs until they are all done, or
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1290 // we get an error.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1291 for (i = 0; i < uio->uio_iovcnt; i++) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1292 cyg_iovec *iov = &uio->uio_iov[i];
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1293 char *buf = (char *) iov->iov_base;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1294 off_t len = iov->iov_len;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1295
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1296 // loop over the vector writing it to the file until it has
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1297 // all been done.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1298 while (len > 0) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1299 //cyg_uint8 *fbuf;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1300 //size_t bsize;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1301 size_t writtenlen;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1302 off_t l = len;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1303 int err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1304
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1305 write_page.index = 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1306
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1307 page_start_pos = pos;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1308 while (page_start_pos >= (PAGE_CACHE_SIZE)) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1309 write_page.index++;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1310 page_start_pos -= PAGE_CACHE_SIZE;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1311 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1312
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1313 if (l > PAGE_CACHE_SIZE - page_start_pos)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1314 l = PAGE_CACHE_SIZE - page_start_pos;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1315
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1316 D2(printf
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1317 ("jffs2_fo_write write_page.index %d\n",
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1318 write_page.index));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1319 D2(printf
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1320 ("jffs2_fo_write page_start_pos %d\n",
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1321 page_start_pos));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1322 D2(printf("jffs2_fo_write transfer size %d\n", l));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1323
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1324 err =
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1325 jffs2_prepare_write(node, &write_page,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1326 page_start_pos,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1327 page_start_pos + l);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1328
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1329 if (err != 0)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1330 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1331
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1332 // copy data in
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1333 memcpy(&read_write_buffer[page_start_pos], buf, l);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1334
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1335 writtenlen =
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1336 jffs2_commit_write(node, &write_page,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1337 page_start_pos,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1338 page_start_pos + l);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1339
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1340 if (writtenlen != l)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1341 return ENOSPC;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1342
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1343 // Update working vars
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1344 len -= l;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1345 buf += l;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1346 pos += l;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1347 resid -= l;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1348 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1349 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1350
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1351 // We wrote some data successfully, update the modified and access
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1352 // times of the node, increase its size appropriately, and update
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1353 // the file offset and transfer residue.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1354 node->i_mtime = node->i_ctime = cyg_timestamp();
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1355 if (pos > node->i_size)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1356 node->i_size = pos;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1357
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1358 uio->uio_resid = resid;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1359 fp->f_offset = pos;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1360
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1361 return ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1362 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1363
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1364 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1365 // jffs2_fo_lseek()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1366 // Seek to a new file position.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1367
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1368 static int jffs2_fo_lseek(struct CYG_FILE_TAG *fp, off_t * apos, int whence)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1369 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1370 struct inode *node = (struct inode *) fp->f_data;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1371 off_t pos = *apos;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1372
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1373 D2(printf("jffs2_fo_lseek\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1374
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1375 switch (whence) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1376 case SEEK_SET:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1377 // Pos is already where we want to be.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1378 break;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1379
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1380 case SEEK_CUR:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1381 // Add pos to current offset.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1382 pos += fp->f_offset;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1383 break;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1384
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1385 case SEEK_END:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1386 // Add pos to file size.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1387 pos += node->i_size;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1388 break;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1389
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1390 default:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1391 return EINVAL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1392 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1393
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1394 // Check that pos is still within current file size, or at the
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1395 // very end.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1396 if (pos < 0 || pos > node->i_size)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1397 return EINVAL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1398
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1399 // All OK, set fp offset and return new position.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1400 *apos = fp->f_offset = pos;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1401
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1402 return ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1403 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1404
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1405 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1406 // jffs2_fo_ioctl()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1407 // Handle ioctls. Currently none are defined.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1408
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1409 static int jffs2_fo_ioctl(struct CYG_FILE_TAG *fp, CYG_ADDRWORD com,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1410 CYG_ADDRWORD data)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1411 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1412 // No Ioctls currenly defined.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1413
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1414 D2(printf("jffs2_fo_ioctl\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1415
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1416 return EINVAL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1417 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1418
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1419 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1420 // jffs2_fo_fsync().
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1421 // Force the file out to data storage.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1422
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1423 static int jffs2_fo_fsync(struct CYG_FILE_TAG *fp, int mode)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1424 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1425 // Data is always permanently where it belongs, nothing to do
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1426 // here.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1427
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1428 D2(printf("jffs2_fo_fsync\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1429
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1430 return ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1431 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1432
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1433 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1434 // jffs2_fo_close()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1435 // Close a file. We just decrement the refcnt and let it go away if
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1436 // that is all that is keeping it here.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1437
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1438 static int jffs2_fo_close(struct CYG_FILE_TAG *fp)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1439 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1440 struct inode *node = (struct inode *) fp->f_data;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1441
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1442 D2(printf("jffs2_fo_close\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1443
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1444 dec_refcnt(node);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1445
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1446 fp->f_data = 0; // zero data pointer
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1447
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1448 return ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1449 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1450
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1451 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1452 //jffs2_fo_fstat()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1453 // Get file status.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1454
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1455 static int jffs2_fo_fstat(struct CYG_FILE_TAG *fp, struct stat *buf)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1456 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1457 struct inode *node = (struct inode *) fp->f_data;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1458
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1459 D2(printf("jffs2_fo_fstat\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1460
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1461 // Fill in the status
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1462 buf->st_mode = node->i_mode;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1463 buf->st_ino = (ino_t) node;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1464 buf->st_dev = 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1465 buf->st_nlink = node->i_nlink;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1466 buf->st_uid = 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1467 buf->st_gid = 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1468 buf->st_size = node->i_size;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1469 buf->st_atime = node->i_atime;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1470 buf->st_mtime = node->i_mtime;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1471 buf->st_ctime = node->i_ctime;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1472
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1473 return ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1474 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1475
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1476 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1477 // jffs2_fo_getinfo()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1478 // Get info. Currently only supports fpathconf().
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1479
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1480 static int jffs2_fo_getinfo(struct CYG_FILE_TAG *fp, int key, void *buf,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1481 int len)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1482 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1483 struct inode *node = (struct inode *) fp->f_data;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1484 int err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1485
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1486 D2(printf("jffs2_fo_getinfo\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1487
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1488 switch (key) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1489 case FS_INFO_CONF:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1490 err = jffs2_pathconf(node, (struct cyg_pathconf_info *) buf);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1491 break;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1492
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1493 default:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1494 err = EINVAL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1495 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1496 return err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1497
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1498 return ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1499 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1500
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1501 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1502 // jffs2_fo_setinfo()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1503 // Set info. Nothing supported here.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1504
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1505 static int jffs2_fo_setinfo(struct CYG_FILE_TAG *fp, int key, void *buf,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1506 int len)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1507 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1508 // No setinfo key supported at present
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1509
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1510 D2(printf("jffs2_fo_setinfo\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1511
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1512 return ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1513 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1514
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1515 //==========================================================================
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1516 // Directory operations
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1517
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1518 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1519 // jffs2_fo_dirread()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1520 // Read a single directory entry from a file.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1521
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1522 static __inline void filldir(char *nbuf, int nlen, const char *name, int namlen)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1523 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1524 int len = nlen < namlen ? nlen : namlen;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1525 memcpy(nbuf, name, len);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1526 nbuf[len] = '\0';
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1527 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1528
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1529 static int jffs2_fo_dirread(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1530 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1531 struct inode *d_inode = (struct inode *) fp->f_data;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1532 struct dirent *ent = (struct dirent *) uio->uio_iov[0].iov_base;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1533 char *nbuf = ent->d_name;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1534 int nlen = sizeof (ent->d_name) - 1;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1535 off_t len = uio->uio_iov[0].iov_len;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1536 struct jffs2_inode_info *f;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1537 struct jffs2_sb_info *c;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1538 struct inode *inode = d_inode;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1539 struct jffs2_full_dirent *fd;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1540 unsigned long offset, curofs;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1541 int found = 1;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1542
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1543 if (len < sizeof (struct dirent))
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1544 return EINVAL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1545
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1546 D1(printk
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1547 (KERN_DEBUG "jffs2_readdir() for dir_i #%lu\n", d_inode->i_ino));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1548
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1549 f = JFFS2_INODE_INFO(inode);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1550 c = JFFS2_SB_INFO(inode->i_sb);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1551
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1552 offset = fp->f_offset;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1553
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1554 if (offset == 0) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1555 D1(printk
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1556 (KERN_DEBUG "Dirent 0: \".\", ino #%lu\n", inode->i_ino));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1557 filldir(nbuf, nlen, ".", 1);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1558 goto out;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1559 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1560 if (offset == 1) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1561 filldir(nbuf, nlen, "..", 2);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1562 goto out;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1563 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1564
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1565 curofs = 1;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1566 down(&f->sem);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1567 for (fd = f->dents; fd; fd = fd->next) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1568
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1569 curofs++;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1570 /* First loop: curofs = 2; offset = 2 */
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1571 if (curofs < offset) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1572 D2(printk
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1573 (KERN_DEBUG
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1574 "Skipping dirent: \"%s\", ino #%u, type %d, because curofs %ld < offset %ld\n",
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1575 fd->name, fd->ino, fd->type, curofs, offset));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1576 continue;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1577 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1578 if (!fd->ino) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1579 D2(printk
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1580 (KERN_DEBUG "Skipping deletion dirent \"%s\"\n",
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1581 fd->name));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1582 offset++;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1583 continue;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1584 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1585 D2(printk
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1586 (KERN_DEBUG "Dirent %ld: \"%s\", ino #%u, type %d\n", offset,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1587 fd->name, fd->ino, fd->type));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1588 filldir(nbuf, nlen, fd->name, strlen(fd->name));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1589 goto out_sem;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1590 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1591 /* Reached the end of the directory */
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1592 found = 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1593 out_sem:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1594 up(&f->sem);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1595 out:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1596 fp->f_offset = ++offset;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1597 if (found) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1598 uio->uio_resid -= sizeof (struct dirent);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1599 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1600 return ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1601 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1602
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1603 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1604 // jffs2_fo_dirlseek()
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1605 // Seek directory to start.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1606
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1607 static int jffs2_fo_dirlseek(struct CYG_FILE_TAG *fp, off_t * pos, int whence)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1608 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1609 // Only allow SEEK_SET to zero
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1610
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1611 D2(printf("jffs2_fo_dirlseek\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1612
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1613 if (whence != SEEK_SET || *pos != 0)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1614 return EINVAL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1615
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1616 *pos = fp->f_offset = 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1617
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1618 return ENOERR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1619 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1620
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1621 //==========================================================================
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1622 //
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1623 // Called by JFFS2
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1624 // ===============
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1625 //
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1626 //
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1627 //==========================================================================
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1628
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1629 struct page *read_cache_page(unsigned long index,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1630 int (*filler) (void *, struct page *), void *data)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1631 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1632 // Only called in gc.c jffs2_garbage_collect_dnode
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1633 // but gets a real page for the specified inode
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1634
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1635 int err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1636 struct page *gc_page = malloc(sizeof (struct page));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1637
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1638 printf("read_cache_page\n");
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1639 memset(&gc_buffer, 0, PAGE_CACHE_SIZE);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1640
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1641 if (gc_page != NULL) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1642 gc_page->virtual = &gc_buffer;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1643 gc_page->index = index;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1644
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1645 err = filler(data, gc_page);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1646 if (err < 0) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1647 free(gc_page);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1648 gc_page = NULL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1649 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1650 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1651
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1652 return gc_page;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1653 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1654
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1655 void page_cache_release(struct page *pg)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1656 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1657
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1658 // Only called in gc.c jffs2_garbage_collect_dnode
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1659 // but should free the page malloc'd by read_cache_page
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1660
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1661 printf("page_cache_release\n");
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1662 free(pg);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1663 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1664
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1665 struct inode *new_inode(struct super_block *sb)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1666 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1667
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1668 // Only called in write.c jffs2_new_inode
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1669 // Always adds itself to inode cache
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1670
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1671 struct inode *inode;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1672 struct inode *cached_inode;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1673
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1674 inode = malloc(sizeof (struct inode));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1675 if (inode == NULL)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1676 return 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1677
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1678 D2(printf
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1679 ("malloc new_inode %x ####################################\n",
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1680 inode));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1681
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1682 memset(inode, 0, sizeof (struct inode));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1683 inode->i_sb = sb;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1684 inode->i_ino = 1;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1685 inode->i_count = 0; //1; // Let ecos manage the open count
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1686
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1687 inode->i_nlink = 1; // Let JFFS2 manage the link count
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1688 inode->i_size = 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1689
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1690 inode->i_cache_next = NULL; // Newest inode, about to be cached
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1691
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1692 // Add to the icache
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1693 for (cached_inode = sb->s_root; cached_inode != NULL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1694 cached_inode = cached_inode->i_cache_next) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1695 if (cached_inode->i_cache_next == NULL) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1696 cached_inode->i_cache_next = inode; // Current last in cache points to newcomer
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1697 inode->i_cache_prev = cached_inode; // Newcomer points back to last
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1698 break;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1699 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1700 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1701
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1702 return inode;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1703 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1704
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1705 struct inode *iget(struct super_block *sb, cyg_uint32 ino)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1706 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1707
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1708 // Substitute for iget drops straight through to reading the
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1709 // inode from disk if it is not in the inode cache
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1710
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1711 // Called in super.c jffs2_read_super, dir.c jffs2_lookup,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1712 // and gc.c jffs2_garbage_collect_pass
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1713
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1714 // Must first check for cached inode
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1715 // If this fails let new_inode create one
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1716
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1717 struct inode *inode;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1718
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1719 D2(printf("iget\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1720
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1721 // Check for this inode in the cache
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1722 for (inode = sb->s_root; inode != NULL; inode = inode->i_cache_next) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1723 if (inode->i_ino == ino)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1724 return inode;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1725 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1726 inode = NULL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1727
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1728 // Not cached, so malloc it
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1729 inode = new_inode(sb);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1730 if (inode == NULL)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1731 return 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1732
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1733 inode->i_ino = ino;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1734 jffs2_read_inode(inode);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1735
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1736 return inode;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1737 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1738
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1739 void iput(struct inode *i)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1740 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1741
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1742 // Called in dec_refcnt, jffs2_find
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1743 // (and jffs2_open and jffs2_ops_mkdir?)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1744 // super.c jffs2_read_super,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1745 // and gc.c jffs2_garbage_collect_pass
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1746
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1747 struct inode *cached_inode;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1748
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1749 D2(printf
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1750 ("free iput inode %x $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n", i));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1751 if (i && i->i_count) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1752 /* Added by dwmw2. iget/iput in Linux track the use count,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1753 don't just unconditionally free it */
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1754 printf("iput called for used inode\n");
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1755 return;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1756 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1757 if (i != NULL) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1758 // Remove from the icache
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1759 for (cached_inode = i->i_sb->s_root; cached_inode != NULL;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1760 cached_inode = cached_inode->i_cache_next) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1761 if (cached_inode == i) {
875
b17faf385ee0 * src/fs-ecos.c
jlarmour
parents: 570
diff changeset
1762 if(cached_inode->i_cache_prev != NULL) {
b17faf385ee0 * src/fs-ecos.c
jlarmour
parents: 570
diff changeset
1763 cached_inode->i_cache_prev->i_cache_next = cached_inode->i_cache_next; // Previous entry points ahead of us
b17faf385ee0 * src/fs-ecos.c
jlarmour
parents: 570
diff changeset
1764 if (cached_inode->i_cache_next != NULL)
b17faf385ee0 * src/fs-ecos.c
jlarmour
parents: 570
diff changeset
1765 cached_inode->i_cache_next->i_cache_prev = cached_inode->i_cache_prev; // Next entry points behind us
b17faf385ee0 * src/fs-ecos.c
jlarmour
parents: 570
diff changeset
1766 }
570
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1767 break;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1768 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1769 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1770 // inode has been seperated from the cache
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1771 jffs2_clear_inode(i);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1772 free(i);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1773 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1774 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1775
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1776 static int return_EIO(void)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1777 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1778 return -EIO;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1779 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1780
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1781 #define EIO_ERROR ((void *) (return_EIO))
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1782
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1783 void make_bad_inode(struct inode *inode)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1784 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1785
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1786 // In readinode.c JFFS2 checks whether the inode has appropriate
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1787 // content for its marked type
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1788
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1789 D2(printf("make_bad_inode\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1790
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1791 inode->i_mode = S_IFREG;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1792 inode->i_atime = inode->i_mtime = inode->i_ctime = cyg_timestamp();
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1793 inode->i_op = EIO_ERROR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1794 inode->i_fop = EIO_ERROR;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1795 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1796
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1797 int is_bad_inode(struct inode *inode)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1798 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1799
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1800 // Called in super.c jffs2_read_super,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1801 // and gc.c jffs2_garbage_collect_pass
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1802
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1803 D2(printf("is_bad_inode\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1804
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1805 return (inode->i_op == EIO_ERROR);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1806 /*if(i == NULL)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1807 return 1;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1808 return 0; */
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1809 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1810
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1811 cyg_bool jffs2_flash_read(struct jffs2_sb_info * c,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1812 cyg_uint32 read_buffer_offset, const size_t size,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1813 size_t * return_size, char *write_buffer)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1814 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1815 Cyg_ErrNo err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1816 cyg_uint32 len = size;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1817 struct super_block *sb = OFNI_BS_2SFFJ(c);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1818
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1819 //D2(printf("FLASH READ\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1820 //D2(printf("read address = %x\n", CYGNUM_FS_JFFS2_BASE_ADDRESS + read_buffer_offset));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1821 //D2(printf("write address = %x\n", write_buffer));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1822 //D2(printf("size = %x\n", size));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1823 err = cyg_io_bread(sb->s_dev, write_buffer, &len, read_buffer_offset);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1824
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1825 *return_size = (size_t) len;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1826 return (err != ENOERR);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1827 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1828
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1829 cyg_bool jffs2_flash_write(struct jffs2_sb_info * c,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1830 cyg_uint32 write_buffer_offset, const size_t size,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1831 size_t * return_size, char *read_buffer)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1832 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1833
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1834 Cyg_ErrNo err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1835 cyg_uint32 len = size;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1836 struct super_block *sb = OFNI_BS_2SFFJ(c);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1837
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1838 // D2(printf("FLASH WRITE ENABLED!!!\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1839 // D2(printf("write address = %x\n", CYGNUM_FS_JFFS2_BASE_ADDRESS + write_buffer_offset));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1840 // D2(printf("read address = %x\n", read_buffer));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1841 // D2(printf("size = %x\n", size));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1842
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1843 err = cyg_io_bwrite(sb->s_dev, read_buffer, &len, write_buffer_offset);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1844 *return_size = (size_t) len;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1845
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1846 return (err != ENOERR);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1847 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1848
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1849 int
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1850 jffs2_flash_writev(struct jffs2_sb_info *c, const struct iovec *vecs,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1851 unsigned long count, loff_t to, size_t * retlen)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1852 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1853 unsigned long i;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1854 size_t totlen = 0, thislen;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1855 int ret = 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1856
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1857 for (i = 0; i < count; i++) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1858 // writes need to be aligned but the data we're passed may not be
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1859 // Observation suggests most unaligned writes are small, so we
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1860 // optimize for that case.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1861
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1862 if (((vecs[i].iov_len & (sizeof (int) - 1))) ||
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1863 (((unsigned long) vecs[i].
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1864 iov_base & (sizeof (unsigned long) - 1)))) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1865 // are there iov's after this one? Or is it so much we'd need
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1866 // to do multiple writes anyway?
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1867 if ((i + 1) < count || vecs[i].iov_len > 256) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1868 // cop out and malloc
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1869 unsigned long j;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1870 ssize_t sizetomalloc = 0, totvecsize = 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1871 char *cbuf, *cbufptr;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1872
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1873 for (j = i; j < count; j++)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1874 totvecsize += vecs[j].iov_len;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1875
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1876 // pad up in case unaligned
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1877 sizetomalloc = totvecsize + sizeof (int) - 1;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1878 sizetomalloc &= ~(sizeof (int) - 1);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1879 cbuf = (char *) malloc(sizetomalloc);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1880 // malloc returns aligned memory
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1881 if (!cbuf) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1882 ret = -ENOMEM;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1883 goto writev_out;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1884 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1885 cbufptr = cbuf;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1886 for (j = i; j < count; j++) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1887 memcpy(cbufptr, vecs[j].iov_base,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1888 vecs[j].iov_len);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1889 cbufptr += vecs[j].iov_len;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1890 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1891 ret =
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1892 jffs2_flash_write(c, to, sizetomalloc,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1893 &thislen, cbuf);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1894 if (thislen > totvecsize) // in case it was aligned up
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1895 thislen = totvecsize;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1896 totlen += thislen;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1897 free(cbuf);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1898 goto writev_out;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1899 } else {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1900 // otherwise optimize for the common case
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1901 int buf[256 / sizeof (int)]; // int, so int aligned
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1902 size_t lentowrite;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1903
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1904 lentowrite = vecs[i].iov_len;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1905 // pad up in case its unaligned
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1906 lentowrite += sizeof (int) - 1;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1907 lentowrite &= ~(sizeof (int) - 1);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1908 memcpy(buf, vecs[i].iov_base, lentowrite);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1909
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1910 ret =
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1911 jffs2_flash_write(c, to, lentowrite,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1912 &thislen, (char *) &buf);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1913 if (thislen > vecs[i].iov_len)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1914 thislen = vecs[i].iov_len;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1915 } // else
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1916 } else
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1917 ret =
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1918 jffs2_flash_write(c, to, vecs[i].iov_len, &thislen,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1919 vecs[i].iov_base);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1920 totlen += thislen;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1921 if (ret || thislen != vecs[i].iov_len)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1922 break;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1923 to += vecs[i].iov_len;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1924 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1925 writev_out:
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1926 if (retlen)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1927 *retlen = totlen;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1928
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1929 return ret;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1930 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1931
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1932 cyg_bool jffs2_flash_erase(struct jffs2_sb_info * c,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1933 struct jffs2_eraseblock * jeb)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1934 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1935 cyg_io_flash_getconfig_erase_t e;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1936 void *err_addr;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1937 Cyg_ErrNo err;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1938 cyg_uint32 len = sizeof (e);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1939 struct super_block *sb = OFNI_BS_2SFFJ(c);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1940
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1941 e.offset = jeb->offset;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1942 e.len = c->sector_size;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1943 e.err_address = &err_addr;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1944
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1945 // D2(printf("FLASH ERASE ENABLED!!!\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1946 // D2(printf("erase address = %x\n", CYGNUM_FS_JFFS2_BASE_ADDRESS + jeb->offset));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1947 // D2(printf("size = %x\n", c->sector_size));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1948
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1949 err = cyg_io_get_config(sb->s_dev, CYG_IO_GET_CONFIG_FLASH_ERASE,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1950 &e, &len);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1951
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1952 return (err != ENOERR || e.flasherr != 0);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1953 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1954
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1955 // -------------------------------------------------------------------------
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1956 // EOF jffs2.c
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1957 void jffs2_clear_inode (struct inode *inode)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1958 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1959 /* We can forget about this inode for now - drop all
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1960 * the nodelists associated with it, etc.
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1961 */
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1962 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1963 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1964
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1965 D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1966
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1967 jffs2_do_clear_inode(c, f);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1968 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1969
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1970
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1971 /* jffs2_new_inode: allocate a new inode and inocache, add it to the hash,
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1972 fill in the raw_inode while you're at it. */
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1973 struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1974 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1975 struct inode *inode;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1976 struct super_block *sb = dir_i->i_sb;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1977 struct jffs2_sb_info *c;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1978 struct jffs2_inode_info *f;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1979 int ret;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1980
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1981 D1(printk(KERN_DEBUG "jffs2_new_inode(): dir_i %ld, mode 0x%x\n", dir_i->i_ino, mode));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1982
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1983 c = JFFS2_SB_INFO(sb);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1984
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1985 inode = new_inode(sb);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1986
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1987 if (!inode)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1988 return ERR_PTR(-ENOMEM);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1989
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1990 f = JFFS2_INODE_INFO(inode);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1991 jffs2_init_inode_info(f);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1992
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1993 memset(ri, 0, sizeof(*ri));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1994 /* Set OS-specific defaults for new inodes */
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1995 ri->uid = ri->gid = cpu_to_je16(0);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1996 ri->mode = cpu_to_jemode(mode);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1997 ret = jffs2_do_new_inode (c, f, mode, ri);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1998 if (ret) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
1999 make_bad_inode(inode);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2000 iput(inode);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2001 return ERR_PTR(ret);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2002 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2003 inode->i_nlink = 1;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2004 inode->i_ino = je32_to_cpu(ri->ino);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2005 inode->i_mode = jemode_to_cpu(ri->mode);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2006 inode->i_gid = je16_to_cpu(ri->gid);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2007 inode->i_uid = je16_to_cpu(ri->uid);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2008 inode->i_atime = inode->i_ctime = inode->i_mtime = cyg_timestamp();
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2009 ri->atime = ri->mtime = ri->ctime = cpu_to_je32(inode->i_mtime);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2010
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2011 inode->i_size = 0;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2012
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2013 insert_inode_hash(inode);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2014
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2015 return inode;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2016 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2017
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2018
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2019 void jffs2_read_inode (struct inode *inode)
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2020 {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2021 struct jffs2_inode_info *f;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2022 struct jffs2_sb_info *c;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2023 struct jffs2_raw_inode latest_node;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2024 int ret;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2025
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2026 D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2027
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2028 f = JFFS2_INODE_INFO(inode);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2029 c = JFFS2_SB_INFO(inode->i_sb);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2030
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2031 jffs2_init_inode_info(f);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2032
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2033 ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2034
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2035 if (ret) {
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2036 make_bad_inode(inode);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2037 up(&f->sem);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2038 return;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2039 }
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2040 inode->i_mode = jemode_to_cpu(latest_node.mode);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2041 inode->i_uid = je16_to_cpu(latest_node.uid);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2042 inode->i_gid = je16_to_cpu(latest_node.gid);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2043 inode->i_size = je32_to_cpu(latest_node.isize);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2044 inode->i_atime = je32_to_cpu(latest_node.atime);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2045 inode->i_mtime = je32_to_cpu(latest_node.mtime);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2046 inode->i_ctime = je32_to_cpu(latest_node.ctime);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2047
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2048 inode->i_nlink = f->inocache->nlink;
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2049 up(&f->sem);
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2050
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2051 D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n"));
a7947d436e85 Update to latest public JFFS2 sources
gthomas
parents:
diff changeset
2052 }