diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-02-16 01:07:24 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-02-16 01:07:24 +0000 |
commit | 95db6b748fc86297827fbd9c9ef174d491c9ad89 (patch) | |
tree | 27a92a942821cde1edda9a1b088718d436b3efe4 /fs | |
parent | 45b27b0a0652331d104c953a5b192d843fff88f8 (diff) |
Merge with Linux 2.3.40.
Diffstat (limited to 'fs')
58 files changed, 857 insertions, 497 deletions
diff --git a/fs/Config.in b/fs/Config.in index 5919ef6f3..daad6d182 100644 --- a/fs/Config.in +++ b/fs/Config.in @@ -53,9 +53,9 @@ if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then bool '/dev/pts filesystem for Unix98 PTYs' CONFIG_DEVPTS_FS fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'QNX filesystem support (read only) (EXPERIMENTAL)' CONFIG_QNX4FS_FS + tristate 'QNX4 filesystem support (read only) (EXPERIMENTAL)' CONFIG_QNX4FS_FS if [ "$CONFIG_QNX4FS_FS" != "n" ]; then - bool ' QNXFS write support (DANGEROUS)' CONFIG_QNX4FS_RW + bool ' QNX4FS write support (DANGEROUS)' CONFIG_QNX4FS_RW fi fi tristate 'ROM filesystem support' CONFIG_ROMFS_FS diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 470c122b2..0d8a3c109 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -29,6 +29,7 @@ #include <linux/personality.h> #include <linux/elfcore.h> #include <linux/init.h> +#include <linux/highuid.h> #include <asm/uaccess.h> #include <asm/pgalloc.h> @@ -1168,8 +1169,8 @@ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file) psinfo.pr_zomb = psinfo.pr_sname == 'Z'; psinfo.pr_nice = current->priority-15; psinfo.pr_flag = current->flags; - psinfo.pr_uid = current->uid; - psinfo.pr_gid = current->gid; + psinfo.pr_uid = NEW_TO_OLD_UID(current->uid); + psinfo.pr_gid = NEW_TO_OLD_GID(current->gid); { int i, len; diff --git a/fs/block_dev.c b/fs/block_dev.c index c32b8c0f2..0e34b95bd 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -298,7 +298,7 @@ ssize_t block_read(struct file * filp, char * buf, size_t count, loff_t *ppos) * since the vma has no handle. */ -int block_fsync(struct file *filp, struct dentry *dentry) +static int block_fsync(struct file *filp, struct dentry *dentry) { return fsync_dev(dentry->d_inode->i_rdev); } @@ -604,8 +604,11 @@ int blkdev_put(struct block_device *bdev, int kind) kdev_t rdev = to_kdev_t(bdev->bd_dev); /* this should become bdev */ down(&bdev->bd_sem); /* syncing will go here */ + if (kind == BDEV_FILE || kind == BDEV_FS) + fsync_dev(rdev); if (atomic_dec_and_test(&bdev->bd_openers)) { /* invalidating buffers will go here */ + invalidate_buffers(rdev); } if (bdev->bd_op->release) { struct inode * fake_inode = get_empty_inode(); diff --git a/fs/cramfs/README b/fs/cramfs/README new file mode 100644 index 000000000..a04f41b1f --- /dev/null +++ b/fs/cramfs/README @@ -0,0 +1,166 @@ +Notes on Filesystem Layout +-------------------------- + +These notes describe what mkcramfs generates. Kernel requirements are +a bit looser, e.g. it doesn't care if the <file_data> items are +swapped around (though it does care that directory entries (inodes) in +a given directory are contiguous, as this is used by readdir). + +All data is in host-endian format; neither mkcramfs nor the kernel +ever do swabbing. (See section `Block Size' below.) + +<filesystem>: + <superblock> + <directory_structure> + <data> + +<superblock>: struct cramfs_super (see cramfs.h). + +<directory_structure>: + For each file: + struct cramfs_inode (see cramfs.h). + Filename. Not generally null-terminated, but it is + null-padded to a multiple of 4 bytes. + +The order of inode traversal is described as "width-first" (not to be +confused with breadth-first); i.e. like depth-first but listing all of +a directory's entries before recursing down its subdirectories: the +same order as `ls -AUR' (but without the /^\..*:$/ directory header +lines); put another way, the same order as `find -type d -exec +ls -AU1 {} \;'. + +<data>: + One <file_data> for each file that's either a symlink or a + regular file of non-zero st_size. + +<file_data>: + nblocks * <block_pointer> + (where nblocks = (st_size - 1) / blksize + 1) + nblocks * <block> + padding to multiple of 4 bytes + +The i'th <block_pointer> for a file stores the byte offset of the +*end* of the i'th <block> (i.e. one past the last byte, which is the +same as the start of the (i+1)'th <block> if there is one). The first +<block> immediately follows the last <block_pointer> for the file. +<block_pointer>s are each 32 bits long. + +The order of <file_data>'s is a depth-first descent of the directory +tree, i.e. the same order as `find -size +0 \( -type f -o -type l \) +-print'. + + +<block>: The i'th <block> is the output of zlib's compress function +applied to the i'th blksize-sized chunk of the input data. +(For the last <block> of the file, the input may of course be smaller.) +Each <block> may be a different size. (See <block_pointer> above.) +<block>s are merely byte-aligned, not generally u32-aligned. + + +Holes +----- + +This kernel supports cramfs holes (i.e. [efficient representation of] +blocks in uncompressed data consisting entirely of NUL bytes), but by +default mkcramfs doesn't test for & create holes, since cramfs in +kernels up to at least 2.3.39 didn't support holes. Compile mkcramfs +with -DDO_HOLES if you want it to create files that can have holes in +them. + + +Tools +----- + +If you're hacking on cramfs, you might find useful some tools for +testing cramfs at <http://cvs.bofh.asn.au/cramfs/>, including a +rudimentary fsck for cramfs. + + +Future Development +================== + +Block Size +---------- + +(Block size in cramfs refers to the size of input data that is +compressed at a time. It's intended to be somewhere around +PAGE_CACHE_SIZE for cramfs_readpage's convenience.) + +The superblock ought to indicate the block size that the fs was +written for, since comments in <linux/pagemap.h> indicate that +PAGE_CACHE_SIZE may grow in future (if I interpret the comment +correctly). + +Currently, mkcramfs #define's PAGE_CACHE_SIZE as 4096 and uses that +for blksize, whereas Linux-2.3.39 uses its PAGE_CACHE_SIZE, which in +turn is defined as PAGE_SIZE (which can be as large as 32KB on arm). +This discrepancy is a bug, though it's not clear which should be +changed. + +One option is to change mkcramfs to take its PAGE_CACHE_SIZE from +<asm/page.h>. Personally I don't like this option, but it does +require the least amount of change: just change `#define +PAGE_CACHE_SIZE (4096)' to `#include <asm/page.h>'. The disadvantage +is that the generated cramfs cannot always be shared between different +kernels, not even necessarily kernels of the same architecture if +PAGE_CACHE_SIZE is subject to change between kernel versions. + + +The remaining options try to make cramfs more sharable. + +One part of that is addressing endianness. The two options here are +`always use little-endian' (like ext2fs) or `writer chooses +endianness; kernel adapts at runtime'. Little-endian wins because of +code simplicity and little CPU overhead even on big-endian machines. + +The cost of swabbing is changing the code to use the le32_to_cpu +etc. macros as used by ext2fs. We don't need to swab the compressed +data, only the superblock, inodes and block pointers. + + +The other part of making cramfs more sharable is choosing a block +size. The options are: + + 1. Always 4096 bytes. + + 2. Writer chooses blocksize; kernel adapts but rejects blocksize > + PAGE_CACHE_SIZE. + + 3. Writer chooses blocksize; kernel adapts even to blocksize > + PAGE_CACHE_SIZE. + +It's easy enough to change the kernel to use a smaller value than +PAGE_CACHE_SIZE: just make cramfs_readpage read multiple blocks. + +The cost of option 1 is that kernels with a larger PAGE_CACHE_SIZE +value don't get as good compression as they can. + +The cost of option 2 relative to option 1 is that the code uses +variables instead of #define'd constants. The gain is that people +with kernels having larger PAGE_CACHE_SIZE can make use of that if +they don't mind their cramfs being inaccessible to kernels with +smaller PAGE_CACHE_SIZE values. + +Option 3 is easy to implement if we don't mind being CPU-inefficient: +e.g. get readpage to decompress to a buffer of size MAX_BLKSIZE (which +must be no larger than 32KB) and discard what it doesn't need. +Getting readpage to read into all the covered pages is harder. + +The main advantage of option 3 over 1, 2, is better compression. The +cost is greater complexity. Probably not worth it, but I hope someone +will disagree. (If it is implemented, then I'll re-use that code in +e2compr.) + + +Another cost of 2 and 3 over 1 is making mkcramfs use a different +block size, but that just means adding and parsing a -b option. + + +Inode Size +---------- + +Given that cramfs will probably be used for CDs etc. as well as just +silicon ROMs, it might make sense to expand the inode a little from +its current 12 bytes. Inodes other than the root inode are followed +by filename, so the expansion doesn't even have to be a multiple of 4 +bytes. diff --git a/fs/cramfs/cramfs.h b/fs/cramfs/cramfs.h index e98cd7309..b7e4e7600 100644 --- a/fs/cramfs/cramfs.h +++ b/fs/cramfs/cramfs.h @@ -5,17 +5,20 @@ #define CRAMFS_SIGNATURE "Compressed ROMFS" /* - * Reasonably terse representation of the inode - * data.. When the mode of the inode indicates - * a special device node, the "offset" bits will - * encode i_rdev. In other cases, "offset" points - * to the ROM image for the actual file data - * (whether that data be directory or compressed - * file data depends on the inode type again) + * Reasonably terse representation of the inode data. */ struct cramfs_inode { u32 mode:16, uid:16; + /* SIZE for device files is i_rdev */ u32 size:24, gid:8; + /* NAMELEN is the length of the file name, divided by 4 and + rounded up. (cramfs doesn't support hard links.) */ + /* OFFSET: For symlinks and non-empty regular files, this + contains the offset (divided by 4) of the file data in + compressed form (starting with an array of block pointers; + see README). For non-empty directories it is the offset + (divided by 4) of the inode of the first file in that + directory. For anything else, offset is zero. */ u32 namelen:6, offset:26; }; @@ -24,7 +27,8 @@ struct cramfs_inode { */ struct cramfs_super { u32 magic; /* 0x28cd3d45 - random number */ - u32 size; /* > offset, < 2**26 */ + u32 size; /* Not used. mkcramfs currently + writes a constant 1<<16 here. */ u32 flags; /* 0 */ u32 future; /* 0 */ u8 signature[16]; /* "Compressed ROMFS" */ @@ -33,6 +37,13 @@ struct cramfs_super { struct cramfs_inode root; /* Root inode data */ }; +/* + * Valid values in super.flags. Currently we refuse to mount + * if (flags & ~CRAMFS_SUPPORTED_FLAGS). Maybe that should be + * changed to test super.future instead. + */ +#define CRAMFS_SUPPORTED_FLAGS (0xff) + /* Uncompression interfaces to the underlying zlib */ int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen); int cramfs_uncompress_init(void); diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index 1bd40cb92..07c8f15a1 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c @@ -27,7 +27,10 @@ static struct inode_operations cramfs_file_inode_operations; static struct inode_operations cramfs_dir_inode_operations; static struct inode_operations cramfs_symlink_inode_operations; +/* These two macros may change in future, to provide better st_ino + semantics. */ #define CRAMINO(x) ((x)->offset?(x)->offset<<2:1) +#define OFFSET(x) ((x)->i_ino) static struct inode *get_cramfs_inode(struct super_block *sb, struct cramfs_inode * cramfs_inode) { @@ -41,6 +44,12 @@ static struct inode *get_cramfs_inode(struct super_block *sb, struct cramfs_inod inode->i_ino = CRAMINO(cramfs_inode); inode->i_sb = sb; inode->i_dev = sb->s_dev; + inode->i_nlink = 1; /* arguably wrong for directories, + but it's the best we can do + without reading the directory + contents. 1 yields the right + result in GNU find, even + without -noleaf option. */ insert_inode_hash(inode); if (S_ISREG(inode->i_mode)) inode->i_op = &cramfs_file_inode_operations; @@ -62,45 +71,75 @@ static struct inode *get_cramfs_inode(struct super_block *sb, struct cramfs_inod * up the accesses should be fairly regular and cached in the * page cache and dentry tree anyway.. * - * This also acts as a way to guarantee contiguous areas of - * up to 2*PAGE_CACHE_SIZE, so that the caller doesn't need - * to worry about end-of-buffer issues even when decompressing - * a full page cache. + * This also acts as a way to guarantee contiguous areas of up to + * BLKS_PER_BUF*PAGE_CACHE_SIZE, so that the caller doesn't need to + * worry about end-of-buffer issues even when decompressing a full + * page cache. */ #define READ_BUFFERS (2) -static unsigned char read_buffers[READ_BUFFERS][PAGE_CACHE_SIZE*4]; -static int buffer_blocknr[READ_BUFFERS]; -static int last_buffer = 0; +/* NEXT_BUFFER(): Loop over [0..(READ_BUFFERS-1)]. */ +#define NEXT_BUFFER(_ix) ((_ix) ^ 1) -static void *cramfs_read(struct super_block *sb, unsigned int offset) +/* + * BLKS_PER_BUF_SHIFT must be at least 1 to allow for "compressed" + * data that takes up more space than the original. 1 is guaranteed + * to suffice, though. Larger values provide more read-ahead and + * proportionally less wastage at the end of the buffer. + */ +#define BLKS_PER_BUF_SHIFT (2) +#define BLKS_PER_BUF (1 << BLKS_PER_BUF_SHIFT) +static unsigned char read_buffers[READ_BUFFERS][BLKS_PER_BUF][PAGE_CACHE_SIZE]; +static unsigned buffer_blocknr[READ_BUFFERS]; +static int next_buffer = 0; + +/* + * Returns a pointer to a buffer containing at least LEN bytes of + * filesystem starting at byte offset OFFSET into the filesystem. + */ +static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned int len) { - struct buffer_head * bh_array[4]; - int i, blocknr, buffer; + struct buffer_head * bh_array[BLKS_PER_BUF]; + unsigned i, blocknr, last_blocknr, buffer; + if (!len) + return NULL; blocknr = offset >> PAGE_CACHE_SHIFT; - offset &= PAGE_CACHE_SIZE-1; + last_blocknr = (offset + len - 1) >> PAGE_CACHE_SHIFT; + if (last_blocknr - blocknr >= BLKS_PER_BUF) + goto eek; resume: + offset &= PAGE_CACHE_SIZE - 1; for (i = 0; i < READ_BUFFERS; i++) { - if (blocknr == buffer_blocknr[i]) - return read_buffers[i] + offset; + if ((blocknr >= buffer_blocknr[i]) && + (last_blocknr - buffer_blocknr[i] < BLKS_PER_BUF)) + return &read_buffers[i][blocknr - buffer_blocknr[i]][offset]; } - /* Ok, read in four buffers completely first */ - for (i = 0; i < 4; i++) + /* Ok, read in BLKS_PER_BUF pages completely first. */ + for (i = 0; i < BLKS_PER_BUF; i++) bh_array[i] = bread(sb->s_dev, blocknr + i, PAGE_CACHE_SIZE); - /* Ok, copy them to the staging area without sleeping.. */ - buffer = last_buffer; - last_buffer = buffer ^ 1; + /* Ok, copy them to the staging area without sleeping. */ + buffer = next_buffer; + next_buffer = NEXT_BUFFER(buffer); buffer_blocknr[buffer] = blocknr; - for (i = 0; i < 4; i++) { + for (i = 0; i < BLKS_PER_BUF; i++) { struct buffer_head * bh = bh_array[i]; if (bh) { - memcpy(read_buffers[buffer] + i*PAGE_CACHE_SIZE, bh->b_data, PAGE_CACHE_SIZE); + memcpy(read_buffers[buffer][i], bh->b_data, PAGE_CACHE_SIZE); bforget(bh); - } - blocknr++; + } else + memset(read_buffers[buffer][i], 0, PAGE_CACHE_SIZE); } - return read_buffers[buffer] + offset; + return read_buffers[buffer][0] + offset; + + eek: + printk(KERN_ERR + "cramfs (device %s): requested chunk (%u:+%u) bigger than buffer\n", + bdevname(sb->s_dev), offset, len); + /* TODO: return EIO to process or kill the current process + instead of resuming. */ + *((int *)0) = 0; /* XXX: doesn't work on all archs */ + goto resume; } @@ -121,7 +160,7 @@ static struct super_block * cramfs_read_super(struct super_block *sb, void *data buffer_blocknr[i] = -1; /* Read the first block and get the superblock from it */ - memcpy(&super, cramfs_read(sb, 0), sizeof(super)); + memcpy(&super, cramfs_read(sb, 0, sizeof(super)), sizeof(super)); /* Do sanity checks on the superblock */ if (super.magic != CRAMFS_MAGIC) { @@ -132,21 +171,23 @@ static struct super_block * cramfs_read_super(struct super_block *sb, void *data printk("wrong signature\n"); goto out; } - - /* Check that the root inode is in a sane state */ - root_offset = super.root.offset << 2; - if (root_offset < sizeof(struct cramfs_super)) { - printk("root offset too small\n"); - goto out; - } - if (root_offset >= super.size) { - printk("root offset too large (%lu %u)\n", root_offset, super.size); + if (super.flags & ~CRAMFS_SUPPORTED_FLAGS) { + printk("unsupported filesystem features\n"); goto out; } + + /* Check that the root inode is in a sane state */ if (!S_ISDIR(super.root.mode)) { printk("root is not a directory\n"); goto out; } + root_offset = super.root.offset << 2; + if (root_offset == 0) + printk(KERN_INFO "cramfs: note: empty filesystem"); + else if (root_offset != sizeof(struct cramfs_super)) { + printk("bad root offset %lu\n", root_offset); + goto out; + } /* Set it all up.. */ sb->s_op = &cramfs_ops; @@ -168,19 +209,20 @@ static int cramfs_statfs(struct super_block *sb, struct statfs *buf, int bufsize { struct statfs tmp; - memset(&tmp, 0, sizeof(tmp)); + /* Unsupported fields set to -1 as per man page. */ + memset(&tmp, 0xff, sizeof(tmp)); + tmp.f_type = CRAMFS_MAGIC; tmp.f_bsize = PAGE_CACHE_SIZE; - tmp.f_blocks = 0; + tmp.f_bfree = 0; + tmp.f_bavail = 0; + tmp.f_ffree = 0; tmp.f_namelen = 255; return copy_to_user(buf, &tmp, bufsize) ? -EFAULT : 0; } /* - * Read a cramfs directory entry.. - * - * Remember: the inode number is the byte offset of the start - * of the directory.. + * Read a cramfs directory entry. */ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir) { @@ -189,7 +231,7 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir) unsigned int offset; int copied; - /* Offset within the thing.. */ + /* Offset within the thing. */ offset = filp->f_pos; if (offset >= inode->i_size) return 0; @@ -204,7 +246,7 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir) char *name; int namelen, error; - de = cramfs_read(sb, offset + inode->i_ino); + de = cramfs_read(sb, OFFSET(inode) + offset, sizeof(*de)+256); name = (char *)(de+1); /* @@ -244,7 +286,7 @@ static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry) char *name; int namelen; - de = cramfs_read(dir->i_sb, offset + dir->i_ino); + de = cramfs_read(dir->i_sb, OFFSET(dir) + offset, sizeof(*de)+256); name = (char *)(de+1); namelen = de->namelen << 2; offset += sizeof(*de) + namelen; @@ -274,27 +316,29 @@ static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry) static int cramfs_readpage(struct dentry *dentry, struct page * page) { struct inode *inode = dentry->d_inode; - unsigned long maxblock, bytes; + u32 maxblock, bytes_filled; maxblock = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; - bytes = 0; + bytes_filled = 0; if (page->index < maxblock) { struct super_block *sb = inode->i_sb; - unsigned long block_offset = inode->i_ino + page->index*4; - unsigned long start_offset = inode->i_ino + maxblock*4; - unsigned long end_offset; + u32 blkptr_offset = OFFSET(inode) + page->index*4; + u32 start_offset, compr_len; - end_offset = *(u32 *) cramfs_read(sb, block_offset); + start_offset = OFFSET(inode) + maxblock*4; if (page->index) - start_offset = *(u32 *) cramfs_read(sb, block_offset-4); - - bytes = inode->i_size & (PAGE_CACHE_SIZE - 1); - if (page->index < maxblock) - bytes = PAGE_CACHE_SIZE; - - cramfs_uncompress_block((void *) page_address(page), PAGE_CACHE_SIZE, cramfs_read(sb, start_offset), end_offset - start_offset); + start_offset = *(u32 *) cramfs_read(sb, blkptr_offset-4, 4); + compr_len = (*(u32 *) cramfs_read(sb, blkptr_offset, 4) + - start_offset); + if (compr_len == 0) + ; /* hole */ + else + bytes_filled = cramfs_uncompress_block((void *) page_address(page), + PAGE_CACHE_SIZE, + cramfs_read(sb, start_offset, compr_len), + compr_len); } - memset((void *) (page_address(page) + bytes), 0, PAGE_CACHE_SIZE - bytes); + memset((void *) (page_address(page) + bytes_filled), 0, PAGE_CACHE_SIZE - bytes_filled); SetPageUptodate(page); UnlockPage(page); return 0; diff --git a/fs/cramfs/uncompress.c b/fs/cramfs/uncompress.c index 8e92eb122..7a34b2b30 100644 --- a/fs/cramfs/uncompress.c +++ b/fs/cramfs/uncompress.c @@ -22,6 +22,7 @@ static z_stream stream; static int initialized = 0; +/* Returns length of decompressed data. */ int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen) { int err; @@ -32,14 +33,22 @@ int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen) stream.next_out = dst; stream.avail_out = dstlen; - inflateReset(&stream); + err = inflateReset(&stream); + if (err != Z_OK) { + printk("inflateReset error %d\n", err); + inflateEnd(&stream); + inflateInit(&stream); + } err = inflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - printk("Error %d while decompressing!\n", err); - printk("%p(%d)->%p(%d)\n", src, srclen, dst, dstlen); - } + if (err != Z_STREAM_END) + goto err; return stream.total_out; + +err: + printk("Error %d while decompressing!\n", err); + printk("%p(%d)->%p(%d)\n", src, srclen, dst, dstlen); + return 0; } int cramfs_uncompress_init(void) diff --git a/fs/efs/inode.c b/fs/efs/inode.c index 7ed3db6ad..75903be12 100644 --- a/fs/efs/inode.c +++ b/fs/efs/inode.c @@ -70,8 +70,8 @@ void efs_read_inode(struct inode *inode) { inode->i_mode = be16_to_cpu(efs_inode->di_mode); inode->i_nlink = be16_to_cpu(efs_inode->di_nlink); - inode->i_uid = be16_to_cpu(efs_inode->di_uid); - inode->i_gid = be16_to_cpu(efs_inode->di_gid); + inode->i_uid = (uid_t)be16_to_cpu(efs_inode->di_uid); + inode->i_gid = (gid_t)be16_to_cpu(efs_inode->di_gid); inode->i_size = be32_to_cpu(efs_inode->di_size); inode->i_atime = be32_to_cpu(efs_inode->di_atime); inode->i_mtime = be32_to_cpu(efs_inode->di_mtime); diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 1c915e274..df010f223 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -28,7 +28,7 @@ #define MIN(a,b) (((a)<(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b)) -static long long ext2_file_lseek(struct file *, long long, int); +static loff_t ext2_file_lseek(struct file *, loff_t, int); static int ext2_open_file (struct inode *, struct file *); #define EXT2_MAX_SIZE(bits) \ @@ -45,9 +45,9 @@ EXT2_MAX_SIZE(10), EXT2_MAX_SIZE(11), EXT2_MAX_SIZE(12), EXT2_MAX_SIZE(13) /* * Make sure the offset never goes beyond the 32-bit mark.. */ -static long long ext2_file_lseek( +static loff_t ext2_file_lseek( struct file *file, - long long offset, + loff_t offset, int origin) { struct inode *inode = file->f_dentry->d_inode; diff --git a/fs/ext2/fsync.c b/fs/ext2/fsync.c index f4e02c2e8..c29fef5ea 100644 --- a/fs/ext2/fsync.c +++ b/fs/ext2/fsync.c @@ -23,6 +23,7 @@ */ #include <linux/fs.h> +#include <linux/locks.h> @@ -40,10 +41,21 @@ static int sync_indirect(struct inode * inode, u32 * block, int wait) if (!bh) return 0; if (wait && buffer_req(bh) && !buffer_uptodate(bh)) { - brelse(bh); - return -1; + /* There can be a parallell read(2) that started read-I/O + on the buffer so we can't assume that there's been + an I/O error without first waiting I/O completation. */ + wait_on_buffer(bh); + if (!buffer_uptodate(bh)) + { + brelse (bh); + return -1; + } } if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh)) { + if (wait) + /* when we return from fsync all the blocks + must be _just_ stored on disk */ + wait_on_buffer(bh); brelse(bh); return 0; } diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index b4f952d07..e92e4080a 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -24,6 +24,7 @@ #include <linux/locks.h> #include <linux/smp_lock.h> #include <linux/sched.h> +#include <linux/highuid.h> @@ -254,6 +255,8 @@ repeat: } if (metadata) { result = getblk (inode->i_dev, tmp, blocksize); + if (!buffer_uptodate(result)) + wait_on_buffer(result); memset(result->b_data, 0, blocksize); mark_buffer_uptodate(result, 1); mark_buffer_dirty(result, 1); @@ -363,6 +366,8 @@ repeat: goto out; if (metadata) { result = getblk (bh->b_dev, tmp, blocksize); + if (!buffer_uptodate(result)) + wait_on_buffer(result); memset(result->b_data, 0, inode->i_sb->s_blocksize); mark_buffer_uptodate(result, 1); mark_buffer_dirty(result, 1); @@ -542,6 +547,8 @@ struct buffer_head * ext2_getblk(struct inode * inode, long block, int create, i struct buffer_head *bh; bh = getblk(dummy.b_dev, dummy.b_blocknr, inode->i_sb->s_blocksize); if (buffer_new(&dummy)) { + if (!buffer_uptodate(bh)) + wait_on_buffer(bh); memset(bh->b_data, 0, inode->i_sb->s_blocksize); mark_buffer_uptodate(bh, 1); mark_buffer_dirty(bh, 1); @@ -655,8 +662,12 @@ void ext2_read_inode (struct inode * inode) raw_inode = (struct ext2_inode *) (bh->b_data + offset); inode->i_mode = le16_to_cpu(raw_inode->i_mode); - inode->i_uid = le16_to_cpu(raw_inode->i_uid); - inode->i_gid = le16_to_cpu(raw_inode->i_gid); + inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); + inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); + if(!(test_opt (inode->i_sb, NO_UID32))) { + inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; + inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; + } inode->i_nlink = le16_to_cpu(raw_inode->i_links_count); inode->i_size = le32_to_cpu(raw_inode->i_size); inode->i_atime = le32_to_cpu(raw_inode->i_atime); @@ -795,8 +806,26 @@ static int ext2_update_inode(struct inode * inode, int do_sync) raw_inode = (struct ext2_inode *) (bh->b_data + offset); raw_inode->i_mode = cpu_to_le16(inode->i_mode); - raw_inode->i_uid = cpu_to_le16(inode->i_uid); - raw_inode->i_gid = cpu_to_le16(inode->i_gid); + if(!(test_opt(inode->i_sb, NO_UID32))) { + raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid)); + raw_inode->i_gid_low = cpu_to_le16(low_16_bits(inode->i_gid)); +/* + * Fix up interoperability with old kernels. Otherwise, old inodes get + * re-used with the upper 16 bits of the uid/gid intact + */ + if(!inode->u.ext2_i.i_dtime) { + raw_inode->i_uid_high = cpu_to_le16(high_16_bits(inode->i_uid)); + raw_inode->i_gid_high = cpu_to_le16(high_16_bits(inode->i_gid)); + } else { + raw_inode->i_uid_high = 0; + raw_inode->i_gid_high = 0; + } + } else { + raw_inode->i_uid_low = cpu_to_le16(fs_high2lowuid(inode->i_uid)); + raw_inode->i_gid_low = cpu_to_le16(fs_high2lowgid(inode->i_gid)); + raw_inode->i_uid_high = 0; + raw_inode->i_gid_high = 0; + } raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); raw_inode->i_size = cpu_to_le32(inode->i_size); raw_inode->i_atime = cpu_to_le32(inode->i_atime); @@ -870,28 +899,28 @@ int ext2_notify_change(struct dentry *dentry, struct iattr *iattr) flags = iattr->ia_attr_flags; if (flags & ATTR_FLAG_SYNCRONOUS) { inode->i_flags |= MS_SYNCHRONOUS; - inode->u.ext2_i.i_flags = EXT2_SYNC_FL; + inode->u.ext2_i.i_flags |= EXT2_SYNC_FL; } else { inode->i_flags &= ~MS_SYNCHRONOUS; inode->u.ext2_i.i_flags &= ~EXT2_SYNC_FL; } if (flags & ATTR_FLAG_NOATIME) { inode->i_flags |= MS_NOATIME; - inode->u.ext2_i.i_flags = EXT2_NOATIME_FL; + inode->u.ext2_i.i_flags |= EXT2_NOATIME_FL; } else { inode->i_flags &= ~MS_NOATIME; inode->u.ext2_i.i_flags &= ~EXT2_NOATIME_FL; } if (flags & ATTR_FLAG_APPEND) { inode->i_flags |= S_APPEND; - inode->u.ext2_i.i_flags = EXT2_APPEND_FL; + inode->u.ext2_i.i_flags |= EXT2_APPEND_FL; } else { inode->i_flags &= ~S_APPEND; inode->u.ext2_i.i_flags &= ~EXT2_APPEND_FL; } if (flags & ATTR_FLAG_IMMUTABLE) { inode->i_flags |= S_IMMUTABLE; - inode->u.ext2_i.i_flags = EXT2_IMMUTABLE_FL; + inode->u.ext2_i.i_flags |= EXT2_IMMUTABLE_FL; } else { inode->i_flags &= ~S_IMMUTABLE; inode->u.ext2_i.i_flags &= ~EXT2_IMMUTABLE_FL; diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 87f39796a..57a0be62d 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -832,6 +832,13 @@ int ext2_rename (struct inode * old_dir, struct dentry *old_dentry, new_dir->i_version = ++event; /* + * Like most other Unix systems, set the ctime for inodes on a + * rename. + */ + old_inode->i_ctime = CURRENT_TIME; + mark_inode_dirty(old_inode); + + /* * ok, that's it */ new_de->inode = le32_to_cpu(old_inode->i_ino); diff --git a/fs/ext2/super.c b/fs/ext2/super.c index cefde46fd..8a06df18b 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -151,6 +151,9 @@ static int parse_options (char * options, unsigned long * sb_block, *value++ = 0; if (!strcmp (this_char, "bsddf")) clear_opt (*mount_options, MINIX_DF); + else if (!strcmp (this_char, "nouid32")) { + set_opt (*mount_options, NO_UID32); + } else if (!strcmp (this_char, "check")) { if (!value || !*value) set_opt (*mount_options, CHECK_NORMAL); diff --git a/fs/fat/dir.c b/fs/fat/dir.c index c31d02024..83565fcbe 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c @@ -289,11 +289,11 @@ parse_long: } Found: - fat_brelse(sb, bh); res = long_slots + 1; *spos = cpos - sizeof(struct msdos_dir_entry); *lpos = cpos - res*sizeof(struct msdos_dir_entry); EODir: + fat_brelse(sb, bh); if (unicode) { free_page((unsigned long) unicode); } diff --git a/fs/hfs/ChangeLog b/fs/hfs/ChangeLog index 11c7d8506..723f2232d 100644 --- a/fs/hfs/ChangeLog +++ b/fs/hfs/ChangeLog @@ -1,3 +1,7 @@ +2000-01-02 a sun <asun@asun.cobalt.com> + + * file.c (hfs_get_block): added hfs_get_block for regular files. + 1999-04-12 a sun <asun@hecate.darksunrising.blah> * file_hdr.c (hdr_read): added rootinfo behaviour for DID header. diff --git a/fs/hfs/extent.c b/fs/hfs/extent.c index 3c92e7def..eca17bc63 100644 --- a/fs/hfs/extent.c +++ b/fs/hfs/extent.c @@ -523,7 +523,7 @@ static void shrink_fork(struct hfs_fork *fork, int ablocks) * Try to add enough allocation blocks to 'fork' * so that it is 'ablock' allocation blocks long. */ -static void grow_fork(struct hfs_fork *fork, int ablocks) +static int grow_fork(struct hfs_fork *fork, int ablocks) { struct hfs_cat_entry *entry = fork->entry; struct hfs_mdb *mdb = entry->mdb; @@ -535,8 +535,8 @@ static void grow_fork(struct hfs_fork *fork, int ablocks) blocks = fork->psize; need = ablocks - blocks/ablksz; - if (need < 1) { - return; + if (need < 1) { /* no need to grow the fork */ + return 0; } /* round up to clumpsize */ @@ -550,7 +550,7 @@ static void grow_fork(struct hfs_fork *fork, int ablocks) /* find last extent record and try to extend it */ if (!(ext = find_ext(fork, blocks/ablksz - 1))) { /* somehow we couldn't find the end of the file! */ - return; + return -1; } /* determine which is the last used extent in the record */ @@ -574,7 +574,7 @@ static void grow_fork(struct hfs_fork *fork, int ablocks) unlock_bitmap(mdb); if (err) { relse_ext(ext); - return; + return -1; } zero_blocks(mdb, start, len); @@ -600,7 +600,7 @@ more_extents: unlock_bitmap(mdb); if (!len || err) { relse_ext(ext); - return; + return -1; } zero_blocks(mdb, start, len); @@ -617,7 +617,7 @@ more_extents: lock_bitmap(mdb); hfs_clear_vbm_bits(mdb, start, len); unlock_bitmap(mdb); - return; + return -1; } } blocks = (fork->psize += len * ablksz); @@ -625,7 +625,7 @@ more_extents: } set_cache(fork, ext); relse_ext(ext); - return; + return 0; } /*================ Global functions ================*/ @@ -738,11 +738,8 @@ int hfs_extent_map(struct hfs_fork *fork, int block, int create) ablock = block / ablksz; if (block >= fork->psize) { - if (create) { - grow_fork(fork, ablock + 1); - } else { + if (!create || (grow_fork(fork, ablock + 1) < 0)) return 0; - } } #if defined(DEBUG_EXTENTS) || defined(DEBUG_ALL) diff --git a/fs/hfs/file.c b/fs/hfs/file.c index 943249478..d5edeac45 100644 --- a/fs/hfs/file.c +++ b/fs/hfs/file.c @@ -28,7 +28,7 @@ static hfs_rwret_t hfs_file_read(struct file *, char *, hfs_rwarg_t, static hfs_rwret_t hfs_file_write(struct file *, const char *, hfs_rwarg_t, loff_t *); static void hfs_file_truncate(struct inode *); -static int hfs_bmap(struct inode *, int); +static int hfs_get_block(struct inode *, long, struct buffer_head *, int); /*================ Global variables ================*/ @@ -61,7 +61,7 @@ struct inode_operations hfs_file_inode_operations = { NULL, /* rename */ NULL, /* readlink */ NULL, /* follow_link */ - hfs_bmap, /* get_block */ + hfs_get_block, /* get_block */ block_read_full_page, /* readpage */ NULL, /* writepage */ hfs_file_truncate, /* truncate */ @@ -124,19 +124,37 @@ struct buffer_head *hfs_getblk(struct hfs_fork *fork, int block, int create) } /* - * hfs_bmap() + * hfs_get_block * - * This is the bmap() field in the inode_operations structure for + * This is the hfs_get_block() field in the inode_operations structure for * "regular" (non-header) files. The purpose is to translate an inode * and a block number within the corresponding file into a physical * block number. This function just calls hfs_extent_map() to do the - * real work. + * real work and then stuffs the appropriate info into the buffer_head. */ -static int hfs_bmap(struct inode * inode, int block) +int hfs_get_block(struct inode *inode, long iblock, struct buffer_head *bh_result, int create) { - return hfs_extent_map(HFS_I(inode)->fork, block, 0); + unsigned long phys; + + phys = hfs_extent_map(HFS_I(inode)->fork, iblock, create); + if (phys) { + bh_result->b_dev = inode->i_dev; + bh_result->b_blocknr = phys; + bh_result->b_state |= (1UL << BH_Mapped); + if (create) + bh_result->b_state |= (1UL << BH_New); + return 0; + } + + if (!create) + return 0; + + /* we tried to add stuff, but we couldn't. send back an out-of-space + * error. */ + return -ENOSPC; } + /* * hfs_file_read() * @@ -146,8 +164,7 @@ static int hfs_bmap(struct inode * inode, int block) * 'filp->offset' bytes into the file. The data is transfered to * user-space at the address 'buf'. Returns the number of bytes * successfully transfered. This function checks the arguments, does - * some setup and then calls hfs_do_read() to do the actual transfer. - */ + * some setup and then calls hfs_do_read() to do the actual transfer. */ static hfs_rwret_t hfs_file_read(struct file * filp, char * buf, hfs_rwarg_t count, loff_t *ppos) { diff --git a/fs/hfs/hfs_btree.h b/fs/hfs/hfs_btree.h index 7f7aea600..97423b350 100644 --- a/fs/hfs/hfs_btree.h +++ b/fs/hfs/hfs_btree.h @@ -34,6 +34,20 @@ #define ndMapNode 0x02 /* Holds part of the bitmap of used nodes */ #define ndLeafNode 0xFF /* A leaf (ndNHeight==1) node */ +/* + * Legal values for the bthAtrb field of a (struct BTHdrRec) + * + * Reference: TN 1150 + */ +#define bthBadClose 0x00000001 /* b-tree not closed properly. not + used by hfsplus. */ +#define bthBigKeys 0x00000002 /* key length is u16 instead of u8. + used by hfsplus. */ +#define bthVarIndxKeys 0x00000004 /* variable key length instead of + max key length. use din catalog + b-tree but not in extents + b-tree (hfsplus). */ + /*================ Function-like macros ================*/ /* Access the cache slot which should contain the desired node */ @@ -70,7 +84,12 @@ struct BTHdrRec { hfs_word_t bthKeyLen; /* (F) The length of a key in an index node */ hfs_lword_t bthNNodes; /* (V) The total number of nodes */ hfs_lword_t bthFree; /* (V) The number of unused nodes */ - hfs_byte_t bthResv[76]; /* Reserved */ + hfs_word_t bthResv1; /* reserved */ + hfs_lword_t bthClpSiz; /* (F) clump size. not usually used. */ + hfs_byte_t bthType; /* (F) BTree type */ + hfs_byte_t bthResv2; /* reserved */ + hfs_lword_t bthAtrb; /* (F) attributes */ + hfs_lword_t bthResv3[16]; /* Reserved */ }; /* @@ -129,6 +148,8 @@ struct hfs_bnode { this node in-core (set for root and head) */ hfs_u32 node; /* Node number */ + hfs_u16 nodeSize; /* node size */ + hfs_u16 keyLen; /* key length */ /* locking related fields: */ hfs_wait_queue wqueue; /* Wait queue for write access */ hfs_wait_queue rqueue; /* Wait queue for read or reserve @@ -176,6 +197,7 @@ struct hfs_btree { int lock; hfs_wait_queue wait; int dirt; + int keySize; /* Fields from the BTHdrRec in native byte-order: */ hfs_u32 bthRoot; hfs_u32 bthNRecs; diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index 8fde9117d..af09655a0 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c @@ -44,14 +44,18 @@ static void init_file_inode(struct inode *inode, hfs_u8 fork) } if (fork == HFS_FK_DATA) { +#if 0 /* XXX: disable crlf translations for now */ hfs_u32 type = hfs_get_nl(entry->info.file.finfo.fdType); - fk = &entry->u.file.data_fork; HFS_I(inode)->convert = ((HFS_SB(inode->i_sb)->s_conv == 't') || ((HFS_SB(inode->i_sb)->s_conv == 'a') && ((type == htonl(0x54455854)) || /* "TEXT" */ (type == htonl(0x7474726f))))); /* "ttro" */ +#else + HFS_I(inode)->convert = 0; +#endif + fk = &entry->u.file.data_fork; } else { fk = &entry->u.file.rsrc_fork; HFS_I(inode)->convert = 0; diff --git a/fs/inode.c b/fs/inode.c index 4990b0497..d6298d349 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -51,6 +51,7 @@ static LIST_HEAD(inode_in_use); static LIST_HEAD(inode_unused); static struct list_head inode_hashtable[HASH_SIZE]; +static LIST_HEAD(anon_hash_chain); /* for inodes with NULL i_sb */ /* * A simple spinlock to protect the list manipulations. @@ -632,7 +633,9 @@ struct inode *iget4(struct super_block *sb, unsigned long ino, find_inode_t find void insert_inode_hash(struct inode *inode) { - struct list_head *head = inode_hashtable + hash(inode->i_sb, inode->i_ino); + struct list_head *head = &anon_hash_chain; + if (inode->i_sb) + head = inode_hashtable + hash(inode->i_sb, inode->i_ino); spin_lock(&inode_lock); list_add(&inode->i_hash, head); spin_unlock(&inode_lock); diff --git a/fs/iobuf.c b/fs/iobuf.c index eaabf2f7c..4eaefe723 100644 --- a/fs/iobuf.c +++ b/fs/iobuf.c @@ -88,7 +88,7 @@ int expand_kiobuf(struct kiobuf *iobuf, int wanted) return 0; } - memcpy (maplist, iobuf->maplist, wanted * sizeof(struct page **)); + memcpy (maplist, iobuf->maplist, iobuf->array_len * sizeof(struct page **)); if (iobuf->array_len > KIO_STATIC_PAGES) kfree (iobuf->maplist); diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index dee4f28e7..a2f280bdc 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c @@ -143,7 +143,7 @@ xdr_encode_mon(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp) char buffer[20]; u32 addr = ntohl(argp->addr); - dprintk("nsm: xdr_encode_mon(%08lx, %ld, %ld, %ld)\n", + dprintk("nsm: xdr_encode_mon(%08x, %d, %d, %d)\n", htonl(argp->addr), htonl(argp->proc), htonl(argp->vers), htonl(argp->proc)); diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 0e59754f3..142d593b2 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c @@ -43,7 +43,7 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, /* Obtain handle for client host */ if (rqstp->rq_client == NULL) { printk(KERN_NOTICE - "lockd: unauthenticated request from (%08lx:%d)\n", + "lockd: unauthenticated request from (%08x:%d)\n", ntohl(rqstp->rq_addr.sin_addr.s_addr), ntohs(rqstp->rq_addr.sin_port)); return nlm_lck_denied_nolocks; @@ -110,7 +110,7 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, /* Now check for conflicting locks */ resp->status = nlmsvc_testlock(file, &argp->lock, &resp->lock); - dprintk("lockd: TEST status %ld\n", ntohl(resp->status)); + dprintk("lockd: TEST status %d\n", ntohl(resp->status)); nlm_release_host(host); nlm_release_file(file); return rpc_success; @@ -153,7 +153,7 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, resp->status = nlmsvc_lock(rqstp, file, &argp->lock, argp->block, &argp->cookie); - dprintk("lockd: LOCK status %ld\n", ntohl(resp->status)); + dprintk("lockd: LOCK status %d\n", ntohl(resp->status)); nlm_release_host(host); nlm_release_file(file); return rpc_success; @@ -183,7 +183,7 @@ nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, /* Try to cancel request. */ resp->status = nlmsvc_cancel_blocked(file, &argp->lock); - dprintk("lockd: CANCEL status %ld\n", ntohl(resp->status)); + dprintk("lockd: CANCEL status %d\n", ntohl(resp->status)); nlm_release_host(host); nlm_release_file(file); return rpc_success; @@ -216,7 +216,7 @@ nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, /* Now try to remove the lock */ resp->status = nlmsvc_unlock(file, &argp->lock); - dprintk("lockd: UNLOCK status %ld\n", ntohl(resp->status)); + dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status)); nlm_release_host(host); nlm_release_file(file); return rpc_success; @@ -234,7 +234,7 @@ nlmsvc_proc_granted(struct svc_rqst *rqstp, struct nlm_args *argp, dprintk("lockd: GRANTED called\n"); resp->status = nlmclnt_grant(&argp->lock); - dprintk("lockd: GRANTED status %ld\n", ntohl(resp->status)); + dprintk("lockd: GRANTED status %d\n", ntohl(resp->status)); return rpc_success; } @@ -340,7 +340,7 @@ nlmsvc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp, /* Now try to create the share */ resp->status = nlmsvc_share_file(host, file, argp); - dprintk("lockd: SHARE status %ld\n", ntohl(resp->status)); + dprintk("lockd: SHARE status %d\n", ntohl(resp->status)); nlm_release_host(host); nlm_release_file(file); return rpc_success; @@ -373,7 +373,7 @@ nlmsvc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp, /* Now try to lock the file */ resp->status = nlmsvc_unshare_file(host, file, argp); - dprintk("lockd: UNSHARE status %ld\n", ntohl(resp->status)); + dprintk("lockd: UNSHARE status %d\n", ntohl(resp->status)); nlm_release_host(host); nlm_release_file(file); return rpc_success; @@ -424,7 +424,7 @@ nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, if (saddr.sin_addr.s_addr != htonl(INADDR_LOOPBACK) || ntohs(saddr.sin_port) >= 1024) { printk(KERN_WARNING - "lockd: rejected NSM callback from %08lx:%d\n", + "lockd: rejected NSM callback from %08x:%d\n", ntohl(rqstp->rq_addr.sin_addr.s_addr), ntohs(rqstp->rq_addr.sin_port)); return rpc_system_err; diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c index 1b1c41069..8d15cba9a 100644 --- a/fs/lockd/svcsubs.c +++ b/fs/lockd/svcsubs.c @@ -86,7 +86,7 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result, * the file. */ if ((nfserr = nlmsvc_ops->fopen(rqstp, fh, &file->f_file)) != 0) { - dprintk("lockd: open failed (nfserr %ld)\n", ntohl(nfserr)); + dprintk("lockd: open failed (nfserr %d)\n", ntohl(nfserr)); goto out_free; } diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c index 85fb7c729..cb090cfd3 100644 --- a/fs/lockd/xdr.c +++ b/fs/lockd/xdr.c @@ -95,8 +95,8 @@ nlm_decode_fh(u32 *p, struct nfs_fh *f) if ((len = ntohl(*p++)) != sizeof(*f)) { printk(KERN_NOTICE - "lockd: bad fhandle size %x (should be %d)\n", - len, sizeof(*f)); + "lockd: bad fhandle size %u (should be %lu)\n", + len, (unsigned long) sizeof(*f)); return NULL; } memcpy(f, p, sizeof(*f)); diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 66582c216..de093d02f 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -20,6 +20,7 @@ #include <linux/locks.h> #include <linux/init.h> #include <linux/smp_lock.h> +#include <linux/highuid.h> #include <asm/system.h> #include <asm/uaccess.h> @@ -1044,8 +1045,8 @@ static void V1_minix_read_inode(struct inode * inode) raw_inode = ((struct minix_inode *) bh->b_data) + (ino-1)%MINIX_INODES_PER_BLOCK; inode->i_mode = raw_inode->i_mode; - inode->i_uid = raw_inode->i_uid; - inode->i_gid = raw_inode->i_gid; + inode->i_uid = (uid_t)raw_inode->i_uid; + inode->i_gid = (gid_t)raw_inode->i_gid; inode->i_nlink = raw_inode->i_nlinks; inode->i_size = raw_inode->i_size; inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time; @@ -1092,8 +1093,8 @@ static void V2_minix_read_inode(struct inode * inode) raw_inode = ((struct minix2_inode *) bh->b_data) + (ino-1)%MINIX2_INODES_PER_BLOCK; inode->i_mode = raw_inode->i_mode; - inode->i_uid = raw_inode->i_uid; - inode->i_gid = raw_inode->i_gid; + inode->i_uid = (uid_t)raw_inode->i_uid; + inode->i_gid = (gid_t)raw_inode->i_gid; inode->i_nlink = raw_inode->i_nlinks; inode->i_size = raw_inode->i_size; inode->i_mtime = raw_inode->i_mtime; @@ -1149,8 +1150,8 @@ static struct buffer_head * V1_minix_update_inode(struct inode * inode) raw_inode = ((struct minix_inode *)bh->b_data) + (ino-1)%MINIX_INODES_PER_BLOCK; raw_inode->i_mode = inode->i_mode; - raw_inode->i_uid = inode->i_uid; - raw_inode->i_gid = inode->i_gid; + raw_inode->i_uid = fs_high2lowuid(inode->i_uid); + raw_inode->i_gid = fs_high2lowgid(inode->i_gid); raw_inode->i_nlinks = inode->i_nlink; raw_inode->i_size = inode->i_size; raw_inode->i_time = inode->i_mtime; @@ -1187,8 +1188,8 @@ static struct buffer_head * V2_minix_update_inode(struct inode * inode) raw_inode = ((struct minix2_inode *)bh->b_data) + (ino-1)%MINIX2_INODES_PER_BLOCK; raw_inode->i_mode = inode->i_mode; - raw_inode->i_uid = inode->i_uid; - raw_inode->i_gid = inode->i_gid; + raw_inode->i_uid = fs_high2lowuid(inode->i_uid); + raw_inode->i_gid = fs_high2lowgid(inode->i_gid); raw_inode->i_nlinks = inode->i_nlink; raw_inode->i_size = inode->i_size; raw_inode->i_mtime = inode->i_mtime; diff --git a/fs/namei.c b/fs/namei.c index 599c873e6..97f8232d4 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -780,16 +780,14 @@ asmlinkage long sys_mknod(const char * filename, int mode, dev_t dev) char * tmp; struct dentry * dentry; - lock_kernel(); - error = -EPERM; if (S_ISDIR(mode) || (!S_ISFIFO(mode) && !capable(CAP_MKNOD))) - goto out; + return -EPERM; tmp = getname(filename); - error = PTR_ERR(tmp); if (IS_ERR(tmp)) - goto out; + return PTR_ERR(tmp); error = -EINVAL; + lock_kernel(); switch (mode & S_IFMT) { case 0: mode |= S_IFREG; /* fallthrough */ @@ -815,10 +813,9 @@ asmlinkage long sys_mknod(const char * filename, int mode, dev_t dev) } break; } + unlock_kernel(); putname(tmp); -out: - unlock_kernel(); return error; } @@ -870,14 +867,14 @@ asmlinkage long sys_mkdir(const char * pathname, int mode) int error; char * tmp; - lock_kernel(); tmp = getname(pathname); - error = PTR_ERR(tmp); - if (!IS_ERR(tmp)) { - error = do_mkdir(tmp,mode); - putname(tmp); - } + if(IS_ERR(tmp)) + return PTR_ERR(tmp); + lock_kernel(); + error = do_mkdir(tmp,mode); unlock_kernel(); + putname(tmp); + return error; } @@ -965,14 +962,15 @@ asmlinkage long sys_rmdir(const char * pathname) int error; char * tmp; - lock_kernel(); tmp = getname(pathname); - error = PTR_ERR(tmp); - if (!IS_ERR(tmp)) { - error = do_rmdir(tmp); - putname(tmp); - } + if(IS_ERR(tmp)) + return PTR_ERR(tmp); + lock_kernel(); + error = do_rmdir(tmp); unlock_kernel(); + + putname(tmp); + return error; } @@ -1018,14 +1016,14 @@ asmlinkage long sys_unlink(const char * pathname) int error; char * tmp; - lock_kernel(); tmp = getname(pathname); - error = PTR_ERR(tmp); - if (!IS_ERR(tmp)) { - error = do_unlink(tmp); - putname(tmp); - } + if(IS_ERR(tmp)) + return PTR_ERR(tmp); + lock_kernel(); + error = do_unlink(tmp); unlock_kernel(); + putname(tmp); + return error; } @@ -1068,21 +1066,20 @@ asmlinkage long sys_symlink(const char * oldname, const char * newname) { int error; char * from; + char * to; - lock_kernel(); from = getname(oldname); - error = PTR_ERR(from); - if (!IS_ERR(from)) { - char * to; - to = getname(newname); - error = PTR_ERR(to); - if (!IS_ERR(to)) { - error = do_symlink(from,to); - putname(to); - } - putname(from); + if(IS_ERR(from)) + return PTR_ERR(from); + to = getname(newname); + error = PTR_ERR(to); + if (!IS_ERR(to)) { + lock_kernel(); + error = do_symlink(from,to); + unlock_kernel(); + putname(to); } - unlock_kernel(); + putname(from); return error; } @@ -1156,21 +1153,21 @@ asmlinkage long sys_link(const char * oldname, const char * newname) { int error; char * from; + char * to; - lock_kernel(); from = getname(oldname); - error = PTR_ERR(from); - if (!IS_ERR(from)) { - char * to; - to = getname(newname); - error = PTR_ERR(to); - if (!IS_ERR(to)) { - error = do_link(from,to); - putname(to); - } - putname(from); + if(IS_ERR(from)) + return PTR_ERR(from); + to = getname(newname); + error = PTR_ERR(to); + if (!IS_ERR(to)) { + lock_kernel(); + error = do_link(from,to); + unlock_kernel(); + putname(to); } - unlock_kernel(); + putname(from); + return error; } @@ -1327,21 +1324,20 @@ asmlinkage long sys_rename(const char * oldname, const char * newname) { int error; char * from; + char * to; - lock_kernel(); from = getname(oldname); - error = PTR_ERR(from); - if (!IS_ERR(from)) { - char * to; - to = getname(newname); - error = PTR_ERR(to); - if (!IS_ERR(to)) { - error = do_rename(from,to); - putname(to); - } - putname(from); + if(IS_ERR(from)) + return PTR_ERR(from); + to = getname(newname); + error = PTR_ERR(to); + if (!IS_ERR(to)) { + lock_kernel(); + error = do_rename(from,to); + unlock_kernel(); + putname(to); } - unlock_kernel(); + putname(from); return error; } diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index 26bd474d2..eca5ddf15 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c @@ -258,7 +258,7 @@ ncp_delete_inode(struct inode *inode) struct super_block * ncp_read_super(struct super_block *sb, void *raw_data, int silent) { - struct ncp_mount_data *data = (struct ncp_mount_data *) raw_data; + struct ncp_mount_data_kernel data; struct ncp_server *server; struct file *ncp_filp; struct inode *root_inode; @@ -270,11 +270,50 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent) struct ncp_entry_info finfo; MOD_INC_USE_COUNT; - if (data == NULL) + if (raw_data == NULL) goto out_no_data; - if (data->version != NCP_MOUNT_VERSION) - goto out_bad_mount; - ncp_filp = fget(data->ncp_fd); + switch (*(int*)raw_data) { + case NCP_MOUNT_VERSION: + { + struct ncp_mount_data* md = (struct ncp_mount_data*)raw_data; + + data.flags = md->flags; + data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE; + data.mounted_uid = md->mounted_uid; + data.wdog_pid = md->wdog_pid; + data.ncp_fd = md->ncp_fd; + data.time_out = md->time_out; + data.retry_count = md->retry_count; + data.uid = md->uid; + data.gid = md->gid; + data.file_mode = md->file_mode; + data.dir_mode = md->dir_mode; + memcpy(data.mounted_vol, md->mounted_vol, + NCP_VOLNAME_LEN+1); + } + break; + case NCP_MOUNT_VERSION_V4: + { + struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data; + + data.flags = md->flags; + data.int_flags = 0; + data.mounted_uid = md->mounted_uid; + data.wdog_pid = md->wdog_pid; + data.ncp_fd = md->ncp_fd; + data.time_out = md->time_out; + data.retry_count = md->retry_count; + data.uid = md->uid; + data.gid = md->gid; + data.file_mode = md->file_mode; + data.dir_mode = md->dir_mode; + data.mounted_vol[0] = 0; + } + break; + default: + goto out_bad_mount; + } + ncp_filp = fget(data.ncp_fd); if (!ncp_filp) goto out_bad_file; if (!S_ISSOCK(ncp_filp->f_dentry->d_inode->i_mode)) @@ -310,7 +349,7 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent) /* server->priv.len = 0; */ /* server->priv.data = NULL; */ - server->m = *data; + server->m = data; /* Althought anything producing this is buggy, it happens now because of PATH_MAX changes.. */ if (server->m.time_out < 1) { diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c index 36063db81..6cf94831f 100644 --- a/fs/ncpfs/ioctl.c +++ b/fs/ncpfs/ioctl.c @@ -15,6 +15,7 @@ #include <linux/ioctl.h> #include <linux/sched.h> #include <linux/mm.h> +#include <linux/highuid.h> #include <linux/ncp_fs.h> @@ -31,25 +32,8 @@ int ncp_ioctl(struct inode *inode, struct file *filp, struct ncp_server *server = NCP_SERVER(inode); int result; struct ncp_ioctl_request request; - struct ncp_fs_info info; char* bouncebuffer; -#ifdef NCP_IOC_GETMOUNTUID_INT - /* remove after ncpfs-2.0.13/2.2.0 gets released */ - if ((NCP_IOC_GETMOUNTUID != NCP_IOC_GETMOUNTUID_INT) && - (cmd == NCP_IOC_GETMOUNTUID_INT)) { - int tmp = server->m.mounted_uid; - - if ( (permission(inode, MAY_READ) != 0) - && (current->uid != server->m.mounted_uid)) - { - return -EACCES; - } - if (put_user(tmp, (unsigned int*) arg)) return -EFAULT; - return 0; - } -#endif /* NCP_IOC_GETMOUNTUID_INT */ - switch (cmd) { case NCP_IOC_NCPREQUEST: @@ -66,10 +50,6 @@ int ncp_ioctl(struct inode *inode, struct file *filp, NCP_PACKET_SIZE - sizeof(struct ncp_request_header))) { return -EINVAL; } - if ((result = verify_area(VERIFY_WRITE, (char *) request.data, - NCP_PACKET_SIZE)) != 0) { - return result; - } bouncebuffer = kmalloc(NCP_PACKET_SIZE, GFP_NFS); if (!bouncebuffer) return -ENOMEM; @@ -107,48 +87,82 @@ int ncp_ioctl(struct inode *inode, struct file *filp, && (current->uid != server->m.mounted_uid)) { return -EACCES; } - if (server->root_setuped) return -EBUSY; + if (!(server->m.int_flags & NCP_IMOUNT_LOGGEDIN_POSSIBLE)) + return -EINVAL; + if (server->root_setuped) + return -EBUSY; server->root_setuped = 1; return ncp_conn_logged_in(inode->i_sb); case NCP_IOC_GET_FS_INFO: + { + struct ncp_fs_info info; - if ((permission(inode, MAY_WRITE) != 0) - && (current->uid != server->m.mounted_uid)) { - return -EACCES; - } - if ((result = verify_area(VERIFY_WRITE, (char *) arg, - sizeof(info))) != 0) { - return result; - } - copy_from_user(&info, (struct ncp_fs_info *) arg, sizeof(info)); + if ((permission(inode, MAY_WRITE) != 0) + && (current->uid != server->m.mounted_uid)) { + return -EACCES; + } + if (copy_from_user(&info, (struct ncp_fs_info *) arg, + sizeof(info))) + return -EFAULT; - if (info.version != NCP_GET_FS_INFO_VERSION) { - DPRINTK("info.version invalid: %d\n", info.version); - return -EINVAL; + if (info.version != NCP_GET_FS_INFO_VERSION) { + DPRINTK("info.version invalid: %d\n", info.version); + return -EINVAL; + } + /* TODO: info.addr = server->m.serv_addr; */ + info.mounted_uid = NEW_TO_OLD_UID(server->m.mounted_uid); + info.connection = server->connection; + info.buffer_size = server->buffer_size; + info.volume_number = NCP_FINFO(inode)->volNumber; + info.directory_id = NCP_FINFO(inode)->DosDirNum; + + if (copy_to_user((struct ncp_fs_info *) arg, &info, + sizeof(info))) return -EFAULT; + return 0; } - /* TODO: info.addr = server->m.serv_addr; */ - info.mounted_uid = server->m.mounted_uid; - info.connection = server->connection; - info.buffer_size = server->buffer_size; - info.volume_number = NCP_FINFO(inode)->volNumber; - info.directory_id = NCP_FINFO(inode)->DosDirNum; - - copy_to_user((struct ncp_fs_info *) arg, &info, sizeof(info)); - return 0; - case NCP_IOC_GETMOUNTUID: + case NCP_IOC_GET_FS_INFO_V2: + { + struct ncp_fs_info_v2 info2; - if ((permission(inode, MAY_READ) != 0) - && (current->uid != server->m.mounted_uid)) { - return -EACCES; + if ((permission(inode, MAY_WRITE) != 0) + && (current->uid != server->m.mounted_uid)) { + return -EACCES; + } + if (copy_from_user(&info2, (struct ncp_fs_info_v2 *) arg, + sizeof(info2))) + return -EFAULT; + + if (info2.version != NCP_GET_FS_INFO_VERSION_V2) { + DPRINTK("info.version invalid: %d\n", info2.version); + return -EINVAL; + } + info2.mounted_uid = server->m.mounted_uid; + info2.connection = server->connection; + info2.buffer_size = server->buffer_size; + info2.volume_number = NCP_FINFO(inode)->volNumber; + info2.directory_id = NCP_FINFO(inode)->DosDirNum; + info2.dummy1 = info2.dummy2 = info2.dummy3 = 0; + + if (copy_to_user((struct ncp_fs_info_v2 *) arg, &info2, + sizeof(info2))) return -EFAULT; + return 0; } - if ((result = verify_area(VERIFY_WRITE, (uid_t *) arg, - sizeof(uid_t))) != 0) { - return result; + + case NCP_IOC_GETMOUNTUID2: + { + unsigned long tmp = server->m.mounted_uid; + + if ( (permission(inode, MAY_READ) != 0) + && (current->uid != server->m.mounted_uid)) + { + return -EACCES; + } + if (put_user(tmp, (unsigned long*) arg)) + return -EFAULT; + return 0; } - put_user(server->m.mounted_uid, (uid_t *) arg); - return 0; #ifdef CONFIG_NCPFS_MOUNT_SUBDIR case NCP_IOC_GETROOT: @@ -371,11 +385,6 @@ int ncp_ioctl(struct inode *inode, struct file *filp, struct ncp_objectname_ioctl user; int outl; - if ((result = verify_area(VERIFY_WRITE, - (struct ncp_objectname_ioctl*)arg, - sizeof(user))) != 0) { - return result; - } if (copy_from_user(&user, (struct ncp_objectname_ioctl*)arg, sizeof(user))) return -EFAULT; @@ -446,11 +455,6 @@ int ncp_ioctl(struct inode *inode, struct file *filp, struct ncp_privatedata_ioctl user; int outl; - if ((result = verify_area(VERIFY_WRITE, - (struct ncp_privatedata_ioctl*)arg, - sizeof(user))) != 0) { - return result; - } if (copy_from_user(&user, (struct ncp_privatedata_ioctl*)arg, sizeof(user))) return -EFAULT; @@ -629,7 +633,19 @@ int ncp_ioctl(struct inode *inode, struct file *filp, return 0; } - default: - return -EINVAL; } +/* #ifdef CONFIG_UID16 */ + /* NCP_IOC_GETMOUNTUID may be same as NCP_IOC_GETMOUNTUID2, + so we have this out of switch */ + if (cmd == NCP_IOC_GETMOUNTUID) { + if ((permission(inode, MAY_READ) != 0) + && (current->uid != server->m.mounted_uid)) { + return -EACCES; + } + if (put_user(NEW_TO_OLD_UID(server->m.mounted_uid), (__kernel_uid_t *) arg)) + return -EFAULT; + return 0; + } +/* #endif */ + return -EINVAL; } diff --git a/fs/ncpfs/ncplib_kernel.c b/fs/ncpfs/ncplib_kernel.c index 7220e4852..73afd107a 100644 --- a/fs/ncpfs/ncplib_kernel.c +++ b/fs/ncpfs/ncplib_kernel.c @@ -617,10 +617,8 @@ int ncp_open_create_file_or_subdir(struct ncp_server *server, target->server_file_handle = ncp_reply_dword(server, 0); target->open_create_action = ncp_reply_byte(server, 4); - if (dir != NULL) { - /* in target there's a new finfo to fill */ - ncp_extract_file_info(ncp_reply_data(server, 6), &(target->i)); - } + /* in target there's a new finfo to fill */ + ncp_extract_file_info(ncp_reply_data(server, 6), &(target->i)); ConvertToNWfromDWORD(target->server_file_handle, target->file_handle); out: diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index abf7f16f9..aae8d3d0a 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -681,7 +681,7 @@ printk("nfs_notify_change: revalidate failed, error=%d\n", error); if (attr->ia_valid & ATTR_SIZE) { if (attr->ia_size != fattr.size) printk("nfs_notify_change: attr=%Ld, fattr=%d??\n", - attr->ia_size, fattr.size); + (long long) attr->ia_size, fattr.size); inode->i_size = attr->ia_size; inode->i_mtime = fattr.mtime.seconds; } diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 14b55c450..4d9a4a727 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c @@ -221,7 +221,7 @@ exp_export(struct nfsctl_export *nxp) dprintk("exp_export called for %s:%s (%x/%ld fl %x).\n", nxp->ex_client, nxp->ex_path, - nxp->ex_dev, nxp->ex_ino, nxp->ex_flags); + nxp->ex_dev, (long) nxp->ex_ino, nxp->ex_flags); dev = to_kdev_t(nxp->ex_dev); ino = nxp->ex_ino; @@ -453,11 +453,11 @@ exp_rootfh(struct svc_client *clp, kdev_t dev, ino_t ino, ino = dentry->d_inode->i_ino; dprintk("nfsd: exp_rootfh(%s [%p] %s:%x/%ld)\n", - path, dentry, clp->cl_ident, dev, ino); + path, dentry, clp->cl_ident, dev, (long) ino); exp = exp_parent(clp, dev, dentry); } else { dprintk("nfsd: exp_rootfh(%s:%x/%ld)\n", - clp->cl_ident, dev, ino); + clp->cl_ident, dev, (long) ino); if ((exp = exp_get(clp, dev, ino))) if (!(dentry = dget(exp->ex_dentry))) { printk("exp_rootfh: Aieee, NULL dentry\n"); @@ -478,7 +478,7 @@ exp_rootfh(struct svc_client *clp, kdev_t dev, ino_t ino, printk("exp_rootfh: Aieee, ino/dev mismatch\n"); printk("exp_rootfh: arg[dev(%x):ino(%ld)]" " inode[dev(%x):ino(%ld)]\n", - dev, ino, inode->i_dev, inode->i_ino); + dev, (long) ino, inode->i_dev, (long) inode->i_ino); } /* @@ -667,7 +667,7 @@ exp_procfs_exports(char *buffer, char **start, off_t offset, if (first++) len += sprintf(buffer+len, "%s", " "); if (tmp->h_client != clp) len += sprintf(buffer+len, "("); - len += sprintf(buffer+len, "%ld.%ld.%ld.%ld", + len += sprintf(buffer+len, "%d.%d.%d.%d", htonl(addr.s_addr) >> 24 & 0xff, htonl(addr.s_addr) >> 16 & 0xff, htonl(addr.s_addr) >> 8 & 0xff, diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index c41dff207..68e7a1dac 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -262,7 +262,7 @@ extern int (*do_nfsservctl)(int, void *, void *); int init_module(void) { - printk("Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n"); + printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n"); do_nfsservctl = handle_sys_nfsservctl; return 0; } diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index ce3b08e9d..e0636f635 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -614,7 +614,7 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry) struct dentry *parent = dentry->d_parent; dprintk("nfsd: fh_compose(exp %x/%ld %s/%s, ino=%ld)\n", - exp->ex_dev, exp->ex_ino, + exp->ex_dev, (long) exp->ex_ino, parent->d_name.name, dentry->d_name.name, (inode ? inode->i_ino : 0)); diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c index 05cc8ef58..28ac3cc3c 100644 --- a/fs/nfsd/nfsproc.c +++ b/fs/nfsd/nfsproc.c @@ -143,7 +143,7 @@ nfsd_proc_read(struct svc_rqst *rqstp, struct nfsd_readargs *argp, if ((avail << 2) < argp->count) { printk(KERN_NOTICE - "oversized read request from %08lx:%d (%d bytes)\n", + "oversized read request from %08x:%d (%d bytes)\n", ntohl(rqstp->rq_addr.sin_addr.s_addr), ntohs(rqstp->rq_addr.sin_port), argp->count); diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 2876b8455..856e345f6 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1590,7 +1590,7 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, *p++ = htonl(eof); /* end of directory */ *countp = (caddr_t) p - (caddr_t) buffer; - dprintk("nfsd: readdir result %d bytes, eof %d offset %ld\n", + dprintk("nfsd: readdir result %d bytes, eof %d offset %d\n", *countp, eof, cd.offset? ntohl(*cd.offset) : -1); err = 0; diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index 7fcc86754..8a5e404b1 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c @@ -612,7 +612,7 @@ int ntfs_vcn_to_lcn(ntfs_inode *ino,int vcn) return 0; for(rnum=0;rnum<data->d.r.len && - vcn>data->d.r.runlist[rnum].len;rnum++) + vcn>=data->d.r.runlist[rnum].len;rnum++) vcn-=data->d.r.runlist[rnum].len; return data->d.r.runlist[rnum].cluster+vcn; diff --git a/fs/ntfs/ntfstypes.h b/fs/ntfs/ntfstypes.h index 075a60806..56c295714 100644 --- a/fs/ntfs/ntfstypes.h +++ b/fs/ntfs/ntfstypes.h @@ -72,11 +72,11 @@ typedef __kernel_mode_t ntmode_t; #endif #ifndef NTFS_UID_T #define NTFS_UID_T -typedef __kernel_uid_t ntfs_uid_t; +typedef uid_t ntfs_uid_t; #endif #ifndef NTFS_GID_T #define NTFS_GID_T -typedef __kernel_gid_t ntfs_gid_t; +typedef gid_t ntfs_gid_t; #endif #ifndef NTFS_SIZE_T #define NTFS_SIZE_T diff --git a/fs/partitions/acorn.c b/fs/partitions/acorn.c index bce1d34aa..34aab5f44 100644 --- a/fs/partitions/acorn.c +++ b/fs/partitions/acorn.c @@ -14,9 +14,10 @@ #include <linux/genhd.h> #include <linux/fs.h> +#include "check.h" #include "acorn.h" -extern void add_gd_partition(struct gendisk *hd, unsigned int minor, unsigned int start, unsigned int size); +extern void add_gd_partition(struct gendisk *hd, int minor, int start, int size); static void adfspart_setgeometry(kdev_t dev, unsigned int secspertrack, unsigned int heads, diff --git a/fs/partitions/check.c b/fs/partitions/check.c index e3d8ed60b..ec0bd3a4b 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c @@ -235,7 +235,7 @@ int get_partition_list(char * page) } #endif -void check_partition(struct gendisk *hd, kdev_t dev, int first_part_minor) +static void check_partition(struct gendisk *hd, kdev_t dev, int first_part_minor) { static int first_time = 1; unsigned long first_sector; @@ -273,13 +273,27 @@ void check_partition(struct gendisk *hd, kdev_t dev, int first_part_minor) * Much of the cleanup from the old partition tables should have already been * done */ -void resetup_one_dev(struct gendisk *dev, int drive) + +void register_disk(struct gendisk *gdev, kdev_t dev, unsigned minors, + struct block_device_operations *ops, long size) +{ + unsigned first = (unsigned)dev; + if (!gdev) + return; + grok_partitions(gdev, MINOR(dev)>>gdev->minor_shift, minors, size); +} + +void grok_partitions(struct gendisk *dev, int drive, unsigned minors, long size) { int i; int first_minor = drive << dev->minor_shift; int end_minor = first_minor + dev->max_p; blk_size[dev->major] = NULL; + dev->part[first_minor].nr_sects = size; + /* No Such Agen^Wdevice or no minors to use for partitions */ + if (!size || minors == 1) + return; check_partition(dev, MKDEV(dev->major, first_minor), 1 + first_minor); /* @@ -293,31 +307,10 @@ void resetup_one_dev(struct gendisk *dev, int drive) } } -static inline void setup_dev(struct gendisk *dev) -{ - int i, drive; - int end_minor = dev->max_nr * dev->max_p; - - blk_size[dev->major] = NULL; - for (i = 0; i < end_minor; i++) { - dev->part[i].start_sect = 0; - dev->part[i].nr_sects = 0; - dev->sizes[i] = 0; - } - dev->init(dev); - for (drive = 0 ; drive < dev->nr_real ; drive++) - resetup_one_dev(dev, drive); -} - int __init partition_setup(void) { - struct gendisk *p; - device_init(); - for (p = gendisk_head ; p ; p=p->next) - setup_dev(p); - #ifdef CONFIG_BLK_DEV_RAM #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start && mount_initrd) initrd_load(); diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c index c05d6cf30..8ab3f071a 100644 --- a/fs/partitions/msdos.c +++ b/fs/partitions/msdos.c @@ -163,25 +163,37 @@ done: bforget(bh); } +static inline struct buffer_head * +get_partition_table_block(struct gendisk *hd, int minor, int blocknr) { + kdev_t dev = MKDEV(hd->major, minor); + return bread(dev, blocknr, get_ptable_blocksize(dev)); +} + #ifdef CONFIG_SOLARIS_X86_PARTITION + +/* james@bpgc.com: Solaris has a nasty indicator: 0x82 which also + indicates linux swap. Be careful before believing this is Solaris. */ + static void -solaris_x86_partition(struct gendisk *hd, kdev_t dev, long offset) { +solaris_x86_partition(struct gendisk *hd, int minor) { + long offset = hd->part[minor].start_sect; struct buffer_head *bh; struct solaris_x86_vtoc *v; struct solaris_x86_slice *s; int i; + char buf[40]; - if(!(bh = bread(dev, 0, get_ptable_blocksize(dev)))) + if(!(bh = get_partition_table_block(hd, minor, 0))) return; v = (struct solaris_x86_vtoc *)(bh->b_data + 512); if(v->v_sanity != SOLARIS_X86_VTOC_SANE) { brelse(bh); return; } - printk(" <solaris:"); + printk(" %s: <solaris:", disk_name(hd, minor, buf)); if(v->v_version != 1) { - printk(" cannot handle version %ld vtoc>", v->v_version); + printk(" cannot handle version %ld vtoc>\n", v->v_version); brelse(bh); return; } @@ -199,21 +211,21 @@ solaris_x86_partition(struct gendisk *hd, kdev_t dev, long offset) { current_minor++; } brelse(bh); - printk(" >"); + printk(" >\n"); } #endif #ifdef CONFIG_BSD_DISKLABEL -static void check_and_add_bsd_partition(struct gendisk *hd, - struct bsd_partition *bsd_p, kdev_t dev) -{ +static void +check_and_add_bsd_partition(struct gendisk *hd, + struct bsd_partition *bsd_p, int minor) { struct hd_struct *lin_p; /* check relative position of partitions. */ - for (lin_p = hd->part + 1 + MINOR(dev); - lin_p - hd->part - MINOR(dev) < current_minor; lin_p++) { + for (lin_p = hd->part + 1 + minor; + lin_p - hd->part - minor < current_minor; lin_p++) { /* no relationship -> try again */ - if (lin_p->start_sect + lin_p->nr_sects <= bsd_p->p_offset - || lin_p->start_sect >= bsd_p->p_offset + bsd_p->p_size) + if (lin_p->start_sect + lin_p->nr_sects <= bsd_p->p_offset || + lin_p->start_sect >= bsd_p->p_offset + bsd_p->p_size) continue; /* equal -> no need to add */ if (lin_p->start_sect == bsd_p->p_offset && @@ -244,26 +256,32 @@ static void check_and_add_bsd_partition(struct gendisk *hd, add_gd_partition(hd, current_minor, bsd_p->p_offset, bsd_p->p_size); current_minor++; } + /* * Create devices for BSD partitions listed in a disklabel, under a * dos-like partition. See extended_partition() for more information. */ -static void bsd_disklabel_partition(struct gendisk *hd, kdev_t dev, - int max_partitions) -{ +static void bsd_disklabel_partition(struct gendisk *hd, int minor, int type) { struct buffer_head *bh; struct bsd_disklabel *l; struct bsd_partition *p; + int max_partitions; int mask = (1 << hd->minor_shift) - 1; + char buf[40]; - if (!(bh = bread(dev,0,get_ptable_blocksize(dev)))) + if (!(bh = get_partition_table_block(hd, minor, 0))) return; l = (struct bsd_disklabel *) (bh->b_data+512); if (l->d_magic != BSD_DISKMAGIC) { brelse(bh); return; } + printk(" %s:", disk_name(hd, minor, buf)); + printk((type == OPENBSD_PARTITION) ? " <openbsd:" : + (type == NETBSD_PARTITION) ? " <netbsd:" : " <bsd:"); + max_partitions = ((type == OPENBSD_PARTITION) ? OPENBSD_MAXPARTITIONS + : BSD_MAXPARTITIONS); if (l->d_npartitions < max_partitions) max_partitions = l->d_npartitions; for (p = l->d_partitions; p - l->d_partitions < max_partitions; p++) { @@ -271,12 +289,13 @@ static void bsd_disklabel_partition(struct gendisk *hd, kdev_t dev, break; if (p->p_fstype != BSD_FS_UNUSED) - check_and_add_bsd_partition(hd, p, dev); + check_and_add_bsd_partition(hd, p, minor); } /* Use bforget(), as we have changed the disk setup */ bforget(bh); + printk(" >\n"); } #endif @@ -285,14 +304,14 @@ static void bsd_disklabel_partition(struct gendisk *hd, kdev_t dev, * Create devices for Unixware partitions listed in a disklabel, under a * dos-like partition. See extended_partition() for more information. */ -static void unixware_partition(struct gendisk *hd, kdev_t dev) -{ +static void unixware_partition(struct gendisk *hd, int minor) { struct buffer_head *bh; struct unixware_disklabel *l; struct unixware_slice *p; int mask = (1 << hd->minor_shift) - 1; + char buf[40]; - if (!(bh = bread(dev, 14, get_ptable_blocksize(dev)))) + if (!(bh = get_partition_table_block(hd, minor, 14))) return; l = (struct unixware_disklabel *) (bh->b_data+512); if (le32_to_cpu(l->d_magic) != UNIXWARE_DISKMAGIC || @@ -300,7 +319,7 @@ static void unixware_partition(struct gendisk *hd, kdev_t dev) brelse(bh); return; } - printk(" <unixware:"); + printk(" %s: <unixware:", disk_name(hd, minor, buf)); p = &l->vtoc.v_slice[1]; /* I omit the 0th slice as it is the same as whole disk. */ while (p - &l->vtoc.v_slice[0] < UNIXWARE_NUMSLICE) { @@ -308,30 +327,26 @@ static void unixware_partition(struct gendisk *hd, kdev_t dev) break; if (p->s_label != UNIXWARE_FS_UNUSED) { - add_gd_partition(hd, current_minor, START_SECT(p), NR_SECTS(p)); + add_gd_partition(hd, current_minor, START_SECT(p), + NR_SECTS(p)); current_minor++; } p++; } /* Use bforget, as we have changed the disk setup */ bforget(bh); - printk(" >"); + printk(" >\n"); } #endif -int msdos_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector, int first_part_minor) -{ +int msdos_partition(struct gendisk *hd, kdev_t dev, + unsigned long first_sector, int first_part_minor) { int i, minor = current_minor = first_part_minor; struct buffer_head *bh; struct partition *p; unsigned char *data; int mask = (1 << hd->minor_shift) - 1; int sector_size = get_hardsect_size(dev) / 512; -#ifdef CONFIG_BSD_DISKLABEL - /* no bsd disklabel as a default */ - kdev_t bsd_kdev = 0; - int bsd_maxpart = BSD_MAXPARTITIONS; -#endif #ifdef CONFIG_BLK_DEV_IDE int tested_for_xlate = 0; @@ -345,7 +360,7 @@ read_mbr: #ifdef CONFIG_BLK_DEV_IDE check_table: #endif - /* Use bforget(), because we have potentially changed the disk geometry */ + /* Use bforget(), because we may have changed the disk geometry */ if (*(unsigned short *) (0x1fe + data) != cpu_to_le16(MSDOS_LABEL_MAGIC)) { bforget(bh); return 0; @@ -410,11 +425,16 @@ check_table: } #endif /* CONFIG_BLK_DEV_IDE */ + /* Look for partitions in two passes: + First find the primary partitions, and the DOS-type extended partitions. + On the second pass look inside *BSD and Unixware and Solaris partitions. */ + current_minor += 4; /* first "extra" minor (for extended partitions) */ for (i=1 ; i<=4 ; minor++,i++,p++) { if (!NR_SECTS(p)) continue; - add_gd_partition(hd, minor, first_sector+START_SECT(p)*sector_size, NR_SECTS(p)*sector_size); + add_gd_partition(hd, minor, first_sector+START_SECT(p)*sector_size, + NR_SECTS(p)*sector_size); if (is_extended_partition(p)) { printk(" <"); /* @@ -432,44 +452,8 @@ check_table: if (hd->part[minor].nr_sects > 2) hd->part[minor].nr_sects = 2; } -#ifdef CONFIG_BSD_DISKLABEL - /* tag first disklabel for late recognition */ - if (SYS_IND(p) == BSD_PARTITION || SYS_IND(p) == NETBSD_PARTITION) { - printk("!"); - if (!bsd_kdev) - bsd_kdev = MKDEV(hd->major, minor); - } else if (SYS_IND(p) == OPENBSD_PARTITION) { - printk("!"); - if (!bsd_kdev) { - bsd_kdev = MKDEV(hd->major, minor); - bsd_maxpart = OPENBSD_MAXPARTITIONS; - } - } -#endif -#ifdef CONFIG_UNIXWARE_DISKLABEL - if (SYS_IND(p) == UNIXWARE_PARTITION) - unixware_partition(hd, MKDEV(hd->major, minor)); -#endif -#ifdef CONFIG_SOLARIS_X86_PARTITION - - /* james@bpgc.com: Solaris has a nasty indicator: 0x82 - * which also means linux swap. For that reason, all - * of the prints are done inside the - * solaris_x86_partition routine */ - - if(SYS_IND(p) == SOLARIS_X86_PARTITION) { - solaris_x86_partition(hd, MKDEV(hd->major, minor), - first_sector+START_SECT(p)); - } -#endif - } -#ifdef CONFIG_BSD_DISKLABEL - if (bsd_kdev) { - printk(" <"); - bsd_disklabel_partition(hd, bsd_kdev, bsd_maxpart); - printk(" >"); } -#endif + /* * Check for old-style Disk Manager partition table */ @@ -485,6 +469,29 @@ check_table: } } printk("\n"); + + /* second pass - output for each on a separate line */ + minor -= 4; + p = (struct partition *) (0x1be + data); + for (i=1 ; i<=4 ; minor++,i++,p++) { + if (!NR_SECTS(p)) + continue; +#ifdef CONFIG_BSD_DISKLABEL + if (SYS_IND(p) == BSD_PARTITION || + SYS_IND(p) == NETBSD_PARTITION || + SYS_IND(p) == OPENBSD_PARTITION) + bsd_disklabel_partition(hd, minor, SYS_IND(p)); +#endif +#ifdef CONFIG_UNIXWARE_DISKLABEL + if (SYS_IND(p) == UNIXWARE_PARTITION) + unixware_partition(hd, minor); +#endif +#ifdef CONFIG_SOLARIS_X86_PARTITION + if(SYS_IND(p) == SOLARIS_X86_PARTITION) + solaris_x86_partition(hd, minor); +#endif + } + bforget(bh); return 1; } diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 5f43c691e..3017323b2 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -20,7 +20,7 @@ static ssize_t proc_file_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos); static ssize_t proc_file_write(struct file * file, const char * buffer, size_t count, loff_t *ppos); -static long long proc_file_lseek(struct file *, long long, int); +static loff_t proc_file_lseek(struct file *, loff_t, int); int proc_match(int len, const char *name,struct proc_dir_entry * de) { @@ -139,8 +139,8 @@ proc_file_write(struct file * file, const char * buffer, } -static long long -proc_file_lseek(struct file * file, long long offset, int orig) +static loff_t +proc_file_lseek(struct file * file, loff_t offset, int orig) { switch (orig) { case 0: diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c index 1b4b7f23b..88d41c3c2 100644 --- a/fs/proc/proc_devtree.c +++ b/fs/proc/proc_devtree.c @@ -59,8 +59,8 @@ static void add_node(struct device_node *np, struct proc_dir_entry *de) * Unfortunately proc_register puts each new entry * at the beginning of the list. So we rearrange them. */ - ent = create_proc_read_entry(de, 0, pp->name, - property_read_proc, pp); + ent = create_proc_read_entry(pp->name, S_IRUGO, de, + property_read_proc, pp); if (ent == 0) break; ent->size = pp->length; @@ -77,7 +77,7 @@ static void add_node(struct device_node *np, struct proc_dir_entry *de) l = strlen(p); if (l > 2 && p[l-2] == '@' && p[l-1] == '0') l -= 2; - ent = proc_mkdir(de, p); + ent = proc_mkdir(p, de); if (ent == 0) break; *lastp = ent; @@ -99,7 +99,7 @@ static void add_node(struct device_node *np, struct proc_dir_entry *de) if (sib->name && strcmp(sib->name, child->name) == 0) break; if (sib == child && strncmp(p, child->name, l) != 0) { - al = proc_symlink(de, child->name, ent->name); + al = proc_symlink(child->name, de, ent->name); if (al == 0) break; *lastp = al; @@ -109,7 +109,7 @@ static void add_node(struct device_node *np, struct proc_dir_entry *de) /* * Add another directory with the @address part as its name. */ - al = proc_symlink(de, at, ent->name); + al = proc_symlink(at, de, ent->name); if (al == 0) break; proc_register(de, al); diff --git a/fs/proc/procfs_syms.c b/fs/proc/procfs_syms.c index 7c986d615..45d80dd5f 100644 --- a/fs/proc/procfs_syms.c +++ b/fs/proc/procfs_syms.c @@ -17,6 +17,7 @@ EXPORT_SYMBOL(proc_root); EXPORT_SYMBOL(proc_root_fs); EXPORT_SYMBOL(proc_net); EXPORT_SYMBOL(proc_bus); +EXPORT_SYMBOL(proc_root_driver); static struct file_system_type proc_fs_type = { "proc", diff --git a/fs/qnx4/README b/fs/qnx4/README index 55cc90bae..937978b5d 100644 --- a/fs/qnx4/README +++ b/fs/qnx4/README @@ -6,4 +6,4 @@ Credits : Richard "Scuba" A. Frowijn <scuba@wxs.nl> Frank "Jedi/Sector One" Denis <j@4u.net> -Anders Larsen <al@alarsen.net> +Anders Larsen <al@alarsen.net> (Maintainer) diff --git a/fs/qnx4/bitmap.c b/fs/qnx4/bitmap.c index c399f85a8..141caa2d1 100644 --- a/fs/qnx4/bitmap.c +++ b/fs/qnx4/bitmap.c @@ -86,6 +86,8 @@ unsigned long qnx4_count_free_inodes(struct super_block *sb) return qnx4_count_free_blocks(sb) * QNX4_INODES_PER_BLOCK; /* FIXME */ } +#ifdef CONFIG_QNX4FS_RW + int qnx4_is_free(struct super_block *sb, long block) { int start = sb->u.qnx4_sb.BitMap->di_first_xtnt.xtnt_blk - 1; @@ -115,8 +117,6 @@ int qnx4_is_free(struct super_block *sb, long block) return ret; } -#ifdef CONFIG_QNX4FS_RW - int qnx4_set_bitmap(struct super_block *sb, long block, int busy) { int start = sb->u.qnx4_sb.BitMap->di_first_xtnt.xtnt_blk - 1; diff --git a/fs/qnx4/dir.c b/fs/qnx4/dir.c index 831219999..7dd304735 100644 --- a/fs/qnx4/dir.c +++ b/fs/qnx4/dir.c @@ -37,8 +37,7 @@ static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir) while (filp->f_pos < inode->i_size) { blknum = qnx4_block_map( inode, filp->f_pos / QNX4_BLOCK_SIZE ); bh = bread(inode->i_dev, blknum, QNX4_BLOCK_SIZE); - if(bh==NULL) - { + if(bh==NULL) { printk(KERN_ERR "qnx4_readdir: bread failed (%ld)\n", blknum); break; } @@ -57,8 +56,7 @@ static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir) QNX4DEBUG(("qnx4_readdir:%.*s\n", size, de->di_fname)); if ( ( de->di_status & QNX4_FILE_LINK ) == 0 ) ino = blknum * QNX4_INODES_PER_BLOCK + ix - 1; - else - { + else { le = (struct qnx4_link_info*)de; ino = ( le->dl_inode_blk - 1 ) * QNX4_INODES_PER_BLOCK + diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c index f77e4e2a5..67c9f3d3a 100644 --- a/fs/qnx4/inode.c +++ b/fs/qnx4/inode.c @@ -22,6 +22,7 @@ #include <linux/fs.h> #include <linux/locks.h> #include <linux/init.h> +#include <linux/highuid.h> #include <asm/uaccess.h> @@ -98,8 +99,8 @@ static void qnx4_write_inode(struct inode *inode) raw_inode = ((struct qnx4_inode_entry *) bh->b_data) + (ino % QNX4_INODES_PER_BLOCK); raw_inode->di_mode = inode->i_mode; - raw_inode->di_uid = inode->i_uid; - raw_inode->di_gid = inode->i_gid; + raw_inode->di_uid = fs_high2lowuid(inode->i_uid); + raw_inode->di_gid = fs_high2lowgid(inode->i_gid); raw_inode->di_nlink = inode->i_nlink; raw_inode->di_size = inode->i_size; raw_inode->di_mtime = inode->i_mtime; @@ -147,23 +148,16 @@ static int qnx4_remount(struct super_block *sb, int *flags, char *data) return 0; } -struct buffer_head *inode_getblk(struct inode *inode, int nr, +struct buffer_head *qnx4_getblk(struct inode *inode, int nr, int create) { - int tmp; - int tst; struct buffer_head *result = NULL; - tst = nr; - repeat: - tmp = tst; - if (tmp) { - result = getblk(inode->i_dev, tmp, QNX4_BLOCK_SIZE); - if (tmp == tst) { - return result; - } - brelse(result); - goto repeat; + if ( nr >= 0 ) + nr = qnx4_block_map( inode, nr ); + if (nr) { + result = getblk(inode->i_dev, nr, QNX4_BLOCK_SIZE); + return result; } if (!create) { return NULL; @@ -190,7 +184,7 @@ struct buffer_head *qnx4_bread(struct inode *inode, int block, int create) { struct buffer_head *bh; - bh = inode_getblk(inode, block, create); + bh = qnx4_getblk(inode, block, create); if (!bh || buffer_uptodate(bh)) { return bh; } @@ -211,15 +205,12 @@ int qnx4_get_block( struct inode *inode, long iblock, struct buffer_head *bh, in QNX4DEBUG(("qnx4: qnx4_get_block inode=[%ld] iblock=[%ld]\n",inode->i_ino,iblock)); phys = qnx4_block_map( inode, iblock ); - if ( phys ) - { + if ( phys ) { // logical block is before EOF bh->b_dev = inode->i_dev; bh->b_blocknr = phys; bh->b_state |= (1UL << BH_Mapped); - } - else if ( create ) - { + } else if ( create ) { // to be done. } return 0; @@ -235,44 +226,35 @@ unsigned long qnx4_block_map( struct inode *inode, long iblock ) struct qnx4_inode_info *qnx4_inode = &inode->u.qnx4_i; qnx4_nxtnt_t nxtnt = qnx4_inode->i_num_xtnts; - if ( iblock < qnx4_inode->i_first_xtnt.xtnt_size ) - { + if ( iblock < qnx4_inode->i_first_xtnt.xtnt_size ) { // iblock is in the first extent. This is easy. block = qnx4_inode->i_first_xtnt.xtnt_blk + iblock - 1; - } - else - { + } else { // iblock is beyond first extent. We have to follow the extent chain. i_xblk = qnx4_inode->i_xblk; offset = iblock - qnx4_inode->i_first_xtnt.xtnt_size; ix = 0; - while ( --nxtnt > 0 ) - { - if ( ix == 0 ) - { + while ( --nxtnt > 0 ) { + if ( ix == 0 ) { // read next xtnt block. bh = bread( inode->i_dev, i_xblk - 1, QNX4_BLOCK_SIZE ); - if ( !bh ) - { + if ( !bh ) { QNX4DEBUG(("qnx4: I/O error reading xtnt block [%ld])\n", i_xblk - 1)); return -EIO; } xblk = (struct qnx4_xblk*)bh->b_data; - if ( memcmp( xblk->xblk_signature, "IamXblk", 7 ) ) - { + if ( memcmp( xblk->xblk_signature, "IamXblk", 7 ) ) { QNX4DEBUG(("qnx4: block at %ld is not a valid xtnt\n", qnx4_inode->i_xblk)); - break; + return -EIO; } } - if ( offset < xblk->xblk_xtnts[ix].xtnt_size ) - { + if ( offset < xblk->xblk_xtnts[ix].xtnt_size ) { // got it! block = xblk->xblk_xtnts[ix].xtnt_blk + offset - 1; break; } offset -= xblk->xblk_xtnts[ix].xtnt_size; - if ( ++ix > QNX4_MAX_XTNTS_PER_XBLK ) - { + if ( ++ix >= xblk->xblk_num_xtnts ) { i_xblk = xblk->xblk_next_xblk; ix = 0; brelse( bh ); @@ -468,8 +450,8 @@ static void qnx4_read_inode(struct inode *inode) (ino % QNX4_INODES_PER_BLOCK); inode->i_mode = raw_inode->di_mode; - inode->i_uid = raw_inode->di_uid; - inode->i_gid = raw_inode->di_gid; + inode->i_uid = (uid_t)raw_inode->di_uid; + inode->i_gid = (gid_t)raw_inode->di_gid; inode->i_nlink = raw_inode->di_nlink; inode->i_size = raw_inode->di_size; inode->i_mtime = raw_inode->di_mtime; diff --git a/fs/qnx4/namei.c b/fs/qnx4/namei.c index 0b6e087e5..16dde5e5f 100644 --- a/fs/qnx4/namei.c +++ b/fs/qnx4/namei.c @@ -33,7 +33,6 @@ static int qnx4_match(int len, const char *name, struct buffer_head *bh, unsigned long *offset) { struct qnx4_inode_entry *de; - struct qnx4_link_info *le; int namelen, thislen; if (bh == NULL) { @@ -80,8 +79,7 @@ static struct buffer_head *qnx4_find_entry(int len, struct inode *dir, block = offset = blkofs = 0; while (blkofs * QNX4_BLOCK_SIZE + offset < dir->i_size) { if (!bh) { - block = qnx4_block_map( dir, blkofs ); - bh = qnx4_bread(dir, block, 0); + bh = qnx4_bread(dir, blkofs, 0); if (!bh) { blkofs++; continue; @@ -89,6 +87,7 @@ static struct buffer_head *qnx4_find_entry(int len, struct inode *dir, } *res_dir = (struct qnx4_inode_entry *) (bh->b_data + offset); if (qnx4_match(len, name, bh, &offset)) { + block = qnx4_block_map( dir, blkofs ); *ino = block * QNX4_INODES_PER_BLOCK + (offset / QNX4_DIR_ENTRY_SIZE) - 1; return bh; diff --git a/fs/qnx4/symlinks.c b/fs/qnx4/symlinks.c index 827b837ee..4eaf27034 100644 --- a/fs/qnx4/symlinks.c +++ b/fs/qnx4/symlinks.c @@ -11,20 +11,8 @@ * 21-06-1998 by Frank Denis : ugly changes to make it compile on Linux 2.1.99+ */ -/* THIS FILE HAS TO BE REWRITTEN */ - -#include <linux/string.h> -#include <linux/errno.h> -#include <linux/sched.h> #include <linux/fs.h> #include <linux/qnx4_fs.h> -#include <linux/stat.h> - -#include <asm/segment.h> -#include <asm/uaccess.h> - -static int qnx4_readlink(struct dentry *, char *, int); -static struct dentry *qnx4_follow_link(struct dentry *, struct dentry *, unsigned int follow); /* * symlinks can't do much... diff --git a/fs/smbfs/ioctl.c b/fs/smbfs/ioctl.c index f9e6fd4c2..dee105a5e 100644 --- a/fs/smbfs/ioctl.c +++ b/fs/smbfs/ioctl.c @@ -11,6 +11,7 @@ #include <linux/ioctl.h> #include <linux/sched.h> #include <linux/mm.h> +#include <linux/highuid.h> #include <linux/smb_fs.h> #include <linux/smb_mount.h> @@ -27,6 +28,9 @@ smb_ioctl(struct inode *inode, struct file *filp, switch (cmd) { case SMB_IOC_GETMOUNTUID: + result = put_user(NEW_TO_OLD_UID(server->mnt->mounted_uid), (uid16_t *) arg); + break; + case SMB_IOC_GETMOUNTUID32: result = put_user(server->mnt->mounted_uid, (uid_t *) arg); break; @@ -8,6 +8,7 @@ #include <linux/errno.h> #include <linux/file.h> #include <linux/smp_lock.h> +#include <linux/highuid.h> #include <asm/uaccess.h> @@ -45,8 +46,8 @@ static int cp_old_stat(struct inode * inode, struct __old_kernel_stat * statbuf) tmp.st_ino = inode->i_ino; tmp.st_mode = inode->i_mode; tmp.st_nlink = inode->i_nlink; - tmp.st_uid = inode->i_uid; - tmp.st_gid = inode->i_gid; + SET_OLDSTAT_UID(tmp, inode->i_uid); + SET_OLDSTAT_GID(tmp, inode->i_gid); tmp.st_rdev = kdev_t_to_nr(inode->i_rdev); tmp.st_size = inode->i_size; tmp.st_atime = inode->i_atime; @@ -67,8 +68,8 @@ static int cp_new_stat(struct inode * inode, struct stat * statbuf) tmp.st_ino = inode->i_ino; tmp.st_mode = inode->i_mode; tmp.st_nlink = inode->i_nlink; - tmp.st_uid = inode->i_uid; - tmp.st_gid = inode->i_gid; + SET_STAT_UID(tmp, inode->i_uid); + SET_STAT_GID(tmp, inode->i_gid); tmp.st_rdev = kdev_t_to_nr(inode->i_rdev); tmp.st_size = inode->i_size; tmp.st_atime = inode->i_atime; diff --git a/fs/super.c b/fs/super.c index 4c67729aa..889938116 100644 --- a/fs/super.c +++ b/fs/super.c @@ -932,7 +932,6 @@ out: /* * Alters the mount flags of a mounted file system. Only the mount point * is used as a reference - file system type and the device are ignored. - * FS-specific mount options can't be altered by remounting. */ static int do_remount_sb(struct super_block *sb, int flags, char *data) @@ -1174,7 +1173,7 @@ void __init mount_root(void) #endif bdev = bdget(kdev_t_to_nr(ROOT_DEV)); - if (!bdget) + if (!bdev) panic(__FUNCTION__ ": unable to allocate root device"); mode = FMODE_READ; if (!(root_mountflags & MS_RDONLY)) diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index 6cd146dbd..cfe016728 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c @@ -33,6 +33,7 @@ #include <linux/locks.h> #include <linux/init.h> #include <linux/smp_lock.h> +#include <linux/highuid.h> #include <asm/byteorder.h> #include <asm/uaccess.h> @@ -1032,8 +1033,8 @@ static void sysv_read_inode(struct inode *inode) mode = from_coh_imode(mode); /* SystemV FS: kludge permissions if ino==SYSV_ROOT_INO ?? */ inode->i_mode = mode; - inode->i_uid = raw_inode->i_uid; - inode->i_gid = raw_inode->i_gid; + inode->i_uid = (uid_t)raw_inode->i_uid; + inode->i_gid = (gid_t)raw_inode->i_gid; inode->i_nlink = raw_inode->i_nlink; if (sb->sv_convert) { inode->i_size = from_coh_ulong(raw_inode->i_size); @@ -1113,8 +1114,8 @@ static struct buffer_head * sysv_update_inode(struct inode * inode) if (sb->sv_kludge_symlinks) mode = to_coh_imode(mode); raw_inode->i_mode = mode; - raw_inode->i_uid = inode->i_uid; - raw_inode->i_gid = inode->i_gid; + raw_inode->i_uid = fs_high2lowuid(inode->i_uid); + raw_inode->i_gid = fs_high2lowgid(inode->i_gid); raw_inode->i_nlink = inode->i_nlink; if (sb->sv_convert) { raw_inode->i_size = to_coh_ulong(inode->i_size); diff --git a/fs/udf/misc.c b/fs/udf/misc.c index 74b2c3965..0b2068015 100644 --- a/fs/udf/misc.c +++ b/fs/udf/misc.c @@ -68,8 +68,6 @@ uid_t udf_convert_uid(int uidin) { if ( uidin == -1 ) return 0; - if ( uidin > (64*1024U - 1) ) /* 16 bit UID */ - return 0; return uidin; } @@ -77,8 +75,6 @@ gid_t udf_convert_gid(int gidin) { if ( gidin == -1 ) return 0; - if ( gidin > (64*1024U - 1) ) /* 16 bit GID */ - return 0; return gidin; } diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c index fa4dfa06a..8b1943a84 100644 --- a/fs/ufs/ialloc.c +++ b/fs/ufs/ialloc.c @@ -289,8 +289,6 @@ cg_found: inode->i_blocks = 0; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; inode->u.ufs_i.i_flags = dir->u.ufs_i.i_flags; - inode->u.ufs_i.i_uid = inode->i_uid; - inode->u.ufs_i.i_gid = inode->i_gid; inode->u.ufs_i.i_lastfrag = 0; inode->i_op = NULL; diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index 21171a864..333186247 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c @@ -54,11 +54,11 @@ static void ufs_print_inode(struct inode * inode) { unsigned swab = inode->i_sb->u.ufs_sb.s_swab; - printk("ino %lu mode 0%6.6o nlink %d uid %d uid32 %u" - " gid %d gid32 %u size %lu blocks %lu\n", + printk("ino %lu mode 0%6.6o nlink %d uid %d gid %d" + " size %lu blocks %lu\n", inode->i_ino, inode->i_mode, inode->i_nlink, - inode->i_uid, inode->u.ufs_i.i_uid, inode->i_gid, - inode->u.ufs_i.i_gid, inode->i_size, inode->i_blocks); + inode->i_uid, inode->i_gid, + inode->i_size, inode->i_blocks); printk(" db <%u %u %u %u %u %u %u %u %u %u %u %u>\n", SWAB32(inode->u.ufs_i.i_u1.i_data[0]), SWAB32(inode->u.ufs_i.i_u1.i_data[1]), @@ -578,17 +578,10 @@ void ufs_read_inode (struct inode * inode) ufs_error (sb, "ufs_read_inode", "inode %lu has zero nlink\n", inode->i_ino); /* - * Linux has only 16-bit uid and gid, so we can't support EFT. - * Files are dynamically chown()ed to root. + * Linux now has 32-bit uid and gid, so we can support EFT. */ - inode->i_uid = inode->u.ufs_i.i_uid = ufs_get_inode_uid(ufs_inode); - inode->i_gid = inode->u.ufs_i.i_gid = ufs_get_inode_gid(ufs_inode); - if (inode->u.ufs_i.i_uid >= UFS_USEEFT) { - inode->i_uid = 0; - } - if (inode->u.ufs_i.i_gid >= UFS_USEEFT) { - inode->i_gid = 0; - } + inode->i_uid = ufs_get_inode_uid(ufs_inode); + inode->i_gid = ufs_get_inode_gid(ufs_inode); /* * Linux i_size can be 32 on some architectures. We will mark @@ -678,15 +671,8 @@ static int ufs_update_inode(struct inode * inode, int do_sync) ufs_inode->ui_mode = SWAB16(inode->i_mode); ufs_inode->ui_nlink = SWAB16(inode->i_nlink); - if (inode->i_uid == 0 && inode->u.ufs_i.i_uid >= UFS_USEEFT) - ufs_set_inode_uid (ufs_inode, inode->u.ufs_i.i_uid); - else - ufs_set_inode_uid (ufs_inode, inode->i_uid); - - if (inode->i_gid == 0 && inode->u.ufs_i.i_gid >= UFS_USEEFT) - ufs_set_inode_gid (ufs_inode, inode->u.ufs_i.i_gid); - else - ufs_set_inode_gid (ufs_inode, inode->i_gid); + ufs_set_inode_uid (ufs_inode, inode->i_uid); + ufs_set_inode_gid (ufs_inode, inode->i_gid); ufs_inode->ui_size = SWAB64((u64)inode->i_size); ufs_inode->ui_atime.tv_sec = SWAB32(inode->i_atime); diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 11a13baec..901c91ff2 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -452,8 +452,14 @@ struct super_block * ufs_read_super (struct super_block * sb, void * data, MOD_INC_USE_COUNT; lock_super (sb); + UFSD(("flag %u\n", (int)(sb->s_flags & MS_RDONLY))) + #ifndef CONFIG_UFS_FS_WRITE - sb->s_flags |= MS_RDONLY; + if (!(sb->s_flags & MS_RDONLY)) { + printk("ufs was compiled with read-only support, " + "can't be mounted as read-write\n"); + goto failed; + } #endif /* * Set default mount options @@ -632,12 +638,14 @@ magic_found: uspi->s_fmask = SWAB32(usb1->fs_fmask); uspi->s_fshift = SWAB32(usb1->fs_fshift); - if (uspi->s_bsize != 4096 && uspi->s_bsize != 8192) { - printk("ufs_read_super: fs_bsize %u != {4096, 8192}\n", uspi->s_bsize); + if (uspi->s_bsize != 4096 && uspi->s_bsize != 8192 + && uspi->s_bsize != 32768) { + printk("ufs_read_super: fs_bsize %u != {4096, 8192, 32768}\n", uspi->s_bsize); goto failed; } - if (uspi->s_fsize != 512 && uspi->s_fsize != 1024 && uspi->s_fsize != 2048) { - printk("ufs_read_super: fs_fsize %u != {512, 1024, 2048}\n", uspi->s_fsize); + if (uspi->s_fsize != 512 && uspi->s_fsize != 1024 + && uspi->s_fsize != 2048 && uspi->s_fsize != 4096) { + printk("ufs_read_super: fs_fsize %u != {512, 1024, 2048. 4096}\n", uspi->s_fsize); goto failed; } if (uspi->s_fsize != block_size || uspi->s_sbsize != super_block_size) { @@ -869,10 +877,15 @@ int ufs_remount (struct super_block * sb, int * mount_flags, char * data) printk("ufstype can't be changed during remount\n"); return -EINVAL; } - sb->u.ufs_sb.s_mount_opt = new_mount_opt; - if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) + if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { + sb->u.ufs_sb.s_mount_opt = new_mount_opt; return 0; + } + + /* + * fs was mouted as rw, remounting ro + */ if (*mount_flags & MS_RDONLY) { ufs_put_cylinder_structures(sb); usb1->fs_time = SWAB32(CURRENT_TIME); @@ -883,18 +896,29 @@ int ufs_remount (struct super_block * sb, int * mount_flags, char * data) sb->s_dirt = 0; sb->s_flags |= MS_RDONLY; } + /* + * fs was mounted as ro, remounting rw + */ else { +#ifndef CONFIG_UFS_FS_WRITE + printk("ufs was compiled with read-only support, " + "can't be mounted as read-write\n"); + return -EINVAL; +#else if (ufstype != UFS_MOUNT_UFSTYPE_SUN && - ufstype != UFS_MOUNT_UFSTYPE_44BSD) { + ufstype != UFS_MOUNT_UFSTYPE_44BSD && + ufstype != UFS_MOUNT_UFSTYPE_SUNx86) { printk("this ufstype is read-only supported\n"); - return 0; + return -EINVAL; } if (!ufs_read_cylinder_structures (sb)) { printk("failed during remounting\n"); - return 0; + return -EPERM; } sb->s_flags &= ~MS_RDONLY; +#endif } + sb->u.ufs_sb.s_mount_opt = new_mount_opt; return 0; } |