Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/fs/devpts/inode.c (Version 2.6.31.13) and /linux/fs/devpts/inode.c (Version 2.6.11.8)


  1 /* -*- linux-c -*- ---------------------------      1 /* -*- linux-c -*- --------------------------------------------------------- *
  2  *                                                  2  *
  3  * linux/fs/devpts/inode.c                          3  * linux/fs/devpts/inode.c
  4  *                                                  4  *
  5  *  Copyright 1998-2004 H. Peter Anvin -- All       5  *  Copyright 1998-2004 H. Peter Anvin -- All Rights Reserved
  6  *                                                  6  *
  7  * This file is part of the Linux kernel and i      7  * This file is part of the Linux kernel and is made available under
  8  * the terms of the GNU General Public License      8  * the terms of the GNU General Public License, version 2, or at your
  9  * option, any later version, incorporated her      9  * option, any later version, incorporated herein by reference.
 10  *                                                 10  *
 11  * -------------------------------------------     11  * ------------------------------------------------------------------------- */
 12                                                    12 
 13 #include <linux/module.h>                          13 #include <linux/module.h>
 14 #include <linux/init.h>                            14 #include <linux/init.h>
 15 #include <linux/fs.h>                              15 #include <linux/fs.h>
 16 #include <linux/sched.h>                           16 #include <linux/sched.h>
 17 #include <linux/namei.h>                           17 #include <linux/namei.h>
 18 #include <linux/mount.h>                           18 #include <linux/mount.h>
 19 #include <linux/tty.h>                             19 #include <linux/tty.h>
 20 #include <linux/mutex.h>                       << 
 21 #include <linux/idr.h>                         << 
 22 #include <linux/devpts_fs.h>                       20 #include <linux/devpts_fs.h>
 23 #include <linux/parser.h>                      !!  21 #include <linux/xattr.h>
 24 #include <linux/fsnotify.h>                    << 
 25 #include <linux/seq_file.h>                    << 
 26                                                    22 
 27 #define DEVPTS_SUPER_MAGIC 0x1cd1                  23 #define DEVPTS_SUPER_MAGIC 0x1cd1
 28                                                    24 
 29 #define DEVPTS_DEFAULT_MODE 0600               !!  25 extern struct xattr_handler devpts_xattr_security_handler;
 30 /*                                             << 
 31  * ptmx is a new node in /dev/pts and will be  << 
 32  * instance) mode. To prevent surprises in use << 
 33  * ptmx to 0. Use 'chmod' or remount with '-o  << 
 34  * permissions.                                << 
 35  */                                            << 
 36 #define DEVPTS_DEFAULT_PTMX_MODE 0000          << 
 37 #define PTMX_MINOR      2                      << 
 38                                                    26 
 39 extern int pty_limit;                   /* Con !!  27 static struct xattr_handler *devpts_xattr_handlers[] = {
 40 static DEFINE_MUTEX(allocated_ptys_lock);      !!  28 #ifdef CONFIG_DEVPTS_FS_SECURITY
                                                   >>  29         &devpts_xattr_security_handler,
                                                   >>  30 #endif
                                                   >>  31         NULL
                                                   >>  32 };
                                                   >>  33 
                                                   >>  34 static struct inode_operations devpts_file_inode_operations = {
                                                   >>  35 #ifdef CONFIG_DEVPTS_FS_XATTR
                                                   >>  36         .setxattr       = generic_setxattr,
                                                   >>  37         .getxattr       = generic_getxattr,
                                                   >>  38         .listxattr      = generic_listxattr,
                                                   >>  39         .removexattr    = generic_removexattr,
                                                   >>  40 #endif
                                                   >>  41 };
 41                                                    42 
 42 static struct vfsmount *devpts_mnt;                43 static struct vfsmount *devpts_mnt;
                                                   >>  44 static struct dentry *devpts_root;
 43                                                    45 
 44 struct pts_mount_opts {                        !!  46 static struct {
 45         int setuid;                                47         int setuid;
 46         int setgid;                                48         int setgid;
 47         uid_t   uid;                               49         uid_t   uid;
 48         gid_t   gid;                               50         gid_t   gid;
 49         umode_t mode;                              51         umode_t mode;
 50         umode_t ptmxmode;                      !!  52 } config = {.mode = 0600};
 51         int newinstance;                       << 
 52 };                                             << 
 53                                                << 
 54 enum {                                         << 
 55         Opt_uid, Opt_gid, Opt_mode, Opt_ptmxmo << 
 56         Opt_err                                << 
 57 };                                             << 
 58                                                << 
 59 static const match_table_t tokens = {          << 
 60         {Opt_uid, "uid=%u"},                   << 
 61         {Opt_gid, "gid=%u"},                   << 
 62         {Opt_mode, "mode=%o"},                 << 
 63 #ifdef CONFIG_DEVPTS_MULTIPLE_INSTANCES        << 
 64         {Opt_ptmxmode, "ptmxmode=%o"},         << 
 65         {Opt_newinstance, "newinstance"},      << 
 66 #endif                                         << 
 67         {Opt_err, NULL}                        << 
 68 };                                             << 
 69                                                << 
 70 struct pts_fs_info {                           << 
 71         struct ida allocated_ptys;             << 
 72         struct pts_mount_opts mount_opts;      << 
 73         struct dentry *ptmx_dentry;            << 
 74 };                                             << 
 75                                                << 
 76 static inline struct pts_fs_info *DEVPTS_SB(st << 
 77 {                                              << 
 78         return sb->s_fs_info;                  << 
 79 }                                              << 
 80                                                << 
 81 static inline struct super_block *pts_sb_from_ << 
 82 {                                              << 
 83 #ifdef CONFIG_DEVPTS_MULTIPLE_INSTANCES        << 
 84         if (inode->i_sb->s_magic == DEVPTS_SUP << 
 85                 return inode->i_sb;            << 
 86 #endif                                         << 
 87         return devpts_mnt->mnt_sb;             << 
 88 }                                              << 
 89                                                    53 
 90 #define PARSE_MOUNT     0                      !!  54 static int devpts_remount(struct super_block *sb, int *flags, char *data)
 91 #define PARSE_REMOUNT   1                      << 
 92                                                << 
 93 /*                                             << 
 94  * parse_mount_options():                      << 
 95  *      Set @opts to mount options specified i << 
 96  *      specified in @data, set it to its defa << 
 97  *      'newinstance' option which can only be << 
 98  *      cannot be changed during remount).     << 
 99  *                                             << 
100  * Note: @data may be NULL (in which case all  << 
101  */                                            << 
102 static int parse_mount_options(char *data, int << 
103 {                                                  55 {
104         char *p;                               !!  56         int setuid = 0;
105                                                !!  57         int setgid = 0;
106         opts->setuid  = 0;                     !!  58         uid_t uid = 0;
107         opts->setgid  = 0;                     !!  59         gid_t gid = 0;
108         opts->uid     = 0;                     !!  60         umode_t mode = 0600;
109         opts->gid     = 0;                     !!  61         char *this_char;
110         opts->mode    = DEVPTS_DEFAULT_MODE;   !!  62 
111         opts->ptmxmode = DEVPTS_DEFAULT_PTMX_M !!  63         this_char = NULL;
112                                                !!  64         while ((this_char = strsep(&data, ",")) != NULL) {
113         /* newinstance makes sense only on ini !!  65                 int n;
114         if (op == PARSE_MOUNT)                 !!  66                 char dummy;
115                 opts->newinstance = 0;         !!  67                 if (!*this_char)
116                                                << 
117         while ((p = strsep(&data, ",")) != NUL << 
118                 substring_t args[MAX_OPT_ARGS] << 
119                 int token;                     << 
120                 int option;                    << 
121                                                << 
122                 if (!*p)                       << 
123                         continue;                  68                         continue;
124                                                !!  69                 if (sscanf(this_char, "uid=%i%c", &n, &dummy) == 1) {
125                 token = match_token(p, tokens, !!  70                         setuid = 1;
126                 switch (token) {               !!  71                         uid = n;
127                 case Opt_uid:                  !!  72                 } else if (sscanf(this_char, "gid=%i%c", &n, &dummy) == 1) {
128                         if (match_int(&args[0] !!  73                         setgid = 1;
129                                 return -EINVAL !!  74                         gid = n;
130                         opts->uid = option;    !!  75                 } else if (sscanf(this_char, "mode=%o%c", &n, &dummy) == 1)
131                         opts->setuid = 1;      !!  76                         mode = n & ~S_IFMT;
132                         break;                 !!  77                 else {
133                 case Opt_gid:                  !!  78                         printk("devpts: called with bogus options\n");
134                         if (match_int(&args[0] << 
135                                 return -EINVAL << 
136                         opts->gid = option;    << 
137                         opts->setgid = 1;      << 
138                         break;                 << 
139                 case Opt_mode:                 << 
140                         if (match_octal(&args[ << 
141                                 return -EINVAL << 
142                         opts->mode = option &  << 
143                         break;                 << 
144 #ifdef CONFIG_DEVPTS_MULTIPLE_INSTANCES        << 
145                 case Opt_ptmxmode:             << 
146                         if (match_octal(&args[ << 
147                                 return -EINVAL << 
148                         opts->ptmxmode = optio << 
149                         break;                 << 
150                 case Opt_newinstance:          << 
151                         /* newinstance makes s << 
152                         if (op == PARSE_MOUNT) << 
153                                 opts->newinsta << 
154                         break;                 << 
155 #endif                                         << 
156                 default:                       << 
157                         printk(KERN_ERR "devpt << 
158                         return -EINVAL;            79                         return -EINVAL;
159                 }                                  80                 }
160         }                                          81         }
                                                   >>  82         config.setuid  = setuid;
                                                   >>  83         config.setgid  = setgid;
                                                   >>  84         config.uid     = uid;
                                                   >>  85         config.gid     = gid;
                                                   >>  86         config.mode    = mode;
161                                                    87 
162         return 0;                                  88         return 0;
163 }                                                  89 }
164                                                    90 
165 #ifdef CONFIG_DEVPTS_MULTIPLE_INSTANCES        !!  91 static struct super_operations devpts_sops = {
166 static int mknod_ptmx(struct super_block *sb)  << 
167 {                                              << 
168         int mode;                              << 
169         int rc = -ENOMEM;                      << 
170         struct dentry *dentry;                 << 
171         struct inode *inode;                   << 
172         struct dentry *root = sb->s_root;      << 
173         struct pts_fs_info *fsi = DEVPTS_SB(sb << 
174         struct pts_mount_opts *opts = &fsi->mo << 
175                                                << 
176         mutex_lock(&root->d_inode->i_mutex);   << 
177                                                << 
178         /* If we have already created ptmx nod << 
179         if (fsi->ptmx_dentry) {                << 
180                 rc = 0;                        << 
181                 goto out;                      << 
182         }                                      << 
183                                                << 
184         dentry = d_alloc_name(root, "ptmx");   << 
185         if (!dentry) {                         << 
186                 printk(KERN_NOTICE "Unable to  << 
187                 goto out;                      << 
188         }                                      << 
189                                                << 
190         /*                                     << 
191          * Create a new 'ptmx' node in this mo << 
192          */                                    << 
193         inode = new_inode(sb);                 << 
194         if (!inode) {                          << 
195                 printk(KERN_ERR "Unable to all << 
196                 dput(dentry);                  << 
197                 goto out;                      << 
198         }                                      << 
199                                                << 
200         inode->i_ino = 2;                      << 
201         inode->i_mtime = inode->i_atime = inod << 
202                                                << 
203         mode = S_IFCHR|opts->ptmxmode;         << 
204         init_special_inode(inode, mode, MKDEV( << 
205                                                << 
206         d_add(dentry, inode);                  << 
207                                                << 
208         fsi->ptmx_dentry = dentry;             << 
209         rc = 0;                                << 
210 out:                                           << 
211         mutex_unlock(&root->d_inode->i_mutex); << 
212         return rc;                             << 
213 }                                              << 
214                                                << 
215 static void update_ptmx_mode(struct pts_fs_inf << 
216 {                                              << 
217         struct inode *inode;                   << 
218         if (fsi->ptmx_dentry) {                << 
219                 inode = fsi->ptmx_dentry->d_in << 
220                 inode->i_mode = S_IFCHR|fsi->m << 
221         }                                      << 
222 }                                              << 
223 #else                                          << 
224 static inline void update_ptmx_mode(struct pts << 
225 {                                              << 
226        return;                                 << 
227 }                                              << 
228 #endif                                         << 
229                                                << 
230 static int devpts_remount(struct super_block * << 
231 {                                              << 
232         int err;                               << 
233         struct pts_fs_info *fsi = DEVPTS_SB(sb << 
234         struct pts_mount_opts *opts = &fsi->mo << 
235                                                << 
236         err = parse_mount_options(data, PARSE_ << 
237                                                << 
238         /*                                     << 
239          * parse_mount_options() restores opti << 
240          * before parsing and may have changed << 
241          * mode in the inode too. Bogus option << 
242          * so do this even on error return.    << 
243          */                                    << 
244         update_ptmx_mode(fsi);                 << 
245                                                << 
246         return err;                            << 
247 }                                              << 
248                                                << 
249 static int devpts_show_options(struct seq_file << 
250 {                                              << 
251         struct pts_fs_info *fsi = DEVPTS_SB(vf << 
252         struct pts_mount_opts *opts = &fsi->mo << 
253                                                << 
254         if (opts->setuid)                      << 
255                 seq_printf(seq, ",uid=%u", opt << 
256         if (opts->setgid)                      << 
257                 seq_printf(seq, ",gid=%u", opt << 
258         seq_printf(seq, ",mode=%03o", opts->mo << 
259 #ifdef CONFIG_DEVPTS_MULTIPLE_INSTANCES        << 
260         seq_printf(seq, ",ptmxmode=%03o", opts << 
261 #endif                                         << 
262                                                << 
263         return 0;                              << 
264 }                                              << 
265                                                << 
266 static const struct super_operations devpts_so << 
267         .statfs         = simple_statfs,           92         .statfs         = simple_statfs,
268         .remount_fs     = devpts_remount,          93         .remount_fs     = devpts_remount,
269         .show_options   = devpts_show_options, << 
270 };                                                 94 };
271                                                    95 
272 static void *new_pts_fs_info(void)             << 
273 {                                              << 
274         struct pts_fs_info *fsi;               << 
275                                                << 
276         fsi = kzalloc(sizeof(struct pts_fs_inf << 
277         if (!fsi)                              << 
278                 return NULL;                   << 
279                                                << 
280         ida_init(&fsi->allocated_ptys);        << 
281         fsi->mount_opts.mode = DEVPTS_DEFAULT_ << 
282         fsi->mount_opts.ptmxmode = DEVPTS_DEFA << 
283                                                << 
284         return fsi;                            << 
285 }                                              << 
286                                                << 
287 static int                                         96 static int
288 devpts_fill_super(struct super_block *s, void      97 devpts_fill_super(struct super_block *s, void *data, int silent)
289 {                                                  98 {
290         struct inode *inode;                   !!  99         struct inode * inode;
291                                                   100 
292         s->s_blocksize = 1024;                    101         s->s_blocksize = 1024;
293         s->s_blocksize_bits = 10;                 102         s->s_blocksize_bits = 10;
294         s->s_magic = DEVPTS_SUPER_MAGIC;          103         s->s_magic = DEVPTS_SUPER_MAGIC;
295         s->s_op = &devpts_sops;                   104         s->s_op = &devpts_sops;
                                                   >> 105         s->s_xattr = devpts_xattr_handlers;
296         s->s_time_gran = 1;                       106         s->s_time_gran = 1;
297                                                   107 
298         s->s_fs_info = new_pts_fs_info();      << 
299         if (!s->s_fs_info)                     << 
300                 goto fail;                     << 
301                                                << 
302         inode = new_inode(s);                     108         inode = new_inode(s);
303         if (!inode)                               109         if (!inode)
304                 goto free_fsi;                 !! 110                 goto fail;
305         inode->i_ino = 1;                         111         inode->i_ino = 1;
306         inode->i_mtime = inode->i_atime = inod    112         inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
                                                   >> 113         inode->i_blocks = 0;
                                                   >> 114         inode->i_blksize = 1024;
                                                   >> 115         inode->i_uid = inode->i_gid = 0;
307         inode->i_mode = S_IFDIR | S_IRUGO | S_    116         inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
308         inode->i_op = &simple_dir_inode_operat    117         inode->i_op = &simple_dir_inode_operations;
309         inode->i_fop = &simple_dir_operations;    118         inode->i_fop = &simple_dir_operations;
310         inode->i_nlink = 2;                       119         inode->i_nlink = 2;
311                                                   120 
312         s->s_root = d_alloc_root(inode);       !! 121         devpts_root = s->s_root = d_alloc_root(inode);
313         if (s->s_root)                            122         if (s->s_root)
314                 return 0;                         123                 return 0;
315                                                !! 124         
316         printk(KERN_ERR "devpts: get root dent !! 125         printk("devpts: get root dentry failed\n");
317         iput(inode);                              126         iput(inode);
318                                                << 
319 free_fsi:                                      << 
320         kfree(s->s_fs_info);                   << 
321 fail:                                             127 fail:
322         return -ENOMEM;                           128         return -ENOMEM;
323 }                                                 129 }
324                                                   130 
325 #ifdef CONFIG_DEVPTS_MULTIPLE_INSTANCES        !! 131 static struct super_block *devpts_get_sb(struct file_system_type *fs_type,
326 static int compare_init_pts_sb(struct super_bl !! 132         int flags, const char *dev_name, void *data)
327 {                                              << 
328         if (devpts_mnt)                        << 
329                 return devpts_mnt->mnt_sb == s << 
330         return 0;                              << 
331 }                                              << 
332                                                << 
333 /*                                             << 
334  * devpts_get_sb()                             << 
335  *                                             << 
336  *     If the '-o newinstance' mount option wa << 
337  *     (private) instance of devpts.  PTYs cre << 
338  *     independent of the PTYs in other devpts << 
339  *                                             << 
340  *     If the '-o newinstance' option was not  << 
341  *     initial kernel mount of devpts.  This t << 
342  *     legacy, single-instance semantics.      << 
343  *                                             << 
344  *     The 'newinstance' option is needed to s << 
345  *     semantics in devpts while preserving ba << 
346  *     current 'single-namespace' semantics. i << 
347  *     without the 'newinstance' mount option  << 
348  *     kernel mount, like get_sb_single().     << 
349  *                                             << 
350  *     Mounts with 'newinstance' option create << 
351  *                                             << 
352  *     NOTE:                                   << 
353  *                                             << 
354  *     For single-mount semantics, devpts cann << 
355  *     because get_sb_single()/sget() find and << 
356  *     the most recent mount of devpts. But th << 
357  *     'newinstance' mount and get_sb_single() << 
358  *     super-block instead of the initial supe << 
359  */                                            << 
360 static int devpts_get_sb(struct file_system_ty << 
361         int flags, const char *dev_name, void  << 
362 {                                              << 
363         int error;                             << 
364         struct pts_mount_opts opts;            << 
365         struct super_block *s;                 << 
366                                                << 
367         error = parse_mount_options(data, PARS << 
368         if (error)                             << 
369                 return error;                  << 
370                                                << 
371         if (opts.newinstance)                  << 
372                 s = sget(fs_type, NULL, set_an << 
373         else                                   << 
374                 s = sget(fs_type, compare_init << 
375                                                << 
376         if (IS_ERR(s))                         << 
377                 return PTR_ERR(s);             << 
378                                                << 
379         if (!s->s_root) {                      << 
380                 s->s_flags = flags;            << 
381                 error = devpts_fill_super(s, d << 
382                 if (error)                     << 
383                         goto out_undo_sget;    << 
384                 s->s_flags |= MS_ACTIVE;       << 
385         }                                      << 
386                                                << 
387         simple_set_mnt(mnt, s);                << 
388                                                << 
389         memcpy(&(DEVPTS_SB(s))->mount_opts, &o << 
390                                                << 
391         error = mknod_ptmx(s);                 << 
392         if (error)                             << 
393                 goto out_dput;                 << 
394                                                << 
395         return 0;                              << 
396                                                << 
397 out_dput:                                      << 
398         dput(s->s_root); /* undo dget() in sim << 
399                                                << 
400 out_undo_sget:                                 << 
401         deactivate_locked_super(s);            << 
402         return error;                          << 
403 }                                              << 
404                                                << 
405 #else                                          << 
406 /*                                             << 
407  * This supports only the legacy single-instan << 
408  * multiple-instance semantics)                << 
409  */                                            << 
410 static int devpts_get_sb(struct file_system_ty << 
411                 const char *dev_name, void *da << 
412 {                                              << 
413         return get_sb_single(fs_type, flags, d << 
414 }                                              << 
415 #endif                                         << 
416                                                << 
417 static void devpts_kill_sb(struct super_block  << 
418 {                                                 133 {
419         struct pts_fs_info *fsi = DEVPTS_SB(sb !! 134         return get_sb_single(fs_type, flags, data, devpts_fill_super);
420                                                << 
421         kfree(fsi);                            << 
422         kill_litter_super(sb);                 << 
423 }                                                 135 }
424                                                   136 
425 static struct file_system_type devpts_fs_type     137 static struct file_system_type devpts_fs_type = {
                                                   >> 138         .owner          = THIS_MODULE,
426         .name           = "devpts",               139         .name           = "devpts",
427         .get_sb         = devpts_get_sb,          140         .get_sb         = devpts_get_sb,
428         .kill_sb        = devpts_kill_sb,      !! 141         .kill_sb        = kill_anon_super,
429 };                                                142 };
430                                                   143 
431 /*                                                144 /*
432  * The normal naming convention is simply /dev    145  * The normal naming convention is simply /dev/pts/<number>; this conforms
433  * to the System V naming convention              146  * to the System V naming convention
434  */                                               147  */
435                                                   148 
436 int devpts_new_index(struct inode *ptmx_inode) !! 149 static struct dentry *get_node(int num)
437 {                                                 150 {
438         struct super_block *sb = pts_sb_from_i !! 151         char s[12];
439         struct pts_fs_info *fsi = DEVPTS_SB(sb !! 152         struct dentry *root = devpts_root;
440         int index;                             !! 153         down(&root->d_inode->i_sem);
441         int ida_ret;                           !! 154         return lookup_one_len(s, root, sprintf(s, "%d", num));
442                                                << 
443 retry:                                         << 
444         if (!ida_pre_get(&fsi->allocated_ptys, << 
445                 return -ENOMEM;                << 
446                                                << 
447         mutex_lock(&allocated_ptys_lock);      << 
448         ida_ret = ida_get_new(&fsi->allocated_ << 
449         if (ida_ret < 0) {                     << 
450                 mutex_unlock(&allocated_ptys_l << 
451                 if (ida_ret == -EAGAIN)        << 
452                         goto retry;            << 
453                 return -EIO;                   << 
454         }                                      << 
455                                                << 
456         if (index >= pty_limit) {              << 
457                 ida_remove(&fsi->allocated_pty << 
458                 mutex_unlock(&allocated_ptys_l << 
459                 return -EIO;                   << 
460         }                                      << 
461         mutex_unlock(&allocated_ptys_lock);    << 
462         return index;                          << 
463 }                                              << 
464                                                << 
465 void devpts_kill_index(struct inode *ptmx_inod << 
466 {                                              << 
467         struct super_block *sb = pts_sb_from_i << 
468         struct pts_fs_info *fsi = DEVPTS_SB(sb << 
469                                                << 
470         mutex_lock(&allocated_ptys_lock);      << 
471         ida_remove(&fsi->allocated_ptys, idx); << 
472         mutex_unlock(&allocated_ptys_lock);    << 
473 }                                                 155 }
474                                                   156 
475 int devpts_pty_new(struct inode *ptmx_inode, s !! 157 int devpts_pty_new(struct tty_struct *tty)
476 {                                                 158 {
477         /* tty layer puts index from devpts_ne << 
478         int number = tty->index;                  159         int number = tty->index;
479         struct tty_driver *driver = tty->drive    160         struct tty_driver *driver = tty->driver;
480         dev_t device = MKDEV(driver->major, dr    161         dev_t device = MKDEV(driver->major, driver->minor_start+number);
481         struct dentry *dentry;                    162         struct dentry *dentry;
482         struct super_block *sb = pts_sb_from_i !! 163         struct inode *inode = new_inode(devpts_mnt->mnt_sb);
483         struct inode *inode = new_inode(sb);   << 
484         struct dentry *root = sb->s_root;      << 
485         struct pts_fs_info *fsi = DEVPTS_SB(sb << 
486         struct pts_mount_opts *opts = &fsi->mo << 
487         char s[12];                            << 
488                                                   164 
489         /* We're supposed to be given the slav    165         /* We're supposed to be given the slave end of a pty */
490         BUG_ON(driver->type != TTY_DRIVER_TYPE    166         BUG_ON(driver->type != TTY_DRIVER_TYPE_PTY);
491         BUG_ON(driver->subtype != PTY_TYPE_SLA    167         BUG_ON(driver->subtype != PTY_TYPE_SLAVE);
492                                                   168 
493         if (!inode)                               169         if (!inode)
494                 return -ENOMEM;                   170                 return -ENOMEM;
495                                                   171 
496         inode->i_ino = number + 3;             !! 172         inode->i_ino = number+2;
497         inode->i_uid = opts->setuid ? opts->ui !! 173         inode->i_blksize = 1024;
498         inode->i_gid = opts->setgid ? opts->gi !! 174         inode->i_uid = config.setuid ? config.uid : current->fsuid;
                                                   >> 175         inode->i_gid = config.setgid ? config.gid : current->fsgid;
499         inode->i_mtime = inode->i_atime = inod    176         inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
500         init_special_inode(inode, S_IFCHR|opts !! 177         init_special_inode(inode, S_IFCHR|config.mode, device);
501         inode->i_private = tty;                !! 178         inode->i_op = &devpts_file_inode_operations;
502         tty->driver_data = inode;              !! 179         inode->u.generic_ip = tty;
503                                                !! 180 
504         sprintf(s, "%d", number);              !! 181         dentry = get_node(number);
505                                                !! 182         if (!IS_ERR(dentry) && !dentry->d_inode)
506         mutex_lock(&root->d_inode->i_mutex);   !! 183                 d_instantiate(dentry, inode);
507                                                << 
508         dentry = d_alloc_name(root, s);        << 
509         if (!IS_ERR(dentry)) {                 << 
510                 d_add(dentry, inode);          << 
511                 fsnotify_create(root->d_inode, << 
512         }                                      << 
513                                                   184 
514         mutex_unlock(&root->d_inode->i_mutex); !! 185         up(&devpts_root->d_inode->i_sem);
515                                                   186 
516         return 0;                                 187         return 0;
517 }                                                 188 }
518                                                   189 
519 struct tty_struct *devpts_get_tty(struct inode !! 190 struct tty_struct *devpts_get_tty(int number)
520 {                                                 191 {
521         struct dentry *dentry;                 !! 192         struct dentry *dentry = get_node(number);
522         struct tty_struct *tty;                   193         struct tty_struct *tty;
523                                                   194 
524         BUG_ON(pts_inode->i_rdev == MKDEV(TTYA << 
525                                                << 
526         /* Ensure dentry has not been deleted  << 
527         dentry = d_find_alias(pts_inode);      << 
528         if (!dentry)                           << 
529                 return NULL;                   << 
530                                                << 
531         tty = NULL;                               195         tty = NULL;
532         if (pts_inode->i_sb->s_magic == DEVPTS !! 196         if (!IS_ERR(dentry)) {
533                 tty = (struct tty_struct *)pts !! 197                 if (dentry->d_inode)
                                                   >> 198                         tty = dentry->d_inode->u.generic_ip;
                                                   >> 199                 dput(dentry);
                                                   >> 200         }
534                                                   201 
535         dput(dentry);                          !! 202         up(&devpts_root->d_inode->i_sem);
536                                                   203 
537         return tty;                               204         return tty;
538 }                                                 205 }
539                                                   206 
540 void devpts_pty_kill(struct tty_struct *tty)   !! 207 void devpts_pty_kill(int number)
541 {                                                 208 {
542         struct inode *inode = tty->driver_data !! 209         struct dentry *dentry = get_node(number);
543         struct super_block *sb = pts_sb_from_i << 
544         struct dentry *root = sb->s_root;      << 
545         struct dentry *dentry;                 << 
546                                                << 
547         BUG_ON(inode->i_rdev == MKDEV(TTYAUX_M << 
548                                                   210 
549         mutex_lock(&root->d_inode->i_mutex);   !! 211         if (!IS_ERR(dentry)) {
550                                                !! 212                 struct inode *inode = dentry->d_inode;
551         dentry = d_find_alias(inode);          !! 213                 if (inode) {
552         if (IS_ERR(dentry))                    !! 214                         inode->i_nlink--;
553                 goto out;                      !! 215                         d_delete(dentry);
554                                                !! 216                         dput(dentry);
555         if (dentry) {                          !! 217                 }
556                 inode->i_nlink--;              !! 218                 dput(dentry);
557                 d_delete(dentry);              << 
558                 dput(dentry);   /* d_alloc_nam << 
559         }                                         219         }
560                                                !! 220         up(&devpts_root->d_inode->i_sem);
561         dput(dentry);           /* d_find_alia << 
562 out:                                           << 
563         mutex_unlock(&root->d_inode->i_mutex); << 
564 }                                                 221 }
565                                                   222 
566 static int __init init_devpts_fs(void)            223 static int __init init_devpts_fs(void)
567 {                                                 224 {
568         int err = register_filesystem(&devpts_    225         int err = register_filesystem(&devpts_fs_type);
569         if (!err) {                               226         if (!err) {
570                 devpts_mnt = kern_mount(&devpt    227                 devpts_mnt = kern_mount(&devpts_fs_type);
571                 if (IS_ERR(devpts_mnt)) {      !! 228                 if (IS_ERR(devpts_mnt))
572                         err = PTR_ERR(devpts_m    229                         err = PTR_ERR(devpts_mnt);
573                         unregister_filesystem( << 
574                 }                              << 
575         }                                         230         }
576         return err;                               231         return err;
577 }                                                 232 }
                                                   >> 233 
                                                   >> 234 static void __exit exit_devpts_fs(void)
                                                   >> 235 {
                                                   >> 236         unregister_filesystem(&devpts_fs_type);
                                                   >> 237         mntput(devpts_mnt);
                                                   >> 238 }
                                                   >> 239 
578 module_init(init_devpts_fs)                       240 module_init(init_devpts_fs)
                                                   >> 241 module_exit(exit_devpts_fs)
                                                   >> 242 MODULE_LICENSE("GPL");
579                                                   243 
  This page was automatically generated by the LXR engine.