Browse Source

ext4: add methods to access file mode, owner, atime, mtime, ctime

pull/22/head
gkostka 8 years ago
parent
commit
83e87bd113
  1. 48
      include/ext4.h
  2. 349
      src/ext4.c

48
include/ext4.h

@ -348,32 +348,64 @@ uint64_t ext4_fsize(ext4_file *f);
* @param path to file/dir/link
* @param mode new mode bits (for example 0777)
* @return standard error code*/
int ext4_chmod(const char *path, uint32_t mode);
int ext4_mode_set(const char *path, uint32_t mode);
/**@brief Get file/directory/link mode bits
* @param path to file/dir/link
* @param mode new mode bits (for example 0777)
* @return standard error code*/
int ext4_mode_get(const char *path, uint32_t *mode);
/**@brief Change file owner and group
* @param path to file/dir/link
* @param uid user id
* @param gid group id
* @return standard error code*/
int ext4_chown(const char *path, uint32_t uid, uint32_t gid);
int ext4_owner_set(const char *path, uint32_t uid, uint32_t gid);
/**@brief Get file/directory/link owner and group
* @param path to file/dir/link
* @param uid user id
* @param gid group id
* @return standard error code*/
int ext4_owner_get(const char *path, uint32_t *uid, uint32_t *gid);
/**@brief Set file/directory/link access time
* @param path to file/dir/link
* @param atime access timestamp
* @return standard error code*/
int ext4_atime_set(const char *path, uint32_t atime);
/**@brief Set file/directory/link modify time
* @param path to file/dir/link
* @param mtime modify timestamp
* @return standard error code*/
int ext4_mtime_set(const char *path, uint32_t mtime);
/**@brief Set file/directory/link change time
* @param path to file/dir/link
* @param ctime change timestamp
* @return standard error code*/
int ext4_ctime_set(const char *path, uint32_t ctime);
/**@brief Set file access time
/**@brief Get file/directory/link access time
* @param path to file/dir/link
* @param atime access timestamp
* @return standard error code*/
int ext4_file_set_atime(const char *path, uint32_t atime);
int ext4_atime_get(const char *path, uint32_t *atime);
/**@brief Set file modify time
/**@brief Get file/directory/link modify time
* @param path to file/dir/link
* @param mtime modify timestamp
* @return standard error code*/
int ext4_file_set_mtime(const char *path, uint32_t mtime);
int ext4_mtime_get(const char *path, uint32_t *mtime);
/**@brief Set file change time
/**@brief Get file/directory/link change time
* @param path to file/dir/link
* @param ctime change timestamp
* @return standard error code*/
int ext4_file_set_ctime(const char *path, uint32_t ctime);
int ext4_ctime_get(const char *path, uint32_t *ctime);
/**@brief Create symbolic link
* @param target destination path

349
src/ext4.c

@ -2055,61 +2055,80 @@ uint64_t ext4_fsize(ext4_file *f)
return f->fsize;
}
int ext4_chmod(const char *path, uint32_t mode)
static int ext4_trans_get_inode_ref(const char *path,
struct ext4_mountpoint *mp,
struct ext4_inode_ref *inode_ref)
{
int r;
uint32_t ino, orig_mode;
ext4_file f;
struct ext4_sblock *sb;
struct ext4_inode_ref inode_ref;
struct ext4_mountpoint *mp = ext4_get_mount(path);
if (!mp)
return ENOENT;
if (mp->fs.read_only)
return EROFS;
EXT4_MP_LOCK(mp);
ext4_trans_start(mp);
r = ext4_generic_open2(&f, path, O_RDWR, EXT4_DE_UNKNOWN, NULL, NULL);
if (r != EOK) {
ext4_trans_abort(mp);
EXT4_MP_UNLOCK(mp);
return r;
}
ino = f.inode;
sb = &mp->fs.sb;
ext4_fclose(&f);
r = ext4_fs_get_inode_ref(&mp->fs, ino, &inode_ref);
r = ext4_fs_get_inode_ref(&mp->fs, f.inode, inode_ref);
if (r != EOK) {
ext4_trans_abort(mp);
EXT4_MP_UNLOCK(mp);
return r;
}
orig_mode = ext4_inode_get_mode(sb, inode_ref.inode);
orig_mode &= ~0xFFF;
orig_mode |= mode & 0xFFF;
ext4_inode_set_mode(sb, inode_ref.inode, orig_mode);
inode_ref.dirty = true;
return r;
}
r = ext4_fs_put_inode_ref(&inode_ref);
static int ext4_trans_put_inode_ref(struct ext4_mountpoint *mp,
struct ext4_inode_ref *inode_ref)
{
int r;
r = ext4_fs_put_inode_ref(inode_ref);
if (r != EOK)
ext4_trans_abort(mp);
else
ext4_trans_stop(mp);
return r;
}
int ext4_mode_set(const char *path, uint32_t mode)
{
int r;
uint32_t orig_mode;
struct ext4_inode_ref inode_ref;
struct ext4_mountpoint *mp = ext4_get_mount(path);
if (!mp)
return ENOENT;
if (mp->fs.read_only)
return EROFS;
EXT4_MP_LOCK(mp);
r = ext4_trans_get_inode_ref(path, mp, &inode_ref);
if (r != EOK)
goto Finish;
orig_mode = ext4_inode_get_mode(&mp->fs.sb, inode_ref.inode);
orig_mode &= ~0xFFF;
orig_mode |= mode & 0xFFF;
ext4_inode_set_mode(&mp->fs.sb, inode_ref.inode, orig_mode);
inode_ref.dirty = true;
r = ext4_trans_put_inode_ref(mp, &inode_ref);
Finish:
EXT4_MP_UNLOCK(mp);
return r;
}
int ext4_chown(const char *path, uint32_t uid, uint32_t gid)
int ext4_owner_set(const char *path, uint32_t uid, uint32_t gid)
{
int r;
ext4_file f;
uint32_t ino;
struct ext4_inode_ref inode_ref;
struct ext4_mountpoint *mp = ext4_get_mount(path);
@ -2120,44 +2139,61 @@ int ext4_chown(const char *path, uint32_t uid, uint32_t gid)
return EROFS;
EXT4_MP_LOCK(mp);
ext4_trans_start(mp);
r = ext4_generic_open2(&f, path, O_RDWR, EXT4_DE_UNKNOWN, NULL, NULL);
if (r != EOK) {
ext4_trans_abort(mp);
EXT4_MP_UNLOCK(mp);
return r;
}
ino = f.inode;
ext4_fclose(&f);
r = ext4_fs_get_inode_ref(&mp->fs, ino, &inode_ref);
if (r != EOK) {
ext4_trans_abort(mp);
EXT4_MP_UNLOCK(mp);
return r;
}
r = ext4_trans_get_inode_ref(path, mp, &inode_ref);
if (r != EOK)
goto Finish;
ext4_inode_set_uid(inode_ref.inode, uid);
ext4_inode_set_gid(inode_ref.inode, gid);
inode_ref.dirty = true;
r = ext4_trans_put_inode_ref(mp, &inode_ref);
r = ext4_fs_put_inode_ref(&inode_ref);
Finish:
EXT4_MP_UNLOCK(mp);
return r;
}
int ext4_mode_get(const char *path, uint32_t *mode)
{
struct ext4_inode_ref inode_ref;
struct ext4_mountpoint *mp = ext4_get_mount(path);
ext4_file f;
int r;
if (!mp)
return ENOENT;
if (mp->fs.read_only)
return EROFS;
EXT4_MP_LOCK(mp);
r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN, NULL, NULL);
if (r != EOK)
ext4_trans_abort(mp);
else
ext4_trans_stop(mp);
goto Finish;
r = ext4_fs_get_inode_ref(&mp->fs, f.inode, &inode_ref);
if (r != EOK)
goto Finish;
*mode = ext4_inode_get_mode(&mp->fs.sb, inode_ref.inode);
r = ext4_fs_put_inode_ref(&inode_ref);
Finish:
EXT4_MP_UNLOCK(mp);
return r;
}
int ext4_file_set_atime(const char *path, uint32_t atime)
int ext4_owner_get(const char *path, uint32_t *uid, uint32_t *gid)
{
int r;
ext4_file f;
uint32_t ino;
struct ext4_inode_ref inode_ref;
struct ext4_mountpoint *mp = ext4_get_mount(path);
ext4_file f;
int r;
if (!mp)
return ENOENT;
@ -2166,43 +2202,58 @@ int ext4_file_set_atime(const char *path, uint32_t atime)
return EROFS;
EXT4_MP_LOCK(mp);
ext4_trans_start(mp);
r = ext4_generic_open2(&f, path, O_RDWR, EXT4_DE_UNKNOWN, NULL, NULL);
if (r != EOK) {
ext4_trans_abort(mp);
EXT4_MP_UNLOCK(mp);
return r;
}
ino = f.inode;
ext4_fclose(&f);
r = ext4_fs_get_inode_ref(&mp->fs, ino, &inode_ref);
if (r != EOK) {
ext4_trans_abort(mp);
EXT4_MP_UNLOCK(mp);
return r;
}
r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN, NULL, NULL);
if (r != EOK)
goto Finish;
ext4_inode_set_access_time(inode_ref.inode, atime);
inode_ref.dirty = true;
r = ext4_fs_get_inode_ref(&mp->fs, f.inode, &inode_ref);
if (r != EOK)
goto Finish;
*uid = ext4_inode_get_uid(inode_ref.inode);
*gid = ext4_inode_get_gid(inode_ref.inode);
r = ext4_fs_put_inode_ref(&inode_ref);
if (r != EOK)
ext4_trans_abort(mp);
else
ext4_trans_stop(mp);
Finish:
EXT4_MP_UNLOCK(mp);
return r;
}
int ext4_file_set_mtime(const char *path, uint32_t mtime)
int ext4_atime_set(const char *path, uint32_t atime)
{
struct ext4_inode_ref inode_ref;
struct ext4_mountpoint *mp = ext4_get_mount(path);
int r;
ext4_file f;
uint32_t ino;
if (!mp)
return ENOENT;
if (mp->fs.read_only)
return EROFS;
EXT4_MP_LOCK(mp);
r = ext4_trans_get_inode_ref(path, mp, &inode_ref);
if (r != EOK)
goto Finish;
ext4_inode_set_access_time(inode_ref.inode, atime);
inode_ref.dirty = true;
r = ext4_trans_put_inode_ref(mp, &inode_ref);
Finish:
EXT4_MP_UNLOCK(mp);
return r;
}
int ext4_mtime_set(const char *path, uint32_t mtime)
{
struct ext4_inode_ref inode_ref;
struct ext4_mountpoint *mp = ext4_get_mount(path);
int r;
if (!mp)
return ENOENT;
@ -2211,43 +2262,87 @@ int ext4_file_set_mtime(const char *path, uint32_t mtime)
return EROFS;
EXT4_MP_LOCK(mp);
ext4_trans_start(mp);
r = ext4_generic_open2(&f, path, O_RDWR, EXT4_DE_UNKNOWN, NULL, NULL);
if (r != EOK) {
ext4_trans_abort(mp);
EXT4_MP_UNLOCK(mp);
return r;
}
ino = f.inode;
ext4_fclose(&f);
r = ext4_fs_get_inode_ref(&mp->fs, ino, &inode_ref);
if (r != EOK) {
ext4_trans_abort(mp);
EXT4_MP_UNLOCK(mp);
return r;
}
r = ext4_trans_get_inode_ref(path, mp, &inode_ref);
if (r != EOK)
goto Finish;
ext4_inode_set_modif_time(inode_ref.inode, mtime);
inode_ref.dirty = true;
r = ext4_trans_put_inode_ref(mp, &inode_ref);
r = ext4_fs_put_inode_ref(&inode_ref);
Finish:
EXT4_MP_UNLOCK(mp);
return r;
}
int ext4_ctime_set(const char *path, uint32_t ctime)
{
struct ext4_inode_ref inode_ref;
struct ext4_mountpoint *mp = ext4_get_mount(path);
int r;
if (!mp)
return ENOENT;
if (mp->fs.read_only)
return EROFS;
EXT4_MP_LOCK(mp);
r = ext4_trans_get_inode_ref(path, mp, &inode_ref);
if (r != EOK)
ext4_trans_abort(mp);
else
ext4_trans_stop(mp);
goto Finish;
ext4_inode_set_change_inode_time(inode_ref.inode, ctime);
inode_ref.dirty = true;
r = ext4_trans_put_inode_ref(mp, &inode_ref);
Finish:
EXT4_MP_UNLOCK(mp);
return r;
}
int ext4_file_set_ctime(const char *path, uint32_t ctime)
int ext4_atime_get(const char *path, uint32_t *atime)
{
int r;
struct ext4_inode_ref inode_ref;
struct ext4_mountpoint *mp = ext4_get_mount(path);
ext4_file f;
uint32_t ino;
int r;
if (!mp)
return ENOENT;
if (mp->fs.read_only)
return EROFS;
EXT4_MP_LOCK(mp);
r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN, NULL, NULL);
if (r != EOK)
goto Finish;
r = ext4_fs_get_inode_ref(&mp->fs, f.inode, &inode_ref);
if (r != EOK)
goto Finish;
*atime = ext4_inode_get_access_time(inode_ref.inode);
r = ext4_fs_put_inode_ref(&inode_ref);
Finish:
EXT4_MP_UNLOCK(mp);
return r;
}
int ext4_mtime_get(const char *path, uint32_t *mtime)
{
struct ext4_inode_ref inode_ref;
struct ext4_mountpoint *mp = ext4_get_mount(path);
ext4_file f;
int r;
if (!mp)
return ENOENT;
@ -2256,33 +2351,53 @@ int ext4_file_set_ctime(const char *path, uint32_t ctime)
return EROFS;
EXT4_MP_LOCK(mp);
ext4_trans_start(mp);
r = ext4_generic_open2(&f, path, O_RDWR, EXT4_DE_UNKNOWN, NULL, NULL);
if (r != EOK) {
ext4_trans_abort(mp);
EXT4_MP_UNLOCK(mp);
return r;
}
ino = f.inode;
ext4_fclose(&f);
r = ext4_fs_get_inode_ref(&mp->fs, ino, &inode_ref);
if (r != EOK) {
ext4_trans_abort(mp);
EXT4_MP_UNLOCK(mp);
return r;
}
r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN, NULL, NULL);
if (r != EOK)
goto Finish;
ext4_inode_set_change_inode_time(inode_ref.inode, ctime);
inode_ref.dirty = true;
r = ext4_fs_get_inode_ref(&mp->fs, f.inode, &inode_ref);
if (r != EOK)
goto Finish;
*mtime = ext4_inode_get_modif_time(inode_ref.inode);
r = ext4_fs_put_inode_ref(&inode_ref);
Finish:
EXT4_MP_UNLOCK(mp);
return r;
}
int ext4_ctime_get(const char *path, uint32_t *ctime)
{
struct ext4_inode_ref inode_ref;
struct ext4_mountpoint *mp = ext4_get_mount(path);
ext4_file f;
int r;
if (!mp)
return ENOENT;
if (mp->fs.read_only)
return EROFS;
EXT4_MP_LOCK(mp);
r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN, NULL, NULL);
if (r != EOK)
ext4_trans_abort(mp);
else
ext4_trans_stop(mp);
goto Finish;
r = ext4_fs_get_inode_ref(&mp->fs, f.inode, &inode_ref);
if (r != EOK)
goto Finish;
*ctime = ext4_inode_get_change_inode_time(inode_ref.inode);
r = ext4_fs_put_inode_ref(&inode_ref);
Finish:
EXT4_MP_UNLOCK(mp);
return r;
}

Loading…
Cancel
Save