~ubuntu-branches/ubuntu/quantal/linux-lowlatency/quantal-proposed

« back to all changes in this revision

Viewing changes to security/inode.c

  • Committer: Package Import Robot
  • Author(s): Andy Whitcroft, Andy Whitcroft
  • Date: 2012-06-21 09:16:38 UTC
  • Revision ID: package-import@ubuntu.com-20120621091638-gubhv4nox8xez1ct
Tags: 3.5.0-1.1
[ Andy Whitcroft]

* Rebuild lowlatency against Ubuntu-3.5.0-1.1
* All new configuration system to allow configuration deltas to be
  exposed via debian.lowlatency/config-delta

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
static struct vfsmount *mount;
26
26
static int mount_count;
27
27
 
28
 
/*
29
 
 * TODO:
30
 
 *   I think I can get rid of these default_file_ops, but not quite sure...
31
 
 */
32
 
static ssize_t default_read_file(struct file *file, char __user *buf,
33
 
                                 size_t count, loff_t *ppos)
34
 
{
35
 
        return 0;
36
 
}
37
 
 
38
 
static ssize_t default_write_file(struct file *file, const char __user *buf,
39
 
                                   size_t count, loff_t *ppos)
40
 
{
41
 
        return count;
42
 
}
43
 
 
44
 
static int default_open(struct inode *inode, struct file *file)
45
 
{
46
 
        if (inode->i_private)
47
 
                file->private_data = inode->i_private;
48
 
 
49
 
        return 0;
50
 
}
51
 
 
52
 
static const struct file_operations default_file_ops = {
53
 
        .read =         default_read_file,
54
 
        .write =        default_write_file,
55
 
        .open =         default_open,
56
 
        .llseek =       noop_llseek,
57
 
};
58
 
 
59
 
static struct inode *get_inode(struct super_block *sb, umode_t mode, dev_t dev)
60
 
{
61
 
        struct inode *inode = new_inode(sb);
62
 
 
63
 
        if (inode) {
64
 
                inode->i_ino = get_next_ino();
65
 
                inode->i_mode = mode;
66
 
                inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
67
 
                switch (mode & S_IFMT) {
68
 
                default:
69
 
                        init_special_inode(inode, mode, dev);
70
 
                        break;
71
 
                case S_IFREG:
72
 
                        inode->i_fop = &default_file_ops;
73
 
                        break;
74
 
                case S_IFDIR:
75
 
                        inode->i_op = &simple_dir_inode_operations;
76
 
                        inode->i_fop = &simple_dir_operations;
77
 
 
78
 
                        /* directory inodes start off with i_nlink == 2 (for "." entry) */
79
 
                        inc_nlink(inode);
80
 
                        break;
81
 
                }
82
 
        }
83
 
        return inode;
84
 
}
85
 
 
86
 
/* SMP-safe */
87
 
static int mknod(struct inode *dir, struct dentry *dentry,
88
 
                         umode_t mode, dev_t dev)
89
 
{
90
 
        struct inode *inode;
91
 
        int error = -ENOMEM;
92
 
 
93
 
        if (dentry->d_inode)
94
 
                return -EEXIST;
95
 
 
96
 
        inode = get_inode(dir->i_sb, mode, dev);
97
 
        if (inode) {
98
 
                d_instantiate(dentry, inode);
99
 
                dget(dentry);
100
 
                error = 0;
101
 
        }
102
 
        return error;
103
 
}
104
 
 
105
 
static int mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
106
 
{
107
 
        int res;
108
 
 
109
 
        mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
110
 
        res = mknod(dir, dentry, mode, 0);
111
 
        if (!res)
112
 
                inc_nlink(dir);
113
 
        return res;
114
 
}
115
 
 
116
 
static int create(struct inode *dir, struct dentry *dentry, umode_t mode)
117
 
{
118
 
        mode = (mode & S_IALLUGO) | S_IFREG;
119
 
        return mknod(dir, dentry, mode, 0);
120
 
}
121
 
 
122
28
static inline int positive(struct dentry *dentry)
123
29
{
124
30
        return dentry->d_inode && !d_unhashed(dentry);
145
51
        .kill_sb =      kill_litter_super,
146
52
};
147
53
 
148
 
static int create_by_name(const char *name, umode_t mode,
149
 
                          struct dentry *parent,
150
 
                          struct dentry **dentry)
151
 
