GNU Linux-libre 4.9.308-gnu1
[releases.git] / fs / affs / amigaffs.c
1 /*
2  *  linux/fs/affs/amigaffs.c
3  *
4  *  (c) 1996  Hans-Joachim Widmaier - Rewritten
5  *
6  *  (C) 1993  Ray Burr - Amiga FFS filesystem.
7  *
8  *  Please send bug reports to: hjw@zvw.de
9  */
10
11 #include <linux/math64.h>
12 #include "affs.h"
13
14 /*
15  * Functions for accessing Amiga-FFS structures.
16  */
17
18
19 /* Insert a header block bh into the directory dir
20  * caller must hold AFFS_DIR->i_hash_lock!
21  */
22
23 int
24 affs_insert_hash(struct inode *dir, struct buffer_head *bh)
25 {
26         struct super_block *sb = dir->i_sb;
27         struct buffer_head *dir_bh;
28         u32 ino, hash_ino;
29         int offset;
30
31         ino = bh->b_blocknr;
32         offset = affs_hash_name(sb, AFFS_TAIL(sb, bh)->name + 1, AFFS_TAIL(sb, bh)->name[0]);
33
34         pr_debug("%s(dir=%lu, ino=%d)\n", __func__, dir->i_ino, ino);
35
36         dir_bh = affs_bread(sb, dir->i_ino);
37         if (!dir_bh)
38                 return -EIO;
39
40         hash_ino = be32_to_cpu(AFFS_HEAD(dir_bh)->table[offset]);
41         while (hash_ino) {
42                 affs_brelse(dir_bh);
43                 dir_bh = affs_bread(sb, hash_ino);
44                 if (!dir_bh)
45                         return -EIO;
46                 hash_ino = be32_to_cpu(AFFS_TAIL(sb, dir_bh)->hash_chain);
47         }
48         AFFS_TAIL(sb, bh)->parent = cpu_to_be32(dir->i_ino);
49         AFFS_TAIL(sb, bh)->hash_chain = 0;
50         affs_fix_checksum(sb, bh);
51
52         if (dir->i_ino == dir_bh->b_blocknr)
53                 AFFS_HEAD(dir_bh)->table[offset] = cpu_to_be32(ino);
54         else
55                 AFFS_TAIL(sb, dir_bh)->hash_chain = cpu_to_be32(ino);
56
57         affs_adjust_checksum(dir_bh, ino);
58         mark_buffer_dirty_inode(dir_bh, dir);
59         affs_brelse(dir_bh);
60
61         dir->i_mtime = dir->i_ctime = current_time(dir);
62         dir->i_version++;
63         mark_inode_dirty(dir);
64
65         return 0;
66 }
67
68 /* Remove a header block from its directory.
69  * caller must hold AFFS_DIR->i_hash_lock!
70  */
71
72 int
73 affs_remove_hash(struct inode *dir, struct buffer_head *rem_bh)
74 {
75         struct super_block *sb;
76         struct buffer_head *bh;
77         u32 rem_ino, hash_ino;
78         __be32 ino;
79         int offset, retval;
80
81         sb = dir->i_sb;
82         rem_ino = rem_bh->b_blocknr;
83         offset = affs_hash_name(sb, AFFS_TAIL(sb, rem_bh)->name+1, AFFS_TAIL(sb, rem_bh)->name[0]);
84         pr_debug("%s(dir=%lu, ino=%d, hashval=%d)\n", __func__, dir->i_ino,
85                  rem_ino, offset);
86
87         bh = affs_bread(sb, dir->i_ino);
88         if (!bh)
89                 return -EIO;
90
91         retval = -ENOENT;
92         hash_ino = be32_to_cpu(AFFS_HEAD(bh)->table[offset]);
93         while (hash_ino) {
94                 if (hash_ino == rem_ino) {
95                         ino = AFFS_TAIL(sb, rem_bh)->hash_chain;
96                         if (dir->i_ino == bh->b_blocknr)
97                                 AFFS_HEAD(bh)->table[offset] = ino;
98                         else
99                                 AFFS_TAIL(sb, bh)->hash_chain = ino;
100                         affs_adjust_checksum(bh, be32_to_cpu(ino) - hash_ino);
101                         mark_buffer_dirty_inode(bh, dir);
102                         AFFS_TAIL(sb, rem_bh)->parent = 0;
103                         retval = 0;
104                         break;
105                 }
106                 affs_brelse(bh);
107                 bh = affs_bread(sb, hash_ino);
108                 if (!bh)
109                         return -EIO;
110                 hash_ino = be32_to_cpu(AFFS_TAIL(sb, bh)->hash_chain);
111         }
112
113         affs_brelse(bh);
114
115         dir->i_mtime = dir->i_ctime = current_time(dir);
116         dir->i_version++;
117         mark_inode_dirty(dir);
118
119         return retval;
120 }
121
122 static void
123 affs_fix_dcache(struct inode *inode, u32 entry_ino)
124 {
125         struct dentry *dentry;
126         spin_lock(&inode->i_lock);
127         hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
128                 if (entry_ino == (u32)(long)dentry->d_fsdata) {
129                         dentry->d_fsdata = (void *)inode->i_ino;
130                         break;
131                 }
132         }
133         spin_unlock(&inode->i_lock);
134 }
135
136
137 /* Remove header from link chain */
138
139 static int
140 affs_remove_link(struct dentry *dentry)
141 {
142         struct inode *dir, *inode = d_inode(dentry);
143         struct super_block *sb = inode->i_sb;
144         struct buffer_head *bh, *link_bh = NULL;
145         u32 link_ino, ino;
146         int retval;
147
148         pr_debug("%s(key=%ld)\n", __func__, inode->i_ino);
149         retval = -EIO;
150         bh = affs_bread(sb, inode->i_ino);
151         if (!bh)
152                 goto done;
153
154         link_ino = (u32)(long)dentry->d_fsdata;
155         if (inode->i_ino == link_ino) {
156                 /* we can't remove the head of the link, as its blocknr is still used as ino,
157                  * so we remove the block of the first link instead.
158                  */ 
159                 link_ino = be32_to_cpu(AFFS_TAIL(sb, bh)->link_chain);
160                 link_bh = affs_bread(sb, link_ino);
161                 if (!link_bh)
162                         goto done;
163
164                 dir = affs_iget(sb, be32_to_cpu(AFFS_TAIL(sb, link_bh)->parent));
165                 if (IS_ERR(dir)) {
166                         retval = PTR_ERR(dir);
167                         goto done;
168                 }
169
170                 affs_lock_dir(dir);
171                 /*
172                  * if there's a dentry for that block, make it
173                  * refer to inode itself.
174                  */
175                 affs_fix_dcache(inode, link_ino);
176                 retval = affs_remove_hash(dir, link_bh);
177                 if (retval) {
178                         affs_unlock_dir(dir);
179                         goto done;
180                 }
181                 mark_buffer_dirty_inode(link_bh, inode);
182
183                 memcpy(AFFS_TAIL(sb, bh)->name, AFFS_TAIL(sb, link_bh)->name, 32);
184                 retval = affs_insert_hash(dir, bh);
185                 if (retval) {
186                         affs_unlock_dir(dir);
187                         goto done;
188                 }
189                 mark_buffer_dirty_inode(bh, inode);
190
191                 affs_unlock_dir(dir);
192                 iput(dir);
193         } else {
194                 link_bh = affs_bread(sb, link_ino);
195                 if (!link_bh)
196                         goto done;
197         }
198
199         while ((ino = be32_to_cpu(AFFS_TAIL(sb, bh)->link_chain)) != 0) {
200                 if (ino == link_ino) {
201                         __be32 ino2 = AFFS_TAIL(sb, link_bh)->link_chain;
202                         AFFS_TAIL(sb, bh)->link_chain = ino2;
203                         affs_adjust_checksum(bh, be32_to_cpu(ino2) - link_ino);
204                         mark_buffer_dirty_inode(bh, inode);
205                         retval = 0;
206                         /* Fix the link count, if bh is a normal header block without links */
207                         switch (be32_to_cpu(AFFS_TAIL(sb, bh)->stype)) {
208                         case ST_LINKDIR:
209                         case ST_LINKFILE:
210                                 break;
211                         default:
212                                 if (!AFFS_TAIL(sb, bh)->link_chain)
213                                         set_nlink(inode, 1);
214                         }
215                         affs_free_block(sb, link_ino);
216                         goto done;
217                 }
218                 affs_brelse(bh);
219                 bh = affs_bread(sb, ino);
220                 if (!bh)
221                         goto done;
222         }
223         retval = -ENOENT;
224 done:
225         affs_brelse(link_bh);
226         affs_brelse(bh);
227         return retval;
228 }
229
230
231 static int
232 affs_empty_dir(struct inode *inode)
233 {
234         struct super_block *sb = inode->i_sb;
235         struct buffer_head *bh;
236         int retval, size;
237
238         retval = -EIO;
239         bh = affs_bread(sb, inode->i_ino);
240         if (!bh)
241                 goto done;
242
243         retval = -ENOTEMPTY;
244         for (size = AFFS_SB(sb)->s_hashsize - 1; size >= 0; size--)
245                 if (AFFS_HEAD(bh)->table[size])
246                         goto not_empty;
247         retval = 0;
248 not_empty:
249         affs_brelse(bh);
250 done:
251         return retval;
252 }
253
254
255 /* Remove a filesystem object. If the object to be removed has
256  * links to it, one of the links must be changed to inherit
257  * the file or directory. As above, any inode will do.
258  * The buffer will not be freed. If the header is a link, the
259  * block will be marked as free.
260  * This function returns a negative error number in case of
261  * an error, else 0 if the inode is to be deleted or 1 if not.
262  */
263
264 int
265 affs_remove_header(struct dentry *dentry)
266 {
267         struct super_block *sb;
268         struct inode *inode, *dir;
269         struct buffer_head *bh = NULL;
270         int retval;
271
272         dir = d_inode(dentry->d_parent);
273         sb = dir->i_sb;
274
275         retval = -ENOENT;
276         inode = d_inode(dentry);
277         if (!inode)
278                 goto done;
279
280         pr_debug("%s(key=%ld)\n", __func__, inode->i_ino);
281         retval = -EIO;
282         bh = affs_bread(sb, (u32)(long)dentry->d_fsdata);
283         if (!bh)
284                 goto done;
285
286         affs_lock_link(inode);
287         affs_lock_dir(dir);
288         switch (be32_to_cpu(AFFS_TAIL(sb, bh)->stype)) {
289         case ST_USERDIR:
290                 /* if we ever want to support links to dirs
291                  * i_hash_lock of the inode must only be
292                  * taken after some checks
293                  */
294                 affs_lock_dir(inode);
295                 retval = affs_empty_dir(inode);
296                 affs_unlock_dir(inode);
297                 if (retval)
298                         goto done_unlock;
299                 break;
300         default:
301                 break;
302         }
303
304         retval = affs_remove_hash(dir, bh);
305         if (retval)
306                 goto done_unlock;
307         mark_buffer_dirty_inode(bh, inode);
308
309         affs_unlock_dir(dir);
310
311         if (inode->i_nlink > 1)
312                 retval = affs_remove_link(dentry);
313         else
314                 clear_nlink(inode);
315         affs_unlock_link(inode);
316         inode->i_ctime = current_time(inode);
317         mark_inode_dirty(inode);
318
319 done:
320         affs_brelse(bh);
321         return retval;
322
323 done_unlock:
324         affs_unlock_dir(dir);
325         affs_unlock_link(inode);
326         goto done;
327 }
328
329 /* Checksum a block, do various consistency checks and optionally return
330    the blocks type number.  DATA points to the block.  If their pointers
331    are non-null, *PTYPE and *STYPE are set to the primary and secondary
332    block types respectively, *HASHSIZE is set to the size of the hashtable
333    (which lets us calculate the block size).
334    Returns non-zero if the block is not consistent. */
335
336 u32
337 affs_checksum_block(struct super_block *sb, struct buffer_head *bh)
338 {
339         __be32 *ptr = (__be32 *)bh->b_data;
340         u32 sum;
341         int bsize;
342
343         sum = 0;
344         for (bsize = sb->s_blocksize / sizeof(__be32); bsize > 0; bsize--)
345                 sum += be32_to_cpu(*ptr++);
346         return sum;
347 }
348
349 /*
350  * Calculate the checksum of a disk block and store it
351  * at the indicated position.
352  */
353
354 void
355 affs_fix_checksum(struct super_block *sb, struct buffer_head *bh)
356 {
357         int cnt = sb->s_blocksize / sizeof(__be32);
358         __be32 *ptr = (__be32 *)bh->b_data;
359         u32 checksum;
360         __be32 *checksumptr;
361
362         checksumptr = ptr + 5;
363         *checksumptr = 0;
364         for (checksum = 0; cnt > 0; ptr++, cnt--)
365                 checksum += be32_to_cpu(*ptr);
366         *checksumptr = cpu_to_be32(-checksum);
367 }
368
369 void
370 secs_to_datestamp(time64_t secs, struct affs_date *ds)
371 {
372         u32      days;
373         u32      minute;
374         s32      rem;
375
376         secs -= sys_tz.tz_minuteswest * 60 + ((8 * 365 + 2) * 24 * 60 * 60);
377         if (secs < 0)
378                 secs = 0;
379         days    = div_s64_rem(secs, 86400, &rem);
380         minute  = rem / 60;
381         rem    -= minute * 60;
382
383         ds->days = cpu_to_be32(days);
384         ds->mins = cpu_to_be32(minute);
385         ds->ticks = cpu_to_be32(rem * 50);
386 }
387
388 umode_t
389 prot_to_mode(u32 prot)
390 {
391         umode_t mode = 0;
392
393         if (!(prot & FIBF_NOWRITE))
394                 mode |= 0200;
395         if (!(prot & FIBF_NOREAD))
396                 mode |= 0400;
397         if (!(prot & FIBF_NOEXECUTE))
398                 mode |= 0100;
399         if (prot & FIBF_GRP_WRITE)
400                 mode |= 0020;
401         if (prot & FIBF_GRP_READ)
402                 mode |= 0040;
403         if (prot & FIBF_GRP_EXECUTE)
404                 mode |= 0010;
405         if (prot & FIBF_OTR_WRITE)
406                 mode |= 0002;
407         if (prot & FIBF_OTR_READ)
408                 mode |= 0004;
409         if (prot & FIBF_OTR_EXECUTE)
410                 mode |= 0001;
411
412         return mode;
413 }
414
415 void
416 mode_to_prot(struct inode *inode)
417 {
418         u32 prot = AFFS_I(inode)->i_protect;
419         umode_t mode = inode->i_mode;
420
421         /*
422          * First, clear all RWED bits for owner, group, other.
423          * Then, recalculate them afresh.
424          *
425          * We'll always clear the delete-inhibit bit for the owner, as that is
426          * the classic single-user mode AmigaOS protection bit and we need to
427          * stay compatible with all scenarios.
428          *
429          * Since multi-user AmigaOS is an extension, we'll only set the
430          * delete-allow bit if any of the other bits in the same user class
431          * (group/other) are used.
432          */
433         prot &= ~(FIBF_NOEXECUTE | FIBF_NOREAD
434                   | FIBF_NOWRITE | FIBF_NODELETE
435                   | FIBF_GRP_EXECUTE | FIBF_GRP_READ
436                   | FIBF_GRP_WRITE   | FIBF_GRP_DELETE
437                   | FIBF_OTR_EXECUTE | FIBF_OTR_READ
438                   | FIBF_OTR_WRITE   | FIBF_OTR_DELETE);
439
440         /* Classic single-user AmigaOS flags. These are inverted. */
441         if (!(mode & 0100))
442                 prot |= FIBF_NOEXECUTE;
443         if (!(mode & 0400))
444                 prot |= FIBF_NOREAD;
445         if (!(mode & 0200))
446                 prot |= FIBF_NOWRITE;
447
448         /* Multi-user extended flags. Not inverted. */
449         if (mode & 0010)
450                 prot |= FIBF_GRP_EXECUTE;
451         if (mode & 0040)
452                 prot |= FIBF_GRP_READ;
453         if (mode & 0020)
454                 prot |= FIBF_GRP_WRITE;
455         if (mode & 0070)
456                 prot |= FIBF_GRP_DELETE;
457
458         if (mode & 0001)
459                 prot |= FIBF_OTR_EXECUTE;
460         if (mode & 0004)
461                 prot |= FIBF_OTR_READ;
462         if (mode & 0002)
463                 prot |= FIBF_OTR_WRITE;
464         if (mode & 0007)
465                 prot |= FIBF_OTR_DELETE;
466
467         AFFS_I(inode)->i_protect = prot;
468 }
469
470 void
471 affs_error(struct super_block *sb, const char *function, const char *fmt, ...)
472 {
473         struct va_format vaf;
474         va_list args;
475
476         va_start(args, fmt);
477         vaf.fmt = fmt;
478         vaf.va = &args;
479         pr_crit("error (device %s): %s(): %pV\n", sb->s_id, function, &vaf);
480         if (!(sb->s_flags & MS_RDONLY))
481                 pr_warn("Remounting filesystem read-only\n");
482         sb->s_flags |= MS_RDONLY;
483         va_end(args);
484 }
485
486 void
487 affs_warning(struct super_block *sb, const char *function, const char *fmt, ...)
488 {
489         struct va_format vaf;
490         va_list args;
491
492         va_start(args, fmt);
493         vaf.fmt = fmt;
494         vaf.va = &args;
495         pr_warn("(device %s): %s(): %pV\n", sb->s_id, function, &vaf);
496         va_end(args);
497 }
498
499 bool
500 affs_nofilenametruncate(const struct dentry *dentry)
501 {
502         return affs_test_opt(AFFS_SB(dentry->d_sb)->s_flags, SF_NO_TRUNCATE);
503 }
504
505 /* Check if the name is valid for a affs object. */
506
507 int
508 affs_check_name(const unsigned char *name, int len, bool notruncate)
509 {
510         int      i;
511
512         if (len > AFFSNAMEMAX) {
513                 if (notruncate)
514                         return -ENAMETOOLONG;
515                 len = AFFSNAMEMAX;
516         }
517         for (i = 0; i < len; i++) {
518                 if (name[i] < ' ' || name[i] == ':'
519                     || (name[i] > 0x7e && name[i] < 0xa0))
520                         return -EINVAL;
521         }
522
523         return 0;
524 }
525
526 /* This function copies name to bstr, with at most 30
527  * characters length. The bstr will be prepended by
528  * a length byte.
529  * NOTE: The name will must be already checked by
530  *       affs_check_name()!
531  */
532
533 int
534 affs_copy_name(unsigned char *bstr, struct dentry *dentry)
535 {
536         u32 len = min(dentry->d_name.len, AFFSNAMEMAX);
537
538         *bstr++ = len;
539         memcpy(bstr, dentry->d_name.name, len);
540         return len;
541 }