diff options
| author | ngkaho1234 <ngkaho1234@gmail.com> | 2016-01-30 23:26:22 +0800 |
|---|---|---|
| committer | ngkaho1234 <ngkaho1234@gmail.com> | 2016-01-30 23:26:22 +0800 |
| commit | 8929c98e42e81dce0b00d03a1c7b2f45ee85fe87 (patch) | |
| tree | 4105a1ca03e0c61983402e087d600e973e43faa9 /src | |
| parent | 9b40d089d6cf5912b558dd3e0ca1a246baa6750a (diff) | |
ext4: add read_only parameter to ext4_mount routine.
Now users can mount a filesystem as read-only mode explicitly.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ext4.c | 62 | ||||
| -rw-r--r-- | src/ext4_fs.c | 27 | ||||
| -rw-r--r-- | src/ext4_mkfs.c | 2 |
3 files changed, 77 insertions, 14 deletions
@@ -329,7 +329,8 @@ static int ext4_unlink(struct ext4_mountpoint *mp, /****************************************************************************/ -int ext4_mount(const char *dev_name, const char *mount_point) +int ext4_mount(const char *dev_name, const char *mount_point, + bool read_only) { ext4_assert(mount_point && dev_name); int r; @@ -375,7 +376,7 @@ int ext4_mount(const char *dev_name, const char *mount_point) if (r != EOK) return r; - r = ext4_fs_init(&mp->fs, bd); + r = ext4_fs_init(&mp->fs, bd, read_only); if (r != EOK) { ext4_block_fini(bd); return r; @@ -475,6 +476,9 @@ static int __ext4_journal_start(const char *mount_point) if (!mp) return ENOENT; + if (mp->fs.read_only) + return EOK; + if (ext4_sb_feature_com(&mp->fs.sb, EXT4_FCOM_HAS_JOURNAL)) { r = jbd_get_fs(&mp->fs, &mp->jbd_fs); @@ -502,6 +506,9 @@ static int __ext4_journal_stop(const char *mount_point) if (!mp) return ENOENT; + if (mp->fs.read_only) + return EOK; + if (ext4_sb_feature_com(&mp->fs.sb, EXT4_FCOM_HAS_JOURNAL)) { r = jbd_journal_stop(&mp->jbd_journal); @@ -893,6 +900,9 @@ static int ext4_generic_open2(ext4_file *f, const char *path, int flags, struct ext4_fs *const fs = &mp->fs; struct ext4_sblock *const sb = &mp->fs.sb; + if (fs->read_only && flags & O_CREAT) + return EROFS; + f->flags = flags; /*Skip mount point*/ @@ -1218,6 +1228,9 @@ int ext4_flink(const char *path, const char *hardlink_path) if (!mp) return ENOENT; + if (mp->fs.read_only) + return EROFS; + /* Will that happen? Anyway return EINVAL for such case. */ if (mp != target_mp) return EINVAL; @@ -1276,6 +1289,9 @@ int ext4_frename(const char *path, const char *new_path) if (!mp) return ENOENT; + if (mp->fs.read_only) + return EROFS; + EXT4_MP_LOCK(mp); ext4_trans_start(mp); @@ -1367,6 +1383,9 @@ int ext4_fremove(const char *path) if (!mp) return ENOENT; + if (mp->fs.read_only) + return EROFS; + EXT4_MP_LOCK(mp); ext4_trans_start(mp); @@ -1590,6 +1609,9 @@ int ext4_ftruncate(ext4_file *f, uint64_t size) int r; ext4_assert(f && f->mp); + if (f->mp->fs.read_only) + return EROFS; + if (f->flags & O_RDONLY) return EPERM; @@ -1623,6 +1645,9 @@ int ext4_fread(ext4_file *f, void *buf, size_t size, size_t *rcnt) ext4_assert(f && f->mp); + if (f->mp->fs.read_only) + return EROFS; + if (f->flags & O_WRONLY) return EPERM; @@ -1783,6 +1808,9 @@ int ext4_fwrite(ext4_file *f, const void *buf, size_t size, size_t *wcnt) ext4_assert(f && f->mp); + if (f->mp->fs.read_only) + return EROFS; + if (f->flags & O_RDONLY) return EPERM; @@ -1998,6 +2026,9 @@ int ext4_chmod(const char *path, uint32_t mode) if (!mp) return ENOENT; + if (mp->fs.read_only) + return EROFS; + EXT4_MP_LOCK(mp); ext4_trans_start(mp); @@ -2044,6 +2075,9 @@ int ext4_chown(const char *path, uint32_t uid, uint32_t gid) if (!mp) return ENOENT; + if (mp->fs.read_only) + return EROFS; + EXT4_MP_LOCK(mp); ext4_trans_start(mp); @@ -2087,6 +2121,9 @@ int ext4_file_set_atime(const char *path, uint32_t atime) if (!mp) return ENOENT; + if (mp->fs.read_only) + return EROFS; + EXT4_MP_LOCK(mp); ext4_trans_start(mp); @@ -2129,6 +2166,9 @@ int ext4_file_set_mtime(const char *path, uint32_t mtime) if (!mp) return ENOENT; + if (mp->fs.read_only) + return EROFS; + EXT4_MP_LOCK(mp); ext4_trans_start(mp); @@ -2171,6 +2211,9 @@ int ext4_file_set_ctime(const char *path, uint32_t ctime) if (!mp) return ENOENT; + if (mp->fs.read_only) + return EROFS; + EXT4_MP_LOCK(mp); ext4_trans_start(mp); @@ -2279,6 +2322,9 @@ int ext4_fsymlink(const char *target, const char *path) if (!mp) return ENOENT; + if (mp->fs.read_only) + return EROFS; + filetype = EXT4_DE_SYMLINK; EXT4_MP_LOCK(mp); @@ -2356,6 +2402,9 @@ int ext4_setxattr(const char *path, const char *name, size_t name_len, if (!mp) return ENOENT; + if (mp->fs.read_only) + return EROFS; + dissected_name = ext4_extract_xattr_name(name, name_len, &name_index, &dissected_len); if (!dissected_len) @@ -2545,6 +2594,9 @@ int ext4_removexattr(const char *path, const char *name, size_t name_len) if (!mp) return ENOENT; + if (mp->fs.read_only) + return EROFS; + dissected_name = ext4_extract_xattr_name(name, name_len, &name_index, &dissected_len); if (!dissected_len) @@ -2610,6 +2662,9 @@ int ext4_dir_rm(const char *path) if (!mp) return ENOENT; + if (mp->fs.read_only) + return EROFS; + EXT4_MP_LOCK(mp); struct ext4_fs *const fs = &mp->fs; @@ -2838,6 +2893,9 @@ int ext4_dir_mk(const char *path) if (!mp) return ENOENT; + if (mp->fs.read_only) + return EROFS; + EXT4_MP_LOCK(mp); ext4_trans_start(mp); diff --git a/src/ext4_fs.c b/src/ext4_fs.c index 392728d..7a97bc6 100644 --- a/src/ext4_fs.c +++ b/src/ext4_fs.c @@ -55,12 +55,12 @@ #include <string.h> -int ext4_fs_init(struct ext4_fs *fs, struct ext4_blockdev *bdev) +int ext4_fs_init(struct ext4_fs *fs, struct ext4_blockdev *bdev, + bool read_only) { int r, i; uint16_t tmp; uint32_t bsize; - bool read_only = false; ext4_assert(fs && bdev); @@ -82,7 +82,7 @@ int ext4_fs_init(struct ext4_fs *fs, struct ext4_blockdev *bdev) return r; if (read_only) - return ENOTSUP; + fs->read_only = true; /* Compute limits for indirect block levels */ uint32_t blocks_id = bsize / sizeof(uint32_t); @@ -104,14 +104,16 @@ int ext4_fs_init(struct ext4_fs *fs, struct ext4_blockdev *bdev) "last umount error: superblock fs_error flag\n"); - /* Mark system as mounted */ - ext4_set16(&fs->sb, state, EXT4_SUPERBLOCK_STATE_ERROR_FS); - r = ext4_sb_write(fs->bdev, &fs->sb); - if (r != EOK) - return r; + if (!fs->read_only) { + /* Mark system as mounted */ + ext4_set16(&fs->sb, state, EXT4_SUPERBLOCK_STATE_ERROR_FS); + r = ext4_sb_write(fs->bdev, &fs->sb); + if (r != EOK) + return r; - /*Update mount count*/ - ext4_set16(&fs->sb, mount_count, ext4_get16(&fs->sb, mount_count) + 1); + /*Update mount count*/ + ext4_set16(&fs->sb, mount_count, ext4_get16(&fs->sb, mount_count) + 1); + } return r; } @@ -123,7 +125,10 @@ int ext4_fs_fini(struct ext4_fs *fs) /*Set superblock state*/ ext4_set16(&fs->sb, state, EXT4_SUPERBLOCK_STATE_VALID_FS); - return ext4_sb_write(fs->bdev, &fs->sb); + if (!fs->read_only) + return ext4_sb_write(fs->bdev, &fs->sb); + + return EOK; } static void ext4_fs_debug_features_inc(uint32_t features_incompatible) diff --git a/src/ext4_mkfs.c b/src/ext4_mkfs.c index 5712ef3..e331c0d 100644 --- a/src/ext4_mkfs.c +++ b/src/ext4_mkfs.c @@ -740,7 +740,7 @@ int ext4_mkfs(struct ext4_fs *fs, struct ext4_blockdev *bd, if (r != EOK) goto cache_fini; - r = ext4_fs_init(fs, bd); + r = ext4_fs_init(fs, bd, false); if (r != EOK) goto cache_fini; |
