diff options
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/base.c | 16 | ||||
-rw-r--r-- | fs/proc/generic.c | 18 | ||||
-rw-r--r-- | fs/proc/proc_sysctl.c | 15 |
3 files changed, 37 insertions, 12 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index acb7ef80ea4f..a49d9dd06d1d 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -561,9 +561,19 @@ static int proc_setattr(struct dentry *dentry, struct iattr *attr) | |||
561 | return -EPERM; | 561 | return -EPERM; |
562 | 562 | ||
563 | error = inode_change_ok(inode, attr); | 563 | error = inode_change_ok(inode, attr); |
564 | if (!error) | 564 | if (error) |
565 | error = inode_setattr(inode, attr); | 565 | return error; |
566 | return error; | 566 | |
567 | if ((attr->ia_valid & ATTR_SIZE) && | ||
568 | attr->ia_size != i_size_read(inode)) { | ||
569 | error = vmtruncate(inode, attr->ia_size); | ||
570 | if (error) | ||
571 | return error; | ||
572 | } | ||
573 | |||
574 | setattr_copy(inode, attr); | ||
575 | mark_inode_dirty(inode); | ||
576 | return 0; | ||
567 | } | 577 | } |
568 | 578 | ||
569 | static const struct inode_operations proc_def_inode_operations = { | 579 | static const struct inode_operations proc_def_inode_operations = { |
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 2791907744ed..dd29f0337661 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/time.h> | 12 | #include <linux/time.h> |
13 | #include <linux/proc_fs.h> | 13 | #include <linux/proc_fs.h> |
14 | #include <linux/stat.h> | 14 | #include <linux/stat.h> |
15 | #include <linux/mm.h> | ||
15 | #include <linux/module.h> | 16 | #include <linux/module.h> |
16 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
17 | #include <linux/mount.h> | 18 | #include <linux/mount.h> |
@@ -258,17 +259,22 @@ static int proc_notify_change(struct dentry *dentry, struct iattr *iattr) | |||
258 | 259 | ||
259 | error = inode_change_ok(inode, iattr); | 260 | error = inode_change_ok(inode, iattr); |
260 | if (error) | 261 | if (error) |
261 | goto out; | 262 | return error; |
262 | 263 | ||
263 | error = inode_setattr(inode, iattr); | 264 | if ((iattr->ia_valid & ATTR_SIZE) && |
264 | if (error) | 265 | iattr->ia_size != i_size_read(inode)) { |
265 | goto out; | 266 | error = vmtruncate(inode, iattr->ia_size); |
267 | if (error) | ||
268 | return error; | ||
269 | } | ||
270 | |||
271 | setattr_copy(inode, iattr); | ||
272 | mark_inode_dirty(inode); | ||
266 | 273 | ||
267 | de->uid = inode->i_uid; | 274 | de->uid = inode->i_uid; |
268 | de->gid = inode->i_gid; | 275 | de->gid = inode->i_gid; |
269 | de->mode = inode->i_mode; | 276 | de->mode = inode->i_mode; |
270 | out: | 277 | return 0; |
271 | return error; | ||
272 | } | 278 | } |
273 | 279 | ||
274 | static int proc_getattr(struct vfsmount *mnt, struct dentry *dentry, | 280 | static int proc_getattr(struct vfsmount *mnt, struct dentry *dentry, |
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 6ff9981f0a18..5be436ea088e 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c | |||
@@ -329,10 +329,19 @@ static int proc_sys_setattr(struct dentry *dentry, struct iattr *attr) | |||
329 | return -EPERM; | 329 | return -EPERM; |
330 | 330 | ||
331 | error = inode_change_ok(inode, attr); | 331 | error = inode_change_ok(inode, attr); |
332 | if (!error) | 332 | if (error) |
333 | error = inode_setattr(inode, attr); | 333 | return error; |
334 | |||
335 | if ((attr->ia_valid & ATTR_SIZE) && | ||
336 | attr->ia_size != i_size_read(inode)) { | ||
337 | error = vmtruncate(inode, attr->ia_size); | ||
338 | if (error) | ||
339 | return error; | ||
340 | } | ||
334 | 341 | ||
335 | return error; | 342 | setattr_copy(inode, attr); |
343 | mark_inode_dirty(inode); | ||
344 | return 0; | ||
336 | } | 345 | } |
337 | 346 | ||
338 | static int proc_sys_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | 347 | static int proc_sys_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) |