Whamcloud - gitweb
Land b_hd_capa onto HEAD (20050809_1942)
[fs/lustre-release.git] / lustre / llite / namei.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
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  *  derived in small part from linux/fs/ext2/namei.c
22  *
23  *  Copyright (C) 1991, 1992  Linus Torvalds
24  *
25  *  Big-endian to little-endian byte-swapping/bitmaps by
26  *        David S. Miller (davem@caip.rutgers.edu), 1995
27  *  Directory entry file type support and forward compatibility hooks
28  *      for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998
29  */
30
31 #include <linux/fs.h>
32 #include <linux/sched.h>
33 #include <linux/mm.h>
34 #include <linux/smp_lock.h>
35 #include <linux/quotaops.h>
36 #include <linux/highmem.h>
37 #include <linux/pagemap.h>
38
39 #define DEBUG_SUBSYSTEM S_LLITE
40
41 #include <linux/obd_support.h>
42 #include <linux/lustre_lite.h>
43 #include <linux/lustre_dlm.h>
44 #include <linux/lustre_version.h>
45 #include "llite_internal.h"
46
47 /* methods */
48
49 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
50 static int ll_test_inode(struct inode *inode, unsigned long ino, void *opaque)
51 #else
52 static int ll_test_inode(struct inode *inode, void *opaque)
53 #endif
54 {
55         static int last_ino, last_gen, last_count;
56         struct lustre_md *md = opaque;
57
58         if (!(md->body->valid & (OBD_MD_FLGENER | OBD_MD_FLID))) {
59                 CERROR("MDS body missing inum or generation\n");
60                 return 0;
61         }
62
63         if (last_ino == id_ino(&md->body->id1) &&
64             last_gen == id_gen(&md->body->id1) &&
65             last_count < 500) {
66                 last_count++;
67         } else {
68                 if (last_count > 1)
69                         CDEBUG(D_VFSTRACE, "compared %u/%u %u times\n",
70                                last_ino, last_gen, last_count);
71                 last_count = 0;
72                 last_ino = id_ino(&md->body->id1);
73                 last_gen = id_gen(&md->body->id1);
74                 CDEBUG(D_VFSTRACE,
75                        "comparing inode %p ino "DLID4" to body "DLID4"\n",
76                        inode, OLID4(&ll_i2info(inode)->lli_id),
77                        OLID4(&md->body->id1));
78         }
79
80 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
81         if (inode->i_ino != id_ino(&md->body->id1))
82                 return 0;
83 #endif
84         if (inode->i_generation != id_gen(&md->body->id1))
85                 return 0;
86
87         if (id_group(&ll_i2info(inode)->lli_id) != id_group(&md->body->id1))
88                 return 0;
89         
90         /* apply the attributes in 'opaque' to this inode. */
91         ll_update_inode(inode, md);
92         return 1;
93 }
94
95 extern struct dentry_operations ll_d_ops;
96
97 int ll_unlock(__u32 mode, struct lustre_handle *lockh)
98 {
99         ENTRY;
100
101         ldlm_lock_decref(lockh, mode);
102
103         RETURN(0);
104 }
105
106 /*
107  * get an inode by inode number (already instantiated by the intent lookup).
108  * Returns inode or NULL.
109  */
110 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
111 int ll_set_inode(struct inode *inode, void *opaque)
112 {
113         ll_read_inode2(inode, opaque);
114         return 0;
115 }
116
117 struct inode *ll_iget(struct super_block *sb, ino_t hash,
118                       struct lustre_md *md)
119 {
120         struct inode *inode;
121
122         LASSERT(hash != 0);
123         inode = iget5_locked(sb, hash, ll_test_inode, ll_set_inode, md);
124
125         if (inode) {
126                 if (inode->i_state & I_NEW)
127                         unlock_new_inode(inode);
128                 CDEBUG(D_VFSTRACE, "inode: %lu/%u(%p)\n", inode->i_ino,
129                        inode->i_generation, inode);
130         }
131
132         return inode;
133 }
134 #else
135 struct inode *ll_iget(struct super_block *sb, ino_t hash,
136                       struct lustre_md *md)
137 {
138         struct inode *inode;
139         LASSERT(hash != 0);
140         inode = iget4(sb, hash, ll_test_inode, md);
141         if (inode)
142                 CDEBUG(D_VFSTRACE, "inode: %lu/%u(%p)\n", inode->i_ino,
143                        inode->i_generation, inode);
144         return inode;
145 }
146 #endif
147
148 int ll_mdc_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
149                         void *data, int flag)
150 {
151         int rc;
152         struct lustre_handle lockh;
153         ENTRY;
154
155         switch (flag) {
156         case LDLM_CB_BLOCKING:
157                 ldlm_lock2handle(lock, &lockh);
158                 rc = ldlm_cli_cancel(&lockh);
159                 if (rc < 0) {
160                         CDEBUG(D_INODE, "ldlm_cli_cancel: %d\n", rc);
161                         RETURN(rc);
162                 }
163                 break;
164         case LDLM_CB_CANCELING: {
165                 struct inode *inode = ll_inode_from_lock(lock);
166                 struct ll_inode_info *li = ll_i2info(inode);
167                 __u64 bits = lock->l_policy_data.l_inodebits.bits;
168
169                 /* For lookup locks: Invalidate all dentries associated with
170                    this inode, for UPDATE locks - invalidate directory pages */
171                 if (inode == NULL)
172                         break;
173
174                 if (lock->l_resource->lr_name.name[0] != id_fid(&li->lli_id) ||
175                     lock->l_resource->lr_name.name[1] != id_group(&li->lli_id)) {
176                         LDLM_ERROR(lock, "data mismatch with object %lu/%lu",
177                                    (unsigned long)id_fid(&li->lli_id),
178                                    (unsigned long)id_group(&li->lli_id));
179                 }
180
181                 if (bits & MDS_INODELOCK_OPEN) {
182                         int flags = 0;
183                         switch (lock->l_req_mode) {
184                         case LCK_CW:
185                                 flags = FMODE_WRITE;
186                                 break;
187                         case LCK_PR:
188                                 flags = FMODE_EXEC;
189                                 break;
190                         case LCK_CR:
191                                 flags = FMODE_READ;
192                                 break;
193                         default:
194                                 CERROR("Unexpected lock mode for OPEN lock "
195                                        "%d, inode %ld\n", lock->l_req_mode,
196                                        inode->i_ino);
197                         }
198                         ll_md_real_close(ll_i2mdexp(inode), inode, flags);
199                 }
200
201                 if ((bits & MDS_INODELOCK_UPDATE) && LLI_HAVE_FLSIZE(inode)) {
202                         CDEBUG(D_OTHER, "isize for %lu/%u(%p) from mds "
203                                "is not actual\n", inode->i_ino,
204                                inode->i_generation, inode);
205                         clear_bit(LLI_F_HAVE_MDS_SIZE_LOCK,
206                                   &(ll_i2info(inode)->lli_flags));
207                 }
208
209
210                 /* If lookup lock is cancelled, we just drop the dentry and
211                    this will cause us to reget data from MDS when we'd want to
212                    access this dentry/inode again. If this is lock on
213                    other parts of inode that is cancelled, we do not need to do
214                    much (but need to discard data from readdir, if any), since
215                    abscence of lock will cause ll_revalidate_it (called from
216                    stat() and similar functions) to renew the data anyway */
217                 if (S_ISDIR(inode->i_mode) &&
218                     (bits & MDS_INODELOCK_UPDATE)) {
219                         CDEBUG(D_INODE, "invalidating inode %lu/%u(%p)\n",
220                                inode->i_ino, inode->i_generation, inode);
221                         truncate_inode_pages(inode->i_mapping, 0);
222                 }
223
224                 ll_inode_invalidate_acl(inode);
225
226                 if (inode->i_sb->s_root &&
227                     inode != inode->i_sb->s_root->d_inode &&
228                     (bits & MDS_INODELOCK_LOOKUP))
229                         ll_unhash_aliases(inode);
230                 iput(inode);
231                 break;
232         }
233         default:
234                 LBUG();
235         }
236
237         RETURN(0);
238 }
239
240 /* Search "inode"'s alias list for a dentry that has the same name and parent as
241  * de.  If found, return it.  If not found, return de. */
242 struct dentry *ll_find_alias(struct inode *inode, struct dentry *de)
243 {
244         struct list_head *tmp;
245
246         spin_lock(&dcache_lock);
247         list_for_each(tmp, &inode->i_dentry) {
248                 struct dentry *dentry = list_entry(tmp, struct dentry, d_alias);
249
250                 /* We are called here with 'de' already on the aliases list. */
251                 if (dentry == de) {
252                         CERROR("whoops\n");
253                         continue;
254                 }
255
256                 if (dentry->d_parent != de->d_parent)
257                         continue;
258
259                 if (dentry->d_name.len != de->d_name.len)
260                         continue;
261
262                 if (memcmp(dentry->d_name.name, de->d_name.name,
263                            de->d_name.len) != 0)
264                         continue;
265
266                 if (!list_empty(&dentry->d_lru))
267                         list_del_init(&dentry->d_lru);
268
269                 hlist_del_init(&dentry->d_hash);
270                 __d_rehash(dentry); /* avoid taking dcache_lock inside */
271                 spin_unlock(&dcache_lock);
272                 atomic_inc(&dentry->d_count);
273                 iput(inode);
274                 dentry->d_flags &= ~DCACHE_LUSTRE_INVALID;
275                 CDEBUG(D_DENTRY, "alias dentry %*s (%p) parent %p inode %p "
276                        "refc %d\n", de->d_name.len, de->d_name.name, de,
277                        de->d_parent, de->d_inode, atomic_read(&de->d_count));
278                 return dentry;
279         }
280
281         spin_unlock(&dcache_lock);
282
283         return de;
284 }
285
286 static int lookup_it_finish(struct ptlrpc_request *request, int offset,
287                             struct lookup_intent *it, void *data)
288 {
289         struct it_cb_data *icbd = data;
290         struct dentry **de = icbd->icbd_childp;
291         struct inode *parent = icbd->icbd_parent;
292         struct ll_sb_info *sbi = ll_i2sbi(parent);
293         struct dentry *dentry = *de, *saved = *de;
294         struct inode *inode = NULL;
295         int rc;
296
297         /* NB 1 request reference will be taken away by ll_intent_lock()
298          * when I return */
299         if (!it_disposition(it, DISP_LOOKUP_NEG)) {
300                 ENTRY;
301
302                 rc = ll_prep_inode(sbi->ll_dt_exp, sbi->ll_md_exp,
303                                    &inode, request, offset, dentry->d_sb);
304                 if (rc)
305                         RETURN(rc);
306
307                 CDEBUG(D_DLMTRACE, "setting l_data to inode %p (%lu/%u)\n",
308                        inode, inode->i_ino, inode->i_generation);
309                 
310                 mdc_set_lock_data(NULL, &LUSTRE_IT(it)->it_lock_handle, inode);
311                 
312                 /* If this is a stat, get the authoritative file size */
313                 if (it->it_op == IT_GETATTR && S_ISREG(inode->i_mode) &&
314                     ll_i2info(inode)->lli_smd != NULL) {
315                         struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd;
316                         ldlm_error_t rc;
317
318                         LASSERT(lsm->lsm_object_id != 0);
319
320                         /* bug 2334: drop MDS lock before acquiring OST lock */
321                         ll_intent_drop_lock(it);
322
323                         if (!LLI_HAVE_FLSIZE(inode)) {
324                                 CDEBUG(D_INODE, "retrieve size from OSS\n");
325                                 rc = ll_glimpse_size(inode);
326                                 if (rc) {
327                                         iput(inode);
328                                         RETURN(rc);
329                                 }
330                         }
331                 }
332
333                 dentry = *de = ll_find_alias(inode, dentry);
334         } else {
335                 ENTRY;
336         }
337
338         dentry->d_op = &ll_d_ops;
339         ll_set_dd(dentry);
340
341         if (dentry == saved)
342                 d_add(dentry, inode);
343
344         RETURN(0);
345 }
346
347 static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry,
348                                    struct nameidata *nd, int flags)
349 {
350         struct lookup_intent *it = flags ? &nd->intent.open : NULL;
351         struct lookup_intent lookup_it = { .it_op = IT_LOOKUP };
352         struct dentry *save = dentry, *retval;
353         struct ptlrpc_request *req = NULL;
354         int rc, gns_it, gns_flags;
355         struct it_cb_data icbd;
356         struct lustre_id pid;
357         ENTRY;
358
359         if (dentry->d_name.len > EXT3_NAME_LEN)
360                 RETURN(ERR_PTR(-ENAMETOOLONG));
361
362         CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p),intent=%s\n",
363                dentry->d_name.len, dentry->d_name.name, parent->i_ino,
364                parent->i_generation, parent, LL_IT2STR(it));
365
366         if (d_mountpoint(dentry))
367                 CERROR("Tell Peter, lookup on mtpt, it %s\n", LL_IT2STR(it));
368
369         if (nd != NULL)
370                 nd->mnt->mnt_last_used = jiffies;
371
372         gns_it = nd ? nd->intent.open.it_op : IT_OPEN;
373         gns_flags = nd ? nd->flags : LOOKUP_CONTINUE;
374         ll_frob_intent(&it, &lookup_it);
375
376         icbd.icbd_childp = &dentry;
377         icbd.icbd_parent = parent;
378         ll_inode2id(&pid, parent);
379
380         /*ONLY need key for open_create file*/
381         rc = ll_crypto_init_it_key(parent, it);
382         if (rc != 0) 
383                 GOTO(out, retval = ERR_PTR(rc)); 
384         
385         rc = md_intent_lock(ll_i2mdexp(parent), &pid,
386                             (char *)dentry->d_name.name, dentry->d_name.len,
387                             NULL, 0, NULL, it, flags, &req,
388                             ll_mdc_blocking_ast);
389         if (rc < 0)
390                 GOTO(out, retval = ERR_PTR(rc));
391
392         rc = lookup_it_finish(req, 1, it, &icbd);
393         if (rc != 0) {
394                 ll_intent_release(it);
395                 GOTO(out, retval = ERR_PTR(rc));
396         }
397
398         ll_lookup_finish_locks(it, dentry);
399
400         if (nd && dentry->d_inode != NULL &&
401             dentry->d_inode->i_mode & S_ISUID && S_ISDIR(dentry->d_inode->i_mode) &&
402             ((gns_flags & LOOKUP_CONTINUE) || (gns_it & (IT_CHDIR | IT_OPEN))))
403         {
404                 CDEBUG(D_DENTRY, "possible GNS dentry %*s %p found, "
405                        "mounting it\n", (int)dentry->d_name.len,
406                        dentry->d_name.name, dentry);
407                 
408                 rc = ll_gns_mount_object(dentry, nd->mnt);
409                 if (rc) {
410                         /* 
411                          * just reporting about GNS failures, lookup() is
412                          * successful, do not stop it.
413                          *
414                          * GNS failure may be that object is found in SUID bit
415                          * marked dir but it is not regular file and we should
416                          * lookup further until we find correct mount
417                          * object. This will allow to perform GNS mount is the
418                          * following case for instance:
419                          *
420                          * /mnt/lustre/gns_mount/.mntinfo/.mntinfo/..../.mntinfo
421                          * where all ".mntinfo" are dirs and only last one is
422                          * reg file.
423                          */
424                         CDEBUG(D_DENTRY, "failed to mount %*s, err %d\n",
425                                (int)dentry->d_name.len, dentry->d_name.name, rc);
426                 }
427         }
428         
429         if (dentry == save)
430                 GOTO(out, retval = NULL);
431         else
432                 GOTO(out, retval = dentry);
433  out:
434         if (req)
435                 ptlrpc_req_finished(req);
436         if (it == &lookup_it)
437                 ll_intent_release(it);
438         if (dentry->d_inode)
439                 CDEBUG(D_INODE, "lookup 0x%p in %lu/%lu: %*s -> %lu/%lu\n",
440                        dentry,
441                        (unsigned long) parent->i_ino,
442                        (unsigned long) parent->i_generation,
443                        dentry->d_name.len, dentry->d_name.name,
444                        (unsigned long) dentry->d_inode->i_ino,
445                        (unsigned long) dentry->d_inode->i_generation);
446         else
447                 CDEBUG(D_INODE, "lookup 0x%p in %lu/%lu: %*s -> ??\n",
448                        dentry,
449                        (unsigned long) parent->i_ino,
450                        (unsigned long) parent->i_generation,
451                        dentry->d_name.len, dentry->d_name.name);
452         return retval;
453 }
454
455 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
456 static struct dentry *ll_lookup_nd(struct inode *parent, struct dentry *dentry,
457                                    struct nameidata *nd)
458 {
459         struct dentry *de;
460         ENTRY;
461
462         if (nd && nd->flags & LOOKUP_LAST && !(nd->flags & LOOKUP_LINK_NOTLAST))
463                 de = ll_lookup_it(parent, dentry, nd, nd->flags);
464         else
465                 de = ll_lookup_it(parent, dentry, nd, 0);
466
467         RETURN(de);
468 }
469 #endif
470
471 /* We depend on "mode" being set with the proper file type/umask by now */
472 static struct inode *ll_create_node(struct inode *dir, const char *name,
473                                     int namelen, const void *data, int datalen,
474                                     int mode, __u64 extra,
475                                     struct lookup_intent *it)
476 {
477         struct inode *inode = NULL;
478         struct ptlrpc_request *request = NULL;
479         struct ll_sb_info *sbi = ll_i2sbi(dir);
480         int rc;
481         ENTRY;
482
483
484         LASSERT(it && LUSTRE_IT(it)->it_disposition);
485   
486         request = LUSTRE_IT(it)->it_data;
487         rc = ll_prep_inode(sbi->ll_dt_exp, sbi->ll_md_exp,
488                            &inode, request, 1, dir->i_sb);
489         if (rc)
490                 GOTO(out, inode = ERR_PTR(rc));
491
492         LASSERT(list_empty(&inode->i_dentry));
493
494         /* We asked for a lock on the directory, but were granted a
495          * lock on the inode.  Since we finally have an inode pointer,
496          * stuff it in the lock. */
497         CDEBUG(D_DLMTRACE, "setting l_ast_data to inode %p (%lu/%u)\n",
498                inode, inode->i_ino, inode->i_generation);
499         mdc_set_lock_data(NULL, &LUSTRE_IT(it)->it_lock_handle, inode);
500         EXIT;
501  out:
502         ptlrpc_req_finished(request);
503         return inode;
504 }
505
506 /*
507  * By the time this is called, we already have created the directory cache
508  * entry for the new file, but it is so far negative - it has no inode.
509  *
510  * We defer creating the OBD object(s) until open, to keep the intent and
511  * non-intent code paths similar, and also because we do not have the MDS
512  * inode number before calling ll_create_node() (which is needed for LOV),
513  * so we would need to do yet another RPC to the MDS to store the LOV EA
514  * data on the MDS.  If needed, we would pass the PACKED lmm as data and
515  * lmm_size in datalen (the MDS still has code which will handle that).
516  *
517  * If the create succeeds, we fill in the inode information
518  * with d_instantiate().
519  */
520 static int ll_create_it(struct inode *dir, struct dentry *dentry, int mode,
521                         struct lookup_intent *it)
522 {
523         struct inode *inode;
524         struct ptlrpc_request *request = LUSTRE_IT(it)->it_data;
525         struct obd_export *md_exp = ll_i2mdexp(dir); 
526         int rc = 0;
527         ENTRY;
528
529         CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p),intent=%s\n",
530                dentry->d_name.len, dentry->d_name.name, dir->i_ino,
531                dir->i_generation, dir, LL_IT2STR(it));
532
533         rc = it_open_error(DISP_OPEN_CREATE, it);
534         if (rc)
535                 RETURN(rc);
536
537         mdc_store_inode_generation(md_exp, request, MDS_REQ_INTENT_REC_OFF, 1);
538         inode = ll_create_node(dir, (char *)dentry->d_name.name,
539                                dentry->d_name.len, NULL, 0, mode, 0, it);
540         if (IS_ERR(inode))
541                 RETURN(PTR_ERR(inode));
542
543         d_instantiate(dentry, inode);
544         RETURN(0);
545 }
546
547 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
548 static int ll_create_nd(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
549 {
550         return ll_create_it(dir, dentry, mode, &nd->intent.open);
551 }
552 #endif
553
554 static void ll_update_times(struct ptlrpc_request *request, int offset,
555                             struct inode *inode)
556 {
557         struct mds_body *body = lustre_msg_buf(request->rq_repmsg, offset,
558                                                sizeof(*body));
559         LASSERT(body);
560
561         if (body->valid & OBD_MD_FLMTIME &&
562             body->mtime > LTIME_S(inode->i_mtime)) {
563                 CDEBUG(D_INODE, "setting ino %lu mtime from %lu to %u\n",
564                        inode->i_ino, LTIME_S(inode->i_mtime), body->mtime);
565                 LTIME_S(inode->i_mtime) = body->mtime;
566         }
567         if (body->valid & OBD_MD_FLCTIME &&
568             body->ctime > LTIME_S(inode->i_ctime))
569                 LTIME_S(inode->i_ctime) = body->ctime;
570 }
571
572 static int ll_mknod_raw(struct nameidata *nd, int mode, dev_t rdev)
573 {
574         struct ptlrpc_request *request = NULL;
575         struct inode *dir = nd->dentry->d_inode;
576         struct ll_sb_info *sbi = ll_i2sbi(dir);
577         struct mdc_op_data *op_data;
578         int err = -EMLINK, key_size = 0;
579         void *key = NULL;
580         ENTRY;
581
582         CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n",
583                nd->last.len, nd->last.name, dir->i_ino,
584                dir->i_generation, dir);
585
586         mode &= ~current->fs->umask;
587
588         switch (mode & S_IFMT) {
589         case 0:
590         case S_IFREG: 
591                 mode |= S_IFREG; /* for mode = 0 case, fallthrough */
592                 ll_crypto_create_key(dir, mode, &key, &key_size);
593         case S_IFCHR:
594         case S_IFBLK:
595         case S_IFIFO:
596         case S_IFSOCK:
597                 OBD_ALLOC(op_data, sizeof(*op_data));
598                 if (op_data == NULL)
599                         RETURN(-ENOMEM);
600                 ll_prepare_mdc_data(op_data, dir, NULL,
601                                     (char *)nd->last.name, 
602                                     nd->last.len, 0);
603                 err = md_create(sbi->ll_md_exp, op_data, key, key_size, mode,
604                                 current->fsuid, current->fsgid, rdev,
605                                 &request);
606                 OBD_FREE(op_data, sizeof(*op_data));
607                 if (err == 0)
608                         ll_update_times(request, 0, dir);
609                 ptlrpc_req_finished(request);
610                 break;
611         case S_IFDIR:
612                 err = -EPERM;
613                 break;
614         default:
615                 err = -EINVAL;
616         }
617         if (key && key_size)
618                 OBD_FREE(key, key_size);
619         RETURN(err);
620 }
621
622 static int ll_mknod(struct inode *dir, struct dentry *dchild,
623                     int mode, ll_dev_t rdev)
624 {
625         struct ptlrpc_request *request = NULL;
626         struct inode *inode = NULL;
627         struct ll_sb_info *sbi = ll_i2sbi(dir);
628         struct mdc_op_data *op_data;
629         int err = -EMLINK;
630         ENTRY;
631
632         CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n",
633                dchild->d_name.len, dchild->d_name.name,
634                dir->i_ino, dir->i_generation, dir);
635
636         mode &= ~current->fs->umask;
637
638         switch (mode & S_IFMT) {
639         case 0:
640         case S_IFREG:
641                 mode |= S_IFREG; /* for mode = 0 case, fallthrough */
642                 
643         case S_IFCHR:
644         case S_IFBLK:
645         case S_IFIFO:
646         case S_IFSOCK:
647                 OBD_ALLOC(op_data, sizeof(*op_data));
648                 if (op_data == NULL)
649                         RETURN(-ENOMEM);
650
651                 ll_prepare_mdc_data(op_data, dir, NULL,
652                                     (char *)dchild->d_name.name, 
653                                     dchild->d_name.len, 0);
654                 
655                 err = md_create(sbi->ll_md_exp, op_data, NULL, 0, mode,
656                                 current->fsuid, current->fsgid, rdev,
657                                 &request);
658                 OBD_FREE(op_data, sizeof(*op_data));
659                 if (err)
660                         GOTO(out_err, err);
661
662                 ll_update_times(request, 0, dir);
663                 err = ll_prep_inode(sbi->ll_dt_exp, sbi->ll_md_exp,
664                                     &inode, request, 0, dchild->d_sb);
665                 if (err)
666                         GOTO(out_err, err);
667                 break;
668         case S_IFDIR:
669                 RETURN(-EPERM);
670                 break;
671         default:
672                 RETURN(-EINVAL);
673         }
674
675         d_instantiate(dchild, inode);
676         EXIT;
677  out_err:
678         ptlrpc_req_finished(request);
679         return err;
680 }
681
682 static int ll_symlink_raw(struct nameidata *nd, const char *tgt)
683 {
684         const char *name = (char *)nd->last.name;
685         struct inode *dir = nd->dentry->d_inode;
686         struct ptlrpc_request *request = NULL;
687         struct ll_sb_info *sbi = ll_i2sbi(dir);
688         struct mdc_op_data *op_data;
689         int len = nd->last.len;
690         int err = -EMLINK;
691         ENTRY;
692
693         CDEBUG(D_VFSTRACE, "VFS Op:name=%*s,dir=%lu/%u(%p),target=%s\n",
694                nd->last.len, nd->last.name, dir->i_ino, dir->i_generation,
695                dir, tgt);
696
697         if (dir->i_nlink >= EXT3_LINK_MAX)
698                 RETURN(err);
699
700         OBD_ALLOC(op_data, sizeof(*op_data));
701         if (op_data == NULL)
702                 RETURN(-ENOMEM);
703         ll_prepare_mdc_data(op_data, dir, NULL, name, len, 0);
704         LASSERT(tgt);
705         err = md_create(sbi->ll_md_exp, op_data,
706                         tgt, strlen(tgt) + 1, S_IFLNK | S_IRWXUGO,
707                         current->fsuid, current->fsgid, 0, &request);
708         OBD_FREE(op_data, sizeof(*op_data));
709         if (err == 0)
710                 ll_update_times(request, 0, dir);
711         
712         ptlrpc_req_finished(request);
713         RETURN(err);
714 }
715
716 static int ll_link_raw(struct nameidata *srcnd, struct nameidata *tgtnd)
717 {
718         struct inode *src = srcnd->dentry->d_inode;
719         struct inode *dir = tgtnd->dentry->d_inode;
720         struct ptlrpc_request *request = NULL;
721         struct ll_sb_info *sbi = ll_i2sbi(dir);
722         struct mdc_op_data *op_data;
723         int err;
724         ENTRY;
725
726         CDEBUG(D_VFSTRACE,
727                "VFS Op: inode=%lu/%u(%p), dir=%lu/%u(%p), target=%.*s\n",
728                src->i_ino, src->i_generation, src, dir->i_ino,
729                dir->i_generation, dir, tgtnd->last.len, tgtnd->last.name);
730
731         OBD_ALLOC(op_data, sizeof(*op_data));
732         if (op_data == NULL)
733                 RETURN(-ENOMEM);
734
735         ll_prepare_mdc_data(op_data, src, dir,
736                             (char *)tgtnd->last.name, 
737                             tgtnd->last.len, 0);
738         
739         err = md_link(sbi->ll_md_exp, op_data, &request);
740         OBD_FREE(op_data, sizeof(*op_data));
741         if (err == 0)
742                 ll_update_times(request, 0, dir);
743         ptlrpc_req_finished(request);
744         RETURN(err);
745 }
746
747
748 static int ll_mkdir_raw(struct nameidata *nd, int mode)
749 {
750         struct inode *dir = nd->dentry->d_inode;
751         struct ptlrpc_request *request = NULL;
752         struct ll_sb_info *sbi = ll_i2sbi(dir);
753         struct mdc_op_data *op_data;
754         int err = -EMLINK;
755         ENTRY;
756         CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n",
757                nd->last.len, nd->last.name, dir->i_ino, dir->i_generation, dir);
758
759         mode = (mode & (S_IRWXUGO|S_ISVTX) & ~current->fs->umask) | S_IFDIR;
760         OBD_ALLOC(op_data, sizeof(*op_data));
761         if (op_data == NULL)
762                 RETURN(-ENOMEM);
763
764         ll_prepare_mdc_data(op_data, dir, NULL,
765                             (char *)nd->last.name, 
766                             nd->last.len, 0);
767         
768         err = md_create(sbi->ll_md_exp, op_data, NULL, 0, mode,
769                         current->fsuid, current->fsgid, 0, &request);
770         OBD_FREE(op_data, sizeof(*op_data));
771         if (err == 0)
772                 ll_update_times(request, 0, dir);
773         ptlrpc_req_finished(request);
774         RETURN(err);
775 }
776
777 static int ll_rmdir_raw(struct nameidata *nd)
778 {
779         struct inode *dir = nd->dentry->d_inode;
780         struct ptlrpc_request *request = NULL;
781         struct mdc_op_data *op_data;
782         int rc;
783
784         ENTRY;
785         CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n",
786                nd->last.len, nd->last.name, dir->i_ino,
787                dir->i_generation, dir);
788
789         OBD_ALLOC(op_data, sizeof(*op_data));
790         if (op_data == NULL)
791                 RETURN(-ENOMEM);
792
793         ll_prepare_mdc_data(op_data, dir, NULL,
794                             (char *)nd->last.name, 
795                             nd->last.len, S_IFDIR);
796         
797         rc = md_unlink(ll_i2sbi(dir)->ll_md_exp, op_data, &request);
798         OBD_FREE(op_data, sizeof(*op_data));
799         if (rc == 0)
800                 ll_update_times(request, 0, dir);
801         ptlrpc_req_finished(request);
802         RETURN(rc);
803 }
804
805 static int ll_unlink_raw(struct nameidata *nd)
806 {
807         struct inode *dir = nd->dentry->d_inode;
808         struct ptlrpc_request *request = NULL;
809         struct mdc_op_data *op_data;
810         int rc;
811         ENTRY;
812         CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n",
813                nd->last.len, nd->last.name, dir->i_ino,
814                dir->i_generation, dir);
815
816         OBD_ALLOC(op_data, sizeof(*op_data));
817         if (op_data == NULL)
818                 RETURN(-ENOMEM);
819         ll_prepare_mdc_data(op_data, dir, NULL,
820                             (char *)nd->last.name, nd->last.len, 0);
821         rc = md_unlink(ll_i2sbi(dir)->ll_md_exp, op_data, &request);
822         OBD_FREE(op_data, sizeof(*op_data));
823         if (rc)
824                 GOTO(out, rc);
825         ll_update_times(request, 0, dir);
826         EXIT;
827 out:
828         ptlrpc_req_finished(request);
829         return rc;
830 }
831
832 static int ll_rename_raw(struct nameidata *srcnd, struct nameidata *tgtnd)
833 {
834         struct inode *src = srcnd->dentry->d_inode;
835         struct inode *tgt = tgtnd->dentry->d_inode;
836         struct ptlrpc_request *request = NULL;
837         struct ll_sb_info *sbi = ll_i2sbi(src);
838         struct mdc_op_data *op_data;
839         int err;
840         ENTRY;
841         
842         if (srcnd->mnt != tgtnd->mnt)
843                 RETURN(-EXDEV);
844
845         CDEBUG(D_VFSTRACE,"VFS Op:oldname=%.*s,src_dir=%lu/%u(%p),newname=%.*s,"
846                "tgt_dir=%lu/%u(%p)\n", srcnd->last.len, srcnd->last.name,
847                src->i_ino, src->i_generation, src, tgtnd->last.len,
848                tgtnd->last.name, tgt->i_ino, tgt->i_generation, tgt);
849
850         OBD_ALLOC(op_data, sizeof(*op_data));
851         if (op_data == NULL)
852                 RETURN(-ENOMEM);
853         ll_prepare_mdc_data(op_data, src, tgt, NULL, 0, 0);
854         err = md_rename(sbi->ll_md_exp, op_data, (char *)srcnd->last.name, 
855                         srcnd->last.len, (char *)tgtnd->last.name,
856                         tgtnd->last.len, &request);
857         OBD_FREE(op_data, sizeof(*op_data));
858         if (!err) {
859                 ll_update_times(request, 0, src);
860                 ll_update_times(request, 0, tgt);
861         }
862
863         ptlrpc_req_finished(request);
864         RETURN(err);
865 }
866
867 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
868 #define LLITE_IT_RAWOPS (IT_MKNOD|IT_MKDIR|IT_SYMLINK|IT_LINK|IT_UNLINK|IT_RMDIR|IT_RENAME)
869 static int ll_rawop_from_intent(struct nameidata *nd)
870 {
871         int error = 0;
872
873         if (!nd || !(nd->intent.open.op & LLITE_IT_RAWOPS))
874                 return 0;
875
876         switch (nd->intent.open.op) {
877         case IT_MKNOD:
878                 error = ll_mknod_raw(nd, nd->intent.open.create_mode,
879                                      nd->intent.open.create.dev);
880                 break;
881         case IT_MKDIR:
882                 error = ll_mkdir_raw(nd, nd->intent.open.create_mode);
883                 break;
884         case IT_RMDIR:
885                 error = ll_rmdir_raw(nd);
886                 break;
887         case IT_UNLINK:
888                 error = ll_unlink_raw(nd);
889                 break;
890         case IT_SYMLINK:
891                 LASSERT(nd->intent.open.create.link);
892                 error = ll_symlink_raw(nd, nd->intent.open.create.link);
893                 break;
894         case IT_LINK:
895                 error = ll_link_raw(nd->intent.open.create.source_nd, nd);
896                 break;
897         case IT_RENAME:
898                 LASSERT(nd->intent.open.create.source_nd);
899                 error = ll_rename_raw(nd->intent.open.create.source_nd, nd);
900                 break;
901         default:
902                 LBUG();
903         }
904         if (error != -EOPNOTSUPP)
905                 nd->intent.open.flags |= IT_STATUS_RAW;
906
907         return error;
908 }
909 #endif
910
911 struct inode_operations ll_dir_inode_operations = {
912         .mknod              = ll_mknod,
913         .setattr            = ll_setattr,
914 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
915         .create_it          = ll_create_it,
916         .lookup_it          = ll_lookup_it,
917         .revalidate_it      = ll_inode_revalidate_it,
918 #else
919         .lookup             = ll_lookup_nd,
920         .create             = ll_create_nd,
921         .getattr            = ll_getattr,
922         .endparentlookup    = ll_rawop_from_intent,
923 #endif
924         .setxattr           = ll_setxattr,
925         .getxattr           = ll_getxattr,
926         .listxattr          = ll_listxattr,
927         .removexattr        = ll_removexattr,
928         .permission         = ll_inode_permission,
929 };