LINUX.ORG.RU

Получить текущий статус flock() из модуля ядра

 ,


0

2

Мне необходимо в модуле ядра определять, заблокирован или нет сейчас файл с помощью flock() . Пока в голову пришло только получить указатель на struct file_lock * из struct file *, но как это сделать?

ssize_t my_driver_write (struct file *filp, const char __user *data, size_t size, loff_t *pos) 
{    
    struct file_lock *fl = НУЖНАЯ_МНЕ_ФУНКЦИЯ(filp);
    if (fl->fl_type == F_UNLCK) { /* ура, файл разблокирован */ }
    return my_driver_write_deeper(data, size);
}

Ответ на: комментарий от gremlin_the_red

vfs_test_lock попробовал. Статус всегда F_UNLCK.

в kernel space:

ssize_t my_driver_write (struct file *filp, const char __user *data, size_t size, loff_t *pos) 
{    
    struct file_lock fl;
    if (vfs_test_lock(filp, &fl) return -1;
    if (fl->fl_type == F_UNLCK) 
        printk(KERN_ALERT "file unlocked");
    else
        printk(KERN_ALERT "file locked");
    return 0;
}

в user space:

    int fd = open(my_device, O_RDWR)
    printf("write: %d\n", write(fd, data, 1)); // выдаёт "file unlocked"
    if (flock(fd, LOCK_EX)) printf("error\n");
    printf("write: %d\n", write(fd, data, 1)); // выдаёт "file unlocked", хотя ожидаю "file locked"
    if (flock(fd, LOCK_UN)) printf("error\n");
    close(fd);

Похоже, вот почему: https://stackoverflow.com/a/42884966/9710442

Как быть? Пока вот что придумал: в модуле добавить свой обработчик для int (*flock) (struct file *, int, struct file_lock *). Передаваемый в него fl->fl_type правильный (проверил), могу его сохранить в filp->private_data и потом проверять в write/read. Как из него вызвать обработчик flock «по-умолчанию», т.е. тот, который используется когда в «struct file_operations» не задаётся?

arhiv_6
() автор топика
Последнее исправление: arhiv_6 (всего исправлений: 4)

struct file_lock *fl = НУЖНАЯ_МНЕ_ФУНКЦИЯ(filp);

Такой функции нет и не может быть, т.к. файлу может соответствовать много локов (структур file_lock), с разными флагами, типами, пидами.

Список file_lock-ов, как правильно написал @metawishmaster, находится по адресу file->f_inode->i_flctx->flc_posix.

i586 ★★★★★
()