Whamcloud - gitweb
merge b_devel into HEAD, which will become 0.7.3
[fs/lustre-release.git] / lustre / include / linux / lustre_mds.h
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  Copyright (C) 2001-2003 Cluster File Systems, Inc. <info@clusterfs.com>
5  *
6  *   This file is part of Lustre, http://www.lustre.org.
7  *
8  *   Lustre is free software; you can redistribute it and/or
9  *   modify it under the terms of version 2 of the GNU General Public
10  *   License as published by the Free Software Foundation.
11  *
12  *   Lustre is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with Lustre; if not, write to the Free Software
19  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  *
21  * MDS data structures.
22  * See also lustre_idl.h for wire formats of requests.
23  *
24  */
25
26 #ifndef _LUSTRE_MDS_H
27 #define _LUSTRE_MDS_H
28
29 #ifdef __KERNEL__
30 # include <linux/fs.h>
31 # include <linux/dcache.h>
32 #endif
33 #include <linux/lustre_handles.h>
34 #include <linux/kp30.h>
35 #include <linux/lustre_idl.h>
36 #include <linux/lustre_lib.h>
37 #include <linux/lustre_dlm.h>
38 #include <linux/lustre_log.h>
39 #include <linux/lustre_export.h>
40
41 struct ldlm_lock_desc;
42 struct mds_obd;
43 struct ptlrpc_connection;
44 struct ptlrpc_client;
45 struct obd_export;
46 struct ptlrpc_request;
47 struct obd_device;
48 struct ll_file_data;
49
50 #define LUSTRE_MDS_NAME "mds"
51 #define LUSTRE_MDT_NAME "mdt"
52 #define LUSTRE_MDC_NAME "mdc"
53
54 struct lustre_md {
55         struct mds_body *body;
56         struct lov_stripe_md *lsm;
57 };
58
59 struct mdc_rpc_lock {
60         struct semaphore rpcl_sem;
61         struct lookup_intent *rpcl_it;
62 };
63 extern struct mdc_rpc_lock mdc_rpc_lock;
64 extern struct mdc_rpc_lock mdc_setattr_lock;
65
66 static inline void mdc_init_rpc_lock(struct mdc_rpc_lock *lck)
67 {
68         sema_init(&lck->rpcl_sem, 1);
69         lck->rpcl_it = NULL;
70 }
71
72 #ifdef __KERNEL__
73 /* Compat code for kernel patch v18 users, can be removed when everyone has
74  * upgraded --phik 02 June 2003 */
75 #ifdef IT_FL_LOCKED
76 static inline void mdc_get_rpc_lock(struct mdc_rpc_lock *lck, 
77                                     struct lookup_intent *it)
78 {
79         down(&lck->rpcl_sem);
80         if (it) { 
81                 lck->rpcl_it = it;
82                 it->it_int_flags |= IT_FL_LOCKED;
83         }
84 }
85
86 static inline void mdc_put_rpc_lock(struct mdc_rpc_lock *lck, 
87                                     struct lookup_intent *it)
88 {
89         if (it == NULL) {
90                 LASSERT(it == lck->rpcl_it);
91                 up(&lck->rpcl_sem);
92                 return;
93         }
94         if (it != NULL && (it->it_int_flags & IT_FL_LOCKED)) {
95                 it->it_int_flags &= ~IT_FL_LOCKED;
96                 LASSERT(it == lck->rpcl_it);
97                 lck->rpcl_it = NULL;
98                 up(&lck->rpcl_sem);
99         }
100 }
101 #else
102 static inline void mdc_get_rpc_lock(struct mdc_rpc_lock *lck, 
103                                     struct lookup_intent *it)
104 {
105         down(&lck->rpcl_sem);
106         if (it) { 
107                 lck->rpcl_it = it;
108                 it->it_iattr = (void *)1;
109         }
110 }
111
112 static inline void mdc_put_rpc_lock(struct mdc_rpc_lock *lck, 
113                                     struct lookup_intent *it)
114 {
115         if (it == NULL) {
116                 LASSERT(it == lck->rpcl_it);
117                 up(&lck->rpcl_sem);
118                 return;
119         }
120         if (it && it->it_iattr) {
121                 it->it_iattr = NULL;
122                 LASSERT(it == lck->rpcl_it);
123                 lck->rpcl_it = NULL;
124                 up(&lck->rpcl_sem);
125         }
126 }
127 #endif
128 #endif
129
130 struct mdc_op_data {
131         __u64   ino1;
132         __u32   gen1;
133         __u32   typ1;
134         __u32   gid1;
135         __u64   ino2;
136         __u32   gen2;
137         __u32   typ2;
138         __u32   gid2;
139         const char *name;
140         int     namelen;
141         int     mode;
142 };
143
144 struct mds_update_record {
145         __u32 ur_opcode;
146         struct ll_fid *ur_fid1;
147         struct ll_fid *ur_fid2;
148         int ur_namelen;
149         char *ur_name;
150         int ur_tgtlen;
151         char *ur_tgt;
152         int ur_eadatalen;
153         void *ur_eadata;
154         int ur_cookielen;
155         struct llog_cookie *ur_logcookies;
156         struct iattr ur_iattr;
157         struct obd_ucred ur_uc;
158         __u64 ur_rdev;
159         __u32 ur_mode;
160         __u32 ur_uid;
161         __u32 ur_gid;
162         __u64 ur_time;
163         __u32 ur_flags;
164 };
165
166 #define ur_fsuid    ur_uc.ouc_fsuid
167 #define ur_fsgid    ur_uc.ouc_fsgid
168 #define ur_cap      ur_uc.ouc_cap
169 #define ur_suppgid1 ur_uc.ouc_suppgid1
170 #define ur_suppgid2 ur_uc.ouc_suppgid2
171
172 /* i_attr_flags holds the open count in the inode in 2.4 */
173 //Alex implement on 2.4 with i_attr_flags and find soln for 2.5 please
174 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
175 # define mds_open_orphan_count(inode)   (0)
176 # define mds_open_orphan_inc(inode)  do { } while (0);
177 # define mds_open_orphan_dec_test(inode)  (0)
178 #else
179 # define mds_inode_oatomic(inode)    ((atomic_t *)&(inode)->i_attr_flags)
180 # define mds_open_orphan_count(inode)                          \
181   atomic_read(mds_inode_oatomic(inode))
182 # define mds_open_orphan_inc(inode)                            \
183   atomic_inc(mds_inode_oatomic(inode))
184 # define mds_open_orphan_dec_test(inode)                       \
185   atomic_dec_and_test(mds_inode_oatomic(inode))
186 #endif
187 #define mds_inode_is_orphan(inode)  ((inode)->i_flags & 0x4000000)
188 #define mds_inode_set_orphan(inode) (inode)->i_flags |= 0x4000000
189
190 #define MDS_LR_SERVER_SIZE    512
191
192 #define MDS_LR_CLIENT_START  8192
193 #define MDS_LR_CLIENT_SIZE    128
194 #if MDS_LR_CLIENT_START < MDS_LR_SERVER_SIZE
195 #error "Can't have MDS_LR_CLIENT_START < MDS_LR_SERVER_SIZE"
196 #endif
197
198 #define MDS_CLIENT_SLOTS 17
199
200 #define MDS_MOUNT_RECOV 2
201
202 /* Data stored per server at the head of the last_rcvd file.  In le32 order. */
203 struct mds_server_data {
204         __u8  msd_uuid[37];        /* server UUID */
205         __u8  uuid_padding[3];     /* unused */
206 //      __u64 msd_last_objid;      /* last created object ID */
207         __u64 msd_last_transno;    /* last completed transaction ID */
208         __u64 msd_mount_count;     /* MDS incarnation number */
209         __u64 msd_padding_until_last_objid_is_enabled;
210         __u32 msd_feature_compat;  /* compatible feature flags */
211         __u32 msd_feature_rocompat;/* read-only compatible feature flags */
212         __u32 msd_feature_incompat;/* incompatible feature flags */
213         __u32 msd_server_size;     /* size of server data area */
214         __u32 msd_client_start;    /* start of per-client data area */
215         __u16 msd_client_size;     /* size of per-client data area */
216         __u16 msd_subdir_count;    /* number of subdirectories for objects */
217         __u64 msd_catalog_oid;     /* recovery catalog object id */
218         __u32 msd_catalog_ogen;    /* recovery catalog inode generation */
219         __u8  msd_peeruuid[37];    /* UUID of LOV/OSC associated with MDS */
220         __u8  peer_padding[3];     /* unused */
221         __u8  msd_padding[MDS_LR_SERVER_SIZE - 140];
222 };
223
224 /* Data stored per client in the last_rcvd file.  In le32 order. */
225 struct mds_client_data {
226         __u8 mcd_uuid[37];      /* client UUID */
227         __u8 uuid_padding[3];   /* unused */
228         __u64 mcd_mount_count;  /* MDS incarnation number */
229         __u64 mcd_last_transno; /* last completed transaction ID */
230         __u64 mcd_last_xid;     /* xid for the last transaction */
231         __u32 mcd_last_result;  /* result from last RPC */
232         __u32 mcd_last_data;    /* per-op data (disposition for open &c.) */
233         __u8 mcd_padding[MDS_LR_CLIENT_SIZE - 72];
234 };
235
236 /* file data for open files on MDS */
237 struct mds_file_data {
238         struct portals_handle mfd_handle; /* must be first */
239         atomic_t              mfd_refcount;
240         struct list_head      mfd_list;
241         __u64                 mfd_xid;
242         int                   mfd_mode;
243         struct dentry        *mfd_dentry;
244 };
245
246 /* mds/mds_reint.c  */
247 int mds_reint_rec(struct mds_update_record *r, int offset,
248                   struct ptlrpc_request *req, struct lustre_handle *);
249
250 /* mds/handler.c */
251 #ifdef __KERNEL__
252 struct dentry *mds_name2locked_dentry(struct obd_device *, struct dentry *dir,
253                                       struct vfsmount **mnt, char *name,
254                                       int namelen, int lock_mode,
255                                       struct lustre_handle *lockh,
256                                       int dir_lock_mode);
257 struct dentry *mds_fid2locked_dentry(struct obd_device *obd, struct ll_fid *fid,
258                                      struct vfsmount **mnt, int lock_mode,
259                                      struct lustre_handle *lockh);
260 struct dentry *mds_fid2dentry(struct mds_obd *mds, struct ll_fid *fid,
261                               struct vfsmount **mnt);
262 int mds_reint(struct ptlrpc_request *req, int offset, struct lustre_handle *);
263 int mds_pack_md(struct obd_device *mds, struct lustre_msg *msg,
264                 int offset, struct mds_body *body, struct inode *inode);
265 void mds_steal_ack_locks(struct obd_export *exp,
266                          struct ptlrpc_request *req);
267 int mds_update_server_data(struct obd_device *);
268
269 /* mds/mds_fs.c */
270 int mds_fs_setup(struct obd_device *obddev, struct vfsmount *mnt);
271 int mds_fs_cleanup(struct obd_device *obddev, int failover);
272 #endif
273
274 /* mds/mds_lov.c */
275 extern int mds_get_lovtgts(struct mds_obd *obd, int tgt_count,
276                            struct obd_uuid *uuidarray);
277 extern int mds_get_lovdesc(struct mds_obd  *obd, struct lov_desc *desc);
278
279 /* mdc/mdc_request.c */
280 int mdc_req2lustre_md(struct ptlrpc_request *req, int offset,
281                       struct lustre_handle *obd_import,
282                       struct lustre_md *md);
283 int mdc_enqueue(struct lustre_handle *conn, int lock_type,
284                 struct lookup_intent *it, int lock_mode,
285                 struct mdc_op_data *enq_data,
286                 struct lustre_handle *lockh, char *tgt, int tgtlen,
287                 ldlm_completion_callback cb_completion,
288                 ldlm_blocking_callback cb_blocking,
289                 void *cb_data);
290 int mdc_getlovinfo(struct obd_device *obd, struct lustre_handle *mdc_connh,
291                    struct ptlrpc_request **request);
292 int mdc_getstatus(struct lustre_handle *conn, struct ll_fid *rootfid);
293 int mdc_getattr(struct lustre_handle *conn, struct ll_fid *fid,
294                 unsigned long valid, unsigned int ea_size,
295                 struct ptlrpc_request **request);
296 int mdc_getattr_name(struct lustre_handle *conn, struct ll_fid *fid,
297                      char *filename, int namelen, unsigned long valid,
298                      unsigned int ea_size, struct ptlrpc_request **request);
299 int mdc_setattr(struct lustre_handle *conn,
300                 struct mdc_op_data *data,
301                 struct iattr *iattr, void *ea, int ealen, void *ea2, int ea2len,
302                 struct ptlrpc_request **request);
303 int mdc_open(struct lustre_handle *conn, obd_id ino, int type, int flags,
304              struct lov_mds_md *lmm, int lmm_size, struct lustre_handle *fh,
305              struct ptlrpc_request **);
306 struct obd_client_handle;
307 void mdc_set_open_replay_data(struct obd_client_handle *och);
308 int mdc_close(struct lustre_handle *conn, obd_id ino, int type,
309               struct lustre_handle *fh,  struct ptlrpc_request **req);
310 int mdc_readpage(struct lustre_handle *conn, obd_id ino, int type, __u64 offset,
311                  struct page *, struct ptlrpc_request **);
312 int mdc_create(struct lustre_handle *conn, struct mdc_op_data *op_data,
313                const void *data, int datalen, int mode, __u32 uid, __u32 gid,
314                __u64 time, __u64 rdev, struct ptlrpc_request **request);
315 int mdc_unlink(struct lustre_handle *conn, struct mdc_op_data *data,
316                struct ptlrpc_request **request);
317 int mdc_link(struct lustre_handle *conn, struct mdc_op_data *data,
318              struct ptlrpc_request **);
319 int mdc_rename(struct lustre_handle *conn, struct mdc_op_data *data,
320                const char *old, int oldlen, const char *new, int newlen,
321                struct ptlrpc_request **request);
322 int mdc_create_client(struct obd_uuid uuid, struct ptlrpc_client *cl);
323
324 /* Store the generation of a newly-created inode in |req| for replay. */
325 void mdc_store_inode_generation(struct ptlrpc_request *req, int reqoff,
326                                 int repoff);
327
328
329 /* ioctls for trying requests */
330 #define IOC_REQUEST_TYPE                   'f'
331 #define IOC_REQUEST_MIN_NR                 30
332
333 #define IOC_REQUEST_GETATTR             _IOWR('f', 30, long)
334 #define IOC_REQUEST_READPAGE            _IOWR('f', 31, long)
335 #define IOC_REQUEST_SETATTR             _IOWR('f', 32, long)
336 #define IOC_REQUEST_CREATE              _IOWR('f', 33, long)
337 #define IOC_REQUEST_OPEN                _IOWR('f', 34, long)
338 #define IOC_REQUEST_CLOSE               _IOWR('f', 35, long)
339 #define IOC_REQUEST_MAX_NR               35
340
341 #define MDS_CHECK_RESENT(req, reconstruct)                                     \
342 {                                                                              \
343         if (lustre_msg_get_flags(req->rq_reqmsg) & MSG_RESENT) {               \
344                 struct mds_client_data *mcd =                                  \
345                         req->rq_export->exp_mds_data.med_mcd;                  \
346                 if (mcd->mcd_last_xid == req->rq_xid) {                        \
347                         reconstruct;                                           \
348                         RETURN(0);                                             \
349                 }                                                              \
350                 DEBUG_REQ(D_HA, req, "no reply for RESENT req (have "LPD64")", \
351                           mcd->mcd_last_xid);                                  \
352         }                                                                      \
353 }
354
355 #endif