summaryrefslogtreecommitdiff
path: root/fs/inode.c
diff options
context:
space:
mode:
authorJames Morris <jmorris@namei.org>2009-02-06 11:01:45 +1100
committerJames Morris <jmorris@namei.org>2009-02-06 11:01:45 +1100
commitcb5629b10d64a8006622ce3a52bc887d91057d69 (patch)
tree7c06d8f30783115e3384721046258ce615b129c5 /fs/inode.c
parent8920d5ad6ba74ae8ab020e90cc4d976980e68701 (diff)
parentf01d1d546abb2f4028b5299092f529eefb01253a (diff)
downloadlwn-cb5629b10d64a8006622ce3a52bc887d91057d69.tar.gz
lwn-cb5629b10d64a8006622ce3a52bc887d91057d69.zip
Merge branch 'master' into next
Conflicts: fs/namei.c Manually merged per: diff --cc fs/namei.c index 734f2b5,bbc15c2..0000000 --- a/fs/namei.c +++ b/fs/namei.c @@@ -860,9 -848,8 +849,10 @@@ static int __link_path_walk(const char nd->flags |= LOOKUP_CONTINUE; err = exec_permission_lite(inode); if (err == -EAGAIN) - err = vfs_permission(nd, MAY_EXEC); + err = inode_permission(nd->path.dentry->d_inode, + MAY_EXEC); + if (!err) + err = ima_path_check(&nd->path, MAY_EXEC); if (err) break; @@@ -1525,14 -1506,9 +1509,14 @@@ int may_open(struct path *path, int acc flag &= ~O_TRUNC; } - error = vfs_permission(nd, acc_mode); + error = inode_permission(inode, acc_mode); if (error) return error; + - error = ima_path_check(&nd->path, ++ error = ima_path_check(path, + acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC)); + if (error) + return error; /* * An append-only file must be opened in append mode for writing. */ Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'fs/inode.c')
-rw-r--r--fs/inode.c74
1 files changed, 68 insertions, 6 deletions
diff --git a/fs/inode.c b/fs/inode.c
index ed22b14f2202..40e37c026565 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -23,6 +23,7 @@
#include <linux/bootmem.h>
#include <linux/inotify.h>
#include <linux/mount.h>
+#include <linux/async.h>
/*
* This is needed for the following functions:
@@ -111,8 +112,8 @@ static void wake_up_inode(struct inode *inode)
/**
* inode_init_always - perform inode structure intialisation
- * @sb - superblock inode belongs to.
- * @inode - inode to initialise
+ * @sb: superblock inode belongs to
+ * @inode: inode to initialise
*
* These are initializations that need to be done on every inode
* allocation as the fields are not initialised by slab allocation.
@@ -132,6 +133,8 @@ struct inode *inode_init_always(struct super_block *sb, struct inode *inode)
inode->i_op = &empty_iops;
inode->i_fop = &empty_fops;
inode->i_nlink = 1;
+ inode->i_uid = 0;
+ inode->i_gid = 0;
atomic_set(&inode->i_writecount, 0);
inode->i_size = 0;
inode->i_blocks = 0;
@@ -165,7 +168,7 @@ struct inode *inode_init_always(struct super_block *sb, struct inode *inode)
mapping->a_ops = &empty_aops;
mapping->host = inode;
mapping->flags = 0;
- mapping_set_gfp_mask(mapping, GFP_HIGHUSER_PAGECACHE);
+ mapping_set_gfp_mask(mapping, GFP_HIGHUSER_MOVABLE);
mapping->assoc_mapping = NULL;
mapping->backing_dev_info = &default_backing_dev_info;
mapping->writeback_index = 0;
@@ -584,8 +587,8 @@ __inode_add_to_lists(struct super_block *sb, struct hlist_head *head,
/**
* inode_add_to_lists - add a new inode to relevant lists
- * @sb - superblock inode belongs to.
- * @inode - inode to mark in use
+ * @sb: superblock inode belongs to
+ * @inode: inode to mark in use
*
* When an inode is allocated it needs to be accounted for, added to the in use
* list, the owning superblock and the inode hash. This needs to be done under
@@ -609,7 +612,7 @@ EXPORT_SYMBOL_GPL(inode_add_to_lists);
* @sb: superblock
*
* Allocates a new inode for given superblock. The default gfp_mask
- * for allocations related to inode->i_mapping is GFP_HIGHUSER_PAGECACHE.
+ * for allocations related to inode->i_mapping is GFP_HIGHUSER_MOVABLE.
* If HIGHMEM pages are unsuitable or it is known that pages allocated
* for the page cache are not reclaimable or migratable,
* mapping_set_gfp_mask() must be called with suitable flags on the
@@ -1042,6 +1045,65 @@ struct inode *iget_locked(struct super_block *sb, unsigned long ino)
EXPORT_SYMBOL(iget_locked);
+int insert_inode_locked(struct inode *inode)
+{
+ struct super_block *sb = inode->i_sb;
+ ino_t ino = inode->i_ino;
+ struct hlist_head *head = inode_hashtable + hash(sb, ino);
+ struct inode *old;
+
+ inode->i_state |= I_LOCK|I_NEW;
+ while (1) {
+ spin_lock(&inode_lock);
+ old = find_inode_fast(sb, head, ino);
+ if (likely(!old)) {
+ hlist_add_head(&inode->i_hash, head);
+ spin_unlock(&inode_lock);
+ return 0;
+ }
+ __iget(old);
+ spin_unlock(&inode_lock);
+ wait_on_inode(old);
+ if (unlikely(!hlist_unhashed(&old->i_hash))) {
+ iput(old);
+ return -EBUSY;
+ }
+ iput(old);
+ }
+}
+
+EXPORT_SYMBOL(insert_inode_locked);
+
+int insert_inode_locked4(struct inode *inode, unsigned long hashval,
+ int (*test)(struct inode *, void *), void *data)
+{
+ struct super_block *sb = inode->i_sb;
+ struct hlist_head *head = inode_hashtable + hash(sb, hashval);
+ struct inode *old;
+
+ inode->i_state |= I_LOCK|I_NEW;
+
+ while (1) {
+ spin_lock(&inode_lock);
+ old = find_inode(sb, head, test, data);
+ if (likely(!old)) {
+ hlist_add_head(&inode->i_hash, head);
+ spin_unlock(&inode_lock);
+ return 0;
+ }
+ __iget(old);
+ spin_unlock(&inode_lock);
+ wait_on_inode(old);
+ if (unlikely(!hlist_unhashed(&old->i_hash))) {
+ iput(old);
+ return -EBUSY;
+ }
+ iput(old);
+ }
+}
+
+EXPORT_SYMBOL(insert_inode_locked4);
+
/**
* __insert_inode_hash - hash an inode
* @inode: unhashed inode