b24413180f560 (Greg Kroah-Hartman 2017-11-01 15:07:57 +0100 1) // SPDX-License-Identifier: GPL-2.0
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3) * linux/fs/isofs/dir.c
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 4) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 5) * (C) 1992, 1993, 1994 Eric Youngdale Modified for ISO 9660 filesystem.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 6) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 7) * (C) 1991 Linus Torvalds - minix filesystem
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 8) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 9) * Steve Beynon : Missing last directory entries fixed
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 10) * (stephen@askone.demon.co.uk) : 21st June 1996
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 11) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 12) * isofs directory handling functions
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 13) */
5a0e3ad6af866 (Tejun Heo 2010-03-24 17:04:11 +0900 14) #include <linux/gfp.h>
94f2f715771d0 (Al Viro 2005-04-25 18:32:12 -0700 15) #include "isofs.h"
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 16)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 17) int isofs_name_translate(struct iso_directory_record *de, char *new, struct inode *inode)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 18) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 19) char * old = de->name;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 20) int len = de->name_len[0];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 21) int i;
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 22)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 23) for (i = 0; i < len; i++) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 24) unsigned char c = old[i];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 25) if (!c)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 26) break;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 27)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 28) if (c >= 'A' && c <= 'Z')
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 29) c |= 0x20; /* lower case */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 30)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 31) /* Drop trailing '.;1' (ISO 9660:1988 7.5.1 requires period) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 32) if (c == '.' && i == len - 3 && old[i + 1] == ';' && old[i + 2] == '1')
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 33) break;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 34)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 35) /* Drop trailing ';1' */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 36) if (c == ';' && i == len - 2 && old[i + 1] == '1')
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 37) break;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 38)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 39) /* Convert remaining ';' to '.' */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 40) /* Also '/' to '.' (broken Acorn-generated ISO9660 images) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 41) if (c == ';' || c == '/')
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 42) c = '.';
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 43)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 44) new[i] = c;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 45) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 46) return i;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 47) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 48)
3d0186bb068e6 (Matthew Wilcox 2018-06-16 17:32:07 -0400 49) /* Acorn extensions written by Matthew Wilcox <willy@infradead.org> 1998 */
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 50) int get_acorn_filename(struct iso_directory_record *de,
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 51) char *retname, struct inode *inode)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 52) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 53) int std;
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 54) unsigned char *chr;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 55) int retnamlen = isofs_name_translate(de, retname, inode);
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 56)
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 57) if (retnamlen == 0)
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 58) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 59) std = sizeof(struct iso_directory_record) + de->name_len[0];
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 60) if (std & 1)
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 61) std++;
e17a21d3bb067 (Al Viro 2016-05-05 10:48:47 -0400 62) if (de->length[0] - std != 32)
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 63) return retnamlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 64) chr = ((unsigned char *) de) + std;
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 65) if (strncmp(chr, "ARCHIMEDES", 10))
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 66) return retnamlen;
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 67) if ((*retname == '_') && ((chr[19] & 1) == 1))
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 68) *retname = '!';
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 69) if (((de->flags[0] & 2) == 0) && (chr[13] == 0xff)
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 70) && ((chr[12] & 0xf0) == 0xf0)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 71) retname[retnamlen] = ',';
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 72) sprintf(retname+retnamlen+1, "%3.3x",
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 73) ((chr[12] & 0xf) << 8) | chr[11]);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 74) retnamlen += 4;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 75) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 76) return retnamlen;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 77) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 78)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 79) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 80) * This should _really_ be cleaned up some day..
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 81) */
bfee7169c0210 (Al Viro 2013-05-17 21:11:59 -0400 82) static int do_isofs_readdir(struct inode *inode, struct file *file,
bfee7169c0210 (Al Viro 2013-05-17 21:11:59 -0400 83) struct dir_context *ctx,
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 84) char *tmpname, struct iso_directory_record *tmpde)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 85) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 86) unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 87) unsigned char bufbits = ISOFS_BUFFER_BITS(inode);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 88) unsigned long block, offset, block_saved, offset_saved;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 89) unsigned long inode_number = 0; /* Quiet GCC */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 90) struct buffer_head *bh = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 91) int len;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 92) int map;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 93) int first_de = 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 94) char *p = NULL; /* Quiet GCC */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 95) struct iso_directory_record *de;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 96) struct isofs_sb_info *sbi = ISOFS_SB(inode->i_sb);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 97)
bfee7169c0210 (Al Viro 2013-05-17 21:11:59 -0400 98) offset = ctx->pos & (bufsize - 1);
bfee7169c0210 (Al Viro 2013-05-17 21:11:59 -0400 99) block = ctx->pos >> bufbits;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 100)
bfee7169c0210 (Al Viro 2013-05-17 21:11:59 -0400 101) while (ctx->pos < inode->i_size) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 102) int de_len;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 103)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 104) if (!bh) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 105) bh = isofs_bread(inode, block);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 106) if (!bh)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 107) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 108) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 109)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 110) de = (struct iso_directory_record *) (bh->b_data + offset);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 111)
bfee7169c0210 (Al Viro 2013-05-17 21:11:59 -0400 112) de_len = *(unsigned char *)de;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 113)
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 114) /*
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 115) * If the length byte is zero, we should move on to the next
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 116) * CDROM sector. If we are at the end of the directory, we
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 117) * kick out of the while loop.
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 118) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 119)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 120) if (de_len == 0) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 121) brelse(bh);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 122) bh = NULL;
bfee7169c0210 (Al Viro 2013-05-17 21:11:59 -0400 123) ctx->pos = (ctx->pos + ISOFS_BLOCK_SIZE) & ~(ISOFS_BLOCK_SIZE - 1);
bfee7169c0210 (Al Viro 2013-05-17 21:11:59 -0400 124) block = ctx->pos >> bufbits;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 125) offset = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 126) continue;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 127) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 128)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 129) block_saved = block;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 130) offset_saved = offset;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 131) offset += de_len;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 132)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 133) /* Make sure we have a full directory entry */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 134) if (offset >= bufsize) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 135) int slop = bufsize - offset + de_len;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 136) memcpy(tmpde, de, slop);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 137) offset &= bufsize - 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 138) block++;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 139) brelse(bh);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 140) bh = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 141) if (offset) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 142) bh = isofs_bread(inode, block);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 143) if (!bh)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 144) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 145) memcpy((void *) tmpde + slop, bh->b_data, offset);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 146) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 147) de = tmpde;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 148) }
2deb1acc653cb (Jan Kara 2008-04-30 00:52:33 -0700 149) /* Basic sanity check, whether name doesn't exceed dir entry */
2deb1acc653cb (Jan Kara 2008-04-30 00:52:33 -0700 150) if (de_len < de->name_len[0] +
2deb1acc653cb (Jan Kara 2008-04-30 00:52:33 -0700 151) sizeof(struct iso_directory_record)) {
2deb1acc653cb (Jan Kara 2008-04-30 00:52:33 -0700 152) printk(KERN_NOTICE "iso9660: Corrupted directory entry"
2deb1acc653cb (Jan Kara 2008-04-30 00:52:33 -0700 153) " in block %lu of inode %lu\n", block,
2deb1acc653cb (Jan Kara 2008-04-30 00:52:33 -0700 154) inode->i_ino);
0a6dc67a6aa45 (Pan Bian 2021-01-18 04:04:55 -0800 155) brelse(bh);
2deb1acc653cb (Jan Kara 2008-04-30 00:52:33 -0700 156) return -EIO;
2deb1acc653cb (Jan Kara 2008-04-30 00:52:33 -0700 157) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 158)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 159) if (first_de) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 160) isofs_normalize_block_and_offset(de,
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 161) &block_saved,
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 162) &offset_saved);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 163) inode_number = isofs_get_ino(block_saved,
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 164) offset_saved, bufbits);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 165) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 166)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 167) if (de->flags[-sbi->s_high_sierra] & 0x80) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 168) first_de = 0;
bfee7169c0210 (Al Viro 2013-05-17 21:11:59 -0400 169) ctx->pos += de_len;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 170) continue;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 171) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 172) first_de = 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 173)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 174) /* Handle the case of the '.' directory */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 175) if (de->name_len[0] == 1 && de->name[0] == 0) {
bfee7169c0210 (Al Viro 2013-05-17 21:11:59 -0400 176) if (!dir_emit_dot(file, ctx))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 177) break;
bfee7169c0210 (Al Viro 2013-05-17 21:11:59 -0400 178) ctx->pos += de_len;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 179) continue;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 180) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 181)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 182) len = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 183)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 184) /* Handle the case of the '..' directory */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 185) if (de->name_len[0] == 1 && de->name[0] == 1) {
bfee7169c0210 (Al Viro 2013-05-17 21:11:59 -0400 186) if (!dir_emit_dotdot(file, ctx))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 187) break;
bfee7169c0210 (Al Viro 2013-05-17 21:11:59 -0400 188) ctx->pos += de_len;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 189) continue;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 190) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 191)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 192) /* Handle everything else. Do name translation if there
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 193) is no Rock Ridge NM field. */
9769f4eb3fad2 (Jeremy White 2005-06-21 17:16:53 -0700 194)
9769f4eb3fad2 (Jeremy White 2005-06-21 17:16:53 -0700 195) /*
9769f4eb3fad2 (Jeremy White 2005-06-21 17:16:53 -0700 196) * Do not report hidden files if so instructed, or associated
9769f4eb3fad2 (Jeremy White 2005-06-21 17:16:53 -0700 197) * files unless instructed to do so
9769f4eb3fad2 (Jeremy White 2005-06-21 17:16:53 -0700 198) */
5404ac8e4418a (Jan Kara 2009-06-17 16:26:27 -0700 199) if ((sbi->s_hide && (de->flags[-sbi->s_high_sierra] & 1)) ||
5404ac8e4418a (Jan Kara 2009-06-17 16:26:27 -0700 200) (!sbi->s_showassoc &&
9769f4eb3fad2 (Jeremy White 2005-06-21 17:16:53 -0700 201) (de->flags[-sbi->s_high_sierra] & 4))) {
bfee7169c0210 (Al Viro 2013-05-17 21:11:59 -0400 202) ctx->pos += de_len;
9769f4eb3fad2 (Jeremy White 2005-06-21 17:16:53 -0700 203) continue;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 204) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 205)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 206) map = 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 207) if (sbi->s_rock) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 208) len = get_rock_ridge_filename(de, tmpname, inode);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 209) if (len != 0) { /* may be -1 */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 210) p = tmpname;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 211) map = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 212) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 213) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 214) if (map) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 215) #ifdef CONFIG_JOLIET
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 216) if (sbi->s_joliet_level) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 217) len = get_joliet_filename(de, tmpname, inode);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 218) p = tmpname;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 219) } else
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 220) #endif
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 221) if (sbi->s_mapping == 'a') {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 222) len = get_acorn_filename(de, tmpname, inode);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 223) p = tmpname;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 224) } else
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 225) if (sbi->s_mapping == 'n') {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 226) len = isofs_name_translate(de, tmpname, inode);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 227) p = tmpname;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 228) } else {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 229) p = de->name;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 230) len = de->name_len[0];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 231) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 232) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 233) if (len > 0) {
bfee7169c0210 (Al Viro 2013-05-17 21:11:59 -0400 234) if (!dir_emit(ctx, p, len, inode_number, DT_UNKNOWN))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 235) break;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 236) }
bfee7169c0210 (Al Viro 2013-05-17 21:11:59 -0400 237) ctx->pos += de_len;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 238)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 239) continue;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 240) }
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 241) if (bh)
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 242) brelse(bh);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 243) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 244) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 245)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 246) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 247) * Handle allocation of temporary space for name translation and
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 248) * handling split directory entries.. The real work is done by
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 249) * "do_isofs_readdir()".
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 250) */
bfee7169c0210 (Al Viro 2013-05-17 21:11:59 -0400 251) static int isofs_readdir(struct file *file, struct dir_context *ctx)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 252) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 253) int result;
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 254) char *tmpname;
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 255) struct iso_directory_record *tmpde;
bfee7169c0210 (Al Viro 2013-05-17 21:11:59 -0400 256) struct inode *inode = file_inode(file);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 257)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 258) tmpname = (char *)__get_free_page(GFP_KERNEL);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 259) if (tmpname == NULL)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 260) return -ENOMEM;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 261)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 262) tmpde = (struct iso_directory_record *) (tmpname+1024);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 263)
bfee7169c0210 (Al Viro 2013-05-17 21:11:59 -0400 264) result = do_isofs_readdir(inode, file, ctx, tmpname, tmpde);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 265)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 266) free_page((unsigned long) tmpname);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 267) return result;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 268) }
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 269)
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 270) const struct file_operations isofs_dir_operations =
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 271) {
ca572727dbb94 (jan Blunck 2010-05-26 14:44:53 -0700 272) .llseek = generic_file_llseek,
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 273) .read = generic_read_dir,
e899108994540 (Al Viro 2016-05-09 12:53:03 -0400 274) .iterate_shared = isofs_readdir,
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 275) };
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 276)
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 277) /*
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 278) * directories can handle most operations...
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 279) */
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 280) const struct inode_operations isofs_dir_inode_operations =
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 281) {
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 282) .lookup = isofs_lookup,
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 283) };
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 284)
c3ed85a36ff5b (Dave Jones 2007-07-15 23:40:03 -0700 285)