summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/Config.in4
-rw-r--r--fs/binfmt_elf.c5
-rw-r--r--fs/block_dev.c5
-rw-r--r--fs/cramfs/README166
-rw-r--r--fs/cramfs/cramfs.h27
-rw-r--r--fs/cramfs/inode.c156
-rw-r--r--fs/cramfs/uncompress.c19
-rw-r--r--fs/efs/inode.c4
-rw-r--r--fs/ext2/file.c6
-rw-r--r--fs/ext2/fsync.c16
-rw-r--r--fs/ext2/inode.c45
-rw-r--r--fs/ext2/namei.c7
-rw-r--r--fs/ext2/super.c3
-rw-r--r--fs/fat/dir.c2
-rw-r--r--fs/hfs/ChangeLog4
-rw-r--r--fs/hfs/extent.c21
-rw-r--r--fs/hfs/file.c35
-rw-r--r--fs/hfs/hfs_btree.h24
-rw-r--r--fs/hfs/inode.c6
-rw-r--r--fs/inode.c5
-rw-r--r--fs/iobuf.c2
-rw-r--r--fs/lockd/mon.c2
-rw-r--r--fs/lockd/svcproc.c18
-rw-r--r--fs/lockd/svcsubs.c2
-rw-r--r--fs/lockd/xdr.c4
-rw-r--r--fs/minix/inode.c17
-rw-r--r--fs/namei.c118
-rw-r--r--fs/ncpfs/inode.c51
-rw-r--r--fs/ncpfs/ioctl.c144
-rw-r--r--fs/ncpfs/ncplib_kernel.c6
-rw-r--r--fs/nfs/inode.c2
-rw-r--r--fs/nfsd/export.c10
-rw-r--r--fs/nfsd/nfsctl.c2
-rw-r--r--fs/nfsd/nfsfh.c2
-rw-r--r--fs/nfsd/nfsproc.c2
-rw-r--r--fs/nfsd/vfs.c2
-rw-r--r--fs/ntfs/inode.c2
-rw-r--r--fs/ntfs/ntfstypes.h4
-rw-r--r--fs/partitions/acorn.c3
-rw-r--r--fs/partitions/check.c39
-rw-r--r--fs/partitions/msdos.c145
-rw-r--r--fs/proc/generic.c6
-rw-r--r--fs/proc/proc_devtree.c10
-rw-r--r--fs/proc/procfs_syms.c1
-rw-r--r--fs/qnx4/README2
-rw-r--r--fs/qnx4/bitmap.c4
-rw-r--r--fs/qnx4/dir.c6
-rw-r--r--fs/qnx4/inode.c64
-rw-r--r--fs/qnx4/namei.c5
-rw-r--r--fs/qnx4/symlinks.c12
-rw-r--r--fs/smbfs/ioctl.c4
-rw-r--r--fs/stat.c9
-rw-r--r--fs/super.c3
-rw-r--r--fs/sysv/inode.c9
-rw-r--r--fs/udf/misc.c4
-rw-r--r--fs/ufs/ialloc.c2
-rw-r--r--fs/ufs/inode.c32
-rw-r--r--fs/ufs/super.c44
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;
diff --git a/fs/stat.c b/fs/stat.c
index 725df6fc8..892d3417d 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -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;
}