1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
3 *
4 * Copyright (C) 2001, 2002 Cluster File Systems, Inc.
5 * Copyright (C) 2000 Stelias Computing, Inc.
6 * Copyright (C) 2000 Red Hat, Inc.
7 *
8 * This file is part of InterMezzo, http://www.inter-mezzo.org.
9 *
10 * InterMezzo is free software; you can redistribute it and/or
11 * modify it under the terms of version 2 of the GNU General Public
12 * License as published by the Free Software Foundation.
13 *
14 * InterMezzo is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with InterMezzo; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 * vfs.c
24 *
25 * This file implements kernel downcalls from lento.
26 *
27 * Author: Rob Simmonds <simmonds@stelias.com>
28 * Andreas Dilger <adilger@stelias.com>
29 * Copyright (C) 2000 Stelias Computing Inc
30 * Copyright (C) 2000 Red Hat Inc.
31 *
32 * Extended attribute support
33 * Copyright (C) 2001 Shirish H. Phatak, Tacit Networks, Inc.
34 *
35 * This code is based on code from namei.c in the linux file system;
36 * see copyright notice below.
37 */
38
39 /** namei.c copyright **/
40
41 /*
42 * linux/fs/namei.c
43 *
44 * Copyright (C) 1991, 1992 Linus Torvalds
45 */
46
47 /*
48 * Some corrections by tytso.
49 */
50
51 /* [Feb 1997 T. Schoebel-Theuer] Complete rewrite of the pathname
52 * lookup logic.
53 */
54
55 /** end of namei.c copyright **/
56
57 #include <linux/mm.h>
58 #include <linux/proc_fs.h>
59 #include <linux/smp_lock.h>
60 #include <linux/quotaops.h>
61
62 #include <asm/uaccess.h>
63 #include <asm/unaligned.h>
64 #include <asm/semaphore.h>
65 #include <asm/pgtable.h>
66
67 #include <linux/file.h>
68 #include <linux/fs.h>
69 #include <linux/blk.h>
70
71 #include <linux/intermezzo_fs.h>
72 #include <linux/intermezzo_psdev.h>
73
74 #ifdef CONFIG_FS_EXT_ATTR
75 # include <linux/ext_attr.h>
76
77 # ifdef CONFIG_FS_POSIX_ACL
78 # include <linux/posix_acl.h>
79 # endif
80 #endif
81
82 extern struct inode_operations presto_sym_iops;
83
84 /* Write the last_rcvd values to the last_rcvd file. We don't know what the
85 * UUID or last_ctime values are, so we have to read from the file first
86 * (sigh).
87 * exported for branch_reinter in kml_reint.c*/
presto_write_last_rcvd(struct rec_info * recinfo,struct presto_file_set * fset,struct lento_vfs_context * info)88 int presto_write_last_rcvd(struct rec_info *recinfo,
89 struct presto_file_set *fset,
90 struct lento_vfs_context *info)
91 {
92 int rc;
93 struct izo_rcvd_rec rcvd_rec;
94
95 ENTRY;
96
97 memset(&rcvd_rec, 0, sizeof(rcvd_rec));
98 memcpy(rcvd_rec.lr_uuid, info->uuid, sizeof(rcvd_rec.lr_uuid));
99 rcvd_rec.lr_remote_recno = HTON__u64(info->recno);
100 rcvd_rec.lr_remote_offset = HTON__u64(info->kml_offset);
101 rcvd_rec.lr_local_recno = HTON__u64(recinfo->recno);
102 rcvd_rec.lr_local_offset = HTON__u64(recinfo->offset + recinfo->size);
103
104 rc = izo_rcvd_write(fset, &rcvd_rec);
105 if (rc < 0) {
106 /* izo_rcvd_write returns negative errors and non-negative
107 * offsets */
108 CERROR("InterMezzo: izo_rcvd_write failed: %d\n", rc);
109 EXIT;
110 return rc;
111 }
112 EXIT;
113 return 0;
114 }
115
116 /*
117 * It's inline, so penalty for filesystems that don't use sticky bit is
118 * minimal.
119 */
check_sticky(struct inode * dir,struct inode * inode)120 static inline int check_sticky(struct inode *dir, struct inode *inode)
121 {
122 if (!(dir->i_mode & S_ISVTX))
123 return 0;
124 if (inode->i_uid == current->fsuid)
125 return 0;
126 if (dir->i_uid == current->fsuid)
127 return 0;
128 return !capable(CAP_FOWNER);
129 }
130
131 /* from linux/fs/namei.c */
may_delete(struct inode * dir,struct dentry * victim,int isdir)132 static inline int may_delete(struct inode *dir,struct dentry *victim, int isdir)
133 {
134 int error;
135 if (!victim->d_inode || victim->d_parent->d_inode != dir)
136 return -ENOENT;
137 error = permission(dir,MAY_WRITE | MAY_EXEC);
138 if (error)
139 return error;
140 if (IS_APPEND(dir))
141 return -EPERM;
142 if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||
143 IS_IMMUTABLE(victim->d_inode))
144 return -EPERM;
145 if (isdir) {
146 if (!S_ISDIR(victim->d_inode->i_mode))
147 return -ENOTDIR;
148 if (IS_ROOT(victim))
149 return -EBUSY;
150 } else if (S_ISDIR(victim->d_inode->i_mode))
151 return -EISDIR;
152 return 0;
153 }
154
155 /* from linux/fs/namei.c */
may_create(struct inode * dir,struct dentry * child)156 static inline int may_create(struct inode *dir, struct dentry *child) {
157 if (child->d_inode)
158 return -EEXIST;
159 if (IS_DEADDIR(dir))
160 return -ENOENT;
161 return permission(dir,MAY_WRITE | MAY_EXEC);
162 }
163
164 #ifdef PRESTO_DEBUG
165 /* The loop_discard_io() function is available via a kernel patch to the
166 * loop block device. It "works" by accepting writes, but throwing them
167 * away, rather than trying to write them to disk. The old method worked
168 * by setting the underlying device read-only, but that has the problem
169 * that dirty buffers are kept in memory, and ext3 didn't like that at all.
170 */
171 #ifdef CONFIG_LOOP_DISCARD
172 #define BLKDEV_FAIL(dev,fail) loop_discard_io(dev,fail)
173 #else
174 #define BLKDEV_FAIL(dev,fail) set_device_ro(dev, 1)
175 #endif
176
177 /* If a breakpoint has been set via /proc/sys/intermezzo/intermezzoX/errorval,
178 * that is the same as "value", the underlying device will "fail" now.
179 */
presto_debug_fail_blkdev(struct presto_file_set * fset,unsigned long value)180 inline void presto_debug_fail_blkdev(struct presto_file_set *fset,
181 unsigned long value)
182 {
183 int minor = presto_f2m(fset);
184 int errorval = izo_channels[minor].uc_errorval;
185 kdev_t dev = fset->fset_dentry->d_inode->i_dev;
186
187 if (errorval && errorval == (long)value && !is_read_only(dev)) {
188 CDEBUG(D_SUPER, "setting device %s read only\n", kdevname(dev));
189 BLKDEV_FAIL(dev, 1);
190 izo_channels[minor].uc_errorval = -dev;
191 }
192 }
193 #else
194 #define presto_debug_fail_blkdev(dev,value) do {} while (0)
195 #endif
196
197
presto_do_kml(struct lento_vfs_context * info,struct dentry * dentry)198 static inline int presto_do_kml(struct lento_vfs_context *info,
199 struct dentry *dentry)
200 {
201 if ( ! (info->flags & LENTO_FL_KML) )
202 return 0;
203 if ( presto_chk(dentry, PRESTO_DONT_JOURNAL) )
204 return 0;
205 return 1;
206 }
207
presto_do_rcvd(struct lento_vfs_context * info,struct dentry * dentry)208 static inline int presto_do_rcvd(struct lento_vfs_context *info,
209 struct dentry *dentry)
210 {
211 if ( ! (info->flags & LENTO_FL_EXPECT) )
212 return 0;
213 if ( presto_chk(dentry, PRESTO_DONT_JOURNAL) )
214 return 0;
215 return 1;
216 }
217
218
219 /* XXX fixme: this should not fail, all these dentries are in memory
220 when _we_ call this */
presto_settime(struct presto_file_set * fset,struct dentry * newobj,struct dentry * parent,struct dentry * target,struct lento_vfs_context * ctx,int valid)221 int presto_settime(struct presto_file_set *fset,
222 struct dentry *newobj,
223 struct dentry *parent,
224 struct dentry *target,
225 struct lento_vfs_context *ctx,
226 int valid)
227 {
228 int error = 0;
229 struct dentry *dentry;
230 struct inode *inode;
231 struct inode_operations *iops;
232 struct iattr iattr;
233
234 ENTRY;
235 if (ctx->flags & LENTO_FL_IGNORE_TIME ) {
236 EXIT;
237 return 0;
238 }
239
240 iattr.ia_ctime = ctx->updated_time;
241 iattr.ia_mtime = ctx->updated_time;
242 iattr.ia_valid = valid;
243
244 while (1) {
245 if (parent && ctx->flags & LENTO_FL_TOUCH_PARENT) {
246 dentry = parent;
247 parent = NULL;
248 } else if (newobj && ctx->flags & LENTO_FL_TOUCH_NEWOBJ) {
249 dentry = newobj;
250 newobj = NULL;
251 } else if (target) {
252 dentry = target;
253 target = NULL;
254 } else
255 break;
256
257 inode = dentry->d_inode;
258
259 error = -EROFS;
260 if (IS_RDONLY(inode)) {
261 EXIT;
262 return -EROFS;
263 }
264
265 if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
266 EXIT;
267 return -EPERM;
268 }
269
270 error = -EPERM;
271 iops = filter_c2cdiops(fset->fset_cache->cache_filter);
272 if (!iops) {
273 EXIT;
274 return error;
275 }
276
277 if (iops->setattr != NULL)
278 error = iops->setattr(dentry, &iattr);
279 else {
280 error = 0;
281 inode_setattr(dentry->d_inode, &iattr);
282 }
283 }
284 EXIT;
285 return error;
286 }
287
izo_get_rollback_data(struct inode * inode,struct izo_rollback_data * rb)288 void izo_get_rollback_data(struct inode *inode, struct izo_rollback_data *rb)
289 {
290 rb->rb_mode = (__u32)inode->i_mode;
291 rb->rb_rdev = (__u32)inode->i_rdev;
292 rb->rb_uid = (__u64)inode->i_uid;
293 rb->rb_gid = (__u64)inode->i_gid;
294 }
295
296
presto_do_close(struct presto_file_set * fset,struct file * file)297 int presto_do_close(struct presto_file_set *fset, struct file *file)
298 {
299 struct rec_info rec;
300 int rc = -ENOSPC;
301 void *handle;
302 struct inode *inode = file->f_dentry->d_inode;
303 struct presto_file_data *fdata =
304 (struct presto_file_data *)file->private_data;
305
306 ENTRY;
307 presto_getversion(&fdata->fd_info.remote_version, inode);
308
309 rc = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH);
310 if (rc) {
311 EXIT;
312 return rc;
313 }
314
315 handle = presto_trans_start(fset, file->f_dentry->d_inode,
316 KML_OPCODE_RELEASE);
317 if ( IS_ERR(handle) ) {
318 CERROR("presto_release: no space for transaction\n");
319 return rc;
320 }
321
322 if (fdata->fd_info.flags & LENTO_FL_KML)
323 rc = presto_journal_close(&rec, fset, file, file->f_dentry,
324 &fdata->fd_version,
325 &fdata->fd_info.remote_version);
326 if (rc) {
327 CERROR("presto_close: cannot journal close\n");
328 goto out;
329 }
330
331 if (fdata->fd_info.flags & LENTO_FL_EXPECT)
332 rc = presto_write_last_rcvd(&rec, fset, &fdata->fd_info);
333
334 if (rc) {
335 CERROR("presto_close: cannot journal last_rcvd\n");
336 goto out;
337 }
338 presto_trans_commit(fset, handle);
339
340 /* cancel the LML record */
341 handle = presto_trans_start(fset, inode, KML_OPCODE_WRITE);
342 if ( IS_ERR(handle) ) {
343 CERROR("presto_release: no space for clear\n");
344 return -ENOSPC;
345 }
346
347 rc = presto_clear_lml_close(fset, fdata->fd_lml_offset);
348 if (rc < 0 ) {
349 CERROR("presto_close: cannot journal close\n");
350 goto out;
351 }
352 presto_truncate_lml(fset);
353
354 out:
355 presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
356 presto_trans_commit(fset, handle);
357 EXIT;
358 return rc;
359 }
360
presto_do_setattr(struct presto_file_set * fset,struct dentry * dentry,struct iattr * iattr,struct lento_vfs_context * info)361 int presto_do_setattr(struct presto_file_set *fset, struct dentry *dentry,
362 struct iattr *iattr, struct lento_vfs_context *info)
363 {
364 struct rec_info rec;
365 struct inode *inode = dentry->d_inode;
366 struct inode_operations *iops;
367 int error;
368 struct presto_version old_ver, new_ver;
369 struct izo_rollback_data rb;
370 void *handle;
371 loff_t old_size=inode->i_size;
372
373 ENTRY;
374 error = -EROFS;
375 if (IS_RDONLY(inode)) {
376 EXIT;
377 return -EROFS;
378 }
379
380 if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
381 EXIT;
382 return -EPERM;
383 }
384
385 presto_getversion(&old_ver, dentry->d_inode);
386 izo_get_rollback_data(dentry->d_inode, &rb);
387 error = -EPERM;
388 iops = filter_c2cdiops(fset->fset_cache->cache_filter);
389
390 error = presto_reserve_space(fset->fset_cache, 2*PRESTO_REQHIGH);
391 if (error) {
392 EXIT;
393 return error;
394 }
395
396 if (iattr->ia_valid & ATTR_SIZE) {
397 if (izo_mark_dentry(dentry, ~PRESTO_DATA, 0, NULL) != 0)
398 CERROR("izo_mark_dentry(inode %ld, ~PRESTO_DATA) "
399 "failed\n", dentry->d_inode->i_ino);
400 handle = presto_trans_start(fset, dentry->d_inode,
401 KML_OPCODE_TRUNC);
402 } else {
403 handle = presto_trans_start(fset, dentry->d_inode,
404 KML_OPCODE_SETATTR);
405 }
406
407 if ( IS_ERR(handle) ) {
408 CERROR("presto_do_setattr: no space for transaction\n");
409 presto_release_space(fset->fset_cache, 2*PRESTO_REQHIGH);
410 return -ENOSPC;
411 }
412
413 if (dentry->d_inode && iops && iops->setattr) {
414 error = iops->setattr(dentry, iattr);
415 } else {
416 error = inode_change_ok(dentry->d_inode, iattr);
417 if (!error)
418 inode_setattr(inode, iattr);
419 }
420
421 if (!error && (iattr->ia_valid & ATTR_SIZE))
422 vmtruncate(inode, iattr->ia_size);
423
424 if (error) {
425 EXIT;
426 goto exit;
427 }
428
429 presto_debug_fail_blkdev(fset, KML_OPCODE_SETATTR | 0x10);
430
431 if ( presto_do_kml(info, dentry) ) {
432 if ((iattr->ia_valid & ATTR_SIZE) && (old_size != inode->i_size)) {
433 struct file file;
434 /* Journal a close whenever we see a potential truncate
435 * At the receiving end, lento should explicitly remove
436 * ATTR_SIZE from the list of valid attributes */
437 presto_getversion(&new_ver, inode);
438 file.private_data = NULL;
439 file.f_dentry = dentry;
440 error = presto_journal_close(&rec, fset, &file, dentry,
441 &old_ver, &new_ver);
442 }
443
444 if (!error)
445 error = presto_journal_setattr(&rec, fset, dentry,
446 &old_ver, &rb, iattr);
447 }
448
449 presto_debug_fail_blkdev(fset, KML_OPCODE_SETATTR | 0x20);
450 if ( presto_do_rcvd(info, dentry) )
451 error = presto_write_last_rcvd(&rec, fset, info);
452
453 presto_debug_fail_blkdev(fset, KML_OPCODE_SETATTR | 0x30);
454
455 EXIT;
456 exit:
457 presto_release_space(fset->fset_cache, 2*PRESTO_REQHIGH);
458 presto_trans_commit(fset, handle);
459 return error;
460 }
461
lento_setattr(const char * name,struct iattr * iattr,struct lento_vfs_context * info)462 int lento_setattr(const char *name, struct iattr *iattr,
463 struct lento_vfs_context *info)
464 {
465 struct nameidata nd;
466 struct dentry *dentry;
467 struct presto_file_set *fset;
468 int error;
469 #ifdef CONFIG_FS_POSIX_ACL
470 int (*set_posix_acl)(struct inode *, int type, posix_acl_t *)=NULL;
471 #endif
472
473 ENTRY;
474 CDEBUG(D_PIOCTL,"name %s, valid %#x, mode %#o, uid %d, gid %d, size %Ld\n",
475 name, iattr->ia_valid, iattr->ia_mode, iattr->ia_uid,
476 iattr->ia_gid, iattr->ia_size);
477 CDEBUG(D_PIOCTL, "atime %#lx, mtime %#lx, ctime %#lx, attr_flags %#x\n",
478 iattr->ia_atime, iattr->ia_mtime, iattr->ia_ctime,
479 iattr->ia_attr_flags);
480 CDEBUG(D_PIOCTL, "offset %d, recno %d, flags %#x\n",
481 info->slot_offset, info->recno, info->flags);
482
483 lock_kernel();
484 error = presto_walk(name, &nd);
485 if (error) {
486 EXIT;
487 goto exit;
488 }
489 dentry = nd.dentry;
490
491 fset = presto_fset(dentry);
492 error = -EINVAL;
493 if ( !fset ) {
494 CERROR("No fileset!\n");
495 EXIT;
496 goto exit_lock;
497 }
498
499 /* NOTE: this prevents us from changing the filetype on setattr,
500 * as we normally only want to change permission bits.
501 * If this is not correct, then we need to fix the perl code
502 * to always send the file type OR'ed with the permission.
503 */
504 if (iattr->ia_valid & ATTR_MODE) {
505 int set_mode = iattr->ia_mode;
506 iattr->ia_mode = (iattr->ia_mode & S_IALLUGO) |
507 (dentry->d_inode->i_mode & ~S_IALLUGO);
508 CDEBUG(D_PIOCTL, "chmod: orig %#o, set %#o, result %#o\n",
509 dentry->d_inode->i_mode, set_mode, iattr->ia_mode);
510 #ifdef CONFIG_FS_POSIX_ACL
511 /* ACl code interacts badly with setattr
512 * since it tries to modify the ACL using
513 * set_ext_attr which recurses back into presto.
514 * This only happens if ATTR_MODE is set.
515 * Here we are doing a "forced" mode set
516 * (initiated by lento), so we disable the
517 * set_posix_acl operation which
518 * prevents such recursion. -SHP
519 *
520 * This will probably still be required when native
521 * acl journalling is in place.
522 */
523 set_posix_acl=dentry->d_inode->i_op->set_posix_acl;
524 dentry->d_inode->i_op->set_posix_acl=NULL;
525 #endif
526 }
527
528 error = presto_do_setattr(fset, dentry, iattr, info);
529
530 if (info->flags & LENTO_FL_SET_DDFILEID) {
531 struct presto_dentry_data *dd = presto_d2d(dentry);
532 if (dd) {
533 dd->remote_ino = info->remote_ino;
534 dd->remote_generation = info->remote_generation;
535 }
536 }
537
538 #ifdef CONFIG_FS_POSIX_ACL
539 /* restore the inode_operations if we changed them*/
540 if (iattr->ia_valid & ATTR_MODE)
541 dentry->d_inode->i_op->set_posix_acl=set_posix_acl;
542 #endif
543
544
545 EXIT;
546 exit_lock:
547 path_release(&nd);
548 exit:
549 unlock_kernel();
550 return error;
551 }
552
presto_do_create(struct presto_file_set * fset,struct dentry * dir,struct dentry * dentry,int mode,struct lento_vfs_context * info)553 int presto_do_create(struct presto_file_set *fset, struct dentry *dir,
554 struct dentry *dentry, int mode,
555 struct lento_vfs_context *info)
556 {
557 struct rec_info rec;
558 int error;
559 struct presto_version tgt_dir_ver, new_file_ver;
560 struct inode_operations *iops;
561 void *handle;
562
563 ENTRY;
564 mode &= S_IALLUGO;
565 mode |= S_IFREG;
566
567 down(&dir->d_inode->i_zombie);
568 error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH);
569 if (error) {
570 EXIT;
571 up(&dir->d_inode->i_zombie);
572 return error;
573 }
574
575 error = may_create(dir->d_inode, dentry);
576 if (error) {
577 EXIT;
578 goto exit_pre_lock;
579 }
580
581 error = -EPERM;
582 iops = filter_c2cdiops(fset->fset_cache->cache_filter);
583 if (!iops->create) {
584 EXIT;
585 goto exit_pre_lock;
586 }
587
588 presto_getversion(&tgt_dir_ver, dir->d_inode);
589 handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_CREATE);
590 if ( IS_ERR(handle) ) {
591 EXIT;
592 presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
593 CERROR("presto_do_create: no space for transaction\n");
594 error=-ENOSPC;
595 goto exit_pre_lock;
596 }
597 DQUOT_INIT(dir->d_inode);
598 lock_kernel();
599 error = iops->create(dir->d_inode, dentry, mode);
600 if (error) {
601 EXIT;
602 goto exit_lock;
603 }
604
605 if (dentry->d_inode) {
606 struct presto_cache *cache = fset->fset_cache;
607 /* was this already done? */
608 presto_set_ops(dentry->d_inode, cache->cache_filter);
609
610 filter_setup_dentry_ops(cache->cache_filter,
611 dentry->d_op,
612 &presto_dentry_ops);
613 dentry->d_op = filter_c2udops(cache->cache_filter);
614
615 /* if Lento creates this file, we won't have data */
616 if ( ISLENTO(presto_c2m(cache)) ) {
617 presto_set(dentry, PRESTO_ATTR);
618 } else {
619 presto_set(dentry, PRESTO_ATTR | PRESTO_DATA);
620 }
621 }
622
623 info->flags |= LENTO_FL_TOUCH_PARENT;
624 error = presto_settime(fset, NULL, dir, dentry,
625 info, ATTR_CTIME | ATTR_MTIME);
626 if (error) {
627 EXIT;
628 goto exit_lock;
629 }
630
631 presto_debug_fail_blkdev(fset, KML_OPCODE_CREATE | 0x10);
632
633 if ( presto_do_kml(info, dentry) ) {
634 presto_getversion(&new_file_ver, dentry->d_inode);
635 error = presto_journal_create(&rec, fset, dentry, &tgt_dir_ver,
636 &new_file_ver,
637 dentry->d_inode->i_mode);
638 }
639
640 presto_debug_fail_blkdev(fset, KML_OPCODE_CREATE | 0x20);
641
642 if ( presto_do_rcvd(info, dentry) )
643 error = presto_write_last_rcvd(&rec, fset, info);
644
645 presto_debug_fail_blkdev(fset, KML_OPCODE_CREATE | 0x30);
646
647 /* add inode dentry */
648 if (fset->fset_cache->cache_filter->o_trops->tr_add_ilookup ) {
649 struct dentry *d;
650 d = fset->fset_cache->cache_filter->o_trops->tr_add_ilookup
651 (dir->d_inode->i_sb->s_root, dentry);
652 }
653
654 EXIT;
655
656 exit_lock:
657 unlock_kernel();
658 presto_trans_commit(fset, handle);
659 exit_pre_lock:
660 presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
661 up(&dir->d_inode->i_zombie);
662 return error;
663 }
664
665 /* from namei.c */
lookup_create(struct nameidata * nd,int is_dir)666 static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
667 {
668 struct dentry *dentry;
669
670 down(&nd->dentry->d_inode->i_sem);
671 dentry = ERR_PTR(-EEXIST);
672 if (nd->last_type != LAST_NORM)
673 goto fail;
674 dentry = lookup_hash(&nd->last, nd->dentry);
675 if (IS_ERR(dentry))
676 goto fail;
677 if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
678 goto enoent;
679 return dentry;
680 enoent:
681 dput(dentry);
682 dentry = ERR_PTR(-ENOENT);
683 fail:
684 return dentry;
685 }
686
lento_create(const char * name,int mode,struct lento_vfs_context * info)687 int lento_create(const char *name, int mode, struct lento_vfs_context *info)
688 {
689 int error;
690 struct nameidata nd;
691 char * pathname;
692 struct dentry *dentry;
693 struct presto_file_set *fset;
694
695 ENTRY;
696 pathname = getname(name);
697 error = PTR_ERR(pathname);
698 if (IS_ERR(pathname)) {
699 EXIT;
700 goto exit;
701 }
702
703 /* this looks up the parent */
704 // if (path_init(pathname, LOOKUP_FOLLOW | LOOKUP_POSITIVE, &nd))
705 if (path_init(pathname, LOOKUP_PARENT, &nd))
706 error = path_walk(pathname, &nd);
707 if (error) {
708 EXIT;
709 goto exit;
710 }
711 dentry = lookup_create(&nd, 0);
712 error = PTR_ERR(dentry);
713 if (IS_ERR(dentry)) {
714 EXIT;
715 goto exit_lock;
716 }
717
718 fset = presto_fset(dentry);
719 error = -EINVAL;
720 if ( !fset ) {
721 CERROR("No fileset!\n");
722 EXIT;
723 goto exit_lock;
724 }
725 error = presto_do_create(fset, dentry->d_parent, dentry, (mode&S_IALLUGO)|S_IFREG,
726 info);
727
728 EXIT;
729
730 exit_lock:
731 path_release (&nd);
732 dput(dentry);
733 up(&dentry->d_parent->d_inode->i_sem);
734 putname(pathname);
735 exit:
736 return error;
737 }
738
presto_do_link(struct presto_file_set * fset,struct dentry * old_dentry,struct dentry * dir,struct dentry * new_dentry,struct lento_vfs_context * info)739 int presto_do_link(struct presto_file_set *fset, struct dentry *old_dentry,
740 struct dentry *dir, struct dentry *new_dentry,
741 struct lento_vfs_context *info)
742 {
743 struct rec_info rec;
744 struct inode *inode;
745 int error;
746 struct inode_operations *iops;
747 struct presto_version tgt_dir_ver;
748 struct presto_version new_link_ver;
749 void *handle;
750
751 down(&dir->d_inode->i_zombie);
752 error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH);
753 if (error) {
754 EXIT;
755 up(&dir->d_inode->i_zombie);
756 return error;
757 }
758 error = -ENOENT;
759 inode = old_dentry->d_inode;
760 if (!inode)
761 goto exit_lock;
762
763 error = may_create(dir->d_inode, new_dentry);
764 if (error)
765 goto exit_lock;
766
767 error = -EXDEV;
768 if (dir->d_inode->i_dev != inode->i_dev)
769 goto exit_lock;
770
771 /*
772 * A link to an append-only or immutable file cannot be created.
773 */
774 error = -EPERM;
775 if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) {
776 EXIT;
777 goto exit_lock;
778 }
779
780 iops = filter_c2cdiops(fset->fset_cache->cache_filter);
781 if (!iops->link) {
782 EXIT;
783 goto exit_lock;
784 }
785
786
787 presto_getversion(&tgt_dir_ver, dir->d_inode);
788 handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_LINK);
789 if ( IS_ERR(handle) ) {
790 presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
791 CERROR("presto_do_link: no space for transaction\n");
792 return -ENOSPC;
793 }
794
795 DQUOT_INIT(dir->d_inode);
796 lock_kernel();
797 error = iops->link(old_dentry, dir->d_inode, new_dentry);
798 unlock_kernel();
799 if (error) {
800 EXIT;
801 goto exit_lock;
802 }
803
804 /* link dd data to that of existing dentry */
805 old_dentry->d_op->d_release(new_dentry);
806 if (!presto_d2d(old_dentry))
807 BUG();
808 presto_d2d(old_dentry)->dd_count++;
809
810 new_dentry->d_fsdata = presto_d2d(old_dentry);
811
812 info->flags |= LENTO_FL_TOUCH_PARENT;
813 error = presto_settime(fset, NULL, dir, new_dentry,
814 info, ATTR_CTIME);
815 if (error) {
816 EXIT;
817 goto exit_lock;
818 }
819
820 presto_debug_fail_blkdev(fset, KML_OPCODE_LINK | 0x10);
821 presto_getversion(&new_link_ver, new_dentry->d_inode);
822 if ( presto_do_kml(info, old_dentry) )
823 error = presto_journal_link(&rec, fset, old_dentry, new_dentry,
824 &tgt_dir_ver, &new_link_ver);
825
826 presto_debug_fail_blkdev(fset, KML_OPCODE_LINK | 0x20);
827 if ( presto_do_rcvd(info, old_dentry) )
828 error = presto_write_last_rcvd(&rec, fset, info);
829
830 presto_debug_fail_blkdev(fset, KML_OPCODE_LINK | 0x30);
831 EXIT;
832 presto_trans_commit(fset, handle);
833 exit_lock:
834 presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
835 up(&dir->d_inode->i_zombie);
836 return error;
837 }
838
839
lento_link(const char * oldname,const char * newname,struct lento_vfs_context * info)840 int lento_link(const char * oldname, const char * newname,
841 struct lento_vfs_context *info)
842 {
843 int error;
844 char * from;
845 char * to;
846 struct presto_file_set *fset;
847
848 from = getname(oldname);
849 if(IS_ERR(from))
850 return PTR_ERR(from);
851 to = getname(newname);
852 error = PTR_ERR(to);
853 if (!IS_ERR(to)) {
854 struct dentry *new_dentry;
855 struct nameidata nd, old_nd;
856
857 error = 0;
858 if (path_init(from, LOOKUP_POSITIVE, &old_nd))
859 error = path_walk(from, &old_nd);
860 if (error)
861 goto exit;
862 if (path_init(to, LOOKUP_PARENT, &nd))
863 error = path_walk(to, &nd);
864 if (error)
865 goto out;
866 error = -EXDEV;
867 if (old_nd.mnt != nd.mnt)
868 goto out;
869 new_dentry = lookup_create(&nd, 0);
870 error = PTR_ERR(new_dentry);
871
872 if (!IS_ERR(new_dentry)) {
873 fset = presto_fset(new_dentry);
874 error = -EINVAL;
875 if ( !fset ) {
876 CERROR("No fileset!\n");
877 EXIT;
878 goto out2;
879 }
880 error = presto_do_link(fset, old_nd.dentry,
881 nd.dentry,
882 new_dentry, info);
883 dput(new_dentry);
884 }
885 out2:
886 up(&nd.dentry->d_inode->i_sem);
887 path_release(&nd);
888 out:
889 path_release(&old_nd);
890 exit:
891 putname(to);
892 }
893 putname(from);
894
895 return error;
896 }
897
presto_do_unlink(struct presto_file_set * fset,struct dentry * dir,struct dentry * dentry,struct lento_vfs_context * info)898 int presto_do_unlink(struct presto_file_set *fset, struct dentry *dir,
899 struct dentry *dentry, struct lento_vfs_context *info)
900 {
901 struct rec_info rec;
902 struct inode_operations *iops;
903 struct presto_version tgt_dir_ver, old_file_ver;
904 struct izo_rollback_data rb;
905 void *handle;
906 int do_kml = 0, do_rcvd = 0, linkno = 0, error, old_targetlen = 0;
907 char *old_target = NULL;
908
909 ENTRY;
910 down(&dir->d_inode->i_zombie);
911 error = may_delete(dir->d_inode, dentry, 0);
912 if (error) {
913 EXIT;
914 up(&dir->d_inode->i_zombie);
915 return error;
916 }
917
918 error = -EPERM;
919 iops = filter_c2cdiops(fset->fset_cache->cache_filter);
920 if (!iops->unlink) {
921 EXIT;
922 up(&dir->d_inode->i_zombie);
923 return error;
924 }
925
926 error = presto_reserve_space(fset->fset_cache, PRESTO_REQLOW);
927 if (error) {
928 EXIT;
929 up(&dir->d_inode->i_zombie);
930 return error;
931 }
932
933
934 if (presto_d2d(dentry)) {
935 struct presto_dentry_data *dd = presto_d2d(dentry);
936 struct dentry *de = dd->dd_inodentry;
937 if (de && dentry->d_inode->i_nlink == 1) {
938 dd->dd_count--;
939 dd->dd_inodentry = NULL;
940 de->d_fsdata = NULL;
941 atomic_dec(&de->d_inode->i_count);
942 de->d_inode = NULL;
943 dput(de);
944 }
945 }
946
947 presto_getversion(&tgt_dir_ver, dir->d_inode);
948 presto_getversion(&old_file_ver, dentry->d_inode);
949 izo_get_rollback_data(dentry->d_inode, &rb);
950 handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_UNLINK);
951 if ( IS_ERR(handle) ) {
952 presto_release_space(fset->fset_cache, PRESTO_REQLOW);
953 CERROR("ERROR: presto_do_unlink: no space for transaction. Tell Peter.\n");
954 up(&dir->d_inode->i_zombie);
955 return -ENOSPC;
956 }
957 DQUOT_INIT(dir->d_inode);
958 if (d_mountpoint(dentry))
959 error = -EBUSY;
960 else {
961 lock_kernel();
962 linkno = dentry->d_inode->i_nlink;
963 if (linkno > 1) {
964 dget(dentry);
965 }
966
967 if (S_ISLNK(dentry->d_inode->i_mode)) {
968 mm_segment_t old_fs;
969 struct inode_operations *riops;
970 riops = filter_c2csiops(fset->fset_cache->cache_filter);
971
972 PRESTO_ALLOC(old_target, PATH_MAX);
973 if (old_target == NULL) {
974 error = -ENOMEM;
975 EXIT;
976 goto exit;
977 }
978
979 old_fs = get_fs();
980 set_fs(get_ds());
981
982 if (riops->readlink == NULL)
983 CERROR("InterMezzo %s: no readlink iops.\n",
984 __FUNCTION__);
985 else
986 old_targetlen =
987 riops->readlink(dentry, old_target,
988 PATH_MAX);
989 if (old_targetlen < 0) {
990 CERROR("InterMezzo: readlink failed: %ld\n",
991 PTR_ERR(old_target));
992 PRESTO_FREE(old_target, PATH_MAX);
993 old_target = NULL;
994 old_targetlen = 0;
995 }
996 set_fs(old_fs);
997 }
998
999 do_kml = presto_do_kml(info, dir);
1000 do_rcvd = presto_do_rcvd(info, dir);
1001 error = iops->unlink(dir->d_inode, dentry);
1002 unlock_kernel();
1003 if (!error)
1004 d_delete(dentry);
1005 }
1006
1007 if (linkno > 1) {
1008 /* FIXME: Combine this with the next call? */
1009 error = presto_settime(fset, NULL, NULL, dentry,
1010 info, ATTR_CTIME);
1011 dput(dentry);
1012 if (error) {
1013 EXIT;
1014 goto exit;
1015 }
1016 }
1017
1018 error = presto_settime(fset, NULL, NULL, dir,
1019 info, ATTR_CTIME | ATTR_MTIME);
1020 if (error) {
1021 EXIT;
1022 goto exit;
1023 }
1024
1025 up(&dir->d_inode->i_zombie);
1026 if (error) {
1027 EXIT;
1028 goto exit;
1029 }
1030
1031 presto_debug_fail_blkdev(fset, KML_OPCODE_UNLINK | 0x10);
1032 if ( do_kml )
1033 error = presto_journal_unlink(&rec, fset, dir, &tgt_dir_ver,
1034 &old_file_ver, &rb, dentry,
1035 old_target, old_targetlen);
1036 presto_debug_fail_blkdev(fset, KML_OPCODE_UNLINK | 0x20);
1037 if ( do_rcvd ) {
1038 error = presto_write_last_rcvd(&rec, fset, info);
1039 }
1040 presto_debug_fail_blkdev(fset, KML_OPCODE_UNLINK | 0x30);
1041 EXIT;
1042 exit:
1043 presto_release_space(fset->fset_cache, PRESTO_REQLOW);
1044 presto_trans_commit(fset, handle);
1045 if (old_target != NULL)
1046 PRESTO_FREE(old_target, PATH_MAX);
1047 return error;
1048 }
1049
1050
lento_unlink(const char * pathname,struct lento_vfs_context * info)1051 int lento_unlink(const char *pathname, struct lento_vfs_context *info)
1052 {
1053 int error = 0;
1054 char * name;
1055 struct dentry *dentry;
1056 struct nameidata nd;
1057 struct presto_file_set *fset;
1058
1059 ENTRY;
1060
1061 name = getname(pathname);
1062 if(IS_ERR(name))
1063 return PTR_ERR(name);
1064
1065 if (path_init(name, LOOKUP_PARENT, &nd))
1066 error = path_walk(name, &nd);
1067 if (error)
1068 goto exit;
1069 error = -EISDIR;
1070 if (nd.last_type != LAST_NORM)
1071 goto exit1;
1072 down(&nd.dentry->d_inode->i_sem);
1073 dentry = lookup_hash(&nd.last, nd.dentry);
1074 error = PTR_ERR(dentry);
1075 if (!IS_ERR(dentry)) {
1076 fset = presto_fset(dentry);
1077 error = -EINVAL;
1078 if ( !fset ) {
1079 CERROR("No fileset!\n");
1080 EXIT;
1081 goto exit2;
1082 }
1083 /* Why not before? Because we want correct error value */
1084 if (nd.last.name[nd.last.len])
1085 goto slashes;
1086 error = presto_do_unlink(fset, nd.dentry, dentry, info);
1087 exit2:
1088 EXIT;
1089 dput(dentry);
1090 }
1091 up(&nd.dentry->d_inode->i_sem);
1092 exit1:
1093 path_release(&nd);
1094 exit:
1095 putname(name);
1096
1097 return error;
1098
1099 slashes:
1100 error = !dentry->d_inode ? -ENOENT :
1101 S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR;
1102 goto exit2;
1103 }
1104
presto_do_symlink(struct presto_file_set * fset,struct dentry * dir,struct dentry * dentry,const char * oldname,struct lento_vfs_context * info)1105 int presto_do_symlink(struct presto_file_set *fset, struct dentry *dir,
1106 struct dentry *dentry, const char *oldname,
1107 struct lento_vfs_context *info)
1108 {
1109 struct rec_info rec;
1110 int error;
1111 struct presto_version tgt_dir_ver, new_link_ver;
1112 struct inode_operations *iops;
1113 void *handle;
1114
1115 ENTRY;
1116 down(&dir->d_inode->i_zombie);
1117 /* record + max path len + space to free */
1118 error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH + 4096);
1119 if (error) {
1120 EXIT;
1121 up(&dir->d_inode->i_zombie);
1122 return error;
1123 }
1124
1125 error = may_create(dir->d_inode, dentry);
1126 if (error) {
1127 EXIT;
1128 goto exit_lock;
1129 }
1130
1131 error = -EPERM;
1132 iops = filter_c2cdiops(fset->fset_cache->cache_filter);
1133 if (!iops->symlink) {
1134 EXIT;
1135 goto exit_lock;
1136 }
1137
1138 presto_getversion(&tgt_dir_ver, dir->d_inode);
1139 handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_SYMLINK);
1140 if ( IS_ERR(handle) ) {
1141 presto_release_space(fset->fset_cache, PRESTO_REQHIGH + 4096);
1142 CERROR("ERROR: presto_do_symlink: no space for transaction. Tell Peter.\n");
1143 EXIT;
1144 up(&dir->d_inode->i_zombie);
1145 return -ENOSPC;
1146 }
1147 DQUOT_INIT(dir->d_inode);
1148 lock_kernel();
1149 error = iops->symlink(dir->d_inode, dentry, oldname);
1150 if (error) {
1151 EXIT;
1152 goto exit;
1153 }
1154
1155 if (dentry->d_inode) {
1156 struct presto_cache *cache = fset->fset_cache;
1157
1158 presto_set_ops(dentry->d_inode, cache->cache_filter);
1159
1160 filter_setup_dentry_ops(cache->cache_filter, dentry->d_op,
1161 &presto_dentry_ops);
1162 dentry->d_op = filter_c2udops(cache->cache_filter);
1163 /* XXX ? Cache state ? if Lento creates a symlink */
1164 if ( ISLENTO(presto_c2m(cache)) ) {
1165 presto_set(dentry, PRESTO_ATTR);
1166 } else {
1167 presto_set(dentry, PRESTO_ATTR | PRESTO_DATA);
1168 }
1169 }
1170
1171 info->flags |= LENTO_FL_TOUCH_PARENT;
1172 error = presto_settime(fset, NULL, dir, dentry,
1173 info, ATTR_CTIME | ATTR_MTIME);
1174 if (error) {
1175 EXIT;
1176 goto exit;
1177 }
1178
1179 presto_debug_fail_blkdev(fset, KML_OPCODE_SYMLINK | 0x10);
1180 presto_getversion(&new_link_ver, dentry->d_inode);
1181 if ( presto_do_kml(info, dentry) )
1182 error = presto_journal_symlink(&rec, fset, dentry, oldname,
1183 &tgt_dir_ver, &new_link_ver);
1184
1185 presto_debug_fail_blkdev(fset, KML_OPCODE_SYMLINK | 0x20);
1186 if ( presto_do_rcvd(info, dentry) )
1187 error = presto_write_last_rcvd(&rec, fset, info);
1188
1189 presto_debug_fail_blkdev(fset, KML_OPCODE_SYMLINK | 0x30);
1190 EXIT;
1191 exit:
1192 unlock_kernel();
1193 presto_trans_commit(fset, handle);
1194 exit_lock:
1195 presto_release_space(fset->fset_cache, PRESTO_REQHIGH + 4096);
1196 up(&dir->d_inode->i_zombie);
1197 return error;
1198 }
1199
lento_symlink(const char * oldname,const char * newname,struct lento_vfs_context * info)1200 int lento_symlink(const char *oldname, const char *newname,
1201 struct lento_vfs_context *info)
1202 {
1203 int error;
1204 char *from;
1205 char *to;
1206 struct dentry *dentry;
1207 struct presto_file_set *fset;
1208 struct nameidata nd;
1209
1210 ENTRY;
1211 lock_kernel();
1212 from = getname(oldname);
1213 error = PTR_ERR(from);
1214 if (IS_ERR(from)) {
1215 EXIT;
1216 goto exit;
1217 }
1218
1219 to = getname(newname);
1220 error = PTR_ERR(to);
1221 if (IS_ERR(to)) {
1222 EXIT;
1223 goto exit_from;
1224 }
1225
1226 if (path_init(to, LOOKUP_PARENT, &nd))
1227 error = path_walk(to, &nd);
1228 if (error) {
1229 EXIT;
1230 goto exit_to;
1231 }
1232
1233 dentry = lookup_create(&nd, 0);
1234 error = PTR_ERR(dentry);
1235 if (IS_ERR(dentry)) {
1236 path_release(&nd);
1237 EXIT;
1238 goto exit_to;
1239 }
1240
1241 fset = presto_fset(dentry);
1242 error = -EINVAL;
1243 if ( !fset ) {
1244 CERROR("No fileset!\n");
1245 path_release(&nd);
1246 EXIT;
1247 goto exit_lock;
1248 }
1249 error = presto_do_symlink(fset, nd.dentry,
1250 dentry, from, info);
1251 path_release(&nd);
1252 EXIT;
1253 exit_lock:
1254 up(&nd.dentry->d_inode->i_sem);
1255 dput(dentry);
1256 exit_to:
1257 putname(to);
1258 exit_from:
1259 putname(from);
1260 exit:
1261 unlock_kernel();
1262 return error;
1263 }
1264
presto_do_mkdir(struct presto_file_set * fset,struct dentry * dir,struct dentry * dentry,int mode,struct lento_vfs_context * info)1265 int presto_do_mkdir(struct presto_file_set *fset, struct dentry *dir,
1266 struct dentry *dentry, int mode,
1267 struct lento_vfs_context *info)
1268 {
1269 struct rec_info rec;
1270 int error;
1271 struct presto_version tgt_dir_ver, new_dir_ver;
1272 void *handle;
1273
1274 ENTRY;
1275 down(&dir->d_inode->i_zombie);
1276
1277 /* one journal record + directory block + room for removals*/
1278 error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH + 4096);
1279 if (error) {
1280 EXIT;
1281 up(&dir->d_inode->i_zombie);
1282 return error;
1283 }
1284
1285 error = may_create(dir->d_inode, dentry);
1286 if (error) {
1287 EXIT;
1288 goto exit_lock;
1289 }
1290
1291 error = -EPERM;
1292 if (!filter_c2cdiops(fset->fset_cache->cache_filter)->mkdir) {
1293 EXIT;
1294 goto exit_lock;
1295 }
1296
1297 error = -ENOSPC;
1298 presto_getversion(&tgt_dir_ver, dir->d_inode);
1299 handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_MKDIR);
1300 if ( IS_ERR(handle) ) {
1301 presto_release_space(fset->fset_cache, PRESTO_REQHIGH + 4096);
1302 CERROR("presto_do_mkdir: no space for transaction\n");
1303 goto exit_lock;
1304 }
1305
1306 DQUOT_INIT(dir->d_inode);
1307 mode &= (S_IRWXUGO|S_ISVTX);
1308 lock_kernel();
1309 error = filter_c2cdiops(fset->fset_cache->cache_filter)->mkdir(dir->d_inode, dentry, mode);
1310 if (error) {
1311 EXIT;
1312 goto exit;
1313 }
1314
1315 if ( dentry->d_inode && !error) {
1316 struct presto_cache *cache = fset->fset_cache;
1317
1318 presto_set_ops(dentry->d_inode, cache->cache_filter);
1319
1320 filter_setup_dentry_ops(cache->cache_filter,
1321 dentry->d_op,
1322 &presto_dentry_ops);
1323 dentry->d_op = filter_c2udops(cache->cache_filter);
1324 /* if Lento does this, we won't have data */
1325 if ( ISLENTO(presto_c2m(cache)) ) {
1326 presto_set(dentry, PRESTO_ATTR);
1327 } else {
1328 presto_set(dentry, PRESTO_ATTR | PRESTO_DATA);
1329 }
1330 }
1331
1332 info->flags |= LENTO_FL_TOUCH_PARENT;
1333 error = presto_settime(fset, NULL, dir, dentry,
1334 info, ATTR_CTIME | ATTR_MTIME);
1335 if (error) {
1336 EXIT;
1337 goto exit;
1338 }
1339
1340 presto_debug_fail_blkdev(fset, KML_OPCODE_MKDIR | 0x10);
1341 presto_getversion(&new_dir_ver, dentry->d_inode);
1342 if ( presto_do_kml(info, dir) )
1343 error = presto_journal_mkdir(&rec, fset, dentry, &tgt_dir_ver,
1344 &new_dir_ver,
1345 dentry->d_inode->i_mode);
1346
1347 presto_debug_fail_blkdev(fset, KML_OPCODE_MKDIR | 0x20);
1348 if ( presto_do_rcvd(info, dentry) )
1349 error = presto_write_last_rcvd(&rec, fset, info);
1350
1351 presto_debug_fail_blkdev(fset, KML_OPCODE_MKDIR | 0x30);
1352 EXIT;
1353 exit:
1354 unlock_kernel();
1355 presto_trans_commit(fset, handle);
1356 exit_lock:
1357 presto_release_space(fset->fset_cache, PRESTO_REQHIGH + 4096);
1358 up(&dir->d_inode->i_zombie);
1359 return error;
1360 }
1361
1362 /*
1363 * Look out: this function may change a normal dentry
1364 * into a directory dentry (different size)..
1365 */
lento_mkdir(const char * name,int mode,struct lento_vfs_context * info)1366 int lento_mkdir(const char *name, int mode, struct lento_vfs_context *info)
1367 {
1368 int error;
1369 char *pathname;
1370 struct dentry *dentry;
1371 struct presto_file_set *fset;
1372 struct nameidata nd;
1373
1374 ENTRY;
1375 CDEBUG(D_PIOCTL, "name: %s, mode %o, offset %d, recno %d, flags %x\n",
1376 name, mode, info->slot_offset, info->recno, info->flags);
1377 pathname = getname(name);
1378 error = PTR_ERR(pathname);
1379 if (IS_ERR(pathname)) {
1380 EXIT;
1381 return error;
1382 }
1383
1384 if (path_init(pathname, LOOKUP_PARENT, &nd))
1385 error = path_walk(pathname, &nd);
1386 if (error)
1387 goto out_name;
1388
1389 dentry = lookup_create(&nd, 1);
1390 error = PTR_ERR(dentry);
1391 if (!IS_ERR(dentry)) {
1392 fset = presto_fset(dentry);
1393 error = -EINVAL;
1394 if (!fset) {
1395 CERROR("No fileset!\n");
1396 EXIT;
1397 goto out_dput;
1398 }
1399
1400 error = presto_do_mkdir(fset, nd.dentry, dentry,
1401 mode & S_IALLUGO, info);
1402 out_dput:
1403 dput(dentry);
1404 }
1405 up(&nd.dentry->d_inode->i_sem);
1406 path_release(&nd);
1407 out_name:
1408 EXIT;
1409 putname(pathname);
1410 CDEBUG(D_PIOCTL, "error: %d\n", error);
1411 return error;
1412 }
1413
d_unhash(struct dentry * dentry)1414 static void d_unhash(struct dentry *dentry)
1415 {
1416 dget(dentry);
1417 switch (atomic_read(&dentry->d_count)) {
1418 default:
1419 shrink_dcache_parent(dentry);
1420 if (atomic_read(&dentry->d_count) != 2)
1421 break;
1422 case 2:
1423 d_drop(dentry);
1424 }
1425 }
1426
presto_do_rmdir(struct presto_file_set * fset,struct dentry * dir,struct dentry * dentry,struct lento_vfs_context * info)1427 int presto_do_rmdir(struct presto_file_set *fset, struct dentry *dir,
1428 struct dentry *dentry, struct lento_vfs_context *info)
1429 {
1430 struct rec_info rec;
1431 int error;
1432 struct presto_version tgt_dir_ver, old_dir_ver;
1433 struct izo_rollback_data rb;
1434 struct inode_operations *iops;
1435 void *handle;
1436 int do_kml, do_rcvd;
1437 int size;
1438
1439 ENTRY;
1440 error = may_delete(dir->d_inode, dentry, 1);
1441 if (error)
1442 return error;
1443
1444 error = -EPERM;
1445 iops = filter_c2cdiops(fset->fset_cache->cache_filter);
1446 if (!iops->rmdir) {
1447 EXIT;
1448 return error;
1449 }
1450
1451 size = PRESTO_REQHIGH - dentry->d_inode->i_size;
1452 error = presto_reserve_space(fset->fset_cache, size);
1453 if (error) {
1454 EXIT;
1455 return error;
1456 }
1457
1458 presto_getversion(&tgt_dir_ver, dir->d_inode);
1459 presto_getversion(&old_dir_ver, dentry->d_inode);
1460 izo_get_rollback_data(dentry->d_inode, &rb);
1461 handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_RMDIR);
1462 if ( IS_ERR(handle) ) {
1463 presto_release_space(fset->fset_cache, size);
1464 CERROR("ERROR: presto_do_rmdir: no space for transaction. Tell Peter.\n");
1465 return -ENOSPC;
1466 }
1467
1468 DQUOT_INIT(dir->d_inode);
1469
1470 do_kml = presto_do_kml(info, dir);
1471 do_rcvd = presto_do_rcvd(info, dir);
1472
1473 double_down(&dir->d_inode->i_zombie, &dentry->d_inode->i_zombie);
1474 d_unhash(dentry);
1475 if (IS_DEADDIR(dir->d_inode))
1476 error = -ENOENT;
1477 else if (d_mountpoint(dentry)) {
1478 CERROR("foo: d_mountpoint(dentry): ino %ld\n",
1479 dentry->d_inode->i_ino);
1480 error = -EBUSY;
1481 } else {
1482 lock_kernel();
1483 error = iops->rmdir(dir->d_inode, dentry);
1484 unlock_kernel();
1485 if (!error) {
1486 dentry->d_inode->i_flags |= S_DEAD;
1487 error = presto_settime(fset, NULL, NULL, dir, info,
1488 ATTR_CTIME | ATTR_MTIME);
1489 }
1490 }
1491 double_up(&dir->d_inode->i_zombie, &dentry->d_inode->i_zombie);
1492 if (!error)
1493 d_delete(dentry);
1494 dput(dentry);
1495
1496 presto_debug_fail_blkdev(fset, KML_OPCODE_RMDIR | 0x10);
1497 if ( !error && do_kml )
1498 error = presto_journal_rmdir(&rec, fset, dir, &tgt_dir_ver,
1499 &old_dir_ver, &rb,
1500 dentry->d_name.len,
1501 dentry->d_name.name);
1502
1503 presto_debug_fail_blkdev(fset, KML_OPCODE_RMDIR | 0x20);
1504 if ( !error && do_rcvd )
1505 error = presto_write_last_rcvd(&rec, fset, info);
1506
1507 presto_debug_fail_blkdev(fset, KML_OPCODE_RMDIR | 0x30);
1508 EXIT;
1509
1510 presto_trans_commit(fset, handle);
1511 presto_release_space(fset->fset_cache, size);
1512 return error;
1513 }
1514
lento_rmdir(const char * pathname,struct lento_vfs_context * info)1515 int lento_rmdir(const char *pathname, struct lento_vfs_context *info)
1516 {
1517 int error = 0;
1518 char * name;
1519 struct dentry *dentry;
1520 struct presto_file_set *fset;
1521 struct nameidata nd;
1522
1523 ENTRY;
1524 name = getname(pathname);
1525 if(IS_ERR(name)) {
1526 EXIT;
1527 return PTR_ERR(name);
1528 }
1529
1530 if (path_init(name, LOOKUP_PARENT, &nd))
1531 error = path_walk(name, &nd);
1532 if (error) {
1533 EXIT;
1534 goto exit;
1535 }
1536 switch(nd.last_type) {
1537 case LAST_DOTDOT:
1538 error = -ENOTEMPTY;
1539 EXIT;
1540 goto exit1;
1541 case LAST_ROOT:
1542 case LAST_DOT:
1543 error = -EBUSY;
1544 EXIT;
1545 goto exit1;
1546 }
1547 down(&nd.dentry->d_inode->i_sem);
1548 dentry = lookup_hash(&nd.last, nd.dentry);
1549 error = PTR_ERR(dentry);
1550 if (!IS_ERR(dentry)) {
1551 fset = presto_fset(dentry);
1552 error = -EINVAL;
1553 if ( !fset ) {
1554 CERROR("No fileset!\n");
1555 EXIT;
1556 goto exit_put;
1557 }
1558 error = presto_do_rmdir(fset, nd.dentry, dentry, info);
1559 exit_put:
1560 dput(dentry);
1561 }
1562 up(&nd.dentry->d_inode->i_sem);
1563 exit1:
1564 path_release(&nd);
1565 exit:
1566 putname(name);
1567 EXIT;
1568 return error;
1569 }
1570
presto_do_mknod(struct presto_file_set * fset,struct dentry * dir,struct dentry * dentry,int mode,dev_t dev,struct lento_vfs_context * info)1571 int presto_do_mknod(struct presto_file_set *fset, struct dentry *dir,
1572 struct dentry *dentry, int mode, dev_t dev,
1573 struct lento_vfs_context *info)
1574 {
1575 struct rec_info rec;
1576 int error = -EPERM;
1577 struct presto_version tgt_dir_ver, new_node_ver;
1578 struct inode_operations *iops;
1579 void *handle;
1580
1581 ENTRY;
1582
1583 down(&dir->d_inode->i_zombie);
1584 /* one KML entry */
1585 error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH);
1586 if (error) {
1587 EXIT;
1588 up(&dir->d_inode->i_zombie);
1589 return error;
1590 }
1591
1592 if ((S_ISCHR(mode) || S_ISBLK(mode)) && !capable(CAP_MKNOD)) {
1593 EXIT;
1594 goto exit_lock;
1595 }
1596
1597 error = may_create(dir->d_inode, dentry);
1598 if (error) {
1599 EXIT;
1600 goto exit_lock;
1601 }
1602
1603 error = -EPERM;
1604 iops = filter_c2cdiops(fset->fset_cache->cache_filter);
1605 if (!iops->mknod) {
1606 EXIT;
1607 goto exit_lock;
1608 }
1609
1610 DQUOT_INIT(dir->d_inode);
1611 lock_kernel();
1612
1613 error = -ENOSPC;
1614 presto_getversion(&tgt_dir_ver, dir->d_inode);
1615 handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_MKNOD);
1616 if ( IS_ERR(handle) ) {
1617 presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
1618 CERROR("presto_do_mknod: no space for transaction\n");
1619 goto exit_lock2;
1620 }
1621
1622 error = iops->mknod(dir->d_inode, dentry, mode, dev);
1623 if (error) {
1624 EXIT;
1625 goto exit_commit;
1626 }
1627 if ( dentry->d_inode) {
1628 struct presto_cache *cache = fset->fset_cache;
1629
1630 presto_set_ops(dentry->d_inode, cache->cache_filter);
1631
1632 filter_setup_dentry_ops(cache->cache_filter, dentry->d_op,
1633 &presto_dentry_ops);
1634 dentry->d_op = filter_c2udops(cache->cache_filter);
1635
1636 /* if Lento does this, we won't have data */
1637 if ( ISLENTO(presto_c2m(cache)) ) {
1638 presto_set(dentry, PRESTO_ATTR);
1639 } else {
1640 presto_set(dentry, PRESTO_ATTR | PRESTO_DATA);
1641 }
1642 }
1643
1644 error = presto_settime(fset, NULL, NULL, dir,
1645 info, ATTR_MTIME);
1646 if (error) {
1647 EXIT;
1648 }
1649 error = presto_settime(fset, NULL, NULL, dentry,
1650 info, ATTR_CTIME | ATTR_MTIME);
1651 if (error) {
1652 EXIT;
1653 }
1654
1655 presto_debug_fail_blkdev(fset, KML_OPCODE_MKNOD | 0x10);
1656 presto_getversion(&new_node_ver, dentry->d_inode);
1657 if ( presto_do_kml(info, dentry) )
1658 error = presto_journal_mknod(&rec, fset, dentry, &tgt_dir_ver,
1659 &new_node_ver,
1660 dentry->d_inode->i_mode,
1661 MAJOR(dev), MINOR(dev) );
1662
1663 presto_debug_fail_blkdev(fset, KML_OPCODE_MKNOD | 0x20);
1664 if ( presto_do_rcvd(info, dentry) )
1665 error = presto_write_last_rcvd(&rec, fset, info);
1666
1667 presto_debug_fail_blkdev(fset, KML_OPCODE_MKNOD | 0x30);
1668 EXIT;
1669 exit_commit:
1670 presto_trans_commit(fset, handle);
1671 exit_lock2:
1672 unlock_kernel();
1673 exit_lock:
1674 presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
1675 up(&dir->d_inode->i_zombie);
1676 return error;
1677 }
1678
lento_mknod(const char * filename,int mode,dev_t dev,struct lento_vfs_context * info)1679 int lento_mknod(const char *filename, int mode, dev_t dev,
1680 struct lento_vfs_context *info)
1681 {
1682 int error = 0;
1683 char * tmp;
1684 struct dentry * dentry;
1685 struct nameidata nd;
1686 struct presto_file_set *fset;
1687
1688 ENTRY;
1689
1690 if (S_ISDIR(mode))
1691 return -EPERM;
1692 tmp = getname(filename);
1693 if (IS_ERR(tmp))
1694 return PTR_ERR(tmp);
1695
1696 if (path_init(tmp, LOOKUP_PARENT, &nd))
1697 error = path_walk(tmp, &nd);
1698 if (error)
1699 goto out;
1700 dentry = lookup_create(&nd, 0);
1701 error = PTR_ERR(dentry);
1702 if (!IS_ERR(dentry)) {
1703 fset = presto_fset(dentry);
1704 error = -EINVAL;
1705 if ( !fset ) {
1706 CERROR("No fileset!\n");
1707 EXIT;
1708 goto exit_put;
1709 }
1710 switch (mode & S_IFMT) {
1711 case 0: case S_IFREG:
1712 error = -EOPNOTSUPP;
1713 break;
1714 case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK:
1715 error = presto_do_mknod(fset, nd.dentry, dentry,
1716 mode, dev, info);
1717 break;
1718 case S_IFDIR:
1719 error = -EPERM;
1720 break;
1721 default:
1722 error = -EINVAL;
1723 }
1724 exit_put:
1725 dput(dentry);
1726 }
1727 up(&nd.dentry->d_inode->i_sem);
1728 path_release(&nd);
1729 out:
1730 putname(tmp);
1731
1732 return error;
1733 }
1734
do_rename(struct presto_file_set * fset,struct dentry * old_parent,struct dentry * old_dentry,struct dentry * new_parent,struct dentry * new_dentry,struct lento_vfs_context * info)1735 int do_rename(struct presto_file_set *fset,
1736 struct dentry *old_parent, struct dentry *old_dentry,
1737 struct dentry *new_parent, struct dentry *new_dentry,
1738 struct lento_vfs_context *info)
1739 {
1740 struct rec_info rec;
1741 int error;
1742 struct inode_operations *iops;
1743 struct presto_version src_dir_ver, tgt_dir_ver;
1744 void *handle;
1745 int new_inode_unlink = 0;
1746 struct inode *old_dir = old_parent->d_inode;
1747 struct inode *new_dir = new_parent->d_inode;
1748
1749 ENTRY;
1750 presto_getversion(&src_dir_ver, old_dir);
1751 presto_getversion(&tgt_dir_ver, new_dir);
1752
1753 error = -EPERM;
1754 iops = filter_c2cdiops(fset->fset_cache->cache_filter);
1755 if (!iops || !iops->rename) {
1756 EXIT;
1757 return error;
1758 }
1759
1760 error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH);
1761 if (error) {
1762 EXIT;
1763 return error;
1764 }
1765 handle = presto_trans_start(fset, old_dir, KML_OPCODE_RENAME);
1766 if ( IS_ERR(handle) ) {
1767 presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
1768 CERROR("presto_do_rename: no space for transaction\n");
1769 return -ENOSPC;
1770 }
1771 if (new_dentry->d_inode && new_dentry->d_inode->i_nlink > 1) {
1772 dget(new_dentry);
1773 new_inode_unlink = 1;
1774 }
1775
1776 error = iops->rename(old_dir, old_dentry, new_dir, new_dentry);
1777
1778 if (error) {
1779 EXIT;
1780 goto exit;
1781 }
1782
1783 if (new_inode_unlink) {
1784 error = presto_settime(fset, NULL, NULL, old_dentry,
1785 info, ATTR_CTIME);
1786 dput(old_dentry);
1787 if (error) {
1788 EXIT;
1789 goto exit;
1790 }
1791 }
1792 info->flags |= LENTO_FL_TOUCH_PARENT;
1793 error = presto_settime(fset, NULL, new_parent, old_parent,
1794 info, ATTR_CTIME | ATTR_MTIME);
1795 if (error) {
1796 EXIT;
1797 goto exit;
1798 }
1799
1800 /* XXX make a distinction between cross file set
1801 * and intra file set renames here
1802 */
1803 presto_debug_fail_blkdev(fset, KML_OPCODE_RENAME | 0x10);
1804 if ( presto_do_kml(info, old_dentry) )
1805 error = presto_journal_rename(&rec, fset, old_dentry,
1806 new_dentry,
1807 &src_dir_ver, &tgt_dir_ver);
1808
1809 presto_debug_fail_blkdev(fset, KML_OPCODE_RENAME | 0x20);
1810
1811 if ( presto_do_rcvd(info, old_dentry) )
1812 error = presto_write_last_rcvd(&rec, fset, info);
1813
1814 presto_debug_fail_blkdev(fset, KML_OPCODE_RENAME | 0x30);
1815 EXIT;
1816 exit:
1817 presto_trans_commit(fset, handle);
1818 presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
1819 return error;
1820 }
1821
1822 static
presto_rename_dir(struct presto_file_set * fset,struct dentry * old_parent,struct dentry * old_dentry,struct dentry * new_parent,struct dentry * new_dentry,struct lento_vfs_context * info)1823 int presto_rename_dir(struct presto_file_set *fset, struct dentry *old_parent,
1824 struct dentry *old_dentry, struct dentry *new_parent,
1825 struct dentry *new_dentry, struct lento_vfs_context *info)
1826 {
1827 int error;
1828 struct inode *target;
1829 struct inode *old_dir = old_parent->d_inode;
1830 struct inode *new_dir = new_parent->d_inode;
1831
1832 if (old_dentry->d_inode == new_dentry->d_inode)
1833 return 0;
1834
1835 error = may_delete(old_dir, old_dentry, 1);
1836 if (error)
1837 return error;
1838
1839 if (new_dir->i_dev != old_dir->i_dev)
1840 return -EXDEV;
1841
1842 if (!new_dentry->d_inode)
1843 error = may_create(new_dir, new_dentry);
1844 else
1845 error = may_delete(new_dir, new_dentry, 1);
1846 if (error)
1847 return error;
1848
1849 if (!old_dir->i_op || !old_dir->i_op->rename)
1850 return -EPERM;
1851
1852 /*
1853 * If we are going to change the parent - check write permissions,
1854 * we'll need to flip '..'.
1855 */
1856 if (new_dir != old_dir) {
1857 error = permission(old_dentry->d_inode, MAY_WRITE);
1858 }
1859 if (error)
1860 return error;
1861
1862 DQUOT_INIT(old_dir);
1863 DQUOT_INIT(new_dir);
1864 down(&old_dir->i_sb->s_vfs_rename_sem);
1865 error = -EINVAL;
1866 if (is_subdir(new_dentry, old_dentry))
1867 goto out_unlock;
1868 target = new_dentry->d_inode;
1869 if (target) { /* Hastur! Hastur! Hastur! */
1870 triple_down(&old_dir->i_zombie,
1871 &new_dir->i_zombie,
1872 &target->i_zombie);
1873 d_unhash(new_dentry);
1874 } else
1875 double_down(&old_dir->i_zombie,
1876 &new_dir->i_zombie);
1877 if (IS_DEADDIR(old_dir)||IS_DEADDIR(new_dir))
1878 error = -ENOENT;
1879 else if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
1880 error = -EBUSY;
1881 else
1882 error = do_rename(fset, old_parent, old_dentry,
1883 new_parent, new_dentry, info);
1884 if (target) {
1885 if (!error)
1886 target->i_flags |= S_DEAD;
1887 triple_up(&old_dir->i_zombie,
1888 &new_dir->i_zombie,
1889 &target->i_zombie);
1890 if (d_unhashed(new_dentry))
1891 d_rehash(new_dentry);
1892 dput(new_dentry);
1893 } else
1894 double_up(&old_dir->i_zombie,
1895 &new_dir->i_zombie);
1896
1897 if (!error)
1898 d_move(old_dentry,new_dentry);
1899 out_unlock:
1900 up(&old_dir->i_sb->s_vfs_rename_sem);
1901 return error;
1902 }
1903
1904 static
presto_rename_other(struct presto_file_set * fset,struct dentry * old_parent,struct dentry * old_dentry,struct dentry * new_parent,struct dentry * new_dentry,struct lento_vfs_context * info)1905 int presto_rename_other(struct presto_file_set *fset, struct dentry *old_parent,
1906 struct dentry *old_dentry, struct dentry *new_parent,
1907 struct dentry *new_dentry, struct lento_vfs_context *info)
1908 {
1909 struct inode *old_dir = old_parent->d_inode;
1910 struct inode *new_dir = new_parent->d_inode;
1911 int error;
1912
1913 if (old_dentry->d_inode == new_dentry->d_inode)
1914 return 0;
1915
1916 error = may_delete(old_dir, old_dentry, 0);
1917 if (error)
1918 return error;
1919
1920 if (new_dir->i_dev != old_dir->i_dev)
1921 return -EXDEV;
1922
1923 if (!new_dentry->d_inode)
1924 error = may_create(new_dir, new_dentry);
1925 else
1926 error = may_delete(new_dir, new_dentry, 0);
1927 if (error)
1928 return error;
1929
1930 if (!old_dir->i_op || !old_dir->i_op->rename)
1931 return -EPERM;
1932
1933 DQUOT_INIT(old_dir);
1934 DQUOT_INIT(new_dir);
1935 double_down(&old_dir->i_zombie, &new_dir->i_zombie);
1936 if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
1937 error = -EBUSY;
1938 else
1939 error = do_rename(fset, old_parent, old_dentry,
1940 new_parent, new_dentry, info);
1941 double_up(&old_dir->i_zombie, &new_dir->i_zombie);
1942 if (error)
1943 return error;
1944 /* The following d_move() should become unconditional */
1945 if (!(old_dir->i_sb->s_type->fs_flags & FS_ODD_RENAME)) {
1946 d_move(old_dentry, new_dentry);
1947 }
1948 return 0;
1949 }
1950
presto_do_rename(struct presto_file_set * fset,struct dentry * old_parent,struct dentry * old_dentry,struct dentry * new_parent,struct dentry * new_dentry,struct lento_vfs_context * info)1951 int presto_do_rename(struct presto_file_set *fset,
1952 struct dentry *old_parent, struct dentry *old_dentry,
1953 struct dentry *new_parent, struct dentry *new_dentry,
1954 struct lento_vfs_context *info)
1955 {
1956 if (S_ISDIR(old_dentry->d_inode->i_mode))
1957 return presto_rename_dir(fset, old_parent,old_dentry,new_parent,
1958 new_dentry, info);
1959 else
1960 return presto_rename_other(fset, old_parent, old_dentry,
1961 new_parent,new_dentry, info);
1962 }
1963
1964
lento_do_rename(const char * oldname,const char * newname,struct lento_vfs_context * info)1965 int lento_do_rename(const char *oldname, const char *newname,
1966 struct lento_vfs_context *info)
1967 {
1968 int error = 0;
1969 struct dentry * old_dir, * new_dir;
1970 struct dentry * old_dentry, *new_dentry;
1971 struct nameidata oldnd, newnd;
1972 struct presto_file_set *fset;
1973
1974 ENTRY;
1975
1976 if (path_init(oldname, LOOKUP_PARENT, &oldnd))
1977 error = path_walk(oldname, &oldnd);
1978
1979 if (error)
1980 goto exit;
1981
1982 if (path_init(newname, LOOKUP_PARENT, &newnd))
1983 error = path_walk(newname, &newnd);
1984 if (error)
1985 goto exit1;
1986
1987 error = -EXDEV;
1988 if (oldnd.mnt != newnd.mnt)
1989 goto exit2;
1990
1991 old_dir = oldnd.dentry;
1992 error = -EBUSY;
1993 if (oldnd.last_type != LAST_NORM)
1994 goto exit2;
1995
1996 new_dir = newnd.dentry;
1997 if (newnd.last_type != LAST_NORM)
1998 goto exit2;
1999
2000 double_lock(new_dir, old_dir);
2001
2002 old_dentry = lookup_hash(&oldnd.last, old_dir);
2003 error = PTR_ERR(old_dentry);
2004 if (IS_ERR(old_dentry))
2005 goto exit3;
2006 /* source must exist */
2007 error = -ENOENT;
2008 if (!old_dentry->d_inode)
2009 goto exit4;
2010 fset = presto_fset(old_dentry);
2011 error = -EINVAL;
2012 if ( !fset ) {
2013 CERROR("No fileset!\n");
2014 EXIT;
2015 goto exit4;
2016 }
2017 /* unless the source is a directory trailing slashes give -ENOTDIR */
2018 if (!S_ISDIR(old_dentry->d_inode->i_mode)) {
2019 error = -ENOTDIR;
2020 if (oldnd.last.name[oldnd.last.len])
2021 goto exit4;
2022 if (newnd.last.name[newnd.last.len])
2023 goto exit4;
2024 }
2025 new_dentry = lookup_hash(&newnd.last, new_dir);
2026 error = PTR_ERR(new_dentry);
2027 if (IS_ERR(new_dentry))
2028 goto exit4;
2029
2030 lock_kernel();
2031 error = presto_do_rename(fset, old_dir, old_dentry,
2032 new_dir, new_dentry, info);
2033 unlock_kernel();
2034
2035 dput(new_dentry);
2036 exit4:
2037 dput(old_dentry);
2038 exit3:
2039 double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem);
2040 exit2:
2041 path_release(&newnd);
2042 exit1:
2043 path_release(&oldnd);
2044 exit:
2045 return error;
2046 }
2047
lento_rename(const char * oldname,const char * newname,struct lento_vfs_context * info)2048 int lento_rename(const char * oldname, const char * newname,
2049 struct lento_vfs_context *info)
2050 {
2051 int error;
2052 char * from;
2053 char * to;
2054
2055 from = getname(oldname);
2056 if(IS_ERR(from))
2057 return PTR_ERR(from);
2058 to = getname(newname);
2059 error = PTR_ERR(to);
2060 if (!IS_ERR(to)) {
2061 error = lento_do_rename(from,to, info);
2062 putname(to);
2063 }
2064 putname(from);
2065 return error;
2066 }
2067
presto_iopen(struct dentry * dentry,ino_t ino,unsigned int generation)2068 struct dentry *presto_iopen(struct dentry *dentry,
2069 ino_t ino, unsigned int generation)
2070 {
2071 struct presto_file_set *fset;
2072 char name[48];
2073 int error;
2074
2075 ENTRY;
2076 /* see if we already have the dentry we want */
2077 if (dentry->d_inode && dentry->d_inode->i_ino == ino &&
2078 dentry->d_inode->i_generation == generation) {
2079 EXIT;
2080 return dentry;
2081 }
2082
2083 /* Make sure we have a cache beneath us. We should always find at
2084 * least one dentry inside the cache (if it exists), otherwise not
2085 * even the cache root exists, or we passed in a bad name.
2086 */
2087 fset = presto_fset(dentry);
2088 error = -EINVAL;
2089 if (!fset) {
2090 CERROR("No fileset for %*s!\n",
2091 dentry->d_name.len, dentry->d_name.name);
2092 EXIT;
2093 dput(dentry);
2094 return ERR_PTR(error);
2095 }
2096 dput(dentry);
2097
2098 sprintf(name, "%s%#lx%c%#x",
2099 PRESTO_ILOOKUP_MAGIC, ino, PRESTO_ILOOKUP_SEP, generation);
2100 CDEBUG(D_PIOCTL, "opening %ld by number (as %s)\n", ino, name);
2101 return lookup_one_len(name, fset->fset_dentry, strlen(name));
2102 }
2103
presto_filp_dopen(struct dentry * dentry,int flags)2104 static struct file *presto_filp_dopen(struct dentry *dentry, int flags)
2105 {
2106 struct file *f;
2107 struct inode *inode;
2108 int flag, error;
2109
2110 ENTRY;
2111 error = -ENFILE;
2112 f = get_empty_filp();
2113 if (!f) {
2114 CDEBUG(D_PIOCTL, "error getting file pointer\n");
2115 EXIT;
2116 goto out;
2117 }
2118 f->f_flags = flag = flags;
2119 f->f_mode = (flag+1) & O_ACCMODE;
2120 inode = dentry->d_inode;
2121 if (f->f_mode & FMODE_WRITE) {
2122 error = get_write_access(inode);
2123 if (error) {
2124 CDEBUG(D_PIOCTL, "error getting write access\n");
2125 EXIT; goto cleanup_file;
2126 }
2127 }
2128
2129 f->f_dentry = dentry;
2130 f->f_pos = 0;
2131 f->f_reada = 0;
2132 f->f_op = NULL;
2133 if (inode->i_op)
2134 /* XXX should we set to presto ops, or leave at cache ops? */
2135 f->f_op = inode->i_fop;
2136 if (f->f_op && f->f_op->open) {
2137 error = f->f_op->open(inode, f);
2138 if (error) {
2139 CDEBUG(D_PIOCTL, "error calling cache 'open'\n");
2140 EXIT;
2141 goto cleanup_all;
2142 }
2143 }
2144 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
2145
2146 return f;
2147
2148 cleanup_all:
2149 if (f->f_mode & FMODE_WRITE)
2150 put_write_access(inode);
2151 cleanup_file:
2152 put_filp(f);
2153 out:
2154 return ERR_PTR(error);
2155 }
2156
2157
2158 /* Open an inode by number. We pass in the cache root name (or a subdirectory
2159 * from the cache that is guaranteed to exist) to be able to access the cache.
2160 */
lento_iopen(const char * name,ino_t ino,unsigned int generation,int flags)2161 int lento_iopen(const char *name, ino_t ino, unsigned int generation,
2162 int flags)
2163 {
2164 char * tmp;
2165 struct dentry *dentry;
2166 struct nameidata nd;
2167 int fd;
2168 int error;
2169
2170 ENTRY;
2171 CDEBUG(D_PIOCTL,
2172 "open %s:inode %#lx (%ld), generation %x (%d), flags %d \n",
2173 name, ino, ino, generation, generation, flags);
2174 /* We don't allow creation of files by number only, as it would
2175 * lead to a dangling files not in any directory. We could also
2176 * just turn off the flag and ignore it.
2177 */
2178 if (flags & O_CREAT) {
2179 CERROR("%s: create file by inode number (%ld) not allowed\n",
2180 __FUNCTION__, ino);
2181 EXIT;
2182 return -EACCES;
2183 }
2184
2185 tmp = getname(name);
2186 if (IS_ERR(tmp)) {
2187 EXIT;
2188 return PTR_ERR(tmp);
2189 }
2190
2191 lock_kernel();
2192 again: /* look the named file or a parent directory so we can get the cache */
2193 error = presto_walk(tmp, &nd);
2194 if ( error && error != -ENOENT ) {
2195 EXIT;
2196 unlock_kernel();
2197 putname(tmp);
2198 return error;
2199 }
2200 if (error == -ENOENT)
2201 dentry = NULL;
2202 else
2203 dentry = nd.dentry;
2204
2205 /* we didn't find the named file, so see if a parent exists */
2206 if (!dentry) {
2207 char *slash;
2208
2209 slash = strrchr(tmp, '/');
2210 if (slash && slash != tmp) {
2211 *slash = '\0';
2212 path_release(&nd);
2213 goto again;
2214 }
2215 /* we should never get here... */
2216 CDEBUG(D_PIOCTL, "no more path components to try!\n");
2217 fd = -ENOENT;
2218 goto exit;
2219 }
2220 CDEBUG(D_PIOCTL, "returned dentry %p\n", dentry);
2221
2222 dentry = presto_iopen(dentry, ino, generation);
2223 fd = PTR_ERR(dentry);
2224 if (IS_ERR(dentry)) {
2225 EXIT;
2226 goto exit;
2227 }
2228
2229 /* XXX start of code that might be replaced by something like:
2230 * if (flags & (O_WRONLY | O_RDWR)) {
2231 * error = get_write_access(dentry->d_inode);
2232 * if (error) {
2233 * EXIT;
2234 * goto cleanup_dput;
2235 * }
2236 * }
2237 * fd = open_dentry(dentry, flags);
2238 *
2239 * including the presto_filp_dopen() function (check dget counts!)
2240 */
2241 fd = get_unused_fd();
2242 if (fd < 0) {
2243 EXIT;
2244 goto exit;
2245 }
2246
2247 {
2248 int error;
2249 struct file * f = presto_filp_dopen(dentry, flags);
2250 error = PTR_ERR(f);
2251 if (IS_ERR(f)) {
2252 put_unused_fd(fd);
2253 fd = error;
2254 } else {
2255 fd_install(fd, f);
2256 }
2257 }
2258 /* end of code that might be replaced by open_dentry */
2259
2260 EXIT;
2261 exit:
2262 unlock_kernel();
2263 path_release(&nd);
2264 putname(tmp);
2265 return fd;
2266 }
2267
2268 #ifdef CONFIG_FS_EXT_ATTR
2269
2270 #ifdef CONFIG_FS_POSIX_ACL
2271 /* Posix ACL code changes i_mode without using a notify_change (or
2272 * a mark_inode_dirty!). We need to duplicate this at the reintegrator
2273 * which is done by this function. This function also takes care of
2274 * resetting the cached posix acls in this inode. If we don't reset these
2275 * VFS continues using the old acl information, which by now may be out of
2276 * date.
2277 */
presto_setmode(struct presto_file_set * fset,struct dentry * dentry,mode_t mode)2278 int presto_setmode(struct presto_file_set *fset, struct dentry *dentry,
2279 mode_t mode)
2280 {
2281 struct inode *inode = dentry->d_inode;
2282
2283 ENTRY;
2284 /* The extended attributes for this inode were modified.
2285 * At this point we can not be sure if any of the ACL
2286 * information for this inode was updated. So we will
2287 * force VFS to reread the acls. Note that we do this
2288 * only when called from the SETEXTATTR ioctl, which is why we
2289 * do this while setting the mode of the file. Also note
2290 * that mark_inode_dirty is not be needed for i_*acl only
2291 * to force i_mode info to disk, and should be removed once
2292 * we use notify_change to update the mode.
2293 * XXX: is mode setting really needed? Just setting acl's should
2294 * be enough! VFS should change the i_mode as needed? SHP
2295 */
2296 if (inode->i_acl &&
2297 inode->i_acl != POSIX_ACL_NOT_CACHED)
2298 posix_acl_release(inode->i_acl);
2299 if (inode->i_default_acl &&
2300 inode->i_default_acl != POSIX_ACL_NOT_CACHED)
2301 posix_acl_release(inode->i_default_acl);
2302 inode->i_acl = POSIX_ACL_NOT_CACHED;
2303 inode->i_default_acl = POSIX_ACL_NOT_CACHED;
2304 inode->i_mode = mode;
2305 /* inode should already be dirty...but just in case */
2306 mark_inode_dirty(inode);
2307 return 0;
2308
2309 #if 0
2310 /* XXX: The following code is the preferred way to set mode,
2311 * however, I need to carefully go through possible recursion
2312 * paths back into presto. See comments in presto_do_setattr.
2313 */
2314 {
2315 int error=0;
2316 struct super_operations *sops;
2317 struct iattr iattr;
2318
2319 iattr.ia_mode = mode;
2320 iattr.ia_valid = ATTR_MODE|ATTR_FORCE;
2321
2322 error = -EPERM;
2323 sops = filter_c2csops(fset->fset_cache->cache_filter);
2324 if (!sops &&
2325 !sops->notify_change) {
2326 EXIT;
2327 return error;
2328 }
2329
2330 error = sops->notify_change(dentry, &iattr);
2331
2332 EXIT;
2333 return error;
2334 }
2335 #endif
2336 }
2337 #endif
2338
2339 /* setextattr Interface to cache filesystem */
presto_do_set_ext_attr(struct presto_file_set * fset,struct dentry * dentry,const char * name,void * buffer,size_t buffer_len,int flags,mode_t * mode,struct lento_vfs_context * info)2340 int presto_do_set_ext_attr(struct presto_file_set *fset,
2341 struct dentry *dentry,
2342 const char *name, void *buffer,
2343 size_t buffer_len, int flags, mode_t *mode,
2344 struct lento_vfs_context *info)
2345 {
2346 struct rec_info rec;
2347 struct inode *inode = dentry->d_inode;
2348 struct inode_operations *iops;
2349 int error;
2350 struct presto_version ver;
2351 void *handle;
2352 char temp[PRESTO_EXT_ATTR_NAME_MAX+1];
2353
2354 ENTRY;
2355 error = -EROFS;
2356 if (IS_RDONLY(inode)) {
2357 EXIT;
2358 return -EROFS;
2359 }
2360
2361 if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
2362 EXIT;
2363 return -EPERM;
2364 }
2365
2366 presto_getversion(&ver, inode);
2367 error = -EPERM;
2368 /* We need to invoke different filters based on whether
2369 * this dentry is a regular file, directory or symlink.
2370 */
2371 switch (inode->i_mode & S_IFMT) {
2372 case S_IFLNK: /* symlink */
2373 iops = filter_c2csiops(fset->fset_cache->cache_filter);
2374 break;
2375 case S_IFDIR: /* directory */
2376 iops = filter_c2cdiops(fset->fset_cache->cache_filter);
2377 break;
2378 case S_IFREG:
2379 default: /* everything else including regular files */
2380 iops = filter_c2cfiops(fset->fset_cache->cache_filter);
2381 }
2382
2383 if (!iops && !iops->set_ext_attr) {
2384 EXIT;
2385 return error;
2386 }
2387
2388 error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH);
2389 if (error) {
2390 EXIT;
2391 return error;
2392 }
2393
2394
2395 handle = presto_trans_start(fset,dentry->d_inode,KML_OPCODE_SETEXTATTR);
2396 if ( IS_ERR(handle) ) {
2397 CERROR("presto_do_set_ext_attr: no space for transaction\n");
2398 presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
2399 return -ENOSPC;
2400 }
2401
2402 /* We first "truncate" name to the maximum allowable in presto */
2403 /* This simulates the strncpy_from_use code in fs/ext_attr.c */
2404 strncpy(temp,name,sizeof(temp));
2405
2406 /* Pass down to cache*/
2407 error = iops->set_ext_attr(inode,temp,buffer,buffer_len,flags);
2408 if (error) {
2409 EXIT;
2410 goto exit;
2411 }
2412
2413 #ifdef CONFIG_FS_POSIX_ACL
2414 /* Reset mode if specified*/
2415 /* XXX: when we do native acl support, move this code out! */
2416 if (mode != NULL) {
2417 error = presto_setmode(fset, dentry, *mode);
2418 if (error) {
2419 EXIT;
2420 goto exit;
2421 }
2422 }
2423 #endif
2424
2425 /* Reset ctime. Only inode change time (ctime) is affected */
2426 error = presto_settime(fset, NULL, NULL, dentry, info, ATTR_CTIME);
2427 if (error) {
2428 EXIT;
2429 goto exit;
2430 }
2431
2432 if (flags & EXT_ATTR_FLAG_USER) {
2433 CERROR(" USER flag passed to presto_do_set_ext_attr!\n");
2434 BUG();
2435 }
2436
2437 /* We are here, so set_ext_attr succeeded. We no longer need to keep
2438 * track of EXT_ATTR_FLAG_{EXISTS,CREATE}, instead, we will force
2439 * the attribute value during log replay. -SHP
2440 */
2441 flags &= ~(EXT_ATTR_FLAG_EXISTS | EXT_ATTR_FLAG_CREATE);
2442
2443 presto_debug_fail_blkdev(fset, KML_OPCODE_SETEXTATTR | 0x10);
2444 if ( presto_do_kml(info, dentry) )
2445 error = presto_journal_set_ext_attr
2446 (&rec, fset, dentry, &ver, name, buffer,
2447 buffer_len, flags);
2448
2449 presto_debug_fail_blkdev(fset, KML_OPCODE_SETEXTATTR | 0x20);
2450 if ( presto_do_rcvd(info, dentry) )
2451 error = presto_write_last_rcvd(&rec, fset, info);
2452
2453 presto_debug_fail_blkdev(fset, KML_OPCODE_SETEXTATTR | 0x30);
2454 EXIT;
2455 exit:
2456 presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
2457 presto_trans_commit(fset, handle);
2458
2459 return error;
2460 }
2461 #endif
2462