summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/block_dev.c4
-rw-r--r--fs/fcntl.c12
-rw-r--r--fs/ncpfs/file.c10
-rw-r--r--fs/ncpfs/ioctl.c26
-rw-r--r--fs/nfs/flushd.c3
-rw-r--r--fs/nfs/inode.c2
-rw-r--r--fs/nfs/write.c28
-rw-r--r--fs/nfsd/nfscache.c9
-rw-r--r--fs/nfsd/nfsfh.c2
-rw-r--r--fs/partitions/check.c12
-rw-r--r--fs/partitions/msdos.c16
-rw-r--r--fs/super.c16
-rw-r--r--fs/ufs/super.c32
13 files changed, 112 insertions, 60 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c
index a170bb2b6..c455a735d 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -313,7 +313,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);
}
@@ -650,7 +650,7 @@ int blkdev_put(struct block_device *bdev, int kind)
return ret;
}
-int blkdev_close(struct inode * inode, struct file * filp)
+static int blkdev_close(struct inode * inode, struct file * filp)
{
return blkdev_put(inode->i_bdev, BDEV_FILE);
}
diff --git a/fs/fcntl.c b/fs/fcntl.c
index d6cebd646..ab758c566 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -259,8 +259,7 @@ out:
/* Table to convert sigio signal codes into poll band bitmaps */
-static long band_table[NSIGPOLL+1] = {
- ~0,
+static long band_table[NSIGPOLL] = {
POLLIN | POLLRDNORM, /* POLL_IN */
POLLOUT | POLLWRNORM | POLLWRBAND, /* POLL_OUT */
POLLIN | POLLRDNORM | POLLMSG, /* POLL_MSG */
@@ -290,10 +289,15 @@ static void send_sigio_to_task(struct task_struct *p,
si.si_signo = fown->signum;
si.si_errno = 0;
si.si_code = reason;
- if (reason < 0 || reason > NSIGPOLL)
+ /* Make sure we are called with one of the POLL_*
+ reasons, otherwise we could leak kernel stack into
+ userspace. */
+ if ((reason & __SI_MASK) != __SI_POLL)
+ BUG();
+ if (reason - POLL_IN > NSIGPOLL)
si.si_band = ~0L;
else
- si.si_band = band_table[reason];
+ si.si_band = band_table[reason - POLL_IN];
si.si_fd = fa->fa_fd;
if (!send_sig_info(fown->signum, &si, p))
break;
diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c
index 657e924de..6f8fd2d63 100644
--- a/fs/ncpfs/file.c
+++ b/fs/ncpfs/file.c
@@ -275,12 +275,22 @@ out:
return already_written ? already_written : errno;
}
+static int ncp_release(struct inode *inode, struct file *file) {
+ if (NCP_FINFO(inode)->opened) {
+ if (ncp_make_closed(inode)) {
+ DPRINTK("ncp_release: failed to close\n");
+ }
+ }
+ return 0;
+}
+
struct file_operations ncp_file_operations =
{
read: ncp_file_read,
write: ncp_file_write,
ioctl: ncp_ioctl,
mmap: ncp_mmap,
+ release: ncp_release,
fsync: ncp_fsync,
};
diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c
index 4f7a1d253..26c95fc8f 100644
--- a/fs/ncpfs/ioctl.c
+++ b/fs/ncpfs/ioctl.c
@@ -250,21 +250,21 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
{
return -EACCES;
}
- if (server->sign_active)
- {
- return -EINVAL;
- }
- if (server->sign_wanted)
- {
- struct ncp_sign_init sign;
+ if (arg) {
+ if (server->sign_wanted)
+ {
+ struct ncp_sign_init sign;
- if (copy_from_user(&sign, (struct ncp_sign_init *) arg,
- sizeof(sign))) return -EFAULT;
- memcpy(server->sign_root,sign.sign_root,8);
- memcpy(server->sign_last,sign.sign_last,16);
- server->sign_active = 1;
+ if (copy_from_user(&sign, (struct ncp_sign_init *) arg,
+ sizeof(sign))) return -EFAULT;
+ memcpy(server->sign_root,sign.sign_root,8);
+ memcpy(server->sign_last,sign.sign_last,16);
+ server->sign_active = 1;
+ }
+ /* ignore when signatures not wanted */
+ } else {
+ server->sign_active = 0;
}
- /* ignore when signatures not wanted */
return 0;
case NCP_IOC_SIGN_WANTED:
diff --git a/fs/nfs/flushd.c b/fs/nfs/flushd.c
index 460d4eba9..02024c90e 100644
--- a/fs/nfs/flushd.c
+++ b/fs/nfs/flushd.c
@@ -136,6 +136,7 @@ int nfs_reqlist_alloc(struct nfs_server *server)
return -ENOMEM;
memset(cache, 0, sizeof(*cache));
+ atomic_set(&cache->nr_requests, 0);
init_waitqueue_head(&cache->request_wait);
server->rw_requests = cache;
@@ -280,7 +281,7 @@ nfs_flushd(struct rpc_task *task)
cache->runat = jiffies + task->tk_timeout;
spin_lock(&nfs_flushd_lock);
- if (!cache->nr_requests && !cache->inodes) {
+ if (!atomic_read(&cache->nr_requests) && !cache->inodes) {
cache->task = NULL;
task->tk_action = NULL;
} else
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 44e3030c3..cf0ea6ef3 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -417,6 +417,8 @@ nfs_read_super(struct super_block *sb, void *raw_data, int silent)
if (data->wsize == 0)
server->wsize = nfs_block_size(fsinfo.wtpref, NULL);
server->dtsize = nfs_block_size(fsinfo.dtpref, NULL);
+ if (server->dtsize > PAGE_CACHE_SIZE)
+ server->dtsize = PAGE_CACHE_SIZE;
/* NFSv3: we don't have bsize, but rather rtmult and wtmult... */
if (!fsinfo.bsize)
fsinfo.bsize = (fsinfo.rtmult>fsinfo.wtmult) ? fsinfo.rtmult : fsinfo.wtmult;
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 464776ac3..cb97c40bc 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -68,7 +68,7 @@
* Spinlock
*/
spinlock_t nfs_wreq_lock = SPIN_LOCK_UNLOCKED;
-static unsigned int nfs_nr_requests = 0;
+static atomic_t nfs_nr_requests = ATOMIC_INIT(0);
/*
* Local structures
@@ -490,9 +490,9 @@ struct nfs_page *nfs_create_request(struct file *file, struct page *page,
*/
do {
/* If we're over the global soft limit, wake up all requests */
- if (nfs_nr_requests >= MAX_REQUEST_SOFT) {
+ if (atomic_read(&nfs_nr_requests) >= MAX_REQUEST_SOFT) {
dprintk("NFS: hit soft limit (%d requests)\n",
- nfs_nr_requests);
+ atomic_read(&nfs_nr_requests));
if (!cache->task)
nfs_reqlist_init(NFS_SERVER(inode));
nfs_wake_flushd();
@@ -500,7 +500,7 @@ struct nfs_page *nfs_create_request(struct file *file, struct page *page,
/* If we haven't reached the local hard limit yet,
* try to allocate the request struct */
- if (cache->nr_requests < MAX_REQUEST_HARD) {
+ if (atomic_read(&cache->nr_requests) < MAX_REQUEST_HARD) {
req = nfs_page_alloc();
if (req != NULL)
break;
@@ -508,7 +508,7 @@ struct nfs_page *nfs_create_request(struct file *file, struct page *page,
/* We're over the hard limit. Wait for better times */
dprintk("NFS: create_request sleeping (total %d pid %d)\n",
- cache->nr_requests, current->pid);
+ atomic_read(&cache->nr_requests), current->pid);
timeout = 1 * HZ;
if (NFS_SERVER(inode)->flags & NFS_MOUNT_INTR) {
@@ -520,7 +520,7 @@ struct nfs_page *nfs_create_request(struct file *file, struct page *page,
sleep_on_timeout(&cache->request_wait, timeout);
dprintk("NFS: create_request waking up (tot %d pid %d)\n",
- cache->nr_requests, current->pid);
+ atomic_read(&cache->nr_requests), current->pid);
} while (!req);
if (!req)
return NULL;
@@ -539,8 +539,8 @@ struct nfs_page *nfs_create_request(struct file *file, struct page *page,
req->wb_count = 1;
/* register request's existence */
- cache->nr_requests++;
- nfs_nr_requests++;
+ atomic_inc(&cache->nr_requests);
+ atomic_inc(&nfs_nr_requests);
return req;
}
@@ -580,9 +580,15 @@ nfs_release_request(struct nfs_page *req)
page_cache_release(page);
nfs_page_free(req);
/* wake up anyone waiting to allocate a request */
- cache->nr_requests--;
- nfs_nr_requests--;
+ atomic_dec(&cache->nr_requests);
+ atomic_dec(&nfs_nr_requests);
wake_up(&cache->request_wait);
+#ifdef NFS_PARANOIA
+ if (atomic_read(&cache->nr_requests) < 0)
+ BUG();
+ if (atomic_read(&nfs_nr_requests) < 0)
+ BUG();
+#endif
}
/*
@@ -931,7 +937,7 @@ nfs_strategy(struct inode *inode)
if (dirty >= wpages)
nfs_flush_file(inode, NULL, 0, 0, 0);
if (inode->u.nfs_i.ncommit > NFS_STRATEGY_PAGES * wpages &&
- nfs_nr_requests > MAX_REQUEST_SOFT)
+ atomic_read(&nfs_nr_requests) > MAX_REQUEST_SOFT)
nfs_commit_file(inode, NULL, 0, 0, 0);
}
#else
diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c
index c47830ff3..357a297f6 100644
--- a/fs/nfsd/nfscache.c
+++ b/fs/nfsd/nfscache.c
@@ -68,7 +68,7 @@ nfsd_cache_init(void)
i = HASHSIZE * sizeof (struct nfscache_head);
hash_list = kmalloc (i, GFP_KERNEL);
if (!hash_list) {
- kfree (nfscache);
+ free_pages ((unsigned long)nfscache, order);
nfscache = NULL;
printk (KERN_ERR "nfsd: cannot allocate %d bytes for hash list\n", i);
return;
@@ -98,6 +98,8 @@ void
nfsd_cache_shutdown(void)
{
struct svc_cacherep *rp;
+ size_t i;
+ unsigned long order;
if (!cache_initialized)
return;
@@ -110,7 +112,10 @@ nfsd_cache_shutdown(void)
cache_initialized = 0;
cache_disabled = 1;
- kfree (nfscache);
+ i = CACHESIZE * sizeof (struct svc_cacherep);
+ for (order = 0; (PAGE_SIZE << order) < i; order++)
+ ;
+ free_pages ((unsigned long)nfscache, order);
nfscache = NULL;
kfree (hash_list);
hash_list = NULL;
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index f681c9bfc..f88161593 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -812,8 +812,8 @@ fh_put(struct svc_fh *fhp)
{
struct dentry * dentry = fhp->fh_dentry;
if (fhp->fh_dverified) {
- fhp->fh_dentry = NULL;
fh_unlock(fhp);
+ fhp->fh_dentry = NULL;
fhp->fh_dverified = 0;
dput(dentry);
nfsd_nr_put++;
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 3b252ec63..b0118ab42 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -76,11 +76,6 @@ static int (*check_part[])(struct gendisk *hd, kdev_t dev, unsigned long first_s
NULL
};
-#if defined CONFIG_BLK_DEV_LVM || defined CONFIG_BLK_DEV_LVM_MODULE
-#include <linux/lvm.h>
-void (*lvm_hd_name_ptr) (char *, int) = NULL;
-#endif
-
/*
* disk_name() is used by genhd.c and blkpg.c.
* It formats the devicename of the indicated disk into
@@ -107,13 +102,6 @@ char *disk_name (struct gendisk *hd, int minor, char *buf)
* This requires special handling here.
*/
switch (hd->major) {
-#if defined CONFIG_BLK_DEV_LVM || defined CONFIG_BLK_DEV_LVM_MODULE
- case LVM_BLK_MAJOR:
- *buf = 0;
- if ( lvm_hd_name_ptr != NULL)
- (lvm_hd_name_ptr) ( buf, minor);
- return buf;
-#endif
case IDE9_MAJOR:
unit += 2;
case IDE8_MAJOR:
diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c
index 886e2f4c0..53386a08d 100644
--- a/fs/partitions/msdos.c
+++ b/fs/partitions/msdos.c
@@ -27,9 +27,9 @@
#include <linux/string.h>
#include <linux/blk.h>
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD)
+#ifdef CONFIG_BLK_DEV_IDE
#include <linux/ide.h> /* IDE xlate */
-#endif /* (CONFIG_BLK_DEV_IDE) || (CONFIG_BLK_DEV_HD) */
+#endif /* CONFIG_BLK_DEV_IDE */
#include <asm/system.h>
@@ -350,19 +350,19 @@ int msdos_partition(struct gendisk *hd, kdev_t dev,
unsigned char *data;
int mask = (1 << hd->minor_shift) - 1;
int sector_size = get_hardsect_size(dev) / 512;
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD)
+#ifdef CONFIG_BLK_DEV_IDE
int tested_for_xlate = 0;
read_mbr:
-#endif /* (CONFIG_BLK_DEV_IDE) || (CONFIG_BLK_DEV_HD) */
+#endif /* CONFIG_BLK_DEV_IDE */
if (!(bh = bread(dev,0,get_ptable_blocksize(dev)))) {
if (warn_no_part) printk(" unable to read partition table\n");
return -1;
}
data = bh->b_data;
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD)
+#ifdef CONFIG_BLK_DEV_IDE
check_table:
-#endif /* (CONFIG_BLK_DEV_IDE) || (CONFIG_BLK_DEV_HD) */
+#endif /* CONFIG_BLK_DEV_IDE */
/* Use bforget(), because we may have changed the disk geometry */
if (*(unsigned short *) (0x1fe + data) != cpu_to_le16(MSDOS_LABEL_MAGIC)) {
bforget(bh);
@@ -370,7 +370,7 @@ check_table:
}
p = (struct partition *) (0x1be + data);
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD)
+#ifdef CONFIG_BLK_DEV_IDE
if (!tested_for_xlate++) { /* Do this only once per disk */
/*
* Look for various forms of IDE disk geometry translation
@@ -426,7 +426,7 @@ check_table:
(void) ide_xlate_1024(dev, 2, heads, " [PTBL]");
}
}
-#endif /* (CONFIG_BLK_DEV_IDE) || (CONFIG_BLK_DEV_HD) */
+#endif /* CONFIG_BLK_DEV_IDE */
/* Look for partitions in two passes:
First find the primary partitions, and the DOS-type extended partitions.
diff --git a/fs/super.c b/fs/super.c
index f1d873331..5b8974e5b 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -1167,7 +1167,8 @@ static int copy_mount_options (const void *data, unsigned long *where)
{
int i;
unsigned long page;
-
+ unsigned long size;
+
*where = 0;
if (!data)
return 0;
@@ -1179,13 +1180,18 @@ static int copy_mount_options (const void *data, unsigned long *where)
* gave us is valid. Just in case, we'll zero
* the remainder of the page.
*/
- i = copy_from_user((void *)page, data, PAGE_SIZE);
- if (i == PAGE_SIZE) {
+ /* copy_from_user cannot cross TASK_SIZE ! */
+ size = TASK_SIZE - (unsigned long)data;
+ if (size > PAGE_SIZE)
+ size = PAGE_SIZE;
+
+ i = size - copy_from_user((void *)page, data, size);
+ if (!i) {
free_page(page);
return -EFAULT;
}
- if (i)
- memset((char *)page + PAGE_SIZE - i, 0, i);
+ if (i != PAGE_SIZE)
+ memset((char *)page + i, 0, PAGE_SIZE - i);
*where = page;
return 0;
}
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index d9620a1c6..7784203e0 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -55,6 +55,9 @@
*
* write support Daniel Pirkl <daniel.pirkl@email.cz> 1998
*
+ * HP/UX hfs filesystem support added by
+ * Martin K. Petersen <mkp@mkp.net>, August 1999
+ *
*/
@@ -279,6 +282,8 @@ static int ufs_parse_options (char * options, unsigned * mount_options)
ufs_set_opt (*mount_options, UFSTYPE_OPENSTEP);
else if (!strcmp (value, "sunx86"))
ufs_set_opt (*mount_options, UFSTYPE_SUNx86);
+ else if (!strcmp (value, "hp"))
+ ufs_set_opt (*mount_options, UFSTYPE_HP);
else {
printk ("UFS-fs: Invalid type option: %s\n", value);
return 0;
@@ -473,7 +478,7 @@ struct super_block * ufs_read_super (struct super_block * sb, void * data,
if (!(sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE)) {
printk("You didn't specify the type of your ufs filesystem\n\n"
"mount -t ufs -o ufstype="
- "sun|sunx86|44bsd|old|nextstep|netxstep-cd|openstep ...\n\n"
+ "sun|sunx86|44bsd|old|hp|nextstep|netxstep-cd|openstep ...\n\n"
">>>WARNING<<< Wrong ufstype may corrupt your filesystem, "
"default is ufstype=old\n");
ufs_set_opt (sb->u.ufs_sb.s_mount_opt, UFSTYPE_OLD);
@@ -573,6 +578,19 @@ struct super_block * ufs_read_super (struct super_block * sb, void * data,
}
break;
+ case UFS_MOUNT_UFSTYPE_HP:
+ UFSD(("ufstype=hp\n"))
+ uspi->s_fsize = block_size = 1024;
+ uspi->s_fmask = ~(1024 - 1);
+ uspi->s_fshift = 10;
+ uspi->s_sbsize = super_block_size = 2048;
+ uspi->s_sbbase = 0;
+ flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;
+ if (!(sb->s_flags & MS_RDONLY)) {
+ printk(KERN_INFO "ufstype=hp is supported read-only\n");
+ sb->s_flags |= MS_RDONLY;
+ }
+ break;
default:
printk("unknown ufstype\n");
goto failed;
@@ -598,18 +616,30 @@ again:
#if defined(__LITTLE_ENDIAN) || defined(__BIG_ENDIAN) /* sane bytesex */
switch (usb3->fs_magic) {
case UFS_MAGIC:
+ case UFS_MAGIC_LFN:
+ case UFS_MAGIC_FEA:
+ case UFS_MAGIC_4GB:
swab = UFS_NATIVE_ENDIAN;
goto magic_found;
case UFS_CIGAM:
+ case UFS_CIGAM_LFN:
+ case UFS_CIGAM_FEA:
+ case UFS_CIGAM_4GB:
swab = UFS_SWABBED_ENDIAN;
goto magic_found;
}
#else /* bytesex perversion */
switch (le32_to_cpup(&usb3->fs_magic)) {
case UFS_MAGIC:
+ case UFS_MAGIC_LFN:
+ case UFS_MAGIC_FEA:
+ case UFS_MAGIC_4GB:
swab = UFS_LITTLE_ENDIAN;
goto magic_found;
case UFS_CIGAM:
+ case UFS_CIGAM_LFN:
+ case UFS_CIGAM_FEA:
+ case UFS_CIGAM_4GB:
swab = UFS_BIG_ENDIAN;
goto magic_found;
}