Mercurial > yaffs-ecoscentric-gpl
annotate direct/yaffsfs.c @ 341:89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
| author | charles <charles> |
|---|---|
| date | Wed, 06 Jan 2010 04:00:23 +0000 |
| parents | 490a804b7bd3 |
| children | ce702882929d |
| rev | line source |
|---|---|
| 1 | 1 /* |
| 167 | 2 * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. |
| 1 | 3 * |
| 167 | 4 * Copyright (C) 2002-2007 Aleph One Ltd. |
| 5 * for Toby Churchill Ltd and Brightstar Engineering | |
| 1 | 6 * |
| 7 * Created by Charles Manning <charles@aleph1.co.uk> | |
| 8 * | |
| 9 * This program is free software; you can redistribute it and/or modify | |
| 10 * it under the terms of the GNU General Public License version 2 as | |
| 11 * published by the Free Software Foundation. | |
| 12 */ | |
| 208 | 13 |
| 1 | 14 #include "yaffsfs.h" |
| 15 #include "yaffs_guts.h" | |
| 16 #include "yaffscfg.h" | |
| 17 #include <string.h> // for memset | |
| 18 #include "yportenv.h" | |
| 19 | |
| 20 #define YAFFSFS_MAX_SYMLINK_DEREFERENCES 5 | |
| 21 | |
| 22 #ifndef NULL | |
| 23 #define NULL ((void *)0) | |
| 24 #endif | |
| 25 | |
| 26 | |
|
341
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
27 const char *yaffsfs_c_version="$Id: yaffsfs.c,v 1.30 2010-01-06 04:00:23 charles Exp $"; |
| 1 | 28 |
| 29 // configurationList is the list of devices that are supported | |
| 30 static yaffsfs_DeviceConfiguration *yaffsfs_configurationList; | |
| 31 | |
| 32 | |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
33 /* Some forward references */ |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
34 static yaffs_Object *yaffsfs_FindObject(yaffs_Object *relativeDirectory, const YCHAR *path, int symDepth); |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
35 static void yaffsfs_RemoveObjectCallback(yaffs_Object *obj); |
| 1 | 36 |
| 37 | |
| 38 // Handle management. | |
| 208 | 39 // |
| 1 | 40 |
| 179 | 41 |
| 42 unsigned int yaffs_wr_attempts; | |
| 43 | |
|
341
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
44 typedef struct { |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
45 int count; |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
46 yaffs_Object *iObj; |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
47 } yaffsfs_Inode; |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
48 |
| 304 | 49 typedef struct{ |
| 1 | 50 __u8 inUse:1; // this handle is in use |
| 51 __u8 readOnly:1; // this handle is read only | |
| 52 __u8 append:1; // append only | |
| 53 __u8 exclusive:1; // exclusive | |
|
341
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
54 int inodeId:20; // the object |
| 1 | 55 __u32 position; // current position in file |
| 56 }yaffsfs_Handle; | |
| 57 | |
|
341
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
58 static yaffsfs_Inode yaffsfs_inode[YAFFSFS_N_HANDLES]; |
| 1 | 59 static yaffsfs_Handle yaffsfs_handle[YAFFSFS_N_HANDLES]; |
| 60 | |
| 61 // yaffsfs_InitHandle | |
| 62 /// Inilitalise handles on start-up. | |
| 63 // | |
| 64 static int yaffsfs_InitHandles(void) | |
| 65 { | |
| 66 int i; | |
|
341
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
67 memset(yaffsfs_inode,0,sizeof(yaffsfs_inode)); |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
68 memset(yaffsfs_handle,0,sizeof(yaffsfs_handle)); |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
69 for(i = 0; i < YAFFSFS_N_HANDLES; i++) |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
70 yaffsfs_handle[i].inodeId = -1; |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
71 |
| 1 | 72 return 0; |
| 73 } | |
| 74 | |
| 75 yaffsfs_Handle *yaffsfs_GetHandlePointer(int h) | |
| 76 { | |
| 77 if(h < 0 || h >= YAFFSFS_N_HANDLES) | |
| 78 return NULL; | |
| 208 | 79 |
| 1 | 80 return &yaffsfs_handle[h]; |
| 81 } | |
| 82 | |
|
341
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
83 yaffsfs_Inode *yaffsfs_GetInodePointer(int handle) |
| 1 | 84 { |
| 85 yaffsfs_Handle *h = yaffsfs_GetHandlePointer(handle); | |
| 86 | |
|
341
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
87 if(h && h->inUse && h->inodeId >= 0 && h->inodeId < YAFFSFS_N_HANDLES) |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
88 return &yaffsfs_inode[h->inodeId]; |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
89 |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
90 return NULL; |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
91 } |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
92 |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
93 yaffs_Object *yaffsfs_GetHandleObject(int handle) |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
94 { |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
95 yaffsfs_Inode *in = yaffsfs_GetInodePointer(handle); |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
96 |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
97 if(in) |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
98 return in->iObj; |
| 208 | 99 |
| 1 | 100 return NULL; |
| 101 } | |
| 102 | |
|
341
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
103 //yaffsfs_GetInodeIdForObject |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
104 // Grab an inode entry when opening a new inode. |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
105 // |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
106 |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
107 static int yaffsfs_GetInodeIdForObject(yaffs_Object *obj) |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
108 { |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
109 int i; |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
110 int ret = -1; |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
111 yaffsfs_Inode *in = NULL; |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
112 |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
113 if(obj) |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
114 obj = yaffs_GetEquivalentObject(obj); |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
115 |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
116 /* Look for it. If we can't find it then make one */ |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
117 for(i = 0; i < YAFFSFS_N_HANDLES && ret < 0; i++){ |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
118 if(yaffsfs_inode[i].iObj == obj) |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
119 ret = i; |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
120 } |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
121 |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
122 for(i = 0; i < YAFFSFS_N_HANDLES && ret < 0; i++){ |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
123 if(!yaffsfs_inode[i].iObj) |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
124 ret = i; |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
125 } |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
126 |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
127 |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
128 if(ret>=0){ |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
129 in = &yaffsfs_inode[ret]; |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
130 if(!in->iObj) |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
131 in->count = 0; |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
132 in->iObj = obj; |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
133 in->count++; |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
134 } |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
135 |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
136 |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
137 return ret; |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
138 } |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
139 |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
140 static void yaffsfs_ReleaseInode(yaffsfs_Inode *in) |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
141 { |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
142 yaffs_Object *obj; |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
143 |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
144 obj = in->iObj; |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
145 |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
146 if(obj->unlinked) |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
147 yaffs_DeleteObject(obj); |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
148 |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
149 obj->myInode = NULL; |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
150 in->iObj = NULL; |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
151 |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
152 } |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
153 |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
154 static void yaffsfs_PutInode(int inodeId) |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
155 { |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
156 if(inodeId >= 0 && inodeId < YAFFSFS_N_HANDLES){ |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
157 yaffsfs_Inode *in = & yaffsfs_inode[inodeId]; |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
158 in->count--; |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
159 if(in->count <= 0) |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
160 yaffsfs_ReleaseInode(in); |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
161 } |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
162 } |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
163 |
| 1 | 164 |
| 165 //yaffsfs_GetHandle | |
| 166 // Grab a handle (when opening a file) | |
| 167 // | |
| 168 | |
| 169 static int yaffsfs_GetHandle(void) | |
| 170 { | |
| 171 int i; | |
| 172 yaffsfs_Handle *h; | |
| 208 | 173 |
| 304 | 174 for(i = 0; i < YAFFSFS_N_HANDLES; i++){ |
| 1 | 175 h = yaffsfs_GetHandlePointer(i); |
| 304 | 176 if(!h){ |
| 1 | 177 // todo bug: should never happen |
| 178 } | |
| 304 | 179 if(!h->inUse){ |
| 1 | 180 memset(h,0,sizeof(yaffsfs_Handle)); |
|
341
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
181 h->inodeId=-1; |
| 1 | 182 h->inUse=1; |
| 183 return i; | |
| 184 } | |
| 185 } | |
| 186 return -1; | |
| 187 } | |
| 188 | |
| 189 // yaffs_PutHandle | |
|
341
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
190 // Let go of a handle when closing a file or aborting an open. |
| 1 | 191 // |
| 192 static int yaffsfs_PutHandle(int handle) | |
| 193 { | |
| 194 yaffsfs_Handle *h = yaffsfs_GetHandlePointer(handle); | |
| 208 | 195 |
| 304 | 196 if(h){ |
|
341
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
197 if(h->inodeId >= 0) |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
198 yaffsfs_PutInode(h->inodeId); |
| 1 | 199 h->inUse = 0; |
|
341
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
200 h->inodeId = -1; |
| 1 | 201 } |
| 202 return 0; | |
| 203 } | |
| 204 | |
| 205 | |
| 206 | |
|
341
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
207 |
| 1 | 208 // Stuff to search for a directory from a path |
| 209 | |
| 210 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
211 int yaffsfs_Match(YCHAR a, YCHAR b) |
| 1 | 212 { |
| 213 // case sensitive | |
| 214 return (a == b); | |
| 215 } | |
| 216 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
217 int yaffsfs_IsPathDivider(YCHAR ch) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
218 { |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
219 YCHAR *str = YAFFS_PATH_DIVIDERS; |
| 208 | 220 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
221 while(*str){ |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
222 if(*str == ch) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
223 return 1; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
224 str++; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
225 } |
| 208 | 226 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
227 return 0; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
228 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
229 |
| 1 | 230 // yaffsfs_FindDevice |
| 231 // yaffsfs_FindRoot | |
| 232 // Scan the configuration list to find the root. | |
|
91
07a42c94dda5
Improve YDI lookup and device prefic handling
charles <charles>
parents:
81
diff
changeset
|
233 // Curveballs: Should match paths that end in '/' too |
|
07a42c94dda5
Improve YDI lookup and device prefic handling
charles <charles>
parents:
81
diff
changeset
|
234 // Curveball2 Might have "/x/ and "/x/y". Need to return the longest match |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
235 static yaffs_Device *yaffsfs_FindDevice(const YCHAR *path, YCHAR **restOfPath) |
| 1 | 236 { |
| 237 yaffsfs_DeviceConfiguration *cfg = yaffsfs_configurationList; | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
238 const YCHAR *leftOver; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
239 const YCHAR *p; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
240 yaffs_Device *retval = NULL; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
241 int thisMatchLength; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
242 int longestMatch = -1; |
| 217 | 243 int matching; |
| 208 | 244 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
245 // Check all configs, choose the one that: |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
246 // 1) Actually matches a prefix (ie /a amd /abc will not match |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
247 // 2) Matches the longest. |
| 304 | 248 while(cfg && cfg->prefix && cfg->dev){ |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
249 leftOver = path; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
250 p = cfg->prefix; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
251 thisMatchLength = 0; |
| 217 | 252 matching = 1; |
| 208 | 253 |
| 254 | |
| 217 | 255 while(matching && *p && *leftOver){ |
| 256 // Skip over any /s | |
| 257 while(yaffsfs_IsPathDivider(*p)) | |
| 208 | 258 p++; |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
259 |
| 217 | 260 // Skip over any /s |
| 261 while(yaffsfs_IsPathDivider(*leftOver)) | |
| 262 leftOver++; | |
| 263 | |
| 264 // Now match the text part | |
| 265 while(matching && | |
| 266 *p && !yaffsfs_IsPathDivider(*p) && | |
| 267 *leftOver && !yaffsfs_IsPathDivider(*leftOver)){ | |
| 268 if(yaffsfs_Match(*p,*leftOver)){ | |
| 269 p++; | |
| 270 leftOver++; | |
| 271 thisMatchLength++; | |
| 272 } else { | |
| 273 matching = 0; | |
| 274 } | |
| 275 } | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
276 } |
| 208 | 277 |
| 217 | 278 // Skip over any /s in leftOver |
| 279 while(yaffsfs_IsPathDivider(*leftOver)) | |
| 280 leftOver++; | |
| 281 | |
| 208 | 282 |
| 304 | 283 if( matching && (thisMatchLength > longestMatch)){ |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
284 // Matched prefix |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
285 *restOfPath = (YCHAR *)leftOver; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
286 retval = cfg->dev; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
287 longestMatch = thisMatchLength; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
288 } |
| 217 | 289 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
290 cfg++; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
291 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
292 return retval; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
293 } |
| 208 | 294 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
295 #if 0 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
296 static yaffs_Device *yaffsfs_FindDevice(const YCHAR *path, YCHAR **restOfPath) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
297 { |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
298 yaffsfs_DeviceConfiguration *cfg = yaffsfs_configurationList; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
299 const YCHAR *leftOver; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
300 const YCHAR *p; |
|
91
07a42c94dda5
Improve YDI lookup and device prefic handling
charles <charles>
parents:
81
diff
changeset
|
301 yaffs_Device *retval = NULL; |
|
07a42c94dda5
Improve YDI lookup and device prefic handling
charles <charles>
parents:
81
diff
changeset
|
302 int thisMatchLength; |
|
07a42c94dda5
Improve YDI lookup and device prefic handling
charles <charles>
parents:
81
diff
changeset
|
303 int longestMatch = -1; |
| 208 | 304 |
|
91
07a42c94dda5
Improve YDI lookup and device prefic handling
charles <charles>
parents:
81
diff
changeset
|
305 // Check all configs, choose the one that: |
|
07a42c94dda5
Improve YDI lookup and device prefic handling
charles <charles>
parents:
81
diff
changeset
|
306 // 1) Actually matches a prefix (ie /a amd /abc will not match |
|
07a42c94dda5
Improve YDI lookup and device prefic handling
charles <charles>
parents:
81
diff
changeset
|
307 // 2) Matches the longest. |
| 304 | 308 while(cfg && cfg->prefix && cfg->dev){ |
| 1 | 309 leftOver = path; |
| 310 p = cfg->prefix; | |
|
91
07a42c94dda5
Improve YDI lookup and device prefic handling
charles <charles>
parents:
81
diff
changeset
|
311 thisMatchLength = 0; |
| 208 | 312 |
| 313 while(*p && //unmatched part of prefix | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
314 !(yaffsfs_IsPathDivider(*p) && (p[1] == 0)) && // the rest of the prefix is not / (to catch / at end) |
| 208 | 315 *leftOver && |
| 304 | 316 yaffsfs_Match(*p,*leftOver)){ |
| 1 | 317 p++; |
| 318 leftOver++; | |
|
91
07a42c94dda5
Improve YDI lookup and device prefic handling
charles <charles>
parents:
81
diff
changeset
|
319 thisMatchLength++; |
| 1 | 320 } |
| 208 | 321 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
322 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
323 if((!*p || (yaffsfs_IsPathDivider(*p) && (p[1] == 0))) && // end of prefix |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
324 (!*leftOver || yaffsfs_IsPathDivider(*leftOver)) && // no more in this path name part |
| 304 | 325 (thisMatchLength > longestMatch)){ |
| 1 | 326 // Matched prefix |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
327 *restOfPath = (YCHAR *)leftOver; |
|
91
07a42c94dda5
Improve YDI lookup and device prefic handling
charles <charles>
parents:
81
diff
changeset
|
328 retval = cfg->dev; |
|
07a42c94dda5
Improve YDI lookup and device prefic handling
charles <charles>
parents:
81
diff
changeset
|
329 longestMatch = thisMatchLength; |
| 1 | 330 } |
| 331 cfg++; | |
| 332 } | |
|
91
07a42c94dda5
Improve YDI lookup and device prefic handling
charles <charles>
parents:
81
diff
changeset
|
333 return retval; |
| 1 | 334 } |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
335 #endif |
| 1 | 336 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
337 static yaffs_Object *yaffsfs_FindRoot(const YCHAR *path, YCHAR **restOfPath) |
| 1 | 338 { |
| 339 | |
| 340 yaffs_Device *dev; | |
| 208 | 341 |
| 1 | 342 dev= yaffsfs_FindDevice(path,restOfPath); |
| 304 | 343 if(dev && dev->isMounted){ |
| 1 | 344 return dev->rootDir; |
| 345 } | |
| 346 return NULL; | |
| 347 } | |
| 348 | |
| 349 static yaffs_Object *yaffsfs_FollowLink(yaffs_Object *obj,int symDepth) | |
| 350 { | |
| 351 | |
| 304 | 352 while(obj && obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK){ |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
353 YCHAR *alias = obj->variant.symLinkVariant.alias; |
| 208 | 354 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
355 if(yaffsfs_IsPathDivider(*alias)) |
| 1 | 356 // Starts with a /, need to scan from root up |
| 357 obj = yaffsfs_FindObject(NULL,alias,symDepth++); | |
| 358 else | |
| 359 // Relative to here, so use the parent of the symlink as a start | |
| 360 obj = yaffsfs_FindObject(obj->parent,alias,symDepth++); | |
| 361 } | |
| 362 return obj; | |
| 363 } | |
| 364 | |
| 365 | |
| 366 // yaffsfs_FindDirectory | |
| 367 // Parse a path to determine the directory and the name within the directory. | |
| 368 // | |
| 369 // eg. "/data/xx/ff" --> puts name="ff" and returns the directory "/data/xx" | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
370 static yaffs_Object *yaffsfs_DoFindDirectory(yaffs_Object *startDir,const YCHAR *path,YCHAR **name,int symDepth) |
| 1 | 371 { |
| 372 yaffs_Object *dir; | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
373 YCHAR *restOfPath; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
374 YCHAR str[YAFFS_MAX_NAME_LENGTH+1]; |
| 1 | 375 int i; |
| 208 | 376 |
| 1 | 377 if(symDepth > YAFFSFS_MAX_SYMLINK_DEREFERENCES) |
| 378 return NULL; | |
| 208 | 379 |
| 304 | 380 if(startDir){ |
| 1 | 381 dir = startDir; |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
382 restOfPath = (YCHAR *)path; |
| 1 | 383 } |
| 384 else | |
| 385 dir = yaffsfs_FindRoot(path,&restOfPath); | |
| 208 | 386 |
| 304 | 387 while(dir){ |
| 1 | 388 // parse off /. |
| 208 | 389 // curve ball: also throw away surplus '/' |
| 1 | 390 // eg. "/ram/x////ff" gets treated the same as "/ram/x/ff" |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
391 while(yaffsfs_IsPathDivider(*restOfPath)) |
| 1 | 392 restOfPath++; // get rid of '/' |
| 208 | 393 |
| 1 | 394 *name = restOfPath; |
| 395 i = 0; | |
| 208 | 396 |
| 304 | 397 while(*restOfPath && !yaffsfs_IsPathDivider(*restOfPath)){ |
| 398 if (i < YAFFS_MAX_NAME_LENGTH){ | |
| 1 | 399 str[i] = *restOfPath; |
| 400 str[i+1] = '\0'; | |
| 401 i++; | |
| 402 } | |
| 403 restOfPath++; | |
| 404 } | |
| 208 | 405 |
| 1 | 406 if(!*restOfPath) |
| 407 // got to the end of the string | |
| 408 return dir; | |
| 304 | 409 else{ |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
410 if(yaffs_strcmp(str,_Y(".")) == 0) |
| 1 | 411 { |
| 412 // Do nothing | |
| 413 } | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
414 else if(yaffs_strcmp(str,_Y("..")) == 0) |
| 1 | 415 dir = dir->parent; |
| 304 | 416 else{ |
| 1 | 417 dir = yaffs_FindObjectByName(dir,str); |
| 208 | 418 |
| 1 | 419 while(dir && dir->variantType == YAFFS_OBJECT_TYPE_SYMLINK) |
| 420 dir = yaffsfs_FollowLink(dir,symDepth); | |
| 208 | 421 |
| 422 | |
| 1 | 423 if(dir && dir->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) |
| 424 dir = NULL; | |
| 425 } | |
| 426 } | |
| 427 } | |
| 428 // directory did not exist. | |
| 429 return NULL; | |
| 430 } | |
| 431 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
432 static yaffs_Object *yaffsfs_FindDirectory(yaffs_Object *relativeDirectory,const YCHAR *path,YCHAR **name,int symDepth) |
| 1 | 433 { |
| 434 return yaffsfs_DoFindDirectory(relativeDirectory,path,name,symDepth); | |
| 435 } | |
| 436 | |
| 437 // yaffsfs_FindObject turns a path for an existing object into the object | |
| 208 | 438 // |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
439 static yaffs_Object *yaffsfs_FindObject(yaffs_Object *relativeDirectory, const YCHAR *path,int symDepth) |
| 1 | 440 { |
| 441 yaffs_Object *dir; | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
442 YCHAR *name; |
| 208 | 443 |
| 1 | 444 dir = yaffsfs_FindDirectory(relativeDirectory,path,&name,symDepth); |
| 208 | 445 |
| 1 | 446 if(dir && *name) |
| 447 return yaffs_FindObjectByName(dir,name); | |
| 208 | 448 |
| 1 | 449 return dir; |
| 450 } | |
| 451 | |
| 452 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
453 int yaffs_dup(int fd) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
454 { |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
455 int newHandle = -1; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
456 yaffsfs_Handle *oldPtr = NULL; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
457 yaffsfs_Handle *newPtr = NULL; |
| 208 | 458 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
459 yaffsfs_Lock(); |
| 208 | 460 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
461 oldPtr = yaffsfs_GetHandlePointer(fd); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
462 if(oldPtr && oldPtr->inUse) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
463 newHandle = yaffsfs_GetHandle(); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
464 if(newHandle >= 0) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
465 newPtr = yaffsfs_GetHandlePointer(newHandle); |
| 208 | 466 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
467 if(newPtr){ |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
468 *newPtr = *oldPtr; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
469 return newHandle; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
470 } |
| 208 | 471 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
472 if(!oldPtr) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
473 yaffsfs_SetError(-EBADF); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
474 else |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
475 yaffsfs_SetError(-ENOMEM); |
| 208 | 476 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
477 return -1; |
| 208 | 478 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
479 } |
| 1 | 480 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
481 int yaffs_open(const YCHAR *path, int oflag, int mode) |
| 1 | 482 { |
| 483 yaffs_Object *obj = NULL; | |
| 484 yaffs_Object *dir = NULL; | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
485 YCHAR *name; |
| 1 | 486 int handle = -1; |
| 487 yaffsfs_Handle *h = NULL; | |
| 488 int alreadyOpen = 0; | |
| 489 int alreadyExclusive = 0; | |
| 490 int openDenied = 0; | |
| 491 int symDepth = 0; | |
| 492 int errorReported = 0; | |
| 208 | 493 |
| 1 | 494 int i; |
| 208 | 495 |
| 496 | |
| 1 | 497 // todo sanity check oflag (eg. can't have O_TRUNC without WRONLY or RDWR |
| 208 | 498 |
| 499 | |
| 1 | 500 yaffsfs_Lock(); |
| 208 | 501 |
| 1 | 502 handle = yaffsfs_GetHandle(); |
| 208 | 503 |
| 304 | 504 if(handle >= 0){ |
| 1 | 505 |
| 506 h = yaffsfs_GetHandlePointer(handle); | |
| 208 | 507 |
| 508 | |
| 1 | 509 // try to find the exisiting object |
| 510 obj = yaffsfs_FindObject(NULL,path,0); | |
| 208 | 511 |
| 1 | 512 if(obj && obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK) |
| 513 obj = yaffsfs_FollowLink(obj,symDepth++); | |
| 514 | |
|
341
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
515 if(obj) |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
516 obj = yaffs_GetEquivalentObject(obj); |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
517 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
518 if(obj && obj->variantType != YAFFS_OBJECT_TYPE_FILE) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
519 obj = NULL; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
520 |
| 304 | 521 if(obj){ |
| 1 | 522 // Check if the object is already in use |
| 523 alreadyOpen = alreadyExclusive = 0; | |
| 208 | 524 |
| 304 | 525 for(i = 0; i < YAFFSFS_N_HANDLES; i++){ |
| 1 | 526 if(i != handle && |
| 527 yaffsfs_handle[i].inUse && | |
|
341
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
528 obj == yaffsfs_inode[yaffsfs_handle[i].inodeId].iObj){ |
| 1 | 529 alreadyOpen = 1; |
| 530 if(yaffsfs_handle[i].exclusive) | |
| 531 alreadyExclusive = 1; | |
| 532 } | |
| 533 } | |
| 534 | |
| 535 if(((oflag & O_EXCL) && alreadyOpen) || alreadyExclusive) | |
| 536 openDenied = 1; | |
| 208 | 537 |
| 1 | 538 // Open should fail if O_CREAT and O_EXCL are specified |
| 304 | 539 if((oflag & O_EXCL) && (oflag & O_CREAT)){ |
| 1 | 540 openDenied = 1; |
| 541 yaffsfs_SetError(-EEXIST); | |
| 542 errorReported = 1; | |
| 543 } | |
| 208 | 544 |
| 1 | 545 // Check file permissions |
| 546 if( (oflag & (O_RDWR | O_WRONLY)) == 0 && // ie O_RDONLY | |
|
21
68dffdfc2095
Some tinkering on test harness and st_xxx to yst_xxx changes
charles <charles>
parents:
17
diff
changeset
|
547 !(obj->yst_mode & S_IREAD)) |
| 1 | 548 openDenied = 1; |
| 549 | |
| 208 | 550 if( (oflag & O_RDWR) && |
|
21
68dffdfc2095
Some tinkering on test harness and st_xxx to yst_xxx changes
charles <charles>
parents:
17
diff
changeset
|
551 !(obj->yst_mode & S_IREAD)) |
| 1 | 552 openDenied = 1; |
| 553 | |
| 208 | 554 if( (oflag & (O_RDWR | O_WRONLY)) && |
|
21
68dffdfc2095
Some tinkering on test harness and st_xxx to yst_xxx changes
charles <charles>
parents:
17
diff
changeset
|
555 !(obj->yst_mode & S_IWRITE)) |
| 1 | 556 openDenied = 1; |
| 208 | 557 |
| 304 | 558 } else if((oflag & O_CREAT)) { |
| 1 | 559 // Let's see if we can create this file |
| 560 dir = yaffsfs_FindDirectory(NULL,path,&name,0); | |
| 561 if(dir) | |
| 208 | 562 obj = yaffs_MknodFile(dir,name,mode,0,0); |
| 304 | 563 else { |
| 1 | 564 yaffsfs_SetError(-ENOTDIR); |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
565 errorReported = 1; |
| 1 | 566 } |
| 567 } | |
| 208 | 568 |
| 304 | 569 if(obj && !openDenied) { |
|
341
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
570 int inodeId = yaffsfs_GetInodeIdForObject(obj); |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
571 |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
572 if(inodeId<0) { |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
573 /* |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
574 * Todo: Fix any problem if inodes run out, though that |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
575 * can't happen if the number of inode items >= number of handles. |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
576 */ |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
577 } |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
578 |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
579 h->inodeId = inodeId; |
| 1 | 580 h->inUse = 1; |
| 304 | 581 h->readOnly = (oflag & (O_WRONLY | O_RDWR)) ? 0 : 1; |
| 1 | 582 h->append = (oflag & O_APPEND) ? 1 : 0; |
| 583 h->exclusive = (oflag & O_EXCL) ? 1 : 0; | |
| 584 h->position = 0; | |
| 208 | 585 |
|
341
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
586 /* Hook inode to object */ |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
587 obj->myInode = (void*) &yaffsfs_inode[inodeId]; |
|
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
588 |
| 208 | 589 if((oflag & O_TRUNC) && !h->readOnly) |
| 590 yaffs_ResizeFile(obj,0); | |
| 304 | 591 } else { |
| 1 | 592 yaffsfs_PutHandle(handle); |
| 304 | 593 if(!errorReported) { |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
594 yaffsfs_SetError(-EACCES); |
| 1 | 595 errorReported = 1; |
| 596 } | |
| 597 handle = -1; | |
| 598 } | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
599 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
600 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
601 yaffsfs_Unlock(); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
602 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
603 return handle; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
604 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
605 |
| 291 | 606 int yaffs_Dofsync(int fd,int datasync) |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
607 { |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
608 yaffsfs_Handle *h = NULL; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
609 int retVal = 0; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
610 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
611 yaffsfs_Lock(); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
612 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
613 h = yaffsfs_GetHandlePointer(fd); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
614 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
615 if(h && h->inUse) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
616 // flush the file |
|
341
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
617 yaffs_FlushFile(yaffsfs_inode[h->inodeId].iObj,1,datasync); |
| 304 | 618 else { |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
619 // bad handle |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
620 yaffsfs_SetError(-EBADF); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
621 retVal = -1; |
| 1 | 622 } |
| 208 | 623 |
| 1 | 624 yaffsfs_Unlock(); |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
625 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
626 return retVal; |
| 1 | 627 } |
| 628 | |
| 291 | 629 int yaffs_fsync(int fd) |
| 630 { | |
| 631 return yaffs_Dofsync(fd,0); | |
| 632 } | |
| 633 | |
| 292 | 634 int yaffs_flush(int fd) |
| 635 { | |
| 636 return yaffs_fsync(fd); | |
| 637 } | |
| 638 | |
| 291 | 639 int yaffs_fdatasync(int fd) |
| 640 { | |
| 641 return yaffs_Dofsync(fd,1); | |
| 642 } | |
| 208 | 643 |
| 1 | 644 int yaffs_close(int fd) |
| 645 { | |
| 646 yaffsfs_Handle *h = NULL; | |
| 647 int retVal = 0; | |
| 208 | 648 |
| 1 | 649 yaffsfs_Lock(); |
| 650 | |
| 651 h = yaffsfs_GetHandlePointer(fd); | |
| 208 | 652 |
| 304 | 653 if(h && h->inUse) { |
| 1 | 654 // clean up |
|
341
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
655 yaffs_FlushFile(yaffsfs_inode[h->inodeId].iObj,1,0); |
| 1 | 656 yaffsfs_PutHandle(fd); |
| 657 retVal = 0; | |
| 304 | 658 } else { |
| 1 | 659 // bad handle |
| 208 | 660 yaffsfs_SetError(-EBADF); |
| 1 | 661 retVal = -1; |
| 662 } | |
| 208 | 663 |
| 1 | 664 yaffsfs_Unlock(); |
| 208 | 665 |
| 1 | 666 return retVal; |
| 667 } | |
| 668 | |
| 669 int yaffs_read(int fd, void *buf, unsigned int nbyte) | |
| 670 { | |
| 671 yaffsfs_Handle *h = NULL; | |
| 672 yaffs_Object *obj = NULL; | |
| 673 int pos = 0; | |
| 674 int nRead = -1; | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
675 unsigned int maxRead; |
| 208 | 676 |
| 1 | 677 yaffsfs_Lock(); |
| 678 h = yaffsfs_GetHandlePointer(fd); | |
| 679 obj = yaffsfs_GetHandleObject(fd); | |
| 208 | 680 |
| 1 | 681 if(!h || !obj) |
| 682 // bad handle | |
| 208 | 683 yaffsfs_SetError(-EBADF); |
| 304 | 684 |
| 685 else if( h && obj){ | |
| 1 | 686 pos= h->position; |
| 687 if(yaffs_GetObjectFileLength(obj) > pos) | |
| 688 maxRead = yaffs_GetObjectFileLength(obj) - pos; | |
| 689 else | |
| 690 maxRead = 0; | |
| 691 | |
| 692 if(nbyte > maxRead) | |
| 693 nbyte = maxRead; | |
| 694 | |
| 208 | 695 |
| 304 | 696 if(nbyte > 0) { |
| 1 | 697 nRead = yaffs_ReadDataFromFile(obj,buf,pos,nbyte); |
| 698 if(nRead >= 0) | |
| 699 h->position = pos + nRead; | |
| 304 | 700 else { |
| 1 | 701 //todo error |
| 702 } | |
| 304 | 703 } else |
| 1 | 704 nRead = 0; |
| 208 | 705 |
| 1 | 706 } |
| 208 | 707 |
| 1 | 708 yaffsfs_Unlock(); |
| 208 | 709 |
| 710 | |
| 1 | 711 return (nRead >= 0) ? nRead : -1; |
| 208 | 712 |
| 1 | 713 } |
| 714 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
715 int yaffs_pread(int fd, void *buf, unsigned int nbyte, unsigned int offset) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
716 { |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
717 yaffsfs_Handle *h = NULL; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
718 yaffs_Object *obj = NULL; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
719 int pos = 0; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
720 int nRead = -1; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
721 unsigned int maxRead; |
| 208 | 722 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
723 yaffsfs_Lock(); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
724 h = yaffsfs_GetHandlePointer(fd); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
725 obj = yaffsfs_GetHandleObject(fd); |
| 208 | 726 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
727 if(!h || !obj) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
728 // bad handle |
| 208 | 729 yaffsfs_SetError(-EBADF); |
| 304 | 730 else if( h && obj) { |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
731 pos= offset; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
732 if(yaffs_GetObjectFileLength(obj) > pos) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
733 maxRead = yaffs_GetObjectFileLength(obj) - pos; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
734 else |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
735 maxRead = 0; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
736 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
737 if(nbyte > maxRead) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
738 nbyte = maxRead; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
739 |
| 208 | 740 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
741 if(nbyte > 0) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
742 nRead = yaffs_ReadDataFromFile(obj,buf,pos,nbyte); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
743 else |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
744 nRead = 0; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
745 } |
| 208 | 746 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
747 yaffsfs_Unlock(); |
| 208 | 748 |
| 749 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
750 return (nRead >= 0) ? nRead : -1; |
| 208 | 751 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
752 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
753 |
| 1 | 754 int yaffs_write(int fd, const void *buf, unsigned int nbyte) |
| 755 { | |
| 756 yaffsfs_Handle *h = NULL; | |
| 757 yaffs_Object *obj = NULL; | |
| 758 int pos = 0; | |
| 759 int nWritten = -1; | |
| 17 | 760 int writeThrough = 0; |
| 208 | 761 |
| 1 | 762 yaffsfs_Lock(); |
| 763 h = yaffsfs_GetHandlePointer(fd); | |
| 764 obj = yaffsfs_GetHandleObject(fd); | |
| 208 | 765 |
| 1 | 766 if(!h || !obj) |
| 767 // bad handle | |
| 208 | 768 yaffsfs_SetError(-EBADF); |
| 304 | 769 else if( h && obj && h->readOnly){ |
| 1 | 770 // todo error |
| 304 | 771 } else if( h && obj){ |
| 1 | 772 if(h->append) |
| 773 pos = yaffs_GetObjectFileLength(obj); | |
| 774 else | |
| 775 pos = h->position; | |
| 208 | 776 |
| 17 | 777 nWritten = yaffs_WriteDataToFile(obj,buf,pos,nbyte,writeThrough); |
| 208 | 778 |
| 1 | 779 if(nWritten >= 0) |
| 780 h->position = pos + nWritten; | |
| 304 | 781 else { |
| 1 | 782 //todo error |
| 783 } | |
| 208 | 784 |
| 1 | 785 } |
| 208 | 786 |
| 1 | 787 yaffsfs_Unlock(); |
| 208 | 788 |
| 789 | |
| 1 | 790 return (nWritten >= 0) ? nWritten : -1; |
| 791 | |
| 792 } | |
| 793 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
794 int yaffs_pwrite(int fd, const void *buf, unsigned int nbyte, unsigned int offset) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
795 { |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
796 yaffsfs_Handle *h = NULL; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
797 yaffs_Object *obj = NULL; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
798 int pos = 0; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
799 int nWritten = -1; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
800 int writeThrough = 0; |
| 208 | 801 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
802 yaffsfs_Lock(); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
803 h = yaffsfs_GetHandlePointer(fd); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
804 obj = yaffsfs_GetHandleObject(fd); |
| 208 | 805 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
806 if(!h || !obj) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
807 // bad handle |
| 208 | 808 yaffsfs_SetError(-EBADF); |
| 304 | 809 else if( h && obj && h->readOnly){ |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
810 // todo error |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
811 } |
| 304 | 812 else if( h && obj){ |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
813 pos = offset; |
| 208 | 814 |
| 815 nWritten = yaffs_WriteDataToFile(obj,buf,pos,nbyte,writeThrough); | |
| 816 | |
| 817 if(nWritten < 0 || ((unsigned int)nWritten) < nbyte) | |
| 818 yaffsfs_SetError(-ENOSPC); | |
| 819 | |
| 820 } | |
| 821 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
822 yaffsfs_Unlock(); |
| 208 | 823 |
| 824 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
825 return (nWritten >= 0) ? nWritten : -1; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
826 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
827 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
828 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
829 |
| 208 | 830 int yaffs_truncate(const YCHAR *path,off_t newSize) |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
831 { |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
832 yaffs_Object *obj = NULL; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
833 int result = YAFFS_FAIL; |
| 208 | 834 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
835 yaffsfs_Lock(); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
836 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
837 obj = yaffsfs_FindObject(NULL,path,0); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
838 if(obj) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
839 obj = yaffs_GetEquivalentObject(obj); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
840 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
841 if(!obj) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
842 yaffsfs_SetError(-ENOENT); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
843 else if(obj->variantType != YAFFS_OBJECT_TYPE_FILE) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
844 yaffsfs_SetError(-EISDIR); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
845 else |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
846 result = yaffs_ResizeFile(obj,newSize); |
| 208 | 847 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
848 yaffsfs_Unlock(); |
| 208 | 849 |
| 850 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
851 return (result) ? 0 : -1; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
852 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
853 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
854 int yaffs_ftruncate(int fd, off_t newSize) |
| 1 | 855 { |
| 856 yaffsfs_Handle *h = NULL; | |
| 857 yaffs_Object *obj = NULL; | |
| 858 int result = 0; | |
| 208 | 859 |
| 1 | 860 yaffsfs_Lock(); |
| 861 h = yaffsfs_GetHandlePointer(fd); | |
| 862 obj = yaffsfs_GetHandleObject(fd); | |
| 208 | 863 |
| 1 | 864 if(!h || !obj) |
| 865 // bad handle | |
| 208 | 866 yaffsfs_SetError(-EBADF); |
| 1 | 867 else |
| 868 // resize the file | |
| 869 result = yaffs_ResizeFile(obj,newSize); | |
| 870 yaffsfs_Unlock(); | |
| 208 | 871 |
| 872 | |
| 1 | 873 return (result) ? 0 : -1; |
| 874 | |
| 875 } | |
| 876 | |
| 208 | 877 off_t yaffs_lseek(int fd, off_t offset, int whence) |
| 1 | 878 { |
| 879 yaffsfs_Handle *h = NULL; | |
| 880 yaffs_Object *obj = NULL; | |
| 881 int pos = -1; | |
| 882 int fSize = -1; | |
| 208 | 883 |
| 1 | 884 yaffsfs_Lock(); |
| 885 h = yaffsfs_GetHandlePointer(fd); | |
| 886 obj = yaffsfs_GetHandleObject(fd); | |
| 208 | 887 |
| 1 | 888 if(!h || !obj) |
| 889 // bad handle | |
| 208 | 890 yaffsfs_SetError(-EBADF); |
| 304 | 891 else if(whence == SEEK_SET){ |
| 1 | 892 if(offset >= 0) |
| 893 pos = offset; | |
| 894 } | |
| 304 | 895 else if(whence == SEEK_CUR) { |
| 1 | 896 if( (h->position + offset) >= 0) |
| 897 pos = (h->position + offset); | |
| 898 } | |
| 304 | 899 else if(whence == SEEK_END) { |
| 1 | 900 fSize = yaffs_GetObjectFileLength(obj); |
| 901 if(fSize >= 0 && (fSize + offset) >= 0) | |
| 902 pos = fSize + offset; | |
| 903 } | |
| 208 | 904 |
| 1 | 905 if(pos >= 0) |
| 906 h->position = pos; | |
| 304 | 907 else { |
| 1 | 908 // todo error |
| 909 } | |
| 910 | |
| 208 | 911 |
| 1 | 912 yaffsfs_Unlock(); |
| 208 | 913 |
| 1 | 914 return pos; |
| 915 } | |
| 916 | |
| 917 | |
| 208 | 918 int yaffsfs_DoUnlink(const YCHAR *path,int isDirectory) |
| 1 | 919 { |
| 920 yaffs_Object *dir = NULL; | |
| 921 yaffs_Object *obj = NULL; | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
922 YCHAR *name; |
| 1 | 923 int result = YAFFS_FAIL; |
| 208 | 924 |
| 1 | 925 yaffsfs_Lock(); |
| 926 | |
| 927 obj = yaffsfs_FindObject(NULL,path,0); | |
| 928 dir = yaffsfs_FindDirectory(NULL,path,&name,0); | |
| 929 if(!dir) | |
| 930 yaffsfs_SetError(-ENOTDIR); | |
| 931 else if(!obj) | |
| 932 yaffsfs_SetError(-ENOENT); | |
| 933 else if(!isDirectory && obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) | |
| 934 yaffsfs_SetError(-EISDIR); | |
| 935 else if(isDirectory && obj->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) | |
| 936 yaffsfs_SetError(-ENOTDIR); | |
| 304 | 937 else { |
| 1 | 938 result = yaffs_Unlink(dir,name); |
| 208 | 939 |
| 1 | 940 if(result == YAFFS_FAIL && isDirectory) |
| 941 yaffsfs_SetError(-ENOTEMPTY); | |
| 942 } | |
| 208 | 943 |
| 1 | 944 yaffsfs_Unlock(); |
| 208 | 945 |
| 1 | 946 // todo error |
| 208 | 947 |
| 1 | 948 return (result == YAFFS_FAIL) ? -1 : 0; |
| 949 } | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
950 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
951 |
| 208 | 952 int yaffs_rmdir(const YCHAR *path) |
| 1 | 953 { |
| 954 return yaffsfs_DoUnlink(path,1); | |
| 955 } | |
| 956 | |
| 208 | 957 int yaffs_unlink(const YCHAR *path) |
| 1 | 958 { |
| 959 return yaffsfs_DoUnlink(path,0); | |
| 960 } | |
| 961 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
962 int yaffs_rename(const YCHAR *oldPath, const YCHAR *newPath) |
| 1 | 963 { |
| 964 yaffs_Object *olddir = NULL; | |
| 965 yaffs_Object *newdir = NULL; | |
| 966 yaffs_Object *obj = NULL; | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
967 YCHAR *oldname; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
968 YCHAR *newname; |
| 1 | 969 int result= YAFFS_FAIL; |
| 970 int renameAllowed = 1; | |
| 208 | 971 |
| 1 | 972 yaffsfs_Lock(); |
| 208 | 973 |
| 1 | 974 olddir = yaffsfs_FindDirectory(NULL,oldPath,&oldname,0); |
| 975 newdir = yaffsfs_FindDirectory(NULL,newPath,&newname,0); | |
| 976 obj = yaffsfs_FindObject(NULL,oldPath,0); | |
| 208 | 977 |
| 304 | 978 if(!olddir || !newdir || !obj) { |
| 1 | 979 // bad file |
| 208 | 980 yaffsfs_SetError(-EBADF); |
| 981 renameAllowed = 0; | |
| 304 | 982 } else if(olddir->myDev != newdir->myDev) { |
| 1 | 983 // oops must be on same device |
| 984 // todo error | |
| 985 yaffsfs_SetError(-EXDEV); | |
| 208 | 986 renameAllowed = 0; |
| 304 | 987 } else if(obj && obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) { |
| 208 | 988 // It is a directory, check that it is not being renamed to |
| 1 | 989 // being its own decendent. |
| 990 // Do this by tracing from the new directory back to the root, checking for obj | |
| 208 | 991 |
| 1 | 992 yaffs_Object *xx = newdir; |
| 208 | 993 |
| 304 | 994 while( renameAllowed && xx){ |
| 1 | 995 if(xx == obj) |
| 996 renameAllowed = 0; | |
| 997 xx = xx->parent; | |
| 998 } | |
| 304 | 999 if(!renameAllowed) |
| 1000 yaffsfs_SetError(-EACCES); | |
| 1 | 1001 } |
| 208 | 1002 |
| 1 | 1003 if(renameAllowed) |
| 1004 result = yaffs_RenameObject(olddir,oldname,newdir,newname); | |
| 208 | 1005 |
| 1 | 1006 yaffsfs_Unlock(); |
| 208 | 1007 |
| 1008 return (result == YAFFS_FAIL) ? -1 : 0; | |
| 1 | 1009 } |
| 1010 | |
| 1011 | |
| 1012 static int yaffsfs_DoStat(yaffs_Object *obj,struct yaffs_stat *buf) | |
| 1013 { | |
| 1014 int retVal = -1; | |
| 1015 | |
| 1016 if(obj) | |
| 1017 obj = yaffs_GetEquivalentObject(obj); | |
| 1018 | |
| 304 | 1019 if(obj && buf){ |
| 1020 buf->st_dev = (int)obj->myDev->genericDevice; | |
| 1021 buf->st_ino = obj->objectId; | |
| 1022 buf->st_mode = obj->yst_mode & ~S_IFMT; // clear out file type bits | |
| 208 | 1023 |
| 304 | 1024 if(obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) |
| 1 | 1025 buf->st_mode |= S_IFDIR; |
| 208 | 1026 else if(obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK) |
| 1 | 1027 buf->st_mode |= S_IFLNK; |
| 1028 else if(obj->variantType == YAFFS_OBJECT_TYPE_FILE) | |
| 1029 buf->st_mode |= S_IFREG; | |
| 208 | 1030 |
| 304 | 1031 buf->st_nlink = yaffs_GetObjectLinkCount(obj); |
| 1032 buf->st_uid = 0; | |
| 1033 buf->st_gid = 0;; | |
| 1034 buf->st_rdev = obj->yst_rdev; | |
| 1035 buf->st_size = yaffs_GetObjectFileLength(obj); | |
| 1036 buf->st_blksize = obj->myDev->nDataBytesPerChunk; | |
| 1037 buf->st_blocks = (buf->st_size + buf->st_blksize -1)/buf->st_blksize; | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1038 #if CONFIG_YAFFS_WINCE |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1039 buf->yst_wince_atime[0] = obj->win_atime[0]; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1040 buf->yst_wince_atime[1] = obj->win_atime[1]; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1041 buf->yst_wince_ctime[0] = obj->win_ctime[0]; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1042 buf->yst_wince_ctime[1] = obj->win_ctime[1]; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1043 buf->yst_wince_mtime[0] = obj->win_mtime[0]; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1044 buf->yst_wince_mtime[1] = obj->win_mtime[1]; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1045 #else |
| 304 | 1046 buf->yst_atime = obj->yst_atime; |
| 1047 buf->yst_ctime = obj->yst_ctime; | |
| 1048 buf->yst_mtime = obj->yst_mtime; | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1049 #endif |
| 1 | 1050 retVal = 0; |
| 1051 } | |
| 1052 return retVal; | |
| 1053 } | |
| 1054 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1055 static int yaffsfs_DoStatOrLStat(const YCHAR *path, struct yaffs_stat *buf,int doLStat) |
| 1 | 1056 { |
| 1057 yaffs_Object *obj; | |
| 208 | 1058 |
| 1 | 1059 int retVal = -1; |
| 208 | 1060 |
| 1 | 1061 yaffsfs_Lock(); |
| 1062 obj = yaffsfs_FindObject(NULL,path,0); | |
| 208 | 1063 |
| 1 | 1064 if(!doLStat && obj) |
| 1065 obj = yaffsfs_FollowLink(obj,0); | |
| 208 | 1066 |
| 1 | 1067 if(obj) |
| 1068 retVal = yaffsfs_DoStat(obj,buf); | |
| 1069 else | |
| 1070 // todo error not found | |
| 1071 yaffsfs_SetError(-ENOENT); | |
| 208 | 1072 |
| 1 | 1073 yaffsfs_Unlock(); |
| 208 | 1074 |
| 1 | 1075 return retVal; |
| 208 | 1076 |
| 1 | 1077 } |
| 1078 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1079 int yaffs_stat(const YCHAR *path, struct yaffs_stat *buf) |
| 1 | 1080 { |
| 1081 return yaffsfs_DoStatOrLStat(path,buf,0); | |
| 1082 } | |
| 1083 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1084 int yaffs_lstat(const YCHAR *path, struct yaffs_stat *buf) |
| 1 | 1085 { |
| 1086 return yaffsfs_DoStatOrLStat(path,buf,1); | |
| 1087 } | |
| 1088 | |
| 1089 int yaffs_fstat(int fd, struct yaffs_stat *buf) | |
| 1090 { | |
| 1091 yaffs_Object *obj; | |
| 208 | 1092 |
| 1 | 1093 int retVal = -1; |
| 208 | 1094 |
| 1 | 1095 yaffsfs_Lock(); |
| 1096 obj = yaffsfs_GetHandleObject(fd); | |
| 208 | 1097 |
| 1 | 1098 if(obj) |
| 1099 retVal = yaffsfs_DoStat(obj,buf); | |
| 1100 else | |
| 1101 // bad handle | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1102 yaffsfs_SetError(-EBADF); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1103 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1104 yaffsfs_Unlock(); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1105 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1106 return retVal; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1107 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1108 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1109 #ifdef CONFIG_YAFFS_WINCE |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1110 int yaffs_get_wince_times(int fd, unsigned *wctime, unsigned *watime, unsigned *wmtime) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1111 { |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1112 yaffs_Object *obj; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1113 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1114 int retVal = -1; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1115 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1116 yaffsfs_Lock(); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1117 obj = yaffsfs_GetHandleObject(fd); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1118 |
| 304 | 1119 if(obj){ |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1120 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1121 if(wctime){ |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1122 wctime[0] = obj->win_ctime[0]; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1123 wctime[1] = obj->win_ctime[1]; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1124 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1125 if(watime){ |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1126 watime[0] = obj->win_atime[0]; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1127 watime[1] = obj->win_atime[1]; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1128 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1129 if(wmtime){ |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1130 wmtime[0] = obj->win_mtime[0]; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1131 wmtime[1] = obj->win_mtime[1]; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1132 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1133 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1134 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1135 retVal = 0; |
| 304 | 1136 } else |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1137 // bad handle |
| 1 | 1138 yaffsfs_SetError(-EBADF); |
| 1139 | |
| 1140 yaffsfs_Unlock(); | |
| 1141 | |
| 1142 return retVal; | |
| 1143 } | |
| 1144 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1145 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1146 int yaffs_set_wince_times(int fd, |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1147 const unsigned *wctime, |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1148 const unsigned *watime, |
| 208 | 1149 const unsigned *wmtime) |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1150 { |
| 208 | 1151 yaffs_Object *obj; |
| 1152 int result; | |
| 1153 int retVal = -1; | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1154 |
| 208 | 1155 yaffsfs_Lock(); |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1156 obj = yaffsfs_GetHandleObject(fd); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1157 |
| 304 | 1158 if(obj){ |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1159 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1160 if(wctime){ |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1161 obj->win_ctime[0] = wctime[0]; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1162 obj->win_ctime[1] = wctime[1]; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1163 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1164 if(watime){ |
| 208 | 1165 obj->win_atime[0] = watime[0]; |
| 1166 obj->win_atime[1] = watime[1]; | |
| 1167 } | |
| 1168 if(wmtime){ | |
| 1169 obj->win_mtime[0] = wmtime[0]; | |
| 1170 obj->win_mtime[1] = wmtime[1]; | |
| 1171 } | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1172 |
| 208 | 1173 obj->dirty = 1; |
| 291 | 1174 result = yaffs_FlushFile(obj,0,0); |
| 208 | 1175 retVal = 0; |
| 304 | 1176 } else |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1177 // bad handle |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1178 yaffsfs_SetError(-EBADF); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1179 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1180 yaffsfs_Unlock(); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1181 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1182 return retVal; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1183 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1184 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1185 #endif |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1186 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1187 |
| 1 | 1188 static int yaffsfs_DoChMod(yaffs_Object *obj,mode_t mode) |
| 1189 { | |
| 225 | 1190 int result = -1; |
| 1 | 1191 |
| 1192 if(obj) | |
| 1193 obj = yaffs_GetEquivalentObject(obj); | |
| 208 | 1194 |
| 304 | 1195 if(obj) { |
|
21
68dffdfc2095
Some tinkering on test harness and st_xxx to yst_xxx changes
charles <charles>
parents:
17
diff
changeset
|
1196 obj->yst_mode = mode; |
| 1 | 1197 obj->dirty = 1; |
| 291 | 1198 result = yaffs_FlushFile(obj,0,0); |
| 1 | 1199 } |
| 208 | 1200 |
| 1 | 1201 return result == YAFFS_OK ? 0 : -1; |
| 1202 } | |
| 1203 | |
| 1204 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1205 int yaffs_access(const YCHAR *path, int amode) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1206 { |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1207 yaffs_Object *obj; |
| 208 | 1208 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1209 int retval = 0; |
| 208 | 1210 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1211 yaffsfs_Lock(); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1212 obj = yaffsfs_FindObject(NULL,path,0); |
| 208 | 1213 |
| 304 | 1214 if(obj) { |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1215 int access_ok = 1; |
| 208 | 1216 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1217 if((amode & R_OK) && !(obj->yst_mode & S_IREAD)) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1218 access_ok = 0; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1219 if((amode & W_OK) && !(obj->yst_mode & S_IWRITE)) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1220 access_ok = 0; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1221 if((amode & X_OK) && !(obj->yst_mode & S_IEXEC)) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1222 access_ok = 0; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1223 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1224 if(!access_ok) { |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1225 yaffsfs_SetError(-EACCES); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1226 retval = -1; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1227 } |
| 304 | 1228 } else { |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1229 // todo error not found |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1230 yaffsfs_SetError(-ENOENT); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1231 retval = -1; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1232 } |
| 208 | 1233 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1234 yaffsfs_Unlock(); |
| 208 | 1235 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1236 return retval; |
| 208 | 1237 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1238 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1239 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1240 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1241 int yaffs_chmod(const YCHAR *path, mode_t mode) |
| 1 | 1242 { |
| 1243 yaffs_Object *obj; | |
| 208 | 1244 |
| 1 | 1245 int retVal = -1; |
| 208 | 1246 |
| 1 | 1247 yaffsfs_Lock(); |
| 1248 obj = yaffsfs_FindObject(NULL,path,0); | |
| 208 | 1249 |
| 1 | 1250 if(obj) |
| 1251 retVal = yaffsfs_DoChMod(obj,mode); | |
| 1252 else | |
| 1253 // todo error not found | |
| 1254 yaffsfs_SetError(-ENOENT); | |
| 208 | 1255 |
| 1 | 1256 yaffsfs_Unlock(); |
| 208 | 1257 |
| 1 | 1258 return retVal; |
| 208 | 1259 |
| 1 | 1260 } |
| 1261 | |
| 1262 | |
| 1263 int yaffs_fchmod(int fd, mode_t mode) | |
| 1264 { | |
| 1265 yaffs_Object *obj; | |
| 208 | 1266 |
| 1 | 1267 int retVal = -1; |
| 208 | 1268 |
| 1 | 1269 yaffsfs_Lock(); |
| 1270 obj = yaffsfs_GetHandleObject(fd); | |
| 208 | 1271 |
| 1 | 1272 if(obj) |
| 1273 retVal = yaffsfs_DoChMod(obj,mode); | |
| 1274 else | |
| 1275 // bad handle | |
| 208 | 1276 yaffsfs_SetError(-EBADF); |
| 1277 | |
| 1 | 1278 yaffsfs_Unlock(); |
| 208 | 1279 |
| 1 | 1280 return retVal; |
| 1281 } | |
| 1282 | |
| 1283 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1284 int yaffs_mkdir(const YCHAR *path, mode_t mode) |
| 1 | 1285 { |
| 1286 yaffs_Object *parent = NULL; | |
| 122 | 1287 yaffs_Object *dir = NULL; |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1288 YCHAR *name; |
| 1 | 1289 int retVal= -1; |
| 208 | 1290 |
| 1 | 1291 yaffsfs_Lock(); |
| 1292 parent = yaffsfs_FindDirectory(NULL,path,&name,0); | |
| 122 | 1293 if(parent) |
| 1294 dir = yaffs_MknodDirectory(parent,name,mode,0,0); | |
| 1 | 1295 if(dir) |
| 1296 retVal = 0; | |
| 304 | 1297 else { |
| 1298 if(!parent) | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1299 yaffsfs_SetError(-ENOENT); // missing path |
| 304 | 1300 else if (yaffs_FindObjectByName(parent,name)) |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1301 yaffsfs_SetError(-EEXIST); // the name already exists |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1302 else |
| 208 | 1303 yaffsfs_SetError(-ENOSPC); // just assume no space |
| 1 | 1304 retVal = -1; |
| 1305 } | |
| 208 | 1306 |
| 1 | 1307 yaffsfs_Unlock(); |
| 208 | 1308 |
| 1 | 1309 return retVal; |
| 1310 } | |
| 1311 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1312 int yaffs_mount(const YCHAR *path) |
| 1 | 1313 { |
| 1314 int retVal=-1; | |
| 1315 int result=YAFFS_FAIL; | |
| 1316 yaffs_Device *dev=NULL; | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1317 YCHAR *dummy; |
| 208 | 1318 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1319 T(YAFFS_TRACE_ALWAYS,(TSTR("yaffs: Mounting %s" TENDSTR),path)); |
| 208 | 1320 |
| 1 | 1321 yaffsfs_Lock(); |
| 1322 dev = yaffsfs_FindDevice(path,&dummy); | |
| 304 | 1323 if(dev){ |
| 1324 if(!dev->isMounted){ | |
| 1 | 1325 result = yaffs_GutsInitialise(dev); |
| 1326 if(result == YAFFS_FAIL) | |
| 1327 // todo error - mount failed | |
| 1328 yaffsfs_SetError(-ENOMEM); | |
| 1329 retVal = result ? 0 : -1; | |
| 208 | 1330 |
| 1 | 1331 } |
| 1332 else | |
| 1333 //todo error - already mounted. | |
| 1334 yaffsfs_SetError(-EBUSY); | |
| 304 | 1335 } else |
| 1 | 1336 // todo error - no device |
| 1337 yaffsfs_SetError(-ENODEV); | |
| 304 | 1338 |
| 1 | 1339 yaffsfs_Unlock(); |
| 1340 return retVal; | |
| 208 | 1341 |
| 1 | 1342 } |
| 1343 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1344 int yaffs_sync(const YCHAR *path) |
| 1 | 1345 { |
| 208 | 1346 int retVal=-1; |
| 1347 yaffs_Device *dev=NULL; | |
| 1348 YCHAR *dummy; | |
| 1349 | |
| 1350 yaffsfs_Lock(); | |
| 1351 dev = yaffsfs_FindDevice(path,&dummy); | |
| 304 | 1352 if(dev){ |
| 1353 if(dev->isMounted){ | |
| 208 | 1354 |
| 1355 yaffs_FlushEntireDeviceCache(dev); | |
| 1356 yaffs_CheckpointSave(dev); | |
| 1357 | |
| 1358 | |
| 304 | 1359 } else |
| 208 | 1360 //todo error - not mounted. |
| 1361 yaffsfs_SetError(-EINVAL); | |
| 1362 | |
| 304 | 1363 }else |
| 208 | 1364 // todo error - no device |
| 1365 yaffsfs_SetError(-ENODEV); | |
| 304 | 1366 |
| 208 | 1367 yaffsfs_Unlock(); |
| 1368 return retVal; | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1369 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1370 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1371 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1372 int yaffs_unmount(const YCHAR *path) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1373 { |
| 208 | 1374 int retVal=-1; |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1375 yaffs_Device *dev=NULL; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1376 YCHAR *dummy; |
| 208 | 1377 |
| 1 | 1378 yaffsfs_Lock(); |
| 1379 dev = yaffsfs_FindDevice(path,&dummy); | |
| 304 | 1380 if(dev){ |
| 1381 if(dev->isMounted){ | |
| 1 | 1382 int i; |
| 1383 int inUse; | |
| 208 | 1384 |
| 123 | 1385 yaffs_FlushEntireDeviceCache(dev); |
| 127 | 1386 yaffs_CheckpointSave(dev); |
| 208 | 1387 |
| 304 | 1388 for(i = inUse = 0; i < YAFFSFS_N_HANDLES && !inUse; i++){ |
|
341
89e691a21fd1
Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
charles <charles>
parents:
326
diff
changeset
|
1389 if(yaffsfs_handle[i].inUse && yaffsfs_inode[yaffsfs_handle[i].inodeId].iObj->myDev == dev) |
| 1 | 1390 inUse = 1; // the device is in use, can't unmount |
| 1391 } | |
| 208 | 1392 |
| 304 | 1393 if(!inUse){ |
| 1 | 1394 yaffs_Deinitialise(dev); |
| 208 | 1395 |
| 1 | 1396 retVal = 0; |
| 304 | 1397 } else |
| 1 | 1398 // todo error can't unmount as files are open |
| 1399 yaffsfs_SetError(-EBUSY); | |
| 208 | 1400 |
| 304 | 1401 } else |
| 1 | 1402 //todo error - not mounted. |
| 1403 yaffsfs_SetError(-EINVAL); | |
| 208 | 1404 |
| 1 | 1405 } |
| 1406 else | |
| 1407 // todo error - no device | |
| 1408 yaffsfs_SetError(-ENODEV); | |
| 304 | 1409 |
| 1 | 1410 yaffsfs_Unlock(); |
| 1411 return retVal; | |
| 208 | 1412 |
| 1 | 1413 } |
| 1414 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1415 loff_t yaffs_freespace(const YCHAR *path) |
| 1 | 1416 { |
|
146
1a32267ef1c1
Add large NAND support and improve retirement handling
charles <charles>
parents:
127
diff
changeset
|
1417 loff_t retVal=-1; |
| 1 | 1418 yaffs_Device *dev=NULL; |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1419 YCHAR *dummy; |
| 208 | 1420 |
| 1 | 1421 yaffsfs_Lock(); |
| 1422 dev = yaffsfs_FindDevice(path,&dummy); | |
| 304 | 1423 if(dev && dev->isMounted){ |
| 1 | 1424 retVal = yaffs_GetNumberOfFreeChunks(dev); |
|
146
1a32267ef1c1
Add large NAND support and improve retirement handling
charles <charles>
parents:
127
diff
changeset
|
1425 retVal *= dev->nDataBytesPerChunk; |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1426 |
| 304 | 1427 } else |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1428 yaffsfs_SetError(-EINVAL); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1429 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1430 yaffsfs_Unlock(); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1431 return retVal; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1432 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1433 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1434 loff_t yaffs_totalspace(const YCHAR *path) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1435 { |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1436 loff_t retVal=-1; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1437 yaffs_Device *dev=NULL; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1438 YCHAR *dummy; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1439 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1440 yaffsfs_Lock(); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1441 dev = yaffsfs_FindDevice(path,&dummy); |
| 304 | 1442 if(dev && dev->isMounted){ |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1443 retVal = (dev->endBlock - dev->startBlock + 1) - dev->nReservedBlocks; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1444 retVal *= dev->nChunksPerBlock; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1445 retVal *= dev->nDataBytesPerChunk; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1446 |
| 304 | 1447 } else |
| 1 | 1448 yaffsfs_SetError(-EINVAL); |
| 208 | 1449 |
| 1 | 1450 yaffsfs_Unlock(); |
| 208 | 1451 return retVal; |
| 1 | 1452 } |
| 1453 | |
|
210
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1454 int yaffs_inodecount(const YCHAR *path) |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1455 { |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1456 loff_t retVal= -1; |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1457 yaffs_Device *dev=NULL; |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1458 YCHAR *dummy; |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1459 |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1460 yaffsfs_Lock(); |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1461 dev = yaffsfs_FindDevice(path,&dummy); |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1462 if(dev && dev->isMounted) { |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1463 int nObjects = dev->nObjectsCreated - dev->nFreeObjects; |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1464 if(nObjects > dev->nHardLinks) |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1465 retVal = nObjects - dev->nHardLinks; |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1466 } |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1467 |
| 304 | 1468 if(retVal < 0) |
|
210
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1469 yaffsfs_SetError(-EINVAL); |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1470 |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1471 yaffsfs_Unlock(); |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1472 return retVal; |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1473 } |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1474 |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1475 |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1476 |
| 1 | 1477 void yaffs_initialise(yaffsfs_DeviceConfiguration *cfgList) |
| 1478 { | |
| 208 | 1479 |
| 1 | 1480 yaffsfs_DeviceConfiguration *cfg; |
| 208 | 1481 |
| 1 | 1482 yaffsfs_configurationList = cfgList; |
| 208 | 1483 |
| 1 | 1484 yaffsfs_InitHandles(); |
| 208 | 1485 |
| 1 | 1486 cfg = yaffsfs_configurationList; |
| 208 | 1487 |
| 304 | 1488 while(cfg && cfg->prefix && cfg->dev){ |
| 1 | 1489 cfg->dev->isMounted = 0; |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1490 cfg->dev->removeObjectCallback = yaffsfs_RemoveObjectCallback; |
| 1 | 1491 cfg++; |
| 1492 } | |
| 208 | 1493 |
| 1494 | |
| 1 | 1495 } |
| 1496 | |
| 1497 | |
| 1498 // | |
| 1499 // Directory search stuff. | |
| 1500 | |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1501 // |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1502 // Directory search context |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1503 // |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1504 // NB this is an opaque structure. |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1505 |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1506 |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1507 typedef struct |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1508 { |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1509 __u32 magic; |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1510 yaffs_dirent de; /* directory entry being used by this dsc */ |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1511 YCHAR name[NAME_MAX+1]; /* name of directory being searched */ |
| 208 | 1512 yaffs_Object *dirObj; /* ptr to directory being searched */ |
| 1513 yaffs_Object *nextReturn; /* obj to be returned by next readddir */ | |
| 1514 int offset; | |
| 1515 struct ylist_head others; | |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1516 } yaffsfs_DirectorySearchContext; |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1517 |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1518 |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1519 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1520 static struct ylist_head search_contexts; |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1521 |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1522 |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1523 static void yaffsfs_SetDirRewound(yaffsfs_DirectorySearchContext *dsc) |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1524 { |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1525 if(dsc && |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1526 dsc->dirObj && |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1527 dsc->dirObj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY){ |
| 208 | 1528 |
| 1529 dsc->offset = 0; | |
| 1530 | |
| 304 | 1531 if( ylist_empty(&dsc->dirObj->variant.directoryVariant.children)) |
| 208 | 1532 dsc->nextReturn = NULL; |
| 304 | 1533 else |
| 208 | 1534 dsc->nextReturn = ylist_entry(dsc->dirObj->variant.directoryVariant.children.next, |
| 1535 yaffs_Object,siblings); | |
| 1536 } else { | |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1537 /* Hey someone isn't playing nice! */ |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1538 } |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1539 } |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1540 |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1541 static void yaffsfs_DirAdvance(yaffsfs_DirectorySearchContext *dsc) |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1542 { |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1543 if(dsc && |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1544 dsc->dirObj && |
| 208 | 1545 dsc->dirObj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY){ |
| 1546 | |
| 1547 if( dsc->nextReturn == NULL || | |
| 304 | 1548 ylist_empty(&dsc->dirObj->variant.directoryVariant.children)) |
| 208 | 1549 dsc->nextReturn = NULL; |
| 304 | 1550 else { |
| 208 | 1551 struct ylist_head *next = dsc->nextReturn->siblings.next; |
| 1552 | |
| 1553 if( next == &dsc->dirObj->variant.directoryVariant.children) | |
| 1554 dsc->nextReturn = NULL; /* end of list */ | |
| 1555 else | |
| 1556 dsc->nextReturn = ylist_entry(next,yaffs_Object,siblings); | |
| 1557 } | |
| 1558 } else { | |
| 1559 /* Hey someone isn't playing nice! */ | |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1560 } |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1561 } |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1562 |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1563 static void yaffsfs_RemoveObjectCallback(yaffs_Object *obj) |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1564 { |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1565 |
| 208 | 1566 struct ylist_head *i; |
| 1567 yaffsfs_DirectorySearchContext *dsc; | |
| 1568 | |
| 1569 /* if search contexts not initilised then skip */ | |
| 1570 if(!search_contexts.next) | |
| 1571 return; | |
| 1572 | |
| 1573 /* Iterate through the directory search contexts. | |
| 1574 * If any are the one being removed, then advance the dsc to | |
| 1575 * the next one to prevent a hanging ptr. | |
| 1576 */ | |
| 1577 ylist_for_each(i, &search_contexts) { | |
| 1578 if (i) { | |
| 1579 dsc = ylist_entry(i, yaffsfs_DirectorySearchContext,others); | |
| 1580 if(dsc->nextReturn == obj) | |
| 1581 yaffsfs_DirAdvance(dsc); | |
| 1582 } | |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1583 } |
| 208 | 1584 |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1585 } |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1586 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1587 yaffs_DIR *yaffs_opendir(const YCHAR *dirname) |
| 1 | 1588 { |
| 1589 yaffs_DIR *dir = NULL; | |
| 1590 yaffs_Object *obj = NULL; | |
| 1591 yaffsfs_DirectorySearchContext *dsc = NULL; | |
| 208 | 1592 |
| 1 | 1593 yaffsfs_Lock(); |
| 208 | 1594 |
| 1 | 1595 obj = yaffsfs_FindObject(NULL,dirname,0); |
| 208 | 1596 |
| 304 | 1597 if(obj && obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY){ |
| 208 | 1598 |
| 1 | 1599 dsc = YMALLOC(sizeof(yaffsfs_DirectorySearchContext)); |
| 1600 dir = (yaffs_DIR *)dsc; | |
| 304 | 1601 |
| 1602 if(dsc){ | |
|
91
07a42c94dda5
Improve YDI lookup and device prefic handling
charles <charles>
parents:
81
diff
changeset
|
1603 memset(dsc,0,sizeof(yaffsfs_DirectorySearchContext)); |
| 208 | 1604 dsc->magic = YAFFS_MAGIC; |
| 1605 dsc->dirObj = obj; | |
| 1606 yaffs_strncpy(dsc->name,dirname,NAME_MAX); | |
| 1607 YINIT_LIST_HEAD(&dsc->others); | |
| 1608 | |
| 1609 if(!search_contexts.next) | |
| 1610 YINIT_LIST_HEAD(&search_contexts); | |
| 1611 | |
| 1612 ylist_add(&dsc->others,&search_contexts); | |
| 304 | 1613 yaffsfs_SetDirRewound(dsc); |
| 1614 } | |
| 208 | 1615 |
| 1616 } | |
| 1617 | |
| 1 | 1618 yaffsfs_Unlock(); |
| 208 | 1619 |
| 1 | 1620 return dir; |
| 1621 } | |
| 1622 | |
| 1623 struct yaffs_dirent *yaffs_readdir(yaffs_DIR *dirp) | |
| 1624 { | |
| 1625 yaffsfs_DirectorySearchContext *dsc = (yaffsfs_DirectorySearchContext *)dirp; | |
| 1626 struct yaffs_dirent *retVal = NULL; | |
| 208 | 1627 |
| 1 | 1628 yaffsfs_Lock(); |
| 208 | 1629 |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1630 if(dsc && dsc->magic == YAFFS_MAGIC){ |
| 1 | 1631 yaffsfs_SetError(0); |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1632 if(dsc->nextReturn){ |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1633 dsc->de.d_ino = yaffs_GetEquivalentObject(dsc->nextReturn)->objectId; |
| 151 | 1634 dsc->de.d_dont_use = (unsigned)dsc->nextReturn; |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1635 dsc->de.d_off = dsc->offset++; |
| 151 | 1636 yaffs_GetObjectName(dsc->nextReturn,dsc->de.d_name,NAME_MAX); |
|
326
490a804b7bd3
Change to strnlen() and strncpy() to avoid problems from unbounded strings
charles <charles>
parents:
304
diff
changeset
|
1637 if(yaffs_strnlen(dsc->de.d_name,NAME_MAX+1) == 0) |
| 151 | 1638 { |
| 1639 // this should not happen! | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1640 yaffs_strcpy(dsc->de.d_name,_Y("zz")); |
| 151 | 1641 } |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1642 dsc->de.d_reclen = sizeof(struct yaffs_dirent); |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1643 retVal = &dsc->de; |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1644 yaffsfs_DirAdvance(dsc); |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1645 } else |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1646 retVal = NULL; |
| 304 | 1647 } else |
| 1 | 1648 yaffsfs_SetError(-EBADF); |
| 208 | 1649 |
| 1 | 1650 yaffsfs_Unlock(); |
| 208 | 1651 |
| 1 | 1652 return retVal; |
| 208 | 1653 |
| 1 | 1654 } |
| 1655 | |
| 1656 | |
| 1657 void yaffs_rewinddir(yaffs_DIR *dirp) | |
| 1658 { | |
| 1659 yaffsfs_DirectorySearchContext *dsc = (yaffsfs_DirectorySearchContext *)dirp; | |
| 208 | 1660 |
| 1 | 1661 yaffsfs_Lock(); |
| 208 | 1662 |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1663 yaffsfs_SetDirRewound(dsc); |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1664 |
| 1 | 1665 yaffsfs_Unlock(); |
| 1666 } | |
| 1667 | |
| 1668 | |
| 1669 int yaffs_closedir(yaffs_DIR *dirp) | |
| 1670 { | |
| 1671 yaffsfs_DirectorySearchContext *dsc = (yaffsfs_DirectorySearchContext *)dirp; | |
| 208 | 1672 |
| 1673 yaffsfs_Lock(); | |
| 1674 dsc->magic = 0; | |
| 1675 ylist_del(&dsc->others); /* unhook from list */ | |
| 1676 YFREE(dsc); | |
| 1677 yaffsfs_Unlock(); | |
| 1678 return 0; | |
| 1 | 1679 } |
| 1680 | |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1681 // end of directory stuff |
| 1 | 1682 |
| 1683 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1684 int yaffs_symlink(const YCHAR *oldpath, const YCHAR *newpath) |
| 1 | 1685 { |
| 1686 yaffs_Object *parent = NULL; | |
| 1687 yaffs_Object *obj; | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1688 YCHAR *name; |
| 1 | 1689 int retVal= -1; |
| 1690 int mode = 0; // ignore for now | |
| 208 | 1691 |
| 1 | 1692 yaffsfs_Lock(); |
| 1693 parent = yaffsfs_FindDirectory(NULL,newpath,&name,0); | |
|
269
4107852bb3cd
Change yaffs_DeleteFile to yaffs_DeleteObject and improve symlink handling
charles <charles>
parents:
225
diff
changeset
|
1694 if(parent){ |
|
4107852bb3cd
Change yaffs_DeleteFile to yaffs_DeleteObject and improve symlink handling
charles <charles>
parents:
225
diff
changeset
|
1695 obj = yaffs_MknodSymLink(parent,name,mode,0,0,oldpath); |
|
4107852bb3cd
Change yaffs_DeleteFile to yaffs_DeleteObject and improve symlink handling
charles <charles>
parents:
225
diff
changeset
|
1696 if(obj) |
|
4107852bb3cd
Change yaffs_DeleteFile to yaffs_DeleteObject and improve symlink handling
charles <charles>
parents:
225
diff
changeset
|
1697 retVal = 0; |
| 304 | 1698 else{ |
|
269
4107852bb3cd
Change yaffs_DeleteFile to yaffs_DeleteObject and improve symlink handling
charles <charles>
parents:
225
diff
changeset
|
1699 yaffsfs_SetError(-ENOSPC); // just assume no space for now |
|
4107852bb3cd
Change yaffs_DeleteFile to yaffs_DeleteObject and improve symlink handling
charles <charles>
parents:
225
diff
changeset
|
1700 retVal = -1; |
|
4107852bb3cd
Change yaffs_DeleteFile to yaffs_DeleteObject and improve symlink handling
charles <charles>
parents:
225
diff
changeset
|
1701 } |
|
4107852bb3cd
Change yaffs_DeleteFile to yaffs_DeleteObject and improve symlink handling
charles <charles>
parents:
225
diff
changeset
|
1702 } else { |
|
4107852bb3cd
Change yaffs_DeleteFile to yaffs_DeleteObject and improve symlink handling
charles <charles>
parents:
225
diff
changeset
|
1703 yaffsfs_SetError(-EINVAL); |
| 1 | 1704 retVal = -1; |
| 1705 } | |
| 208 | 1706 |
| 1 | 1707 yaffsfs_Unlock(); |
| 208 | 1708 |
| 1 | 1709 return retVal; |
| 208 | 1710 |
| 1 | 1711 } |
| 1712 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1713 int yaffs_readlink(const YCHAR *path, YCHAR *buf, int bufsiz) |
| 1 | 1714 { |
| 1715 yaffs_Object *obj = NULL; | |
| 1716 int retVal; | |
| 1717 | |
| 208 | 1718 |
| 1 | 1719 yaffsfs_Lock(); |
| 208 | 1720 |
| 1 | 1721 obj = yaffsfs_FindObject(NULL,path,0); |
| 208 | 1722 |
| 304 | 1723 if(!obj) { |
| 1 | 1724 yaffsfs_SetError(-ENOENT); |
| 1725 retVal = -1; | |
| 304 | 1726 } else if(obj->variantType != YAFFS_OBJECT_TYPE_SYMLINK) { |
| 1 | 1727 yaffsfs_SetError(-EINVAL); |
| 1728 retVal = -1; | |
| 304 | 1729 } else { |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1730 YCHAR *alias = obj->variant.symLinkVariant.alias; |
| 1 | 1731 memset(buf,0,bufsiz); |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1732 yaffs_strncpy(buf,alias,bufsiz - 1); |
| 1 | 1733 retVal = 0; |
| 1734 } | |
| 1735 yaffsfs_Unlock(); | |
| 1736 return retVal; | |
| 1737 } | |
| 1738 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1739 int yaffs_link(const YCHAR *oldpath, const YCHAR *newpath) |
| 119 | 1740 { |
| 1741 // Creates a link called newpath to existing oldpath | |
| 1742 yaffs_Object *obj = NULL; | |
| 1743 yaffs_Object *target = NULL; | |
| 125 | 1744 int retVal = 0; |
|
326
490a804b7bd3
Change to strnlen() and strncpy() to avoid problems from unbounded strings
charles <charles>
parents:
304
diff
changeset
|
1745 int newNameLength = 0; |
| 119 | 1746 |
| 208 | 1747 |
| 119 | 1748 yaffsfs_Lock(); |
| 208 | 1749 |
| 119 | 1750 obj = yaffsfs_FindObject(NULL,oldpath,0); |
| 1751 target = yaffsfs_FindObject(NULL,newpath,0); | |
| 208 | 1752 |
| 304 | 1753 if(!obj) { |
| 119 | 1754 yaffsfs_SetError(-ENOENT); |
| 1755 retVal = -1; | |
| 304 | 1756 } else if(target) { |
| 119 | 1757 yaffsfs_SetError(-EEXIST); |
| 1758 retVal = -1; | |
| 304 | 1759 } else { |
| 119 | 1760 yaffs_Object *newdir = NULL; |
| 1761 yaffs_Object *link = NULL; | |
| 208 | 1762 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1763 YCHAR *newname; |
| 208 | 1764 |
| 119 | 1765 newdir = yaffsfs_FindDirectory(NULL,newpath,&newname,0); |
| 208 | 1766 |
| 304 | 1767 if(!newdir){ |
| 119 | 1768 yaffsfs_SetError(-ENOTDIR); |
| 1769 retVal = -1; | |
| 304 | 1770 }else if(newdir->myDev != obj->myDev){ |
| 119 | 1771 yaffsfs_SetError(-EXDEV); |
| 1772 retVal = -1; | |
| 1773 } | |
|
326
490a804b7bd3
Change to strnlen() and strncpy() to avoid problems from unbounded strings
charles <charles>
parents:
304
diff
changeset
|
1774 |
|
490a804b7bd3
Change to strnlen() and strncpy() to avoid problems from unbounded strings
charles <charles>
parents:
304
diff
changeset
|
1775 newNameLength = yaffs_strnlen(newname,YAFFS_MAX_NAME_LENGTH+1); |
|
490a804b7bd3
Change to strnlen() and strncpy() to avoid problems from unbounded strings
charles <charles>
parents:
304
diff
changeset
|
1776 |
|
490a804b7bd3
Change to strnlen() and strncpy() to avoid problems from unbounded strings
charles <charles>
parents:
304
diff
changeset
|
1777 if(newNameLength == 0){ |
|
490a804b7bd3
Change to strnlen() and strncpy() to avoid problems from unbounded strings
charles <charles>
parents:
304
diff
changeset
|
1778 yaffsfs_SetError(-ENOENT); |
|
490a804b7bd3
Change to strnlen() and strncpy() to avoid problems from unbounded strings
charles <charles>
parents:
304
diff
changeset
|
1779 retVal = -1; |
|
490a804b7bd3
Change to strnlen() and strncpy() to avoid problems from unbounded strings
charles <charles>
parents:
304
diff
changeset
|
1780 } else if (newNameLength > YAFFS_MAX_NAME_LENGTH){ |
|
490a804b7bd3
Change to strnlen() and strncpy() to avoid problems from unbounded strings
charles <charles>
parents:
304
diff
changeset
|
1781 yaffsfs_SetError(-ENAMETOOLONG); |
|
490a804b7bd3
Change to strnlen() and strncpy() to avoid problems from unbounded strings
charles <charles>
parents:
304
diff
changeset
|
1782 retVal = -1; |
|
490a804b7bd3
Change to strnlen() and strncpy() to avoid problems from unbounded strings
charles <charles>
parents:
304
diff
changeset
|
1783 } |
|
490a804b7bd3
Change to strnlen() and strncpy() to avoid problems from unbounded strings
charles <charles>
parents:
304
diff
changeset
|
1784 |
|
490a804b7bd3
Change to strnlen() and strncpy() to avoid problems from unbounded strings
charles <charles>
parents:
304
diff
changeset
|
1785 if(retVal == 0) { |
| 119 | 1786 link = yaffs_Link(newdir,newname,obj); |
| 1787 if(link) | |
| 1788 retVal = 0; | |
| 304 | 1789 else{ |
| 119 | 1790 yaffsfs_SetError(-ENOSPC); |
| 1791 retVal = -1; | |
| 1792 } | |
| 1793 | |
| 1794 } | |
| 1795 } | |
| 1796 yaffsfs_Unlock(); | |
| 208 | 1797 |
| 119 | 1798 return retVal; |
| 1799 } | |
| 1800 | |
| 292 | 1801 int yaffs_mknod(const YCHAR *pathname, mode_t mode, dev_t dev) |
| 1802 { | |
| 1803 return -1; | |
| 1804 } | |
| 1 | 1805 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1806 int yaffs_DumpDevStruct(const YCHAR *path) |
| 1 | 1807 { |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1808 #if 0 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1809 YCHAR *rest; |
| 208 | 1810 |
| 1 | 1811 yaffs_Object *obj = yaffsfs_FindRoot(path,&rest); |
| 208 | 1812 |
| 304 | 1813 if(obj){ |
| 1 | 1814 yaffs_Device *dev = obj->myDev; |
| 208 | 1815 |
| 1 | 1816 printf("\n" |
| 1817 "nPageWrites.......... %d\n" | |
| 1818 "nPageReads........... %d\n" | |
| 1819 "nBlockErasures....... %d\n" | |
| 1820 "nGCCopies............ %d\n" | |
| 1821 "garbageCollections... %d\n" | |
| 1822 "passiveGarbageColl'ns %d\n" | |
| 1823 "\n", | |
| 1824 dev->nPageWrites, | |
| 1825 dev->nPageReads, | |
| 1826 dev->nBlockErasures, | |
| 1827 dev->nGCCopies, | |
| 1828 dev->garbageCollections, | |
| 1829 dev->passiveGarbageCollections | |
| 1830 ); | |
| 208 | 1831 |
| 1 | 1832 } |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1833 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1834 #endif |
| 1 | 1835 return 0; |
| 1836 } | |
| 1837 |
