summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/9p/error.c1
-rw-r--r--fs/9p/trans_sock.c3
-rw-r--r--fs/9p/v9fs.c6
-rw-r--r--fs/9p/vfs_inode.c10
-rw-r--r--fs/Kconfig1
-rw-r--r--fs/affs/file.c18
-rw-r--r--fs/affs/super.c16
-rw-r--r--fs/afs/file.c33
-rw-r--r--fs/afs/inode.c2
-rw-r--r--fs/afs/internal.h1
-rw-r--r--fs/aio.c31
-rw-r--r--fs/autofs/waitq.c6
-rw-r--r--fs/autofs4/inode.c6
-rw-r--r--fs/autofs4/waitq.c6
-rw-r--r--fs/befs/linuxvfs.c20
-rw-r--r--fs/binfmt_elf.c3
-rw-r--r--fs/binfmt_elf_fdpic.c15
-rw-r--r--fs/buffer.c6
-rw-r--r--fs/cifs/asn1.c3
-rw-r--r--fs/cifs/connect.c81
-rw-r--r--fs/cifs/link.c23
-rw-r--r--fs/cifs/misc.c15
-rw-r--r--fs/cifs/xattr.c15
-rw-r--r--fs/compat_ioctl.c3
-rw-r--r--fs/dcache.c10
-rw-r--r--fs/devfs/base.c6
-rw-r--r--fs/dquot.c1
-rw-r--r--fs/exec.c4
-rw-r--r--fs/ext2/acl.c6
-rw-r--r--fs/file_table.c4
-rw-r--r--fs/freevxfs/vxfs_extern.h4
-rw-r--r--fs/freevxfs/vxfs_inode.c11
-rw-r--r--fs/fs-writeback.c7
-rw-r--r--fs/fuse/dev.c7
-rw-r--r--fs/fuse/dir.c172
-rw-r--r--fs/fuse/file.c132
-rw-r--r--fs/fuse/fuse_i.h17
-rw-r--r--fs/hostfs/hostfs_kern.c3
-rw-r--r--fs/hpfs/dnode.c8
-rw-r--r--fs/hpfs/super.c10
-rw-r--r--fs/isofs/inode.c12
-rw-r--r--fs/jbd/commit.c6
-rw-r--r--fs/jbd/recovery.c4
-rw-r--r--fs/jbd/transaction.c9
-rw-r--r--fs/jffs/intrep.c18
-rw-r--r--fs/jffs2/readinode.c8
-rw-r--r--fs/jffs2/wbuf.c3
-rw-r--r--fs/lockd/clntproc.c3
-rw-r--r--fs/lockd/svcsubs.c43
-rw-r--r--fs/mbcache.c3
-rw-r--r--fs/namei.c2
-rw-r--r--fs/nfs/delegation.c41
-rw-r--r--fs/nfs/delegation.h1
-rw-r--r--fs/nfs/dir.c3
-rw-r--r--fs/nfs/direct.c10
-rw-r--r--fs/nfs/inode.c22
-rw-r--r--fs/nfs/nfs4_fs.h4
-rw-r--r--fs/nfs/nfs4proc.c120
-rw-r--r--fs/nfs/nfs4state.c94
-rw-r--r--fs/nfs/read.c4
-rw-r--r--fs/nfs/unlink.c3
-rw-r--r--fs/nfs/write.c14
-rw-r--r--fs/nfsd/export.c6
-rw-r--r--fs/nfsd/nfs3xdr.c3
-rw-r--r--fs/nfsd/nfs4xdr.c9
-rw-r--r--fs/nfsd/nfscache.c3
-rw-r--r--fs/nfsd/nfsctl.c98
-rw-r--r--fs/nfsd/nfssvc.c80
-rw-r--r--fs/nfsd/vfs.c9
-rw-r--r--fs/open.c19
-rw-r--r--fs/openpromfs/inode.c3
-rw-r--r--fs/partitions/ibm.c15
-rw-r--r--fs/quota.c1
-rw-r--r--fs/smbfs/request.c3
-rw-r--r--fs/smbfs/symlink.c4
-rw-r--r--fs/super.c2
-rw-r--r--fs/udf/udf_sb.h3
-rw-r--r--fs/ufs/super.c14
-rw-r--r--fs/xattr.c9
-rw-r--r--fs/xfs/linux-2.6/kmem.h4
80 files changed, 843 insertions, 595 deletions
diff --git a/fs/9p/error.c b/fs/9p/error.c
index fee5d19..834cb17 100644
--- a/fs/9p/error.c
+++ b/fs/9p/error.c
@@ -33,6 +33,7 @@
#include <linux/list.h>
#include <linux/jhash.h>
+#include <linux/string.h>
#include "debug.h"
#include "error.h"
diff --git a/fs/9p/trans_sock.c b/fs/9p/trans_sock.c
index 01e26f0..a93c2bf 100644
--- a/fs/9p/trans_sock.c
+++ b/fs/9p/trans_sock.c
@@ -269,8 +269,7 @@ static void v9fs_sock_close(struct v9fs_transport *trans)
dprintk(DEBUG_TRANS, "socket closed\n");
}
- if (ts)
- kfree(ts);
+ kfree(ts);
trans->priv = NULL;
}
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index 82303f3..418c374 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -266,7 +266,7 @@ v9fs_session_init(struct v9fs_session_info *v9ses,
v9ses->remotename = __getname();
if (!v9ses->remotename) {
- putname(v9ses->name);
+ __putname(v9ses->name);
return -ENOMEM;
}
@@ -411,8 +411,8 @@ void v9fs_session_close(struct v9fs_session_info *v9ses)
if (v9ses->transport)
v9ses->transport->close(v9ses->transport);
- putname(v9ses->name);
- putname(v9ses->remotename);
+ __putname(v9ses->name);
+ __putname(v9ses->remotename);
}
/**
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 2b696ae..be72881 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -1105,7 +1105,7 @@ static int v9fs_vfs_readlink(struct dentry *dentry, char __user * buffer,
}
}
- putname(link);
+ __putname(link);
return retval;
}
@@ -1129,7 +1129,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd)
len = v9fs_readlink(dentry, link, strlen(link));
if (len < 0) {
- putname(link);
+ __putname(link);
link = ERR_PTR(len);
} else
link[len] = 0;
@@ -1152,7 +1152,7 @@ static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void
dprintk(DEBUG_VFS, " %s %s\n", dentry->d_name.name, s);
if (!IS_ERR(s))
- putname(s);
+ __putname(s);
}
/**
@@ -1228,7 +1228,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
FreeMem:
kfree(mistat);
kfree(fcall);
- putname(symname);
+ __putname(symname);
return retval;
}
@@ -1319,7 +1319,7 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
FreeMem:
kfree(mistat);
kfree(fcall);
- putname(symname);
+ __putname(symname);
return retval;
}
diff --git a/fs/Kconfig b/fs/Kconfig
index 01a2952..7cf36ca 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -898,6 +898,7 @@ config AFFS_FS
config HFS_FS
tristate "Apple Macintosh file system support (EXPERIMENTAL)"
depends on EXPERIMENTAL
+ select NLS
help
If you say Y here, you will be able to mount Macintosh-formatted
floppy disks and hard drive partitions with full read-write access.
diff --git a/fs/affs/file.c b/fs/affs/file.c
index 6744924..f72fb77 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -22,14 +22,13 @@ static int affs_grow_extcache(struct inode *inode, u32 lc_idx);
static struct buffer_head *affs_alloc_extblock(struct inode *inode, struct buffer_head *bh, u32 ext);
static inline struct buffer_head *affs_get_extblock(struct inode *inode, u32 ext);
static struct buffer_head *affs_get_extblock_slow(struct inode *inode, u32 ext);
-static ssize_t affs_file_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos);
static int affs_file_open(struct inode *inode, struct file *filp);
static int affs_file_release(struct inode *inode, struct file *filp);
struct file_operations affs_file_operations = {
.llseek = generic_file_llseek,
.read = generic_file_read,
- .write = affs_file_write,
+ .write = generic_file_write,
.mmap = generic_file_mmap,
.open = affs_file_open,
.release = affs_file_release,
@@ -473,21 +472,6 @@ affs_getemptyblk_ino(struct inode *inode, int block)
return ERR_PTR(err);
}
-static ssize_t
-affs_file_write(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- ssize_t retval;
-
- retval = generic_file_write (file, buf, count, ppos);
- if (retval >0) {
- struct inode *inode = file->f_dentry->d_inode;
- inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
- mark_inode_dirty(inode);
- }
- return retval;
-}
-
static int
affs_do_readpage_ofs(struct file *file, struct page *page, unsigned from, unsigned to)
{
diff --git a/fs/affs/super.c b/fs/affs/super.c
index 9c30807..aaec015 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -35,8 +35,7 @@ affs_put_super(struct super_block *sb)
mark_buffer_dirty(sbi->s_root_bh);
}
- if (sbi->s_prefix)
- kfree(sbi->s_prefix);
+ kfree(sbi->s_prefix);
affs_free_bitmap(sb);
affs_brelse(sbi->s_root_bh);
kfree(sbi);
@@ -198,10 +197,9 @@ parse_options(char *options, uid_t *uid, gid_t *gid, int *mode, int *reserved, s
*mount_opts |= SF_MUFS;
break;
case Opt_prefix:
- if (*prefix) { /* Free any previous prefix */
- kfree(*prefix);
- *prefix = NULL;
- }
+ /* Free any previous prefix */
+ kfree(*prefix);
+ *prefix = NULL;
*prefix = match_strdup(&args[0]);
if (!*prefix)
return 0;
@@ -462,11 +460,9 @@ got_root:
out_error:
if (root_inode)
iput(root_inode);
- if (sbi->s_bitmap)
- kfree(sbi->s_bitmap);
+ kfree(sbi->s_bitmap);
affs_brelse(root_bh);
- if (sbi->s_prefix)
- kfree(sbi->s_prefix);
+ kfree(sbi->s_prefix);
kfree(sbi);
sb->s_fs_info = NULL;
return -EINVAL;
diff --git a/fs/afs/file.c b/fs/afs/file.c
index 4975c9c..150b192 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -31,24 +31,10 @@ static int afs_file_readpage(struct file *file, struct page *page);
static int afs_file_invalidatepage(struct page *page, unsigned long offset);
static int afs_file_releasepage(struct page *page, gfp_t gfp_flags);
-static ssize_t afs_file_write(struct file *file, const char __user *buf,
- size_t size, loff_t *off);
-
struct inode_operations afs_file_inode_operations = {
.getattr = afs_inode_getattr,
};
-struct file_operations afs_file_file_operations = {
- .read = generic_file_read,
- .write = afs_file_write,
- .mmap = generic_file_mmap,
-#if 0
- .open = afs_file_open,
- .release = afs_file_release,
- .fsync = afs_file_fsync,
-#endif
-};
-
struct address_space_operations afs_fs_aops = {
.readpage = afs_file_readpage,
.sync_page = block_sync_page,
@@ -59,22 +45,6 @@ struct address_space_operations afs_fs_aops = {
/*****************************************************************************/
/*
- * AFS file write
- */
-static ssize_t afs_file_write(struct file *file, const char __user *buf,
- size_t size, loff_t *off)
-{
- struct afs_vnode *vnode;
-
- vnode = AFS_FS_I(file->f_dentry->d_inode);
- if (vnode->flags & AFS_VNODE_DELETED)
- return -ESTALE;
-
- return -EIO;
-} /* end afs_file_write() */
-
-/*****************************************************************************/
-/*
* deal with notification that a page was read from the cache
*/
#ifdef AFS_CACHING_SUPPORT
@@ -295,8 +265,7 @@ static int afs_file_releasepage(struct page *page, gfp_t gfp_flags)
set_page_private(page, 0);
ClearPagePrivate(page);
- if (pageio)
- kfree(pageio);
+ kfree(pageio);
}
_leave(" = 0");
diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index c476fde..4ebb30a 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -49,7 +49,7 @@ static int afs_inode_map_status(struct afs_vnode *vnode)
case AFS_FTYPE_FILE:
inode->i_mode = S_IFREG | vnode->status.mode;
inode->i_op = &afs_file_inode_operations;
- inode->i_fop = &afs_file_file_operations;
+ inode->i_fop = &generic_ro_fops;
break;
case AFS_FTYPE_DIR:
inode->i_mode = S_IFDIR | vnode->status.mode;
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index f09860b..ab8f87c 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -71,7 +71,6 @@ extern struct file_operations afs_dir_file_operations;
*/
extern struct address_space_operations afs_fs_aops;
extern struct inode_operations afs_file_inode_operations;
-extern struct file_operations afs_file_file_operations;
#ifdef AFS_CACHING_SUPPORT
extern int afs_cache_get_page_cookie(struct page *page,
diff --git a/fs/aio.c b/fs/aio.c
index edfca5b..20bb919 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -42,8 +42,9 @@
#endif
/*------ sysctl variables----*/
-atomic_t aio_nr = ATOMIC_INIT(0); /* current system wide number of aio requests */
-unsigned aio_max_nr = 0x10000; /* system wide maximum number of aio requests */
+static DEFINE_SPINLOCK(aio_nr_lock);
+unsigned long aio_nr; /* current system wide number of aio requests */
+unsigned long aio_max_nr = 0x10000; /* system wide maximum number of aio requests */
/*----end sysctl variables---*/
static kmem_cache_t *kiocb_cachep;
@@ -208,7 +209,7 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
return ERR_PTR(-EINVAL);
}
- if (nr_events > aio_max_nr)
+ if ((unsigned long)nr_events > aio_max_nr)
return ERR_PTR(-EAGAIN);
ctx = kmem_cache_alloc(kioctx_cachep, GFP_KERNEL);
@@ -233,8 +234,14 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
goto out_freectx;
/* limit the number of system wide aios */
- atomic_add(ctx->max_reqs, &aio_nr); /* undone by __put_ioctx */
- if (unlikely(atomic_read(&aio_nr) > aio_max_nr))
+ spin_lock(&aio_nr_lock);
+ if (aio_nr + ctx->max_reqs > aio_max_nr ||
+ aio_nr + ctx->max_reqs < aio_nr)
+ ctx->max_reqs = 0;
+ else
+ aio_nr += ctx->max_reqs;
+ spin_unlock(&aio_nr_lock);
+ if (ctx->max_reqs == 0)
goto out_cleanup;
/* now link into global list. kludge. FIXME */
@@ -248,8 +255,6 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
return ctx;
out_cleanup:
- atomic_sub(ctx->max_reqs, &aio_nr);
- ctx->max_reqs = 0; /* prevent __put_ioctx from sub'ing aio_nr */
__put_ioctx(ctx);
return ERR_PTR(-EAGAIN);
@@ -374,7 +379,12 @@ void fastcall __put_ioctx(struct kioctx *ctx)
pr_debug("__put_ioctx: freeing %p\n", ctx);
kmem_cache_free(kioctx_cachep, ctx);
- atomic_sub(nr_events, &aio_nr);
+ if (nr_events) {
+ spin_lock(&aio_nr_lock);
+ BUG_ON(aio_nr - nr_events > aio_nr);
+ aio_nr -= nr_events;
+ spin_unlock(&aio_nr_lock);
+ }
}
/* aio_get_req
@@ -1258,8 +1268,9 @@ asmlinkage long sys_io_setup(unsigned nr_events, aio_context_t __user *ctxp)
goto out;
ret = -EINVAL;
- if (unlikely(ctx || (int)nr_events <= 0)) {
- pr_debug("EINVAL: io_setup: ctx or nr_events > max\n");
+ if (unlikely(ctx || nr_events == 0)) {
+ pr_debug("EINVAL: io_setup: ctx %lu nr_events %u\n",
+ ctx, nr_events);
goto out;
}
diff --git a/fs/autofs/waitq.c b/fs/autofs/waitq.c
index 1fcaa156..633f628 100644
--- a/fs/autofs/waitq.c
+++ b/fs/autofs/waitq.c
@@ -150,10 +150,8 @@ int autofs_wait(struct autofs_sb_info *sbi, struct qstr *name)
if ( sbi->catatonic ) {
/* We might have slept, so check again for catatonic mode */
wq->status = -ENOENT;
- if ( wq->name ) {
- kfree(wq->name);
- wq->name = NULL;
- }
+ kfree(wq->name);
+ wq->name = NULL;
}
if ( wq->name ) {
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index 0a3c05d..818b37b 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -22,10 +22,8 @@
static void ino_lnkfree(struct autofs_info *ino)
{
- if (ino->u.symlink) {
- kfree(ino->u.symlink);
- ino->u.symlink = NULL;
- }
+ kfree(ino->u.symlink);
+ ino->u.symlink = NULL;
}
struct autofs_info *autofs4_init_ino(struct autofs_info *ino,
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index 3df8628..394ff36 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -243,10 +243,8 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
if ( sbi->catatonic ) {
/* We might have slept, so check again for catatonic mode */
wq->status = -ENOENT;
- if ( wq->name ) {
- kfree(wq->name);
- wq->name = NULL;
- }
+ kfree(wq->name);
+ wq->name = NULL;
}
if ( wq->name ) {
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index e0a6025..2d365cb 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -73,12 +73,6 @@ static struct inode_operations befs_dir_inode_operations = {
.lookup = befs_lookup,
};
-static struct file_operations befs_file_operations = {
- .llseek = default_llseek,
- .read = generic_file_read,
- .mmap = generic_file_readonly_mmap,
-};
-
static struct address_space_operations befs_aops = {
.readpage = befs_readpage,
.sync_page = block_sync_page,
@@ -398,7 +392,7 @@ befs_read_inode(struct inode *inode)
inode->i_mapping->a_ops = &befs_aops;
if (S_ISREG(inode->i_mode)) {
- inode->i_fop = &befs_file_operations;
+ inode->i_fop = &generic_ro_fops;
} else if (S_ISDIR(inode->i_mode)) {
inode->i_op = &befs_dir_inode_operations;
inode->i_fop = &befs_dir_operations;
@@ -731,20 +725,16 @@ parse_options(char *options, befs_mount_options * opts)
static void
befs_put_super(struct super_block *sb)
{
- if (BEFS_SB(sb)->mount_opts.iocharset) {
- kfree(BEFS_SB(sb)->mount_opts.iocharset);
- BEFS_SB(sb)->mount_opts.iocharset = NULL;
- }
+ kfree(BEFS_SB(sb)->mount_opts.iocharset);
+ BEFS_SB(sb)->mount_opts.iocharset = NULL;
if (BEFS_SB(sb)->nls) {
unload_nls(BEFS_SB(sb)->nls);
BEFS_SB(sb)->nls = NULL;
}
- if (sb->s_fs_info) {
- kfree(sb->s_fs_info);
- sb->s_fs_info = NULL;
- }
+ kfree(sb->s_fs_info);
+ sb->s_fs_info = NULL;
return;
}
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 6fa6adc..f36f221 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1006,8 +1006,7 @@ out_free_dentry:
if (interpreter)
fput(interpreter);
out_free_interp:
- if (elf_interpreter)
- kfree(elf_interpreter);
+ kfree(elf_interpreter);
out_free_file:
sys_close(elf_exec_fileno);
out_free_fh:
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index dda87c4..e0344f6 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -411,16 +411,11 @@ error:
allow_write_access(interpreter);
fput(interpreter);
}
- if (interpreter_name)
- kfree(interpreter_name);
- if (exec_params.phdrs)
- kfree(exec_params.phdrs);
- if (exec_params.loadmap)
- kfree(exec_params.loadmap);
- if (interp_params.phdrs)
- kfree(interp_params.phdrs);
- if (interp_params.loadmap)
- kfree(interp_params.loadmap);
+ kfree(interpreter_name);
+ kfree(exec_params.phdrs);
+ kfree(exec_params.loadmap);
+ kfree(interp_params.phdrs);
+ kfree(interp_params.loadmap);
return retval;
/* unrecoverable error - kill the process */
diff --git a/fs/buffer.c b/fs/buffer.c
index 35fa349..5287be1 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -396,7 +396,7 @@ asmlinkage long sys_fdatasync(unsigned int fd)
* private_lock is contended then so is mapping->tree_lock).
*/
static struct buffer_head *
-__find_get_block_slow(struct block_device *bdev, sector_t block, int unused)
+__find_get_block_slow(struct block_device *bdev, sector_t block)
{
struct inode *bd_inode = bdev->bd_inode;
struct address_space *bd_mapping = bd_inode->i_mapping;
@@ -1438,7 +1438,7 @@ __find_get_block(struct block_device *bdev, sector_t block, int size)
struct buffer_head *bh = lookup_bh_lru(bdev, block, size);
if (bh == NULL) {
- bh = __find_get_block_slow(bdev, block, size);
+ bh = __find_get_block_slow(bdev, block);
if (bh)
bh_lru_install(bh);
}
@@ -1705,7 +1705,7 @@ void unmap_underlying_metadata(struct block_device *bdev, sector_t block)
might_sleep();
- old_bh = __find_get_block_slow(bdev, block, 0);
+ old_bh = __find_get_block_slow(bdev, block);
if (old_bh) {
clear_buffer_dirty(old_bh);
wait_on_buffer(old_bh);
diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c
index 98539e2..086ae8f 100644
--- a/fs/cifs/asn1.c
+++ b/fs/cifs/asn1.c
@@ -553,8 +553,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
*(oid + 3)));
rc = compare_oid(oid, oidlen, NTLMSSP_OID,
NTLMSSP_OID_LEN);
- if(oid)
- kfree(oid);
+ kfree(oid);
if (rc)
use_ntlmssp = TRUE;
}
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index d74367a..450ab75 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1265,8 +1265,7 @@ connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
the helper that resolves tcp names, mount to it, try to
tcon to it unmount it if fail */
- if(referrals)
- kfree(referrals);
+ kfree(referrals);
return rc;
}
@@ -1535,10 +1534,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
memset(&volume_info,0,sizeof(struct smb_vol));
if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
- if(volume_info.UNC)
- kfree(volume_info.UNC);
- if(volume_info.password)
- kfree(volume_info.password);
+ kfree(volume_info.UNC);
+ kfree(volume_info.password);
FreeXid(xid);
return -EINVAL;
}
@@ -1551,10 +1548,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
cifserror("No username specified ");
/* In userspace mount helper we can get user name from alternate
locations such as env variables and files on disk */
- if(volume_info.UNC)
- kfree(volume_info.UNC);
- if(volume_info.password)
- kfree(volume_info.password);
+ kfree(volume_info.UNC);
+ kfree(volume_info.password);
FreeXid(xid);
return -EINVAL;
}
@@ -1573,10 +1568,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
if(rc <= 0) {
/* we failed translating address */
- if(volume_info.UNC)
- kfree(volume_info.UNC);
- if(volume_info.password)
- kfree(volume_info.password);
+ kfree(volume_info.UNC);
+ kfree(volume_info.password);
FreeXid(xid);
return -EINVAL;
}
@@ -1587,19 +1580,15 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
} else if (volume_info.UNCip){
/* BB using ip addr as server name connect to the DFS root below */
cERROR(1,("Connecting to DFS root not implemented yet"));
- if(volume_info.UNC)
- kfree(volume_info.UNC);
- if(volume_info.password)
- kfree(volume_info.password);
+ kfree(volume_info.UNC);
+ kfree(volume_info.password);
FreeXid(xid);
return -EINVAL;
} else /* which servers DFS root would we conect to */ {
cERROR(1,
("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified "));
- if(volume_info.UNC)
- kfree(volume_info.UNC);
- if(volume_info.password)
- kfree(volume_info.password);
+ kfree(volume_info.UNC);
+ kfree(volume_info.password);
FreeXid(xid);
return -EINVAL;
}
@@ -1612,10 +1601,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
cifs_sb->local_nls = load_nls(volume_info.iocharset);
if(cifs_sb->local_nls == NULL) {
cERROR(1,("CIFS mount error: iocharset %s not found",volume_info.iocharset));
- if(volume_info.UNC)
- kfree(volume_info.UNC);
- if(volume_info.password)
- kfree(volume_info.password);
+ kfree(volume_info.UNC);
+ kfree(volume_info.password);
FreeXid(xid);
return -ELIBACC;
}
@@ -1630,10 +1617,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
&sin_server6.sin6_addr,
volume_info.username, &srvTcp);
else {
- if(volume_info.UNC)
- kfree(volume_info.UNC);
- if(volume_info.password)
- kfree(volume_info.password);
+ kfree(volume_info.UNC);
+ kfree(volume_info.password);
FreeXid(xid);
return -EINVAL;
}
@@ -1654,10 +1639,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
("Error connecting to IPv4 socket. Aborting operation"));
if(csocket != NULL)
sock_release(csocket);
- if(volume_info.UNC)
- kfree(volume_info.UNC);
- if(volume_info.password)
- kfree(volume_info.password);
+ kfree(volume_info.UNC);
+ kfree(volume_info.password);
FreeXid(xid);
return rc;
}
@@ -1666,10 +1649,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
if (srvTcp == NULL) {
rc = -ENOMEM;
sock_release(csocket);
- if(volume_info.UNC)
- kfree(volume_info.UNC);
- if(volume_info.password)
- kfree(volume_info.password);
+ kfree(volume_info.UNC);
+ kfree(volume_info.password);
FreeXid(xid);
return rc;
} else {
@@ -1692,10 +1673,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
if(rc < 0) {
rc = -ENOMEM;
sock_release(csocket);
- if(volume_info.UNC)
- kfree(volume_info.UNC);
- if(volume_info.password)
- kfree(volume_info.password);
+ kfree(volume_info.UNC);
+ kfree(volume_info.password);
FreeXid(xid);
return rc;
}
@@ -1710,8 +1689,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
if (existingCifsSes) {
pSesInfo = existingCifsSes;
cFYI(1, ("Existing smb sess found "));
- if(volume_info.password)
- kfree(volume_info.password);
+ kfree(volume_info.password);
/* volume_info.UNC freed at end of function */
} else if (!rc) {
cFYI(1, ("Existing smb sess not found "));
@@ -1741,8 +1719,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
if(!rc)
atomic_inc(&srvTcp->socketUseCount);
} else
- if(volume_info.password)
- kfree(volume_info.password);
+ kfree(volume_info.password);
}
/* search for existing tcon to this server share */
@@ -1821,8 +1798,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
"", cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
- if(volume_info.UNC)
- kfree(volume_info.UNC);
+ kfree(volume_info.UNC);
FreeXid(xid);
return -ENODEV;
} else {
@@ -1925,8 +1901,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
(in which case it is not needed anymore) but when new sesion is created
the password ptr is put in the new session structure (in which case the
password will be freed at unmount time) */
- if(volume_info.UNC)
- kfree(volume_info.UNC);
+ kfree(volume_info.UNC);
FreeXid(xid);
return rc;
}
@@ -3283,8 +3258,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
if ((bcc_ptr + (2 * length)) -
pByteArea(smb_buffer_response) <=
BCC(smb_buffer_response)) {
- if(tcon->nativeFileSystem)
- kfree(tcon->nativeFileSystem);
+ kfree(tcon->nativeFileSystem);
tcon->nativeFileSystem =
kzalloc(length + 2, GFP_KERNEL);
cifs_strfromUCS_le(tcon->nativeFileSystem,
@@ -3301,8 +3275,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
if ((bcc_ptr + length) -
pByteArea(smb_buffer_response) <=
BCC(smb_buffer_response)) {
- if(tcon->nativeFileSystem)
- kfree(tcon->nativeFileSystem);
+ kfree(tcon->nativeFileSystem);
tcon->nativeFileSystem =
kzalloc(length + 1, GFP_KERNEL);
strncpy(tcon->nativeFileSystem, bcc_ptr,
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index b43e071..0f99aae 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -84,10 +84,8 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
cifsInode->time = 0; /* will force revalidate to go get info when needed */
cifs_hl_exit:
- if (fromName)
- kfree(fromName);
- if (toName)
- kfree(toName);
+ kfree(fromName);
+ kfree(toName);
FreeXid(xid);
return rc;
}
@@ -206,8 +204,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
}
}
- if (full_path)
- kfree(full_path);
+ kfree(full_path);
FreeXid(xid);
return rc;
}
@@ -253,8 +250,7 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
len = buflen;
tmpbuffer = kmalloc(len,GFP_KERNEL);
if(tmpbuffer == NULL) {
- if (full_path)
- kfree(full_path);
+ kfree(full_path);
FreeXid(xid);
return -ENOMEM;
}
@@ -303,8 +299,7 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
strncpy(tmpbuffer, referrals, len-1);
}
}
- if(referrals)
- kfree(referrals);
+ kfree(referrals);
kfree(tmp_path);
}
/* BB add code like else decode referrals then memcpy to
@@ -323,12 +318,8 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
rc));
}
- if (tmpbuffer) {
- kfree(tmpbuffer);
- }
- if (full_path) {
- kfree(full_path);
- }
+ kfree(tmpbuffer);
+ kfree(full_path);
FreeXid(xid);
return rc;
}
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index eba1de9..34a0669 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -98,14 +98,10 @@ sesInfoFree(struct cifsSesInfo *buf_to_free)
atomic_dec(&sesInfoAllocCount);
list_del(&buf_to_free->cifsSessionList);
write_unlock(&GlobalSMBSeslock);
- if (buf_to_free->serverOS)
- kfree(buf_to_free->serverOS);
- if (buf_to_free->serverDomain)
- kfree(buf_to_free->serverDomain);
- if (buf_to_free->serverNOS)
- kfree(buf_to_free->serverNOS);
- if (buf_to_free->password)
- kfree(buf_to_free->password);
+ kfree(buf_to_free->serverOS);
+ kfree(buf_to_free->serverDomain);
+ kfree(buf_to_free->serverNOS);
+ kfree(buf_to_free->password);
kfree(buf_to_free);
}
@@ -144,8 +140,7 @@ tconInfoFree(struct cifsTconInfo *buf_to_free)
atomic_dec(&tconInfoAllocCount);
list_del(&buf_to_free->cifsConnectionList);
write_unlock(&GlobalSMBSeslock);
- if (buf_to_free->nativeFileSystem)
- kfree(buf_to_free->nativeFileSystem);
+ kfree(buf_to_free->nativeFileSystem);
kfree(buf_to_free);
}
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index c1e02ef..f375f87 100644
--- a/fs/cifs/xattr.c
+++ b/fs/cifs/xattr.c
@@ -87,8 +87,7 @@ int cifs_removexattr(struct dentry * direntry, const char * ea_name)
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
}
remove_ea_exit:
- if (full_path)
- kfree(full_path);
+ kfree(full_path);
FreeXid(xid);
#endif
return rc;
@@ -132,8 +131,7 @@ int cifs_setxattr(struct dentry * direntry, const char * ea_name,
returns as xattrs */
if(value_size > MAX_EA_VALUE_SIZE) {
cFYI(1,("size of EA value too large"));
- if(full_path)
- kfree(full_path);
+ kfree(full_path);
FreeXid(xid);
return -EOPNOTSUPP;
}
@@ -195,8 +193,7 @@ int cifs_setxattr(struct dentry * direntry, const char * ea_name,
}
set_ea_exit:
- if (full_path)
- kfree(full_path);
+ kfree(full_path);
FreeXid(xid);
#endif
return rc;
@@ -298,8 +295,7 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name,
rc = -EOPNOTSUPP;
get_ea_exit:
- if (full_path)
- kfree(full_path);
+ kfree(full_path);
FreeXid(xid);
#endif
return rc;
@@ -345,8 +341,7 @@ ssize_t cifs_listxattr(struct dentry * direntry, char * data, size_t buf_size)
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (full_path)
- kfree(full_path);
+ kfree(full_path);
FreeXid(xid);
#endif
return rc;
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 43dbcb0..4909754 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -2235,7 +2235,8 @@ static int fd_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
if (err)
err = -EFAULT;
-out: if (karg) kfree(karg);
+out:
+ kfree(karg);
return err;
}
diff --git a/fs/dcache.c b/fs/dcache.c
index e90512e..17e43913 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -644,7 +644,7 @@ void shrink_dcache_parent(struct dentry * parent)
*
* Prune the dentries that are anonymous
*
- * parsing d_hash list does not hlist_for_each_rcu() as it
+ * parsing d_hash list does not hlist_for_each_entry_rcu() as it
* done under dcache_lock.
*
*/
@@ -1043,15 +1043,13 @@ struct dentry * __d_lookup(struct dentry * parent, struct qstr * name)
struct hlist_head *head = d_hash(parent,hash);
struct dentry *found = NULL;
struct hlist_node *node;
+ struct dentry *dentry;
rcu_read_lock();
- hlist_for_each_rcu(node, head) {
- struct dentry *dentry;
+ hlist_for_each_entry_rcu(dentry, node, head, d_hash) {
struct qstr *qstr;
- dentry = hlist_entry(node, struct dentry, d_hash);
-
if (dentry->d_name.hash != hash)
continue;
if (dentry->d_parent != parent)
@@ -1123,7 +1121,7 @@ int d_validate(struct dentry *dentry, struct dentry *dparent)
spin_lock(&dcache_lock);
base = d_hash(dparent, dentry->d_name.hash);
hlist_for_each(lhp,base) {
- /* hlist_for_each_rcu() not required for d_hash list
+ /* hlist_for_each_entry_rcu() not required for d_hash list
* as it is parsed under dcache_lock
*/
if (dentry == hlist_entry(lhp, struct dentry, d_hash)) {
diff --git a/fs/devfs/base.c b/fs/devfs/base.c
index 8b679b6..1274422 100644
--- a/fs/devfs/base.c
+++ b/fs/devfs/base.c
@@ -2738,10 +2738,8 @@ static int devfsd_close(struct inode *inode, struct file *file)
entry = fs_info->devfsd_first_event;
fs_info->devfsd_first_event = NULL;
fs_info->devfsd_last_event = NULL;
- if (fs_info->devfsd_info) {
- kfree(fs_info->devfsd_info);
- fs_info->devfsd_info = NULL;
- }
+ kfree(fs_info->devfsd_info);
+ fs_info->devfsd_info = NULL;
spin_unlock(&fs_info->devfsd_buffer_lock);
fs_info->devfsd_pgrp = 0;
fs_info->devfsd_task = NULL;
diff --git a/fs/dquot.c b/fs/dquot.c
index ea76442..afa06a8 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -77,6 +77,7 @@
#include <linux/kmod.h>
#include <linux/namei.h>
#include <linux/buffer_head.h>
+#include <linux/quotaops.h>
#include <asm/uaccess.h>
diff --git a/fs/exec.c b/fs/exec.c
index 10d493f..cd6c574 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -48,6 +48,7 @@
#include <linux/syscalls.h>
#include <linux/rmap.h>
#include <linux/acct.h>
+#include <linux/cn_proc.h>
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
@@ -1096,6 +1097,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
fput(bprm->file);
bprm->file = NULL;
current->did_exec = 1;
+ proc_exec_connector(current);
return retval;
}
read_lock(&binfmt_lock);
@@ -1509,7 +1511,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
goto close_fail;
if (!file->f_op->write)
goto close_fail;
- if (do_truncate(file->f_dentry, 0) != 0)
+ if (do_truncate(file->f_dentry, 0, file) != 0)
goto close_fail;
retval = binfmt->core_dump(signr, regs, file);
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c
index 213148c..6af2f41 100644
--- a/fs/ext2/acl.c
+++ b/fs/ext2/acl.c
@@ -194,8 +194,7 @@ ext2_get_acl(struct inode *inode, int type)
acl = NULL;
else
acl = ERR_PTR(retval);
- if (value)
- kfree(value);
+ kfree(value);
if (!IS_ERR(acl)) {
switch(type) {
@@ -262,8 +261,7 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
error = ext2_xattr_set(inode, name_index, "", value, size, 0);
- if (value)
- kfree(value);
+ kfree(value);
if (!error) {
switch(type) {
case ACL_TYPE_ACCESS:
diff --git a/fs/file_table.c b/fs/file_table.c
index 4dc2055..c3a5e2f 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -35,7 +35,7 @@ static DEFINE_SPINLOCK(filp_count_lock);
* context and must be fully threaded - use a local spinlock
* to protect files_stat.nr_files
*/
-void filp_ctor(void * objp, struct kmem_cache_s *cachep, unsigned long cflags)
+void filp_ctor(void *objp, struct kmem_cache *cachep, unsigned long cflags)
{
if ((cflags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
SLAB_CTOR_CONSTRUCTOR) {
@@ -46,7 +46,7 @@ void filp_ctor(void * objp, struct kmem_cache_s *cachep, unsigned long cflags)
}
}
-void filp_dtor(void * objp, struct kmem_cache_s *cachep, unsigned long dflags)
+void filp_dtor(void *objp, struct kmem_cache *cachep, unsigned long dflags)
{
unsigned long flags;
spin_lock_irqsave(&filp_count_lock, flags);
diff --git a/fs/freevxfs/vxfs_extern.h b/fs/freevxfs/vxfs_extern.h
index d8be917..927acf7 100644
--- a/fs/freevxfs/vxfs_extern.h
+++ b/fs/freevxfs/vxfs_extern.h
@@ -38,7 +38,7 @@
*/
-struct kmem_cache_s;
+struct kmem_cache;
struct super_block;
struct vxfs_inode_info;
struct inode;
@@ -51,7 +51,7 @@ extern daddr_t vxfs_bmap1(struct inode *, long);
extern int vxfs_read_fshead(struct super_block *);
/* vxfs_inode.c */
-extern struct kmem_cache_s *vxfs_inode_cachep;
+extern struct kmem_cache *vxfs_inode_cachep;
extern void vxfs_dumpi(struct vxfs_inode_info *, ino_t);
extern struct inode * vxfs_get_fake_inode(struct super_block *,
struct vxfs_inode_info *);
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
index 9672d2f..f544aae 100644
--- a/fs/freevxfs/vxfs_inode.c
+++ b/fs/freevxfs/vxfs_inode.c
@@ -46,15 +46,6 @@ extern struct address_space_operations vxfs_immed_aops;
extern struct inode_operations vxfs_immed_symlink_iops;
-static struct file_operations vxfs_file_operations = {
- .open = generic_file_open,
- .llseek = generic_file_llseek,
- .read = generic_file_read,
- .mmap = generic_file_mmap,
- .sendfile = generic_file_sendfile,
-};
-
-
kmem_cache_t *vxfs_inode_cachep;
@@ -318,7 +309,7 @@ vxfs_read_inode(struct inode *ip)
aops = &vxfs_aops;
if (S_ISREG(ip->i_mode)) {
- ip->i_fop = &vxfs_file_operations;
+ ip->i_fop = &generic_ro_fops;
ip->i_mapping->a_ops = aops;
} else if (S_ISDIR(ip->i_mode)) {
ip->i_op = &vxfs_dir_inode_ops;
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index c27f8d4..785c721 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -562,7 +562,7 @@ int write_inode_now(struct inode *inode, int sync)
};
if (!mapping_cap_writeback_dirty(inode->i_mapping))
- return 0;
+ wbc.nr_to_write = 0;
might_sleep();
spin_lock(&inode_lock);
@@ -606,7 +606,7 @@ EXPORT_SYMBOL(sync_inode);
* O_SYNC flag set, to flush dirty writes to disk.
*
* @what is a bitmask, specifying which part of the inode's data should be
- * written and waited upon:
+ * written and waited upon.
*
* OSYNC_DATA: i_mapping's dirty data
* OSYNC_METADATA: the buffers at i_mapping->private_list
@@ -672,8 +672,9 @@ int writeback_acquire(struct backing_dev_info *bdi)
/**
* writeback_in_progress: determine whether there is writeback in progress
- * against a backing device.
* @bdi: the device's backing_dev_info structure.
+ *
+ * Determine whether there is writeback in progress against a backing device.
*/
int writeback_in_progress(struct backing_dev_info *bdi)
{
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index a6f90a6..8f873e62 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -184,6 +184,13 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
fuse_putback_request() */
for (i = 1; i < FUSE_MAX_OUTSTANDING; i++)
up(&fc->outstanding_sem);
+ } else if (req->in.h.opcode == FUSE_RELEASE && req->inode == NULL) {
+ /* Special case for failed iget in CREATE */
+ u64 nodeid = req->in.h.nodeid;
+ __fuse_get_request(req);
+ fuse_reset_request(req);
+ fuse_send_forget(fc, req, nodeid, 1);
+ putback = 0;
}
if (putback)
fuse_putback_request(fc, req);
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 70dba72..c045cc7 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -13,6 +13,7 @@
#include <linux/gfp.h>
#include <linux/sched.h>
#include <linux/namei.h>
+#include <linux/mount.h>
static inline unsigned long time_to_jiffies(unsigned long sec,
unsigned long nsec)
@@ -134,6 +135,101 @@ static void fuse_invalidate_entry(struct dentry *entry)
entry->d_time = jiffies - 1;
}
+static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
+ struct nameidata *nd)
+{
+ int err;
+ struct inode *inode;
+ struct fuse_conn *fc = get_fuse_conn(dir);
+ struct fuse_req *req;
+ struct fuse_open_in inarg;
+ struct fuse_open_out outopen;
+ struct fuse_entry_out outentry;
+ struct fuse_inode *fi;
+ struct fuse_file *ff;
+ struct file *file;
+ int flags = nd->intent.open.flags - 1;
+
+ err = -ENOSYS;
+ if (fc->no_create)
+ goto out;
+
+ err = -ENAMETOOLONG;
+ if (entry->d_name.len > FUSE_NAME_MAX)
+ goto out;
+
+ err = -EINTR;
+ req = fuse_get_request(fc);
+ if (!req)
+ goto out;
+
+ ff = fuse_file_alloc();
+ if (!ff)
+ goto out_put_request;
+
+ flags &= ~O_NOCTTY;
+ memset(&inarg, 0, sizeof(inarg));
+ inarg.flags = flags;
+ inarg.mode = mode;
+ req->in.h.opcode = FUSE_CREATE;
+ req->in.h.nodeid = get_node_id(dir);
+ req->inode = dir;
+ req->in.numargs = 2;
+ req->in.args[0].size = sizeof(inarg);
+ req->in.args[0].value = &inarg;
+ req->in.args[1].size = entry->d_name.len + 1;
+ req->in.args[1].value = entry->d_name.name;
+ req->out.numargs = 2;
+ req->out.args[0].size = sizeof(outentry);
+ req->out.args[0].value = &outentry;
+ req->out.args[1].size = sizeof(outopen);
+ req->out.args[1].value = &outopen;
+ request_send(fc, req);
+ err = req->out.h.error;
+ if (err) {
+ if (err == -ENOSYS)
+ fc->no_create = 1;
+ goto out_free_ff;
+ }
+
+ err = -EIO;
+ if (!S_ISREG(outentry.attr.mode))
+ goto out_free_ff;
+
+ inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
+ &outentry.attr);
+ err = -ENOMEM;
+ if (!inode) {
+ flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
+ ff->fh = outopen.fh;
+ fuse_send_release(fc, ff, outentry.nodeid, NULL, flags, 0);
+ goto out_put_request;
+ }
+ fuse_put_request(fc, req);
+ entry->d_time = time_to_jiffies(outentry.entry_valid,
+ outentry.entry_valid_nsec);
+ fi = get_fuse_inode(inode);
+ fi->i_time = time_to_jiffies(outentry.attr_valid,
+ outentry.attr_valid_nsec);
+
+ d_instantiate(entry, inode);
+ file = lookup_instantiate_filp(nd, entry, generic_file_open);
+ if (IS_ERR(file)) {
+ ff->fh = outopen.fh;
+ fuse_send_release(fc, ff, outentry.nodeid, inode, flags, 0);
+ return PTR_ERR(file);
+ }
+ fuse_finish_open(inode, file, ff, &outopen);
+ return 0;
+
+ out_free_ff:
+ fuse_file_free(ff);
+ out_put_request:
+ fuse_put_request(fc, req);
+ out:
+ return err;
+}
+
static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
struct inode *dir, struct dentry *entry,
int mode)
@@ -208,6 +304,12 @@ static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode,
static int fuse_create(struct inode *dir, struct dentry *entry, int mode,
struct nameidata *nd)
{
+ if (nd && (nd->flags & LOOKUP_CREATE)) {
+ int err = fuse_create_open(dir, entry, mode, nd);
+ if (err != -ENOSYS)
+ return err;
+ /* Fall back on mknod */
+ }
return fuse_mknod(dir, entry, mode, 0);
}
@@ -461,6 +563,38 @@ static int fuse_revalidate(struct dentry *entry)
return fuse_do_getattr(inode);
}
+static int fuse_access(struct inode *inode, int mask)
+{
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_req *req;
+ struct fuse_access_in inarg;
+ int err;
+
+ if (fc->no_access)
+ return 0;
+
+ req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ memset(&inarg, 0, sizeof(inarg));
+ inarg.mask = mask;
+ req->in.h.opcode = FUSE_ACCESS;
+ req->in.h.nodeid = get_node_id(inode);
+ req->inode = inode;
+ req->in.numargs = 1;
+ req->in.args[0].size = sizeof(inarg);
+ req->in.args[0].value = &inarg;
+ request_send(fc, req);
+ err = req->out.h.error;
+ fuse_put_request(fc, req);
+ if (err == -ENOSYS) {
+ fc->no_access = 1;
+ err = 0;
+ }
+ return err;
+}
+
static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
{
struct fuse_conn *fc = get_fuse_conn(inode);
@@ -491,11 +625,11 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
return err;
} else {
int mode = inode->i_mode;
- if ((mask & MAY_WRITE) && IS_RDONLY(inode) &&
- (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
- return -EROFS;
if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO))
return -EACCES;
+
+ if (nd && (nd->flags & LOOKUP_ACCESS))
+ return fuse_access(inode, mask);
return 0;
}
}
@@ -629,29 +763,29 @@ static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync)
return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
}
-static unsigned iattr_to_fattr(struct iattr *iattr, struct fuse_attr *fattr)
+static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
{
unsigned ivalid = iattr->ia_valid;
- unsigned fvalid = 0;
-
- memset(fattr, 0, sizeof(*fattr));
if (ivalid & ATTR_MODE)
- fvalid |= FATTR_MODE, fattr->mode = iattr->ia_mode;
+ arg->valid |= FATTR_MODE, arg->mode = iattr->ia_mode;
if (ivalid & ATTR_UID)
- fvalid |= FATTR_UID, fattr->uid = iattr->ia_uid;
+ arg->valid |= FATTR_UID, arg->uid = iattr->ia_uid;
if (ivalid & ATTR_GID)
- fvalid |= FATTR_GID, fattr->gid = iattr->ia_gid;
+ arg->valid |= FATTR_GID, arg->gid = iattr->ia_gid;
if (ivalid & ATTR_SIZE)
- fvalid |= FATTR_SIZE, fattr->size = iattr->ia_size;
+ arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size;
/* You can only _set_ these together (they may change by themselves) */
if ((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) {
- fvalid |= FATTR_ATIME | FATTR_MTIME;
- fattr->atime = iattr->ia_atime.tv_sec;
- fattr->mtime = iattr->ia_mtime.tv_sec;
+ arg->valid |= FATTR_ATIME | FATTR_MTIME;
+ arg->atime = iattr->ia_atime.tv_sec;
+ arg->mtime = iattr->ia_mtime.tv_sec;
+ }
+ if (ivalid & ATTR_FILE) {
+ struct fuse_file *ff = iattr->ia_file->private_data;
+ arg->valid |= FATTR_FH;
+ arg->fh = ff->fh;
}
-
- return fvalid;
}
static int fuse_setattr(struct dentry *entry, struct iattr *attr)
@@ -686,7 +820,7 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
return -EINTR;
memset(&inarg, 0, sizeof(inarg));
- inarg.valid = iattr_to_fattr(attr, &inarg.attr);
+ iattr_to_fattr(attr, &inarg);
req->in.h.opcode = FUSE_SETATTR;
req->in.h.nodeid = get_node_id(inode);
req->inode = inode;
@@ -735,7 +869,9 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
struct nameidata *nd)
{
struct inode *inode;
- int err = fuse_lookup_iget(dir, entry, &inode);
+ int err;
+
+ err = fuse_lookup_iget(dir, entry, &inode);
if (err)
return ERR_PTR(err);
if (inode && S_ISDIR(inode->i_mode)) {
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 657ab11..2ca8614 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -14,11 +14,69 @@
static struct file_operations fuse_direct_io_file_operations;
-int fuse_open_common(struct inode *inode, struct file *file, int isdir)
+static int fuse_send_open(struct inode *inode, struct file *file, int isdir,
+ struct fuse_open_out *outargp)
{
struct fuse_conn *fc = get_fuse_conn(inode);
- struct fuse_req *req;
struct fuse_open_in inarg;
+ struct fuse_req *req;
+ int err;
+
+ req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ memset(&inarg, 0, sizeof(inarg));
+ inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
+ req->in.h.opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN;
+ req->in.h.nodeid = get_node_id(inode);
+ req->inode = inode;
+ req->in.numargs = 1;
+ req->in.args[0].size = sizeof(inarg);
+ req->in.args[0].value = &inarg;
+ req->out.numargs = 1;
+ req->out.args[0].size = sizeof(*outargp);
+ req->out.args[0].value = outargp;
+ request_send(fc, req);
+ err = req->out.h.error;
+ fuse_put_request(fc, req);
+
+ return err;
+}
+
+struct fuse_file *fuse_file_alloc(void)
+{
+ struct fuse_file *ff;
+ ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL);
+ if (ff) {
+ ff->release_req = fuse_request_alloc();
+ if (!ff->release_req) {
+ kfree(ff);
+ ff = NULL;
+ }
+ }
+ return ff;
+}
+
+void fuse_file_free(struct fuse_file *ff)
+{
+ fuse_request_free(ff->release_req);
+ kfree(ff);
+}
+
+void fuse_finish_open(struct inode *inode, struct file *file,
+ struct fuse_file *ff, struct fuse_open_out *outarg)
+{
+ if (outarg->open_flags & FOPEN_DIRECT_IO)
+ file->f_op = &fuse_direct_io_file_operations;
+ if (!(outarg->open_flags & FOPEN_KEEP_CACHE))
+ invalidate_inode_pages(inode->i_mapping);
+ ff->fh = outarg->fh;
+ file->private_data = ff;
+}
+
+int fuse_open_common(struct inode *inode, struct file *file, int isdir)
+{
struct fuse_open_out outarg;
struct fuse_file *ff;
int err;
@@ -34,73 +92,53 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir)
/* If opening the root node, no lookup has been performed on
it, so the attributes must be refreshed */
if (get_node_id(inode) == FUSE_ROOT_ID) {
- int err = fuse_do_getattr(inode);
+ err = fuse_do_getattr(inode);
if (err)
return err;
}
- req = fuse_get_request(fc);
- if (!req)
- return -EINTR;
-
- err = -ENOMEM;
- ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL);
+ ff = fuse_file_alloc();
if (!ff)
- goto out_put_request;
+ return -ENOMEM;
- ff->release_req = fuse_request_alloc();
- if (!ff->release_req) {
- kfree(ff);
- goto out_put_request;
- }
-
- memset(&inarg, 0, sizeof(inarg));
- inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
- req->in.h.opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN;
- req->in.h.nodeid = get_node_id(inode);
- req->inode = inode;
- req->in.numargs = 1;
- req->in.args[0].size = sizeof(inarg);
- req->in.args[0].value = &inarg;
- req->out.numargs = 1;
- req->out.args[0].size = sizeof(outarg);
- req->out.args[0].value = &outarg;
- request_send(fc, req);
- err = req->out.h.error;
- if (err) {
- fuse_request_free(ff->release_req);
- kfree(ff);
- } else {
- if (!isdir && (outarg.open_flags & FOPEN_DIRECT_IO))
- file->f_op = &fuse_direct_io_file_operations;
- if (!(outarg.open_flags & FOPEN_KEEP_CACHE))
- invalidate_inode_pages(inode->i_mapping);
- ff->fh = outarg.fh;
- file->private_data = ff;
+ err = fuse_send_open(inode, file, isdir, &outarg);
+ if (err)
+ fuse_file_free(ff);
+ else {
+ if (isdir)
+ outarg.open_flags &= ~FOPEN_DIRECT_IO;
+ fuse_finish_open(inode, file, ff, &outarg);
}
- out_put_request:
- fuse_put_request(fc, req);
return err;
}
-int fuse_release_common(struct inode *inode, struct file *file, int isdir)
+void fuse_send_release(struct fuse_conn *fc, struct fuse_file *ff,
+ u64 nodeid, struct inode *inode, int flags, int isdir)
{
- struct fuse_conn *fc = get_fuse_conn(inode);
- struct fuse_file *ff = file->private_data;
- struct fuse_req *req = ff->release_req;
+ struct fuse_req * req = ff->release_req;
struct fuse_release_in *inarg = &req->misc.release_in;
inarg->fh = ff->fh;
- inarg->flags = file->f_flags & ~O_EXCL;
+ inarg->flags = flags;
req->in.h.opcode = isdir ? FUSE_RELEASEDIR : FUSE_RELEASE;
- req->in.h.nodeid = get_node_id(inode);
+ req->in.h.nodeid = nodeid;
req->inode = inode;
req->in.numargs = 1;
req->in.args[0].size = sizeof(struct fuse_release_in);
req->in.args[0].value = inarg;
request_send_background(fc, req);
kfree(ff);
+}
+
+int fuse_release_common(struct inode *inode, struct file *file, int isdir)
+{
+ struct fuse_file *ff = file->private_data;
+ if (ff) {
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ u64 nodeid = get_node_id(inode);
+ fuse_send_release(fc, ff, nodeid, inode, file->f_flags, isdir);
+ }
/* Return value is ignored by VFS */
return 0;
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 5cb456f5..0ea5301 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -266,6 +266,12 @@ struct fuse_conn {
/** Is removexattr not implemented by fs? */
unsigned no_removexattr : 1;
+ /** Is access not implemented by fs? */
+ unsigned no_access : 1;
+
+ /** Is create not implemented by fs? */
+ unsigned no_create : 1;
+
/** Backing dev info */
struct backing_dev_info bdi;
};
@@ -337,6 +343,17 @@ size_t fuse_send_read_common(struct fuse_req *req, struct file *file,
*/
int fuse_open_common(struct inode *inode, struct file *file, int isdir);
+struct fuse_file *fuse_file_alloc(void);
+void fuse_file_free(struct fuse_file *ff);
+void fuse_finish_open(struct inode *inode, struct file *file,
+ struct fuse_file *ff, struct fuse_open_out *outarg);
+
+/**
+ * Send a RELEASE request
+ */
+void fuse_send_release(struct fuse_conn *fc, struct fuse_file *ff,
+ u64 nodeid, struct inode *inode, int flags, int isdir);
+
/**
* Send RELEASE or RELEASEDIR request
*/
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index dd71131..a33fb1d 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -294,8 +294,7 @@ static void hostfs_delete_inode(struct inode *inode)
static void hostfs_destroy_inode(struct inode *inode)
{
- if(HOSTFS_I(inode)->host_filename)
- kfree(HOSTFS_I(inode)->host_filename);
+ kfree(HOSTFS_I(inode)->host_filename);
/*XXX: This should not happen, probably. The check is here for
* additional safety.*/
diff --git a/fs/hpfs/dnode.c b/fs/hpfs/dnode.c
index 1d21307..229ff2f 100644
--- a/fs/hpfs/dnode.c
+++ b/fs/hpfs/dnode.c
@@ -244,12 +244,12 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno,
go_up:
if (namelen >= 256) {
hpfs_error(i->i_sb, "hpfs_add_to_dnode: namelen == %d", namelen);
- if (nd) kfree(nd);
+ kfree(nd);
kfree(nname);
return 1;
}
if (!(d = hpfs_map_dnode(i->i_sb, dno, &qbh))) {
- if (nd) kfree(nd);
+ kfree(nd);
kfree(nname);
return 1;
}
@@ -257,7 +257,7 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno,
if (hpfs_sb(i->i_sb)->sb_chk)
if (hpfs_stop_cycles(i->i_sb, dno, &c1, &c2, "hpfs_add_to_dnode")) {
hpfs_brelse4(&qbh);
- if (nd) kfree(nd);
+ kfree(nd);
kfree(nname);
return 1;
}
@@ -270,7 +270,7 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno,
for_all_poss(i, hpfs_pos_subst, 5, t + 1);
hpfs_mark_4buffers_dirty(&qbh);
hpfs_brelse4(&qbh);
- if (nd) kfree(nd);
+ kfree(nd);
kfree(nname);
return 0;
}
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index 8eefa63..63e88d7 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -75,7 +75,7 @@ void hpfs_error(struct super_block *s, char *m,...)
} else if (s->s_flags & MS_RDONLY) printk("; going on - but anything won't be destroyed because it's read-only\n");
else printk("; corrupted filesystem mounted read/write - your computer will explode within 20 seconds ... but you wanted it so!\n");
} else printk("\n");
- if (buf) kfree(buf);
+ kfree(buf);
hpfs_sb(s)->sb_was_error = 1;
}
@@ -102,8 +102,8 @@ int hpfs_stop_cycles(struct super_block *s, int key, int *c1, int *c2,
static void hpfs_put_super(struct super_block *s)
{
struct hpfs_sb_info *sbi = hpfs_sb(s);
- if (sbi->sb_cp_table) kfree(sbi->sb_cp_table);
- if (sbi->sb_bmp_dir) kfree(sbi->sb_bmp_dir);
+ kfree(sbi->sb_cp_table);
+ kfree(sbi->sb_bmp_dir);
unmark_dirty(s);
s->s_fs_info = NULL;
kfree(sbi);
@@ -654,8 +654,8 @@ bail3: brelse(bh1);
bail2: brelse(bh0);
bail1:
bail0:
- if (sbi->sb_bmp_dir) kfree(sbi->sb_bmp_dir);
- if (sbi->sb_cp_table) kfree(sbi->sb_cp_table);
+ kfree(sbi->sb_bmp_dir);
+ kfree(sbi->sb_cp_table);
s->s_fs_info = NULL;
kfree(sbi);
return -EINVAL;
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 1652de1..298f08b 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -855,8 +855,7 @@ root_found:
if (opt.check == 'r') table++;
s->s_root->d_op = &isofs_dentry_ops[table];
- if (opt.iocharset)
- kfree(opt.iocharset);
+ kfree(opt.iocharset);
return 0;
@@ -895,8 +894,7 @@ out_unknown_format:
out_freebh:
brelse(bh);
out_freesbi:
- if (opt.iocharset)
- kfree(opt.iocharset);
+ kfree(opt.iocharset);
kfree(sbi);
s->s_fs_info = NULL;
return -EINVAL;
@@ -1164,8 +1162,7 @@ out_nomem:
out_noread:
printk(KERN_INFO "ISOFS: unable to read i-node block %lu\n", block);
- if (tmpde)
- kfree(tmpde);
+ kfree(tmpde);
return -EIO;
out_toomany:
@@ -1334,8 +1331,7 @@ static void isofs_read_inode(struct inode *inode)
init_special_inode(inode, inode->i_mode, inode->i_rdev);
out:
- if (tmpde)
- kfree(tmpde);
+ kfree(tmpde);
if (bh)
brelse(bh);
return;
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index 2a3e310..002ad2b 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -261,10 +261,8 @@ void journal_commit_transaction(journal_t *journal)
struct buffer_head *bh = jh2bh(jh);
jbd_lock_bh_state(bh);
- if (jh->b_committed_data) {
- kfree(jh->b_committed_data);
- jh->b_committed_data = NULL;
- }
+ kfree(jh->b_committed_data);
+ jh->b_committed_data = NULL;
jbd_unlock_bh_state(bh);
}
journal_refile_buffer(journal, jh);
diff --git a/fs/jbd/recovery.c b/fs/jbd/recovery.c
index 103c34e..80d7f53 100644
--- a/fs/jbd/recovery.c
+++ b/fs/jbd/recovery.c
@@ -210,7 +210,7 @@ do { \
} while (0)
/**
- * int journal_recover(journal_t *journal) - recovers a on-disk journal
+ * journal_recover - recovers a on-disk journal
* @journal: the journal to recover
*
* The primary function for recovering the log contents when mounting a
@@ -266,7 +266,7 @@ int journal_recover(journal_t *journal)
}
/**
- * int journal_skip_recovery() - Start journal and wipe exiting records
+ * journal_skip_recovery - Start journal and wipe exiting records
* @journal: journal to startup
*
* Locate any valid recovery information from the journal and set up the
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index 13cb05b..429f4b2 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -227,8 +227,7 @@ repeat_locked:
spin_unlock(&transaction->t_handle_lock);
spin_unlock(&journal->j_state_lock);
out:
- if (new_transaction)
- kfree(new_transaction);
+ kfree(new_transaction);
return ret;
}
@@ -725,8 +724,7 @@ done:
journal_cancel_revoke(handle, jh);
out:
- if (frozen_buffer)
- kfree(frozen_buffer);
+ kfree(frozen_buffer);
JBUFFER_TRACE(jh, "exit");
return error;
@@ -905,8 +903,7 @@ repeat:
jbd_unlock_bh_state(bh);
out:
journal_put_journal_head(jh);
- if (committed_data)
- kfree(committed_data);
+ kfree(committed_data);
return err;
}
diff --git a/fs/jffs/intrep.c b/fs/jffs/intrep.c
index 27f199e..b2e9542 100644
--- a/fs/jffs/intrep.c
+++ b/fs/jffs/intrep.c
@@ -462,7 +462,7 @@ jffs_checksum_flash(struct mtd_info *mtd, loff_t start, int size, __u32 *result)
}
/* Free read buffer */
- kfree (read_buf);
+ kfree(read_buf);
/* Return result */
D3(printk("checksum result: 0x%08x\n", sum));
@@ -1011,12 +1011,12 @@ jffs_scan_flash(struct jffs_control *c)
offset , fmc->sector_size);
flash_safe_release(fmc->mtd);
- kfree (read_buf);
+ kfree(read_buf);
return -1; /* bad, bad, bad! */
}
flash_safe_release(fmc->mtd);
- kfree (read_buf);
+ kfree(read_buf);
return -EAGAIN; /* erased offending sector. Try mount one more time please. */
}
@@ -1112,7 +1112,7 @@ jffs_scan_flash(struct jffs_control *c)
if (!node) {
if (!(node = jffs_alloc_node())) {
/* Free read buffer */
- kfree (read_buf);
+ kfree(read_buf);
/* Release the flash device */
flash_safe_release(fmc->mtd);
@@ -1269,7 +1269,7 @@ jffs_scan_flash(struct jffs_control *c)
DJM(no_jffs_node--);
/* Free read buffer */
- kfree (read_buf);
+ kfree(read_buf);
/* Release the flash device */
flash_safe_release(fmc->mtd);
@@ -1296,7 +1296,7 @@ jffs_scan_flash(struct jffs_control *c)
flash_safe_release(fmc->flash_part);
/* Free read buffer */
- kfree (read_buf);
+ kfree(read_buf);
return -ENOMEM;
}
@@ -1324,7 +1324,7 @@ jffs_scan_flash(struct jffs_control *c)
jffs_build_end(fmc);
/* Free read buffer */
- kfree (read_buf);
+ kfree(read_buf);
if(!num_free_space){
printk(KERN_WARNING "jffs_scan_flash(): Did not find even a single "
@@ -1747,9 +1747,7 @@ jffs_find_child(struct jffs_file *dir, const char *name, int len)
}
printk("jffs_find_child(): Didn't find the file \"%s\".\n",
(copy ? copy : ""));
- if (copy) {
- kfree(copy);
- }
+ kfree(copy);
});
return f;
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index 5b2a835..1a96903 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -490,7 +490,7 @@ int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *i
up(&f->sem);
jffs2_do_clear_inode(c, f);
}
- kfree (f);
+ kfree(f);
return ret;
}
@@ -742,10 +742,8 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
/* For symlink inodes we us f->dents to store the target path name */
if (S_ISLNK(OFNI_EDONI_2SFFJ(f)->i_mode)) {
- if (f->dents) {
- kfree(f->dents);
- f->dents = NULL;
- }
+ kfree(f->dents);
+ f->dents = NULL;
} else {
fds = f->dents;
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index 316133c..7bc7f2d 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -327,8 +327,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
c->wbuf_ofs = ofs + towrite;
memmove(c->wbuf, rewrite_buf + towrite, c->wbuf_len);
/* Don't muck about with c->wbuf_inodes. False positives are harmless. */
- if (buf)
- kfree(buf);
+ kfree(buf);
} else {
/* OK, now we're left with the dregs in whichever buffer we're using */
if (buf) {
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index 87332f3..c5a3364 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -112,8 +112,7 @@ static struct nlm_lockowner *nlm_find_lockowner(struct nlm_host *host, fl_owner_
}
}
spin_unlock(&host->h_lock);
- if (new != NULL)
- kfree(new);
+ kfree(new);
return res;
}
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c
index de75363..62f4a38 100644
--- a/fs/lockd/svcsubs.c
+++ b/fs/lockd/svcsubs.c
@@ -30,6 +30,36 @@
static struct nlm_file * nlm_files[FILE_NRHASH];
static DECLARE_MUTEX(nlm_file_sema);
+#ifdef NFSD_DEBUG
+static inline void nlm_debug_print_fh(char *msg, struct nfs_fh *f)
+{
+ u32 *fhp = (u32*)f->data;
+
+ /* print the first 32 bytes of the fh */
+ dprintk("lockd: %s (%08x %08x %08x %08x %08x %08x %08x %08x)\n",
+ msg, fhp[0], fhp[1], fhp[2], fhp[3],
+ fhp[4], fhp[5], fhp[6], fhp[7]);
+}
+
+static inline void nlm_debug_print_file(char *msg, struct nlm_file *file)
+{
+ struct inode *inode = file->f_file->f_dentry->d_inode;
+
+ dprintk("lockd: %s %s/%ld\n",
+ msg, inode->i_sb->s_id, inode->i_ino);
+}
+#else
+static inline void nlm_debug_print_fh(char *msg, struct nfs_fh *f)
+{
+ return;
+}
+
+static inline void nlm_debug_print_file(char *msg, struct nlm_file *file)
+{
+ return;
+}
+#endif
+
static inline unsigned int file_hash(struct nfs_fh *f)
{
unsigned int tmp=0;
@@ -55,11 +85,8 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result,
struct nlm_file *file;
unsigned int hash;
u32 nfserr;
- u32 *fhp = (u32*)f->data;
-
- dprintk("lockd: nlm_file_lookup(%08x %08x %08x %08x %08x %08x)\n",
- fhp[0], fhp[1], fhp[2], fhp[3], fhp[4], fhp[5]);
+ nlm_debug_print_fh("nlm_file_lookup", f);
hash = file_hash(f);
@@ -70,8 +97,7 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result,
if (!nfs_compare_fh(&file->f_handle, f))
goto found;
- dprintk("lockd: creating file for (%08x %08x %08x %08x %08x %08x)\n",
- fhp[0], fhp[1], fhp[2], fhp[3], fhp[4], fhp[5]);
+ nlm_debug_print_fh("creating file for", f);
nfserr = nlm_lck_denied_nolocks;
file = (struct nlm_file *) kmalloc(sizeof(*file), GFP_KERNEL);
@@ -124,11 +150,10 @@ out_free:
static inline void
nlm_delete_file(struct nlm_file *file)
{
- struct inode *inode = file->f_file->f_dentry->d_inode;
struct nlm_file **fp, *f;
- dprintk("lockd: closing file %s/%ld\n",
- inode->i_sb->s_id, inode->i_ino);
+ nlm_debug_print_file("closing file", file);
+
fp = nlm_files + file->f_hash;
while ((f = *fp) != NULL) {
if (f == file) {
diff --git a/fs/mbcache.c b/fs/mbcache.c
index 298997f..0f1e453 100644
--- a/fs/mbcache.c
+++ b/fs/mbcache.c
@@ -301,8 +301,7 @@ fail:
if (cache) {
while (--m >= 0)
kfree(cache->c_indexes_hash[m]);
- if (cache->c_block_hash)
- kfree(cache->c_block_hash);
+ kfree(cache->c_block_hash);
kfree(cache);
}
return NULL;
diff --git a/fs/namei.c b/fs/namei.c
index c5769c4..b3f8a19 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1459,7 +1459,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
if (!error) {
DQUOT_INIT(inode);
- error = do_truncate(dentry, 0);
+ error = do_truncate(dentry, 0, NULL);
}
put_write_access(inode);
if (error)
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 44135af..618a327 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -31,11 +31,42 @@ static void nfs_free_delegation(struct nfs_delegation *delegation)
kfree(delegation);
}
+static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state)
+{
+ struct inode *inode = state->inode;
+ struct file_lock *fl;
+ int status;
+
+ for (fl = inode->i_flock; fl != 0; fl = fl->fl_next) {
+ if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
+ continue;
+ if ((struct nfs_open_context *)fl->fl_file->private_data != ctx)
+ continue;
+ status = nfs4_lock_delegation_recall(state, fl);
+ if (status >= 0)
+ continue;
+ switch (status) {
+ default:
+ printk(KERN_ERR "%s: unhandled error %d.\n",
+ __FUNCTION__, status);
+ case -NFS4ERR_EXPIRED:
+ /* kill_proc(fl->fl_pid, SIGLOST, 1); */
+ case -NFS4ERR_STALE_CLIENTID:
+ nfs4_schedule_state_recovery(NFS_SERVER(inode)->nfs4_state);
+ goto out_err;
+ }
+ }
+ return 0;
+out_err:
+ return status;
+}
+
static void nfs_delegation_claim_opens(struct inode *inode)
{
struct nfs_inode *nfsi = NFS_I(inode);
struct nfs_open_context *ctx;
struct nfs4_state *state;
+ int err;
again:
spin_lock(&inode->i_lock);
@@ -47,9 +78,12 @@ again:
continue;
get_nfs_open_context(ctx);
spin_unlock(&inode->i_lock);
- if (nfs4_open_delegation_recall(ctx->dentry, state) < 0)
- return;
+ err = nfs4_open_delegation_recall(ctx->dentry, state);
+ if (err >= 0)
+ err = nfs_delegation_claim_locks(ctx, state);
put_nfs_open_context(ctx);
+ if (err != 0)
+ return;
goto again;
}
spin_unlock(&inode->i_lock);
@@ -115,8 +149,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
}
}
spin_unlock(&clp->cl_lock);
- if (delegation != NULL)
- kfree(delegation);
+ kfree(delegation);
return status;
}
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
index 8017846..2fcc30d 100644
--- a/fs/nfs/delegation.h
+++ b/fs/nfs/delegation.h
@@ -38,6 +38,7 @@ void nfs_delegation_reap_unclaimed(struct nfs4_client *clp);
/* NFSv4 delegation-related procedures */
int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid);
int nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state);
+int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl);
static inline int nfs_have_delegation(struct inode *inode, int flags)
{
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 8272ed3..7370583 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1257,6 +1257,9 @@ dentry->d_parent->d_name.name, dentry->d_name.name);
sprintf(silly, ".nfs%*.*lx",
i_inosize, i_inosize, dentry->d_inode->i_ino);
+ /* Return delegation in anticipation of the rename */
+ nfs_inode_return_delegation(dentry->d_inode);
+
sdentry = NULL;
do {
char *suffix = silly + slen - countersize;
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 6537f2c..b497c71 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -655,7 +655,6 @@ nfs_file_direct_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t
struct file *file = iocb->ki_filp;
struct nfs_open_context *ctx =
(struct nfs_open_context *) file->private_data;
- struct dentry *dentry = file->f_dentry;
struct address_space *mapping = file->f_mapping;
struct inode *inode = mapping->host;
struct iovec iov = {
@@ -664,7 +663,8 @@ nfs_file_direct_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t
};
dprintk("nfs: direct read(%s/%s, %lu@%lu)\n",
- dentry->d_parent->d_name.name, dentry->d_name.name,
+ file->f_dentry->d_parent->d_name.name,
+ file->f_dentry->d_name.name,
(unsigned long) count, (unsigned long) pos);
if (!is_sync_kiocb(iocb))
@@ -730,7 +730,6 @@ nfs_file_direct_write(struct kiocb *iocb, const char __user *buf, size_t count,
struct file *file = iocb->ki_filp;
struct nfs_open_context *ctx =
(struct nfs_open_context *) file->private_data;
- struct dentry *dentry = file->f_dentry;
struct address_space *mapping = file->f_mapping;
struct inode *inode = mapping->host;
struct iovec iov = {
@@ -739,8 +738,9 @@ nfs_file_direct_write(struct kiocb *iocb, const char __user *buf, size_t count,
};
dfprintk(VFS, "nfs: direct write(%s/%s(%ld), %lu@%lu)\n",
- dentry->d_parent->d_name.name, dentry->d_name.name,
- inode->i_ino, (unsigned long) count, (unsigned long) pos);
+ file->f_dentry->d_parent->d_name.name,
+ file->f_dentry->d_name.name, inode->i_ino,
+ (unsigned long) count, (unsigned long) pos);
if (!is_sync_kiocb(iocb))
goto out;
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index fc0f12b..6391d89 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1009,13 +1009,18 @@ void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx)
spin_unlock(&inode->i_lock);
}
-struct nfs_open_context *nfs_find_open_context(struct inode *inode, int mode)
+/*
+ * Given an inode, search for an open context with the desired characteristics
+ */
+struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, int mode)
{
struct nfs_inode *nfsi = NFS_I(inode);
struct nfs_open_context *pos, *ctx = NULL;
spin_lock(&inode->i_lock);
list_for_each_entry(pos, &nfsi->open_files, list) {
+ if (cred != NULL && pos->cred != cred)
+ continue;
if ((pos->mode & mode) == mode) {
ctx = get_nfs_open_context(pos);
break;
@@ -1683,8 +1688,7 @@ static void nfs_kill_super(struct super_block *s)
rpciod_down(); /* release rpciod */
- if (server->hostname != NULL)
- kfree(server->hostname);
+ kfree(server->hostname);
kfree(server);
}
@@ -1903,8 +1907,7 @@ nfs_copy_user_string(char *dst, struct nfs_string *src, int maxlen)
return ERR_PTR(-ENOMEM);
}
if (copy_from_user(dst, src->data, maxlen)) {
- if (p != NULL)
- kfree(p);
+ kfree(p);
return ERR_PTR(-EFAULT);
}
dst[maxlen] = '\0';
@@ -1995,10 +1998,8 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
out_err:
s = (struct super_block *)p;
out_free:
- if (server->mnt_path)
- kfree(server->mnt_path);
- if (server->hostname)
- kfree(server->hostname);
+ kfree(server->mnt_path);
+ kfree(server->hostname);
kfree(server);
return s;
}
@@ -2018,8 +2019,7 @@ static void nfs4_kill_super(struct super_block *sb)
destroy_nfsv4_state(server);
- if (server->hostname != NULL)
- kfree(server->hostname);
+ kfree(server->hostname);
kfree(server);
}
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 78a53f5..b7f262d 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -214,7 +214,7 @@ extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short);
extern int nfs4_proc_setclientid_confirm(struct nfs4_client *);
extern int nfs4_proc_async_renew(struct nfs4_client *);
extern int nfs4_proc_renew(struct nfs4_client *);
-extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state, mode_t mode);
+extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state);
extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *);
@@ -247,7 +247,7 @@ extern void nfs4_drop_state_owner(struct nfs4_state_owner *);
extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *);
extern void nfs4_put_open_state(struct nfs4_state *);
extern void nfs4_close_state(struct nfs4_state *, mode_t);
-extern struct nfs4_state *nfs4_find_state(struct inode *, struct rpc_cred *, mode_t mode);
+extern void nfs4_state_set_mode_locked(struct nfs4_state *, mode_t);
extern void nfs4_schedule_state_recovery(struct nfs4_client *);
extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 933e13b..21482b2 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -214,16 +214,15 @@ static void update_open_stateid(struct nfs4_state *state, nfs4_stateid *stateid,
struct inode *inode = state->inode;
open_flags &= (FMODE_READ|FMODE_WRITE);
- /* Protect against nfs4_find_state() */
+ /* Protect against nfs4_find_state_byowner() */
spin_lock(&state->owner->so_lock);
spin_lock(&inode->i_lock);
- state->state |= open_flags;
- /* NB! List reordering - see the reclaim code for why. */
- if ((open_flags & FMODE_WRITE) && 0 == state->nwriters++)
- list_move(&state->open_states, &state->owner->so_states);
+ memcpy(&state->stateid, stateid, sizeof(state->stateid));
+ if ((open_flags & FMODE_WRITE))
+ state->nwriters++;
if (open_flags & FMODE_READ)
state->nreaders++;
- memcpy(&state->stateid, stateid, sizeof(state->stateid));
+ nfs4_state_set_mode_locked(state, state->state | open_flags);
spin_unlock(&inode->i_lock);
spin_unlock(&state->owner->so_lock);
}
@@ -896,7 +895,6 @@ static void nfs4_close_done(struct rpc_task *task)
break;
case -NFS4ERR_STALE_STATEID:
case -NFS4ERR_EXPIRED:
- state->state = calldata->arg.open_flags;
nfs4_schedule_state_recovery(server->nfs4_state);
break;
default:
@@ -906,7 +904,6 @@ static void nfs4_close_done(struct rpc_task *task)
}
}
nfs_refresh_inode(calldata->inode, calldata->res.fattr);
- state->state = calldata->arg.open_flags;
nfs4_free_closedata(calldata);
}
@@ -920,24 +917,26 @@ static void nfs4_close_begin(struct rpc_task *task)
.rpc_resp = &calldata->res,
.rpc_cred = state->owner->so_cred,
};
- int mode = 0;
+ int mode = 0, old_mode;
int status;
status = nfs_wait_on_sequence(calldata->arg.seqid, task);
if (status != 0)
return;
- /* Don't reorder reads */
- smp_rmb();
/* Recalculate the new open mode in case someone reopened the file
* while we were waiting in line to be scheduled.
*/
- if (state->nreaders != 0)
- mode |= FMODE_READ;
- if (state->nwriters != 0)
- mode |= FMODE_WRITE;
- if (test_bit(NFS_DELEGATED_STATE, &state->flags))
- state->state = mode;
- if (mode == state->state) {
+ spin_lock(&state->owner->so_lock);
+ spin_lock(&calldata->inode->i_lock);
+ mode = old_mode = state->state;
+ if (state->nreaders == 0)
+ mode &= ~FMODE_READ;
+ if (state->nwriters == 0)
+ mode &= ~FMODE_WRITE;
+ nfs4_state_set_mode_locked(state, mode);
+ spin_unlock(&calldata->inode->i_lock);
+ spin_unlock(&state->owner->so_lock);
+ if (mode == old_mode || test_bit(NFS_DELEGATED_STATE, &state->flags)) {
nfs4_free_closedata(calldata);
task->tk_exit = NULL;
rpc_exit(task, 0);
@@ -961,7 +960,7 @@ static void nfs4_close_begin(struct rpc_task *task)
*
* NOTE: Caller must be holding the sp->so_owner semaphore!
*/
-int nfs4_do_close(struct inode *inode, struct nfs4_state *state, mode_t mode)
+int nfs4_do_close(struct inode *inode, struct nfs4_state *state)
{
struct nfs_server *server = NFS_SERVER(inode);
struct nfs4_closedata *calldata;
@@ -1275,7 +1274,8 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
{
struct rpc_cred *cred;
struct inode *inode = dentry->d_inode;
- struct nfs4_state *state;
+ struct nfs_open_context *ctx;
+ struct nfs4_state *state = NULL;
int status;
nfs_fattr_init(fattr);
@@ -1283,22 +1283,18 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
cred = rpcauth_lookupcred(NFS_SERVER(inode)->client->cl_auth, 0);
if (IS_ERR(cred))
return PTR_ERR(cred);
- /* Search for an existing WRITE delegation first */
- state = nfs4_open_delegated(inode, FMODE_WRITE, cred);
- if (!IS_ERR(state)) {
- /* NB: nfs4_open_delegated() bumps the inode->i_count */
- iput(inode);
- } else {
- /* Search for an existing open(O_WRITE) stateid */
- state = nfs4_find_state(inode, cred, FMODE_WRITE);
- }
+
+ /* Search for an existing open(O_WRITE) file */
+ ctx = nfs_find_open_context(inode, cred, FMODE_WRITE);
+ if (ctx != NULL)
+ state = ctx->state;
status = nfs4_do_setattr(NFS_SERVER(inode), fattr,
NFS_FH(inode), sattr, state);
if (status == 0)
nfs_setattr_update_inode(inode, sattr);
- if (state != NULL)
- nfs4_close_state(state, FMODE_WRITE);
+ if (ctx != NULL)
+ put_nfs_open_context(ctx);
put_rpccred(cred);
return status;
}
@@ -2599,12 +2595,10 @@ int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct
case -NFS4ERR_GRACE:
case -NFS4ERR_DELAY:
ret = nfs4_delay(server->client, &exception->timeout);
- if (ret == 0)
- exception->retry = 1;
- break;
+ if (ret != 0)
+ break;
case -NFS4ERR_OLD_STATEID:
- if (ret == 0)
- exception->retry = 1;
+ exception->retry = 1;
}
/* We failed to handle the error */
return nfs4_map_errors(ret);
@@ -2924,6 +2918,10 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *
struct nfs4_lock_state *lsp;
int status;
+ /* Is this a delegated lock? */
+ if (test_bit(NFS_DELEGATED_STATE, &state->flags))
+ return do_vfs_lock(request->fl_file, request);
+
status = nfs4_set_lock_state(state, request);
if (status != 0)
return status;
@@ -3038,6 +3036,9 @@ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request
struct nfs4_exception exception = { };
int err;
+ /* Cache the lock if possible... */
+ if (test_bit(NFS_DELEGATED_STATE, &state->flags))
+ return 0;
do {
err = _nfs4_do_setlk(state, F_SETLK, request, 1);
if (err != -NFS4ERR_DELAY)
@@ -3053,6 +3054,9 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request
struct nfs4_exception exception = { };
int err;
+ err = nfs4_set_lock_state(state, request);
+ if (err != 0)
+ return err;
do {
err = _nfs4_do_setlk(state, F_SETLK, request, 0);
if (err != -NFS4ERR_DELAY)
@@ -3068,15 +3072,25 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock
int status;
down_read(&clp->cl_sem);
- status = nfs4_set_lock_state(state, request);
- if (status == 0)
- status = _nfs4_do_setlk(state, cmd, request, 0);
- if (status == 0) {
- /* Note: we always want to sleep here! */
- request->fl_flags |= FL_SLEEP;
- if (do_vfs_lock(request->fl_file, request) < 0)
- printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __FUNCTION__);
+ /* Is this a delegated open? */
+ if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
+ /* Yes: cache locks! */
+ status = do_vfs_lock(request->fl_file, request);
+ /* ...but avoid races with delegation recall... */
+ if (status < 0 || test_bit(NFS_DELEGATED_STATE, &state->flags))
+ goto out;
}
+ status = nfs4_set_lock_state(state, request);
+ if (status != 0)
+ goto out;
+ status = _nfs4_do_setlk(state, cmd, request, 0);
+ if (status != 0)
+ goto out;
+ /* Note: we always want to sleep here! */
+ request->fl_flags |= FL_SLEEP;
+ if (do_vfs_lock(request->fl_file, request) < 0)
+ printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __FUNCTION__);
+out:
up_read(&clp->cl_sem);
return status;
}
@@ -3130,6 +3144,24 @@ nfs4_proc_lock(struct file *filp, int cmd, struct file_lock *request)
return status;
}
+int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
+{
+ struct nfs_server *server = NFS_SERVER(state->inode);
+ struct nfs4_exception exception = { };
+ int err;
+
+ err = nfs4_set_lock_state(state, fl);
+ if (err != 0)
+ goto out;
+ do {
+ err = _nfs4_do_setlk(state, F_SETLK, fl, 0);
+ if (err != -NFS4ERR_DELAY)
+ break;
+ err = nfs4_handle_exception(server, err, &exception);
+ } while (exception.retry);
+out:
+ return err;
+}
#define XATTR_NAME_NFSV4_ACL "system.nfs4_acl"
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 2d5a6a2..0675f32 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -69,10 +69,8 @@ init_nfsv4_state(struct nfs_server *server)
void
destroy_nfsv4_state(struct nfs_server *server)
{
- if (server->mnt_path) {
- kfree(server->mnt_path);
- server->mnt_path = NULL;
- }
+ kfree(server->mnt_path);
+ server->mnt_path = NULL;
if (server->nfs4_state) {
nfs4_put_client(server->nfs4_state);
server->nfs4_state = NULL;
@@ -311,8 +309,7 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct
new = NULL;
}
spin_unlock(&clp->cl_lock);
- if (new)
- kfree(new);
+ kfree(new);
if (sp != NULL)
return sp;
put_rpccred(cred);
@@ -366,30 +363,21 @@ nfs4_alloc_open_state(void)
return state;
}
-static struct nfs4_state *
-__nfs4_find_state(struct inode *inode, struct rpc_cred *cred, mode_t mode)
+void
+nfs4_state_set_mode_locked(struct nfs4_state *state, mode_t mode)
{
- struct nfs_inode *nfsi = NFS_I(inode);
- struct nfs4_state *state;
-
- mode &= (FMODE_READ|FMODE_WRITE);
- list_for_each_entry(state, &nfsi->open_states, inode_states) {
- if (state->owner->so_cred != cred)
- continue;
- if ((mode & FMODE_READ) != 0 && state->nreaders == 0)
- continue;
- if ((mode & FMODE_WRITE) != 0 && state->nwriters == 0)
- continue;
- if ((state->state & mode) != mode)
- continue;
- atomic_inc(&state->count);
- if (mode & FMODE_READ)
- state->nreaders++;
+ if (state->state == mode)
+ return;
+ /* NB! List reordering - see the reclaim code for why. */
+ if ((mode & FMODE_WRITE) != (state->state & FMODE_WRITE)) {
if (mode & FMODE_WRITE)
- state->nwriters++;
- return state;
+ list_move(&state->open_states, &state->owner->so_states);
+ else
+ list_move_tail(&state->open_states, &state->owner->so_states);
}
- return NULL;
+ if (mode == 0)
+ list_del_init(&state->inode_states);
+ state->state = mode;
}
static struct nfs4_state *
@@ -400,7 +388,7 @@ __nfs4_find_state_byowner(struct inode *inode, struct nfs4_state_owner *owner)
list_for_each_entry(state, &nfsi->open_states, inode_states) {
/* Is this in the process of being freed? */
- if (state->nreaders == 0 && state->nwriters == 0)
+ if (state->state == 0)
continue;
if (state->owner == owner) {
atomic_inc(&state->count);
@@ -410,17 +398,6 @@ __nfs4_find_state_byowner(struct inode *inode, struct nfs4_state_owner *owner)
return NULL;
}
-struct nfs4_state *
-nfs4_find_state(struct inode *inode, struct rpc_cred *cred, mode_t mode)
-{
- struct nfs4_state *state;
-
- spin_lock(&inode->i_lock);
- state = __nfs4_find_state(inode, cred, mode);
- spin_unlock(&inode->i_lock);
- return state;
-}
-
static void
nfs4_free_open_state(struct nfs4_state *state)
{
@@ -481,7 +458,6 @@ void nfs4_put_open_state(struct nfs4_state *state)
spin_unlock(&inode->i_lock);
spin_unlock(&owner->so_lock);
iput(inode);
- BUG_ON (state->state != 0);
nfs4_free_open_state(state);
nfs4_put_state_owner(owner);
}
@@ -493,7 +469,7 @@ void nfs4_close_state(struct nfs4_state *state, mode_t mode)
{
struct inode *inode = state->inode;
struct nfs4_state_owner *owner = state->owner;
- int newstate;
+ int oldstate, newstate = 0;
atomic_inc(&owner->so_count);
/* Protect against nfs4_find_state() */
@@ -503,30 +479,20 @@ void nfs4_close_state(struct nfs4_state *state, mode_t mode)
state->nreaders--;
if (mode & FMODE_WRITE)
state->nwriters--;
- if (state->nwriters == 0) {
- if (state->nreaders == 0)
- list_del_init(&state->inode_states);
- /* See reclaim code */
- list_move_tail(&state->open_states, &owner->so_states);
+ oldstate = newstate = state->state;
+ if (state->nreaders == 0)
+ newstate &= ~FMODE_READ;
+ if (state->nwriters == 0)
+ newstate &= ~FMODE_WRITE;
+ if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
+ nfs4_state_set_mode_locked(state, newstate);
+ oldstate = newstate;
}
spin_unlock(&inode->i_lock);
spin_unlock(&owner->so_lock);
- newstate = 0;
- if (state->state != 0) {
- if (state->nreaders)
- newstate |= FMODE_READ;
- if (state->nwriters)
- newstate |= FMODE_WRITE;
- if (state->state == newstate)
- goto out;
- if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
- state->state = newstate;
- goto out;
- }
- if (nfs4_do_close(inode, state, newstate) == 0)
- return;
- }
-out:
+
+ if (oldstate != newstate && nfs4_do_close(inode, state) == 0)
+ return;
nfs4_put_open_state(state);
nfs4_put_state_owner(owner);
}
@@ -815,7 +781,7 @@ static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_s
int status = 0;
for (fl = inode->i_flock; fl != 0; fl = fl->fl_next) {
- if (!(fl->fl_flags & FL_POSIX))
+ if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
continue;
if (((struct nfs_open_context *)fl->fl_file->private_data)->state != state)
continue;
@@ -830,7 +796,7 @@ static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_s
case -NFS4ERR_NO_GRACE:
case -NFS4ERR_RECLAIM_BAD:
case -NFS4ERR_RECLAIM_CONFLICT:
- /* kill_proc(fl->fl_owner, SIGLOST, 1); */
+ /* kill_proc(fl->fl_pid, SIGLOST, 1); */
break;
case -NFS4ERR_STALE_CLIENTID:
goto out_err;
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 43b03b1..5f20eaf 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -507,7 +507,7 @@ int nfs_readpage(struct file *file, struct page *page)
goto out_error;
if (file == NULL) {
- ctx = nfs_find_open_context(inode, FMODE_READ);
+ ctx = nfs_find_open_context(inode, NULL, FMODE_READ);
if (ctx == NULL)
return -EBADF;
} else
@@ -576,7 +576,7 @@ int nfs_readpages(struct file *filp, struct address_space *mapping,
nr_pages);
if (filp == NULL) {
- desc.ctx = nfs_find_open_context(inode, FMODE_READ);
+ desc.ctx = nfs_find_open_context(inode, NULL, FMODE_READ);
if (desc.ctx == NULL)
return -EBADF;
} else
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index f732541..d639d17 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -52,8 +52,7 @@ nfs_put_unlinkdata(struct nfs_unlinkdata *data)
{
if (--data->count == 0) {
nfs_detach_unlinkdata(data);
- if (data->name.name != NULL)
- kfree(data->name.name);
+ kfree(data->name.name);
kfree(data);
}
}
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 819a65f..8f71e76 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -294,7 +294,7 @@ int nfs_writepage(struct page *page, struct writeback_control *wbc)
if (page->index >= end_index+1 || !offset)
goto out;
do_it:
- ctx = nfs_find_open_context(inode, FMODE_WRITE);
+ ctx = nfs_find_open_context(inode, NULL, FMODE_WRITE);
if (ctx == NULL) {
err = -EBADF;
goto out;
@@ -734,14 +734,14 @@ int nfs_updatepage(struct file *file, struct page *page,
unsigned int offset, unsigned int count)
{
struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data;
- struct dentry *dentry = file->f_dentry;
struct inode *inode = page->mapping->host;
struct nfs_page *req;
int status = 0;
dprintk("NFS: nfs_updatepage(%s/%s %d@%Ld)\n",
- dentry->d_parent->d_name.name, dentry->d_name.name,
- count, (long long)(page_offset(page) +offset));
+ file->f_dentry->d_parent->d_name.name,
+ file->f_dentry->d_name.name, count,
+ (long long)(page_offset(page) +offset));
if (IS_SYNC(inode)) {
status = nfs_writepage_sync(ctx, inode, page, offset, count, 0);
@@ -850,7 +850,6 @@ static void nfs_write_rpcsetup(struct nfs_page *req,
unsigned int count, unsigned int offset,
int how)
{
- struct rpc_task *task = &data->task;
struct inode *inode;
/* Set up the RPC argument and reply structs
@@ -881,7 +880,7 @@ static void nfs_write_rpcsetup(struct nfs_page *req,
data->task.tk_release = nfs_writedata_release;
dprintk("NFS: %4d initiated write call (req %s/%Ld, %u bytes @ offset %Lu)\n",
- task->tk_pid,
+ data->task.tk_pid,
inode->i_sb->s_id,
(long long)NFS_FILEID(inode),
count,
@@ -1217,7 +1216,6 @@ static void nfs_commit_release(struct rpc_task *task)
static void nfs_commit_rpcsetup(struct list_head *head,
struct nfs_write_data *data, int how)
{
- struct rpc_task *task = &data->task;
struct nfs_page *first;
struct inode *inode;
@@ -1248,7 +1246,7 @@ static void nfs_commit_rpcsetup(struct list_head *head,
/* Release requests */
data->task.tk_release = nfs_commit_release;
- dprintk("NFS: %4d initiated commit call\n", task->tk_pid);
+ dprintk("NFS: %4d initiated commit call\n", data->task.tk_pid);
}
/*
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 057aff7..417ec02 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -190,8 +190,7 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
out:
if (dom)
auth_domain_put(dom);
- if (buf)
- kfree(buf);
+ kfree(buf);
return err;
}
@@ -428,8 +427,7 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
path_release(&nd);
if (dom)
auth_domain_put(dom);
- if (buf)
- kfree(buf);
+ kfree(buf);
return err;
}
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index e0e134d..9147b85 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -366,7 +366,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
len = args->len = ntohl(*p++);
hdr = (void*)p - rqstp->rq_arg.head[0].iov_base;
- if (rqstp->rq_arg.len < len + hdr)
+ if (rqstp->rq_arg.len < hdr ||
+ rqstp->rq_arg.len - hdr < len)
return 0;
args->vec[0].iov_base = (void*)p;
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 4c41463..dcd6731 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -151,8 +151,7 @@ static u32 *read_buf(struct nfsd4_compoundargs *argp, int nbytes)
if (nbytes <= sizeof(argp->tmp))
p = argp->tmp;
else {
- if (argp->tmpp)
- kfree(argp->tmpp);
+ kfree(argp->tmpp);
p = argp->tmpp = kmalloc(nbytes, GFP_KERNEL);
if (!p)
return NULL;
@@ -2476,10 +2475,8 @@ void nfsd4_release_compoundargs(struct nfsd4_compoundargs *args)
kfree(args->ops);
args->ops = args->iops;
}
- if (args->tmpp) {
- kfree(args->tmpp);
- args->tmpp = NULL;
- }
+ kfree(args->tmpp);
+ args->tmpp = NULL;
while (args->to_free) {
struct tmpbuf *tb = args->to_free;
args->to_free = tb->next;
diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c
index 119e4d4..d852ebb 100644
--- a/fs/nfsd/nfscache.c
+++ b/fs/nfsd/nfscache.c
@@ -93,8 +93,7 @@ nfsd_cache_shutdown(void)
cache_disabled = 1;
- if (hash_list)
- kfree (hash_list);
+ kfree (hash_list);
hash_list = NULL;
}
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 841c562..a0871b3 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -23,6 +23,7 @@
#include <linux/seq_file.h>
#include <linux/pagemap.h>
#include <linux/init.h>
+#include <linux/string.h>
#include <linux/nfs.h>
#include <linux/nfsd_idmap.h>
@@ -35,6 +36,8 @@
#include <asm/uaccess.h>
+unsigned int nfsd_versbits = ~0;
+
/*
* We have a single directory with 9 nodes in it.
*/
@@ -50,8 +53,15 @@ enum {
NFSD_List,
NFSD_Fh,
NFSD_Threads,
+ NFSD_Versions,
+ /*
+ * The below MUST come last. Otherwise we leave a hole in nfsd_files[]
+ * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops
+ */
+#ifdef CONFIG_NFSD_V4
NFSD_Leasetime,
NFSD_RecoveryDir,
+#endif
};
/*
@@ -66,8 +76,11 @@ static ssize_t write_getfd(struct file *file, char *buf, size_t size);
static ssize_t write_getfs(struct file *file, char *buf, size_t size);
static ssize_t write_filehandle(struct file *file, char *buf, size_t size);
static ssize_t write_threads(struct file *file, char *buf, size_t size);
+static ssize_t write_versions(struct file *file, char *buf, size_t size);
+#ifdef CONFIG_NFSD_V4
static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
+#endif
static ssize_t (*write_op[])(struct file *, char *, size_t) = {
[NFSD_Svc] = write_svc,
@@ -79,8 +92,11 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = {
[NFSD_Getfs] = write_getfs,
[NFSD_Fh] = write_filehandle,
[NFSD_Threads] = write_threads,
+ [NFSD_Versions] = write_versions,
+#ifdef CONFIG_NFSD_V4
[NFSD_Leasetime] = write_leasetime,
[NFSD_RecoveryDir] = write_recoverydir,
+#endif
};
static ssize_t nfsctl_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
@@ -104,9 +120,23 @@ static ssize_t nfsctl_transaction_write(struct file *file, const char __user *bu
return rv;
}
+static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size_t size, loff_t *pos)
+{
+ if (! file->private_data) {
+ /* An attempt to read a transaction file without writing
+ * causes a 0-byte write so that the file can return
+ * state information
+ */
+ ssize_t rv = nfsctl_transaction_write(file, buf, 0, pos);
+ if (rv < 0)
+ return rv;
+ }
+ return simple_transaction_read(file, buf, size, pos);
+}
+
static struct file_operations transaction_ops = {
.write = nfsctl_transaction_write,
- .read = simple_transaction_read,
+ .read = nfsctl_transaction_read,
.release = simple_transaction_release,
};
@@ -329,6 +359,70 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size)
return strlen(buf);
}
+static ssize_t write_versions(struct file *file, char *buf, size_t size)
+{
+ /*
+ * Format:
+ * [-/+]vers [-/+]vers ...
+ */
+ char *mesg = buf;
+ char *vers, sign;
+ int len, num;
+ ssize_t tlen = 0;
+ char *sep;
+
+ if (size>0) {
+ if (nfsd_serv)
+ return -EBUSY;
+ if (buf[size-1] != '\n')
+ return -EINVAL;
+ buf[size-1] = 0;
+
+ vers = mesg;
+ len = qword_get(&mesg, vers, size);
+ if (len <= 0) return -EINVAL;
+ do {
+ sign = *vers;
+ if (sign == '+' || sign == '-')
+ num = simple_strtol((vers+1), NULL, 0);
+ else
+ num = simple_strtol(vers, NULL, 0);
+ switch(num) {
+ case 2:
+ case 3:
+ case 4:
+ if (sign != '-')
+ NFSCTL_VERSET(nfsd_versbits, num);
+ else
+ NFSCTL_VERUNSET(nfsd_versbits, num);
+ break;
+ default:
+ return -EINVAL;
+ }
+ vers += len + 1;
+ tlen += len;
+ } while ((len = qword_get(&mesg, vers, size)) > 0);
+ /* If all get turned off, turn them back on, as
+ * having no versions is BAD
+ */
+ if ((nfsd_versbits & NFSCTL_VERALL)==0)
+ nfsd_versbits = NFSCTL_VERALL;
+ }
+ /* Now write current state into reply buffer */
+ len = 0;
+ sep = "";
+ for (num=2 ; num <= 4 ; num++)
+ if (NFSCTL_VERISSET(NFSCTL_VERALL, num)) {
+ len += sprintf(buf+len, "%s%c%d", sep,
+ NFSCTL_VERISSET(nfsd_versbits, num)?'+':'-',
+ num);
+ sep = " ";
+ }
+ len += sprintf(buf+len, "\n");
+ return len;
+}
+
+#ifdef CONFIG_NFSD_V4
extern time_t nfs4_leasetime(void);
static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
@@ -370,6 +464,7 @@ static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)
status = nfs4_reset_recoverydir(recdir);
return strlen(buf);
}
+#endif
/*----------------------------------------------------------------------------*/
/*
@@ -389,6 +484,7 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
[NFSD_List] = {"exports", &exports_operations, S_IRUGO},
[NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR},
[NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
+ [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
#ifdef CONFIG_NFSD_V4
[NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
[NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 1697539..89ed046 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -30,6 +30,7 @@
#include <linux/nfsd/nfsd.h>
#include <linux/nfsd/stats.h>
#include <linux/nfsd/cache.h>
+#include <linux/nfsd/syscall.h>
#include <linux/lockd/bind.h>
#include <linux/nfsacl.h>
@@ -52,7 +53,7 @@
extern struct svc_program nfsd_program;
static void nfsd(struct svc_rqst *rqstp);
struct timeval nfssvc_boot;
-static struct svc_serv *nfsd_serv;
+ struct svc_serv *nfsd_serv;
static atomic_t nfsd_busy;
static unsigned long nfsd_last_call;
static DEFINE_SPINLOCK(nfsd_call_lock);
@@ -63,6 +64,31 @@ struct nfsd_list {
};
static struct list_head nfsd_list = LIST_HEAD_INIT(nfsd_list);
+static struct svc_version * nfsd_version[] = {
+ [2] = &nfsd_version2,
+#if defined(CONFIG_NFSD_V3)
+ [3] = &nfsd_version3,
+#endif
+#if defined(CONFIG_NFSD_V4)
+ [4] = &nfsd_version4,
+#endif
+};
+
+#define NFSD_MINVERS 2
+#define NFSD_NRVERS (sizeof(nfsd_version)/sizeof(nfsd_version[0]))
+static struct svc_version *nfsd_versions[NFSD_NRVERS];
+
+struct svc_program nfsd_program = {
+ .pg_prog = NFS_PROGRAM, /* program number */
+ .pg_nvers = NFSD_NRVERS, /* nr of entries in nfsd_version */
+ .pg_vers = nfsd_versions, /* version table */
+ .pg_name = "nfsd", /* program name */
+ .pg_class = "nfsd", /* authentication class */
+ .pg_stats = &nfsd_svcstats, /* version table */
+ .pg_authenticate = &svc_set_client, /* export authentication */
+
+};
+
/*
* Maximum number of nfsd processes
*/
@@ -80,11 +106,12 @@ int
nfsd_svc(unsigned short port, int nrservs)
{
int error;
- int none_left;
+ int none_left, found_one, i;
struct list_head *victim;
lock_kernel();
- dprintk("nfsd: creating service\n");
+ dprintk("nfsd: creating service: vers 0x%x\n",
+ nfsd_versbits);
error = -EINVAL;
if (nrservs <= 0)
nrservs = 0;
@@ -99,6 +126,27 @@ nfsd_svc(unsigned short port, int nrservs)
if (error<0)
goto out;
if (!nfsd_serv) {
+ /*
+ * Use the nfsd_ctlbits to define which
+ * versions that will be advertised.
+ * If nfsd_ctlbits doesn't list any version,
+ * export them all.
+ */
+ found_one = 0;
+
+ for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
+ if (NFSCTL_VERISSET(nfsd_versbits, i)) {
+ nfsd_program.pg_vers[i] = nfsd_version[i];
+ found_one = 1;
+ } else
+ nfsd_program.pg_vers[i] = NULL;
+ }
+
+ if (!found_one) {
+ for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++)
+ nfsd_program.pg_vers[i] = nfsd_version[i];
+ }
+
atomic_set(&nfsd_busy, 0);
error = -ENOMEM;
nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE);
@@ -379,6 +427,7 @@ static struct svc_program nfsd_acl_program = {
.pg_name = "nfsd",
.pg_class = "nfsd",
.pg_stats = &nfsd_acl_svcstats,
+ .pg_authenticate = &svc_set_client,
};
static struct svc_stat nfsd_acl_svcstats = {
@@ -389,28 +438,3 @@ static struct svc_stat nfsd_acl_svcstats = {
#else
#define nfsd_acl_program_p NULL
#endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */
-
-extern struct svc_version nfsd_version2, nfsd_version3, nfsd_version4;
-
-static struct svc_version * nfsd_version[] = {
- [2] = &nfsd_version2,
-#if defined(CONFIG_NFSD_V3)
- [3] = &nfsd_version3,
-#endif
-#if defined(CONFIG_NFSD_V4)
- [4] = &nfsd_version4,
-#endif
-};
-
-#define NFSD_NRVERS (sizeof(nfsd_version)/sizeof(nfsd_version[0]))
-struct svc_program nfsd_program = {
- .pg_next = nfsd_acl_program_p,
- .pg_prog = NFS_PROGRAM, /* program number */
- .pg_nvers = NFSD_NRVERS, /* nr of entries in nfsd_version */
- .pg_vers = nfsd_version, /* version table */
- .pg_name = "nfsd", /* program name */
- .pg_class = "nfsd", /* authentication class */
- .pg_stats = &nfsd_svcstats, /* version table */
- .pg_authenticate = &svc_set_client, /* export authentication */
-
-};
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 4f2cd3d..af7c3c3 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -254,12 +254,19 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
/* Get inode */
err = fh_verify(rqstp, fhp, ftype, accmode);
- if (err || !iap->ia_valid)
+ if (err)
goto out;
dentry = fhp->fh_dentry;
inode = dentry->d_inode;
+ /* Ignore any mode updates on symlinks */
+ if (S_ISLNK(inode->i_mode))
+ iap->ia_valid &= ~ATTR_MODE;
+
+ if (!iap->ia_valid)
+ goto out;
+
/* NFSv2 does not differentiate between "set-[ac]time-to-now"
* which only requires access, and "set-[ac]time-to-X" which
* requires ownership.
diff --git a/fs/open.c b/fs/open.c
index 8d06ec9..6e81367 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -194,7 +194,7 @@ out:
return error;
}
-int do_truncate(struct dentry *dentry, loff_t length)
+int do_truncate(struct dentry *dentry, loff_t length, struct file *filp)
{
int err;
struct iattr newattrs;
@@ -205,6 +205,10 @@ int do_truncate(struct dentry *dentry, loff_t length)
newattrs.ia_size = length;
newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
+ if (filp) {
+ newattrs.ia_file = filp;
+ newattrs.ia_valid |= ATTR_FILE;
+ }
down(&dentry->d_inode->i_sem);
err = notify_change(dentry, &newattrs);
@@ -262,7 +266,7 @@ static inline long do_sys_truncate(const char __user * path, loff_t length)
error = locks_verify_truncate(inode, NULL, length);
if (!error) {
DQUOT_INIT(inode);
- error = do_truncate(nd.dentry, length);
+ error = do_truncate(nd.dentry, length, NULL);
}
put_write_access(inode);
@@ -314,7 +318,7 @@ static inline long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
error = locks_verify_truncate(inode, file, length);
if (!error)
- error = do_truncate(dentry, length);
+ error = do_truncate(dentry, length, file);
out_putf:
fput(file);
out:
@@ -887,6 +891,10 @@ struct file *nameidata_to_filp(struct nameidata *nd, int flags)
return filp;
}
+/*
+ * dentry_open() will have done dput(dentry) and mntput(mnt) if it returns an
+ * error.
+ */
struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
{
int error;
@@ -894,8 +902,11 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
error = -ENFILE;
f = get_empty_filp();
- if (f == NULL)
+ if (f == NULL) {
+ dput(dentry);
+ mntput(mnt);
return ERR_PTR(error);
+ }
return __dentry_open(dentry, mnt, flags, f, NULL);
}
diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c
index 1be11ce..aeb0106 100644
--- a/fs/openpromfs/inode.c
+++ b/fs/openpromfs/inode.c
@@ -1088,8 +1088,7 @@ static void __exit exit_openprom_fs(void)
unregister_filesystem(&openprom_fs_type);
free_pages ((unsigned long)nodes, alloced);
for (i = 0; i < aliases_nodes; i++)
- if (alias_names [i])
- kfree (alias_names [i]);
+ kfree (alias_names [i]);
nodes = NULL;
}
diff --git a/fs/partitions/ibm.c b/fs/partitions/ibm.c
index d59dcbf..6327bcb 100644
--- a/fs/partitions/ibm.c
+++ b/fs/partitions/ibm.c
@@ -29,7 +29,7 @@
* cyl-cyl-head-head structure
*/
static inline int
-cchh2blk (cchh_t *ptr, struct hd_geometry *geo) {
+cchh2blk (struct vtoc_cchh *ptr, struct hd_geometry *geo) {
return ptr->cc * geo->heads * geo->sectors +
ptr->hh * geo->sectors;
}
@@ -40,7 +40,7 @@ cchh2blk (cchh_t *ptr, struct hd_geometry *geo) {
* cyl-cyl-head-head-block structure
*/
static inline int
-cchhb2blk (cchhb_t *ptr, struct hd_geometry *geo) {
+cchhb2blk (struct vtoc_cchhb *ptr, struct hd_geometry *geo) {
return ptr->cc * geo->heads * geo->sectors +
ptr->hh * geo->sectors +
ptr->b;
@@ -56,7 +56,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
struct hd_geometry *geo;
char type[5] = {0,};
char name[7] = {0,};
- volume_label_t *vlabel;
+ struct vtoc_volume_label *vlabel;
unsigned char *data;
Sector sect;
@@ -64,7 +64,8 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
goto out_noinfo;
if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL)
goto out_nogeo;
- if ((vlabel = kmalloc(sizeof(volume_label_t), GFP_KERNEL)) == NULL)
+ if ((vlabel = kmalloc(sizeof(struct vtoc_volume_label),
+ GFP_KERNEL)) == NULL)
goto out_novlab;
if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 ||
@@ -86,7 +87,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
strncpy(name, data + 8, 6);
else
strncpy(name, data + 4, 6);
- memcpy (vlabel, data, sizeof(volume_label_t));
+ memcpy (vlabel, data, sizeof(struct vtoc_volume_label));
put_dev_sector(sect);
EBCASC(type, 4);
@@ -129,9 +130,9 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
counter = 0;
while ((data = read_dev_sector(bdev, blk*(blocksize/512),
&sect)) != NULL) {
- format1_label_t f1;
+ struct vtoc_format1_label f1;
- memcpy(&f1, data, sizeof(format1_label_t));
+ memcpy(&f1, data, sizeof(struct vtoc_format1_label));
put_dev_sector(sect);
/* skip FMT4 / FMT5 / FMT7 labels */
diff --git a/fs/quota.c b/fs/quota.c
index 1df7832..612e04d 100644
--- a/fs/quota.c
+++ b/fs/quota.c
@@ -15,6 +15,7 @@
#include <linux/security.h>
#include <linux/syscalls.h>
#include <linux/buffer_head.h>
+#include <linux/quotaops.h>
/* Check validity of generic quotactl commands */
static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
diff --git a/fs/smbfs/request.c b/fs/smbfs/request.c
index 2d85dd7..a0f296d 100644
--- a/fs/smbfs/request.c
+++ b/fs/smbfs/request.c
@@ -786,8 +786,7 @@ int smb_request_recv(struct smb_sb_info *server)
/* We should never be called with any of these states */
case SMB_RECV_END:
case SMB_RECV_REQUEST:
- server->rstate = SMB_RECV_END;
- break;
+ BUG();
}
if (result < 0) {
diff --git a/fs/smbfs/symlink.c b/fs/smbfs/symlink.c
index 0c64bc3..cdc53c4 100644
--- a/fs/smbfs/symlink.c
+++ b/fs/smbfs/symlink.c
@@ -45,7 +45,7 @@ static void *smb_follow_link(struct dentry *dentry, struct nameidata *nd)
int len = smb_proc_read_link(server_from_dentry(dentry),
dentry, link, PATH_MAX - 1);
if (len < 0) {
- putname(link);
+ __putname(link);
link = ERR_PTR(len);
} else {
link[len] = 0;
@@ -59,7 +59,7 @@ static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
{
char *s = nd_get_link(nd);
if (!IS_ERR(s))
- putname(s);
+ __putname(s);
}
struct inode_operations smb_link_inode_operations =
diff --git a/fs/super.c b/fs/super.c
index f60155e..eed6c31 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -474,8 +474,6 @@ rescan:
return NULL;
}
-EXPORT_SYMBOL(user_get_super);
-
asmlinkage long sys_ustat(unsigned dev, struct ustat __user * ubuf)
{
struct super_block *s;
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h
index 0e54922..6636698 100644
--- a/fs/udf/udf_sb.h
+++ b/fs/udf/udf_sb.h
@@ -39,8 +39,7 @@ static inline struct udf_sb_info *UDF_SB(struct super_block *sb)
{\
if (UDF_SB(X))\
{\
- if (UDF_SB_PARTMAPS(X))\
- kfree(UDF_SB_PARTMAPS(X));\
+ kfree(UDF_SB_PARTMAPS(X));\
UDF_SB_PARTMAPS(X) = NULL;\
}\
}
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index f036d69..54828eb 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -472,13 +472,14 @@ static int ufs_read_cylinder_structures (struct super_block *sb) {
return 1;
failed:
- if (base) kfree (base);
+ kfree (base);
if (sbi->s_ucg) {
for (i = 0; i < uspi->s_ncg; i++)
- if (sbi->s_ucg[i]) brelse (sbi->s_ucg[i]);
+ if (sbi->s_ucg[i])
+ brelse (sbi->s_ucg[i]);
kfree (sbi->s_ucg);
for (i = 0; i < UFS_MAX_GROUP_LOADED; i++)
- if (sbi->s_ucpi[i]) kfree (sbi->s_ucpi[i]);
+ kfree (sbi->s_ucpi[i]);
}
UFSD(("EXIT (FAILED)\n"))
return 0;
@@ -981,9 +982,10 @@ magic_found:
dalloc_failed:
iput(inode);
failed:
- if (ubh) ubh_brelse_uspi (uspi);
- if (uspi) kfree (uspi);
- if (sbi) kfree(sbi);
+ if (ubh)
+ ubh_brelse_uspi (uspi);
+ kfree (uspi);
+ kfree(sbi);
sb->s_fs_info = NULL;
UFSD(("EXIT (FAILED)\n"))
return -EINVAL;
diff --git a/fs/xattr.c b/fs/xattr.c
index f6e00c0..a9db225 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -74,8 +74,7 @@ setxattr(struct dentry *d, char __user *name, void __user *value,
}
out:
up(&d->d_inode->i_sem);
- if (kvalue)
- kfree(kvalue);
+ kfree(kvalue);
return error;
}
@@ -173,8 +172,7 @@ getxattr(struct dentry *d, char __user *name, void __user *value, size_t size)
error = -E2BIG;
}
out:
- if (kvalue)
- kfree(kvalue);
+ kfree(kvalue);
return error;
}
@@ -259,8 +257,7 @@ listxattr(struct dentry *d, char __user *list, size_t size)
error = -E2BIG;
}
out:
- if (klist)
- kfree(klist);
+ kfree(klist);
return error;
}
diff --git a/fs/xfs/linux-2.6/kmem.h b/fs/xfs/linux-2.6/kmem.h
index 8f82c1a..c64a29cd 100644
--- a/fs/xfs/linux-2.6/kmem.h
+++ b/fs/xfs/linux-2.6/kmem.h
@@ -30,8 +30,8 @@
#define KM_NOFS 0x0004u
#define KM_MAYFAIL 0x0008u
-#define kmem_zone kmem_cache_s
-#define kmem_zone_t kmem_cache_t
+#define kmem_zone kmem_cache
+#define kmem_zone_t struct kmem_cache
typedef unsigned long xfs_pflags_t;
OpenPOWER on IntegriCloud