X-Git-Url: https://yaffs.net/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=direct%2Fyaffsfs.c;h=7afde717b97655b253e619bd43014cdb19a5337c;hp=a01155ff9320b66051e465d6809aaa14b792e654;hb=1c39c5b648b8aa5d7961d10135fca68eb8069be4;hpb=53892fe9e3770882fd8f53f1a8a392d875175b4b diff --git a/direct/yaffsfs.c b/direct/yaffsfs.c index a01155f..7afde71 100644 --- a/direct/yaffsfs.c +++ b/direct/yaffsfs.c @@ -398,7 +398,7 @@ static void yaffsfs_BreakDeviceHandles(struct yaffs_dev *dev) * Stuff to handle names. */ #ifdef CONFIG_YAFFS_CASE_INSENSITIVE - +#ifndef CONFIG_YAFFS_WINCE static int yaffs_toupper(YCHAR a) { if (a >= 'a' && a <= 'z') @@ -406,6 +406,7 @@ static int yaffs_toupper(YCHAR a) else return a; } +#endif static int yaffsfs_Match(YCHAR a, YCHAR b) { @@ -432,7 +433,7 @@ static int yaffsfs_IsPathDivider(YCHAR ch) return 0; } -static int yaffsfs_CheckNameLength(const char *name) +static int yaffsfs_CheckNameLength(const YCHAR *name) { int retVal = 0; @@ -514,17 +515,17 @@ static struct yaffs_dev *yaffsfs_FindDevice(const YCHAR *path, thisMatchLength = 0; matching = 1; + if(!p) continue; - while (matching && *p && *leftOver) { - /* Skip over any /s */ - while (yaffsfs_IsPathDivider(*p)) - p++; + /* Skip over any leading /s */ + while (yaffsfs_IsPathDivider(*p)) + p++; + while (yaffsfs_IsPathDivider(*leftOver)) + leftOver++; - /* Skip over any /s */ - while (yaffsfs_IsPathDivider(*leftOver)) - leftOver++; + while (matching && *p && *leftOver) { /* Now match the text part */ while (matching && @@ -538,6 +539,16 @@ static struct yaffs_dev *yaffsfs_FindDevice(const YCHAR *path, matching = 0; } } + + if ((*p && !yaffsfs_IsPathDivider(*p)) || + (*leftOver && !yaffsfs_IsPathDivider(*leftOver))) + matching = 0; + else { + while (yaffsfs_IsPathDivider(*p)) + p++; + while (yaffsfs_IsPathDivider(*leftOver)) + leftOver++; + } } /* Skip over any /s in leftOver */ @@ -558,7 +569,6 @@ static struct yaffs_dev *yaffsfs_FindDevice(const YCHAR *path, retval = dev; longestMatch = thisMatchLength; } - } return retval; } @@ -737,7 +747,20 @@ static struct yaffs_obj *yaffsfs_FindObject(struct yaffs_obj *relDir, if (dirOut) *dirOut = dir; - if (dir && *name) + /* At this stage we have looked up directory part and have the name part + * in name if there is one. + * + * eg /nand/x/ will give us a name of "" + * /nand/x will give us a name of "x" + * + * Since the name part might be "." or ".." which need to be fixed. + */ + if (dir && (yaffs_strcmp(name, _Y("..")) == 0)) { + dir = dir->parent; + obj = dir; + } else if (dir && (yaffs_strcmp(name, _Y(".")) == 0)) + obj = dir; + else if (dir && *name) obj = yaffs_find_by_name(dir, name); else obj = dir; @@ -1077,7 +1100,7 @@ static int yaffs_Dofsync(int handle, int datasync) else if (obj->my_dev->read_only) yaffsfs_SetError(-EROFS); else { - yaffs_flush_file(obj, 1, datasync); + yaffs_flush_file(obj, 1, datasync, 0); retVal = 0; } @@ -1119,7 +1142,7 @@ int yaffs_close(int handle) else { /* clean up */ if(!f->isDir) - yaffs_flush_file(obj, 1, 0); + yaffs_flush_file(obj, 1, 0, 1); yaffsfs_PutHandle(handle); retVal = 0; } @@ -1854,8 +1877,6 @@ static int yaffsfs_DoUtime(struct yaffs_obj *obj, const struct yaffs_utimbuf *buf) { int retVal = -1; - int result; - struct yaffs_utimbuf local; obj = yaffs_get_equivalent_obj(obj); @@ -1865,6 +1886,7 @@ static int yaffsfs_DoUtime(struct yaffs_obj *obj, return -1; } +#if !CONFIG_YAFFS_WINCE if (!buf) { local.actime = Y_CURRENT_TIME; local.modtime = local.actime; @@ -1872,12 +1894,15 @@ static int yaffsfs_DoUtime(struct yaffs_obj *obj, } if (obj) { + int result; + obj->yst_atime = buf->actime; obj->yst_mtime = buf->modtime; obj->dirty = 1; - result = yaffs_flush_file(obj, 0, 0); + result = yaffs_flush_file(obj, 0, 0, 0); retVal = result == YAFFS_OK ? 0 : -1; } +#endif return retVal; } @@ -2460,7 +2485,7 @@ int yaffs_set_wince_times(int fd, } obj->dirty = 1; - result = yaffs_flush_file(obj, 0, 0); + result = yaffs_flush_file(obj, 0, 0, 0); retVal = 0; } else /* bad handle */ @@ -2483,7 +2508,7 @@ static int yaffsfs_DoChMod(struct yaffs_obj *obj, mode_t mode) if (obj) { obj->yst_mode = mode; obj->dirty = 1; - result = yaffs_flush_file(obj, 0, 0); + result = yaffs_flush_file(obj, 0, 0, 0); } return result == YAFFS_OK ? 0 : -1; @@ -2866,7 +2891,7 @@ int yaffs_sync_common(struct yaffs_dev *dev, const YCHAR *path) yaffsfs_SetError(-EROFS); else { - yaffs_flush_whole_cache(dev); + yaffs_flush_whole_cache(dev, 0); yaffs_checkpoint_save(dev); retVal = 0; @@ -2888,6 +2913,57 @@ int yaffs_sync(const YCHAR *path) return yaffs_sync_common(NULL, path); } + +static int yaffsfs_bg_gc_common(struct yaffs_dev *dev, + const YCHAR *path, + int urgency) +{ + int retVal = -1; + YCHAR *dummy; + + if (!dev) { + if (yaffsfs_CheckMemRegion(path, 0, 0) < 0) { + yaffsfs_SetError(-EFAULT); + return -1; + } + + if (yaffsfs_CheckPath(path) < 0) { + yaffsfs_SetError(-ENAMETOOLONG); + return -1; + } + } + + yaffsfs_Lock(); + if (!dev) + dev = yaffsfs_FindDevice(path, &dummy); + + if (dev) { + if (!dev->is_mounted) + yaffsfs_SetError(-EINVAL); + else + retVal = yaffs_bg_gc(dev, urgency); + } else + yaffsfs_SetError(-ENODEV); + + yaffsfs_Unlock(); + return retVal; +} + +/* Background gc functions. + * These return 0 when bg done or greater than 0 when gc has been + * done and there is still a lot of garbage to be cleaned up. + */ + +int yaffs_do_background_gc(const YCHAR *path, int urgency) +{ + return yaffsfs_bg_gc_common(NULL, path, urgency); +} + +int yaffs_do_background_gc_reldev(struct yaffs_dev *dev, int urgency) +{ + return yaffsfs_bg_gc_common(dev, NULL, urgency); +} + static int yaffsfs_IsDevBusy(struct yaffs_dev *dev) { int i; @@ -2922,7 +2998,7 @@ int yaffs_remount_common(struct yaffs_dev *dev, const YCHAR *path, if (dev) { if (dev->is_mounted) { - yaffs_flush_whole_cache(dev); + yaffs_flush_whole_cache(dev, 0); if (force || !yaffsfs_IsDevBusy(dev)) { if (read_only) @@ -2973,7 +3049,7 @@ int yaffs_unmount2_common(struct yaffs_dev *dev, const YCHAR *path, int force) if (dev) { if (dev->is_mounted) { int inUse; - yaffs_flush_whole_cache(dev); + yaffs_flush_whole_cache(dev, 0); yaffs_checkpoint_save(dev); inUse = yaffsfs_IsDevBusy(dev); if (!inUse || force) { @@ -3046,7 +3122,7 @@ int yaffs_format_common(struct yaffs_dev *dev, if (dev->is_mounted && unmount_flag) { int inUse; - yaffs_flush_whole_cache(dev); + yaffs_flush_whole_cache(dev, 0); yaffs_checkpoint_save(dev); inUse = yaffsfs_IsDevBusy(dev); if (!inUse || force_unmount_flag) { @@ -3365,6 +3441,7 @@ static yaffs_DIR *yaffsfs_opendir_reldir_no_lock(struct yaffs_obj *reldir, } obj = yaffsfs_FindObject(reldir, dirname, 0, 1, NULL, ¬Dir, &loop); + obj = yaffsfs_FollowLink(obj, 0, &loop); if (!obj && notDir) yaffsfs_SetError(-ENOTDIR); @@ -3410,6 +3487,12 @@ yaffs_DIR *yaffs_opendir_reldir(struct yaffs_obj *reldir, const YCHAR *dirname) yaffsfs_Unlock(); return ret; } + +yaffs_DIR *yaffs_opendir_reldev(struct yaffs_dev *dev, const YCHAR *dirname) +{ + return yaffs_opendir_reldir(ROOT_DIR(dev), dirname); +} + yaffs_DIR *yaffs_opendir(const YCHAR *dirname) { return yaffs_opendir_reldir(NULL, dirname);