Mercurial > yaffs-ecoscentric-gpl
annotate direct/yaffsfs.c @ 356:7ee0cc4ba753
Rationalise context and parameter handling
| author | charles <charles> |
|---|---|
| date | Thu, 18 Feb 2010 01:18:04 +0000 |
| parents | c640f5d8f33e |
| children | 578449a365d7 |
| rev | line source |
|---|---|
| 1 | 1 /* |
| 167 | 2 * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. |
| 1 | 3 * |
| 167 | 4 * Copyright (C) 2002-2007 Aleph One Ltd. |
| 5 * for Toby Churchill Ltd and Brightstar Engineering | |
| 1 | 6 * |
| 7 * Created by Charles Manning <charles@aleph1.co.uk> | |
| 8 * | |
| 9 * This program is free software; you can redistribute it and/or modify | |
| 10 * it under the terms of the GNU General Public License version 2 as | |
| 11 * published by the Free Software Foundation. | |
| 12 */ | |
| 208 | 13 |
| 1 | 14 #include "yaffsfs.h" |
| 15 #include "yaffs_guts.h" | |
| 16 #include "yaffscfg.h" | |
| 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 |
|
356
7ee0cc4ba753
Rationalise context and parameter handling
charles <charles>
parents:
351
diff
changeset
|
34 const char *yaffsfs_c_version="$Id: yaffsfs.c,v 1.34 2010-02-18 01:18:05 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 |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
696 int yaffsfs_do_read(int fd, void *buf, 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; |
| 208 | 706 |
| 1 | 707 yaffsfs_Lock(); |
| 708 h = yaffsfs_GetHandlePointer(fd); | |
| 709 obj = yaffsfs_GetHandleObject(fd); | |
| 208 | 710 |
|
349
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
711 if(!h || !obj){ |
| 1 | 712 // bad handle |
| 208 | 713 yaffsfs_SetError(-EBADF); |
|
349
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
714 totalRead = -1; |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
715 } else if( h && obj){ |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
716 if(isPread) |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
717 startPos = offset; |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
718 else |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
719 startPos = h->position; |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
720 |
| 1 | 721 if(yaffs_GetObjectFileLength(obj) > pos) |
| 722 maxRead = yaffs_GetObjectFileLength(obj) - pos; | |
| 723 else | |
| 724 maxRead = 0; | |
| 725 | |
| 726 if(nbyte > maxRead) | |
| 727 nbyte = maxRead; | |
| 728 | |
| 208 | 729 |
| 304 | 730 if(nbyte > 0) { |
|
349
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
731 yaffsfs_GetHandle(fd); |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
732 pos = startPos; |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
733 |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
734 while(nbyte > 0) { |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
735 nToRead = YAFFSFS_RW_SIZE - (pos & (YAFFSFS_RW_SIZE -1)); |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
736 if(nToRead > nbyte) |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
737 nToRead = nbyte; |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
738 |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
739 nRead = yaffs_ReadDataFromFile(obj,buf,pos,nToRead); |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
740 |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
741 if(nRead > 0){ |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
742 totalRead += nRead; |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
743 pos += nRead; |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
744 buf += nRead; |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
745 } |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
746 |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
747 if(nRead == nToRead) |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
748 nbyte-=nRead; |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
749 else |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
750 nbyte = 0; /* no more to read */ |
|
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 |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
753 if(nbyte > 0){ |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
754 yaffsfs_Unlock(); |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
755 yaffsfs_Lock(); |
|
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 |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
758 } |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
759 |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
760 yaffsfs_PutHandle(fd); |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
761 if(!isPread) { |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
762 if(totalRead >= 0) |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
763 h->position = startPos + totalRead; |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
764 else { |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
765 //todo error |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
766 } |
| 1 | 767 } |
| 304 | 768 } else |
|
349
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
769 totalRead = 0; |
| 208 | 770 |
| 1 | 771 } |
| 208 | 772 |
| 1 | 773 yaffsfs_Unlock(); |
| 208 | 774 |
|
349
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
775 return (totalRead >= 0) ? totalRead : -1; |
| 208 | 776 |
|
349
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
777 } |
| 208 | 778 |
|
349
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
779 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
|
780 { |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
781 return yaffsfs_do_read(fd, buf, nbyte, 0, 0); |
| 1 | 782 } |
| 783 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
784 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
|
785 { |
|
349
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
786 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
|
787 } |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
788 |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
789 int yaffsfs_do_write(int fd, const void *buf, unsigned int nbyte, int isPwrite, int offset) |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
790 { |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
791 yaffsfs_Handle *h = NULL; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
792 yaffs_Object *obj = NULL; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
793 int pos = 0; |
|
349
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
794 int startPos = 0; |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
795 int nWritten = 0; |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
796 int totalWritten = 0; |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
797 int writeThrough = 0; |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
798 int nToWrite = 0; |
| 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; |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
818 if( nbyte > 0){ |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
819 yaffsfs_GetHandle(fd); |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
820 pos = startPos; |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
821 while(nbyte > 0) { |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
822 nToWrite = YAFFSFS_RW_SIZE - (pos & (YAFFSFS_RW_SIZE -1)); |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
823 if(nToWrite > nbyte) |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
824 nToWrite = nbyte; |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
825 |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
826 nWritten = yaffs_WriteDataToFile(obj,buf,pos,nToWrite,writeThrough); |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
827 if(nWritten > 0){ |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
828 totalWritten += nWritten; |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
829 pos += nWritten; |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
830 buf += nWritten; |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
831 } |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
832 |
|
349
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
833 if(nWritten == nToWrite) |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
834 nbyte -= nToWrite; |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
835 else |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
836 nbyte = 0; |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
837 |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
838 if(nWritten < 1 && totalWritten < 1){ |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
839 yaffsfs_SetError(-ENOSPC); |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
840 totalWritten = -1; |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
841 } |
| 208 | 842 |
|
349
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
843 if(nbyte > 0){ |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
844 yaffsfs_Unlock(); |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
845 yaffsfs_Lock(); |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
846 } |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
847 } |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
848 |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
849 yaffsfs_PutHandle(fd); |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
850 |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
851 if(!isPwrite){ |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
852 if(totalWritten > 0) |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
853 h->position = startPos + totalWritten; |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
854 else { |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
855 //todo error |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
856 } |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
857 } |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
858 } else |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
859 totalWritten = 0; |
|
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
860 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
861 } |
| 208 | 862 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
863 yaffsfs_Unlock(); |
| 208 | 864 |
|
349
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
865 return (totalWritten >= 0) ? totalWritten : -1; |
| 208 | 866 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
867 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
868 |
| 1 | 869 int yaffs_write(int fd, const void *buf, unsigned int nbyte) |
| 870 { | |
|
349
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
871 return yaffsfs_do_write(fd, buf, nbyte, 0, 0); |
| 1 | 872 } |
| 873 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
874 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
|
875 { |
|
349
9b5336e51f28
Break up yaffs direct reads and writes to prevent locking with long operations
charles <charles>
parents:
342
diff
changeset
|
876 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
|
877 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
878 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
879 |
| 208 | 880 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
|
881 { |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
882 yaffs_Object *obj = NULL; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
883 int result = YAFFS_FAIL; |
| 208 | 884 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
885 yaffsfs_Lock(); |
|
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 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
|
888 if(obj) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
889 obj = yaffs_GetEquivalentObject(obj); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
890 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
891 if(!obj) |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
892 yaffsfs_SetError(-ENOENT); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
893 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
|
894 yaffsfs_SetError(-EISDIR); |
|
351
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
895 else if(obj->myDev->readOnly) |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
896 yaffsfs_SetError(-EINVAL); |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
897 else |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
898 result = yaffs_ResizeFile(obj,newSize); |
| 208 | 899 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
900 yaffsfs_Unlock(); |
| 208 | 901 |
| 902 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
903 return (result) ? 0 : -1; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
904 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
905 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
906 int yaffs_ftruncate(int fd, off_t newSize) |
| 1 | 907 { |
| 908 yaffsfs_Handle *h = NULL; | |
| 909 yaffs_Object *obj = NULL; | |
| 910 int result = 0; | |
| 208 | 911 |
| 1 | 912 yaffsfs_Lock(); |
| 913 h = yaffsfs_GetHandlePointer(fd); | |
| 914 obj = yaffsfs_GetHandleObject(fd); | |
| 208 | 915 |
| 1 | 916 if(!h || !obj) |
| 917 // bad handle | |
| 208 | 918 yaffsfs_SetError(-EBADF); |
|
351
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
919 else if(obj->myDev->readOnly) |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
920 yaffsfs_SetError(-EINVAL); |
| 1 | 921 else |
| 922 // resize the file | |
| 923 result = yaffs_ResizeFile(obj,newSize); | |
| 924 yaffsfs_Unlock(); | |
| 208 | 925 |
| 926 | |
| 1 | 927 return (result) ? 0 : -1; |
| 928 | |
| 929 } | |
| 930 | |
| 208 | 931 off_t yaffs_lseek(int fd, off_t offset, int whence) |
| 1 | 932 { |
| 933 yaffsfs_Handle *h = NULL; | |
| 934 yaffs_Object *obj = NULL; | |
| 935 int pos = -1; | |
| 936 int fSize = -1; | |
| 208 | 937 |
| 1 | 938 yaffsfs_Lock(); |
| 939 h = yaffsfs_GetHandlePointer(fd); | |
| 940 obj = yaffsfs_GetHandleObject(fd); | |
| 208 | 941 |
| 1 | 942 if(!h || !obj) |
| 943 // bad handle | |
| 208 | 944 yaffsfs_SetError(-EBADF); |
| 304 | 945 else if(whence == SEEK_SET){ |
| 1 | 946 if(offset >= 0) |
| 947 pos = offset; | |
| 948 } | |
| 304 | 949 else if(whence == SEEK_CUR) { |
| 1 | 950 if( (h->position + offset) >= 0) |
| 951 pos = (h->position + offset); | |
| 952 } | |
| 304 | 953 else if(whence == SEEK_END) { |
| 1 | 954 fSize = yaffs_GetObjectFileLength(obj); |
| 955 if(fSize >= 0 && (fSize + offset) >= 0) | |
| 956 pos = fSize + offset; | |
| 957 } | |
| 208 | 958 |
| 1 | 959 if(pos >= 0) |
| 960 h->position = pos; | |
| 304 | 961 else { |
| 1 | 962 // todo error |
| 963 } | |
| 964 | |
| 208 | 965 |
| 1 | 966 yaffsfs_Unlock(); |
| 208 | 967 |
| 1 | 968 return pos; |
| 969 } | |
| 970 | |
| 971 | |
| 208 | 972 int yaffsfs_DoUnlink(const YCHAR *path,int isDirectory) |
| 1 | 973 { |
| 974 yaffs_Object *dir = NULL; | |
| 975 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
|
976 YCHAR *name; |
| 1 | 977 int result = YAFFS_FAIL; |
| 208 | 978 |
| 1 | 979 yaffsfs_Lock(); |
| 980 | |
| 981 obj = yaffsfs_FindObject(NULL,path,0); | |
| 982 dir = yaffsfs_FindDirectory(NULL,path,&name,0); | |
| 983 if(!dir) | |
| 984 yaffsfs_SetError(-ENOTDIR); | |
| 985 else if(!obj) | |
| 986 yaffsfs_SetError(-ENOENT); | |
|
351
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
987 else if(obj->myDev->readOnly) |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
988 yaffsfs_SetError(-EINVAL); |
| 1 | 989 else if(!isDirectory && obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) |
| 990 yaffsfs_SetError(-EISDIR); | |
| 991 else if(isDirectory && obj->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) | |
| 992 yaffsfs_SetError(-ENOTDIR); | |
| 304 | 993 else { |
| 1 | 994 result = yaffs_Unlink(dir,name); |
| 208 | 995 |
| 1 | 996 if(result == YAFFS_FAIL && isDirectory) |
| 997 yaffsfs_SetError(-ENOTEMPTY); | |
| 998 } | |
| 208 | 999 |
| 1 | 1000 yaffsfs_Unlock(); |
| 208 | 1001 |
| 1 | 1002 // todo error |
| 208 | 1003 |
| 1 | 1004 return (result == YAFFS_FAIL) ? -1 : 0; |
| 1005 } | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1006 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1007 |
| 208 | 1008 int yaffs_rmdir(const YCHAR *path) |
| 1 | 1009 { |
| 1010 return yaffsfs_DoUnlink(path,1); | |
| 1011 } | |
| 1012 | |
| 208 | 1013 int yaffs_unlink(const YCHAR *path) |
| 1 | 1014 { |
| 1015 return yaffsfs_DoUnlink(path,0); | |
| 1016 } | |
| 1017 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1018 int yaffs_rename(const YCHAR *oldPath, const YCHAR *newPath) |
| 1 | 1019 { |
| 1020 yaffs_Object *olddir = NULL; | |
| 1021 yaffs_Object *newdir = NULL; | |
| 1022 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
|
1023 YCHAR *oldname; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1024 YCHAR *newname; |
| 1 | 1025 int result= YAFFS_FAIL; |
| 1026 int renameAllowed = 1; | |
| 208 | 1027 |
| 1 | 1028 yaffsfs_Lock(); |
| 208 | 1029 |
| 1 | 1030 olddir = yaffsfs_FindDirectory(NULL,oldPath,&oldname,0); |
| 1031 newdir = yaffsfs_FindDirectory(NULL,newPath,&newname,0); | |
| 1032 obj = yaffsfs_FindObject(NULL,oldPath,0); | |
| 208 | 1033 |
| 304 | 1034 if(!olddir || !newdir || !obj) { |
| 1 | 1035 // bad file |
| 208 | 1036 yaffsfs_SetError(-EBADF); |
| 1037 renameAllowed = 0; | |
|
351
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1038 } else if(obj->myDev->readOnly){ |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1039 yaffsfs_SetError(-EINVAL); |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1040 renameAllowed = 0; |
| 304 | 1041 } else if(olddir->myDev != newdir->myDev) { |
| 1 | 1042 // oops must be on same device |
| 1043 // todo error | |
| 1044 yaffsfs_SetError(-EXDEV); | |
| 208 | 1045 renameAllowed = 0; |
| 304 | 1046 } else if(obj && obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) { |
| 208 | 1047 // It is a directory, check that it is not being renamed to |
| 1 | 1048 // being its own decendent. |
| 1049 // Do this by tracing from the new directory back to the root, checking for obj | |
| 208 | 1050 |
| 1 | 1051 yaffs_Object *xx = newdir; |
| 208 | 1052 |
| 304 | 1053 while( renameAllowed && xx){ |
| 1 | 1054 if(xx == obj) |
| 1055 renameAllowed = 0; | |
| 1056 xx = xx->parent; | |
| 1057 } | |
| 304 | 1058 if(!renameAllowed) |
| 1059 yaffsfs_SetError(-EACCES); | |
| 1 | 1060 } |
| 208 | 1061 |
| 1 | 1062 if(renameAllowed) |
| 1063 result = yaffs_RenameObject(olddir,oldname,newdir,newname); | |
| 208 | 1064 |
| 1 | 1065 yaffsfs_Unlock(); |
| 208 | 1066 |
| 1067 return (result == YAFFS_FAIL) ? -1 : 0; | |
| 1 | 1068 } |
| 1069 | |
| 1070 | |
| 1071 static int yaffsfs_DoStat(yaffs_Object *obj,struct yaffs_stat *buf) | |
| 1072 { | |
| 1073 int retVal = -1; | |
| 1074 | |
| 1075 if(obj) | |
| 1076 obj = yaffs_GetEquivalentObject(obj); | |
| 1077 | |
| 304 | 1078 if(obj && buf){ |
|
356
7ee0cc4ba753
Rationalise context and parameter handling
charles <charles>
parents:
351
diff
changeset
|
1079 buf->st_dev = (int)obj->myDev->context; |
| 304 | 1080 buf->st_ino = obj->objectId; |
| 1081 buf->st_mode = obj->yst_mode & ~S_IFMT; // clear out file type bits | |
| 208 | 1082 |
| 304 | 1083 if(obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) |
| 1 | 1084 buf->st_mode |= S_IFDIR; |
| 208 | 1085 else if(obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK) |
| 1 | 1086 buf->st_mode |= S_IFLNK; |
| 1087 else if(obj->variantType == YAFFS_OBJECT_TYPE_FILE) | |
| 1088 buf->st_mode |= S_IFREG; | |
| 208 | 1089 |
| 304 | 1090 buf->st_nlink = yaffs_GetObjectLinkCount(obj); |
| 1091 buf->st_uid = 0; | |
| 1092 buf->st_gid = 0;; | |
| 1093 buf->st_rdev = obj->yst_rdev; | |
| 1094 buf->st_size = yaffs_GetObjectFileLength(obj); | |
| 1095 buf->st_blksize = obj->myDev->nDataBytesPerChunk; | |
| 1096 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
|
1097 #if CONFIG_YAFFS_WINCE |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1098 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
|
1099 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
|
1100 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
|
1101 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
|
1102 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
|
1103 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
|
1104 #else |
| 304 | 1105 buf->yst_atime = obj->yst_atime; |
| 1106 buf->yst_ctime = obj->yst_ctime; | |
| 1107 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
|
1108 #endif |
| 1 | 1109 retVal = 0; |
| 1110 } | |
| 1111 return retVal; | |
| 1112 } | |
| 1113 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1114 static int yaffsfs_DoStatOrLStat(const YCHAR *path, struct yaffs_stat *buf,int doLStat) |
| 1 | 1115 { |
| 1116 yaffs_Object *obj; | |
| 208 | 1117 |
| 1 | 1118 int retVal = -1; |
| 208 | 1119 |
| 1 | 1120 yaffsfs_Lock(); |
| 1121 obj = yaffsfs_FindObject(NULL,path,0); | |
| 208 | 1122 |
| 1 | 1123 if(!doLStat && obj) |
| 1124 obj = yaffsfs_FollowLink(obj,0); | |
| 208 | 1125 |
| 1 | 1126 if(obj) |
| 1127 retVal = yaffsfs_DoStat(obj,buf); | |
| 1128 else | |
| 1129 // todo error not found | |
| 1130 yaffsfs_SetError(-ENOENT); | |
| 208 | 1131 |
| 1 | 1132 yaffsfs_Unlock(); |
| 208 | 1133 |
| 1 | 1134 return retVal; |
| 208 | 1135 |
| 1 | 1136 } |
| 1137 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1138 int yaffs_stat(const YCHAR *path, struct yaffs_stat *buf) |
| 1 | 1139 { |
| 1140 return yaffsfs_DoStatOrLStat(path,buf,0); | |
| 1141 } | |
| 1142 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1143 int yaffs_lstat(const YCHAR *path, struct yaffs_stat *buf) |
| 1 | 1144 { |
| 1145 return yaffsfs_DoStatOrLStat(path,buf,1); | |
| 1146 } | |
| 1147 | |
| 1148 int yaffs_fstat(int fd, struct yaffs_stat *buf) | |
| 1149 { | |
| 1150 yaffs_Object *obj; | |
| 208 | 1151 |
| 1 | 1152 int retVal = -1; |
| 208 | 1153 |
| 1 | 1154 yaffsfs_Lock(); |
| 1155 obj = yaffsfs_GetHandleObject(fd); | |
| 208 | 1156 |
| 1 | 1157 if(obj) |
| 1158 retVal = yaffsfs_DoStat(obj,buf); | |
| 1159 else | |
| 1160 // bad handle | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1161 yaffsfs_SetError(-EBADF); |
|
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 yaffsfs_Unlock(); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1164 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1165 return retVal; |
|
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 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1168 #ifdef CONFIG_YAFFS_WINCE |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1169 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
|
1170 { |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1171 yaffs_Object *obj; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1172 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1173 int retVal = -1; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1174 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1175 yaffsfs_Lock(); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1176 obj = yaffsfs_GetHandleObject(fd); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1177 |
| 304 | 1178 if(obj){ |
|
204
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(wctime){ |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1181 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
|
1182 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
|
1183 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1184 if(watime){ |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1185 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
|
1186 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
|
1187 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1188 if(wmtime){ |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1189 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
|
1190 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
|
1191 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1192 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1193 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1194 retVal = 0; |
| 304 | 1195 } else |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1196 // bad handle |
| 1 | 1197 yaffsfs_SetError(-EBADF); |
| 1198 | |
| 1199 yaffsfs_Unlock(); | |
| 1200 | |
| 1201 return retVal; | |
| 1202 } | |
| 1203 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1204 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1205 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
|
1206 const unsigned *wctime, |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1207 const unsigned *watime, |
| 208 | 1208 const unsigned *wmtime) |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1209 { |
| 208 | 1210 yaffs_Object *obj; |
| 1211 int result; | |
| 1212 int retVal = -1; | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1213 |
| 208 | 1214 yaffsfs_Lock(); |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1215 obj = yaffsfs_GetHandleObject(fd); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1216 |
| 304 | 1217 if(obj){ |
|
204
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(wctime){ |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1220 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
|
1221 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
|
1222 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1223 if(watime){ |
| 208 | 1224 obj->win_atime[0] = watime[0]; |
| 1225 obj->win_atime[1] = watime[1]; | |
| 1226 } | |
| 1227 if(wmtime){ | |
| 1228 obj->win_mtime[0] = wmtime[0]; | |
| 1229 obj->win_mtime[1] = wmtime[1]; | |
| 1230 } | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1231 |
| 208 | 1232 obj->dirty = 1; |
| 291 | 1233 result = yaffs_FlushFile(obj,0,0); |
| 208 | 1234 retVal = 0; |
| 304 | 1235 } else |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1236 // bad handle |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1237 yaffsfs_SetError(-EBADF); |
|
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 yaffsfs_Unlock(); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1240 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1241 return retVal; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1242 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1243 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1244 #endif |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1245 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1246 |
| 1 | 1247 static int yaffsfs_DoChMod(yaffs_Object *obj,mode_t mode) |
| 1248 { | |
| 225 | 1249 int result = -1; |
| 1 | 1250 |
| 1251 if(obj) | |
| 1252 obj = yaffs_GetEquivalentObject(obj); | |
| 208 | 1253 |
| 304 | 1254 if(obj) { |
|
21
68dffdfc2095
Some tinkering on test harness and st_xxx to yst_xxx changes
charles <charles>
parents:
17
diff
changeset
|
1255 obj->yst_mode = mode; |
| 1 | 1256 obj->dirty = 1; |
| 291 | 1257 result = yaffs_FlushFile(obj,0,0); |
| 1 | 1258 } |
| 208 | 1259 |
| 1 | 1260 return result == YAFFS_OK ? 0 : -1; |
| 1261 } | |
| 1262 | |
| 1263 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1264 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
|
1265 { |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1266 yaffs_Object *obj; |
| 208 | 1267 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1268 int retval = 0; |
| 208 | 1269 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1270 yaffsfs_Lock(); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1271 obj = yaffsfs_FindObject(NULL,path,0); |
| 208 | 1272 |
| 304 | 1273 if(obj) { |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1274 int access_ok = 1; |
| 208 | 1275 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1276 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
|
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 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
|
1279 access_ok = 0; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1280 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
|
1281 access_ok = 0; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1282 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1283 if(!access_ok) { |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1284 yaffsfs_SetError(-EACCES); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1285 retval = -1; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1286 } |
| 304 | 1287 } else { |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1288 // todo error not found |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1289 yaffsfs_SetError(-ENOENT); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1290 retval = -1; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1291 } |
| 208 | 1292 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1293 yaffsfs_Unlock(); |
| 208 | 1294 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1295 return retval; |
| 208 | 1296 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1297 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1298 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1299 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1300 int yaffs_chmod(const YCHAR *path, mode_t mode) |
| 1 | 1301 { |
| 1302 yaffs_Object *obj; | |
| 208 | 1303 |
| 1 | 1304 int retVal = -1; |
| 208 | 1305 |
| 1 | 1306 yaffsfs_Lock(); |
| 1307 obj = yaffsfs_FindObject(NULL,path,0); | |
| 208 | 1308 |
|
351
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1309 if(!obj) |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1310 yaffsfs_SetError(-ENOENT); |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1311 else if(obj->myDev->readOnly) |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1312 yaffsfs_SetError(-EINVAL); |
| 1 | 1313 else |
|
351
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1314 retVal = yaffsfs_DoChMod(obj,mode); |
| 208 | 1315 |
| 1 | 1316 yaffsfs_Unlock(); |
| 208 | 1317 |
| 1 | 1318 return retVal; |
| 208 | 1319 |
| 1 | 1320 } |
| 1321 | |
| 1322 | |
| 1323 int yaffs_fchmod(int fd, mode_t mode) | |
| 1324 { | |
| 1325 yaffs_Object *obj; | |
| 208 | 1326 |
| 1 | 1327 int retVal = -1; |
| 208 | 1328 |
| 1 | 1329 yaffsfs_Lock(); |
| 1330 obj = yaffsfs_GetHandleObject(fd); | |
| 208 | 1331 |
|
351
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1332 if(!obj) |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1333 yaffsfs_SetError(-ENOENT); |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1334 else if(obj->myDev->readOnly) |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1335 yaffsfs_SetError(-EINVAL); |
| 1 | 1336 else |
|
351
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1337 retVal = yaffsfs_DoChMod(obj,mode); |
| 208 | 1338 |
| 1 | 1339 yaffsfs_Unlock(); |
| 208 | 1340 |
| 1 | 1341 return retVal; |
| 1342 } | |
| 1343 | |
| 1344 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1345 int yaffs_mkdir(const YCHAR *path, mode_t mode) |
| 1 | 1346 { |
| 1347 yaffs_Object *parent = NULL; | |
| 122 | 1348 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
|
1349 YCHAR *name; |
| 1 | 1350 int retVal= -1; |
| 208 | 1351 |
| 1 | 1352 yaffsfs_Lock(); |
| 1353 parent = yaffsfs_FindDirectory(NULL,path,&name,0); | |
|
351
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1354 if(parent && parent->myDev->readOnly){ |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1355 yaffsfs_SetError(-EINVAL); |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1356 } else { |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1357 if(parent) |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1358 dir = yaffs_MknodDirectory(parent,name,mode,0,0); |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1359 if(dir) |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1360 retVal = 0; |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1361 else { |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1362 if(!parent) |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1363 yaffsfs_SetError(-ENOENT); // missing path |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1364 else if (yaffs_FindObjectByName(parent,name)) |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1365 yaffsfs_SetError(-EEXIST); // the name already exists |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1366 else |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1367 yaffsfs_SetError(-ENOSPC); // just assume no space |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1368 retVal = -1; |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1369 } |
| 1 | 1370 } |
| 208 | 1371 |
| 1 | 1372 yaffsfs_Unlock(); |
| 208 | 1373 |
| 1 | 1374 return retVal; |
| 1375 } | |
| 1376 | |
|
351
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1377 int yaffs_mount2(const YCHAR *path,int readOnly) |
| 1 | 1378 { |
| 1379 int retVal=-1; | |
| 1380 int result=YAFFS_FAIL; | |
| 1381 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
|
1382 YCHAR *dummy; |
| 208 | 1383 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1384 T(YAFFS_TRACE_ALWAYS,(TSTR("yaffs: Mounting %s" TENDSTR),path)); |
| 208 | 1385 |
| 1 | 1386 yaffsfs_Lock(); |
| 1387 dev = yaffsfs_FindDevice(path,&dummy); | |
| 304 | 1388 if(dev){ |
| 1389 if(!dev->isMounted){ | |
|
351
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1390 dev->readOnly = readOnly ? 1 : 0; |
| 1 | 1391 result = yaffs_GutsInitialise(dev); |
| 1392 if(result == YAFFS_FAIL) | |
| 1393 // todo error - mount failed | |
| 1394 yaffsfs_SetError(-ENOMEM); | |
| 1395 retVal = result ? 0 : -1; | |
| 208 | 1396 |
| 1 | 1397 } |
| 1398 else | |
| 1399 //todo error - already mounted. | |
| 1400 yaffsfs_SetError(-EBUSY); | |
| 304 | 1401 } else |
| 1 | 1402 // todo error - no device |
| 1403 yaffsfs_SetError(-ENODEV); | |
| 304 | 1404 |
| 1 | 1405 yaffsfs_Unlock(); |
| 1406 return retVal; | |
| 208 | 1407 |
| 1 | 1408 } |
| 1409 | |
|
351
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1410 int yaffs_mount(const YCHAR *path) |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1411 { |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1412 return yaffs_mount2(path,0); |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1413 } |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1414 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1415 int yaffs_sync(const YCHAR *path) |
| 1 | 1416 { |
| 208 | 1417 int retVal=-1; |
| 1418 yaffs_Device *dev=NULL; | |
| 1419 YCHAR *dummy; | |
| 1420 | |
| 1421 yaffsfs_Lock(); | |
| 1422 dev = yaffsfs_FindDevice(path,&dummy); | |
| 304 | 1423 if(dev){ |
| 1424 if(dev->isMounted){ | |
| 208 | 1425 |
| 1426 yaffs_FlushEntireDeviceCache(dev); | |
| 1427 yaffs_CheckpointSave(dev); | |
| 1428 | |
| 1429 | |
| 304 | 1430 } else |
| 208 | 1431 //todo error - not mounted. |
| 1432 yaffsfs_SetError(-EINVAL); | |
| 1433 | |
| 304 | 1434 }else |
| 208 | 1435 // todo error - no device |
| 1436 yaffsfs_SetError(-ENODEV); | |
| 304 | 1437 |
| 208 | 1438 yaffsfs_Unlock(); |
| 1439 return retVal; | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1440 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1441 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1442 |
|
351
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1443 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
|
1444 { |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1445 int retVal=-1; |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1446 yaffs_Device *dev=NULL; |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1447 YCHAR *dummy; |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1448 |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1449 yaffsfs_Lock(); |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1450 dev = yaffsfs_FindDevice(path,&dummy); |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1451 if(dev){ |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1452 if(dev->isMounted){ |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1453 int i; |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1454 int inUse; |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1455 |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1456 yaffs_FlushEntireDeviceCache(dev); |
|
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 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
|
1459 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
|
1460 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
|
1461 } |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1462 |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1463 if(!inUse || force){ |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1464 if(readOnly) |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1465 yaffs_CheckpointSave(dev); |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1466 dev->readOnly = readOnly ? 1 : 0; |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1467 retVal = 0; |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1468 } else |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1469 yaffsfs_SetError(-EBUSY); |
|
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(-EINVAL); |
|
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 } |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1475 else |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1476 yaffsfs_SetError(-ENODEV); |
|
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 yaffsfs_Unlock(); |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1479 return retVal; |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1480 |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1481 } |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1482 |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1483 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
|
1484 { |
| 208 | 1485 int retVal=-1; |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1486 yaffs_Device *dev=NULL; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1487 YCHAR *dummy; |
| 208 | 1488 |
| 1 | 1489 yaffsfs_Lock(); |
| 1490 dev = yaffsfs_FindDevice(path,&dummy); | |
| 304 | 1491 if(dev){ |
| 1492 if(dev->isMounted){ | |
| 1 | 1493 int i; |
| 1494 int inUse; | |
| 208 | 1495 |
| 123 | 1496 yaffs_FlushEntireDeviceCache(dev); |
| 127 | 1497 yaffs_CheckpointSave(dev); |
| 208 | 1498 |
| 304 | 1499 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
|
1500 if(yaffsfs_handle[i].useCount > 0 && yaffsfs_inode[yaffsfs_handle[i].inodeId].iObj->myDev == dev) |
| 1 | 1501 inUse = 1; // the device is in use, can't unmount |
| 1502 } | |
| 208 | 1503 |
|
351
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1504 if(!inUse || force){ |
| 1 | 1505 yaffs_Deinitialise(dev); |
| 208 | 1506 |
| 1 | 1507 retVal = 0; |
| 304 | 1508 } else |
| 1 | 1509 // todo error can't unmount as files are open |
| 1510 yaffsfs_SetError(-EBUSY); | |
| 208 | 1511 |
| 304 | 1512 } else |
| 1 | 1513 //todo error - not mounted. |
| 1514 yaffsfs_SetError(-EINVAL); | |
| 208 | 1515 |
| 1 | 1516 } |
| 1517 else | |
| 1518 // todo error - no device | |
| 1519 yaffsfs_SetError(-ENODEV); | |
| 304 | 1520 |
| 1 | 1521 yaffsfs_Unlock(); |
| 1522 return retVal; | |
| 208 | 1523 |
| 1 | 1524 } |
| 1525 | |
|
351
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1526 int yaffs_unmount(const YCHAR *path) |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1527 { |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1528 return yaffs_unmount2(path,0); |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1529 } |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1530 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1531 loff_t yaffs_freespace(const YCHAR *path) |
| 1 | 1532 { |
|
146
1a32267ef1c1
Add large NAND support and improve retirement handling
charles <charles>
parents:
127
diff
changeset
|
1533 loff_t retVal=-1; |
| 1 | 1534 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
|
1535 YCHAR *dummy; |
| 208 | 1536 |
| 1 | 1537 yaffsfs_Lock(); |
| 1538 dev = yaffsfs_FindDevice(path,&dummy); | |
| 304 | 1539 if(dev && dev->isMounted){ |
| 1 | 1540 retVal = yaffs_GetNumberOfFreeChunks(dev); |
|
146
1a32267ef1c1
Add large NAND support and improve retirement handling
charles <charles>
parents:
127
diff
changeset
|
1541 retVal *= dev->nDataBytesPerChunk; |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1542 |
| 304 | 1543 } else |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1544 yaffsfs_SetError(-EINVAL); |
|
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 yaffsfs_Unlock(); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1547 return retVal; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1548 } |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1549 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1550 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
|
1551 { |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1552 loff_t retVal=-1; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1553 yaffs_Device *dev=NULL; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1554 YCHAR *dummy; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1555 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1556 yaffsfs_Lock(); |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1557 dev = yaffsfs_FindDevice(path,&dummy); |
| 304 | 1558 if(dev && dev->isMounted){ |
|
356
7ee0cc4ba753
Rationalise context and parameter handling
charles <charles>
parents:
351
diff
changeset
|
1559 retVal = (dev->param.endBlock - dev->param.startBlock + 1) - dev->param.nReservedBlocks; |
|
7ee0cc4ba753
Rationalise context and parameter handling
charles <charles>
parents:
351
diff
changeset
|
1560 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
|
1561 retVal *= dev->nDataBytesPerChunk; |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1562 |
| 304 | 1563 } else |
| 1 | 1564 yaffsfs_SetError(-EINVAL); |
| 208 | 1565 |
| 1 | 1566 yaffsfs_Unlock(); |
| 208 | 1567 return retVal; |
| 1 | 1568 } |
| 1569 | |
|
210
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1570 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
|
1571 { |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1572 loff_t retVal= -1; |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1573 yaffs_Device *dev=NULL; |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1574 YCHAR *dummy; |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1575 |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1576 yaffsfs_Lock(); |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1577 dev = yaffsfs_FindDevice(path,&dummy); |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1578 if(dev && dev->isMounted) { |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1579 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
|
1580 if(nObjects > dev->nHardLinks) |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1581 retVal = nObjects - dev->nHardLinks; |
|
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 |
| 304 | 1584 if(retVal < 0) |
|
210
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1585 yaffsfs_SetError(-EINVAL); |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1586 |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1587 yaffsfs_Unlock(); |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1588 return retVal; |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1589 } |
|
8a4f31e59ad8
Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
charles <charles>
parents:
208
diff
changeset
|
1590 |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1591 |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1592 |
| 1 | 1593 void yaffs_initialise(yaffsfs_DeviceConfiguration *cfgList) |
| 1594 { | |
| 208 | 1595 |
| 1 | 1596 yaffsfs_DeviceConfiguration *cfg; |
| 208 | 1597 |
| 1 | 1598 yaffsfs_configurationList = cfgList; |
| 208 | 1599 |
| 1 | 1600 yaffsfs_InitHandles(); |
| 208 | 1601 |
| 1 | 1602 cfg = yaffsfs_configurationList; |
| 208 | 1603 |
| 304 | 1604 while(cfg && cfg->prefix && cfg->dev){ |
| 1 | 1605 cfg->dev->isMounted = 0; |
|
356
7ee0cc4ba753
Rationalise context and parameter handling
charles <charles>
parents:
351
diff
changeset
|
1606 cfg->dev->param.removeObjectCallback = yaffsfs_RemoveObjectCallback; |
| 1 | 1607 cfg++; |
| 1608 } | |
| 208 | 1609 |
| 1610 | |
| 1 | 1611 } |
| 1612 | |
| 1613 | |
| 1614 // | |
| 1615 // Directory search stuff. | |
| 1616 | |
|
81
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 // Directory search context |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1619 // |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1620 // NB this is an opaque structure. |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1621 |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1622 |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1623 typedef struct |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1624 { |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1625 __u32 magic; |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1626 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
|
1627 YCHAR name[NAME_MAX+1]; /* name of directory being searched */ |
| 208 | 1628 yaffs_Object *dirObj; /* ptr to directory being searched */ |
| 1629 yaffs_Object *nextReturn; /* obj to be returned by next readddir */ | |
| 1630 int offset; | |
| 1631 struct ylist_head others; | |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1632 } yaffsfs_DirectorySearchContext; |
|
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 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1636 static struct ylist_head search_contexts; |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1637 |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1638 |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1639 static void yaffsfs_SetDirRewound(yaffsfs_DirectorySearchContext *dsc) |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1640 { |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1641 if(dsc && |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1642 dsc->dirObj && |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1643 dsc->dirObj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY){ |
| 208 | 1644 |
| 1645 dsc->offset = 0; | |
| 1646 | |
| 304 | 1647 if( ylist_empty(&dsc->dirObj->variant.directoryVariant.children)) |
| 208 | 1648 dsc->nextReturn = NULL; |
| 304 | 1649 else |
| 208 | 1650 dsc->nextReturn = ylist_entry(dsc->dirObj->variant.directoryVariant.children.next, |
| 1651 yaffs_Object,siblings); | |
| 1652 } else { | |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1653 /* Hey someone isn't playing nice! */ |
|
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 } |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1656 |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1657 static void yaffsfs_DirAdvance(yaffsfs_DirectorySearchContext *dsc) |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1658 { |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1659 if(dsc && |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1660 dsc->dirObj && |
| 208 | 1661 dsc->dirObj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY){ |
| 1662 | |
| 1663 if( dsc->nextReturn == NULL || | |
| 304 | 1664 ylist_empty(&dsc->dirObj->variant.directoryVariant.children)) |
| 208 | 1665 dsc->nextReturn = NULL; |
| 304 | 1666 else { |
| 208 | 1667 struct ylist_head *next = dsc->nextReturn->siblings.next; |
| 1668 | |
| 1669 if( next == &dsc->dirObj->variant.directoryVariant.children) | |
| 1670 dsc->nextReturn = NULL; /* end of list */ | |
| 1671 else | |
| 1672 dsc->nextReturn = ylist_entry(next,yaffs_Object,siblings); | |
| 1673 } | |
| 1674 } else { | |
| 1675 /* Hey someone isn't playing nice! */ | |
|
81
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 } |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1678 |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1679 static void yaffsfs_RemoveObjectCallback(yaffs_Object *obj) |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1680 { |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1681 |
| 208 | 1682 struct ylist_head *i; |
| 1683 yaffsfs_DirectorySearchContext *dsc; | |
| 1684 | |
| 1685 /* if search contexts not initilised then skip */ | |
| 1686 if(!search_contexts.next) | |
| 1687 return; | |
| 1688 | |
| 1689 /* Iterate through the directory search contexts. | |
| 1690 * If any are the one being removed, then advance the dsc to | |
| 1691 * the next one to prevent a hanging ptr. | |
| 1692 */ | |
| 1693 ylist_for_each(i, &search_contexts) { | |
| 1694 if (i) { | |
| 1695 dsc = ylist_entry(i, yaffsfs_DirectorySearchContext,others); | |
| 1696 if(dsc->nextReturn == obj) | |
| 1697 yaffsfs_DirAdvance(dsc); | |
| 1698 } | |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1699 } |
| 208 | 1700 |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1701 } |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1702 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1703 yaffs_DIR *yaffs_opendir(const YCHAR *dirname) |
| 1 | 1704 { |
| 1705 yaffs_DIR *dir = NULL; | |
| 1706 yaffs_Object *obj = NULL; | |
| 1707 yaffsfs_DirectorySearchContext *dsc = NULL; | |
| 208 | 1708 |
| 1 | 1709 yaffsfs_Lock(); |
| 208 | 1710 |
| 1 | 1711 obj = yaffsfs_FindObject(NULL,dirname,0); |
| 208 | 1712 |
| 304 | 1713 if(obj && obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY){ |
| 208 | 1714 |
| 1 | 1715 dsc = YMALLOC(sizeof(yaffsfs_DirectorySearchContext)); |
| 1716 dir = (yaffs_DIR *)dsc; | |
| 304 | 1717 |
| 1718 if(dsc){ | |
|
91
07a42c94dda5
Improve YDI lookup and device prefic handling
charles <charles>
parents:
81
diff
changeset
|
1719 memset(dsc,0,sizeof(yaffsfs_DirectorySearchContext)); |
| 208 | 1720 dsc->magic = YAFFS_MAGIC; |
| 1721 dsc->dirObj = obj; | |
| 1722 yaffs_strncpy(dsc->name,dirname,NAME_MAX); | |
| 1723 YINIT_LIST_HEAD(&dsc->others); | |
| 1724 | |
| 1725 if(!search_contexts.next) | |
| 1726 YINIT_LIST_HEAD(&search_contexts); | |
| 1727 | |
| 1728 ylist_add(&dsc->others,&search_contexts); | |
| 304 | 1729 yaffsfs_SetDirRewound(dsc); |
| 1730 } | |
| 208 | 1731 |
| 1732 } | |
| 1733 | |
| 1 | 1734 yaffsfs_Unlock(); |
| 208 | 1735 |
| 1 | 1736 return dir; |
| 1737 } | |
| 1738 | |
| 1739 struct yaffs_dirent *yaffs_readdir(yaffs_DIR *dirp) | |
| 1740 { | |
| 1741 yaffsfs_DirectorySearchContext *dsc = (yaffsfs_DirectorySearchContext *)dirp; | |
| 1742 struct yaffs_dirent *retVal = NULL; | |
| 208 | 1743 |
| 1 | 1744 yaffsfs_Lock(); |
| 208 | 1745 |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1746 if(dsc && dsc->magic == YAFFS_MAGIC){ |
| 1 | 1747 yaffsfs_SetError(0); |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1748 if(dsc->nextReturn){ |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1749 dsc->de.d_ino = yaffs_GetEquivalentObject(dsc->nextReturn)->objectId; |
| 151 | 1750 dsc->de.d_dont_use = (unsigned)dsc->nextReturn; |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1751 dsc->de.d_off = dsc->offset++; |
| 151 | 1752 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
|
1753 if(yaffs_strnlen(dsc->de.d_name,NAME_MAX+1) == 0) |
| 151 | 1754 { |
| 1755 // 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
|
1756 yaffs_strcpy(dsc->de.d_name,_Y("zz")); |
| 151 | 1757 } |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1758 dsc->de.d_reclen = sizeof(struct yaffs_dirent); |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1759 retVal = &dsc->de; |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1760 yaffsfs_DirAdvance(dsc); |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1761 } else |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1762 retVal = NULL; |
| 304 | 1763 } else |
| 1 | 1764 yaffsfs_SetError(-EBADF); |
| 208 | 1765 |
| 1 | 1766 yaffsfs_Unlock(); |
| 208 | 1767 |
| 1 | 1768 return retVal; |
| 208 | 1769 |
| 1 | 1770 } |
| 1771 | |
| 1772 | |
| 1773 void yaffs_rewinddir(yaffs_DIR *dirp) | |
| 1774 { | |
| 1775 yaffsfs_DirectorySearchContext *dsc = (yaffsfs_DirectorySearchContext *)dirp; | |
| 208 | 1776 |
| 1 | 1777 yaffsfs_Lock(); |
| 208 | 1778 |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1779 yaffsfs_SetDirRewound(dsc); |
|
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1780 |
| 1 | 1781 yaffsfs_Unlock(); |
| 1782 } | |
| 1783 | |
| 1784 | |
| 1785 int yaffs_closedir(yaffs_DIR *dirp) | |
| 1786 { | |
| 1787 yaffsfs_DirectorySearchContext *dsc = (yaffsfs_DirectorySearchContext *)dirp; | |
| 208 | 1788 |
| 1789 yaffsfs_Lock(); | |
| 1790 dsc->magic = 0; | |
| 1791 ylist_del(&dsc->others); /* unhook from list */ | |
| 1792 YFREE(dsc); | |
| 1793 yaffsfs_Unlock(); | |
| 1794 return 0; | |
| 1 | 1795 } |
| 1796 | |
|
81
5cb5d7aef5d7
Add support for faster yaffs direct look-ups.
charles <charles>
parents:
21
diff
changeset
|
1797 // end of directory stuff |
| 1 | 1798 |
| 1799 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1800 int yaffs_symlink(const YCHAR *oldpath, const YCHAR *newpath) |
| 1 | 1801 { |
| 1802 yaffs_Object *parent = NULL; | |
| 1803 yaffs_Object *obj; | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1804 YCHAR *name; |
| 1 | 1805 int retVal= -1; |
| 1806 int mode = 0; // ignore for now | |
| 208 | 1807 |
| 1 | 1808 yaffsfs_Lock(); |
| 1809 parent = yaffsfs_FindDirectory(NULL,newpath,&name,0); | |
|
351
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1810 if(parent && parent->myDev->readOnly) |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1811 yaffsfs_SetError(-EINVAL); |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1812 else if(parent){ |
|
269
4107852bb3cd
Change yaffs_DeleteFile to yaffs_DeleteObject and improve symlink handling
charles <charles>
parents:
225
diff
changeset
|
1813 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
|
1814 if(obj) |
|
4107852bb3cd
Change yaffs_DeleteFile to yaffs_DeleteObject and improve symlink handling
charles <charles>
parents:
225
diff
changeset
|
1815 retVal = 0; |
| 304 | 1816 else{ |
|
269
4107852bb3cd
Change yaffs_DeleteFile to yaffs_DeleteObject and improve symlink handling
charles <charles>
parents:
225
diff
changeset
|
1817 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
|
1818 retVal = -1; |
|
4107852bb3cd
Change yaffs_DeleteFile to yaffs_DeleteObject and improve symlink handling
charles <charles>
parents:
225
diff
changeset
|
1819 } |
|
4107852bb3cd
Change yaffs_DeleteFile to yaffs_DeleteObject and improve symlink handling
charles <charles>
parents:
225
diff
changeset
|
1820 } else { |
|
4107852bb3cd
Change yaffs_DeleteFile to yaffs_DeleteObject and improve symlink handling
charles <charles>
parents:
225
diff
changeset
|
1821 yaffsfs_SetError(-EINVAL); |
| 1 | 1822 retVal = -1; |
| 1823 } | |
| 208 | 1824 |
| 1 | 1825 yaffsfs_Unlock(); |
| 208 | 1826 |
| 1 | 1827 return retVal; |
| 208 | 1828 |
| 1 | 1829 } |
| 1830 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1831 int yaffs_readlink(const YCHAR *path, YCHAR *buf, int bufsiz) |
| 1 | 1832 { |
| 1833 yaffs_Object *obj = NULL; | |
| 1834 int retVal; | |
| 1835 | |
| 208 | 1836 |
| 1 | 1837 yaffsfs_Lock(); |
| 208 | 1838 |
| 1 | 1839 obj = yaffsfs_FindObject(NULL,path,0); |
| 208 | 1840 |
| 304 | 1841 if(!obj) { |
| 1 | 1842 yaffsfs_SetError(-ENOENT); |
| 1843 retVal = -1; | |
| 304 | 1844 } else if(obj->variantType != YAFFS_OBJECT_TYPE_SYMLINK) { |
| 1 | 1845 yaffsfs_SetError(-EINVAL); |
| 1846 retVal = -1; | |
| 304 | 1847 } else { |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1848 YCHAR *alias = obj->variant.symLinkVariant.alias; |
| 1 | 1849 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
|
1850 yaffs_strncpy(buf,alias,bufsiz - 1); |
| 1 | 1851 retVal = 0; |
| 1852 } | |
| 1853 yaffsfs_Unlock(); | |
| 1854 return retVal; | |
| 1855 } | |
| 1856 | |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1857 int yaffs_link(const YCHAR *oldpath, const YCHAR *newpath) |
| 119 | 1858 { |
| 1859 // Creates a link called newpath to existing oldpath | |
| 1860 yaffs_Object *obj = NULL; | |
| 1861 yaffs_Object *target = NULL; | |
| 125 | 1862 int retVal = 0; |
|
326
490a804b7bd3
Change to strnlen() and strncpy() to avoid problems from unbounded strings
charles <charles>
parents:
304
diff
changeset
|
1863 int newNameLength = 0; |
| 119 | 1864 |
| 208 | 1865 |
| 119 | 1866 yaffsfs_Lock(); |
| 208 | 1867 |
| 119 | 1868 obj = yaffsfs_FindObject(NULL,oldpath,0); |
| 1869 target = yaffsfs_FindObject(NULL,newpath,0); | |
| 208 | 1870 |
| 304 | 1871 if(!obj) { |
| 119 | 1872 yaffsfs_SetError(-ENOENT); |
| 1873 retVal = -1; | |
|
351
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1874 } else if(obj->myDev->readOnly){ |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1875 yaffsfs_SetError(-EINVAL); |
|
c640f5d8f33e
Add remount and forced unmount to yaffs direct
charles <charles>
parents:
349
diff
changeset
|
1876 retVal= -1; |
| 304 | 1877 } else if(target) { |
| 119 | 1878 yaffsfs_SetError(-EEXIST); |
| 1879 retVal = -1; | |
| 304 | 1880 } else { |
| 119 | 1881 yaffs_Object *newdir = NULL; |
| 1882 yaffs_Object *link = NULL; | |
| 208 | 1883 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1884 YCHAR *newname; |
| 208 | 1885 |
| 119 | 1886 newdir = yaffsfs_FindDirectory(NULL,newpath,&newname,0); |
| 208 | 1887 |
| 304 | 1888 if(!newdir){ |
| 119 | 1889 yaffsfs_SetError(-ENOTDIR); |
| 1890 retVal = -1; | |
| 304 | 1891 }else if(newdir->myDev != obj->myDev){ |
| 119 | 1892 yaffsfs_SetError(-EXDEV); |
| 1893 retVal = -1; | |
| 1894 } | |
|
326
490a804b7bd3
Change to strnlen() and strncpy() to avoid problems from unbounded strings
charles <charles>
parents:
304
diff
changeset
|
1895 |
|
490a804b7bd3
Change to strnlen() and strncpy() to avoid problems from unbounded strings
charles <charles>
parents:
304
diff
changeset
|
1896 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
|
1897 |
|
490a804b7bd3
Change to strnlen() and strncpy() to avoid problems from unbounded strings
charles <charles>
parents:
304
diff
changeset
|
1898 if(newNameLength == 0){ |
|
490a804b7bd3
Change to strnlen() and strncpy() to avoid problems from unbounded strings
charles <charles>
parents:
304
diff
changeset
|
1899 yaffsfs_SetError(-ENOENT); |
|
490a804b7bd3
Change to strnlen() and strncpy() to avoid problems from unbounded strings
charles <charles>
parents:
304
diff
changeset
|
1900 retVal = -1; |
|
490a804b7bd3
Change to strnlen() and strncpy() to avoid problems from unbounded strings
charles <charles>
parents:
304
diff
changeset
|
1901 } 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
|
1902 yaffsfs_SetError(-ENAMETOOLONG); |
|
490a804b7bd3
Change to strnlen() and strncpy() to avoid problems from unbounded strings
charles <charles>
parents:
304
diff
changeset
|
1903 retVal = -1; |
|
490a804b7bd3
Change to strnlen() and strncpy() to avoid problems from unbounded strings
charles <charles>
parents:
304
diff
changeset
|
1904 } |
|
490a804b7bd3
Change to strnlen() and strncpy() to avoid problems from unbounded strings
charles <charles>
parents:
304
diff
changeset
|
1905 |
|
490a804b7bd3
Change to strnlen() and strncpy() to avoid problems from unbounded strings
charles <charles>
parents:
304
diff
changeset
|
1906 if(retVal == 0) { |
| 119 | 1907 link = yaffs_Link(newdir,newname,obj); |
| 1908 if(link) | |
| 1909 retVal = 0; | |
| 304 | 1910 else{ |
| 119 | 1911 yaffsfs_SetError(-ENOSPC); |
| 1912 retVal = -1; | |
| 1913 } | |
| 1914 | |
| 1915 } | |
| 1916 } | |
| 1917 yaffsfs_Unlock(); | |
| 208 | 1918 |
| 119 | 1919 return retVal; |
| 1920 } | |
| 1921 | |
| 292 | 1922 int yaffs_mknod(const YCHAR *pathname, mode_t mode, dev_t dev) |
| 1923 { | |
| 1924 return -1; | |
| 1925 } | |
| 1 | 1926 |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1927 int yaffs_DumpDevStruct(const YCHAR *path) |
| 1 | 1928 { |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1929 #if 0 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1930 YCHAR *rest; |
| 208 | 1931 |
| 1 | 1932 yaffs_Object *obj = yaffsfs_FindRoot(path,&rest); |
| 208 | 1933 |
| 304 | 1934 if(obj){ |
| 1 | 1935 yaffs_Device *dev = obj->myDev; |
| 208 | 1936 |
| 1 | 1937 printf("\n" |
| 1938 "nPageWrites.......... %d\n" | |
| 1939 "nPageReads........... %d\n" | |
| 1940 "nBlockErasures....... %d\n" | |
| 1941 "nGCCopies............ %d\n" | |
| 1942 "garbageCollections... %d\n" | |
| 1943 "passiveGarbageColl'ns %d\n" | |
| 1944 "\n", | |
| 1945 dev->nPageWrites, | |
| 1946 dev->nPageReads, | |
| 1947 dev->nBlockErasures, | |
| 1948 dev->nGCCopies, | |
| 1949 dev->garbageCollections, | |
| 1950 dev->passiveGarbageCollections | |
| 1951 ); | |
| 208 | 1952 |
| 1 | 1953 } |
|
204
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1954 |
|
0f70320a2274
Check in inband tags, some extra yaffs direct functions and some other changes
charles <charles>
parents:
179
diff
changeset
|
1955 #endif |
| 1 | 1956 return 0; |
| 1957 } | |
| 1958 |
