Jump to content











Photo
- - - - -

Unmap requests sent to proxy

trim unmap

  • Please log in to reply
4 replies to this topic

#1 v77

v77

    Silver Member

  • Team Reboot
  • 602 posts
  •  
    France

Posted 27 June 2016 - 11:05 PM

I would like to know what kind of structure we get with these requests. I found nothing about that.

(I am trying to choose between the TRIM and FSCTL_GET_VOLUME_BITMAP for the dynamic ramdisks of ImDisk Toolkit, there are advantages in both sides)



#2 Olof Lagerkvist

Olof Lagerkvist

    Gold Member

  • Developer
  • 1448 posts
  • Location:Borås, Sweden
  •  
    Sweden

Posted 28 June 2016 - 10:58 AM

I started documenting the proxy message formats a while ago but never finished, but I should definitely do that.

 

In short, the unmap and zero requests are a number of DEVICE_DATA_SET_RANGE structures (defined in ntddstor.h) passed in the data area of the message. Header is basically the usual proxy header:

uint64 request_code;

uint64 length;

 

This structure is defined as IMDPROXY_UNMAP_REQ in the header file.

 

Where request_code is either of IMDPROXY_REQ_UNMAP or IMDPROXY_REQ_ZERO in this case. The length field indicates total size in bytes of valid data passed in the data area, that is the DEVICE_DATA_SET_RANGE structures.

 

Response is called IMDPROXY_UNMAP_RESP:

uint64 error_code;

 

(Set to zero.)

 

I would recommend that you respond quickly to these messages and queue work to some worker thread. There usually arrive several TRIM/UNMAP requests within a small amount of time (within a few seconds or so) so for some implementations it could also make sense to create a queue and work through them after a few seconds. But that depends of course on how you handle them internally.



#3 v77

v77

    Silver Member

  • Team Reboot
  • 602 posts
  •  
    France

Posted 28 June 2016 - 11:57 AM

Sorry I was not clear. Of course, I already seen the proxy structures in imdproxy.h. I was speaking only of what we get as data.
I now understand better why I have got only one unmap request when I tried to delete a fragmented file.

It remains a question: even if it's very unlikely to happen, especially for a ramdisk, what happens if the shared memory buffer is not large enough to hold all the DEVICE_DATA_SET_RANGE structures?
 

 

I would recommend that you respond quickly to these messages and queue work to some worker thread. There usually arrive several TRIM/UNMAP requests within a small amount of time (within a few seconds or so) so for some implementations it could also make sense to create a queue and work through them after a few seconds. But that depends of course on how you handle them internally.

 

Thanks for the remark. In my case (ramdisk), a few seconds is huge. But even in the case where we take too much time, the requests are not lost, right?



#4 Olof Lagerkvist

Olof Lagerkvist

    Gold Member

  • Developer
  • 1448 posts
  • Location:Borås, Sweden
  •  
    Sweden

Posted 29 June 2016 - 09:34 PM

Sorry I was not clear. Of course, I already seen the proxy structures in imdproxy.h. I was speaking only of what we get as data.
I now understand better why I have got only one unmap request when I tried to delete a fragmented file.


Internally in filesystem drivers, things like these are queued on worker threads and dispatched in background to not affect performance of actual read and write requests. So when sent, they are not anymore connected to a particular file deletion operation. This also means that in many cases you can see requests to unmap ranges that have been allocated by different files as one single request and you can see ranges allocated by one single file split into several requests.
 

It remains a question: even if it's very unlikely to happen, especially for a ramdisk, what happens if the shared memory buffer is not large enough to hold all the DEVICE_DATA_SET_RANGE structures?


I have never seen actual IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES requests sent with more than a few hundred bytes of data structures in one single request, so our proxy buffer size is not even close to the maximum size needed. If for some reason a larger request would arrive it would be denied by the driver and lost. I could of course easily change the driver code to split such requests if we notice larger requests somewhere, but so far I have seen nothing even close to the buffer sizes we normally use for proxies.
 

Thanks for the remark. In my case (ramdisk), a few seconds is huge. But even in the case where we take too much time, the requests are not lost, right?


Of course seconds is a huge amount of time for actual read/write requests, but is that really a huge amount of time for handling trim operations and unallocating ranges? Anyway, my point here was that I would recommend that you respond quickly to trim requests because otherwise the driver will need to queue read and write requests while your proxy service spends time handling a trim request. Nothing is lost of course, but it degrades performance in general if the proxy end is not ready when a read/write request arrives and the driver needs to wait for the proxy end to get ready.



#5 v77

v77

    Silver Member

  • Team Reboot
  • 602 posts
  •  
    France

Posted 29 June 2016 - 11:17 PM

I have never seen actual IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES requests sent with more than a few hundred bytes of data structures in one single request, so our proxy buffer size is not even close to the maximum size needed. If for some reason a larger request would arrive it would be denied by the driver and lost. I could of course easily change the driver code to split such requests if we notice larger requests somewhere, but so far I have seen nothing even close to the buffer sizes we normally use for proxies.


Yes, a test seems useless in these circumstances. Even if a request was lost, this would not affect data integrity.
 

Of course seconds is a huge amount of time for actual read/write requests, but is that really a huge amount of time for handling trim operations and unallocating ranges? Anyway, my point here was that I would recommend that you respond quickly to trim requests because otherwise the driver will need to queue read and write requests while your proxy service spends time handling a trim request. Nothing is lost of course, but it degrades performance in general if the proxy end is not ready when a read/write request arrives and the driver needs to wait for the proxy end to get ready.

 

I already have some ideas for processing that in a very fast way.
If we use a dedicated thread, there is a risk of conflict with following write requests. Of course, with a good logic and synchronization objects, we can fix that, but in the case of a ramdisk, this would have a huge impact on performances, even when there is no unmap request to process.
However, this might be required for physical disk, so your warning is welcome.

 

 

Anyway, I now think to give up FSCTL_GET_VOLUME_BITMAP. It lacks some important informations so I have a bad feeling about that. The TRIM requests will be faster and more reliable, and there are now enough people who are using Windows 7 or later.
For others, the current method will still be available.


  • Olof Lagerkvist likes this




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users