1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * Lustre Metadata Server (mds) journal abstraction routines
8 * Copyright (C) 2002 Cluster File Systems, Inc.
9 * author: Andreas Dilger <adilger@clusterfs.com>
11 * This code is issued under the GNU General Public License.
12 * See the file COPYING in this distribution
16 #define DEBUG_SUBSYSTEM S_MDS
19 #include <linux/jbd.h>
20 #include <linux/ext3_fs.h>
21 #include <linux/ext3_jbd.h>
22 #include <linux/lustre_mds.h>
25 * We don't currently need any additional blocks for rmdir and
26 * unlink transactions because we are storing the OST oa_id inside
27 * the inode (which we will be changing anyways as part of this
30 static void *mds_ext3_start(struct inode *inode, int op)
32 /* For updates to the last recieved file */
33 int nblocks = EXT3_DATA_TRANS_BLOCKS;
38 nblocks += EXT3_DELETE_TRANS_BLOCKS; break;
40 nblocks += EXT3_DATA_TRANS_BLOCKS;
42 // FIXME: when we store oa_id in an EA we need more blocks
45 case MDS_FSOP_SYMLINK:
46 /* Create new directory or symlink (more data blocks) */
49 /* Change parent directory + setattr on new inode */
50 nblocks += EXT3_DATA_TRANS_BLOCKS + 3;
53 return journal_start(EXT3_JOURNAL(inode), nblocks);
56 static int mds_ext3_commit(struct inode *inode, void *handle)
58 return journal_stop((handle_t *)handle);
61 static int mds_ext3_setattr(struct dentry *dentry, void *handle,
64 struct inode *inode = dentry->d_inode;
66 /* a _really_ horrible hack to avoid removing the data stored
67 in the block pointers; this data is the object id
68 this will go into an extended attribute at some point.
70 if (iattr->ia_valid & ATTR_SIZE) {
71 /* ATTR_SIZE would invoke truncate: clear it */
72 iattr->ia_valid &= ~ATTR_SIZE;
73 inode->i_size = iattr->ia_size;
75 /* an _even_more_ horrible hack to make this hack work with
76 * ext3. This is because ext3 keeps a separate inode size
77 * until the inode is committed to ensure consistency. This
78 * will also go away with the move to EAs.
80 EXT3_I(inode)->i_disksize = inode->i_size;
82 /* make sure _something_ gets set - so new inode
83 goes to disk (probably won't work over XFS */
84 if (!iattr->ia_valid & ATTR_MODE) {
85 iattr->ia_valid |= ATTR_MODE;
86 iattr->ia_mode = inode->i_mode;
90 if (inode->i_op->setattr)
91 return inode->i_op->setattr(dentry, iattr);
93 return inode_setattr(inode, iattr);
97 * FIXME: nasty hack - store the object id in the first two
98 * direct block spots. This should be done with EAs...
99 * Note also that this does not currently mark the inode
100 * dirty (it currently is used with other operations that
101 * subsequently also mark the inode dirty).
103 static int mds_ext3_set_objid(struct inode *inode, void *handle, obd_id id)
105 (__u64)EXT3_I(inode)->i_data[0] = cpu_to_le64(id);
109 static void mds_ext3_get_objid(struct inode *inode, obd_id *id)
111 *id = le64_to_cpu(EXT3_I(inode)->i_data[0]);
114 static ssize_t mds_ext3_readpage(struct file *file, char *buf, size_t count,
117 struct inode *inode = file->f_dentry->d_inode;
120 if (S_ISREG(inode->i_mode))
121 rc = file->f_op->read(file, buf, count, offset);
123 struct buffer_head *bh;
125 /* FIXME: this assumes the blocksize == count, but the calling
126 * function will detect this as an error for now */
127 bh = ext3_bread(NULL, inode,
128 *offset >> inode->i_sb->s_blocksize_bits,
132 memcpy(buf, bh->b_data, inode->i_blksize);
134 rc = inode->i_blksize;
141 struct mds_fs_operations mds_ext3_fs_ops;
143 void mds_ext3_delete_inode(struct inode * inode)
147 if (S_ISREG(inode->i_mode)) {
148 handle = mds_ext3_start(inode, MDS_FSOP_UNLINK);
150 if (IS_ERR(handle)) {
151 CERROR("unable to start transaction");
155 if (mds_ext3_set_objid(inode, handle, 0))
156 CERROR("error clearing objid on %ld\n", inode->i_ino);
158 if (mds_ext3_fs_ops.cl_delete_inode)
159 mds_ext3_fs_ops.cl_delete_inode(inode);
161 if (mds_ext3_commit(inode, handle))
162 CERROR("error closing handle on %ld\n", inode->i_ino);
164 mds_ext3_fs_ops.cl_delete_inode(inode);
167 struct mds_fs_operations mds_ext3_fs_ops = {
168 fs_start: mds_ext3_start,
169 fs_commit: mds_ext3_commit,
170 fs_setattr: mds_ext3_setattr,
171 fs_set_objid: mds_ext3_set_objid,
172 fs_get_objid: mds_ext3_get_objid,
173 fs_readpage: mds_ext3_readpage,
174 fs_delete_inode:mds_ext3_delete_inode,
175 cl_delete_inode:clear_inode,