Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * QNX4 file system, Linux implementation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Version : 0.2.1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Using parts of the xiafs filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * History :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * 28-05-1998 by Richard Frowijn : first release.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * 20-06-1998 by Frank Denis : Linux 2.1.99+ & dcache support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/buffer_head.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include "qnx4.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * A qnx4 directory entry is an inode entry or link info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * depending on the status field in the last byte. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * first byte is where the name start either way, and a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * zero means it's empty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * Also, due to a bug in gcc, we don't want to use the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * real (differently sized) name arrays in the inode and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * link entries, but always the 'de_name[]' one in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * fake struct entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * See
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  *   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99578#c6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * for details, but basically gcc will take the size of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  * 'name' array from one of the used union entries randomly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  * This use of 'de_name[]' (48 bytes) avoids the false positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  * warnings that would happen if gcc decides to use 'inode.di_name'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * (16 bytes) even when the pointer and size were to come from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * 'link.dl_name' (48 bytes).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  * In all cases the actual name pointer itself is the same, it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  * only the gcc internal 'what is the size of this field' logic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  * that can get confused.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) union qnx4_directory_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		const char de_name[48];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		u8 de_pad[15];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		u8 de_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	struct qnx4_inode_entry inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	struct qnx4_link_info link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) static int qnx4_readdir(struct file *file, struct dir_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	unsigned int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	struct buffer_head *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	unsigned long blknum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	int ix, ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	QNX4DEBUG((KERN_INFO "qnx4_readdir:i_size = %ld\n", (long) inode->i_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	QNX4DEBUG((KERN_INFO "pos                 = %ld\n", (long) ctx->pos));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	while (ctx->pos < inode->i_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		blknum = qnx4_block_map(inode, ctx->pos >> QNX4_BLOCK_SIZE_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		bh = sb_bread(inode->i_sb, blknum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		if (bh == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 			printk(KERN_ERR "qnx4_readdir: bread failed (%ld)\n", blknum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		ix = (ctx->pos >> QNX4_DIR_ENTRY_SIZE_BITS) % QNX4_INODES_PER_BLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		for (; ix < QNX4_INODES_PER_BLOCK; ix++, ctx->pos += QNX4_DIR_ENTRY_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 			union qnx4_directory_entry *de;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 			offset = ix * QNX4_DIR_ENTRY_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 			de = (union qnx4_directory_entry *) (bh->b_data + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 			if (!de->de_name[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 			if (!(de->de_status & (QNX4_FILE_USED|QNX4_FILE_LINK)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 			if (!(de->de_status & QNX4_FILE_LINK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 				size = sizeof(de->inode.di_fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 				ino = blknum * QNX4_INODES_PER_BLOCK + ix - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 				size = sizeof(de->link.dl_fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 				ino = ( le32_to_cpu(de->link.dl_inode_blk) - 1 ) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 					QNX4_INODES_PER_BLOCK +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 					de->link.dl_inode_ndx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 			size = strnlen(de->de_name, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 			QNX4DEBUG((KERN_INFO "qnx4_readdir:%.*s\n", size, name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 			if (!dir_emit(ctx, de->de_name, size, ino, DT_UNKNOWN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 				brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) const struct file_operations qnx4_dir_operations =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	.llseek		= generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	.read		= generic_read_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	.iterate_shared	= qnx4_readdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	.fsync		= generic_file_fsync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) const struct inode_operations qnx4_dir_inode_operations =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	.lookup		= qnx4_lookup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) };