Whamcloud - gitweb
- changed back to using no optimization for UML modules, and no -g2
[fs/lustre-release.git] / lustre / mds / mds_reint.c
1 /*
2  *  linux/mds/mds_reint.c
3  *  
4  *  Lustre Metadata Server (mds) reintegration routines
5  * 
6  *  Copyright (C) 2002  Cluster File Systems, Inc.
7  *  author: Peter Braam <braam@clusterfs.com>
8  *
9  *  This code is issued under the GNU General Public License.
10  *  See the file COPYING in this distribution
11  *
12  */
13
14 // XXX - add transaction sequence numbers
15
16 #define EXPORT_SYMTAB
17
18 #include <linux/version.h>
19 #include <linux/module.h>
20 #include <linux/fs.h>
21 #include <linux/stat.h>
22 #include <linux/locks.h>
23 #include <linux/ext2_fs.h>
24 #include <linux/quotaops.h>
25 #include <asm/unistd.h>
26 #include <asm/uaccess.h>
27 #include <linux/obd_support.h>
28 #include <linux/obd.h>
29 #include <linux/lustre_lib.h>
30 #include <linux/lustre_idl.h>
31 #include <linux/lustre_mds.h>
32 #include <linux/obd_class.h>
33
34 extern struct ptlrpc_request *mds_prep_req(int size, int opcode, int namelen, char *name, int tgtlen, char *tgt);
35
36 static int mds_reint_setattr(struct mds_update_record *rec, struct ptlrpc_request *req)
37 {
38         struct vfsmount *mnt;
39         struct dentry *de;
40
41         de = mds_fid2dentry(req->rq_obd, rec->ur_fid1, &mnt);
42         if (IS_ERR(de)) { 
43                 req->rq_rephdr->status = -ESTALE;
44                 return 0;
45         }
46
47         printk("mds_setattr: ino %ld\n", de->d_inode->i_ino);
48         if ( de->d_inode->i_op->setattr ) {
49                 req->rq_rephdr->status =
50                         de->d_inode->i_op->setattr(de, &rec->ur_iattr);
51         } else { 
52                 req->rq_rephdr->status =
53                         inode_setattr(de->d_inode, &rec->ur_iattr);
54         }
55
56         dput(de);
57         EXIT;
58         return 0;
59 }
60
61 /* 
62    XXX nasty hack: store the object id in the first two
63    direct block spots 
64 */
65 static inline void mds_store_objid(struct inode *inode, __u64 *id)
66 {
67         memcpy(&inode->u.ext2_i.i_data, id, sizeof(*id));
68 }
69
70
71 static int mds_reint_create(struct mds_update_record *rec, 
72                             struct ptlrpc_request *req)
73 {
74         struct vfsmount *mnt;
75         int type = rec->ur_mode & S_IFMT;
76         struct dentry *de;
77         struct mds_rep *rep = req->rq_rep.mds;
78         struct dentry *dchild; 
79         int rc;
80
81         de = mds_fid2dentry(req->rq_obd, rec->ur_fid1, &mnt);
82         if (IS_ERR(de)) { 
83                 req->rq_rephdr->status = -ESTALE;
84                 return 0;
85         }
86         printk("mds_reint_create: ino %ld\n", de->d_inode->i_ino);
87
88         dchild = lookup_one_len(rec->ur_name, de, rec->ur_namelen);
89         rc = PTR_ERR(dchild);
90         if (IS_ERR(dchild)) { 
91                 printk(__FUNCTION__ "child lookup error %d\n", rc);
92                 dput(de); 
93                 req->rq_rephdr->status = -ESTALE;
94                 return 0;
95         }
96
97         if (dchild->d_inode) {
98                 printk(__FUNCTION__ "child exists (dir %ld, name %s\n", 
99                        de->d_inode->i_ino, rec->ur_name);
100                 dput(de); 
101                 req->rq_rephdr->status = -ESTALE;
102                 return 0;
103         }
104
105         switch (type) {
106         case S_IFREG: { 
107                 rc = vfs_create(de->d_inode, dchild, rec->ur_mode);
108                 
109                 if (!rc) { 
110                         mds_store_objid(dchild->d_inode, &rec->ur_id); 
111                         dchild->d_inode->i_atime = rec->ur_time;
112                         dchild->d_inode->i_ctime = rec->ur_time;
113                         dchild->d_inode->i_mtime = rec->ur_time;
114                         dchild->d_inode->i_uid = rec->ur_uid;
115                         dchild->d_inode->i_gid = rec->ur_gid;
116                         rep->ino = dchild->d_inode->i_ino;
117                 }
118                 break;
119         }
120         case S_IFDIR: { 
121                 rc = vfs_mkdir(de->d_inode, dchild, rec->ur_mode);
122                 break;
123         } 
124         case S_IFCHR:
125         case S_IFBLK:
126         case S_IFIFO:
127         case S_IFSOCK: { 
128                 int rdev = rec->ur_id;
129                 rc = vfs_mknod(de->d_inode, dchild, rec->ur_mode, rdev); 
130                 break;
131         }
132         }
133         req->rq_rephdr->status = rc;
134
135         dput(de);
136         dput(dchild); 
137         EXIT;
138         return 0;
139 }
140
141 typedef int (*mds_reinter)(struct mds_update_record *, struct ptlrpc_request*); 
142
143 static mds_reinter  reinters[REINT_MAX+1] = { 
144         [REINT_SETATTR]   mds_reint_setattr, 
145         [REINT_CREATE]   mds_reint_create
146 };
147
148 int mds_reint_rec(struct mds_update_record *rec, struct ptlrpc_request *req)
149 {
150         int rc; 
151
152         if (rec->ur_opcode < 0 || rec->ur_opcode > REINT_MAX) { 
153                 printk(__FUNCTION__ "opcode %d not valid\n", 
154                        rec->ur_opcode); 
155                 rc = req->rq_status = -EINVAL;
156                 return rc;
157         }
158
159         rc = mds_pack_rep(NULL, 0, NULL, 0, &req->rq_rephdr, &req->rq_rep.mds, 
160                           &req->rq_replen, &req->rq_repbuf);
161         if (rc) { 
162                 EXIT;
163                 printk("mds: out of memory\n");
164                 rc = req->rq_status = -ENOMEM;
165                 return rc;
166         }
167         req->rq_rephdr->seqno = req->rq_reqhdr->seqno;
168
169         rc = reinters[rec->ur_opcode](rec, req); 
170         req->rq_status = rc;
171
172         return rc;
173
174