Я искал источник ядра для ядра linux 4.4.0-57-generic и не вижу никаких блокировок в источнике writev()
. Есть что-то, что мне не хватает? Я не вижу, как writev()
является атомарным или потокобезопасным.Атомность системного вызова writev() в Linux
ответ
Не эксперт в области ядра здесь, но я поделюсь своей точкой зрения в любом случае. Не стесняйтесь выявлять любые ошибки.
Просмотр ядра (v4.9, хотя я бы не ожидал, что это так отличается), и пытается проследить writev(2)
системный вызов, я могу наблюдать последующие вызовы функций, которые создают следующий путь:
Теперь путь ветви, в зависимости от того, реализуется и подключил на struct file_operations
поле struct file
, что системный вызов со ссылкой на метод write_iter
.
- Если это не
NULL
, путь:
5а. do_iter_readv_writev(..)
, который называет метод filp->f_op->write_iter(..)
at this point.
- Если
NULL
, путь:
5b. do_loop_readv_writev(..)
, который неоднократно вызывает в цикле метод filp->f_op->write
at this point.
Итак, насколько я понимаю, writev()
системный вызов как нить безопасно, так как лежащий в основе write()
(или write_iter()
) является, что, конечно, могут быть реализованы различными способами, например, в драйвере устройства и может или не может использовать блокировки в соответствии с его потребностями и его конструкцией.
EDIT:
В ядре v4.4 дорожки выглядят довольно похожи:
, а затем это зависит от того метода write_iter
как поле в struct file_operations
из struct file
- NULL
или нет, точно так же, как в случае, описанном выше в версии 4.9.
VFS (Virtual File System) самих по себе не гарантируетатомарности из writev()
вызова. Он просто вызывает метод .write_iter
с файловой системой struct file_operations
.
Это ответственности конкретной реализации файловой системы для метода делает атомарной записи в файл.
Например, в функции файловой системы ext4 ext4_file_write_iter использует
mutex_lock(&inode->i_mutex);
для макияжа сочинительство атомарным.
Нашел в fs.h:
static inline void file_start_write(struct file *file)
{
if (!S_ISREG(file_inode(file)->i_mode))
return;
__sb_start_write(file_inode(file)->i_sb, SB_FREEZE_WRITE, true);
}
, а затем в super.c:
/*
* This is an internal function, please use sb_start_{write,pagefault,intwrite}
* instead.
*/
int __sb_start_write(struct super_block *sb, int level, bool wait)
{
bool force_trylock = false;
int ret = 1;
#ifdef CONFIG_LOCKDEP
/*
* We want lockdep to tell us about possible deadlocks with freezing
* but it's it bit tricky to properly instrument it. Getting a freeze
* protection works as getting a read lock but there are subtle
* problems. XFS for example gets freeze protection on internal level
* twice in some cases, which is OK only because we already hold a
* freeze protection also on higher level. Due to these cases we have
* to use wait == F (trylock mode) which must not fail.
*/
if (wait) {
int i;
for (i = 0; i < level - 1; i++)
if (percpu_rwsem_is_held(sb->s_writers.rw_sem + i)) {
force_trylock = true;
break;
}
}
#endif
if (wait && !force_trylock)
percpu_down_read(sb->s_writers.rw_sem + level-1);
else
ret = percpu_down_read_trylock(sb->s_writers.rw_sem + level-1);
WARN_ON(force_trylock & !ret);
return ret;
}
EXPORT_SYMBOL(__sb_start_write);
Еще раз спасибо.
- 1. Создание системного вызова в Linux
- 2. Реализация системного вызова Linux 'socketcall'
- 3. Последовательность потока системного вызова Linux
- 4. Добавление системного вызова в ядро linux 3.8.8
- 5. магических чисел в Linux перезагрузки() системного вызова
- 6. Каков тип аргументов системного вызова в Linux?
- 7. Эквивалент системного вызова sync_file_range Linux в Windows?
- 8. Ограничение доступа системного вызова для приложения Linux
- 9. 64-разрядная версия системного вызова socketcall Linux
- 10. Что делает Linux при создании системного вызова?
- 11. Сборка ошибка сегментации Linux системного вызова
- 12. системного вызова() для вызова tkill()
- 13. Открытие открытого неиспользуемого порта и системного вызова ("/ dev/tty", ...) writev (7, [{"*** обнаружено glibc ***", 23}
- 14. Атомность гарантирована на методах «блокировки» в Linux?
- 15. измерение скорости системного вызова
- 16. Тестирование системного вызова в qemu
- 17. Изменение системного вызова
- 18. Поведение системного вызова fork() в Linux в этом коде
- 19. Написание нового системного вызова
- 20. Переключение системного вызова модуля ядра
- 21. более чем одной команды для системного вызова в Linux
- 22. Есть ли обратная операция для системного вызова vmsplice() в Linux?
- 23. Получить атрибут страниц с помощью системного вызова в Linux
- 24. Запустить вызовы системного вызова в Linux, C-программу?
- 25. Где функция системного вызова "sys_getpid" находится в ядре linux?
- 26. Добавление нового системного вызова в ядро Linux 3.3
- 27. Размер возвращаемого значения или тип системного вызова в Linux
- 28. Добавление нового системного вызова в ядро linux, похоже, не работает
- 29. Измерять время на C++ для команды системного вызова в Linux
- 30. Вызов системного вызова перед основным
Downvoter поможет объяснить, где ошибка? – chrk
Или кто-нибудь еще? Я в процессе изучения этого материала, и выявление любой ошибки было бы полезно. – chrk
Это тот самый путь, который я видел. Странно было тогда зависеть от метода записи под 'filp-> f_op-> write' для атомарности после того, как я прочитал этот writev (2): *** Передача данных, выполняемая readv() и writev(), является атомарной: * * данные, записанные writev(), записываются как один блок, который не смешивается с выводами из записей в других процессах (но см. pipe (7) для исключения); Аналогично, readv() гарантированно считывает непрерывный блок данных из файла, независимо от операций чтения, выполняемых в других потоках или процессах с файловыми дескрипторами. , , – C6Up1bQ73STi29cA