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