patch-2.4.20 linux-2.4.20/fs/intermezzo/vfs.c
Next file: linux-2.4.20/fs/iobuf.c
Previous file: linux-2.4.20/fs/intermezzo/upcall.c
Back to the patch index
Back to the overall index
- Lines: 1702
- Date:
Thu Nov 28 15:53:15 2002
- Orig file:
linux-2.4.19/fs/intermezzo/vfs.c
- Orig date:
Fri Aug 2 17:39:45 2002
diff -urN linux-2.4.19/fs/intermezzo/vfs.c linux-2.4.20/fs/intermezzo/vfs.c
@@ -1,4 +1,25 @@
-/*
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Copyright (C) 2001, 2002 Cluster File Systems, Inc.
+ * Copyright (C) 2000 Stelias Computing, Inc.
+ * Copyright (C) 2000 Red Hat, Inc.
+ *
+ * This file is part of InterMezzo, http://www.inter-mezzo.org.
+ *
+ * InterMezzo is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * InterMezzo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with InterMezzo; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
* vfs.c
*
* This file implements kernel downcalls from lento.
@@ -48,20 +69,50 @@
#include <linux/blk.h>
#include <linux/intermezzo_fs.h>
-#include <linux/intermezzo_upcall.h>
#include <linux/intermezzo_psdev.h>
-#include <linux/intermezzo_kml.h>
#ifdef CONFIG_FS_EXT_ATTR
-#include <linux/ext_attr.h>
+# include <linux/ext_attr.h>
-#ifdef CONFIG_FS_POSIX_ACL
-#include <linux/posix_acl.h>
-#endif
+# ifdef CONFIG_FS_POSIX_ACL
+# include <linux/posix_acl.h>
+# endif
#endif
extern struct inode_operations presto_sym_iops;
+/* Write the last_rcvd values to the last_rcvd file. We don't know what the
+ * UUID or last_ctime values are, so we have to read from the file first
+ * (sigh).
+ * exported for branch_reinter in kml_reint.c*/
+int presto_write_last_rcvd(struct rec_info *recinfo,
+ struct presto_file_set *fset,
+ struct lento_vfs_context *info)
+{
+ int rc;
+ struct izo_rcvd_rec rcvd_rec;
+
+ ENTRY;
+
+ memset(&rcvd_rec, 0, sizeof(rcvd_rec));
+ memcpy(rcvd_rec.lr_uuid, info->uuid, sizeof(rcvd_rec.lr_uuid));
+ rcvd_rec.lr_remote_recno = HTON__u64(info->recno);
+ rcvd_rec.lr_remote_offset = HTON__u64(info->kml_offset);
+ rcvd_rec.lr_local_recno = HTON__u64(recinfo->recno);
+ rcvd_rec.lr_local_offset = HTON__u64(recinfo->offset + recinfo->size);
+
+ rc = izo_rcvd_write(fset, &rcvd_rec);
+ if (rc < 0) {
+ /* izo_rcvd_write returns negative errors and non-negative
+ * offsets */
+ CERROR("InterMezzo: izo_rcvd_write failed: %d\n", rc);
+ EXIT;
+ return rc;
+ }
+ EXIT;
+ return 0;
+}
+
/*
* It's inline, so penalty for filesystems that don't use sticky bit is
* minimal.
@@ -130,13 +181,13 @@
unsigned long value)
{
int minor = presto_f2m(fset);
- int errorval = upc_comms[minor].uc_errorval;
- kdev_t dev = fset->fset_mtpt->d_inode->i_dev;
+ int errorval = izo_channels[minor].uc_errorval;
+ kdev_t dev = fset->fset_dentry->d_inode->i_dev;
if (errorval && errorval == (long)value && !is_read_only(dev)) {
CDEBUG(D_SUPER, "setting device %s read only\n", kdevname(dev));
BLKDEV_FAIL(dev, 1);
- upc_comms[minor].uc_errorval = -dev;
+ izo_channels[minor].uc_errorval = -dev;
}
}
#else
@@ -144,20 +195,22 @@
#endif
-static inline int presto_do_kml(struct lento_vfs_context *info, struct inode* inode)
+static inline int presto_do_kml(struct lento_vfs_context *info,
+ struct dentry *dentry)
{
- if ( ! (info->flags & LENTO_FL_KML) )
+ if ( ! (info->flags & LENTO_FL_KML) )
return 0;
- if ( inode->i_gid == presto_excluded_gid )
+ if ( presto_chk(dentry, PRESTO_DONT_JOURNAL) )
return 0;
return 1;
}
-static inline int presto_do_expect(struct lento_vfs_context *info, struct inode *inode)
+static inline int presto_do_rcvd(struct lento_vfs_context *info,
+ struct dentry *dentry)
{
if ( ! (info->flags & LENTO_FL_EXPECT) )
return 0;
- if ( inode->i_gid == presto_excluded_gid )
+ if ( presto_chk(dentry, PRESTO_DONT_JOURNAL) )
return 0;
return 1;
}
@@ -166,12 +219,15 @@
/* XXX fixme: this should not fail, all these dentries are in memory
when _we_ call this */
int presto_settime(struct presto_file_set *fset,
- struct dentry *dentry,
+ struct dentry *newobj,
+ struct dentry *parent,
+ struct dentry *target,
struct lento_vfs_context *ctx,
int valid)
{
- int error;
- struct inode *inode = dentry->d_inode;
+ int error = 0;
+ struct dentry *dentry;
+ struct inode *inode;
struct inode_operations *iops;
struct iattr iattr;
@@ -180,39 +236,128 @@
EXIT;
return 0;
}
+
iattr.ia_ctime = ctx->updated_time;
iattr.ia_mtime = ctx->updated_time;
iattr.ia_valid = valid;
- error = -EROFS;
- if (IS_RDONLY(inode)) {
- EXIT;
- return -EROFS;
+ while (1) {
+ if (parent && ctx->flags & LENTO_FL_TOUCH_PARENT) {
+ dentry = parent;
+ parent = NULL;
+ } else if (newobj && ctx->flags & LENTO_FL_TOUCH_NEWOBJ) {
+ dentry = newobj;
+ newobj = NULL;
+ } else if (target) {
+ dentry = target;
+ target = NULL;
+ } else
+ break;
+
+ inode = dentry->d_inode;
+
+ error = -EROFS;
+ if (IS_RDONLY(inode)) {
+ EXIT;
+ return -EROFS;
+ }
+
+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
+ EXIT;
+ return -EPERM;
+ }
+
+ error = -EPERM;
+ iops = filter_c2cdiops(fset->fset_cache->cache_filter);
+ if (!iops) {
+ EXIT;
+ return error;
+ }
+
+ if (iops->setattr != NULL)
+ error = iops->setattr(dentry, &iattr);
+ else {
+ error = 0;
+ inode_setattr(dentry->d_inode, &iattr);
+ }
}
+ EXIT;
+ return error;
+}
- if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
+void izo_get_rollback_data(struct inode *inode, struct izo_rollback_data *rb)
+{
+ rb->rb_mode = (__u32)inode->i_mode;
+ rb->rb_rdev = (__u32)inode->i_rdev;
+ rb->rb_uid = (__u64)inode->i_uid;
+ rb->rb_gid = (__u64)inode->i_gid;
+}
+
+
+int presto_do_close(struct presto_file_set *fset, struct file *file)
+{
+ struct rec_info rec;
+ int rc = -ENOSPC;
+ void *handle;
+ struct inode *inode = file->f_dentry->d_inode;
+ struct presto_file_data *fdata =
+ (struct presto_file_data *)file->private_data;
+
+ ENTRY;
+ presto_getversion(&fdata->fd_info.remote_version, inode);
+
+ rc = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH);
+ if (rc) {
EXIT;
- return -EPERM;
+ return rc;
}
- error = -EPERM;
- iops = filter_c2cdiops(fset->fset_cache->cache_filter);
- if (!iops) {
- EXIT;
- return error;
+ handle = presto_trans_start(fset, file->f_dentry->d_inode,
+ KML_OPCODE_RELEASE);
+ if ( IS_ERR(handle) ) {
+ CERROR("presto_release: no space for transaction\n");
+ return rc;
}
- if (iops->setattr != NULL)
- error = iops->setattr(dentry, &iattr);
- else {
- error = 0;
- inode_setattr(dentry->d_inode, &iattr);
- }
+ if (fdata->fd_info.flags & LENTO_FL_KML)
+ rc = presto_journal_close(&rec, fset, file, file->f_dentry,
+ &fdata->fd_version,
+ &fdata->fd_info.remote_version);
+ if (rc) {
+ CERROR("presto_close: cannot journal close\n");
+ goto out;
+ }
+
+ if (fdata->fd_info.flags & LENTO_FL_EXPECT)
+ rc = presto_write_last_rcvd(&rec, fset, &fdata->fd_info);
+
+ if (rc) {
+ CERROR("presto_close: cannot journal last_rcvd\n");
+ goto out;
+ }
+ presto_trans_commit(fset, handle);
+
+ /* cancel the LML record */
+ handle = presto_trans_start(fset, inode, KML_OPCODE_WRITE);
+ if ( IS_ERR(handle) ) {
+ CERROR("presto_release: no space for clear\n");
+ return -ENOSPC;
+ }
+
+ rc = presto_clear_lml_close(fset, fdata->fd_lml_offset);
+ if (rc < 0 ) {
+ CERROR("presto_close: cannot journal close\n");
+ goto out;
+ }
+ presto_truncate_lml(fset);
+
+ out:
+ presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
+ presto_trans_commit(fset, handle);
EXIT;
- return error;
+ return rc;
}
-
int presto_do_setattr(struct presto_file_set *fset, struct dentry *dentry,
struct iattr *iattr, struct lento_vfs_context *info)
{
@@ -221,8 +366,9 @@
struct inode_operations *iops;
int error;
struct presto_version old_ver, new_ver;
+ struct izo_rollback_data rb;
void *handle;
- off_t old_size=inode->i_size;
+ loff_t old_size=inode->i_size;
ENTRY;
error = -EROFS;
@@ -237,33 +383,34 @@
}
presto_getversion(&old_ver, dentry->d_inode);
+ izo_get_rollback_data(dentry->d_inode, &rb);
error = -EPERM;
iops = filter_c2cdiops(fset->fset_cache->cache_filter);
- if (!iops &&
- !iops->setattr) {
+
+ error = presto_reserve_space(fset->fset_cache, 2*PRESTO_REQHIGH);
+ if (error) {
EXIT;
return error;
}
- error = presto_reserve_space(fset->fset_cache, 2*PRESTO_REQHIGH);
- if (error) {
- EXIT;
- return error;
- }
-
- if (iattr->ia_valid & ATTR_SIZE) {
- handle = presto_trans_start(fset, dentry->d_inode, PRESTO_OP_TRUNC);
- } else {
- handle = presto_trans_start(fset, dentry->d_inode, PRESTO_OP_SETATTR);
- }
+ if (iattr->ia_valid & ATTR_SIZE) {
+ if (izo_mark_dentry(dentry, ~PRESTO_DATA, 0, NULL) != 0)
+ CERROR("izo_mark_dentry(inode %ld, ~PRESTO_DATA) "
+ "failed\n", dentry->d_inode->i_ino);
+ handle = presto_trans_start(fset, dentry->d_inode,
+ KML_OPCODE_TRUNC);
+ } else {
+ handle = presto_trans_start(fset, dentry->d_inode,
+ KML_OPCODE_SETATTR);
+ }
if ( IS_ERR(handle) ) {
- printk("presto_do_setattr: no space for transaction\n");
- presto_release_space(fset->fset_cache, 2*PRESTO_REQHIGH);
+ CERROR("presto_do_setattr: no space for transaction\n");
+ presto_release_space(fset->fset_cache, 2*PRESTO_REQHIGH);
return -ENOSPC;
}
- if (dentry->d_inode && iops->setattr) {
+ if (dentry->d_inode && iops && iops->setattr) {
error = iops->setattr(dentry, iattr);
} else {
error = inode_change_ok(dentry->d_inode, iattr);
@@ -271,41 +418,43 @@
inode_setattr(inode, iattr);
}
- if (!error && (iattr->ia_valid & ATTR_SIZE))
- vmtruncate(inode, iattr->ia_size);
+ if (!error && (iattr->ia_valid & ATTR_SIZE))
+ vmtruncate(inode, iattr->ia_size);
if (error) {
EXIT;
goto exit;
}
- presto_debug_fail_blkdev(fset, PRESTO_OP_SETATTR | 0x10);
+ presto_debug_fail_blkdev(fset, KML_OPCODE_SETATTR | 0x10);
- if ( presto_do_kml(info, dentry->d_inode) ) {
+ if ( presto_do_kml(info, dentry) ) {
if ((iattr->ia_valid & ATTR_SIZE) && (old_size != inode->i_size)) {
- struct file file;
- /* Journal a close whenever we see a potential truncate
- * At the receiving end, lento should explicitly remove
- * ATTR_SIZE from the list of valid attributes */
- presto_getversion(&new_ver, inode);
- file.private_data = NULL;
- file.f_dentry = dentry;
- error=presto_journal_close(&rec, fset, &file, dentry, &new_ver);
- }
+ struct file file;
+ /* Journal a close whenever we see a potential truncate
+ * At the receiving end, lento should explicitly remove
+ * ATTR_SIZE from the list of valid attributes */
+ presto_getversion(&new_ver, inode);
+ file.private_data = NULL;
+ file.f_dentry = dentry;
+ error = presto_journal_close(&rec, fset, &file, dentry,
+ &old_ver, &new_ver);
+ }
- if (!error)
- error = presto_journal_setattr(&rec, fset, dentry, &old_ver, iattr);
+ if (!error)
+ error = presto_journal_setattr(&rec, fset, dentry,
+ &old_ver, &rb, iattr);
}
- presto_debug_fail_blkdev(fset, PRESTO_OP_SETATTR | 0x20);
- if ( presto_do_expect(info, dentry->d_inode) )
+ presto_debug_fail_blkdev(fset, KML_OPCODE_SETATTR | 0x20);
+ if ( presto_do_rcvd(info, dentry) )
error = presto_write_last_rcvd(&rec, fset, info);
- presto_debug_fail_blkdev(fset, PRESTO_OP_SETATTR | 0x30);
+ presto_debug_fail_blkdev(fset, KML_OPCODE_SETATTR | 0x30);
EXIT;
exit:
- presto_release_space(fset->fset_cache, 2*PRESTO_REQHIGH);
+ presto_release_space(fset->fset_cache, 2*PRESTO_REQHIGH);
presto_trans_commit(fset, handle);
return error;
}
@@ -342,7 +491,7 @@
fset = presto_fset(dentry);
error = -EINVAL;
if ( !fset ) {
- printk("No fileset!\n");
+ CERROR("No fileset!\n");
EXIT;
goto exit_lock;
}
@@ -378,6 +527,14 @@
error = presto_do_setattr(fset, dentry, iattr, info);
+ if (info->flags & LENTO_FL_SET_DDFILEID) {
+ struct presto_dentry_data *dd = presto_d2d(dentry);
+ if (dd) {
+ dd->remote_ino = info->remote_ino;
+ dd->remote_generation = info->remote_generation;
+ }
+ }
+
#ifdef CONFIG_FS_POSIX_ACL
/* restore the inode_operations if we changed them*/
if (iattr->ia_valid & ATTR_MODE)
@@ -408,12 +565,12 @@
mode |= S_IFREG;
down(&dir->d_inode->i_zombie);
- error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH);
- if (error) {
- EXIT;
- up(&dir->d_inode->i_zombie);
- return error;
- }
+ error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH);
+ if (error) {
+ EXIT;
+ up(&dir->d_inode->i_zombie);
+ return error;
+ }
error = may_create(dir->d_inode, dentry);
if (error) {
@@ -429,13 +586,13 @@
}
presto_getversion(&tgt_dir_ver, dir->d_inode);
- handle = presto_trans_start(fset, dir->d_inode, PRESTO_OP_CREATE);
+ handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_CREATE);
if ( IS_ERR(handle) ) {
EXIT;
- presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
- printk("presto_do_create: no space for transaction\n");
+ presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
+ CERROR("presto_do_create: no space for transaction\n");
error=-ENOSPC;
- goto exit_pre_lock;
+ goto exit_pre_lock;
}
DQUOT_INIT(dir->d_inode);
lock_kernel();
@@ -445,21 +602,11 @@
goto exit_lock;
}
- if (dentry->d_inode &&
- dentry->d_inode->i_gid != presto_excluded_gid) {
+ if (dentry->d_inode) {
struct presto_cache *cache = fset->fset_cache;
/* was this already done? */
- if ( !filter_c2cfiops(cache->cache_filter) )
- filter_setup_file_ops(cache->cache_filter,
- dentry->d_inode,
- &presto_file_iops,
- &presto_file_fops);
-
- /* make the new inode ours */
- dentry->d_inode->i_op =
- filter_c2ufiops(cache->cache_filter);
- dentry->d_inode->i_fop =
- filter_c2uffops(cache->cache_filter);
+ presto_set_ops(dentry->d_inode, cache->cache_filter);
+
filter_setup_dentry_ops(cache->cache_filter,
dentry->d_op,
&presto_dentry_ops);
@@ -473,37 +620,44 @@
}
}
- error = presto_settime(fset, dir, info, ATTR_CTIME | ATTR_MTIME);
- if (error) {
- EXIT;
- goto exit_lock;
- }
- error = presto_settime(fset, dentry, info, ATTR_CTIME | ATTR_MTIME);
+ info->flags |= LENTO_FL_TOUCH_PARENT;
+ error = presto_settime(fset, NULL, dir, dentry,
+ info, ATTR_CTIME | ATTR_MTIME);
if (error) {
EXIT;
goto exit_lock;
}
+ presto_debug_fail_blkdev(fset, KML_OPCODE_CREATE | 0x10);
- presto_debug_fail_blkdev(fset, PRESTO_OP_CREATE | 0x10);
- presto_getversion(&new_file_ver, dentry->d_inode);
- if ( presto_do_kml(info, dentry->d_inode) )
+ if ( presto_do_kml(info, dentry) ) {
+ presto_getversion(&new_file_ver, dentry->d_inode);
error = presto_journal_create(&rec, fset, dentry, &tgt_dir_ver,
- &new_file_ver,
+ &new_file_ver,
dentry->d_inode->i_mode);
+ }
+
+ presto_debug_fail_blkdev(fset, KML_OPCODE_CREATE | 0x20);
- presto_debug_fail_blkdev(fset, PRESTO_OP_CREATE | 0x20);
- if ( presto_do_expect(info, dentry->d_inode) )
+ if ( presto_do_rcvd(info, dentry) )
error = presto_write_last_rcvd(&rec, fset, info);
- presto_debug_fail_blkdev(fset, PRESTO_OP_CREATE | 0x30);
+ presto_debug_fail_blkdev(fset, KML_OPCODE_CREATE | 0x30);
+
+ /* add inode dentry */
+ if (fset->fset_cache->cache_filter->o_trops->tr_add_ilookup ) {
+ struct dentry *d;
+ d = fset->fset_cache->cache_filter->o_trops->tr_add_ilookup
+ (dir->d_inode->i_sb->s_root, dentry);
+ }
+
EXIT;
exit_lock:
unlock_kernel();
presto_trans_commit(fset, handle);
exit_pre_lock:
- presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
+ presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
up(&dir->d_inode->i_zombie);
return error;
}
@@ -551,9 +705,9 @@
if (path_init(pathname, LOOKUP_PARENT, &nd))
error = path_walk(pathname, &nd);
if (error) {
- EXIT;
+ EXIT;
goto exit;
- }
+ }
dentry = lookup_create(&nd, 0);
error = PTR_ERR(dentry);
if (IS_ERR(dentry)) {
@@ -564,7 +718,7 @@
fset = presto_fset(dentry);
error = -EINVAL;
if ( !fset ) {
- printk("No fileset!\n");
+ CERROR("No fileset!\n");
EXIT;
goto exit_lock;
}
@@ -575,7 +729,7 @@
exit_lock:
path_release (&nd);
- dput(dentry);
+ dput(dentry);
up(&dentry->d_parent->d_inode->i_sem);
putname(pathname);
exit:
@@ -595,12 +749,12 @@
void *handle;
down(&dir->d_inode->i_zombie);
- error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH);
- if (error) {
- EXIT;
- up(&dir->d_inode->i_zombie);
- return error;
- }
+ error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH);
+ if (error) {
+ EXIT;
+ up(&dir->d_inode->i_zombie);
+ return error;
+ }
error = -ENOENT;
inode = old_dentry->d_inode;
if (!inode)
@@ -631,10 +785,10 @@
presto_getversion(&tgt_dir_ver, dir->d_inode);
- handle = presto_trans_start(fset, dir->d_inode, PRESTO_OP_LINK);
+ handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_LINK);
if ( IS_ERR(handle) ) {
- presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
- printk("presto_do_link: no space for transaction\n");
+ presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
+ CERROR("presto_do_link: no space for transaction\n");
return -ENOSPC;
}
@@ -647,32 +801,37 @@
goto exit_lock;
}
- error = presto_settime(fset, dir, info, ATTR_CTIME | ATTR_MTIME);
- if (error) {
- EXIT;
- goto exit_lock;
- }
- error = presto_settime(fset, new_dentry, info, ATTR_CTIME);
+ /* link dd data to that of existing dentry */
+ old_dentry->d_op->d_release(new_dentry);
+ if (!presto_d2d(old_dentry))
+ BUG();
+ presto_d2d(old_dentry)->dd_count++;
+
+ new_dentry->d_fsdata = presto_d2d(old_dentry);
+
+ info->flags |= LENTO_FL_TOUCH_PARENT;
+ error = presto_settime(fset, NULL, dir, new_dentry,
+ info, ATTR_CTIME);
if (error) {
EXIT;
goto exit_lock;
}
- presto_debug_fail_blkdev(fset, PRESTO_OP_LINK | 0x10);
+ presto_debug_fail_blkdev(fset, KML_OPCODE_LINK | 0x10);
presto_getversion(&new_link_ver, new_dentry->d_inode);
- if ( presto_do_kml(info, old_dentry->d_inode) )
+ if ( presto_do_kml(info, old_dentry) )
error = presto_journal_link(&rec, fset, old_dentry, new_dentry,
&tgt_dir_ver, &new_link_ver);
- presto_debug_fail_blkdev(fset, PRESTO_OP_LINK | 0x20);
- if ( presto_do_expect(info, old_dentry->d_inode) )
+ presto_debug_fail_blkdev(fset, KML_OPCODE_LINK | 0x20);
+ if ( presto_do_rcvd(info, old_dentry) )
error = presto_write_last_rcvd(&rec, fset, info);
- presto_debug_fail_blkdev(fset, PRESTO_OP_LINK | 0x30);
+ presto_debug_fail_blkdev(fset, KML_OPCODE_LINK | 0x30);
EXIT;
presto_trans_commit(fset, handle);
exit_lock:
- presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
+ presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
up(&dir->d_inode->i_zombie);
return error;
}
@@ -714,7 +873,7 @@
fset = presto_fset(new_dentry);
error = -EINVAL;
if ( !fset ) {
- printk("No fileset!\n");
+ CERROR("No fileset!\n");
EXIT;
goto out2;
}
@@ -736,17 +895,17 @@
return error;
}
-
int presto_do_unlink(struct presto_file_set *fset, struct dentry *dir,
struct dentry *dentry, struct lento_vfs_context *info)
{
struct rec_info rec;
- int error;
struct inode_operations *iops;
struct presto_version tgt_dir_ver, old_file_ver;
+ struct izo_rollback_data rb;
void *handle;
- int do_kml = 0, do_expect =0;
- int linkno = 0;
+ int do_kml = 0, do_rcvd = 0, linkno = 0, error, old_targetlen = 0;
+ char *old_target = NULL;
+
ENTRY;
down(&dir->d_inode->i_zombie);
error = may_delete(dir->d_inode, dentry, 0);
@@ -764,19 +923,34 @@
return error;
}
- error = presto_reserve_space(fset->fset_cache, PRESTO_REQLOW);
- if (error) {
- EXIT;
- up(&dir->d_inode->i_zombie);
- return error;
- }
+ error = presto_reserve_space(fset->fset_cache, PRESTO_REQLOW);
+ if (error) {
+ EXIT;
+ up(&dir->d_inode->i_zombie);
+ return error;
+ }
+
+
+ if (presto_d2d(dentry)) {
+ struct presto_dentry_data *dd = presto_d2d(dentry);
+ struct dentry *de = dd->dd_inodentry;
+ if (de && dentry->d_inode->i_nlink == 1) {
+ dd->dd_count--;
+ dd->dd_inodentry = NULL;
+ de->d_fsdata = NULL;
+ atomic_dec(&de->d_inode->i_count);
+ de->d_inode = NULL;
+ dput(de);
+ }
+ }
presto_getversion(&tgt_dir_ver, dir->d_inode);
presto_getversion(&old_file_ver, dentry->d_inode);
- handle = presto_trans_start(fset, dir->d_inode, PRESTO_OP_UNLINK);
+ izo_get_rollback_data(dentry->d_inode, &rb);
+ handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_UNLINK);
if ( IS_ERR(handle) ) {
- presto_release_space(fset->fset_cache, PRESTO_REQLOW);
- printk("ERROR: presto_do_unlink: no space for transaction. Tell Peter.\n");
+ presto_release_space(fset->fset_cache, PRESTO_REQLOW);
+ CERROR("ERROR: presto_do_unlink: no space for transaction. Tell Peter.\n");
up(&dir->d_inode->i_zombie);
return -ENOSPC;
}
@@ -785,12 +959,45 @@
error = -EBUSY;
else {
lock_kernel();
- linkno = dentry->d_inode->i_nlink;
- if (linkno > 1) {
- dget(dentry);
- }
- do_kml = presto_do_kml(info, dir->d_inode);
- do_expect = presto_do_expect(info, dir->d_inode);
+ linkno = dentry->d_inode->i_nlink;
+ if (linkno > 1) {
+ dget(dentry);
+ }
+
+ if (S_ISLNK(dentry->d_inode->i_mode)) {
+ mm_segment_t old_fs;
+ struct inode_operations *riops;
+ riops = filter_c2csiops(fset->fset_cache->cache_filter);
+
+ PRESTO_ALLOC(old_target, PATH_MAX);
+ if (old_target == NULL) {
+ error = -ENOMEM;
+ EXIT;
+ goto exit;
+ }
+
+ old_fs = get_fs();
+ set_fs(get_ds());
+
+ if (riops->readlink == NULL)
+ CERROR("InterMezzo %s: no readlink iops.\n",
+ __FUNCTION__);
+ else
+ old_targetlen =
+ riops->readlink(dentry, old_target,
+ PATH_MAX);
+ if (old_targetlen < 0) {
+ CERROR("InterMezzo: readlink failed: %ld\n",
+ PTR_ERR(old_target));
+ PRESTO_FREE(old_target, PATH_MAX);
+ old_target = NULL;
+ old_targetlen = 0;
+ }
+ set_fs(old_fs);
+ }
+
+ do_kml = presto_do_kml(info, dir);
+ do_rcvd = presto_do_rcvd(info, dir);
error = iops->unlink(dir->d_inode, dentry);
unlock_kernel();
if (!error)
@@ -798,7 +1005,9 @@
}
if (linkno > 1) {
- error = presto_settime(fset, dentry, info, ATTR_CTIME);
+ /* FIXME: Combine this with the next call? */
+ error = presto_settime(fset, NULL, NULL, dentry,
+ info, ATTR_CTIME);
dput(dentry);
if (error) {
EXIT;
@@ -806,7 +1015,8 @@
}
}
- error = presto_settime(fset, dir, info, ATTR_CTIME | ATTR_MTIME);
+ error = presto_settime(fset, NULL, NULL, dir,
+ info, ATTR_CTIME | ATTR_MTIME);
if (error) {
EXIT;
goto exit;
@@ -818,22 +1028,22 @@
goto exit;
}
- presto_debug_fail_blkdev(fset, PRESTO_OP_UNLINK | 0x10);
- if ( do_kml ) {
+ presto_debug_fail_blkdev(fset, KML_OPCODE_UNLINK | 0x10);
+ if ( do_kml )
error = presto_journal_unlink(&rec, fset, dir, &tgt_dir_ver,
- &old_file_ver,
- dentry->d_name.len,
- dentry->d_name.name);
- }
- presto_debug_fail_blkdev(fset, PRESTO_OP_UNLINK | 0x20);
- if ( do_expect ) {
+ &old_file_ver, &rb, dentry,
+ old_target, old_targetlen);
+ presto_debug_fail_blkdev(fset, KML_OPCODE_UNLINK | 0x20);
+ if ( do_rcvd ) {
error = presto_write_last_rcvd(&rec, fset, info);
- }
- presto_debug_fail_blkdev(fset, PRESTO_OP_UNLINK | 0x30);
+ }
+ presto_debug_fail_blkdev(fset, KML_OPCODE_UNLINK | 0x30);
EXIT;
exit:
- presto_release_space(fset->fset_cache, PRESTO_REQLOW);
+ presto_release_space(fset->fset_cache, PRESTO_REQLOW);
presto_trans_commit(fset, handle);
+ if (old_target != NULL)
+ PRESTO_FREE(old_target, PATH_MAX);
return error;
}
@@ -866,7 +1076,7 @@
fset = presto_fset(dentry);
error = -EINVAL;
if ( !fset ) {
- printk("No fileset!\n");
+ CERROR("No fileset!\n");
EXIT;
goto exit2;
}
@@ -904,13 +1114,13 @@
ENTRY;
down(&dir->d_inode->i_zombie);
- /* record + max path len + space to free */
- error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH + 4096);
- if (error) {
- EXIT;
- up(&dir->d_inode->i_zombie);
- return error;
- }
+ /* record + max path len + space to free */
+ error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH + 4096);
+ if (error) {
+ EXIT;
+ up(&dir->d_inode->i_zombie);
+ return error;
+ }
error = may_create(dir->d_inode, dentry);
if (error) {
@@ -926,11 +1136,12 @@
}
presto_getversion(&tgt_dir_ver, dir->d_inode);
- handle = presto_trans_start(fset, dir->d_inode, PRESTO_OP_SYMLINK);
+ handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_SYMLINK);
if ( IS_ERR(handle) ) {
- presto_release_space(fset->fset_cache, PRESTO_REQHIGH + 4096);
- printk("ERROR: presto_do_symlink: no space for transaction. Tell Peter.\n");
+ presto_release_space(fset->fset_cache, PRESTO_REQHIGH + 4096);
+ CERROR("ERROR: presto_do_symlink: no space for transaction. Tell Peter.\n");
EXIT;
+ up(&dir->d_inode->i_zombie);
return -ENOSPC;
}
DQUOT_INIT(dir->d_inode);
@@ -941,19 +1152,11 @@
goto exit;
}
- if (dentry->d_inode &&
- dentry->d_inode->i_gid != presto_excluded_gid) {
+ if (dentry->d_inode) {
struct presto_cache *cache = fset->fset_cache;
- /* was this already done? */
- if ( !filter_c2csiops(cache->cache_filter) )
- filter_setup_symlink_ops(cache->cache_filter,
- dentry->d_inode,
- &presto_sym_iops,
- NULL);
+ presto_set_ops(dentry->d_inode, cache->cache_filter);
- /* make the new inode ours */
- dentry->d_inode->i_op = filter_c2usiops(cache->cache_filter);
filter_setup_dentry_ops(cache->cache_filter, dentry->d_op,
&presto_dentry_ops);
dentry->d_op = filter_c2udops(cache->cache_filter);
@@ -965,34 +1168,31 @@
}
}
- error = presto_settime(fset, dir, info, ATTR_CTIME | ATTR_MTIME);
- if (error) {
- EXIT;
- goto exit;
- }
- error = presto_settime(fset, dentry, info, ATTR_CTIME | ATTR_MTIME);
+ info->flags |= LENTO_FL_TOUCH_PARENT;
+ error = presto_settime(fset, NULL, dir, dentry,
+ info, ATTR_CTIME | ATTR_MTIME);
if (error) {
EXIT;
goto exit;
}
- presto_debug_fail_blkdev(fset, PRESTO_OP_SYMLINK | 0x10);
+ presto_debug_fail_blkdev(fset, KML_OPCODE_SYMLINK | 0x10);
presto_getversion(&new_link_ver, dentry->d_inode);
- if ( presto_do_kml(info, dentry->d_inode) )
+ if ( presto_do_kml(info, dentry) )
error = presto_journal_symlink(&rec, fset, dentry, oldname,
&tgt_dir_ver, &new_link_ver);
- presto_debug_fail_blkdev(fset, PRESTO_OP_SYMLINK | 0x20);
- if ( presto_do_expect(info, dentry->d_inode) )
+ presto_debug_fail_blkdev(fset, KML_OPCODE_SYMLINK | 0x20);
+ if ( presto_do_rcvd(info, dentry) )
error = presto_write_last_rcvd(&rec, fset, info);
- presto_debug_fail_blkdev(fset, PRESTO_OP_SYMLINK | 0x30);
+ presto_debug_fail_blkdev(fset, KML_OPCODE_SYMLINK | 0x30);
EXIT;
exit:
unlock_kernel();
presto_trans_commit(fset, handle);
exit_lock:
- presto_release_space(fset->fset_cache, PRESTO_REQHIGH + 4096);
+ presto_release_space(fset->fset_cache, PRESTO_REQHIGH + 4096);
up(&dir->d_inode->i_zombie);
return error;
}
@@ -1033,7 +1233,7 @@
dentry = lookup_create(&nd, 0);
error = PTR_ERR(dentry);
if (IS_ERR(dentry)) {
- path_release(&nd);
+ path_release(&nd);
EXIT;
goto exit_to;
}
@@ -1041,8 +1241,8 @@
fset = presto_fset(dentry);
error = -EINVAL;
if ( !fset ) {
- printk("No fileset!\n");
- path_release(&nd);
+ CERROR("No fileset!\n");
+ path_release(&nd);
EXIT;
goto exit_lock;
}
@@ -1073,11 +1273,12 @@
ENTRY;
down(&dir->d_inode->i_zombie);
- /* one journal record + directory block + room for removals*/
- error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH + 4096);
- if (error) {
+
+ /* one journal record + directory block + room for removals*/
+ error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH + 4096);
+ if (error) {
EXIT;
- up(&dir->d_inode->i_zombie);
+ up(&dir->d_inode->i_zombie);
return error;
}
@@ -1095,10 +1296,10 @@
error = -ENOSPC;
presto_getversion(&tgt_dir_ver, dir->d_inode);
- handle = presto_trans_start(fset, dir->d_inode, PRESTO_OP_MKDIR);
+ handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_MKDIR);
if ( IS_ERR(handle) ) {
- presto_release_space(fset->fset_cache, PRESTO_REQHIGH + 4096);
- printk("presto_do_mkdir: no space for transaction\n");
+ presto_release_space(fset->fset_cache, PRESTO_REQHIGH + 4096);
+ CERROR("presto_do_mkdir: no space for transaction\n");
goto exit_lock;
}
@@ -1111,11 +1312,11 @@
goto exit;
}
- if ( dentry->d_inode && !error &&
- dentry->d_inode->i_gid != presto_excluded_gid) {
+ if ( dentry->d_inode && !error) {
struct presto_cache *cache = fset->fset_cache;
- /* make it ours */
- dentry->d_inode->i_op = filter_c2udiops(cache->cache_filter);
+
+ presto_set_ops(dentry->d_inode, cache->cache_filter);
+
filter_setup_dentry_ops(cache->cache_filter,
dentry->d_op,
&presto_dentry_ops);
@@ -1128,35 +1329,32 @@
}
}
- error = presto_settime(fset, dir, info, ATTR_CTIME | ATTR_MTIME);
- if (error) {
- EXIT;
- goto exit;
- }
- error = presto_settime(fset, dentry, info, ATTR_CTIME | ATTR_MTIME);
+ info->flags |= LENTO_FL_TOUCH_PARENT;
+ error = presto_settime(fset, NULL, dir, dentry,
+ info, ATTR_CTIME | ATTR_MTIME);
if (error) {
EXIT;
goto exit;
}
- presto_debug_fail_blkdev(fset, PRESTO_OP_MKDIR | 0x10);
+ presto_debug_fail_blkdev(fset, KML_OPCODE_MKDIR | 0x10);
presto_getversion(&new_dir_ver, dentry->d_inode);
- if ( presto_do_kml(info, dentry->d_inode) )
+ if ( presto_do_kml(info, dir) )
error = presto_journal_mkdir(&rec, fset, dentry, &tgt_dir_ver,
- &new_dir_ver,
+ &new_dir_ver,
dentry->d_inode->i_mode);
- presto_debug_fail_blkdev(fset, PRESTO_OP_MKDIR | 0x20);
- if ( presto_do_expect(info, dentry->d_inode) )
+ presto_debug_fail_blkdev(fset, KML_OPCODE_MKDIR | 0x20);
+ if ( presto_do_rcvd(info, dentry) )
error = presto_write_last_rcvd(&rec, fset, info);
- presto_debug_fail_blkdev(fset, PRESTO_OP_MKDIR | 0x30);
+ presto_debug_fail_blkdev(fset, KML_OPCODE_MKDIR | 0x30);
EXIT;
exit:
unlock_kernel();
presto_trans_commit(fset, handle);
exit_lock:
- presto_release_space(fset->fset_cache, PRESTO_REQHIGH + 4096);
+ presto_release_space(fset->fset_cache, PRESTO_REQHIGH + 4096);
up(&dir->d_inode->i_zombie);
return error;
}
@@ -1193,8 +1391,8 @@
if (!IS_ERR(dentry)) {
fset = presto_fset(dentry);
error = -EINVAL;
- if ( !fset ) {
- printk("No fileset!\n");
+ if (!fset) {
+ CERROR("No fileset!\n");
EXIT;
goto out_dput;
}
@@ -1202,14 +1400,14 @@
error = presto_do_mkdir(fset, nd.dentry, dentry,
mode & S_IALLUGO, info);
out_dput:
- dput(dentry);
+ dput(dentry);
}
- up(&nd.dentry->d_inode->i_sem);
- path_release(&nd);
+ up(&nd.dentry->d_inode->i_sem);
+ path_release(&nd);
out_name:
EXIT;
putname(pathname);
- CDEBUG(D_PIOCTL, "error: %d\n", error);
+ CDEBUG(D_PIOCTL, "error: %d\n", error);
return error;
}
@@ -1232,10 +1430,11 @@
struct rec_info rec;
int error;
struct presto_version tgt_dir_ver, old_dir_ver;
+ struct izo_rollback_data rb;
struct inode_operations *iops;
void *handle;
- int do_kml, do_expect;
- int size;
+ int do_kml, do_rcvd;
+ int size;
ENTRY;
error = may_delete(dir->d_inode, dentry, 1);
@@ -1249,64 +1448,67 @@
return error;
}
- size = PRESTO_REQHIGH - dentry->d_inode->i_size;
- error = presto_reserve_space(fset->fset_cache, size);
- if (error) {
- EXIT;
- return error;
- }
+ size = PRESTO_REQHIGH - dentry->d_inode->i_size;
+ error = presto_reserve_space(fset->fset_cache, size);
+ if (error) {
+ EXIT;
+ return error;
+ }
presto_getversion(&tgt_dir_ver, dir->d_inode);
presto_getversion(&old_dir_ver, dentry->d_inode);
- handle = presto_trans_start(fset, dir->d_inode, PRESTO_OP_RMDIR);
+ izo_get_rollback_data(dentry->d_inode, &rb);
+ handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_RMDIR);
if ( IS_ERR(handle) ) {
- presto_release_space(fset->fset_cache, size);
- printk("ERROR: presto_do_rmdir: no space for transaction. Tell Peter.\n");
+ presto_release_space(fset->fset_cache, size);
+ CERROR("ERROR: presto_do_rmdir: no space for transaction. Tell Peter.\n");
return -ENOSPC;
}
DQUOT_INIT(dir->d_inode);
- do_kml = presto_do_kml(info, dir->d_inode);
- do_expect = presto_do_expect(info, dir->d_inode);
+ do_kml = presto_do_kml(info, dir);
+ do_rcvd = presto_do_rcvd(info, dir);
double_down(&dir->d_inode->i_zombie, &dentry->d_inode->i_zombie);
d_unhash(dentry);
if (IS_DEADDIR(dir->d_inode))
error = -ENOENT;
- else if (d_mountpoint(dentry))
+ else if (d_mountpoint(dentry)) {
+ CERROR("foo: d_mountpoint(dentry): ino %ld\n",
+ dentry->d_inode->i_ino);
error = -EBUSY;
- else {
+ } else {
lock_kernel();
error = iops->rmdir(dir->d_inode, dentry);
unlock_kernel();
if (!error) {
dentry->d_inode->i_flags |= S_DEAD;
- error = presto_settime(fset, dir, info,
- ATTR_CTIME | ATTR_MTIME);
- }
+ error = presto_settime(fset, NULL, NULL, dir, info,
+ ATTR_CTIME | ATTR_MTIME);
+ }
}
double_up(&dir->d_inode->i_zombie, &dentry->d_inode->i_zombie);
if (!error)
d_delete(dentry);
dput(dentry);
- presto_debug_fail_blkdev(fset, PRESTO_OP_RMDIR | 0x10);
+ presto_debug_fail_blkdev(fset, KML_OPCODE_RMDIR | 0x10);
if ( !error && do_kml )
error = presto_journal_rmdir(&rec, fset, dir, &tgt_dir_ver,
- &old_dir_ver,
+ &old_dir_ver, &rb,
dentry->d_name.len,
dentry->d_name.name);
- presto_debug_fail_blkdev(fset, PRESTO_OP_RMDIR | 0x20);
- if ( !error && do_expect )
+ presto_debug_fail_blkdev(fset, KML_OPCODE_RMDIR | 0x20);
+ if ( !error && do_rcvd )
error = presto_write_last_rcvd(&rec, fset, info);
- presto_debug_fail_blkdev(fset, PRESTO_OP_RMDIR | 0x30);
+ presto_debug_fail_blkdev(fset, KML_OPCODE_RMDIR | 0x30);
EXIT;
presto_trans_commit(fset, handle);
- presto_release_space(fset->fset_cache, size);
+ presto_release_space(fset->fset_cache, size);
return error;
}
@@ -1320,21 +1522,27 @@
ENTRY;
name = getname(pathname);
- if(IS_ERR(name))
+ if(IS_ERR(name)) {
+ EXIT;
return PTR_ERR(name);
+ }
if (path_init(name, LOOKUP_PARENT, &nd))
error = path_walk(name, &nd);
- if (error)
+ if (error) {
+ EXIT;
goto exit;
-
+ }
switch(nd.last_type) {
- case LAST_DOTDOT:
- error = -ENOTEMPTY;
- goto exit1;
- case LAST_ROOT: case LAST_DOT:
- error = -EBUSY;
- goto exit1;
+ case LAST_DOTDOT:
+ error = -ENOTEMPTY;
+ EXIT;
+ goto exit1;
+ case LAST_ROOT:
+ case LAST_DOT:
+ error = -EBUSY;
+ EXIT;
+ goto exit1;
}
down(&nd.dentry->d_inode->i_sem);
dentry = lookup_hash(&nd.last, nd.dentry);
@@ -1343,7 +1551,7 @@
fset = presto_fset(dentry);
error = -EINVAL;
if ( !fset ) {
- printk("No fileset!\n");
+ CERROR("No fileset!\n");
EXIT;
goto exit_put;
}
@@ -1353,11 +1561,10 @@
}
up(&nd.dentry->d_inode->i_sem);
exit1:
- EXIT;
path_release(&nd);
exit:
- EXIT;
putname(name);
+ EXIT;
return error;
}
@@ -1374,13 +1581,13 @@
ENTRY;
down(&dir->d_inode->i_zombie);
- /* one KML entry */
- error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH);
- if (error) {
- EXIT;
- up(&dir->d_inode->i_zombie);
- return error;
- }
+ /* one KML entry */
+ error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH);
+ if (error) {
+ EXIT;
+ up(&dir->d_inode->i_zombie);
+ return error;
+ }
if ((S_ISCHR(mode) || S_ISBLK(mode)) && !capable(CAP_MKNOD)) {
EXIT;
@@ -1405,10 +1612,10 @@
error = -ENOSPC;
presto_getversion(&tgt_dir_ver, dir->d_inode);
- handle = presto_trans_start(fset, dir->d_inode, PRESTO_OP_MKNOD);
+ handle = presto_trans_start(fset, dir->d_inode, KML_OPCODE_MKNOD);
if ( IS_ERR(handle) ) {
- presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
- printk("presto_do_mknod: no space for transaction\n");
+ presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
+ CERROR("presto_do_mknod: no space for transaction\n");
goto exit_lock2;
}
@@ -1417,11 +1624,11 @@
EXIT;
goto exit_commit;
}
- if ( dentry->d_inode &&
- dentry->d_inode->i_gid != presto_excluded_gid) {
+ if ( dentry->d_inode) {
struct presto_cache *cache = fset->fset_cache;
- /* make it ours */
- dentry->d_inode->i_op = filter_c2udiops(cache->cache_filter);
+
+ presto_set_ops(dentry->d_inode, cache->cache_filter);
+
filter_setup_dentry_ops(cache->cache_filter, dentry->d_op,
&presto_dentry_ops);
dentry->d_op = filter_c2udops(cache->cache_filter);
@@ -1434,35 +1641,37 @@
}
}
- error = presto_settime(fset, dir, info, ATTR_MTIME);
+ error = presto_settime(fset, NULL, NULL, dir,
+ info, ATTR_MTIME);
if (error) {
EXIT;
}
- error = presto_settime(fset, dentry, info, ATTR_CTIME | ATTR_MTIME);
+ error = presto_settime(fset, NULL, NULL, dentry,
+ info, ATTR_CTIME | ATTR_MTIME);
if (error) {
EXIT;
}
- presto_debug_fail_blkdev(fset, PRESTO_OP_MKNOD | 0x10);
+ presto_debug_fail_blkdev(fset, KML_OPCODE_MKNOD | 0x10);
presto_getversion(&new_node_ver, dentry->d_inode);
- if ( presto_do_kml(info, dentry->d_inode) )
+ if ( presto_do_kml(info, dentry) )
error = presto_journal_mknod(&rec, fset, dentry, &tgt_dir_ver,
- &new_node_ver,
+ &new_node_ver,
dentry->d_inode->i_mode,
MAJOR(dev), MINOR(dev) );
- presto_debug_fail_blkdev(fset, PRESTO_OP_MKNOD | 0x20);
- if ( presto_do_expect(info, dentry->d_inode) )
+ presto_debug_fail_blkdev(fset, KML_OPCODE_MKNOD | 0x20);
+ if ( presto_do_rcvd(info, dentry) )
error = presto_write_last_rcvd(&rec, fset, info);
- presto_debug_fail_blkdev(fset, PRESTO_OP_MKNOD | 0x30);
+ presto_debug_fail_blkdev(fset, KML_OPCODE_MKNOD | 0x30);
EXIT;
exit_commit:
presto_trans_commit(fset, handle);
exit_lock2:
unlock_kernel();
exit_lock:
- presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
+ presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
up(&dir->d_inode->i_zombie);
return error;
}
@@ -1494,7 +1703,7 @@
fset = presto_fset(dentry);
error = -EINVAL;
if ( !fset ) {
- printk("No fileset!\n");
+ CERROR("No fileset!\n");
EXIT;
goto exit_put;
}
@@ -1523,7 +1732,7 @@
return error;
}
-static int do_rename(struct presto_file_set *fset,
+int 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)
@@ -1533,7 +1742,7 @@
struct inode_operations *iops;
struct presto_version src_dir_ver, tgt_dir_ver;
void *handle;
- int new_inode_unlink = 0;
+ int new_inode_unlink = 0;
struct inode *old_dir = old_parent->d_inode;
struct inode *new_dir = new_parent->d_inode;
@@ -1548,15 +1757,15 @@
return error;
}
- error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH);
- if (error) {
- EXIT;
- return error;
- }
- handle = presto_trans_start(fset, old_dir, PRESTO_OP_RENAME);
+ error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH);
+ if (error) {
+ EXIT;
+ return error;
+ }
+ handle = presto_trans_start(fset, old_dir, KML_OPCODE_RENAME);
if ( IS_ERR(handle) ) {
- presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
- printk("presto_do_rename: no space for transaction\n");
+ presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
+ CERROR("presto_do_rename: no space for transaction\n");
return -ENOSPC;
}
if (new_dentry->d_inode && new_dentry->d_inode->i_nlink > 1) {
@@ -1572,19 +1781,17 @@
}
if (new_inode_unlink) {
- error = presto_settime(fset, old_dentry, info, ATTR_CTIME);
+ error = presto_settime(fset, NULL, NULL, old_dentry,
+ info, ATTR_CTIME);
dput(old_dentry);
if (error) {
EXIT;
goto exit;
}
}
- error = presto_settime(fset, old_parent, info, ATTR_CTIME | ATTR_MTIME);
- if (error) {
- EXIT;
- goto exit;
- }
- error = presto_settime(fset, new_parent, info, ATTR_CTIME | ATTR_MTIME);
+ info->flags |= LENTO_FL_TOUCH_PARENT;
+ error = presto_settime(fset, NULL, new_parent, old_parent,
+ info, ATTR_CTIME | ATTR_MTIME);
if (error) {
EXIT;
goto exit;
@@ -1593,21 +1800,22 @@
/* XXX make a distinction between cross file set
* and intra file set renames here
*/
- presto_debug_fail_blkdev(fset, PRESTO_OP_RENAME | 0x10);
- if ( presto_do_kml(info, old_dir) )
- error = presto_journal_rename(&rec, fset, old_dentry, new_dentry,
+ presto_debug_fail_blkdev(fset, KML_OPCODE_RENAME | 0x10);
+ if ( presto_do_kml(info, old_dentry) )
+ error = presto_journal_rename(&rec, fset, old_dentry,
+ new_dentry,
&src_dir_ver, &tgt_dir_ver);
- presto_debug_fail_blkdev(fset, PRESTO_OP_RENAME | 0x20);
+ presto_debug_fail_blkdev(fset, KML_OPCODE_RENAME | 0x20);
- if ( presto_do_expect(info, new_dir) )
+ if ( presto_do_rcvd(info, old_dentry) )
error = presto_write_last_rcvd(&rec, fset, info);
- presto_debug_fail_blkdev(fset, PRESTO_OP_RENAME | 0x30);
+ presto_debug_fail_blkdev(fset, KML_OPCODE_RENAME | 0x30);
EXIT;
exit:
presto_trans_commit(fset, handle);
- presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
+ presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
return error;
}
@@ -1729,7 +1937,7 @@
error = -EBUSY;
else
error = do_rename(fset, old_parent, old_dentry,
- new_parent, new_dentry, info);
+ new_parent, new_dentry, info);
double_up(&old_dir->i_zombie, &new_dir->i_zombie);
if (error)
return error;
@@ -1802,7 +2010,7 @@
fset = presto_fset(old_dentry);
error = -EINVAL;
if ( !fset ) {
- printk("No fileset!\n");
+ CERROR("No fileset!\n");
EXIT;
goto exit4;
}
@@ -1852,7 +2060,7 @@
if (!IS_ERR(to)) {
error = lento_do_rename(from,to, info);
putname(to);
- }
+ }
putname(from);
return error;
}
@@ -1879,7 +2087,7 @@
fset = presto_fset(dentry);
error = -EINVAL;
if (!fset) {
- printk("No fileset for %*s!\n",
+ CERROR("No fileset for %*s!\n",
dentry->d_name.len, dentry->d_name.name);
EXIT;
dput(dentry);
@@ -1890,7 +2098,7 @@
sprintf(name, "%s%#lx%c%#x",
PRESTO_ILOOKUP_MAGIC, ino, PRESTO_ILOOKUP_SEP, generation);
CDEBUG(D_PIOCTL, "opening %ld by number (as %s)\n", ino, name);
- return lookup_one_len(name, fset->fset_mtpt, strlen(name));
+ return lookup_one_len(name, fset->fset_dentry, strlen(name));
}
static struct file *presto_filp_dopen(struct dentry *dentry, int flags)
@@ -1914,8 +2122,7 @@
error = get_write_access(inode);
if (error) {
CDEBUG(D_PIOCTL, "error getting write access\n");
- EXIT;
- goto cleanup_file;
+ EXIT; goto cleanup_file;
}
}
@@ -1969,8 +2176,8 @@
* just turn off the flag and ignore it.
*/
if (flags & O_CREAT) {
- printk(KERN_WARNING "%s: create file by inode number (%ld) not allowed\n",
- __FUNCTION__, ino);
+ CERROR("%s: create file by inode number (%ld) not allowed\n",
+ __FUNCTION__, ino);
EXIT;
return -EACCES;
}
@@ -1986,6 +2193,7 @@
error = presto_walk(tmp, &nd);
if ( error && error != -ENOENT ) {
EXIT;
+ unlock_kernel();
return error;
}
if (error == -ENOENT)
@@ -2000,7 +2208,7 @@
slash = strrchr(tmp, '/');
if (slash && slash != tmp) {
*slash = '\0';
- path_release(&nd);
+ path_release(&nd);
goto again;
}
/* we should never get here... */
@@ -2052,7 +2260,7 @@
EXIT;
exit:
unlock_kernel();
- path_release(&nd);
+ path_release(&nd);
putname(tmp);
return fd;
@@ -2061,72 +2269,6 @@
goto exit;
}
-int lento_close(unsigned int fd, struct lento_vfs_context *info)
-{
- struct rec_info rec;
- int error;
- struct file * filp;
- struct dentry *dentry;
- int do_kml, do_expect;
-
- ENTRY;
- lock_kernel();
-
- error = -EBADF;
- filp = fcheck(fd);
- if (filp) {
-
- struct files_struct * files = current->files;
- dentry = filp->f_dentry;
- dget(dentry);
- do_kml = presto_do_kml(info, dentry->d_inode);
- do_expect = presto_do_expect(info, dentry->d_inode);
- files->fd[fd] = NULL;
- put_unused_fd(fd);
- FD_CLR(fd, files->close_on_exec);
- error = filp_close(filp, files);
- } else {
- EXIT;
- return error;
- }
-
- if (error) {
- EXIT;
- goto exit;
- }
-
- if ( do_kml ) {
- struct presto_file_set *fset;
- struct presto_version new_file_ver;
-
- fset = presto_fset(dentry);
- error = -EINVAL;
- if (!fset) {
- printk("No fileset for %*s!\n",
- dentry->d_name.len, dentry->d_name.name);
- EXIT;
- goto exit;
- }
- presto_getversion(&new_file_ver, dentry->d_inode);
- error = presto_journal_close(&rec, fset, filp, dentry,
- &new_file_ver);
- if ( error ) {
- printk("presto: close error %d!\n", error);
- EXIT;
- goto exit;
- }
- if ( do_expect )
-
- error = presto_write_last_rcvd(&rec, fset, info);
- }
-
- EXIT;
-exit:
- dput(dentry);
- unlock_kernel();
- return error;
-}
-
#ifdef CONFIG_FS_EXT_ATTR
#ifdef CONFIG_FS_POSIX_ACL
@@ -2254,9 +2396,9 @@
}
- handle = presto_trans_start(fset,dentry->d_inode,PRESTO_OP_SETEXTATTR);
+ handle = presto_trans_start(fset,dentry->d_inode,KML_OPCODE_SETEXTATTR);
if ( IS_ERR(handle) ) {
- printk("presto_do_set_ext_attr: no space for transaction\n");
+ CERROR("presto_do_set_ext_attr: no space for transaction\n");
presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
return -ENOSPC;
}
@@ -2285,15 +2427,15 @@
#endif
/* Reset ctime. Only inode change time (ctime) is affected */
- error = presto_settime(fset, dentry, info, ATTR_CTIME);
+ error = presto_settime(fset, NULL, NULL, dentry, info, ATTR_CTIME);
if (error) {
EXIT;
goto exit;
}
if (flags & EXT_ATTR_FLAG_USER) {
- printk(" USER flag passed to presto_do_set_ext_attr!\n");
- *(int *)0 = 1;
+ CERROR(" USER flag passed to presto_do_set_ext_attr!\n");
+ BUG();
}
/* We are here, so set_ext_attr succeeded. We no longer need to keep
@@ -2302,17 +2444,17 @@
*/
flags &= ~(EXT_ATTR_FLAG_EXISTS | EXT_ATTR_FLAG_CREATE);
- presto_debug_fail_blkdev(fset, PRESTO_OP_SETEXTATTR | 0x10);
- if ( presto_do_kml(info, dentry->d_inode) )
+ presto_debug_fail_blkdev(fset, KML_OPCODE_SETEXTATTR | 0x10);
+ if ( presto_do_kml(info, dentry) )
error = presto_journal_set_ext_attr
(&rec, fset, dentry, &ver, name, buffer,
buffer_len, flags);
- presto_debug_fail_blkdev(fset, PRESTO_OP_SETEXTATTR | 0x20);
- if ( presto_do_expect(info, dentry->d_inode) )
+ presto_debug_fail_blkdev(fset, KML_OPCODE_SETEXTATTR | 0x20);
+ if ( presto_do_rcvd(info, dentry) )
error = presto_write_last_rcvd(&rec, fset, info);
- presto_debug_fail_blkdev(fset, PRESTO_OP_SETEXTATTR | 0x30);
+ presto_debug_fail_blkdev(fset, KML_OPCODE_SETEXTATTR | 0x30);
EXIT;
exit:
presto_release_space(fset->fset_cache, PRESTO_REQHIGH);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)