aboutsummaryrefslogtreecommitdiffstats
path: root/fs/attr.c
diff options
context:
space:
mode:
authornpiggin@suse.de <npiggin@suse.de>2009-08-20 12:35:05 -0400
committeral <al@dizzy.pdmi.ras.ru>2009-09-24 08:41:47 -0400
commit25d9e2d15286281ec834b829a4aaf8969011f1cd (patch)
treee4329a481ca197afae30f04335e023c7d04f7d67 /fs/attr.c
parenteca6f534e61919b28fb21aafbd1c2983deae75be (diff)
truncate: new helpers
Introduce new truncate helpers truncate_pagecache and inode_newsize_ok. vmtruncate is also consolidated from mm/memory.c and mm/nommu.c and into mm/truncate.c. Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Nick Piggin <npiggin@suse.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/attr.c')
-rw-r--r--fs/attr.c46
1 files changed, 44 insertions, 2 deletions
diff --git a/fs/attr.c b/fs/attr.c
index 9fe1b1bd30a8..96d394bdaddf 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -18,7 +18,7 @@
18/* Taken over from the old code... */ 18/* Taken over from the old code... */
19 19
20/* POSIX UID/GID verification for setting inode attributes. */ 20/* POSIX UID/GID verification for setting inode attributes. */
21int inode_change_ok(struct inode *inode, struct iattr *attr) 21int inode_change_ok(const struct inode *inode, struct iattr *attr)
22{ 22{
23 int retval = -EPERM; 23 int retval = -EPERM;
24 unsigned int ia_valid = attr->ia_valid; 24 unsigned int ia_valid = attr->ia_valid;
@@ -60,9 +60,51 @@ fine:
60error: 60error:
61 return retval; 61 return retval;
62} 62}
63
64EXPORT_SYMBOL(inode_change_ok); 63EXPORT_SYMBOL(inode_change_ok);
65 64
65/**
66 * inode_newsize_ok - may this inode be truncated to a given size
67 * @inode: the inode to be truncated
68 * @offset: the new size to assign to the inode
69 * @Returns: 0 on success, -ve errno on failure
70 *
71 * inode_newsize_ok will check filesystem limits and ulimits to check that the
72 * new inode size is within limits. inode_newsize_ok will also send SIGXFSZ
73 * when necessary. Caller must not proceed with inode size change if failure is
74 * returned. @inode must be a file (not directory), with appropriate
75 * permissions to allow truncate (inode_newsize_ok does NOT check these
76 * conditions).
77 *
78 * inode_newsize_ok must be called with i_mutex held.
79 */
80int inode_newsize_ok(const struct inode *inode, loff_t offset)
81{
82 if (inode->i_size < offset) {
83 unsigned long limit;
84
85 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
86 if (limit != RLIM_INFINITY && offset > limit)
87 goto out_sig;
88 if (offset > inode->i_sb->s_maxbytes)
89 goto out_big;
90 } else {
91 /*
92 * truncation of in-use swapfiles is disallowed - it would
93 * cause subsequent swapout to scribble on the now-freed
94 * blocks.
95 */
96 if (IS_SWAPFILE(inode))
97 return -ETXTBSY;
98 }
99
100 return 0;
101out_sig:
102 send_sig(SIGXFSZ, current, 0);
103out_big:
104 return -EFBIG;
105}
106EXPORT_SYMBOL(inode_newsize_ok);
107
66int inode_setattr(struct inode * inode, struct iattr * attr) 108int inode_setattr(struct inode * inode, struct iattr * attr)
67{ 109{
68 unsigned int ia_valid = attr->ia_valid; 110 unsigned int ia_valid = attr->ia_valid;