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