Skip to content

Split View: [운영체제] 13. 파일 시스템 인터페이스

|

[운영체제] 13. 파일 시스템 인터페이스

파일 시스템 인터페이스

파일 시스템은 운영체제에서 가장 눈에 띄는 부분 중 하나입니다. 사용자가 데이터를 저장하고 관리하는 논리적 인터페이스를 제공합니다. 이 글에서는 파일 개념, 접근 방법, 디렉토리 구조, 그리고 파일 보호 메커니즘을 살펴봅니다.


1. 파일 개념

파일은 보조 저장장치에 기록된 관련 정보의 이름 있는 집합입니다.

파일 속성

속성설명
이름(Name)사람이 읽을 수 있는 식별자
식별자(Identifier)파일 시스템 내 고유 번호 (inode 번호 등)
유형(Type)확장자 또는 매직 넘버로 식별
위치(Location)장치상 물리적 위치 포인터
크기(Size)현재 파일 크기 (바이트, 블록)
보호(Protection)읽기, 쓰기, 실행 권한
타임스탬프생성, 수정, 접근 시간
소유자(Owner)파일 소유 사용자

파일 연산

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main() {
    // 1. 파일 생성 및 열기
    int fd = open("example.txt", O_CREAT | O_WRONLY | O_TRUNC, 0644);
    if (fd == -1) {
        perror("open failed");
        return 1;
    }

    // 2. 파일 쓰기
    const char *data = "Hello, File System!";
    write(fd, data, 19);

    // 3. 파일 닫기
    close(fd);

    // 4. 읽기 모드로 다시 열기
    fd = open("example.txt", O_RDONLY);

    // 5. 파일 읽기
    char buffer[256];
    ssize_t bytes_read = read(fd, buffer, sizeof(buffer) - 1);
    buffer[bytes_read] = '\0';
    printf("읽은 내용: %s\n", buffer);

    // 6. 파일 위치 이동 (seek)
    lseek(fd, 0, SEEK_SET);  // 파일 시작으로 이동

    // 7. 파일 닫기
    close(fd);

    // 8. 파일 삭제
    unlink("example.txt");

    return 0;
}

오픈 파일 테이블

운영체제는 열린 파일을 관리하기 위해 테이블을 유지합니다.

프로세스 A                    프로세스 B
┌──────────────┐             ┌──────────────┐
│ fd 테이블    │             │ fd 테이블    │
0: stdin     │             │ 0: stdin     │
1: stdout    │             │ 1: stdout    │
2: stderr    │             │ 2: stderr    │
3: ─────────┐│             │ 3: ─────────┐│
└─────────────┘│             └─────────────┘│
               ↓                            ↓
        ┌──────────────────────────────────────┐
        │      시스템 전역 오픈 파일 테이블       │
        │ ┌─────────────────────────────────┐   │
        │ │ 파일 A: offset=100, refCount=1  │   │
        │ │ 파일 B: offset=0,   refCount=2  │ ← 공유│
        │ └─────────────────────────────────┘   │
        └──────────────────────────────────────┘
              ┌──────────────────┐
              │   inode 테이블    │
                (디스크 위치 등)              └──────────────────┘

2. 접근 방법

순차 접근 (Sequential Access)

파일의 처음부터 끝까지 순서대로 접근합니다. 테이프 모델에 기반합니다.

┌───┬───┬───┬───┬───┬───┬───┐
0123456 │  ← 레코드
└───┴───┴───┴───┴───┴───┴───┘
     현재 위치 포인터
     (앞으로만 이동하거나 되감기)
// 순차 접근 예시
FILE *fp = fopen("log.txt", "r");
char line[1024];

// 처음부터 끝까지 순서대로 읽기
while (fgets(line, sizeof(line), fp) != NULL) {
    printf("%s", line);
}

// 되감기 (처음으로)
rewind(fp);
fclose(fp);

직접 접근 (Direct / Random Access)

임의의 위치에 직접 접근할 수 있습니다. 디스크 모델에 기반합니다.

┌───┬───┬───┬───┬───┬───┬───┐
0123456 │  ← 블록 번호
└───┴───┴───┴───┴───┴───┴───┘
  ↑               ↑       ↑
  직접 접근 가능 (어느 블록이든)
