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