В связи с начавшейся разработкой использования протокола SMB2 в модуле CIFS надо перейти на модель разделённого суперблока, чтобы избежать потери валидности данных из-за различных айнодов на клиенте в рамках одной сесси для одного и того же файла на сервере.
Исследовал проблему. Получается, что сейчас без значительных переделок мы можем только расшаривать суперблок между несколькими точками монтирования, которые используют одну и ту же сессию. Если же устанавливается несколько сессий с одного клиента, что предложил менять каждый раз идентификатор клиента, чтобы сервер думал, что к нему подключились разные клиенты. Отправил сообщение в рассылку, чтобы согласовать данную переделку с апстрим.
Тред обсуждения: http://article.gmane.org/gmane.linux.kernel.cifs/2850.
Получил комментарии по своему предложению. После изучения выяснилось, что можно-таки использовать разделённый суперблок для разных сессий, но пока непонятно, как различать на конечном этапе, какое соединение использовать при работе с айнодами и элементами директорий. Можно попробовать различать по fsuid, но в таком случае мы упрёмся в ситуацию, когда один и тот же fsuid монтирует одну и ту же шару, но используя различные username. Проблема требует дальнейшего размышления - далее собираюсь оформить текущие соображения и отправить ответ в рассылку.
Продолжил исследование данного вопроса. Обсудил данный вопрос с Джефом Лэйтоном. Пока не видится возможным раличать шары при монтировании их один и тем же fsuid. Выхода два: 1) Разделять суперблок только для одного соединения. 2) Разделять суперблок для разных соединений, но только для разных fsuid. Дальше буду изучать, какой из вариантов будет предпочтительней выбрать в данной ситуации.
(В ответ на comment #4) > Продолжил исследование данного вопроса. Обсудил данный вопрос с Джефом > Лэйтоном. Пока не видится возможным раличать шары при монтировании их один и > тем же fsuid. Выхода два: > 1) Разделять суперблок только для одного соединения. > 2) Разделять суперблок для разных соединений, но только для разных fsuid. > > Дальше буду изучать, какой из вариантов будет предпочтительней выбрать в данной > ситуации. Второй вариант кажется не реализуемым в рамках данной архитектуры (без серьёзных переделок не только cifs, но и других частей ядра) - поэтому остановлюсь на первом варианте. Составил и написал письмо в рассылку.
Получил положительный ответ. Так же изучил спецификацию на счёт различия открытых дескрипторов одного и того же файла на сервере с разных суперблоков - предлагается менять LeaseKey для каждого такого файла. Написал об этом в рассылку.
Начал работу над реализацией: http://git.etersoft.ru/people/piastry/packages/?p=cifs-2.6.git;a=commitdiff;h=8465ca7be65b1d29726b09703986a93f84dc6241 Суперблок разделяется между точками монтирования, если параметры сессии, и //server/sharename совпадают. Далее займусь проверкой на совпадение опций монтирования.
Нашёл ошибки и поправил стиль: http://git.etersoft.ru/people/piastry/packages/?p=cifs-2.6.git;a=commitdiff;h=757240eb17085a5f93920b11a1b8a1416b379993
Добавил сравнения опций монтирования. Итоговый патч выглядит так: http://git.etersoft.ru/people/piastry/packages/?p=cifs-2.6.git;a=commitdiff;h=a9490870a1a14c07f5aa50dbb9931ceda9c8fb51 Отправил в рассылку.
Разбил патч на три, применив их поверх патчей DFS (которые сейчас находятся в почти законченном состоянии в рассылке, но ещё не апстрим): https://patchwork.kernel.org/patch/696451/ https://patchwork.kernel.org/patch/696461/ https://patchwork.kernel.org/patch/696471/
Получил комментарии по патчам. Требуется более общее решения для обработки prefixpath опции. Для этого предлагается завести один суперблок для //server/sharename, а потом выставлять различные root dentry для монтирования вида //server/sharename/foo, //server/sharename/foo/bar. Для этого потребуется полность переработать патчи 2 и 3.
Создал предварительную версию патча, удаляющую prefixpath логику и использующую суперблок на корневой каталог шары с последующим выставлением нужного mnt_root согласно prefixpath опции монтирования: http://git.etersoft.ru/people/piastry/packages/?p=cifs-2.6.git;a=commitdiff;h=ef3148d7d0c5b079ea19552714f02f500be15fcb
Переработал код и подготовил серию из четырёх патчей (переработал оригинальные патчи 2 (теперь 2) и 3 (теперь 4) и добавил новый (3)): http://git.etersoft.ru/people/piastry/packages/?p=cifs-2.6.git;a=shortlog;h=refs/heads/shared-sb Далее займусь более тщательным тестирование нового функионала.
Обнаружил и исправил ошибку в третьем патче - dentry соединялась с inode, но не помечалась как HASHED. Так же провёл небольшой рефакторинг кода.
В процессе тестирования обнаружил ошибку cifs в разборе опций монтирования (при разборе пароля возможен выход за границы массива, если следующий символ за массивом равен символу разделителя, что начало проявляться после того, как я применил патчи DFS). Создал патч, исправляющий это: http://git.etersoft.ru/people/piastry/packages/?p=cifs-2.6.git;a=commitdiff;h=f2834d26a747b2e6bc03aee88eb053c972e64753
Портировал предыдущий патч под бранч master и отправил в рассылку.
Согласно http://bugs.etersoft.ru/show_bug.cgi?id=6517#c23, переделал патчи shared-sb + обнаружил неточность в патчах (при переразбиении получилось так, что один промежуточный патч не компилился, что недопустимо для git bisect при обнаружении ошибок). Обновил обе ветки shared-sb (основана на for-2.6.40 бранче) и shared-sb-new (основана на for-next).
Отправил shared-sb в рассылку.
Патч, исправляющий ошибку в cifs_parse_mount_option, получил Reviewed-by.
багфикс в 2.6.39-rc5. Патчи относящиесяк реализации разделённого суперблока: 1, 2 - ok, 3 - ест замечания, надо поправить, 4 - пока не получил комментариев.
Исправил недочёты, применил патчи на ветку for-next (http://bugs.etersoft.ru/show_bug.cgi?id=6517#c37) в ветку share-sb-new: http://git.etersoft.ru/people/piastry/packages/?p=cifs-2.6.git;a=shortlog;h=refs/heads/shared-sb-new Отправил в рассылку вместе с пояснительным письмом.
Наложил патчи на текущую ветку master.
Провёл обсуждение патчей со Стивом Френчем - первые два патча в апстрим.
Синхронизировался с апстрим. Исправил конфликты слияния для третьего патча. Применил патчи #3 и #4 на ветку master и пометил как for-next. Протестировал с помощью connectathon test suite. Обновил ветки master и for-next на git.eter.
Обновил ветку for-next на git.eter с учётом изменений из патча: http://bugs.etersoft.ru/show_bug.cgi?id=6517#c45. Переработал #4 патч. В процессе обнаружил ошибку утечки памяти. После обсуждения со Стивом Френчем выяснилось, что данные патчи надо прокинуть поверх вновь пришедших в master патчей. Далее займусь этим.
Поправил патчи #3 и #4. Внёс в ветку for-next отправил в рассылку.
Обсудил логику обработки опции wsize в cifs_compare_mount_options. Поправил патч #4.
После обсуждения патчей, в процессе которого переотослал патч 4 с небольшими изменениями. #3 и #4 патчи в апстрим. Решено. http://git.kernel.org/?p=linux/kernel/git/sfrench/cifs-2.6.git;a=commit;h=f87d39d951329cd8f462bf9007d334122c0599d0 http://git.kernel.org/?p=linux/kernel/git/sfrench/cifs-2.6.git;a=commit;h=25c7f41e9234f60af30e086278f1de7974f8816f