// 직접 접근 예시 - 데이터베이스의 레코드 접근
#include <stdio.h>

typedef struct {
    int id;
    char name[50];
    double balance;
} Account;

// 특정 레코드 번호로 직접 접근
Account read_account(FILE *fp, int record_num) {
    Account acc;
    // 레코드 번호로 오프셋 계산하여 직접 이동
    fseek(fp, record_num * sizeof(Account), SEEK_SET);
    fread(&acc, sizeof(Account), 1, fp);
    return acc;
}

void write_account(FILE *fp, int record_num, Account *acc) {
    fseek(fp, record_num * sizeof(Account), SEEK_SET);
    fwrite(acc, sizeof(Account), 1, fp);
}

인덱스 접근

인덱스 파일을 통해 데이터 파일의 레코드를 찾는 방식입니다.

인덱스 파일:                     데이터 파일:
┌──────┬─────────┐              ┌─────────────────┐
│ 키   │ 포인터  │              │ 레코드 0├──────┼─────────┤        ┌───→│ Smith, 1000Kim  │ ──────────────┐  │    ├─────────────────┤
Lee  │ ────────────┐ │  │    │ 레코드 1Park │ ──────┐     │ │  │    │ Lee, 2000Smith│ ──────┼─────┼─┼──┘    ├─────────────────┤
└──────┴───────┘     │ │       │ 레코드 2                     │ └──────→│ Kim, 3000                     │         ├─────────────────┤
                     └────────→│ 레코드 3Park, 4000                               └─────────────────┘

3. 디렉토리 구조

디렉토리는 파일 이름을 해당 파일의 메타데이터로 매핑하는 테이블입니다.

단일 수준 디렉토리

┌──────────────────────────────────────┐
│             루트 디렉토리              │
│                                      │
│  cat  bo  a   test  data  mail  hex  │
│   │   │   │    │     │     │     │   │
│   ○   ○   ○    ○     ○     ○     ○   │
└──────────────────────────────────────┘
모든 파일이 같은 디렉토리에 존재
→ 이름 충돌 문제, 그룹화 불가

2단계 디렉토리

┌────────────────────────────────────┐
│          마스터 파일 디렉토리        │
│                                    │
│   user1        user2       user3   │
│     │            │           │     │
│  ┌──┴──┐     ┌──┴──┐    ┌──┴──┐  │
│  │ UFD │     │ UFD │    │ UFD │  │
│  │cat a│     │cat b│    │  a  │  │
│  └─────┘     └─────┘    └─────┘  │
└────────────────────────────────────┘
사용자별 별도 디렉토리 → 이름 충돌 해결

트리 구조 디렉토리

현대 파일 시스템의 기본 구조입니다.

              / (루트)
            ╱   │    ╲
         home  etc    var
        ╱   ╲   │      │
     user1 user2 passwd log
      │      │          │
    docs   code      syslog
    │  │     │
  a.txt b.txt main.c
# 트리 구조에서의 경로
# 절대 경로: 루트부터 시작
/home/user1/docs/a.txt

# 상대 경로: 현재 디렉토리 기준
# 현재 디렉토리가 /home/user1 일 때
docs/a.txt

비순환 그래프 디렉토리

파일이나 디렉토리를 여러 곳에서 공유할 수 있습니다. (하드 링크, 심볼릭 링크)

         /
      home
     ╱    ╲
  user1   user2
    │       │
  shared ──┘  (심볼릭 링크 또는 하드 링크)
  project
// 하드 링크 생성 (같은 inode를 가리킴)
#include <unistd.h>

int main() {
    // 하드 링크: 동일한 inode에 대한 새 이름
    link("/home/user1/shared/project",
         "/home/user2/project");

    // 심볼릭(소프트) 링크: 경로명을 가리키는 특수 파일
    symlink("/home/user1/shared/project",
            "/home/user2/project_link");

    return 0;
}

하드 링크 vs 심볼릭 링크

특성하드 링크심볼릭 링크
inode원본과 동일별도 inode
파일 시스템 간불가가능
디렉토리 링크불가 (루프 방지)가능
원본 삭제 시데이터 유지깨진 링크
크기디렉토리 엔트리만경로명 크기

4. 파일 공유

다중 사용자 환경에서의 파일 공유

