+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;
+ }
+ }
+
+ yaffsfs_Lock();
+ if (!dev)
+ dev = yaffsfs_FindMountPoint(path);
+
+ if (dev) {
+ int was_mounted = dev->is_mounted;
+
+ if (dev->is_mounted && unmount_flag) {
+ int inUse;
+ yaffs_flush_whole_cache(dev, 0);
+ yaffs_checkpoint_save(dev);
+ inUse = yaffsfs_IsDevBusy(dev);
+ if (!inUse || force_unmount_flag) {
+ if (inUse)
+ yaffsfs_BreakDeviceHandles(dev);
+ yaffs_deinitialise(dev);
+ }
+ }
+
+ if(dev->is_mounted) {
+ yaffsfs_SetError(-EBUSY);
+ retVal = -1;
+ } else {
+ yaffs_guts_format_dev(dev);
+ if(was_mounted && remount_flag) {
+ result = yaffs_guts_initialise(dev);
+ if (result == YAFFS_FAIL) {
+ yaffsfs_SetError(-ENOMEM);
+ retVal = -1;
+ }
+ }
+ }
+ } else {
+ yaffsfs_SetError(-ENODEV);
+ retVal = -1;
+ }
+
+ yaffsfs_Unlock();
+ return retVal;
+
+}
+
+int yaffs_format_reldev(struct yaffs_dev *dev,
+ int unmount_flag,
+ int force_unmount_flag,
+ int remount_flag)
+{
+ return yaffs_format_common(dev, NULL, unmount_flag,
+ force_unmount_flag, remount_flag);
+}
+
+int yaffs_format(const YCHAR *path,
+ int unmount_flag,
+ int force_unmount_flag,
+ int remount_flag)
+{
+ return yaffs_format_common(NULL, path, unmount_flag,
+ force_unmount_flag, remount_flag);
+}
+
+Y_LOFF_T yaffs_freespace_common(struct yaffs_dev *dev, const YCHAR *path)
+{
+ Y_LOFF_T 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 && dev->is_mounted) {
+ retVal = yaffs_get_n_free_chunks(dev);
+ retVal *= dev->data_bytes_per_chunk;
+
+ } else
+ yaffsfs_SetError(-EINVAL);
+
+ yaffsfs_Unlock();
+ return retVal;
+}
+
+Y_LOFF_T yaffs_freespace_reldev(struct yaffs_dev *dev)
+{
+ return yaffs_freespace_common(dev, NULL);
+}
+
+Y_LOFF_T yaffs_freespace(const YCHAR *path)
+{
+ return yaffs_freespace_common(NULL, path);
+}
+
+Y_LOFF_T yaffs_totalspace_common(struct yaffs_dev *dev, const YCHAR *path)
+{
+ Y_LOFF_T 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 && dev->is_mounted) {
+ retVal = (dev->param.end_block - dev->param.start_block + 1) -
+ dev->param.n_reserved_blocks;
+ retVal *= dev->param.chunks_per_block;
+ retVal *= dev->data_bytes_per_chunk;
+
+ } else
+ yaffsfs_SetError(-EINVAL);
+
+ yaffsfs_Unlock();
+ return retVal;
+}
+
+Y_LOFF_T yaffs_totalspace_reldev(struct yaffs_dev *dev)
+{
+ return yaffs_totalspace_common(dev, NULL);
+}
+
+Y_LOFF_T yaffs_totalspace(const YCHAR *path)
+{
+ return yaffs_totalspace_common(NULL, path);
+}
+
+int yaffs_inodecount_common(struct yaffs_dev *dev, const YCHAR *path)
+{
+ Y_LOFF_T 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 && dev->is_mounted) {
+ int n_obj = dev->n_obj;
+ if (n_obj > dev->n_hardlinks)
+ retVal = n_obj - dev->n_hardlinks;
+ }
+
+ if (retVal < 0)
+ yaffsfs_SetError(-EINVAL);
+
+ yaffsfs_Unlock();
+ return retVal;
+}
+
+int yaffs_inodecount_reldev(struct yaffs_dev *dev)
+{
+ return yaffs_inodecount_common(dev, NULL);
+}
+
+int yaffs_inodecount(const YCHAR *path)
+{
+ return yaffs_inodecount_common(NULL, path);
+}
+
+void yaffs_add_device(struct yaffs_dev *dev)
+{
+ struct list_head *cfg;
+ /* First check that the device is not in the list. */
+
+ list_for_each(cfg, &yaffsfs_deviceList) {
+ if (dev == list_entry(cfg, struct yaffs_dev, dev_list))
+ return;
+ }
+
+ dev->is_mounted = 0;
+ dev->param.remove_obj_fn = yaffsfs_RemoveObjectCallback;
+
+ if (!dev->dev_list.next)
+ INIT_LIST_HEAD(&dev->dev_list);
+
+ list_add(&dev->dev_list, &yaffsfs_deviceList);