Whamcloud - gitweb
Don't output message on MDS for normal occurrence (fixed previously in
[fs/lustre-release.git] / lustre / smfs / dir.c
1 /*
2  * dir.c
3  */
4 #define DEBUG_SUBSYSTEM S_SNAP
5
6 #include <linux/module.h>
7 #include <linux/kernel.h>
8 #include <linux/string.h>
9 #include <linux/slab.h>
10 #include <linux/stat.h>
11 #include <linux/unistd.h>
12 #include <linux/lustre_idl.h> 
13 #include <linux/smp_lock.h>
14
15 #include "smfs_internal.h" 
16 #include "kml_idl.h" 
17
18 #define NAME_ALLOC_LEN(len)     ((len+16) & ~15)
19                                                                                                                                                                                         
20 void prepare_parent_dentry(struct dentry *dentry, struct inode *inode)
21 {
22         atomic_set(&dentry->d_count, 1);
23         dentry->d_vfs_flags = 0;
24         dentry->d_flags = 0;
25         dentry->d_inode = inode;
26         dentry->d_op = NULL;
27         dentry->d_fsdata = NULL;
28         dentry->d_mounted = 0;
29         INIT_LIST_HEAD(&dentry->d_hash);
30         INIT_LIST_HEAD(&dentry->d_lru);
31         INIT_LIST_HEAD(&dentry->d_subdirs);
32         INIT_LIST_HEAD(&dentry->d_alias);
33 }
34
35 void d_unalloc(struct dentry *dentry)
36 {
37
38         list_del(&dentry->d_hash);
39         INIT_LIST_HEAD(&dentry->d_hash);
40         dput(dentry); /* this will free the dentry memory */
41 }
42
43 static int smfs_create(struct inode *dir, 
44                        struct dentry *dentry, 
45                        int mode)
46 {
47         struct  inode *cache_dir; 
48         struct  inode *cache_inode = NULL, *inode;
49         struct  dentry parent; 
50         struct  dentry *cache_dentry = NULL;
51         int     rc;
52         
53         ENTRY;
54         
55         cache_dir = I2CI(dir);
56         if (!cache_dir)
57                 RETURN(-ENOENT);
58        
59         prepare_parent_dentry(&parent, cache_dir);      
60         cache_dentry = d_alloc(&parent, &dentry->d_name);
61         
62         if (!cache_dentry) {
63                 RETURN(-ENOMEM);
64         }
65                  
66         if (cache_dir && cache_dir->i_op->create)
67                 rc = cache_dir->i_op->create(cache_dir, cache_dentry, mode);
68         
69         if (rc)
70                 GOTO(exit, rc);
71
72         cache_inode = igrab(cache_dentry->d_inode);
73         
74         inode = iget(dir->i_sb, cache_inode->i_ino);    
75
76         if (!inode) 
77                 GOTO(exit, rc = -ENOMEM);
78                 
79         d_instantiate(dentry, inode);   
80         
81         sm_set_inode_ops(cache_inode, inode);
82 exit:
83         d_unalloc(cache_dentry);
84         RETURN(rc);
85 }
86
87 static struct dentry *smfs_lookup(struct inode *dir,
88                                   struct dentry *dentry)
89 {
90         struct  inode *cache_dir; 
91         struct  inode *cache_inode = NULL, *inode;
92         struct  dentry parent; 
93         struct  dentry *cache_dentry = NULL;
94         struct  dentry *rc = NULL;
95         
96         ENTRY;
97         
98         cache_dir = I2CI(dir);
99         if (!cache_dir)
100                 RETURN(ERR_PTR(-ENOENT));
101         prepare_parent_dentry(&parent, cache_dir);      
102         cache_dentry = d_alloc(&parent, &dentry->d_name);
103       
104         if(cache_dir && cache_dir->i_op->lookup)
105                 rc = cache_dir->i_op->lookup(cache_dir, cache_dentry);
106
107         if (rc || !cache_dentry->d_inode || 
108             is_bad_inode(cache_dentry->d_inode) ||
109             IS_ERR(cache_dentry->d_inode)) {
110                 GOTO(exit, rc); 
111         }
112
113         cache_inode = igrab(cache_dentry->d_inode);
114         
115         inode = iget(dir->i_sb, cache_inode->i_ino);    
116                 
117         d_add(dentry, inode);   
118 exit:
119         d_unalloc(cache_dentry);
120         RETURN(rc);
121 }                      
122
123 static int smfs_lookup_raw(struct inode *dir, const char *name,
124                            int len, ino_t *data)
125 {
126         struct  inode *cache_dir; 
127         int     rc = 0;
128
129         cache_dir = I2CI(dir);
130
131         if (!cache_dir) 
132                 RETURN(-ENOENT);
133         
134         if (cache_dir->i_op->lookup_raw)
135                 rc = cache_dir->i_op->lookup_raw(cache_dir, name, len, data);           
136                 
137         RETURN(rc);
138 }
139
140 static int smfs_link(struct dentry * old_dentry,
141                      struct inode * dir, struct dentry *dentry)
142 {
143         struct  inode *cache_old_inode = NULL; 
144         struct  inode *cache_dir = I2CI(dir); 
145         struct  inode *inode = NULL; 
146         struct  dentry *cache_dentry;
147         struct  dentry *cache_old_dentry;
148         struct  dentry parent; 
149         struct  dentry parent_old; 
150         int     rc = 0;
151
152         inode = old_dentry->d_inode;
153         
154         cache_old_inode = I2CI(inode);
155         
156         if (!cache_old_inode || !cache_dir) 
157                 RETURN(-ENOENT);
158         
159         prepare_parent_dentry(&parent, cache_dir);
160         cache_dentry = d_alloc(&parent, &dentry->d_name);
161         
162         prepare_parent_dentry(&parent_old, cache_dir);
163         cache_old_dentry = d_alloc(&parent_old, &dentry->d_name);
164         d_add(cache_old_dentry, cache_old_inode); 
165         pre_smfs_inode(inode, cache_old_dentry->d_inode);
166         
167         if (cache_dir->i_op->link)
168                 rc = cache_dir->i_op->link(cache_old_dentry, cache_dir, cache_dentry);          
169         
170         if (rc)
171                 GOTO(exit, rc); 
172         
173         atomic_inc(&inode->i_count);
174         post_smfs_inode(inode, cache_old_dentry->d_inode);
175         d_instantiate(dentry, inode);
176
177 exit:
178         if (cache_dentry->d_inode)      
179                 igrab(cache_dentry->d_inode);
180         if (cache_old_dentry->d_inode)
181                 igrab(cache_old_dentry->d_inode);
182         
183         d_unalloc(cache_dentry);
184         d_unalloc(cache_old_dentry);
185
186         RETURN(rc);
187 }
188
189 static int smfs_unlink(struct inode * dir, 
190                        struct dentry *dentry)
191 {
192         struct inode *cache_dir = I2CI(dir);
193         struct inode *cache_inode = I2CI(dentry->d_inode);
194         struct dentry *cache_dentry;
195         struct dentry parent; 
196         int    rc = 0;
197
198         if (!cache_dir || !cache_inode)
199                 RETURN(-ENOENT);
200         
201         prepare_parent_dentry(&parent, cache_dir);
202         cache_dentry = d_alloc(&parent, &dentry->d_name);
203         d_add(cache_dentry, cache_inode);
204
205         if (cache_dir->i_op->unlink)
206                 rc = cache_dir->i_op->unlink(cache_dir, cache_dentry);
207
208         
209         post_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
210         post_smfs_inode(dir, cache_dir);
211         
212         igrab(cache_dentry->d_inode);
213
214         d_unalloc(cache_dentry);        
215         RETURN(rc);     
216 }
217
218 static int smfs_symlink (struct inode * dir,
219                          struct dentry *dentry, 
220                          const char * symname)
221 {
222         struct inode *cache_dir = I2CI(dir);
223         struct inode *cache_inode = NULL;
224         struct inode *inode = NULL;
225         struct dentry *cache_dentry; 
226         struct dentry parent; 
227         int    rc = 0;
228
229         if (!cache_dir) 
230                 RETURN(-ENOENT);
231         
232         prepare_parent_dentry(&parent, cache_dir);
233         cache_dentry = d_alloc(&parent, &dentry->d_name);
234
235         if (cache_dir->i_op->symlink)
236                 rc = cache_dir->i_op->symlink(cache_dir, cache_dentry, symname);
237         
238         cache_inode = igrab(cache_dentry->d_inode);
239         
240         inode = iget(dir->i_sb, cache_inode->i_ino);
241
242         if (inode)
243                 d_instantiate(dentry, inode);
244         else
245                 rc = -ENOENT;
246         
247         d_unalloc(cache_dentry);        
248         
249         RETURN(rc);                     
250 }
251
252 static int smfs_mkdir(struct inode * dir, 
253                       struct dentry * dentry, 
254                       int mode)
255 {
256         struct inode *cache_dir = I2CI(dir);
257         struct inode *cache_inode = NULL;
258         struct inode *inode = NULL;
259         struct dentry *cache_dentry;
260         struct dentry parent;
261         void   *handle;
262         int    rc = 0;
263
264         if (!cache_dir) 
265                 RETURN(-ENOENT);
266
267         handle = smfs_trans_start(cache_dir, KML_OPCODE_MKDIR);
268         if (IS_ERR(handle) ) {
269                 CERROR("smfs_do_mkdir: no space for transaction\n");
270                 RETURN(-ENOSPC);
271         }
272         
273         prepare_parent_dentry(&parent, cache_dir);
274         cache_dentry = d_alloc(&parent, &dentry->d_name);
275
276         pre_smfs_inode(dir, cache_dir);
277         lock_kernel();  
278         if (cache_dir->i_op->mkdir)
279                 rc = cache_dir->i_op->mkdir(cache_dir, cache_dentry, mode);
280
281         cache_inode = igrab(cache_dentry->d_inode);
282
283         inode = iget(dir->i_sb, cache_inode->i_ino);
284
285         if (!inode)
286                 GOTO(exit, rc = -ENOENT);
287  
288         d_instantiate(dentry, inode);   
289         /*Do KML post hook*/
290         if (smfs_do_kml(dir)) {
291                 rc = post_kml_mkdir(dir, dentry);
292                 GOTO(exit, rc);
293         }
294         post_smfs_inode(dir, cache_dir);
295 exit:
296         unlock_kernel();        
297         smfs_trans_commit(handle);
298         d_unalloc(cache_dentry);
299         RETURN(rc);             
300 }
301
302 static int  smfs_rmdir(struct inode * dir, 
303                        struct dentry *dentry) 
304 {
305         struct inode *cache_dir = I2CI(dir);
306         struct inode *cache_inode = I2CI(dentry->d_inode);
307         struct dentry *cache_dentry;
308         struct dentry parent;
309         int    rc = 0;
310
311         if (!cache_dir) 
312                 RETURN(-ENOENT);
313         
314         prepare_parent_dentry(&parent, cache_dir);
315         cache_dentry = d_alloc(&parent, &dentry->d_name);
316         d_add(cache_dentry, cache_inode);
317         igrab(cache_inode);
318         
319         pre_smfs_inode(dir, cache_dir);
320         pre_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
321         
322         
323         if (cache_dir->i_op->rmdir)
324                 rc = cache_dir->i_op->rmdir(cache_dir, cache_dentry);
325
326         post_smfs_inode(dir, cache_dir);
327         post_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
328         d_unalloc(cache_dentry);
329         RETURN(rc);             
330 }
331
332 static int smfs_mknod(struct inode * dir, struct dentry *dentry,
333                       int mode, int rdev)
334 {
335         struct inode *cache_dir = I2CI(dir);
336         struct inode *inode = NULL;
337         struct inode *cache_inode = NULL;
338         struct dentry *cache_dentry;
339         struct dentry parent;
340         int    rc = 0;
341
342         if (!cache_dir) 
343                 RETURN(-ENOENT);
344
345         prepare_parent_dentry(&parent, cache_dir);
346         cache_dentry = d_alloc(&parent, &dentry->d_name);
347         
348         pre_smfs_inode(dir, cache_dir);
349         pre_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
350         
351         if (cache_dir->i_op->mknod)
352                 rc = cache_dir->i_op->mknod(cache_dir, cache_dentry, mode, rdev);
353         
354         if (cache_dentry->d_inode)
355                 cache_inode = igrab(cache_dentry->d_inode);
356         if (rc)
357                 GOTO(exit, rc);
358         
359         inode = iget(dir->i_sb, cache_inode->i_ino);
360         d_instantiate(dentry, inode);
361         post_smfs_inode(dir, cache_dir);
362         post_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
363 exit:
364         d_unalloc(cache_dentry);
365         RETURN(rc);             
366 }
367 static int smfs_rename(struct inode * old_dir, struct dentry *old_dentry,
368                        struct inode * new_dir,struct dentry *new_dentry)
369 {
370         struct inode *cache_old_dir = I2CI(old_dir);
371         struct inode *cache_new_dir = I2CI(new_dir);
372         struct inode *cache_old_inode = I2CI(old_dentry->d_inode);
373         struct dentry *cache_old_dentry;
374         struct dentry *cache_new_dentry;
375         struct dentry parent_new;
376         struct dentry parent_old;
377         int    rc = 0;
378
379         if (!cache_old_dir || !cache_new_dir || !cache_old_inode) 
380                 RETURN(-ENOENT);
381         
382         prepare_parent_dentry(&parent_old, cache_old_dir);
383         cache_old_dentry = d_alloc(&parent_old, &old_dentry->d_name);
384         d_add(cache_old_dentry, cache_old_inode);
385         igrab(cache_old_inode); 
386
387         prepare_parent_dentry(&parent_new, cache_new_dir);
388         cache_new_dentry = d_alloc(&parent_new, &new_dentry->d_name);
389         
390         pre_smfs_inode(old_dir, cache_old_dir) ;
391         pre_smfs_inode(new_dir, cache_new_dir);
392         
393         if (cache_old_dir->i_op->rename)
394                 rc = cache_old_dir->i_op->rename(cache_old_dir, cache_old_dentry,
395                                                  cache_new_dir, cache_new_dentry);
396
397         post_smfs_inode(old_dir, cache_old_dir) ;
398         post_smfs_inode(new_dir, cache_new_dir);
399         if (cache_new_dentry->d_inode) {
400                 igrab(cache_new_dentry->d_inode);       
401         }
402         d_unalloc(cache_old_dentry);
403         d_unalloc(cache_new_dentry);
404         RETURN(rc);             
405 }
406
407 struct inode_operations smfs_dir_iops = {
408         create:         smfs_create,
409         lookup:         smfs_lookup,
410         lookup_raw:     smfs_lookup_raw,        /* BKL held */
411         link:           smfs_link,              /* BKL held */
412         unlink:         smfs_unlink,            /* BKL held */
413         symlink:        smfs_symlink,           /* BKL held */
414         mkdir:          smfs_mkdir,             /* BKL held */
415         rmdir:          smfs_rmdir,             /* BKL held */
416         mknod:          smfs_mknod,             /* BKL held */
417         rename:         smfs_rename,            /* BKL held */
418         setxattr:       smfs_setxattr,          /* BKL held */
419         getxattr:       smfs_getxattr,          /* BKL held */
420         listxattr:      smfs_listxattr,         /* BKL held */
421         removexattr:    smfs_removexattr,       /* BKL held */
422 };
423
424 static ssize_t smfs_read_dir(struct file *filp, char *buf, 
425                              size_t size, loff_t *ppos)
426 {
427         struct dentry *dentry = filp->f_dentry;
428         struct inode *cache_inode = NULL;
429         struct  file open_file;
430         struct  dentry open_dentry;
431         int    rc = 0;
432         
433         cache_inode = I2CI(dentry->d_inode);
434
435         if (!cache_inode) 
436                 RETURN(-EINVAL);
437
438         smfs_prepare_cachefile(dentry->d_inode, filp, cache_inode, 
439                                &open_file, &open_dentry);
440         
441         if (cache_inode->i_fop->read)
442                 rc = cache_inode->i_fop->read(&open_file, buf, size, ppos);
443
444         smfs_update_file(filp, &open_file);     
445         RETURN(rc);     
446 }
447
448 static int smfs_readdir(struct file * filp,
449                         void * dirent, 
450                         filldir_t filldir)
451 {
452         struct dentry *dentry = filp->f_dentry;
453         struct inode *cache_inode = NULL;
454         struct  file open_file;
455         struct  dentry open_dentry;
456         int    rc = 0;
457         
458         cache_inode = I2CI(dentry->d_inode);
459
460         if (!cache_inode) 
461                 RETURN(-EINVAL);
462
463         smfs_prepare_cachefile(dentry->d_inode, filp, cache_inode, 
464                                &open_file, &open_dentry);
465         
466         if (cache_inode->i_fop->readdir)
467                 rc = cache_inode->i_fop->readdir(&open_file, dirent, filldir);
468         
469         smfs_update_file(filp, &open_file);     
470         RETURN(rc);     
471 }
472
473 struct file_operations smfs_dir_fops = {
474         read:           smfs_read_dir,  
475         readdir:        smfs_readdir,           /* BKL held */
476         ioctl:          smfs_ioctl,             /* BKL held */
477         fsync:          smfs_fsync,         /* BKL held */
478 };