사용자 A (소유자)
    ├── 파일 X (읽기/쓰기/실행)
    │      │
    │      ├── 사용자 B (그룹) → 읽기/실행
    │      │
    │      └── 기타 사용자 → 읽기만
    └── 그룹: developers

파일 잠금 (File Locking)

#include <fcntl.h>
#include <unistd.h>

int main() {
    int fd = open("shared_data.txt", O_RDWR);

    struct flock lock;
    lock.l_type   = F_WRLCK;    // 쓰기 잠금
    lock.l_whence = SEEK_SET;
    lock.l_start  = 0;          // 시작 오프셋
    lock.l_len    = 0;          // 전체 파일

    // 잠금 획득 (다른 프로세스는 대기)
    fcntl(fd, F_SETLKW, &lock);

    // 파일 작업 수행
    write(fd, "critical data", 13);

    // 잠금 해제
    lock.l_type = F_UNLCK;
    fcntl(fd, F_SETLK, &lock);

    close(fd);
    return 0;
}

잠금 유형

유형설명호환성
공유 잠금 (Read Lock)여러 프로세스가 동시 읽기 가능공유 잠금끼리 호환
배타 잠금 (Write Lock)하나의 프로세스만 접근 가능모든 잠금과 비호환
강제 잠금 (Mandatory)커널이 강제 적용시스템 의존
권고 잠금 (Advisory)프로세스가 자발적 준수POSIX 기본

5. 보호 (Protection)

접근 제어 리스트 (ACL)

파일: /project/secret.txt

ACL (Access Control List):
┌──────────┬─────────────────┐
│ 사용자   │ 권한             │
├──────────┼─────────────────┤
│ admin    │ 읽기, 쓰기, 실행 │
│ user1    │ 읽기, 쓰기       │
│ user2    │ 읽기             │
│ group:dev│ 읽기, 실행       │
│ others    (없음)└──────────┴─────────────────┘

UNIX 권한 모델

UNIX는 소유자(owner), 그룹(group), 기타(others)의 3가지 범주와 읽기(r), 쓰기(w), 실행(x)의 3가지 권한을 조합합니다.

$ ls -l example.txt
-rwxr-x--- 1 user1 developers 1024 Mar 19 10:00 example.txt

 │││││││││
 │├┤├┤├┤
 │ │ │ └── others:  --- (권한 없음)
 │ │ └──── group:   r-x (읽기, 실행)
 │ └────── owner:   rwx (읽기, 쓰기, 실행)
 └──────── 파일 유형: - (일반 파일)
#include <sys/stat.h>

int main() {
    // 8진수로 권한 설정
    // 7=rwx, 5=r-x, 0=---
    chmod("example.txt", 0750);

    // 소유자 변경
    chown("example.txt", 1000, 100);  // uid=1000, gid=100

    // 새 파일 생성 시 기본 권한 마스크
    umask(0022);  // 기본 권한에서 group/others의 쓰기 제거

    return 0;
}

특수 권한 비트

비트심볼효과
setuids (소유자 실행)실행 시 파일 소유자 권한으로 실행
setgids (그룹 실행)실행 시 파일 그룹 권한으로 실행
sticky bitt (기타 실행)디렉토리 내 파일은 소유자만 삭제 가능
# setuid 설정 예시 (passwd 명령어)
# 일반 사용자도 root 소유 파일을 수정 가능
$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 68208 ... /usr/bin/passwd
    ^
    setuid 비트 설정됨

# sticky bit 설정 예시 (/tmp 디렉토리)
$ ls -ld /tmp
drwxrwxrwt 15 root root 4096 ... /tmp
         ^
         sticky bit 설정됨

6. 정리

  • 파일 개념: 이름 있는 정보 집합으로, 속성과 연산이 정의됨
  • 접근 방법: 순차(테이프 모델), 직접(디스크 모델), 인덱스 접근
  • 디렉토리 구조: 단일 수준에서 비순환 그래프까지 발전. 현대 시스템은 트리 + 링크
  • 파일 공유: 잠금 메커니즘(공유/배타, 강제/권고)으로 동시 접근 관리
  • 보호: UNIX 권한 모델(rwx, owner/group/others)과 ACL로 접근 제어
퀴즈: 파일 시스템 인터페이스

