Whamcloud - gitweb
Remove use of ext2-specific inode flags to signal objid-in-i_data. Just
[fs/lustre-release.git] / lustre / mds / mds_ext3.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  linux/mds/mds_ext3.c
5  *
6  *  Lustre Metadata Server (mds) journal abstraction routines
7  *
8  *  Copyright (C) 2002  Cluster File Systems, Inc.
9  *  author: Andreas Dilger <adilger@clusterfs.com>
10  *
11  *  This code is issued under the GNU General Public License.
12  *  See the file COPYING in this distribution
13  *
14  */
15
16 #define DEBUG_SUBSYSTEM S_MDS
17
18 #include <linux/fs.h>
19 #include <linux/jbd.h>
20 #include <linux/ext3_fs.h>
21 #include <linux/ext3_jbd.h>
22 #include <linux/lustre_mds.h>
23
24 /*
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
28  * transaction).
29  */
30 static void *mds_ext3_start(struct inode *inode, int op)
31 {
32         /* For updates to the last recieved file */
33         int nblocks = EXT3_DATA_TRANS_BLOCKS;
34
35         switch(op) {
36         case MDS_FSOP_RMDIR:
37         case MDS_FSOP_UNLINK:
38                 nblocks += EXT3_DELETE_TRANS_BLOCKS; break;
39         case MDS_FSOP_RENAME:
40                 nblocks += EXT3_DATA_TRANS_BLOCKS;
41         case MDS_FSOP_CREATE:
42                 // FIXME: when we store oa_id in an EA we need more blocks
43                 // nblocks += 0;
44         case MDS_FSOP_MKDIR:
45         case MDS_FSOP_SYMLINK:
46                 /* Create new directory or symlink (more data blocks) */
47                 nblocks += 2;
48         case MDS_FSOP_MKNOD:
49                 /* Change parent directory + setattr on new inode */
50                 nblocks += EXT3_DATA_TRANS_BLOCKS + 3;
51         }
52
53         return journal_start(EXT3_JOURNAL(inode), nblocks);
54 }
55
56 static int mds_ext3_commit(struct inode *inode, void *handle)
57 {
58         return journal_stop((handle_t *)handle);
59 }
60
61 static int mds_ext3_setattr(struct dentry *dentry, void *handle,
62                             struct iattr *iattr)
63 {
64         struct inode *inode = dentry->d_inode;
65
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.
69         */
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;
74
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.
79                  */
80                 EXT3_I(inode)->i_disksize = inode->i_size;
81
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;
87                 }
88         }
89
90         if (inode->i_op->setattr)
91                 return inode->i_op->setattr(dentry, iattr);
92         else
93                 return inode_setattr(inode, iattr);
94 }
95
96 /*
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).
102  */
103 static int mds_ext3_set_objid(struct inode *inode, void *handle, obd_id id)
104 {
105         (__u64)EXT3_I(inode)->i_data[0] = cpu_to_le64(id);
106         return 0;
107 }
108
109 static void mds_ext3_get_objid(struct inode *inode, obd_id *id)
110 {
111         *id = le64_to_cpu(EXT3_I(inode)->i_data[0]);
112 }
113
114 static ssize_t mds_ext3_readpage(struct file *file, char *buf, size_t count,
115                                  loff_t *offset)
116 {
117         struct inode *inode = file->f_dentry->d_inode;
118         int rc = 0;
119
120         if (S_ISREG(inode->i_mode))
121                 rc = file->f_op->read(file, buf, count, offset);
122         else {
123                 struct buffer_head *bh;
124
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,
129                                 0, &rc);
130
131                 if (bh) {
132                         memcpy(buf, bh->b_data, inode->i_blksize);
133                         brelse(bh);
134                         rc = inode->i_blksize;
135                 }
136         }
137
138         return rc;
139 }
140
141 struct mds_fs_operations mds_ext3_fs_ops;
142
143 void mds_ext3_delete_inode(struct inode * inode)
144 {
145         void *handle;
146
147         if (S_ISREG(inode->i_mode)) {
148                 handle = mds_ext3_start(inode, MDS_FSOP_UNLINK);
149
150                 if (IS_ERR(handle)) {
151                         CERROR("unable to start transaction");
152                         EXIT;
153                         return;
154                 }
155                 if (mds_ext3_set_objid(inode, handle, 0))
156                         CERROR("error clearing objid on %ld\n", inode->i_ino);
157
158                 if (mds_ext3_fs_ops.cl_delete_inode)
159                         mds_ext3_fs_ops.cl_delete_inode(inode);
160
161                 if (mds_ext3_commit(inode, handle))
162                         CERROR("error closing handle on %ld\n", inode->i_ino);
163         } else
164                 mds_ext3_fs_ops.cl_delete_inode(inode);
165 }
166
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,
176 };