Whamcloud - gitweb
3ac318b6a83f577b0c370476928b35c6c4f23c35
[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-2004 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 <assert.h>
29 #include <time.h>
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <sys/fcntl.h>
33 #include <sys/queue.h>
34
35 #ifndef __CYGWIN__
36 # include <sys/statvfs.h>
37 #else
38 # include <sys/statfs.h>
39 #endif
40
41 #ifdef HAVE_XTIO_H
42 #include <xtio.h>
43 #endif
44 #include <sysio.h>
45 #include <mount.h>
46 #include <inode.h>
47 #include <fs.h>
48 #ifdef HAVE_FILE_H
49 #include <file.h>
50 #endif
51
52 #undef LIST_HEAD
53 #include "llite_lib.h"
54
55 #ifndef MAY_EXEC
56 #  define MAY_EXEC        1
57 #  define MAY_WRITE       2
58 #  define MAY_READ        4
59 #endif
60
61 #define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH)
62
63 static int ll_permission(struct inode *inode, int mask)
64 {
65         struct llu_inode_info *lli = llu_i2info(inode);
66         mode_t mode = lli->lli_st_mode;
67
68         if (current->fsuid == lli->lli_st_uid)
69                 mode >>= 6;
70         else if (in_group_p(lli->lli_st_gid))
71                 mode >>= 3;
72
73         if ((mode & mask & (MAY_READ|MAY_WRITE|MAY_EXEC)) == mask)
74                 return 0;
75
76         if ((mask & (MAY_READ|MAY_WRITE)) ||
77             (lli->lli_st_mode & S_IXUGO))
78                 if (capable(CAP_DAC_OVERRIDE))
79                         return 0;
80
81         if (mask == MAY_READ ||
82             (S_ISDIR(lli->lli_st_mode) && !(mask & MAY_WRITE))) {
83                 if (capable(CAP_DAC_READ_SEARCH))
84                         return 0;
85         }
86
87         return -EACCES;
88 }
89
90 static void llu_fsop_gone(struct filesys *fs)
91 {
92         struct llu_sb_info *sbi = (struct llu_sb_info *)fs->fs_private;
93         struct obd_device *obd = class_exp2obd(sbi->ll_md_exp);
94         struct lustre_cfg_bufs bufs;
95         struct lustre_cfg *lcfg;
96         int next = 0;
97         ENTRY;
98
99         list_del(&sbi->ll_conn_chain);
100         obd_disconnect(sbi->ll_dt_exp, 0);
101         obd_disconnect(sbi->ll_md_exp, 0);
102
103         while ((obd = class_devices_in_group(&sbi->ll_sb_uuid, &next)) != NULL)
104         {
105                 int err;
106         
107                 lustre_cfg_bufs_reset(&bufs, obd->obd_name);
108                 lcfg = lustre_cfg_new(LCFG_CLEANUP, &bufs);
109                 err = class_process_config(lcfg);
110                 if (err) {
111                         CERROR("cleanup failed: %s\n", obd->obd_name);
112                 }
113                 
114                 lcfg->lcfg_command = LCFG_DETACH; 
115                 err = class_process_config(lcfg);
116                 lustre_cfg_free(lcfg);
117                 if (err) {
118                         CERROR("detach failed: %s\n", obd->obd_name);
119                 }
120         }
121
122         obd_disconnect(sbi->ll_md_exp, 0);
123         OBD_FREE(sbi, sizeof(*sbi));
124         EXIT;
125 }
126
127 struct inode_ops llu_inode_ops;
128
129 void llu_update_inode(struct inode *inode, struct mds_body *body,
130                       struct lov_stripe_md *lsm)
131 {
132         struct llu_inode_info *lli = llu_i2info(inode);
133
134         LASSERT ((lsm != NULL) == ((body->valid & OBD_MD_FLEASIZE) != 0));
135         if (lsm != NULL) {
136                 if (lli->lli_smd == NULL) {
137                         lli->lli_smd = lsm;
138                         lli->lli_maxbytes = lsm->lsm_maxbytes;
139                         if (lli->lli_maxbytes > PAGE_CACHE_MAXBYTES)
140                                 lli->lli_maxbytes = PAGE_CACHE_MAXBYTES;
141                 } else {
142                         if (memcmp(lli->lli_smd, lsm, sizeof(*lsm))) {
143                                 CERROR("lsm mismatch for inode %ld\n",
144                                        lli->lli_st_ino);
145                                 LBUG();
146                         }
147                 }
148         }
149
150         id_assign_fid(&lli->lli_id, &body->id1);
151         
152         if ((body->valid & OBD_MD_FLID) || (body->valid & OBD_MD_FLGENER))
153                 id_assign_stc(&lli->lli_id, &body->id1);
154         if (body->valid & OBD_MD_FLID)
155                 lli->lli_st_ino = id_ino(&body->id1);
156         if (body->valid & OBD_MD_FLGENER)
157                 lli->lli_st_generation = id_gen(&body->id1);
158
159         if (body->valid & OBD_MD_FLATIME)
160                 LTIME_S(lli->lli_st_atime) = body->atime;
161         if (body->valid & OBD_MD_FLMTIME)
162                 LTIME_S(lli->lli_st_mtime) = body->mtime;
163         if (body->valid & OBD_MD_FLCTIME)
164                 LTIME_S(lli->lli_st_ctime) = body->ctime;
165         if (body->valid & OBD_MD_FLMODE)
166                 lli->lli_st_mode = (lli->lli_st_mode & S_IFMT)|(body->mode & ~S_IFMT);
167         if (body->valid & OBD_MD_FLTYPE)
168                 lli->lli_st_mode = (lli->lli_st_mode & ~S_IFMT)|(body->mode & S_IFMT);
169         if (body->valid & OBD_MD_FLUID)
170                 lli->lli_st_uid = body->uid;
171         if (body->valid & OBD_MD_FLGID)
172                 lli->lli_st_gid = body->gid;
173         if (body->valid & OBD_MD_FLFLAGS)
174                 lli->lli_st_flags = body->flags;
175         if (body->valid & OBD_MD_FLNLINK)
176                 lli->lli_st_nlink = body->nlink;
177         if (body->valid & OBD_MD_FLRDEV)
178                 lli->lli_st_rdev = body->rdev;
179         if (body->valid & OBD_MD_FLSIZE)
180                 lli->lli_st_size = body->size;
181         if (body->valid & OBD_MD_FLBLOCKS)
182                 lli->lli_st_blocks = body->blocks;
183 }
184
185 void obdo_to_inode(struct inode *dst, struct obdo *src, obd_valid valid)
186 {
187         struct llu_inode_info *lli = llu_i2info(dst);
188
189         valid &= src->o_valid;
190
191         if (valid & (OBD_MD_FLCTIME | OBD_MD_FLMTIME))
192                 CDEBUG(D_INODE, "valid "LPX64", cur time %lu/%lu, new %lu/%lu\n",
193                        src->o_valid, 
194                        LTIME_S(lli->lli_st_mtime), LTIME_S(lli->lli_st_ctime),
195                        (long)src->o_mtime, (long)src->o_ctime);
196
197         if (valid & OBD_MD_FLATIME)
198                 LTIME_S(lli->lli_st_atime) = src->o_atime;
199         if (valid & OBD_MD_FLMTIME)
200                 LTIME_S(lli->lli_st_mtime) = src->o_mtime;
201         if (valid & OBD_MD_FLCTIME && src->o_ctime > LTIME_S(lli->lli_st_ctime))
202                 LTIME_S(lli->lli_st_ctime) = src->o_ctime;
203         if (valid & OBD_MD_FLSIZE)
204                 lli->lli_st_size = src->o_size;
205         if (valid & OBD_MD_FLBLOCKS) /* allocation of space */
206                 lli->lli_st_blocks = src->o_blocks;
207         if (valid & OBD_MD_FLBLKSZ)
208                 lli->lli_st_blksize = src->o_blksize;
209         if (valid & OBD_MD_FLTYPE)
210                 lli->lli_st_mode = (lli->lli_st_mode & ~S_IFMT) | (src->o_mode & S_IFMT);
211         if (valid & OBD_MD_FLMODE)
212                 lli->lli_st_mode = (lli->lli_st_mode & S_IFMT) | (src->o_mode & ~S_IFMT);
213         if (valid & OBD_MD_FLUID)
214                 lli->lli_st_uid = src->o_uid;
215         if (valid & OBD_MD_FLGID)
216                 lli->lli_st_gid = src->o_gid;
217         if (valid & OBD_MD_FLFLAGS)
218                 lli->lli_st_flags = src->o_flags;
219         if (valid & OBD_MD_FLGENER)
220                 lli->lli_st_generation = src->o_generation;
221 }
222
223 #define S_IRWXUGO       (S_IRWXU|S_IRWXG|S_IRWXO)
224 #define S_IALLUGO       (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO)
225
226 void obdo_from_inode(struct obdo *dst, struct inode *src, obd_valid valid)
227 {
228         struct llu_inode_info *lli = llu_i2info(src);
229         obd_valid newvalid = 0;
230
231         if (valid & (OBD_MD_FLCTIME | OBD_MD_FLMTIME))
232                 CDEBUG(D_INODE, "valid "LPX64", new time %lu/%lu\n",
233                        valid, LTIME_S(lli->lli_st_mtime), 
234                        LTIME_S(lli->lli_st_ctime));
235
236         if (valid & OBD_MD_FLATIME) {
237                 dst->o_atime = LTIME_S(lli->lli_st_atime);
238                 newvalid |= OBD_MD_FLATIME;
239         }
240         if (valid & OBD_MD_FLMTIME) {
241                 dst->o_mtime = LTIME_S(lli->lli_st_mtime);
242                 newvalid |= OBD_MD_FLMTIME;
243         }
244         if (valid & OBD_MD_FLCTIME) {
245                 dst->o_ctime = LTIME_S(lli->lli_st_ctime);
246                 newvalid |= OBD_MD_FLCTIME;
247         }
248         if (valid & OBD_MD_FLSIZE) {
249                 dst->o_size = lli->lli_st_size;
250                 newvalid |= OBD_MD_FLSIZE;
251         }
252         if (valid & OBD_MD_FLBLOCKS) {  /* allocation of space (x512 bytes) */
253                 dst->o_blocks = lli->lli_st_blocks;
254                 newvalid |= OBD_MD_FLBLOCKS;
255         }
256         if (valid & OBD_MD_FLBLKSZ) {   /* optimal block size */
257                 dst->o_blksize = lli->lli_st_blksize;
258                 newvalid |= OBD_MD_FLBLKSZ;
259         }
260         if (valid & OBD_MD_FLTYPE) {
261                 dst->o_mode = (dst->o_mode & S_IALLUGO)|(lli->lli_st_mode & S_IFMT);
262                 newvalid |= OBD_MD_FLTYPE;
263         }
264         if (valid & OBD_MD_FLMODE) {
265                 dst->o_mode = (dst->o_mode & S_IFMT)|(lli->lli_st_mode & S_IALLUGO);
266                 newvalid |= OBD_MD_FLMODE;
267         }
268         if (valid & OBD_MD_FLUID) {
269                 dst->o_uid = lli->lli_st_uid;
270                 newvalid |= OBD_MD_FLUID;
271         }
272         if (valid & OBD_MD_FLGID) {
273                 dst->o_gid = lli->lli_st_gid;
274                 newvalid |= OBD_MD_FLGID;
275         }
276         if (valid & OBD_MD_FLFLAGS) {
277                 dst->o_flags = lli->lli_st_flags;
278                 newvalid |= OBD_MD_FLFLAGS;
279         }
280         if (valid & OBD_MD_FLGENER) {
281                 dst->o_generation = lli->lli_st_generation;
282                 newvalid |= OBD_MD_FLGENER;
283         }
284
285         dst->o_valid |= newvalid;
286 }
287
288 /*
289  * really does the getattr on the inode and updates its fields
290  */
291 int llu_inode_getattr(struct inode *inode, struct lov_stripe_md *lsm)
292 {
293         struct llu_inode_info *lli = llu_i2info(inode);
294         struct obd_export *exp = llu_i2dtexp(inode);
295         struct ptlrpc_request_set *set;
296         struct obdo oa;
297         obd_valid refresh_valid;
298         int rc;
299         ENTRY;
300
301         LASSERT(lsm);
302         LASSERT(lli);
303
304         memset(&oa, 0, sizeof oa);
305         oa.o_id = lsm->lsm_object_id;
306         oa.o_mode = S_IFREG;
307         oa.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLSIZE |
308                 OBD_MD_FLBLOCKS | OBD_MD_FLBLKSZ | OBD_MD_FLMTIME |
309                 OBD_MD_FLCTIME;
310
311         set = ptlrpc_prep_set();
312         if (set == NULL) {
313                 CERROR ("ENOMEM allocing request set\n");
314                 rc = -ENOMEM;
315         } else {
316                 rc = obd_getattr_async(exp, &oa, lsm, set);
317                 if (rc == 0)
318                         rc = ptlrpc_set_wait(set);
319                 ptlrpc_set_destroy(set);
320         }
321         if (rc)
322                 RETURN(rc);
323
324         refresh_valid = OBD_MD_FLBLOCKS | OBD_MD_FLBLKSZ | OBD_MD_FLMTIME | 
325                         OBD_MD_FLCTIME | OBD_MD_FLSIZE;
326
327         /* We set this flag in commit write as we extend the file size.  When
328          * the bit is set and the lock is canceled that covers the file size,
329          * we clear the bit.  This is enough to protect the window where our
330          * local size extension is needed for writeback.  However, it relies on
331          * behaviour that won't be true in the near future.  This assumes that
332          * all getattr callers get extent locks, which they currnetly do.  It
333          * also assumes that we only send discarding asts for {0,eof} truncates
334          * as is currently the case.  This will have to be replaced by the
335          * proper eoc communication between clients and the ost, which is on
336          * its way. */
337         if (test_bit(LLI_F_PREFER_EXTENDED_SIZE, &lli->lli_flags)) {
338                 if (oa.o_size < lli->lli_st_size)
339                         refresh_valid &= ~OBD_MD_FLSIZE;
340                 else 
341                         clear_bit(LLI_F_PREFER_EXTENDED_SIZE, &lli->lli_flags);
342         }
343
344         obdo_refresh_inode(inode, &oa, refresh_valid);
345
346         RETURN(0);
347 }
348
349 static struct inode *llu_new_inode(struct filesys *fs,
350                                    struct lustre_id *id)
351 {
352         struct inode *inode;
353         struct intnl_stat stat;
354         struct llu_inode_info *lli;
355
356         OBD_ALLOC(lli, sizeof(*lli));
357         if (!lli)
358                 return NULL;
359
360         /* initialize lli here */
361         lli->lli_sbi = llu_fs2sbi(fs);
362         lli->lli_smd = NULL;
363         lli->lli_symlink_name = NULL;
364         lli->lli_flags = 0;
365         lli->lli_maxbytes = (__u64)(~0UL);
366         lli->lli_file_data = NULL;
367
368         lli->lli_sysio_fid.fid_data = &lli->lli_id;
369         lli->lli_sysio_fid.fid_len = sizeof(lli->lli_id);
370
371         memcpy(&lli->lli_id, id, sizeof(*id));
372
373 #warning "fill @stat by desired attributes of new inode before using_sysio_i_new()"
374         memset(&stat, 0, sizeof(stat));
375         stat.st_ino = id_ino(id);
376         
377         /* file identifier is needed by functions like _sysio_i_find() */
378         inode = _sysio_i_new(fs, &lli->lli_sysio_fid,
379                              &stat, 0, &llu_inode_ops, lli);
380
381         if (!inode)
382                 OBD_FREE(lli, sizeof(*lli));
383
384         return inode;
385 }
386
387 static int llu_have_md_lock(struct inode *inode, __u64 lockpart)
388 {
389         struct llu_sb_info *sbi = llu_i2sbi(inode);
390         struct llu_inode_info *lli = llu_i2info(inode);
391         struct lustre_handle lockh;
392         struct ldlm_res_id res_id = { .name = {0} };
393         struct obd_device *obddev;
394         ldlm_policy_data_t policy = { .l_inodebits = { lockpart } };
395         int flags;
396         ENTRY;
397
398         LASSERT(inode);
399
400         obddev = sbi->ll_md_exp->exp_obd;
401         res_id.name[0] = id_fid(&lli->lli_id);
402         res_id.name[1] = id_group(&lli->lli_id);
403
404         CDEBUG(D_INFO, "trying to match res "LPU64"\n", res_id.name[0]);
405
406         /* FIXME use LDLM_FL_TEST_LOCK instead */
407         flags = LDLM_FL_BLOCK_GRANTED | LDLM_FL_CBPENDING;
408         if (ldlm_lock_match(obddev->obd_namespace, flags, &res_id, LDLM_IBITS,
409                             &policy, LCK_PR, &lockh)) {
410                 ldlm_lock_decref(&lockh, LCK_PR);
411                 RETURN(1);
412         }
413
414         if (ldlm_lock_match(obddev->obd_namespace, flags, &res_id, LDLM_IBITS,
415                             &policy, LCK_PW, &lockh)) {
416                 ldlm_lock_decref(&lockh, LCK_PW);
417                 RETURN(1);
418         }
419         RETURN(0);
420 }
421
422 static int llu_inode_revalidate(struct inode *inode)
423 {
424         struct llu_inode_info *lli = llu_i2info(inode);
425         struct lov_stripe_md *lsm = NULL;
426         ENTRY;
427
428         if (!inode) {
429                 CERROR("REPORT THIS LINE TO PETER\n");
430                 RETURN(0);
431         }
432
433         if (!llu_have_md_lock(inode, MDS_INODELOCK_UPDATE)) {
434                 struct lustre_md md;
435                 struct ptlrpc_request *req = NULL;
436                 struct llu_sb_info *sbi = llu_i2sbi(inode);
437                 struct lustre_id id;
438                 __u64 valid = 0;
439                 int rc, ealen = 0;
440
441                 /* Why don't we update all valid MDS fields here, if we're doing
442                  * an RPC anyways?  -phil */
443                 if (S_ISREG(lli->lli_st_mode)) {
444                         ealen = obd_size_diskmd(sbi->ll_dt_exp, NULL);
445                         valid |= OBD_MD_FLEASIZE;
446                 }
447                 ll_inode2id(&id, inode);
448
449                 /* XXX: capa is NULL here, is it correct? */
450                 rc = mdc_getattr(sbi->ll_md_exp, &id, valid, NULL, NULL,
451                                  0, ealen, NULL, &req);
452                 if (rc) {
453                         CERROR("failure %d inode %lu\n", rc, lli->lli_st_ino);
454                         RETURN(-abs(rc));
455                 }
456                 rc = mdc_req2lustre_md(sbi->ll_md_exp, req, 0, 
457                                        sbi->ll_dt_exp, &md);
458
459                 /* XXX Too paranoid? */
460                 if (((md.body->valid ^ valid) & OBD_MD_FLEASIZE) &&
461                     !((md.body->valid & OBD_MD_FLNLINK) &&
462                       (md.body->nlink == 0))) {
463                         CERROR("Asked for %s eadata but got %s (%d)\n",
464                                (valid & OBD_MD_FLEASIZE) ? "some" : "no",
465                                (md.body->valid & OBD_MD_FLEASIZE) ? "some":"none",
466                                 md.body->eadatasize);
467                 }
468                 if (rc) {
469                         ptlrpc_req_finished(req);
470                         RETURN(rc);
471                 }
472
473
474                 llu_update_inode(inode, md.body, md.lsm);
475                 if (md.lsm != NULL && llu_i2info(inode)->lli_smd != md.lsm)
476                         obd_free_memmd(sbi->ll_dt_exp, &md.lsm);
477
478                 if (md.body->valid & OBD_MD_FLSIZE)
479                         set_bit(LLI_F_HAVE_MDS_SIZE_LOCK,
480                                 &llu_i2info(inode)->lli_flags);
481                 ptlrpc_req_finished(req);
482         }
483
484         lsm = llu_i2info(inode)->lli_smd;
485         if (!lsm)       /* object not yet allocated, don't validate size */
486                 RETURN(0);
487
488         /* ll_glimpse_size will prefer locally cached writes if they extend
489          * the file */
490         RETURN(llu_glimpse_size(inode));
491 }
492
493 static void copy_stat_buf_lli(struct llu_inode_info *lli,
494                               struct intnl_stat *b)
495 {
496         b->st_dev = lli->lli_st_dev;
497         b->st_ino = lli->lli_st_ino;
498         b->st_mode = lli->lli_st_mode;
499         b->st_nlink = lli->lli_st_nlink;
500         b->st_uid = lli->lli_st_uid;
501         b->st_gid = lli->lli_st_gid;
502         b->st_rdev = lli->lli_st_rdev;
503         b->st_size = lli->lli_st_size;
504         b->st_blksize = lli->lli_st_blksize;
505         b->st_blocks = lli->lli_st_blocks;
506         b->st_atime = lli->lli_st_atime;
507         b->st_mtime = lli->lli_st_mtime;
508         b->st_ctime = lli->lli_st_ctime;
509 }
510
511 static void copy_stat_buf(struct inode *ino, struct intnl_stat *b)
512 {
513         struct llu_inode_info *lli = llu_i2info(ino);
514         copy_stat_buf_lli(lli, b);
515 }
516
517 static int llu_iop_getattr(struct pnode *pno,
518                            struct inode *ino,
519                            struct intnl_stat *b)
520 {
521         int rc;
522         ENTRY;
523
524         liblustre_wait_event(0);
525
526         if (!ino) {
527                 LASSERT(pno);
528                 LASSERT(pno->p_base->pb_ino);
529                 ino = pno->p_base->pb_ino;
530         } else {
531                 LASSERT(!pno || pno->p_base->pb_ino == ino);
532         }
533
534         /* libsysio might call us directly without intent lock,
535          * we must re-fetch the attrs here
536          */
537         rc = llu_inode_revalidate(ino);
538         if (!rc) {
539                 copy_stat_buf(ino, b);
540                 LASSERT(!llu_i2info(ino)->lli_it);
541         }
542
543         RETURN(rc);
544 }
545
546 static int null_if_equal(struct ldlm_lock *lock, void *data)
547 {
548         if (data == lock->l_ast_data) {
549                 lock->l_ast_data = NULL;
550
551                 if (lock->l_req_mode != lock->l_granted_mode)
552                         LDLM_ERROR(lock,"clearing inode with ungranted lock\n");
553         }
554
555         return LDLM_ITER_CONTINUE;
556 }
557
558 void llu_clear_inode(struct inode *inode)
559 {
560         struct lustre_id id;
561         struct llu_inode_info *lli = llu_i2info(inode);
562         struct llu_sb_info *sbi = llu_i2sbi(inode);
563         ENTRY;
564
565         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%lu(%p)\n", lli->lli_st_ino,
566                lli->lli_st_generation, inode);
567
568         ll_inode2id(&id, inode);
569         clear_bit(LLI_F_HAVE_MDS_SIZE_LOCK, &(lli->lli_flags));
570         mdc_change_cbdata(sbi->ll_md_exp, &id, null_if_equal, inode);
571
572         if (lli->lli_smd)
573                 obd_change_cbdata(sbi->ll_dt_exp, lli->lli_smd,
574                                   null_if_equal, inode);
575
576         if (lli->lli_smd) {
577                 obd_free_memmd(sbi->ll_dt_exp, &lli->lli_smd);
578                 lli->lli_smd = NULL;
579         }
580
581         if (lli->lli_symlink_name) {
582                 OBD_FREE(lli->lli_symlink_name,
583                          strlen(lli->lli_symlink_name) + 1);
584                 lli->lli_symlink_name = NULL;
585         }
586
587         EXIT;
588 }
589
590 void llu_iop_gone(struct inode *inode)
591 {
592         struct llu_inode_info *lli = llu_i2info(inode);
593         ENTRY;
594
595         liblustre_wait_event(0);
596         llu_clear_inode(inode);
597
598         OBD_FREE(lli, sizeof(*lli));
599         EXIT;
600 }
601
602 static int inode_setattr(struct inode * inode, struct iattr * attr)
603 {
604         unsigned int ia_valid = attr->ia_valid;
605         struct llu_inode_info *lli = llu_i2info(inode);
606         int error = 0;
607
608         if (ia_valid & ATTR_SIZE) {
609                 error = llu_vmtruncate(inode, attr->ia_size);
610                 if (error)
611                         goto out;
612         }
613
614         if (ia_valid & ATTR_UID)
615                 lli->lli_st_uid = attr->ia_uid;
616         if (ia_valid & ATTR_GID)
617                 lli->lli_st_gid = attr->ia_gid;
618         if (ia_valid & ATTR_ATIME)
619                 lli->lli_st_atime = attr->ia_atime;
620         if (ia_valid & ATTR_MTIME)
621                 lli->lli_st_mtime = attr->ia_mtime;
622         if (ia_valid & ATTR_CTIME)
623                 lli->lli_st_ctime = attr->ia_ctime;
624         if (ia_valid & ATTR_MODE) {
625                 lli->lli_st_mode = attr->ia_mode;
626                 if (!in_group_p(lli->lli_st_gid) && !capable(CAP_FSETID))
627                         lli->lli_st_mode &= ~S_ISGID;
628         }
629         /* mark_inode_dirty(inode); */
630 out:
631         return error;
632 }
633
634 /* If this inode has objects allocated to it (lsm != NULL), then the OST
635  * object(s) determine the file size and mtime.  Otherwise, the MDS will
636  * keep these values until such a time that objects are allocated for it.
637  * We do the MDS operations first, as it is checking permissions for us.
638  * We don't to the MDS RPC if there is nothing that we want to store there,
639  * otherwise there is no harm in updating mtime/atime on the MDS if we are
640  * going to do an RPC anyways.
641  *
642  * If we are doing a truncate, we will send the mtime and ctime updates
643  * to the OST with the punch RPC, otherwise we do an explicit setattr RPC.
644  * I don't believe it is possible to get e.g. ATTR_MTIME_SET and ATTR_SIZE
645  * at the same time.
646  */
647 int llu_setattr_raw(struct inode *inode, struct iattr *attr)
648 {
649         struct lov_stripe_md *lsm = llu_i2info(inode)->lli_smd;
650         struct llu_sb_info *sbi = llu_i2sbi(inode);
651         struct llu_inode_info *lli = llu_i2info(inode);
652         struct ptlrpc_request *request = NULL;
653         struct mdc_op_data op_data;
654         int ia_valid = attr->ia_valid;
655         int rc = 0;
656         ENTRY;
657
658         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu\n", lli->lli_st_ino);
659
660         if (ia_valid & ATTR_SIZE) {
661                 if (attr->ia_size > ll_file_maxbytes(inode)) {
662                         CDEBUG(D_INODE, "file too large %llu > "LPU64"\n",
663                                attr->ia_size, ll_file_maxbytes(inode));
664                         RETURN(-EFBIG);
665                 }
666
667                 attr->ia_valid |= ATTR_MTIME | ATTR_CTIME;
668         }
669
670         /* We mark all of the fields "set" so MDS/OST does not re-set them */
671         if (attr->ia_valid & ATTR_CTIME) {
672                 attr->ia_ctime = CURRENT_TIME;
673                 attr->ia_valid |= ATTR_CTIME_SET;
674         }
675         if (!(ia_valid & ATTR_ATIME_SET) && (attr->ia_valid & ATTR_ATIME)) {
676                 attr->ia_atime = CURRENT_TIME;
677                 attr->ia_valid |= ATTR_ATIME_SET;
678         }
679         if (!(ia_valid & ATTR_MTIME_SET) && (attr->ia_valid & ATTR_MTIME)) {
680                 attr->ia_mtime = CURRENT_TIME;
681                 attr->ia_valid |= ATTR_MTIME_SET;
682         }
683
684         if (attr->ia_valid & (ATTR_MTIME | ATTR_CTIME))
685                 CDEBUG(D_INODE, "setting mtime %lu, ctime %lu, now = %lu\n",
686                        LTIME_S(attr->ia_mtime), LTIME_S(attr->ia_ctime),
687                        LTIME_S(CURRENT_TIME));
688         if (lsm)
689                 attr->ia_valid &= ~ATTR_SIZE;
690
691         /* If only OST attributes being set on objects, don't do MDS RPC.
692          * In that case, we need to check permissions and update the local
693          * inode ourselves so we can call obdo_from_inode() always. */
694         if (ia_valid & (lsm ? ~(ATTR_SIZE | ATTR_FROM_OPEN | ATTR_RAW) : ~0)) {
695                 struct lustre_md md;
696                 llu_prepare_mdc_data(&op_data, inode, NULL, NULL, 0, 0);
697
698                 rc = mdc_setattr(sbi->ll_md_exp, &op_data,
699                                  attr, NULL, 0, NULL, 0, NULL, 0, &request);
700                 
701                 if (rc) {
702                         ptlrpc_req_finished(request);
703                         if (rc != -EPERM && rc != -EACCES)
704                                 CERROR("mdc_setattr fails: rc = %d\n", rc);
705                         RETURN(rc);
706                 }
707
708                 rc = mdc_req2lustre_md(sbi->ll_md_exp, request, 0, 
709                                        sbi->ll_dt_exp, &md);
710                 if (rc) {
711                         ptlrpc_req_finished(request);
712                         RETURN(rc);
713                 }
714
715                 /* Won't invoke vmtruncate as we already cleared ATTR_SIZE,
716                  * but needed to set timestamps backwards on utime. */
717                 inode_setattr(inode, attr);
718                 llu_update_inode(inode, md.body, md.lsm);
719                 ptlrpc_req_finished(request);
720
721                 if (!md.lsm || !S_ISREG(lli->lli_st_mode)) {
722                         CDEBUG(D_INODE, "no lsm: not setting attrs on OST\n");
723                         RETURN(0);
724                 }
725         } else {
726                 /* The OST doesn't check permissions, but the alternative is
727                  * a gratuitous RPC to the MDS.  We already rely on the client
728                  * to do read/write/truncate permission checks, so is mtime OK?
729                  */
730                 if (ia_valid & (ATTR_MTIME | ATTR_ATIME)) {
731                         /* from sys_utime() */
732                         if (!(ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET))) {
733                                 if (current->fsuid != lli->lli_st_uid &&
734                                     (rc = ll_permission(inode, MAY_WRITE)) != 0)
735                                         RETURN(rc);
736                         } else {
737                                 /* from inode_change_ok() */
738                                 if (current->fsuid != lli->lli_st_uid &&
739                                     !capable(CAP_FOWNER))
740                                         RETURN(-EPERM);
741                         }
742                 }
743
744                 /* Won't invoke vmtruncate, as we already cleared ATTR_SIZE */
745                 inode_setattr(inode, attr);
746         }
747
748         if (ia_valid & ATTR_SIZE) {
749                 ldlm_policy_data_t policy = { .l_extent = {attr->ia_size,
750                                                            OBD_OBJECT_EOF} };
751                 struct lustre_handle lockh = { 0 };
752                 int err, ast_flags = 0;
753                 /* XXX when we fix the AST intents to pass the discard-range
754                  * XXX extent, make ast_flags always LDLM_AST_DISCARD_DATA
755                  * XXX here. */
756                 if (attr->ia_size == 0)
757                         ast_flags = LDLM_AST_DISCARD_DATA;
758
759                 rc = llu_extent_lock(NULL, inode, lsm, LCK_PW, &policy,
760                                      &lockh, ast_flags);
761                 if (rc != ELDLM_OK) {
762                         if (rc > 0)
763                                 RETURN(-ENOLCK);
764                         RETURN(rc);
765                 }
766
767                 rc = llu_vmtruncate(inode, attr->ia_size);
768
769                 /* unlock now as we don't mind others file lockers racing with
770                  * the mds updates below? */
771                 err = llu_extent_unlock(NULL, inode, lsm, LCK_PW, &lockh);
772                 if (err) {
773                         CERROR("llu_extent_unlock failed: %d\n", err);
774                         if (!rc)
775                                 rc = err;
776                 }
777         } else if (ia_valid & (ATTR_MTIME | ATTR_MTIME_SET)) {
778                 struct obdo oa;
779
780                 CDEBUG(D_INODE, "set mtime on OST inode %lu to %lu\n",
781                        lli->lli_st_ino, LTIME_S(attr->ia_mtime));
782                 oa.o_id = lsm->lsm_object_id;
783                 oa.o_valid = OBD_MD_FLID;
784                 obdo_from_inode(&oa, inode, OBD_MD_FLTYPE | OBD_MD_FLATIME |
785                                             OBD_MD_FLMTIME | OBD_MD_FLCTIME);
786                 rc = obd_setattr(sbi->ll_dt_exp, &oa, lsm, NULL);
787                 if (rc)
788                         CERROR("obd_setattr fails: rc=%d\n", rc);
789         }
790         RETURN(rc);
791 }
792
793 /* here we simply act as a thin layer to glue it with
794  * llu_setattr_raw(), which is copy from kernel
795  */
796 static int llu_iop_setattr(struct pnode *pno,
797                            struct inode *ino,
798                            unsigned mask,
799                            struct intnl_stat *stbuf)
800 {
801         struct iattr iattr;
802         ENTRY;
803
804         liblustre_wait_event(0);
805
806         LASSERT(!(mask & ~(SETATTR_MTIME | SETATTR_ATIME | 
807                            SETATTR_UID | SETATTR_GID |
808                            SETATTR_LEN | SETATTR_MODE)));
809         memset(&iattr, 0, sizeof(iattr));
810
811         if (mask & SETATTR_MODE) {
812                 iattr.ia_mode = stbuf->st_mode;
813                 iattr.ia_valid |= ATTR_MODE;
814         }
815         if (mask & SETATTR_MTIME) {
816                 iattr.ia_mtime = stbuf->st_mtime;
817                 iattr.ia_valid |= ATTR_MTIME;
818         }
819         if (mask & SETATTR_ATIME) {
820                 iattr.ia_atime = stbuf->st_atime;
821                 iattr.ia_valid |= ATTR_ATIME;
822         }
823         if (mask & SETATTR_UID) {
824                 iattr.ia_uid = stbuf->st_uid;
825                 iattr.ia_valid |= ATTR_UID;
826         }
827         if (mask & SETATTR_GID) {
828                 iattr.ia_gid = stbuf->st_gid;
829                 iattr.ia_valid |= ATTR_GID;
830         }
831         if (mask & SETATTR_LEN) {
832                 iattr.ia_size = stbuf->st_size; /* XXX signed expansion problem */
833                 iattr.ia_valid |= ATTR_SIZE;
834         }
835
836         iattr.ia_valid |= ATTR_RAW;
837
838         RETURN(llu_setattr_raw(ino, &iattr));
839 }
840
841 #define EXT2_LINK_MAX           32000
842
843 static int llu_iop_symlink_raw(struct pnode *pno, const char *tgt)
844 {
845         struct inode *dir = pno->p_base->pb_parent->pb_ino;
846         struct qstr *qstr = &pno->p_base->pb_name;
847         const char *name = qstr->name;
848         int len = qstr->len;
849         struct ptlrpc_request *request = NULL;
850         struct llu_sb_info *sbi = llu_i2sbi(dir);
851         struct mdc_op_data op_data;
852         int err = -EMLINK;
853         ENTRY;
854
855         if (llu_i2info(dir)->lli_st_nlink >= EXT2_LINK_MAX)
856                 RETURN(err);
857
858         llu_prepare_mdc_data(&op_data, dir, NULL, name, len, 0);
859         err = mdc_create(sbi->ll_md_exp, &op_data,
860                          tgt, strlen(tgt) + 1, S_IFLNK | S_IRWXUGO,
861                          current->fsuid, current->fsgid, 0, &request);
862         ptlrpc_req_finished(request);
863         RETURN(err);
864 }
865
866 static int llu_readlink_internal(struct inode *inode,
867                                  struct ptlrpc_request **request,
868                                  char **symname)
869 {
870         struct llu_inode_info *lli = llu_i2info(inode);
871         struct llu_sb_info *sbi = llu_i2sbi(inode);
872         struct lustre_id id;
873         struct mds_body *body;
874         int rc, symlen = lli->lli_st_size + 1;
875         ENTRY;
876
877         *request = NULL;
878
879         if (lli->lli_symlink_name) {
880                 *symname = lli->lli_symlink_name;
881                 CDEBUG(D_INODE, "using cached symlink %s\n", *symname);
882                 RETURN(0);
883         }
884
885         ll_inode2id(&id, inode);
886
887         /* XXX: capa is NULL here, is it correct? */
888         rc = mdc_getattr(sbi->ll_md_exp, &id, OBD_MD_LINKNAME, NULL, 0,
889                          0, symlen, NULL, request);
890         if (rc) {
891                 CERROR("inode %lu: rc = %d\n", lli->lli_st_ino, rc);
892                 RETURN(rc);
893         }
894
895         body = lustre_msg_buf ((*request)->rq_repmsg, 0, sizeof (*body));
896         LASSERT (body != NULL);
897         LASSERT_REPSWABBED (*request, 0);
898
899         if ((body->valid & OBD_MD_LINKNAME) == 0) {
900                 CERROR ("OBD_MD_LINKNAME not set on reply\n");
901                 GOTO (failed, rc = -EPROTO);
902         }
903         
904         LASSERT (symlen != 0);
905         if (body->eadatasize != symlen) {
906                 CERROR ("inode %lu: symlink length %d not expected %d\n",
907                         lli->lli_st_ino, body->eadatasize - 1, symlen - 1);
908                 GOTO (failed, rc = -EPROTO);
909         }
910
911         *symname = lustre_msg_buf ((*request)->rq_repmsg, 1, symlen);
912         if (*symname == NULL ||
913             strnlen (*symname, symlen) != symlen - 1) {
914                 /* not full/NULL terminated */
915                 CERROR ("inode %lu: symlink not NULL terminated string"
916                         "of length %d\n", lli->lli_st_ino, symlen - 1);
917                 GOTO (failed, rc = -EPROTO);
918         }
919
920         OBD_ALLOC(lli->lli_symlink_name, symlen);
921         /* do not return an error if we cannot cache the symlink locally */
922         if (lli->lli_symlink_name)
923                 memcpy(lli->lli_symlink_name, *symname, symlen);
924
925         RETURN(0);
926
927  failed:
928         ptlrpc_req_finished (*request);
929         RETURN (-EPROTO);
930 }
931
932 static int llu_iop_readlink(struct pnode *pno, char *data, size_t bufsize)
933 {
934         struct inode *inode = pno->p_base->pb_ino;
935         struct ptlrpc_request *request;
936         char *symname;
937         int rc;
938         ENTRY;
939
940         rc = llu_readlink_internal(inode, &request, &symname);
941         if (rc)
942                 GOTO(out, rc);
943
944         LASSERT(symname);
945         strncpy(data, symname, bufsize);
946
947         ptlrpc_req_finished(request);
948  out:
949         RETURN(rc);
950 }
951
952 static int llu_iop_mknod_raw(struct pnode *pno,
953                              mode_t mode,
954                              dev_t dev)
955 {
956         struct ptlrpc_request *request = NULL;
957         struct inode *dir = pno->p_parent->p_base->pb_ino;
958         struct llu_sb_info *sbi = llu_i2sbi(dir);
959         struct mdc_op_data op_data;
960         int err = -EMLINK;
961         ENTRY;
962
963         CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu\n",
964                (int)pno->p_base->pb_name.len, pno->p_base->pb_name.name,
965                llu_i2info(dir)->lli_st_ino);
966
967         if (llu_i2info(dir)->lli_st_nlink >= EXT2_LINK_MAX)
968                 RETURN(err);
969
970         mode &= ~current->fs->umask;
971
972         switch (mode & S_IFMT) {
973         case 0:
974         case S_IFREG:
975                 mode |= S_IFREG; /* for mode = 0 case, fallthrough */
976         case S_IFCHR:
977         case S_IFBLK:
978         case S_IFIFO:
979         case S_IFSOCK:
980                 llu_prepare_mdc_data(&op_data, dir, NULL,
981                                      pno->p_base->pb_name.name,
982                                      pno->p_base->pb_name.len,
983                                      0);
984                 err = mdc_create(sbi->ll_md_exp, &op_data, NULL, 0, mode,
985                                  current->fsuid, current->fsgid, dev, &request);
986                 ptlrpc_req_finished(request);
987                 break;
988         case S_IFDIR:
989                 err = -EPERM;
990                 break;
991         default:
992                 err = -EINVAL;
993         }
994         RETURN(err);
995 }
996
997 static int llu_iop_link_raw(struct pnode *old, struct pnode *new)
998 {
999         struct inode *src = old->p_base->pb_ino;
1000         struct inode *dir = new->p_parent->p_base->pb_ino;
1001         const char *name = new->p_base->pb_name.name;
1002         int namelen = new->p_base->pb_name.len;
1003         struct ptlrpc_request *request = NULL;
1004         struct mdc_op_data op_data;
1005         int rc;
1006         ENTRY;
1007
1008         LASSERT(src);
1009         LASSERT(dir);
1010
1011         liblustre_wait_event(0);
1012         llu_prepare_mdc_data(&op_data, src, dir, name, namelen, 0);
1013         rc = mdc_link(llu_i2sbi(src)->ll_md_exp, &op_data, &request);
1014         ptlrpc_req_finished(request);
1015         liblustre_wait_event(0);
1016
1017         RETURN(rc);
1018 }
1019
1020 /*
1021  * libsysio will clear the inode immediately after return
1022  */
1023 static int llu_iop_unlink_raw(struct pnode *pno)
1024 {
1025         struct inode *dir = pno->p_base->pb_parent->pb_ino;
1026         struct qstr *qstr = &pno->p_base->pb_name;
1027         const char *name = qstr->name;
1028         int len = qstr->len;
1029         struct inode *target = pno->p_base->pb_ino;
1030         struct ptlrpc_request *request = NULL;
1031         struct mdc_op_data op_data;
1032         int rc;
1033         ENTRY;
1034
1035         LASSERT(target);
1036
1037         liblustre_wait_event(0);
1038         llu_prepare_mdc_data(&op_data, dir, NULL, name, len, 0);
1039         rc = mdc_unlink(llu_i2sbi(dir)->ll_md_exp, &op_data, &request);
1040         if (!rc)
1041                 rc = llu_objects_destroy(request, dir);
1042         ptlrpc_req_finished(request);
1043         liblustre_wait_event(0);
1044         RETURN(rc);
1045 }
1046
1047 static int llu_iop_rename_raw(struct pnode *old, struct pnode *new)
1048 {
1049         struct inode *src = old->p_parent->p_base->pb_ino;
1050         struct inode *tgt = new->p_parent->p_base->pb_ino;
1051         const char *oldname = old->p_base->pb_name.name;
1052         int oldnamelen = old->p_base->pb_name.len;
1053         const char *newname = new->p_base->pb_name.name;
1054         int newnamelen = new->p_base->pb_name.len;
1055         struct ptlrpc_request *request = NULL;
1056         struct mdc_op_data op_data;
1057         int rc;
1058         ENTRY;
1059
1060         LASSERT(src);
1061         LASSERT(tgt);
1062
1063         llu_prepare_mdc_data(&op_data, src, tgt, NULL, 0, 0);
1064         rc = mdc_rename(llu_i2sbi(src)->ll_md_exp, &op_data,
1065                         oldname, oldnamelen, newname, newnamelen,
1066                         &request);
1067         if (!rc) {
1068                 rc = llu_objects_destroy(request, src);
1069         }
1070
1071         ptlrpc_req_finished(request);
1072
1073         RETURN(rc);
1074 }
1075
1076 #ifdef _HAVE_STATVFS
1077 static int llu_statfs_internal(struct llu_sb_info *sbi,
1078                                struct obd_statfs *osfs,
1079                                unsigned long max_age)
1080 {
1081         struct obd_statfs obd_osfs;
1082         int rc;
1083         ENTRY;
1084
1085         rc = obd_statfs(class_exp2obd(sbi->ll_md_exp), osfs, max_age);
1086         if (rc) {
1087                 CERROR("mdc_statfs fails: rc = %d\n", rc);
1088                 RETURN(rc);
1089         }
1090
1091         CDEBUG(D_SUPER, "MDC blocks "LPU64"/"LPU64" objects "LPU64"/"LPU64"\n",
1092                osfs->os_bavail, osfs->os_blocks, osfs->os_ffree,osfs->os_files);
1093
1094         rc = obd_statfs(class_exp2obd(sbi->ll_dt_exp), &obd_osfs, max_age);
1095         if (rc) {
1096                 CERROR("obd_statfs fails: rc = %d\n", rc);
1097                 RETURN(rc);
1098         }
1099
1100         CDEBUG(D_SUPER, "OSC blocks "LPU64"/"LPU64" objects "LPU64"/"LPU64"\n",
1101                obd_osfs.os_bavail, obd_osfs.os_blocks, obd_osfs.os_ffree,
1102                obd_osfs.os_files);
1103
1104         osfs->os_blocks = obd_osfs.os_blocks;
1105         osfs->os_bfree = obd_osfs.os_bfree;
1106         osfs->os_bavail = obd_osfs.os_bavail;
1107
1108         /* If we don't have as many objects free on the OST as inodes
1109          * on the MDS, we reduce the total number of inodes to
1110          * compensate, so that the "inodes in use" number is correct.
1111          */
1112         if (obd_osfs.os_ffree < osfs->os_ffree) {
1113                 osfs->os_files = (osfs->os_files - osfs->os_ffree) +
1114                         obd_osfs.os_ffree;
1115                 osfs->os_ffree = obd_osfs.os_ffree;
1116         }
1117
1118         RETURN(rc);
1119 }
1120
1121 static int llu_statfs(struct llu_sb_info *sbi, struct statfs *sfs)
1122 {
1123         struct obd_statfs osfs;
1124         int rc;
1125
1126         CDEBUG(D_VFSTRACE, "VFS Op:\n");
1127
1128         /* For now we will always get up-to-date statfs values, but in the
1129          * future we may allow some amount of caching on the client (e.g.
1130          * from QOS or lprocfs updates). */
1131         rc = llu_statfs_internal(sbi, &osfs, jiffies - 1);
1132         if (rc)
1133                 return rc;
1134
1135         statfs_unpack(sfs, &osfs);
1136
1137         if (sizeof(sfs->f_blocks) == 4) {
1138                 while (osfs.os_blocks > ~0UL) {
1139                         sfs->f_bsize <<= 1;
1140
1141                         osfs.os_blocks >>= 1;
1142                         osfs.os_bfree >>= 1;
1143                         osfs.os_bavail >>= 1;
1144                 }
1145         }
1146
1147         sfs->f_blocks = osfs.os_blocks;
1148         sfs->f_bfree = osfs.os_bfree;
1149         sfs->f_bavail = osfs.os_bavail;
1150
1151         return 0;
1152 }
1153
1154 static int llu_iop_statvfs(struct pnode *pno,
1155                            struct inode *ino,
1156                            struct intnl_statvfs *buf)
1157 {
1158         struct statfs fs;
1159         int rc;
1160         ENTRY;
1161
1162         liblustre_wait_event(0);
1163
1164 #ifndef __CYGWIN__
1165         LASSERT(pno->p_base->pb_ino);
1166         rc = llu_statfs(llu_i2sbi(pno->p_base->pb_ino), &fs);
1167         if (rc)
1168                 RETURN(rc);
1169
1170         /* from native driver */
1171         buf->f_bsize = fs.f_bsize;  /* file system block size */
1172         buf->f_frsize = fs.f_bsize; /* file system fundamental block size */
1173         buf->f_blocks = fs.f_blocks;
1174         buf->f_bfree = fs.f_bfree;
1175         buf->f_bavail = fs.f_bavail;
1176         buf->f_files = fs.f_files;  /* Total number serial numbers */
1177         buf->f_ffree = fs.f_ffree;  /* Number free serial numbers */
1178         buf->f_favail = fs.f_ffree; /* Number free ser num for non-privileged*/
1179         buf->f_fsid = fs.f_fstc.__val[1];
1180         buf->f_flag = 0;            /* No equiv in statfs; maybe use type? */
1181         buf->f_namemax = fs.f_namelen;
1182 #endif
1183
1184         RETURN(0);
1185 }
1186 #endif /* _HAVE_STATVFS */
1187
1188 static int llu_iop_mkdir_raw(struct pnode *pno, mode_t mode)
1189 {
1190         struct inode *dir = pno->p_base->pb_parent->pb_ino;
1191         struct qstr *qstr = &pno->p_base->pb_name;
1192         const char *name = qstr->name;
1193         int len = qstr->len;
1194         struct ptlrpc_request *request = NULL;
1195         struct llu_inode_info *lli = llu_i2info(dir);
1196         struct mdc_op_data op_data;
1197         int err = -EMLINK;
1198         ENTRY;
1199         CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%lu(%p)\n",
1200                len, name, lli->lli_st_ino, lli->lli_st_generation, dir);
1201
1202         if (lli->lli_st_nlink >= EXT2_LINK_MAX)
1203                 RETURN(err);
1204
1205         mode = (mode & (S_IRWXUGO|S_ISVTX) & ~current->fs->umask) | S_IFDIR;
1206         llu_prepare_mdc_data(&op_data, dir, NULL, name, len, 0);
1207         err = mdc_create(llu_i2sbi(dir)->ll_md_exp, &op_data, NULL, 0, mode,
1208                          current->fsuid, current->fsgid, 0, &request);
1209         ptlrpc_req_finished(request);
1210         RETURN(err);
1211 }
1212
1213 static int llu_iop_rmdir_raw(struct pnode *pno)
1214 {
1215         struct inode *dir = pno->p_base->pb_parent->pb_ino;
1216         struct qstr *qstr = &pno->p_base->pb_name;
1217         const char *name = qstr->name;
1218         int len = qstr->len;
1219         struct ptlrpc_request *request = NULL;
1220         struct mdc_op_data op_data;
1221         struct llu_inode_info *lli = llu_i2info(dir);
1222         int rc;
1223         ENTRY;
1224         CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%lu(%p)\n",
1225                len, name, lli->lli_st_ino, lli->lli_st_generation, dir);
1226
1227         llu_prepare_mdc_data(&op_data, dir, NULL, name, len, S_IFDIR);
1228         rc = mdc_unlink(llu_i2sbi(dir)->ll_md_exp, &op_data, &request);
1229         ptlrpc_req_finished(request);
1230
1231         RETURN(rc);
1232 }
1233
1234 #ifdef O_DIRECT
1235 #define FCNTL_FLMASK (O_APPEND|O_NONBLOCK|O_ASYNC|O_DIRECT)
1236 #else
1237 #define FCNTL_FLMASK (O_APPEND|O_NONBLOCK|O_ASYNC)
1238 #endif
1239 #define FCNTL_FLMASK_INVALID (O_NONBLOCK|O_ASYNC)
1240
1241 static int llu_iop_fcntl(struct inode *ino, int cmd, va_list ap, int *rtn)
1242 {
1243         struct llu_inode_info *lli = llu_i2info(ino);
1244         long flags;
1245
1246         switch (cmd) {
1247         case F_GETFL:
1248                 *rtn = lli->lli_open_flags;
1249                 return 0;
1250         case F_SETFL:
1251                 flags = va_arg(ap, long);
1252                 flags &= FCNTL_FLMASK;
1253                 if (flags & FCNTL_FLMASK_INVALID) {
1254                         CERROR("liblustre don't support O_NONBLOCK, O_ASYNC, "
1255                                "and O_DIRECT on file descriptor\n");
1256                         *rtn = -1;
1257                         return EINVAL;
1258                 }
1259                 lli->lli_open_flags = (int) flags;
1260                 *rtn = 0;
1261                 return 0;
1262         }
1263
1264         CERROR("unsupported fcntl cmd %x\n", cmd);
1265         *rtn = -1;
1266         return ENOSYS;
1267 }
1268
1269 static int llu_get_grouplock(struct inode *inode, unsigned long arg)
1270 {
1271         struct llu_inode_info *lli = llu_i2info(inode);
1272         struct ll_file_data *fd = lli->lli_file_data;
1273         ldlm_policy_data_t policy = { .l_extent = { .start = 0,
1274                                                     .end = OBD_OBJECT_EOF}};
1275         struct lustre_handle lockh = { 0 };
1276         struct lov_stripe_md *lsm = lli->lli_smd;
1277         ldlm_error_t err;
1278         int flags = 0;
1279         ENTRY;
1280
1281         if (fd->fd_flags & LL_FILE_GROUP_LOCKED) {
1282                 RETURN(-EINVAL);
1283         }
1284
1285         policy.l_extent.gid = arg;
1286         if (lli->lli_open_flags & O_NONBLOCK)
1287                 flags = LDLM_FL_BLOCK_NOWAIT;
1288
1289         err = llu_extent_lock(fd, inode, lsm, LCK_GROUP, &policy, &lockh,
1290                               flags);
1291         if (err)
1292                 RETURN(err);
1293
1294         fd->fd_flags |= LL_FILE_GROUP_LOCKED|LL_FILE_IGNORE_LOCK;
1295         fd->fd_gid = arg;
1296         memcpy(&fd->fd_cwlockh, &lockh, sizeof(lockh));
1297
1298         RETURN(0);
1299 }
1300
1301 static int llu_put_grouplock(struct inode *inode, unsigned long arg)
1302 {
1303         struct llu_inode_info *lli = llu_i2info(inode);
1304         struct ll_file_data *fd = lli->lli_file_data;
1305         struct lov_stripe_md *lsm = lli->lli_smd;
1306         ldlm_error_t err;
1307         ENTRY;
1308
1309         if (!(fd->fd_flags & LL_FILE_GROUP_LOCKED))
1310                 RETURN(-EINVAL);
1311
1312         if (fd->fd_gid != arg)
1313                 RETURN(-EINVAL);
1314
1315         fd->fd_flags &= ~(LL_FILE_GROUP_LOCKED|LL_FILE_IGNORE_LOCK);
1316
1317         err = llu_extent_unlock(fd, inode, lsm, LCK_GROUP, &fd->fd_cwlockh);
1318         if (err)
1319                 RETURN(err);
1320
1321         fd->fd_gid = 0;
1322         memset(&fd->fd_cwlockh, 0, sizeof(fd->fd_cwlockh));
1323
1324         RETURN(0);
1325 }       
1326
1327 static int llu_iop_ioctl(struct inode *ino, unsigned long int request,
1328                          va_list ap)
1329 {
1330         unsigned long arg;
1331
1332         liblustre_wait_event(0);
1333
1334         switch (request) {
1335         case LL_IOC_GROUP_LOCK:
1336                 arg = va_arg(ap, unsigned long);
1337                 return llu_get_grouplock(ino, arg);
1338         case LL_IOC_GROUP_UNLOCK:
1339                 arg = va_arg(ap, unsigned long);
1340                 return llu_put_grouplock(ino, arg);
1341         }
1342
1343         CERROR("did not support ioctl cmd %lx\n", request);
1344         return -ENOSYS;
1345 }
1346
1347 /*
1348  * we already do syncronous read/write
1349  */
1350 static int llu_iop_sync(struct inode *inode)
1351 {
1352         liblustre_wait_event(0);
1353         return 0;
1354 }
1355
1356 static int llu_iop_datasync(struct inode *inode)
1357 {
1358         liblustre_wait_event(0);
1359         return 0;
1360 }
1361
1362 struct filesys_ops llu_filesys_ops =
1363 {
1364         fsop_gone: llu_fsop_gone,
1365 };
1366
1367 struct inode *llu_iget(struct filesys *fs, struct lustre_md *md)
1368 {
1369         struct inode *inode;
1370         struct lustre_id id;
1371         struct file_identifier fileid = {&id, sizeof(id)};
1372
1373         if ((md->body->valid &
1374              (OBD_MD_FLGENER | OBD_MD_FLID | OBD_MD_FLTYPE)) !=
1375             (OBD_MD_FLGENER | OBD_MD_FLID | OBD_MD_FLTYPE)) {
1376                 CERROR("bad md body valid mask 0x"LPX64"\n", 
1377                        md->body->valid);
1378                 LBUG();
1379                 return ERR_PTR(-EPERM);
1380         }
1381
1382         id = md->body->id1;
1383
1384         /* try to find existing inode */
1385         inode = _sysio_i_find(fs, &fileid);
1386         if (inode) {
1387                 struct llu_inode_info *lli = llu_i2info(inode);
1388
1389                 if (inode->i_zombie ||
1390                     lli->lli_st_generation != id_gen(&md->body->id1)) {
1391                         I_RELE(inode);
1392                 }
1393                 else {
1394                         llu_update_inode(inode, md->body, md->lsm);
1395                         return inode;
1396                 }
1397         }
1398
1399         inode = llu_new_inode(fs, &id);
1400         if (inode)
1401                 llu_update_inode(inode, md->body, md->lsm);
1402         
1403         return inode;
1404 }
1405
1406 static int
1407 llu_fsswop_mount(const char *source,
1408                  unsigned flags,
1409                  const void *data __IS_UNUSED,
1410                  struct pnode *tocover,
1411                  struct mount **mntp)
1412 {
1413         struct filesys *fs;
1414         struct inode *root;
1415         struct pnode_base *rootpb;
1416         struct obd_device *obd;
1417         struct lustre_id rootid;
1418         struct llu_sb_info *sbi;
1419         struct obd_statfs osfs;
1420         static struct qstr noname = { NULL, 0, 0 };
1421         struct ptlrpc_request *request = NULL;
1422         struct lustre_handle lmv_conn = {0, };
1423         struct lustre_handle lov_conn = {0, };
1424         struct lustre_md md;
1425         class_uuid_t uuid;
1426         struct config_llog_instance cfg;
1427         struct lustre_profile *lprof;
1428         char *lov = NULL, *lmv = NULL;
1429         int async = 1, err = -EINVAL;
1430
1431         ENTRY;
1432
1433         /* allocate & initialize sbi */
1434         OBD_ALLOC(sbi, sizeof(*sbi));
1435         if (!sbi)
1436                 RETURN(-ENOMEM);
1437
1438         INIT_LIST_HEAD(&sbi->ll_conn_chain);
1439         generate_random_uuid(uuid);
1440         class_uuid_unparse(uuid, &sbi->ll_sb_uuid);
1441
1442         /* generate a string unique to this super, let's try
1443          the address of the super itself.*/
1444         OBD_ALLOC(sbi->ll_instance, sizeof(sbi) * 2 + 1);
1445         if (sbi->ll_instance == NULL) 
1446                 GOTO(out_free, err = -ENOMEM);
1447         sprintf(sbi->ll_instance, "%p", sbi);
1448
1449         /* retrive & parse config log */
1450         cfg.cfg_instance = sbi->ll_instance;
1451         cfg.cfg_uuid = sbi->ll_sb_uuid;
1452         err = liblustre_process_log(&cfg, 1);
1453         if (err < 0) {
1454                 CERROR("Unable to process log: %s\n", g_zconf_profile);
1455                 GOTO(out_free, err);
1456         }
1457
1458         lprof = class_get_profile(g_zconf_profile);
1459         if (lprof == NULL) {
1460                 CERROR("No profile found: %s\n", g_zconf_profile);
1461                 GOTO(out_free, err = -EINVAL);
1462         }
1463         if (lov)
1464                 OBD_FREE(lov, strlen(lov) + 1);
1465         OBD_ALLOC(lov, strlen(lprof->lp_lov) + 
1466                   strlen(sbi->ll_instance) + 2);
1467         sprintf(lov, "%s-%s", lprof->lp_lov, sbi->ll_instance);
1468
1469         if (lmv)
1470                 OBD_FREE(lmv, strlen(lmv) + 1);
1471         OBD_ALLOC(lmv, strlen(lprof->lp_lmv) + 
1472                   strlen(sbi->ll_instance) + 2);
1473         sprintf(lmv, "%s-%s", lprof->lp_lmv, sbi->ll_instance);
1474
1475         if (!lov) {
1476                 CERROR("no osc\n");
1477                 GOTO(out_free, err = -EINVAL);
1478         }
1479         if (!lmv) {
1480                 CERROR("no mdc\n");
1481                 GOTO(out_free, err = -EINVAL);
1482         }
1483
1484         fs = _sysio_fs_new(&llu_filesys_ops, flags, sbi);
1485         if (!fs) {
1486                 err = -ENOMEM;
1487                 goto out_free;
1488         }
1489
1490         obd = class_name2obd(lmv);
1491         if (!obd) {
1492                 CERROR("MDC %s: not setup or attached\n", lmv);
1493                 GOTO(out_free, err = -EINVAL);
1494         }
1495         obd_set_info(obd->obd_self_export, strlen("async"), "async",
1496                      sizeof(async), &async);
1497 #if 0
1498         if (mdc_init_ea_size(obd, osc))
1499                 GOTO(out_free, err = -EINVAL);
1500 #endif
1501         /* setup mdc */
1502         err = obd_connect(&lmv_conn, obd, &sbi->ll_sb_uuid, NULL, 0);
1503         if (err) {
1504                 CERROR("cannot connect to %s: rc = %d\n", lmv, err);
1505                 GOTO(out_free, err);
1506         }
1507         sbi->ll_md_exp = class_conn2export(&lmv_conn);
1508
1509         err = obd_statfs(obd, &osfs, 100000000);
1510         if (err)
1511                 GOTO(out_lmv, err);
1512
1513         /*
1514          * FIXME fill fs stat data into sbi here!!! FIXME
1515          */
1516
1517         /* setup lov */
1518         obd = class_name2obd(lov);
1519         if (!obd) {
1520                 CERROR("OSC %s: not setup or attached\n", lov);
1521                 GOTO(out_lmv, err = -EINVAL);
1522         }
1523         obd_set_info(obd->obd_self_export, strlen("async"), "async",
1524                      sizeof(async), &async);
1525
1526         err = obd_connect(&lov_conn, obd, &sbi->ll_sb_uuid, NULL, 0);
1527         if (err) {
1528                 CERROR("cannot connect to %s: rc = %d\n", lov, err);
1529                 GOTO(out_lmv, err);
1530         }
1531         sbi->ll_dt_exp = class_conn2export(&lov_conn);
1532
1533         err = mdc_getstatus(sbi->ll_md_exp, &rootid);
1534         if (err) {
1535                 CERROR("cannot mds_connect: rc = %d\n", err);
1536                 GOTO(out_lov, err);
1537         }
1538         CDEBUG(D_SUPER, "rootid "LPU64"\n", rootid.li_stc.u.e3s.l3s_ino);
1539         sbi->ll_rootino = rootid.li_stc.u.e3s.l3s_ino;
1540
1541         /* XXX: capa is NULL here, is it correct? */
1542         err = mdc_getattr(sbi->ll_md_exp, &rootid,
1543                           (OBD_MD_FLNOTOBD | OBD_MD_FLBLOCKS), NULL, 0,
1544                           0, 0, NULL, &request);
1545         if (err) {
1546                 CERROR("mdc_getattr failed for root: rc = %d\n", err);
1547                 GOTO(out_lov, err);
1548         }
1549
1550         err = mdc_req2lustre_md(sbi->ll_md_exp, request, 0, 
1551                                 sbi->ll_dt_exp, &md);
1552         if (err) {
1553                 CERROR("failed to understand root inode md: rc = %d\n",err);
1554                 GOTO(out_request, err);
1555         }
1556
1557         LASSERT(sbi->ll_rootino != 0);
1558
1559         root = llu_iget(fs, &md);
1560         if (!root || IS_ERR(root)) {
1561                 CERROR("fail to generate root inode\n");
1562                 GOTO(out_request, err = -EBADF);
1563         }
1564
1565         /*
1566          * Generate base path-node for root.
1567          */
1568         rootpb = _sysio_pb_new(&noname, NULL, root);
1569         if (!rootpb) {
1570                 err = -ENOMEM;
1571                 goto out_inode;
1572         }
1573
1574         err = _sysio_do_mount(fs, rootpb, flags, tocover, mntp);
1575         if (err) {
1576                 _sysio_pb_gone(rootpb);
1577                 goto out_inode;
1578         }
1579
1580         ptlrpc_req_finished(request);
1581
1582         printf("LibLustre: namespace mounted successfully!\n");
1583
1584         return 0;
1585
1586 out_inode:
1587         _sysio_i_gone(root);
1588 out_request:
1589         ptlrpc_req_finished(request);
1590 out_lov:
1591         obd_disconnect(sbi->ll_dt_exp, 0);
1592 out_lmv:
1593         obd_disconnect(sbi->ll_md_exp, 0);
1594 out_free:
1595         OBD_FREE(sbi, sizeof(*sbi));
1596         return err;
1597 }
1598
1599 struct fssw_ops llu_fssw_ops = {
1600         llu_fsswop_mount
1601 };
1602
1603 struct inode_ops llu_inode_ops = {
1604         .inop_lookup         = llu_iop_lookup,
1605         .inop_getattr        = llu_iop_getattr,
1606         .inop_setattr        = llu_iop_setattr,
1607         .inop_getdirentries  = llu_iop_getdirentries,
1608         .inop_mkdir          = llu_iop_mkdir_raw,
1609         .inop_rmdir          = llu_iop_rmdir_raw,
1610         .inop_symlink        = llu_iop_symlink_raw,
1611         .inop_readlink       = llu_iop_readlink,
1612         .inop_open           = llu_iop_open,
1613         .inop_close          = llu_iop_close,
1614         .inop_link           = llu_iop_link_raw,
1615         .inop_unlink         = llu_iop_unlink_raw,
1616         .inop_rename         = llu_iop_rename_raw,
1617         .inop_iodone         = llu_iop_iodone,
1618         .inop_fcntl          = llu_iop_fcntl,
1619         .inop_sync           = llu_iop_sync,
1620         .inop_read           = llu_iop_read,
1621         .inop_write          = llu_iop_write,
1622         .inop_datasync       = llu_iop_datasync,
1623         .inop_ioctl          = llu_iop_ioctl,
1624         .inop_mknod          = llu_iop_mknod_raw,
1625 #ifdef _HAVE_STATVFS
1626         .inop_statvfs        = llu_iop_statvfs,
1627 #endif
1628         .inop_gone           = llu_iop_gone,
1629 };