Q1. 하드 링크와 심볼릭 링크의 차이점을 설명하세요.

A1. 하드 링크는 원본 파일과 동일한 inode를 공유하므로 원본이 삭제되어도 데이터에 접근할 수 있습니다. 심볼릭 링크는 별도의 inode를 가지며 경로명을 저장하므로, 원본이 삭제되면 깨진 링크가 됩니다. 하드 링크는 파일 시스템 경계를 넘을 수 없고 디렉토리에 적용할 수 없지만, 심볼릭 링크는 두 가지 모두 가능합니다.

Q2. UNIX 파일 권한 0754는 어떤 의미인가요?

A2. 소유자(7=rwx): 읽기, 쓰기, 실행 모두 가능. 그룹(5=r-x): 읽기와 실행 가능, 쓰기 불가. 기타(4=r--): 읽기만 가능.

Q3. sticky bit의 용도는 무엇인가요?

A3. sticky bit이 디렉토리에 설정되면, 해당 디렉토리 내의 파일은 파일의 소유자, 디렉토리의 소유자, 또는 root만 삭제할 수 있습니다. /tmp 디렉토리에 설정되어 모든 사용자가 파일을 만들 수 있지만 다른 사용자의 파일은 삭제할 수 없게 합니다.

[OS Concepts] 13. File-System Interface

File-System Interface

The file system is one of the most visible parts of the operating system. It provides the logical interface through which users store and manage data. This article examines file concepts, access methods, directory structures, and file protection mechanisms.


1. File Concepts

A file is a named collection of related information recorded on secondary storage.

File Attributes

AttributeDescription
NameHuman-readable identifier
IdentifierUnique number within the file system (inode, etc.)
TypeIdentified by extension or magic number
LocationPointer to physical location on device
SizeCurrent file size (bytes, blocks)
ProtectionRead, write, execute permissions
TimestampsCreation, modification, access times
OwnerUser who owns the file

File Operations

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main() {
    // 1. 파일 생성 및 열기
    int fd = open("example.txt", O_CREAT | O_WRONLY | O_TRUNC, 0644);
    if (fd == -1) {
        perror("open failed");
        return 1;
    }

    // 2. 파일 쓰기
    const char *data = "Hello, File System!";
    write(fd, data, 19);

    // 3. 파일 닫기
    close(fd);

    // 4. 읽기 모드로 다시 열기
    fd = open("example.txt", O_RDONLY);

    // 5. 파일 읽기
    char buffer[256];
    ssize_t bytes_read = read(fd, buffer, sizeof(buffer) - 1);
    buffer[bytes_read] = '\0';
    printf("읽은 내용: %s\n", buffer);

    // 6. 파일 위치 이동 (seek)
    lseek(fd, 0, SEEK_SET);  // 파일 시작으로 이동

    // 7. 파일 닫기
    close(fd);

    // 8. 파일 삭제
    unlink("example.txt");

    return 0;
}

Open File Table

The operating system maintains tables to manage open files.

Process A                    Process B
┌──────────────┐             ┌──────────────┐
│ fd table     │             │ fd table     │
0: stdin     │             │ 0: stdin     │
1: stdout    │             │ 1: stdout    │
2: stderr    │             │ 2: stderr    │
3: ─────────┐│             │ 3: ─────────┐│
└─────────────┘│             └─────────────┘│
               ↓                            ↓
        ┌──────────────────────────────────────┐
System-wide Open File Table        │ ┌─────────────────────────────────┐   │
        │ │ File A: offset=100, refCount=1  │   │
        │ │ File B: offset=0,   refCount=2  │ ← shared
        │ └─────────────────────────────────┘   │
        └──────────────────────────────────────┘
              ┌──────────────────┐
              │   inode table    │
               (disk location)              └──────────────────┘

2. Access Methods

Sequential Access

Accesses the file from beginning to end in order. Based on the tape model.

┌───┬───┬───┬───┬───┬───┬───┐
0123456 │  ← Records
└───┴───┴───┴───┴───┴───┴───┘
     Current position pointer
     (moves forward or rewinds)
// 순차 접근 예시
FILE *fp = fopen("log.txt", "r");
char line[1024];

// 처음부터 끝까지 순서대로 읽기
while (fgets(line, sizeof(line), fp) != NULL) {
    printf("%s", line);
}

