+ 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;
+ struct yaffs_obj *obj;
+
+ for (i = 0; i < YAFFSFS_N_HANDLES; i++) {
+ obj = yaffsfs_HandleToObject(i);
+ if (obj && obj->my_dev == dev)
+ return 1;
+ }
+ return 0;
+}
+
+int yaffs_remount_common(struct yaffs_dev *dev, const YCHAR *path,
+ int force, int read_only)
+{
+ 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;
+ }
+
+ yaffsfs_Lock();
+ if (!dev)
+ dev = yaffsfs_FindMountPoint(path);
+
+ if (dev) {
+ if (dev->is_mounted) {
+ yaffs_flush_whole_cache(dev);
+
+ if (force || !yaffsfs_IsDevBusy(dev)) {
+ if (read_only)
+ yaffs_checkpoint_save(dev);
+ dev->read_only = read_only ? 1 : 0;
+ retVal = 0;
+ } else
+ yaffsfs_SetError(-EBUSY);
+
+ } else
+ yaffsfs_SetError(-EINVAL);
+
+ } else
+ yaffsfs_SetError(-ENODEV);
+
+ yaffsfs_Unlock();
+ return retVal;
+
+}
+
+int yaffs_remount_reldev(struct yaffs_dev *dev, int force, int read_only)
+{
+ return yaffs_remount_common(dev, NULL, force, read_only);
+}
+int yaffs_remount(const YCHAR *path, int force, int read_only)
+{
+ return yaffs_remount_common(NULL, path, force, read_only);
+}
+
+int yaffs_unmount2_common(struct yaffs_dev *dev, const YCHAR *path, int force)
+{
+ 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;
+ }
+
+ yaffsfs_Lock();
+ if (!dev)
+ dev = yaffsfs_FindMountPoint(path);
+
+ if (dev) {
+ if (dev->is_mounted) {
+ int inUse;
+ yaffs_flush_whole_cache(dev);
+ yaffs_checkpoint_save(dev);
+ inUse = yaffsfs_IsDevBusy(dev);
+ if (!inUse || force) {
+ if (inUse)
+ yaffsfs_BreakDeviceHandles(dev);
+ yaffs_deinitialise(dev);
+
+ retVal = 0;
+ } else
+ yaffsfs_SetError(-EBUSY);
+
+ } else
+ yaffsfs_SetError(-EINVAL);
+
+ } else
+ yaffsfs_SetError(-ENODEV);
+
+ yaffsfs_Unlock();
+ return retVal;
+
+}
+
+int yaffs_unmount2_reldev(struct yaffs_dev *dev, int force)
+{
+ return yaffs_unmount2_common(dev, NULL, force);
+}
+
+int yaffs_unmount2(const YCHAR *path, int force)
+{
+ return yaffs_unmount2_common(NULL, path, force);
+}
+
+int yaffs_unmount_reldev(struct yaffs_dev *dev)
+{
+ return yaffs_unmount2_reldev(dev, 0);
+}
+
+int yaffs_unmount(const YCHAR *path)
+{
+ return yaffs_unmount2(path, 0);
+}
+
+int yaffs_format_common(struct yaffs_dev *dev,
+ const YCHAR *path,
+ int unmount_flag,
+ int force_unmount_flag,
+ int remount_flag)
+{
+ int retVal = 0;
+ int result;
+
+ if (!dev) {
+ if (!path) {
+ yaffsfs_SetError(-EFAULT);
+ return -1;
+ }
+
+ if (yaffsfs_CheckPath(path) < 0) {
+ yaffsfs_SetError(-ENAMETOOLONG);
+ return -1;
+ }
+ }
+