1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2001, 2002 Cluster File Systems, Inc.
5 * Copyright (C) 2000 Stelias Computing, Inc.
6 * Copyright (C) 2000 Red Hat, Inc.
8 * This file is part of InterMezzo, http://www.inter-mezzo.org.
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.
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.
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.
25 * This file implements kernel downcalls from lento.
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.
32 * Extended attribute support
33 * Copyright (C) 2001 Shirish H. Phatak, Tacit Networks, Inc.
35 * This code is based on code from namei.c in the linux file system;
36 * see copyright notice below.
39 /** namei.c copyright **/
44 * Copyright (C) 1991, 1992 Linus Torvalds
47 * Some corrections by tytso.
50 /* [Feb 1997 T. Schoebel-Theuer] Complete rewrite of the pathname
54 /** end of namei.c copyright **/
57 #include <linux/proc_fs.h>
58 #include <linux/quotaops.h>
60 #include <asm/uaccess.h>
61 #include <asm/unaligned.h>
62 #include <asm/semaphore.h>
63 #include <asm/pgtable.h>
65 #include <linux/file.h>
67 #include <linux/namei.h>
68 #include <linux/genhd.h>
70 #include "intermezzo_fs.h"
71 #include "intermezzo_psdev.h"
73 #ifdef CONFIG_FS_EXT_ATTR
74 # include <linux/ext_attr.h>
76 # if 0 /* was a broken check for Posix ACLs */
77 # include <linux/posix_acl.h>
81 extern struct inode_operations presto_sym_iops;
83 /* Write the last_rcvd values to the last_rcvd file. We don't know what the
84 * UUID or last_ctime values are, so we have to read from the file first
86 * exported for branch_reinter in kml_reint.c*/
87 int presto_write_last_rcvd(struct rec_info *recinfo,
88 struct presto_file_set *fset,
89 struct lento_vfs_context *info)
92 struct izo_rcvd_rec rcvd_rec;
96 memset(&rcvd_rec, 0, sizeof(rcvd_rec));
97 memcpy(rcvd_rec.lr_uuid, info->uuid, sizeof(rcvd_rec.lr_uuid));
98 rcvd_rec.lr_remote_recno = HTON__u64(info->recno);
99 rcvd_rec.lr_remote_offset = HTON__u64(info->kml_offset);
100 rcvd_rec.lr_local_recno = HTON__u64(recinfo->recno);
101 rcvd_rec.lr_local_offset = HTON__u64(recinfo->offset + recinfo->size);
103 rc = izo_rcvd_write(fset, &rcvd_rec);
105 /* izo_rcvd_write returns negative errors and non-negative
107 CERROR("InterMezzo: izo_rcvd_write failed: %d\n", rc);
116 * It's inline, so penalty for filesystems that don't use sticky bit is
119 static inline int check_sticky(struct inode *dir, struct inode *inode)
121 if (!(dir->i_mode & S_ISVTX))
123 if (inode->i_uid == current->fsuid)
125 if (dir->i_uid == current->fsuid)
127 return !capable(CAP_FOWNER);
130 /* from linux/fs/namei.c */
131 static inline int may_delete(struct inode *dir,struct dentry *victim, int isdir)
134 if (!victim->d_inode || victim->d_parent->d_inode != dir)
136 error = permission(dir,MAY_WRITE | MAY_EXEC, NULL);
141 if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||
142 IS_IMMUTABLE(victim->d_inode))
145 if (!S_ISDIR(victim->d_inode->i_mode))
149 } else if (S_ISDIR(victim->d_inode->i_mode))
154 /* from linux/fs/namei.c */
155 static inline int may_create(struct inode *dir, struct dentry *child) {
160 return permission(dir,MAY_WRITE | MAY_EXEC, NULL);
164 /* The loop_discard_io() function is available via a kernel patch to the
165 * loop block device. It "works" by accepting writes, but throwing them
166 * away, rather than trying to write them to disk. The old method worked
167 * by setting the underlying device read-only, but that has the problem
168 * that dirty buffers are kept in memory, and ext3 didn't like that at all.
170 #ifdef CONFIG_LOOP_DISCARD
171 #define BLKDEV_FAIL(dev,fail) loop_discard_io(dev,fail)
173 #define BLKDEV_FAIL(dev,fail) set_device_ro(dev, 1)
176 /* If a breakpoint has been set via /proc/sys/intermezzo/intermezzoX/errorval,
177 * that is the same as "value", the underlying device will "fail" now.
179 inline void presto_debug_fail_blkdev(struct presto_file_set *fset,
182 int minor = presto_f2m(fset);
183 int errorval = izo_channels[minor].uc_errorval;
184 struct block_device *bdev = fset->fset_dentry->d_inode->i_sb->s_bdev;
185 char b[BDEVNAME_SIZE];
187 if (errorval && errorval == (long)value && !bdev_read_only(bdev)) {
188 CDEBUG(D_SUPER, "setting device %s read only\n",
190 BLKDEV_FAIL(bdev, 1);
191 izo_channels[minor].uc_errorval = -bdev->bd_dev;
195 #define presto_debug_fail_blkdev(dev,value) do {} while (0)
199 static inline int presto_do_kml(struct lento_vfs_context *info,
200 struct dentry *dentry)
202 if ( ! (info->flags & LENTO_FL_KML) )
204 if ( presto_chk(dentry, PRESTO_DONT_JOURNAL) )
209 static inline int presto_do_rcvd(struct lento_vfs_context *info,
210 struct dentry *dentry)
212 if ( ! (info->flags & LENTO_FL_EXPECT) )
214 if ( presto_chk(dentry, PRESTO_DONT_JOURNAL) )
220 /* XXX fixme: this should not fail, all these dentries are in memory
221 when _we_ call this */
222 int presto_settime(struct presto_file_set *fset,
223 struct dentry *newobj,
224 struct dentry *parent,
225 struct dentry *target,
226 struct lento_vfs_context *ctx,
230 struct dentry *dentry;
232 struct inode_operations *iops;
236 if (ctx->flags & LENTO_FL_IGNORE_TIME ) {
241 iattr.ia_ctime = ctx->updated_time;
242 iattr.ia_mtime = ctx->updated_time;
243 iattr.ia_valid = valid;
246 if (parent && ctx->flags & LENTO_FL_TOUCH_PARENT) {
249 } else if (newobj && ctx->flags & LENTO_FL_TOUCH_NEWOBJ) {
258 inode = dentry->d_inode;
261 if (IS_RDONLY(inode)) {
266 if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
272 iops = filter_c2cdiops(fset->fset_cache->cache_filter);
278 if (iops->setattr != NULL)
279 error = iops->setattr(dentry, &iattr);
282 inode_setattr(dentry->d_inode, &iattr);
289 void izo_get_rollback_data(struct inode *inode, struct izo_rollback_data *rb)
291 rb->rb_mode = (__u32)inode->i_mode;
292 rb->rb_rdev = (__u32)old_encode_dev(inode->i_rdev);
293 rb->rb_uid = (__u64)inode->i_uid;
294 rb->rb_gid = (__u64)inode->i_gid;
298 int presto_do_close(struct presto_file_set *fset, struct file *file)
303 struct inode *inode = file->f_dentry->d_inode;
304 struct presto_file_data *fdata =
305 (struct presto_file_data *)file->private_data;
308 presto_getversion(&fdata->fd_info.remote_version, inode);
310 rc = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH);
316 handle = presto_trans_start(fset, file->f_dentry->d_inode,
318 if ( IS_ERR(handle) ) {
319 CERROR("presto_release: no space for transaction\n");
323 if (fdata->fd_info.flags & LENTO_FL_KML)
324 rc = presto_journal_close(&rec, fset, fdata, file->f_dentry,
326 &fdata->fd_info.remote_version);
328 CERROR("presto_close: cannot journal close\n");
332 if (fdata->fd_info.flags & LENTO_FL_EXPECT)
333 rc = presto_write_last_rcvd(&rec, fset, &fdata->fd_info);
336 CERROR("presto_close: cannot journal last_rcvd\n");
339 presto_trans_commit(fset, handle);
341 /* cancel the LML record */
342 handle = presto_trans_start(fset, inode, KML_OPCODE_WRITE);
343 if ( IS_ERR(handle) ) {
344 CERROR("presto_release: no space for clear\n");
348 rc = presto_clear_lml_close(fset, fdata->fd_lml_offset);
350 CERROR("presto_close: cannot journal close\n");
353 presto_truncate_lml(fset);
356 presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
357 presto_trans_commit(fset, handle);
362 int presto_do_setattr(struct presto_file_set *fset, struct dentry *dentry,
363 struct iattr *iattr, struct lento_vfs_context *info)
366 struct inode *inode = dentry->d_inode;
367 struct inode_operations *iops;
369 struct presto_version old_ver, new_ver;
370 struct izo_rollback_data rb;
372 loff_t old_size=inode->i_size;
376 if (IS_RDONLY(inode)) {
381 if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
386 presto_getversion(&old_ver, dentry->d_inode);
387 izo_get_rollback_data(dentry->d_inode, &rb);
389 iops = filter_c2cdiops(fset->fset_cache->cache_filter);
391 error = presto_reserve_space(fset->fset_cache, 2*PRESTO_REQHIGH);
397 if (iattr->ia_valid & ATTR_SIZE) {
398 if (izo_mark_dentry(dentry, ~PRESTO_DATA, 0, NULL) != 0)
399 CERROR("izo_mark_dentry(inode %ld, ~PRESTO_DATA) "
400 "failed\n", dentry->d_inode->i_ino);
401 handle = presto_trans_start(fset, dentry->d_inode,
404 handle = presto_trans_start(fset, dentry->d_inode,
408 if ( IS_ERR(handle) ) {
409 CERROR("presto_do_setattr: no space for transaction\n");
410 presto_release_space(fset->fset_cache, 2*PRESTO_REQHIGH);
414 if (dentry->d_inode && iops && iops->setattr) {
415 error = iops->setattr(dentry, iattr);
417 error = inode_change_ok(dentry->d_inode, iattr);
419 inode_setattr(inode, iattr);
422 if (!error && (iattr->ia_valid & ATTR_SIZE))
423 vmtruncate(inode, iattr->ia_size);
430 presto_debug_fail_blkdev(fset, KML_OPCODE_SETATTR | 0x10);
432 if ( presto_do_kml(info, dentry) ) {
433 if ((iattr->ia_valid & ATTR_SIZE) && (old_size != inode->i_size)) {
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 error = presto_journal_close(&rec, fset, NULL, dentry,
443 error = presto_journal_setattr(&rec, fset, dentry,
444 &old_ver, &rb, iattr);
447 presto_debug_fail_blkdev(fset, KML_OPCODE_SETATTR | 0x20);
448 if ( presto_do_rcvd(info, dentry) )
449 error = presto_write_last_rcvd(&rec, fset, info);
451 presto_debug_fail_blkdev(fset, KML_OPCODE_SETATTR | 0x30);
455 presto_release_space(fset->fset_cache, 2*PRESTO_REQHIGH);
456 presto_trans_commit(fset, handle);
460 int lento_setattr(const char *name, struct iattr *iattr,
461 struct lento_vfs_context *info)
464 struct dentry *dentry;
465 struct presto_file_set *fset;
467 #if 0 /* was a broken check for Posix ACLs */
468 int (*set_posix_acl)(struct inode *, int type, posix_acl_t *)=NULL;
472 CDEBUG(D_PIOCTL,"name %s, valid %#x, mode %#o, uid %d, gid %d, size %Ld\n",
473 name, iattr->ia_valid, iattr->ia_mode, iattr->ia_uid,
474 iattr->ia_gid, iattr->ia_size);
475 CDEBUG(D_PIOCTL, "atime %#lx, mtime %#lx, ctime %#lx, attr_flags %#x\n",
476 iattr->ia_atime.tv_sec, iattr->ia_mtime.tv_sec, iattr->ia_ctime.tv_sec,
477 iattr->ia_attr_flags);
478 CDEBUG(D_PIOCTL, "offset %d, recno %d, flags %#x\n",
479 info->slot_offset, info->recno, info->flags);
482 error = presto_walk(name, &nd);
489 fset = presto_fset(dentry);
492 CERROR("No fileset!\n");
497 /* NOTE: this prevents us from changing the filetype on setattr,
498 * as we normally only want to change permission bits.
499 * If this is not correct, then we need to fix the perl code
500 * to always send the file type OR'ed with the permission.
502 if (iattr->ia_valid & ATTR_MODE) {
503 int set_mode = iattr->ia_mode;
504 iattr->ia_mode = (iattr->ia_mode & S_IALLUGO) |
505 (dentry->d_inode->i_mode & ~S_IALLUGO);
506 CDEBUG(D_PIOCTL, "chmod: orig %#o, set %#o, result %#o\n",
507 dentry->d_inode->i_mode, set_mode, iattr->ia_mode);
508 #if 0 /* was a broken check for Posix ACLs */
509 /* ACl code interacts badly with setattr
510 * since it tries to modify the ACL using
511 * set_ext_attr which recurses back into presto.
512 * This only happens if ATTR_MODE is set.
513 * Here we are doing a "forced" mode set
514 * (initiated by lento), so we disable the
515 * set_posix_acl operation which
516 * prevents such recursion. -SHP
518 * This will probably still be required when native
519 * acl journalling is in place.
521 set_posix_acl=dentry->d_inode->i_op->set_posix_acl;
522 dentry->d_inode->i_op->set_posix_acl=NULL;
526 error = presto_do_setattr(fset, dentry, iattr, info);
528 if (info->flags & LENTO_FL_SET_DDFILEID) {
529 struct presto_dentry_data *dd = presto_d2d(dentry);
531 dd->remote_ino = info->remote_ino;
532 dd->remote_generation = info->remote_generation;
536 #if 0 /* was a broken check for Posix ACLs */
537 /* restore the inode_operations if we changed them*/
538 if (iattr->ia_valid & ATTR_MODE)
539 dentry->d_inode->i_op->set_posix_acl=set_posix_acl;
551 int presto_do_create(struct presto_file_set *fset, struct dentry *dir,
552 struct dentry *dentry, int mode,
553 struct lento_vfs_context *info)
557 struct presto_version tgt_dir_ver, new_file_ver;
558 struct inode_operations *iops;
565 // down(&dir->d_inode->i_zombie);
566 error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH);
569 // up(&dir->d_inode->i_zombie);
573 error = may_create(dir->d_inode, dentry);
580 iops = filter_c2cdiops(fset->fset_cache->cache_filter);
586 presto_getversion(&tgt_dir_ver, dir->d_inode);
587 handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_CREATE);
588 if ( IS_ERR(handle) ) {
590 presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
591 CERROR("presto_do_create: no space for transaction\n");
595 DQUOT_INIT(dir->d_inode);
597 error = iops->create(dir->d_inode, dentry, mode, NULL);
603 if (dentry->d_inode) {
604 struct presto_cache *cache = fset->fset_cache;
605 /* was this already done? */
606 presto_set_ops(dentry->d_inode, cache->cache_filter);
608 filter_setup_dentry_ops(cache->cache_filter,
611 dentry->d_op = filter_c2udops(cache->cache_filter);
613 /* if Lento creates this file, we won't have data */
614 if ( ISLENTO(presto_c2m(cache)) ) {
615 presto_set(dentry, PRESTO_ATTR);
617 presto_set(dentry, PRESTO_ATTR | PRESTO_DATA);
621 info->flags |= LENTO_FL_TOUCH_PARENT;
622 error = presto_settime(fset, NULL, dir, dentry,
623 info, ATTR_CTIME | ATTR_MTIME);
629 presto_debug_fail_blkdev(fset, KML_OPCODE_CREATE | 0x10);
631 if ( presto_do_kml(info, dentry) ) {
632 presto_getversion(&new_file_ver, dentry->d_inode);
633 error = presto_journal_create(&rec, fset, dentry, &tgt_dir_ver,
635 dentry->d_inode->i_mode);
638 presto_debug_fail_blkdev(fset, KML_OPCODE_CREATE | 0x20);
640 if ( presto_do_rcvd(info, dentry) )
641 error = presto_write_last_rcvd(&rec, fset, info);
643 presto_debug_fail_blkdev(fset, KML_OPCODE_CREATE | 0x30);
645 /* add inode dentry */
646 if (fset->fset_cache->cache_filter->o_trops->tr_add_ilookup ) {
648 d = fset->fset_cache->cache_filter->o_trops->tr_add_ilookup
649 (dir->d_inode->i_sb->s_root, dentry);
656 presto_trans_commit(fset, handle);
658 presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
659 // up(&dir->d_inode->i_zombie);
663 int lento_create(const char *name, int mode, struct lento_vfs_context *info)
668 struct dentry *dentry;
669 struct presto_file_set *fset;
672 pathname = getname(name);
673 error = PTR_ERR(pathname);
674 if (IS_ERR(pathname)) {
679 /* this looks up the parent */
680 error = path_lookup(pathname, LOOKUP_PARENT, &nd);
685 dentry = lookup_create(&nd, 0);
686 error = PTR_ERR(dentry);
687 if (IS_ERR(dentry)) {
692 fset = presto_fset(dentry);
695 CERROR("No fileset!\n");
699 error = presto_do_create(fset, dentry->d_parent, dentry, (mode&S_IALLUGO)|S_IFREG,
707 up(&dentry->d_parent->d_inode->i_sem);
713 int presto_do_link(struct presto_file_set *fset, struct dentry *old_dentry,
714 struct dentry *dir, struct dentry *new_dentry,
715 struct lento_vfs_context *info)
720 struct inode_operations *iops;
721 struct presto_version tgt_dir_ver;
722 struct presto_version new_link_ver;
725 // down(&dir->d_inode->i_zombie);
726 error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH);
729 // up(&dir->d_inode->i_zombie);
733 inode = old_dentry->d_inode;
737 error = may_create(dir->d_inode, new_dentry);
742 if (dir->d_inode->i_sb != inode->i_sb)
746 * A link to an append-only or immutable file cannot be created.
749 if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) {
754 iops = filter_c2cdiops(fset->fset_cache->cache_filter);
761 presto_getversion(&tgt_dir_ver, dir->d_inode);
762 handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_LINK);
763 if ( IS_ERR(handle) ) {
764 presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
765 CERROR("presto_do_link: no space for transaction\n");
769 DQUOT_INIT(dir->d_inode);
771 error = iops->link(old_dentry, dir->d_inode, new_dentry);
778 /* link dd data to that of existing dentry */
779 old_dentry->d_op->d_release(new_dentry);
780 if (!presto_d2d(old_dentry))
782 presto_d2d(old_dentry)->dd_count++;
784 new_dentry->d_fsdata = presto_d2d(old_dentry);
786 info->flags |= LENTO_FL_TOUCH_PARENT;
787 error = presto_settime(fset, NULL, dir, new_dentry,
794 presto_debug_fail_blkdev(fset, KML_OPCODE_LINK | 0x10);
795 presto_getversion(&new_link_ver, new_dentry->d_inode);
796 if ( presto_do_kml(info, old_dentry) )
797 error = presto_journal_link(&rec, fset, old_dentry, new_dentry,
798 &tgt_dir_ver, &new_link_ver);
800 presto_debug_fail_blkdev(fset, KML_OPCODE_LINK | 0x20);
801 if ( presto_do_rcvd(info, old_dentry) )
802 error = presto_write_last_rcvd(&rec, fset, info);
804 presto_debug_fail_blkdev(fset, KML_OPCODE_LINK | 0x30);
806 presto_trans_commit(fset, handle);
808 presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
809 // up(&dir->d_inode->i_zombie);
814 int lento_link(const char * oldname, const char * newname,
815 struct lento_vfs_context *info)
819 struct presto_file_set *fset;
821 to = getname(newname);
824 struct dentry *new_dentry;
825 struct nameidata nd, old_nd;
827 error = __user_walk(oldname, 0, &old_nd);
830 error = path_lookup(to, LOOKUP_PARENT, &nd);
834 if (old_nd.mnt != nd.mnt)
836 new_dentry = lookup_create(&nd, 0);
837 error = PTR_ERR(new_dentry);
839 if (!IS_ERR(new_dentry)) {
840 fset = presto_fset(new_dentry);
843 CERROR("No fileset!\n");
847 error = presto_do_link(fset, old_nd.dentry,
853 up(&nd.dentry->d_inode->i_sem);
856 path_release(&old_nd);
863 int presto_do_unlink(struct presto_file_set *fset, struct dentry *dir,
864 struct dentry *dentry, struct lento_vfs_context *info)
867 struct inode_operations *iops;
868 struct presto_version tgt_dir_ver, old_file_ver;
869 struct izo_rollback_data rb;
871 int do_kml = 0, do_rcvd = 0, linkno = 0, error, old_targetlen = 0;
872 char *old_target = NULL;
875 // down(&dir->d_inode->i_zombie);
876 error = may_delete(dir->d_inode, dentry, 0);
879 // up(&dir->d_inode->i_zombie);
884 iops = filter_c2cdiops(fset->fset_cache->cache_filter);
887 // up(&dir->d_inode->i_zombie);
891 error = presto_reserve_space(fset->fset_cache, PRESTO_REQLOW);
894 // up(&dir->d_inode->i_zombie);
899 if (presto_d2d(dentry)) {
900 struct presto_dentry_data *dd = presto_d2d(dentry);
901 struct dentry *de = dd->dd_inodentry;
902 if (de && dentry->d_inode->i_nlink == 1) {
904 dd->dd_inodentry = NULL;
906 atomic_dec(&de->d_inode->i_count);
912 presto_getversion(&tgt_dir_ver, dir->d_inode);
913 presto_getversion(&old_file_ver, dentry->d_inode);
914 izo_get_rollback_data(dentry->d_inode, &rb);
915 handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_UNLINK);
916 if ( IS_ERR(handle) ) {
917 presto_release_space(fset->fset_cache, PRESTO_REQLOW);
918 CERROR("ERROR: presto_do_unlink: no space for transaction. Tell Peter.\n");
919 // up(&dir->d_inode->i_zombie);
922 DQUOT_INIT(dir->d_inode);
923 if (d_mountpoint(dentry))
927 linkno = dentry->d_inode->i_nlink;
932 if (S_ISLNK(dentry->d_inode->i_mode)) {
934 struct inode_operations *riops;
935 riops = filter_c2csiops(fset->fset_cache->cache_filter);
937 PRESTO_ALLOC(old_target, PATH_MAX);
938 if (old_target == NULL) {
947 if (riops->readlink == NULL)
948 CERROR("InterMezzo %s: no readlink iops.\n",
952 riops->readlink(dentry, old_target,
954 if (old_targetlen < 0) {
955 CERROR("InterMezzo: readlink failed: %ld\n",
956 PTR_ERR(old_target));
957 PRESTO_FREE(old_target, PATH_MAX);
964 do_kml = presto_do_kml(info, dir);
965 do_rcvd = presto_do_rcvd(info, dir);
966 error = iops->unlink(dir->d_inode, dentry);
971 /* FIXME: Combine this with the next call? */
972 error = presto_settime(fset, NULL, NULL, dentry,
981 error = presto_settime(fset, NULL, NULL, dir,
982 info, ATTR_CTIME | ATTR_MTIME);
988 // up(&dir->d_inode->i_zombie);
990 presto_debug_fail_blkdev(fset, KML_OPCODE_UNLINK | 0x10);
992 error = presto_journal_unlink(&rec, fset, dir, &tgt_dir_ver,
993 &old_file_ver, &rb, dentry,
994 old_target, old_targetlen);
995 presto_debug_fail_blkdev(fset, KML_OPCODE_UNLINK | 0x20);
997 error = presto_write_last_rcvd(&rec, fset, info);
999 presto_debug_fail_blkdev(fset, KML_OPCODE_UNLINK | 0x30);
1002 presto_release_space(fset->fset_cache, PRESTO_REQLOW);
1003 presto_trans_commit(fset, handle);
1004 if (old_target != NULL)
1005 PRESTO_FREE(old_target, PATH_MAX);
1010 int lento_unlink(const char *pathname, struct lento_vfs_context *info)
1014 struct dentry *dentry;
1015 struct nameidata nd;
1016 struct presto_file_set *fset;
1020 name = getname(pathname);
1022 return PTR_ERR(name);
1024 error = path_lookup(name, LOOKUP_PARENT, &nd);
1028 if (nd.last_type != LAST_NORM)
1030 down(&nd.dentry->d_inode->i_sem);
1031 dentry = lookup_hash(&nd.last, nd.dentry);
1032 error = PTR_ERR(dentry);
1033 if (!IS_ERR(dentry)) {
1034 fset = presto_fset(dentry);
1037 CERROR("No fileset!\n");
1041 /* Why not before? Because we want correct error value */
1042 if (nd.last.name[nd.last.len])
1044 error = presto_do_unlink(fset, nd.dentry, dentry, info);
1051 up(&nd.dentry->d_inode->i_sem);
1060 error = !dentry->d_inode ? -ENOENT :
1061 S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR;
1065 int presto_do_symlink(struct presto_file_set *fset, struct dentry *dir,
1066 struct dentry *dentry, const char *oldname,
1067 struct lento_vfs_context *info)
1069 struct rec_info rec;
1071 struct presto_version tgt_dir_ver, new_link_ver;
1072 struct inode_operations *iops;
1076 // down(&dir->d_inode->i_zombie);
1077 /* record + max path len + space to free */
1078 error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH + 4096);
1081 // up(&dir->d_inode->i_zombie);
1085 error = may_create(dir->d_inode, dentry);
1092 iops = filter_c2cdiops(fset->fset_cache->cache_filter);
1093 if (!iops->symlink) {
1098 presto_getversion(&tgt_dir_ver, dir->d_inode);
1099 handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_SYMLINK);
1100 if ( IS_ERR(handle) ) {
1101 presto_release_space(fset->fset_cache, PRESTO_REQHIGH + 4096);
1102 CERROR("ERROR: presto_do_symlink: no space for transaction. Tell Peter.\n");
1104 // up(&dir->d_inode->i_zombie);
1107 DQUOT_INIT(dir->d_inode);
1109 error = iops->symlink(dir->d_inode, dentry, oldname);
1115 if (dentry->d_inode) {
1116 struct presto_cache *cache = fset->fset_cache;
1118 presto_set_ops(dentry->d_inode, cache->cache_filter);
1120 filter_setup_dentry_ops(cache->cache_filter, dentry->d_op,
1121 &presto_dentry_ops);
1122 dentry->d_op = filter_c2udops(cache->cache_filter);
1123 /* XXX ? Cache state ? if Lento creates a symlink */
1124 if ( ISLENTO(presto_c2m(cache)) ) {
1125 presto_set(dentry, PRESTO_ATTR);
1127 presto_set(dentry, PRESTO_ATTR | PRESTO_DATA);
1131 info->flags |= LENTO_FL_TOUCH_PARENT;
1132 error = presto_settime(fset, NULL, dir, dentry,
1133 info, ATTR_CTIME | ATTR_MTIME);
1139 presto_debug_fail_blkdev(fset, KML_OPCODE_SYMLINK | 0x10);
1140 presto_getversion(&new_link_ver, dentry->d_inode);
1141 if ( presto_do_kml(info, dentry) )
1142 error = presto_journal_symlink(&rec, fset, dentry, oldname,
1143 &tgt_dir_ver, &new_link_ver);
1145 presto_debug_fail_blkdev(fset, KML_OPCODE_SYMLINK | 0x20);
1146 if ( presto_do_rcvd(info, dentry) )
1147 error = presto_write_last_rcvd(&rec, fset, info);
1149 presto_debug_fail_blkdev(fset, KML_OPCODE_SYMLINK | 0x30);
1153 presto_trans_commit(fset, handle);
1155 presto_release_space(fset->fset_cache, PRESTO_REQHIGH + 4096);
1156 // up(&dir->d_inode->i_zombie);
1160 int lento_symlink(const char *oldname, const char *newname,
1161 struct lento_vfs_context *info)
1166 struct dentry *dentry;
1167 struct presto_file_set *fset;
1168 struct nameidata nd;
1172 from = getname(oldname);
1173 error = PTR_ERR(from);
1179 to = getname(newname);
1180 error = PTR_ERR(to);
1186 error = path_lookup(to, LOOKUP_PARENT, &nd);
1192 dentry = lookup_create(&nd, 0);
1193 error = PTR_ERR(dentry);
1194 if (IS_ERR(dentry)) {
1200 fset = presto_fset(dentry);
1203 CERROR("No fileset!\n");
1208 error = presto_do_symlink(fset, nd.dentry,
1209 dentry, from, info);
1213 up(&nd.dentry->d_inode->i_sem);
1224 int presto_do_mkdir(struct presto_file_set *fset, struct dentry *dir,
1225 struct dentry *dentry, int mode,
1226 struct lento_vfs_context *info)
1228 struct rec_info rec;
1230 struct presto_version tgt_dir_ver, new_dir_ver;
1234 // down(&dir->d_inode->i_zombie);
1236 /* one journal record + directory block + room for removals*/
1237 error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH + 4096);
1240 // up(&dir->d_inode->i_zombie);
1244 error = may_create(dir->d_inode, dentry);
1251 if (!filter_c2cdiops(fset->fset_cache->cache_filter)->mkdir) {
1257 presto_getversion(&tgt_dir_ver, dir->d_inode);
1258 handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_MKDIR);
1259 if ( IS_ERR(handle) ) {
1260 presto_release_space(fset->fset_cache, PRESTO_REQHIGH + 4096);
1261 CERROR("presto_do_mkdir: no space for transaction\n");
1265 DQUOT_INIT(dir->d_inode);
1266 mode &= (S_IRWXUGO|S_ISVTX);
1268 error = filter_c2cdiops(fset->fset_cache->cache_filter)->mkdir(dir->d_inode, dentry, mode);
1274 if ( dentry->d_inode && !error) {
1275 struct presto_cache *cache = fset->fset_cache;
1277 presto_set_ops(dentry->d_inode, cache->cache_filter);
1279 filter_setup_dentry_ops(cache->cache_filter,
1281 &presto_dentry_ops);
1282 dentry->d_op = filter_c2udops(cache->cache_filter);
1283 /* if Lento does this, we won't have data */
1284 if ( ISLENTO(presto_c2m(cache)) ) {
1285 presto_set(dentry, PRESTO_ATTR);
1287 presto_set(dentry, PRESTO_ATTR | PRESTO_DATA);
1291 info->flags |= LENTO_FL_TOUCH_PARENT;
1292 error = presto_settime(fset, NULL, dir, dentry,
1293 info, ATTR_CTIME | ATTR_MTIME);
1299 presto_debug_fail_blkdev(fset, KML_OPCODE_MKDIR | 0x10);
1300 presto_getversion(&new_dir_ver, dentry->d_inode);
1301 if ( presto_do_kml(info, dir) )
1302 error = presto_journal_mkdir(&rec, fset, dentry, &tgt_dir_ver,
1304 dentry->d_inode->i_mode);
1306 presto_debug_fail_blkdev(fset, KML_OPCODE_MKDIR | 0x20);
1307 if ( presto_do_rcvd(info, dentry) )
1308 error = presto_write_last_rcvd(&rec, fset, info);
1310 presto_debug_fail_blkdev(fset, KML_OPCODE_MKDIR | 0x30);
1314 presto_trans_commit(fset, handle);
1316 presto_release_space(fset->fset_cache, PRESTO_REQHIGH + 4096);
1317 // up(&dir->d_inode->i_zombie);
1322 * Look out: this function may change a normal dentry
1323 * into a directory dentry (different size)..
1325 int lento_mkdir(const char *name, int mode, struct lento_vfs_context *info)
1329 struct dentry *dentry;
1330 struct presto_file_set *fset;
1331 struct nameidata nd;
1334 CDEBUG(D_PIOCTL, "name: %s, mode %o, offset %d, recno %d, flags %x\n",
1335 name, mode, info->slot_offset, info->recno, info->flags);
1336 pathname = getname(name);
1337 error = PTR_ERR(pathname);
1338 if (IS_ERR(pathname)) {
1343 error = path_lookup(pathname, LOOKUP_PARENT, &nd);
1347 dentry = lookup_create(&nd, 1);
1348 error = PTR_ERR(dentry);
1349 if (!IS_ERR(dentry)) {
1350 fset = presto_fset(dentry);
1353 CERROR("No fileset!\n");
1358 error = presto_do_mkdir(fset, nd.dentry, dentry,
1359 mode & S_IALLUGO, info);
1363 up(&nd.dentry->d_inode->i_sem);
1368 CDEBUG(D_PIOCTL, "error: %d\n", error);
1372 static void d_unhash(struct dentry *dentry)
1375 switch (atomic_read(&dentry->d_count)) {
1377 shrink_dcache_parent(dentry);
1378 if (atomic_read(&dentry->d_count) != 2)
1385 int presto_do_rmdir(struct presto_file_set *fset, struct dentry *dir,
1386 struct dentry *dentry, struct lento_vfs_context *info)
1388 struct rec_info rec;
1390 struct presto_version tgt_dir_ver, old_dir_ver;
1391 struct izo_rollback_data rb;
1392 struct inode_operations *iops;
1394 int do_kml, do_rcvd;
1398 error = may_delete(dir->d_inode, dentry, 1);
1403 iops = filter_c2cdiops(fset->fset_cache->cache_filter);
1409 size = PRESTO_REQHIGH - dentry->d_inode->i_size;
1410 error = presto_reserve_space(fset->fset_cache, size);
1416 presto_getversion(&tgt_dir_ver, dir->d_inode);
1417 presto_getversion(&old_dir_ver, dentry->d_inode);
1418 izo_get_rollback_data(dentry->d_inode, &rb);
1419 handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_RMDIR);
1420 if ( IS_ERR(handle) ) {
1421 presto_release_space(fset->fset_cache, size);
1422 CERROR("ERROR: presto_do_rmdir: no space for transaction. Tell Peter.\n");
1426 DQUOT_INIT(dir->d_inode);
1428 do_kml = presto_do_kml(info, dir);
1429 do_rcvd = presto_do_rcvd(info, dir);
1431 // double_down(&dir->d_inode->i_zombie, &dentry->d_inode->i_zombie);
1433 if (IS_DEADDIR(dir->d_inode))
1435 else if (d_mountpoint(dentry)) {
1436 CERROR("foo: d_mountpoint(dentry): ino %ld\n",
1437 dentry->d_inode->i_ino);
1441 error = iops->rmdir(dir->d_inode, dentry);
1444 dentry->d_inode->i_flags |= S_DEAD;
1445 error = presto_settime(fset, NULL, NULL, dir, info,
1446 ATTR_CTIME | ATTR_MTIME);
1449 // double_up(&dir->d_inode->i_zombie, &dentry->d_inode->i_zombie);
1454 presto_debug_fail_blkdev(fset, KML_OPCODE_RMDIR | 0x10);
1455 if ( !error && do_kml )
1456 error = presto_journal_rmdir(&rec, fset, dir, &tgt_dir_ver,
1459 dentry->d_name.name);
1461 presto_debug_fail_blkdev(fset, KML_OPCODE_RMDIR | 0x20);
1462 if ( !error && do_rcvd )
1463 error = presto_write_last_rcvd(&rec, fset, info);
1465 presto_debug_fail_blkdev(fset, KML_OPCODE_RMDIR | 0x30);
1468 presto_trans_commit(fset, handle);
1469 presto_release_space(fset->fset_cache, size);
1473 int lento_rmdir(const char *pathname, struct lento_vfs_context *info)
1477 struct dentry *dentry;
1478 struct presto_file_set *fset;
1479 struct nameidata nd;
1482 name = getname(pathname);
1485 return PTR_ERR(name);
1488 error = path_lookup(name, LOOKUP_PARENT, &nd);
1493 switch(nd.last_type) {
1504 down(&nd.dentry->d_inode->i_sem);
1505 dentry = lookup_hash(&nd.last, nd.dentry);
1506 error = PTR_ERR(dentry);
1507 if (!IS_ERR(dentry)) {
1508 fset = presto_fset(dentry);
1511 CERROR("No fileset!\n");
1515 error = presto_do_rmdir(fset, nd.dentry, dentry, info);
1519 up(&nd.dentry->d_inode->i_sem);
1528 int presto_do_mknod(struct presto_file_set *fset, struct dentry *dir,
1529 struct dentry *dentry, int mode, dev_t dev,
1530 struct lento_vfs_context *info)
1532 struct rec_info rec;
1534 struct presto_version tgt_dir_ver, new_node_ver;
1535 struct inode_operations *iops;
1540 // down(&dir->d_inode->i_zombie);
1542 error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH);
1545 // up(&dir->d_inode->i_zombie);
1549 if ((S_ISCHR(mode) || S_ISBLK(mode)) && !capable(CAP_MKNOD)) {
1554 error = may_create(dir->d_inode, dentry);
1561 iops = filter_c2cdiops(fset->fset_cache->cache_filter);
1567 DQUOT_INIT(dir->d_inode);
1571 presto_getversion(&tgt_dir_ver, dir->d_inode);
1572 handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_MKNOD);
1573 if ( IS_ERR(handle) ) {
1574 presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
1575 CERROR("presto_do_mknod: no space for transaction\n");
1579 error = iops->mknod(dir->d_inode, dentry, mode, dev);
1584 if ( dentry->d_inode) {
1585 struct presto_cache *cache = fset->fset_cache;
1587 presto_set_ops(dentry->d_inode, cache->cache_filter);
1589 filter_setup_dentry_ops(cache->cache_filter, dentry->d_op,
1590 &presto_dentry_ops);
1591 dentry->d_op = filter_c2udops(cache->cache_filter);
1593 /* if Lento does this, we won't have data */
1594 if ( ISLENTO(presto_c2m(cache)) ) {
1595 presto_set(dentry, PRESTO_ATTR);
1597 presto_set(dentry, PRESTO_ATTR | PRESTO_DATA);
1601 error = presto_settime(fset, NULL, NULL, dir,
1606 error = presto_settime(fset, NULL, NULL, dentry,
1607 info, ATTR_CTIME | ATTR_MTIME);
1612 presto_debug_fail_blkdev(fset, KML_OPCODE_MKNOD | 0x10);
1613 presto_getversion(&new_node_ver, dentry->d_inode);
1614 if ( presto_do_kml(info, dentry) )
1615 error = presto_journal_mknod(&rec, fset, dentry, &tgt_dir_ver,
1617 dentry->d_inode->i_mode,
1618 MAJOR(dev), MINOR(dev) );
1620 presto_debug_fail_blkdev(fset, KML_OPCODE_MKNOD | 0x20);
1621 if ( presto_do_rcvd(info, dentry) )
1622 error = presto_write_last_rcvd(&rec, fset, info);
1624 presto_debug_fail_blkdev(fset, KML_OPCODE_MKNOD | 0x30);
1627 presto_trans_commit(fset, handle);
1631 presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
1632 // up(&dir->d_inode->i_zombie);
1636 int lento_mknod(const char *filename, int mode, dev_t dev,
1637 struct lento_vfs_context *info)
1641 struct dentry * dentry;
1642 struct nameidata nd;
1643 struct presto_file_set *fset;
1649 tmp = getname(filename);
1651 return PTR_ERR(tmp);
1653 error = path_lookup(tmp, LOOKUP_PARENT, &nd);
1656 dentry = lookup_create(&nd, 0);
1657 error = PTR_ERR(dentry);
1658 if (!IS_ERR(dentry)) {
1659 fset = presto_fset(dentry);
1662 CERROR("No fileset!\n");
1666 switch (mode & S_IFMT) {
1667 case 0: case S_IFREG:
1668 error = -EOPNOTSUPP;
1670 case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK:
1671 error = presto_do_mknod(fset, nd.dentry, dentry,
1683 up(&nd.dentry->d_inode->i_sem);
1691 int do_rename(struct presto_file_set *fset,
1692 struct dentry *old_parent, struct dentry *old_dentry,
1693 struct dentry *new_parent, struct dentry *new_dentry,
1694 struct lento_vfs_context *info)
1696 struct rec_info rec;
1698 struct inode_operations *iops;
1699 struct presto_version src_dir_ver, tgt_dir_ver;
1701 int new_inode_unlink = 0;
1702 struct inode *old_dir = old_parent->d_inode;
1703 struct inode *new_dir = new_parent->d_inode;
1706 presto_getversion(&src_dir_ver, old_dir);
1707 presto_getversion(&tgt_dir_ver, new_dir);
1710 iops = filter_c2cdiops(fset->fset_cache->cache_filter);
1711 if (!iops || !iops->rename) {
1716 error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH);
1721 handle = presto_trans_start(fset, old_dir, KML_OPCODE_RENAME);
1722 if ( IS_ERR(handle) ) {
1723 presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
1724 CERROR("presto_do_rename: no space for transaction\n");
1727 if (new_dentry->d_inode && new_dentry->d_inode->i_nlink > 1) {
1729 new_inode_unlink = 1;
1732 error = iops->rename(old_dir, old_dentry, new_dir, new_dentry);
1739 if (new_inode_unlink) {
1740 error = presto_settime(fset, NULL, NULL, old_dentry,
1748 info->flags |= LENTO_FL_TOUCH_PARENT;
1749 error = presto_settime(fset, NULL, new_parent, old_parent,
1750 info, ATTR_CTIME | ATTR_MTIME);
1756 /* XXX make a distinction between cross file set
1757 * and intra file set renames here
1759 presto_debug_fail_blkdev(fset, KML_OPCODE_RENAME | 0x10);
1760 if ( presto_do_kml(info, old_dentry) )
1761 error = presto_journal_rename(&rec, fset, old_dentry,
1763 &src_dir_ver, &tgt_dir_ver);
1765 presto_debug_fail_blkdev(fset, KML_OPCODE_RENAME | 0x20);
1767 if ( presto_do_rcvd(info, old_dentry) )
1768 error = presto_write_last_rcvd(&rec, fset, info);
1770 presto_debug_fail_blkdev(fset, KML_OPCODE_RENAME | 0x30);
1773 presto_trans_commit(fset, handle);
1774 presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
1779 int presto_rename_dir(struct presto_file_set *fset, struct dentry *old_parent,
1780 struct dentry *old_dentry, struct dentry *new_parent,
1781 struct dentry *new_dentry, struct lento_vfs_context *info)
1784 struct inode *target;
1785 struct inode *old_dir = old_parent->d_inode;
1786 struct inode *new_dir = new_parent->d_inode;
1788 if (old_dentry->d_inode == new_dentry->d_inode)
1791 error = may_delete(old_dir, old_dentry, 1);
1795 if (new_dir->i_sb != old_dir->i_sb)
1798 if (!new_dentry->d_inode)
1799 error = may_create(new_dir, new_dentry);
1801 error = may_delete(new_dir, new_dentry, 1);
1805 if (!old_dir->i_op || !old_dir->i_op->rename)
1809 * If we are going to change the parent - check write permissions,
1810 * we'll need to flip '..'.
1812 if (new_dir != old_dir) {
1813 error = permission(old_dentry->d_inode, MAY_WRITE, NULL);
1818 DQUOT_INIT(old_dir);
1819 DQUOT_INIT(new_dir);
1820 down(&old_dir->i_sb->s_vfs_rename_sem);
1822 if (is_subdir(new_dentry, old_dentry))
1824 target = new_dentry->d_inode;
1825 if (target) { /* Hastur! Hastur! Hastur! */
1826 // triple_down(&old_dir->i_zombie,
1827 // &new_dir->i_zombie,
1828 // &target->i_zombie);
1829 d_unhash(new_dentry);
1831 // double_down(&old_dir->i_zombie,
1832 // &new_dir->i_zombie);
1833 if (IS_DEADDIR(old_dir)||IS_DEADDIR(new_dir))
1835 else if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
1838 error = do_rename(fset, old_parent, old_dentry,
1839 new_parent, new_dentry, info);
1842 target->i_flags |= S_DEAD;
1843 // triple_up(&old_dir->i_zombie,
1844 // &new_dir->i_zombie,
1845 // &target->i_zombie);
1846 if (d_unhashed(new_dentry))
1847 d_rehash(new_dentry);
1850 // double_up(&old_dir->i_zombie,
1851 // &new_dir->i_zombie);
1854 d_move(old_dentry,new_dentry);
1856 up(&old_dir->i_sb->s_vfs_rename_sem);
1861 int presto_rename_other(struct presto_file_set *fset, struct dentry *old_parent,
1862 struct dentry *old_dentry, struct dentry *new_parent,
1863 struct dentry *new_dentry, struct lento_vfs_context *info)
1865 struct inode *old_dir = old_parent->d_inode;
1866 struct inode *new_dir = new_parent->d_inode;
1869 if (old_dentry->d_inode == new_dentry->d_inode)
1872 error = may_delete(old_dir, old_dentry, 0);
1876 if (new_dir->i_sb != old_dir->i_sb)
1879 if (!new_dentry->d_inode)
1880 error = may_create(new_dir, new_dentry);
1882 error = may_delete(new_dir, new_dentry, 0);
1886 if (!old_dir->i_op || !old_dir->i_op->rename)
1889 DQUOT_INIT(old_dir);
1890 DQUOT_INIT(new_dir);
1891 // double_down(&old_dir->i_zombie, &new_dir->i_zombie);
1892 if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
1895 error = do_rename(fset, old_parent, old_dentry,
1896 new_parent, new_dentry, info);
1897 // double_up(&old_dir->i_zombie, &new_dir->i_zombie);
1900 /* The following d_move() should become unconditional */
1901 if (!(old_dir->i_sb->s_type->fs_flags & FS_ODD_RENAME)) {
1902 d_move(old_dentry, new_dentry);
1907 int presto_do_rename(struct presto_file_set *fset,
1908 struct dentry *old_parent, struct dentry *old_dentry,
1909 struct dentry *new_parent, struct dentry *new_dentry,
1910 struct lento_vfs_context *info)
1912 if (S_ISDIR(old_dentry->d_inode->i_mode))
1913 return presto_rename_dir(fset, old_parent,old_dentry,new_parent,
1916 return presto_rename_other(fset, old_parent, old_dentry,
1917 new_parent,new_dentry, info);
1921 int lento_do_rename(const char *oldname, const char *newname,
1922 struct lento_vfs_context *info)
1925 struct dentry * old_dir, * new_dir;
1926 struct dentry * old_dentry, *new_dentry;
1927 struct nameidata oldnd, newnd;
1928 struct presto_file_set *fset;
1932 error = path_lookup(oldname, LOOKUP_PARENT, &oldnd);
1936 error = path_lookup(newname, LOOKUP_PARENT, &newnd);
1941 if (oldnd.mnt != newnd.mnt)
1944 old_dir = oldnd.dentry;
1946 if (oldnd.last_type != LAST_NORM)
1949 new_dir = newnd.dentry;
1950 if (newnd.last_type != LAST_NORM)
1953 lock_rename(new_dir, old_dir);
1955 old_dentry = lookup_hash(&oldnd.last, old_dir);
1956 error = PTR_ERR(old_dentry);
1957 if (IS_ERR(old_dentry))
1959 /* source must exist */
1961 if (!old_dentry->d_inode)
1963 fset = presto_fset(old_dentry);
1966 CERROR("No fileset!\n");
1970 /* unless the source is a directory trailing slashes give -ENOTDIR */
1971 if (!S_ISDIR(old_dentry->d_inode->i_mode)) {
1973 if (oldnd.last.name[oldnd.last.len])
1975 if (newnd.last.name[newnd.last.len])
1978 new_dentry = lookup_hash(&newnd.last, new_dir);
1979 error = PTR_ERR(new_dentry);
1980 if (IS_ERR(new_dentry))
1984 error = presto_do_rename(fset, old_dir, old_dentry,
1985 new_dir, new_dentry, info);
1992 unlock_rename(new_dir, old_dir);
1994 path_release(&newnd);
1996 path_release(&oldnd);
2001 int lento_rename(const char * oldname, const char * newname,
2002 struct lento_vfs_context *info)
2008 from = getname(oldname);
2010 return PTR_ERR(from);
2011 to = getname(newname);
2012 error = PTR_ERR(to);
2014 error = lento_do_rename(from,to, info);
2021 struct dentry *presto_iopen(struct dentry *dentry,
2022 ino_t ino, unsigned int generation)
2024 struct presto_file_set *fset;
2029 /* see if we already have the dentry we want */
2030 if (dentry->d_inode && dentry->d_inode->i_ino == ino &&
2031 dentry->d_inode->i_generation == generation) {
2036 /* Make sure we have a cache beneath us. We should always find at
2037 * least one dentry inside the cache (if it exists), otherwise not
2038 * even the cache root exists, or we passed in a bad name.
2040 fset = presto_fset(dentry);
2043 CERROR("No fileset for %*s!\n",
2044 dentry->d_name.len, dentry->d_name.name);
2047 return ERR_PTR(error);
2051 sprintf(name, "%s%#lx%c%#x",
2052 PRESTO_ILOOKUP_MAGIC, ino, PRESTO_ILOOKUP_SEP, generation);
2053 CDEBUG(D_PIOCTL, "opening %ld by number (as %s)\n", ino, name);
2054 return lookup_one_len(name, fset->fset_dentry, strlen(name));
2057 static struct file *presto_filp_dopen(struct dentry *dentry, int flags)
2060 struct inode *inode;
2065 f = get_empty_filp();
2067 CDEBUG(D_PIOCTL, "error getting file pointer\n");
2071 f->f_flags = flag = flags;
2072 f->f_mode = (flag+1) & O_ACCMODE;
2073 inode = dentry->d_inode;
2074 if (f->f_mode & FMODE_WRITE) {
2075 error = get_write_access(inode);
2077 CDEBUG(D_PIOCTL, "error getting write access\n");
2078 EXIT; goto cleanup_file;
2082 /* XXX: where the fuck is ->f_vfsmnt? */
2083 f->f_dentry = dentry;
2084 f->f_mapping = dentry->d_inode->i_mapping;
2089 /* XXX should we set to presto ops, or leave at cache ops? */
2090 f->f_op = inode->i_fop;
2091 if (f->f_op && f->f_op->open) {
2092 error = f->f_op->open(inode, f);
2094 CDEBUG(D_PIOCTL, "error calling cache 'open'\n");
2099 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
2104 if (f->f_mode & FMODE_WRITE)
2105 put_write_access(inode);
2109 return ERR_PTR(error);
2113 /* Open an inode by number. We pass in the cache root name (or a subdirectory
2114 * from the cache that is guaranteed to exist) to be able to access the cache.
2116 int lento_iopen(const char *name, ino_t ino, unsigned int generation,
2120 struct dentry *dentry;
2121 struct nameidata nd;
2127 "open %s:inode %#lx (%ld), generation %x (%d), flags %d \n",
2128 name, ino, ino, generation, generation, flags);
2129 /* We don't allow creation of files by number only, as it would
2130 * lead to a dangling files not in any directory. We could also
2131 * just turn off the flag and ignore it.
2133 if (flags & O_CREAT) {
2134 CERROR("%s: create file by inode number (%ld) not allowed\n",
2140 tmp = getname(name);
2143 return PTR_ERR(tmp);
2147 again: /* look the named file or a parent directory so we can get the cache */
2148 error = presto_walk(tmp, &nd);
2149 if ( error && error != -ENOENT ) {
2155 if (error == -ENOENT)
2160 /* we didn't find the named file, so see if a parent exists */
2164 slash = strrchr(tmp, '/');
2165 if (slash && slash != tmp) {
2170 /* we should never get here... */
2171 CDEBUG(D_PIOCTL, "no more path components to try!\n");
2175 CDEBUG(D_PIOCTL, "returned dentry %p\n", dentry);
2177 dentry = presto_iopen(dentry, ino, generation);
2178 fd = PTR_ERR(dentry);
2179 if (IS_ERR(dentry)) {
2184 /* XXX start of code that might be replaced by something like:
2185 * if (flags & (O_WRONLY | O_RDWR)) {
2186 * error = get_write_access(dentry->d_inode);
2189 * goto cleanup_dput;
2192 * fd = open_dentry(dentry, flags);
2194 * including the presto_filp_dopen() function (check dget counts!)
2196 fd = get_unused_fd();
2204 struct file * f = presto_filp_dopen(dentry, flags);
2213 /* end of code that might be replaced by open_dentry */
2223 #ifdef CONFIG_FS_EXT_ATTR
2225 #if 0 /* was a broken check for Posix ACLs */
2226 /* Posix ACL code changes i_mode without using a notify_change (or
2227 * a mark_inode_dirty!). We need to duplicate this at the reintegrator
2228 * which is done by this function. This function also takes care of
2229 * resetting the cached posix acls in this inode. If we don't reset these
2230 * VFS continues using the old acl information, which by now may be out of
2233 int presto_setmode(struct presto_file_set *fset, struct dentry *dentry,
2236 struct inode *inode = dentry->d_inode;
2239 /* The extended attributes for this inode were modified.
2240 * At this point we can not be sure if any of the ACL
2241 * information for this inode was updated. So we will
2242 * force VFS to reread the acls. Note that we do this
2243 * only when called from the SETEXTATTR ioctl, which is why we
2244 * do this while setting the mode of the file. Also note
2245 * that mark_inode_dirty is not be needed for i_*acl only
2246 * to force i_mode info to disk, and should be removed once
2247 * we use notify_change to update the mode.
2248 * XXX: is mode setting really needed? Just setting acl's should
2249 * be enough! VFS should change the i_mode as needed? SHP
2252 inode->i_acl != POSIX_ACL_NOT_CACHED)
2253 posix_acl_release(inode->i_acl);
2254 if (inode->i_default_acl &&
2255 inode->i_default_acl != POSIX_ACL_NOT_CACHED)
2256 posix_acl_release(inode->i_default_acl);
2257 inode->i_acl = POSIX_ACL_NOT_CACHED;
2258 inode->i_default_acl = POSIX_ACL_NOT_CACHED;
2259 inode->i_mode = mode;
2260 /* inode should already be dirty...but just in case */
2261 mark_inode_dirty(inode);
2265 /* XXX: The following code is the preferred way to set mode,
2266 * however, I need to carefully go through possible recursion
2267 * paths back into presto. See comments in presto_do_setattr.
2271 struct super_operations *sops;
2274 iattr.ia_mode = mode;
2275 iattr.ia_valid = ATTR_MODE|ATTR_FORCE;
2278 sops = filter_c2csops(fset->fset_cache->cache_filter);
2280 !sops->notify_change) {
2285 error = sops->notify_change(dentry, &iattr);
2294 /* setextattr Interface to cache filesystem */
2295 int presto_do_set_ext_attr(struct presto_file_set *fset,
2296 struct dentry *dentry,
2297 const char *name, void *buffer,
2298 size_t buffer_len, int flags, mode_t *mode,
2299 struct lento_vfs_context *info)
2301 struct rec_info rec;
2302 struct inode *inode = dentry->d_inode;
2303 struct inode_operations *iops;
2305 struct presto_version ver;
2307 char temp[PRESTO_EXT_ATTR_NAME_MAX+1];
2311 if (IS_RDONLY(inode)) {
2316 if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
2321 presto_getversion(&ver, inode);
2323 /* We need to invoke different filters based on whether
2324 * this dentry is a regular file, directory or symlink.
2326 switch (inode->i_mode & S_IFMT) {
2327 case S_IFLNK: /* symlink */
2328 iops = filter_c2csiops(fset->fset_cache->cache_filter);
2330 case S_IFDIR: /* directory */
2331 iops = filter_c2cdiops(fset->fset_cache->cache_filter);
2334 default: /* everything else including regular files */
2335 iops = filter_c2cfiops(fset->fset_cache->cache_filter);
2338 if (!iops && !iops->set_ext_attr) {
2343 error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH);
2350 handle = presto_trans_start(fset,dentry->d_inode,KML_OPCODE_SETEXTATTR);
2351 if ( IS_ERR(handle) ) {
2352 CERROR("presto_do_set_ext_attr: no space for transaction\n");
2353 presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
2357 /* We first "truncate" name to the maximum allowable in presto */
2358 /* This simulates the strncpy_from_use code in fs/ext_attr.c */
2359 strlcpy(temp,name,sizeof(temp));
2361 /* Pass down to cache*/
2362 error = iops->set_ext_attr(inode,temp,buffer,buffer_len,flags);
2368 #if 0 /* was a broken check for Posix ACLs */
2369 /* Reset mode if specified*/
2370 /* XXX: when we do native acl support, move this code out! */
2372 error = presto_setmode(fset, dentry, *mode);
2380 /* Reset ctime. Only inode change time (ctime) is affected */
2381 error = presto_settime(fset, NULL, NULL, dentry, info, ATTR_CTIME);
2387 if (flags & EXT_ATTR_FLAG_USER) {
2388 CERROR(" USER flag passed to presto_do_set_ext_attr!\n");
2392 /* We are here, so set_ext_attr succeeded. We no longer need to keep
2393 * track of EXT_ATTR_FLAG_{EXISTS,CREATE}, instead, we will force
2394 * the attribute value during log replay. -SHP
2396 flags &= ~(EXT_ATTR_FLAG_EXISTS | EXT_ATTR_FLAG_CREATE);
2398 presto_debug_fail_blkdev(fset, KML_OPCODE_SETEXTATTR | 0x10);
2399 if ( presto_do_kml(info, dentry) )
2400 error = presto_journal_set_ext_attr
2401 (&rec, fset, dentry, &ver, name, buffer,
2404 presto_debug_fail_blkdev(fset, KML_OPCODE_SETEXTATTR | 0x20);
2405 if ( presto_do_rcvd(info, dentry) )
2406 error = presto_write_last_rcvd(&rec, fset, info);
2408 presto_debug_fail_blkdev(fset, KML_OPCODE_SETEXTATTR | 0x30);
2411 presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
2412 presto_trans_commit(fset, handle);