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