if (!err) {
- file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
+ file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it);
-+ intent_release(&it);
++ intent_release(&it);
if (!IS_ERR(file)) {
err = deny_write_access(file);
if (err) {
return file;
}
}
-+ intent_release(&it);
++ intent_release(&it);
path_release(&nd);
}
goto out;
{
old_nd->dentry = mnt->mnt_mountpoint;
old_nd->mnt = mnt->mnt_parent;
-+ UNPIN(old_nd->dentry, old_nd->mnt, 1);
++ UNPIN(old_nd->dentry, old_nd->mnt, 1);
mnt->mnt_parent = mnt;
mnt->mnt_mountpoint = mnt->mnt_root;
list_del_init(&mnt->mnt_child);
{
mnt->mnt_parent = mntget(nd->mnt);
mnt->mnt_mountpoint = dget(nd->dentry);
-+ PIN(nd->dentry, nd->mnt, 1);
++ PIN(nd->dentry, nd->mnt, 1);
list_add(&mnt->mnt_hash, mount_hashtable+hash(nd->mnt, nd->dentry));
list_add(&mnt->mnt_child, &nd->mnt->mnt_mounts);
nd->dentry->d_mounted++;
{
struct nameidata old_nd;
struct vfsmount *mnt = NULL;
-+ struct lookup_intent it = { .it_op = IT_GETATTR };
++ struct lookup_intent it = { .it_op = IT_GETATTR };
int err = mount_is_safe(nd);
if (err)
return err;
- err = path_lookup(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd);
- if (err)
+ err = path_lookup_it(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd, &it);
-+ if (err) {
-+ intent_release(&it);
++ if (err) {
++ intent_release(&it);
return err;
-+ }
++ }
down_write(¤t->namespace->sem);
err = -EINVAL;
}
up_write(¤t->namespace->sem);
-+ intent_release(&it);
++ intent_release(&it);
path_release(&old_nd);
return err;
}
{
struct nameidata nd;
- int retval = 0;
-+ struct lookup_intent it = { .it_op = IT_GETATTR };
-+ int retval = 0;
++ struct lookup_intent it = { .it_op = IT_GETATTR };
++ int retval = 0;
int mnt_flags = 0;
/* Discard magic */
- retval = path_lookup(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd);
- if (retval)
+ retval = path_lookup_it(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd, &it);
-+ if (retval) {
-+ intent_release(&it);
++ if (retval) {
++ intent_release(&it);
return retval;
-
-+ }
++ }
if (flags & MS_REMOUNT)
retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
data_page);
retval = do_add_mount(&nd, type_page, flags, mnt_flags,
dev_name, data_page);
+
-+ intent_release(&it);
++ intent_release(&it);
path_release(&nd);
return retval;
}
{
struct vfsmount *tmp;
struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd;
-+ struct lookup_intent new_it = { .it_op = IT_GETATTR };
-+ struct lookup_intent old_it = { .it_op = IT_GETATTR };
++ struct lookup_intent new_it = { .it_op = IT_GETATTR };
++ struct lookup_intent old_it = { .it_op = IT_GETATTR };
int error;
if (!capable(CAP_SYS_ADMIN))
up(&old_nd.dentry->d_inode->i_zombie);
up_write(¤t->namespace->sem);
path_release(&user_nd);
-+ intent_release(&old_it);
++ intent_release(&old_it);
path_release(&old_nd);
out1:
-+ intent_release(&new_it);
++ intent_release(&new_it);
path_release(&new_nd);
out0:
unlock_kernel();
+ err = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
+ else
+ err = dentry->d_inode->i_op->follow_link(dentry, nd);
-+ if (!err && it != NULL && !(it->it_int_flags & IT_FL_FOLLOWED)) {
-+ /* vfs_follow_link was never called */
++ if (!err && it != NULL && !(it->it_int_flags & IT_FL_FOLLOWED)) {
++ /* vfs_follow_link was never called */
+ intent_release(it);
-+ path_release(nd);
-+ err = -ENOLINK;
-+ }
++ path_release(nd);
++ err = -ENOLINK;
++ }
current->link_count--;
return err;
loop:
*/
dentry = nd->dentry;
- if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
-+ revalidate_again:
++ revalidate_again:
+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) {
+ err = -ESTALE;
+ if (!dentry->d_op->d_revalidate_it(dentry, 0, it)) {
-+ struct dentry *new;
-+ err = permission(dentry->d_parent->d_inode,
-+ MAY_EXEC);
-+ if (err)
-+ break;
-+ new = real_lookup(dentry->d_parent,
-+ &dentry->d_name, 0, NULL);
++ struct dentry *new;
++ err = permission(dentry->d_parent->d_inode,
++ MAY_EXEC);
++ if (err)
++ break;
++ new = real_lookup(dentry->d_parent,
++ &dentry->d_name, 0, NULL);
+ d_invalidate(dentry);
-+ dput(dentry);
-+ dentry = new;
-+ goto revalidate_again;
++ dput(dentry);
++ dentry = new;
++ goto revalidate_again;
+ }
-+ }
-+ else if (dentry && dentry->d_op && dentry->d_op->d_revalidate){
++ }
++ else if (dentry && dentry->d_op && dentry->d_op->d_revalidate){
err = -ESTALE;
if (!dentry->d_op->d_revalidate(dentry, 0)) {
d_invalidate(dentry);
return retval;
}
-+static int vfs_create_it(struct inode *dir, struct dentry *dentry, int mode,
-+ struct lookup_intent *it)
++static int vfs_create_it(struct inode *dir, struct dentry *dentry, int mode,
++ struct lookup_intent *it)
+{
+ int error;
+
+
+ DQUOT_INIT(dir);
+ lock_kernel();
-+ if (dir->i_op->create_it)
-+ error = dir->i_op->create_it(dir, dentry, mode, it);
-+ else
-+ error = dir->i_op->create(dir, dentry, mode);
++ if (dir->i_op->create_it)
++ error = dir->i_op->create_it(dir, dentry, mode, it);
++ else
++ error = dir->i_op->create(dir, dentry, mode);
+ unlock_kernel();
+exit_lock:
+ up(&dir->i_zombie);
DQUOT_INIT(dir);
lock_kernel();
- error = dir->i_op->create(dir, dentry, mode);
-+ error = dir->i_op->create(dir, dentry, mode);
++ error = dir->i_op->create(dir, dentry, mode);
unlock_kernel();
exit_lock:
up(&dir->i_zombie);
+extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
+ int flags, struct lookup_intent *it);
+
-+struct file *filp_open(const char * pathname, int open_flags, int mode)
++struct file *filp_open(const char * pathname, int open_flags, int mode)
{
int acc_mode, error = 0;
- struct inode *inode;
UPDATE_ATIME(dentry->d_inode);
- error = dentry->d_inode->i_op->follow_link(dentry, &nd);
+ nd.it = ⁢
-+ error = dentry->d_inode->i_op->follow_link(dentry, &nd);
++ error = dentry->d_inode->i_op->follow_link(dentry, &nd);
+ if (error) {
+ intent_release(&it);
+ } else if (!(it.it_int_flags & IT_FL_FOLLOWED)) {
}
+ if (nd.dentry->d_inode->i_op->rmdir_raw) {
+ struct inode_operations *op = nd.dentry->d_inode->i_op;
-+
++
+ error = op->rmdir_raw(&nd);
+ /* the file system wants to use normal vfs path now */
+ if (error != -EOPNOTSUPP)
if (old_nd.mnt != nd.mnt)
goto out_release;
- new_dentry = lookup_create(&nd, 0);
-+ if (nd.dentry->d_inode->i_op->link_raw) {
-+ struct inode_operations *op = nd.dentry->d_inode->i_op;
-+ error = op->link_raw(&old_nd, &nd);
-+ /* the file system wants to use normal vfs path now */
-+ if (error != -EOPNOTSUPP)
-+ goto out_release;
-+ }
++ if (nd.dentry->d_inode->i_op->link_raw) {
++ struct inode_operations *op = nd.dentry->d_inode->i_op;
++ error = op->link_raw(&old_nd, &nd);
++ /* the file system wants to use normal vfs path now */
++ if (error != -EOPNOTSUPP)
++ goto out_release;
++ }
+ new_dentry = lookup_create(&nd, 0, NULL);
error = PTR_ERR(new_dentry);
if (!IS_ERR(new_dentry)) {
goto exit2;
+ if (old_dir->d_inode->i_op->rename_raw) {
-+ lock_kernel();
++ lock_kernel();
+ error = old_dir->d_inode->i_op->rename_raw(&oldnd, &newnd);
-+ unlock_kernel();
++ unlock_kernel();
+ /* the file system wants to use normal vfs path now */
+ if (error != -EOPNOTSUPP)
+ goto exit2;
int error;
struct iattr newattrs;
-@@ -108,7 +111,14 @@ int do_truncate(struct dentry *dentry, l
+@@ -108,7 +111,13 @@ int do_truncate(struct dentry *dentry, l
down(&inode->i_sem);
newattrs.ia_size = length;
newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
+ newattrs.ia_valid |= ATTR_FROM_OPEN;
+ if (op->setattr_raw) {
+ newattrs.ia_valid |= ATTR_RAW;
-+ newattrs.ia_ctime = CURRENT_TIME;
+ error = op->setattr_raw(inode, &newattrs);
-+ } else
++ } else
+ error = notify_change(dentry, &newattrs);
up(&inode->i_sem);
return error;
error = -EROFS;
if (IS_RDONLY(inode))
goto dput_and_out;
-@@ -279,11 +294,29 @@ asmlinkage long sys_utime(char * filenam
+@@ -279,11 +294,25 @@ asmlinkage long sys_utime(char * filenam
goto dput_and_out;
newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
+ goto dput_and_out;
+ }
+
-+ error = -EROFS;
-+ if (IS_RDONLY(inode))
-+ goto dput_and_out;
-+
+ error = -EPERM;
+ if (!times) {
if (current->fsuid != inode->i_uid &&
+
+ newattrs.ia_uid = user;
+ newattrs.ia_gid = group;
-+ newattrs.ia_valid = ATTR_UID | ATTR_GID;
++ newattrs.ia_valid = ATTR_UID | ATTR_GID | ATTR_CTIME;
+ newattrs.ia_valid |= ATTR_RAW;
+ error = op->setattr_raw(inode, &newattrs);
+ /* the file system wants to use normal vfs path now */
}
if (f->f_op && f->f_op->open) {
-+ f->f_it = it;
++ f->f_it = it;
error = f->f_op->open(inode,f);
-+ f->f_it = NULL;
++ f->f_it = NULL;
if (error)
goto cleanup_all;
}
}
-static int do_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
-+static int do_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat,
-+ struct lookup_intent *it)
++static int do_getattr(struct vfsmount *mnt, struct dentry *dentry,
++ struct kstat *stat, struct lookup_intent *it)
{
int res = 0;
unsigned int blocks, indirect;
error = inode->u.proc_i.op.proc_get_link(inode, &nd->dentry, &nd->mnt);
nd->last_type = LAST_BIND;
-+
-+ if (nd->it != NULL)
-+ nd->it->it_int_flags |= IT_FL_FOLLOWED;
++
++ if (nd->it != NULL)
++ nd->it->it_int_flags |= IT_FL_FOLLOWED;
out:
return error;
}
#include <linux/mount.h>
+#include <linux/string.h>
+
-+#define IT_OPEN (1)
-+#define IT_CREAT (1<<1)
-+#define IT_READDIR (1<<2)
-+#define IT_GETATTR (1<<3)
-+#define IT_LOOKUP (1<<4)
-+#define IT_UNLINK (1<<5)
-+#define IT_GETXATTR (1<<6)
-+#define IT_EXEC (1<<7)
-+#define IT_PIN (1<<8)
++#define IT_OPEN 0x0001
++#define IT_CREAT 0x0002
++#define IT_READDIR 0x0004
++#define IT_GETATTR 0x0008
++#define IT_LOOKUP 0x0010
++#define IT_UNLINK 0x0020
++#define IT_GETXATTR 0x0040
++#define IT_EXEC 0x0080
++#define IT_PIN 0x0100
+
-+#define IT_FL_LOCKED (1)
-+#define IT_FL_FOLLOWED (1<<1) /* set by vfs_follow_link */
++#define IT_FL_LOCKED 0x0001
++#define IT_FL_FOLLOWED 0x0002 /* set by vfs_follow_link */
+
+#define INTENT_MAGIC 0x19620323
+
+
+static inline void intent_init(struct lookup_intent *it, int op, int flags)
+{
-+ memset(it, 0, sizeof(*it));
-+ it->it_magic = INTENT_MAGIC;
-+ it->it_op = op;
-+ it->it_flags = flags;
++ memset(it, 0, sizeof(*it));
++ it->it_magic = INTENT_MAGIC;
++ it->it_op = op;
++ it->it_flags = flags;
+}
+
};
+#define PIN(de,mnt,flag) if (de->d_op && de->d_op->d_pin) \
-+ de->d_op->d_pin(de, mnt, flag);
++ de->d_op->d_pin(de, mnt, flag);
+#define UNPIN(de,mnt,flag) if (de->d_op && de->d_op->d_unpin) \
-+ de->d_op->d_unpin(de, mnt, flag);
++ de->d_op->d_unpin(de, mnt, flag);
+
+
+/* defined in fs/namei.c */
extern spinlock_t dcache_lock;
---- linux-2.4.18-p4smp/include/linux/fs.h~vfs_intent-2.4.18-18-chaos65 2003-07-09 13:20:34.000000000 -0600
-+++ linux-2.4.18-p4smp-braam/include/linux/fs.h 2003-07-09 13:20:37.000000000 -0600
-@@ -339,6 +339,8 @@ extern void set_bh_page(struct buffer_he
+--- linux-2.4.18-p4smp/include/linux/fs.h~vfs_intent-2.4.18-18-chaos65 2003-07-08 14:41:47.000000000 -0600
++++ linux-2.4.18-p4smp-braam/include/linux/fs.h 2003-07-08 14:45:17.000000000 -0600
+@@ -339,6 +339,9 @@ extern void set_bh_page(struct buffer_he
#define ATTR_MTIME_SET 256
#define ATTR_FORCE 512 /* Not a change, but a change it */
#define ATTR_ATTR_FLAG 1024
-+#define ATTR_RAW 2048 /* file system, not vfs will massage attrs */
-+#define ATTR_FROM_OPEN 4096 /* called from open path, ie O_TRUNC */
++#define ATTR_RAW 0x0800 /* file system, not vfs will massage attrs */
++#define ATTR_FROM_OPEN 0x1000 /* called from open path, ie O_TRUNC */
++#define ATTR_CTIME_SET 0x2000 /* called from open path, ie O_TRUNC */
/*
* This is the Inode Attributes structure, used for notify_change(). It
extern int vfs_unlink(struct inode *, struct dentry *);
-extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
+int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
-+ struct inode *new_dir, struct dentry *new_dentry);
++ struct inode *new_dir, struct dentry *new_dentry);
/*
* File types
fs->umask = old->umask;
read_lock(&old->lock);
fs->rootmnt = mntget(old->rootmnt);
-+ PIN(old->pwd, old->pwdmnt, 0);
-+ PIN(old->root, old->rootmnt, 1);
++ PIN(old->pwd, old->pwdmnt, 0);
++ PIN(old->root, old->rootmnt, 1);
fs->root = dget(old->root);
fs->pwdmnt = mntget(old->pwdmnt);
fs->pwd = dget(old->pwd);
if (old->altroot) {
-+ PIN(old->altroot, old->altrootmnt, 1);
++ PIN(old->altroot, old->altrootmnt, 1);
fs->altrootmnt = mntget(old->altrootmnt);
fs->altroot = dget(old->altroot);
} else {
{
/* No need to hold fs->lock if we are killing it */
if (atomic_dec_and_test(&fs->count)) {
-+ UNPIN(fs->pwd, fs->pwdmnt, 0);
-+ UNPIN(fs->root, fs->rootmnt, 1);
++ UNPIN(fs->pwd, fs->pwdmnt, 0);
++ UNPIN(fs->root, fs->rootmnt, 1);
dput(fs->root);
mntput(fs->rootmnt);
dput(fs->pwd);
mntput(fs->pwdmnt);
if (fs->altroot) {
-+ UNPIN(fs->altroot, fs->altrootmnt, 1);
++ UNPIN(fs->altroot, fs->altrootmnt, 1);
dput(fs->altroot);
mntput(fs->altrootmnt);
}
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Copyright (C) 2003 Cluster File Systems, Inc.
+ *
+ * This code is issued under the GNU General Public License.
+ * See the file COPYING in this distribution
+ */
+
#ifndef _FILTER_INTERNAL_H
#define _FILTER_INTERNAL_H
-
#ifdef __KERNEL__
# include <linux/spinlock.h>
#endif
# define OBD_FILTER_SAN_DEVICENAME "sanobdfilter"
#endif
+#define LAST_RCVD "last_rcvd"
+#define INIT_OBJID 2
+
#define FILTER_LR_SERVER_SIZE 512
#define FILTER_LR_CLIENT_START 8192
#define FILTER_LR_CLIENT_SIZE 128
+/* This limit is arbitrary, but for now we fit it in 1 page (32k clients) */
+#define FILTER_LR_MAX_CLIENTS (PAGE_SIZE * 8)
+#define FILTER_LR_MAX_CLIENT_WORDS (FILTER_LR_MAX_CLIENTS/sizeof(unsigned long))
+
#define FILTER_SUBDIR_COUNT 32 /* set to zero for no subdirs */
#define FILTER_MOUNT_RECOV 2
#define FILTER_DENTRY_MAGIC 0x9efba101
#define FILTER_FLAG_DESTROY 0x0001 /* destroy dentry on last file close */
+/* Limit the returned fields marked valid to those that we actually might set */
+#define FILTER_VALID_FLAGS (OBD_MD_FLTYPE | OBD_MD_FLMODE | OBD_MD_FLGENER |\
+ OBD_MD_FLSIZE | OBD_MD_FLBLOCKS | OBD_MD_FLBLKSZ|\
+ OBD_MD_FLATIME | OBD_MD_FLMTIME | OBD_MD_FLCTIME)
+
enum {
LPROC_FILTER_READ_BYTES = 0,
LPROC_FILTER_WRITE_BYTES = 1,
void f_dput(struct dentry *);
struct dentry *filter_fid2dentry(struct obd_device *, struct dentry *dir,
obd_mode mode, obd_id id);
+struct dentry *__filter_oa2dentry(struct obd_device *obd,struct obdo *oa,
+ char *what);
+#define filter_oa2dentry(obd, oa) __filter_oa2dentry(obd, oa, __FUNCTION__)
+
int filter_finish_transno(struct obd_export *, struct obd_trans_info *, int rc);
__u64 filter_next_id(struct filter_obd *);
int filter_update_server_data(struct file *, struct filter_server_data *);
int filter_preprw(int cmd, struct obd_export *, struct obdo *, int objcount,
struct obd_ioobj *, int niocount, struct niobuf_remote *,
struct niobuf_local *, struct obd_trans_info *);
-int filter_commitrw(int cmd, struct obd_export *, int objcount,
+int filter_commitrw(int cmd, struct obd_export *, struct obdo *, int objcount,
struct obd_ioobj *, int niocount, struct niobuf_local *,
struct obd_trans_info *);
-int filter_brw(int cmd, struct lustre_handle *, struct lov_stripe_md *,
- obd_count oa_bufs, struct brw_page *, struct obd_trans_info *);
+int filter_brw(int cmd, struct lustre_handle *, struct obdo *,
+ struct lov_stripe_md *, obd_count oa_bufs, struct brw_page *,
+ struct obd_trans_info *);
/* filter_log.c */
int filter_log_cancel(struct lustre_handle *, struct lov_stripe_md *,
/* filter_san.c */
int filter_san_setup(struct obd_device *obd, obd_count len, void *buf);
-int filter_san_preprw(int cmd, struct lustre_handle *, int objcount,
+int filter_san_preprw(int cmd, struct obd_export *, struct obdo *, int objcount,
struct obd_ioobj *, int niocount, struct niobuf_remote *);
#endif