aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2010-07-20 03:51:31 -0400
committerAlex Elder <aelder@sgi.com>2010-07-26 14:16:52 -0400
commit5d18898b20dfed5f373f8a9a7cbe01446036f8e9 (patch)
treedc96915d62c7140ad4ac33a3724ddf36f9db022f /fs/xfs
parent939d723b721eef71060201738653a73443ff4510 (diff)
xfs: simplify xfs_truncate_file
xfs_truncate_file is only used for truncating quota files. Move it to xfs_qm_syscalls.c so it can be marked static and take advatange of the fact by removing the unused page cache validation and taking the iget into the helper. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/quota/xfs_qm_syscalls.c70
-rw-r--r--fs/xfs/xfs_utils.c83
-rw-r--r--fs/xfs/xfs_utils.h1
3 files changed, 52 insertions, 102 deletions
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c
index 73f2b203975e..d257eb8557c4 100644
--- a/fs/xfs/quota/xfs_qm_syscalls.c
+++ b/fs/xfs/quota/xfs_qm_syscalls.c
@@ -238,40 +238,74 @@ out_unlock:
238 return error; 238 return error;
239} 239}
240 240
241STATIC int
242xfs_qm_scall_trunc_qfile(
243 struct xfs_mount *mp,
244 xfs_ino_t ino)
245{
246 struct xfs_inode *ip;
247 struct xfs_trans *tp;
248 int error;
249
250 if (ino == NULLFSINO)
251 return 0;
252
253 error = xfs_iget(mp, NULL, ino, 0, 0, &ip);
254 if (error)
255 return error;
256
257 xfs_ilock(ip, XFS_IOLOCK_EXCL);
258
259 tp = xfs_trans_alloc(mp, XFS_TRANS_TRUNCATE_FILE);
260 error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0,
261 XFS_TRANS_PERM_LOG_RES,
262 XFS_ITRUNCATE_LOG_COUNT);
263 if (error) {
264 xfs_trans_cancel(tp, 0);
265 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
266 goto out_put;
267 }
268
269 xfs_ilock(ip, XFS_ILOCK_EXCL);
270 xfs_trans_ijoin(tp, ip);
271
272 error = xfs_itruncate_finish(&tp, ip, 0, XFS_DATA_FORK, 1);
273 if (error) {
274 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES |
275 XFS_TRANS_ABORT);
276 goto out_unlock;
277 }
278
279 xfs_ichgtime(ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
280 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
281
282out_unlock:
283 xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
284out_put:
285 IRELE(ip);
286 return error;
287}
288
241int 289int
242xfs_qm_scall_trunc_qfiles( 290xfs_qm_scall_trunc_qfiles(
243 xfs_mount_t *mp, 291 xfs_mount_t *mp,
244 uint flags) 292 uint flags)
245{ 293{
246 int error = 0, error2 = 0; 294 int error = 0, error2 = 0;
247 xfs_inode_t *qip;
248 295
249 if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0) { 296 if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0) {
250 qdprintk("qtrunc flags=%x m_qflags=%x\n", flags, mp->m_qflags); 297 qdprintk("qtrunc flags=%x m_qflags=%x\n", flags, mp->m_qflags);
251 return XFS_ERROR(EINVAL); 298 return XFS_ERROR(EINVAL);
252 } 299 }
253 300
254 if ((flags & XFS_DQ_USER) && mp->m_sb.sb_uquotino != NULLFSINO) { 301 if (flags & XFS_DQ_USER)
255 error = xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, 0, 0, &qip); 302 error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_uquotino);
256 if (!error) { 303 if (flags & (XFS_DQ_GROUP|XFS_DQ_PROJ))
257 error = xfs_truncate_file(mp, qip); 304 error2 = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_gquotino);
258 IRELE(qip);
259 }
260 }
261
262 if ((flags & (XFS_DQ_GROUP|XFS_DQ_PROJ)) &&
263 mp->m_sb.sb_gquotino != NULLFSINO) {
264 error2 = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 0, 0, &qip);
265 if (!error2) {
266 error2 = xfs_truncate_file(mp, qip);
267 IRELE(qip);
268 }
269 }
270 305
271 return error ? error : error2; 306 return error ? error : error2;
272} 307}
273 308
274
275/* 309/*
276 * Switch on (a given) quota enforcement for a filesystem. This takes 310 * Switch on (a given) quota enforcement for a filesystem. This takes
277 * effect immediately. 311 * effect immediately.
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
index 102ce4898ab7..b7d5769d2df0 100644
--- a/fs/xfs/xfs_utils.c
+++ b/fs/xfs/xfs_utils.c
@@ -320,86 +320,3 @@ xfs_bumplink(
320 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 320 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
321 return 0; 321 return 0;
322} 322}
323
324/*
325 * Try to truncate the given file to 0 length. Currently called
326 * only out of xfs_remove when it has to truncate a file to free
327 * up space for the remove to proceed.
328 */
329int
330xfs_truncate_file(
331 xfs_mount_t *mp,
332 xfs_inode_t *ip)
333{
334 xfs_trans_t *tp;
335 int error;
336
337#ifdef QUOTADEBUG
338 /*
339 * This is called to truncate the quotainodes too.
340 */
341 if (XFS_IS_UQUOTA_ON(mp)) {
342 if (ip->i_ino != mp->m_sb.sb_uquotino)
343 ASSERT(ip->i_udquot);
344 }
345 if (XFS_IS_OQUOTA_ON(mp)) {
346 if (ip->i_ino != mp->m_sb.sb_gquotino)
347 ASSERT(ip->i_gdquot);
348 }
349#endif
350 /*
351 * Make the call to xfs_itruncate_start before starting the
352 * transaction, because we cannot make the call while we're
353 * in a transaction.
354 */
355 xfs_ilock(ip, XFS_IOLOCK_EXCL);
356 error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, (xfs_fsize_t)0);
357 if (error) {
358 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
359 return error;
360 }
361
362 tp = xfs_trans_alloc(mp, XFS_TRANS_TRUNCATE_FILE);
363 if ((error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0,
364 XFS_TRANS_PERM_LOG_RES,
365 XFS_ITRUNCATE_LOG_COUNT))) {
366 xfs_trans_cancel(tp, 0);
367 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
368 return error;
369 }
370
371 /*
372 * Follow the normal truncate locking protocol. Since we
373 * hold the inode in the transaction, we know that its number
374 * of references will stay constant.
375 */
376 xfs_ilock(ip, XFS_ILOCK_EXCL);
377 xfs_trans_ijoin(tp, ip);
378
379 /*
380 * Signal a sync xaction. The only case where that isn't
381 * the case is if we're truncating an already unlinked file
382 * on a wsync fs. In that case, we know the blocks can't
383 * reappear in the file because the links to file are
384 * permanently toast. Currently, we're always going to
385 * want a sync transaction because this code is being
386 * called from places where nlink is guaranteed to be 1
387 * but I'm leaving the tests in to protect against future
388 * changes -- rcc.
389 */
390 error = xfs_itruncate_finish(&tp, ip, (xfs_fsize_t)0,
391 XFS_DATA_FORK,
392 ((ip->i_d.di_nlink != 0 ||
393 !(mp->m_flags & XFS_MOUNT_WSYNC))
394 ? 1 : 0));
395 if (error) {
396 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES |
397 XFS_TRANS_ABORT);
398 } else {
399 xfs_ichgtime(ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
400 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
401 }
402 xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
403
404 return error;
405}
diff --git a/fs/xfs/xfs_utils.h b/fs/xfs/xfs_utils.h
index ef321225d269..f55b9678264f 100644
--- a/fs/xfs/xfs_utils.h
+++ b/fs/xfs/xfs_utils.h
@@ -18,7 +18,6 @@
18#ifndef __XFS_UTILS_H__ 18#ifndef __XFS_UTILS_H__
19#define __XFS_UTILS_H__ 19#define __XFS_UTILS_H__
20 20
21extern int xfs_truncate_file(xfs_mount_t *, xfs_inode_t *);
22extern int xfs_dir_ialloc(xfs_trans_t **, xfs_inode_t *, mode_t, xfs_nlink_t, 21extern int xfs_dir_ialloc(xfs_trans_t **, xfs_inode_t *, mode_t, xfs_nlink_t,
23 xfs_dev_t, cred_t *, prid_t, int, 22 xfs_dev_t, cred_t *, prid_t, int,
24 xfs_inode_t **, int *); 23 xfs_inode_t **, int *);