// 되감기 (처음으로)
rewind(fp);
fclose(fp);

Direct Access (Random Access)

Allows direct access to any arbitrary position. Based on the disk model.

┌───┬───┬───┬───┬───┬───┬───┐
0123456 │  ← Block numbers
└───┴───┴───┴───┴───┴───┴───┘
  ↑               ↑       ↑
  Direct access possible (any block)
// 직접 접근 예시 - 데이터베이스의 레코드 접근
#include <stdio.h>

typedef struct {
    int id;
    char name[50];
    double balance;
} Account;

// 특정 레코드 번호로 직접 접근
Account read_account(FILE *fp, int record_num) {
    Account acc;
    // 레코드 번호로 오프셋 계산하여 직접 이동
    fseek(fp, record_num * sizeof(Account), SEEK_SET);
    fread(&acc, sizeof(Account), 1, fp);
    return acc;
}

void write_account(FILE *fp, int record_num, Account *acc) {
    fseek(fp, record_num * sizeof(Account), SEEK_SET);
    fwrite(acc, sizeof(Account), 1, fp);
}

Indexed Access

Finds records in the data file through an index file.

Index File:                      Data File:
┌──────┬─────────┐              ┌─────────────────┐
KeyPointer │              │ Record 0├──────┼─────────┤        ┌───→│ Smith, 1000Kim  │ ──────────────┐  │    ├─────────────────┤
Lee  │ ────────────┐ │  │    │ Record 1Park │ ──────┐     │ │  │    │ Lee, 2000Smith│ ──────┼─────┼─┼──┘    ├─────────────────┤
└──────┴───────┘     │ │       │ Record 2                     │ └──────→│ Kim, 3000                     │         ├─────────────────┤
                     └────────→│ Record 3Park, 4000                               └─────────────────┘

3. Directory Structure

A directory is a table that maps file names to their metadata.

Single-Level Directory

┌──────────────────────────────────────┐
Root Directory│                                      │
│  cat  bo  a   test  data  mail  hex  │
│   │   │   │    │     │     │     │   │
│   ○   ○   ○    ○     ○     ○     ○   │
└──────────────────────────────────────┘
All files in the same directory
Name collision issues, no grouping possible

Two-Level Directory

┌────────────────────────────────────┐
Master File Directory│                                    │
│   user1        user2       user3   │
│     │            │           │     │
│  ┌──┴──┐     ┌──┴──┐    ┌──┴──┐  │
│  │ UFD │     │ UFD │    │ UFD │  │
│  │cat a│     │cat b│    │  a  │  │
│  └─────┘     └─────┘    └─────┘  │
└────────────────────────────────────┘
Separate directory per user → resolves name collisions

Tree-Structured Directory

The basic structure of modern file systems.

              / (root)
            ╱   │    ╲
         home  etc    var
        ╱   ╲   │      │
     user1 user2 passwd log
      │      │          │
    docs   code      syslog
    │  │     │
  a.txt b.txt main.c
# 트리 구조에서의 경로
# 절대 경로: 루트부터 시작
/home/user1/docs/a.txt

# 상대 경로: 현재 디렉토리 기준
# 현재 디렉토리가 /home/user1 일 때
docs/a.txt

Acyclic-Graph Directory

Files or directories can be shared from multiple locations. (Hard links, symbolic links)

         /
      home
     ╱    ╲
  user1   user2
    │       │
  shared ──┘  (symbolic or hard link)
  project
// 하드 링크 생성 (같은 inode를 가리킴)
#include <unistd.h>

int main() {
    // 하드 링크: 동일한 inode에 대한 새 이름
    link("/home/user1/shared/project",
         "/home/user2/project");

    // 심볼릭(소프트) 링크: 경로명을 가리키는 특수 파일
    symlink("/home/user1/shared/project",
            "/home/user2/project_link");

    return 0;
}

Hard Link vs Symbolic Link

PropertyHard LinkSymbolic Link
inodeSame as originalSeparate
Cross FSNot possiblePossible
Directory linksNot allowed (loop)Allowed
Original deletedData preservedBroken link
SizeDirectory entryPath name

4. File Sharing

File Sharing in Multi-User Environments

