From 14dd2ec093cfabda3ae7efeeaf0e23c66ebaccc0 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 16 Jun 2000 23:00:36 +0000 Subject: Merge with 2.4.0-test1. --- fs/block_dev.c | 4 ++-- fs/fcntl.c | 12 ++++++++---- fs/ncpfs/file.c | 10 ++++++++++ fs/ncpfs/ioctl.c | 26 +++++++++++++------------- fs/nfs/flushd.c | 3 ++- fs/nfs/inode.c | 2 ++ fs/nfs/write.c | 28 +++++++++++++++++----------- fs/nfsd/nfscache.c | 9 +++++++-- fs/nfsd/nfsfh.c | 2 +- fs/partitions/check.c | 12 ------------ fs/partitions/msdos.c | 16 ++++++++-------- fs/super.c | 16 +++++++++++----- fs/ufs/super.c | 32 +++++++++++++++++++++++++++++++- 13 files changed, 112 insertions(+), 60 deletions(-) (limited to 'fs') 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 -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 #include -#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) +#ifdef CONFIG_BLK_DEV_IDE #include /* IDE xlate */ -#endif /* (CONFIG_BLK_DEV_IDE) || (CONFIG_BLK_DEV_HD) */ +#endif /* CONFIG_BLK_DEV_IDE */ #include @@ -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 1998 * + * HP/UX hfs filesystem support added by + * Martin K. Petersen , 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; } -- cgit v1.2.3