summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/affs/amigaffs.c2
-rw-r--r--fs/affs/symlink.c5
-rw-r--r--fs/afs/super.c2
-rw-r--r--fs/autofs/symlink.c11
-rw-r--r--fs/autofs/waitq.c2
-rw-r--r--fs/autofs4/symlink.c13
-rw-r--r--fs/autofs4/waitq.c2
-rw-r--r--fs/bad_inode.c4
-rw-r--r--fs/befs/linuxvfs.c65
-rw-r--r--fs/coda/cnode.c5
-rw-r--r--fs/dcache.c11
-rw-r--r--fs/devfs/base.c26
-rw-r--r--fs/dnotify.c20
-rw-r--r--fs/eventpoll.c2
-rw-r--r--fs/ext2/symlink.c18
-rw-r--r--fs/ext3/symlink.c20
-rw-r--r--fs/freevxfs/vxfs_immed.c30
-rw-r--r--fs/hfs/super.c2
-rw-r--r--fs/hfsplus/bnode.c10
-rw-r--r--fs/hfsplus/wrapper.c2
-rw-r--r--fs/hpfs/alloc.c4
-rw-r--r--fs/inode.c2
-rw-r--r--fs/isofs/inode.c23
-rw-r--r--fs/jbd/commit.c2
-rw-r--r--fs/jffs2/symlink.c40
-rw-r--r--fs/jfs/jfs_extent.c2
-rw-r--r--fs/jfs/jfs_logmgr.c2
-rw-r--r--fs/jfs/jfs_txnmgr.c2
-rw-r--r--fs/jfs/symlink.c12
-rw-r--r--fs/lockd/host.c4
-rw-r--r--fs/lockd/svclock.c10
-rw-r--r--fs/lockd/svcshare.c2
-rw-r--r--fs/minix/inode.c5
-rw-r--r--fs/namei.c80
-rw-r--r--fs/partitions/msdos.c6
-rw-r--r--fs/proc/generic.c14
-rw-r--r--fs/proc/kcore.c3
-rw-r--r--fs/proc/proc_misc.c1
-rw-r--r--fs/quota.c2
-rw-r--r--fs/reiserfs/namei.c5
-rw-r--r--fs/smbfs/proto.h2
-rw-r--r--fs/smbfs/symlink.c49
-rw-r--r--fs/sysv/inode.c5
-rw-r--r--fs/sysv/symlink.c13
-rw-r--r--fs/ufs/symlink.c12
-rw-r--r--fs/xfs/Makefile1
-rw-r--r--fs/xfs/linux-2.6/kmem.c127
-rw-r--r--fs/xfs/linux-2.6/kmem.h116
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c57
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c56
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.h20
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c8
-rw-r--r--fs/xfs/linux-2.6/xfs_fs_subr.c6
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c31
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c40
-rw-r--r--fs/xfs/linux-2.6/xfs_super.h9
-rw-r--r--fs/xfs/xfs.h1
-rw-r--r--fs/xfs/xfs_acl.c4
-rw-r--r--fs/xfs/xfs_acl.h26
-rw-r--r--fs/xfs/xfs_arch.h10
-rw-r--r--fs/xfs/xfs_attr.c6
-rw-r--r--fs/xfs/xfs_bit.c24
-rw-r--r--fs/xfs/xfs_dmapi.h13
-rw-r--r--fs/xfs/xfs_inode.c9
-rw-r--r--fs/xfs/xfs_inode.h4
-rw-r--r--fs/xfs/xfs_mount.h6
-rw-r--r--fs/xfs/xfs_rtalloc.c6
-rw-r--r--fs/xfs/xfs_vfsops.c4
-rw-r--r--fs/xfs/xfs_vnodeops.c16
69 files changed, 607 insertions, 547 deletions
diff --git a/fs/affs/amigaffs.c b/fs/affs/amigaffs.c
index ddd53ec12a92..17a4bfbb1f58 100644
--- a/fs/affs/amigaffs.c
+++ b/fs/affs/amigaffs.c
@@ -201,7 +201,7 @@ affs_remove_link(struct dentry *dentry)
goto done;
}
- while ((ino = be32_to_cpu(AFFS_TAIL(sb, bh)->link_chain))) {
+ while ((ino = be32_to_cpu(AFFS_TAIL(sb, bh)->link_chain)) != 0) {
if (ino == link_ino) {
ino = AFFS_TAIL(sb, link_bh)->link_chain;
AFFS_TAIL(sb, bh)->link_chain = ino;
diff --git a/fs/affs/symlink.c b/fs/affs/symlink.c
index c01cd4c64a61..4ef626e49381 100644
--- a/fs/affs/symlink.c
+++ b/fs/affs/symlink.c
@@ -78,7 +78,8 @@ struct address_space_operations affs_symlink_aops = {
};
struct inode_operations affs_symlink_inode_operations = {
- .readlink = page_readlink,
- .follow_link = page_follow_link,
+ .readlink = generic_readlink,
+ .follow_link = page_follow_link_light,
+ .put_link = page_put_link,
.setattr = affs_notify_change,
};
diff --git a/fs/afs/super.c b/fs/afs/super.c
index bcf81d358df0..bdf830191f62 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -172,7 +172,7 @@ static int afs_super_parse_options(struct afs_mount_params *params,
options[PAGE_SIZE - 1] = 0;
ret = 0;
- while ((key = strsep(&options, ",")))
+ while ((key = strsep(&options, ",")) != 0)
{
value = strchr(key, '=');
if (value)
diff --git a/fs/autofs/symlink.c b/fs/autofs/symlink.c
index 237a6305ab48..f028396f1383 100644
--- a/fs/autofs/symlink.c
+++ b/fs/autofs/symlink.c
@@ -12,19 +12,14 @@
#include "autofs_i.h"
-static int autofs_readlink(struct dentry *dentry, char *buffer, int buflen)
-{
- char *s=((struct autofs_symlink *)dentry->d_inode->u.generic_ip)->data;
- return vfs_readlink(dentry, buffer, buflen, s);
-}
-
static int autofs_follow_link(struct dentry *dentry, struct nameidata *nd)
{
char *s=((struct autofs_symlink *)dentry->d_inode->u.generic_ip)->data;
- return vfs_follow_link(nd, s);
+ nd_set_link(nd, s);
+ return 0;
}
struct inode_operations autofs_symlink_inode_operations = {
- .readlink = autofs_readlink,
+ .readlink = generic_readlink,
.follow_link = autofs_follow_link
};
diff --git a/fs/autofs/waitq.c b/fs/autofs/waitq.c
index d08b648ccae5..1fcaa1568541 100644
--- a/fs/autofs/waitq.c
+++ b/fs/autofs/waitq.c
@@ -183,7 +183,7 @@ int autofs_wait_release(struct autofs_sb_info *sbi, autofs_wqt_t wait_queue_toke
{
struct autofs_wait_queue *wq, **wql;
- for ( wql = &sbi->queues ; (wq = *wql) ; wql = &wq->next ) {
+ for ( wql = &sbi->queues ; (wq = *wql) != 0 ; wql = &wq->next ) {
if ( wq->wait_queue_token == wait_queue_token )
break;
}
diff --git a/fs/autofs4/symlink.c b/fs/autofs4/symlink.c
index 9cc355a0812c..c265a66edf0f 100644
--- a/fs/autofs4/symlink.c
+++ b/fs/autofs4/symlink.c
@@ -12,21 +12,14 @@
#include "autofs_i.h"
-static int autofs4_readlink(struct dentry *dentry, char *buffer, int buflen)
-{
- struct autofs_info *ino = autofs4_dentry_ino(dentry);
-
- return vfs_readlink(dentry, buffer, buflen, ino->u.symlink);
-}
-
static int autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct autofs_info *ino = autofs4_dentry_ino(dentry);
-
- return vfs_follow_link(nd, ino->u.symlink);
+ nd_set_link(nd, (char *)ino->u.symlink);
+ return 0;
}
struct inode_operations autofs4_symlink_inode_operations = {
- .readlink = autofs4_readlink,
+ .readlink = generic_readlink,
.follow_link = autofs4_follow_link
};
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index caae47fd7a8e..b2f2e885d94b 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -275,7 +275,7 @@ int autofs4_wait_release(struct autofs_sb_info *sbi, autofs_wqt_t wait_queue_tok
struct autofs_wait_queue *wq, **wql;
down(&sbi->wq_sem);
- for ( wql = &sbi->queues ; (wq = *wql) ; wql = &wq->next ) {
+ for ( wql = &sbi->queues ; (wq = *wql) != 0 ; wql = &wq->next ) {
if ( wq->wait_queue_token == wait_queue_token )
break;
}
diff --git a/fs/bad_inode.c b/fs/bad_inode.c
index c0619d21a00e..3957ad190aa4 100644
--- a/fs/bad_inode.c
+++ b/fs/bad_inode.c
@@ -13,6 +13,7 @@
#include <linux/stat.h>
#include <linux/time.h>
#include <linux/smp_lock.h>
+#include <linux/namei.h>
/*
* The follow_link operation is special: it must behave as a no-op
@@ -21,7 +22,8 @@
*/
static int bad_follow_link(struct dentry *dent, struct nameidata *nd)
{
- return vfs_follow_link(nd, ERR_PTR(-EIO));
+ nd_set_link(nd, ERR_PTR(-EIO));
+ return 0;
}
static int return_EIO(void)
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index 649d02b03012..49cf3428d511 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -14,6 +14,7 @@
#include <linux/buffer_head.h>
#include <linux/vfs.h>
#include <linux/parser.h>
+#include <linux/namei.h>
#include "befs.h"
#include "btree.h"
@@ -40,8 +41,8 @@ static struct inode *befs_alloc_inode(struct super_block *sb);
static void befs_destroy_inode(struct inode *inode);
static int befs_init_inodecache(void);
static void befs_destroy_inodecache(void);
-static int befs_readlink(struct dentry *, char __user *, int);
-static int befs_follow_link(struct dentry *, struct nameidata *nd);
+static int befs_follow_link(struct dentry *, struct nameidata *);
+static void befs_put_link(struct dentry *, struct nameidata *);
static int befs_utf2nls(struct super_block *sb, const char *in, int in_len,
char **out, int *out_len);
static int befs_nls2utf(struct super_block *sb, const char *in, int in_len,
@@ -85,8 +86,9 @@ struct address_space_operations befs_aops = {
};
static struct inode_operations befs_symlink_inode_operations = {
- .readlink = befs_readlink,
+ .readlink = generic_readlink,
.follow_link = befs_follow_link,
+ .put_link = befs_put_link,
};
/*
@@ -462,71 +464,40 @@ befs_destroy_inodecache(void)
static int
befs_follow_link(struct dentry *dentry, struct nameidata *nd)
{
- struct super_block *sb = dentry->d_sb;
befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
char *link;
- int res;
if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
+ struct super_block *sb = dentry->d_sb;
befs_data_stream *data = &befs_ino->i_data.ds;
- befs_off_t linklen = data->size;
+ befs_off_t len = data->size;
befs_debug(sb, "Follow long symlink");
- link = kmalloc(linklen, GFP_NOFS);
- if (link == NULL)
- return -ENOMEM;
-
- if (befs_read_lsymlink(sb, data, link, linklen) != linklen) {
+ link = kmalloc(len, GFP_NOFS);
+ if (!link) {
+ link = ERR_PTR(-ENOMEM);
+ } else if (befs_read_lsymlink(sb, data, link, len) != len) {
kfree(link);
befs_error(sb, "Failed to read entire long symlink");
- return -EIO;
+ link = ERR_PTR(-EIO);
}
-
- res = vfs_follow_link(nd, link);
-
- kfree(link);
} else {
link = befs_ino->i_data.symlink;
- res = vfs_follow_link(nd, link);
}
- return res;
+ nd_set_link(nd, link);
+ return 0;
}
-static int
-befs_readlink(struct dentry *dentry, char __user *buffer, int buflen)
+static void befs_put_link(struct dentry *dentry, struct nameidata *nd)
{
- struct super_block *sb = dentry->d_sb;
befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
- char *link;
- int res;
-
if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
- befs_data_stream *data = &befs_ino->i_data.ds;
- befs_off_t linklen = data->size;
-
- befs_debug(sb, "Read long symlink");
-
- link = kmalloc(linklen, GFP_NOFS);
- if (link == NULL)
- return -ENOMEM;
-
- if (befs_read_lsymlink(sb, data, link, linklen) != linklen) {
- kfree(link);
- befs_error(sb, "Failed to read entire long symlink");
- return -EIO;
- }
-
- res = vfs_readlink(dentry, buffer, buflen, link);
-
- kfree(link);
- } else {
- link = befs_ino->i_data.symlink;
- res = vfs_readlink(dentry, buffer, buflen, link);
+ char *p = nd_get_link(nd);
+ if (!IS_ERR(p))
+ kfree(p);
}
-
- return res;
}
/*
diff --git a/fs/coda/cnode.c b/fs/coda/cnode.c
index 9ef74a31af47..6bf72ebb1c57 100644
--- a/fs/coda/cnode.c
+++ b/fs/coda/cnode.c
@@ -17,8 +17,9 @@ inline int coda_fideq(struct CodaFid *fid1, struct CodaFid *fid2)
}
static struct inode_operations coda_symlink_inode_operations = {
- .readlink = page_readlink,
- .follow_link = page_follow_link,
+ .readlink = generic_readlink,
+ .follow_link = page_follow_link_light,
+ .put_link = page_put_link,
.setattr = coda_setattr,
};
diff --git a/fs/dcache.c b/fs/dcache.c
index 4c632e1261dc..ac36b5c5fdf2 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -32,9 +32,10 @@
#include <linux/swap.h>
#include <linux/bootmem.h>
-#define DCACHE_PARANOIA 1
/* #define DCACHE_DEBUG 1 */
+int sysctl_vfs_cache_pressure = 100;
+
spinlock_t dcache_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
seqlock_t rename_lock __cacheline_aligned_in_smp = SEQLOCK_UNLOCKED;
@@ -65,9 +66,9 @@ struct dentry_stat_t dentry_stat = {
.age_limit = 45,
};
-static void d_callback(void *arg)
+static void d_callback(struct rcu_head *head)
{
- struct dentry * dentry = (struct dentry *)arg;
+ struct dentry * dentry = container_of(head, struct dentry, d_rcu);
if (dname_external(dentry))
kfree(dentry->d_name.name);
@@ -82,7 +83,7 @@ static void d_free(struct dentry *dentry)
{
if (dentry->d_op && dentry->d_op->d_release)
dentry->d_op->d_release(dentry);
- call_rcu(&dentry->d_rcu, d_callback, dentry);
+ call_rcu(&dentry->d_rcu, d_callback);
}
/*
@@ -664,7 +665,7 @@ static int shrink_dcache_memory(int nr, unsigned int gfp_mask)
return -1;
prune_dcache(nr);
}
- return dentry_stat.nr_unused;
+ return (dentry_stat.nr_unused / 100) * sysctl_vfs_cache_pressure;
}
/**
diff --git a/fs/devfs/base.c b/fs/devfs/base.c
index deab8f23ffa1..b0fb34873825 100644
--- a/fs/devfs/base.c
+++ b/fs/devfs/base.c
@@ -2490,29 +2490,11 @@ static int devfs_mknod(struct inode *dir, struct dentry *dentry, int mode,
return 0;
} /* End Function devfs_mknod */
-static int devfs_readlink(struct dentry *dentry, char __user *buffer,
- int buflen)
-{
- int err;
- struct devfs_entry *de;
-
- de = get_devfs_entry_from_vfs_inode(dentry->d_inode);
- if (!de)
- return -ENODEV;
- err = vfs_readlink(dentry, buffer, buflen, de->u.symlink.linkname);
- return err;
-} /* End Function devfs_readlink */
-
static int devfs_follow_link(struct dentry *dentry, struct nameidata *nd)
{
- int err;
- struct devfs_entry *de;
-
- de = get_devfs_entry_from_vfs_inode(dentry->d_inode);
- if (!de)
- return -ENODEV;
- err = vfs_follow_link(nd, de->u.symlink.linkname);
- return err;
+ struct devfs_entry *p = get_devfs_entry_from_vfs_inode(dentry->d_inode);
+ nd_set_link(nd, p ? p->u.symlink.linkname : ERR_PTR(-ENODEV));
+ return 0;
} /* End Function devfs_follow_link */
static struct inode_operations devfs_iops = {
@@ -2530,7 +2512,7 @@ static struct inode_operations devfs_dir_iops = {
};
static struct inode_operations devfs_symlink_iops = {
- .readlink = devfs_readlink,
+ .readlink = generic_readlink,
.follow_link = devfs_follow_link,
.setattr = devfs_notify_change,
};
diff --git a/fs/dnotify.c b/fs/dnotify.c
index daee2edb17cc..2801eb4fdf10 100644
--- a/fs/dnotify.c
+++ b/fs/dnotify.c
@@ -23,7 +23,6 @@
int dir_notify_enable = 1;
-static rwlock_t dn_lock = RW_LOCK_UNLOCKED;
static kmem_cache_t *dn_cache;
static void redo_inode_mask(struct inode *inode)
@@ -46,7 +45,7 @@ void dnotify_flush(struct file *filp, fl_owner_t id)
inode = filp->f_dentry->d_inode;
if (!S_ISDIR(inode->i_mode))
return;
- write_lock(&dn_lock);
+ spin_lock(&inode->i_lock);
prev = &inode->i_dnotify;
while ((dn = *prev) != NULL) {
if ((dn->dn_owner == id) && (dn->dn_filp == filp)) {
@@ -57,7 +56,7 @@ void dnotify_flush(struct file *filp, fl_owner_t id)
}
prev = &dn->dn_next;
}
- write_unlock(&dn_lock);
+ spin_unlock(&inode->i_lock);
}
int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
@@ -81,7 +80,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
dn = kmem_cache_alloc(dn_cache, SLAB_KERNEL);
if (dn == NULL)
return -ENOMEM;
- write_lock(&dn_lock);
+ spin_lock(&inode->i_lock);
prev = &inode->i_dnotify;
while ((odn = *prev) != NULL) {
if ((odn->dn_owner == id) && (odn->dn_filp == filp)) {
@@ -104,12 +103,13 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
inode->i_dnotify_mask |= arg & ~DN_MULTISHOT;
dn->dn_next = inode->i_dnotify;
inode->i_dnotify = dn;
-out:
- write_unlock(&dn_lock);
- return error;
+ spin_unlock(&inode->i_lock);
+ return 0;
+
out_free:
+ spin_unlock(&inode->i_lock);
kmem_cache_free(dn_cache, dn);
- goto out;
+ return error;
}
void __inode_dir_notify(struct inode *inode, unsigned long event)
@@ -119,7 +119,7 @@ void __inode_dir_notify(struct inode *inode, unsigned long event)
struct fown_struct * fown;
int changed = 0;
- write_lock(&dn_lock);
+ spin_lock(&inode->i_lock);
prev = &inode->i_dnotify;
while ((dn = *prev) != NULL) {
if ((dn->dn_mask & event) == 0) {
@@ -138,7 +138,7 @@ void __inode_dir_notify(struct inode *inode, unsigned long event)
}
if (changed)
redo_inode_mask(inode);
- write_unlock(&dn_lock);
+ spin_unlock(&inode->i_lock);
}
EXPORT_SYMBOL(__inode_dir_notify);
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 86464ead1961..a05a3ce255b8 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -802,7 +802,7 @@ static void ep_free(struct eventpoll *ep)
* write-holding "sem" we can be sure that no file cleanup code will hit
* us during this operation. So we can avoid the lock on "ep->lock".
*/
- while ((rbp = rb_first(&ep->rbr))) {
+ while ((rbp = rb_first(&ep->rbr)) != 0) {
epi = rb_entry(rbp, struct epitem, rbn);
ep_remove(ep, epi);
}
diff --git a/fs/ext2/symlink.c b/fs/ext2/symlink.c
index b282670a54bc..4680ea7ecc12 100644
--- a/fs/ext2/symlink.c
+++ b/fs/ext2/symlink.c
@@ -19,23 +19,19 @@
#include "ext2.h"
#include "xattr.h"
-
-static int
-ext2_readlink(struct dentry *dentry, char __user *buffer, int buflen)
-{
- struct ext2_inode_info *ei = EXT2_I(dentry->d_inode);
- return vfs_readlink(dentry, buffer, buflen, (char *)ei->i_data);
-}
+#include <linux/namei.h>
static int ext2_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct ext2_inode_info *ei = EXT2_I(dentry->d_inode);
- return vfs_follow_link(nd, (char *)ei->i_data);
+ nd_set_link(nd, (char *)ei->i_data);
+ return 0;
}
struct inode_operations ext2_symlink_inode_operations = {
- .readlink = page_readlink,
- .follow_link = page_follow_link,
+ .readlink = generic_readlink,
+ .follow_link = page_follow_link_light,
+ .put_link = page_put_link,
.setxattr = ext2_setxattr,
.getxattr = ext2_getxattr,
.listxattr = ext2_listxattr,
@@ -43,7 +39,7 @@ struct inode_operations ext2_symlink_inode_operations = {
};
struct inode_operations ext2_fast_symlink_inode_operations = {
- .readlink = ext2_readlink,
+ .readlink = generic_readlink,
.follow_link = ext2_follow_link,
.setxattr = ext2_setxattr,
.getxattr = ext2_getxattr,
diff --git a/fs/ext3/symlink.c b/fs/ext3/symlink.c
index ae092875b62a..867f713a102c 100644
--- a/fs/ext3/symlink.c
+++ b/fs/ext3/symlink.c
@@ -20,24 +20,20 @@
#include <linux/fs.h>
#include <linux/jbd.h>
#include <linux/ext3_fs.h>
+#include <linux/namei.h>
#include "xattr.h"
-static int
-ext3_readlink(struct dentry *dentry, char __user *buffer, int buflen)
-{
- struct ext3_inode_info *ei = EXT3_I(dentry->d_inode);
- return vfs_readlink(dentry, buffer, buflen, (char*)ei->i_data);
-}
-
static int ext3_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct ext3_inode_info *ei = EXT3_I(dentry->d_inode);
- return vfs_follow_link(nd, (char*)ei->i_data);
+ nd_set_link(nd, (char*)ei->i_data);
+ return 0;
}
struct inode_operations ext3_symlink_inode_operations = {
- .readlink = page_readlink,
- .follow_link = page_follow_link,
+ .readlink = generic_readlink,
+ .follow_link = page_follow_link_light,
+ .put_link = page_put_link,
.setxattr = ext3_setxattr,
.getxattr = ext3_getxattr,
.listxattr = ext3_listxattr,
@@ -45,8 +41,8 @@ struct inode_operations ext3_symlink_inode_operations = {
};
struct inode_operations ext3_fast_symlink_inode_operations = {
- .readlink = ext3_readlink, /* BKL not held. Don't need */
- .follow_link = ext3_follow_link, /* BKL not held. Don't need */
+ .readlink = generic_readlink,
+ .follow_link = ext3_follow_link,
.setxattr = ext3_setxattr,
.getxattr = ext3_getxattr,
.listxattr = ext3_listxattr,
diff --git a/fs/freevxfs/vxfs_immed.c b/fs/freevxfs/vxfs_immed.c
index be243053a7c1..ac677ab262b2 100644
--- a/fs/freevxfs/vxfs_immed.c
+++ b/fs/freevxfs/vxfs_immed.c
@@ -32,12 +32,12 @@
*/
#include <linux/fs.h>
#include <linux/pagemap.h>
+#include <linux/namei.h>
#include "vxfs.h"
#include "vxfs_inode.h"
-static int vxfs_immed_readlink(struct dentry *, char __user *, int);
static int vxfs_immed_follow_link(struct dentry *, struct nameidata *);
static int vxfs_immed_readpage(struct file *, struct page *);
@@ -49,7 +49,7 @@ static int vxfs_immed_readpage(struct file *, struct page *);
* but do all work directly on the inode.
*/
struct inode_operations vxfs_immed_symlink_iops = {
- .readlink = vxfs_immed_readlink,
+ .readlink = generic_readlink,
.follow_link = vxfs_immed_follow_link,
};
@@ -60,28 +60,6 @@ struct address_space_operations vxfs_immed_aops = {
.readpage = vxfs_immed_readpage,
};
-
-/**
- * vxfs_immed_readlink - read immed symlink
- * @dp: dentry for the link
- * @bp: output buffer
- * @buflen: length of @bp
- *
- * Description:
- * vxfs_immed_readlink calls vfs_readlink to read the link
- * described by @dp into userspace.
- *
- * Returns:
- * Number of bytes successfully copied to userspace.
- */
-static int
-vxfs_immed_readlink(struct dentry *dp, char __user *bp, int buflen)
-{
- struct vxfs_inode_info *vip = VXFS_INO(dp->d_inode);
-
- return (vfs_readlink(dp, bp, buflen, vip->vii_immed.vi_immed));
-}
-
/**
* vxfs_immed_follow_link - follow immed symlink
* @dp: dentry for the link
@@ -98,8 +76,8 @@ static int
vxfs_immed_follow_link(struct dentry *dp, struct nameidata *np)
{
struct vxfs_inode_info *vip = VXFS_INO(dp->d_inode);
-
- return (vfs_follow_link(np, vip->vii_immed.vi_immed));
+ nd_set_link(np, vip->vii_immed.vi_immed);
+ return 0;
}
/**
diff --git a/fs/hfs/super.c b/fs/hfs/super.c
index 2b7d0b21d896..345651903fe0 100644
--- a/fs/hfs/super.c
+++ b/fs/hfs/super.c
@@ -161,7 +161,7 @@ static int parse_options(char *options, struct hfs_sb_info *hsb)
if (!options)
return 1;
- while ((this_char = strsep(&options, ","))) {
+ while ((this_char = strsep(&options, ",")) != 0) {
if (!*this_char)
continue;
value = strchr(this_char, '=');
diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c
index ec8cb5dd28c2..5ce5d7713013 100644
--- a/fs/hfsplus/bnode.c
+++ b/fs/hfsplus/bnode.c
@@ -34,7 +34,7 @@ void hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len)
memcpy(buf, kmap(*pagep) + off, l);
kunmap(*pagep);
- while ((len -= l)) {
+ while ((len -= l) != 0) {
buf += l;
l = min(len, (int)PAGE_CACHE_SIZE);
memcpy(buf, kmap(*++pagep), l);
@@ -87,7 +87,7 @@ void hfs_bnode_write(struct hfs_bnode *node, void *buf, int off, int len)
set_page_dirty(*pagep);
kunmap(*pagep);
- while ((len -= l)) {
+ while ((len -= l) != 0) {
buf += l;
l = min(len, (int)PAGE_CACHE_SIZE);
memcpy(kmap(*++pagep), buf, l);
@@ -117,7 +117,7 @@ void hfs_bnode_clear(struct hfs_bnode *node, int off, int len)
set_page_dirty(*pagep);
kunmap(*pagep);
- while ((len -= l)) {
+ while ((len -= l) != 0) {
l = min(len, (int)PAGE_CACHE_SIZE);
memset(kmap(*++pagep), 0, l);
set_page_dirty(*pagep);
@@ -150,7 +150,7 @@ void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst,
set_page_dirty(*dst_page);
kunmap(*dst_page);
- while ((len -= l)) {
+ while ((len -= l) != 0) {
l = min(len, (int)PAGE_CACHE_SIZE);
memcpy(kmap(*++dst_page), kmap(*++src_page), l);
kunmap(*src_page);
@@ -258,7 +258,7 @@ void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len)
set_page_dirty(*dst_page);
kunmap(*dst_page);
- while ((len -= l)) {
+ while ((len -= l) != 0) {
l = min(len, (int)PAGE_CACHE_SIZE);
memmove(kmap(*++dst_page), kmap(*++src_page), l);
kunmap(*src_page);
diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c
index ca595223a07e..777db1122f64 100644
--- a/fs/hfsplus/wrapper.c
+++ b/fs/hfsplus/wrapper.c
@@ -135,7 +135,7 @@ int hfsplus_read_wrapper(struct super_block *sb)
return -EINVAL;
HFSPLUS_SB(sb).alloc_blksz = blocksize;
HFSPLUS_SB(sb).alloc_blksz_shift = 0;
- while (blocksize >>= 1)
+ while ((blocksize >>= 1) != 0)
HFSPLUS_SB(sb).alloc_blksz_shift++;
blocksize = min(HFSPLUS_SB(sb).alloc_blksz, (u32)PAGE_SIZE);
diff --git a/fs/hpfs/alloc.c b/fs/hpfs/alloc.c
index 72ea1412b467..2baa977ffa1d 100644
--- a/fs/hpfs/alloc.c
+++ b/fs/hpfs/alloc.c
@@ -88,7 +88,7 @@ static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigne
goto rt;
}*/
q = nr + n; b = 0;
- while ((a = tstbits(bmp, q, n + forward))) {
+ while ((a = tstbits(bmp, q, n + forward)) != 0) {
q += a;
if (n != 1) q = ((q-1)&~(n-1))+n;
if (!b) {
@@ -116,7 +116,7 @@ static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigne
}
}
if (n != 1) q = ((q-1)&~(n-1))+n;
- while ((a = tstbits(bmp, q, n + forward))) {
+ while ((a = tstbits(bmp, q, n + forward)) != 0) {
q += a;
if (n != 1) q = ((q-1)&~(n-1))+n;
if (q>>5 > i) break;
diff --git a/fs/inode.c b/fs/inode.c
index e802a3c35fd2..ad1dd009acbc 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -488,7 +488,7 @@ static int shrink_icache_memory(int nr, unsigned int gfp_mask)
if (gfp_mask & __GFP_FS)
prune_icache(nr);
}
- return inodes_stat.nr_unused;
+ return (inodes_stat.nr_unused / 100) * sysctl_vfs_cache_pressure;
}
static void __wait_on_freeing_inode(struct inode *inode);
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 9d498e25107f..491dcde30a0e 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -1266,30 +1266,13 @@ static void isofs_read_inode(struct inode * inode)
}
/*
- * The ISO-9660 filesystem only stores 32 bits for file size.
- * mkisofs handles files up to 2GB-2 = 2147483646 = 0x7FFFFFFE bytes
- * in size. This is according to the large file summit paper from 1996.
- * WARNING: ISO-9660 filesystems > 1 GB and even > 2 GB are fully
- * legal. Do not prevent to use DVD's schilling@fokus.gmd.de
- */
- if ((inode->i_size < 0 || inode->i_size > 0x7FFFFFFE) &&
- sbi->s_cruft == 'n') {
- printk(KERN_WARNING "Warning: defective CD-ROM. "
- "Enabling \"cruft\" mount option.\n");
- sbi->s_cruft = 'y';
- }
-
- /*
* Some dipshit decided to store some other bit of information
- * in the high byte of the file length. Catch this and holler.
- * WARNING: this will make it impossible for a file to be > 16MB
- * on the CDROM.
+ * in the high byte of the file length. Truncate size in case
+ * this CDROM was mounted with the cruft option.
*/
- if (sbi->s_cruft == 'y' &&
- inode->i_size & 0xff000000) {
+ if (sbi->s_cruft == 'y')
inode->i_size &= 0x00ffffff;
- }
if (de->interleave[0]) {
printk("Interleaved files not (yet) supported.\n");
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index c1eb3c536474..72e56d62c373 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -503,7 +503,7 @@ write_out_data:
start_journal_io:
for (i = 0; i < bufs; i++) {
struct buffer_head *bh = wbuf[i];
- set_buffer_locked(bh);
+ lock_buffer(bh);
clear_buffer_dirty(bh);
set_buffer_uptodate(bh);
bh->b_end_io = journal_end_buffer_io_sync;
diff --git a/fs/jffs2/symlink.c b/fs/jffs2/symlink.c
index 46d306cf0df4..d0adaf6fd5df 100644
--- a/fs/jffs2/symlink.c
+++ b/fs/jffs2/symlink.c
@@ -15,43 +15,31 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/fs.h>
+#include <linux/namei.h>
#include "nodelist.h"
-int jffs2_readlink(struct dentry *dentry, char *buffer, int buflen);
-int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd);
+static int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd);
+static void jffs2_put_link(struct dentry *dentry, struct nameidata *nd);
struct inode_operations jffs2_symlink_inode_operations =
{
- .readlink = jffs2_readlink,
+ .readlink = generic_readlink,
.follow_link = jffs2_follow_link,
+ .put_link = jffs2_put_link,
.setattr = jffs2_setattr
};
-int jffs2_readlink(struct dentry *dentry, char *buffer, int buflen)
-{
- unsigned char *kbuf;
- int ret;
-
- kbuf = jffs2_getlink(JFFS2_SB_INFO(dentry->d_inode->i_sb), JFFS2_INODE_INFO(dentry->d_inode));
- if (IS_ERR(kbuf))
- return PTR_ERR(kbuf);
-
- ret = vfs_readlink(dentry, buffer, buflen, kbuf);
- kfree(kbuf);
- return ret;
-}
-
-int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd)
+static int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd)
{
unsigned char *buf;
- int ret;
-
buf = jffs2_getlink(JFFS2_SB_INFO(dentry->d_inode->i_sb), JFFS2_INODE_INFO(dentry->d_inode));
+ nd_set_link(nd, buf);
+ return 0;
+}
- if (IS_ERR(buf))
- return PTR_ERR(buf);
-
- ret = vfs_follow_link(nd, buf);
- kfree(buf);
- return ret;
+static void jffs2_put_link(struct dentry *dentry, struct nameidata *nd)
+{
+ char *s = nd_get_link(nd);
+ if (!IS_ERR(s))
+ kfree(s);
}
diff --git a/fs/jfs/jfs_extent.c b/fs/jfs/jfs_extent.c
index 399572237f35..2068c4746e02 100644
--- a/fs/jfs/jfs_extent.c
+++ b/fs/jfs/jfs_extent.c
@@ -533,7 +533,7 @@ extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno)
nb = nblks = *nblocks;
/* try to allocate blocks */
- while ((rc = dbAlloc(ip, hint, nb, &daddr))) {
+ while ((rc = dbAlloc(ip, hint, nb, &daddr)) != 0) {
/* if something other than an out of space error,
* stop and return this error.
*/
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
index f4ce4609c43b..83dc99db1e5b 100644
--- a/fs/jfs/jfs_logmgr.c
+++ b/fs/jfs/jfs_logmgr.c
@@ -2321,7 +2321,7 @@ int jfsIOWait(void *arg)
DECLARE_WAITQUEUE(wq, current);
spin_lock_irq(&log_redrive_lock);
- while ((bp = log_redrive_list)) {
+ while ((bp = log_redrive_list) != 0) {
log_redrive_list = bp->l_redrive_next;
bp->l_redrive_next = NULL;
spin_unlock_irq(&log_redrive_lock);
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index f48fdeae5eae..7e08dd5025ad 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -2580,7 +2580,7 @@ void txFreelock(struct inode *ip)
TXN_LOCK();
xtlck = (struct tlock *) &jfs_ip->atlhead;
- while ((lid = xtlck->next)) {
+ while ((lid = xtlck->next) != 0) {
tlck = lid_to_tlock(lid);
if (tlck->flag & tlckFREELOCK) {
xtlck->next = tlck->next;
diff --git a/fs/jfs/symlink.c b/fs/jfs/symlink.c
index 6e028d912e62..ef4c07ee92b2 100644
--- a/fs/jfs/symlink.c
+++ b/fs/jfs/symlink.c
@@ -17,23 +17,19 @@
*/
#include <linux/fs.h>
+#include <linux/namei.h>
#include "jfs_incore.h"
#include "jfs_xattr.h"
static int jfs_follow_link(struct dentry *dentry, struct nameidata *nd)
{
char *s = JFS_IP(dentry->d_inode)->i_inline;
- return vfs_follow_link(nd, s);
-}
-
-static int jfs_readlink(struct dentry *dentry, char __user *buffer, int buflen)
-{
- char *s = JFS_IP(dentry->d_inode)->i_inline;
- return vfs_readlink(dentry, buffer, buflen, s);
+ nd_set_link(nd, s);
+ return 0;
}
struct inode_operations jfs_symlink_inode_operations = {
- .readlink = jfs_readlink,
+ .readlink = generic_readlink,
.follow_link = jfs_follow_link,
.setxattr = jfs_setxattr,
.getxattr = jfs_getxattr,
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 67f6a5886dc3..6bf6befe6fa3 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -76,7 +76,7 @@ nlm_lookup_host(int server, struct sockaddr_in *sin,
if (time_after_eq(jiffies, next_gc))
nlm_gc_hosts();
- for (hp = &nlm_hosts[hash]; (host = *hp); hp = &host->h_next) {
+ for (hp = &nlm_hosts[hash]; (host = *hp) != 0; hp = &host->h_next) {
if (host->h_proto != proto)
continue;
if (host->h_version != version)
@@ -145,7 +145,7 @@ nlm_find_client(void)
down(&nlm_host_sema);
for (hash = 0 ; hash < NLM_HOST_NRHASH; hash++) {
struct nlm_host *host, **hp;
- for (hp = &nlm_hosts[hash]; (host = *hp) ; hp = &host->h_next) {
+ for (hp = &nlm_hosts[hash]; (host = *hp) != 0; hp = &host->h_next) {
if (host->h_server &&
host->h_killed == 0) {
nlm_get_host(host);
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index d96319004853..2addc9200763 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -67,7 +67,7 @@ nlmsvc_insert_block(struct nlm_block *block, unsigned long when)
while ((b = *bp) && time_before_eq(b->b_when,when) && b->b_when != NLM_NEVER)
bp = &b->b_next;
} else
- while ((b = *bp))
+ while ((b = *bp) != 0)
bp = &b->b_next;
block->b_queued = 1;
@@ -86,7 +86,7 @@ nlmsvc_remove_block(struct nlm_block *block)
if (!block->b_queued)
return 1;
- for (bp = &nlm_blocked; (b = *bp); bp = &b->b_next) {
+ for (bp = &nlm_blocked; (b = *bp) != 0; bp = &b->b_next) {
if (b == block) {
*bp = block->b_next;
block->b_queued = 0;
@@ -111,7 +111,7 @@ nlmsvc_lookup_block(struct nlm_file *file, struct nlm_lock *lock, int remove)
file, lock->fl.fl_pid,
(long long)lock->fl.fl_start,
(long long)lock->fl.fl_end, lock->fl.fl_type);
- for (head = &nlm_blocked; (block = *head); head = &block->b_next) {
+ for (head = &nlm_blocked; (block = *head) != 0; head = &block->b_next) {
fl = &block->b_call.a_args.lock.fl;
dprintk("lockd: check f=%p pd=%d %Ld-%Ld ty=%d cookie=%x\n",
block->b_file, fl->fl_pid,
@@ -468,7 +468,7 @@ nlmsvc_notify_blocked(struct file_lock *fl)
struct nlm_block **bp, *block;
dprintk("lockd: VFS unblock notification for block %p\n", fl);
- for (bp = &nlm_blocked; (block = *bp); bp = &block->b_next) {
+ for (bp = &nlm_blocked; (block = *bp) != 0; bp = &block->b_next) {
if (nlm_compare_locks(&block->b_call.a_args.lock.fl, fl)) {
nlmsvc_insert_block(block, 0);
svc_wake_up(block->b_daemon);
@@ -653,7 +653,7 @@ nlmsvc_retry_blocked(void)
dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n",
nlm_blocked,
nlm_blocked? nlm_blocked->b_when : 0);
- while ((block = nlm_blocked)) {
+ while ((block = nlm_blocked) != 0) {
if (block->b_when == NLM_NEVER)
break;
if (time_after(block->b_when,jiffies))
diff --git a/fs/lockd/svcshare.c b/fs/lockd/svcshare.c
index ef24965f997b..4943fb7836ce 100644
--- a/fs/lockd/svcshare.c
+++ b/fs/lockd/svcshare.c
@@ -71,7 +71,7 @@ nlmsvc_unshare_file(struct nlm_host *host, struct nlm_file *file,
struct nlm_share *share, **shpp;
struct xdr_netobj *oh = &argp->lock.oh;
- for (shpp = &file->f_shares; (share = *shpp); shpp = &share->s_next) {
+ for (shpp = &file->f_shares; (share = *shpp) != 0; shpp = &share->s_next) {
if (share->s_host == host && nlm_cmp_owner(share, oh)) {
*shpp = share->s_next;
kfree(share);
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index 11dab7f1a008..4b52a2ee41be 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -343,8 +343,9 @@ static struct address_space_operations minix_aops = {
};
static struct inode_operations minix_symlink_inode_operations = {
- .readlink = page_readlink,
- .follow_link = page_follow_link,
+ .readlink = generic_readlink,
+ .follow_link = page_follow_link_light,
+ .put_link = page_put_link,
.getattr = minix_getattr,
};
diff --git a/fs/namei.c b/fs/namei.c
index efaaf1dd1d7d..141a691c96c0 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -395,6 +395,8 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s
return result;
}
+static inline int __vfs_follow_link(struct nameidata *, const char *);
+
/*
* This limits recursive symlink follows to 8, while
* limiting consecutive symlinks to 40.
@@ -405,19 +407,30 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s
static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
{
int err = -ELOOP;
- if (current->link_count >= 5)
+ if (current->link_count >= MAX_NESTED_LINKS)
goto loop;
if (current->total_link_count >= 40)
goto loop;
+ BUG_ON(nd->depth >= MAX_NESTED_LINKS);
cond_resched();
err = security_inode_follow_link(dentry, nd);
if (err)
goto loop;
current->link_count++;
current->total_link_count++;
+ nd->depth++;
touch_atime(nd->mnt, dentry);
+ nd_set_link(nd, NULL);
err = dentry->d_inode->i_op->follow_link(dentry, nd);
+ if (!err) {
+ char *s = nd_get_link(nd);
+ if (s)
+ err = __vfs_follow_link(nd, s);
+ if (dentry->d_inode->i_op->put_link)
+ dentry->d_inode->i_op->put_link(dentry, nd);
+ }
current->link_count--;
+ nd->depth--;
return err;
loop:
path_release(nd);
@@ -587,7 +600,7 @@ int fastcall link_path_walk(const char * name, struct nameidata *nd)
goto return_reval;
inode = nd->dentry->d_inode;
- if (current->link_count)
+ if (nd->depth)
lookup_flags = LOOKUP_FOLLOW;
/* At this point we know we have a real path component. */
@@ -795,6 +808,7 @@ static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
*/
nd_root.last_type = LAST_ROOT;
nd_root.flags = nd->flags;
+ nd_root.depth = 0;
memcpy(&nd_root.intent, &nd->intent, sizeof(nd_root.intent));
read_lock(&current->fs->lock);
nd_root.mnt = mntget(current->fs->rootmnt);
@@ -867,6 +881,7 @@ int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata
nd->last_type = LAST_ROOT; /* if there are only slashes... */
nd->flags = flags;
+ nd->depth = 0;
read_lock(&current->fs->lock);
if (*name=='/') {
@@ -1385,7 +1400,15 @@ do_link:
if (error)
goto exit_dput;
touch_atime(nd->mnt, dentry);
+ nd_set_link(nd, NULL);
error = dentry->d_inode->i_op->follow_link(dentry, nd);
+ if (!error) {
+ char *s = nd_get_link(nd);
+ if (s)
+ error = __vfs_follow_link(nd, s);
+ if (dentry->d_inode->i_op->put_link)
+ dentry->d_inode->i_op->put_link(dentry, nd);
+ }
dput(dentry);
if (error)
return error;
@@ -2166,6 +2189,25 @@ out:
return len;
}
+/*
+ * A helper for ->readlink(). This should be used *ONLY* for symlinks that
+ * have ->follow_link() touching nd only in nd_set_link(). Using (or not
+ * using) it for any given inode is up to filesystem.
+ */
+int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen)
+{
+ struct nameidata nd;
+ int res;
+ nd.depth = 0;
+ res = dentry->d_inode->i_op->follow_link(dentry, &nd);
+ if (!res) {
+ res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd));
+ if (dentry->d_inode->i_op->put_link)
+ dentry->d_inode->i_op->put_link(dentry, &nd);
+ }
+ return res;
+}
+
static inline int
__vfs_follow_link(struct nameidata *nd, const char *link)
{
@@ -2182,7 +2224,7 @@ __vfs_follow_link(struct nameidata *nd, const char *link)
}
res = link_path_walk(link, nd);
out:
- if (current->link_count || res || nd->last_type!=LAST_NORM)
+ if (nd->depth || res || nd->last_type!=LAST_NORM)
return res;
/*
* If it is an iterative symlinks resolution in open_namei() we
@@ -2242,6 +2284,30 @@ int page_readlink(struct dentry *dentry, char __user *buffer, int buflen)
return res;
}
+int page_follow_link_light(struct dentry *dentry, struct nameidata *nd)
+{
+ struct page *page;
+ char *s = page_getlink(dentry, &page);
+ if (!IS_ERR(s)) {
+ nd_set_link(nd, s);
+ s = NULL;
+ }
+ return PTR_ERR(s);
+}
+
+void page_put_link(struct dentry *dentry, struct nameidata *nd)
+{
+ if (!IS_ERR(nd_get_link(nd))) {
+ struct page *page;
+ page = find_get_page(dentry->d_inode->i_mapping, 0);
+ if (!page)
+ BUG();
+ kunmap(page);
+ page_cache_release(page);
+ page_cache_release(page);
+ }
+}
+
int page_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct page *page = NULL;
@@ -2296,8 +2362,9 @@ fail:
}
struct inode_operations page_symlink_inode_operations = {
- .readlink = page_readlink,
- .follow_link = page_follow_link,
+ .readlink = generic_readlink,
+ .follow_link = page_follow_link_light,
+ .put_link = page_put_link,
};
EXPORT_SYMBOL(__user_walk);
@@ -2310,6 +2377,8 @@ EXPORT_SYMBOL(lookup_create);
EXPORT_SYMBOL(lookup_hash);
EXPORT_SYMBOL(lookup_one_len);
EXPORT_SYMBOL(page_follow_link);
+EXPORT_SYMBOL(page_follow_link_light);
+EXPORT_SYMBOL(page_put_link);
EXPORT_SYMBOL(page_readlink);
EXPORT_SYMBOL(page_symlink);
EXPORT_SYMBOL(page_symlink_inode_operations);
@@ -2329,3 +2398,4 @@ EXPORT_SYMBOL(vfs_rename);
EXPORT_SYMBOL(vfs_rmdir);
EXPORT_SYMBOL(vfs_symlink);
EXPORT_SYMBOL(vfs_unlink);
+EXPORT_SYMBOL(generic_readlink);
diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c
index e98505bf803d..100fa7548a42 100644
--- a/fs/partitions/msdos.c
+++ b/fs/partitions/msdos.c
@@ -422,8 +422,8 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
* On the second pass look inside *BSD, Unixware and Solaris partitions.
*/
- state->next = DOS_EXTENDED_PARTITION;
- for (slot = 1 ; slot < DOS_EXTENDED_PARTITION ; slot++, p++) {
+ state->next = 5;
+ for (slot = 1 ; slot <= 4 ; slot++, p++) {
u32 start = START_SECT(p)*sector_size;
u32 size = NR_SECTS(p)*sector_size;
if (!size)
@@ -450,7 +450,7 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
/* second pass - output for each on a separate line */
p = (struct partition *) (0x1be + data);
- for (slot = 1 ; slot < DOS_EXTENDED_PARTITION ; slot++, p++) {
+ for (slot = 1 ; slot <= 4 ; slot++, p++) {
unsigned char id = SYS_IND(p);
int n;
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index bc3e3e0af651..b16a42d5f682 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -17,6 +17,7 @@
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/idr.h>
+#include <linux/namei.h>
#include <asm/uaccess.h>
#include <asm/bitops.h>
@@ -321,21 +322,14 @@ static void release_inode_number(unsigned int inum)
spin_unlock(&proc_inum_lock);
}
-static int
-proc_readlink(struct dentry *dentry, char __user *buffer, int buflen)
-{
- char *s = PDE(dentry->d_inode)->data;
- return vfs_readlink(dentry, buffer, buflen, s);
-}
-
static int proc_follow_link(struct dentry *dentry, struct nameidata *nd)
{
- char *s = PDE(dentry->d_inode)->data;
- return vfs_follow_link(nd, s);
+ nd_set_link(nd, PDE(dentry->d_inode)->data);
+ return 0;
}
static struct inode_operations proc_link_inode_operations = {
- .readlink = proc_readlink,
+ .readlink = generic_readlink,
.follow_link = proc_follow_link,
};
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
index 1f55db799b51..3b1f58300d36 100644
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@ -18,6 +18,7 @@
#include <linux/elfcore.h>
#include <linux/vmalloc.h>
#include <linux/highmem.h>
+#include <linux/init.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -84,8 +85,6 @@ kclist_del(void *addr)
return 0;
}
-extern char saved_command_line[];
-
static size_t get_kcore_size(int *nphdr, size_t *elf_buflen)
{
size_t try, size;
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index a46bd705e93b..415d6ee489b4 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -518,7 +518,6 @@ static int filesystems_read_proc(char *page, char **start, off_t off,
static int cmdline_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
- extern char saved_command_line[];
int len;
len = sprintf(page, "%s\n", saved_command_line);
diff --git a/fs/quota.c b/fs/quota.c
index cf2c31ea8df0..3dd9be6b2377 100644
--- a/fs/quota.c
+++ b/fs/quota.c
@@ -141,7 +141,7 @@ void sync_dquots(struct super_block *sb, int type)
sb->s_qcop->quota_sync(sb, type);
}
else {
- while ((sb = get_super_to_sync(type))) {
+ while ((sb = get_super_to_sync(type)) != 0) {
if (sb->s_qcop->quota_sync)
sb->s_qcop->quota_sync(sb, type);
drop_super(sb);
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index 52d88ae28302..48eb7986166f 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -1389,8 +1389,9 @@ struct inode_operations reiserfs_dir_inode_operations = {
* stuff added
*/
struct inode_operations reiserfs_symlink_inode_operations = {
- .readlink = page_readlink,
- .follow_link = page_follow_link,
+ .readlink = generic_readlink,
+ .follow_link = page_follow_link_light,
+ .put_link = page_put_link,
.setattr = reiserfs_setattr,
.setxattr = reiserfs_setxattr,
.getxattr = reiserfs_getxattr,
diff --git a/fs/smbfs/proto.h b/fs/smbfs/proto.h
index 7266ff5f3d58..e8946c455d8b 100644
--- a/fs/smbfs/proto.h
+++ b/fs/smbfs/proto.h
@@ -87,7 +87,5 @@ extern int smb_request_send_req(struct smb_request *req);
extern int smb_request_send_server(struct smb_sb_info *server);
extern int smb_request_recv(struct smb_sb_info *server);
/* symlink.c */
-extern int smb_read_link(struct dentry *dentry, char *buffer, int len);
extern int smb_symlink(struct inode *inode, struct dentry *dentry, const char *oldname);
-extern int smb_follow_link(struct dentry *dentry, struct nameidata *nd);
extern struct inode_operations smb_link_inode_operations;
diff --git a/fs/smbfs/symlink.c b/fs/smbfs/symlink.c
index 44d6f58b0741..8b069e06433d 100644
--- a/fs/smbfs/symlink.c
+++ b/fs/smbfs/symlink.c
@@ -16,6 +16,7 @@
#include <linux/pagemap.h>
#include <linux/smp_lock.h>
#include <linux/net.h>
+#include <linux/namei.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -26,19 +27,6 @@
#include "smb_debug.h"
#include "proto.h"
-int smb_read_link(struct dentry *dentry, char *buffer, int len)
-{
- char link[256]; /* FIXME: pain ... */
- int r;
- DEBUG1("read link buffer len = %d\n", len);
-
- r = smb_proc_read_link(server_from_dentry(dentry), dentry, link,
- sizeof(link) - 1);
- if (r < 0)
- return -ENOENT;
- return vfs_readlink(dentry, buffer, len, link);
-}
-
int smb_symlink(struct inode *inode, struct dentry *dentry, const char *oldname)
{
DEBUG1("create symlink %s -> %s/%s\n", oldname, DENTRY_PATH(dentry));
@@ -46,24 +34,37 @@ int smb_symlink(struct inode *inode, struct dentry *dentry, const char *oldname)
return smb_proc_symlink(server_from_dentry(dentry), dentry, oldname);
}
-int smb_follow_link(struct dentry *dentry, struct nameidata *nd)
+static int smb_follow_link(struct dentry *dentry, struct nameidata *nd)
{
- char link[256]; /* FIXME: pain ... */
- int len;
+ char *link = __getname();
DEBUG1("followlink of %s/%s\n", DENTRY_PATH(dentry));
- len = smb_proc_read_link(server_from_dentry(dentry), dentry, link,
- sizeof(link) - 1);
- if(len < 0)
- return -ENOENT;
-
- link[len] = 0;
- return vfs_follow_link(nd, link);
+ if (!link) {
+ link = ERR_PTR(-ENOMEM);
+ } else {
+ int len = smb_proc_read_link(server_from_dentry(dentry),
+ dentry, link, PATH_MAX - 1);
+ if (len < 0) {
+ putname(link);
+ link = ERR_PTR(len);
+ } else {
+ link[len] = 0;
+ }
+ }
+ nd_set_link(nd, link);
+ return 0;
}
+static void smb_put_link(struct dentry *dentry, struct nameidata *nd)
+{
+ char *s = nd_get_link(nd);
+ if (!IS_ERR(s))
+ putname(s);
+}
struct inode_operations smb_link_inode_operations =
{
- .readlink = smb_read_link,
+ .readlink = generic_readlink,
.follow_link = smb_follow_link,
+ .put_link = smb_put_link,
};
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index 379d42408f53..960da9b041a4 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -142,8 +142,9 @@ static inline void write3byte(struct sysv_sb_info *sbi,
}
static struct inode_operations sysv_symlink_inode_operations = {
- .readlink = page_readlink,
- .follow_link = page_follow_link,
+ .readlink = generic_readlink,
+ .follow_link = page_follow_link_light,
+ .put_link = page_put_link,
.getattr = sysv_getattr,
};
diff --git a/fs/sysv/symlink.c b/fs/sysv/symlink.c
index 97ea7613782c..ed637db2dcb1 100644
--- a/fs/sysv/symlink.c
+++ b/fs/sysv/symlink.c
@@ -6,20 +6,15 @@
*/
#include "sysv.h"
-
-static int sysv_readlink(struct dentry *dentry, char *buffer, int buflen)
-{
- char *s = (char *)SYSV_I(dentry->d_inode)->i_data;
- return vfs_readlink(dentry, buffer, buflen, s);
-}
+#include <linux/namei.h>
static int sysv_follow_link(struct dentry *dentry, struct nameidata *nd)
{
- char *s = (char *)SYSV_I(dentry->d_inode)->i_data;
- return vfs_follow_link(nd, s);
+ nd_set_link(nd, (char *)SYSV_I(dentry->d_inode)->i_data);
+ return 0;
}
struct inode_operations sysv_fast_symlink_inode_operations = {
- .readlink = sysv_readlink,
+ .readlink = generic_readlink,
.follow_link = sysv_follow_link,
};
diff --git a/fs/ufs/symlink.c b/fs/ufs/symlink.c
index 245225e0da53..a0e49149098f 100644
--- a/fs/ufs/symlink.c
+++ b/fs/ufs/symlink.c
@@ -26,21 +26,17 @@
*/
#include <linux/fs.h>
+#include <linux/namei.h>
#include <linux/ufs_fs.h>
-static int ufs_readlink(struct dentry *dentry, char *buffer, int buflen)
-{
- struct ufs_inode_info *p = UFS_I(dentry->d_inode);
- return vfs_readlink(dentry, buffer, buflen, (char*)p->i_u1.i_symlink);
-}
-
static int ufs_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct ufs_inode_info *p = UFS_I(dentry->d_inode);
- return vfs_follow_link(nd, (char*)p->i_u1.i_symlink);
+ nd_set_link(nd, (char*)p->i_u1.i_symlink);
+ return 0;
}
struct inode_operations ufs_fast_symlink_inode_operations = {
- .readlink = ufs_readlink,
+ .readlink = generic_readlink,
.follow_link = ufs_follow_link,
};
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
index 3795a5c8e8ff..09f81b3793e1 100644
--- a/fs/xfs/Makefile
+++ b/fs/xfs/Makefile
@@ -126,6 +126,7 @@ xfs-$(CONFIG_XFS_TRACE) += xfs_dir2_trace.o
# Objects in linux-2.6/
xfs-y += $(addprefix linux-2.6/, \
+ kmem.o \
xfs_aops.o \
xfs_buf.o \
xfs_file.o \
diff --git a/fs/xfs/linux-2.6/kmem.c b/fs/xfs/linux-2.6/kmem.c
new file mode 100644
index 000000000000..fae717655486
--- /dev/null
+++ b/fs/xfs/linux-2.6/kmem.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/highmem.h>
+#include <linux/swap.h>
+
+#include "time.h"
+#include "kmem.h"
+
+#define MAX_VMALLOCS 6
+#define MAX_SLAB_SIZE 0x20000
+
+
+void *
+kmem_alloc(size_t size, int flags)
+{
+ int retries = 0, lflags = kmem_flags_convert(flags);
+ void *ptr;
+
+ do {
+ if (size < MAX_SLAB_SIZE || retries > MAX_VMALLOCS)
+ ptr = kmalloc(size, lflags);
+ else
+ ptr = __vmalloc(size, lflags, PAGE_KERNEL);
+ if (ptr || (flags & (KM_MAYFAIL|KM_NOSLEEP)))
+ return ptr;
+ if (!(++retries % 100))
+ printk(KERN_ERR "possible deadlock in %s (mode:0x%x)\n",
+ __FUNCTION__, lflags);
+ } while (1);
+}
+
+void *
+kmem_zalloc(size_t size, int flags)
+{
+ void *ptr;
+
+ ptr = kmem_alloc(size, flags);
+ if (ptr)
+ memset((char *)ptr, 0, (int)size);
+ return ptr;
+}
+
+void
+kmem_free(void *ptr, size_t size)
+{
+ if (((unsigned long)ptr < VMALLOC_START) ||
+ ((unsigned long)ptr >= VMALLOC_END)) {
+ kfree(ptr);
+ } else {
+ vfree(ptr);
+ }
+}
+
+void *
+kmem_realloc(void *ptr, size_t newsize, size_t oldsize, int flags)
+{
+ void *new;
+
+ new = kmem_alloc(newsize, flags);
+ if (ptr) {
+ if (new)
+ memcpy(new, ptr,
+ ((oldsize < newsize) ? oldsize : newsize));
+ kmem_free(ptr, oldsize);
+ }
+ return new;
+}
+
+void *
+kmem_zone_alloc(kmem_zone_t *zone, int flags)
+{
+ int retries = 0, lflags = kmem_flags_convert(flags);
+ void *ptr;
+
+ do {
+ ptr = kmem_cache_alloc(zone, lflags);
+ if (ptr || (flags & (KM_MAYFAIL|KM_NOSLEEP)))
+ return ptr;
+ if (!(++retries % 100))
+ printk(KERN_ERR "possible deadlock in %s (mode:0x%x)\n",
+ __FUNCTION__, lflags);
+ } while (1);
+}
+
+void *
+kmem_zone_zalloc(kmem_zone_t *zone, int flags)
+{
+ void *ptr;
+
+ ptr = kmem_zone_alloc(zone, flags);
+ if (ptr)
+ memset((char *)ptr, 0, kmem_cache_size(zone));
+ return ptr;
+}
diff --git a/fs/xfs/linux-2.6/kmem.h b/fs/xfs/linux-2.6/kmem.h
index 13e6dcd595c9..ffe383e14e36 100644
--- a/fs/xfs/linux-2.6/kmem.h
+++ b/fs/xfs/linux-2.6/kmem.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -32,32 +32,34 @@
#ifndef __XFS_SUPPORT_KMEM_H__
#define __XFS_SUPPORT_KMEM_H__
-#include <linux/mm.h>
-#include <linux/highmem.h>
#include <linux/slab.h>
-#include <linux/vmalloc.h>
-
-/*
- * Cutoff point to use vmalloc instead of kmalloc.
- */
-#define MAX_SLAB_SIZE 0x20000
+#include <linux/sched.h>
+#include <linux/mm.h>
/*
- * XFS uses slightly different names for these due to the
- * IRIX heritage.
+ * memory management routines
*/
-#define kmem_zone kmem_cache_s
-#define kmem_zone_t kmem_cache_t
-
#define KM_SLEEP 0x0001
#define KM_NOSLEEP 0x0002
#define KM_NOFS 0x0004
-#define KM_MAYFAIL 0x0005
+#define KM_MAYFAIL 0x0008
+
+#define kmem_zone kmem_cache_s
+#define kmem_zone_t kmem_cache_t
typedef unsigned long xfs_pflags_t;
+#define PFLAGS_TEST_NOIO() (current->flags & PF_NOIO)
#define PFLAGS_TEST_FSTRANS() (current->flags & PF_FSTRANS)
+#define PFLAGS_SET_NOIO() do { \
+ current->flags |= PF_NOIO; \
+} while (0)
+
+#define PFLAGS_CLEAR_NOIO() do { \
+ current->flags &= ~PF_NOIO; \
+} while (0)
+
/* these could be nested, so we save state */
#define PFLAGS_SET_FSTRANS(STATEP) do { \
*(STATEP) = current->flags; \
@@ -79,12 +81,11 @@ typedef unsigned long xfs_pflags_t;
*(NSTATEP) = *(OSTATEP); \
} while (0)
-static __inline unsigned int
-kmem_flags_convert(int flags)
+static __inline unsigned int kmem_flags_convert(int flags)
{
int lflags;
-#if DEBUG
+#ifdef DEBUG
if (unlikely(flags & ~(KM_SLEEP|KM_NOSLEEP|KM_NOFS|KM_MAYFAIL))) {
printk(KERN_WARNING
"XFS: memory allocation with wrong flags (%x)\n", flags);
@@ -100,54 +101,9 @@ kmem_flags_convert(int flags)
/* avoid recusive callbacks to filesystem during transactions */
if (PFLAGS_TEST_FSTRANS() || (flags & KM_NOFS))
lflags &= ~__GFP_FS;
-
- if (!(flags & KM_MAYFAIL))
- lflags |= __GFP_NOFAIL;
- }
-
- return lflags;
-}
-
-static __inline void *
-kmem_alloc(size_t size, int flags)
-{
- if (unlikely(MAX_SLAB_SIZE < size))
- /* Avoid doing filesystem sensitive stuff to get this */
- return __vmalloc(size, kmem_flags_convert(flags), PAGE_KERNEL);
- return kmalloc(size, kmem_flags_convert(flags));
-}
-
-static __inline void *
-kmem_zalloc(size_t size, int flags)
-{
- void *ptr = kmem_alloc(size, flags);
- if (likely(ptr != NULL))
- memset(ptr, 0, size);
- return ptr;
-}
-
-static __inline void
-kmem_free(void *ptr, size_t size)
-{
- if (unlikely((unsigned long)ptr < VMALLOC_START ||
- (unsigned long)ptr >= VMALLOC_END))
- kfree(ptr);
- else
- vfree(ptr);
-}
-
-static __inline void *
-kmem_realloc(void *ptr, size_t newsize, size_t oldsize, int flags)
-{
- void *new = kmem_alloc(newsize, flags);
-
- if (likely(ptr != NULL)) {
- if (likely(new != NULL))
- memcpy(new, ptr, min(oldsize, newsize));
- kmem_free(ptr, oldsize);
}
-
- return new;
+
+ return lflags;
}
static __inline kmem_zone_t *
@@ -156,27 +112,33 @@ kmem_zone_init(int size, char *zone_name)
return kmem_cache_create(zone_name, size, 0, 0, NULL, NULL);
}
-static __inline void *
-kmem_zone_alloc(kmem_zone_t *zone, int flags)
+static __inline void
+kmem_zone_free(kmem_zone_t *zone, void *ptr)
{
- return kmem_cache_alloc(zone, kmem_flags_convert(flags));
+ kmem_cache_free(zone, ptr);
}
-static __inline void *
-kmem_zone_zalloc(kmem_zone_t *zone, int flags)
+static __inline void
+kmem_zone_destroy(kmem_zone_t *zone)
{
- void *ptr = kmem_zone_alloc(zone, flags);
- if (likely(ptr != NULL))
- memset(ptr, 0, kmem_cache_size(zone));
- return ptr;
+ if (zone && kmem_cache_destroy(zone))
+ BUG();
}
-static __inline void
-kmem_zone_free(kmem_zone_t *zone, void *ptr)
+static __inline int
+kmem_zone_shrink(kmem_zone_t *zone)
{
- kmem_cache_free(zone, ptr);
+ return kmem_cache_shrink(zone);
}
+extern void *kmem_zone_zalloc(kmem_zone_t *, int);
+extern void *kmem_zone_alloc(kmem_zone_t *, int);
+
+extern void *kmem_alloc(size_t, int);
+extern void *kmem_realloc(void *, size_t, size_t, int);
+extern void *kmem_zalloc(size_t, int);
+extern void kmem_free(void *, size_t);
+
typedef struct shrinker *kmem_shaker_t;
typedef int (*kmem_shake_func_t)(int, unsigned int);
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 200159fece50..7122efdba491 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -172,28 +172,15 @@ xfs_map_blocks(
struct inode *inode,
loff_t offset,
ssize_t count,
- xfs_iomap_t *iomapp,
+ xfs_iomap_t *mapp,
int flags)
{
vnode_t *vp = LINVFS_GET_VP(inode);
- int error, niomaps = 1;
-
- if (((flags & (BMAPI_DIRECT|BMAPI_SYNC)) == BMAPI_DIRECT) &&
- (offset >= i_size_read(inode)))
- count = max_t(ssize_t, count, XFS_WRITE_IO_LOG);
-retry:
- VOP_BMAP(vp, offset, count, flags, iomapp, &niomaps, error);
- if ((error == EAGAIN) || (error == EIO))
- return -error;
- if (unlikely((flags & (BMAPI_WRITE|BMAPI_DIRECT)) ==
- (BMAPI_WRITE|BMAPI_DIRECT) && niomaps &&
- (iomapp->iomap_flags & IOMAP_DELAY))) {
- flags = BMAPI_ALLOCATE;
- goto retry;
- }
- if (flags & (BMAPI_WRITE|BMAPI_ALLOCATE)) {
+ int error, nmaps = 1;
+
+ VOP_BMAP(vp, offset, count, flags, mapp, &nmaps, error);
+ if (!error && (flags & (BMAPI_WRITE|BMAPI_ALLOCATE)))
VMODIFY(vp);
- }
return -error;
}
@@ -288,7 +275,7 @@ xfs_probe_unwritten_page(
*fsbs = 0;
bh = head = page_buffers(page);
do {
- if (!buffer_unwritten(bh))
+ if (!buffer_unwritten(bh) || !buffer_uptodate(bh))
break;
if (!xfs_offset_to_map(page, iomapp, p_offset))
break;
@@ -681,13 +668,12 @@ xfs_cluster_write(
xfs_iomap_t *iomapp,
struct writeback_control *wbc,
int startio,
- int all_bh)
+ int all_bh,
+ pgoff_t tlast)
{
- pgoff_t tlast;
struct page *page;
- tlast = (iomapp->iomap_offset + iomapp->iomap_bsize) >> PAGE_CACHE_SHIFT;
- for (; tindex < tlast; tindex++) {
+ for (; tindex <= tlast; tindex++) {
page = xfs_probe_delalloc_page(inode, tindex);
if (!page)
break;
@@ -725,17 +711,20 @@ xfs_page_state_convert(
{
struct buffer_head *bh_arr[MAX_BUF_PER_PAGE], *bh, *head;
xfs_iomap_t *iomp, iomap;
- unsigned long p_offset = 0;
- pgoff_t end_index;
loff_t offset;
- unsigned long long end_offset;
+ unsigned long p_offset = 0;
+ __uint64_t end_offset;
+ pgoff_t end_index, last_index, tlast;
int len, err, i, cnt = 0, uptodate = 1;
int flags = startio ? 0 : BMAPI_TRYLOCK;
int page_dirty = 1;
+ int delalloc = 0;
/* Are we off the end of the file ? */
- end_index = i_size_read(inode) >> PAGE_CACHE_SHIFT;
+ offset = i_size_read(inode);
+ end_index = offset >> PAGE_CACHE_SHIFT;
+ last_index = (offset - 1) >> PAGE_CACHE_SHIFT;
if (page->index >= end_index) {
if ((page->index >= end_index + 1) ||
!(i_size_read(inode) & (PAGE_CACHE_SIZE - 1))) {
@@ -769,6 +758,8 @@ xfs_page_state_convert(
* extent state conversion transaction on completion.
*/
if (buffer_unwritten(bh)) {
+ if (!startio)
+ continue;
if (!iomp) {
err = xfs_map_blocks(inode, offset, len, &iomap,
BMAPI_READ|BMAPI_IGNSTATE);
@@ -778,7 +769,7 @@ xfs_page_state_convert(
iomp = xfs_offset_to_map(page, &iomap,
p_offset);
}
- if (iomp && startio) {
+ if (iomp) {
if (!bh->b_end_io) {
err = xfs_map_unwritten(inode, page,
head, bh, p_offset,
@@ -787,7 +778,10 @@ xfs_page_state_convert(
if (err) {
goto error;
}
+ } else {
+ set_bit(BH_Lock, &bh->b_state);
}
+ BUG_ON(!buffer_locked(bh));
bh_arr[cnt++] = bh;
page_dirty = 0;
}
@@ -797,6 +791,7 @@ xfs_page_state_convert(
*/
} else if (buffer_delay(bh)) {
if (!iomp) {
+ delalloc = 1;
err = xfs_map_blocks(inode, offset, len, &iomap,
BMAPI_ALLOCATE | flags);
if (err) {
@@ -871,8 +866,12 @@ xfs_page_state_convert(
xfs_submit_page(page, bh_arr, cnt);
if (iomp) {
+ tlast = (iomp->iomap_offset + iomp->iomap_bsize - 1) >>
+ PAGE_CACHE_SHIFT;
+ if (delalloc && (tlast > last_index))
+ tlast = last_index;
xfs_cluster_write(inode, page->index + 1, iomp, wbc,
- startio, unmapped);
+ startio, unmapped, tlast);
}
return page_dirty;
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index b6dc7d9dca7d..c05024715231 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -65,7 +65,8 @@
*/
STATIC kmem_cache_t *pagebuf_cache;
-STATIC void pagebuf_daemon_wakeup(void);
+STATIC kmem_shaker_t pagebuf_shake;
+STATIC int pagebuf_daemon_wakeup(int, unsigned int);
STATIC void pagebuf_delwri_queue(xfs_buf_t *, int);
STATIC struct workqueue_struct *pagebuf_logio_workqueue;
STATIC struct workqueue_struct *pagebuf_dataio_workqueue;
@@ -384,13 +385,13 @@ _pagebuf_lookup_pages(
* But until all the XFS lowlevel code is revamped to
* handle buffer allocation failures we can't do much.
*/
- if (!(++retries % 100)) {
- printk(KERN_ERR "possibly deadlocking in %s\n",
- __FUNCTION__);
- }
+ if (!(++retries % 100))
+ printk(KERN_ERR
+ "possible deadlock in %s (mode:0x%x)\n",
+ __FUNCTION__, gfp_mask);
XFS_STATS_INC(pb_page_retries);
- pagebuf_daemon_wakeup();
+ pagebuf_daemon_wakeup(0, gfp_mask);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(10);
goto retry;
@@ -1566,11 +1567,20 @@ void
pagebuf_delwri_dequeue(
xfs_buf_t *pb)
{
- PB_TRACE(pb, "delwri_uq", 0);
+ int dequeued = 0;
+
spin_lock(&pbd_delwrite_lock);
- list_del_init(&pb->pb_list);
+ if ((pb->pb_flags & PBF_DELWRI) && !list_empty(&pb->pb_list)) {
+ list_del_init(&pb->pb_list);
+ dequeued = 1;
+ }
pb->pb_flags &= ~PBF_DELWRI;
spin_unlock(&pbd_delwrite_lock);
+
+ if (dequeued)
+ pagebuf_rele(pb);
+
+ PB_TRACE(pb, "delwri_dq", (long)dequeued);
}
STATIC void
@@ -1586,12 +1596,16 @@ STATIC struct task_struct *pagebuf_daemon_task;
STATIC int pagebuf_daemon_active;
STATIC int force_flush;
-STATIC void
-pagebuf_daemon_wakeup(void)
+
+STATIC int
+pagebuf_daemon_wakeup(
+ int priority,
+ unsigned int mask)
{
force_flush = 1;
barrier();
wake_up_process(pagebuf_daemon_task);
+ return 0;
}
STATIC int
@@ -1775,21 +1789,28 @@ pagebuf_init(void)
pagebuf_cache = kmem_cache_create("xfs_buf_t", sizeof(xfs_buf_t), 0,
SLAB_HWCACHE_ALIGN, NULL, NULL);
if (pagebuf_cache == NULL) {
- printk("pagebuf: couldn't init pagebuf cache\n");
+ printk("XFS: couldn't init xfs_buf_t cache\n");
pagebuf_terminate();
return -ENOMEM;
}
- for (i = 0; i < NHASH; i++) {
- spin_lock_init(&pbhash[i].pb_hash_lock);
- INIT_LIST_HEAD(&pbhash[i].pb_hash);
- }
-
#ifdef PAGEBUF_TRACE
pagebuf_trace_buf = ktrace_alloc(PAGEBUF_TRACE_SIZE, KM_SLEEP);
#endif
pagebuf_daemon_start();
+
+ pagebuf_shake = kmem_shake_register(pagebuf_daemon_wakeup);
+ if (pagebuf_shake == NULL) {
+ pagebuf_terminate();
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < NHASH; i++) {
+ spin_lock_init(&pbhash[i].pb_hash_lock);
+ INIT_LIST_HEAD(&pbhash[i].pb_hash);
+ }
+
return 0;
}
@@ -1808,5 +1829,6 @@ pagebuf_terminate(void)
ktrace_free(pagebuf_trace_buf);
#endif
- kmem_cache_destroy(pagebuf_cache);
+ kmem_zone_destroy(pagebuf_cache);
+ kmem_shake_deregister(pagebuf_shake);
}
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h
index f97e6c0cd597..7bebfd65a7fc 100644
--- a/fs/xfs/linux-2.6/xfs_buf.h
+++ b/fs/xfs/linux-2.6/xfs_buf.h
@@ -347,27 +347,15 @@ extern void pagebuf_trace(
#define XFS_BUF_ISSTALE(x) ((x)->pb_flags & XFS_B_STALE)
#define XFS_BUF_SUPER_STALE(x) do { \
XFS_BUF_STALE(x); \
- xfs_buf_undelay(x); \
+ pagebuf_delwri_dequeue(x); \
XFS_BUF_DONE(x); \
} while (0)
#define XFS_BUF_MANAGE PBF_FS_MANAGED
#define XFS_BUF_UNMANAGE(x) ((x)->pb_flags &= ~PBF_FS_MANAGED)
-static inline void xfs_buf_undelay(xfs_buf_t *pb)
-{
- if (pb->pb_flags & PBF_DELWRI) {
- if (pb->pb_list.next != &pb->pb_list) {
- pagebuf_delwri_dequeue(pb);
- pagebuf_rele(pb);
- } else {
- pb->pb_flags &= ~PBF_DELWRI;
- }
- }
-}
-
#define XFS_BUF_DELAYWRITE(x) ((x)->pb_flags |= PBF_DELWRI)
-#define XFS_BUF_UNDELAYWRITE(x) xfs_buf_undelay(x)
+#define XFS_BUF_UNDELAYWRITE(x) pagebuf_delwri_dequeue(x)
#define XFS_BUF_ISDELAYWRITE(x) ((x)->pb_flags & PBF_DELWRI)
#define XFS_BUF_ERROR(x,no) pagebuf_ioerror(x,no)
@@ -500,7 +488,7 @@ static inline int xfs_bawrite(void *mp, xfs_buf_t *bp)
{
bp->pb_fspriv3 = mp;
bp->pb_strat = xfs_bdstrat_cb;
- xfs_buf_undelay(bp);
+ pagebuf_delwri_dequeue(bp);
return pagebuf_iostart(bp, PBF_WRITE | PBF_ASYNC | _PBF_RUN_QUEUES);
}
@@ -540,7 +528,7 @@ static inline int XFS_bwrite(xfs_buf_t *pb)
if (!iowait)
pb->pb_flags |= _PBF_RUN_QUEUES;
- xfs_buf_undelay(pb);
+ pagebuf_delwri_dequeue(pb);
pagebuf_iostrategy(pb);
if (iowait) {
error = pagebuf_iowait(pb);
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index aaa74d256889..e8e02f501013 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -53,6 +53,7 @@
#include "xfs_rw.h"
#include <linux/dcache.h>
+#include <linux/smp_lock.h>
static struct vm_operations_struct linvfs_file_vm_ops;
@@ -440,9 +441,10 @@ linvfs_ioctl(
int error;
vnode_t *vp = LINVFS_GET_VP(inode);
- ASSERT(vp);
+ unlock_kernel();
VOP_IOCTL(vp, inode, filp, 0, cmd, arg, error);
VMODIFY(vp);
+ lock_kernel();
/* NOTE: some of the ioctl's return positive #'s as a
* byte count indicating success, such as
@@ -463,9 +465,11 @@ linvfs_ioctl_invis(
int error;
vnode_t *vp = LINVFS_GET_VP(inode);
+ unlock_kernel();
ASSERT(vp);
VOP_IOCTL(vp, inode, filp, IO_INVIS, cmd, arg, error);
VMODIFY(vp);
+ lock_kernel();
/* NOTE: some of the ioctl's return positive #'s as a
* byte count indicating success, such as
diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.c b/fs/xfs/linux-2.6/xfs_fs_subr.c
index afad97018512..05ebd30ec96f 100644
--- a/fs/xfs/linux-2.6/xfs_fs_subr.c
+++ b/fs/xfs/linux-2.6/xfs_fs_subr.c
@@ -36,7 +36,7 @@
* Stub for no-op vnode operations that return error status.
*/
int
-fs_noerr()
+fs_noerr(void)
{
return 0;
}
@@ -45,7 +45,7 @@ fs_noerr()
* Operation unsupported under this file system.
*/
int
-fs_nosys()
+fs_nosys(void)
{
return ENOSYS;
}
@@ -55,7 +55,7 @@ fs_nosys()
*/
/* ARGSUSED */
void
-fs_noval()
+fs_noval(void)
{
}
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index f43f7c370ca7..a76f59645b64 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -67,6 +67,7 @@
#include "xfs_utils.h"
#include <linux/xattr.h>
+#include <linux/namei.h>
/*
@@ -419,13 +420,16 @@ linvfs_follow_link(
ASSERT(nd);
link = (char *)kmalloc(MAXNAMELEN+1, GFP_KERNEL);
- if (!link)
- return -ENOMEM;
+ if (!link) {
+ nd_set_link(nd, ERR_PTR(-ENOMEM));
+ return 0;
+ }
uio = (uio_t *)kmalloc(sizeof(uio_t), GFP_KERNEL);
if (!uio) {
kfree(link);
- return -ENOMEM;
+ nd_set_link(nd, ERR_PTR(-ENOMEM));
+ return 0;
}
vp = LINVFS_GET_VP(dentry->d_inode);
@@ -441,18 +445,22 @@ linvfs_follow_link(
VOP_READLINK(vp, uio, 0, NULL, error);
if (error) {
- kfree(uio);
kfree(link);
- return -error;
+ link = ERR_PTR(-error);
+ } else {
+ link[MAXNAMELEN - uio->uio_resid] = '\0';
}
-
- link[MAXNAMELEN - uio->uio_resid] = '\0';
kfree(uio);
- /* vfs_follow_link returns (-) errors */
- error = vfs_follow_link(nd, link);
- kfree(link);
- return error;
+ nd_set_link(nd, link);
+ return 0;
+}
+
+static void linvfs_put_link(struct dentry *dentry, struct nameidata *nd)
+{
+ char *s = nd_get_link(nd);
+ if (!IS_ERR(s))
+ kfree(s);
}
#ifdef CONFIG_XFS_POSIX_ACL
@@ -692,6 +700,7 @@ struct inode_operations linvfs_dir_inode_operations = {
struct inode_operations linvfs_symlink_inode_operations = {
.readlink = linvfs_readlink,
.follow_link = linvfs_follow_link,
+ .put_link = linvfs_put_link,
.permission = linvfs_permission,
.getattr = linvfs_getattr,
.setattr = linvfs_setattr,
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index e7825df99003..00818cd70e7d 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -76,7 +76,8 @@
STATIC struct quotactl_ops linvfs_qops;
STATIC struct super_operations linvfs_sops;
STATIC struct export_operations linvfs_export_ops;
-STATIC kmem_cache_t * linvfs_inode_cachep;
+STATIC kmem_zone_t *linvfs_inode_zone;
+STATIC kmem_shaker_t xfs_inode_shaker;
STATIC struct xfs_mount_args *
xfs_args_allocate(
@@ -289,7 +290,7 @@ linvfs_alloc_inode(
{
vnode_t *vp;
- vp = (vnode_t *)kmem_cache_alloc(linvfs_inode_cachep,
+ vp = (vnode_t *)kmem_cache_alloc(linvfs_inode_zone,
kmem_flags_convert(KM_SLEEP));
if (!vp)
return NULL;
@@ -300,7 +301,20 @@ STATIC void
linvfs_destroy_inode(
struct inode *inode)
{
- kmem_cache_free(linvfs_inode_cachep, LINVFS_GET_VP(inode));
+ kmem_cache_free(linvfs_inode_zone, LINVFS_GET_VP(inode));
+}
+
+int
+xfs_inode_shake(
+ int priority,
+ unsigned int gfp_mask)
+{
+ int pages;
+
+
+ pages = kmem_zone_shrink(linvfs_inode_zone);
+ pages += kmem_zone_shrink(xfs_inode_zone);
+ return pages;
}
STATIC void
@@ -319,12 +333,12 @@ init_once(
STATIC int
init_inodecache( void )
{
- linvfs_inode_cachep = kmem_cache_create("linvfs_icache",
+ linvfs_inode_zone = kmem_cache_create("linvfs_icache",
sizeof(vnode_t), 0,
SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
- if (linvfs_inode_cachep == NULL)
+ if (linvfs_inode_zone == NULL)
return -ENOMEM;
return 0;
}
@@ -332,7 +346,7 @@ init_inodecache( void )
STATIC void
destroy_inodecache( void )
{
- if (kmem_cache_destroy(linvfs_inode_cachep))
+ if (kmem_cache_destroy(linvfs_inode_zone))
printk(KERN_WARNING "%s: cache still in use!\n", __FUNCTION__);
}
@@ -835,15 +849,24 @@ init_xfs_fs( void )
vn_init();
xfs_init();
uuid_init();
- vfs_initdmapi();
vfs_initquota();
+ xfs_inode_shaker = kmem_shake_register(xfs_inode_shake);
+ if (!xfs_inode_shaker) {
+ error = -ENOMEM;
+ goto undo_shaker;
+ }
+
error = register_filesystem(&xfs_fs_type);
if (error)
goto undo_register;
+ XFS_DM_INIT(&xfs_fs_type);
return 0;
undo_register:
+ kmem_shake_deregister(xfs_inode_shaker);
+
+undo_shaker:
pagebuf_terminate();
undo_pagebuf:
@@ -857,8 +880,9 @@ STATIC void __exit
exit_xfs_fs( void )
{
vfs_exitquota();
- vfs_exitdmapi();
+ XFS_DM_EXIT(&xfs_fs_type);
unregister_filesystem(&xfs_fs_type);
+ kmem_shake_deregister(xfs_inode_shaker);
xfs_cleanup();
pagebuf_terminate();
destroy_inodecache();
diff --git a/fs/xfs/linux-2.6/xfs_super.h b/fs/xfs/linux-2.6/xfs_super.h
index 0d3703db3cee..866c7ad75f92 100644
--- a/fs/xfs/linux-2.6/xfs_super.h
+++ b/fs/xfs/linux-2.6/xfs_super.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -92,6 +92,12 @@ extern void xfs_qm_exit(void);
# define XFS_TRACE_STRING
#endif
+#ifdef CONFIG_XFS_DMAPI
+# define XFS_DMAPI_STRING "dmapi support, "
+#else
+# define XFS_DMAPI_STRING
+#endif
+
#ifdef DEBUG
# define XFS_DBG_STRING "debug"
#else
@@ -103,6 +109,7 @@ extern void xfs_qm_exit(void);
XFS_REALTIME_STRING \
XFS_BIGFS_STRING \
XFS_TRACE_STRING \
+ XFS_DMAPI_STRING \
XFS_DBG_STRING /* DBG must be last */
#define LINVFS_GET_VFS(s) \
diff --git a/fs/xfs/xfs.h b/fs/xfs/xfs.h
index 809bee71dd72..7e276dcaf4dc 100644
--- a/fs/xfs/xfs.h
+++ b/fs/xfs/xfs.h
@@ -35,5 +35,6 @@
#include <linux-2.6/xfs_linux.h>
#include <xfs_fs.h>
+#include <xfs_macros.h>
#endif /* __XFS_H__ */
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index ad9f5de3ae57..b800f8f4e058 100644
--- a/fs/xfs/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -231,8 +231,6 @@ xfs_acl_vget(
int flags = 0;
VN_HOLD(vp);
- if ((error = _MAC_VACCESS(vp, NULL, VREAD)))
- goto out;
if(size) {
if (!(_ACL_ALLOC(xfs_acl))) {
error = ENOMEM;
@@ -395,8 +393,6 @@ xfs_acl_allow_set(
return ENOTDIR;
if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
return EROFS;
- if ((error = _MAC_VACCESS(vp, NULL, VWRITE)))
- return error;
va.va_mask = XFS_AT_UID;
VOP_GETATTR(vp, &va, 0, NULL, error);
if (error)
diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h
index ab15998d469f..35e56b7f00ab 100644
--- a/fs/xfs/xfs_acl.h
+++ b/fs/xfs/xfs_acl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2001-2004 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -61,14 +61,17 @@ typedef struct xfs_acl {
#define SGI_ACL_DEFAULT_SIZE (sizeof(SGI_ACL_DEFAULT)-1)
-#ifdef __KERNEL__
-
#ifdef CONFIG_XFS_POSIX_ACL
struct vattr;
struct vnode;
struct xfs_inode;
+extern struct kmem_zone *xfs_acl_zone;
+#define xfs_acl_zone_init(zone, name) \
+ (zone) = kmem_zone_init(sizeof(xfs_acl_t), name)
+#define xfs_acl_zone_destroy(zone) kmem_cache_destroy(zone)
+
extern int xfs_acl_inherit(struct vnode *, struct vattr *, xfs_acl_t *);
extern int xfs_acl_iaccess(struct xfs_inode *, mode_t, cred_t *);
extern int xfs_acl_get(struct vnode *, xfs_acl_t *, xfs_acl_t *);
@@ -80,17 +83,10 @@ extern int xfs_acl_vset(struct vnode *, void *, size_t, int);
extern int xfs_acl_vget(struct vnode *, void *, size_t, int);
extern int xfs_acl_vremove(struct vnode *vp, int);
-extern struct kmem_zone *xfs_acl_zone;
-
#define _ACL_TYPE_ACCESS 1
#define _ACL_TYPE_DEFAULT 2
#define _ACL_PERM_INVALID(perm) ((perm) & ~(ACL_READ|ACL_WRITE|ACL_EXECUTE))
-#define _ACL_DECL(a) xfs_acl_t *(a) = NULL
-#define _ACL_ALLOC(a) ((a) = kmem_zone_alloc(xfs_acl_zone, KM_SLEEP))
-#define _ACL_FREE(a) ((a)? kmem_zone_free(xfs_acl_zone, (a)) : 0)
-#define _ACL_ZONE_INIT(z,name) ((z) = kmem_zone_init(sizeof(xfs_acl_t), name))
-#define _ACL_ZONE_DESTROY(z) (kmem_cache_destroy(z))
#define _ACL_INHERIT(c,v,d) (xfs_acl_inherit(c,v,d))
#define _ACL_GET_ACCESS(pv,pa) (xfs_acl_vtoacl(pv,pa,NULL) == 0)
#define _ACL_GET_DEFAULT(pv,pd) (xfs_acl_vtoacl(pv,NULL,pd) == 0)
@@ -98,17 +94,19 @@ extern struct kmem_zone *xfs_acl_zone;
#define _ACL_DEFAULT_EXISTS xfs_acl_vhasacl_default
#define _ACL_XFS_IACCESS(i,m,c) (XFS_IFORK_Q(i) ? xfs_acl_iaccess(i,m,c) : -1)
+#define _ACL_ALLOC(a) ((a) = kmem_zone_alloc(xfs_acl_zone, KM_SLEEP))
+#define _ACL_FREE(a) ((a)? kmem_zone_free(xfs_acl_zone, (a)) : 0)
+
#else
+#define xfs_acl_zone_init(zone,name)
+#define xfs_acl_zone_destroy(zone)
#define xfs_acl_vset(v,p,sz,t) (-EOPNOTSUPP)
#define xfs_acl_vget(v,p,sz,t) (-EOPNOTSUPP)
#define xfs_acl_vremove(v,t) (-EOPNOTSUPP)
#define xfs_acl_vhasacl_access(v) (0)
#define xfs_acl_vhasacl_default(v) (0)
-#define _ACL_DECL(a) ((void)0)
#define _ACL_ALLOC(a) (1) /* successfully allocate nothing */
#define _ACL_FREE(a) ((void)0)
-#define _ACL_ZONE_INIT(z,name) ((void)0)
-#define _ACL_ZONE_DESTROY(z) ((void)0)
#define _ACL_INHERIT(c,v,d) (0)
#define _ACL_GET_ACCESS(pv,pa) (0)
#define _ACL_GET_DEFAULT(pv,pd) (0)
@@ -117,6 +115,4 @@ extern struct kmem_zone *xfs_acl_zone;
#define _ACL_XFS_IACCESS(i,m,c) (-1)
#endif
-#endif /* __KERNEL__ */
-
#endif /* __XFS_ACL_H__ */
diff --git a/fs/xfs/xfs_arch.h b/fs/xfs/xfs_arch.h
index 3d65fe3c6583..3c7a90bfb0e3 100644
--- a/fs/xfs/xfs_arch.h
+++ b/fs/xfs/xfs_arch.h
@@ -157,11 +157,11 @@
/* does not return a value */
#define INT_MOD_EXPR(reference,arch,code) \
- (void)(((arch) == ARCH_NOCONVERT) \
+ (((arch) == ARCH_NOCONVERT) \
? \
- ((reference) code) \
+ (void)((reference) code) \
: \
- ( \
+ (void)( \
(reference) = INT_GET((reference),arch) , \
((reference) code), \
INT_SET(reference, arch, reference) \
@@ -187,10 +187,10 @@
/* does not return a value */
#define INT_COPY(dst,src,arch) \
- (void)( \
+ ( \
((sizeof(dst) == sizeof(src)) || ((arch) == ARCH_NOCONVERT)) \
? \
- ((dst) = (src)) \
+ (void)((dst) = (src)) \
: \
INT_SET(dst, arch, INT_GET(src, arch)) \
)
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index 8eb321eec512..f1ccb5890665 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -2149,8 +2149,8 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)
/*
* If the "remote" value is in the cache, remove it.
*/
- /* bp = incore(mp->m_dev, dblkno, blkcnt, 1); */
- bp = xfs_incore(mp->m_ddev_targp, dblkno, blkcnt, 1);
+ bp = xfs_incore(mp->m_ddev_targp, dblkno, blkcnt,
+ XFS_INCORE_TRYLOCK);
if (bp) {
XFS_BUF_STALE(bp);
XFS_BUF_UNDELAYWRITE(bp);
diff --git a/fs/xfs/xfs_bit.c b/fs/xfs/xfs_bit.c
index ec12a13d8fac..a20a6c3dc13e 100644
--- a/fs/xfs/xfs_bit.c
+++ b/fs/xfs/xfs_bit.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -154,14 +154,17 @@ int
xfs_lowbit64(
__uint64_t v)
{
- int n;
- n = ffs((unsigned)v);
- if (n <= 0) {
- n = ffs(v >> 32);
- if (n >= 0)
- n+=32;
+ __uint32_t w = (__uint32_t)v;
+ int n = 0;
+
+ if (w) { /* lower bits */
+ n = ffs(w);
+ } else { /* upper bits */
+ w = (__uint32_t)(v >> 32);
+ if (w && (n = ffs(w)))
+ n += 32;
}
- return (n <= 0) ? n : n-1;
+ return n - 1;
}
/*
@@ -171,10 +174,11 @@ int
xfs_highbit64(
__uint64_t v)
{
- __uint32_t h = v >> 32;
+ __uint32_t h = (__uint32_t)(v >> 32);
+
if (h)
return xfs_highbit32(h) + 32;
- return xfs_highbit32((__u32)v);
+ return xfs_highbit32((__uint32_t)v);
}
diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h
index 53838b48b7d8..55ae3e67d245 100644
--- a/fs/xfs/xfs_dmapi.h
+++ b/fs/xfs/xfs_dmapi.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -199,7 +199,14 @@ typedef enum {
extern struct bhv_vfsops xfs_dmops;
-extern int dmapi_init(void);
-extern void dmapi_uninit(void);
+#ifdef CONFIG_XFS_DMAPI
+void xfs_dm_init(struct file_system_type *);
+void xfs_dm_exit(struct file_system_type *);
+#define XFS_DM_INIT(fstype) xfs_dm_init(fstype)
+#define XFS_DM_EXIT(fstype) xfs_dm_exit(fstype)
+#else
+#define XFS_DM_INIT(fstype)
+#define XFS_DM_EXIT(fstype)
+#endif
#endif /* __XFS_DMAPI_H__ */
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index ab973fe102a2..8a821fed5a8c 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1140,8 +1140,7 @@ xfs_ialloc(
* Call the space management code to pick
* the on-disk inode to be allocated.
*/
- ASSERT(pip != NULL);
- error = xfs_dialloc(tp, pip ? pip->i_ino : 0, mode, okalloc,
+ error = xfs_dialloc(tp, pip->i_ino, mode, okalloc,
ialloc_context, call_again, &ino);
if (error != 0) {
return error;
@@ -3696,12 +3695,6 @@ xfs_iaccess(
mode_t orgmode = mode;
struct inode *inode = LINVFS_GET_IP(XFS_ITOV(ip));
- /*
- * Verify that the MAC policy allows the requested access.
- */
- if ((error = _MAC_XFS_IACCESS(ip, mode, cr)))
- return XFS_ERROR(error);
-
if (mode & S_IWUSR) {
umode_t imode = inode->i_mode;
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 13abdd55ee90..f606073adf6b 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -459,8 +459,8 @@ xfs_inode_t *xfs_bhvtoi(struct bhv_desc *bhvp);
* directory, group of new file is set to that of the parent, and
* new subdirectory gets S_ISGID bit from parent.
*/
-#define XFS_INHERIT_GID(pip, vfsp) ((pip) != NULL && \
- (((vfsp)->vfs_flag & VFS_GRPID) || ((pip)->i_d.di_mode & S_ISGID)))
+#define XFS_INHERIT_GID(pip, vfsp) \
+ (((vfsp)->vfs_flag & VFS_GRPID) || ((pip)->i_d.di_mode & S_ISGID))
/*
* xfs_iget.c prototypes.
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 1ee2bbf6362a..f51ec12968d0 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -424,10 +424,6 @@ typedef struct xfs_mount {
*/
#define XFS_READIO_LOG_LARGE 16
#define XFS_WRITEIO_LOG_LARGE 16
-/*
- * Default allocation size
- */
-#define XFS_WRITE_IO_LOG 16
/*
* Max and min values for UIO and mount-option defined I/O sizes;
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 524d8b211e8d..c130d4259fec 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -100,7 +100,9 @@ STATIC int
xfs_lowbit32(
__uint32_t v)
{
- return ffs(v)-1;
+ if (v)
+ return ffs(v) - 1;
+ return -1;
}
/*
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index be1188165660..114c53a766a2 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -118,7 +118,7 @@ xfs_init(void)
xfs_ili_zone = kmem_zone_init(sizeof(xfs_inode_log_item_t), "xfs_ili");
xfs_chashlist_zone = kmem_zone_init(sizeof(xfs_chashlist_t),
"xfs_chashlist");
- _ACL_ZONE_INIT(xfs_acl_zone, "xfs_acl");
+ xfs_acl_zone_init(xfs_acl_zone, "xfs_acl");
/*
* Allocate global trace buffers.
@@ -170,6 +170,7 @@ xfs_cleanup(void)
xfs_cleanup_procfs();
xfs_sysctl_unregister();
xfs_refcache_destroy();
+ xfs_acl_zone_destroy(xfs_acl_zone);
#ifdef XFS_DIR2_TRACE
ktrace_free(xfs_dir2_trace_buf);
@@ -202,7 +203,6 @@ xfs_cleanup(void)
kmem_cache_destroy(xfs_ifork_zone);
kmem_cache_destroy(xfs_ili_zone);
kmem_cache_destroy(xfs_chashlist_zone);
- _ACL_ZONE_DESTROY(xfs_acl_zone);
}
/*
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index ab9b4d18113c..72a04a11cec4 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -411,11 +411,6 @@ xfs_setattr(
xfs_ilock(ip, lock_flags);
- if (_MAC_XFS_IACCESS(ip, MACWRITE, credp)) {
- code = XFS_ERROR(EACCES);
- goto error_return;
- }
-
/* boolean: are we the file owner? */
file_owner = (current_fsuid(credp) == ip->i_d.di_uid);
@@ -2446,11 +2441,6 @@ xfs_remove(
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
}
- if ((error = _MAC_XFS_IACCESS(ip, MACWRITE, credp))) {
- REMOVE_DEBUG_TRACE(__LINE__);
- goto error_return;
- }
-
/*
* Entry must exist since we did a lookup in xfs_lock_dir_and_entry.
*/
@@ -2536,8 +2526,6 @@ xfs_remove(
error1:
xfs_bmap_cancel(&free_list);
cancel_flags |= XFS_TRANS_ABORT;
-
- error_return:
xfs_trans_cancel(tp, cancel_flags);
goto std_return;
@@ -3105,10 +3093,6 @@ xfs_rmdir(
ITRACE(cdp);
xfs_trans_ijoin(tp, cdp, XFS_ILOCK_EXCL);
- if ((error = _MAC_XFS_IACCESS(cdp, MACWRITE, credp))) {
- goto error_return;
- }
-
ASSERT(cdp->i_d.di_nlink >= 2);
if (cdp->i_d.di_nlink != 2) {
error = XFS_ERROR(ENOTEMPTY);