Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/viro/vfs

Pull vfs pile #2 from Al Viro:
 "Next pile (and there'll be one or two more).

  The large piece in this one is getting rid of /proc/*/ns/* weirdness;
  among other things, it allows to (finally) make nameidata completely
  opaque outside of fs/namei.c, making for easier further cleanups in
  there"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  coda_venus_readdir(): use file_inode()
  fs/namei.c: fold link_path_walk() call into path_init()
  path_init(): don't bother with LOOKUP_PARENT in argument
  fs/namei.c: new helper (path_cleanup())
  path_init(): store the "base" pointer to file in nameidata itself
  make default ->i_fop have ->open() fail with ENXIO
  make nameidata completely opaque outside of fs/namei.c
  kill proc_ns completely
  take the targets of /proc/*/ns/* symlinks to separate fs
  bury struct proc_ns in fs/proc
  copy address of proc_ns_ops into ns_common
  new helpers: ns_alloc_inum/ns_free_inum
  make proc_ns_operations work with struct ns_common * instead of void *
  switch the rest of proc_ns_operations to working with &...->ns
  netns: switch ->get()/->put()/->install()/->inum() to working with &net->ns
  make mntns ->get()/->put()/->install()/->inum() work with &mnt_ns->ns
  common object embedded into various struct ....ns
  • Loading branch information
torvalds committed Dec 16, 2014
2 parents 31f48fc + 93fe74b commit 603ba7e
Show file tree
Hide file tree
Showing 36 changed files with 416 additions and 430 deletions.
10 changes: 0 additions & 10 deletions arch/ia64/kernel/perfmon.c
Original file line number Diff line number Diff line change
Expand Up @@ -2145,22 +2145,12 @@ pfm_close(struct inode *inode, struct file *filp)
return 0;
}

static int
pfm_no_open(struct inode *irrelevant, struct file *dontcare)
{
DPRINT(("pfm_no_open called\n"));
return -ENXIO;
}



static const struct file_operations pfm_file_ops = {
.llseek = no_llseek,
.read = pfm_read,
.write = pfm_write,
.poll = pfm_poll,
.unlocked_ioctl = pfm_ioctl,
.open = pfm_no_open, /* special open code to disallow open via /proc */
.fasync = pfm_fasync,
.release = pfm_close,
.flush = pfm_flush
Expand Down
2 changes: 1 addition & 1 deletion fs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ obj-y := open.o read_write.o file_table.o super.o \
attr.o bad_inode.o file.o filesystems.o namespace.o \
seq_file.o xattr.o libfs.o fs-writeback.o \
pnode.o splice.o sync.o utimes.o \
stack.o fs_struct.o statfs.o fs_pin.o
stack.o fs_struct.o statfs.o fs_pin.o nsfs.o

ifeq ($(CONFIG_BLOCK),y)
obj-y += buffer.o block_dev.o direct-io.o mpage.o
Expand Down
4 changes: 1 addition & 3 deletions fs/coda/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,6 @@ static int coda_venus_readdir(struct file *coda_file, struct dir_context *ctx)
struct coda_file_info *cfi;
struct coda_inode_info *cii;
struct file *host_file;
struct dentry *de;
struct venus_dirent *vdir;
unsigned long vdir_size = offsetof(struct venus_dirent, d_name);
unsigned int type;
Expand All @@ -438,8 +437,7 @@ static int coda_venus_readdir(struct file *coda_file, struct dir_context *ctx)
BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
host_file = cfi->cfi_container;

de = coda_file->f_path.dentry;
cii = ITOC(de->d_inode);
cii = ITOC(file_inode(coda_file));

vdir = kmalloc(sizeof(*vdir), GFP_KERNEL);
if (!vdir) return -ENOMEM;
Expand Down
11 changes: 8 additions & 3 deletions fs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ int proc_nr_inodes(struct ctl_table *table, int write,
}
#endif

static int no_open(struct inode *inode, struct file *file)
{
return -ENXIO;
}