{
152
 
        int error = 0;
153
 
 
154
 
        *dentry = NULL;
155
 
 
156
 
        /* If the parent is not specified, we create it in the root.
157
 
         * We need the root dentry to do this, which is in the super
158
 
         * block. A pointer to that is in the struct vfsmount that we
159
 
         * have around.
160
 
         */
161
 
        if (!parent)
162
 
                parent = mount->mnt_sb->s_root;
163
 
 
164
 
        mutex_lock(&parent->d_inode->i_mutex);
165
 
        *dentry = lookup_one_len(name, parent, strlen(name));
166
 
        if (!IS_ERR(*dentry)) {
167
 
                if ((mode & S_IFMT) == S_IFDIR)
168
 
                        error = mkdir(parent->d_inode, *dentry, mode);
169
 
                else
170
 
                        error = create(parent->d_inode, *dentry, mode);
171
 
                if (error)
172
 
                        dput(*dentry);
173
 
        } else
174
 
                error = PTR_ERR(*dentry);
175
 
        mutex_unlock(&parent->d_inode->i_mutex);
176
 
 
177
 
        return error;
178
 
}
179
 
 
180
54
/**
181
55
 * securityfs_create_file - create a file in the securityfs filesystem
182
56
 *
209
83
                                   struct dentry *parent, void *data,
210
84
                                   const struct file_operations *fops)
211
85
{
212
 
        struct dentry *dentry = NULL;
 
86
        struct dentry *dentry;
 
87
        int is_dir = S_ISDIR(mode);
 
88
        struct inode *dir, *inode;
213
89
        int error;
214
90
 
 
91
        if (!is_dir) {
 
92
                BUG_ON(!fops);
 
93
                mode = (mode & S_IALLUGO) | S_IFREG;
 
94
        }
 
95
 
215
96
        pr_debug("securityfs: creating file '%s'\n",name);
216
97
 
217
98
        error = simple_pin_fs(&fs_type, &mount, &mount_count);
218
 
        if (error) {
219
 
                dentry = ERR_PTR(error);
220
 
                goto exit;
221
 
        }
222
 
 
223
 
        error = create_by_name(name, mode, parent, &dentry);
224
 
        if (error) {
225
 
                dentry = ERR_PTR(error);
226
 
                simple_release_fs(&mount, &mount_count);
227
 
                goto exit;
228
 
        }
 
99
        if (error)
 
100
                return ERR_PTR(error);
 
101
 
 
102
        if (!parent)
 
103
                parent = mount->mnt_root;
 
104
 
 
105
        dir = parent->d_inode;
 
106
 
 
107
        mutex_lock(&dir->i_mutex);
 
108
        dentry = lookup_one_len(name, parent, strlen(name));
 
109
        if (IS_ERR(dentry))
 
110
                goto out;
229
111
 
230
112
        if (dentry->d_inode) {
231
 
                if (fops)
232
 
                        dentry->d_inode->i_fop = fops;
233
 
                if (data)
234
 
                        dentry->d_inode->i_private = data;
235
 
        }
236
 
exit:
 
113
                error = -EEXIST;
 
114
                goto out1;
 
115
        }
 
116
 
 
117
        inode = new_inode(dir->i_sb);
 
118
        if (!inode) {
 
119
                error = -ENOMEM;
 
120
                goto out1;
 
121
        }
 
122
 
 
123
        inode->i_ino = get_next_ino();
 
124
        inode->i_mode = mode;
 
125
        inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 
126
        inode->i_private = data;
 
127
        if (is_dir) {
 
128
                inode->i_op = &simple_dir_inode_operations;
 
129
                inode->i_fop = &simple_dir_operations;
 
130
                inc_nlink(inode);
 
131
                inc_nlink(dir);
 
132
        } else {
 
133
                inode->i_fop = fops;
 
134
        }
 
135
        d_instantiate(dentry, inode);
 
136
        dget(dentry);
 
137
        mutex_unlock(&dir->i_mutex);
 
138
        return dentry;
 
139
 
 
140
out1:
 
141
        dput(dentry);
 
142
        dentry = ERR_PTR(error);
 
143
out:
 
144
        mutex_unlock(&dir->i_mutex);
 
145
        simple_release_fs(&mount, &mount_count);
237
146
        return dentry;
238
147
}
239
148
EXPORT_SYMBOL_GPL(securityfs_create_file);