]>
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 "
36 using ceph::bufferlist
;
37 using ceph::bufferptr
;
39 // some fuse-y bits of state
41 struct fuse_args args
;
43 #if FUSE_VERSION < FUSE_MAKE_VERSION(3, 0)
49 int FuseStore::open_file(string p
, struct fuse_file_info
*fi
,
50 std::function
<int(bufferlist
*bl
)> f
)
52 if (open_files
.count(p
)) {
53 OpenFile
*o
= open_files
[p
];
54 fi
->fh
= reinterpret_cast<uint64_t>(o
);
63 OpenFile
*o
= new OpenFile
;
65 o
->bl
= std::move(bl
);
67 fi
->fh
= reinterpret_cast<uint64_t>(o
);
72 FuseStore::FuseStore(ObjectStore
*s
, string p
)
80 FuseStore::~FuseStore()
88 * $cid/type - objectstore type
89 * $cid/bitwise_hash_start = lowest hash value
90 * $cid/bitwise_hash_end = highest hash value
91 * $cid/bitwise_hash_bits - how many bits are significant
92 * $cid/pgmeta/ - pgmeta object
93 * $cid/all/ - all objects
95 * $cid/all/$obj/bitwise_hash
97 * $cid/all/$obj/omap/$key
98 * $cid/all/$obj/attr/$name
99 * $cid/by_bitwise_hash/$hash/$bits/$obj - all objects with this (bitwise) hash (prefix)
111 FN_OBJECT_OMAP_HEADER
,
121 static int parse_fn(CephContext
* cct
, const char *path
, coll_t
*cid
,
122 ghobject_t
*oid
, string
*key
,
123 uint32_t *hash
, uint32_t *hash_bits
)
126 for (const char *p
= path
; *p
; ++p
) {
130 for (e
= p
+ 1; *e
&& *e
!= '/'; e
++) ;
137 ldout(cct
, 10) << __func__
<< " path " << path
<< " -> " << v
<< dendl
;
142 if (v
.front() == "type")
145 if (!cid
->parse(v
.front())) {
149 return FN_COLLECTION
;
152 if (v
.front() == "bitwise_hash_start")
153 return FN_HASH_START
;
154 if (v
.front() == "bitwise_hash_end")
156 if (v
.front() == "bitwise_hash_bits")
158 if (v
.front() == "pgmeta") {
160 if (cid
->is_pg(&pgid
)) {
161 *oid
= pgid
.make_pgmeta_oid();
169 if (v
.front() == "all") {
175 if (v
.front() == "by_bitwise_hash") {
179 unsigned long hv
, hm
;
180 int r
= sscanf(v
.front().c_str(), "%lx", &hv
);
183 int shift
= 32 - v
.front().length() * 4;
187 r
= sscanf(v
.front().c_str(), "%ld", &hm
);
190 if (hm
< 1 || hm
> 32)
193 *hash
= hv
<< shift
;//hobject_t::_reverse_bits(hv << shift);
203 string o
= v
.front();
204 if (!oid
->parse(o
)) {
213 if (v
.front() == "data")
214 return FN_OBJECT_DATA
;
215 if (v
.front() == "omap_header")
216 return FN_OBJECT_OMAP_HEADER
;
217 if (v
.front() == "omap") {
220 return FN_OBJECT_OMAP
;
224 return FN_OBJECT_OMAP_VAL
;
227 if (v
.front() == "attr") {
230 return FN_OBJECT_ATTR
;
234 return FN_OBJECT_ATTR_VAL
;
237 if (v
.front() == "bitwise_hash")
238 return FN_OBJECT_HASH
;
243 static int os_getattr(const char *path
, struct stat
*stbuf
244 #if FUSE_VERSION >= FUSE_MAKE_VERSION(3, 0)
245 , struct fuse_file_info
*fi
249 fuse_context
*fc
= fuse_get_context();
250 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
251 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< dendl
;
255 uint32_t hash_value
, hash_bits
;
256 int t
= parse_fn(fs
->store
->cct
, path
, &cid
, &oid
, &key
, &hash_value
,
261 std::lock_guard
<std::mutex
> l(fs
->lock
);
266 stbuf
->st_mode
= S_IFREG
| 0700;
268 auto ch
= fs
->store
->open_collection(cid
);
275 case FN_OBJECT_OMAP_HEADER
:
276 case FN_OBJECT_OMAP_VAL
:
279 if (cid
.is_pg(&pgid
)) {
283 int bits
= fs
->store
->collection_bits(ch
);
284 if (bits
>= 0 && !oid
.match(bits
, pgid
.ps())) {
285 // sorry, not part of this PG
297 if (!fs
->store
->exists(ch
, oid
))
304 if (!fs
->store
->collection_exists(cid
))
308 stbuf
->st_mode
= S_IFDIR
| 0700;
312 stbuf
->st_size
= fs
->store
->get_type().length() + 1;
316 if (!fs
->store
->exists(ch
, oid
))
324 if (fs
->store
->collection_bits(ch
) < 0)
335 int bits
= fs
->store
->collection_bits(ch
);
339 snprintf(buf
, sizeof(buf
), "%d\n", bits
);
340 stbuf
->st_size
= strlen(buf
);
346 if (!fs
->store
->exists(ch
, oid
))
348 int r
= fs
->store
->stat(ch
, oid
, stbuf
);
354 case FN_OBJECT_OMAP_HEADER
:
356 if (!fs
->store
->exists(ch
, oid
))
359 fs
->store
->omap_get_header(ch
, oid
, &bl
);
360 stbuf
->st_size
= bl
.length();
364 case FN_OBJECT_OMAP_VAL
:
366 if (!fs
->store
->exists(ch
, oid
))
370 map
<string
,bufferlist
> v
;
371 fs
->store
->omap_get_values(ch
, oid
, k
, &v
);
375 stbuf
->st_size
= v
[key
].length();
379 case FN_OBJECT_ATTR_VAL
:
381 if (!fs
->store
->exists(ch
, oid
))
384 int r
= fs
->store
->getattr(ch
, oid
, key
.c_str(), v
);
389 stbuf
->st_size
= v
.length();
400 static int os_readdir(const char *path
,
402 fuse_fill_dir_t filler
,
404 struct fuse_file_info
*fi
405 #if FUSE_VERSION >= FUSE_MAKE_VERSION(3, 0)
406 , enum fuse_readdir_flags
410 fuse_context
*fc
= fuse_get_context();
411 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
412 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< " offset " << offset
417 uint32_t hash_value
, hash_bits
;
418 int t
= parse_fn(fs
->store
->cct
, path
, &cid
, &oid
, &key
, &hash_value
,
423 std::lock_guard
<std::mutex
> l(fs
->lock
);
425 auto ch
= fs
->store
->open_collection(cid
);
427 // we can't shift 32 bits or else off_t will go negative
428 const int hash_shift
= 31;
433 filler_compat(filler
, buf
, "type", NULL
, 0);
435 fs
->store
->list_collections(cls
);
437 int r
= filler_compat(filler
, buf
, stringify(c
).c_str(), NULL
, 0);
449 filler_compat(filler
, buf
, "bitwise_hash_start", NULL
, 0);
450 if (fs
->store
->collection_bits(ch
) >= 0) {
451 filler_compat(filler
, buf
, "bitwise_hash_end", NULL
, 0);
452 filler_compat(filler
, buf
, "bitwise_hash_bits", NULL
, 0);
454 filler_compat(filler
, buf
, "all", NULL
, 0);
455 filler_compat(filler
, buf
, "by_bitwise_hash", NULL
, 0);
457 if (cid
.is_pg(&pgid
) &&
458 fs
->store
->exists(ch
, pgid
.make_pgmeta_oid())) {
459 filler_compat(filler
, buf
, "pgmeta", NULL
, 0);
466 filler_compat(filler
, buf
, "bitwise_hash", NULL
, 0);
467 filler_compat(filler
, buf
, "data", NULL
, 0);
468 filler_compat(filler
, buf
, "omap", NULL
, 0);
469 filler_compat(filler
, buf
, "attr", NULL
, 0);
470 filler_compat(filler
, buf
, "omap_header", NULL
, 0);
477 uint32_t bitwise_hash
= (offset
>> hash_shift
) & 0xffffffff;
478 uint32_t hashoff
= offset
- (bitwise_hash
<< hash_shift
);
480 ghobject_t next
= cid
.get_min_hobj();
483 next
.hobj
.set_hash(hobject_t::_reverse_bits(bitwise_hash
));
484 } else if (t
== FN_HASH_VAL
) {
485 next
.hobj
.set_hash(hobject_t::_reverse_bits(hash_value
));
488 if (t
== FN_HASH_VAL
) {
490 uint64_t rev_end
= (hash_value
| (0xffffffff >> hash_bits
)) + 1;
491 if (rev_end
>= 0x100000000)
492 last
= ghobject_t::get_max();
494 last
.hobj
.set_hash(hobject_t::_reverse_bits(rev_end
));
496 last
= ghobject_t::get_max();
498 ldout(fs
->store
->cct
, 10) << __func__
<< std::hex
499 << " offset " << offset
<< " hash "
500 << hobject_t::_reverse_bits(hash_value
)
503 << " first " << next
<< " last " << last
506 vector
<ghobject_t
> ls
;
507 int r
= fs
->store
->collection_list(
508 ch
, next
, last
, 1000, &ls
, &next
);
516 uint32_t cur_bitwise_hash
= p
.hobj
.get_bitwise_key_u32();
517 if (cur_bitwise_hash
!= bitwise_hash
) {
518 bitwise_hash
= cur_bitwise_hash
;
522 uint64_t cur_off
= ((uint64_t)bitwise_hash
<< hash_shift
) |
524 string s
= stringify(p
);
525 r
= filler_compat(filler
, buf
, s
.c_str(), NULL
, cur_off
);
531 if (next
== ghobject_t::get_max() || next
== last
)
540 fs
->store
->omap_get_keys(ch
, oid
, &keys
);
541 unsigned skip
= offset
;
542 for (auto k
: keys
) {
548 int r
= filler_compat(filler
, buf
, k
.c_str(), NULL
, offset
);
557 map
<string
,bufferptr
> aset
;
558 fs
->store
->getattrs(ch
, oid
, aset
);
559 unsigned skip
= offset
;
560 for (auto a
: aset
) {
566 int r
= filler_compat(filler
, buf
, a
.first
.c_str(), NULL
, offset
);
576 static int os_open(const char *path
, struct fuse_file_info
*fi
)
578 fuse_context
*fc
= fuse_get_context();
579 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
580 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< dendl
;
584 uint32_t hash_value
, hash_bits
;
585 int t
= parse_fn(fs
->store
->cct
, path
, &cid
, &oid
, &key
, &hash_value
,
590 std::lock_guard
<std::mutex
> l(fs
->lock
);
592 auto ch
= fs
->store
->open_collection(cid
);
597 pbl
= new bufferlist
;
598 pbl
->append(fs
->store
->get_type());
604 pbl
= new bufferlist
;
606 if (cid
.is_pg(&pgid
)) {
608 h
= hobject_t::_reverse_bits(pgid
.ps());
610 snprintf(buf
, sizeof(buf
), "%08lx\n", h
);
613 pbl
->append("00000000\n");
625 if (cid
.is_pg(&pgid
)) {
626 int hash_bits
= fs
->store
->collection_bits(ch
);
627 if (hash_bits
>= 0) {
628 uint64_t rev_start
= hobject_t::_reverse_bits(pgid
.ps());
629 uint64_t rev_end
= (rev_start
| (0xffffffff >> hash_bits
));
638 snprintf(buf
, sizeof(buf
), "%08lx\n", h
);
639 pbl
= new bufferlist
;
649 int r
= fs
->store
->collection_bits(ch
);
653 snprintf(buf
, sizeof(buf
), "%d\n", r
);
654 pbl
= new bufferlist
;
661 pbl
= new bufferlist
;
663 snprintf(buf
, sizeof(buf
), "%08x\n",
664 (unsigned)oid
.hobj
.get_bitwise_key_u32());
671 int r
= fs
->open_file(
673 [&](bufferlist
*pbl
) {
674 return fs
->store
->read(ch
, oid
, 0, 0, *pbl
);
682 case FN_OBJECT_ATTR_VAL
:
684 int r
= fs
->open_file(
686 [&](bufferlist
*pbl
) {
688 int r
= fs
->store
->getattr(ch
, oid
, key
.c_str(), bp
);
699 case FN_OBJECT_OMAP_VAL
:
701 int r
= fs
->open_file(
703 [&](bufferlist
*pbl
) {
706 map
<string
,bufferlist
> v
;
707 int r
= fs
->store
->omap_get_values(ch
, oid
, k
, &v
);
718 case FN_OBJECT_OMAP_HEADER
:
720 int r
= fs
->open_file(
722 [&](bufferlist
*pbl
) {
723 return fs
->store
->omap_get_header(ch
, oid
, pbl
);
732 FuseStore::OpenFile
*o
= new FuseStore::OpenFile
;
733 o
->bl
= std::move(*pbl
);
734 fi
->fh
= reinterpret_cast<uint64_t>(o
);
739 static int os_mkdir(const char *path
, mode_t mode
)
741 fuse_context
*fc
= fuse_get_context();
742 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
743 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< dendl
;
747 uint32_t hash_value
, hash_bits
;
748 int f
= parse_fn(fs
->store
->cct
, path
, &cid
, &oid
, &key
, &hash_value
,
753 std::lock_guard
<std::mutex
> l(fs
->lock
);
755 ObjectStore::CollectionHandle ch
;
757 ObjectStore::Transaction t
;
761 ch
= fs
->store
->open_collection(cid
);
766 if (cid
.is_pg(&pgid
)) {
767 int bits
= fs
->store
->collection_bits(ch
);
768 if (bits
>= 0 && !oid
.match(bits
, pgid
.ps())) {
769 // sorry, not part of this PG
774 ch
= fs
->store
->open_collection(cid
);
780 // use the mode for the bit count. e.g., mkdir --mode=0003
781 // mnt/0.7_head will create 0.7 with bits = 3.
788 t
.create_collection(cid
, mode
);
789 ch
= fs
->store
->create_new_collection(cid
);
797 fs
->store
->queue_transaction(ch
, std::move(t
));
803 static int os_chmod(const char *path
, mode_t mode
804 #if FUSE_VERSION >= FUSE_MAKE_VERSION(3, 0)
805 , struct fuse_file_info
*fi
809 fuse_context
*fc
= fuse_get_context();
810 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
811 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< dendl
;
815 static int os_create(const char *path
, mode_t mode
, struct fuse_file_info
*fi
)
817 fuse_context
*fc
= fuse_get_context();
818 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
819 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< dendl
;
823 uint32_t hash_value
, hash_bits
;
824 int f
= parse_fn(fs
->store
->cct
, path
, &cid
, &oid
, &key
, &hash_value
,
829 std::lock_guard
<std::mutex
> l(fs
->lock
);
831 ObjectStore::CollectionHandle ch
= fs
->store
->open_collection(cid
);
833 ObjectStore::Transaction t
;
838 pbl
= new bufferlist
;
839 fs
->store
->read(ch
, oid
, 0, 0, *pbl
);
843 case FN_OBJECT_ATTR_VAL
:
845 pbl
= new bufferlist
;
847 int r
= fs
->store
->getattr(ch
, oid
, key
.c_str(), bp
);
850 t
.setattr(cid
, oid
, key
.c_str(), empty
);
856 case FN_OBJECT_OMAP_VAL
:
858 pbl
= new bufferlist
;
861 map
<string
,bufferlist
> v
;
862 fs
->store
->omap_get_values(ch
, oid
, k
, &v
);
863 if (v
.count(key
) == 0) {
864 map
<string
,bufferlist
> aset
;
865 aset
[key
] = bufferlist();
866 t
.omap_setkeys(cid
, oid
, aset
);
875 fs
->store
->queue_transaction(ch
, std::move(t
));
879 FuseStore::OpenFile
*o
= new FuseStore::OpenFile
;
880 o
->bl
= std::move(*pbl
);
882 fi
->fh
= reinterpret_cast<uint64_t>(o
);
887 static int os_release(const char *path
, struct fuse_file_info
*fi
)
889 fuse_context
*fc
= fuse_get_context();
890 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
891 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< dendl
;
892 std::lock_guard
<std::mutex
> l(fs
->lock
);
893 FuseStore::OpenFile
*o
= reinterpret_cast<FuseStore::OpenFile
*>(fi
->fh
);
895 ldout(fs
->store
->cct
, 10) << __func__
<< " closing last " << o
->path
<< dendl
;
896 fs
->open_files
.erase(o
->path
);
902 static int os_read(const char *path
, char *buf
, size_t size
, off_t offset
,
903 struct fuse_file_info
*fi
)
905 fuse_context
*fc
= fuse_get_context();
906 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
907 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< " offset " << offset
908 << " size " << size
<< dendl
;
909 std::lock_guard
<std::mutex
> l(fs
->lock
);
910 FuseStore::OpenFile
*o
= reinterpret_cast<FuseStore::OpenFile
*>(fi
->fh
);
913 if (offset
>= o
->bl
.length())
915 if (offset
+ size
> o
->bl
.length())
916 size
= o
->bl
.length() - offset
;
918 r
.substr_of(o
->bl
, offset
, size
);
919 memcpy(buf
, r
.c_str(), r
.length());
923 static int os_write(const char *path
, const char *buf
, size_t size
,
924 off_t offset
, struct fuse_file_info
*fi
)
926 fuse_context
*fc
= fuse_get_context();
927 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
928 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< " offset " << offset
929 << " size " << size
<< dendl
;
930 std::lock_guard
<std::mutex
> l(fs
->lock
);
931 FuseStore::OpenFile
*o
= reinterpret_cast<FuseStore::OpenFile
*>(fi
->fh
);
937 if (offset
> o
->bl
.length()) {
938 final
.substr_of(o
->bl
, 0, offset
);
940 final
.claim_append(o
->bl
);
941 size_t zlen
= offset
- final
.length();
942 final
.append_zero(zlen
);
945 final
.append(buf
, size
);
946 if (offset
+ size
< o
->bl
.length()) {
948 rest
.substr_of(o
->bl
, offset
+ size
, o
->bl
.length() - offset
- size
);
949 final
.claim_append(rest
);
956 int os_flush(const char *path
, struct fuse_file_info
*fi
)
958 fuse_context
*fc
= fuse_get_context();
959 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
960 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< dendl
;
964 uint32_t hash_value
, hash_bits
;
965 int f
= parse_fn(fs
->store
->cct
, path
, &cid
, &oid
, &key
, &hash_value
,
970 std::lock_guard
<std::mutex
> l(fs
->lock
);
972 FuseStore::OpenFile
*o
= reinterpret_cast<FuseStore::OpenFile
*>(fi
->fh
);
978 ObjectStore::CollectionHandle ch
= fs
->store
->open_collection(cid
);
980 ObjectStore::Transaction t
;
984 t
.write(cid
, oid
, 0, o
->bl
.length(), o
->bl
);
987 case FN_OBJECT_ATTR_VAL
:
988 t
.setattr(cid
, oid
, key
.c_str(), o
->bl
);
991 case FN_OBJECT_OMAP_VAL
:
993 map
<string
,bufferlist
> aset
;
995 t
.omap_setkeys(cid
, oid
, aset
);
999 case FN_OBJECT_OMAP_HEADER
:
1000 t
.omap_setheader(cid
, oid
, o
->bl
);
1007 fs
->store
->queue_transaction(ch
, std::move(t
));
1012 static int os_unlink(const char *path
)
1014 fuse_context
*fc
= fuse_get_context();
1015 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
1016 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< dendl
;
1020 uint32_t hash_value
, hash_bits
;
1021 int f
= parse_fn(fs
->store
->cct
, path
, &cid
, &oid
, &key
, &hash_value
,
1026 std::lock_guard
<std::mutex
> l(fs
->lock
);
1028 ObjectStore::CollectionHandle ch
= fs
->store
->open_collection(cid
);
1029 ObjectStore::Transaction t
;
1032 case FN_OBJECT_OMAP_VAL
:
1034 t
.omap_rmkey(cid
, oid
, key
);
1038 case FN_OBJECT_ATTR_VAL
:
1039 t
.rmattr(cid
, oid
, key
.c_str());
1042 case FN_OBJECT_OMAP_HEADER
:
1045 t
.omap_setheader(cid
, oid
, empty
);
1056 int r
= fs
->store
->collection_empty(ch
, &empty
);
1061 t
.remove_collection(cid
);
1065 case FN_OBJECT_DATA
:
1066 t
.truncate(cid
, oid
, 0);
1073 fs
->store
->queue_transaction(ch
, std::move(t
));
1078 static int os_truncate(const char *path
, off_t size
1079 #if FUSE_VERSION >= FUSE_MAKE_VERSION(3, 0)
1080 , struct fuse_file_info
*fi
1084 fuse_context
*fc
= fuse_get_context();
1085 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
1086 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< " size " << size
<< dendl
;
1090 uint32_t hash_value
, hash_bits
;
1091 int f
= parse_fn(fs
->store
->cct
, path
, &cid
, &oid
, &key
, &hash_value
,
1096 if (f
== FN_OBJECT_OMAP_VAL
||
1097 f
== FN_OBJECT_ATTR_VAL
||
1098 f
== FN_OBJECT_OMAP_HEADER
) {
1103 if (f
!= FN_OBJECT_DATA
)
1106 std::lock_guard
<std::mutex
> l(fs
->lock
);
1108 if (fs
->open_files
.count(path
)) {
1109 FuseStore::OpenFile
*o
= fs
->open_files
[path
];
1110 if (o
->bl
.length() > size
) {
1112 t
.substr_of(o
->bl
, 0, size
);
1117 ObjectStore::CollectionHandle ch
= fs
->store
->open_collection(cid
);
1118 ObjectStore::Transaction t
;
1119 t
.truncate(cid
, oid
, size
);
1120 fs
->store
->queue_transaction(ch
, std::move(t
));
1124 static int os_statfs(const char *path
, struct statvfs
*stbuf
)
1126 fuse_context
*fc
= fuse_get_context();
1127 FuseStore
*fs
= static_cast<FuseStore
*>(fc
->private_data
);
1128 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< dendl
;
1129 std::lock_guard
<std::mutex
> l(fs
->lock
);
1131 struct store_statfs_t s
;
1132 int r
= fs
->store
->statfs(&s
);
1135 stbuf
->f_bsize
= 4096; // LIES!
1136 stbuf
->f_blocks
= s
.total
/ 4096;
1137 stbuf
->f_bavail
= s
.available
/ 4096;
1138 stbuf
->f_bfree
= stbuf
->f_bavail
;
1140 ldout(fs
->store
->cct
, 10) << __func__
<< " " << path
<< ": "
1141 << stbuf
->f_bavail
<< "/" << stbuf
->f_blocks
<< dendl
;
1145 static struct fuse_operations fs_oper
= {
1146 getattr
: os_getattr
,
1148 #if FUSE_VERSION < FUSE_MAKE_VERSION(3, 0)
1160 truncate
: os_truncate
,
1161 #if FUSE_VERSION < FUSE_MAKE_VERSION(3, 0)
1169 release
: os_release
,
1176 readdir
: os_readdir
,
1185 int FuseStore::main()
1189 mount_point
.c_str(),
1194 auto fuse_debug
= store
->cct
->_conf
.get_val
<bool>("fuse_debug");
1197 return fuse_main(c
, (char**)v
, &fs_oper
, (void*)this);
1200 int FuseStore::start()
1202 dout(10) << __func__
<< dendl
;
1204 memset(&info
->args
, 0, sizeof(info
->args
));
1207 mount_point
.c_str(),
1212 #if FUSE_VERSION >= FUSE_MAKE_VERSION(3, 0)
1214 struct fuse_cmdline_opts opts
= {};
1216 auto fuse_debug
= store
->cct
->_conf
.get_val
<bool>("fuse_debug");
1219 fuse_args a
= FUSE_ARGS_INIT(c
, (char**)v
);
1221 #if FUSE_VERSION >= FUSE_MAKE_VERSION(3, 0)
1222 if (fuse_parse_cmdline(&info
->args
, &opts
) == -1) {
1224 if (fuse_parse_cmdline(&info
->args
, &info
->mountpoint
, NULL
, NULL
) == -1) {
1226 derr
<< __func__
<< " failed to parse args" << dendl
;
1230 #if FUSE_VERSION >= FUSE_MAKE_VERSION(3, 0)
1231 info
->mountpoint
= opts
.mountpoint
;
1232 info
->f
= fuse_new(&info
->args
, &fs_oper
, sizeof(fs_oper
), (void*)this);
1234 derr
<< __func__
<< " fuse_new failed" << dendl
;
1238 rc
= fuse_mount(info
->f
, info
->mountpoint
);
1240 derr
<< __func__
<< " fuse_mount failed" << dendl
;
1244 info
->ch
= fuse_mount(info
->mountpoint
, &info
->args
);
1246 derr
<< __func__
<< " fuse_mount failed" << dendl
;
1250 info
->f
= fuse_new(info
->ch
, &info
->args
, &fs_oper
, sizeof(fs_oper
),
1253 fuse_unmount(info
->mountpoint
, info
->ch
);
1254 derr
<< __func__
<< " fuse_new failed" << dendl
;
1259 fuse_thread
.create("fusestore");
1260 dout(10) << __func__
<< " done" << dendl
;
1264 int FuseStore::loop()
1266 dout(10) << __func__
<< " enter" << dendl
;
1267 int r
= fuse_loop(info
->f
);
1269 derr
<< __func__
<< " got " << cpp_strerror(r
) << dendl
;
1270 dout(10) << __func__
<< " exit" << dendl
;
1274 int FuseStore::stop()
1276 dout(10) << __func__
<< " enter" << dendl
;
1277 #if FUSE_VERSION >= FUSE_MAKE_VERSION(3, 0)
1278 fuse_unmount(info
->f
);
1280 fuse_unmount(info
->mountpoint
, info
->ch
);
1283 fuse_destroy(info
->f
);
1284 dout(10) << __func__
<< " exit" << dendl
;