+int yaffs_setxattr_reldir(struct yaffs_obj *reldir, const YCHAR *path,
+ const char *name, const void *data, int size, int flags)
+{
+ return yaffs_do_setxattr_reldir(reldir, path, name, data, size, flags, 1);
+}
+
+int yaffs_setxattr_reldev(struct yaffs_dev *dev, const YCHAR *path,
+ const char *name, const void *data, int size, int flags)
+{
+ return yaffs_setxattr_reldir(ROOT_DIR(dev), path, name, data, size, flags);
+}
+
+int yaffs_setxattr(const YCHAR *path, const char *name,
+ const void *data, int size, int flags)
+{
+ return yaffs_setxattr_reldir(NULL, path, name, data, size, flags);
+}
+
+int yaffs_lsetxattr_reldir(struct yaffs_obj *reldir, const YCHAR *path, const char *name,
+ const void *data, int size, int flags)
+{
+ return yaffs_do_setxattr_reldir(reldir, path, name, data, size, flags, 0);
+}
+
+int yaffs_lsetxattr_reldev(struct yaffs_dev *dev, const YCHAR *path, const char *name,
+ const void *data, int size, int flags)
+{
+ return yaffs_lsetxattr_reldir(ROOT_DIR(dev), path, name, data, size, flags);
+}
+
+int yaffs_lsetxattr(const YCHAR *path, const char *name,
+ const void *data, int size, int flags)
+{
+ return yaffs_lsetxattr_reldir(NULL, path, name, data, size, flags);
+}
+
+int yaffs_fsetxattr(int fd, const char *name,
+ const void *data, int size, int flags)
+{
+ struct yaffs_obj *obj;
+
+ int retVal = -1;
+
+ if (yaffsfs_CheckMemRegion(name, 0, 0) < 0 ||
+ yaffsfs_CheckMemRegion(data, size, 0) < 0) {
+ yaffsfs_SetError(-EFAULT);
+ return -1;
+ }
+
+ yaffsfs_Lock();
+ obj = yaffsfs_HandleToObject(fd);
+
+ if (!obj)
+ yaffsfs_SetError(-EBADF);
+ else {
+ retVal = yaffs_set_xattrib(obj, name, data, size, flags);
+ if (retVal < 0) {
+ yaffsfs_SetError(retVal);
+ retVal = -1;
+ }
+ }
+
+ yaffsfs_Unlock();
+
+ return retVal;
+}
+
+static int yaffs_do_getxattr_reldir(struct yaffs_obj *reldir, const YCHAR *path,
+ const char *name, void *data, int size, int follow)
+{
+ struct yaffs_obj *obj;
+ struct yaffs_obj *dir;
+ int retVal = -1;
+ int notDir = 0;
+ int loop = 0;
+
+ if (yaffsfs_CheckMemRegion(path, 0, 0) < 0 ||
+ yaffsfs_CheckMemRegion(name, 0, 0) < 0 ||
+ yaffsfs_CheckMemRegion(data, size, 1) < 0) {
+ yaffsfs_SetError(-EFAULT);
+ return -1;
+ }
+
+ if (yaffsfs_CheckPath(path) < 0) {
+ yaffsfs_SetError(-ENAMETOOLONG);
+ return -1;
+ }
+
+ yaffsfs_Lock();
+
+ obj = yaffsfs_FindObject(reldir, path, 0, 1, &dir, ¬Dir, &loop);
+
+ if (follow)
+ obj = yaffsfs_FollowLink(obj, 0, &loop);
+
+ if (!dir && notDir)
+ yaffsfs_SetError(-ENOTDIR);
+ else if (loop)
+ yaffsfs_SetError(-ELOOP);
+ else if (!dir || !obj)
+ yaffsfs_SetError(-ENOENT);
+ else {
+ retVal = yaffs_get_xattrib(obj, name, data, size);
+ if (retVal < 0) {
+ yaffsfs_SetError(retVal);
+ retVal = -1;
+ }
+ }
+ yaffsfs_Unlock();
+
+ return retVal;
+
+}
+
+int yaffs_getxattr_reldir(struct yaffs_obj *reldir, const YCHAR *path,
+ const char *name, void *data, int size)
+{
+ return yaffs_do_getxattr_reldir(reldir, path, name, data, size, 1);
+}
+
+int yaffs_getxattr_reldev(struct yaffs_dev *dev, const YCHAR *path, const char *name, void *data, int size)
+{
+ return yaffs_getxattr_reldir(ROOT_DIR(dev), path, name, data, size);
+}
+
+int yaffs_getxattr(const YCHAR *path, const char *name, void *data, int size)
+{
+ return yaffs_getxattr_reldir(NULL, path, name, data, size);
+}
+
+int yaffs_lgetxattr_reldir(struct yaffs_obj *reldir, const YCHAR *path,
+ const char *name, void *data, int size)
+{
+ return yaffs_do_getxattr_reldir(reldir, path, name, data, size, 0);
+}
+
+int yaffs_lgetxattr_reldev(struct yaffs_dev *dev, const YCHAR *path, const char *name, void *data, int size)
+{
+ return yaffs_lgetxattr_reldir(ROOT_DIR(dev), path, name, data, size);
+}
+
+int yaffs_lgetxattr(const YCHAR *path, const char *name, void *data, int size)
+{
+ return yaffs_lgetxattr_reldir(NULL, path, name, data, size);
+}
+
+int yaffs_fgetxattr(int fd, const char *name, void *data, int size)
+{
+ struct yaffs_obj *obj;
+
+ int retVal = -1;
+
+ if (yaffsfs_CheckMemRegion(name, 0, 0) < 0 ||
+ yaffsfs_CheckMemRegion(data, size, 1) < 0) {
+ yaffsfs_SetError(-EFAULT);
+ return -1;
+ }
+
+ yaffsfs_Lock();
+ obj = yaffsfs_HandleToObject(fd);
+
+ if (obj) {
+ retVal = yaffs_get_xattrib(obj, name, data, size);
+ if (retVal < 0) {
+ yaffsfs_SetError(retVal);
+ retVal = -1;
+ }
+ } else
+ /* bad handle */
+ yaffsfs_SetError(-EBADF);
+
+ yaffsfs_Unlock();
+
+ return retVal;
+}
+
+static int yaffs_do_listxattr_reldir(struct yaffs_obj *reldir, const YCHAR *path,
+ char *data, int size, int follow)
+{
+ struct yaffs_obj *obj = NULL;
+ struct yaffs_obj *dir = NULL;
+ int retVal = -1;
+ int notDir = 0;
+ int loop = 0;
+
+ if (yaffsfs_CheckMemRegion(path, 0, 0) < 0 ||
+ yaffsfs_CheckMemRegion(data, size, 1) < 0) {
+ yaffsfs_SetError(-EFAULT);
+ return -1;
+ }
+
+ if (yaffsfs_CheckPath(path) < 0) {
+ yaffsfs_SetError(-ENAMETOOLONG);
+ return -1;
+ }
+
+ yaffsfs_Lock();
+
+ obj = yaffsfs_FindObject(reldir, path, 0, 1, &dir, ¬Dir, &loop);
+
+ if (follow)
+ obj = yaffsfs_FollowLink(obj, 0, &loop);
+
+ if (!dir && notDir)
+ yaffsfs_SetError(-ENOTDIR);
+ else if (loop)
+ yaffsfs_SetError(-ELOOP);
+ else if (!dir || !obj)
+ yaffsfs_SetError(-ENOENT);
+ else {
+ retVal = yaffs_list_xattrib(obj, data, size);
+ if (retVal < 0) {
+ yaffsfs_SetError(retVal);
+ retVal = -1;
+ }
+ }
+
+ yaffsfs_Unlock();
+
+ return retVal;
+
+}
+
+int yaffs_listxattr_reldir(struct yaffs_obj *reldir, const YCHAR *path,
+ char *data, int size)
+{
+ return yaffs_do_listxattr_reldir(reldir, path, data, size, 1);
+}
+
+int yaffs_listxattr_reldev(struct yaffs_dev *dev, const YCHAR *path, char *data, int size)
+{
+ return yaffs_listxattr_reldir(ROOT_DIR(dev), path, data, size);
+}
+
+int yaffs_listxattr(const YCHAR *path, char *data, int size)
+{
+ return yaffs_listxattr_reldir(NULL, path, data, size);
+}
+
+int yaffs_llistxattr_reldir(struct yaffs_obj *reldir, const YCHAR *path,
+ char *data, int size)
+{
+ return yaffs_do_listxattr_reldir(reldir, path, data, size, 0);
+}
+
+int yaffs_llistxattr_reldev(struct yaffs_dev *dev, const YCHAR *path, char *data, int size)
+{
+ return yaffs_llistxattr_reldir(ROOT_DIR(dev), path, data, size);
+}
+
+int yaffs_llistxattr(const YCHAR *path, char *data, int size)
+{
+ return yaffs_llistxattr_reldir(NULL, path, data, size);
+}
+
+int yaffs_flistxattr(int fd, char *data, int size)
+{
+ struct yaffs_obj *obj;
+
+ int retVal = -1;
+
+ if (yaffsfs_CheckMemRegion(data, size, 1) < 0) {
+ yaffsfs_SetError(-EFAULT);
+ return -1;
+ }
+
+ yaffsfs_Lock();
+ obj = yaffsfs_HandleToObject(fd);
+
+ if (obj) {
+ retVal = yaffs_list_xattrib(obj, data, size);
+ if (retVal < 0) {
+ yaffsfs_SetError(retVal);
+ retVal = -1;
+ }
+ } else
+ /* bad handle */
+ yaffsfs_SetError(-EBADF);
+
+ yaffsfs_Unlock();
+
+ return retVal;
+}
+
+static int yaffs_do_removexattr_reldir(struct yaffs_obj *reldir, const YCHAR *path,
+ const char *name, int follow)
+{
+ struct yaffs_obj *obj = NULL;
+ struct yaffs_obj *dir = NULL;
+ int notDir = 0;
+ int loop = 0;
+ int retVal = -1;
+
+ if (yaffsfs_CheckMemRegion(path, 0, 0) < 0 ||
+ yaffsfs_CheckMemRegion(name, 0, 0) < 0) {
+ yaffsfs_SetError(-EFAULT);
+ return -1;
+ }
+
+ if (yaffsfs_CheckPath(path) < 0) {
+ yaffsfs_SetError(-ENAMETOOLONG);
+ return -1;
+ }
+
+ yaffsfs_Lock();
+
+ obj = yaffsfs_FindObject(reldir, path, 0, 1, &dir, ¬Dir, &loop);
+
+ if (follow)
+ obj = yaffsfs_FollowLink(obj, 0, &loop);
+
+ if (!dir && notDir)
+ yaffsfs_SetError(-ENOTDIR);
+ else if (loop)
+ yaffsfs_SetError(-ELOOP);
+ else if (!dir || !obj)
+ yaffsfs_SetError(-ENOENT);
+ else {
+ retVal = yaffs_remove_xattrib(obj, name);
+ if (retVal < 0) {
+ yaffsfs_SetError(retVal);
+ retVal = -1;
+ }
+ }
+
+ yaffsfs_Unlock();
+
+ return retVal;
+
+}
+
+int yaffs_removexattr_reldir(struct yaffs_obj *reldir, const YCHAR *path,
+ const char *name)
+{
+ return yaffs_do_removexattr_reldir(reldir, path, name, 1);
+}
+
+int yaffs_removexattr_reldev(struct yaffs_dev *dev, const YCHAR *path, const char *name)
+{
+ return yaffs_removexattr_reldir(ROOT_DIR(dev), path, name);
+}
+
+int yaffs_removexattr(const YCHAR *path, const char *name)
+{
+ return yaffs_removexattr_reldir(NULL, path, name);
+}
+
+int yaffs_lremovexattr_reldir(struct yaffs_obj *reldir, const YCHAR *path,
+ const char *name)
+{
+ return yaffs_do_removexattr_reldir(reldir, path, name, 0);
+}
+
+int yaffs_lremovexattr_reldev(struct yaffs_dev *dev, const YCHAR *path, const char *name)
+{
+ return yaffs_lremovexattr_reldir(ROOT_DIR(dev), path, name);
+}
+
+int yaffs_lremovexattr(const YCHAR *path, const char *name)
+{
+ return yaffs_lremovexattr_reldir(NULL, path, name);
+}
+
+int yaffs_fremovexattr(int fd, const char *name)
+{
+ struct yaffs_obj *obj;
+
+ int retVal = -1;
+
+ if (yaffsfs_CheckMemRegion(name, 0, 0) < 0) {
+ yaffsfs_SetError(-EFAULT);
+ return -1;
+ }
+
+ yaffsfs_Lock();
+ obj = yaffsfs_HandleToObject(fd);
+
+ if (obj) {
+ retVal = yaffs_remove_xattrib(obj, name);
+ if (retVal < 0) {
+ yaffsfs_SetError(retVal);
+ retVal = -1;
+ }
+ } else
+ /* bad handle */
+ yaffsfs_SetError(-EBADF);
+
+ yaffsfs_Unlock();
+
+ return retVal;
+}
+#endif
+
+#ifdef CONFIG_YAFFS_WINCE
+int yaffs_get_wince_times(int fd, unsigned *wctime,
+ unsigned *watime, unsigned *wmtime)
+{
+ struct yaffs_obj *obj;
+
+ int retVal = -1;
+
+ yaffsfs_Lock();
+ obj = yaffsfs_HandleToObject(fd);
+
+ if (obj) {
+
+ if (wctime) {
+ wctime[0] = obj->win_ctime[0];
+ wctime[1] = obj->win_ctime[1];
+ }
+ if (watime) {
+ watime[0] = obj->win_atime[0];
+ watime[1] = obj->win_atime[1];
+ }
+ if (wmtime) {
+ wmtime[0] = obj->win_mtime[0];
+ wmtime[1] = obj->win_mtime[1];
+ }
+
+ retVal = 0;
+ } else
+ /* bad handle */
+ yaffsfs_SetError(-EBADF);
+
+ yaffsfs_Unlock();
+
+ return retVal;
+}
+
+int yaffs_set_wince_times(int fd,
+ const unsigned *wctime,
+ const unsigned *watime, const unsigned *wmtime)
+{
+ struct yaffs_obj *obj;
+ int result;
+ int retVal = -1;
+
+ yaffsfs_Lock();
+ obj = yaffsfs_HandleToObject(fd);
+
+ if (obj) {
+
+ if (wctime) {
+ obj->win_ctime[0] = wctime[0];
+ obj->win_ctime[1] = wctime[1];
+ }
+ if (watime) {
+ obj->win_atime[0] = watime[0];
+ obj->win_atime[1] = watime[1];
+ }
+ if (wmtime) {
+ obj->win_mtime[0] = wmtime[0];
+ obj->win_mtime[1] = wmtime[1];
+ }
+
+ obj->dirty = 1;
+ result = yaffs_flush_file(obj, 0, 0, 0);
+ retVal = 0;
+ } else
+ /* bad handle */
+ yaffsfs_SetError(-EBADF);
+
+ yaffsfs_Unlock();
+
+ return retVal;
+}
+
+#endif
+
+static int yaffsfs_DoChMod(struct yaffs_obj *obj, mode_t mode)
+{
+ int result = -1;
+
+ if (obj)
+ obj = yaffs_get_equivalent_obj(obj);
+
+ if (obj) {
+ obj->yst_mode = mode;
+ obj->dirty = 1;
+ result = yaffs_flush_file(obj, 0, 0, 0);
+ }
+
+ return result == YAFFS_OK ? 0 : -1;
+}
+
+int yaffs_access_reldir(struct yaffs_obj *reldir, const YCHAR *path, int amode)
+{
+ struct yaffs_obj *obj = NULL;
+ struct yaffs_obj *dir = NULL;
+ int notDir = 0;
+ int loop = 0;
+ int retval = -1;
+
+ if (yaffsfs_CheckMemRegion(path, 0, 0) < 0) {
+ yaffsfs_SetError(-EFAULT);
+ return -1;
+ }
+
+ if (yaffsfs_CheckPath(path) < 0) {
+ yaffsfs_SetError(-ENAMETOOLONG);
+ return -1;
+ }
+
+ if (amode & ~(R_OK | W_OK | X_OK)) {
+ yaffsfs_SetError(-EINVAL);
+ return -1;
+ }
+
+ yaffsfs_Lock();
+
+ obj = yaffsfs_FindObject(reldir, path, 0, 1, &dir, ¬Dir, &loop);
+ obj = yaffsfs_FollowLink(obj, 0, &loop);
+
+ if (!dir && notDir)
+ yaffsfs_SetError(-ENOTDIR);
+ else if (loop)
+ yaffsfs_SetError(-ELOOP);
+ else if (!dir || !obj)
+ yaffsfs_SetError(-ENOENT);
+ else if ((amode & W_OK) && obj->my_dev->read_only)
+ yaffsfs_SetError(-EROFS);
+ else {
+ int access_ok = 1;
+
+ if ((amode & R_OK) && !(obj->yst_mode & S_IRUSR))
+ access_ok = 0;
+ if ((amode & W_OK) && !(obj->yst_mode & S_IWUSR))
+ access_ok = 0;
+ if ((amode & X_OK) && !(obj->yst_mode & S_IXUSR))
+ access_ok = 0;
+
+ if (!access_ok)
+ yaffsfs_SetError(-EACCES);
+ else
+ retval = 0;
+ }
+
+ yaffsfs_Unlock();
+
+ return retval;
+
+}
+
+int yaffs_access_reldev(struct yaffs_dev *dev, const YCHAR *path, int amode)
+{
+ return yaffs_access_reldir(ROOT_DIR(dev), path, amode);
+}
+
+int yaffs_access(const YCHAR *path, int amode)
+{
+ return yaffs_access_reldir(NULL, path, amode);
+}
+
+int yaffs_chmod_reldir(struct yaffs_obj *reldir, const YCHAR *path, mode_t mode)
+{
+ struct yaffs_obj *obj = NULL;
+ struct yaffs_obj *dir = NULL;
+ int retVal = -1;
+ int notDir = 0;
+ int loop = 0;
+
+ if (yaffsfs_CheckMemRegion(path, 0, 0) < 0) {
+ yaffsfs_SetError(-EFAULT);
+ return -1;
+ }