Mark a file as "in use" - filesystems

I'm developping a "MP3 player"-like USB device. It is seen as a Mass Storage device by the USB host (Windows). I'd like to be able to keep the current song playing while the device is connected.
In an ideal world, the user should be able to delete every mp3 files using his file explorer but the one currently playing, which would be seen as "in use" by Windows.
The filesystem is FAT, I use FatFS for reading files on the device.
Does FAT allow such thing (mark a file as "in use") ? Any smarter idea ?

Like every filesystem that isn't specifically designed for this purpose, FAT isn't a cluster filesystem. As such, there are no provisions for mounting it from more than one host at a time. So it can't be mounted from the USB host's operating system and from the USB device's embedded operating system at the same time. The concept of a file being "in use" at the filesystem level is moot for a non-cluster filesystem.
For examples of cluster filesystems, look at OCFS2 or GFS2. But those require things like network lock managers and it is very unlikely that you can easily use them for an application like a USB device.

Related

Emulator for FAT32 mass storage with device file

I have a smart card-like miniSD card (it's a javacard as far as I know) and I'm trying to write an emulator for it that runs on Windows and Linux. The emulator will be used in software integration tests. I want to test my client without using the actual hardware for several reasons. One reason is that the actual hardware will change its state irreversibly and doesn't allow a complete reset.
The device implements a mass storage with FAT32 file system. It contains a special device file that is being used for controlling the device via simple file write/read operations.
My goal is that the virtual (emulated) device appears with drive letter in Windows explorer as soon as the emulator is started, similar as if someone would actually plug a real device.
I wonder if there is any open software project that I can base my program on? The biggest challenges are obviously
Providing/developing a "virtual" (USB/SD) mass storage device
Intercepting file I/O operations on the special device file.
According to Wikipedia, device files are a common way to simplify driver development. So I wondered if there are existing emulation solutions for driver developers. At least I couldn't find any.
Simulating the device file itself would be an important first step. My first idea was to use a normal file and to communicate with the client by actually reading/writing to this file while observing it. I.e. clear the file as soon as the client wrote to it and write the response into it. I don't know if this could work at all. One problem is that the client doesn't open the file with shared mode, so my simulator cannot access it at the same time.
Then I found out that QEMU can emulate mass storage, however it seems that it only supports image files and that probably doesn't allow device file.
Microsoft has some documentation about how to write USB device emulators and drivers but it seems to be very complex and I wondered if there is an exisiting solution that could be extended:
Finally there is the USB/IP Project, but I don't know if it is helpful as I still need to develop a driver and then I'm back at the complex MS documentation above.

What is the difference between formatting and mounting a file

From Wikipedia
Disk formatting
Disk formatting is the process of preparing a data storage device such as a hard disk drive, solid-state drive, floppy disk or USB flash drive for initial use.
Mount (computing)
Mounting is a process by which the operating system makes files and directories on a storage device (such as hard drive, CD-ROM, or network share) available for user to access via the computer's file system.
I don't understand how these two sentences are different
You format a device. You mount a filesystem.
Mounting a Filesystem
Typically, to make a device ready to be written to by the system, you'd have to do the following:
Physically connect the device to the system
(optional but recommended) Create a partition on your device
Create a filesystem on the device/partition
Mount the filesystem on the device/partition to a directory on your system's filesystem, so that you can access the filesystem of the device/partition from your system.
Formatting a Device
Therefore, every filesystem is backed by some block storage device. The storage medium of a block storage device (e.g. a hard disk) is divided into many sections, called sectors. Each sector has a unique address. Whenever you write to, or read from, the device, it is done by writing/reading whole sectors. Therefore, the sector is a smallest addressable physical unit for a block storage device.
When you format a device, you are adding 'marks' onto the storage medium to mark the location of these sectors.
Source of Confusion
Formatting has nothing to do with the filesystem, or mounting. The confusion often arise from Windows users, because on Windows, the term 'formatting' also includes the creation of the filesystem. On Windows, when you format a disk, you are also creating a filesystem on it (and Windows also automatically mount devices you connect).
To distinguish between Window's version of 'formatting', and actual formatting, people have used the term low-level formatting for actual formatting, and high-level formatting for creating the filesystem.
Formatting a disk or partition usually means that you're actually creating or have already created a volume, and it is the volume that you are formatting. Formatting a volume is to write an empty filesystem with the initialised filesystem structures like the MFT to the volume.
Mount has the notion of putting something on top of the other. But what is considered to be on top and what is considered to be at the bottom varies.
For mount points, the mount directory and the existing directory tree is considered to be on the bottom, and you mount the volume on top of / to the directory. This is despite the mount points actually being logically higher than the volume in the driver stack and the process of interacting with files. You sometimes see people say mounting the filesystem to the mount point, like the Linux df command. This makes sense because the file system is indeed logically between the volume and the mount point.
For mounting filesystems to volumes, the filesystem is on top and the volume is below. You mount the filesystem onto the volume. It is actually logically on top of the volume because on Windows it is consulted by the I/O Manager before the volume and it is up to the file system to interact with the volume stack.
On Windows, the volume is mounted to its mount points (C:\ if the symbolic link is \DosDevices\C:) and then you mount the file system to the volume by formatting the volume. Formatting the volume with a file system causes the file system driver to mount the volume. The file system will then mount itself to the volume every time the volume is detected 'arrives' on the system so long as it has been formatted with that file system because the file system driver detects its filesystem on the volume.
Formatting is usually done ONCE during the lifetime of the hard drive.
The hard drive is written to, wiping away anything that was on it previously, so that it can be accepted as a filesystem.
Mounting usually happens every time the system has been restarted. It allows the operating system to access the hard drive as a filesystem. Mounting a drive does NOT alter the hard drive, although once a filesystem has been mounted it can be modified (unless it was mounted read-only) by typical filesystem operations like creating a directory/folder, creating files, modifying files, etc ....
Mounting tells the operating system which filesystem type (ext3, ext4, HFS+, NTFS, ZFS ...) the hard drive is allowing the OS kernel to map the virtual filesystem functions to the real filesystem functions.

Waiting for all USB drives to load

I'm currently working with an application that has branching logic depending on whether a specific USB drive is inserted into the system. It does this by polling all drive letters looking for a path on the root of each drive.
This works for the majority of machines, but often, this application runs on startup with the USB drive inserted. In addition, some machines are especially slow and take a good minute to load the USB drive once Windows boots. In these machines, the code reaches the check of whether this drive exists, it can't find the drive, and the wrong branch is executed.
It could be possible to wait a minute before checking for drives. I'd prefer to have the application wait for all USB devices (or simply only mass storage devices) to load before checking for the drives, or something even more intelligent.
Unfortunately, I am unfamiliar with the methods needed to wait for all USB devices to finish loading, and with the DDK in general. I can see that it's possible to register a window for device notifications with GUID_DEVINTERFACE_USB_DEVICE, possibly receiving messages like DBT_DEVICEARRIVAL, DBT_DEVNODES_CHANGED, and WM_DEVICECHANGE, the distinctions of which I do not know.
However, the USB drive will likely be already inserted and detected (but not having a drive letter) into the system before the program executes. So, registering for all device change notifications would not make sense. If it's possible to identify devices which are inserted but not loaded (possibly with SetupDiEnumDeviceInterfaces) and then register for "loaded" notifications on all of those devices, it might work. I don't have familiarity with any this, so pointers (or sample code) would be extremely helpful.
I don't think you can.
The problem is that you're tyring to distinguish two cases which are not actually distinct, that of plugging in a USB device during boot and plugging it in later.
You have to know that USB is a protocol which requires a non-trivial amount of intelligence in the USB slave devices. They exchange multiple messages with the USB host (i.e. your OS). This exchange isn't instant. For instance, your USB harddrive will need to ask for permission to draw more than 100mA power. To answer that, the power drivers of Windows must be up and running. The phsyical disk can only spin up when the answer arrives.
So, there's a whole message sequence going on, and the drive letter shows up only fairly late. Windows must know how many partitions exist. So during this exchange, new devices are being created all the time.
When you enumerate devices while devices are actively being added, you're really asking for troubles. The SetupDiEnumDeviceInterfaces API doesn't operate on a snapshot (which we know because there's no Close method); you're asking for the N'th device until you get an "no more devices" error an you know N was to big. But when devices are still actively being added, N changes. And I don't see a guarantee that the list order is by age; devices might be added in the middle as well.
I don't think that getting notifications about drivers being installed for newly plugged-in devices would help you much. When you plug in the same device repeatedly, the drivers are usually installed only the first time.
Also, an USB flash drive, although physically looks like one compact device, is represented by at least three PnP devices by Windows: an USB mass storage device (represents the USB endpoint), a disk device (represents the physical disk inside the flash drive) and one or multiple Volume devices (each represents one volume = partition in your case). Drive letters may be assigned to the Volume devices.
What you can possibly do is monitoring the arrival and removal of Volume devices (RegisterDeviceNotification for GUID_DEVINTERFACE_VOLUME) and examining each volume device that arrives (I believe that Setup API allows you to track its "parents" to the USB stack).

What file system to use for an embedded linux with a eMMC NAND Flash

I'm in charge of choosing a file system for an embedded Linux device.
The device is a Freescale iMX6 running with a eMMC NAND flash memory and a kernel v3.10.17.
I plan to partition the Flash as decribed below:
Partition #1: kernel - not mounted
Partition #2: rootfs - mounted at "/" in read-only mode
Partition #3: userdata - mounted at "/home" in read-write mode
"/var" and "/tmp" directories will be mounted as tmpfs.
In some previous embedded linux projects, I used to use UBIFS on NAND flashes that were not eMMC NAND flash.
Since eMMC NAND flashes include a wear leveling feature, UBIFS should not be used with them as UBIFS' wear leveling feature may interfere with the one used by the eMMC NAND flashes.
I was planning to use ext2 or ext3 for the Partition #2 (rootfs) and ext3 for the Partition #3. I was wondering if ext3 is robust enough so my data won't get corrupted easily after a power failure of a hardreset reboot.
Does anyone have a strong backgroung with all of this and could help me to figure out what file system would be the best ?
Thanks.
I use ext4 file-system on an eMMC device that contains user data in read/write mode on an embedded-linux system.
The system shuts down by hard-reset several times a day for months now. have not witnessed problems with data consistency yet.
cramfs and squashfs are popular for read-only embedded filesystems, because they are highly compressed in storage.
For read-write filesystems, the "normal" ones you might find on a standard Linux desktop install work well (ext3, ext4, etc.). Read about them and pick one that has a balance of overhead and error-correction, depending on what you need for your device.
For the most part the popularity of these filesystems is independent of the hardware you're using as storage -- drivers are used to actually write to the hardware; the filesystem is an abstraction layer above this.
Your comment about ubifs being inappropriate since the driver already does wear-levelling sounds correct to me. UBIFS is weird in that way. Other filesystems are pretty storage-agnostic.

Reading from usb as a comport

I'm quite a beginner in the embedded world, since I'm always at the "other side of the wire" as a SW engineer so please don't crucify me for a question that might seem silly.
When I'm working with a Bluetooth device that connects to the computer, it is usually presented as a virtual COM-port which I connect and read the data from using winapi. Now our embedded engineer presented me a device that sends the same data through a USB cable which also presents as a virtual comport at my system which I read the same (meaning, for me it is completely transparent).
Now I wonder, in any other devices that use a USB connection, I don't see the device as a comport (like a mouse, or a keyboard), yet the info is sent. Why there is a need in a comport in this case, and what other reading options available?
You should read some basic USB information.
The difference you've noticed is because USB supports something called "device classes", that basically control how the computer (the host) views the device.
One such class is "USB communications device" which often becomes a virtual COM port, for instance.
Another is the very commonly seen "USB mass storage device" which is what e.g. flash drives use.
A third is the one you mention for mouses and keyboards, which is called "USB human interface device".
Which class a particular device uses is communicated when it's first connected on the bus, so that the host can load the proper driver. You cannot magically force a device to switch classes, the class is typically a "hard" (non-modifiable) part of the device's implementation, chosen by the designers of the device.

Resources