summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2001-01-11 04:02:40 +0000
committerRalf Baechle <ralf@linux-mips.org>2001-01-11 04:02:40 +0000
commite47f00743fc4776491344f2c618cc8dc2c23bcbc (patch)
tree13e03a113a82a184c51c19c209867cfd3a59b3b9 /fs
parentb2ad5f821b1381492d792ca10b1eb7a107b48f14 (diff)
Merge with Linux 2.4.0.
Diffstat (limited to 'fs')
-rw-r--r--fs/buffer.c74
-rw-r--r--fs/dcache.c11
-rw-r--r--fs/exec.c6
-rw-r--r--fs/isofs/inode.c2
-rw-r--r--fs/nfsd/nfsfh.c33
-rw-r--r--fs/smbfs/smb_debug.h6
-rw-r--r--fs/umsdos/mangle.c2
7 files changed, 60 insertions, 74 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index 601276bbc..0096524bf 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -118,8 +118,7 @@ union bdflush_param {
wake-cycle */
int nrefill; /* Number of clean buffers to try to obtain
each time we call refill */
- int nref_dirt; /* Dirty buffer threshold for activating bdflush
- when trying to refill buffers. */
+ int dummy1; /* unused */
int interval; /* jiffies delay between kupdate flushes */
int age_buffer; /* Time for normal buffer to age before we flush it */
int nfract_sync; /* Percentage of buffer cache dirty to
@@ -128,7 +127,7 @@ union bdflush_param {
int dummy3; /* unused */
} b_un;
unsigned int data[N_PARAM];
-} bdf_prm = {{40, 500, 64, 256, 5*HZ, 30*HZ, 80, 0, 0}};
+} bdf_prm = {{30, 64, 64, 256, 5*HZ, 30*HZ, 60, 0, 0}};
/* These are the min and max parameter values that we will allow to be assigned */
int bdflush_min[N_PARAM] = { 0, 10, 5, 25, 0, 1*HZ, 0, 0, 0};
@@ -755,11 +754,15 @@ void set_blocksize(kdev_t dev, int size)
/*
* We used to try various strange things. Let's not.
+ * We'll just try to balance dirty buffers, and possibly
+ * launder some pages.
*/
static void refill_freelist(int size)
{
- if (!grow_buffers(size))
- wakeup_bdflush(1); /* Sets task->state to TASK_RUNNING */
+ balance_dirty(NODEV);
+ if (free_shortage())
+ page_launder(GFP_BUFFER, 0);
+ grow_buffers(size);
}
void init_buffer(struct buffer_head *bh, bh_end_io_t *handler, void *private)
@@ -1090,8 +1093,10 @@ void __mark_buffer_dirty(struct buffer_head *bh)
void mark_buffer_dirty(struct buffer_head *bh)
{
- __mark_buffer_dirty(bh);
- balance_dirty(bh->b_dev);
+ if (!atomic_set_buffer_dirty(bh)) {
+ __mark_dirty(bh);
+ balance_dirty(bh->b_dev);
+ }
}
/*
@@ -2528,34 +2533,6 @@ void __init buffer_init(unsigned long mempages)
* response to dirty buffers. Once this process is activated, we write back
* a limited number of buffers to the disks and then go back to sleep again.
*/
-static DECLARE_WAIT_QUEUE_HEAD(bdflush_done);
-struct task_struct *bdflush_tsk = 0;
-
-void wakeup_bdflush(int block)
-{
- DECLARE_WAITQUEUE(wait, current);
-
- if (current == bdflush_tsk)
- return;
-
- if (!block) {
- wake_up_process(bdflush_tsk);
- return;
- }
-
- /* bdflush can wakeup us before we have a chance to
- go to sleep so we must be smart in handling
- this wakeup event from bdflush to avoid deadlocking in SMP
- (we are not holding any lock anymore in these two paths). */
- __set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(&bdflush_done, &wait);
-
- wake_up_process(bdflush_tsk);
- schedule();
-
- remove_wait_queue(&bdflush_done, &wait);
- __set_current_state(TASK_RUNNING);
-}
/* This is the _only_ function that deals with flushing async writes
to disk.
@@ -2611,6 +2588,18 @@ static int flush_dirty_buffers(int check_flushtime)
return flushed;
}
+struct task_struct *bdflush_tsk = 0;
+
+void wakeup_bdflush(int block)
+{
+ if (current != bdflush_tsk) {
+ wake_up_process(bdflush_tsk);
+
+ if (block)
+ flush_dirty_buffers(0);
+ }
+}
+
/*
* Here we attempt to write back old buffers. We also try to flush inodes
* and supers as well, since this function is essentially "update", and
@@ -2725,23 +2714,14 @@ int bdflush(void *sem)
flushed = flush_dirty_buffers(0);
if (free_shortage())
- flushed += page_launder(GFP_BUFFER, 0);
-
- /* If wakeup_bdflush will wakeup us
- after our bdflush_done wakeup, then
- we must make sure to not sleep
- in schedule_timeout otherwise
- wakeup_bdflush may wait for our
- bdflush_done wakeup that would never arrive
- (as we would be sleeping) and so it would
- deadlock in SMP. */
- __set_current_state(TASK_INTERRUPTIBLE);
- wake_up_all(&bdflush_done);
+ flushed += page_launder(GFP_KERNEL, 0);
+
/*
* If there are still a lot of dirty buffers around,
* skip the sleep and flush some more. Otherwise, we
* go to sleep waiting a wakeup.
*/
+ set_current_state(TASK_INTERRUPTIBLE);
if (!flushed || balance_dirty_state(NODEV) < 0) {
run_task_queue(&tq_disk);
schedule();
diff --git a/fs/dcache.c b/fs/dcache.c
index 090bf1686..e0b170ad7 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -339,10 +339,18 @@ void prune_dcache(int count)
if (tmp == &dentry_unused)
break;
- dentry_stat.nr_unused--;
list_del_init(tmp);
dentry = list_entry(tmp, struct dentry, d_lru);
+ /* If the dentry was recently referenced, don't free it. */
+ if (dentry->d_flags & DCACHE_REFERENCED) {
+ dentry->d_flags &= ~DCACHE_REFERENCED;
+ list_add(&dentry->d_lru, &dentry_unused);
+ count--;
+ continue;
+ }
+ dentry_stat.nr_unused--;
+
/* Unused dentry with a count? */
if (atomic_read(&dentry->d_count))
BUG();
@@ -732,6 +740,7 @@ struct dentry * d_lookup(struct dentry * parent, struct qstr * name)
continue;
}
__dget_locked(dentry);
+ dentry->d_flags |= DCACHE_REFERENCED;
spin_unlock(&dcache_lock);
return dentry;
}
diff --git a/fs/exec.c b/fs/exec.c
index 36f3a8c6e..07ee80d0c 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -403,6 +403,12 @@ static int exec_mmap(void)
mmdrop(mm);
return -ENOMEM;
}
+
+ /* Add it to the list of mm's */
+ spin_lock(&mmlist_lock);
+ list_add(&mm->mmlist, &init_mm.mmlist);
+ spin_unlock(&mmlist_lock);
+
task_lock(current);
current->mm = mm;
current->active_mm = mm;
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 5d50c37a6..757a87070 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -1264,7 +1264,7 @@ static void isofs_read_inode(struct inode * inode)
(volume_seq_no != 0) && (volume_seq_no != 1)) {
printk(KERN_WARNING "Multi-volume CD somehow got mounted.\n");
} else
-#endif IGNORE_WRONG_MULTI_VOLUME_SPECS
+#endif /*IGNORE_WRONG_MULTI_VOLUME_SPECS */
{
if (S_ISREG(inode->i_mode)) {
inode->i_fop = &generic_ro_fops;
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 7bf572e34..78c729c09 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -346,7 +346,7 @@ find_fh_dentry(struct super_block *sb, ino_t ino, int generation, ino_t dirino,
struct dentry *dentry, *result = NULL;
struct dentry *tmp;
int found =0;
- int err;
+ int err = -ESTALE;
/* the sb->s_nfsd_free_path_sem semaphore is needed to make sure that only one unconnected (free)
* dcache path ever exists, as otherwise two partial paths might get
* joined together, which would be very confusing.
@@ -360,19 +360,18 @@ find_fh_dentry(struct super_block *sb, ino_t ino, int generation, ino_t dirino,
* Attempt to find the inode.
*/
retry:
+ down(&sb->s_nfsd_free_path_sem);
result = nfsd_iget(sb, ino, generation);
- err = PTR_ERR(result);
- if (IS_ERR(result))
- goto err_out;
- err = -ESTALE;
- if (! (result->d_flags & DCACHE_NFSD_DISCONNECTED))
- return result;
-
- /* result is now an anonymous dentry, which may be adequate as it stands, or else
- * will get spliced into the dcache tree */
-
- if (!S_ISDIR(result->d_inode->i_mode) && ! needpath) {
- nfsdstats.fh_anon++;
+ if (IS_ERR(result)
+ || !(result->d_flags & DCACHE_NFSD_DISCONNECTED)
+ || (!S_ISDIR(result->d_inode->i_mode) && ! needpath)) {
+ up(&sb->s_nfsd_free_path_sem);
+
+ err = PTR_ERR(result);
+ if (IS_ERR(result))
+ goto err_out;
+ if ((result->d_flags & DCACHE_NFSD_DISCONNECTED))
+ nfsdstats.fh_anon++;
return result;
}
@@ -380,14 +379,6 @@ find_fh_dentry(struct super_block *sb, ino_t ino, int generation, ino_t dirino,
* location in the tree.
*/
dprintk("nfs_fh: need to look harder for %d/%ld\n",sb->s_dev,ino);
- down(&sb->s_nfsd_free_path_sem);
-
- /* claiming the semaphore might have allowed things to get fixed up */
- if (! (result->d_flags & DCACHE_NFSD_DISCONNECTED)) {
- up(&sb->s_nfsd_free_path_sem);
- return result;
- }
-
found = 0;
if (!S_ISDIR(result->d_inode->i_mode)) {
diff --git a/fs/smbfs/smb_debug.h b/fs/smbfs/smb_debug.h
index a656c356e..746a99fe3 100644
--- a/fs/smbfs/smb_debug.h
+++ b/fs/smbfs/smb_debug.h
@@ -11,14 +11,14 @@
* these are normally enabled.
*/
#ifdef SMBFS_PARANOIA
-#define PARANOIA(x...) printk(KERN_NOTICE __FUNCTION__ ": " ## x)
+#define PARANOIA(x...) printk(KERN_NOTICE __FUNCTION__ ": " x)
#else
#define PARANOIA(x...) do { ; } while(0)
#endif
/* lots of debug messages */
#ifdef SMBFS_DEBUG_VERBOSE
-#define VERBOSE(x...) printk(KERN_DEBUG __FUNCTION__ ": " ## x)
+#define VERBOSE(x...) printk(KERN_DEBUG __FUNCTION__ ": " x)
#else
#define VERBOSE(x...) do { ; } while(0)
#endif
@@ -28,7 +28,7 @@
* too common name.
*/
#ifdef SMBFS_DEBUG
-#define DEBUG1(x...) printk(KERN_DEBUG __FUNCTION__ ": " ## x)
+#define DEBUG1(x...) printk(KERN_DEBUG __FUNCTION__ ": " x)
#else
#define DEBUG1(x...) do { ; } while(0)
#endif
diff --git a/fs/umsdos/mangle.c b/fs/umsdos/mangle.c
index 08de621e7..a1feba0ea 100644
--- a/fs/umsdos/mangle.c
+++ b/fs/umsdos/mangle.c
@@ -435,7 +435,7 @@ struct MANG_TEST tb[] =
"HELLO", 1, "hello",
"Hello.1", 1, "hello.1",
"Hello.c", 1, "hello.c",
-#elseif
+#else
/*
* I find the three examples below very unfortunate. I propose to
* convert them to lower case in a quick preliminary pass, then test