Hi, I have one slow flash block device, which act as usb-mass storage device, and during the data transfer with windows PC, it will get ALLOW_MEDIUM_REMOVAL , and sync the file system cache, however, it takes too much time (by log about 10s) and the usb reset occurs. however, if the /proc/sys/vm_dirty_ratio changed from 20 to 0 or 4, everything is ok. I made some code change to defer the file cache flash for your review, currently the do_verify() and do_synchronize_cache() not touched. diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index b02ff32..7ddcc5c 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -1491,6 +1491,14 @@ static int do_start_stop(struct fsg_common *common) : 0; } +void fsg_lun_fsync_deferred_func(struct work_struct *work) +{ + struct fsg_lun *curlun = + container_of(work, struct fsg_lun, fsync_deferred_work); + + fsg_lun_fsync_sub(curlun); +} + static int do_prevent_allow(struct fsg_common *common) { struct fsg_lun *curlun = common->curlun; @@ -1510,7 +1518,7 @@ static int do_prevent_allow(struct fsg_common *common) } if (curlun->prevent_medium_removal && !prevent) - fsg_lun_fsync_sub(curlun); + schedule_work(&curlun->fsync_deferred_work); curlun->prevent_medium_removal = prevent; return 0; } @@ -2835,6 +2843,8 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, ? cfg->lun_name_format : "lun%d", i); + INIT_WORK(&curlun->fsync_deferred_work, + fsg_lun_fsync_deferred_func); rc = device_register(&curlun->dev); if (rc) { diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 0333cc5..c7266c0 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -1853,6 +1853,13 @@ static int do_start_stop(struct fsg_dev *fsg) return 0; } +void fsg_lun_fsync_deferred_func(struct work_struct *work) +{ + struct fsg_lun *curlun = + container_of(work, struct fsg_lun, fsync_deferred_work); + + fsg_lun_fsync_sub(curlun); +} static int do_prevent_allow(struct fsg_dev *fsg) { @@ -1871,7 +1878,7 @@ static int do_prevent_allow(struct fsg_dev *fsg) } if (curlun->prevent_medium_removal && !prevent) - fsg_lun_fsync_sub(curlun); + schedule_work(&curlun->fsync_deferred_work); curlun->prevent_medium_removal = prevent; return 0; } @@ -3420,6 +3427,8 @@ static int __init fsg_bind(struct usb_gadget *gadget) dev_set_drvdata(&curlun->dev, &fsg->filesem); dev_set_name(&curlun->dev,"%s-lun%d", dev_name(&gadget->dev), i); + INIT_WORK(&curlun->fsync_deferred_work, + fsg_lun_fsync_deferred_func); kref_get(&fsg->ref); rc = device_register(&curlun->dev); diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 840a4be..16bcb3d 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -250,6 +250,7 @@ struct fsg_lun { unsigned int blkbits; /* Bits of logical block size */ unsigned int blksize; /* logic block size of backing device */ struct device dev; + struct work_struct fsync_deferred_work; }; #define fsg_lun_is_open(curlun) ((curlun)->filp != NULL) thanks Yuping Luo -- 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