summaryrefslogtreecommitdiff
path: root/src/client/MetaRequest.h
blob: 695717d6fb04ec58116f07851fd557472c03b108 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab

#ifndef CEPH_CLIENT_METAREQUEST_H
#define CEPH_CLIENT_METAREQUEST_H


#include "include/types.h"
#include "msg/msg_types.h"
#include "mds/mds_types.h"

#include "include/xlist.h"
#include "include/filepath.h"
#include "common/Mutex.h"

#include "messages/MClientRequest.h"

class MClientReply;
class Inode;
class Dentry;

struct MetaRequest {
  uint64_t tid;
  ceph_mds_request_head head;
  filepath path, path2;
  bufferlist data;
  int inode_drop; //the inode caps this operation will drop
  int inode_unless; //unless we have these caps already
  int old_inode_drop, old_inode_unless;
  int dentry_drop, dentry_unless;
  int old_dentry_drop, old_dentry_unless;
  int other_inode_drop, other_inode_unless;
  vector<MClientRequest::Release> cap_releases;
  Inode *inode;
  Inode *old_inode, *other_inode;
  Dentry *dentry; //associated with path
  Dentry *old_dentry; //associated with path2

 
  utime_t  sent_stamp;
  int      mds;                // who i am asking
  int      resend_mds;         // someone wants you to (re)send the request here
  bool     send_to_auth;       // must send to auth mds
  __u32    sent_on_mseq;       // mseq at last submission of this request
  int      num_fwd;            // # of times i've been forwarded
  int      retry_attempt;
  int      ref;
  
  MClientReply *reply;         // the reply
  bool kick;
  
  // readdir result
  frag_t readdir_frag;
  string readdir_start;  // starting _after_ this name
  uint64_t readdir_offset;

  vector<pair<string,Inode*> > readdir_result;
  bool readdir_end;
  int readdir_num;
  string readdir_last_name;

  //possible responses
  bool got_safe;
  bool got_unsafe;

  xlist<MetaRequest*>::item item;
  xlist<MetaRequest*>::item unsafe_item;
  Mutex lock; //for get/set sync

  Cond  *caller_cond;          // who to take up
  Cond  *dispatch_cond;        // who to kick back

  Inode *target;

  MetaRequest(int op) : 
    tid(0),
    inode_drop(0), inode_unless(0),
    old_inode_drop(0), old_inode_unless(0),
    dentry_drop(0), dentry_unless(0),
    old_dentry_drop(0), old_dentry_unless(0),
    other_inode_drop(0), other_inode_unless(0),
    inode(NULL), old_inode(NULL), other_inode(NULL),
    dentry(NULL), old_dentry(NULL),
    mds(-1), resend_mds(-1), send_to_auth(false), sent_on_mseq(0),
    num_fwd(0), retry_attempt(0),
    ref(1), reply(0), 
    kick(false),
    readdir_offset(0), readdir_end(false), readdir_num(0),
    got_safe(false), got_unsafe(false), item(this), unsafe_item(this),
    lock("MetaRequest lock"),
    caller_cond(0), dispatch_cond(0),
    target(0) {
    memset(&head, 0, sizeof(ceph_mds_request_head));
    head.op = op;
  }
  ~MetaRequest();

  MetaRequest* get() {
    ++ref;
    return this;
  }

  void put() {
    if (--ref == 0)
      delete this;
  }

  // normal fields
  void set_tid(tid_t t) { tid = t; }
  void set_oldest_client_tid(tid_t t) { head.oldest_client_tid = t; }
  void inc_num_fwd() { head.num_fwd = head.num_fwd + 1; }
  void set_retry_attempt(int a) { head.num_retry = a; }
  void set_filepath(const filepath& fp) { path = fp; }
  void set_filepath2(const filepath& fp) { path2 = fp; }
  void set_string2(const char *s) { path2.set_path(s, 0); }
  void set_caller_uid(unsigned u) { head.caller_uid = u; }
  void set_caller_gid(unsigned g) { head.caller_gid = g; }
  void set_data(const bufferlist &d) { data = d; }
  void set_dentry_wanted() {
    head.flags = head.flags | CEPH_MDS_FLAG_WANT_DENTRY;
  }
  int get_op() { return head.op; }
  tid_t get_tid() { return tid; }
  filepath& get_filepath() { return path; }
  filepath& get_filepath2() { return path2; }

  bool is_write() {
    return
      (head.op & CEPH_MDS_OP_WRITE) || 
      (head.op == CEPH_MDS_OP_OPEN && !(head.args.open.flags & (O_CREAT|O_TRUNC))) ||
      (head.op == CEPH_MDS_OP_CREATE && !(head.args.open.flags & (O_CREAT|O_TRUNC)));
  }
  bool can_forward() {
    if (is_write() ||
	head.op == CEPH_MDS_OP_OPEN ||   // do not forward _any_ open request.
	head.op == CEPH_MDS_OP_CREATE)   // do not forward _any_ open request.
      return false;
    return true;
  }
  bool auth_is_best() {
    if (is_write()) 
      return true;
    if (head.op == CEPH_MDS_OP_OPEN ||
	head.op == CEPH_MDS_OP_CREATE ||
	head.op == CEPH_MDS_OP_READDIR) 
      return true;
    return false;    
  }

  void dump(Formatter *f) const;
};

#endif