2727#include <ccan/endian/endian.h>
2828
2929#include "ioctl.h"
30- #include "util.h"
31- #include "log.h"
3230#include "private.h"
3331
3432static int nvme_verify_chr (struct nvme_transport_handle * hdl )
@@ -100,17 +98,23 @@ int nvme_get_nsid(struct nvme_transport_handle *hdl, __u32 *nsid)
10098}
10199
102100__attribute__((weak ))
103- int nvme_submit_passthru (struct nvme_transport_handle * hdl ,
104- unsigned long ioctl_cmd , struct nvme_passthru_cmd * cmd ,
105- __u64 * result )
101+ void * nvme_submit_entry (struct nvme_transport_handle * hdl ,
102+ struct nvme_passthru_cmd * cmd )
106103{
107- int err = ioctl (hdl -> fd , ioctl_cmd , cmd );
104+ return NULL ;
105+ }
108106
109- if (err >= 0 && result )
110- * result = cmd -> result ;
111- if (err < 0 )
112- return - errno ;
113- return err ;
107+ __attribute__((weak ))
108+ void nvme_submit_exit (struct nvme_transport_handle * hdl ,
109+ struct nvme_passthru_cmd * cmd , int err , void * user_data )
110+ {
111+ }
112+
113+ __attribute__((weak ))
114+ bool nvme_decide_retry (struct nvme_transport_handle * hdl ,
115+ struct nvme_passthru_cmd * cmd , int err )
116+ {
117+ return false;
114118}
115119
116120/*
@@ -122,17 +126,29 @@ static int nvme_submit_passthru32(struct nvme_transport_handle *hdl,
122126 __u64 * result )
123127{
124128 struct linux_passthru_cmd32 cmd32 ;
125- int err ;
129+ void * user_data ;
130+ int err = 0 ;
131+
132+ user_data = nvme_submit_entry (hdl , cmd );
133+ if (hdl -> ctx -> dry_run )
134+ goto out ;
126135
127136 memcpy (& cmd32 , cmd , offsetof(struct linux_passthru_cmd32 , result ));
128137 cmd32 .result = 0 ;
129138
130- err = ioctl (hdl -> fd , ioctl_cmd , & cmd32 );
139+ do {
140+ err = ioctl (hdl -> fd , ioctl_cmd , & cmd32 );
141+ if (err >= 0 )
142+ break ;
143+ err = - errno ;
144+ } while (nvme_decide_retry (hdl , cmd , err ));
145+
146+ out :
131147 cmd -> result = cmd32 .result ;
132148 if (err >= 0 && result )
133149 * result = cmd -> result ;
134- if ( err < 0 )
135- return - errno ;
150+
151+ nvme_submit_exit ( hdl , cmd , err , user_data ) ;
136152 return err ;
137153}
138154
@@ -144,13 +160,29 @@ static int nvme_submit_passthru64(struct nvme_transport_handle *hdl,
144160 unsigned long ioctl_cmd , struct nvme_passthru_cmd * cmd ,
145161 __u64 * result )
146162{
147- int err ;
163+ void * user_data ;
164+ int err = 0 ;
165+
166+ user_data = nvme_submit_entry (hdl , cmd );
167+ if (hdl -> ctx -> dry_run )
168+ goto out ;
148169
149- err = ioctl (hdl -> fd , ioctl_cmd , cmd );
170+ do {
171+ /*
172+ * struct nvme_passtrhu_cmd is identically to struct
173+ * linux_passthru_cmd64, thus just pass it in directly.
174+ */
175+ err = ioctl (hdl -> fd , ioctl_cmd , cmd );
176+ if (err >= 0 )
177+ break ;
178+ err = - errno ;
179+ } while (nvme_decide_retry (hdl , cmd , err ));
180+
181+ out :
150182 if (err >= 0 && result )
151183 * result = cmd -> result ;
152- if ( err < 0 )
153- return - errno ;
184+
185+ nvme_submit_exit ( hdl , cmd , err , user_data ) ;
154186 return err ;
155187}
156188
0 commit comments