diff options
| author | Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com> | 2009-01-02 08:41:21 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-02 13:19:35 -0500 |
| commit | e76b7c01e598d2d14ddfdb6ae5c6afe45245d0de (patch) | |
| tree | 1ecd14fb7aa17e49857d20d974e843edd20bbedc /fs/devpts | |
| parent | 59e55e6cf86eb472e8373831c4234252916c53ef (diff) | |
Per-mount allocated_ptys
To enable multiple mounts of devpts, 'allocated_ptys' must be a per-mount
variable rather than a global variable. Move 'allocated_ptys' into the
super_block's s_fs_info.
Changelog[v2]:
Define and use DEVPTS_SB() wrapper.
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/devpts')
| -rw-r--r-- | fs/devpts/inode.c | 55 |
1 files changed, 48 insertions, 7 deletions
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index f96e10a109fe..49d879d911b1 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c | |||
| @@ -30,7 +30,6 @@ | |||
| 30 | #define PTMX_MINOR 2 | 30 | #define PTMX_MINOR 2 |
| 31 | 31 | ||
| 32 | extern int pty_limit; /* Config limit on Unix98 ptys */ | 32 | extern int pty_limit; /* Config limit on Unix98 ptys */ |
| 33 | static DEFINE_IDA(allocated_ptys); | ||
| 34 | static DEFINE_MUTEX(allocated_ptys_lock); | 33 | static DEFINE_MUTEX(allocated_ptys_lock); |
| 35 | 34 | ||
| 36 | static struct vfsmount *devpts_mnt; | 35 | static struct vfsmount *devpts_mnt; |
| @@ -55,6 +54,15 @@ static const match_table_t tokens = { | |||
| 55 | {Opt_err, NULL} | 54 | {Opt_err, NULL} |
| 56 | }; | 55 | }; |
| 57 | 56 | ||
| 57 | struct pts_fs_info { | ||
| 58 | struct ida allocated_ptys; | ||
| 59 | }; | ||
| 60 | |||
| 61 | static inline struct pts_fs_info *DEVPTS_SB(struct super_block *sb) | ||
| 62 | { | ||
| 63 | return sb->s_fs_info; | ||
| 64 | } | ||
| 65 | |||
| 58 | static inline struct super_block *pts_sb_from_inode(struct inode *inode) | 66 | static inline struct super_block *pts_sb_from_inode(struct inode *inode) |
| 59 | { | 67 | { |
| 60 | if (inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC) | 68 | if (inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC) |
| @@ -126,6 +134,19 @@ static const struct super_operations devpts_sops = { | |||
| 126 | .show_options = devpts_show_options, | 134 | .show_options = devpts_show_options, |
| 127 | }; | 135 | }; |
| 128 | 136 | ||
| 137 | static void *new_pts_fs_info(void) | ||
| 138 | { | ||
| 139 | struct pts_fs_info *fsi; | ||
| 140 | |||
| 141 | fsi = kzalloc(sizeof(struct pts_fs_info), GFP_KERNEL); | ||
| 142 | if (!fsi) | ||
| 143 | return NULL; | ||
| 144 | |||
| 145 | ida_init(&fsi->allocated_ptys); | ||
| 146 | |||
| 147 | return fsi; | ||
| 148 | } | ||
| 149 | |||
| 129 | static int | 150 | static int |
| 130 | devpts_fill_super(struct super_block *s, void *data, int silent) | 151 | devpts_fill_super(struct super_block *s, void *data, int silent) |
| 131 | { | 152 | { |
| @@ -137,9 +158,13 @@ devpts_fill_super(struct super_block *s, void *data, int silent) | |||
| 137 | s->s_op = &devpts_sops; | 158 | s->s_op = &devpts_sops; |
| 138 | s->s_time_gran = 1; | 159 | s->s_time_gran = 1; |
| 139 | 160 | ||
| 161 | s->s_fs_info = new_pts_fs_info(); | ||
| 162 | if (!s->s_fs_info) | ||
| 163 | goto fail; | ||
| 164 | |||
| 140 | inode = new_inode(s); | 165 | inode = new_inode(s); |
| 141 | if (!inode) | 166 | if (!inode) |
| 142 | goto fail; | 167 | goto free_fsi; |
| 143 | inode->i_ino = 1; | 168 | inode->i_ino = 1; |
| 144 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 169 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
| 145 | inode->i_blocks = 0; | 170 | inode->i_blocks = 0; |
| @@ -155,6 +180,9 @@ devpts_fill_super(struct super_block *s, void *data, int silent) | |||
| 155 | 180 | ||
| 156 | printk("devpts: get root dentry failed\n"); | 181 | printk("devpts: get root dentry failed\n"); |
| 157 | iput(inode); | 182 | iput(inode); |
| 183 | |||
| 184 | free_fsi: | ||
| 185 | kfree(s->s_fs_info); | ||
| 158 | fail: | 186 | fail: |
| 159 | return -ENOMEM; | 187 | return -ENOMEM; |
| 160 | } | 188 | } |
| @@ -165,11 +193,19 @@ static int devpts_get_sb(struct file_system_type *fs_type, | |||
| 165 | return get_sb_single(fs_type, flags, data, devpts_fill_super, mnt); | 193 | return get_sb_single(fs_type, flags, data, devpts_fill_super, mnt); |
| 166 | } | 194 | } |
| 167 | 195 | ||
| 196 | static void devpts_kill_sb(struct super_block *sb) | ||
| 197 | { | ||
| 198 | struct pts_fs_info *fsi = DEVPTS_SB(sb); | ||
| 199 | |||
| 200 | kfree(fsi); | ||
| 201 | kill_anon_super(sb); | ||
| 202 | } | ||
| 203 | |||
| 168 | static struct file_system_type devpts_fs_type = { | 204 | static struct file_system_type devpts_fs_type = { |
| 169 | .owner = THIS_MODULE, | 205 | .owner = THIS_MODULE, |
| 170 | .name = "devpts", | 206 | .name = "devpts", |
| 171 | .get_sb = devpts_get_sb, | 207 | .get_sb = devpts_get_sb, |
| 172 | .kill_sb = kill_anon_super, | 208 | .kill_sb = devpts_kill_sb, |
| 173 | }; | 209 | }; |
| 174 | 210 | ||
| 175 | /* | 211 | /* |
| @@ -179,16 +215,18 @@ static struct file_system_type devpts_fs_type = { | |||
| 179 | 215 | ||
| 180 | int devpts_new_index(struct inode *ptmx_inode) | 216 | int devpts_new_index(struct inode *ptmx_inode) |
| 181 | { | 217 | { |
| 218 | struct super_block *sb = pts_sb_from_inode(ptmx_inode); | ||
| 219 | struct pts_fs_info *fsi = DEVPTS_SB(sb); | ||
| 182 | int index; | 220 | int index; |
| 183 | int ida_ret; | 221 | int ida_ret; |
| 184 | 222 | ||
| 185 | retry: | 223 | retry: |
| 186 | if (!ida_pre_get(&allocated_ptys, GFP_KERNEL)) { | 224 | if (!ida_pre_get(&fsi->allocated_ptys, GFP_KERNEL)) { |
| 187 | return -ENOMEM; | 225 | return -ENOMEM; |
| 188 | } | 226 | } |
| 189 | 227 | ||
| 190 | mutex_lock(&allocated_ptys_lock); | 228 | mutex_lock(&allocated_ptys_lock); |
| 191 | ida_ret = ida_get_new(&allocated_ptys, &index); | 229 | ida_ret = ida_get_new(&fsi->allocated_ptys, &index); |
| 192 | if (ida_ret < 0) { | 230 | if (ida_ret < 0) { |
| 193 | mutex_unlock(&allocated_ptys_lock); | 231 | mutex_unlock(&allocated_ptys_lock); |
| 194 | if (ida_ret == -EAGAIN) | 232 | if (ida_ret == -EAGAIN) |
| @@ -197,7 +235,7 @@ retry: | |||
| 197 | } | 235 | } |
| 198 | 236 | ||
| 199 | if (index >= pty_limit) { | 237 | if (index >= pty_limit) { |
| 200 | ida_remove(&allocated_ptys, index); | 238 | ida_remove(&fsi->allocated_ptys, index); |
| 201 | mutex_unlock(&allocated_ptys_lock); | 239 | mutex_unlock(&allocated_ptys_lock); |
| 202 | return -EIO; | 240 | return -EIO; |
| 203 | } | 241 | } |
| @@ -207,8 +245,11 @@ retry: | |||
| 207 | 245 | ||
| 208 | void devpts_kill_index(struct inode *ptmx_inode, int idx) | 246 | void devpts_kill_index(struct inode *ptmx_inode, int idx) |
| 209 | { | 247 | { |
| 248 | struct super_block *sb = pts_sb_from_inode(ptmx_inode); | ||
| 249 | struct pts_fs_info *fsi = DEVPTS_SB(sb); | ||
| 250 | |||
| 210 | mutex_lock(&allocated_ptys_lock); | 251 | mutex_lock(&allocated_ptys_lock); |
| 211 | ida_remove(&allocated_ptys, idx); | 252 | ida_remove(&fsi->allocated_ptys, idx); |
| 212 | mutex_unlock(&allocated_ptys_lock); | 253 | mutex_unlock(&allocated_ptys_lock); |
| 213 | } | 254 | } |
| 214 | 255 | ||
