@@ -19,7 +19,8 @@ my_bool my_may_have_atomic_write= IF_WIN(1,0);
19
19
20
20
#ifdef __linux__
21
21
22
- my_bool has_shannon_atomic_write = 0 , has_fusion_io_atomic_write = 0 ;
22
+ my_bool has_shannon_atomic_write = 0 , has_fusion_io_atomic_write = 0 ,
23
+ has_sfx_atomic_write = 0 ;
23
24
24
25
#include <sys/ioctl.h>
25
26
@@ -254,6 +255,109 @@ static my_bool shannon_has_atomic_write(File file, int page_size)
254
255
}
255
256
256
257
258
+ /***********************************************************************
259
+ ScaleFlux
260
+ ************************************************************************/
261
+
262
+ #define SFX_GET_ATOMIC_SIZE _IO('N', 0x244)
263
+ #define SFX_MAX_DEVICES 32
264
+ #define SFX_NO_ATOMIC_SIZE_YET -2
265
+
266
+ struct sfx_dev
267
+ {
268
+ char dev_name [32 ];
269
+ dev_t st_dev ;
270
+ int atomic_size ;
271
+ };
272
+
273
+ static struct sfx_dev sfx_devices [SFX_MAX_DEVICES + 1 ];
274
+
275
+ /**
276
+ Check if the system has a ScaleFlux card
277
+ If card exists, record device numbers to allow us to later check if
278
+ a given file is on this device.
279
+ @return TRUE Card exists
280
+ */
281
+
282
+ static my_bool test_if_sfx_card_exists ()
283
+ {
284
+ uint sfx_found_devices = 0 ;
285
+ uint dev_num ;
286
+
287
+ for (dev_num = 0 ; dev_num < SFX_MAX_DEVICES ; dev_num ++ )
288
+ {
289
+ struct stat stat_buff ;
290
+
291
+ sprintf (sfx_devices [sfx_found_devices ].dev_name , "/dev/sfdv%dn1" ,
292
+ dev_num );
293
+ if (lstat (sfx_devices [sfx_found_devices ].dev_name ,
294
+ & stat_buff ) < 0 )
295
+ break ;
296
+
297
+ sfx_devices [sfx_found_devices ].st_dev = stat_buff .st_rdev ;
298
+ /*
299
+ The atomic size will be checked on first access. This is needed
300
+ as a normal user can't open the /dev/sfdvXn1 file
301
+ */
302
+ sfx_devices [sfx_found_devices ].atomic_size = SFX_NO_ATOMIC_SIZE_YET ;
303
+ if (++ sfx_found_devices == SFX_MAX_DEVICES )
304
+ goto end ;
305
+ }
306
+ end :
307
+ sfx_devices [sfx_found_devices ].st_dev = 0 ;
308
+ return sfx_found_devices > 0 ;
309
+ }
310
+
311
+ static my_bool sfx_dev_has_atomic_write (struct sfx_dev * dev ,
312
+ int page_size )
313
+ {
314
+ if (dev -> atomic_size == SFX_NO_ATOMIC_SIZE_YET )
315
+ {
316
+ int fd = open (dev -> dev_name , 0 );
317
+ if (fd < 0 )
318
+ {
319
+ perror ("open() failed!" );
320
+ dev -> atomic_size = 0 ; /* Don't try again */
321
+ return FALSE;
322
+ }
323
+
324
+ dev -> atomic_size = ioctl (fd , SFX_GET_ATOMIC_SIZE );
325
+ close (fd );
326
+ }
327
+
328
+ return (page_size <= dev -> atomic_size );
329
+ }
330
+
331
+
332
+ /**
333
+ Check if a file is on a ScaleFlux device and that it supports atomic_write
334
+ @param[in] file OS file handle
335
+ @param[in] page_size page size
336
+ @return TRUE Atomic write supported
337
+
338
+ @notes
339
+ This is called only at first open of a file. In this case it's doesn't
340
+ matter so much that we loop over all cards.
341
+ We update the atomic size on first access.
342
+ */
343
+
344
+ static my_bool sfx_has_atomic_write (File file , int page_size )
345
+ {
346
+ struct sfx_dev * dev ;
347
+ struct stat stat_buff ;
348
+
349
+ if (fstat (file , & stat_buff ) < 0 )
350
+ {
351
+ return 0 ;
352
+ }
353
+
354
+ for (dev = sfx_devices ; dev -> st_dev ; dev ++ )
355
+ {
356
+ if (stat_buff .st_dev == dev -> st_dev )
357
+ return sfx_dev_has_atomic_write (dev , page_size );
358
+ }
359
+ return 0 ;
360
+ }
257
361
/***********************************************************************
258
362
Generic atomic write code
259
363
************************************************************************/
@@ -266,7 +370,8 @@ static my_bool shannon_has_atomic_write(File file, int page_size)
266
370
void my_init_atomic_write (void )
267
371
{
268
372
if ((has_shannon_atomic_write = test_if_shannon_card_exists ()) ||
269
- (has_fusion_io_atomic_write = test_if_fusion_io_card_exists ()))
373
+ (has_fusion_io_atomic_write = test_if_fusion_io_card_exists ()) ||
374
+ (has_sfx_atomic_write = test_if_sfx_card_exists ()))
270
375
my_may_have_atomic_write = 1 ;
271
376
#ifdef TEST_SHANNON
272
377
printf ("%s(): has_shannon_atomic_write=%d, my_may_have_atomic_write=%d\n" ,
@@ -294,6 +399,7 @@ my_bool my_test_if_atomic_write(File handle, int page_size)
294
399
#endif
295
400
if (!my_may_have_atomic_write )
296
401
return 0 ;
402
+
297
403
if (has_shannon_atomic_write &&
298
404
shannon_has_atomic_write (handle , page_size ))
299
405
return 1 ;
@@ -302,6 +408,10 @@ my_bool my_test_if_atomic_write(File handle, int page_size)
302
408
fusion_io_has_atomic_write (handle , page_size ))
303
409
return 1 ;
304
410
411
+ if (has_sfx_atomic_write &&
412
+ sfx_has_atomic_write (handle , page_size ))
413
+ return 1 ;
414
+
305
415
return 0 ;
306
416
}
307
417
0 commit comments