Whamcloud - gitweb
landing b_hd_sec, b6818, b7244
[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, (char *)dentry->d_name.name,
386                             dentry->d_name.len, NULL, 0, NULL, it, flags, &req,
387                             ll_mdc_blocking_ast);
388         if (rc < 0)
389                 GOTO(out, retval = ERR_PTR(rc));
390
391         rc = lookup_it_finish(req, 1, it, &icbd);
392         if (rc != 0) {
393                 ll_intent_release(it);
394                 GOTO(out, retval = ERR_PTR(rc));
395         }
396
397         ll_lookup_finish_locks(it, dentry);
398
399         if (nd && dentry->d_inode != NULL &&
400             dentry->d_inode->i_mode & S_ISUID && S_ISDIR(dentry->d_inode->i_mode) &&
401             ((gns_flags & LOOKUP_CONTINUE) || (gns_it & (IT_CHDIR | IT_OPEN))))
402         {
403                 CDEBUG(D_DENTRY, "possible GNS dentry %*s %p found, "
404                        "mounting it\n", (int)dentry->d_name.len,
405                        dentry->d_name.name, dentry);
406                 
407                 rc = ll_gns_mount_object(dentry, nd->mnt);
408                 if (rc) {
409                         /* 
410                          * just reporting about GNS failures, lookup() is
411                          * successful, do not stop it.
412                          *
413                          * GNS failure may be that object is found in SUID bit
414                          * marked dir but it is not regular file and we should
415                          * lookup further until we find correct mount
416                          * object. This will allow to perform GNS mount is the
417                          * following case for instance:
418                          *
419                          * /mnt/lustre/gns_mount/.mntinfo/.mntinfo/..../.mntinfo
420                          * where all ".mntinfo" are dirs and only last one is
421                          * reg file.
422                          */
423                         CDEBUG(D_DENTRY, "failed to mount %*s, err %d\n",
424                                (int)dentry->d_name.len, dentry->d_name.name, rc);
425                 }
426         }
427         
428         if (dentry == save)
429                 GOTO(out, retval = NULL);
430         else
431                 GOTO(out, retval = dentry);
432  out:
433         if (req)
434                 ptlrpc_req_finished(req);
435         if (it == &lookup_it)
436                 ll_intent_release(it);
437         if (dentry->d_inode)
438                 CDEBUG(D_INODE, "lookup 0x%p in %lu/%lu: %*s -> %lu/%lu\n",
439                        dentry,
440                        (unsigned long) parent->i_ino,
441                        (unsigned long) parent->i_generation,
442                        dentry->d_name.len, dentry->d_name.name,
443                        (unsigned long) dentry->d_inode->i_ino,
444                        (unsigned long) dentry->d_inode->i_generation);
445         else
446                 CDEBUG(D_INODE, "lookup 0x%p in %lu/%lu: %*s -> ??\n",
447                        dentry,
448                        (unsigned long) parent->i_ino,
449                        (unsigned long) parent->i_generation,
450                        dentry->d_name.len, dentry->d_name.name);
451         return retval;
452 }
453
454 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
455 static struct dentry *ll_lookup_nd(struct inode *parent, struct dentry *dentry,
456                                    struct nameidata *nd)
457 {
458         struct dentry *de;
459         ENTRY;
460
461         if (nd && nd->flags & LOOKUP_LAST && !(nd->flags & LOOKUP_LINK_NOTLAST))
462                 de = ll_lookup_it(parent, dentry, nd, nd->flags);
463         else
464                 de = ll_lookup_it(parent, dentry, nd, 0);
465
466         RETURN(de);
467 }
468 #endif
469
470 /* We depend on "mode" being set with the proper file type/umask by now */
471 static struct inode *ll_create_node(struct inode *dir, const char *name,
472                                     int namelen, const void *data, int datalen,
473                                     int mode, __u64 extra,
474                                     struct lookup_intent *it)
475 {
476         struct inode *inode = NULL;
477         struct ptlrpc_request *request = NULL;
478         struct ll_sb_info *sbi = ll_i2sbi(dir);
479         int rc;
480         ENTRY;
481
482
483         LASSERT(it && LUSTRE_IT(it)->it_disposition);
484   
485         request = LUSTRE_IT(it)->it_data;
486         rc = ll_prep_inode(sbi->ll_dt_exp, sbi->ll_md_exp,
487                            &inode, request, 1, dir->i_sb);
488         if (rc)
489                 GOTO(out, inode = ERR_PTR(rc));
490
491         LASSERT(list_empty(&inode->i_dentry));
492
493         /* We asked for a lock on the directory, but were granted a
494          * lock on the inode.  Since we finally have an inode pointer,
495          * stuff it in the lock. */
496         CDEBUG(D_DLMTRACE, "setting l_ast_data to inode %p (%lu/%u)\n",
497                inode, inode->i_ino, inode->i_generation);
498         mdc_set_lock_data(NULL, &LUSTRE_IT(it)->it_lock_handle, inode);
499         EXIT;
500  out:
501         ptlrpc_req_finished(request);
502         return inode;
503 }
504
505 /*
506  * By the time this is called, we already have created the directory cache
507  * entry for the new file, but it is so far negative - it has no inode.
508  *
509  * We defer creating the OBD object(s) until open, to keep the intent and
510  * non-intent code paths similar, and also because we do not have the MDS
511  * inode number before calling ll_create_node() (which is needed for LOV),
512  * so we would need to do yet another RPC to the MDS to store the LOV EA
513  * data on the MDS.  If needed, we would pass the PACKED lmm as data and
514  * lmm_size in datalen (the MDS still has code which will handle that).
515  *
516  * If the create succeeds, we fill in the inode information
517  * with d_instantiate().
518  */
519 static int ll_create_it(struct inode *dir, struct dentry *dentry, int mode,
520                         struct lookup_intent *it)
521 {
522         struct inode *inode;
523         struct ptlrpc_request *request = LUSTRE_IT(it)->it_data;
524         struct obd_export *md_exp = ll_i2mdexp(dir); 
525         int rc = 0;
526         ENTRY;
527
528         CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p),intent=%s\n",
529                dentry->d_name.len, dentry->d_name.name, dir->i_ino,
530                dir->i_generation, dir, LL_IT2STR(it));
531
532         rc = it_open_error(DISP_OPEN_CREATE, it);
533         if (rc)
534                 RETURN(rc);
535
536         mdc_store_inode_generation(md_exp, request, MDS_REQ_INTENT_REC_OFF, 1);
537         inode = ll_create_node(dir, (char *)dentry->d_name.name,
538                                dentry->d_name.len, NULL, 0, mode, 0, it);
539         if (IS_ERR(inode))
540                 RETURN(PTR_ERR(inode));
541
542         d_instantiate(dentry, inode);
543         RETURN(0);
544 }
545
546 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
547 static int ll_create_nd(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
548 {
549         return ll_create_it(dir, dentry, mode, &nd->intent.open);
550 }
551 #endif
552
553 static void ll_update_times(struct ptlrpc_request *request, int offset,
554                             struct inode *inode)
555 {
556         struct mds_body *body = lustre_msg_buf(request->rq_repmsg, offset,
557                                                sizeof(*body));
558         LASSERT(body);
559
560         if (body->valid & OBD_MD_FLMTIME &&
561             body->mtime > LTIME_S(inode->i_mtime)) {
562                 CDEBUG(D_INODE, "setting ino %lu mtime from %lu to %u\n",
563                        inode->i_ino, LTIME_S(inode->i_mtime), body->mtime);
564                 LTIME_S(inode->i_mtime) = body->mtime;
565         }
566         if (body->valid & OBD_MD_FLCTIME &&
567             body->ctime > LTIME_S(inode->i_ctime))
568                 LTIME_S(inode->i_ctime) = body->ctime;
569 }
570
571 static int ll_mknod_raw(struct nameidata *nd, int mode, dev_t rdev)
572 {
573         struct ptlrpc_request *request = NULL;
574         struct inode *dir = nd->dentry->d_inode;
575         struct ll_sb_info *sbi = ll_i2sbi(dir);
576         struct mdc_op_data *op_data;
577         int err = -EMLINK, key_size = 0;
578         void *key = NULL;
579         ENTRY;
580
581         CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n",
582                nd->last.len, nd->last.name, dir->i_ino,
583                dir->i_generation, dir);
584
585         mode &= ~current->fs->umask;
586
587         switch (mode & S_IFMT) {
588         case 0:
589         case S_IFREG: 
590                 mode |= S_IFREG; /* for mode = 0 case, fallthrough */
591                 ll_crypto_create_key(dir, mode, &key, &key_size);
592         case S_IFCHR:
593         case S_IFBLK:
594         case S_IFIFO:
595         case S_IFSOCK:
596                 OBD_ALLOC(op_data, sizeof(*op_data));
597                 if (op_data == NULL)
598                         RETURN(-ENOMEM);
599                 ll_prepare_mdc_data(op_data, dir, NULL,
600                                     (char *)nd->last.name, 
601                                     nd->last.len, 0);
602                 err = md_create(sbi->ll_md_exp, op_data, key, key_size, mode,
603                                 current->fsuid, current->fsgid, rdev,
604                                 &request);
605                 OBD_FREE(op_data, sizeof(*op_data));
606                 if (err == 0)
607                         ll_update_times(request, 0, dir);
608                 ptlrpc_req_finished(request);
609                 break;
610         case S_IFDIR:
611                 err = -EPERM;
612                 break;
613         default:
614                 err = -EINVAL;
615         }
616         if (key && key_size)
617                 OBD_FREE(key, key_size);
618         RETURN(err);
619 }
620
621 static int ll_mknod(struct inode *dir, struct dentry *dchild,
622                     int mode, ll_dev_t rdev)
623 {
624         struct ptlrpc_request *request = NULL;
625         struct inode *inode = NULL;
626         struct ll_sb_info *sbi = ll_i2sbi(dir);
627         struct mdc_op_data *op_data;
628         int err = -EMLINK;
629         ENTRY;
630
631         CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n",
632                dchild->d_name.len, dchild->d_name.name,
633                dir->i_ino, dir->i_generation, dir);
634
635         mode &= ~current->fs->umask;
636
637         switch (mode & S_IFMT) {
638         case 0:
639         case S_IFREG:
640                 mode |= S_IFREG; /* for mode = 0 case, fallthrough */
641                 
642         case S_IFCHR:
643         case S_IFBLK:
644         case S_IFIFO:
645         case S_IFSOCK:
646                 OBD_ALLOC(op_data, sizeof(*op_data));
647                 if (op_data == NULL)
648                         RETURN(-ENOMEM);
649
650                 ll_prepare_mdc_data(op_data, dir, NULL,
651                                     (char *)dchild->d_name.name, 
652                                     dchild->d_name.len, 0);
653                 
654                 err = md_create(sbi->ll_md_exp, op_data, NULL, 0, mode,
655                                 current->fsuid, current->fsgid, rdev,
656                                 &request);
657                 OBD_FREE(op_data, sizeof(*op_data));
658                 if (err)
659                         GOTO(out_err, err);
660
661                 ll_update_times(request, 0, dir);
662                 err = ll_prep_inode(sbi->ll_dt_exp, sbi->ll_md_exp,
663                                     &inode, request, 0, dchild->d_sb);
664                 if (err)
665                         GOTO(out_err, err);
666                 break;
667         case S_IFDIR:
668                 RETURN(-EPERM);
669                 break;
670         default:
671                 RETURN(-EINVAL);
672         }
673
674         d_instantiate(dchild, inode);
675         EXIT;
676  out_err:
677         ptlrpc_req_finished(request);
678         return err;
679 }
680
681 static int ll_symlink_raw(struct nameidata *nd, const char *tgt)
682 {
683         const char *name = (char *)nd->last.name;
684         struct inode *dir = nd->dentry->d_inode;
685         struct ptlrpc_request *request = NULL;
686         struct ll_sb_info *sbi = ll_i2sbi(dir);
687         struct mdc_op_data *op_data;
688         int len = nd->last.len;
689         int err = -EMLINK;
690         ENTRY;
691
692         CDEBUG(D_VFSTRACE, "VFS Op:name=%*s,dir=%lu/%u(%p),target=%s\n",
693                nd->last.len, nd->last.name, dir->i_ino, dir->i_generation,
694                dir, tgt);
695
696         if (dir->i_nlink >= EXT3_LINK_MAX)
697                 RETURN(err);
698
699         OBD_ALLOC(op_data, sizeof(*op_data));
700         if (op_data == NULL)
701                 RETURN(-ENOMEM);
702         ll_prepare_mdc_data(op_data, dir, NULL, name, len, 0);
703         LASSERT(tgt);
704         err = md_create(sbi->ll_md_exp, op_data,
705                         tgt, strlen(tgt) + 1, S_IFLNK | S_IRWXUGO,
706                         current->fsuid, current->fsgid, 0, &request);
707         OBD_FREE(op_data, sizeof(*op_data));
708         if (err == 0)
709                 ll_update_times(request, 0, dir);
710         
711         ptlrpc_req_finished(request);
712         RETURN(err);
713 }
714
715 static int ll_link_raw(struct nameidata *srcnd, struct nameidata *tgtnd)
716 {
717         struct inode *src = srcnd->dentry->d_inode;
718         struct inode *dir = tgtnd->dentry->d_inode;
719         struct ptlrpc_request *request = NULL;
720         struct ll_sb_info *sbi = ll_i2sbi(dir);
721         struct mdc_op_data *op_data;
722         int err;
723         ENTRY;
724
725         CDEBUG(D_VFSTRACE,
726                "VFS Op: inode=%lu/%u(%p), dir=%lu/%u(%p), target=%.*s\n",
727                src->i_ino, src->i_generation, src, dir->i_ino,
728                dir->i_generation, dir, tgtnd->last.len, tgtnd->last.name);
729
730         OBD_ALLOC(op_data, sizeof(*op_data));
731         if (op_data == NULL)
732                 RETURN(-ENOMEM);
733
734         ll_prepare_mdc_data(op_data, src, dir,
735                             (char *)tgtnd->last.name, 
736                             tgtnd->last.len, 0);
737         
738         err = md_link(sbi->ll_md_exp, op_data, &request);
739         OBD_FREE(op_data, sizeof(*op_data));
740         if (err == 0)
741                 ll_update_times(request, 0, dir);
742         ptlrpc_req_finished(request);
743         RETURN(err);
744 }
745
746
747 static int ll_mkdir_raw(struct nameidata *nd, int mode)
748 {
749         struct inode *dir = nd->dentry->d_inode;
750         struct ptlrpc_request *request = NULL;
751         struct ll_sb_info *sbi = ll_i2sbi(dir);
752         struct mdc_op_data *op_data;
753         int err = -EMLINK;
754         ENTRY;
755         CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n",
756                nd->last.len, nd->last.name, dir->i_ino, dir->i_generation, dir);
757
758         mode = (mode & (S_IRWXUGO|S_ISVTX) & ~current->fs->umask) | S_IFDIR;
759         OBD_ALLOC(op_data, sizeof(*op_data));
760         if (op_data == NULL)
761                 RETURN(-ENOMEM);
762
763         ll_prepare_mdc_data(op_data, dir, NULL,
764                             (char *)nd->last.name, 
765                             nd->last.len, 0);
766         
767         err = md_create(sbi->ll_md_exp, op_data, NULL, 0, mode,
768                         current->fsuid, current->fsgid, 0, &request);
769         OBD_FREE(op_data, sizeof(*op_data));
770         if (err == 0)
771                 ll_update_times(request, 0, dir);
772         ptlrpc_req_finished(request);
773         RETURN(err);
774 }
775
776 static int ll_rmdir_raw(struct nameidata *nd)
777 {
778         struct inode *dir = nd->dentry->d_inode;
779         struct ptlrpc_request *request = NULL;
780         struct mdc_op_data *op_data;
781         int rc;
782
783         ENTRY;
784         CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n",
785                nd->last.len, nd->last.name, dir->i_ino,
786                dir->i_generation, dir);
787
788         OBD_ALLOC(op_data, sizeof(*op_data));
789         if (op_data == NULL)
790                 RETURN(-ENOMEM);
791
792         ll_prepare_mdc_data(op_data, dir, NULL,
793                             (char *)nd->last.name, 
794                             nd->last.len, S_IFDIR);
795         
796         rc = md_unlink(ll_i2sbi(dir)->ll_md_exp, op_data, &request);
797         OBD_FREE(op_data, sizeof(*op_data));
798         if (rc == 0)
799                 ll_update_times(request, 0, dir);
800         ptlrpc_req_finished(request);
801         RETURN(rc);
802 }
803
804 static int ll_unlink_raw(struct nameidata *nd)
805 {
806         struct inode *dir = nd->dentry->d_inode;
807         struct ptlrpc_request *request = NULL;
808         struct mdc_op_data *op_data;
809         int rc;
810         ENTRY;
811         CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n",
812                nd->last.len, nd->last.name, dir->i_ino,
813                dir->i_generation, dir);
814
815         OBD_ALLOC(op_data, sizeof(*op_data));
816         if (op_data == NULL)
817                 RETURN(-ENOMEM);
818         ll_prepare_mdc_data(op_data, dir, NULL,
819                             (char *)nd->last.name, nd->last.len, 0);
820         rc = md_unlink(ll_i2sbi(dir)->ll_md_exp, op_data, &request);
821         OBD_FREE(op_data, sizeof(*op_data));
822         if (rc)
823                 GOTO(out, rc);
824         ll_update_times(request, 0, dir);
825         EXIT;
826 out:
827         ptlrpc_req_finished(request);
828         return rc;
829 }
830
831 static int ll_rename_raw(struct nameidata *srcnd, struct nameidata *tgtnd)
832 {
833         struct inode *src = srcnd->dentry->d_inode;
834         struct inode *tgt = tgtnd->dentry->d_inode;
835         struct ptlrpc_request *request = NULL;
836         struct ll_sb_info *sbi = ll_i2sbi(src);
837         struct mdc_op_data *op_data;
838         int err;
839         ENTRY;
840         
841         if (srcnd->mnt != tgtnd->mnt)
842                 RETURN(-EXDEV);
843
844         CDEBUG(D_VFSTRACE,"VFS Op:oldname=%.*s,src_dir=%lu/%u(%p),newname=%.*s,"
845                "tgt_dir=%lu/%u(%p)\n", srcnd->last.len, srcnd->last.name,
846                src->i_ino, src->i_generation, src, tgtnd->last.len,
847                tgtnd->last.name, tgt->i_ino, tgt->i_generation, tgt);
848
849         OBD_ALLOC(op_data, sizeof(*op_data));
850         if (op_data == NULL)
851                 RETURN(-ENOMEM);
852         ll_prepare_mdc_data(op_data, src, tgt, NULL, 0, 0);
853         err = md_rename(sbi->ll_md_exp, op_data, (char *)srcnd->last.name, 
854                         srcnd->last.len, (char *)tgtnd->last.name,
855                         tgtnd->last.len, &request);
856         OBD_FREE(op_data, sizeof(*op_data));
857         if (!err) {
858                 ll_update_times(request, 0, src);
859                 ll_update_times(request, 0, tgt);
860         }
861
862         ptlrpc_req_finished(request);
863         RETURN(err);
864 }
865
866 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
867 #define LLITE_IT_RAWOPS (IT_MKNOD|IT_MKDIR|IT_SYMLINK|IT_LINK|IT_UNLINK|IT_RMDIR|IT_RENAME)
868 static int ll_rawop_from_intent(struct nameidata *nd)
869 {
870         int error = 0;
871
872         if (!nd || !(nd->intent.open.op & LLITE_IT_RAWOPS))
873                 return 0;
874
875         switch (nd->intent.open.op) {
876         case IT_MKNOD:
877                 error = ll_mknod_raw(nd, nd->intent.open.create_mode,
878                                      nd->intent.open.create.dev);
879                 break;
880         case IT_MKDIR:
881                 error = ll_mkdir_raw(nd, nd->intent.open.create_mode);
882                 break;
883         case IT_RMDIR:
884                 error = ll_rmdir_raw(nd);
885                 break;
886         case IT_UNLINK:
887                 error = ll_unlink_raw(nd);
888                 break;
889         case IT_SYMLINK:
890                 LASSERT(nd->intent.open.create.link);
891                 error = ll_symlink_raw(nd, nd->intent.open.create.link);
892                 break;
893         case IT_LINK:
894                 error = ll_link_raw(nd->intent.open.create.source_nd, nd);
895                 break;
896         case IT_RENAME:
897                 LASSERT(nd->intent.open.create.source_nd);
898                 error = ll_rename_raw(nd->intent.open.create.source_nd, nd);
899                 break;
900         default:
901                 LBUG();
902         }
903         if (error != -EOPNOTSUPP)
904                 nd->intent.open.flags |= IT_STATUS_RAW;
905
906         return error;
907 }
908 #endif
909
910 struct inode_operations ll_dir_inode_operations = {
911         .mknod              = ll_mknod,
912         .setattr            = ll_setattr,
913 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
914         .create_it          = ll_create_it,
915         .lookup_it          = ll_lookup_it,
916         .revalidate_it      = ll_inode_revalidate_it,
917 #else
918         .lookup             = ll_lookup_nd,
919         .create             = ll_create_nd,
920         .getattr            = ll_getattr,
921         .endparentlookup    = ll_rawop_from_intent,
922 #endif
923         .setxattr           = ll_setxattr,
924         .getxattr           = ll_getxattr,
925         .listxattr          = ll_listxattr,
926         .removexattr        = ll_removexattr,
927         .permission         = ll_inode_permission,
928 };