ref: 64d18a993fec0fc3d69e58514341d6afcea6c092
parent: f39e53151bfcbecdced66cf9fcec75a27507ee54
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Wed Feb 14 14:22:49 EST 2024
ext4srv: clean up and fix a couple bugs * replace nonsensical string matching with explicit mount point arg * fix ext4_fseek _subtracting_ the offset if seeking from the EOF * fix ext4_fwrite - always set the number of bytes written * remove symlink resolving - it's Plan 9. give up. * reduce the number of allocations
--- a/sys/man/4/ext4srv
+++ b/sys/man/4/ext4srv
@@ -4,7 +4,7 @@
.SH SYNOPSIS
.B ext4srv
[
-.B -Clrs
+.B -Crs
] [
.B -g
.I groupfile
@@ -95,11 +95,6 @@
in this case is
.IR 0 .
.PP
-Optional flag
-.B -l
-enables symlink resolving, otherwise symlinks are hidden by
-default entirely, as Plan 9 does not have that concept.
-.PP
Some file system state is cached in memory, and may
be flushed only when the file system is unmounted if
.B -C
@@ -133,6 +128,7 @@
Yes.
.PP
Permission checking is very basic and may not be complete.
+Symlinks are not resolved.
There may be many bugs.
It is advisable to use
.I ext4srv
--- a/sys/src/cmd/ext4srv/common.h
+++ b/sys/src/cmd/ext4srv/common.h
@@ -1,13 +1,9 @@
typedef struct Opts Opts;
typedef struct Part Part;
-#pragma varargck type "Ð" Part*
-#pragma varargck type "M" Part*
-
struct Opts {
char *group;
int cachewb;
- int linkmode;
int asroot;
int rdonly;
@@ -23,10 +19,9 @@
QLock;
Part *prev, *next;
- char dev[32];
- char mnt[32];
char *partdev;
+ struct ext4_mountpoint mp;
struct ext4_blockdev bdev;
struct ext4_blockdev_iface bdif;
struct ext4_sblock *sb;
@@ -36,11 +31,6 @@
Groups groups;
int f;
uchar blkbuf[];
-};
-
-enum {
- Lhide,
- Lresolve = 1,
};
Part *openpart(char *dev, Opts *opts);
--- a/sys/src/cmd/ext4srv/ext4.c
+++ b/sys/src/cmd/ext4srv/ext4.c
@@ -18,6 +18,14 @@
char Eperm[] = "permission denied";
char Erdonlyfs[] = "read-only fs";
+static char *
+basename(char *s)
+{
+ char *e;
+ e = utfrrune(s, '/');
+ return e == nil ? s : e+1;
+}
+
/**@brief Mount point OS dependent lock*/
#define EXT4_MP_LOCK(_m) \
do { \
@@ -32,98 +40,6 @@
(_m)->os_locks->unlock((_m)->os_locks->p_user); \
} while (0)
-/**@brief Mount point descriptor.*/
-struct ext4_mountpoint {
-
- /**@brief Mount done flag.*/
- bool mounted;
-
- /**@brief Mount point name (@ref ext4_mount)*/
- char name[CONFIG_EXT4_MAX_MP_NAME + 1];
-
- /**@brief OS dependent lock/unlock functions.*/
- const struct ext4_lock *os_locks;
-
- /**@brief Ext4 filesystem internals.*/
- struct ext4_fs fs;
-
- /**@brief JBD fs.*/
- struct jbd_fs jbd_fs;
-
- /**@brief Journal.*/
- struct jbd_journal jbd_journal;
-
- /**@brief Block cache.*/
- struct ext4_bcache bc;
-};
-
-/**@brief Block devices descriptor.*/
-struct ext4_block_devices {
-
- /**@brief Block device name.*/
- char name[CONFIG_EXT4_MAX_BLOCKDEV_NAME + 1];
-
- /**@brief Block device handle.*/
- struct ext4_blockdev *bd;
-};
-
-/**@brief Block devices.*/
-static struct ext4_block_devices s_bdevices[CONFIG_EXT4_BLOCKDEVS_COUNT];
-
-/**@brief Mountpoints.*/
-static struct ext4_mountpoint s_mp[CONFIG_EXT4_MOUNTPOINTS_COUNT];
-
-int ext4_device_register(struct ext4_blockdev *bd,
- const char *dev_name)
-{
- assert(bd && dev_name);
-
- if (strlen(dev_name) > CONFIG_EXT4_MAX_BLOCKDEV_NAME) {
- werrstr("dev name too long: %s", dev_name);
- return -1;
- }
-
- for (usize i = 0; i < CONFIG_EXT4_BLOCKDEVS_COUNT; ++i) {
- if (!strcmp(s_bdevices[i].name, dev_name)) {
- werrstr("dev already exists: %s", dev_name);
- return -1;
- }
- }
-
- for (usize i = 0; i < CONFIG_EXT4_BLOCKDEVS_COUNT; ++i) {
- if (!s_bdevices[i].bd) {
- strcpy(s_bdevices[i].name, dev_name);
- s_bdevices[i].bd = bd;
- return 0;
- }
- }
-
- werrstr("dev limit reached");
- return -1;
-}
-
-int ext4_device_unregister(const char *dev_name)
-{
- assert(dev_name);
-
- for (usize i = 0; i < CONFIG_EXT4_BLOCKDEVS_COUNT; ++i) {
- if (strcmp(s_bdevices[i].name, dev_name) == 0) {
- memset(&s_bdevices[i], 0, sizeof(s_bdevices[i]));
- return 0;
- }
- }
-
- werrstr("dev not found: %s", dev_name);
- return -1;
-}
-
-int ext4_device_unregister_all(void)
-{
- memset(s_bdevices, 0, sizeof(s_bdevices));
-
- return 0;
-}
-
static bool ext4_is_dots(const u8int *name, usize name_size)
{
if ((name_size == 1) && (name[0] == '.'))
@@ -270,8 +186,7 @@
static int ext4_unlink(struct ext4_mountpoint *mp,
struct ext4_inode_ref *parent,
- struct ext4_inode_ref *child, const char *name,
- u32int name_len)
+ struct ext4_inode_ref *child, const char *name)
{
bool has_children;
int rc = ext4_has_children(&has_children, child);
@@ -285,7 +200,8 @@
}
/* Remove entry from parent directory */
- rc = ext4_dir_remove_entry(parent, name, name_len);
+ name = basename(name);
+ rc = ext4_dir_remove_entry(parent, name, strlen(name));
if (rc != 0)
return rc;
@@ -321,58 +237,14 @@
return 0;
}
-int ext4_mount(const char *dev_name, const char *mount_point,
- bool read_only)
+int ext4_mount(struct ext4_mountpoint *mp, struct ext4_blockdev *bd, bool read_only)
{
int r;
u32int bsize;
struct ext4_bcache *bc;
- struct ext4_blockdev *bd = 0;
- struct ext4_mountpoint *mp = 0;
- assert(mount_point && dev_name);
+ memset(mp, 0, sizeof(*mp));
- usize mp_len = strlen(mount_point);
-
- if (mp_len > CONFIG_EXT4_MAX_MP_NAME) {
- werrstr("mount point name too long: %s", mount_point);
- return -1;
- }
-
- if (mount_point[mp_len - 1] != '/') {
- werrstr("invalid mount point: %s", mount_point);
- return -1;
- }
-
- for (usize i = 0; i < CONFIG_EXT4_BLOCKDEVS_COUNT; ++i) {
- if (!strcmp(dev_name, s_bdevices[i].name)) {
- bd = s_bdevices[i].bd;
- break;
- }
- }
-
- if (!bd) {
- werrstr("dev not found: %s", dev_name);
- return -1;
- }
-
- for (usize i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {
- if (!s_mp[i].mounted) {
- strcpy(s_mp[i].name, mount_point);
- s_mp[i].mounted = 1;
- mp = &s_mp[i];
- break;
- }
-
- if (!strcmp(s_mp[i].name, mount_point))
- return 0;
- }
-
- if (!mp) {
- werrstr("memory");
- return -1;
- }
-
r = ext4_block_init(bd);
if (r != 0)
return r;
@@ -379,6 +251,7 @@
r = ext4_fs_init(&mp->fs, bd, read_only);
if (r != 0) {
+err:
ext4_block_fini(bd);
return r;
}
@@ -388,14 +261,13 @@
bc = &mp->bc;
r = ext4_bcache_init_dynamic(bc, CONFIG_BLOCK_DEV_CACHE_SIZE, bsize);
- if (r != 0) {
- ext4_block_fini(bd);
- return r;
- }
+ if (r != 0)
+ goto err;
if (bsize != bc->itemsize) {
werrstr("unsupported block size: %d", bsize);
- return -1;
+ ext4_bcache_fini_dynamic(bc);
+ goto err;
}
/*Bind block cache to block device*/
@@ -402,41 +274,24 @@
r = ext4_block_bind_bcache(bd, bc);
if (r != 0) {
ext4_bcache_cleanup(bc);
- ext4_block_fini(bd);
ext4_bcache_fini_dynamic(bc);
- return r;
+ goto err;
}
bd->fs = &mp->fs;
+ mp->mounted = true;
return r;
}
-static struct ext4_mountpoint *ext4_get_mount(const char *path)
+int ext4_umount(struct ext4_mountpoint *mp)
{
- for (usize i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {
- if (!s_mp[i].mounted)
- continue;
- if (!strncmp(s_mp[i].name, path, strlen(s_mp[i].name)))
- return &s_mp[i];
- }
-
- werrstr("mount point not found: %s", path);
- return nil;
-}
-
-int ext4_umount(const char *mount_point)
-{
int r;
- struct ext4_mountpoint *mp = ext4_get_mount(mount_point);
- if (!mp)
- return -1;
-
r = ext4_fs_fini(&mp->fs);
if (r != 0)
goto Finish;
- mp->mounted = 0;
+ mp->mounted = false;
ext4_bcache_cleanup(mp->fs.bdev->bc);
ext4_bcache_fini_dynamic(mp->fs.bdev->bc);
@@ -447,13 +302,10 @@
return r;
}
-int ext4_journal_start(const char *mount_point)
+int ext4_journal_start(struct ext4_mountpoint *mp)
{
int r;
- struct ext4_mountpoint *mp = ext4_get_mount(mount_point);
- if (!mp)
- return -1;
if (mp->fs.read_only)
return 0;
if (!ext4_sb_feature_com(&mp->fs.sb, EXT4_FCOM_HAS_JOURNAL))
@@ -476,13 +328,10 @@
return r;
}
-int ext4_journal_stop(const char *mount_point)
+int ext4_journal_stop(struct ext4_mountpoint *mp)
{
int r;
- struct ext4_mountpoint *mp = ext4_get_mount(mount_point);
- if (!mp)
- return -1;
if (mp->fs.read_only)
return 0;
if (!ext4_sb_feature_com(&mp->fs.sb, EXT4_FCOM_HAS_JOURNAL))
@@ -510,14 +359,10 @@
return r;
}
-int ext4_recover(const char *mount_point)
+int ext4_recover(struct ext4_mountpoint *mp)
{
- struct ext4_mountpoint *mp = ext4_get_mount(mount_point);
int r;
- if (!mp)
- return -1;
-
EXT4_MP_LOCK(mp);
if (!ext4_sb_feature_com(&mp->fs.sb, EXT4_FCOM_HAS_JOURNAL))
return 0;
@@ -612,14 +457,9 @@
}
}
-int ext4_mount_point_stats(const char *mount_point,
+int ext4_mount_point_stats(struct ext4_mountpoint *mp,
struct ext4_mount_stats *stats)
{
- struct ext4_mountpoint *mp = ext4_get_mount(mount_point);
-
- if (!mp)
- return -1;
-
EXT4_MP_LOCK(mp);
stats->inodes_count = ext4_get32(&mp->fs.sb, inodes_count);
stats->free_inodes_count = ext4_get32(&mp->fs.sb, free_inodes_count);
@@ -637,23 +477,9 @@
return 0;
}
-int ext4_mount_setup_locks(const char *mount_point,
+int ext4_mount_setup_locks(struct ext4_mountpoint *mp,
const struct ext4_lock *locks)
{
- u32int i;
- struct ext4_mountpoint *mp = nil;
-
- for (i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {
- if (!strcmp(s_mp[i].name, mount_point)) {
- mp = &s_mp[i];
- break;
- }
- }
- if (!mp) {
- werrstr("mount point not found: %s", mount_point);
- return -1;
- }
-
mp->os_locks = locks;
return 0;
}
@@ -664,8 +490,7 @@
{
int i;
- for (i = 0; i < EXT4_DIRECTORY_FILENAME_LEN; ++i) {
-
+ for(i = 0; i < EXT4_DIRECTORY_FILENAME_LEN; ++i) {
if (path[i] == '/') {
*is_goal = false;
return i;
@@ -828,9 +653,9 @@
* NOTICE: if filetype is equal to EXT4_DIRENTRY_UNKNOWN,
* any filetype of the target dir entry will be accepted.
*/
-static int ext4_generic_open2(ext4_file *f, const char *path, int flags,
- int ftype, u32int *parent_inode,
- u32int *name_off)
+static int ext4_generic_open2(struct ext4_mountpoint *mp,
+ ext4_file *f, const char *path, int flags,
+ int ftype, u32int *parent_inode)
{
bool is_goal = false;
u32int imode = EXT4_INODE_MODE_DIRECTORY;
@@ -838,15 +663,11 @@
int r;
int len;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
struct ext4_dir_search_result result;
struct ext4_inode_ref ref;
f->mp = 0;
- if (!mp)
- return -1;
-
struct ext4_fs *const fs = &mp->fs;
struct ext4_sblock *const sb = &mp->fs.sb;
@@ -857,12 +678,6 @@
f->flags = flags;
- /*Skip mount point*/
- path += strlen(mp->name);
-
- if (name_off)
- *name_off = strlen(mp->name);
-
/*Load root*/
r = ext4_fs_get_inode_ref(fs, EXT4_INODE_ROOT_INDEX, &ref);
if (r != 0)
@@ -967,9 +782,6 @@
break;
path += len + 1;
-
- if (name_off)
- *name_off += len + 1;
}
if (r != 0) {
@@ -1000,14 +812,13 @@
/****************************************************************************/
-static int ext4_generic_open(ext4_file *f, const char *path, const char *flags,
- bool file_expect, u32int *parent_inode,
- u32int *name_off)
+static int ext4_generic_open(struct ext4_mountpoint *mp,
+ ext4_file *f, const char *path, const char *flags,
+ bool file_expect, u32int *parent_inode)
{
u32int iflags;
int filetype;
int r;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
if (ext4_parse_flags(flags, &iflags) == false)
return -1;
@@ -1020,7 +831,7 @@
if (iflags & O_CREAT)
ext4_trans_start(mp);
- r = ext4_generic_open2(f, path, iflags, filetype, parent_inode, name_off);
+ r = ext4_generic_open2(mp, f, path, iflags, filetype, parent_inode);
if (iflags & O_CREAT) {
if (r == 0)
@@ -1032,7 +843,8 @@
return r;
}
-static int ext4_create_hardlink(const char *path,
+static int ext4_create_hardlink(struct ext4_mountpoint *mp,
+ const char *path,
struct ext4_inode_ref *child_ref, bool rename)
{
bool is_goal = false;
@@ -1041,19 +853,12 @@
int r;
int len;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
struct ext4_dir_search_result result;
struct ext4_inode_ref ref;
- if (!mp)
- return -1;
-
struct ext4_fs *const fs = &mp->fs;
struct ext4_sblock *const sb = &mp->fs.sb;
- /*Skip mount point*/
- path += strlen(mp->name);
-
/*Load root*/
r = ext4_fs_get_inode_ref(fs, EXT4_INODE_ROOT_INDEX, &ref);
if (r != 0)
@@ -1136,25 +941,15 @@
return r;
}
-static int ext4_remove_orig_reference(const char *path, u32int name_off,
+static int ext4_remove_orig_reference(struct ext4_mountpoint *mp,
+ const char *path,
struct ext4_inode_ref *parent_ref,
struct ext4_inode_ref *child_ref)
{
- bool is_goal;
int r;
- int len;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
- if (!mp)
- return -1;
-
- /*Set path*/
- path += name_off;
-
- len = ext4_path_check(path, &is_goal);
-
/* Remove entry from parent directory */
- r = ext4_dir_remove_entry(parent_ref, path, len);
+ r = ext4_dir_remove_entry(parent_ref, path, strlen(path));
if (r != 0)
goto Finish;
@@ -1167,33 +962,21 @@
return r;
}
-int ext4_flink(const char *path, const char *hardlink_path)
+int ext4_flink(struct ext4_mountpoint *mp, const char *path, const char *hardlink_path)
{
int r;
ext4_file f;
- u32int name_off;
bool child_loaded = false;
u32int parent_inode, child_inode;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
- struct ext4_mountpoint *target_mp = ext4_get_mount(hardlink_path);
struct ext4_inode_ref child_ref;
- if (!mp)
- return -1;
-
if (mp->fs.read_only) {
werrstr(Erdonlyfs);
return -1;
}
- /* Will that happen? */
- if (mp != target_mp) {
- werrstr("mount point must be the same: %s vs %s", path, hardlink_path);
- return -1;
- }
-
EXT4_MP_LOCK(mp);
- r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN, &parent_inode, &name_off);
+ r = ext4_generic_open2(mp, &f, path, O_RDONLY, EXT4_DE_UNKNOWN, &parent_inode);
if (r != 0) {
EXT4_MP_UNLOCK(mp);
return r;
@@ -1217,7 +1000,7 @@
goto Finish;
}
- r = ext4_create_hardlink(hardlink_path, &child_ref, false);
+ r = ext4_create_hardlink(mp, hardlink_path, &child_ref, false);
Finish:
if (child_loaded)
@@ -1233,19 +1016,14 @@
}
-int ext4_frename(const char *path, const char *new_path)
+int ext4_frename(struct ext4_mountpoint *mp, const char *path, const char *new_path)
{
int r;
ext4_file f;
- u32int name_off;
bool parent_loaded = false, child_loaded = false;
u32int parent_inode, child_inode;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
struct ext4_inode_ref child_ref, parent_ref;
- if (!mp)
- return -1;
-
if (mp->fs.read_only) {
werrstr(Erdonlyfs);
return -1;
@@ -1253,8 +1031,7 @@
EXT4_MP_LOCK(mp);
- r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN,
- &parent_inode, &name_off);
+ r = ext4_generic_open2(mp, &f, path, O_RDONLY, EXT4_DE_UNKNOWN, &parent_inode);
if (r != 0) {
EXT4_MP_UNLOCK(mp);
return r;
@@ -1278,11 +1055,11 @@
child_loaded = true;
- r = ext4_create_hardlink(new_path, &child_ref, true);
+ r = ext4_create_hardlink(mp, new_path, &child_ref, true);
if (r != 0)
goto Finish;
- r = ext4_remove_orig_reference(path, name_off, &parent_ref, &child_ref);
+ r = ext4_remove_orig_reference(mp, basename(path), &parent_ref, &child_ref);
if (r != 0)
goto Finish;
@@ -1305,25 +1082,16 @@
/****************************************************************************/
-int ext4_get_sblock(const char *mount_point, struct ext4_sblock **sb)
+int ext4_get_sblock(struct ext4_mountpoint *mp, struct ext4_sblock **sb)
{
- struct ext4_mountpoint *mp = ext4_get_mount(mount_point);
-
- if (!mp)
- return -1;
-
*sb = &mp->fs.sb;
return 0;
}
-int ext4_cache_write_back(const char *path, bool on)
+int ext4_cache_write_back(struct ext4_mountpoint *mp, bool on)
{
- struct ext4_mountpoint *mp = ext4_get_mount(path);
int ret;
- if (!mp)
- return -1;
-
EXT4_MP_LOCK(mp);
ret = ext4_block_cache_write_back(mp->fs.bdev, on);
EXT4_MP_UNLOCK(mp);
@@ -1330,14 +1098,10 @@
return ret;
}
-int ext4_cache_flush(const char *path)
+int ext4_cache_flush(struct ext4_mountpoint *mp)
{
- struct ext4_mountpoint *mp = ext4_get_mount(path);
int ret;
- if (!mp)
- return -1;
-
EXT4_MP_LOCK(mp);
ret = ext4_block_cache_flush(mp->fs.bdev);
EXT4_MP_UNLOCK(mp);
@@ -1344,22 +1108,15 @@
return ret;
}
-int ext4_fremove(const char *path)
+int ext4_fremove(struct ext4_mountpoint *mp, const char *path)
{
ext4_file f;
u32int parent_inode;
u32int child_inode;
- u32int name_off;
- bool is_goal;
int r;
- int len;
struct ext4_inode_ref child;
struct ext4_inode_ref parent;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
- if (!mp)
- return -1;
-
if (mp->fs.read_only) {
werrstr(Erdonlyfs);
return -1;
@@ -1366,7 +1123,7 @@
}
EXT4_MP_LOCK(mp);
- r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN, &parent_inode, &name_off);
+ r = ext4_generic_open2(mp, &f, path, O_RDONLY, EXT4_DE_UNKNOWN, &parent_inode);
if (r != 0) {
EXT4_MP_UNLOCK(mp);
return r;
@@ -1416,13 +1173,8 @@
ext4_block_cache_write_back(mp->fs.bdev, 0);
}
- /*Set path*/
- path += name_off;
-
- len = ext4_path_check(path, &is_goal);
-
/*Unlink from parent*/
- r = ext4_unlink(mp, &parent, &child, path, len);
+ r = ext4_unlink(mp, &parent, &child, path);
if (r != 0)
goto Finish;
@@ -1448,18 +1200,14 @@
return r;
}
-int ext4_fopen(ext4_file *file, const char *path, const char *flags)
+int ext4_fopen(struct ext4_mountpoint *mp, ext4_file *file, const char *path, const char *flags)
{
- struct ext4_mountpoint *mp = ext4_get_mount(path);
int r;
- if (!mp)
- return -1;
-
EXT4_MP_LOCK(mp);
ext4_block_cache_write_back(mp->fs.bdev, 1);
- r = ext4_generic_open(file, path, flags, true, 0, 0);
+ r = ext4_generic_open(mp, file, path, flags, true, nil);
ext4_block_cache_write_back(mp->fs.bdev, 0);
EXT4_MP_UNLOCK(mp);
@@ -1466,15 +1214,11 @@
return r;
}
-int ext4_fopen2(ext4_file *file, const char *path, int flags)
+int ext4_fopen2(struct ext4_mountpoint *mp, ext4_file *file, const char *path, int flags)
{
- struct ext4_mountpoint *mp = ext4_get_mount(path);
int r;
int filetype;
- if (!mp)
- return -1;
-
filetype = EXT4_DE_REG_FILE;
EXT4_MP_LOCK(mp);
@@ -1483,7 +1227,7 @@
if (flags & O_CREAT)
ext4_trans_start(mp);
- r = ext4_generic_open2(file, path, flags, filetype, nil, nil);
+ r = ext4_generic_open2(mp, file, path, flags, filetype, nil);
if (flags & O_CREAT) {
if (r == 0)
@@ -1765,6 +1509,9 @@
assert(file && file->mp);
+ if(wcnt)
+ *wcnt = 0;
+
if (file->mp->fs.read_only) {
werrstr(Erdonlyfs);
return -1;
@@ -1784,9 +1531,6 @@
struct ext4_fs *const fs = &file->mp->fs;
struct ext4_sblock *const sb = &file->mp->fs.sb;
- if (wcnt)
- *wcnt = 0;
-
r = ext4_fs_get_inode_ref(fs, file->inode, &ref);
if (r != 0) {
ext4_trans_abort(file->mp);
@@ -1798,12 +1542,11 @@
file->fsize = ext4_inode_get_size(sb, ref.inode);
block_size = ext4_sb_get_block_size(sb);
- iblock_last = (u32int)((file->fpos + size) / block_size);
- iblk_idx = (u32int)(file->fpos / block_size);
- ifile_blocks = (u32int)((file->fsize + block_size - 1) / block_size);
+ iblock_last = (file->fpos + size) / block_size;
+ iblk_idx = file->fpos / block_size;
+ ifile_blocks = (file->fsize + block_size - 1) / block_size;
+ unalg = file->fpos % block_size;
- unalg = (file->fpos) % block_size;
-
if (unalg) {
usize len = size;
u64int off;
@@ -1941,33 +1684,27 @@
return r;
}
-int ext4_fseek(ext4_file *file, s64int offset, u32int origin)
+int ext4_fseek(ext4_file *file, s64int offset, int origin)
{
switch (origin) {
+ case 2:
+ offset += file->fsize;
+ if(0){
+ case 1:
+ offset += file->fpos;
+ /* slippery slope */
+ }
case 0:
- if (offset < 0 || (u64int)offset > file->fsize)
- break;
+ if(offset < 0)
+ offset = 0;
+ else if(offset > file->fsize)
+ offset = file->fsize;
file->fpos = offset;
- return 0;
- case 1:
- if ((offset < 0 && (u64int)(-offset) > file->fpos) ||
- (offset > 0 &&
- (u64int)offset > (file->fsize - file->fpos)))
- break;
-
- file->fpos += offset;
- return 0;
- case 2:
- if (offset < 0 || (u64int)offset > file->fsize)
- break;
-
- file->fpos = file->fsize - offset;
- return 0;
+ break;
}
- werrstr(Einval);
- return -1;
+ return 0;
}
u64int ext4_ftell(ext4_file *file)
@@ -1981,14 +1718,14 @@
}
-static int ext4_trans_get_inode_ref(const char *path,
- struct ext4_mountpoint *mp,
+static int ext4_trans_get_inode_ref(struct ext4_mountpoint *mp,
+ const char *path,
struct ext4_inode_ref *inode_ref)
{
int r;
ext4_file f;
- r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN, nil, nil);
+ r = ext4_generic_open2(mp, &f, path, O_RDONLY, EXT4_DE_UNKNOWN, nil);
if (r != 0)
return r;
@@ -2018,20 +1755,17 @@
}
-int ext4_raw_inode_fill(const char *path, u32int *ret_ino,
+int ext4_raw_inode_fill(struct ext4_mountpoint *mp,
+ const char *path, u32int *ret_ino,
struct ext4_inode *inode)
{
int r;
ext4_file f;
struct ext4_inode_ref inode_ref;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
- if (!mp)
- return -1;
-
EXT4_MP_LOCK(mp);
- r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN, nil, nil);
+ r = ext4_generic_open2(mp, &f, path, O_RDONLY, EXT4_DE_UNKNOWN, nil);
if (r != 0) {
EXT4_MP_UNLOCK(mp);
return r;
@@ -2055,32 +1789,24 @@
return r;
}
-int ext4_inode_exist(const char *path, int type)
+int ext4_inode_exist(struct ext4_mountpoint *mp, const char *path, int type)
{
int r;
ext4_file f;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
- if (!mp)
- return -1;
-
EXT4_MP_LOCK(mp);
- r = ext4_generic_open2(&f, path, O_RDONLY, type, nil, nil);
+ r = ext4_generic_open2(mp, &f, path, O_RDONLY, type, nil);
EXT4_MP_UNLOCK(mp);
return r;
}
-int ext4_mode_set(const char *path, u32int mode)
+int ext4_mode_set(struct ext4_mountpoint *mp, const char *path, u32int mode)
{
int r;
u32int orig_mode;
struct ext4_inode_ref inode_ref;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
- if (!mp)
- return -1;
-
if (mp->fs.read_only) {
werrstr(Erdonlyfs);
return -1;
@@ -2088,7 +1814,7 @@
EXT4_MP_LOCK(mp);
- r = ext4_trans_get_inode_ref(path, mp, &inode_ref);
+ r = ext4_trans_get_inode_ref(mp, path, &inode_ref);
if (r != 0)
goto Finish;
@@ -2106,15 +1832,11 @@
return r;
}
-int ext4_owner_set(const char *path, u32int uid, u32int gid)
+int ext4_owner_set(struct ext4_mountpoint *mp, const char *path, u32int uid, u32int gid)
{
int r;
struct ext4_inode_ref inode_ref;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
- if (!mp)
- return -1;
-
if (mp->fs.read_only) {
werrstr(Erdonlyfs);
return -1;
@@ -2122,7 +1844,7 @@
EXT4_MP_LOCK(mp);
- r = ext4_trans_get_inode_ref(path, mp, &inode_ref);
+ r = ext4_trans_get_inode_ref(mp, path, &inode_ref);
if (r != 0)
goto Finish;
@@ -2138,19 +1860,15 @@
return r;
}
-int ext4_mode_get(const char *path, u32int *mode)
+int ext4_mode_get(struct ext4_mountpoint *mp, const char *path, u32int *mode)
{
struct ext4_inode_ref inode_ref;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
ext4_file f;
int r;
- if (!mp)
- return -1;
-
EXT4_MP_LOCK(mp);
- r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN, nil, nil);
+ r = ext4_generic_open2(mp, &f, path, O_RDONLY, EXT4_DE_UNKNOWN, nil);
if (r != 0)
goto Finish;
@@ -2167,19 +1885,14 @@
return r;
}
-int ext4_owner_get(const char *path, u32int *uid, u32int *gid)
+int ext4_owner_get(struct ext4_mountpoint *mp, const char *path, u32int *uid, u32int *gid)
{
struct ext4_inode_ref inode_ref;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
ext4_file f;
int r;
-
- if (!mp)
- return -1;
-
EXT4_MP_LOCK(mp);
- r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN, nil, nil);
+ r = ext4_generic_open2(mp, &f, path, O_RDONLY, EXT4_DE_UNKNOWN, nil);
if (r != 0)
goto Finish;
@@ -2197,15 +1910,11 @@
return r;
}
-int ext4_atime_set(const char *path, u32int atime)
+int ext4_atime_set(struct ext4_mountpoint *mp, const char *path, u32int atime)
{
struct ext4_inode_ref inode_ref;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
int r;
- if (!mp)
- return -1;
-
if (mp->fs.read_only) {
werrstr(Erdonlyfs);
return -1;
@@ -2213,7 +1922,7 @@
EXT4_MP_LOCK(mp);
- r = ext4_trans_get_inode_ref(path, mp, &inode_ref);
+ r = ext4_trans_get_inode_ref(mp, path, &inode_ref);
if (r != 0)
goto Finish;
@@ -2227,15 +1936,11 @@
return r;
}
-int ext4_mtime_set(const char *path, u32int mtime)
+int ext4_mtime_set(struct ext4_mountpoint *mp, const char *path, u32int mtime)
{
struct ext4_inode_ref inode_ref;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
int r;
- if (!mp)
- return -1;
-
if (mp->fs.read_only) {
werrstr(Erdonlyfs);
return -1;
@@ -2243,7 +1948,7 @@
EXT4_MP_LOCK(mp);
- r = ext4_trans_get_inode_ref(path, mp, &inode_ref);
+ r = ext4_trans_get_inode_ref(mp, path, &inode_ref);
if (r != 0)
goto Finish;
@@ -2257,15 +1962,11 @@
return r;
}
-int ext4_ctime_set(const char *path, u32int ctime)
+int ext4_ctime_set(struct ext4_mountpoint *mp, const char *path, u32int ctime)
{
struct ext4_inode_ref inode_ref;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
int r;
- if (!mp)
- return -1;
-
if (mp->fs.read_only) {
werrstr(Erdonlyfs);
return -1;
@@ -2273,7 +1974,7 @@
EXT4_MP_LOCK(mp);
- r = ext4_trans_get_inode_ref(path, mp, &inode_ref);
+ r = ext4_trans_get_inode_ref(mp, path, &inode_ref);
if (r != 0)
goto Finish;
@@ -2287,19 +1988,15 @@
return r;
}
-int ext4_atime_get(const char *path, u32int *atime)
+int ext4_atime_get(struct ext4_mountpoint *mp, const char *path, u32int *atime)
{
struct ext4_inode_ref inode_ref;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
ext4_file f;
int r;
- if (!mp)
- return -1;
-
EXT4_MP_LOCK(mp);
- r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN, nil, nil);
+ r = ext4_generic_open2(mp, &f, path, O_RDONLY, EXT4_DE_UNKNOWN, nil);
if (r != 0)
goto Finish;
@@ -2316,19 +2013,15 @@
return r;
}
-int ext4_mtime_get(const char *path, u32int *mtime)
+int ext4_mtime_get(struct ext4_mountpoint *mp, const char *path, u32int *mtime)
{
struct ext4_inode_ref inode_ref;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
ext4_file f;
int r;
- if (!mp)
- return -1;
-
EXT4_MP_LOCK(mp);
- r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN, nil, nil);
+ r = ext4_generic_open2(mp, &f, path, O_RDONLY, EXT4_DE_UNKNOWN, nil);
if (r != 0)
goto Finish;
@@ -2345,19 +2038,15 @@
return r;
}
-int ext4_ctime_get(const char *path, u32int *ctime)
+int ext4_ctime_get(struct ext4_mountpoint *mp, const char *path, u32int *ctime)
{
struct ext4_inode_ref inode_ref;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
ext4_file f;
int r;
- if (!mp)
- return -1;
-
EXT4_MP_LOCK(mp);
- r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN, nil, nil);
+ r = ext4_generic_open2(mp, &f, path, O_RDONLY, EXT4_DE_UNKNOWN, nil);
if (r != 0)
goto Finish;
@@ -2443,16 +2132,12 @@
return r;
}
-int ext4_fsymlink(const char *target, const char *path)
+int ext4_fsymlink(struct ext4_mountpoint *mp, const char *target, const char *path)
{
- struct ext4_mountpoint *mp = ext4_get_mount(path);
int r;
ext4_file f;
int filetype;
- if (!mp)
- return -1;
-
if (mp->fs.read_only) {
werrstr(Erdonlyfs);
return -1;
@@ -2464,7 +2149,7 @@
ext4_block_cache_write_back(mp->fs.bdev, 1);
ext4_trans_start(mp);
- r = ext4_generic_open2(&f, path, O_RDWR | O_CREAT, filetype, nil, nil);
+ r = ext4_generic_open2(mp, &f, path, O_RDWR | O_CREAT, filetype, nil);
if (r == 0)
r = ext4_fsymlink_set(&f, target, strlen(target));
else
@@ -2483,9 +2168,8 @@
return r;
}
-int ext4_readlink(const char *path, char *buf, usize bufsize, usize *rcnt)
+int ext4_readlink(struct ext4_mountpoint *mp, const char *path, char *buf, usize bufsize, usize *rcnt)
{
- struct ext4_mountpoint *mp = ext4_get_mount(path);
int r;
ext4_file f;
int filetype;
@@ -2492,14 +2176,11 @@
assert(buf != nil);
- if (!mp)
- return -1;
-
filetype = EXT4_DE_SYMLINK;
EXT4_MP_LOCK(mp);
ext4_block_cache_write_back(mp->fs.bdev, 1);
- r = ext4_generic_open2(&f, path, O_RDONLY, filetype, nil, nil);
+ r = ext4_generic_open2(mp, &f, path, O_RDONLY, filetype, nil);
if (r == 0)
r = ext4_fread(&f, buf, bufsize, rcnt);
else
@@ -2536,15 +2217,11 @@
return r;
}
-int ext4_mknod(const char *path, int filetype, u32int dev)
+int ext4_mknod(struct ext4_mountpoint *mp, const char *path, int filetype, u32int dev)
{
- struct ext4_mountpoint *mp = ext4_get_mount(path);
int r;
ext4_file f;
- if (!mp)
- return -1;
-
if (mp->fs.read_only) {
werrstr(Erdonlyfs);
return -1;
@@ -2576,7 +2253,7 @@
ext4_block_cache_write_back(mp->fs.bdev, 1);
ext4_trans_start(mp);
- r = ext4_generic_open2(&f, path, O_RDWR | O_CREAT, filetype, nil, nil);
+ r = ext4_generic_open2(mp, &f, path, O_RDWR | O_CREAT, filetype, nil);
if (r == 0) {
if (filetype == EXT4_DE_CHRDEV ||
filetype == EXT4_DE_BLKDEV)
@@ -2600,29 +2277,22 @@
/*********************************DIRECTORY OPERATION************************/
-int ext4_dir_rm(const char *path)
+int ext4_dir_rm(struct ext4_mountpoint *mp, const char *path)
{
int r;
- int len;
ext4_file f;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
struct ext4_inode_ref act;
struct ext4_inode_ref child;
struct ext4_dir_iter it;
- u32int name_off;
u32int inode_up;
u32int inode_current;
u32int depth = 1;
bool has_children;
- bool is_goal;
bool dir_end;
- if (!mp)
- return -1;
-
if (mp->fs.read_only) {
werrstr(Erdonlyfs);
return -1;
@@ -2633,20 +2303,17 @@
struct ext4_fs *const fs = &mp->fs;
/*Check if exist.*/
- r = ext4_generic_open(&f, path, "r", false, &inode_up, &name_off);
+ r = ext4_generic_open(mp, &f, path, "r", false, &inode_up);
if (r != 0) {
EXT4_MP_UNLOCK(mp);
return r;
}
- path += name_off;
- len = ext4_path_check(path, &is_goal);
inode_current = f.inode;
ext4_block_cache_write_back(mp->fs.bdev, 1);
do {
-
u64int act_curr_pos = 0;
has_children = false;
dir_end = false;
@@ -2723,9 +2390,7 @@
/*No children in child directory or file. Just
* unlink.*/
- r = ext4_unlink(f.mp, &act, &child,
- (char *)it.curr->name,
- it.curr->name_len);
+ r = ext4_unlink(f.mp, &act, &child, (char *)it.curr->name);
if (r != 0) {
ext4_fs_put_inode_ref(&child);
goto End;
@@ -2798,8 +2463,7 @@
/* In this place all directories should be
* unlinked.
* Last unlink from root of current directory*/
- r = ext4_unlink(f.mp, &parent, &act,
- (char *)path, len);
+ r = ext4_unlink(f.mp, &parent, &act, (char *)path);
if (r != 0) {
ext4_fs_put_inode_ref(&parent);
ext4_fs_put_inode_ref(&act);
@@ -2844,20 +2508,16 @@
return r;
}
-int ext4_dir_mv(const char *path, const char *new_path)
+int ext4_dir_mv(struct ext4_mountpoint *mp, const char *path, const char *new_path)
{
- return ext4_frename(path, new_path);
+ return ext4_frename(mp, path, new_path);
}
-int ext4_dir_mk(const char *path)
+int ext4_dir_mk(struct ext4_mountpoint *mp, const char *path)
{
int r;
ext4_file f;
- struct ext4_mountpoint *mp = ext4_get_mount(path);
- if (!mp)
- return -1;
-
if (mp->fs.read_only) {
werrstr(Erdonlyfs);
return -1;
@@ -2866,7 +2526,7 @@
EXT4_MP_LOCK(mp);
/*Check if exist.*/
- r = ext4_generic_open(&f, path, "r", false, 0, 0);
+ r = ext4_generic_open(mp, &f, path, "r", false, nil);
if (r == 0) {
werrstr(Eexists);
r = -1;
@@ -2874,7 +2534,7 @@
}
/*Create new directory.*/
- r = ext4_generic_open(&f, path, "w", false, 0, 0);
+ r = ext4_generic_open(mp, &f, path, "w", false, nil);
Finish:
EXT4_MP_UNLOCK(mp);
@@ -2881,16 +2541,12 @@
return r;
}
-int ext4_dir_open(ext4_dir *dir, const char *path)
+int ext4_dir_open(struct ext4_mountpoint *mp, ext4_dir *dir, const char *path)
{
- struct ext4_mountpoint *mp = ext4_get_mount(path);
int r;
- if (!mp)
- return -1;
-
EXT4_MP_LOCK(mp);
- r = ext4_generic_open(&dir->f, path, "r", false, 0, 0);
+ r = ext4_generic_open(mp, &dir->f, path, "r", false, nil);
dir->next_off = 0;
EXT4_MP_UNLOCK(mp);
return r;
--- a/sys/src/cmd/ext4srv/ext4_dir.c
+++ b/sys/src/cmd/ext4srv/ext4_dir.c
@@ -462,6 +462,7 @@
return r;
}
+ werrstr(Enotfound);
return EXT4_ERR_NOT_FOUND;
}
@@ -636,6 +637,7 @@
}
/* Entry not found */
+ werrstr(Enotfound);
return EXT4_ERR_NOT_FOUND;
}
--- a/sys/src/cmd/ext4srv/ext4_dir_idx.c
+++ b/sys/src/cmd/ext4srv/ext4_dir_idx.c
@@ -661,6 +661,7 @@
p->position = p->entries;
}
+ werrstr(Enotfound);
return EXT4_ERR_NOT_FOUND;
}
--- a/sys/src/cmd/ext4srv/ext4srv.c
+++ b/sys/src/cmd/ext4srv/ext4srv.c
@@ -36,7 +36,6 @@
.cachewb = 0,
.asroot = 0,
.rdonly = 0,
- .linkmode = Lhide,
.fstype = -1,
.blksz = 1024,
@@ -48,60 +47,14 @@
static u8int zero[65536];
static char *srvname = "ext4";
-static char *
-linkresolve(Aux *a, char *s, char **value)
-{
- char *q, buf[4096+1];
- usize sz;
- int res;
-
- res = 0;
- if(opts.linkmode == Lresolve && (res = ext4_readlink(s, buf, sizeof(buf), &sz)) == 0){
- if(sz == sizeof(buf)){
- werrstr("readlink: %s: path too long", s);
- free(s);
- return nil;
- }
-
- buf[sz] = 0;
- if(value != nil)
- *value = strdup(buf);
- cleanname(buf);
- if(buf[0] == '/'){
- free(s);
- s = smprint("%M%s", a->p, buf);
- }else{
- q = strrchr(s, '/');
- *q = 0;
- q = s;
- s = smprint("%s/%s", q, buf);
- free(q);
- cleanname(strchr(s+1, '/'));
- }
- }else{
- if(res != 0)
- werrstr("readlink: %s: %r", s);
- if(value != nil)
- *value = nil;
- }
-
- return s;
-}
-
-static char *
-fullpath(Aux *a)
-{
- return linkresolve(a, smprint("%M/%s", a->p, a->path), nil);
-}
-
static int
haveperm(Aux *a, int p, struct ext4_inode *inodeout)
{
+ struct ext4_mountpoint *mp;
struct ext4_inode inode;
u32int ino, id;
int m, fm;
Group *g;
- char *s;
switch(p & 3){
case OREAD:
@@ -122,14 +75,11 @@
if(p & OTRUNC)
p |= AWRITE;
- if((s = fullpath(a)) == nil)
+ mp = &a->p->mp;
+ if(ext4_raw_inode_fill(mp, a->path, &ino, &inode) != 0){
+ werrstr("%s: %r", a->path);
return -1;
- if(ext4_raw_inode_fill(s, &ino, &inode) != 0){
- werrstr("%s: %r", s);
- free(s);
- return -1;
}
- free(s);
if(inodeout != nil)
memmove(inodeout, &inode, sizeof(inode));
@@ -178,7 +128,7 @@
incref(a->p);
a->type = Adir;
- a->path = strdup("");
+ a->path = estrdup9p("");
r->ofcall.qid = a->p->qidmask;
r->fid->qid = a->p->qidmask;
r->fid->aux = a;
@@ -217,11 +167,13 @@
static void
ropen(Req *r)
{
+ struct ext4_mountpoint *mp;
char *path;
int res;
Aux *a;
a = r->fid->aux;
+ mp = &a->p->mp;
switch(a->type){
case Adir:
if(r->ifcall.mode != OREAD || !haveperm(a, r->ifcall.mode, nil)){
@@ -234,12 +186,12 @@
}
if((a->dir = malloc(sizeof(*a->dir))) == nil)
goto Nomem;
- if((path = smprint("%M/%s", a->p, a->path)) == nil){
+ if((path = estrdup9p(a->path)) == nil){
free(a->dir);
a->dir = nil;
goto Nomem;
}
- res = ext4_dir_open(a->dir, path);
+ res = ext4_dir_open(mp, a->dir, path);
free(path);
if(res != 0){
free(a->dir);
@@ -260,12 +212,12 @@
}
if((a->file = malloc(sizeof(*a->file))) == nil)
goto Nomem;
- if((path = smprint("%M/%s", a->p, a->path)) == nil){
+ if((path = estrdup9p(a->path)) == nil){
free(a->file);
a->file = nil;
goto Nomem;
}
- res = ext4_fopen2(a->file, path, toext4mode(r->ifcall.mode, 0, 0));
+ res = ext4_fopen2(mp, a->file, path, toext4mode(r->ifcall.mode, 0, 0));
free(path);
if(res != 0){
free(a->file);
@@ -288,14 +240,16 @@
static void
rcreate(Req *r)
{
+ struct ext4_mountpoint *mp;
u32int perm, dirperm, t;
struct ext4_inode inode;
- char *s, *q;
- int mkdir;
+ int mkdir, isroot;
long tm;
+ char *s;
Aux *a;
a = r->fid->aux;
+ mp = &a->p->mp;
s = nil;
if(a->file != nil || a->dir != nil){
@@ -308,26 +262,19 @@
}
/* first make sure this is a directory */
- t = ext4_inode_type(a->p->sb, &inode);
- if(t != EXT4_INODE_MODE_DIRECTORY){
- werrstr("create in non-directory");
- goto error;
+ isroot = r->fid->qid.path == a->p->qidmask.path;
+ if(!isroot){
+ t = ext4_inode_type(a->p->sb, &inode);
+ if(t != EXT4_INODE_MODE_DIRECTORY){
+ werrstr("create in non-directory");
+ goto error;
+ }
}
+ ext4_mode_get(mp, a->path, &dirperm);
- if((s = fullpath(a)) == nil)
- goto error;
- ext4_mode_get(s, &dirperm);
-
/* check if the entry already exists */
- if((q = smprint("%s/%s", s, r->ifcall.name)) == nil){
-Nomem:
- werrstr("memory");
- goto error;
- }
- free(s);
- s = q;
- cleanname(s);
- if(ext4_inode_exist(s, EXT4_DE_UNKNOWN) == 0){
+ s = isroot ? estrdup9p(r->ifcall.name) : smprint("%s/%s", a->path, r->ifcall.name);
+ if(ext4_inode_exist(mp, s, EXT4_DE_UNKNOWN) == 0){
werrstr("file already exists");
goto error;
}
@@ -338,11 +285,10 @@
if(mkdir){
a->type = Adir;
- if(ext4_dir_mk(s) != 0)
+ if(ext4_dir_mk(mp, s) < 0)
goto error;
- if((a->dir = malloc(sizeof(*a->dir))) == nil)
- goto Nomem;
- if(ext4_dir_open(a->dir, s) < 0){
+ a->dir = emalloc9p(sizeof(*a->dir));
+ if(ext4_dir_open(mp, a->dir, s) < 0){
free(a->dir);
a->dir = nil;
goto ext4errorrm;
@@ -349,9 +295,8 @@
}
}else{
a->type = Afile;
- if((a->file = malloc(sizeof(*a->file))) == nil)
- goto Nomem;
- if(ext4_fopen2(a->file, s, toext4mode(r->ifcall.mode, perm, 1)) < 0){
+ a->file = emalloc9p(sizeof(*a->file));
+ if(ext4_fopen2(mp, a->file, s, toext4mode(r->ifcall.mode, perm, 1)) < 0){
free(a->file);
a->file = nil;
goto error;
@@ -358,12 +303,12 @@
}
}
- if(ext4_mode_set(s, perm) < 0)
+ if(ext4_mode_set(mp, s, perm) < 0)
goto ext4errorrm;
- ext4_owner_set(s, a->uid, a->uid);
+ ext4_owner_set(mp, s, a->uid, a->uid);
tm = time(nil);
- ext4_mtime_set(s, tm);
- ext4_ctime_set(s, tm);
+ ext4_mtime_set(mp, s, tm);
+ ext4_ctime_set(mp, s, tm);
r->fid->qid.path = a->p->qidmask.path | a->file->inode;
r->fid->qid.vers = 0;
@@ -371,8 +316,7 @@
r->ofcall.qid = r->fid->qid;
free(a->path);
- a->path = strdup(strchr(s+1, '/')+1);
- free(s);
+ a->path = s;
r->ofcall.iounit = 0;
respond(r, nil);
return;
@@ -379,9 +323,9 @@
ext4errorrm:
if(mkdir)
- ext4_dir_rm(s);
+ ext4_dir_rm(mp, s);
else
- ext4_fremove(s);
+ ext4_fremove(mp, s);
error:
free(s);
responderror(r);
@@ -390,34 +334,26 @@
static int
dirfill(Dir *dir, Aux *a, char *path)
{
+ struct ext4_mountpoint *mp;
struct ext4_inode inode;
u32int t, ino, id;
char tmp[16];
- char *s, *q;
Group *g;
+ char *s;
+ int r;
memset(dir, 0, sizeof(*dir));
+ mp = &a->p->mp;
if(path == nil){
- path = a->path;
- s = smprint("%M/%s", a->p, a->path);
+ r = ext4_raw_inode_fill(mp, a->path, &ino, &inode);
}else{
- if(*a->path == 0 && *path == 0)
- path = "/";
- s = smprint("%M%s%s/%s", a->p, *a->path ? "/" : "", a->path, path);
- }
- if((s = linkresolve(a, s, nil)) == nil)
- return -1;
- if(ext4_raw_inode_fill(s, &ino, &inode) < 0){
- werrstr("inode: %s: %r", s);
+ s = smprint("%s%s%s", a->path, *a->path ? "/" : "", path);
+ r = ext4_raw_inode_fill(mp, s, &ino, &inode);
free(s);
- return -1;
}
-
- t = ext4_inode_type(a->p->sb, &inode);
- if(opts.linkmode == Lhide && t == EXT4_INODE_MODE_SOFTLINK){
- werrstr("softlinks resolving disabled");
- free(s);
+ if(r < 0){
+ werrstr("inode: %s: %r", path ? path : "/");
return -1;
}
@@ -425,6 +361,7 @@
dir->qid.path = a->p->qidmask.path | ino;
dir->qid.vers = ext4_inode_get_generation(&inode);
dir->qid.type = 0;
+ t = ext4_inode_type(a->p->sb, &inode);
if(t == EXT4_INODE_MODE_DIRECTORY){
dir->qid.type |= QTDIR;
dir->mode |= DMDIR;
@@ -435,9 +372,9 @@
dir->mode |= DMAPPEND;
}
- if((q = strrchr(path, '/')) != nil)
- path = q+1;
- dir->name = estrdup9p(path);
+ if(path != nil && (s = strrchr(path, '/')) != nil)
+ path = s+1;
+ dir->name = estrdup9p(path != nil ? path : "");
dir->atime = ext4_inode_get_access_time(&inode);
dir->mtime = ext4_inode_get_modif_time(&inode);
@@ -447,8 +384,6 @@
sprint(tmp, "%ud", id = ext4_inode_get_gid(&inode));
dir->gid = estrdup9p((g = findgroupid(&a->p->groups, id)) != nil ? g->name : tmp);
- free(s);
-
return 0;
}
@@ -470,7 +405,7 @@
return -1;
}while(e->name == nil || strcmp((char*)e->name, ".") == 0 || strcmp((char*)e->name, "..") == 0);
- if(opts.linkmode == Lhide && e->inode_type == EXT4_DE_SYMLINK)
+ if(e->inode_type != EXT4_DE_REG_FILE && e->inode_type != EXT4_DE_DIR)
continue;
if(a->doff++ != n)
@@ -513,9 +448,7 @@
Aux *a;
a = r->fid->aux;
- if(a->type == Adir){
- respond(r, "can't write to dir");
- }else if(a->type == Afile){
+ if(a->type == Afile){
while(ext4_fsize(a->file) < r->ifcall.offset){
ext4_fseek(a->file, 0, 2);
sz = MIN(r->ifcall.offset-ext4_fsize(a->file), sizeof(zero));
@@ -524,15 +457,21 @@
}
if(ext4_fseek(a->file, r->ifcall.offset, 0) < 0)
goto error;
+ if(ext4_ftell(a->file) != r->ifcall.offset){
+ werrstr("could not seek");
+ goto error;
+ }
if(ext4_fwrite(a->file, r->ifcall.data, r->ifcall.count, &n) < 0)
goto error;
+ assert(r->ifcall.count >= n);
r->ofcall.count = n;
respond(r, nil);
+ return;
+ }else{
+ werrstr("can only write to files");
}
- return;
-
error:
responderror(r);
}
@@ -540,27 +479,24 @@
static void
rremove(Req *r)
{
+ struct ext4_mountpoint *mp;
struct ext4_inode inode;
const ext4_direntry *e;
u32int ino, t, empty;
ext4_dir dir;
Group *g;
- char *s;
Aux *a;
a = r->fid->aux;
+ mp = &a->p->mp;
/* do not resolve links here as most likely it's JUST the link we want to remove */
- if((s = smprint("%M/%s", a->p, a->path)) == nil){
- werrstr("memory");
+ if(ext4_raw_inode_fill(mp, a->path, &ino, &inode) < 0)
goto error;
- }
- if(ext4_raw_inode_fill(s, &ino, &inode) < 0)
- goto error;
if(a->uid == Root || ((g = findgroupid(&a->p->groups, ext4_inode_get_uid(&inode))) != nil && g->id == a->uid)){
t = ext4_inode_type(a->p->sb, &inode);
- if(t == EXT4_INODE_MODE_DIRECTORY && ext4_dir_open(&dir, s) == 0){
+ if(t == EXT4_INODE_MODE_DIRECTORY && ext4_dir_open(mp, &dir, a->path) == 0){
for(empty = 1; empty;){
if((e = ext4_dir_entry_next(&dir)) == nil)
break;
@@ -570,9 +506,9 @@
if(!empty){
werrstr("directory not empty");
goto error;
- }else if(ext4_dir_rm(s) < 0)
+ }else if(ext4_dir_rm(mp, a->path) < 0)
goto error;
- }else if(ext4_fremove(s) < 0)
+ }else if(ext4_fremove(mp, a->path) < 0)
goto error;
}else{
werrstr(Eperm);
@@ -579,12 +515,10 @@
goto error;
}
- free(s);
respond(r, nil);
return;
error:
- free(s);
responderror(r);
}
@@ -604,29 +538,23 @@
rwstat(Req *r)
{
int res, isdir, wrperm, isowner, n;
+ struct ext4_mountpoint *mp;
struct ext4_inode inode;
- char *old, *new, *s;
u32int uid, gid;
ext4_file f;
Aux *a, o;
Group *g;
+ char *s;
a = r->fid->aux;
- old = nil;
- new = nil;
+ mp = &a->p->mp;
/* can't do anything to root, can't change the owner */
- if(a->path[0] == 0 || (r->d.uid != nil && r->d.uid[0] != 0)){
+ if(*a->path == 0 || (r->d.uid != nil && r->d.uid[0] != 0)){
werrstr(Eperm);
goto error;
}
- if((old = smprint("%M/%s", a->p, a->path)) == nil){
- werrstr("memory");
- goto error;
- }
- new = old;
-
wrperm = haveperm(a, OWRITE, &inode);
uid = ext4_inode_get_uid(&inode);
isowner = uid == Root || a->uid == uid;
@@ -638,31 +566,6 @@
goto error;
}
- /* permission to rename */
- if(r->d.name != nil && r->d.name[0] != 0){
- if((s = strrchr(old, '/')) == nil){
- werrstr("botched name");
- goto error;
- }
- n = s - old;
- if((new = malloc(n + 1 + strlen(r->d.name) + 1)) == nil){
- werrstr("memory");
- goto error;
- }
- memmove(new, old, n);
- new[n++] = '/';
- strcpy(new+n, r->d.name);
-
- /* check parent write permission */
- o = *a;
- o.path = old;
- if(!haveperm(&o, OWRITE, nil)){
- werrstr(Eperm);
- goto error;
- }
- *s = '/';
- }
-
/* permission to change mode */
if(r->d.mode != ~0){
/* has to be owner and can't change dir bit */
@@ -687,24 +590,37 @@
}
}
- /* done checking permissions, now apply all the changes and hope it all works */
-
- /* rename */
+ /* check for permission to rename and do the rename */
if(r->d.name != nil && r->d.name[0] != 0){
- if(ext4_frename(old, new) < 0)
+ /* check parent write permission */
+ o = *a;
+ o.path = a->path;
+ if(!haveperm(&o, OWRITE, nil)){
+ werrstr(Eperm);
goto error;
+ }
- free(old);
- old = new;
- new = nil;
+ if((s = strrchr(a->path, '/')) != nil){
+ n = s - a->path;
+ s = emalloc9p(n + 1 + strlen(r->d.name) + 1);
+ memmove(s, a->path, n);
+ s[n++] = '/';
+ strcpy(s+n, r->d.name);
+ }else{
+ s = estrdup9p(r->d.name);
+ }
+ if(ext4_frename(mp, a->path, s) < 0){
+ free(s);
+ goto error;
+ }
free(a->path);
- a->path = strdup(strchr(old+1, '/')+1);
+ a->path = s;
}
/* truncate */
if(r->d.length >= 0){
- if(ext4_fopen2(&f, new, toext4mode(OWRITE, 0, 0)) < 0)
+ if(ext4_fopen2(mp, &f, a->path, toext4mode(OWRITE, 0, 0)) < 0)
goto error;
res = ext4_ftruncate(&f, r->d.length);
ext4_fclose(&f);
@@ -713,27 +629,21 @@
}
/* mode */
- if(r->d.mode != ~0 && ext4_mode_set(new, r->d.mode & 0x1ff) < 0)
+ if(r->d.mode != ~0 && ext4_mode_set(mp, a->path, r->d.mode & 0x1ff) < 0)
goto error;
/* mtime */
- if(r->d.mtime != ~0 && ext4_mtime_set(new, r->d.mtime) < 0)
+ if(r->d.mtime != ~0 && ext4_mtime_set(mp, a->path, r->d.mtime) < 0)
goto error;
/* gid */
- if(r->d.gid != nil && r->d.gid[0] != 0 && ext4_owner_set(new, uid, gid) < 0)
+ if(r->d.gid != nil && r->d.gid[0] != 0 && ext4_owner_set(mp, a->path, uid, gid) < 0)
goto error;
- free(old);
- if(new != old)
- free(new);
respond(r, nil);
return;
error:
- free(old);
- if(new != old)
- free(new);
responderror(r);
}
@@ -740,52 +650,50 @@
static char *
rwalk1(Fid *fid, char *name, Qid *qid)
{
+ struct ext4_mountpoint *mp;
static char errbuf[ERRMAX];
struct ext4_inode inode;
u32int ino, t;
Aux *a, dir;
- char *s, *q;
+ int isroot;
+ char *s;
a = fid->aux;
+ mp = &a->p->mp;
+ isroot = fid->qid.path == a->p->qidmask.path;
+ s = nil;
- /* try walking to the real file first */
- if((s = fullpath(a)) == nil){
- /* else try link itself. might want to just remove it anyway */
- if((s = smprint("%M/%s", a->p, a->path)) == nil)
- return "memory";
+ if(isroot && strcmp(name, "..") == 0){
+ *qid = a->p->qidmask;
+ fid->qid = a->p->qidmask;
+ return nil;
}
- if(ext4_raw_inode_fill(s, &ino, &inode) < 0)
- goto error;
- t = ext4_inode_type(a->p->sb, &inode);
- if(t != EXT4_INODE_MODE_DIRECTORY){
- free(s);
- return "not a directory";
- }
- dir = *a;
- dir.path = strchr(s+1, '/')+1;
- if(!haveperm(&dir, OEXEC, nil)){
- free(s);
- return Eperm;
- }
- q = s;
- s = smprint("%s/%s", q, name);
- cleanname(strchr(s+1, '/'));
- free(q);
- if((q = linkresolve(a, s, nil)) == nil){
-error:
+ if(ext4_raw_inode_fill(mp, a->path, &ino, &inode) < 0){
+err:
free(s);
rerrstr(errbuf, sizeof(errbuf));
return errbuf;
}
- s = q;
- if(ext4_raw_inode_fill(s, &ino, &inode) < 0)
- goto error;
+
t = ext4_inode_type(a->p->sb, &inode);
- if(opts.linkmode == Lhide && t == EXT4_INODE_MODE_SOFTLINK){
+ if(t != EXT4_INODE_MODE_DIRECTORY)
+ return "not a directory";
+ dir = *a;
+ dir.path = a->path;
+ if(!haveperm(&dir, OEXEC, nil))
+ return Eperm;
+
+ s = isroot ? estrdup9p(name) : smprint("%s/%s", a->path, name);
+ cleanname(s);
+ if(ext4_raw_inode_fill(mp, s, &ino, &inode) < 0)
+ goto err;
+ t = ext4_inode_type(a->p->sb, &inode);
+ if(t != EXT4_INODE_MODE_FILE && t != EXT4_INODE_MODE_DIRECTORY){
free(s);
return "not found";
}
+
qid->type = 0;
qid->path = a->p->qidmask.path | ino;
qid->vers = ext4_inode_get_generation(&inode);
@@ -797,8 +705,7 @@
if(ext4_inode_get_flags(&inode) & EXT4_INODE_FLAG_APPEND)
qid->type |= QTAPPEND;
free(a->path);
- a->path = strdup(strchr(s+1, '/')+1);
- free(s);
+ a->path = s;
fid->qid = *qid;
return nil;
@@ -814,7 +721,7 @@
if((c = calloc(1, sizeof(*c))) == nil)
return "memory";
memmove(c, a, sizeof(*c));
- c->path = strdup(a->path);
+ c->path = estrdup9p(a->path);
c->file = nil;
c->dir = nil;
@@ -935,7 +842,7 @@
static void
usage(void)
{
- fprint(2, "usage: %s [-Clrs] [-g groupfile] [-R uid] [srvname]\n", argv0);
+ fprint(2, "usage: %s [-Crs] [-g groupfile] [-R uid] [srvname]\n", argv0);
fprint(2, "mkfs: %s -M (2|3|4) [-L label] [-b blksize] [-N numinodes] [-I inodesize] device\n", argv0);
threadexitsall("usage");
}
@@ -963,9 +870,6 @@
break;
case 'C':
opts.cachewb = 1;
- goto nomkfs;
- case 'l':
- opts.linkmode = Lresolve;
goto nomkfs;
case 'g':
gr = EARGF(usage());
--- a/sys/src/cmd/ext4srv/include/ext4.h
+++ b/sys/src/cmd/ext4srv/include/ext4.h
@@ -3,9 +3,31 @@
#include "ext4_types.h"
#include "ext4_debug.h"
#include "ext4_blockdev.h"
+#include "ext4_fs.h"
+#include "ext4_journal.h"
-#pragma incomplete struct ext4_mountpoint
+/**@brief Mount point descriptor.*/
+struct ext4_mountpoint {
+ /**@brief Mount done flag.*/
+ bool mounted;
+
+ /**@brief OS dependent lock/unlock functions.*/
+ const struct ext4_lock *os_locks;
+
+ /**@brief Ext4 filesystem internals.*/
+ struct ext4_fs fs;
+
+ /**@brief JBD fs.*/
+ struct jbd_fs jbd_fs;
+
+ /**@brief Journal.*/
+ struct jbd_journal jbd_journal;
+
+ /**@brief Block cache.*/
+ struct ext4_bcache bc;
+};
+
/********************************OS LOCK INFERFACE***************************/
/**@brief OS dependent lock interface.*/
@@ -65,79 +87,12 @@
/********************************MOUNT OPERATIONS****************************/
-/**@brief Register block device.
- *
- * @param bd Block device.
- * @param dev_name Block device name.
- *
- * @return Standard error code.*/
-int ext4_device_register(struct ext4_blockdev *bd,
- const char *dev_name);
+int ext4_mount(struct ext4_mountpoint *mp, struct ext4_blockdev *bd, bool read_only);
+int ext4_umount(struct ext4_mountpoint *mp);
+int ext4_journal_start(struct ext4_mountpoint *mp);
+int ext4_journal_stop(struct ext4_mountpoint *mp);
+int ext4_recover(struct ext4_mountpoint *mp);
-/**@brief Un-register block device.
- *
- * @param dev_name Block device name.
- *
- * @return Standard error code.*/
-int ext4_device_unregister(const char *dev_name);
-
-/**@brief Un-register all block devices.
- *
- * @return Standard error code.*/
-int ext4_device_unregister_all(void);
-
-/**@brief Mount a block device with EXT4 partition to the mount point.
- *
- * @param dev_name Block device name (@ref ext4_device_register).
- * @param mount_point Mount point, for example:
- * - /
- * - /my_partition/
- * - /my_second_partition/
- * @param read_only mount as read-only mode.
- *
- * @return Standard error code */
-int ext4_mount(const char *dev_name,
- const char *mount_point,
- bool read_only);
-
-/**@brief Umount operation.
- *
- * @param mount_point Mount point.
- *
- * @return Standard error code */
-int ext4_umount(const char *mount_point);
-
-/**@brief Starts journaling. Journaling start/stop functions are transparent
- * and might be used on filesystems without journaling support.
- * @warning Usage:
- * ext4_mount("sda1", "/");
- * ext4_journal_start("/");
- *
- * //File operations here...
- *
- * ext4_journal_stop("/");
- * ext4_umount("/");
- * @param mount_point Mount point.
- *
- * @return Standard error code. */
-int ext4_journal_start(const char *mount_point);
-
-/**@brief Stops journaling. Journaling start/stop functions are transparent
- * and might be used on filesystems without journaling support.
- *
- * @param mount_point Mount point name.
- *
- * @return Standard error code. */
-int ext4_journal_stop(const char *mount_point);
-
-/**@brief Journal recovery.
- * @warning Must be called after @ref ext4_mount.
- *
- * @param mount_point Mount point.
- *
- * @return Standard error code. */
-int ext4_recover(const char *mount_point);
-
/**@brief Some of the filesystem stats. */
struct ext4_mount_stats {
u32int inodes_count;
@@ -153,77 +108,12 @@
char volume_name[16];
};
-/**@brief Get file mount point stats.
- *
- * @param mount_point Mount point.
- * @param stats Filesystem stats.
- *
- * @return Standard error code. */
-int ext4_mount_point_stats(const char *mount_point,
- struct ext4_mount_stats *stats);
+int ext4_mount_point_stats(struct ext4_mountpoint *mp, struct ext4_mount_stats *stats);
+int ext4_mount_setup_locks(struct ext4_mountpoint *mp, const struct ext4_lock *locks);
+int ext4_get_sblock(struct ext4_mountpoint *mp, struct ext4_sblock **sb);
+int ext4_cache_write_back(struct ext4_mountpoint *mp, bool on);
+int ext4_cache_flush(struct ext4_mountpoint *mp);
-/**@brief Setup OS lock routines.
- *
- * @param mount_point Mount point.
- * @param locks Lock and unlock functions
- *
- * @return Standard error code. */
-int ext4_mount_setup_locks(const char *mount_point,
- const struct ext4_lock *locks);
-
-/**@brief Acquire the filesystem superblock pointer of a mp.
- *
- * @param mount_point Mount point.
- * @param sb Superblock handle
- *
- * @return Standard error code. */
-int ext4_get_sblock(const char *mount_point, struct ext4_sblock **sb);
-
-/**@brief Enable/disable write back cache mode.
- * @warning Default model of cache is write through. It means that when you do:
- *
- * ext4_fopen(...);
- * ext4_fwrite(...);
- * < --- data is flushed to physical drive
- *
- * When you do:
- * ext4_cache_write_back(..., 1);
- * ext4_fopen(...);
- * ext4_fwrite(...);
- * < --- data is NOT flushed to physical drive
- * ext4_cache_write_back(..., 0);
- * < --- when write back mode is disabled all
- * cache data will be flushed
- * To enable write back mode permanently just call this function
- * once after ext4_mount (and disable before ext4_umount).
- *
- * Some of the function use write back cache mode internally.
- * If you enable write back mode twice you have to disable it twice
- * to flush all data:
- *
- * ext4_cache_write_back(..., 1);
- * ext4_cache_write_back(..., 1);
- *
- * ext4_cache_write_back(..., 0);
- * ext4_cache_write_back(..., 0);
- *
- * Write back mode is useful when you want to create a lot of empty
- * files/directories.
- *
- * @param path Path.
- * @param on Enable/disable cache writeback mode.
- *
- * @return Standard error code. */
-int ext4_cache_write_back(const char *path, bool on);
-
-
-/**@brief Force cache flush.
- *
- * @param path Path.
- *
- * @return Standard error code. */
-int ext4_cache_flush(const char *path);
-
/********************************FILE OPERATIONS*****************************/
/**@brief Remove file by path.
@@ -231,7 +121,7 @@
* @param path Path to file.
*
* @return Standard error code. */
-int ext4_fremove(const char *path);
+int ext4_fremove(struct ext4_mountpoint *mp, const char *path);
/**@brief Create a hardlink for a file.
*
@@ -239,13 +129,13 @@
* @param hardlink_path Path of hardlink.
*
* @return Standard error code. */
-int ext4_flink(const char *path, const char *hardlink_path);
+int ext4_flink(struct ext4_mountpoint *mp, const char *path, const char *hardlink_path);
/**@brief Rename file.
* @param path Source.
* @param new_path Destination.
* @return Standard error code. */
-int ext4_frename(const char *path, const char *new_path);
+int ext4_frename(struct ext4_mountpoint *mp, const char *path, const char *new_path);
/**@brief File open function.
*
@@ -267,7 +157,7 @@
* |---------------------------------------------------------------|
*
* @return Standard error code.*/
-int ext4_fopen(ext4_file *file, const char *path, const char *flags);
+int ext4_fopen(struct ext4_mountpoint *mp, ext4_file *file, const char *path, const char *flags);
/**@brief Alternate file open function.
*
@@ -276,7 +166,7 @@
* @param flags File open flags.
*
* @return Standard error code.*/
-int ext4_fopen2(ext4_file *file, const char *path, int flags);
+int ext4_fopen2(struct ext4_mountpoint *mp, ext4_file *file, const char *path, int flags);
/**@brief File close function.
*
@@ -319,12 +209,12 @@
* @param file File handle.
* @param offset Offset to seek.
* @param origin Seek type:
- * @ref SEEK_SET
- * @ref SEEK_CUR
- * @ref SEEK_END
+ * @ref 0 (set)
+ * @ref 1 (cur)
+ * @ref 2 (end)
*
* @return Standard error code.*/
-int ext4_fseek(ext4_file *file, s64int offset, u32int origin);
+int ext4_fseek(ext4_file *file, s64int offset, int origin);
/**@brief Get file position.
*
@@ -348,7 +238,7 @@
* @param inode Inode internals.
*
* @return Standard error code.*/
-int ext4_raw_inode_fill(const char *path, u32int *ret_ino,
+int ext4_raw_inode_fill(struct ext4_mountpoint *mp, const char *path, u32int *ret_ino,
struct ext4_inode *inode);
/**@brief Check if inode exists.
@@ -365,7 +255,7 @@
* @ref EXT4_DE_SYMLINK
*
* @return Standard error code.*/
-int ext4_inode_exist(const char *path, int type);
+int ext4_inode_exist(struct ext4_mountpoint *mp, const char *path, int type);
/**@brief Change file/directory/link mode bits.
*
@@ -373,7 +263,7 @@
* @param mode New mode bits (for example 0777).
*
* @return Standard error code.*/
-int ext4_mode_set(const char *path, u32int mode);
+int ext4_mode_set(struct ext4_mountpoint *mp, const char *path, u32int mode);
/**@brief Get file/directory/link mode bits.
@@ -382,7 +272,7 @@
* @param mode New mode bits (for example 0777).
*
* @return Standard error code.*/
-int ext4_mode_get(const char *path, u32int *mode);
+int ext4_mode_get(struct ext4_mountpoint *mp, const char *path, u32int *mode);
/**@brief Change file owner and group.
*
@@ -391,7 +281,7 @@
* @param gid Group id.
*
* @return Standard error code.*/
-int ext4_owner_set(const char *path, u32int uid, u32int gid);
+int ext4_owner_set(struct ext4_mountpoint *mp, const char *path, u32int uid, u32int gid);
/**@brief Get file/directory/link owner and group.
*
@@ -400,7 +290,7 @@
* @param gid Group id.
*
* @return Standard error code.*/
-int ext4_owner_get(const char *path, u32int *uid, u32int *gid);
+int ext4_owner_get(struct ext4_mountpoint *mp, const char *path, u32int *uid, u32int *gid);
/**@brief Set file/directory/link access time.
*
@@ -408,7 +298,7 @@
* @param atime Access timestamp.
*
* @return Standard error code.*/
-int ext4_atime_set(const char *path, u32int atime);
+int ext4_atime_set(struct ext4_mountpoint *mp, const char *path, u32int atime);
/**@brief Set file/directory/link modify time.
*
@@ -416,7 +306,7 @@
* @param mtime Modify timestamp.
*
* @return Standard error code.*/
-int ext4_mtime_set(const char *path, u32int mtime);
+int ext4_mtime_set(struct ext4_mountpoint *mp, const char *path, u32int mtime);
/**@brief Set file/directory/link change time.
*
@@ -424,7 +314,7 @@
* @param ctime Change timestamp.
*
* @return Standard error code.*/
-int ext4_ctime_set(const char *path, u32int ctime);
+int ext4_ctime_set(struct ext4_mountpoint *mp, const char *path, u32int ctime);
/**@brief Get file/directory/link access time.
*
@@ -432,7 +322,7 @@
* @param atime Access timestamp.
*
* @return Standard error code.*/
-int ext4_atime_get(const char *path, u32int *atime);
+int ext4_atime_get(struct ext4_mountpoint *mp, const char *path, u32int *atime);
/**@brief Get file/directory/link modify time.
*
@@ -440,7 +330,7 @@
* @param mtime Modify timestamp.
*
* @return Standard error code.*/
-int ext4_mtime_get(const char *path, u32int *mtime);
+int ext4_mtime_get(struct ext4_mountpoint *mp, const char *path, u32int *mtime);
/**@brief Get file/directory/link change time.
*
@@ -448,7 +338,7 @@
* @param ctime Change timestamp.
*
* @return standard error code*/
-int ext4_ctime_get(const char *path, u32int *ctime);
+int ext4_ctime_get(struct ext4_mountpoint *mp, const char *path, u32int *ctime);
/**@brief Create symbolic link.
*
@@ -456,7 +346,7 @@
* @param path Source entry path.
*
* @return Standard error code.*/
-int ext4_fsymlink(const char *target, const char *path);
+int ext4_fsymlink(struct ext4_mountpoint *mp, const char *target, const char *path);
/**@brief Create special file.
* @param path Path to new special file.
@@ -465,7 +355,7 @@
* @param dev If filetype is char device or block device,
* the device number will become the payload in the inode.
* @return Standard error code.*/
-int ext4_mknod(const char *path, int filetype, u32int dev);
+int ext4_mknod(struct ext4_mountpoint *mp, const char *path, int filetype, u32int dev);
/**@brief Read symbolic link payload.
*
@@ -475,7 +365,7 @@
* @param rcnt Bytes read.
*
* @return Standard error code.*/
-int ext4_readlink(const char *path, char *buf, usize bufsize, usize *rcnt);
+int ext4_readlink(struct ext4_mountpoint *mp, const char *path, char *buf, usize bufsize, usize *rcnt);
/*********************************DIRECTORY OPERATION***********************/
@@ -484,7 +374,7 @@
* @param path Directory path to remove
*
* @return Standard error code.*/
-int ext4_dir_rm(const char *path);
+int ext4_dir_rm(struct ext4_mountpoint *mp, const char *path);
/**@brief Rename/move directory.
*
@@ -492,7 +382,7 @@
* @param new_path Destination path.
*
* @return Standard error code. */
-int ext4_dir_mv(const char *path, const char *new_path);
+int ext4_dir_mv(struct ext4_mountpoint *mp, const char *path, const char *new_path);
/**@brief Create new directory.
*
@@ -499,7 +389,7 @@
* @param path Directory name.
*
* @return Standard error code.*/
-int ext4_dir_mk(const char *path);
+int ext4_dir_mk(struct ext4_mountpoint *mp, const char *path);
/**@brief Directory open.
*
@@ -507,7 +397,7 @@
* @param path Directory path.
*
* @return Standard error code.*/
-int ext4_dir_open(ext4_dir *dir, const char *path);
+int ext4_dir_open(struct ext4_mountpoint *mp, ext4_dir *dir, const char *path);
/**@brief Directory close.
*
--- a/sys/src/cmd/ext4srv/part.c
+++ b/sys/src/cmd/ext4srv/part.c
@@ -161,8 +161,8 @@
d = nil;
while(*path == '/')
path++;
- s = smprint("%M/%s", p, path);
- r = ext4_fopen2(&f, s, O_RDONLY);
+ s = smprint("/%s", path);
+ r = ext4_fopen2(&p->mp, &f, s, O_RDONLY);
free(s);
if(r == 0){
@@ -197,47 +197,37 @@
static int
mountpart(Part *p, Opts *opts)
{
+ struct ext4_mountpoint *mp;
usize sz;
char *gr;
int r;
- r = 0;
- if(snprint(p->dev, sizeof(p->dev), "%Ð", p) >= sizeof(p->dev)){
- werrstr("part path too long");
- goto error;
- }
- if(snprint(p->mnt, sizeof(p->mnt), "%M/", p) >= sizeof(p->mnt)){
- werrstr("part path too long");
- goto error;
- }
- if(ext4_device_register(&p->bdev, p->dev) < 0){
- werrstr("register: %r");
- goto error;
- }
- if(ext4_mount(p->dev, p->mnt, opts->rdonly) < 0){
+ mp = &p->mp;
+ if(ext4_mount(mp, &p->bdev, opts->rdonly) < 0){
werrstr("mount: %r");
goto error;
}
- if(ext4_mount_setup_locks(p->mnt, &p->oslocks) < 0){
+ if(ext4_mount_setup_locks(mp, &p->oslocks) < 0){
werrstr("locks: %r");
goto error;
}
- if(ext4_recover(p->mnt) < 0){
+ if(ext4_recover(mp) < 0){
werrstr("recover: %r");
goto error;
}
- if(ext4_journal_start(p->mnt) < 0){
+ if(ext4_journal_start(mp) < 0){
werrstr("journal: %r");
goto error;
}
if(opts->cachewb)
- ext4_cache_write_back(p->mnt, 1);
+ ext4_cache_write_back(mp, 1);
- if(ext4_get_sblock(p->mnt, &p->sb) < 0){
+ if(ext4_get_sblock(mp, &p->sb) < 0){
werrstr("sblock: %r");
goto error;
}
+ r = 0;
if(opts->group != nil){
r = loadgroups(&p->groups, opts->group);
}else if((gr = readfile(p, "/etc/group", &sz)) != nil){
@@ -288,9 +278,6 @@
s = nil;
qlock(&sv);
- fmtinstall(L'Ð', fmtpart);
- fmtinstall('M', fmtpart);
-
f = open(dev, ORDWR);
if(f < 0 || (d = dirfstat(f)) == nil)
goto error;
@@ -367,13 +354,14 @@
static void
_closepart(Part *p)
{
- ext4_cache_write_back(p->mnt, 0);
- if(ext4_journal_stop(p->mnt) < 0)
- fprint(2, "closepart: journal %s: %r\n", p->mnt);
- if(ext4_umount(p->mnt) < 0)
- fprint(2, "closepart: umount %s: %r\n", p->mnt);
- if(ext4_device_unregister(p->dev) < 0)
- fprint(2, "closepart: unregister %s: %r\n", p->dev);
+ struct ext4_mountpoint *mp;
+
+ mp = &p->mp;
+ ext4_cache_write_back(mp, 0);
+ if(ext4_journal_stop(mp) < 0)
+ fprint(2, "closepart: journal: %s: %r\n", p->partdev);
+ if(ext4_umount(mp) < 0)
+ fprint(2, "closepart: umount %s: %r\n", p->partdev);
close(p->f);
if(p->prev != nil)
p->prev = p->next;
@@ -411,7 +399,7 @@
qlock(&sv);
for(p = sv.ps; p != nil; p = p->next){
- if(ext4_mount_point_stats(p->mnt, &s) < 0){
+ if(ext4_mount_point_stats(&p->mp, &s) < 0){
fprint(2, "%s: %r\n", p->partdev);
}else{
print(
@@ -447,7 +435,7 @@
Part *p;
qlock(&sv);
for(p = sv.ps; p != nil; p = p->next){
- if(ext4_cache_flush(p->mnt) < 0)
+ if(ext4_cache_flush(&p->mp) < 0)
fprint(2, "%s: %r\n", p->partdev);
}
qunlock(&sv);