User A (Owner)
    ├── File X (read/write/execute)
    │      │
    │      ├── User B (group) → read/execute
    │      │
    │      └── Others → read only
    └── Group: developers

File Locking

#include <fcntl.h>
#include <unistd.h>

int main() {
    int fd = open("shared_data.txt", O_RDWR);

    struct flock lock;
    lock.l_type   = F_WRLCK;    // 쓰기 잠금
    lock.l_whence = SEEK_SET;
    lock.l_start  = 0;          // 시작 오프셋
    lock.l_len    = 0;          // 전체 파일

    // 잠금 획득 (다른 프로세스는 대기)
    fcntl(fd, F_SETLKW, &lock);

    // 파일 작업 수행
    write(fd, "critical data", 13);

    // 잠금 해제
    lock.l_type = F_UNLCK;
    fcntl(fd, F_SETLK, &lock);

    close(fd);
    return 0;
}

Lock Types

TypeDescriptionCompatibility
Shared Lock (Read Lock)Multiple processes can read concurrentlyCompatible with shared
Exclusive Lock (Write)Only one process can accessIncompatible with all
Mandatory LockEnforced by the kernelSystem-dependent
Advisory LockProcesses comply voluntarilyPOSIX default

5. Protection

Access Control Lists (ACL)

File: /project/secret.txt

ACL (Access Control List):
┌──────────┬─────────────────┐
UserPermissions├──────────┼─────────────────┤
│ admin    │ read, write, exec│
│ user1    │ read, write      │
│ user2    │ read             │
│ group:dev│ read, exec       │
│ others    (none)└──────────┴─────────────────┘

UNIX Permission Model

UNIX combines three categories -- owner, group, and others -- with three permissions -- read (r), write (w), and execute (x).

$ ls -l example.txt
-rwxr-x--- 1 user1 developers 1024 Mar 19 10:00 example.txt

 │││││││││
 │├┤├┤├┤
 │ │ │ └── others:  --- (no permissions)
 │ │ └──── group:   r-x (read, execute)
 │ └────── owner:   rwx (read, write, execute)
 └──────── file type: - (regular file)
#include <sys/stat.h>

int main() {
    // 8진수로 권한 설정
    // 7=rwx, 5=r-x, 0=---
    chmod("example.txt", 0750);

    // 소유자 변경
    chown("example.txt", 1000, 100);  // uid=1000, gid=100

    // 새 파일 생성 시 기본 권한 마스크
    umask(0022);  // 기본 권한에서 group/others의 쓰기 제거

    return 0;
}

Special Permission Bits

BitSymbolEffect
setuids (owner exec)Runs with file owner's permissions
setgids (group exec)Runs with file group's permissions
sticky bitt (others exec)Only owner can delete files in the directory
# setuid 설정 예시 (passwd 명령어)
# 일반 사용자도 root 소유 파일을 수정 가능
$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 68208 ... /usr/bin/passwd
    ^
    setuid 비트 설정됨

# sticky bit 설정 예시 (/tmp 디렉토리)
$ ls -ld /tmp
drwxrwxrwt 15 root root 4096 ... /tmp
         ^
         sticky bit 설정됨

6. Summary

  • File Concepts: A named collection of information with defined attributes and operations
  • Access Methods: Sequential (tape model), direct (disk model), and indexed access
  • Directory Structure: Evolved from single-level to acyclic graphs. Modern systems use trees with links
  • File Sharing: Concurrent access managed through locking mechanisms (shared/exclusive, mandatory/advisory)
  • Protection: Access control via UNIX permission model (rwx, owner/group/others) and ACLs
Quiz: File-System Interface

Q1. Explain the differences between hard links and symbolic links.

A1. Hard links share the same inode as the original file, so data remains accessible even if the original is deleted. Symbolic links have a separate inode and store a path name, so they become broken links if the original is deleted. Hard links cannot cross file system boundaries or be applied to directories, but symbolic links can do both.

Q2. What does the UNIX file permission 0754 mean?

A2. Owner (7=rwx): read, write, and execute. Group (5=r-x): read and execute, no write. Others (4=r--): read only.

Q3. What is the purpose of the sticky bit?

A3. When the sticky bit is set on a directory, files within that directory can only be deleted by the file's owner, the directory's owner, or root. It is set on the /tmp directory so all users can create files but cannot delete other users' files.