]>
git.proxmox.com Git - ceph.git/blob - ceph/src/os/FuseStore.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "include/compat.h"
5 #include "include/ceph_fuse.h"
7 #include "os/ObjectStore.h"
8 #include "include/stringify.h"
9 #include "common/errno.h"
11 #include <fuse_lowlevel.h>
13 #include <sys/types.h>
16 #include <fcntl.h> /* Definition of AT_* constants */
19 #if defined(__APPLE__) || defined(__FreeBSD__)
20 #include <sys/param.h>
21 #include <sys/mount.h>
24 #define dout_context store->cct
25 #define dout_subsys ceph_subsys_fuse
26 #include "common/debug.h"
28 #define dout_prefix *_dout << "fuse "
30 // some fuse-y bits of state
32 struct fuse_args args
;
34 #if FUSE_VERSION < FUSE_MAKE_VERSION(3, 0)
40 int FuseStore::open_file(string p
, struct fuse_file_info
*fi
,
41 std::function
<int(bufferlist
*bl
)> f
)
43 if (open_files
.count(p
)) {
44 OpenFile
*o
= open_files
[p
];
45 fi
->fh
= reinterpret_cast<uint64_t>(o
);
54 OpenFile
*o
= new OpenFile
;
58 fi
->fh
= reinterpret_cast<uint64_t>(o
);
63 FuseStore::FuseStore(ObjectStore
*s
, string p
)
71 FuseStore::~FuseStore()
79 * $cid/type - objectstore type
80 * $cid/bitwise_hash_start = lowest hash value
81 * $cid/bitwise_hash_end = highest hash value
82 * $cid/bitwise_hash_bits - how many bits are significant
83 * $cid/pgmeta/ - pgmeta object
84 * $cid/all/ - all objects
86 * $cid/all/$obj/bitwise_hash
88 * $cid/all/$obj/omap/$key
89 * $cid/all/$obj/attr/$name
90 * $cid/by_bitwise_hash/$hash/$bits/$obj - all objects with this (bitwise) hash (prefix)
102 FN_OBJECT_OMAP_HEADER
,
112 static int parse_fn(CephContext
* cct
, const char *path
, coll_t
*cid
,
113 ghobject_t
*oid
, string
*key
,
114 uint32_t *hash
, uint32_t *hash_bits
)
117 for (const char *p
= path
; *p
; ++p
) {
121 for (e
= p
+ 1; *e
&& *e
!= '/'; e
++) ;
128 ldout(cct
, 10) << __func__
<< " path " << path
<< " -> " << v
<< dendl
;
133 if (v
.front() == "type")
136 if (!cid
->parse(v
.front())) {
140 return FN_COLLECTION
;
143 if (v
.front() == "bitwise_hash_start")
144 return FN_HASH_START
;
145 if (v
.front() == "bitwise_hash_end")
147 if (v
.front() == "bitwise_hash_bits")
149 if (v
.front() == "pgmeta") {
151 if (cid
->is_pg(&pgid
)) {
152 *oid
= pgid
.make_pgmeta_oid();
160 if (v
.front() == "all") {
166 if (v
.front() == "by_bitwise_hash") {
170 unsigned long hv
, hm
;
171 int r
= sscanf(v
.front().c_str(), "%lx", &hv
);
174 int shift
= 32 - v
.front().length() * 4;
178 r
= sscanf(v
.front().c_str(), "%ld", &hm
);
181 if (hm
< 1 || hm
> 32)
184 *hash
= hv
<< shift
;//hobject_t::_reverse_bits(hv << shift);
194 string o
= v
.front();
195 if (!oid
->parse(o
)) {
204 if (v
.front() == "data")
205 return FN_OBJECT_DATA
;
206 if (v
.front() == "omap_header")
207 return FN_OBJECT_OMAP_HEADER
;
208 if (v
.front() == "omap") {
211 return FN_OBJECT_OMAP
;
215 return FN_OBJECT_OMAP_VAL
;
218 if (v
.front() == "attr") {
221 return FN_OBJECT_ATTR
;
225 return FN_OBJECT_ATTR_VAL
;
228 if (v
.front() == "bitwise_hash")
229 return FN_OBJECT_HASH
;
234 static int os_getattr(const char *path
, struct stat
*stbuf
235 #if FUSE_VERSION >= FUSE_MAKE_VERSION(3, 0)
236 , struct fuse_file_info
*fi
240 fuse_context
*fc
= fuse_get_context();
241 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
242 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< dendl
;
246 uint32_t hash_value
, hash_bits
;
247 int t
= parse_fn(fs
->store
->cct
, path
, &cid
, &oid
, &key
, &hash_value
,
252 std::lock_guard
<std::mutex
> l(fs
->lock
);
257 stbuf
->st_mode
= S_IFREG
| 0700;
259 auto ch
= fs
->store
->open_collection(cid
);
266 case FN_OBJECT_OMAP_HEADER
:
267 case FN_OBJECT_OMAP_VAL
:
270 if (cid
.is_pg(&pgid
)) {
274 int bits
= fs
->store
->collection_bits(ch
);
275 if (bits
>= 0 && !oid
.match(bits
, pgid
.ps())) {
276 // sorry, not part of this PG
288 if (!fs
->store
->exists(ch
, oid
))
295 if (!fs
->store
->collection_exists(cid
))
299 stbuf
->st_mode
= S_IFDIR
| 0700;
303 stbuf
->st_size
= fs
->store
->get_type().length() + 1;
307 if (!fs
->store
->exists(ch
, oid
))
315 if (fs
->store
->collection_bits(ch
) < 0)
326 int bits
= fs
->store
->collection_bits(ch
);
330 snprintf(buf
, sizeof(buf
), "%d\n", bits
);
331 stbuf
->st_size
= strlen(buf
);
337 if (!fs
->store
->exists(ch
, oid
))
339 int r
= fs
->store
->stat(ch
, oid
, stbuf
);
345 case FN_OBJECT_OMAP_HEADER
:
347 if (!fs
->store
->exists(ch
, oid
))
350 fs
->store
->omap_get_header(ch
, oid
, &bl
);
351 stbuf
->st_size
= bl
.length();
355 case FN_OBJECT_OMAP_VAL
:
357 if (!fs
->store
->exists(ch
, oid
))
361 map
<string
,bufferlist
> v
;
362 fs
->store
->omap_get_values(ch
, oid
, k
, &v
);
366 stbuf
->st_size
= v
[key
].length();
370 case FN_OBJECT_ATTR_VAL
:
372 if (!fs
->store
->exists(ch
, oid
))
375 int r
= fs
->store
->getattr(ch
, oid
, key
.c_str(), v
);
380 stbuf
->st_size
= v
.length();
391 static int os_readdir(const char *path
,
393 fuse_fill_dir_t filler
,
395 struct fuse_file_info
*fi
396 #if FUSE_VERSION >= FUSE_MAKE_VERSION(3, 0)
397 , enum fuse_readdir_flags
401 fuse_context
*fc
= fuse_get_context();
402 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
403 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< " offset " << offset
408 uint32_t hash_value
, hash_bits
;
409 int t
= parse_fn(fs
->store
->cct
, path
, &cid
, &oid
, &key
, &hash_value
,
414 std::lock_guard
<std::mutex
> l(fs
->lock
);
416 auto ch
= fs
->store
->open_collection(cid
);
418 // we can't shift 32 bits or else off_t will go negative
419 const int hash_shift
= 31;
424 filler_compat(filler
, buf
, "type", NULL
, 0);
426 fs
->store
->list_collections(cls
);
428 int r
= filler_compat(filler
, buf
, stringify(c
).c_str(), NULL
, 0);
440 filler_compat(filler
, buf
, "bitwise_hash_start", NULL
, 0);
441 if (fs
->store
->collection_bits(ch
) >= 0) {
442 filler_compat(filler
, buf
, "bitwise_hash_end", NULL
, 0);
443 filler_compat(filler
, buf
, "bitwise_hash_bits", NULL
, 0);
445 filler_compat(filler
, buf
, "all", NULL
, 0);
446 filler_compat(filler
, buf
, "by_bitwise_hash", NULL
, 0);
448 if (cid
.is_pg(&pgid
) &&
449 fs
->store
->exists(ch
, pgid
.make_pgmeta_oid())) {
450 filler_compat(filler
, buf
, "pgmeta", NULL
, 0);
457 filler_compat(filler
, buf
, "bitwise_hash", NULL
, 0);
458 filler_compat(filler
, buf
, "data", NULL
, 0);
459 filler_compat(filler
, buf
, "omap", NULL
, 0);
460 filler_compat(filler
, buf
, "attr", NULL
, 0);
461 filler_compat(filler
, buf
, "omap_header", NULL
, 0);
468 uint32_t bitwise_hash
= (offset
>> hash_shift
) & 0xffffffff;
469 uint32_t hashoff
= offset
- (bitwise_hash
<< hash_shift
);
471 ghobject_t next
= cid
.get_min_hobj();
474 next
.hobj
.set_hash(hobject_t::_reverse_bits(bitwise_hash
));
475 } else if (t
== FN_HASH_VAL
) {
476 next
.hobj
.set_hash(hobject_t::_reverse_bits(hash_value
));
479 if (t
== FN_HASH_VAL
) {
481 uint64_t rev_end
= (hash_value
| (0xffffffff >> hash_bits
)) + 1;
482 if (rev_end
>= 0x100000000)
483 last
= ghobject_t::get_max();
485 last
.hobj
.set_hash(hobject_t::_reverse_bits(rev_end
));
487 last
= ghobject_t::get_max();
489 ldout(fs
->store
->cct
, 10) << __func__
<< std::hex
490 << " offset " << offset
<< " hash "
491 << hobject_t::_reverse_bits(hash_value
)
494 << " first " << next
<< " last " << last
497 vector
<ghobject_t
> ls
;
498 int r
= fs
->store
->collection_list(
499 ch
, next
, last
, 1000, &ls
, &next
);
507 uint32_t cur_bitwise_hash
= p
.hobj
.get_bitwise_key_u32();
508 if (cur_bitwise_hash
!= bitwise_hash
) {
509 bitwise_hash
= cur_bitwise_hash
;
513 uint64_t cur_off
= ((uint64_t)bitwise_hash
<< hash_shift
) |
515 string s
= stringify(p
);
516 r
= filler_compat(filler
, buf
, s
.c_str(), NULL
, cur_off
);
522 if (next
== ghobject_t::get_max() || next
== last
)
531 fs
->store
->omap_get_keys(ch
, oid
, &keys
);
532 unsigned skip
= offset
;
533 for (auto k
: keys
) {
539 int r
= filler_compat(filler
, buf
, k
.c_str(), NULL
, offset
);
548 map
<string
,bufferptr
> aset
;
549 fs
->store
->getattrs(ch
, oid
, aset
);
550 unsigned skip
= offset
;
551 for (auto a
: aset
) {
557 int r
= filler_compat(filler
, buf
, a
.first
.c_str(), NULL
, offset
);
567 static int os_open(const char *path
, struct fuse_file_info
*fi
)
569 fuse_context
*fc
= fuse_get_context();
570 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
571 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< dendl
;
575 uint32_t hash_value
, hash_bits
;
576 int t
= parse_fn(fs
->store
->cct
, path
, &cid
, &oid
, &key
, &hash_value
,
581 std::lock_guard
<std::mutex
> l(fs
->lock
);
583 auto ch
= fs
->store
->open_collection(cid
);
588 pbl
= new bufferlist
;
589 pbl
->append(fs
->store
->get_type());
595 pbl
= new bufferlist
;
597 if (cid
.is_pg(&pgid
)) {
599 h
= hobject_t::_reverse_bits(pgid
.ps());
601 snprintf(buf
, sizeof(buf
), "%08lx\n", h
);
604 pbl
->append("00000000\n");
616 if (cid
.is_pg(&pgid
)) {
617 int hash_bits
= fs
->store
->collection_bits(ch
);
618 if (hash_bits
>= 0) {
619 uint64_t rev_start
= hobject_t::_reverse_bits(pgid
.ps());
620 uint64_t rev_end
= (rev_start
| (0xffffffff >> hash_bits
));
629 snprintf(buf
, sizeof(buf
), "%08lx\n", h
);
630 pbl
= new bufferlist
;
640 int r
= fs
->store
->collection_bits(ch
);
644 snprintf(buf
, sizeof(buf
), "%d\n", r
);
645 pbl
= new bufferlist
;
652 pbl
= new bufferlist
;
654 snprintf(buf
, sizeof(buf
), "%08x\n",
655 (unsigned)oid
.hobj
.get_bitwise_key_u32());
662 int r
= fs
->open_file(
664 [&](bufferlist
*pbl
) {
665 return fs
->store
->read(ch
, oid
, 0, 0, *pbl
);
673 case FN_OBJECT_ATTR_VAL
:
675 int r
= fs
->open_file(
677 [&](bufferlist
*pbl
) {
679 int r
= fs
->store
->getattr(ch
, oid
, key
.c_str(), bp
);
690 case FN_OBJECT_OMAP_VAL
:
692 int r
= fs
->open_file(
694 [&](bufferlist
*pbl
) {
697 map
<string
,bufferlist
> v
;
698 int r
= fs
->store
->omap_get_values(ch
, oid
, k
, &v
);
709 case FN_OBJECT_OMAP_HEADER
:
711 int r
= fs
->open_file(
713 [&](bufferlist
*pbl
) {
714 return fs
->store
->omap_get_header(ch
, oid
, pbl
);
723 FuseStore::OpenFile
*o
= new FuseStore::OpenFile
;
725 fi
->fh
= reinterpret_cast<uint64_t>(o
);
730 static int os_mkdir(const char *path
, mode_t mode
)
732 fuse_context
*fc
= fuse_get_context();
733 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
734 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< dendl
;
738 uint32_t hash_value
, hash_bits
;
739 int f
= parse_fn(fs
->store
->cct
, path
, &cid
, &oid
, &key
, &hash_value
,
744 std::lock_guard
<std::mutex
> l(fs
->lock
);
746 ObjectStore::CollectionHandle ch
;
748 ObjectStore::Transaction t
;
752 ch
= fs
->store
->open_collection(cid
);
757 if (cid
.is_pg(&pgid
)) {
758 int bits
= fs
->store
->collection_bits(ch
);
759 if (bits
>= 0 && !oid
.match(bits
, pgid
.ps())) {
760 // sorry, not part of this PG
765 ch
= fs
->store
->open_collection(cid
);
771 // use the mode for the bit count. e.g., mkdir --mode=0003
772 // mnt/0.7_head will create 0.7 with bits = 3.
779 t
.create_collection(cid
, mode
);
780 ch
= fs
->store
->create_new_collection(cid
);
788 fs
->store
->queue_transaction(ch
, std::move(t
));
794 static int os_chmod(const char *path
, mode_t mode
795 #if FUSE_VERSION >= FUSE_MAKE_VERSION(3, 0)
796 , struct fuse_file_info
*fi
800 fuse_context
*fc
= fuse_get_context();
801 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
802 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< dendl
;
806 static int os_create(const char *path
, mode_t mode
, struct fuse_file_info
*fi
)
808 fuse_context
*fc
= fuse_get_context();
809 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
810 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< dendl
;
814 uint32_t hash_value
, hash_bits
;
815 int f
= parse_fn(fs
->store
->cct
, path
, &cid
, &oid
, &key
, &hash_value
,
820 std::lock_guard
<std::mutex
> l(fs
->lock
);
822 ObjectStore::CollectionHandle ch
= fs
->store
->open_collection(cid
);
824 ObjectStore::Transaction t
;
829 pbl
= new bufferlist
;
830 fs
->store
->read(ch
, oid
, 0, 0, *pbl
);
834 case FN_OBJECT_ATTR_VAL
:
836 pbl
= new bufferlist
;
838 int r
= fs
->store
->getattr(ch
, oid
, key
.c_str(), bp
);
841 t
.setattr(cid
, oid
, key
.c_str(), empty
);
847 case FN_OBJECT_OMAP_VAL
:
849 pbl
= new bufferlist
;
852 map
<string
,bufferlist
> v
;
853 fs
->store
->omap_get_values(ch
, oid
, k
, &v
);
854 if (v
.count(key
) == 0) {
855 map
<string
,bufferlist
> aset
;
856 aset
[key
] = bufferlist();
857 t
.omap_setkeys(cid
, oid
, aset
);
866 fs
->store
->queue_transaction(ch
, std::move(t
));
870 FuseStore::OpenFile
*o
= new FuseStore::OpenFile
;
873 fi
->fh
= reinterpret_cast<uint64_t>(o
);
878 static int os_release(const char *path
, struct fuse_file_info
*fi
)
880 fuse_context
*fc
= fuse_get_context();
881 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
882 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< dendl
;
883 std::lock_guard
<std::mutex
> l(fs
->lock
);
884 FuseStore::OpenFile
*o
= reinterpret_cast<FuseStore::OpenFile
*>(fi
->fh
);
886 ldout(fs
->store
->cct
, 10) << __func__
<< " closing last " << o
->path
<< dendl
;
887 fs
->open_files
.erase(o
->path
);
893 static int os_read(const char *path
, char *buf
, size_t size
, off_t offset
,
894 struct fuse_file_info
*fi
)
896 fuse_context
*fc
= fuse_get_context();
897 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
898 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< " offset " << offset
899 << " size " << size
<< dendl
;
900 std::lock_guard
<std::mutex
> l(fs
->lock
);
901 FuseStore::OpenFile
*o
= reinterpret_cast<FuseStore::OpenFile
*>(fi
->fh
);
904 if (offset
>= o
->bl
.length())
906 if (offset
+ size
> o
->bl
.length())
907 size
= o
->bl
.length() - offset
;
909 r
.substr_of(o
->bl
, offset
, size
);
910 memcpy(buf
, r
.c_str(), r
.length());
914 static int os_write(const char *path
, const char *buf
, size_t size
,
915 off_t offset
, struct fuse_file_info
*fi
)
917 fuse_context
*fc
= fuse_get_context();
918 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
919 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< " offset " << offset
920 << " size " << size
<< dendl
;
921 std::lock_guard
<std::mutex
> l(fs
->lock
);
922 FuseStore::OpenFile
*o
= reinterpret_cast<FuseStore::OpenFile
*>(fi
->fh
);
928 if (offset
> o
->bl
.length()) {
929 final
.substr_of(o
->bl
, 0, offset
);
931 final
.claim_append(o
->bl
);
932 size_t zlen
= offset
- final
.length();
933 final
.append_zero(zlen
);
936 final
.append(buf
, size
);
937 if (offset
+ size
< o
->bl
.length()) {
939 rest
.substr_of(o
->bl
, offset
+ size
, o
->bl
.length() - offset
- size
);
940 final
.claim_append(rest
);
947 int os_flush(const char *path
, struct fuse_file_info
*fi
)
949 fuse_context
*fc
= fuse_get_context();
950 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
951 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< dendl
;
955 uint32_t hash_value
, hash_bits
;
956 int f
= parse_fn(fs
->store
->cct
, path
, &cid
, &oid
, &key
, &hash_value
,
961 std::lock_guard
<std::mutex
> l(fs
->lock
);
963 FuseStore::OpenFile
*o
= reinterpret_cast<FuseStore::OpenFile
*>(fi
->fh
);
969 ObjectStore::CollectionHandle ch
= fs
->store
->open_collection(cid
);
971 ObjectStore::Transaction t
;
975 t
.write(cid
, oid
, 0, o
->bl
.length(), o
->bl
);
978 case FN_OBJECT_ATTR_VAL
:
979 t
.setattr(cid
, oid
, key
.c_str(), o
->bl
);
982 case FN_OBJECT_OMAP_VAL
:
984 map
<string
,bufferlist
> aset
;
986 t
.omap_setkeys(cid
, oid
, aset
);
990 case FN_OBJECT_OMAP_HEADER
:
991 t
.omap_setheader(cid
, oid
, o
->bl
);
998 fs
->store
->queue_transaction(ch
, std::move(t
));
1003 static int os_unlink(const char *path
)
1005 fuse_context
*fc
= fuse_get_context();
1006 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
1007 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< dendl
;
1011 uint32_t hash_value
, hash_bits
;
1012 int f
= parse_fn(fs
->store
->cct
, path
, &cid
, &oid
, &key
, &hash_value
,
1017 std::lock_guard
<std::mutex
> l(fs
->lock
);
1019 ObjectStore::CollectionHandle ch
= fs
->store
->open_collection(cid
);
1020 ObjectStore::Transaction t
;
1023 case FN_OBJECT_OMAP_VAL
:
1025 t
.omap_rmkey(cid
, oid
, key
);
1029 case FN_OBJECT_ATTR_VAL
:
1030 t
.rmattr(cid
, oid
, key
.c_str());
1033 case FN_OBJECT_OMAP_HEADER
:
1036 t
.omap_setheader(cid
, oid
, empty
);
1047 int r
= fs
->store
->collection_empty(ch
, &empty
);
1052 t
.remove_collection(cid
);
1056 case FN_OBJECT_DATA
:
1057 t
.truncate(cid
, oid
, 0);
1064 fs
->store
->queue_transaction(ch
, std::move(t
));
1069 static int os_truncate(const char *path
, off_t size
1070 #if FUSE_VERSION >= FUSE_MAKE_VERSION(3, 0)
1071 , struct fuse_file_info
*fi
1075 fuse_context
*fc
= fuse_get_context();
1076 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
1077 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< " size " << size
<< dendl
;
1081 uint32_t hash_value
, hash_bits
;
1082 int f
= parse_fn(fs
->store
->cct
, path
, &cid
, &oid
, &key
, &hash_value
,
1087 if (f
== FN_OBJECT_OMAP_VAL
||
1088 f
== FN_OBJECT_ATTR_VAL
||
1089 f
== FN_OBJECT_OMAP_HEADER
) {
1094 if (f
!= FN_OBJECT_DATA
)
1097 std::lock_guard
<std::mutex
> l(fs
->lock
);
1099 if (fs
->open_files
.count(path
)) {
1100 FuseStore::OpenFile
*o
= fs
->open_files
[path
];
1101 if (o
->bl
.length() > size
) {
1103 t
.substr_of(o
->bl
, 0, size
);
1108 ObjectStore::CollectionHandle ch
= fs
->store
->open_collection(cid
);
1109 ObjectStore::Transaction t
;
1110 t
.truncate(cid
, oid
, size
);
1111 fs
->store
->queue_transaction(ch
, std::move(t
));
1115 static int os_statfs(const char *path
, struct statvfs
*stbuf
)
1117 fuse_context
*fc
= fuse_get_context();
1118 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
1119 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< dendl
;
1120 std::lock_guard
<std::mutex
> l(fs
->lock
);
1122 struct store_statfs_t s
;
1123 int r
= fs
->store
->statfs(&s
);
1126 stbuf
->f_bsize
= 4096; // LIES!
1127 stbuf
->f_blocks
= s
.total
/ 4096;
1128 stbuf
->f_bavail
= s
.available
/ 4096;
1129 stbuf
->f_bfree
= stbuf
->f_bavail
;
1131 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< ": "
1132 << stbuf
->f_bavail
<< "/" << stbuf
->f_blocks
<< dendl
;
1136 static struct fuse_operations fs_oper
= {
1137 getattr
: os_getattr
,
1139 #if FUSE_VERSION < FUSE_MAKE_VERSION(3, 0)
1151 truncate
: os_truncate
,
1152 #if FUSE_VERSION < FUSE_MAKE_VERSION(3, 0)
1160 release
: os_release
,
1167 readdir
: os_readdir
,
1176 int FuseStore::main()
1180 mount_point
.c_str(),
1185 auto fuse_debug
= store
->cct
->_conf
.get_val
<bool>("fuse_debug");
1188 return fuse_main(c
, (char**)v
, &fs_oper
, (void*)this);
1191 int FuseStore::start()
1193 dout(10) << __func__
<< dendl
;
1195 memset(&info
->args
, 0, sizeof(info
->args
));
1198 mount_point
.c_str(),
1203 #if FUSE_VERSION >= FUSE_MAKE_VERSION(3, 0)
1205 struct fuse_cmdline_opts opts
= {};
1207 auto fuse_debug
= store
->cct
->_conf
.get_val
<bool>("fuse_debug");
1210 fuse_args a
= FUSE_ARGS_INIT(c
, (char**)v
);
1212 #if FUSE_VERSION >= FUSE_MAKE_VERSION(3, 0)
1213 if (fuse_parse_cmdline(&info
->args
, &opts
) == -1) {
1215 if (fuse_parse_cmdline(&info
->args
, &info
->mountpoint
, NULL
, NULL
) == -1) {
1217 derr
<< __func__
<< " failed to parse args" << dendl
;
1221 #if FUSE_VERSION >= FUSE_MAKE_VERSION(3, 0)
1222 info
->mountpoint
= opts
.mountpoint
;
1223 info
->f
= fuse_new(&info
->args
, &fs_oper
, sizeof(fs_oper
), (void*)this);
1225 derr
<< __func__
<< " fuse_new failed" << dendl
;
1229 rc
= fuse_mount(info
->f
, info
->mountpoint
);
1231 derr
<< __func__
<< " fuse_mount failed" << dendl
;
1235 info
->ch
= fuse_mount(info
->mountpoint
, &info
->args
);
1237 derr
<< __func__
<< " fuse_mount failed" << dendl
;
1241 info
->f
= fuse_new(info
->ch
, &info
->args
, &fs_oper
, sizeof(fs_oper
),
1244 fuse_unmount(info
->mountpoint
, info
->ch
);
1245 derr
<< __func__
<< " fuse_new failed" << dendl
;
1250 fuse_thread
.create("fusestore");
1251 dout(10) << __func__
<< " done" << dendl
;
1255 int FuseStore::loop()
1257 dout(10) << __func__
<< " enter" << dendl
;
1258 int r
= fuse_loop(info
->f
);
1260 derr
<< __func__
<< " got " << cpp_strerror(r
) << dendl
;
1261 dout(10) << __func__
<< " exit" << dendl
;
1265 int FuseStore::stop()
1267 dout(10) << __func__
<< " enter" << dendl
;
1268 #if FUSE_VERSION >= FUSE_MAKE_VERSION(3, 0)
1269 fuse_unmount(info
->f
);
1271 fuse_unmount(info
->mountpoint
, info
->ch
);
1274 fuse_destroy(info
->f
);
1275 dout(10) << __func__
<< " exit" << dendl
;