Whamcloud - gitweb
merge b_devel into HEAD (20030703)
[fs/lustre-release.git] / lustre / llite / dir.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
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/dir.c
12  *  linux/fs/ext2/dir.c
13  *
14  *  Copyright (C) 1991, 1992  Linus Torvalds
15  *
16  *  ext2 directory handling functions
17  *
18  *  Big-endian to little-endian byte-swapping/bitmaps by
19  *        David S. Miller (davem@caip.rutgers.edu), 1995
20  *
21  *  All code that works with directory layout had been switched to pagecache
22  *  and moved here. AV
23  *
24  *  Adapted for Lustre Light
25  *  Copyright (C) 2002-2003, Cluster File Systems, Inc.
26  *
27  */
28
29 #include <linux/fs.h>
30 #include <linux/ext2_fs.h>
31 #include <linux/pagemap.h>
32 #include <linux/mm.h>
33 #include <linux/version.h>
34 #include <linux/smp_lock.h>
35 #include <asm/uaccess.h>
36 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
37 #include <linux/locks.h>   // for wait_on_buffer
38 #else
39 #include <linux/buffer_head.h>   // for wait_on_buffer
40 #endif
41
42 #define DEBUG_SUBSYSTEM S_LLITE
43
44 #include <linux/obd_support.h>
45 #include <linux/obd_class.h>
46 #include <linux/lustre_lib.h>
47 #include <linux/lustre_idl.h>
48 #include <linux/lustre_mds.h>
49 #include <linux/lustre_lite.h>
50 #include <linux/lustre_dlm.h>
51
52 typedef struct ext2_dir_entry_2 ext2_dirent;
53
54 #define PageChecked(page)        test_bit(PG_checked, &(page)->flags)
55 #define SetPageChecked(page)     set_bit(PG_checked, &(page)->flags)
56
57
58 static int ll_dir_prepare_write(struct file *file, struct page *page,
59                                 unsigned from, unsigned to)
60 {
61         CDEBUG(D_VFSTRACE, "VFS Op:\n");
62         return 0;
63 }
64
65 /* returns the page unlocked, but with a reference */
66 static int ll_dir_readpage(struct file *file, struct page *page)
67 {
68         struct inode *inode = page->mapping->host;
69         struct ll_sb_info *sbi = ll_i2sbi(inode);
70         __u64 offset;
71         int rc = 0;
72         struct ptlrpc_request *request;
73         struct lustre_handle lockh;
74         struct mds_body *body;
75         struct lookup_intent it = { .it_op = IT_READDIR };
76         struct mdc_op_data data;
77         struct obd_device *obddev = class_conn2obd(&sbi->ll_mdc_conn);
78         struct ldlm_res_id res_id =
79                 { .name = {inode->i_ino, (__u64)inode->i_generation} };
80         int flags = LDLM_FL_BLOCK_GRANTED | LDLM_FL_MATCH_DATA;
81         ENTRY;
82
83         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n", inode->i_ino,
84                inode->i_generation, inode);
85         if ((inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_SHIFT <= page->index){
86                 /* XXX why do we need this exactly, and why do we think that
87                  *     an all-zero directory page is useful?
88                  */
89                 CERROR("memsetting dir page %lu to zero (size %lld)\n",
90                        page->index, inode->i_size);
91                 memset(kmap(page), 0, PAGE_CACHE_SIZE);
92                 kunmap(page);
93                 GOTO(readpage_out, rc);
94         }
95
96         rc = ldlm_lock_match(obddev->obd_namespace, flags, &res_id,
97                              LDLM_PLAIN, NULL, 0, LCK_PR, inode,
98                              &lockh);
99         if (!rc) {
100                 ll_prepare_mdc_op_data(&data, inode, NULL, NULL, 0, 0);
101                 
102                 rc = mdc_enqueue(&sbi->ll_mdc_conn, LDLM_PLAIN, &it, LCK_PR,
103                                  &data, &lockh, NULL, 0,
104                                  ldlm_completion_ast, ll_mdc_blocking_ast,
105                                  inode);
106                 request = (struct ptlrpc_request *)it.it_data;
107                 if (request)
108                         ptlrpc_req_finished(request);
109                 if (rc < 0) {
110                         CERROR("lock enqueue: err: %d\n", rc);
111                         unlock_page(page);
112                         RETURN(rc);
113                 }
114         }
115         ldlm_lock_dump_handle(D_OTHER, &lockh);
116
117         if (PageUptodate(page)) {
118                 CERROR("Explain this please?\n");
119                 GOTO(readpage_out, rc);
120         }
121
122         offset = page->index << PAGE_SHIFT;
123         rc = mdc_readpage(&sbi->ll_mdc_conn, inode->i_ino,
124                           S_IFDIR, offset, page, &request);
125         if (!rc) {
126                 body = lustre_msg_buf(request->rq_repmsg, 0, sizeof (*body));
127                 LASSERT (body != NULL);         /* checked by mdc_readpage() */
128                 LASSERT_REPSWABBED (request, 0); /* swabbed by mdc_readpage() */
129
130                 inode->i_size = body->size;
131         }
132         ptlrpc_req_finished(request);
133         EXIT;
134
135  readpage_out:
136         if (!rc)
137                 SetPageUptodate(page);
138
139         unlock_page(page);
140         ll_unlock(LCK_PR, &lockh);
141         if (rc != ELDLM_OK)
142                 CERROR("ll_unlock: err: %d\n", rc);
143         return rc;
144 }
145
146 struct address_space_operations ll_dir_aops = {
147         readpage: ll_dir_readpage,
148         prepare_write: ll_dir_prepare_write
149 };
150
151 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3))
152 int waitfor_one_page(struct page *page)
153 {
154         int error = 0;
155         struct buffer_head *bh, *head = page->buffers;
156
157         bh = head;
158         do {
159                 wait_on_buffer(bh);
160                 if (buffer_req(bh) && !buffer_uptodate(bh))
161                         error = -EIO;
162         } while ((bh = bh->b_this_page) != head);
163         return error;
164 }
165 #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
166 int waitfor_one_page(struct page *page)
167 {
168         wait_on_page_locked(page);
169         return 0;
170 }
171 #endif
172
173 /*
174  * ext2 uses block-sized chunks. Arguably, sector-sized ones would be
175  * more robust, but we have what we have
176  */
177 static inline unsigned ext2_chunk_size(struct inode *inode)
178 {
179         return inode->i_sb->s_blocksize;
180 }
181
182 static inline void ext2_put_page(struct page *page)
183 {
184         kunmap(page);
185         page_cache_release(page);
186 }
187
188 static inline unsigned long dir_pages(struct inode *inode)
189 {
190         return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT;
191 }
192
193 extern void set_page_clean(struct page *page);
194
195 static int ext2_commit_chunk(struct page *page, unsigned from, unsigned to)
196 {
197         struct inode *dir = page->mapping->host;
198         loff_t new_size = (page->index << PAGE_CACHE_SHIFT) + to;
199         int err = 0;
200
201 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
202         dir->i_version = ++event;
203 #endif
204         if (new_size > dir->i_size)
205                 dir->i_size = new_size;
206         SetPageUptodate(page);
207         set_page_clean(page);
208
209         //page->mapping->a_ops->commit_write(NULL, page, from, to);
210         //if (IS_SYNC(dir))
211         //      err = waitfor_one_page(page);
212         return err;
213 }
214
215 static void ext2_check_page(struct page *page)
216 {
217         struct inode *dir = page->mapping->host;
218         unsigned chunk_size = ext2_chunk_size(dir);
219         char *kaddr = page_address(page);
220         //      u32 max_inumber = le32_to_cpu(sb->u.ext2_sb.s_es->s_inodes_count);
221         unsigned offs, rec_len;
222         unsigned limit = PAGE_CACHE_SIZE;
223         ext2_dirent *p;
224         char *error;
225
226         if ((dir->i_size >> PAGE_CACHE_SHIFT) == page->index) {
227                 limit = dir->i_size & ~PAGE_CACHE_MASK;
228                 if (limit & (chunk_size - 1)) {
229                         CERROR("limit %d dir size %lld index %ld\n",
230                                limit, dir->i_size, page->index);
231                         goto Ebadsize;
232                 }
233                 for (offs = limit; offs<PAGE_CACHE_SIZE; offs += chunk_size) {
234                         ext2_dirent *p = (ext2_dirent*)(kaddr + offs);
235                         p->rec_len = cpu_to_le16(chunk_size);
236                         p->name_len = 0;
237                         p->inode = 0;
238                 }
239                 if (!limit)
240                         goto out;
241         }
242         for (offs = 0; offs <= limit - EXT2_DIR_REC_LEN(1); offs += rec_len) {
243                 p = (ext2_dirent *)(kaddr + offs);
244                 rec_len = le16_to_cpu(p->rec_len);
245
246                 if (rec_len < EXT2_DIR_REC_LEN(1))
247                         goto Eshort;
248                 if (rec_len & 3)
249                         goto Ealign;
250                 if (rec_len < EXT2_DIR_REC_LEN(p->name_len))
251                         goto Enamelen;
252                 if (((offs + rec_len - 1) ^ offs) & ~(chunk_size-1))
253                         goto Espan;
254                 //              if (le32_to_cpu(p->inode) > max_inumber)
255                 //goto Einumber;
256         }
257         if (offs != limit)
258                 goto Eend;
259 out:
260         SetPageChecked(page);
261         return;
262
263         /* Too bad, we had an error */
264
265 Ebadsize:
266         CERROR("ext2_check_page"
267                 "size of directory #%lu is not a multiple of chunk size\n",
268                 dir->i_ino
269         );
270         goto fail;
271 Eshort:
272         error = "rec_len is smaller than minimal";
273         goto bad_entry;
274 Ealign:
275         error = "unaligned directory entry";
276         goto bad_entry;
277 Enamelen:
278         error = "rec_len is too small for name_len";
279         goto bad_entry;
280 Espan:
281         error = "directory entry across blocks";
282         goto bad_entry;
283         //Einumber:
284         // error = "inode out of bounds";
285 bad_entry:
286         CERROR("ext2_check_page: bad entry in directory #%lu: %s - "
287                 "offset=%lu+%u, inode=%lu, rec_len=%d, name_len=%d",
288                 dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT), offs,
289                 (unsigned long) le32_to_cpu(p->inode),
290                 rec_len, p->name_len);
291         goto fail;
292 Eend:
293         p = (ext2_dirent *)(kaddr + offs);
294         CERROR("ext2_check_page"
295                 "entry in directory #%lu spans the page boundary"
296                 "offset=%lu, inode=%lu",
297                 dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
298                 (unsigned long) le32_to_cpu(p->inode));
299 fail:
300         SetPageChecked(page);
301         SetPageError(page);
302         LBUG();
303 }
304
305 static struct page *ll_get_dir_page(struct inode *dir, unsigned long n)
306 {
307         struct address_space *mapping = dir->i_mapping;
308         struct page *page = read_cache_page(mapping, n,
309                                 (filler_t*)mapping->a_ops->readpage, NULL);
310         if (!IS_ERR(page)) {
311                 wait_on_page(page);
312                 kmap(page);
313                 if (!PageUptodate(page))
314                         goto fail;
315                 if (!PageChecked(page))
316                         ext2_check_page(page);
317                 if (PageError(page))
318                         goto fail;
319         }
320         return page;
321
322 fail:
323         ext2_put_page(page);
324         return ERR_PTR(-EIO);
325 }
326
327 /*
328  * NOTE! unlike strncmp, ext2_match returns 1 for success, 0 for failure.
329  *
330  * len <= EXT2_NAME_LEN and de != NULL are guaranteed by caller.
331  */
332 static inline int ext2_match (int len, const char * const name,
333                                         struct ext2_dir_entry_2 * de)
334 {
335         if (len != de->name_len)
336                 return 0;
337         if (!de->inode)
338                 return 0;
339         return !memcmp(name, de->name, len);
340 }
341
342 /*
343  * p is at least 6 bytes before the end of page
344  */
345 static inline ext2_dirent *ext2_next_entry(ext2_dirent *p)
346 {
347         return (ext2_dirent *)((char*)p + le16_to_cpu(p->rec_len));
348 }
349
350 static inline unsigned
351 ext2_validate_entry(char *base, unsigned offset, unsigned mask)
352 {
353         ext2_dirent *de = (ext2_dirent*)(base + offset);
354         ext2_dirent *p = (ext2_dirent*)(base + (offset&mask));
355         while ((char*)p < (char*)de)
356                 p = ext2_next_entry(p);
357         return (char *)p - base;
358 }
359
360 static unsigned char ext2_filetype_table[EXT2_FT_MAX] = {
361         [EXT2_FT_UNKNOWN]       DT_UNKNOWN,
362         [EXT2_FT_REG_FILE]      DT_REG,
363         [EXT2_FT_DIR]           DT_DIR,
364         [EXT2_FT_CHRDEV]        DT_CHR,
365         [EXT2_FT_BLKDEV]        DT_BLK,
366         [EXT2_FT_FIFO]          DT_FIFO,
367         [EXT2_FT_SOCK]          DT_SOCK,
368         [EXT2_FT_SYMLINK]       DT_LNK,
369 };
370
371 static unsigned int ll_dt2fmt[DT_WHT + 1] = {
372         [EXT2_FT_UNKNOWN]       0,
373         [EXT2_FT_REG_FILE]      S_IFREG,
374         [EXT2_FT_DIR]           S_IFDIR,
375         [EXT2_FT_CHRDEV]        S_IFCHR,
376         [EXT2_FT_BLKDEV]        S_IFBLK,
377         [EXT2_FT_FIFO]          S_IFIFO,
378         [EXT2_FT_SOCK]          S_IFSOCK,
379         [EXT2_FT_SYMLINK]       S_IFLNK
380 };
381
382 #define S_SHIFT 12
383 static unsigned char ext2_type_by_mode[S_IFMT >> S_SHIFT] = {
384         [S_IFREG >> S_SHIFT]    EXT2_FT_REG_FILE,
385         [S_IFDIR >> S_SHIFT]    EXT2_FT_DIR,
386         [S_IFCHR >> S_SHIFT]    EXT2_FT_CHRDEV,
387         [S_IFBLK >> S_SHIFT]    EXT2_FT_BLKDEV,
388         [S_IFIFO >> S_SHIFT]    EXT2_FT_FIFO,
389         [S_IFSOCK >> S_SHIFT]   EXT2_FT_SOCK,
390         [S_IFLNK >> S_SHIFT]    EXT2_FT_SYMLINK,
391 };
392
393 static inline void ext2_set_de_type(ext2_dirent *de, struct inode *inode)
394 {
395         mode_t mode = inode->i_mode;
396         de->file_type = ext2_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
397 }
398
399 int ll_readdir(struct file * filp, void * dirent, filldir_t filldir)
400 {
401         loff_t pos = filp->f_pos;
402         struct inode *inode = filp->f_dentry->d_inode;
403         // XXX struct super_block *sb = inode->i_sb;
404         unsigned offset = pos & ~PAGE_CACHE_MASK;
405         unsigned long n = pos >> PAGE_CACHE_SHIFT;
406         unsigned long npages = dir_pages(inode);
407         unsigned chunk_mask = ~(ext2_chunk_size(inode)-1);
408         unsigned char *types = NULL;
409         int need_revalidate = (filp->f_version != inode->i_version);
410         ENTRY;
411
412         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n", inode->i_ino,
413                inode->i_generation, inode);
414         if (pos > inode->i_size - EXT2_DIR_REC_LEN(1))
415                 GOTO(done, 0);
416
417         types = ext2_filetype_table;
418
419         for ( ; n < npages; n++, offset = 0) {
420                 char *kaddr, *limit;
421                 ext2_dirent *de;
422                 struct page *page;
423
424                 CDEBUG(D_EXT2, "reading %lu of dir %lu page %lu, size %llu\n",
425                        PAGE_CACHE_SIZE, inode->i_ino, n, inode->i_size);
426                 page = ll_get_dir_page(inode, n);
427
428                 /* size might have been updated by mdc_readpage */
429                 npages = dir_pages(inode);
430
431                 if (IS_ERR(page))
432                         continue;
433                 kaddr = page_address(page);
434                 if (need_revalidate) {
435                         offset = ext2_validate_entry(kaddr, offset, chunk_mask);
436                         need_revalidate = 0;
437                 }
438                 de = (ext2_dirent *)(kaddr+offset);
439                 limit = kaddr + PAGE_CACHE_SIZE - EXT2_DIR_REC_LEN(1);
440                 for ( ;(char*)de <= limit; de = ext2_next_entry(de))
441                         if (de->inode) {
442                                 int over;
443                                 unsigned char d_type = DT_UNKNOWN;
444
445                                 if (types && de->file_type < EXT2_FT_MAX)
446                                         d_type = types[de->file_type];
447
448                                 offset = (char *)de - kaddr;
449                                 over = filldir(dirent, de->name, de->name_len,
450                                                (n<<PAGE_CACHE_SHIFT) | offset,
451                                                le32_to_cpu(de->inode), d_type);
452                                 if (over) {
453                                         ext2_put_page(page);
454                                         GOTO(done,0);
455                                 }
456                         }
457                 ext2_put_page(page);
458         }
459
460 done:
461         filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
462         filp->f_version = inode->i_version;
463         UPDATE_ATIME(inode);
464         RETURN(0);
465 }
466
467 /*
468  *      ext2_find_entry()
469  *
470  * finds an entry in the specified directory with the wanted name. It
471  * returns the page in which the entry was found, and the entry itself
472  * (as a parameter - res_dir). Page is returned mapped and unlocked.
473  * Entry is guaranteed to be valid.
474  */
475 struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
476                         struct dentry *dentry, struct page ** res_page)
477 {
478         const char *name = dentry->d_name.name;
479         int namelen = dentry->d_name.len;
480         unsigned reclen = EXT2_DIR_REC_LEN(namelen);
481         unsigned long start, n;
482         unsigned long npages = dir_pages(dir);
483         struct page *page = NULL;
484         ext2_dirent * de;
485
486         /* OFFSET_CACHE */
487         *res_page = NULL;
488
489         //      start = dir->u.ext2_i.i_dir_start_lookup;
490         start = 0;
491         if (start >= npages)
492                 start = 0;
493         n = start;
494         do {
495                 char *kaddr;
496                 page = ll_get_dir_page(dir, n);
497                 if (!IS_ERR(page)) {
498                         kaddr = page_address(page);
499                         de = (ext2_dirent *) kaddr;
500                         kaddr += PAGE_CACHE_SIZE - reclen;
501                         while ((char *) de <= kaddr) {
502                                 if (ext2_match (namelen, name, de))
503                                         goto found;
504                                 de = ext2_next_entry(de);
505                         }
506                         ext2_put_page(page);
507                 }
508                 if (++n >= npages)
509                         n = 0;
510         } while (n != start);
511         return NULL;
512
513 found:
514         *res_page = page;
515         //      dir->u.ext2_i.i_dir_start_lookup = n;
516         return de;
517 }
518
519 struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p)
520 {
521         struct page *page = ll_get_dir_page(dir, 0);
522         ext2_dirent *de = NULL;
523
524         if (!IS_ERR(page)) {
525                 de = ext2_next_entry((ext2_dirent *) page_address(page));
526                 *p = page;
527         }
528         return de;
529 }
530
531 obd_id ll_inode_by_name(struct inode * dir, struct dentry *dentry, int *type)
532 {
533         obd_id res = 0;
534         struct ext2_dir_entry_2 * de;
535         struct page *page;
536
537         de = ext2_find_entry (dir, dentry, &page);
538         if (de) {
539                 res = le32_to_cpu(de->inode);
540                 *type = ll_dt2fmt[de->file_type];
541                 kunmap(page);
542                 page_cache_release(page);
543         }
544         return res;
545 }
546
547 /* Releases the page */
548 void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
549                         struct page *page, struct inode *inode)
550 {
551         unsigned from = (char *) de - (char *) page_address(page);
552         unsigned to = from + le16_to_cpu(de->rec_len);
553         int err;
554
555         lock_page(page);
556         err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
557         if (err)
558                 LBUG();
559         de->inode = cpu_to_le32(inode->i_ino);
560         ext2_set_de_type (de, inode);
561         dir->i_mtime = dir->i_ctime = CURRENT_TIME;
562         err = ext2_commit_chunk(page, from, to);
563         unlock_page(page);
564         ext2_put_page(page);
565 }
566
567 /*
568  *      Parent is locked.
569  */
570 int ll_add_link (struct dentry *dentry, struct inode *inode)
571 {
572         struct inode *dir = dentry->d_parent->d_inode;
573         const char *name = dentry->d_name.name;
574         int namelen = dentry->d_name.len;
575         unsigned reclen = EXT2_DIR_REC_LEN(namelen);
576         unsigned short rec_len, name_len;
577         struct page *page = NULL;
578         ext2_dirent * de;
579         unsigned long npages = dir_pages(dir);
580         unsigned long n;
581         char *kaddr;
582         unsigned from, to;
583         int err;
584
585         /* We take care of directory expansion in the same loop */
586         for (n = 0; n <= npages; n++) {
587                 page = ll_get_dir_page(dir, n);
588                 err = PTR_ERR(page);
589                 if (IS_ERR(page))
590                         goto out;
591                 kaddr = page_address(page);
592                 de = (ext2_dirent *)kaddr;
593                 kaddr += PAGE_CACHE_SIZE - reclen;
594                 while ((char *)de <= kaddr) {
595                         err = -EEXIST;
596                         if (ext2_match (namelen, name, de))
597                                 goto out_page;
598                         name_len = EXT2_DIR_REC_LEN(de->name_len);
599                         rec_len = le16_to_cpu(de->rec_len);
600                         if ( n==npages && rec_len == 0) {
601                                 CERROR("Fatal dir behaviour\n");
602                                 goto out_page;
603                         }
604                         if (!de->inode && rec_len >= reclen)
605                                 goto got_it;
606                         if (rec_len >= name_len + reclen)
607                                 goto got_it;
608                         de = (ext2_dirent *) ((char *) de + rec_len);
609                 }
610                 ext2_put_page(page);
611         }
612         LBUG();
613         return -EINVAL;
614
615 got_it:
616         from = (char*)de - (char*)page_address(page);
617         to = from + rec_len;
618         lock_page(page);
619         err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
620         if (err)
621                 goto out_unlock;
622         if (de->inode) {
623                 ext2_dirent *de1 = (ext2_dirent *) ((char *) de + name_len);
624                 de1->rec_len = cpu_to_le16(rec_len - name_len);
625                 de->rec_len = cpu_to_le16(name_len);
626                 de = de1;
627         }
628         de->name_len = namelen;
629         memcpy (de->name, name, namelen);
630         de->inode = cpu_to_le32(inode->i_ino);
631         ext2_set_de_type (de, inode);
632         CDEBUG(D_INODE, "type set to %o\n", de->file_type);
633         dir->i_mtime = dir->i_ctime = CURRENT_TIME;
634         err = ext2_commit_chunk(page, from, to);
635
636         // change_inode happens with the commit_chunk
637         /* XXX OFFSET_CACHE */
638
639 out_unlock:
640         unlock_page(page);
641 out_page:
642         ext2_put_page(page);
643 out:
644         return err;
645 }
646
647 /*
648  * ext2_delete_entry deletes a directory entry by merging it with the
649  * previous entry. Page is up-to-date. Releases the page.
650  */
651 int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
652 {
653         struct address_space *mapping = page->mapping;
654         struct inode *inode = mapping->host;
655         char *kaddr = page_address(page);
656         unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1);
657         unsigned to = ((char*)dir - kaddr) + le16_to_cpu(dir->rec_len);
658         ext2_dirent * pde = NULL;
659         ext2_dirent * de = (ext2_dirent *) (kaddr + from);
660         int err;
661
662         while ((char*)de < (char*)dir) {
663                 pde = de;
664                 de = ext2_next_entry(de);
665         }
666         if (pde)
667                 from = (char*)pde - (char*)page_address(page);
668         lock_page(page);
669         err = mapping->a_ops->prepare_write(NULL, page, from, to);
670         if (err)
671                 LBUG();
672         if (pde)
673                 pde->rec_len = cpu_to_le16(to-from);
674         dir->inode = 0;
675         inode->i_ctime = inode->i_mtime = CURRENT_TIME;
676         err = ext2_commit_chunk(page, from, to);
677         unlock_page(page);
678         ext2_put_page(page);
679         return err;
680 }
681
682 /*
683  * Set the first fragment of directory.
684  */
685 int ext2_make_empty(struct inode *inode, struct inode *parent)
686 {
687         struct address_space *mapping = inode->i_mapping;
688         struct page *page = grab_cache_page(mapping, 0);
689         unsigned chunk_size = ext2_chunk_size(inode);
690         struct ext2_dir_entry_2 * de;
691         char *base;
692         int err;
693         ENTRY;
694
695         if (!page)
696                 return -ENOMEM;
697         base = kmap(page);
698         if (!base)
699                 return -ENOMEM;
700
701         err = mapping->a_ops->prepare_write(NULL, page, 0, chunk_size);
702         if (err)
703                 goto fail;
704
705         de = (struct ext2_dir_entry_2 *) base;
706         de->name_len = 1;
707         de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(1));
708         memcpy (de->name, ".\0\0", 4);
709         de->inode = cpu_to_le32(inode->i_ino);
710         ext2_set_de_type (de, inode);
711
712         de = (struct ext2_dir_entry_2 *) (base + EXT2_DIR_REC_LEN(1));
713         de->name_len = 2;
714         de->rec_len = cpu_to_le16(chunk_size - EXT2_DIR_REC_LEN(1));
715         de->inode = cpu_to_le32(parent->i_ino);
716         memcpy (de->name, "..\0", 4);
717         ext2_set_de_type (de, inode);
718
719         err = ext2_commit_chunk(page, 0, chunk_size);
720 fail:
721         kunmap(page);
722         unlock_page(page);
723         page_cache_release(page);
724         ENTRY;
725         return err;
726 }
727
728 /*
729  * routine to check that the specified directory is empty (for rmdir)
730  */
731 int ext2_empty_dir (struct inode * inode)
732 {
733         struct page *page = NULL;
734         unsigned long i, npages = dir_pages(inode);
735
736         for (i = 0; i < npages; i++) {
737                 char *kaddr;
738                 ext2_dirent * de;
739                 page = ll_get_dir_page(inode, i);
740
741                 if (IS_ERR(page))
742                         continue;
743
744                 kaddr = page_address(page);
745                 de = (ext2_dirent *)kaddr;
746                 kaddr += PAGE_CACHE_SIZE-EXT2_DIR_REC_LEN(1);
747
748                 while ((char *)de <= kaddr) {
749                         if (de->inode != 0) {
750                                 /* check for . and .. */
751                                 if (de->name[0] != '.')
752                                         goto not_empty;
753                                 if (de->name_len > 2)
754                                         goto not_empty;
755                                 if (de->name_len < 2) {
756                                         if (de->inode !=
757                                             cpu_to_le32(inode->i_ino))
758                                                 goto not_empty;
759                                 } else if (de->name[1] != '.')
760                                         goto not_empty;
761                         }
762                         de = ext2_next_entry(de);
763                 }
764                 ext2_put_page(page);
765         }
766         return 1;
767
768 not_empty:
769         ext2_put_page(page);
770         return 0;
771 }
772
773 static int ll_dir_ioctl(struct inode *inode, struct file *file,
774                         unsigned int cmd, unsigned long arg)
775 {
776         struct ll_sb_info *sbi = ll_i2sbi(inode);
777         struct obd_ioctl_data *data;
778         ENTRY;
779         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p),cmd=%u\n", inode->i_ino,
780                inode->i_generation, inode, cmd);
781
782         if (_IOC_TYPE(cmd) == 'T') /* tty ioctls */
783                 return -ENOTTY;
784
785         switch(cmd) {
786         case IOC_MDC_LOOKUP: {
787                 struct ptlrpc_request *request = NULL;
788                 struct ll_fid fid;
789                 char *buf = NULL;
790                 struct mds_body *body;
791                 char *filename;
792                 int namelen, rc, err, len = 0;
793                 unsigned long valid;
794
795                 rc = obd_ioctl_getdata(&buf, &len, (void *)arg);
796                 if (rc)
797                         RETURN(rc);
798                 data = (void *)buf;
799
800                 filename = data->ioc_inlbuf1;
801                 namelen = data->ioc_inllen1;
802
803                 if (namelen < 1) {
804                         CERROR("IOC_MDC_LOOKUP missing filename\n");
805                         GOTO(out, rc = -EINVAL);
806                 }
807
808                 valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLSIZE;
809                 ll_inode2fid(&fid, inode);
810                 rc = mdc_getattr_name(&sbi->ll_mdc_conn, &fid,
811                                       filename, namelen, valid, 0, &request);
812                 if (rc < 0) {
813                         CERROR("mdc_getattr_name: %d\n", rc);
814                         GOTO(out, rc);
815                 }
816
817                 body = lustre_msg_buf(request->rq_repmsg, 0, sizeof (*body));
818                 LASSERT(body != NULL);         /* checked by mdc_getattr_name */
819                 LASSERT_REPSWABBED(request, 0);/* swabbed by mdc_getattr_name */
820
821                 /* surely there's a better way -phik */
822                 data->ioc_obdo1.o_mode = body->mode;
823                 data->ioc_obdo1.o_uid = body->uid;
824                 data->ioc_obdo1.o_gid = body->gid;
825
826                 ptlrpc_req_finished(request);
827
828                 err = copy_to_user((void *)arg, buf, len);
829                 if (err)
830                         GOTO(out, rc = -EFAULT);
831
832                 EXIT;
833         out:
834                 obd_ioctl_freedata(buf, len);
835                 return rc;
836         }
837         default:
838                 CERROR("unrecognized ioctl %#x\n", cmd);
839                 RETURN(-ENOTTY);
840         }
841 }
842
843 int ll_dir_open(struct inode *inode, struct file *file)
844 {
845         return ll_file_open(inode, file);
846 }
847
848 int ll_dir_release(struct inode *inode, struct file *file)
849 {
850         return ll_file_release(inode, file);
851 }
852
853 struct file_operations ll_dir_operations = {
854         open: ll_dir_open,
855         release: ll_dir_release,
856         read: generic_read_dir,
857         readdir: ll_readdir,
858         ioctl: ll_dir_ioctl
859 };
860