Whamcloud - gitweb
9738874ccd215a4b4e658f7fdcf420193d7ba1c1
[fs/lustre-release.git] / lustre / obdfs / namei.c
1 /*
2  *  linux/fs/ext2/namei.c
3  *
4  * Copyright (C) 1992, 1993, 1994, 1995
5  * Remy Card (card@masi.ibp.fr)
6  * Laboratoire MASI - Institut Blaise Pascal
7  * Universite Pierre et Marie Curie (Paris VI)
8  *
9  *  from
10  *
11  *  linux/fs/minix/namei.c
12  *
13  *  Copyright (C) 1991, 1992  Linus Torvalds
14  *
15  *  Big-endian to little-endian byte-swapping/bitmaps by
16  *        David S. Miller (davem@caip.rutgers.edu), 1995
17  *  Directory entry file type support and forward compatibility hooks
18  *      for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998
19  * 
20  *  Changes for use in OBDFS
21  *  Copyright (c) 1999, Seagate Technology Inc.
22  * 
23  */
24
25 #include <asm/uaccess.h>
26
27 #include <linux/errno.h>
28 #include <linux/fs.h>
29 #include <linux/ext2_fs.h>
30 #include <linux/fcntl.h>
31 #include <linux/sched.h>
32 #include <linux/stat.h>
33 #include <linux/string.h>
34 #include <linux/locks.h>
35 #include <linux/quotaops.h>
36 #include <linux/iobuf.h>
37
38 #include <linux/obd_support.h>
39 #include "obdfs.h"
40
41 /*
42  * define how far ahead to read directories while searching them.
43  */
44 #define NAMEI_RA_CHUNKS  2
45 #define NAMEI_RA_BLOCKS  4
46 #define NAMEI_RA_SIZE        (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
47 #define NAMEI_RA_INDEX(c,b)  (((c) * NAMEI_RA_BLOCKS) + (b))
48
49 /*
50  * NOTE! unlike strncmp, ext2_match returns 1 for success, 0 for failure.
51  *
52  * `len <= EXT2_NAME_LEN' is guaranteed by caller.
53  * `de != NULL' is guaranteed by caller.
54  */
55 static inline int ext2_match (int len, const char * const name,
56                        struct ext2_dir_entry_2 * de)
57 {
58         if (len != de->name_len)
59                 return 0;
60         if (!de->inode)
61                 return 0;
62         return !memcmp(name, de->name, len);
63 }
64
65 /*
66  *      ext2_find_entry()
67  *
68  * finds an entry in the specified directory with the wanted name. It
69  * returns the cache buffer in which the entry was found, and the entry
70  * itself (as a parameter - res_dir). It does NOT read the inode of the
71  * entry - you'll have to do that yourself if you want to.
72  */
73 struct page * obdfs_find_entry (struct inode * dir,
74                                              const char * const name, int namelen,
75                                              struct ext2_dir_entry_2 ** res_dir)
76 {
77         struct super_block * sb;
78         unsigned long offset;
79         struct page * page;
80
81         *res_dir = NULL;
82         sb = dir->i_sb;
83
84         if (namelen > EXT2_NAME_LEN)
85                 return NULL;
86
87         for (page = 0, offset = 0; offset < dir->i_size; page++) {
88                 struct ext2_dir_entry_2 * de;
89                 char * dlimit;
90
91                 page = obdfs_getpage(dir, offset, 0, NOLOCK);
92                 if ( !page ) 
93                         return NULL;
94
95                 de = (struct ext2_dir_entry_2 *) page_address(page);
96                 dlimit = (char *)page_address(page) + PAGE_SIZE; 
97                 while ((char *) de < dlimit) {
98                         /* this code is executed quadratically often */
99                         /* do minimal checking `by hand' */
100                         int de_len;
101
102                         if ((char *) de + namelen <= dlimit &&
103                             ext2_match (namelen, name, de)) {
104                                 /* found a match -
105                                    just to be sure, do a full check */
106 #if 0
107                                 if (!ext2_check_dir_entry("ext2_find_entry",
108                                                           dir, de, bh, offset))
109                                         goto failure;
110 #endif
111                                 *res_dir = de;
112                                 return page;
113                         }
114                         /* prevent looping on a bad block */
115                         de_len = le16_to_cpu(de->rec_len);
116                         if (de_len <= 0)
117                                 goto failure;
118                         offset += de_len;
119                         de = (struct ext2_dir_entry_2 *)
120                                 ((char *) de + de_len);
121                 }
122                 page_cache_release(page);
123         }
124
125 failure:
126         page_cache_release(page);
127         return NULL;
128 }
129
130 struct dentry *obdfs_lookup(struct inode * dir, struct dentry *dentry)
131 {
132         struct inode * inode;
133         struct ext2_dir_entry_2 * de;
134         struct page * page;
135
136         if (dentry->d_name.len > EXT2_NAME_LEN)
137                 return ERR_PTR(-ENAMETOOLONG);
138
139         page = obdfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &de);
140         inode = NULL;
141         if (page) {
142                 unsigned long ino = le32_to_cpu(de->inode);
143                 page_cache_release(page);
144                 inode = iget(dir->i_sb, ino);
145
146                 if (!inode)
147                         return ERR_PTR(-EACCES);
148         }
149         d_add(dentry, inode);
150         return NULL;
151 }
152
153
154 /*
155  *      ext2_add_entry()
156  *
157  * adds a file entry to the specified directory, using the same
158  * semantics as ext2_find_entry(). It returns NULL if it failed.
159  *
160  * NOTE!! The inode part of 'de' is left at 0 - which means you
161  * may not sleep between calling this and putting something into
162  * the entry, as someone else might have used it while you slept.
163
164  * returns a locked page
165  */
166 static struct page *obdfs_add_entry (struct inode * dir,
167                                      const char * name, int namelen,
168                                      struct ext2_dir_entry_2 ** res_dir,
169                                      int *err)
170 {
171         unsigned long offset;
172         unsigned short rec_len;
173         struct page *page;
174         struct ext2_dir_entry_2 * de, * de1;
175         struct super_block * sb;
176
177         *err = -EINVAL;
178         *res_dir = NULL;
179         if (!dir || !dir->i_nlink)
180                 return NULL;
181         sb = dir->i_sb;
182
183         if (!namelen)
184                 return NULL;
185         /*
186          * Is this a busy deleted directory?  Can't create new files if so
187          */
188         if (dir->i_size == 0)
189         {
190                 *err = -ENOENT;
191                 return NULL;
192         }
193         page = obdfs_getpage(dir, 0, 0, LOCKED);
194         if (!page)
195                 return NULL;
196         rec_len = EXT2_DIR_REC_LEN(namelen);
197         offset = 0;
198         de = (struct ext2_dir_entry_2 *) page_address(page);
199         *err = -ENOSPC;
200         while (1) {
201                 if ((char *)de >= PAGE_SIZE + (char *)page_address(page)) {
202                         UnlockPage(page);
203                         page_cache_release(page);
204                         page = obdfs_getpage(dir, offset, 1, LOCKED);
205                         if (page)
206                                 return NULL;
207                         if (dir->i_size <= offset) {
208                                 if (dir->i_size == 0) {
209                                         *err = -ENOENT;
210                                         return NULL;
211                                 }
212
213                                 ext2_debug ("creating next block\n");
214
215                                 de = (struct ext2_dir_entry_2 *) page_address(page);
216                                 de->inode = 0;
217                                 de->rec_len = le16_to_cpu(sb->s_blocksize);
218                                 dir->i_size = offset + PAGE_SIZE;
219                                 dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
220                                 mark_inode_dirty(dir);
221                         } else {
222
223                                 ext2_debug ("skipping to next block\n");
224
225                                 de = (struct ext2_dir_entry_2 *) page_address(page);
226                         }
227                 }
228 #if 0
229                 if (!ext2_check_dir_entry ("ext2_add_entry", dir, de, bh,
230                                            offset)) {
231                         *err = -ENOENT;
232                         brelse (bh);
233                         return NULL;
234                 }
235 #endif
236                 if (ext2_match (namelen, name, de)) {
237                                 *err = -EEXIST;
238                                 UnlockPage(page);
239                                 page_cache_release(page);
240                                 return NULL;
241                 }
242                 if ((le32_to_cpu(de->inode) == 0 && le16_to_cpu(de->rec_len) >= rec_len) ||
243                     (le16_to_cpu(de->rec_len) >= EXT2_DIR_REC_LEN(de->name_len) + rec_len)) {
244                         offset += le16_to_cpu(de->rec_len);
245                         if (le32_to_cpu(de->inode)) {
246                                 de1 = (struct ext2_dir_entry_2 *) ((char *) de +
247                                         EXT2_DIR_REC_LEN(de->name_len));
248                                 de1->rec_len = cpu_to_le16(le16_to_cpu(de->rec_len) -
249                                         EXT2_DIR_REC_LEN(de->name_len));
250                                 de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(de->name_len));
251                                 de = de1;
252                         }
253                         de->inode = 0;
254                         de->name_len = namelen;
255                         de->file_type = 0;
256                         memcpy (de->name, name, namelen);
257                         /*
258                          * XXX shouldn't update any times until successful
259                          * completion of syscall, but too many callers depend
260                          * on this.
261                          *
262                          * XXX similarly, too many callers depend on
263                          * ext2_new_inode() setting the times, but error
264                          * recovery deletes the inode, so the worst that can
265                          * happen is that the times are slightly out of date
266                          * and/or different from the directory change time.
267                          */
268                         dir->i_mtime = dir->i_ctime = CURRENT_TIME;
269                         dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
270                         mark_inode_dirty(dir);
271                         dir->i_version = ++event;
272                         *res_dir = de;
273                         *err = 0;
274                         PDEBUG(page, "addentry");
275                         return page;
276                 }
277                 offset += le16_to_cpu(de->rec_len);
278                 de = (struct ext2_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
279         }
280
281         UnlockPage(page);
282         page_cache_release(page);
283         PDEBUG(page, "addentry");
284         EXIT;
285         return NULL;
286 }
287
288 /*
289  * ext2_delete_entry deletes a directory entry by merging it with the
290  * previous entry
291  */
292 static int obdfs_delete_entry (struct ext2_dir_entry_2 * dir,
293                               struct page * page)
294 {
295         struct ext2_dir_entry_2 * de, * pde;
296         int i;
297
298         i = 0;
299         pde = NULL;
300         de = (struct ext2_dir_entry_2 *) page_address(page);
301         while (i < PAGE_SIZE) {
302 #if 0
303                 if (!ext2_check_dir_entry ("ext2_delete_entry", NULL, 
304                                            de, bh, i))
305                         return -EIO;
306 #endif
307                 if (de == dir)  {
308                         if (pde)
309                                 pde->rec_len =
310                                         cpu_to_le16(le16_to_cpu(pde->rec_len) +
311                                                     le16_to_cpu(dir->rec_len));
312                         else
313                                 dir->inode = 0;
314                         return 0;
315                 }
316                 i += le16_to_cpu(de->rec_len);
317                 pde = de;
318                 de = (struct ext2_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
319         }
320         return -ENOENT;
321 }
322
323
324 static inline void ext2_set_de_type(struct super_block *sb,
325                                 struct ext2_dir_entry_2 *de,
326                                 umode_t mode) {
327         if (!EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_FILETYPE))
328                 return;
329         if (S_ISCHR(mode))
330                 de->file_type = EXT2_FT_CHRDEV;
331         else if (S_ISBLK(mode))
332                 de->file_type = EXT2_FT_BLKDEV;
333         else if (S_ISFIFO(mode))  
334                 de->file_type = EXT2_FT_FIFO;
335         else if (S_ISLNK(mode))
336                 de->file_type = EXT2_FT_SYMLINK;
337         else if (S_ISREG(mode))
338                 de->file_type = EXT2_FT_REG_FILE;
339         else if (S_ISDIR(mode))  
340                 de->file_type = EXT2_FT_DIR;
341 }
342
343 /*
344  * By the time this is called, we already have created
345  * the directory cache entry for the new file, but it
346  * is so far negative - it has no inode.
347  *
348  * If the create succeeds, we fill in the inode information
349  * with d_instantiate(). 
350  */
351 int obdfs_create (struct inode * dir, struct dentry * dentry, int mode)
352 {
353         struct inode * inode;
354         struct page *page;
355         struct ext2_dir_entry_2 * de;
356         int err = -EIO;
357         struct obdfs_sb_info *sbi;
358         ino_t ino;
359
360         ENTRY;
361
362         sbi = dir->i_sb->u.generic_sbp;
363         /*
364          * N.B. Several error exits in ext2_new_inode don't set err.
365          */
366         ino = sbi->osi_ops->o_create(sbi->osi_obd, 0, &err);
367         if ( ino == -1 ) 
368                 return -1;
369         inode =  iget(dir->i_sb, ino);
370         if (!inode)
371                 return err;
372
373         inode->i_op = &obdfs_inode_ops;
374         inode->i_mode = mode;
375         mark_inode_dirty(inode);
376         page = obdfs_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
377         if (!page) {
378                 inode->i_nlink--;
379                 mark_inode_dirty(inode);
380                 iput (inode);
381                 return err;
382         }
383         de->inode = cpu_to_le32(inode->i_ino);
384         ext2_set_de_type(dir->i_sb, de, S_IFREG);
385         dir->i_version = ++event;
386         sbi->osi_ops->o_brw(WRITE, sbi->osi_conn_info.conn_id, 
387                             dir->i_ino, page, 0);
388         UnlockPage(page);
389 #if 0
390         if (IS_SYNC(dir)) {
391                 ll_rw_block (WRITE, 1, &bh);
392                 wait_on_buffer (bh);
393         }
394 #endif
395         page_cache_release(page);
396         d_instantiate(dentry, inode);
397         return 0;
398 }
399
400 int obdfs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)
401 {
402         struct inode * inode;
403         struct page *page;
404         struct ext2_dir_entry_2 * de;
405         int err = -EIO;
406         struct obdfs_sb_info *sbi;
407
408         ino_t ino;
409
410         ENTRY;
411
412         sbi = dir->i_sb->u.generic_sbp;
413         /*
414          * N.B. Several error exits in ext2_new_inode don't set err.
415          */
416         ino = sbi->osi_ops->o_create(sbi->osi_obd, 0, &err);
417         if ( ino == -1 ) 
418                 return -1;
419         inode =  iget(dir->i_sb, ino);
420         if (!inode)
421                 return err;
422
423         inode->i_uid = current->fsuid;
424         init_special_inode(inode, mode, rdev);
425         page = obdfs_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
426         if (!page)
427                 goto out_no_entry;
428         de->inode = cpu_to_le32(inode->i_ino);
429         dir->i_version = ++event;
430         ext2_set_de_type(dir->i_sb, de, inode->i_mode);
431         mark_inode_dirty(inode);
432         sbi->osi_ops->o_brw(WRITE, sbi->osi_conn_info.conn_id, 
433                             dir->i_ino, page, 0);
434         UnlockPage(page);
435
436 #if 0
437         if (IS_SYNC(dir)) {
438                 ll_rw_block (WRITE, 1, &bh);
439                 wait_on_buffer (bh);
440         }
441 #endif
442         d_instantiate(dentry, inode);
443         page_cache_release(page);
444         err = 0;
445 out:
446         return err;
447
448 out_no_entry:
449         inode->i_nlink--;
450         mark_inode_dirty(inode);
451         iput(inode);
452         goto out;
453 }
454
455 int obdfs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
456 {
457         struct inode * child;
458         struct page *page, *child_page;
459         struct ext2_dir_entry_2 * de;
460         struct obdfs_sb_info *sbi;
461         int err;
462         ino_t ino;
463
464         ENTRY;
465         sbi = dir->i_sb->u.generic_sbp;
466
467         err = -EMLINK;
468         if (dir->i_nlink >= EXT2_LINK_MAX)
469                 goto out;
470
471         err = -EIO;
472         ino = iops(dir)->o_create(sbi->osi_obd, 0, &err);
473         if ( ino == -1 ) 
474                 return -1;
475         child =  iget(dir->i_sb, ino);
476         if (!child)
477                 return err;
478
479
480         child->i_op = &obdfs_inode_ops;
481         child->i_size = PAGE_SIZE;
482         child->i_blocks = 0;    
483         child_page = obdfs_getpage(child, 0, 1, LOCKED);
484         if (!child_page) {
485                 child->i_nlink--; /* is this nlink == 0? */
486                 mark_inode_dirty(child);
487                 iput (child);
488                 return err;
489         }
490         child->i_blocks = PAGE_SIZE/child->i_sb->s_blocksize;
491
492         /* create . and .. */
493         de = (struct ext2_dir_entry_2 *) page_address(child_page);
494         de->inode = cpu_to_le32(child->i_ino);
495         de->name_len = 1;
496         de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(de->name_len));
497         strcpy (de->name, ".");
498         ext2_set_de_type(dir->i_sb, de, S_IFDIR);
499         
500         de = (struct ext2_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
501         de->inode = cpu_to_le32(dir->i_ino);
502         de->rec_len = cpu_to_le16(child->i_sb->s_blocksize - EXT2_DIR_REC_LEN(1));
503         de->name_len = 2;
504         strcpy (de->name, "..");
505         ext2_set_de_type(dir->i_sb, de, S_IFDIR);
506         
507         iops(dir)->o_brw(WRITE, sbi->osi_conn_info.conn_id, child->i_ino, child_page, 1);
508         UnlockPage(child_page);
509         page_cache_release(child_page);
510
511         child->i_nlink = 2;
512         child->i_mode = S_IFDIR | mode;
513         if (dir->i_mode & S_ISGID)
514                 child->i_mode |= S_ISGID;
515         mark_inode_dirty(child);
516
517         /* now deal with the parent */
518         page = obdfs_add_entry(dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
519         if (!page) {
520                 goto out_no_entry;
521         }
522
523         de->inode = cpu_to_le32(child->i_ino);
524         ext2_set_de_type(dir->i_sb, de, S_IFDIR);
525         dir->i_version = ++event;
526
527 #if 0
528         if (IS_SYNC(dir)) {
529                 ll_rw_block (WRITE, 1, &bh);
530                 wait_on_buffer (bh);
531         }
532 #endif
533         dir->i_nlink++;
534         dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
535         mark_inode_dirty(dir);
536         iops(dir)->o_brw(WRITE, sbi->osi_conn_info.conn_id, dir->i_ino, page, 1);
537         UnlockPage(page);
538         page_cache_release(page);
539         d_instantiate(dentry, child);
540         err = 0;
541 out:
542         EXIT;
543         return err;
544
545 out_no_entry:
546         child->i_nlink = 0;
547         mark_inode_dirty(child);
548         iput (child);
549         goto out;
550 }
551
552
553 /*
554  * routine to check that the specified directory is empty (for rmdir)
555  */
556 static int empty_dir (struct inode * inode)
557 {
558         unsigned long offset;
559         struct page *page;
560         struct ext2_dir_entry_2 * de, * de1;
561         struct super_block * sb;
562
563         sb = inode->i_sb;
564         if (inode->i_size < EXT2_DIR_REC_LEN(1) + EXT2_DIR_REC_LEN(2) ||
565             !(page = obdfs_getpage (inode, 0, 0, NOLOCK))) {
566                 ext2_warning (inode->i_sb, "empty_dir",
567                               "bad directory (dir #%lu) - no data block",
568                               inode->i_ino);
569                 return 1;
570         }
571         de = (struct ext2_dir_entry_2 *) page_address(page);
572         de1 = (struct ext2_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
573         if (le32_to_cpu(de->inode) != inode->i_ino || !le32_to_cpu(de1->inode) || 
574             strcmp (".", de->name) || strcmp ("..", de1->name)) {
575                 ext2_warning (inode->i_sb, "empty_dir",
576                               "bad directory (dir #%lu) - no `.' or `..'",
577                               inode->i_ino);
578                 page_cache_release(page);
579                 return 1;
580         }
581         offset = le16_to_cpu(de->rec_len) + le16_to_cpu(de1->rec_len);
582         de = (struct ext2_dir_entry_2 *) ((char *) de1 + le16_to_cpu(de1->rec_len));
583         while (offset < inode->i_size ) {
584                 if (!page || (void *) de >= (void *) (page_address(page) + PAGE_SIZE)) {
585                         if (page) 
586                                 page_cache_release(page);
587                         page = obdfs_getpage(inode, offset, 0, NOLOCK);
588                         if (!page) {
589 #if 0
590                                 ext2_error (sb, "empty_dir",
591                                             "directory #%lu contains a hole at offset %lu",
592                                             inode->i_ino, offset);
593 #endif
594                                 offset += sb->s_blocksize;
595                                 continue;
596                         }
597                         de = (struct ext2_dir_entry_2 *) page_address(page);
598                 }
599 #if 0
600                 if (!ext2_check_dir_entry ("empty_dir", inode, de, bh,
601                                            offset)) {
602                         brelse (bh);
603                         return 1;
604                 }
605 #endif
606                 if (le32_to_cpu(de->inode)) {
607                         page_cache_release(page);
608                         return 0;
609                 }
610                 offset += le16_to_cpu(de->rec_len);
611                 de = (struct ext2_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
612         }
613         page_cache_release(page);
614         return 1;
615 }
616
617 int obdfs_rmdir (struct inode * dir, struct dentry *dentry)
618 {
619         int retval;
620         struct inode * inode;
621         struct page *page;
622         struct ext2_dir_entry_2 * de;
623         struct obdfs_sb_info *sbi;
624
625         ENTRY;
626         sbi = dir->i_sb->u.generic_sbp;
627
628         retval = -ENOENT;
629         page = obdfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &de);
630         if (!page)
631                 goto end_rmdir;
632
633         inode = dentry->d_inode;
634         DQUOT_INIT(inode);
635
636         retval = -EIO;
637         if (le32_to_cpu(de->inode) != inode->i_ino)
638                 goto end_rmdir;
639
640         retval = -ENOTEMPTY;
641         if (!empty_dir (inode))
642                 goto end_rmdir;
643
644         retval = obdfs_delete_entry (de, page);
645         dir->i_version = ++event;
646         if (retval)
647                 goto end_rmdir;
648         sbi->osi_ops->o_brw(WRITE, sbi->osi_conn_info.conn_id, 
649                             dir->i_ino, page, 0);
650         UnlockPage(page);
651 #if 0
652         if (IS_SYNC(dir)) {
653                 ll_rw_block (WRITE, 1, &bh);
654                 wait_on_buffer (bh);
655         }
656 #endif
657         if (inode->i_nlink != 2)
658                 ext2_warning (inode->i_sb, "ext2_rmdir",
659                               "empty directory has nlink!=2 (%d)",
660                               inode->i_nlink);
661         inode->i_version = ++event;
662         inode->i_nlink = 0;
663         inode->i_size = 0;
664         mark_inode_dirty(inode);
665         dir->i_nlink--;
666         inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
667         dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
668         mark_inode_dirty(dir);
669         d_delete(dentry);
670
671 end_rmdir:
672         if ( page )
673                 page_cache_release(page);
674         return retval;
675 }
676
677 int obdfs_unlink(struct inode * dir, struct dentry *dentry)
678 {
679         int retval;
680         struct inode * inode;
681         struct page *page;
682         struct ext2_dir_entry_2 * de;
683         struct obdfs_sb_info *sbi;
684
685         ENTRY;
686         sbi = dir->i_sb->u.generic_sbp;
687
688         retval = -ENOENT;
689         page = obdfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &de);
690         if (!page)
691                 goto end_unlink;
692
693         inode = dentry->d_inode;
694         DQUOT_INIT(inode);
695
696         retval = -EIO;
697         if (le32_to_cpu(de->inode) != inode->i_ino)
698                 goto end_unlink;
699         
700         if (!inode->i_nlink) {
701                 ext2_warning (inode->i_sb, "ext2_unlink",
702                               "Deleting nonexistent file (%lu), %d",
703                               inode->i_ino, inode->i_nlink);
704                 inode->i_nlink = 1;
705         }
706         retval = obdfs_delete_entry (de, page);
707         if (retval)
708                 goto end_unlink;
709         dir->i_version = ++event;
710         sbi->osi_ops->o_brw(WRITE, sbi->osi_conn_info.conn_id, 
711                             dir->i_ino, page, 0);
712         UnlockPage(page);
713 #if 0
714         if (IS_SYNC(dir)) {
715                 ll_rw_block (WRITE, 1, &bh);
716                 wait_on_buffer (bh);
717         }
718 #endif
719         dir->i_ctime = dir->i_mtime = CURRENT_TIME;
720         dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
721         mark_inode_dirty(dir);
722         inode->i_nlink--;
723         mark_inode_dirty(inode);
724         inode->i_ctime = dir->i_ctime;
725         retval = 0;
726         d_delete(dentry);       /* This also frees the inode */
727
728 end_unlink:
729         if (page)
730                 page_cache_release(page);
731         return retval;
732 }
733
734 int obdfs_symlink (struct inode * dir, struct dentry *dentry, const char * symname)
735 {
736         struct ext2_dir_entry_2 * de;
737         struct inode * inode;
738         struct page* page = NULL, * name_page = NULL;
739         char * link;
740         int i, l, err = -EIO;
741         char c;
742         struct obdfs_sb_info *sbi;
743         ino_t ino;
744
745         ENTRY;
746
747         sbi = dir->i_sb->u.generic_sbp;
748         /*
749          * N.B. Several error exits in ext2_new_inode don't set err.
750          */
751         ino = sbi->osi_ops->o_create(sbi->osi_obd, 0, &err);
752         if ( ino == -1 ) 
753                 return -1;
754         inode =  iget(dir->i_sb, ino);
755         if (!inode)
756                 return err;
757
758         inode->i_mode = S_IFLNK | S_IRWXUGO;
759         inode->i_op = &obdfs_inode_ops;
760         for (l = 0; l < inode->i_sb->s_blocksize - 1 &&
761              symname [l]; l++)
762                 ;
763         if (l >= sizeof (inode->u.ext2_i.i_data)) {
764
765                 ext2_debug ("l=%d, normal symlink\n", l);
766
767                 name_page = obdfs_getpage(inode, 0, 1, LOCKED);
768                 if (!name_page) {
769                         inode->i_nlink--;
770                         mark_inode_dirty(inode);
771                         iput (inode);
772                         return err;
773                 }
774                 link = (char *)page_address(name_page);
775         } else {
776                 link = (char *) inode->u.ext2_i.i_data;
777
778                 ext2_debug ("l=%d, fast symlink\n", l);
779
780         }
781         i = 0;
782         while (i < inode->i_sb->s_blocksize - 1 && (c = *(symname++)))
783                 link[i++] = c;
784         link[i] = 0;
785         if (name_page) {
786                 sbi->osi_ops->o_brw(WRITE, sbi->osi_conn_info.conn_id, 
787                                     inode->i_ino, name_page, 1);
788                 PDEBUG(name_page, "symlink");
789                 UnlockPage(name_page);
790                 page_cache_release(name_page);
791         }
792         inode->i_size = i;
793         mark_inode_dirty(inode);
794
795         page = obdfs_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
796         if (!page)
797                 goto out_no_entry;
798         de->inode = cpu_to_le32(inode->i_ino);
799         ext2_set_de_type(dir->i_sb, de, S_IFLNK);
800         dir->i_version = ++event;
801         sbi->osi_ops->o_brw(WRITE, sbi->osi_conn_info.conn_id, 
802                             dir->i_ino, page, 1);
803         UnlockPage(page);
804 #if 0
805         if (IS_SYNC(dir)) {
806                 ll_rw_block (WRITE, 1, &bh);
807                 wait_on_buffer (bh);
808         }
809 #endif
810         d_instantiate(dentry, inode);
811         err = 0;
812 out:
813         return err;
814
815 out_no_entry:
816         inode->i_nlink--;
817         mark_inode_dirty(inode);
818         iput (inode);
819         goto out;
820 }
821
822 int obdfs_link (struct dentry * old_dentry,
823                 struct inode * dir, struct dentry *dentry)
824 {
825         struct inode *inode = old_dentry->d_inode;
826         struct ext2_dir_entry_2 * de;
827         struct page *page;
828         int err;
829         struct obdfs_sb_info *sbi;
830
831         ENTRY;
832         sbi = dir->i_sb->u.generic_sbp;
833
834         if (S_ISDIR(inode->i_mode))
835                 return -EPERM;
836
837         if (inode->i_nlink >= EXT2_LINK_MAX)
838                 return -EMLINK;
839
840         page = obdfs_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
841         if (!page)
842                 return err;
843
844         de->inode = cpu_to_le32(inode->i_ino);
845         ext2_set_de_type(dir->i_sb, de, inode->i_mode);
846         dir->i_version = ++event;
847         sbi->osi_ops->o_brw(WRITE, sbi->osi_conn_info.conn_id, 
848                             dir->i_ino, page, 0);
849         UnlockPage(page);
850
851 #if 0
852         if (IS_SYNC(dir)) {
853                 ll_rw_block (WRITE, 1, &bh);
854                 wait_on_buffer (bh);
855         }
856 #endif
857         page_cache_release(page);
858         inode->i_nlink++;
859         inode->i_ctime = CURRENT_TIME;
860         mark_inode_dirty(inode);
861         inode->i_count++;
862         d_instantiate(dentry, inode);
863         return 0;
864 }
865
866 #define PARENT_INO(buffer) \
867         ((struct ext2_dir_entry_2 *) ((char *) buffer + \
868         le16_to_cpu(((struct ext2_dir_entry_2 *) buffer)->rec_len)))->inode
869
870 /*
871  * Anybody can rename anything with this: the permission checks are left to the
872  * higher-level routines.
873  */
874 int obdfs_rename (struct inode * old_dir, struct dentry *old_dentry,
875                            struct inode * new_dir,struct dentry *new_dentry)
876 {
877         struct inode * old_inode, * new_inode;
878         struct page * old_page, * new_page, * dir_page;
879         struct ext2_dir_entry_2 * old_de, * new_de;
880         int retval;
881         struct obdfs_sb_info *sbi;
882
883         ENTRY;
884         sbi = old_dir->i_sb->u.generic_sbp;
885
886         new_page = dir_page = NULL;
887
888         old_page = obdfs_find_entry (old_dir, old_dentry->d_name.name, old_dentry->d_name.len, &old_de);
889         /*
890          *  Check for inode number is _not_ due to possible IO errors.
891          *  We might rmdir the source, keep it as pwd of some process
892          *  and merrily kill the link to whatever was created under the
893          *  same name. Goodbye sticky bit ;-<
894          */
895         old_inode = old_dentry->d_inode;
896         retval = -ENOENT;
897         if (!old_page || le32_to_cpu(old_de->inode) != old_inode->i_ino)
898                 goto end_rename;
899
900         new_inode = new_dentry->d_inode;
901         new_page = obdfs_find_entry (new_dir, new_dentry->d_name.name,
902                                 new_dentry->d_name.len, &new_de);
903         if (new_page) {
904                 if (!new_inode) {
905                         page_cache_release(new_page);
906                         new_page = NULL;
907                 } else {
908                         DQUOT_INIT(new_inode);
909                 }
910         }
911         if (S_ISDIR(old_inode->i_mode)) {
912                 if (new_inode) {
913                         retval = -ENOTEMPTY;
914                         if (!empty_dir (new_inode))
915                                 goto end_rename;
916                 }
917                 retval = -EIO;
918                 dir_page= obdfs_getpage (old_inode, 0, 0, LOCKED);
919                 if (!dir_page)
920                         goto end_rename;
921                 if (le32_to_cpu(PARENT_INO(page_address(dir_page))) != old_dir->i_ino)
922                         goto end_rename;
923                 retval = -EMLINK;
924                 if (!new_inode && new_dir!=old_dir &&
925                                 new_dir->i_nlink >= EXT2_LINK_MAX)
926                         goto end_rename;
927         }
928         if (!new_page) {
929                 new_page = obdfs_add_entry (new_dir, new_dentry->d_name.name,
930                                         new_dentry->d_name.len, &new_de,
931                                         &retval);
932                 if (!new_page)
933                         goto end_rename;
934         }
935         new_dir->i_version = ++event;
936
937         /*
938          * ok, that's it
939          */
940         new_de->inode = le32_to_cpu(old_inode->i_ino);
941         if (EXT2_HAS_INCOMPAT_FEATURE(new_dir->i_sb,
942                                       EXT2_FEATURE_INCOMPAT_FILETYPE))
943                 new_de->file_type = old_de->file_type;
944         
945         obdfs_delete_entry (old_de, old_page);
946
947         old_dir->i_version = ++event;
948         if (new_inode) {
949                 new_inode->i_nlink--;
950                 new_inode->i_ctime = CURRENT_TIME;
951                 mark_inode_dirty(new_inode);
952         }
953         old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
954         old_dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
955         mark_inode_dirty(old_dir);
956         if (dir_page) {
957                 PARENT_INO(page_address(dir_page)) = le32_to_cpu(new_dir->i_ino);
958                 sbi->osi_ops->o_brw(WRITE, sbi->osi_conn_info.conn_id, 
959                             new_dir->i_ino, dir_page, 0);
960                 old_dir->i_nlink--;
961                 mark_inode_dirty(old_dir);
962                 if (new_inode) {
963                         new_inode->i_nlink--;
964                         mark_inode_dirty(new_inode);
965                 } else {
966                         new_dir->i_nlink++;
967                         new_dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
968                         mark_inode_dirty(new_dir);
969                 }
970         }
971         sbi->osi_ops->o_brw(WRITE, sbi->osi_conn_info.conn_id, 
972                             old_inode->i_ino, old_page, 0);
973 #if 0
974         if (IS_SYNC(old_dir)) {
975                 ll_rw_block (WRITE, 1, &old_bh);
976                 wait_on_buffer (old_bh);
977         }
978 #endif
979         sbi->osi_ops->o_brw(WRITE, sbi->osi_conn_info.conn_id, 
980                             new_inode->i_ino, new_page, 0);
981 #if 0
982         if (IS_SYNC(new_dir)) {
983                 ll_rw_block (WRITE, 1, &new_bh);
984                 wait_on_buffer (new_bh);
985         }
986 #endif
987
988         retval = 0;
989
990 end_rename:
991         if (old_page)
992                 page_cache_release(old_page);
993         if (new_page)
994                 page_cache_release(new_page);
995         if (dir_page)
996                 page_cache_release(dir_page);
997         return retval;
998 }