Merge tag 'nfsd-6.4-2' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux
[linux-2.6-microblaze.git] / fs / udf / directory.c
1 /*
2  * directory.c
3  *
4  * PURPOSE
5  *      Directory related functions
6  *
7  * COPYRIGHT
8  *      This file is distributed under the terms of the GNU General Public
9  *      License (GPL). Copies of the GPL can be obtained from:
10  *              ftp://prep.ai.mit.edu/pub/gnu/GPL
11  *      Each contributing author retains all rights to their own work.
12  */
13
14 #include "udfdecl.h"
15 #include "udf_i.h"
16
17 #include <linux/fs.h>
18 #include <linux/string.h>
19 #include <linux/bio.h>
20 #include <linux/crc-itu-t.h>
21 #include <linux/iversion.h>
22
23 static int udf_verify_fi(struct udf_fileident_iter *iter)
24 {
25         unsigned int len;
26
27         if (iter->fi.descTag.tagIdent != cpu_to_le16(TAG_IDENT_FID)) {
28                 udf_err(iter->dir->i_sb,
29                         "directory (ino %lu) has entry at pos %llu with incorrect tag %x\n",
30                         iter->dir->i_ino, (unsigned long long)iter->pos,
31                         le16_to_cpu(iter->fi.descTag.tagIdent));
32                 return -EFSCORRUPTED;
33         }
34         len = udf_dir_entry_len(&iter->fi);
35         if (le16_to_cpu(iter->fi.lengthOfImpUse) & 3) {
36                 udf_err(iter->dir->i_sb,
37                         "directory (ino %lu) has entry at pos %llu with unaligned length of impUse field\n",
38                         iter->dir->i_ino, (unsigned long long)iter->pos);
39                 return -EFSCORRUPTED;
40         }
41         /*
42          * This is in fact allowed by the spec due to long impUse field but
43          * we don't support it. If there is real media with this large impUse
44          * field, support can be added.
45          */
46         if (len > 1 << iter->dir->i_blkbits) {
47                 udf_err(iter->dir->i_sb,
48                         "directory (ino %lu) has too big (%u) entry at pos %llu\n",
49                         iter->dir->i_ino, len, (unsigned long long)iter->pos);
50                 return -EFSCORRUPTED;
51         }
52         if (iter->pos + len > iter->dir->i_size) {
53                 udf_err(iter->dir->i_sb,
54                         "directory (ino %lu) has entry past directory size at pos %llu\n",
55                         iter->dir->i_ino, (unsigned long long)iter->pos);
56                 return -EFSCORRUPTED;
57         }
58         if (udf_dir_entry_len(&iter->fi) !=
59             sizeof(struct tag) + le16_to_cpu(iter->fi.descTag.descCRCLength)) {
60                 udf_err(iter->dir->i_sb,
61                         "directory (ino %lu) has entry where CRC length (%u) does not match entry length (%u)\n",
62                         iter->dir->i_ino,
63                         (unsigned)le16_to_cpu(iter->fi.descTag.descCRCLength),
64                         (unsigned)(udf_dir_entry_len(&iter->fi) -
65                                                         sizeof(struct tag)));
66                 return -EFSCORRUPTED;
67         }
68         return 0;
69 }
70
71 static int udf_copy_fi(struct udf_fileident_iter *iter)
72 {
73         struct udf_inode_info *iinfo = UDF_I(iter->dir);
74         u32 blksize = 1 << iter->dir->i_blkbits;
75         u32 off, len, nameoff;
76         int err;
77
78         /* Skip copying when we are at EOF */
79         if (iter->pos >= iter->dir->i_size) {
80                 iter->name = NULL;
81                 return 0;
82         }
83         if (iter->dir->i_size < iter->pos + sizeof(struct fileIdentDesc)) {
84                 udf_err(iter->dir->i_sb,
85                         "directory (ino %lu) has entry straddling EOF\n",
86                         iter->dir->i_ino);
87                 return -EFSCORRUPTED;
88         }
89         if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
90                 memcpy(&iter->fi, iinfo->i_data + iinfo->i_lenEAttr + iter->pos,
91                        sizeof(struct fileIdentDesc));
92                 err = udf_verify_fi(iter);
93                 if (err < 0)
94                         return err;
95                 iter->name = iinfo->i_data + iinfo->i_lenEAttr + iter->pos +
96                         sizeof(struct fileIdentDesc) +
97                         le16_to_cpu(iter->fi.lengthOfImpUse);
98                 return 0;
99         }
100
101         off = iter->pos & (blksize - 1);
102         len = min_t(int, sizeof(struct fileIdentDesc), blksize - off);
103         memcpy(&iter->fi, iter->bh[0]->b_data + off, len);
104         if (len < sizeof(struct fileIdentDesc))
105                 memcpy((char *)(&iter->fi) + len, iter->bh[1]->b_data,
106                        sizeof(struct fileIdentDesc) - len);
107         err = udf_verify_fi(iter);
108         if (err < 0)
109                 return err;
110
111         /* Handle directory entry name */
112         nameoff = off + sizeof(struct fileIdentDesc) +
113                                 le16_to_cpu(iter->fi.lengthOfImpUse);
114         if (off + udf_dir_entry_len(&iter->fi) <= blksize) {
115                 iter->name = iter->bh[0]->b_data + nameoff;
116         } else if (nameoff >= blksize) {
117                 iter->name = iter->bh[1]->b_data + (nameoff - blksize);
118         } else {
119                 iter->name = iter->namebuf;
120                 len = blksize - nameoff;
121                 memcpy(iter->name, iter->bh[0]->b_data + nameoff, len);
122                 memcpy(iter->name + len, iter->bh[1]->b_data,
123                        iter->fi.lengthFileIdent - len);
124         }
125         return 0;
126 }
127
128 /* Readahead 8k once we are at 8k boundary */
129 static void udf_readahead_dir(struct udf_fileident_iter *iter)
130 {
131         unsigned int ralen = 16 >> (iter->dir->i_blkbits - 9);
132         struct buffer_head *tmp, *bha[16];
133         int i, num;
134         udf_pblk_t blk;
135
136         if (iter->loffset & (ralen - 1))
137                 return;
138
139         if (iter->loffset + ralen > (iter->elen >> iter->dir->i_blkbits))
140                 ralen = (iter->elen >> iter->dir->i_blkbits) - iter->loffset;
141         num = 0;
142         for (i = 0; i < ralen; i++) {
143                 blk = udf_get_lb_pblock(iter->dir->i_sb, &iter->eloc,
144                                         iter->loffset + i);
145                 tmp = sb_getblk(iter->dir->i_sb, blk);
146                 if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp))
147                         bha[num++] = tmp;
148                 else
149                         brelse(tmp);
150         }
151         if (num) {
152                 bh_readahead_batch(num, bha, REQ_RAHEAD);
153                 for (i = 0; i < num; i++)
154                         brelse(bha[i]);
155         }
156 }
157
158 static struct buffer_head *udf_fiiter_bread_blk(struct udf_fileident_iter *iter)
159 {
160         udf_pblk_t blk;
161
162         udf_readahead_dir(iter);
163         blk = udf_get_lb_pblock(iter->dir->i_sb, &iter->eloc, iter->loffset);
164         return sb_bread(iter->dir->i_sb, blk);
165 }
166
167 /*
168  * Updates loffset to point to next directory block; eloc, elen & epos are
169  * updated if we need to traverse to the next extent as well.
170  */
171 static int udf_fiiter_advance_blk(struct udf_fileident_iter *iter)
172 {
173         iter->loffset++;
174         if (iter->loffset < DIV_ROUND_UP(iter->elen, 1<<iter->dir->i_blkbits))
175                 return 0;
176
177         iter->loffset = 0;
178         if (udf_next_aext(iter->dir, &iter->epos, &iter->eloc, &iter->elen, 1)
179                         != (EXT_RECORDED_ALLOCATED >> 30)) {
180                 if (iter->pos == iter->dir->i_size) {
181                         iter->elen = 0;
182                         return 0;
183                 }
184                 udf_err(iter->dir->i_sb,
185                         "extent after position %llu not allocated in directory (ino %lu)\n",
186                         (unsigned long long)iter->pos, iter->dir->i_ino);
187                 return -EFSCORRUPTED;
188         }
189         return 0;
190 }
191
192 static int udf_fiiter_load_bhs(struct udf_fileident_iter *iter)
193 {
194         int blksize = 1 << iter->dir->i_blkbits;
195         int off = iter->pos & (blksize - 1);
196         int err;
197         struct fileIdentDesc *fi;
198
199         /* Is there any further extent we can map from? */
200         if (!iter->bh[0] && iter->elen) {
201                 iter->bh[0] = udf_fiiter_bread_blk(iter);
202                 if (!iter->bh[0]) {
203                         err = -ENOMEM;
204                         goto out_brelse;
205                 }
206                 if (!buffer_uptodate(iter->bh[0])) {
207                         err = -EIO;
208                         goto out_brelse;
209                 }
210         }
211         /* There's no next block so we are done */
212         if (iter->pos >= iter->dir->i_size)
213                 return 0;
214         /* Need to fetch next block as well? */
215         if (off + sizeof(struct fileIdentDesc) > blksize)
216                 goto fetch_next;
217         fi = (struct fileIdentDesc *)(iter->bh[0]->b_data + off);
218         /* Need to fetch next block to get name? */
219         if (off + udf_dir_entry_len(fi) > blksize) {
220 fetch_next:
221                 err = udf_fiiter_advance_blk(iter);
222                 if (err)
223                         goto out_brelse;
224                 iter->bh[1] = udf_fiiter_bread_blk(iter);
225                 if (!iter->bh[1]) {
226                         err = -ENOMEM;
227                         goto out_brelse;
228                 }
229                 if (!buffer_uptodate(iter->bh[1])) {
230                         err = -EIO;
231                         goto out_brelse;
232                 }
233         }
234         return 0;
235 out_brelse:
236         brelse(iter->bh[0]);
237         brelse(iter->bh[1]);
238         iter->bh[0] = iter->bh[1] = NULL;
239         return err;
240 }
241
242 int udf_fiiter_init(struct udf_fileident_iter *iter, struct inode *dir,
243                     loff_t pos)
244 {
245         struct udf_inode_info *iinfo = UDF_I(dir);
246         int err = 0;
247
248         iter->dir = dir;
249         iter->bh[0] = iter->bh[1] = NULL;
250         iter->pos = pos;
251         iter->elen = 0;
252         iter->epos.bh = NULL;
253         iter->name = NULL;
254         /*
255          * When directory is verified, we don't expect directory iteration to
256          * fail and it can be difficult to undo without corrupting filesystem.
257          * So just do not allow memory allocation failures here.
258          */
259         iter->namebuf = kmalloc(UDF_NAME_LEN_CS0, GFP_KERNEL | __GFP_NOFAIL);
260
261         if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
262                 err = udf_copy_fi(iter);
263                 goto out;
264         }
265
266         if (inode_bmap(dir, iter->pos >> dir->i_blkbits, &iter->epos,
267                        &iter->eloc, &iter->elen, &iter->loffset) !=
268             (EXT_RECORDED_ALLOCATED >> 30)) {
269                 if (pos == dir->i_size)
270                         return 0;
271                 udf_err(dir->i_sb,
272                         "position %llu not allocated in directory (ino %lu)\n",
273                         (unsigned long long)pos, dir->i_ino);
274                 err = -EFSCORRUPTED;
275                 goto out;
276         }
277         err = udf_fiiter_load_bhs(iter);
278         if (err < 0)
279                 goto out;
280         err = udf_copy_fi(iter);
281 out:
282         if (err < 0)
283                 udf_fiiter_release(iter);
284         return err;
285 }
286
287 int udf_fiiter_advance(struct udf_fileident_iter *iter)
288 {
289         unsigned int oldoff, len;
290         int blksize = 1 << iter->dir->i_blkbits;
291         int err;
292
293         oldoff = iter->pos & (blksize - 1);
294         len = udf_dir_entry_len(&iter->fi);
295         iter->pos += len;
296         if (UDF_I(iter->dir)->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
297                 if (oldoff + len >= blksize) {
298                         brelse(iter->bh[0]);
299                         iter->bh[0] = NULL;
300                         /* Next block already loaded? */
301                         if (iter->bh[1]) {
302                                 iter->bh[0] = iter->bh[1];
303                                 iter->bh[1] = NULL;
304                         } else {
305                                 err = udf_fiiter_advance_blk(iter);
306                                 if (err < 0)
307                                         return err;
308                         }
309                 }
310                 err = udf_fiiter_load_bhs(iter);
311                 if (err < 0)
312                         return err;
313         }
314         return udf_copy_fi(iter);
315 }
316
317 void udf_fiiter_release(struct udf_fileident_iter *iter)
318 {
319         iter->dir = NULL;
320         brelse(iter->bh[0]);
321         brelse(iter->bh[1]);
322         iter->bh[0] = iter->bh[1] = NULL;
323         kfree(iter->namebuf);
324         iter->namebuf = NULL;
325 }
326
327 static void udf_copy_to_bufs(void *buf1, int len1, void *buf2, int len2,
328                              int off, void *src, int len)
329 {
330         int copy;
331
332         if (off >= len1) {
333                 off -= len1;
334         } else {
335                 copy = min(off + len, len1) - off;
336                 memcpy(buf1 + off, src, copy);
337                 src += copy;
338                 len -= copy;
339                 off = 0;
340         }
341         if (len > 0) {
342                 if (WARN_ON_ONCE(off + len > len2 || !buf2))
343                         return;
344                 memcpy(buf2 + off, src, len);
345         }
346 }
347
348 static uint16_t udf_crc_fi_bufs(void *buf1, int len1, void *buf2, int len2,
349                                 int off, int len)
350 {
351         int copy;
352         uint16_t crc = 0;
353
354         if (off >= len1) {
355                 off -= len1;
356         } else {
357                 copy = min(off + len, len1) - off;
358                 crc = crc_itu_t(crc, buf1 + off, copy);
359                 len -= copy;
360                 off = 0;
361         }
362         if (len > 0) {
363                 if (WARN_ON_ONCE(off + len > len2 || !buf2))
364                         return 0;
365                 crc = crc_itu_t(crc, buf2 + off, len);
366         }
367         return crc;
368 }
369
370 static void udf_copy_fi_to_bufs(char *buf1, int len1, char *buf2, int len2,
371                                 int off, struct fileIdentDesc *fi,
372                                 uint8_t *impuse, uint8_t *name)
373 {
374         uint16_t crc;
375         int fioff = off;
376         int crcoff = off + sizeof(struct tag);
377         unsigned int crclen = udf_dir_entry_len(fi) - sizeof(struct tag);
378         char zeros[UDF_NAME_PAD] = {};
379         int endoff = off + udf_dir_entry_len(fi);
380
381         udf_copy_to_bufs(buf1, len1, buf2, len2, off, fi,
382                          sizeof(struct fileIdentDesc));
383         off += sizeof(struct fileIdentDesc);
384         if (impuse)
385                 udf_copy_to_bufs(buf1, len1, buf2, len2, off, impuse,
386                                  le16_to_cpu(fi->lengthOfImpUse));
387         off += le16_to_cpu(fi->lengthOfImpUse);
388         if (name) {
389                 udf_copy_to_bufs(buf1, len1, buf2, len2, off, name,
390                                  fi->lengthFileIdent);
391                 off += fi->lengthFileIdent;
392                 udf_copy_to_bufs(buf1, len1, buf2, len2, off, zeros,
393                                  endoff - off);
394         }
395
396         crc = udf_crc_fi_bufs(buf1, len1, buf2, len2, crcoff, crclen);
397         fi->descTag.descCRC = cpu_to_le16(crc);
398         fi->descTag.descCRCLength = cpu_to_le16(crclen);
399         fi->descTag.tagChecksum = udf_tag_checksum(&fi->descTag);
400
401         udf_copy_to_bufs(buf1, len1, buf2, len2, fioff, fi, sizeof(struct tag));
402 }
403
404 void udf_fiiter_write_fi(struct udf_fileident_iter *iter, uint8_t *impuse)
405 {
406         struct udf_inode_info *iinfo = UDF_I(iter->dir);
407         void *buf1, *buf2 = NULL;
408         int len1, len2 = 0, off;
409         int blksize = 1 << iter->dir->i_blkbits;
410
411         off = iter->pos & (blksize - 1);
412         if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
413                 buf1 = iinfo->i_data + iinfo->i_lenEAttr;
414                 len1 = iter->dir->i_size;
415         } else {
416                 buf1 = iter->bh[0]->b_data;
417                 len1 = blksize;
418                 if (iter->bh[1]) {
419                         buf2 = iter->bh[1]->b_data;
420                         len2 = blksize;
421                 }
422         }
423
424         udf_copy_fi_to_bufs(buf1, len1, buf2, len2, off, &iter->fi, impuse,
425                             iter->name == iter->namebuf ? iter->name : NULL);
426
427         if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
428                 mark_inode_dirty(iter->dir);
429         } else {
430                 mark_buffer_dirty_inode(iter->bh[0], iter->dir);
431                 if (iter->bh[1])
432                         mark_buffer_dirty_inode(iter->bh[1], iter->dir);
433         }
434         inode_inc_iversion(iter->dir);
435 }
436
437 void udf_fiiter_update_elen(struct udf_fileident_iter *iter, uint32_t new_elen)
438 {
439         struct udf_inode_info *iinfo = UDF_I(iter->dir);
440         int diff = new_elen - iter->elen;
441
442         /* Skip update when we already went past the last extent */
443         if (!iter->elen)
444                 return;
445         iter->elen = new_elen;
446         if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
447                 iter->epos.offset -= sizeof(struct short_ad);
448         else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
449                 iter->epos.offset -= sizeof(struct long_ad);
450         udf_write_aext(iter->dir, &iter->epos, &iter->eloc, iter->elen, 1);
451         iinfo->i_lenExtents += diff;
452         mark_inode_dirty(iter->dir);
453 }
454
455 /* Append new block to directory. @iter is expected to point at EOF */
456 int udf_fiiter_append_blk(struct udf_fileident_iter *iter)
457 {
458         struct udf_inode_info *iinfo = UDF_I(iter->dir);
459         int blksize = 1 << iter->dir->i_blkbits;
460         struct buffer_head *bh;
461         sector_t block;
462         uint32_t old_elen = iter->elen;
463         int err;
464
465         if (WARN_ON_ONCE(iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB))
466                 return -EINVAL;
467
468         /* Round up last extent in the file */
469         udf_fiiter_update_elen(iter, ALIGN(iter->elen, blksize));
470
471         /* Allocate new block and refresh mapping information */
472         block = iinfo->i_lenExtents >> iter->dir->i_blkbits;
473         bh = udf_bread(iter->dir, block, 1, &err);
474         if (!bh) {
475                 udf_fiiter_update_elen(iter, old_elen);
476                 return err;
477         }
478         if (inode_bmap(iter->dir, block, &iter->epos, &iter->eloc, &iter->elen,
479                        &iter->loffset) != (EXT_RECORDED_ALLOCATED >> 30)) {
480                 udf_err(iter->dir->i_sb,
481                         "block %llu not allocated in directory (ino %lu)\n",
482                         (unsigned long long)block, iter->dir->i_ino);
483                 return -EFSCORRUPTED;
484         }
485         if (!(iter->pos & (blksize - 1))) {
486                 brelse(iter->bh[0]);
487                 iter->bh[0] = bh;
488         } else {
489                 iter->bh[1] = bh;
490         }
491         return 0;
492 }
493
494 struct short_ad *udf_get_fileshortad(uint8_t *ptr, int maxoffset, uint32_t *offset,
495                               int inc)
496 {
497         struct short_ad *sa;
498
499         if ((!ptr) || (!offset)) {
500                 pr_err("%s: invalidparms\n", __func__);
501                 return NULL;
502         }
503
504         if ((*offset + sizeof(struct short_ad)) > maxoffset)
505                 return NULL;
506         else {
507                 sa = (struct short_ad *)ptr;
508                 if (sa->extLength == 0)
509                         return NULL;
510         }
511
512         if (inc)
513                 *offset += sizeof(struct short_ad);
514         return sa;
515 }
516
517 struct long_ad *udf_get_filelongad(uint8_t *ptr, int maxoffset, uint32_t *offset, int inc)
518 {
519         struct long_ad *la;
520
521         if ((!ptr) || (!offset)) {
522                 pr_err("%s: invalidparms\n", __func__);
523                 return NULL;
524         }
525
526         if ((*offset + sizeof(struct long_ad)) > maxoffset)
527                 return NULL;
528         else {
529                 la = (struct long_ad *)ptr;
530                 if (la->extLength == 0)
531                         return NULL;
532         }
533
534         if (inc)
535                 *offset += sizeof(struct long_ad);
536         return la;
537 }