to setattr everywhere -- dbench 50 completes, so does bonnie++.
UnlockPage(page);
ext2_put_page(page);
dir->i_mtime = dir->i_ctime = CURRENT_TIME;
- mark_inode_dirty(dir);
+ obdfs_change_inode(dir);
}
/*
ext2_set_de_type (de, inode);
err = ext2_commit_chunk(page, from, to);
dir->i_mtime = dir->i_ctime = CURRENT_TIME;
- mark_inode_dirty(dir);
+ obdfs_change_inode(dir);
/* OFFSET_CACHE */
out_unlock:
UnlockPage(page);
UnlockPage(page);
ext2_put_page(page);
inode->i_ctime = inode->i_mtime = CURRENT_TIME;
- mark_inode_dirty(inode);
+ obdfs_change_inode(inode);
return err;
}
#include <linux/obd_support.h>
#include <linux/obdfs.h>
+void obdfs_change_inode(struct inode *inode);
+
static inline void obdfs_remove_suid(struct inode *inode)
{
unsigned int mode;
mode &= inode->i_mode;
if (mode && !capable(CAP_FSETID)) {
inode->i_mode &= ~mode;
- mark_inode_dirty(inode);
+ obdfs_change_inode(inode);
}
}
struct inode *inode = file->f_dentry->d_inode;
obdfs_remove_suid(inode);
inode->i_ctime = inode->i_mtime = CURRENT_TIME;
- mark_inode_dirty(inode);
+ obdfs_change_inode(inode);
}
EXIT;
return retval;
mmap: generic_file_mmap, /* mmap */
};
-extern int obdfs_notify_change(struct dentry *de, struct iattr *attr);
+extern int obdfs_setattr(struct dentry *de, struct iattr *attr);
struct inode_operations obdfs_file_inode_operations = {
truncate: obdfs_truncate,
- setattr: obdfs_notify_change
+ setattr: obdfs_setattr
};
#include <linux/obdfs.h>
extern struct address_space_operations obdfs_aops;
+/* from super.c */
+extern void obdfs_change_inode(struct inode *inode);
+extern int obdfs_setattr(struct dentry *de, struct iattr *attr);
+
/* from dir.c */
extern int ext2_add_link (struct dentry *dentry, struct inode *inode);
extern ino_t ext2_inode_by_name(struct inode * dir, struct dentry *dentry);
static inline void ext2_inc_count(struct inode *inode)
{
inode->i_nlink++;
- mark_inode_dirty(inode);
+ obdfs_change_inode(inode);
}
static inline void ext2_dec_count(struct inode *inode)
{
inode->i_nlink--;
- mark_inode_dirty(inode);
+ obdfs_change_inode(inode);
}
static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode)
err = IOPS(dir, create)(IID(dir), oa);
if ( err ) {
- CDEBUG(D_INODE, "fatal: creating new inode (err %d)\n", err);
+ printk("new_inode - fatal: err %d\n", err);
obdo_free(oa);
EXIT;
return ERR_PTR(err);
inode = iget(dir->i_sb, (ino_t)oa->o_id);
if (!inode) {
- CDEBUG(D_INODE, "fatal: get new inode %ld\n", (long)oa->o_id);
+ printk("new_inode -fatal: %ld\n", (long)oa->o_id);
IOPS(dir, destroy)(IID(dir), oa);
obdo_free(oa);
EXIT;
}
if (!list_empty(&inode->i_dentry)) {
- CDEBUG(D_INODE, "New inode (%ld) has aliases!\n", inode->i_ino);
+ printk("new_inode -fatal: aliases %ld, ct %d lnk %d\n", (long)oa->o_id,
+ atomic_read(&inode->i_count), inode->i_nlink);
IOPS(dir, destroy)(IID(dir), oa);
obdo_free(oa);
iput(inode);
inode->i_op = &obdfs_file_inode_operations;
inode->i_fop = &obdfs_file_operations;
inode->i_mapping->a_ops = &obdfs_aops;
- mark_inode_dirty(inode);
+ obdfs_change_inode(inode);
err = ext2_add_nondir(dentry, inode);
}
return err;
int err = PTR_ERR(inode);
if (!IS_ERR(inode)) {
init_special_inode(inode, mode, rdev);
- mark_inode_dirty(inode);
+ obdfs_change_inode(inode);
err = ext2_add_nondir(dentry, inode);
}
return err;
memcpy(oinfo->oi_inline, symname, l);
inode->i_size = l-1;
}
- mark_inode_dirty(inode);
+ obdfs_change_inode(inode);
err = ext2_add_nondir(dentry, inode);
out:
rmdir: obdfs_rmdir,
mknod: obdfs_mknod,
rename: obdfs_rename,
+ setattr: obdfs_setattr
};
#include <linux/obd_ext2.h>
#include <linux/obdfs.h>
+void obdfs_change_inode(struct inode *inode);
/* SYNCHRONOUS I/O for an inode */
static int obdfs_brw(int rw, struct inode *inode, struct page *page, int create)
kunmap(page);
if (pos > inode->i_size) {
inode->i_size = pos;
- mark_inode_dirty(inode);
+ obdfs_change_inode(inode);
}
return 0;
}
return;
}
-static void obdfs_write_inode(struct inode *inode, int wait)
+void obdfs_change_inode(struct inode *inode)
{
struct obdo *oa;
int err;
oa->o_valid = OBD_MD_FLNOTOBD;
obdfs_from_inode(oa, inode);
+ /* XXX how do we know that this inode is now clean? */
+ printk("delete_inode ------> link %d\n", inode->i_nlink);
ODEBUG(oa);
err = IOPS(inode, destroy)(IID(inode), oa);
obdo_free(oa);
} /* obdfs_delete_inode */
-int obdfs_notify_change(struct dentry *de, struct iattr *attr)
+
+int inode_copy_attr(struct inode * inode, struct iattr * attr)
+{
+ unsigned int ia_valid = attr->ia_valid;
+ int error = 0;
+
+ if (ia_valid & ATTR_SIZE) {
+ error = vmtruncate(inode, attr->ia_size);
+ if (error)
+ goto out;
+ }
+
+ if (ia_valid & ATTR_UID)
+ inode->i_uid = attr->ia_uid;
+ if (ia_valid & ATTR_GID)
+ inode->i_gid = attr->ia_gid;
+ if (ia_valid & ATTR_ATIME)
+ inode->i_atime = attr->ia_atime;
+ if (ia_valid & ATTR_MTIME)
+ inode->i_mtime = attr->ia_mtime;
+ if (ia_valid & ATTR_CTIME)
+ inode->i_ctime = attr->ia_ctime;
+ if (ia_valid & ATTR_MODE) {
+ inode->i_mode = attr->ia_mode;
+ if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
+ inode->i_mode &= ~S_ISGID;
+ }
+out:
+ return error;
+}
+
+int obdfs_setattr(struct dentry *de, struct iattr *attr)
{
struct inode *inode = de->d_inode;
struct obdo *oa;
return -ENOMEM;
}
- inode_setattr(inode, attr);
+ inode_copy_attr(inode, attr);
oa->o_id = inode->i_ino;
obdo_from_iattr(oa, attr);
err = IOPS(inode, setattr)(IID(inode), oa);
EXIT;
obdo_free(oa);
return err;
-} /* obdfs_notify_change */
+} /* obdfs_setattr */
static int obdfs_statfs(struct super_block *sb, struct statfs *buf)
struct super_operations obdfs_super_operations =
{
read_inode: obdfs_read_inode,
- write_inode: obdfs_write_inode,
put_inode: obdfs_put_inode,
delete_inode: obdfs_delete_inode,
put_super: obdfs_put_super,
return vfs_follow_link(nd, s);
}
+extern int obdfs_setattr(struct dentry *de, struct iattr *attr);
struct inode_operations obdfs_fast_symlink_inode_operations = {
readlink: obdfs_fast_readlink,
follow_link: obdfs_fast_follow_link,
+ setattr: obdfs_setattr
};
static int obdfs_readlink(struct dentry *dentry, char *buffer, int buflen)
struct inode_operations obdfs_symlink_inode_operations = {
readlink: obdfs_readlink,
follow_link: obdfs_follow_link,
+ setattr: obdfs_setattr
};