296
need_fresh_lookup (int32_t op_ret, int32_t op_errno,
297
loc_t *loc, struct stat *buf)
423
/* courtesy of folly */
425
stat2attr (struct stat *st, struct fuse_attr *fa)
300
gf_log ("fuse-bridge", GF_LOG_DEBUG,
301
"revalidate of %s failed (%s)",
302
loc->path, strerror (op_errno));
306
if (loc->inode->ino != buf->st_ino) {
307
gf_log ("fuse-bridge", GF_LOG_DEBUG,
308
"inode num of %s changed %"PRId64" -> %"PRId64,
309
loc->path, loc->inode->ino, buf->st_ino);
313
if ((loc->inode->st_mode & S_IFMT) ^ (buf->st_mode & S_IFMT)) {
314
gf_log ("fuse-bridge", GF_LOG_DEBUG,
315
"inode mode of %s changed 0%o -> 0%o",
316
loc->path, loc->inode->st_mode, buf->st_mode);
427
fa->ino = st->st_ino;
428
fa->size = st->st_size;
429
fa->blocks = st->st_blocks;
430
fa->atime = st->st_atime;
431
fa->mtime = st->st_mtime;
432
fa->ctime = st->st_ctime;
433
fa->atimensec = ST_ATIM_NSEC (st);
434
fa->mtimensec = ST_MTIM_NSEC (st);
435
fa->ctimensec = ST_CTIM_NSEC (st);
436
fa->mode = st->st_mode;
437
fa->nlink = st->st_nlink;
438
fa->uid = st->st_uid;
439
fa->gid = st->st_gid;
440
fa->rdev = st->st_rdev;
441
fa->blksize = st->st_blksize;
325
fuse_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
326
int32_t op_ret, int32_t op_errno,
327
inode_t *inode, struct stat *stat, dict_t *dict);
330
446
fuse_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
331
447
int32_t op_ret, int32_t op_errno,
332
448
inode_t *inode, struct stat *buf)
334
450
fuse_state_t *state = NULL;
335
fuse_req_t req = NULL;
336
struct fuse_entry_param e = {0, };
451
fuse_in_header_t *finh = NULL;
452
struct fuse_entry_out feo = {0, };
337
453
fuse_private_t *priv = NULL;
454
inode_t *linked_inode = NULL;
339
456
priv = this->private;
340
457
state = frame->root->state;
343
460
if (!op_ret && state->loc.ino == 1) {
347
if (state->is_revalidate == 1
348
&& need_fresh_lookup (op_ret, op_errno, &state->loc, buf)) {
465
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
466
"%"PRIu64": %s() %s => %"PRId64" (%"PRId64")",
467
frame->root->unique, gf_fop_list[frame->root->op],
468
state->loc.path, buf->st_ino, state->loc.ino);
470
buf->st_blksize = this->ctx->page_size;
471
stat2attr (buf, &feo.attr);
474
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
475
"%"PRIu64": %s() %s returning inode 0",
477
gf_fop_list[frame->root->op], state->loc.path);
480
linked_inode = inode_link (inode, state->loc.parent,
481
state->loc.name, buf);
483
if (linked_inode != inode) {
484
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
485
"%s(%s) inode (ptr=%p, ino=%"PRId64", "
486
"gen=%"PRId64") found conflict (ptr=%p, "
487
"ino=%"PRId64", gen=%"PRId64")",
488
gf_fop_list[frame->root->op],
489
state->loc.path, inode, inode->ino,
490
inode->generation, linked_inode,
491
linked_inode->ino, linked_inode->generation);
494
inode_lookup (linked_inode);
496
/* TODO: make these timeouts configurable (via meta?) */
497
feo.nodeid = inode_to_nodeid (linked_inode);
499
feo.generation = linked_inode->generation;
501
inode_unref (linked_inode);
504
calc_timeout_sec (priv->entry_timeout);
505
feo.entry_valid_nsec =
506
calc_timeout_nsec (priv->entry_timeout);
508
calc_timeout_sec (priv->attribute_timeout);
509
feo.attr_valid_nsec =
510
calc_timeout_nsec (priv->attribute_timeout);
512
priv->proto_minor >= 9 ?
513
send_fuse_obj (this, finh, &feo) :
514
send_fuse_data (this, finh, &feo,
515
FUSE_COMPAT_ENTRY_OUT_SIZE);
517
gf_log ("glusterfs-fuse",
518
(op_errno == ENOENT ? GF_LOG_TRACE : GF_LOG_WARNING),
519
"%"PRIu64": %s() %s => -1 (%s)", frame->root->unique,
520
gf_fop_list[frame->root->op], state->loc.path,
521
strerror (op_errno));
522
send_fuse_err (this, state->finh, op_errno);
526
STACK_DESTROY (frame->root);
532
fuse_newentry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
533
int32_t op_ret, int32_t op_errno,
534
inode_t *inode, struct stat *buf, struct stat *preparent,
535
struct stat *postparent)
537
fuse_entry_cbk (frame, cookie, this, op_ret, op_errno, inode, buf);
543
fuse_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
544
int32_t op_ret, int32_t op_errno,
545
inode_t *inode, struct stat *stat, dict_t *dict,
546
struct stat *postparent)
548
fuse_state_t *state = NULL;
549
call_frame_t *prev = NULL;
551
state = frame->root->state;
554
if (op_ret == -1 && state->is_revalidate == 1) {
349
555
inode_unref (state->loc.inode);
350
556
state->loc.inode = inode_new (state->itable);
351
557
state->is_revalidate = 2;
353
559
STACK_WIND (frame, fuse_lookup_cbk,
355
FIRST_CHILD (this)->fops->lookup,
560
prev->this, prev->this->fops->lookup,
356
561
&state->loc, state->dict);
362
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
363
"%"PRId64": %s() %s => %"PRId64" (%"PRId64")",
364
frame->root->unique, gf_fop_list[frame->root->op],
365
state->loc.path, buf->st_ino, state->loc.ino);
367
inode_link (inode, state->loc.parent, state->loc.name, buf);
369
inode_lookup (inode);
371
/* TODO: make these timeouts configurable (via meta?) */
374
#ifdef GF_DARWIN_HOST_OS
377
e.generation = buf->st_ctime;
380
buf->st_blksize = this->ctx->page_size;
381
e.entry_timeout = priv->entry_timeout;
382
e.attr_timeout = priv->attribute_timeout;
385
if (!e.ino || !buf->st_ino) {
386
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
387
"%"PRId64": %s() %s returning inode 0",
389
gf_fop_list[frame->root->op], state->loc.path);
392
if (state->loc.parent)
393
fuse_reply_entry (req, &e);
395
fuse_reply_attr (req, buf, priv->attribute_timeout);
397
gf_log ("glusterfs-fuse",
398
(op_errno == ENOENT ? GF_LOG_TRACE : GF_LOG_WARNING),
399
"%"PRId64": %s() %s => -1 (%s)", frame->root->unique,
400
gf_fop_list[frame->root->op], state->loc.path,
401
strerror (op_errno));
402
fuse_reply_err (req, op_errno);
406
STACK_DESTROY (frame->root);
412
fuse_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
413
int32_t op_ret, int32_t op_errno,
414
inode_t *inode, struct stat *stat, dict_t *dict)
416
565
fuse_entry_cbk (frame, cookie, this, op_ret, op_errno, inode, stat);
422
fuse_lookup (fuse_req_t req, fuse_ino_t par, const char *name)
571
fuse_lookup (xlator_t *this, fuse_in_header_t *finh, void *msg)
424
575
fuse_state_t *state = NULL;
425
576
int32_t ret = -1;
427
state = state_from_req (req);
578
GET_STATE (this, finh, state);
429
ret = fuse_loc_fill (&state->loc, state, 0, par, name);
580
ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
432
583
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
433
"%"PRId64": LOOKUP %"PRId64"/%s (fuse_loc_fill() failed)",
434
req_callid (req), (ino_t)par, name);
584
"%"PRIu64": LOOKUP %"PRIu64"/%s (fuse_loc_fill() failed)",
585
finh->unique, finh->nodeid, name);
435
586
free_state (state);
436
fuse_reply_err (req, ENOENT);
587
send_fuse_err (this, finh, ENOENT);
440
591
if (!state->loc.inode) {
441
592
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
442
"%"PRId64": LOOKUP %s", req_callid (req),
593
"%"PRIu64": LOOKUP %s", finh->unique,
443
594
state->loc.path);
445
596
state->loc.inode = inode_new (state->itable);
446
/* to differntiate in entry_cbk what kind of call it is */
447
state->is_revalidate = -1;
449
598
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
450
"%"PRId64": LOOKUP %s(%"PRId64")", req_callid (req),
599
"%"PRIu64": LOOKUP %s(%"PRId64")", finh->unique,
451
600
state->loc.path, state->loc.inode->ino);
452
601
state->is_revalidate = 1;
509
704
/* TODO: make these timeouts configurable via meta */
510
705
/* TODO: what if the inode number has changed by now */
511
706
buf->st_blksize = this->ctx->page_size;
513
fuse_reply_attr (req, buf, priv->attribute_timeout);
707
stat2attr (buf, &fao.attr);
709
fao.attr_valid = calc_timeout_sec (priv->attribute_timeout);
710
fao.attr_valid_nsec =
711
calc_timeout_nsec (priv->attribute_timeout);
713
priv->proto_minor >= 9 ?
714
send_fuse_obj (this, finh, &fao) :
715
send_fuse_data (this, finh, &fao,
716
FUSE_COMPAT_ATTR_OUT_SIZE);
515
718
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
516
"%"PRId64": %s() %s => -1 (%s)", frame->root->unique,
719
"%"PRIu64": %s() %s => -1 (%s)", frame->root->unique,
517
720
gf_fop_list[frame->root->op],
518
721
state->loc.path ? state->loc.path : "ERR",
519
722
strerror (op_errno));
521
fuse_reply_err (req, op_errno);
724
send_fuse_err (this, finh, op_errno);
524
727
free_state (state);
525
728
STACK_DESTROY (frame->root);
735
fuse_root_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
736
int32_t op_ret, int32_t op_errno,
737
inode_t *inode, struct stat *stat, dict_t *dict,
738
struct stat *postparent)
740
fuse_attr_cbk (frame, cookie, this, op_ret, op_errno, stat);
531
fuse_getattr (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
747
fuse_getattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
533
749
fuse_state_t *state;
535
751
int32_t ret = -1;
537
state = state_from_req (req);
753
GET_STATE (this, finh, state);
540
ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
755
if (finh->nodeid == 1) {
756
ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
542
758
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
543
"%"PRId64": GETATTR %"PRId64" (fuse_loc_fill() failed)",
544
req_callid (req), (ino_t)ino);
545
fuse_reply_err (req, ENOENT);
759
"%"PRIu64": GETATTR %"PRIu64" (fuse_loc_fill() failed)",
760
finh->unique, finh->nodeid);
761
send_fuse_err (this, finh, ENOENT);
546
762
free_state (state);
550
if (state->loc.inode)
551
state->is_revalidate = 1;
553
state->is_revalidate = -1;
555
766
state->dict = dict_new ();
557
FUSE_FOP (state, fuse_lookup_cbk, GF_FOP_LOOKUP,
768
FUSE_FOP (state, fuse_root_lookup_cbk, GF_FOP_LOOKUP,
558
769
lookup, &state->loc, state->dict);
562
ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
773
ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
564
775
if (!state->loc.inode) {
565
776
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
566
"%"PRId64": GETATTR %"PRId64" (%s) (fuse_loc_fill() returned NULL inode)",
567
req_callid (req), (int64_t)ino, state->loc.path);
568
fuse_reply_err (req, ENOENT);
777
"%"PRIu64": GETATTR %"PRIu64" (%s) (fuse_loc_fill() returned NULL inode)",
778
finh->unique, finh->nodeid, state->loc.path);
779
send_fuse_err (this, finh, ENOENT);
572
fd = fd_lookup (state->loc.inode, get_pid_from_req (req));
784
fd = fd_lookup (state->loc.inode, finh->pid);
574
786
if (!fd || S_ISDIR (state->loc.inode->st_mode)) {
575
787
/* this is the @ret of fuse_loc_fill, checked here
657
do_chmod (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
658
struct fuse_file_info *fi)
660
fuse_state_t *state = NULL;
664
state = state_from_req (req);
671
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
672
"%"PRId64": FCHMOD %p", req_callid (req), fd);
674
FUSE_FOP (state, fuse_attr_cbk, GF_FOP_FCHMOD,
675
fchmod, fd, attr->st_mode);
677
ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
679
if ((state->loc.inode == NULL) ||
681
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
682
"%"PRId64": CHMOD %"PRId64" (%s) (fuse_loc_fill() failed)",
683
req_callid (req), (int64_t)ino,
685
fuse_reply_err (req, ENOENT);
691
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
692
"%"PRId64": CHMOD %s", req_callid (req),
695
FUSE_FOP (state, fuse_attr_cbk, GF_FOP_CHMOD,
696
chmod, &state->loc, attr->st_mode);
702
do_chown (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
703
int valid, struct fuse_file_info *fi)
705
fuse_state_t *state = NULL;
711
uid = (valid & FUSE_SET_ATTR_UID) ? attr->st_uid : (uid_t) -1;
712
gid = (valid & FUSE_SET_ATTR_GID) ? attr->st_gid : (gid_t) -1;
713
state = state_from_req (req);
721
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
722
"%"PRId64": FCHOWN %p", req_callid (req), fd);
724
FUSE_FOP (state, fuse_attr_cbk, GF_FOP_FCHOWN,
725
fchown, fd, uid, gid);
727
ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
728
if ((state->loc.inode == NULL) ||
730
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
731
"%"PRId64": CHOWN %"PRId64" (%s) (fuse_loc_fill() failed)",
732
req_callid (req), (int64_t)ino,
734
fuse_reply_err (req, ENOENT);
739
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
740
"%"PRId64": CHOWN %s", req_callid (req),
743
FUSE_FOP (state, fuse_attr_cbk, GF_FOP_CHOWN,
744
chown, &state->loc, uid, gid);
750
do_truncate (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
751
struct fuse_file_info *fi)
753
fuse_state_t *state = NULL;
757
state = state_from_req (req);
765
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
766
"%"PRId64": FTRUNCATE %p/%"PRId64, req_callid (req),
769
FUSE_FOP (state, fuse_attr_cbk, GF_FOP_FTRUNCATE,
770
ftruncate, fd, attr->st_size);
772
ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
773
if ((state->loc.inode == NULL) ||
775
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
776
"%"PRId64": TRUNCATE %s/%"PRId64" (fuse_loc_fill() failed)",
777
req_callid (req), state->loc.path,
779
fuse_reply_err (req, ENOENT);
784
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
785
"%"PRId64": TRUNCATE %s/%"PRId64"(%lu)",
787
state->loc.path, attr->st_size, ino);
789
FUSE_FOP (state, fuse_attr_cbk, GF_FOP_TRUNCATE,
790
truncate, &state->loc, attr->st_size);
870
fuse_do_truncate (fuse_state_t *state, size_t size)
873
FUSE_FOP (state, fuse_truncate_cbk, GF_FOP_FTRUNCATE,
874
ftruncate, state->fd, size);
876
FUSE_FOP (state, fuse_truncate_cbk, GF_FOP_TRUNCATE,
877
truncate, &state->loc, size);
798
do_utimes (fuse_req_t req, fuse_ino_t ino, struct stat *attr)
885
fuse_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
886
int32_t op_ret, int32_t op_errno,
887
struct stat *statpre, struct stat *statpost)
800
fuse_state_t *state = NULL;
801
struct timespec tv[2];
804
tv[0].tv_sec = attr->st_atime;
805
tv[0].tv_nsec = ST_ATIM_NSEC (attr);
806
tv[1].tv_sec = attr->st_mtime;
807
tv[1].tv_nsec = ST_ATIM_NSEC (attr);
809
state = state_from_req (req);
810
ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
811
if ((state->loc.inode == NULL) ||
890
fuse_in_header_t *finh;
891
fuse_private_t *priv = NULL;
892
struct fuse_attr_out fao;
896
priv = this->private;
897
state = frame->root->state;
901
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
902
"%"PRIu64": %s() %s => %"PRId64, frame->root->unique,
903
gf_fop_list[frame->root->op],
904
state->loc.path ? state->loc.path : "ERR",
907
/* TODO: make these timeouts configurable via meta */
908
/* TODO: what if the inode number has changed by now */
910
statpost->st_blksize = this->ctx->page_size;
912
stat2attr (statpost, &fao.attr);
914
fao.attr_valid = calc_timeout_sec (priv->attribute_timeout);
915
fao.attr_valid_nsec =
916
calc_timeout_nsec (priv->attribute_timeout);
918
if (state->truncate_needed) {
919
fuse_do_truncate (state, state->size);
921
priv->proto_minor >= 9 ?
922
send_fuse_obj (this, finh, &fao) :
923
send_fuse_data (this, finh, &fao,
924
FUSE_COMPAT_ATTR_OUT_SIZE);
813
928
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
814
"%"PRId64": UTIMENS %s (fuse_loc_fill() failed)",
815
req_callid (req), state->loc.path);
816
fuse_reply_err (req, ENOENT);
929
"%"PRIu64": %s() %s => -1 (%s)", frame->root->unique,
930
gf_fop_list[frame->root->op],
931
state->loc.path ? state->loc.path : "ERR",
932
strerror (op_errno));
934
send_fuse_err (this, finh, op_errno);
817
939
free_state (state);
940
STACK_DESTROY (frame->root);
821
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
822
"%"PRId64": UTIMENS (%lu)%s", req_callid (req),
823
ino, state->loc.path);
825
FUSE_FOP (state, fuse_attr_cbk, GF_FOP_UTIMENS,
826
utimens, &state->loc, tv);
948
fattr_to_gf_set_attr (int32_t valid)
950
int32_t gf_valid = 0;
952
if (valid & FATTR_MODE)
953
gf_valid |= GF_SET_ATTR_MODE;
955
if (valid & FATTR_UID)
956
gf_valid |= GF_SET_ATTR_UID;
958
if (valid & FATTR_GID)
959
gf_valid |= GF_SET_ATTR_GID;
961
if (valid & FATTR_ATIME)
962
gf_valid |= GF_SET_ATTR_ATIME;
964
if (valid & FATTR_MTIME)
965
gf_valid |= GF_SET_ATTR_MTIME;
967
if (valid & FATTR_SIZE)
968
gf_valid |= GF_SET_ATTR_SIZE;
974
#define FATTR_MASK (FATTR_SIZE \
975
| FATTR_UID | FATTR_GID \
976
| FATTR_ATIME | FATTR_MTIME \
831
fuse_setattr (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
832
int valid, struct fuse_file_info *fi)
981
fuse_setattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
835
if (valid & FUSE_SET_ATTR_MODE)
836
do_chmod (req, ino, attr, fi);
837
else if (valid & (FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID))
838
do_chown (req, ino, attr, valid, fi);
839
else if (valid & FUSE_SET_ATTR_SIZE)
840
do_truncate (req, ino, attr, fi);
841
else if (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME))
842
do_utimes (req, ino, attr);
983
struct fuse_setattr_in *fsi = msg;
985
struct stat attr = {0, };
987
fuse_private_t *priv = NULL;
988
fuse_state_t *state = NULL;
992
GET_STATE (this, finh, state);
994
if (fsi->valid & FATTR_FH &&
995
!(fsi->valid & (FATTR_ATIME|FATTR_MTIME)))
996
/* We need no loc if kernel sent us an fd and
997
* we are not fiddling with times */
844
fuse_getattr (req, ino, fi);
1000
ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0,
1004
* This is just stub code demonstrating how to retrieve
1005
* lock_owner in setattr, according to the FUSE proto.
1006
* We do not make use of ATM. Its purpose is supporting
1007
* mandatory locking, but getting that right is further
1008
* down the road. Cf.
1010
* http://thread.gmane.org/gmane.comp.file-systems.fuse.devel/
1013
* http://git.kernel.org/?p=linux/kernel/git/torvalds/
1014
* linux-2.6.git;a=commit;h=v2.6.23-5896-gf333211
1016
priv = this->private;
1017
if (priv->proto_minor >= 9 && fsi->valid & FATTR_LOCKOWNER)
1018
state->lk_owner = fsi->lock_owner;
1020
if ((state->loc.inode == NULL && ret == 0) ||
1023
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
1024
"%"PRIu64": SETATTR %s (fuse_loc_fill() failed)",
1025
finh->unique, state->loc.path);
1027
send_fuse_err (this, finh, ENOENT);
1033
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
1034
"%"PRIu64": SETATTR (%"PRIu64")%s", finh->unique,
1035
finh->nodeid, state->loc.path);
1039
if (fsi->valid & FATTR_FH) {
1040
state->fd = FH_TO_FD (fsi->fh);
1043
if ((valid & (FATTR_MASK)) != FATTR_SIZE) {
1044
if (valid & FATTR_SIZE) {
1045
state->size = fsi->size;
1046
state->truncate_needed = _gf_true;
1049
attr.st_size = fsi->size;
1050
attr.st_atime = fsi->atime;
1051
attr.st_mtime = fsi->mtime;
1052
ST_ATIM_NSEC_SET (&attr, fsi->atimensec);
1053
ST_MTIM_NSEC_SET (&attr, fsi->mtimensec);
1055
attr.st_mode = fsi->mode;
1056
attr.st_uid = fsi->uid;
1057
attr.st_gid = fsi->gid;
1060
!((fsi->valid & FATTR_ATIME) || (fsi->valid & FATTR_MTIME))) {
1063
there is no "futimes" call, so don't send
1064
fsetattr if ATIME or MTIME is set
1067
FUSE_FOP (state, fuse_setattr_cbk, GF_FOP_FSETATTR,
1068
fsetattr, state->fd, &attr,
1069
fattr_to_gf_set_attr (fsi->valid));
1071
FUSE_FOP (state, fuse_setattr_cbk, GF_FOP_SETATTR,
1072
setattr, &state->loc, &attr,
1073
fattr_to_gf_set_attr (fsi->valid));
1076
fuse_do_truncate (state, fsi->size);
848
1082
static int gf_fuse_xattr_enotsup_log;
1084
fuse_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
1085
int32_t op_ret, int32_t op_errno, struct stat *prebuf,
1086
struct stat *postbuf)
1088
fuse_state_t *state = frame->root->state;
1089
fuse_in_header_t *finh = state->finh;
1092
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
1093
"%"PRIu64": %s() %s => 0", frame->root->unique,
1094
gf_fop_list[frame->root->op],
1095
state->loc.path ? state->loc.path : "ERR");
1097
send_fuse_err (this, finh, 0);
1099
if (frame->root->op == GF_FOP_SETXATTR) {
1100
op_ret = gf_compat_setxattr (state->dict);
1103
if (op_errno == ENOTSUP) {
1104
gf_fuse_xattr_enotsup_log++;
1105
if (!(gf_fuse_xattr_enotsup_log % GF_UNIVERSAL_ANSWER))
1106
gf_log ("glusterfs-fuse",
1108
"extended attribute not "
1109
"supported by the backend "
1113
if ((frame->root->op == GF_FOP_REMOVEXATTR)
1114
&& (op_errno == ENOATTR)) {
1117
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
1118
"%"PRIu64": %s() %s => -1 (%s)",
1119
frame->root->unique,
1120
gf_fop_list[frame->root->op],
1121
state->loc.path ? state->loc.path : "ERR",
1122
strerror (op_errno));
1126
send_fuse_err (this, finh, op_errno);
1130
STACK_DESTROY (frame->root);
851
1137
fuse_err_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
852
1138
int32_t op_ret, int32_t op_errno)
854
1140
fuse_state_t *state = frame->root->state;
855
fuse_req_t req = state->req;
1141
fuse_in_header_t *finh = state->finh;
857
1143
if (op_ret == 0) {
858
1144
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
859
"%"PRId64": %s() %s => 0", frame->root->unique,
1145
"%"PRIu64": %s() %s => 0", frame->root->unique,
860
1146
gf_fop_list[frame->root->op],
861
1147
state->loc.path ? state->loc.path : "ERR");
863
fuse_reply_err (req, 0);
1149
send_fuse_err (this, finh, 0);
865
1151
if (frame->root->op == GF_FOP_SETXATTR) {
866
1152
op_ret = gf_compat_setxattr (state->dict);
1231
fuse_rename (fuse_req_t req, fuse_ino_t oldpar, const char *oldname,
1232
fuse_ino_t newpar, const char *newname)
1539
fuse_rename (xlator_t *this, fuse_in_header_t *finh, void *msg)
1541
struct fuse_rename_in *fri = msg;
1542
char *oldname = (char *)(fri + 1);
1543
char *newname = oldname + strlen (oldname) + 1;
1234
1545
fuse_state_t *state = NULL;
1235
1546
int32_t ret = -1;
1237
state = state_from_req (req);
1548
GET_STATE (this, finh, state);
1239
ret = fuse_loc_fill (&state->loc, state, 0, oldpar, oldname);
1550
ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, oldname);
1240
1551
if ((state->loc.inode == NULL) ||
1242
1553
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
1243
"for %s %"PRId64": RENAME `%s' -> `%s' (fuse_loc_fill() failed)",
1244
state->loc.path, req_callid (req), state->loc.path,
1554
"for %s %"PRIu64": RENAME `%s' -> `%s' (fuse_loc_fill() failed)",
1555
state->loc.path, finh->unique, state->loc.path,
1245
1556
state->loc2.path);
1247
fuse_reply_err (req, ENOENT);
1558
send_fuse_err (this, finh, ENOENT);
1248
1559
free_state (state);
1252
ret = fuse_loc_fill (&state->loc2, state, 0, newpar, newname);
1563
ret = fuse_loc_fill (&state->loc2, state, 0, fri->newdir, newname);
1254
1565
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
1255
"for %s %"PRId64": RENAME `%s' -> `%s' (fuse_loc_fill() failed)",
1256
state->loc.path, req_callid (req), state->loc.path,
1566
"for %s %"PRIu64": RENAME `%s' -> `%s' (fuse_loc_fill() failed)",
1567
state->loc.path, finh->unique, state->loc.path,
1257
1568
state->loc2.path);
1259
fuse_reply_err (req, ENOENT);
1570
send_fuse_err (this, finh, ENOENT);
1260
1571
free_state (state);
1264
1575
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
1265
"%"PRId64": RENAME `%s (%"PRId64")' -> `%s (%"PRId64")'",
1266
req_callid (req), state->loc.path, state->loc.ino,
1576
"%"PRIu64": RENAME `%s (%"PRId64")' -> `%s (%"PRId64")'",
1577
finh->unique, state->loc.path, state->loc.ino,
1267
1578
state->loc2.path, state->loc2.ino);
1269
1580
FUSE_FOP (state, fuse_rename_cbk, GF_FOP_RENAME,
1312
1628
fuse_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
1313
1629
int32_t op_ret, int32_t op_errno,
1314
fd_t *fd, inode_t *inode, struct stat *buf)
1630
fd_t *fd, inode_t *inode, struct stat *buf,
1631
struct stat *preparent, struct stat *postparent)
1316
1633
fuse_state_t *state = NULL;
1317
fuse_req_t req = NULL;
1634
fuse_in_header_t *finh = NULL;
1318
1635
fuse_private_t *priv = NULL;
1319
struct fuse_file_info fi = {0, };
1320
struct fuse_entry_param e = {0, };
1636
struct fuse_out_header fouh = {0, };
1637
struct fuse_entry_out feo = {0, };
1638
struct fuse_open_out foo = {0, };
1639
struct iovec iov_out[3];
1640
inode_t *linked_inode = NULL;
1322
1643
state = frame->root->state;
1323
1644
priv = this->private;
1325
fi.flags = state->flags;
1327
1648
if (op_ret >= 0) {
1328
fi.fh = (unsigned long) fd;
1649
foo.fh = (uintptr_t) fd;
1330
if ((fi.flags & 3) && priv->direct_io_mode)
1651
if (((state->flags & O_ACCMODE) != O_RDONLY) &&
1652
priv->direct_io_mode)
1653
foo.open_flags |= FOPEN_DIRECT_IO;
1333
1655
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
1334
"%"PRId64": %s() %s => %p (ino=%"PRId64")",
1656
"%"PRIu64": %s() %s => %p (ino=%"PRId64")",
1335
1657
frame->root->unique, gf_fop_list[frame->root->op],
1336
1658
state->loc.path, fd, buf->st_ino);
1338
e.ino = buf->st_ino;
1340
#ifdef GF_DARWIN_HOST_OS
1343
e.generation = buf->st_ctime;
1346
1660
buf->st_blksize = this->ctx->page_size;
1347
e.entry_timeout = priv->entry_timeout;
1348
e.attr_timeout = priv->attribute_timeout;
1353
inode_link (inode, state->loc.parent,
1354
state->loc.name, buf);
1356
inode_lookup (inode);
1661
stat2attr (buf, &feo.attr);
1663
linked_inode = inode_link (inode, state->loc.parent,
1664
state->loc.name, buf);
1666
if (linked_inode != inode) {
1667
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
1668
"create(%s) inode (ptr=%p, ino=%"PRId64", "
1669
"gen=%"PRId64") found conflict (ptr=%p, "
1670
"ino=%"PRId64", gen=%"PRId64")",
1671
state->loc.path, inode, inode->ino,
1672
inode->generation, linked_inode,
1673
linked_inode->ino, linked_inode->generation);
1676
VERY racy code (if used anywhere else)
1677
-- don't do this without understanding
1679
inode_unref (fd->inode);
1680
fd->inode = inode_ref (linked_inode);
1683
inode_lookup (linked_inode);
1685
inode_unref (linked_inode);
1359
if (fuse_reply_create (req, &e, &fi) == -ENOENT) {
1689
feo.nodeid = inode_to_nodeid (linked_inode);
1691
feo.generation = linked_inode->generation;
1693
feo.entry_valid = calc_timeout_sec (priv->entry_timeout);
1694
feo.entry_valid_nsec = calc_timeout_nsec (priv->entry_timeout);
1695
feo.attr_valid = calc_timeout_sec (priv->attribute_timeout);
1696
feo.attr_valid_nsec =
1697
calc_timeout_nsec (priv->attribute_timeout);
1700
iov_out[0].iov_base = &fouh;
1701
iov_out[1].iov_base = &feo;
1702
iov_out[1].iov_len = priv->proto_minor >= 9 ?
1704
FUSE_COMPAT_ENTRY_OUT_SIZE;
1705
iov_out[2].iov_base = &foo;
1706
iov_out[2].iov_len = sizeof (foo);
1707
if (send_fuse_iov (this, finh, iov_out, 3) == ENOENT) {
1360
1708
gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
1361
1709
"create(%s) got EINTR", state->loc.path);
1362
1710
inode_forget (inode, 1);
1383
fuse_create (fuse_req_t req, fuse_ino_t par, const char *name,
1384
mode_t mode, struct fuse_file_info *fi)
1731
fuse_create (xlator_t *this, fuse_in_header_t *finh, void *msg)
1733
struct fuse_create_in *fci = msg;
1734
char *name = (char *)(fci + 1);
1736
fuse_private_t *priv = NULL;
1386
1737
fuse_state_t *state = NULL;
1387
1738
fd_t *fd = NULL;
1388
1739
int32_t ret = -1;
1390
state = state_from_req (req);
1391
state->flags = fi->flags;
1393
ret = fuse_loc_fill (&state->loc, state, 0, par, name);
1741
priv = this->private;
1742
if (priv->proto_minor < 12)
1743
name = (char *)((struct fuse_open_in *)msg + 1);
1745
GET_STATE (this, finh, state);
1746
state->flags = fci->flags;
1748
ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
1395
1750
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
1396
"%"PRId64" CREATE %s (fuse_loc_fill() failed)",
1397
req_callid (req), state->loc.path);
1398
fuse_reply_err (req, ENOENT);
1751
"%"PRIu64" CREATE %s (fuse_loc_fill() failed)",
1752
finh->unique, state->loc.path);
1753
send_fuse_err (this, finh, ENOENT);
1399
1754
free_state (state);
1403
1758
state->loc.inode = inode_new (state->itable);
1405
fd = fd_create (state->loc.inode, get_pid_from_req (req));
1760
fd = fd_create (state->loc.inode, finh->pid);
1406
1761
state->fd = fd;
1407
1762
fd->flags = state->flags;
1409
1764
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
1410
"%"PRId64": CREATE %s", req_callid (req),
1765
"%"PRIu64": CREATE %s", finh->unique,
1411
1766
state->loc.path);
1413
1768
FUSE_FOP (state, fuse_create_cbk, GF_FOP_CREATE,
1414
create, &state->loc, state->flags, mode, fd);
1769
create, &state->loc, state->flags, fci->mode, fd);
1421
fuse_open (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
1776
fuse_open (xlator_t *this, fuse_in_header_t *finh, void *msg)
1778
struct fuse_open_in *foi = msg;
1423
1780
fuse_state_t *state = NULL;
1424
1781
fd_t *fd = NULL;
1425
1782
int32_t ret = -1;
1427
state = state_from_req (req);
1428
state->flags = fi->flags;
1784
GET_STATE (this, finh, state);
1785
state->flags = foi->flags;
1430
ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
1787
ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
1431
1788
if ((state->loc.inode == NULL) ||
1433
1790
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
1434
"%"PRId64": OPEN %s (fuse_loc_fill() failed)",
1435
req_callid (req), state->loc.path);
1791
"%"PRIu64": OPEN %s (fuse_loc_fill() failed)",
1792
finh->unique, state->loc.path);
1437
fuse_reply_err (req, ENOENT);
1794
send_fuse_err (this, finh, ENOENT);
1438
1795
free_state (state);
1442
fd = fd_create (state->loc.inode, get_pid_from_req (req));
1799
fd = fd_create (state->loc.inode, finh->pid);
1443
1800
state->fd = fd;
1444
fd->flags = fi->flags;
1801
fd->flags = foi->flags;
1446
1803
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
1447
"%"PRId64": OPEN %s", req_callid (req),
1804
"%"PRIu64": OPEN %s", finh->unique,
1448
1805
state->loc.path);
1450
1807
FUSE_FOP (state, fuse_fd_cbk, GF_FOP_OPEN,
1451
open, &state->loc, fi->flags, fd);
1808
open, &state->loc, foi->flags, fd, 0);
1673
fuse_fsync (fuse_req_t req, fuse_ino_t ino, int datasync,
1674
struct fuse_file_info *fi)
2075
fuse_fsync (xlator_t *this, fuse_in_header_t *finh, void *msg)
2077
struct fuse_fsync_in *fsi = msg;
1676
2079
fuse_state_t *state = NULL;
1677
2080
fd_t *fd = NULL;
1679
state = state_from_req (req);
2082
GET_STATE (this, finh, state);
2083
fd = FH_TO_FD (fsi->fh);
1681
2084
state->fd = fd;
1683
2086
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
1684
"%"PRId64": FSYNC %p", req_callid (req), fd);
2087
"%"PRIu64": FSYNC %p", finh->unique, fd);
1686
FUSE_FOP (state, fuse_err_cbk, GF_FOP_FSYNC,
1687
fsync, fd, datasync);
2089
/* fsync_flags: 1 means "datasync" (no defines for this) */
2090
FUSE_FOP (state, fuse_fsync_cbk, GF_FOP_FSYNC,
2091
fsync, fd, fsi->fsync_flags & 1);
1694
fuse_opendir (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
2098
fuse_opendir (xlator_t *this, fuse_in_header_t *finh, void *msg)
2101
struct fuse_open_in *foi = msg;
1696
2104
fuse_state_t *state = NULL;
1697
2105
fd_t *fd = NULL;
1698
2106
int32_t ret = -1;
1700
state = state_from_req (req);
1701
ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
2108
GET_STATE (this, finh, state);
2109
ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
1702
2110
if ((state->loc.inode == NULL) ||
1704
2112
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
1705
"%"PRId64": OPENDIR %s (fuse_loc_fill() failed)",
1706
req_callid (req), state->loc.path);
2113
"%"PRIu64": OPENDIR %s (fuse_loc_fill() failed)",
2114
finh->unique, state->loc.path);
1708
fuse_reply_err (req, ENOENT);
2116
send_fuse_err (this, finh, ENOENT);
1709
2117
free_state (state);
1713
fd = fd_create (state->loc.inode, get_pid_from_req (req));
2121
fd = fd_create (state->loc.inode, finh->pid);
1714
2122
state->fd = fd;
1716
2124
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
1717
"%"PRId64": OPENDIR %s", req_callid (req),
2125
"%"PRIu64": OPENDIR %s", finh->unique,
1718
2126
state->loc.path);
1720
2128
FUSE_FOP (state, fuse_fd_cbk, GF_FOP_OPENDIR,
2134
d_type_from_stat (struct stat *buf)
2136
unsigned char d_type;
2138
if (S_ISLNK (buf->st_mode)) {
2141
} else if (S_ISDIR (buf->st_mode)) {
2144
} else if (S_ISFIFO (buf->st_mode)) {
2147
} else if (S_ISSOCK (buf->st_mode)) {
2150
} else if (S_ISCHR (buf->st_mode)) {
2153
} else if (S_ISBLK (buf->st_mode)) {
2156
} else if (S_ISREG (buf->st_mode)) {
2160
d_type = DT_UNKNOWN;
1726
2168
fuse_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
1727
2169
int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
1729
2171
fuse_state_t *state = NULL;
1730
fuse_req_t req = NULL;
2172
fuse_in_header_t *finh = NULL;
1733
2174
char *buf = NULL;
1734
2175
gf_dirent_t *entry = NULL;
1735
struct stat stbuf = {0, };
2176
struct fuse_dirent *fde = NULL;
1737
2178
state = frame->root->state;
1740
2181
if (op_ret < 0) {
1741
2182
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
1742
"%"PRId64": READDIR => -1 (%s)", frame->root->unique,
2183
"%"PRIu64": READDIR => -1 (%s)", frame->root->unique,
1743
2184
strerror (op_errno));
1745
fuse_reply_err (req, op_errno);
2186
send_fuse_err (this, finh, op_errno);
1749
2190
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
1750
"%"PRId64": READDIR => %d/%"GF_PRI_SIZET",%"PRId64,
2191
"%"PRIu64": READDIR => %d/%"GF_PRI_SIZET",%"PRId64,
1751
2192
frame->root->unique, op_ret, state->size, state->off);
1753
2194
list_for_each_entry (entry, &entries->list, list) {
1754
size += fuse_dirent_size (strlen (entry->d_name));
2195
size += FUSE_DIRENT_ALIGN (FUSE_NAME_OFFSET +
2196
strlen (entry->d_name));
1757
2199
buf = CALLOC (1, size);
1759
2201
gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
1760
"%"PRId64": READDIR => -1 (%s)", frame->root->unique,
2202
"%"PRIu64": READDIR => -1 (%s)", frame->root->unique,
1761
2203
strerror (ENOMEM));
1762
fuse_reply_err (req, -ENOMEM);
2204
send_fuse_err (this, finh, ENOMEM);
1767
2209
list_for_each_entry (entry, &entries->list, list) {
1768
stbuf.st_ino = entry->d_ino;
1769
entry_size = fuse_dirent_size (strlen (entry->d_name));
1770
fuse_add_direntry (req, buf + size, entry_size,
1771
entry->d_name, &stbuf,
2210
fde = (struct fuse_dirent *)(buf + size);
2211
fde->ino = entry->d_ino;
2212
fde->off = entry->d_off;
2213
fde->type = d_type_from_stat (&entry->d_stat);
2214
fde->namelen = strlen (entry->d_name);
2215
strncpy (fde->name, entry->d_name, fde->namelen);
2216
size += FUSE_DIRENT_SIZE (fde);
1776
fuse_reply_buf (req, (void *)buf, size);
2219
send_fuse_data (this, finh, buf, size);
1779
2222
free_state (state);
1931
fuse_setxattr (fuse_req_t req, fuse_ino_t ino, const char *name,
1932
const char *value, size_t size, int flags)
2391
fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
2393
struct fuse_setxattr_in *fsi = msg;
2394
char *name = (char *)(fsi + 1);
2395
char *value = name + strlen (name) + 1;
1934
2397
fuse_state_t *state = NULL;
1935
2398
char *dict_value = NULL;
1936
2399
int32_t ret = -1;
1938
2401
#ifdef DISABLE_POSIX_ACL
1939
2402
if (!strncmp (name, "system.", 7)) {
1940
fuse_reply_err (req, EOPNOTSUPP);
2403
send_fuse_err (this, finh, EOPNOTSUPP);
1945
state = state_from_req (req);
1947
ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
2409
GET_STATE (this, finh, state);
2410
state->size = fsi->size;
2411
ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
1948
2412
if ((state->loc.inode == NULL) ||
1950
2414
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
1951
"%"PRId64": SETXATTR %s/%"PRId64" (%s) (fuse_loc_fill() failed)",
1953
state->loc.path, (int64_t)ino, name);
2415
"%"PRIu64": SETXATTR %s/%"PRIu64" (%s) (fuse_loc_fill() failed)",
2417
state->loc.path, finh->nodeid, name);
1955
fuse_reply_err (req, ENOENT);
2419
send_fuse_err (this, finh, ENOENT);
1956
2420
free_state (state);
1960
2424
state->dict = get_new_dict ();
1962
dict_value = memdup (value, size);
2426
gf_log ("glusterfs-fuse", GF_LOG_ERROR,
2427
"%"PRIu64": SETXATTR dict allocation failed",
2434
dict_value = memdup (value, fsi->size);
1963
2435
dict_set (state->dict, (char *)name,
1964
data_from_dynptr ((void *)dict_value, size));
2436
data_from_dynptr ((void *)dict_value, fsi->size));
1965
2437
dict_ref (state->dict);
1967
2439
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
1968
"%"PRId64": SETXATTR %s/%"PRId64" (%s)", req_callid (req),
1969
state->loc.path, (int64_t)ino, name);
2440
"%"PRIu64": SETXATTR %s/%"PRIu64" (%s)", finh->unique,
2441
state->loc.path, finh->nodeid, name);
1971
2443
FUSE_FOP (state, fuse_err_cbk, GF_FOP_SETXATTR,
1972
setxattr, &state->loc, state->dict, flags);
2444
setxattr, &state->loc, state->dict, fsi->flags);
1978
fuse_reply_xattr_buf (fuse_state_t *state, fuse_req_t req, const char *value,
2450
send_fuse_xattr (xlator_t *this, fuse_in_header_t *finh, const char *value,
2451
size_t size, size_t expected)
2453
struct fuse_getxattr_out fgxo;
1981
2455
/* linux kernel limits the size of xattr value to 64k */
1982
if (ret > GLUSTERFS_XATTR_LEN_MAX)
1983
fuse_reply_err (req, E2BIG);
1984
else if (state->size) {
2456
if (size > GLUSTERFS_XATTR_LEN_MAX)
2457
send_fuse_err (this, finh, E2BIG);
2458
else if (expected) {
1985
2459
/* if callback for getxattr and asks for value */
1986
if (ret > state->size)
2460
if (size > expected)
1987
2461
/* reply would be bigger than
1988
2462
* what was asked by kernel */
1989
fuse_reply_err (req, ERANGE);
2463
send_fuse_err (this, finh, ERANGE);
1991
fuse_reply_buf (req, value, ret);
1993
fuse_reply_xattr (req, ret);
2465
send_fuse_data (this, finh, (void *)value, size);
2468
send_fuse_obj (this, finh, &fgxo);
2350
fuse_setlk (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi,
2351
struct flock *lock, int sleep)
2859
fuse_setlk (xlator_t *this, fuse_in_header_t *finh, void *msg)
2861
struct fuse_lk_in *fli = msg;
2353
2863
fuse_state_t *state = NULL;
2354
2864
fd_t *fd = NULL;
2865
struct flock lock = {0, };
2357
state = state_from_req (req);
2867
fd = FH_TO_FD (fli->fh);
2868
GET_STATE (this, finh, state);
2359
2870
state->fd = fd;
2871
convert_fuse_file_lock (&fli->lk, &lock);
2873
state->lk_owner = fli->owner;
2361
2875
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
2362
"%"PRId64": SETLK %p (sleep=%d)", req_callid (req), fd,
2876
"%"PRIu64": SETLK%s %p", finh->unique,
2877
finh->opcode == FUSE_SETLK ? "" : "W", fd);
2365
2879
FUSE_FOP (state, fuse_setlk_cbk, GF_FOP_LK,
2366
lk, fd, (sleep ? F_SETLKW : F_SETLK), lock);
2373
fuse_init (void *data, struct fuse_conn_info *conn)
2379
fuse_destroy (void *data)
2384
static struct fuse_lowlevel_ops fuse_ops = {
2386
.destroy = fuse_destroy,
2387
.lookup = fuse_lookup,
2388
.forget = fuse_forget,
2389
.getattr = fuse_getattr,
2390
.setattr = fuse_setattr,
2391
.opendir = fuse_opendir,
2392
.readdir = fuse_readdir,
2393
.releasedir = fuse_releasedir,
2394
.access = fuse_access,
2395
.readlink = fuse_readlink,
2396
.mknod = fuse_mknod,
2397
.mkdir = fuse_mkdir,
2398
.unlink = fuse_unlink,
2399
.rmdir = fuse_rmdir,
2400
.symlink = fuse_symlink,
2401
.rename = fuse_rename,
2403
.create = fuse_create,
2406
.write = fuse_write,
2407
.flush = fuse_flush,
2408
.release = fuse_release,
2409
.fsync = fuse_fsync,
2410
.fsyncdir = fuse_fsyncdir,
2411
.statfs = fuse_statfs,
2412
.setxattr = fuse_setxattr,
2413
.getxattr = fuse_getxattr,
2414
.listxattr = fuse_listxattr,
2415
.removexattr = fuse_removexattr,
2416
.getlk = fuse_getlk,
2880
lk, fd, finh->opcode == FUSE_SETLK ? F_SETLK : F_SETLKW,
2888
fuse_init (xlator_t *this, fuse_in_header_t *finh, void *msg)
2890
struct fuse_init_in *fini = msg;
2892
struct fuse_init_out fino;
2893
fuse_private_t *priv = NULL;
2896
priv = this->private;
2898
if (!priv->first_call) {
2899
gf_log ("glusterfs-fuse", GF_LOG_ERROR,
2900
"got INIT after first message");
2906
if (fini->major != FUSE_KERNEL_VERSION) {
2907
gf_log ("glusterfs-fuse", GF_LOG_ERROR,
2908
"unsupported FUSE protocol version %d.%d",
2909
fini->major, fini->minor);
2914
priv->proto_minor = fini->minor;
2916
fino.major = FUSE_KERNEL_VERSION;
2917
fino.minor = FUSE_KERNEL_MINOR_VERSION;
2918
fino.max_readahead = 1 << 17;
2919
fino.max_write = 1 << 17;
2920
fino.flags = FUSE_ASYNC_READ | FUSE_POSIX_LOCKS;
2921
if (fini->minor >= 6 /* fuse_init_in has flags */ &&
2922
fini->flags & FUSE_BIG_WRITES) {
2923
/* no need for direct I/O mode if big writes are supported */
2924
priv->direct_io_mode = 0;
2925
fino.flags |= FUSE_BIG_WRITES;
2927
if (fini->minor >= 13) {
2928
/* these values seemed to work fine during testing */
2930
fino.max_background = 64;
2931
fino.congestion_threshold = 48;
2933
if (fini->minor < 9)
2934
*priv->msg0_len_p = sizeof(*finh) + FUSE_COMPAT_WRITE_IN_SIZE;
2936
ret = send_fuse_obj (this, finh, &fino);
2938
gf_log ("glusterfs-fuse", GF_LOG_INFO,
2939
"FUSE inited with protocol versions:"
2940
" glusterfs %d.%d kernel %d.%d",
2941
FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION,
2942
fini->major, fini->minor);
2944
gf_log ("glusterfs-fuse", GF_LOG_ERROR,
2945
"FUSE init failed (%s)", strerror (ret));
2956
fuse_enosys (xlator_t *this, fuse_in_header_t *finh, void *msg)
2958
send_fuse_err (this, finh, ENOSYS);
2965
fuse_destroy (xlator_t *this, fuse_in_header_t *finh, void *msg)
2967
send_fuse_err (this, finh, 0);
2972
static fuse_handler_t *fuse_ops[FUSE_713_OP_HIGH];
2422
fuse_root_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
2423
int32_t op_ret, int32_t op_errno,
2424
inode_t *inode, struct stat *buf, dict_t *xattr)
2975
fuse_first_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
2976
int32_t op_ret, int32_t op_errno,
2977
inode_t *inode, struct stat *buf, dict_t *xattr,
2978
struct stat *postparent)
2426
2980
fuse_private_t *priv = NULL;
2806
3435
&priv->strict_volfile_check);
2809
priv->ch = fuse_mount (priv->mount_point, &args);
2810
if (priv->ch == NULL) {
2811
if (errno == ENOTCONN) {
2812
gf_log ("glusterfs-fuse", GF_LOG_ERROR,
2813
"A stale mount is present on %s. "
2814
"Run 'umount %s' and try again",
2818
if (errno == ENOENT) {
2819
gf_log ("glusterfs-fuse", GF_LOG_ERROR,
2820
"Unable to mount on %s. Run "
2821
"'modprobe fuse' and try again",
2824
gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
2825
"fuse_mount() failed%s%s "
2826
"on mount point %s",
2827
errno ? " with error " : "",
2828
errno ? strerror (errno) : "",
2838
priv->se = fuse_lowlevel_new (&args, &fuse_ops,
2839
sizeof (fuse_ops), this_xl);
2840
if (priv->se == NULL && !errno) {
2842
* Option parsing misery. Can happen if libfuse is of
2843
* FUSE < 2.7.0, as then the "-o subtype" option is not
2846
* Best we can do to is to handle it at runtime -- this is not
2847
* a binary incompatibility issue (which should dealt with at
2848
* compile time), but a behavioural incompatibility issue. Ie.
2849
* we can't tell in advance whether the lib we use supports
2850
* "-o subtype". So try to be clever now.
2852
* Delete the subtype option, and try again.
2854
if (fuse_opt_parse (&args, NULL, subtype_workaround,
2855
subtype_workaround_optproc) == 0)
2856
priv->se = fuse_lowlevel_new (&args, &fuse_ops,
2861
if (priv->se == NULL) {
2862
gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
2863
"fuse_lowlevel_new() failed with error %s on "
2865
strerror (errno), priv->mount_point);
2869
ret = fuse_set_signal_handlers (priv->se);
2871
gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
2872
"fuse_set_signal_handlers() failed on mount point %s",
2877
fuse_opt_free_args (&args);
2880
fuse_session_add_chan (priv->se, priv->ch);
2882
priv->fd = fuse_chan_fd (priv->ch);
3438
fsname = this_xl->ctx->cmd_args.volume_file;
3439
fsname = (fsname ? fsname : this_xl->ctx->cmd_args.volfile_server);
3440
fsname = (fsname ? fsname : "glusterfs");
3442
this_xl->itable = inode_table_new (0, this_xl);
3443
if (!this_xl->itable) {
3444
gf_log ("glusterfs-fuse", GF_LOG_ERROR,
3450
priv->fd = gf_fuse_mount (priv->mount_point, fsname,
3451
"allow_other,default_permissions,"
2884
3456
this_xl->ctx->top = this_xl;
3458
priv->first_call = 2;
2886
3460
pthread_cond_init (&priv->child_up_cond, NULL);
2887
3461
pthread_mutex_init (&priv->child_up_mutex, NULL);
2888
3462
priv->child_up_value = 1;
2890
priv->first_call = 2;
2891
this_xl->itable = inode_table_new (0, this_xl);
3464
for (i = 0; i < FUSE_713_OP_HIGH; i++)
3465
fuse_ops[i] = fuse_enosys;
3466
fuse_ops[FUSE_INIT] = fuse_init;
3467
fuse_ops[FUSE_DESTROY] = fuse_destroy;
3468
fuse_ops[FUSE_LOOKUP] = fuse_lookup;
3469
fuse_ops[FUSE_FORGET] = fuse_forget;
3470
fuse_ops[FUSE_GETATTR] = fuse_getattr;
3471
fuse_ops[FUSE_SETATTR] = fuse_setattr;
3472
fuse_ops[FUSE_OPENDIR] = fuse_opendir;
3473
fuse_ops[FUSE_READDIR] = fuse_readdir;
3474
fuse_ops[FUSE_RELEASEDIR] = fuse_releasedir;
3475
fuse_ops[FUSE_ACCESS] = fuse_access;
3476
fuse_ops[FUSE_READLINK] = fuse_readlink;
3477
fuse_ops[FUSE_MKNOD] = fuse_mknod;
3478
fuse_ops[FUSE_MKDIR] = fuse_mkdir;
3479
fuse_ops[FUSE_UNLINK] = fuse_unlink;
3480
fuse_ops[FUSE_RMDIR] = fuse_rmdir;
3481
fuse_ops[FUSE_SYMLINK] = fuse_symlink;
3482
fuse_ops[FUSE_RENAME] = fuse_rename;
3483
fuse_ops[FUSE_LINK] = fuse_link;
3484
fuse_ops[FUSE_CREATE] = fuse_create;
3485
fuse_ops[FUSE_OPEN] = fuse_open;
3486
fuse_ops[FUSE_READ] = fuse_readv;
3487
fuse_ops[FUSE_WRITE] = fuse_write;
3488
fuse_ops[FUSE_FLUSH] = fuse_flush;
3489
fuse_ops[FUSE_RELEASE] = fuse_release;
3490
fuse_ops[FUSE_FSYNC] = fuse_fsync;
3491
fuse_ops[FUSE_FSYNCDIR] = fuse_fsyncdir;
3492
fuse_ops[FUSE_STATFS] = fuse_statfs;
3493
fuse_ops[FUSE_SETXATTR] = fuse_setxattr;
3494
fuse_ops[FUSE_GETXATTR] = fuse_getxattr;
3495
fuse_ops[FUSE_LISTXATTR] = fuse_listxattr;
3496
fuse_ops[FUSE_REMOVEXATTR] = fuse_removexattr;
3497
fuse_ops[FUSE_GETLK] = fuse_getlk;
3498
fuse_ops[FUSE_SETLK] = fuse_setlk;
3499
fuse_ops[FUSE_SETLKW] = fuse_setlk;
2895
fuse_unmount (priv->mount_point, priv->ch);
2897
fuse_opt_free_args (&args);
3504
if (xl_name_allocated)
3505
FREE (this_xl->name);
2900
3507
FREE (priv->mount_point);