Skip to content

Commit 79a2831

Browse files
authored
Implement simplefs_file_ops:open (#56)
In the registration of simplefs_file_ops callbacks, there is no open operation, which may lead to creating unexpected space. This commit adds an open operation to handle file truncation when opening files with O_WRONLY, O_RDWR, and O_TRUNC flags. This prevents unintended space allocation by ensuring proper truncation of files. The implementation checks the flags associated with the file opening mode and performs truncation if the file is being opened for write or read/write and the O_TRUNC flag is set. Truncation is achieved by reading the file's index block from disk, iterating over the data block pointers, releasing the associated data blocks, and updating the inode metadata (size and block count). Close #55
1 parent 2ee1fc1 commit 79a2831

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

file.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,54 @@ static int simplefs_write_end(struct file *file,
245245
return ret;
246246
}
247247

248+
/*
249+
* Called when a file is opened in the simplefs.
250+
* It checks the flags associated with the file opening mode (O_WRONLY, O_RDWR,
251+
* O_TRUNC) and performs truncation if the file is being opened for write or
252+
* read/write and the O_TRUNC flag is set.
253+
*
254+
* Truncation is achieved by reading the file's index block from disk, iterating
255+
* over the data block pointers, releasing the associated data blocks, and
256+
* updating the inode metadata (size and block count).
257+
*/
258+
static int simplefs_file_open(struct inode *inode, struct file *filp)
259+
{
260+
bool wronly = (filp->f_flags & O_WRONLY);
261+
bool rdwr = (filp->f_flags & O_RDWR);
262+
bool trunc = (filp->f_flags & O_TRUNC);
263+
264+
if ((wronly || rdwr) && trunc && inode->i_size) {
265+
struct buffer_head *bh_index;
266+
struct simplefs_file_ei_block *ei_block;
267+
sector_t iblock;
268+
269+
/* Fetch the file's extent block from disk */
270+
bh_index = sb_bread(inode->i_sb, SIMPLEFS_INODE(inode)->ei_block);
271+
if (!bh_index)
272+
return -EIO;
273+
274+
ei_block = (struct simplefs_file_ei_block *) bh_index->b_data;
275+
276+
for (iblock = 0; iblock <= SIMPLEFS_MAX_EXTENTS &&
277+
ei_block->extents[iblock].ee_start;
278+
iblock++) {
279+
put_blocks(SIMPLEFS_SB(inode->i_sb),
280+
ei_block->extents[iblock].ee_start,
281+
ei_block->extents[iblock].ee_len);
282+
memset(&ei_block->extents[iblock], 0,
283+
sizeof(struct simplefs_extent));
284+
}
285+
/* Update inode metadata */
286+
inode->i_size = 0;
287+
inode->i_blocks = 1;
288+
289+
mark_buffer_dirty(bh_index);
290+
brelse(bh_index);
291+
mark_inode_dirty(inode);
292+
}
293+
return 0;
294+
}
295+
248296
const struct address_space_operations simplefs_aops = {
249297
#if SIMPLEFS_AT_LEAST(5, 19, 0)
250298
.readahead = simplefs_readahead,
@@ -262,4 +310,5 @@ const struct file_operations simplefs_file_ops = {
262310
.read_iter = generic_file_read_iter,
263311
.write_iter = generic_file_write_iter,
264312
.fsync = generic_file_fsync,
313+
.open = simplefs_file_open,
265314
};

0 commit comments

Comments
 (0)