/**
* inode_init_always - perform inode structure intialisation
* @sb: superblock inode belongs to
Expand All @@ -125,15 +130,15 @@ int proc_nr_inodes(struct ctl_table *table, int write,
int inode_init_always(struct super_block *sb, struct inode *inode)
{
static const struct inode_operations empty_iops;
static const struct file_operations empty_fops;
static const struct file_operations no_open_fops = {.open = no_open};
struct address_space *const mapping = &inode->i_data;

inode->i_sb = sb;
inode->i_blkbits = sb->s_blocksize_bits;
inode->i_flags = 0;
atomic_set(&inode->i_count, 1);
inode->i_op = &empty_iops;
inode->i_fop = &empty_fops;
inode->i_fop = &no_open_fops;
inode->__i_nlink = 1;
inode->i_opflags = 0;
i_uid_write(inode, 0);
Expand Down Expand Up @@ -1798,7 +1803,7 @@ void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev)
} else if (S_ISFIFO(mode))
inode->i_fop = &pipefifo_fops;
else if (S_ISSOCK(mode))
inode->i_fop = &bad_sock_fops;
; /* leave it no_open_fops */
else
printk(KERN_DEBUG "init_special_inode: bogus i_mode (%o) for"
" inode %s:%lu\n", mode, inode->i_sb->s_id,
Expand Down
5 changes: 5 additions & 0 deletions fs/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,8 @@ extern const struct file_operations pipefifo_fops;
*/
extern void sb_pin_kill(struct super_block *sb);
extern void mnt_pin_kill(struct mount *m);

/*
* fs/nsfs.c
*/
extern struct dentry_operations ns_dentry_operations;
3 changes: 2 additions & 1 deletion fs/mount.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#include <linux/mount.h>
#include <linux/seq_file.h>
#include <linux/poll.h>
#include <linux/ns_common.h>

struct mnt_namespace {
atomic_t count;
unsigned int proc_inum;
struct ns_common ns;
struct mount * root;
struct list_head list;
struct user_namespace *user_ns;
Expand Down
98 changes: 51 additions & 47 deletions fs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,19 @@ void path_put(const struct path *path)
}
EXPORT_SYMBOL(path_put);

struct nameidata {
struct path path;
struct qstr last;
struct path root;
struct inode *inode; /* path.dentry.d_inode */
unsigned int flags;
unsigned seq, m_seq;
int last_type;
unsigned depth;
struct file *base;
char *saved_names[MAX_NESTED_LINKS + 1];
};

/*
* Path walking has 2 modes, rcu-walk and ref-walk (see
* Documentation/filesystems/path-lookup.txt). In situations when we can't
Expand Down Expand Up @@ -695,6 +708,18 @@ void nd_jump_link(struct nameidata *nd, struct path *path)
nd->flags |= LOOKUP_JUMPED;
}

void nd_set_link(struct nameidata *nd, char *path)
{
nd->saved_names[nd->depth] = path;
}
EXPORT_SYMBOL(nd_set_link);

char *nd_get_link(struct nameidata *nd)
{
return nd->saved_names[nd->depth];
}
EXPORT_SYMBOL(nd_get_link);

static inline void put_link(struct nameidata *nd, struct path *link, void *cookie)
{
struct inode *inode = link->dentry->d_inode;
Expand Down Expand Up @@ -1821,13 +1846,14 @@ static int link_path_walk(const char *name, struct nameidata *nd)
}

static int path_init(int dfd, const char *name, unsigned int flags,
struct nameidata *nd, struct file **fp)
struct nameidata *nd)
{
int retval = 0;

nd->last_type = LAST_ROOT; /* if there are only slashes... */
nd->flags = flags | LOOKUP_JUMPED;
nd->flags = flags | LOOKUP_JUMPED | LOOKUP_PARENT;
nd->depth = 0;
nd->base = NULL;
if (flags & LOOKUP_ROOT) {
struct dentry *root = nd->root.dentry;
struct inode *inode = root->d_inode;
Expand All @@ -1847,7 +1873,7 @@ static int path_init(int dfd, const char *name, unsigned int flags,
} else {
path_get(&nd->path);
}
return 0;
goto done;
}

nd->root.mnt = NULL;
Expand Down Expand Up @@ -1897,7 +1923,7 @@ static int path_init(int dfd, const char *name, unsigned int flags,
nd->path = f.file->f_path;
if (flags & LOOKUP_RCU) {
if (f.flags & FDPUT_FPUT)
*fp = f.file;
nd->base = f.file;
nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq);
rcu_read_lock();
} else {
Expand All @@ -1908,13 +1934,26 @@ static int path_init(int dfd, const char *name, unsigned int flags,

nd->inode = nd->path.dentry->d_inode;
if (!(flags & LOOKUP_RCU))
return 0;
goto done;
if (likely(!read_seqcount_retry(&nd->path.dentry->d_seq, nd->seq)))
return 0;
goto done;
if (!(nd->flags & LOOKUP_ROOT))
nd->root.mnt = NULL;
rcu_read_unlock();
return -ECHILD;
done:
current->total_link_count = 0;
return link_path_walk(name, nd);
}

static void path_cleanup(struct nameidata *nd)
{
if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT)) {
path_put(&nd->root);
nd->root.mnt = NULL;
}
if (unlikely(nd->base))
fput(nd->base);
}

