GNU Linux-libre 4.9.308-gnu1
[releases.git] / fs / minix / dir.c
1 /*
2  *  linux/fs/minix/dir.c
3  *
4  *  Copyright (C) 1991, 1992 Linus Torvalds
5  *
6  *  minix directory handling functions
7  *
8  *  Updated to filesystem version 3 by Daniel Aragones
9  */
10
11 #include "minix.h"
12 #include <linux/buffer_head.h>
13 #include <linux/highmem.h>
14 #include <linux/swap.h>
15
16 typedef struct minix_dir_entry minix_dirent;
17 typedef struct minix3_dir_entry minix3_dirent;
18
19 static int minix_readdir(struct file *, struct dir_context *);
20
21 const struct file_operations minix_dir_operations = {
22         .llseek         = generic_file_llseek,
23         .read           = generic_read_dir,
24         .iterate_shared = minix_readdir,
25         .fsync          = generic_file_fsync,
26 };
27
28 static inline void dir_put_page(struct page *page)
29 {
30         kunmap(page);
31         put_page(page);
32 }
33
34 /*
35  * Return the offset into page `page_nr' of the last valid
36  * byte in that page, plus one.
37  */
38 static unsigned
39 minix_last_byte(struct inode *inode, unsigned long page_nr)
40 {
41         unsigned last_byte = PAGE_SIZE;
42
43         if (page_nr == (inode->i_size >> PAGE_SHIFT))
44                 last_byte = inode->i_size & (PAGE_SIZE - 1);
45         return last_byte;
46 }
47
48 static int dir_commit_chunk(struct page *page, loff_t pos, unsigned len)
49 {
50         struct address_space *mapping = page->mapping;
51         struct inode *dir = mapping->host;
52         int err = 0;
53         block_write_end(NULL, mapping, pos, len, len, page, NULL);
54
55         if (pos+len > dir->i_size) {
56                 i_size_write(dir, pos+len);
57                 mark_inode_dirty(dir);
58         }
59         if (IS_DIRSYNC(dir))
60                 err = write_one_page(page, 1);
61         else
62                 unlock_page(page);
63         return err;
64 }
65
66 static struct page * dir_get_page(struct inode *dir, unsigned long n)
67 {
68         struct address_space *mapping = dir->i_mapping;
69         struct page *page = read_mapping_page(mapping, n, NULL);
70         if (!IS_ERR(page))
71                 kmap(page);
72         return page;
73 }
74
75 static inline void *minix_next_entry(void *de, struct minix_sb_info *sbi)
76 {
77         return (void*)((char*)de + sbi->s_dirsize);
78 }
79
80 static int minix_readdir(struct file *file, struct dir_context *ctx)
81 {
82         struct inode *inode = file_inode(file);
83         struct super_block *sb = inode->i_sb;
84         struct minix_sb_info *sbi = minix_sb(sb);
85         unsigned chunk_size = sbi->s_dirsize;
86         unsigned long npages = dir_pages(inode);
87         unsigned long pos = ctx->pos;
88         unsigned offset;
89         unsigned long n;
90
91         ctx->pos = pos = ALIGN(pos, chunk_size);
92         if (pos >= inode->i_size)
93                 return 0;
94
95         offset = pos & ~PAGE_MASK;
96         n = pos >> PAGE_SHIFT;
97
98         for ( ; n < npages; n++, offset = 0) {
99                 char *p, *kaddr, *limit;
100                 struct page *page = dir_get_page(inode, n);
101
102                 if (IS_ERR(page))
103                         continue;
104                 kaddr = (char *)page_address(page);
105                 p = kaddr+offset;
106                 limit = kaddr + minix_last_byte(inode, n) - chunk_size;
107                 for ( ; p <= limit; p = minix_next_entry(p, sbi)) {
108                         const char *name;
109                         __u32 inumber;
110                         if (sbi->s_version == MINIX_V3) {
111                                 minix3_dirent *de3 = (minix3_dirent *)p;
112                                 name = de3->name;
113                                 inumber = de3->inode;
114                         } else {
115                                 minix_dirent *de = (minix_dirent *)p;
116                                 name = de->name;
117                                 inumber = de->inode;
118                         }
119                         if (inumber) {
120                                 unsigned l = strnlen(name, sbi->s_namelen);
121                                 if (!dir_emit(ctx, name, l,
122                                               inumber, DT_UNKNOWN)) {
123                                         dir_put_page(page);
124                                         return 0;
125                                 }
126                         }
127                         ctx->pos += chunk_size;
128                 }
129                 dir_put_page(page);
130         }
131         return 0;
132 }
133
134 static inline int namecompare(int len, int maxlen,
135         const char * name, const char * buffer)
136 {
137         if (len < maxlen && buffer[len])
138                 return 0;
139         return !memcmp(name, buffer, len);
140 }
141
142 /*
143  *      minix_find_entry()
144  *
145  * finds an entry in the specified directory with the wanted name. It
146  * returns the cache buffer in which the entry was found, and the entry
147  * itself (as a parameter - res_dir). It does NOT read the inode of the
148  * entry - you'll have to do that yourself if you want to.
149  */
150 minix_dirent *minix_find_entry(struct dentry *dentry, struct page **res_page)
151 {
152         const char * name = dentry->d_name.name;
153         int namelen = dentry->d_name.len;
154         struct inode * dir = d_inode(dentry->d_parent);
155         struct super_block * sb = dir->i_sb;
156         struct minix_sb_info * sbi = minix_sb(sb);
157         unsigned long n;
158         unsigned long npages = dir_pages(dir);
159         struct page *page = NULL;
160         char *p;
161
162         char *namx;
163         __u32 inumber;
164         *res_page = NULL;
165
166         for (n = 0; n < npages; n++) {
167                 char *kaddr, *limit;
168
169                 page = dir_get_page(dir, n);
170                 if (IS_ERR(page))
171                         continue;
172
173                 kaddr = (char*)page_address(page);
174                 limit = kaddr + minix_last_byte(dir, n) - sbi->s_dirsize;
175                 for (p = kaddr; p <= limit; p = minix_next_entry(p, sbi)) {
176                         if (sbi->s_version == MINIX_V3) {
177                                 minix3_dirent *de3 = (minix3_dirent *)p;
178                                 namx = de3->name;
179                                 inumber = de3->inode;
180                         } else {
181                                 minix_dirent *de = (minix_dirent *)p;
182                                 namx = de->name;
183                                 inumber = de->inode;
184                         }
185                         if (!inumber)
186                                 continue;
187                         if (namecompare(namelen, sbi->s_namelen, name, namx))
188                                 goto found;
189                 }
190                 dir_put_page(page);
191         }
192         return NULL;
193
194 found:
195         *res_page = page;
196         return (minix_dirent *)p;
197 }
198
199 int minix_add_link(struct dentry *dentry, struct inode *inode)
200 {
201         struct inode *dir = d_inode(dentry->d_parent);
202         const char * name = dentry->d_name.name;
203         int namelen = dentry->d_name.len;
204         struct super_block * sb = dir->i_sb;
205         struct minix_sb_info * sbi = minix_sb(sb);
206         struct page *page = NULL;
207         unsigned long npages = dir_pages(dir);
208         unsigned long n;
209         char *kaddr, *p;
210         minix_dirent *de;
211         minix3_dirent *de3;
212         loff_t pos;
213         int err;
214         char *namx = NULL;
215         __u32 inumber;
216
217         /*
218          * We take care of directory expansion in the same loop
219          * This code plays outside i_size, so it locks the page
220          * to protect that region.
221          */
222         for (n = 0; n <= npages; n++) {
223                 char *limit, *dir_end;
224
225                 page = dir_get_page(dir, n);
226                 err = PTR_ERR(page);
227                 if (IS_ERR(page))
228                         goto out;
229                 lock_page(page);
230                 kaddr = (char*)page_address(page);
231                 dir_end = kaddr + minix_last_byte(dir, n);
232                 limit = kaddr + PAGE_SIZE - sbi->s_dirsize;
233                 for (p = kaddr; p <= limit; p = minix_next_entry(p, sbi)) {
234                         de = (minix_dirent *)p;
235                         de3 = (minix3_dirent *)p;
236                         if (sbi->s_version == MINIX_V3) {
237                                 namx = de3->name;
238                                 inumber = de3->inode;
239                         } else {
240                                 namx = de->name;
241                                 inumber = de->inode;
242                         }
243                         if (p == dir_end) {
244                                 /* We hit i_size */
245                                 if (sbi->s_version == MINIX_V3)
246                                         de3->inode = 0;
247                                 else
248                                         de->inode = 0;
249                                 goto got_it;
250                         }
251                         if (!inumber)
252                                 goto got_it;
253                         err = -EEXIST;
254                         if (namecompare(namelen, sbi->s_namelen, name, namx))
255                                 goto out_unlock;
256                 }
257                 unlock_page(page);
258                 dir_put_page(page);
259         }
260         BUG();
261         return -EINVAL;
262
263 got_it:
264         pos = page_offset(page) + p - (char *)page_address(page);
265         err = minix_prepare_chunk(page, pos, sbi->s_dirsize);
266         if (err)
267                 goto out_unlock;
268         memcpy (namx, name, namelen);
269         if (sbi->s_version == MINIX_V3) {
270                 memset (namx + namelen, 0, sbi->s_dirsize - namelen - 4);
271                 de3->inode = inode->i_ino;
272         } else {
273                 memset (namx + namelen, 0, sbi->s_dirsize - namelen - 2);
274                 de->inode = inode->i_ino;
275         }
276         err = dir_commit_chunk(page, pos, sbi->s_dirsize);
277         dir->i_mtime = dir->i_ctime = current_time(dir);
278         mark_inode_dirty(dir);
279 out_put:
280         dir_put_page(page);
281 out:
282         return err;
283 out_unlock:
284         unlock_page(page);
285         goto out_put;
286 }
287
288 int minix_delete_entry(struct minix_dir_entry *de, struct page *page)
289 {
290         struct inode *inode = page->mapping->host;
291         char *kaddr = page_address(page);
292         loff_t pos = page_offset(page) + (char*)de - kaddr;
293         struct minix_sb_info *sbi = minix_sb(inode->i_sb);
294         unsigned len = sbi->s_dirsize;
295         int err;
296
297         lock_page(page);
298         err = minix_prepare_chunk(page, pos, len);
299         if (err == 0) {
300                 if (sbi->s_version == MINIX_V3)
301                         ((minix3_dirent *) de)->inode = 0;
302                 else
303                         de->inode = 0;
304                 err = dir_commit_chunk(page, pos, len);
305         } else {
306                 unlock_page(page);
307         }
308         dir_put_page(page);
309         inode->i_ctime = inode->i_mtime = current_time(inode);
310         mark_inode_dirty(inode);
311         return err;
312 }
313
314 int minix_make_empty(struct inode *inode, struct inode *dir)
315 {
316         struct page *page = grab_cache_page(inode->i_mapping, 0);
317         struct minix_sb_info *sbi = minix_sb(inode->i_sb);
318         char *kaddr;
319         int err;
320
321         if (!page)
322                 return -ENOMEM;
323         err = minix_prepare_chunk(page, 0, 2 * sbi->s_dirsize);
324         if (err) {
325                 unlock_page(page);
326                 goto fail;
327         }
328
329         kaddr = kmap_atomic(page);
330         memset(kaddr, 0, PAGE_SIZE);
331
332         if (sbi->s_version == MINIX_V3) {
333                 minix3_dirent *de3 = (minix3_dirent *)kaddr;
334
335                 de3->inode = inode->i_ino;
336                 strcpy(de3->name, ".");
337                 de3 = minix_next_entry(de3, sbi);
338                 de3->inode = dir->i_ino;
339                 strcpy(de3->name, "..");
340         } else {
341                 minix_dirent *de = (minix_dirent *)kaddr;
342
343                 de->inode = inode->i_ino;
344                 strcpy(de->name, ".");
345                 de = minix_next_entry(de, sbi);
346                 de->inode = dir->i_ino;
347                 strcpy(de->name, "..");
348         }
349         kunmap_atomic(kaddr);
350
351         err = dir_commit_chunk(page, 0, 2 * sbi->s_dirsize);
352 fail:
353         put_page(page);
354         return err;
355 }
356
357 /*
358  * routine to check that the specified directory is empty (for rmdir)
359  */
360 int minix_empty_dir(struct inode * inode)
361 {
362         struct page *page = NULL;
363         unsigned long i, npages = dir_pages(inode);
364         struct minix_sb_info *sbi = minix_sb(inode->i_sb);
365         char *name;
366         __u32 inumber;
367
368         for (i = 0; i < npages; i++) {
369                 char *p, *kaddr, *limit;
370
371                 page = dir_get_page(inode, i);
372                 if (IS_ERR(page))
373                         continue;
374
375                 kaddr = (char *)page_address(page);
376                 limit = kaddr + minix_last_byte(inode, i) - sbi->s_dirsize;
377                 for (p = kaddr; p <= limit; p = minix_next_entry(p, sbi)) {
378                         if (sbi->s_version == MINIX_V3) {
379                                 minix3_dirent *de3 = (minix3_dirent *)p;
380                                 name = de3->name;
381                                 inumber = de3->inode;
382                         } else {
383                                 minix_dirent *de = (minix_dirent *)p;
384                                 name = de->name;
385                                 inumber = de->inode;
386                         }
387
388                         if (inumber != 0) {
389                                 /* check for . and .. */
390                                 if (name[0] != '.')
391                                         goto not_empty;
392                                 if (!name[1]) {
393                                         if (inumber != inode->i_ino)
394                                                 goto not_empty;
395                                 } else if (name[1] != '.')
396                                         goto not_empty;
397                                 else if (name[2])
398                                         goto not_empty;
399                         }
400                 }
401                 dir_put_page(page);
402         }
403         return 1;
404
405 not_empty:
406         dir_put_page(page);
407         return 0;
408 }
409
410 /* Releases the page */
411 void minix_set_link(struct minix_dir_entry *de, struct page *page,
412         struct inode *inode)
413 {
414         struct inode *dir = page->mapping->host;
415         struct minix_sb_info *sbi = minix_sb(dir->i_sb);
416         loff_t pos = page_offset(page) +
417                         (char *)de-(char*)page_address(page);
418         int err;
419
420         lock_page(page);
421
422         err = minix_prepare_chunk(page, pos, sbi->s_dirsize);
423         if (err == 0) {
424                 if (sbi->s_version == MINIX_V3)
425                         ((minix3_dirent *) de)->inode = inode->i_ino;
426                 else
427                         de->inode = inode->i_ino;
428                 err = dir_commit_chunk(page, pos, sbi->s_dirsize);
429         } else {
430                 unlock_page(page);
431         }
432         dir_put_page(page);
433         dir->i_mtime = dir->i_ctime = current_time(dir);
434         mark_inode_dirty(dir);
435 }
436
437 struct minix_dir_entry * minix_dotdot (struct inode *dir, struct page **p)
438 {
439         struct page *page = dir_get_page(dir, 0);
440         struct minix_sb_info *sbi = minix_sb(dir->i_sb);
441         struct minix_dir_entry *de = NULL;
442
443         if (!IS_ERR(page)) {
444                 de = minix_next_entry(page_address(page), sbi);
445                 *p = page;
446         }
447         return de;
448 }
449
450 ino_t minix_inode_by_name(struct dentry *dentry)
451 {
452         struct page *page;
453         struct minix_dir_entry *de = minix_find_entry(dentry, &page);
454         ino_t res = 0;
455
456         if (de) {
457                 struct address_space *mapping = page->mapping;
458                 struct inode *inode = mapping->host;
459                 struct minix_sb_info *sbi = minix_sb(inode->i_sb);
460
461                 if (sbi->s_version == MINIX_V3)
462                         res = ((minix3_dirent *) de)->inode;
463                 else
464                         res = de->inode;
465                 dir_put_page(page);
466         }
467         return res;
468 }