diff options
Diffstat (limited to 'fs')
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(¤t->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(¤t->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); |