static inline int lookup_last(struct nameidata *nd, struct path *path)
Expand All @@ -1930,7 +1969,6 @@ static inline int lookup_last(struct nameidata *nd, struct path *path)
static int path_lookupat(int dfd, const char *name,
unsigned int flags, struct nameidata *nd)
{
struct file *base = NULL;
struct path path;
int err;

Expand All @@ -1948,14 +1986,7 @@ static int path_lookupat(int dfd, const char *name,
* be handled by restarting a traditional ref-walk (which will always
* be able to complete).
*/
err = path_init(dfd, name, flags | LOOKUP_PARENT, nd, &base);

if (unlikely(err))
goto out;

current->total_link_count = 0;
err = link_path_walk(name, nd);

err = path_init(dfd, name, flags, nd);
if (!err && !(flags & LOOKUP_PARENT)) {
err = lookup_last(nd, &path);
while (err > 0) {
Expand Down Expand Up @@ -1983,14 +2014,7 @@ static int path_lookupat(int dfd, const char *name,
}
}

out:
if (base)
fput(base);

if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT)) {
path_put(&nd->root);
nd->root.mnt = NULL;
}
path_cleanup(nd);
return err;
}

Expand Down Expand Up @@ -2297,19 +2321,13 @@ mountpoint_last(struct nameidata *nd, struct path *path)
static int
path_mountpoint(int dfd, const char *name, struct path *path, unsigned int flags)
{
struct file *base = NULL;
struct nameidata nd;
int err;

err = path_init(dfd, name, flags | LOOKUP_PARENT, &nd, &base);
err = path_init(dfd, name, flags, &nd);
if (unlikely(err))
goto out;

current->total_link_count = 0;
err = link_path_walk(name, &nd);
if (err)
goto out;

err = mountpoint_last(&nd, path);
while (err > 0) {
void *cookie;
Expand All @@ -2325,12 +2343,7 @@ path_mountpoint(int dfd, const char *name, struct path *path, unsigned int flags
put_link(&nd, &link, cookie);
}
out:
if (base)
fput(base);

if (nd.root.mnt && !(nd.flags & LOOKUP_ROOT))
path_put(&nd.root);

path_cleanup(&nd);
return err;
}

Expand Down Expand Up @@ -3181,7 +3194,6 @@ static int do_tmpfile(int dfd, struct filename *pathname,
static struct file *path_openat(int dfd, struct filename *pathname,
struct nameidata *nd, const struct open_flags *op, int flags)
{
struct file *base = NULL;
struct file *file;
struct path path;
int opened = 0;
Expand All @@ -3198,12 +3210,7 @@ static struct file *path_openat(int dfd, struct filename *pathname,
goto out;
}

error = path_init(dfd, pathname->name, flags | LOOKUP_PARENT, nd, &base);
if (unlikely(error))
goto out;

current->total_link_count = 0;
error = link_path_walk(pathname->name, nd);
error = path_init(dfd, pathname->name, flags, nd);
if (unlikely(error))
goto out;

Expand All @@ -3229,10 +3236,7 @@ static struct file *path_openat(int dfd, struct filename *pathname,
put_link(nd, &link, cookie);
}
out:
if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT))
path_put(&nd->root);
if (base)
fput(base);
path_cleanup(nd);
if (!(opened & FILE_OPENED)) {
BUG_ON(!error);
put_filp(file);
Expand Down
Loading

0 comments on commit 603ba7e

Please sign in to comment.