git://ftp.safe.ca
/
safe
/
jmp
/
linux-2.6
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
netfilter: nfnetlink_log: fix silly refcount leak
[safe/jmp/linux-2.6]
/
mm
/
shmem.c
diff --git
a/mm/shmem.c
b/mm/shmem.c
index
ccf446a
..
eef4ebe
100644
(file)
--- a/
mm/shmem.c
+++ b/
mm/shmem.c
@@
-29,7
+29,6
@@
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/swap.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/swap.h>
-#include <linux/ima.h>
static struct vfsmount *shm_mnt;
static struct vfsmount *shm_mnt;
@@
-42,6
+41,7
@@
static struct vfsmount *shm_mnt;
#include <linux/xattr.h>
#include <linux/exportfs.h>
#include <linux/xattr.h>
#include <linux/exportfs.h>
+#include <linux/posix_acl.h>
#include <linux/generic_acl.h>
#include <linux/mman.h>
#include <linux/string.h>
#include <linux/generic_acl.h>
#include <linux/mman.h>
#include <linux/string.h>
@@
-218,7
+218,7
@@
static const struct file_operations shmem_file_operations;
static const struct inode_operations shmem_inode_operations;
static const struct inode_operations shmem_dir_inode_operations;
static const struct inode_operations shmem_special_inode_operations;
static const struct inode_operations shmem_inode_operations;
static const struct inode_operations shmem_dir_inode_operations;
static const struct inode_operations shmem_special_inode_operations;
-static struct vm_operations_struct shmem_vm_ops;
+static
const
struct vm_operations_struct shmem_vm_ops;
static struct backing_dev_info shmem_backing_dev_info __read_mostly = {
.ra_pages = 0, /* No readahead */
static struct backing_dev_info shmem_backing_dev_info __read_mostly = {
.ra_pages = 0, /* No readahead */
@@
-810,7
+810,7
@@
static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
error = inode_setattr(inode, attr);
#ifdef CONFIG_TMPFS_POSIX_ACL
if (!error && (attr->ia_valid & ATTR_MODE))
error = inode_setattr(inode, attr);
#ifdef CONFIG_TMPFS_POSIX_ACL
if (!error && (attr->ia_valid & ATTR_MODE))
- error = generic_acl_chmod(inode
, &shmem_acl_ops
);
+ error = generic_acl_chmod(inode);
#endif
if (page)
page_cache_release(page);
#endif
if (page)
page_cache_release(page);
@@
-1017,7
+1017,14
@@
int shmem_unuse(swp_entry_t entry, struct page *page)
goto out;
}
mutex_unlock(&shmem_swaplist_mutex);
goto out;
}
mutex_unlock(&shmem_swaplist_mutex);
-out: return found; /* 0 or 1 or -ENOMEM */
+ /*
+ * Can some race bring us here? We've been holding page lock,
+ * so I think not; but would rather try again later than BUG()
+ */
+ unlock_page(page);
+ page_cache_release(page);
+out:
+ return (found < 0) ? found : 0;
}
/*
}
/*
@@
-1080,7
+1087,7
@@
static int shmem_writepage(struct page *page, struct writeback_control *wbc)
else
inode = NULL;
spin_unlock(&info->lock);
else
inode = NULL;
spin_unlock(&info->lock);
- swap_
duplicate
(swap);
+ swap_
shmem_alloc
(swap);
BUG_ON(page_mapped(page));
page_cache_release(page); /* pagecache ref */
swap_writepage(page, wbc);
BUG_ON(page_mapped(page));
page_cache_release(page); /* pagecache ref */
swap_writepage(page, wbc);
@@
-1817,11
+1824,15
@@
shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
return error;
}
}
return error;
}
}
- error = shmem_acl_init(inode, dir);
+#ifdef CONFIG_TMPFS_POSIX_ACL
+ error = generic_acl_init(inode, dir);
if (error) {
iput(inode);
return error;
}
if (error) {
iput(inode);
return error;
}
+#else
+ error = 0;
+#endif
if (dir->i_mode & S_ISGID) {
inode->i_gid = dir->i_gid;
if (S_ISDIR(mode))
if (dir->i_mode & S_ISGID) {
inode->i_gid = dir->i_gid;
if (S_ISDIR(mode))
@@
-2036,27
+2047,28
@@
static const struct inode_operations shmem_symlink_inode_operations = {
* filesystem level, though.
*/
* filesystem level, though.
*/
-static size_t shmem_xattr_security_list(struct
inode *inode
, char *list,
+static size_t shmem_xattr_security_list(struct
dentry *dentry
, char *list,
size_t list_len, const char *name,
size_t list_len, const char *name,
- size_t name_len)
+ size_t name_len
, int handler_flags
)
{
{
- return security_inode_listsecurity(inode, list, list_len);
+ return security_inode_listsecurity(
dentry->d_
inode, list, list_len);
}
}
-static int shmem_xattr_security_get(struct
inode *inode
, const char *name,
-
void *buffer, size_t size
)
+static int shmem_xattr_security_get(struct
dentry *dentry
, const char *name,
+
void *buffer, size_t size, int handler_flags
)
{
if (strcmp(name, "") == 0)
return -EINVAL;
{
if (strcmp(name, "") == 0)
return -EINVAL;
- return xattr_getsecurity(inode, name, buffer, size);
+ return xattr_getsecurity(
dentry->d_
inode, name, buffer, size);
}
}
-static int shmem_xattr_security_set(struct
inode *inode
, const char *name,
-
const void *value, size_t size, int
flags)
+static int shmem_xattr_security_set(struct
dentry *dentry
, const char *name,
+
const void *value, size_t size, int flags, int handler_
flags)
{
if (strcmp(name, "") == 0)
return -EINVAL;
{
if (strcmp(name, "") == 0)
return -EINVAL;
- return security_inode_setsecurity(inode, name, value, size, flags);
+ return security_inode_setsecurity(dentry->d_inode, name, value,
+ size, flags);
}
static struct xattr_handler shmem_xattr_security_handler = {
}
static struct xattr_handler shmem_xattr_security_handler = {
@@
-2067,8
+2079,8
@@
static struct xattr_handler shmem_xattr_security_handler = {
};
static struct xattr_handler *shmem_xattr_handlers[] = {
};
static struct xattr_handler *shmem_xattr_handlers[] = {
- &
shmem_xattr
_acl_access_handler,
- &
shmem_xattr
_acl_default_handler,
+ &
generic
_acl_access_handler,
+ &
generic
_acl_default_handler,
&shmem_xattr_security_handler,
NULL
};
&shmem_xattr_security_handler,
NULL
};
@@
-2447,7
+2459,7
@@
static const struct inode_operations shmem_inode_operations = {
.getxattr = generic_getxattr,
.listxattr = generic_listxattr,
.removexattr = generic_removexattr,
.getxattr = generic_getxattr,
.listxattr = generic_listxattr,
.removexattr = generic_removexattr,
- .check_acl =
shmem
_check_acl,
+ .check_acl =
generic
_check_acl,
#endif
};
#endif
};
@@
-2470,7
+2482,7
@@
static const struct inode_operations shmem_dir_inode_operations = {
.getxattr = generic_getxattr,
.listxattr = generic_listxattr,
.removexattr = generic_removexattr,
.getxattr = generic_getxattr,
.listxattr = generic_listxattr,
.removexattr = generic_removexattr,
- .check_acl =
shmem
_check_acl,
+ .check_acl =
generic
_check_acl,
#endif
};
#endif
};
@@
-2481,7
+2493,7
@@
static const struct inode_operations shmem_special_inode_operations = {
.getxattr = generic_getxattr,
.listxattr = generic_listxattr,
.removexattr = generic_removexattr,
.getxattr = generic_getxattr,
.listxattr = generic_listxattr,
.removexattr = generic_removexattr,
- .check_acl =
shmem
_check_acl,
+ .check_acl =
generic
_check_acl,
#endif
};
#endif
};
@@
-2498,7
+2510,7
@@
static const struct super_operations shmem_ops = {
.put_super = shmem_put_super,
};
.put_super = shmem_put_super,
};
-static struct vm_operations_struct shmem_vm_ops = {
+static
const
struct vm_operations_struct shmem_vm_ops = {
.fault = shmem_fault,
#ifdef CONFIG_NUMA
.set_policy = shmem_set_policy,
.fault = shmem_fault,
#ifdef CONFIG_NUMA
.set_policy = shmem_set_policy,
@@
-2619,7
+2631,8
@@
struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags
int error;
struct file *file;
struct inode *inode;
int error;
struct file *file;
struct inode *inode;
- struct dentry *dentry, *root;
+ struct path path;
+ struct dentry *root;
struct qstr this;
if (IS_ERR(shm_mnt))
struct qstr this;
if (IS_ERR(shm_mnt))
@@
-2636,38
+2649,35
@@
struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags
this.len = strlen(name);
this.hash = 0; /* will go */
root = shm_mnt->mnt_root;
this.len = strlen(name);
this.hash = 0; /* will go */
root = shm_mnt->mnt_root;
- dentry = d_alloc(root, &this);
- if (!dentry)
+
path.
dentry = d_alloc(root, &this);
+ if (!
path.
dentry)
goto put_memory;
goto put_memory;
-
- error = -ENFILE;
- file = get_empty_filp();
- if (!file)
- goto put_dentry;
+ path.mnt = mntget(shm_mnt);
error = -ENOSPC;
inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0, flags);
if (!inode)
error = -ENOSPC;
inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0, flags);
if (!inode)
- goto
close_file
;
+ goto
put_dentry
;
- d_instantiate(dentry, inode);
+ d_instantiate(
path.
dentry, inode);
inode->i_size = size;
inode->i_nlink = 0; /* It is unlinked */
inode->i_size = size;
inode->i_nlink = 0; /* It is unlinked */
- init_file(file, shm_mnt, dentry, FMODE_WRITE | FMODE_READ,
- &shmem_file_operations);
-
#ifndef CONFIG_MMU
error = ramfs_nommu_expand_for_mapping(inode, size);
if (error)
#ifndef CONFIG_MMU
error = ramfs_nommu_expand_for_mapping(inode, size);
if (error)
- goto
close_file
;
+ goto
put_dentry
;
#endif
#endif
- ima_counts_get(file);
+
+ error = -ENFILE;
+ file = alloc_file(&path, FMODE_WRITE | FMODE_READ,
+ &shmem_file_operations);
+ if (!file)
+ goto put_dentry;
+
return file;
return file;
-close_file:
- put_filp(file);
put_dentry:
put_dentry:
-
dput(dentry
);
+
path_put(&path
);
put_memory:
shmem_unacct_size(flags, size);
return ERR_PTR(error);
put_memory:
shmem_unacct_size(flags, size);
return ERR_PTR(error);