terom@7: terom@7: #include terom@7: terom@7: #include "dirbuf.h" terom@7: #include "lib/log.h" terom@7: #include "lib/math.h" terom@7: terom@7: int dirbuf_init (struct dirbuf *buf, size_t req_size) { terom@7: buf->len = req_size; terom@7: buf->off = 0; terom@7: terom@7: INFO("\tdirbuf.init: req_size=%zu", req_size); terom@7: terom@7: // allocate the mem terom@7: if ((buf->buf = malloc(buf->len)) == NULL) terom@7: ERROR("malloc"); terom@7: terom@7: // ok terom@7: return 0; terom@7: terom@7: error: terom@7: return -1; terom@7: } terom@7: terom@26: size_t difbuf_estimate (size_t req_size, size_t min_namelen) { terom@26: char namebuf[DIRBUF_NAME_MAX]; terom@26: int i; terom@26: terom@26: // build a dummy string of the right length terom@26: for (i = 0; i < min_namelen && i < DIRBUF_NAME_MAX - 1; i++) terom@26: namebuf[i] = 'x'; terom@26: terom@26: namebuf[i] = '\0'; terom@26: terom@26: return req_size / (fuse_add_direntry(NULL, NULL, 0, namebuf, NULL, 0)); terom@26: } terom@26: terom@7: int dirbuf_add (fuse_req_t req, off_t req_off, struct dirbuf *buf, off_t ent_off, off_t next_off, const char *ent_name, fuse_ino_t ent_ino, mode_t ent_mode) { terom@7: struct stat stbuf; terom@7: size_t ent_size; terom@7: terom@7: INFO("\tdirbuf.add: req_off=%zu, buf->len=%zu, buf->off=%zu, ent_off=%zu, next_off=%zu, ent_name=`%s`, ent_ino=%lu, ent_mode=%07o", terom@7: req_off, buf->len, buf->off, ent_off, next_off, ent_name, ent_ino, ent_mode); terom@7: terom@7: // skip entries as needed terom@7: if (ent_off < req_off) terom@7: return 0; terom@7: terom@7: // set ino terom@7: stbuf.st_ino = ent_ino; terom@7: stbuf.st_mode = ent_mode; terom@7: terom@7: // try and add the dirent, and see if it fits terom@7: if ((ent_size = fuse_add_direntry(req, buf->buf + buf->off, buf->len - buf->off, ent_name, &stbuf, next_off)) > (buf->len - buf->off)) { terom@7: // 'tis full terom@7: return 1; terom@7: terom@7: } else { terom@7: // it fit terom@7: buf->off += ent_size; terom@7: } terom@7: terom@7: // success terom@7: return 0; terom@7: } terom@7: terom@7: int dirbuf_done (fuse_req_t req, struct dirbuf *buf) { terom@7: int err; terom@7: terom@7: // send the reply, return the error later terom@7: err = fuse_reply_buf(req, buf->buf, buf->off); terom@7: terom@7: INFO("\tdirbuf.done: size=%zu/%zu, err=%d", buf->off, buf->len, err); terom@7: terom@7: // free the dirbuf terom@7: free(buf->buf); terom@7: terom@7: // return the error code terom@7: return err; terom@7: } terom@7: