On Fri, 12 Aug 2011, Barry Song wrote: > From: Peiyu Li <peiyu.li@xxxxxxx> > > Now the mass storage driver has fixed logic block size of 512 bytes. > > The mass storage gadget read/write bound devices only through vfs, so the bottom level > devices actually are just RAW devices to the driver and connected PC. As a raw, hosts > can always format, read and write it right in 512 bytes logic block and don't care about > the actual logic block devices bound to the gadget. > > But if we want to share the bound block device partition between target board and PC, > in case the logic block size of the bound block device is 4KB, we execute the following > steps: > 1. connect a board with mass storage gadget to PC(the board has set one partition of > on-board block device as file name of the mass storage) > 2. PC format the mass storage to VFAT by default logic block size and read/write it > 3. disconnect boards from PC > 4. target board mount the partition as VFAT > Step 4 will fail since kernel on target thinks the logic block size of the bound partition > as 4KB. > A typical error is > "FAT: logical sector size too small for device (logical sector size = 512)" > > If we execute opposite steps: > 1. format the partion to FAT on target board and read/write this partition > 2. connect the board to Windows PC as usb mass storage gadget, windows will think the disk > is not formatted > > So the conclusion is that only as a gadget, the mass storage driver has no any problem. > But being shared VFAT or other filesystem on PC and target board, it will fail. > > This patch adapts logic block size to bound block devices and fix the issue. ... > @@ -580,7 +581,9 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) > rc = (int) size; > goto out; > } > - num_sectors = size >> 9; /* File size in 512-byte blocks */ > + curlun->l_blkbits = blksize_bits( > + bdev_logical_block_size(inode->i_bdev)); Will this work if the backing file is not a block device? What if it's just a regular file? As long as you're doing this, you might as well store (1 << l_blkbits) in curlun too, instead of recomputing it all the time. > + num_sectors = size >> curlun->l_blkbits; /* File size in logic-block-size blocks */ > min_sectors = 1; > if (curlun->cdrom) { > num_sectors &= ~3; /* Reduce to a multiple of 2048 */ And as long as you're using variable logical block sizes, you might as well set l_blkbits here to 11, because cdroms always use a block size of 2048. Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html