File: /usr/src/linux/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
9 #include <linux/fs.h>
10 #include <linux/minix_fs.h>
11 #include <linux/pagemap.h>
12
13 typedef struct minix_dir_entry minix_dirent;
14
15 static int minix_readdir(struct file *, void *, filldir_t);
16
17 struct file_operations minix_dir_operations = {
18 read: generic_read_dir,
19 readdir: minix_readdir,
20 fsync: minix_sync_file,
21 };
22
23 static inline void dir_put_page(struct page *page)
24 {
25 kunmap(page);
26 page_cache_release(page);
27 }
28
29 static inline unsigned long dir_pages(struct inode *inode)
30 {
31 return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT;
32 }
33
34 static int dir_commit_chunk(struct page *page, unsigned from, unsigned to)
35 {
36 struct inode *dir = (struct inode *)page->mapping->host;
37 int err = 0;
38 page->mapping->a_ops->commit_write(NULL, page, from, to);
39 if (IS_SYNC(dir))
40 err = waitfor_one_page(page);
41 return err;
42 }
43
44 static struct page * dir_get_page(struct inode *dir, unsigned long n)
45 {
46 struct address_space *mapping = dir->i_mapping;
47 struct page *page = read_cache_page(mapping, n,
48 (filler_t*)mapping->a_ops->readpage, NULL);
49 if (!IS_ERR(page)) {
50 wait_on_page(page);
51 kmap(page);
52 if (!Page_Uptodate(page))
53 goto fail;
54 }
55 return page;
56
57 fail:
58 dir_put_page(page);
59 return ERR_PTR(-EIO);
60 }
61
62 static inline void *minix_next_entry(void *de, struct minix_sb_info *sbi)
63 {
64 return (void*)((char*)de + sbi->s_dirsize);
65 }
66
67 static int minix_readdir(struct file * filp, void * dirent, filldir_t filldir)
68 {
69 unsigned long pos = filp->f_pos;
70 struct inode *inode = filp->f_dentry->d_inode;
71 struct super_block *sb = inode->i_sb;
72 unsigned offset = pos & ~PAGE_CACHE_MASK;
73 unsigned long n = pos >> PAGE_CACHE_SHIFT;
74 unsigned long npages = dir_pages(inode);
75 struct minix_sb_info *sbi = &sb->u.minix_sb;
76 unsigned chunk_size = sbi->s_dirsize;
77
78 pos = (pos + chunk_size-1) & ~(chunk_size-1);
79 if (pos >= inode->i_size)
80 goto done;
81
82 for ( ; n < npages; n++, offset = 0) {
83 char *p, *kaddr, *limit;
84 struct page *page = dir_get_page(inode, n);
85
86 if (IS_ERR(page))
87 continue;
88 kaddr = (char *)page_address(page);
89 p = kaddr+offset;
90 limit = kaddr + PAGE_CACHE_SIZE - chunk_size;
91 for ( ; p <= limit ; p = minix_next_entry(p, sbi)) {
92 minix_dirent *de = (minix_dirent *)p;
93 if (de->inode) {
94 int over;
95 unsigned l = strnlen(de->name,sbi->s_namelen);
96
97 offset = p - kaddr;
98 over = filldir(dirent, de->name, l,
99 (n<<PAGE_CACHE_SHIFT) | offset,
100 de->inode, DT_UNKNOWN);
101 if (over) {
102 dir_put_page(page);
103 goto done;
104 }
105 }
106 }
107 dir_put_page(page);
108 }
109
110 done:
111 filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
112 UPDATE_ATIME(inode);
113 return 0;
114 }
115
116 static inline int namecompare(int len, int maxlen,
117 const char * name, const char * buffer)
118 {
119 if (len < maxlen && buffer[len])
120 return 0;
121 return !memcmp(name, buffer, len);
122 }
123
124 /*
125 * minix_find_entry()
126 *
127 * finds an entry in the specified directory with the wanted name. It
128 * returns the cache buffer in which the entry was found, and the entry
129 * itself (as a parameter - res_dir). It does NOT read the inode of the
130 * entry - you'll have to do that yourself if you want to.
131 */
132 minix_dirent *minix_find_entry(struct dentry *dentry, struct page **res_page)
133 {
134 const char * name = dentry->d_name.name;
135 int namelen = dentry->d_name.len;
136 struct inode * dir = dentry->d_parent->d_inode;
137 struct super_block * sb = dir->i_sb;
138 struct minix_sb_info * sbi = &sb->u.minix_sb;
139 unsigned long n;
140 unsigned long npages = dir_pages(dir);
141 struct page *page = NULL;
142 struct minix_dir_entry *de;
143
144 *res_page = NULL;
145
146 for (n = 0; n < npages; n++) {
147 char *kaddr;
148 page = dir_get_page(dir, n);
149 if (IS_ERR(page))
150 continue;
151
152 kaddr = (char*)page_address(page);
153 de = (struct minix_dir_entry *) kaddr;
154 kaddr += PAGE_CACHE_SIZE - sbi->s_dirsize;
155 for ( ; (char *) de <= kaddr ; de = minix_next_entry(de,sbi)) {
156 if (!de->inode)
157 continue;
158 if (namecompare(namelen,sbi->s_namelen,name,de->name))
159 goto found;
160 }
161 dir_put_page(page);
162 }
163 return NULL;
164
165 found:
166 *res_page = page;
167 return de;
168 }
169
170 int minix_add_link(struct dentry *dentry, struct inode *inode)
171 {
172 struct inode *dir = dentry->d_parent->d_inode;
173 const char * name = dentry->d_name.name;
174 int namelen = dentry->d_name.len;
175 struct super_block * sb = dir->i_sb;
176 struct minix_sb_info * sbi = &sb->u.minix_sb;
177 struct page *page = NULL;
178 struct minix_dir_entry * de;
179 unsigned long npages = dir_pages(dir);
180 unsigned long n;
181 char *kaddr;
182 unsigned from, to;
183 int err;
184
185 /* We take care of directory expansion in the same loop */
186 for (n = 0; n <= npages; n++) {
187 page = dir_get_page(dir, n);
188 err = PTR_ERR(page);
189 if (IS_ERR(page))
190 goto out;
191 kaddr = (char*)page_address(page);
192 de = (minix_dirent *)kaddr;
193 kaddr += PAGE_CACHE_SIZE - sbi->s_dirsize;
194 while ((char *)de <= kaddr) {
195 if (!de->inode)
196 goto got_it;
197 err = -EEXIST;
198 if (namecompare(namelen,sbi->s_namelen,name,de->name))
199 goto out_page;
200 de = minix_next_entry(de, sbi);
201 }
202 dir_put_page(page);
203 }
204 BUG();
205 return -EINVAL;
206
207 got_it:
208 from = (char*)de - (char*)page_address(page);
209 to = from + sbi->s_dirsize;
210 lock_page(page);
211 err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
212 if (err)
213 goto out_unlock;
214 memcpy (de->name, name, namelen);
215 memset (de->name + namelen, 0, sbi->s_dirsize - namelen - 2);
216 de->inode = inode->i_ino;
217 err = dir_commit_chunk(page, from, to);
218 dir->i_mtime = dir->i_ctime = CURRENT_TIME;
219 mark_inode_dirty(dir);
220 out_unlock:
221 UnlockPage(page);
222 out_page:
223 dir_put_page(page);
224 out:
225 return err;
226 }
227
228 int minix_delete_entry(struct minix_dir_entry *de, struct page *page)
229 {
230 struct address_space *mapping = page->mapping;
231 struct inode *inode = (struct inode*)mapping->host;
232 char *kaddr = (char*)page_address(page);
233 unsigned from = (char*)de - kaddr;
234 unsigned to = from + inode->i_sb->u.minix_sb.s_dirsize;
235 int err;
236
237 lock_page(page);
238 err = mapping->a_ops->prepare_write(NULL, page, from, to);
239 if (err)
240 BUG();
241 de->inode = 0;
242 err = dir_commit_chunk(page, from, to);
243 UnlockPage(page);
244 dir_put_page(page);
245 inode->i_ctime = inode->i_mtime = CURRENT_TIME;
246 mark_inode_dirty(inode);
247 return err;
248 }
249
250 int minix_make_empty(struct inode *inode, struct inode *dir)
251 {
252 struct address_space *mapping = inode->i_mapping;
253 struct page *page = grab_cache_page(mapping, 0);
254 struct minix_sb_info * sbi = &inode->i_sb->u.minix_sb;
255 struct minix_dir_entry * de;
256 char *base;
257 int err;
258
259 if (!page)
260 return -ENOMEM;
261 err = mapping->a_ops->prepare_write(NULL, page, 0, 2 * sbi->s_dirsize);
262 if (err)
263 goto fail;
264
265 base = (char*)page_address(page);
266 memset(base, 0, PAGE_CACHE_SIZE);
267
268 de = (struct minix_dir_entry *) base;
269 de->inode = inode->i_ino;
270 strcpy(de->name,".");
271 de = minix_next_entry(de, sbi);
272 de->inode = dir->i_ino;
273 strcpy(de->name,"..");
274
275 err = dir_commit_chunk(page, 0, 2 * sbi->s_dirsize);
276 fail:
277 UnlockPage(page);
278 page_cache_release(page);
279 return err;
280 }
281
282 /*
283 * routine to check that the specified directory is empty (for rmdir)
284 */
285 int minix_empty_dir(struct inode * inode)
286 {
287 struct page *page = NULL;
288 unsigned long i, npages = dir_pages(inode);
289 struct minix_sb_info *sbi = &inode->i_sb->u.minix_sb;
290
291 for (i = 0; i < npages; i++) {
292 char *kaddr;
293 minix_dirent * de;
294 page = dir_get_page(inode, i);
295
296 if (IS_ERR(page))
297 continue;
298
299 kaddr = (char *)page_address(page);
300 de = (minix_dirent *)kaddr;
301 kaddr += PAGE_CACHE_SIZE - sbi->s_dirsize;
302
303 while ((char *)de <= kaddr) {
304 if (de->inode != 0) {
305 /* check for . and .. */
306 if (de->name[0] != '.')
307 goto not_empty;
308 if (!de->name[1]) {
309 if (de->inode != inode->i_ino)
310 goto not_empty;
311 } else if (de->name[1] != '.')
312 goto not_empty;
313 else if (de->name[2])
314 goto not_empty;
315 }
316 de = minix_next_entry(de, sbi);
317 }
318 dir_put_page(page);
319 }
320 return 1;
321
322 not_empty:
323 dir_put_page(page);
324 return 0;
325 }
326
327 /* Releases the page */
328 void minix_set_link(struct minix_dir_entry *de, struct page *page,
329 struct inode *inode)
330 {
331 struct inode *dir = (struct inode*)page->mapping->host;
332 struct minix_sb_info *sbi = &dir->i_sb->u.minix_sb;
333 unsigned from = (char *)de-(char*)page_address(page);
334 unsigned to = from + sbi->s_dirsize;
335 int err;
336
337 lock_page(page);
338 err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
339 if (err)
340 BUG();
341 de->inode = inode->i_ino;
342 err = dir_commit_chunk(page, from, to);
343 UnlockPage(page);
344 dir_put_page(page);
345 dir->i_mtime = dir->i_ctime = CURRENT_TIME;
346 mark_inode_dirty(dir);
347 }
348
349 struct minix_dir_entry * minix_dotdot (struct inode *dir, struct page **p)
350 {
351 struct page *page = dir_get_page(dir, 0);
352 struct minix_sb_info *sbi = &dir->i_sb->u.minix_sb;
353 struct minix_dir_entry *de = NULL;
354
355 if (!IS_ERR(page)) {
356 de = minix_next_entry(page_address(page), sbi);
357 *p = page;
358 }
359 return de;
360 }
361
362 ino_t minix_inode_by_name(struct dentry *dentry)
363 {
364 struct page *page;
365 struct minix_dir_entry *de = minix_find_entry(dentry, &page);
366 ino_t res = 0;
367
368 if (de) {
369 res = de->inode;
370 dir_put_page(page);
371 }
372 return res;
373 }
374