aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2006-08-06 04:47:34 -0400
committerJeff Garzik <jeff@garzik.org>2006-08-06 04:47:34 -0400
commite8b8341d44c0dcfab2ba016449d51e1579a9894a (patch)
tree04a6f3280115c66c8ab23802dcc9fd10aeff7910
parent590d1454714cd8c1395b0d94ba83268b420e6f57 (diff)
downloaddbfs-e8b8341d44c0dcfab2ba016449d51e1579a9894a.tar.gz
Implement setattr op.
-rw-r--r--dbfs-backend.c2
-rw-r--r--dbfs.c95
-rw-r--r--dbfs.h1
3 files changed, 81 insertions, 17 deletions
diff --git a/dbfs-backend.c b/dbfs-backend.c
index d233170..30ef303 100644
--- a/dbfs-backend.c
+++ b/dbfs-backend.c
@@ -939,7 +939,7 @@ static int dbfs_inode_realloc(struct dbfs_inode *ino,
return 0;
}
-static int dbfs_inode_resize(struct dbfs_inode *ino, guint64 new_size)
+int dbfs_inode_resize(struct dbfs_inode *ino, guint64 new_size)
{
guint64 old_size, diff, diff_ext;
unsigned int grow, i, new_n_extents, tmp;
diff --git a/dbfs.c b/dbfs.c
index 4370faa..eb65e8f 100644
--- a/dbfs.c
+++ b/dbfs.c
@@ -41,6 +41,24 @@ static void dbfs_fill_ent(const struct dbfs_inode *ino,
ent->entry_timeout = 2.0;
}
+static void dbfs_fill_attr(const struct dbfs_inode *ino, struct stat *st)
+{
+ memset(st, 0, sizeof(*st));
+ st->st_dev = 1;
+ st->st_ino = GUINT64_FROM_LE(ino->raw_inode->ino);
+ st->st_mode = GUINT32_FROM_LE(ino->raw_inode->mode);
+ st->st_nlink = GUINT32_FROM_LE(ino->raw_inode->nlink);
+ st->st_uid = GUINT32_FROM_LE(ino->raw_inode->uid);
+ st->st_gid = GUINT32_FROM_LE(ino->raw_inode->gid);
+ st->st_rdev = GUINT64_FROM_LE(ino->raw_inode->rdev);
+ st->st_size = GUINT64_FROM_LE(ino->raw_inode->size);
+ st->st_blksize = 512;
+ st->st_blocks = GUINT64_FROM_LE(ino->raw_inode->size) / 512ULL;
+ st->st_atime = GUINT64_FROM_LE(ino->raw_inode->atime);
+ st->st_mtime = GUINT64_FROM_LE(ino->raw_inode->mtime);
+ st->st_ctime = GUINT64_FROM_LE(ino->raw_inode->ctime);
+}
+
static void dbfs_reply_ino(fuse_req_t req, struct dbfs_inode *ino)
{
struct fuse_entry_param ent;
@@ -102,7 +120,7 @@ static void dbfs_op_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
static void dbfs_op_getattr(fuse_req_t req, fuse_ino_t ino_n,
struct fuse_file_info *fi)
{
- struct dbfs_inode *ino = NULL;
+ struct dbfs_inode *ino;
struct stat st;
int rc;
@@ -116,20 +134,7 @@ static void dbfs_op_getattr(fuse_req_t req, fuse_ino_t ino_n,
/* fill in stat buf, taking care to convert from
* little endian to native endian
*/
- memset(&st, 0, sizeof(st));
- st.st_dev = 1;
- st.st_ino = ino_n;
- st.st_mode = GUINT32_FROM_LE(ino->raw_inode->mode);
- st.st_nlink = GUINT32_FROM_LE(ino->raw_inode->nlink);
- st.st_uid = GUINT32_FROM_LE(ino->raw_inode->uid);
- st.st_gid = GUINT32_FROM_LE(ino->raw_inode->gid);
- st.st_rdev = GUINT64_FROM_LE(ino->raw_inode->rdev);
- st.st_size = GUINT64_FROM_LE(ino->raw_inode->size);
- st.st_blksize = 512;
- st.st_blocks = GUINT64_FROM_LE(ino->raw_inode->size) / 512ULL;
- st.st_atime = GUINT64_FROM_LE(ino->raw_inode->atime);
- st.st_mtime = GUINT64_FROM_LE(ino->raw_inode->mtime);
- st.st_ctime = GUINT64_FROM_LE(ino->raw_inode->ctime);
+ dbfs_fill_attr(ino, &st);
/* send result back to FUSE */
fuse_reply_attr(req, &st, 2.0);
@@ -137,6 +142,64 @@ static void dbfs_op_getattr(fuse_req_t req, fuse_ino_t ino_n,
dbfs_inode_free(ino);
}
+static void dbfs_op_setattr(fuse_req_t req, fuse_ino_t ino_n,
+ struct stat *attr, int to_set,
+ struct fuse_file_info *fi)
+{
+ struct dbfs_inode *ino;
+ struct stat st;
+ int rc, dirty = 0;
+
+ /* read inode from database */
+ rc = dbfs_inode_read(ino_n, &ino);
+ if (rc)
+ goto err_out;
+
+ if (to_set & FUSE_SET_ATTR_MODE) {
+ ino->raw_inode->mode = GUINT32_TO_LE(attr->st_mode);
+ dirty = 1;
+ }
+ if (to_set & FUSE_SET_ATTR_UID) {
+ ino->raw_inode->uid = GUINT32_TO_LE(attr->st_uid);
+ dirty = 1;
+ }
+ if (to_set & FUSE_SET_ATTR_GID) {
+ ino->raw_inode->gid = GUINT32_TO_LE(attr->st_gid);
+ dirty = 1;
+ }
+ if (to_set & FUSE_SET_ATTR_SIZE) {
+ rc = dbfs_inode_resize(ino, attr->st_size);
+ if (rc)
+ goto err_out_free;
+ ino->raw_inode->size = GUINT64_TO_LE(attr->st_size);
+ dirty = 1;
+ }
+ if (to_set & FUSE_SET_ATTR_ATIME) {
+ ino->raw_inode->atime = GUINT64_TO_LE(attr->st_atime);
+ dirty = 1;
+ }
+ if (to_set & FUSE_SET_ATTR_MTIME) {
+ ino->raw_inode->mtime = GUINT64_TO_LE(attr->st_mtime);
+ dirty = 1;
+ }
+
+ if (dirty) {
+ rc = dbfs_inode_write(ino);
+ if (rc)
+ goto err_out_free;
+ }
+
+ dbfs_fill_attr(ino, &st);
+ dbfs_inode_free(ino);
+ fuse_reply_attr(req, &st, 2.0);
+ return;
+
+err_out_free:
+ dbfs_inode_free(ino);
+err_out:
+ fuse_reply_err(req, -rc);
+}
+
static void dbfs_op_readlink(fuse_req_t req, fuse_ino_t ino)
{
int rc;
@@ -559,7 +622,7 @@ static struct fuse_lowlevel_ops dbfs_ops = {
.lookup = dbfs_op_lookup,
.forget = NULL,
.getattr = dbfs_op_getattr,
- .setattr = NULL,
+ .setattr = dbfs_op_setattr,
.readlink = dbfs_op_readlink,
.mknod = dbfs_op_mknod,
.mkdir = dbfs_op_mkdir,
diff --git a/dbfs.h b/dbfs.h
index 2c541bb..0516fac 100644
--- a/dbfs.h
+++ b/dbfs.h
@@ -156,6 +156,7 @@ extern int dbfs_xattr_remove(guint64, const char *, gboolean);
extern int dbfs_xattr_list(guint64 ino, void **buf_out, size_t *buflen_out);
extern int dbfs_read(guint64, guint64, size_t, void **);
extern int dbfs_write(guint64, guint64, const void *, size_t);
+extern int dbfs_inode_resize(struct dbfs_inode *ino, guint64 new_size);
/* libdbfs.c */
extern int dbfs_open(struct dbfs *, unsigned int, unsigned int, const char *);