Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions file.c
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,9 @@ static ssize_t simplefs_write(struct file *file,
ssize_t bytes_write = 0;
loff_t pos = *ppos;

/* A zero-byte write makes callers such as dd retry forever. */
if (len && pos >= SIMPLEFS_MAX_FILESIZE)
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
Resolved
return -EFBIG;
if (pos > inode->i_size)
return 0;
len = min_t(size_t, len, SIMPLEFS_MAX_FILESIZE - pos);
Expand Down
8 changes: 0 additions & 8 deletions fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,6 @@ struct dentry *simplefs_mount(struct file_system_type *fs_type,
/* Unmount a simplefs partition */
void simplefs_kill_sb(struct super_block *sb)
{
struct simplefs_sb_info *sbi = SIMPLEFS_SB(sb);
#if SIMPLEFS_AT_LEAST(6, 9, 0)
if (sbi->s_journal_bdev_file)
fput(sbi->s_journal_bdev_file);
#elif SIMPLEFS_AT_LEAST(6, 7, 0)
if (sbi->s_journal_bdev_handle)
bdev_release(sbi->s_journal_bdev_handle);
#endif
kill_block_super(sb);

pr_info("unmounted disk\n");
Expand Down
4 changes: 2 additions & 2 deletions inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ struct inode *simplefs_iget(struct super_block *sb, unsigned long ino)
if (!inode)
return ERR_PTR(-ENOMEM);

/* If inode is in cache, return it */
/* If inode is in cache, return it */
#if SIMPLEFS_AT_LEAST(6, 19, 0)
if (!(inode_state_read_once(inode) & I_NEW))
/* inode->i_state is struct inode_state_flags in kernels v6.19 +,
Expand Down Expand Up @@ -784,7 +784,7 @@ static int simplefs_unlink(struct inode *dir, struct dentry *dentry)
if (S_ISLNK(inode->i_mode))
goto clean_inode;

/* Update inode stats */
/* Update inode stats */
#if SIMPLEFS_AT_LEAST(6, 7, 0)
simple_inode_init_ts(dir);
#elif SIMPLEFS_AT_LEAST(6, 6, 0)
Expand Down
2 changes: 1 addition & 1 deletion mkfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ static struct superblock *write_superblock(int fd, struct stat *fstats)
nr_blocks - nr_istore_blocks - nr_ifree_blocks - nr_bfree_blocks;

memset(sb, 0, sizeof(struct superblock));
sb->info = (struct simplefs_sb_info){
sb->info = (struct simplefs_sb_info) {
.magic = htole32(SIMPLEFS_MAGIC),
.nr_blocks = htole32(nr_blocks),
.nr_inodes = htole32(nr_inodes),
Expand Down
5 changes: 4 additions & 1 deletion script/test_large_file.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
# file too large
test_too_large_file() {
TESTLG_FILE_SZ=$(( $MAXFILESIZE / 1024 / 1024 + 1 ))
test_op "dd if=/dev/zero of=exceed_max_sz_file bs=1M count=$TESTLG_FILE_SZ status=none"
# writing past the limit must fail with EFBIG, not succeed or spin
if sudo sh -c "dd if=/dev/zero of=exceed_max_sz_file bs=1M count=$TESTLG_FILE_SZ status=none" 2>/dev/null; then
echo "Failed, write over the size limit succeeded"
fi
echo
filesize=$(sudo ls -lR | grep -e "$F_MOD 1".*file | awk '{print $5}')
test $filesize -le $MAXFILESIZE || echo "Failed, file size over the limit"
Expand Down
62 changes: 33 additions & 29 deletions super.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,16 +138,23 @@ static void simplefs_put_super(struct super_block *sb)
if (sbi->s_journal_bdev_file) {
sync_blockdev(file_bdev(sbi->s_journal_bdev_file));
invalidate_bdev(file_bdev(sbi->s_journal_bdev_file));
#if SIMPLEFS_AT_LEAST(7, 3, 0)
fs_bdev_file_release(sbi->s_journal_bdev_file, sb);
#else
fput(sbi->s_journal_bdev_file);
#endif
}
#elif SIMPLEFS_AT_LEAST(6, 7, 0)
if (sbi->s_journal_bdev_handle) {
sync_blockdev(sbi->s_journal_bdev_handle->bdev);
invalidate_bdev(sbi->s_journal_bdev_handle->bdev);
bdev_release(sbi->s_journal_bdev_handle);
}
#elif SIMPLEFS_AT_LEAST(6, 6, 0)
if (sbi->s_journal_bdev) {
sync_blockdev(sbi->s_journal_bdev);
invalidate_bdev(sbi->s_journal_bdev);
blkdev_put(sbi->s_journal_bdev, sb);
}
#elif SIMPLEFS_AT_LEAST(6, 5, 0)
if (sbi->s_journal_bdev) {
Expand All @@ -165,11 +172,9 @@ static void simplefs_put_super(struct super_block *sb)
}
#endif

if (sbi) {
kfree(sbi->ifree_bitmap);
kfree(sbi->bfree_bitmap);
kfree(sbi);
}
kfree(sbi->ifree_bitmap);
kfree(sbi->bfree_bitmap);
kfree(sbi);
}

static int simplefs_sync_fs(struct super_block *sb, int wait)
Expand Down Expand Up @@ -401,7 +406,7 @@ static journal_t *simplefs_get_dev_journal(struct super_block *sb,
#elif SIMPLEFS_AT_LEAST(5, 10, 0)
blkdev_put(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
#endif
return NULL;
return ERR_PTR(errno);
}

static int simplefs_load_journal(struct super_block *sb,
Expand Down Expand Up @@ -493,7 +498,7 @@ int simplefs_parse_param(struct fs_context *fc, struct fs_parameter *param)
static int simplefs_parse_options(struct super_block *sb, char *options)
{
substring_t args[MAX_OPT_ARGS];
int token, ret = 0, arg;
int token, ret = 0, arg = 0;
char *p;
char *journal_path;
struct inode *journal_inode;
Expand All @@ -512,7 +517,7 @@ static int simplefs_parse_options(struct super_block *sb, char *options)
case SIMPLEFS_OPT_JOURNAL_DEV:
if (args->from && match_int(args, &arg)) {
pr_err("simplefs_parse_options: match_int failed\n");
return 1;
return -EINVAL;
}
if ((ret = simplefs_load_journal(sb, arg))) {
pr_err(
Expand Down Expand Up @@ -543,15 +548,16 @@ static int simplefs_parse_options(struct super_block *sb, char *options)
if (S_ISBLK(journal_inode->i_mode)) {
unsigned long journal_devnum =
new_encode_dev(journal_inode->i_rdev);
if ((ret = simplefs_load_journal(sb, journal_devnum))) {
pr_err(
"simplefs_parse_options: simplefs_load_journal failed "
"with %d\n",
ret);
return ret;
}
ret = simplefs_load_journal(sb, journal_devnum);
}
path_put(&path);
if (ret) {
pr_err(
"simplefs_parse_options: simplefs_load_journal failed "
"with %d\n",
ret);
return ret;
}
break;
}
}
Expand Down Expand Up @@ -622,6 +628,7 @@ int simplefs_fill_super(struct super_block *sb, void *data, int silent)
sb->s_fs_info = sbi;

brelse(bh);
bh = NULL;

/* Allocate and copy ifree_bitmap */
sbi->ifree_bitmap =
Expand Down Expand Up @@ -689,7 +696,7 @@ inode_init_owner(root_inode, NULL, root_inode->i_mode);
sb->s_root = d_make_root(root_inode);
if (!sb->s_root) {
ret = -ENOMEM;
goto iput;
goto free_bfree;
}

#if SIMPLEFS_AT_LEAST(6, 18, 0)
Expand All @@ -705,24 +712,22 @@ inode_init_owner(root_inode, NULL, root_inode->i_mode);
}
if (ctx->journal_path) {
struct path path;
struct inode *inode;
ret = kern_path(ctx->journal_path, LOOKUP_FOLLOW, &path);
if (ret) {
pr_err("simplefs_parse_options: kern_path failed with error %d\n",
ret);
return ret;
}
inode = d_inode(path.dentry);
if (S_ISBLK(d_inode(path.dentry)->i_mode))
ret = simplefs_load_journal(
sb, new_encode_dev(d_inode(path.dentry)->i_rdev));
path_put(&path);
if (S_ISBLK(inode->i_mode)) {
unsigned long journal_devnum = new_encode_dev(inode->i_rdev);
if ((ret = simplefs_load_journal(sb, journal_devnum))) {
pr_err(
"simplefs_parse_options: simplefs_load_journal failed "
"with %d\n",
ret);
return ret;
}
if (ret) {
pr_err(
"simplefs_parse_options: simplefs_load_journal failed with "
"%d\n",
ret);
return ret;
}
}
#else
Expand All @@ -735,14 +740,13 @@ inode_init_owner(root_inode, NULL, root_inode->i_mode);
#endif
return 0;

iput:
iput(root_inode);
free_bfree:
kfree(sbi->bfree_bitmap);
free_ifree:
kfree(sbi->ifree_bitmap);
free_sbi:
kfree(sbi);
sb->s_fs_info = NULL;
release:
brelse(bh);

Expand Down
Loading