을 호출할 때 함수 그래프를 추적해 보면 write()
함수 내부에서 호출에 의해 ext4_file_write_iter()
처음에 inode->i_rwsem
잠겨 있는 것을 발견했습니다. 그런 다음 파일에 데이터를 쓰기 위해 inode_lock(inode)
호출됩니다 . __generic_file_write_iter()
그리고 inode
마침내 잠금이 해제되었습니다.
그렇다면 inode->i_rwsem
동일한 파일에 대한 동시 쓰기를 보호하는 데 사용됩니까?
그런데 파일의 같은 영역에 동시에 데이터를 쓰는 프로그램을 작성했는데( pwrite(fd,buf,SIZE,0)
) 쓰기가 직렬화되지 않은 것으로 나타났습니다. .dll 파일에 따라 동시 쓰기를 직렬화하려면 flock
/를 사용해야 한다는 것을 알았습니다 .fcntl
inode->i_flctx
제가 묻고 싶은 것은 이것의 목적이 무엇입니까 inode->i_rwsem
?
inode->i_rwsem
이들 , inode->i_flctx
그리고 의 차이점은 무엇인가요 inode->i_lock
?
감사해요.
답변1
inode->i_rwsem
커널 자체가 손상이나 경쟁 조건을 피하기 위해 동시에 파일을 읽거나 쓰지 않도록 하기 위해 커널에서 내부적으로 사용됩니다. 사용자 공간에는 영향을 주지 않습니다. 동시에 여러 프로세스에서 읽고 쓸 수 있도록 파일을 열어 둘 수 있습니다. 그러나 여러 프로세스가 동시에 파일 읽기/쓰기를 시도하는 경우 커널은 실제로 뒤에서 이 작업을 순차적으로 수행합니다.
pwrite(fd,buf,SIZE,0)
귀하의 경우 내부 잠금 메커니즘(사용되는 것과 같은) 없이 동일한 영역에 쓰려고 하는 두 개의 프로세스가 있는 경우 i_rwsem
커널은 첫 번째 프로세스에서 일부 데이터를 쓰기 시작할 수 있으며 동시에 두 프로세스가 데이터 쓰기를 시작하지만 쓰기 작업이 없습니다.첫 번째프로세스가 완료되었습니다. 전체 파일 시스템의 무결성에 영향을 미치며 커널 패닉을 일으킬 수도 있습니다.경쟁 조건.
커널의 내부 잠금은 이러한 상황이 발생하는 것을 방지합니다. 첫 번째 프로세스의 첫 번째 쓰기는 두 번째 쓰기가 수행되기 전에 완료됩니다(둘 다 파일의 정확히 동일한 영역에 쓰는 경우 첫 번째 프로세스의 "쓰기"를 덮어쓸 수 있음).
inode->i_flctx
이미 발견했듯이 프로세스 자체가 동시에 파일을 열 수 있는 프로세스 수를 제한하려는 경우 flock
사용자 공간의 / 호출에 의해 제어됩니다. fcntl
예를 들어, 한 프로세스가 쓰기 위해 파일을 잠글 수 있으며, 다른 프로세스가 동일한 파일을 해제하기 전에 다른 프로세스가 파일을 잠그려고 하면 해당 파일이 거부되거나 차단됩니다.
동일한 파일에 쓰고 서로 다른 쓰기를 수행하는 두 프로세스의 예를 들어 보겠습니다. 각 프로세스는 다른 프로세스가 쓴 데이터를 덮어쓸 수 있습니다. 피하기 위해사용자 공간, 이것애플리케이션 자체flock
/는 fcntl
두 프로세스가 동일한 파일을 여는 것을 방지하는 데 사용할 수 있습니다 .
또 다른 예는 다음과 같습니다.
- 한 프로세스는 파일에 쓰고 두 번째 프로세스는 동일한 파일을 읽습니다.
- 첫 번째 프로세스가 아직 쓰기를 완료하지 않았기 때문에 두 번째 프로세스는 데이터의 일부를 읽을 수 있습니다.
이 경우 이를 방지하려면 다음을 수행하십시오.
- 첫 번째 프로세스는 쓰기가 완료될 때까지 다른 프로세스가 파일을 열지 못하도록 파일에 대한 잠금을 획득해야 합니다.
- 두 번째 프로세스는 동일한 파일에 대한 잠금을 얻으려고 시도하지만 이미 다른 프로세스에 의해 잠겨 있기 때문에 차단됩니다(또는 파일 잠금 시도에 따라 실패).
- 첫 번째 프로세스는 쓰기를 마치고 잠금을 해제합니다(다시 말하지만 명시적으로사용자 공간언급된 시스템 호출 중 하나를 호출하여)
- 그런 다음에만 두 번째 프로세스가 읽기 위해 파일을 잠글 수 있습니다.
- 두 번째 프로세스가 파일을 읽는 동안 파일 잠금을 획득하려는 다른 프로세스는 다음이 될 때까지 다시 차단됩니다.
- 읽기 과정을 통해 읽기가 완료됩니다.
따라서 flock
/를 사용하면 fcntl
이러한 상황을 처리할 수 있습니다.프로그래밍 방식으로애플리케이션의 소스 코드에서 커널은 i_flctx
프로세스가 파일에 대한 잠금을 획득했는지 확인하고 첫 번째 프로세스가 잠금을 해제할 때까지 다른 프로세스가 다른 잠금을 획득하지 못하도록 방지하는 데 사용됩니다.
inode->i_lock
, like 는 inode->i_rwsem
커널에서 inode 상태를 처리할 때 경쟁 조건으로부터 커널을 보호하기 위해 커널에서만 사용됩니다. inode 상태의 i_rwsem
쓰기 및 변경을 보호하는 데 사용됩니다 .i_lock
즉, 커널 개발자가 아닌 이상 커널 inode 구현 메커니즘의 일부인 또는 사용자 공간에서 파일을 잠그는 커널 내부 구현의 일부인 또는 중 하나 inode->i_lock
에 대해 걱정할 필요가 없습니다.inode->i_rwsem
inode->i_flctx