Whamcloud - gitweb
- merge 0.7rc1 from b_devel to HEAD (20030612 merge point)
[fs/lustre-release.git] / lustre / liblustre / super.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * Lustre Light Super operations
5  *
6  *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
7  *
8  *   This file is part of Lustre, http://www.lustre.org.
9  *
10  *   Lustre is free software; you can redistribute it and/or
11  *   modify it under the terms of version 2 of the GNU General Public
12  *   License as published by the Free Software Foundation.
13  *
14  *   Lustre is distributed in the hope that it will be useful,
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *   GNU General Public License for more details.
18  *
19  *   You should have received a copy of the GNU General Public License
20  *   along with Lustre; if not, write to the Free Software
21  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23
24 #define DEBUG_SUBSYSTEM S_LLITE
25
26 #include <stdlib.h>
27 #include <string.h>
28 #include <error.h>
29 #include <assert.h>
30 #include <time.h>
31 #include <sys/types.h>
32 #include <sys/queue.h>
33
34 #include <sysio.h>
35 #include <fs.h>
36 #include <mount.h>
37 #include <inode.h>
38 #include <file.h>
39
40 #include "llite_lib.h"
41
42 static void llu_fsop_gone(struct filesys *fs)
43 {
44         /* FIXME */
45 }
46
47 static struct inode_ops llu_inode_ops;
48
49 void llu_update_inode(struct inode *inode, struct mds_body *body,
50                       struct lov_stripe_md *lsm)
51 {
52         struct llu_inode_info *lli = llu_i2info(inode);
53
54         LASSERT ((lsm != NULL) == ((body->valid & OBD_MD_FLEASIZE) != 0));
55         if (lsm != NULL) {
56                 if (lli->lli_smd == NULL)                        
57                         lli->lli_smd = lsm;
58                 else
59                         LASSERT (!memcmp (lli->lli_smd, lsm,
60                                           sizeof (*lsm)));
61         }
62
63         if (body->valid & OBD_MD_FLID)
64                 lli->lli_st_ino = body->ino;
65         if (body->valid & OBD_MD_FLATIME)
66                 LTIME_S(lli->lli_st_atime) = body->atime;
67         if (body->valid & OBD_MD_FLMTIME)
68                 LTIME_S(lli->lli_st_mtime) = body->mtime;
69         if (body->valid & OBD_MD_FLCTIME)
70                 LTIME_S(lli->lli_st_ctime) = body->ctime;
71         if (body->valid & OBD_MD_FLMODE)
72                 lli->lli_st_mode = (lli->lli_st_mode & S_IFMT)|(body->mode & ~S_IFMT);
73         if (body->valid & OBD_MD_FLTYPE)
74                 lli->lli_st_mode = (lli->lli_st_mode & ~S_IFMT)|(body->mode & S_IFMT);
75         if (body->valid & OBD_MD_FLUID)
76                 lli->lli_st_uid = body->uid;
77         if (body->valid & OBD_MD_FLGID)
78                 lli->lli_st_gid = body->gid;
79         if (body->valid & OBD_MD_FLFLAGS)
80                 lli->lli_st_flags = body->flags;
81         if (body->valid & OBD_MD_FLNLINK)
82                 lli->lli_st_nlink = body->nlink;
83         if (body->valid & OBD_MD_FLGENER)
84                 lli->lli_st_generation = body->generation;
85         if (body->valid & OBD_MD_FLRDEV)
86                 lli->lli_st_rdev = body->rdev;
87         if (body->valid & OBD_MD_FLSIZE)
88                 lli->lli_st_size = body->size;
89         if (body->valid & OBD_MD_FLBLOCKS)
90                 lli->lli_st_blocks = body->blocks;
91
92         /* fillin fid */
93         if (body->valid & OBD_MD_FLID)
94                 lli->lli_fid.id = body->ino;
95         if (body->valid & OBD_MD_FLGENER)
96                 lli->lli_fid.generation = body->generation;
97         if (body->valid & OBD_MD_FLTYPE)
98                 lli->lli_fid.f_type = body->mode & S_IFMT;
99 }
100
101 void obdo_to_inode(struct inode *dst, struct obdo *src, obd_flag valid)
102 {
103         struct llu_inode_info *lli = llu_i2info(dst);
104
105         valid &= src->o_valid;
106
107         if (valid & OBD_MD_FLATIME)
108                 LTIME_S(lli->lli_st_atime) = src->o_atime;
109         if (valid & OBD_MD_FLMTIME)
110                 LTIME_S(lli->lli_st_mtime) = src->o_mtime;
111         if (valid & OBD_MD_FLCTIME && src->o_ctime > LTIME_S(lli->lli_st_ctime))
112                 LTIME_S(lli->lli_st_ctime) = src->o_ctime;
113         if (valid & OBD_MD_FLSIZE)
114                 lli->lli_st_size = src->o_size;
115         if (valid & OBD_MD_FLBLOCKS) /* allocation of space */
116                 lli->lli_st_blocks = src->o_blocks;
117         if (valid & OBD_MD_FLBLKSZ)
118                 lli->lli_st_blksize = src->o_blksize;
119         if (valid & OBD_MD_FLTYPE)
120                 lli->lli_st_mode = (lli->lli_st_mode & ~S_IFMT) | (src->o_mode & S_IFMT);
121         if (valid & OBD_MD_FLMODE)
122                 lli->lli_st_mode = (lli->lli_st_mode & S_IFMT) | (src->o_mode & ~S_IFMT);
123         if (valid & OBD_MD_FLUID)
124                 lli->lli_st_uid = src->o_uid;
125         if (valid & OBD_MD_FLGID)
126                 lli->lli_st_gid = src->o_gid;
127         if (valid & OBD_MD_FLFLAGS)
128                 lli->lli_st_flags = src->o_flags;
129         if (valid & OBD_MD_FLNLINK)
130                 lli->lli_st_nlink = src->o_nlink;
131         if (valid & OBD_MD_FLGENER)
132                 lli->lli_st_generation = src->o_generation;
133         if (valid & OBD_MD_FLRDEV)
134                 lli->lli_st_rdev = src->o_rdev;
135 }
136
137 void obdo_from_inode(struct obdo *dst, struct inode *src, obd_flag valid)
138 {
139         struct llu_inode_info *lli = llu_i2info(src);
140
141         if (valid & OBD_MD_FLATIME)
142                 dst->o_atime = LTIME_S(lli->lli_st_atime);
143         if (valid & OBD_MD_FLMTIME)
144                 dst->o_mtime = LTIME_S(lli->lli_st_mtime);
145         if (valid & OBD_MD_FLCTIME)
146                 dst->o_ctime = LTIME_S(lli->lli_st_ctime);
147         if (valid & OBD_MD_FLSIZE)
148                 dst->o_size = lli->lli_st_size;
149         if (valid & OBD_MD_FLBLOCKS)   /* allocation of space */
150                 dst->o_blocks = lli->lli_st_blocks;
151         if (valid & OBD_MD_FLBLKSZ)
152                 dst->o_blksize = lli->lli_st_blksize;
153         if (valid & OBD_MD_FLTYPE)
154                 dst->o_mode = (dst->o_mode & ~S_IFMT) | (lli->lli_st_mode & S_IFMT);
155         if (valid & OBD_MD_FLMODE)
156                 dst->o_mode = (dst->o_mode & S_IFMT) | (lli->lli_st_mode & ~S_IFMT);
157         if (valid & OBD_MD_FLUID)
158                 dst->o_uid = lli->lli_st_uid;
159         if (valid & OBD_MD_FLGID)
160                 dst->o_gid = lli->lli_st_gid;
161         if (valid & OBD_MD_FLFLAGS)
162                 dst->o_flags = lli->lli_st_flags;
163         if (valid & OBD_MD_FLNLINK)
164                 dst->o_nlink = lli->lli_st_nlink;
165         if (valid & OBD_MD_FLGENER)
166                 dst->o_generation = lli->lli_st_generation;
167         if (valid & OBD_MD_FLRDEV)
168                 dst->o_rdev = (__u32)(lli->lli_st_rdev);
169
170         dst->o_valid |= (valid & ~OBD_MD_FLID);
171 }
172
173 int llu_inode_getattr(struct inode *inode, struct lov_stripe_md *lsm,
174                       char *ostdata)
175 {
176         struct llu_sb_info *sbi = llu_i2sbi(inode);
177         struct obdo oa;
178         int rc;
179         ENTRY;
180
181         LASSERT(lsm);
182         LASSERT(sbi);
183
184         memset(&oa, 0, sizeof oa);
185         oa.o_id = lsm->lsm_object_id;
186         oa.o_mode = S_IFREG;
187         oa.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLSIZE |
188                 OBD_MD_FLBLOCKS | OBD_MD_FLMTIME | OBD_MD_FLCTIME;
189
190         if (ostdata != NULL) {
191                 memcpy(&oa.o_inline, ostdata, FD_OSTDATA_SIZE);
192                 oa.o_valid |= OBD_MD_FLHANDLE;
193         }
194
195         rc = obd_getattr(&sbi->ll_osc_conn, &oa, lsm);
196         if (rc)
197                 RETURN(rc);
198
199         obdo_to_inode(inode, &oa, OBD_MD_FLSIZE | OBD_MD_FLBLOCKS |
200                            OBD_MD_FLMTIME | OBD_MD_FLCTIME);
201
202         RETURN(0);
203 }
204
205 struct inode* llu_new_inode(struct filesys *fs, ino_t ino, mode_t mode)
206 {
207         struct inode *inode;
208         struct llu_inode_info *lli;
209
210         OBD_ALLOC(lli, sizeof(*lli));
211         if (!lli)
212                 return NULL;
213
214         /* initialize lli here */
215         lli->lli_sbi = llu_fs2sbi(fs);
216         lli->lli_smd = NULL;
217         lli->lli_symlink_name = NULL;
218         lli->lli_flags = 0;
219         INIT_LIST_HEAD(&lli->lli_read_extents);
220         lli->lli_file_data = NULL;
221
222         /* could file_identifier be 0 ? FIXME */
223         inode = _sysio_i_new(fs, ino, NULL,
224 #ifndef AUTOMOUNT_FILE_NAME
225                              mode & S_IFMT,
226 #else
227                              mode,      /* all of the bits! */
228 #endif
229                              0,
230                              &llu_inode_ops, lli);
231
232         if (!inode)
233                 OBD_FREE(lli, sizeof(*lli));
234
235         return inode;
236 }
237
238 static int llu_iop_lookup(struct pnode *pnode,
239                           struct inode **inop,
240                           struct intent *intnt __IS_UNUSED,
241                           const char *path __IS_UNUSED)
242 {
243         struct pnode_base *pb_dir = pnode->p_parent->p_base;
244         struct ptlrpc_request *request = NULL;
245         struct llu_sb_info *sbi = llu_i2sbi(pb_dir->pb_ino);
246         struct ll_fid *fid = &llu_i2info(pb_dir->pb_ino)->lli_fid;
247         struct qstr *name = &pnode->p_base->pb_name;
248         struct mds_body *body;
249         unsigned long valid;
250         char *pname;
251         int rc, easize;
252         struct ll_read_inode2_cookie lic = {.lic_body = NULL, .lic_lsm = NULL};
253
254         /* the mount root inode have no name, so don't call
255          * remote in this case. but probably we need revalidate
256          * it here? FIXME */
257         if (pnode->p_mount->mnt_root == pnode) {
258                 struct inode *i = pnode->p_base->pb_ino;
259                 I_REF(i);
260                 *inop = i;
261                 return 0;
262         }
263
264         if (!name->len)
265                 return -EINVAL;
266
267         /* mdc_getattr_name require NULL-terminated name */
268         OBD_ALLOC(pname, name->len + 1);
269         if (!pname)
270                 return -ENOMEM;
271         memcpy(pname, name->name, name->len);
272         pname[name->len] = 0;
273
274         valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLSIZE;
275
276         /* FIXME before getattr_name, we don't know whether
277          * the inode we are finding is regular or not, so here
278          * we blindly require server feed in EA data */
279         easize = obd_size_diskmd(&sbi->ll_osc_conn, NULL);
280         valid |= OBD_MD_FLEASIZE;
281
282         rc = mdc_getattr_name(&sbi->ll_mdc_conn, fid,
283                               pname, name->len + 1,
284                               valid, easize, &request);
285         if (rc < 0) {
286                 CERROR("mdc_getattr_name: %d\n", rc);
287                 rc = -ENOENT;
288                 goto out;
289         }
290         body = lustre_msg_buf(request->rq_repmsg, 0, sizeof(*body));
291
292         *inop = llu_new_inode(pnode->p_mount->mnt_fs, body->ino, body->mode);
293         if (!inop)
294                 goto out;
295
296         lic.lic_body = lustre_msg_buf(request->rq_repmsg, 0, sizeof(*lic.lic_body));
297         LASSERT (lic.lic_body != NULL);
298         LASSERT_REPSWABBED (request, 0);
299
300         if (S_ISREG(lic.lic_body->mode) &&
301             lic.lic_body->valid & OBD_MD_FLEASIZE) {
302                 struct lov_mds_md    *lmm;
303                 int                   lmm_size;
304                 int                   rc;
305                 
306                 lmm_size = lic.lic_body->eadatasize;
307                 if (lmm_size == 0) {
308                         CERROR ("OBD_MD_FLEASIZE set but eadatasize 0\n");
309                         RETURN (-EPROTO);
310                 }
311                 lmm = lustre_msg_buf(request->rq_repmsg, 0 + 1, lmm_size);
312                 LASSERT(lmm != NULL);
313                 LASSERT_REPSWABBED (request, 0 + 1);
314
315                 rc = obd_unpackmd (&sbi->ll_osc_conn, 
316                                    &lic.lic_lsm, lmm, lmm_size);
317                 if (rc < 0) {
318                         CERROR ("Error %d unpacking eadata\n", rc);
319                         RETURN (rc);
320                 }
321                 LASSERT (rc >= sizeof (*lic.lic_lsm));
322
323         } else {
324                 lic.lic_lsm = NULL;
325         }
326
327         llu_update_inode(*inop, body, lic.lic_lsm);
328
329         if (llu_i2info(*inop)->lli_smd) {
330                 rc = llu_inode_getattr(*inop, llu_i2info(*inop)->lli_smd, NULL);
331                 if (rc)
332                         _sysio_i_gone(*inop);
333         }
334
335 out:
336         ptlrpc_req_finished(request);
337         OBD_FREE(pname, name->len + 1);
338
339         return rc;
340 }
341
342 static int llu_iop_getattr(struct pnode *pno,
343                            struct inode *ino,
344                            struct intnl_stat *b)
345 {
346         struct llu_inode_info *lli = llu_i2info(ino);
347
348         b->st_dev = lli->lli_st_dev;
349         b->st_ino = lli->lli_st_ino;
350         b->st_mode = lli->lli_st_mode;
351         b->st_nlink = lli->lli_st_nlink;
352         b->st_uid = lli->lli_st_uid;
353         b->st_gid = lli->lli_st_gid;
354         b->st_rdev = lli->lli_st_rdev;
355         b->st_size = lli->lli_st_size;
356         b->st_blksize = lli->lli_st_blksize;
357         b->st_blocks = lli->lli_st_blocks;
358         b->st_atime = lli->lli_st_atime;
359         b->st_mtime = lli->lli_st_mtime;
360         b->st_ctime = lli->lli_st_ctime;
361
362         return 0;
363 }
364
365 int llu_mdc_cancel_unused(struct lustre_handle *conn,
366                           struct llu_inode_info *lli,
367                           int flags)
368 {
369         struct ldlm_res_id res_id =
370                 { .name = {lli->lli_st_ino, lli->lli_st_generation} };
371         struct obd_device *obddev = class_conn2obd(conn);
372         ENTRY;
373         RETURN(ldlm_cli_cancel_unused(obddev->obd_namespace, &res_id, flags));
374 }
375
376 static void llu_clear_inode(struct inode *inode)
377 {
378         struct llu_sb_info *sbi = llu_i2sbi(inode);
379         struct llu_inode_info *lli = llu_i2info(inode);
380         int rc;
381         ENTRY;
382
383         CDEBUG(D_INODE, "clear inode: %lu\n", lli->lli_st_ino);
384         rc = llu_mdc_cancel_unused(&sbi->ll_mdc_conn, lli,
385                                    LDLM_FL_NO_CALLBACK);
386         if (rc < 0) {
387                 CERROR("ll_mdc_cancel_unused: %d\n", rc);
388                 /* XXX FIXME do something dramatic */
389         }
390
391         if (lli->lli_smd) {
392                 rc = obd_cancel_unused(&sbi->ll_osc_conn, lli->lli_smd, 0);
393                 if (rc < 0) {
394                         CERROR("obd_cancel_unused: %d\n", rc);
395                         /* XXX FIXME do something dramatic */
396                 }
397         }
398
399         if (lli->lli_smd)
400                 obd_free_memmd(&sbi->ll_osc_conn, &lli->lli_smd);
401
402         if (lli->lli_symlink_name) {
403                 OBD_FREE(lli->lli_symlink_name,
404                          strlen(lli->lli_symlink_name) + 1);
405                 lli->lli_symlink_name = NULL;
406         }
407
408         EXIT;
409 }
410
411 void llu_iop_gone(struct inode *inode)
412 {
413         struct llu_inode_info *lli = llu_i2info(inode);
414
415         llu_clear_inode(inode);
416
417         OBD_FREE(lli, sizeof(*lli));
418 }
419
420 static int llu_setattr_raw(struct inode *inode, struct iattr *attr)
421 {
422         struct ptlrpc_request *request = NULL;
423         struct llu_sb_info *sbi = llu_i2sbi(inode);
424         struct llu_inode_info *lli = llu_i2info(inode);
425         struct mdc_op_data op_data;
426         int err = 0;
427         ENTRY;
428         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu\n", lli->lli_st_ino);
429
430         /* if need truncate, do it at first */
431         if (attr->ia_valid & ATTR_SIZE) {
432                 printf("************* don't support truncate now !!!!!!!!\n");
433                 LBUG();
434         }
435
436         /* Don't send size changes to MDS to avoid "fast EA" problems, and
437          * also avoid a pointless RPC (we get file size from OST anyways).
438          */
439         attr->ia_valid &= ~ATTR_SIZE;
440         if (!attr->ia_valid)
441                 RETURN(0);
442
443         llu_prepare_mdc_op_data(&op_data, inode, NULL, NULL, 0, 0);
444
445         err = mdc_setattr(&sbi->ll_mdc_conn, &op_data,
446                           attr, NULL, 0, &request);
447         if (err)
448                 CERROR("mdc_setattr fails: err = %d\n", err);
449
450         ptlrpc_req_finished(request);
451
452         if (S_ISREG(inode->i_mode) && attr->ia_valid & ATTR_MTIME_SET) {
453                 struct lov_stripe_md *lsm = lli->lli_smd;
454                 struct obdo oa;
455                 int err2;
456
457                 CDEBUG(D_INODE, "set mtime on OST inode %lu to %lu\n",
458                        lli->lli_st_ino, attr->ia_mtime);
459                 oa.o_id = lsm->lsm_object_id;
460                 oa.o_mode = S_IFREG;
461                 oa.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMTIME;
462                 oa.o_mtime = attr->ia_mtime;
463                 err2 = obd_setattr(&sbi->ll_osc_conn, &oa, lsm, NULL);
464                 if (err2) {
465                         CERROR("obd_setattr fails: rc=%d\n", err);
466                         if (!err)
467                                 err = err2;
468                 }
469         }
470         RETURN(err);
471 }
472
473 /* FIXME here we simply act as a thin layer to glue it with
474  * llu_setattr_raw(), which is copy from kernel
475  */
476 static int llu_iop_setattr(struct pnode *pno,
477                            struct inode *ino,
478                            unsigned mask,
479                            struct intnl_stat *stbuf)
480 {
481         struct iattr iattr;
482
483         memset(&iattr, 0, sizeof(iattr));
484
485         if (mask & SETATTR_MODE) {
486                 iattr.ia_mode = stbuf->st_mode;
487                 iattr.ia_valid |= ATTR_MODE;
488         }
489         if (mask & SETATTR_MTIME) {
490                 iattr.ia_mtime = stbuf->st_mtime;
491                 iattr.ia_valid |= ATTR_MTIME;
492         }
493         if (mask & SETATTR_ATIME) {
494                 iattr.ia_atime = stbuf->st_atime;
495                 iattr.ia_valid |= ATTR_ATIME;
496         }
497         if (mask & SETATTR_UID) {
498                 iattr.ia_uid = stbuf->st_uid;
499                 iattr.ia_valid |= ATTR_UID;
500         }
501         if (mask & SETATTR_GID) {
502                 iattr.ia_gid = stbuf->st_gid;
503                 iattr.ia_valid |= ATTR_GID;
504         }
505         if (mask & SETATTR_LEN) {
506                 iattr.ia_size = stbuf->st_size; /* FIXME signed expansion problem */
507                 iattr.ia_valid |= ATTR_SIZE;
508         }
509
510         iattr.ia_valid |= ATTR_RAW;
511         /* FIXME FIXME FIXME FIXME FIXME FIXME FIXME
512          * without ATTR_FROM_OPEN, mds_reint_setattr will call
513          * mds_fid2locked_dentry() and deadlocked at completion_ast call.
514          * Here we workaround it and avoid any locking.
515          * FIXME FIXME FIXME FIXME FIXME FIXME FIXME
516          */
517         iattr.ia_valid |= ATTR_FROM_OPEN;
518
519         return llu_setattr_raw(ino, &iattr);
520 }
521
522
523 static int llu_mkdir2(struct inode *dir, const char *name, int len, int mode)
524 {
525         struct ptlrpc_request *request = NULL;
526         time_t curtime = CURRENT_TIME;
527         struct llu_sb_info *sbi = llu_i2sbi(dir);
528         struct llu_inode_info *lli = llu_i2info(dir);
529         struct mdc_op_data op_data;
530         int err = -EMLINK;
531         ENTRY;
532         CDEBUG(D_VFSTRACE, "VFS Op:name=%s,dir=%lu\n",
533                name, lli->lli_st_ino);
534
535         /* FIXME check this later */
536 #if 0 
537         if (dir->i_nlink >= EXT2_LINK_MAX)
538                 RETURN(err);
539         mode = (mode & (S_IRWXUGO|S_ISVTX) & ~current->fs->umask) | S_IFDIR;
540 #endif
541         mode |= S_IFDIR;
542         llu_prepare_mdc_op_data(&op_data, dir, NULL, name, len, 0);
543         err = mdc_create(&sbi->ll_mdc_conn, &op_data, NULL, 0, mode,
544                          current->fsuid, current->fsgid,
545                          curtime, 0, &request);
546         ptlrpc_req_finished(request);
547         RETURN(err);
548 }
549
550 static int llu_iop_mkdir(struct pnode *pno, mode_t mode)
551 {
552         struct inode *dir = pno->p_base->pb_parent->pb_ino;
553         struct qstr *qstr = &pno->p_base->pb_name;
554         int rc;
555
556         LASSERT(dir);
557
558         rc = llu_mkdir2(dir, qstr->name, qstr->len, mode);
559
560         return rc;
561 }
562
563 #ifndef S_IRWXUGO
564 #define S_IRWXUGO       (S_IRWXU|S_IRWXG|S_IRWXO)
565 #endif
566
567 static int llu_symlink2(struct inode *dir, const char *name, int len,
568                         const char *tgt)
569 {
570         struct ptlrpc_request *request = NULL;
571         time_t curtime = CURRENT_TIME;
572         struct llu_sb_info *sbi = llu_i2sbi(dir);
573         struct llu_inode_info *lli = llu_i2info(dir);
574         struct mdc_op_data op_data;
575         int err = -EMLINK;
576         ENTRY;
577
578         CDEBUG(D_VFSTRACE, "VFS Op:name=%s,dir=%lu,target=%s\n",
579                name, lli->lli_st_ino, tgt);
580
581 #if 0
582         if (dir->i_nlink >= EXT2_LINK_MAX)
583                 RETURN(err);
584 #endif
585         llu_prepare_mdc_op_data(&op_data, dir, NULL, name, len, 0);
586         err = mdc_create(&sbi->ll_mdc_conn, &op_data,
587                          tgt, strlen(tgt) + 1, S_IFLNK | S_IRWXUGO,
588                          current->fsuid, current->fsgid, curtime, 0, &request);
589         ptlrpc_req_finished(request);
590         RETURN(err);
591 }
592
593 static int llu_iop_symlink(struct pnode *pno, const char *data)
594 {
595         struct inode *dir = pno->p_base->pb_parent->pb_ino;
596         struct qstr *qstr = &pno->p_base->pb_name;
597         int rc;
598         
599         LASSERT(dir);
600
601         rc = llu_symlink2(dir, qstr->name, qstr->len, data);
602
603         return rc;
604 }
605
606 struct filesys_ops llu_filesys_ops =
607 {
608         fsop_gone: llu_fsop_gone,
609 };
610
611
612 static struct inode_ops llu_inode_ops = {
613         inop_lookup:    llu_iop_lookup,
614         inop_getattr:   llu_iop_getattr,
615         inop_setattr:   llu_iop_setattr,
616         inop_getdirentries:     NULL,
617         inop_mkdir:     llu_iop_mkdir,
618         inop_rmdir:     NULL,
619         inop_symlink:   llu_iop_symlink,
620         inop_readlink:  NULL,
621         inop_open:      llu_iop_open,
622         inop_close:     llu_iop_close,
623         inop_unlink:    NULL,
624         inop_ipreadv:   llu_iop_ipreadv,
625         inop_ipwritev:  llu_iop_ipwritev,
626         inop_iodone:    llu_iop_iodone,
627         inop_fcntl:     NULL,
628         inop_sync:      NULL,
629         inop_datasync:  NULL,
630         inop_ioctl:     NULL,
631         inop_mknod:     NULL,
632         inop_statvfs:   NULL,
633         inop_gone:      llu_iop_gone,
634 };
635
636
637 static int
638 llu_fsswop_mount(const char *source,
639                  unsigned flags,
640                  const void *data __IS_UNUSED,
641                  struct pnode *tocover,
642                  struct mount **mntp)
643 {
644         struct filesys *fs;
645         struct inode *root;
646         struct pnode_base *rootpb;
647         static struct qstr noname = { NULL, 0, 0 };
648         struct ll_fid rootfid;
649
650         struct llu_sb_info *sbi;
651         struct ptlrpc_connection *mdc_conn;
652         struct ptlrpc_request *request = NULL;
653         struct mds_body *root_body;
654         struct obd_uuid param_uuid;
655         class_uuid_t uuid;
656         struct obd_device *obd;
657         char *osc=mount_option.osc_uuid;
658         char *mdc=mount_option.mdc_uuid;
659         int err = -EINVAL;
660
661         ENTRY;
662
663         OBD_ALLOC(sbi, sizeof(*sbi));
664         if (!sbi)
665                 RETURN(-ENOMEM);
666
667         INIT_LIST_HEAD(&sbi->ll_conn_chain);
668         generate_random_uuid(uuid);
669         class_uuid_unparse(uuid, &sbi->ll_sb_uuid);
670
671         fs = _sysio_fs_new(&llu_filesys_ops, flags, sbi);
672         if (!fs) {
673                 err = -ENOMEM;
674                 goto out_free;
675         }
676
677         strncpy(param_uuid.uuid, mdc, sizeof(param_uuid.uuid));
678         obd = class_uuid2obd(&param_uuid);
679         if (!obd) {
680                 CERROR("MDC %s: not setup or attached\n", mdc);
681                 err = -EINVAL;
682                 goto out_free;
683         }
684
685         /* setup mdc */
686         /* FIXME need recover stuff */
687         err = obd_connect(&sbi->ll_mdc_conn, obd, &sbi->ll_sb_uuid);
688         if (err) {
689                 CERROR("cannot connect to %s: rc = %d\n", mdc, err);
690                 goto out_free;
691         }
692
693         mdc_conn = sbi2mdc(sbi)->cl_import->imp_connection;
694
695         /* setup osc */
696         strncpy(param_uuid.uuid, osc, sizeof(param_uuid.uuid));
697         obd = class_uuid2obd(&param_uuid);
698         if (!obd) {
699                 CERROR("OSC %s: not setup or attached\n", osc);
700                 err = -EINVAL;
701                 goto out_mdc;
702         }
703
704         err = obd_connect(&sbi->ll_osc_conn, obd, &sbi->ll_sb_uuid);
705         if (err) {
706                 CERROR("cannot connect to %s: rc = %d\n", osc, err);
707                 goto out_mdc;
708         }
709
710         err = mdc_getstatus(&sbi->ll_mdc_conn, &rootfid);
711         if (err) {
712                 CERROR("cannot mds_connect: rc = %d\n", err);
713                 goto out_osc;
714         }
715         CDEBUG(D_SUPER, "rootfid "LPU64"\n", rootfid.id);
716         sbi->ll_rootino = rootfid.id;
717
718 /* XXX do we need this??
719         memset(&osfs, 0, sizeof(osfs));
720         rc = obd_statfs(&sbi->ll_mdc_conn, &osfs);
721 */
722         /* fetch attr of root inode */
723         err = mdc_getattr(&sbi->ll_mdc_conn, &rootfid,
724                           OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, 0, &request);
725         if (err) {
726                 CERROR("mdc_getattr failed for root: rc = %d\n", err);
727                 goto out_request;
728         }
729
730         root_body = lustre_msg_buf(request->rq_repmsg, 0, sizeof(*root_body));
731         LASSERT(sbi->ll_rootino != 0);
732
733         root = llu_new_inode(fs, root_body->ino, root_body->mode);
734         if (!root) {
735                 err = -ENOMEM;
736                 goto out_request;
737         }
738
739         llu_update_inode(root, root_body, NULL);
740
741         /*
742          * Generate base path-node for root.
743          */
744         rootpb = _sysio_pb_new(&noname, NULL, root);
745         if (!rootpb) {
746                 err = -ENOMEM;
747                 goto out_inode;
748         }
749
750         err = _sysio_do_mount(fs, rootpb, flags, NULL, mntp);
751         if (err) {
752                 _sysio_pb_gone(rootpb);
753                 goto out_inode;
754         }
755
756         ptlrpc_req_finished(request);
757         request = NULL;
758
759         printf("************************************************\n");
760         printf("*          Mount successfully!!!!!!!           *\n");
761         printf("************************************************\n");
762
763         return 0;
764
765 out_inode:
766         _sysio_i_gone(root);
767 out_request:
768         ptlrpc_req_finished(request);
769 out_osc:
770         obd_disconnect(&sbi->ll_osc_conn);
771 out_mdc:
772         obd_disconnect(&sbi->ll_mdc_conn);
773 out_free:
774         OBD_FREE(sbi, sizeof(*sbi));
775         return err;
776 }
777
778 struct fssw_ops llu_fssw_ops = {
779         llu_fsswop_mount
780 };
781