summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-21 08:54:32 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-21 08:54:32 -0700
commit2fb59d623ad85dfdb8ce03a660051743f7361896 (patch)
tree3991ab2b88cc369444c136089d9c1570c26c6072 /fs
parentefdc31319d43050a5742fb690b1a4beb68092a94 (diff)
parent74c3cbe33bc077ac1159cadfea608b501e100344 (diff)
Merge branch 'audit.b43' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current
* 'audit.b43' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current: [PATCH] audit: watching subtrees [PATCH] new helper - inotify_evict_watch() [PATCH] new helper - inotify_clone_watch() [PATCH] new helpers - collect_mounts() and release_collected_mounts() [PATCH] pass dentry to audit_inode()/audit_inode_child()
Diffstat (limited to 'fs')
-rw-r--r--fs/dcache.c2
-rw-r--r--fs/debugfs/inode.c2
-rw-r--r--fs/inotify.c43
-rw-r--r--fs/namei.c10
-rw-r--r--fs/namespace.c22
-rw-r--r--fs/open.c4
-rw-r--r--fs/pnode.h1
-rw-r--r--fs/xattr.c8
8 files changed, 78 insertions, 14 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 5489b2d98a0..2bb3f7ac683 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -38,7 +38,7 @@ int sysctl_vfs_cache_pressure __read_mostly = 100;
EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure);
__cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lock);
-static __cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock);
+__cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock);
EXPORT_SYMBOL(dcache_lock);
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 11be8a325e2..6a713b33992 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -413,7 +413,7 @@ struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
d_move(old_dentry, dentry);
fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name,
old_dentry->d_name.name, S_ISDIR(old_dentry->d_inode->i_mode),
- NULL, old_dentry->d_inode);
+ NULL, old_dentry);
fsnotify_oldname_free(old_name);
unlock_rename(new_dir, old_dir);
dput(dentry);
diff --git a/fs/inotify.c b/fs/inotify.c
index 7457501b956..2c5b9215287 100644
--- a/fs/inotify.c
+++ b/fs/inotify.c
@@ -667,6 +667,49 @@ out:
EXPORT_SYMBOL_GPL(inotify_add_watch);
/**
+ * inotify_clone_watch - put the watch next to existing one
+ * @old: already installed watch
+ * @new: new watch
+ *
+ * Caller must hold the inotify_mutex of inode we are dealing with;
+ * it is expected to remove the old watch before unlocking the inode.
+ */
+s32 inotify_clone_watch(struct inotify_watch *old, struct inotify_watch *new)
+{
+ struct inotify_handle *ih = old->ih;
+ int ret = 0;
+
+ new->mask = old->mask;
+ new->ih = ih;
+
+ mutex_lock(&ih->mutex);
+
+ /* Initialize a new watch */
+ ret = inotify_handle_get_wd(ih, new);
+ if (unlikely(ret))
+ goto out;
+ ret = new->wd;
+
+ get_inotify_handle(ih);
+
+ new->inode = igrab(old->inode);
+
+ list_add(&new->h_list, &ih->watches);
+ list_add(&new->i_list, &old->inode->inotify_watches);
+out:
+ mutex_unlock(&ih->mutex);
+ return ret;
+}
+
+void inotify_evict_watch(struct inotify_watch *watch)
+{
+ get_inotify_watch(watch);
+ mutex_lock(&watch->ih->mutex);
+ inotify_remove_watch_locked(watch->ih, watch);
+ mutex_unlock(&watch->ih->mutex);
+}
+
+/**
* inotify_rm_wd - remove a watch from an inotify instance
* @ih: inotify handle
* @wd: watch descriptor to remove
diff --git a/fs/namei.c b/fs/namei.c
index 1e5c7166916..3b993db26ce 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1174,7 +1174,7 @@ static int fastcall do_path_lookup(int dfd, const char *name,
out:
if (unlikely(!retval && !audit_dummy_context() && nd->dentry &&
nd->dentry->d_inode))
- audit_inode(name, nd->dentry->d_inode);
+ audit_inode(name, nd->dentry);
out_fail:
return retval;
@@ -1214,7 +1214,7 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
retval = path_walk(name, nd);
if (unlikely(!retval && !audit_dummy_context() && nd->dentry &&
nd->dentry->d_inode))
- audit_inode(name, nd->dentry->d_inode);
+ audit_inode(name, nd->dentry);
return retval;
@@ -1469,7 +1469,7 @@ static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
return -ENOENT;
BUG_ON(victim->d_parent->d_inode != dir);
- audit_inode_child(victim->d_name.name, victim->d_inode, dir);
+ audit_inode_child(victim->d_name.name, victim, dir);
error = permission(dir,MAY_WRITE | MAY_EXEC, NULL);
if (error)
@@ -1783,7 +1783,7 @@ do_last:
* It already exists.
*/
mutex_unlock(&dir->d_inode->i_mutex);
- audit_inode(pathname, path.dentry->d_inode);
+ audit_inode(pathname, path.dentry);
error = -EEXIST;
if (flag & O_EXCL)
@@ -2562,7 +2562,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
if (!error) {
const char *new_name = old_dentry->d_name.name;
fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir,
- new_dentry->d_inode, old_dentry->d_inode);
+ new_dentry->d_inode, old_dentry);
}
fsnotify_oldname_free(old_name);
diff --git a/fs/namespace.c b/fs/namespace.c
index 860752998fb..06083885b21 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -246,7 +246,7 @@ static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root,
list_add(&mnt->mnt_slave, &old->mnt_slave_list);
mnt->mnt_master = old;
CLEAR_MNT_SHARED(mnt);
- } else {
+ } else if (!(flag & CL_PRIVATE)) {
if ((flag & CL_PROPAGATION) || IS_MNT_SHARED(old))
list_add(&mnt->mnt_share, &old->mnt_share);
if (IS_MNT_SLAVE(old))
@@ -746,6 +746,26 @@ Enomem:
return NULL;
}
+struct vfsmount *collect_mounts(struct vfsmount *mnt, struct dentry *dentry)
+{
+ struct vfsmount *tree;
+ down_read(&namespace_sem);
+ tree = copy_tree(mnt, dentry, CL_COPY_ALL | CL_PRIVATE);
+ up_read(&namespace_sem);
+ return tree;
+}
+
+void drop_collected_mounts(struct vfsmount *mnt)
+{
+ LIST_HEAD(umount_list);
+ down_read(&namespace_sem);
+ spin_lock(&vfsmount_lock);
+ umount_tree(mnt, 0, &umount_list);
+ spin_unlock(&vfsmount_lock);
+ up_read(&namespace_sem);
+ release_mounts(&umount_list);
+}
+
/*
* @source_mnt : mount tree to be attached
* @nd : place the mount tree @source_mnt is attached
diff --git a/fs/open.c b/fs/open.c
index 75385144df7..3b69c53e183 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -569,7 +569,7 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
dentry = file->f_path.dentry;
inode = dentry->d_inode;
- audit_inode(NULL, inode);
+ audit_inode(NULL, dentry);
err = -EROFS;
if (IS_RDONLY(inode))
@@ -727,7 +727,7 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group)
goto out;
dentry = file->f_path.dentry;
- audit_inode(NULL, dentry->d_inode);
+ audit_inode(NULL, dentry);
error = chown_common(dentry, user, group);
fput(file);
out:
diff --git a/fs/pnode.h b/fs/pnode.h
index d45bd8ec36b..f249be2fee7 100644
--- a/fs/pnode.h
+++ b/fs/pnode.h
@@ -22,6 +22,7 @@
#define CL_COPY_ALL 0x04
#define CL_MAKE_SHARED 0x08
#define CL_PROPAGATION 0x10
+#define CL_PRIVATE 0x20
static inline void set_mnt_shared(struct vfsmount *mnt)
{
diff --git a/fs/xattr.c b/fs/xattr.c
index a44fd92caca..6645b7313b3 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -267,7 +267,7 @@ sys_fsetxattr(int fd, char __user *name, void __user *value,
if (!f)
return error;
dentry = f->f_path.dentry;
- audit_inode(NULL, dentry->d_inode);
+ audit_inode(NULL, dentry);
error = setxattr(dentry, name, value, size, flags);
fput(f);
return error;
@@ -349,7 +349,7 @@ sys_fgetxattr(int fd, char __user *name, void __user *value, size_t size)
f = fget(fd);
if (!f)
return error;
- audit_inode(NULL, f->f_path.dentry->d_inode);
+ audit_inode(NULL, f->f_path.dentry);
error = getxattr(f->f_path.dentry, name, value, size);
fput(f);
return error;
@@ -422,7 +422,7 @@ sys_flistxattr(int fd, char __user *list, size_t size)
f = fget(fd);
if (!f)
return error;
- audit_inode(NULL, f->f_path.dentry->d_inode);
+ audit_inode(NULL, f->f_path.dentry);
error = listxattr(f->f_path.dentry, list, size);
fput(f);
return error;
@@ -485,7 +485,7 @@ sys_fremovexattr(int fd, char __user *name)
if (!f)
return error;
dentry = f->f_path.dentry;
- audit_inode(NULL, dentry->d_inode);
+ audit_inode(NULL, dentry);
error = removexattr(dentry, name);
fput(f);
return error;