blob: b0bda1e912259056ac7f3e219005c8569371542e [file] [log] [blame]
Boaz Harroshe8062712008-10-27 18:37:02 +02001/*
2 * Copyright (C) 2005, 2006
3 * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
4 * Copyright (C) 2005, 2006
5 * International Business Machines
6 * Copyright (C) 2008, 2009
7 * Boaz Harrosh <bharrosh@panasas.com>
8 *
9 * Copyrights for code taken from ext2:
10 * Copyright (C) 1992, 1993, 1994, 1995
11 * Remy Card (card@masi.ibp.fr)
12 * Laboratoire MASI - Institut Blaise Pascal
13 * Universite Pierre et Marie Curie (Paris VI)
14 * from
15 * linux/fs/minix/inode.c
16 * Copyright (C) 1991, 1992 Linus Torvalds
17 *
18 * This file is part of exofs.
19 *
20 * exofs is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation. Since it is based on ext2, and the only
23 * valid version of GPL for the Linux kernel is version 2, the only valid
24 * version of GPL for exofs is version 2.
25 *
26 * exofs is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
30 *
31 * You should have received a copy of the GNU General Public License
32 * along with exofs; if not, write to the Free Software
33 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 */
35
36#include <linux/writeback.h>
37#include <linux/buffer_head.h>
38
39#include "exofs.h"
40
41#ifdef CONFIG_EXOFS_DEBUG
42# define EXOFS_DEBUG_OBJ_ISIZE 1
43#endif
44
45/******************************************************************************
46 * INODE OPERATIONS
47 *****************************************************************************/
48
49/*
50 * Test whether an inode is a fast symlink.
51 */
52static inline int exofs_inode_is_fast_symlink(struct inode *inode)
53{
54 struct exofs_i_info *oi = exofs_i(inode);
55
56 return S_ISLNK(inode->i_mode) && (oi->i_data[0] != 0);
57}
58
59/*
60 * get_block_t - Fill in a buffer_head
61 * An OSD takes care of block allocation so we just fake an allocation by
62 * putting in the inode's sector_t in the buffer_head.
63 * TODO: What about the case of create==0 and @iblock does not exist in the
64 * object?
65 */
66static int exofs_get_block(struct inode *inode, sector_t iblock,
67 struct buffer_head *bh_result, int create)
68{
69 map_bh(bh_result, inode->i_sb, iblock);
70 return 0;
71}
72
73const struct osd_attr g_attr_logical_length = ATTR_DEF(
74 OSD_APAGE_OBJECT_INFORMATION, OSD_ATTR_OI_LOGICAL_LENGTH, 8);
75
76/*
77 * Truncate a file to the specified size - all we have to do is set the size
78 * attribute. We make sure the object exists first.
79 */
80void exofs_truncate(struct inode *inode)
81{
82 struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;
83 struct exofs_i_info *oi = exofs_i(inode);
84 struct osd_obj_id obj = {sbi->s_pid, inode->i_ino + EXOFS_OBJ_OFF};
85 struct osd_request *or;
86 struct osd_attr attr;
87 loff_t isize = i_size_read(inode);
88 __be64 newsize;
89 int ret;
90
91 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)
92 || S_ISLNK(inode->i_mode)))
93 return;
94 if (exofs_inode_is_fast_symlink(inode))
95 return;
96 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
97 return;
98 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
99
100 nobh_truncate_page(inode->i_mapping, isize, exofs_get_block);
101
102 or = osd_start_request(sbi->s_dev, GFP_KERNEL);
103 if (unlikely(!or)) {
104 EXOFS_ERR("ERROR: exofs_truncate: osd_start_request failed\n");
105 goto fail;
106 }
107
108 osd_req_set_attributes(or, &obj);
109
110 newsize = cpu_to_be64((u64)isize);
111 attr = g_attr_logical_length;
112 attr.val_ptr = &newsize;
113 osd_req_add_set_attr_list(or, &attr, 1);
114
115 /* if we are about to truncate an object, and it hasn't been
116 * created yet, wait
117 */
118 if (unlikely(wait_obj_created(oi)))
119 goto fail;
120
121 ret = exofs_sync_op(or, sbi->s_timeout, oi->i_cred);
122 osd_end_request(or);
123 if (ret)
124 goto fail;
125
126out:
127 mark_inode_dirty(inode);
128 return;
129fail:
130 make_bad_inode(inode);
131 goto out;
132}
133
134/*
135 * Set inode attributes - just call generic functions.
136 */
137int exofs_setattr(struct dentry *dentry, struct iattr *iattr)
138{
139 struct inode *inode = dentry->d_inode;
140 int error;
141
142 error = inode_change_ok(inode, iattr);
143 if (error)
144 return error;
145
146 error = inode_setattr(inode, iattr);
147 return error;
148}