0
# File and Directory Management
1
2
Operations for creating, removing, and modifying files and directories. These operations handle filesystem structure changes including file creation, deletion, linking, and renaming.
3
4
## Capabilities
5
6
### File Creation and Removal
7
8
Create and remove files and directories in the filesystem.
9
10
```python { .api }
11
def mknod(self, path, mode, dev):
12
"""
13
Create a file node (regular file, device file, etc.).
14
15
Args:
16
path (str): Path where to create the file
17
mode (int): File type and permissions (stat.S_IFREG | 0o644)
18
dev (int): Device number (for device files, usually 0)
19
20
Returns:
21
int: 0 on success, negative errno on error
22
"""
23
24
def create(self, path, mode, fi):
25
"""
26
Create and open a file atomically.
27
28
Args:
29
path (str): Path where to create the file
30
mode (int): File permissions
31
fi (FuseFileInfo): File info structure
32
33
Returns:
34
int: 0 on success, negative errno on error
35
"""
36
37
def mkdir(self, path, mode):
38
"""
39
Create a directory.
40
41
Args:
42
path (str): Path where to create directory
43
mode (int): Directory permissions (typically 0o755)
44
45
Returns:
46
int: 0 on success, negative errno on error
47
"""
48
49
def unlink(self, path):
50
"""
51
Remove a file.
52
53
Args:
54
path (str): Path to file to remove
55
56
Returns:
57
int: 0 on success, negative errno on error
58
"""
59
60
def rmdir(self, path):
61
"""
62
Remove a directory (must be empty).
63
64
Args:
65
path (str): Path to directory to remove
66
67
Returns:
68
int: 0 on success, negative errno on error
69
"""
70
```
71
72
**Usage Example:**
73
74
```python
75
def mknod(self, path, mode, dev):
76
if path in self.files:
77
return -errno.EEXIST
78
79
# Create regular file
80
if stat.S_ISREG(mode):
81
self.files[path] = b''
82
return 0
83
else:
84
return -errno.EPERM # Only support regular files
85
86
def mkdir(self, path, mode):
87
if path in self.dirs:
88
return -errno.EEXIST
89
90
# Check parent exists
91
parent = os.path.dirname(path)
92
if parent != '/' and parent not in self.dirs:
93
return -errno.ENOENT
94
95
self.dirs[path] = {}
96
return 0
97
98
def unlink(self, path):
99
if path not in self.files:
100
return -errno.ENOENT
101
102
del self.files[path]
103
return 0
104
```
105
106
### Linking Operations
107
108
Create and manage file links including symbolic and hard links.
109
110
```python { .api }
111
def symlink(self, target, path):
112
"""
113
Create a symbolic link.
114
115
Args:
116
target (str): Target path the symlink points to
117
path (str): Path where to create the symlink
118
119
Returns:
120
int: 0 on success, negative errno on error
121
"""
122
123
def readlink(self, path):
124
"""
125
Read the target of a symbolic link.
126
127
Args:
128
path (str): Path to symbolic link
129
130
Returns:
131
str: Target path that the symlink points to
132
int: Negative errno on error (e.g., -errno.ENOENT, -errno.EINVAL)
133
"""
134
135
def link(self, target, path):
136
"""
137
Create a hard link.
138
139
Args:
140
target (str): Existing file path
141
path (str): New link path
142
143
Returns:
144
int: 0 on success, negative errno on error
145
"""
146
```
147
148
**Usage Example:**
149
150
```python
151
def symlink(self, target, path):
152
if path in self.files or path in self.links:
153
return -errno.EEXIST
154
155
self.links[path] = target
156
return 0
157
158
def readlink(self, path):
159
if path not in self.links:
160
return -errno.ENOENT
161
162
return self.links[path]
163
164
def link(self, target, path):
165
if target not in self.files:
166
return -errno.ENOENT
167
168
if path in self.files:
169
return -errno.EEXIST
170
171
# Create hard link by sharing content
172
self.files[path] = self.files[target]
173
return 0
174
```
175
176
### File Movement and Renaming
177
178
Move and rename files and directories within the filesystem.
179
180
```python { .api }
181
def rename(self, old_path, new_path):
182
"""
183
Rename/move a file or directory.
184
185
Args:
186
old_path (str): Current path
187
new_path (str): New path
188
189
Returns:
190
int: 0 on success, negative errno on error
191
"""
192
```
193
194
**Usage Example:**
195
196
```python
197
def rename(self, old_path, new_path):
198
# Check if source exists
199
if old_path not in self.files and old_path not in self.dirs:
200
return -errno.ENOENT
201
202
# Check if destination parent exists
203
parent = os.path.dirname(new_path)
204
if parent != '/' and parent not in self.dirs:
205
return -errno.ENOENT
206
207
# Move file
208
if old_path in self.files:
209
if new_path in self.dirs:
210
return -errno.EISDIR
211
212
self.files[new_path] = self.files[old_path]
213
del self.files[old_path]
214
215
# Move directory
216
elif old_path in self.dirs:
217
if new_path in self.files:
218
return -errno.ENOTDIR
219
220
self.dirs[new_path] = self.dirs[old_path]
221
del self.dirs[old_path]
222
223
return 0
224
```
225
226
### File Handle Operations
227
228
Extended file operations that work with file handles for efficiency.
229
230
```python { .api }
231
def fgetattr(self, path, fh):
232
"""
233
Get file attributes using file handle.
234
235
Args:
236
path (str): Path to file
237
fh (int): File handle from open()
238
239
Returns:
240
Stat: File attributes object
241
int: Negative errno on error
242
"""
243
244
def ftruncate(self, path, size, fh):
245
"""
246
Truncate file using file handle.
247
248
Args:
249
path (str): Path to file
250
size (int): New file size
251
fh (int): File handle from open()
252
253
Returns:
254
int: 0 on success, negative errno on error
255
"""
256
```
257
258
**Usage Example:**
259
260
```python
261
def fgetattr(self, path, fh):
262
# Use file handle for more efficient attribute retrieval
263
return self.getattr(path)
264
265
def ftruncate(self, path, size, fh):
266
if path not in self.files:
267
return -errno.ENOENT
268
269
if size < len(self.files[path]):
270
self.files[path] = self.files[path][:size]
271
else:
272
self.files[path] += b'\0' * (size - len(self.files[path]))
273
274
return 0
275
```
276
277
## Advanced File Operations
278
279
### File Access Control
280
281
```python { .api }
282
def access(self, path, mode):
283
"""
284
Check file access permissions.
285
286
Args:
287
path (str): Path to file or directory
288
mode (int): Access mode to check (R_OK, W_OK, X_OK, F_OK)
289
290
Returns:
291
int: 0 if access granted, negative errno on error
292
"""
293
```
294
295
**Usage Example:**
296
297
```python
298
def access(self, path, mode):
299
if path not in self.files and path not in self.dirs:
300
return -errno.ENOENT
301
302
# Simple permission check (in real implementation, check actual permissions)
303
if mode & os.W_OK and path.startswith('/readonly'):
304
return -errno.EACCES
305
306
return 0
307
```
308
309
### Block Mapping
310
311
```python { .api }
312
def bmap(self, path, blocksize, idx):
313
"""
314
Map file block to filesystem block (for direct I/O).
315
316
Args:
317
path (str): Path to file
318
blocksize (int): Block size in bytes
319
idx (int): Block index in file
320
321
Returns:
322
int: Physical block number, or negative errno on error
323
"""
324
```
325
326
## Error Handling
327
328
File management operations commonly return these errors:
329
330
- `ENOENT`: File or directory not found
331
- `EEXIST`: File or directory already exists
332
- `ENOTDIR`: Component in path is not a directory
333
- `EISDIR`: Is a directory (when file expected)
334
- `ENOTEMPTY`: Directory not empty (for rmdir)
335
- `EXDEV`: Cross-device link (for link operations)
336
- `EACCES`: Permission denied
337
- `EPERM`: Operation not permitted
338
- `ENOSPC`: No space left on device
339
340
## Best Practices
341
342
- Always check parent directory existence before creating files/directories
343
- Ensure proper cleanup of resources when operations fail
344
- Handle atomic operations (like `create`) properly to avoid partial states
345
- Consider filesystem-specific constraints (maximum filename length, etc.)
346
- Implement proper reference counting for hard links
347
- Validate paths and handle edge cases (empty paths, root directory operations)