* [PATCH] icreate-7
@ 2002-05-01 22:59 Jan Harkes
2002-05-01 23:58 ` Anton Altaparmakov
2002-05-02 14:22 ` Chris Mason
0 siblings, 2 replies; 9+ messages in thread
From: Jan Harkes @ 2002-05-01 22:59 UTC (permalink / raw)
To: linux-fsdevel
Another day another update,
Fixed the documentation error, thanks Kai, and tried to follow Al's
advice by not including ino separately, but using *(ino_t *)data for
the inode hash calculation. Don't really like it myself, but who am
I to argue and it might end up making life a bit simpler for NFS and
Intermezzo because we end up having only a single identifier for an
object. OTOH, if everything switches to icreate the filesystems will
have to provide a lookup mechanism through export_ops.
Jan
Patch is against 2.5.12
diff -urN orig/Documentation/filesystems/Locking icreate7a/Documentation/filesystems/Locking
--- orig/Documentation/filesystems/Locking Wed May 1 00:27:32 2002
+++ icreate7a/Documentation/filesystems/Locking Wed May 1 00:35:58 2002
@@ -115,7 +115,7 @@
remount_fs: yes yes maybe (see below)
umount_begin: yes no maybe (see below)
-->read_inode() is not a method - it's a callback used in iget()/iget4().
+->read_inode() is not a method - it's a callback used in iget().
rules for mount_sem are not too nice - it is going to die and be replaced
by better scheme anyway.
diff -urN orig/Documentation/filesystems/porting icreate7a/Documentation/filesystems/porting
--- orig/Documentation/filesystems/porting Mon Apr 29 10:23:27 2002
+++ icreate7a/Documentation/filesystems/porting Wed May 1 18:37:47 2002
@@ -146,3 +146,35 @@
It is planned that this will be required for exporting once the code
settles down a bit.
+
+---
+[mandatory]
+
+iget4() and the read_inode2 callback have been superseded by icreate()
+which has the following prototype,
+
+ struct inode *icreate(struct super_block *sb, unsigned long ino,
+ int (*test)(struct inode *, void *),
+ int (*set)(struct inode *, void *),
+ void *data);
+
+'test' is an additional function that can be used when the inode
+number is not sufficient to identify the actual file object. 'set'
+should be a non-blocking function that initializes those parts of a
+newly created inode to allow the test function to succeed. 'data' is
+passed as an opaque value to both test and set functions. To improve
+lookup performance it is advised to have a hash or similar unique
+unsigned long value at the beginning of 'data'.
+
+When the inode has been created by icreate(), it will be returned with
+the I_NEW flag set and will still be locked. read_inode has not been
+called so the file system still has to finalize the initialization. Once
+the inode is initialized is must be unlocked by calling unlock_new_inode().
+
+e.g.
+ inode = icreate(sb, NULL, NULL, &ino);
+ if (inode->i_state & I_NEW) {
+ read_inode_from_disk(inode);
+ unlock_new_inode(inode);
+ }
+
diff -urN orig/fs/Makefile icreate7a/fs/Makefile
--- orig/fs/Makefile Wed May 1 00:27:34 2002
+++ icreate7a/fs/Makefile Wed May 1 00:35:58 2002
@@ -7,7 +7,7 @@
O_TARGET := fs.o
-export-objs := filesystems.o open.o dcache.o buffer.o bio.o
+export-objs := filesystems.o open.o dcache.o buffer.o bio.o inode.o
mod-subdirs := nls
obj-y := open.o read_write.o devices.o file_table.o buffer.o \
diff -urN orig/fs/coda/cnode.c icreate7a/fs/coda/cnode.c
--- orig/fs/coda/cnode.c Wed Apr 24 21:39:46 2002
+++ icreate7a/fs/coda/cnode.c Wed May 1 18:23:27 2002
@@ -25,9 +25,15 @@
return 1;
}
-static int coda_inocmp(struct inode *inode, unsigned long ino, void *opaque)
+struct coda_icreate_args {
+ ino_t ino;
+ ViceFid fid;
+};
+
+static int coda_inocmp(struct inode *inode, void *data)
{
- return (coda_fideq((ViceFid *)opaque, &(ITOC(inode)->c_fid)));
+ struct coda_icreate_args *args = data;
+ return (coda_fideq(&(ITOC(inode)->c_fid), &args->fid));
}
static struct inode_operations coda_symlink_inode_operations = {
@@ -55,26 +61,34 @@
init_special_inode(inode, inode->i_mode, attr->va_rdev);
}
+int coda_init_inode(struct inode *inode, void *data)
+{
+ struct coda_icreate_args *args = data;
+ ITOC(inode)->c_fid = args->fid;
+ return 0;
+}
+
struct inode * coda_iget(struct super_block * sb, ViceFid * fid,
struct coda_vattr * attr)
{
struct inode *inode;
struct coda_inode_info *cii;
- ino_t ino = coda_f2i(fid);
+ struct coda_sb_info *sbi = coda_sbp(sb);
+ struct coda_icreate_args args;
- inode = iget4(sb, ino, coda_inocmp, fid);
+ args.ino = coda_f2i(fid);
+ args.fid = *fid;
+
+ inode = icreate(sb, coda_inocmp, coda_init_inode, &args);
if (!inode)
return ERR_PTR(-ENOMEM);
- /* check if the inode is already initialized */
- cii = ITOC(inode);
- if (coda_isnullfid(&cii->c_fid))
- /* new, empty inode found... initializing */
- cii->c_fid = *fid;
-
- /* we shouldnt see inode collisions anymore */
- if (!coda_fideq(fid, &cii->c_fid)) BUG();
+ if (inode->i_state & I_NEW) {
+ cii = ITOC(inode);
+ list_add(&cii->c_cilist, &sbi->sbi_cihead);
+ unlock_new_inode(inode);
+ }
/* always replace the attributes, type might have changed */
coda_fill_inode(inode, attr);
@@ -126,37 +140,32 @@
insert_inode_hash(inode);
}
+int coda_fail_inode(struct inode *inode, void *data)
+{
+ return -1;
+}
+
/* convert a fid to an inode. */
struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb)
{
- ino_t nr;
struct inode *inode;
- struct coda_inode_info *cii;
+ struct coda_icreate_args args;
+
+ args.ino = coda_f2i(fid);
+ args.fid = *fid;
if ( !sb ) {
printk("coda_fid_to_inode: no sb!\n");
return NULL;
}
- nr = coda_f2i(fid);
- inode = iget4(sb, nr, coda_inocmp, fid);
- if ( !inode ) {
- printk("coda_fid_to_inode: null from iget, sb %p, nr %ld.\n",
- sb, (long)nr);
- return NULL;
- }
-
- cii = ITOC(inode);
-
- /* The inode could already be purged due to memory pressure */
- if (coda_isnullfid(&cii->c_fid)) {
- inode->i_nlink = 0;
- iput(inode);
+ inode = icreate(sb, coda_inocmp, coda_fail_inode, &args);
+ if ( !inode )
return NULL;
- }
- /* we shouldn't see inode collisions anymore */
- if ( !coda_fideq(fid, &cii->c_fid) ) BUG();
+ /* we should never see newly created inodes here because we
+ * intentionally fail in the initialization callback */
+ BUG_ON(inode->i_state & I_NEW);
return inode;
}
@@ -164,18 +173,18 @@
/* the CONTROL inode is made without asking attributes from Venus */
int coda_cnode_makectl(struct inode **inode, struct super_block *sb)
{
- int error = 0;
+ int error = -ENOMEM;
+
+ *inode = icreate_light(sb, CTL_INO);
+
+ if ( *inode && ((*inode)->i_state & I_NEW) ) {
+ (*inode)->i_op = &coda_ioctl_inode_operations;
+ (*inode)->i_fop = &coda_ioctl_operations;
+ (*inode)->i_mode = 0444;
+ unlock_new_inode(*inode);
+ error = 0;
+ }
- *inode = iget(sb, CTL_INO);
- if ( *inode ) {
- (*inode)->i_op = &coda_ioctl_inode_operations;
- (*inode)->i_fop = &coda_ioctl_operations;
- (*inode)->i_mode = 0444;
- error = 0;
- } else {
- error = -ENOMEM;
- }
-
- return error;
+ return error;
}
diff -urN orig/fs/coda/inode.c icreate7a/fs/coda/inode.c
--- orig/fs/coda/inode.c Wed Apr 24 21:39:46 2002
+++ icreate7a/fs/coda/inode.c Wed May 1 00:35:58 2002
@@ -229,16 +229,9 @@
kfree(sbi);
}
-/* all filling in of inodes postponed until lookup */
static void coda_read_inode(struct inode *inode)
{
- struct coda_sb_info *sbi = coda_sbp(inode->i_sb);
- struct coda_inode_info *cii;
-
- if (!sbi) BUG();
-
- cii = ITOC(inode);
- list_add(&cii->c_cilist, &sbi->sbi_cihead);
+ make_bad_inode(inode);
}
static void coda_clear_inode(struct inode *inode)
diff -urN orig/fs/inode.c icreate7a/fs/inode.c
--- orig/fs/inode.c Wed May 1 00:27:35 2002
+++ icreate7a/fs/inode.c Wed May 1 18:22:32 2002
@@ -12,6 +12,7 @@
#include <linux/quotaops.h>
#include <linux/slab.h>
#include <linux/writeback.h>
+#include <linux/module.h>
/*
* New inode.c implementation.
@@ -452,7 +453,7 @@
* by hand after calling find_inode now! This simplifies iunique and won't
* add any additional branch in the common code.
*/
-static struct inode * find_inode(struct super_block * sb, unsigned long ino, struct list_head *head, find_inode_t find_actor, void *opaque)
+static struct inode * find_inode(struct super_block * sb, struct list_head *head, int (*test)(struct inode *, void *), void *data)
{
struct list_head *tmp;
struct inode * inode;
@@ -464,11 +465,11 @@
if (tmp == head)
break;
inode = list_entry(tmp, struct inode, i_hash);
- if (inode->i_ino != ino)
+ if (inode->i_ino != *(ino_t *)data)
continue;
if (inode->i_sb != sb)
continue;
- if (find_actor && !find_actor(inode, ino, opaque))
+ if (test && !test(inode, data))
continue;
break;
}
@@ -501,53 +502,60 @@
return inode;
}
+void unlock_new_inode(struct inode *inode)
+{
+ BUG_ON(!(inode->i_state & I_NEW));
+ /*
+ * This is special! We do not need the spinlock
+ * when clearing I_LOCK, because we're guaranteed
+ * that nobody else tries to do anything about the
+ * state of the inode when it is locked, as we
+ * just created it (so there can be no old holders
+ * that haven't tested I_LOCK).
+ */
+ inode->i_state &= ~(I_LOCK|I_NEW);
+ wake_up(&inode->i_wait);
+}
+
+
/*
* This is called without the inode lock held.. Be careful.
*
* We no longer cache the sb_flags in i_flags - see fs.h
* -- rmk@arm.uk.linux.org
*/
-static struct inode * get_new_inode(struct super_block *sb, unsigned long ino, struct list_head *head, find_inode_t find_actor, void *opaque)
+static struct inode * get_new_inode(struct super_block *sb, struct list_head *head, int (*test)(struct inode *, void *), int (*set)(struct inode *, void *), void *data)
{
struct inode * inode;
+ int is_set;
inode = alloc_inode(sb);
if (inode) {
struct inode * old;
+ inode->i_state = I_LOCK|I_NEW;
spin_lock(&inode_lock);
/* We released the lock, so.. */
- old = find_inode(sb, ino, head, find_actor, opaque);
+ old = find_inode(sb, head, test, data);
if (!old) {
- inodes_stat.nr_inodes++;
- list_add(&inode->i_list, &inode_in_use);
- list_add(&inode->i_hash, head);
- inode->i_ino = ino;
- inode->i_state = I_LOCK;
+ inode->i_ino = *(ino_t *)data;
+ is_set = !set || set(inode, data) == 0;
+ if (!is_set) {
+ inodes_stat.nr_inodes++;
+ list_add(&inode->i_list, &inode_in_use);
+ list_add(&inode->i_hash, head);
+ }
spin_unlock(&inode_lock);
- /* reiserfs specific hack right here. We don't
- ** want this to last, and are looking for VFS changes
- ** that will allow us to get rid of it.
- ** -- mason@suse.com
- */
- if (sb->s_op->read_inode2) {
- sb->s_op->read_inode2(inode, opaque) ;
- } else {
- sb->s_op->read_inode(inode);
+ /* failed to initialize? */
+ if (is_set) {
+ destroy_inode(inode);
+ return NULL;
}
- /*
- * This is special! We do not need the spinlock
- * when clearing I_LOCK, because we're guaranteed
- * that nobody else tries to do anything about the
- * state of the inode when it is locked, as we
- * just created it (so there can be no old holders
- * that haven't tested I_LOCK).
+ /* Return the locked inode with I_NEW set, the
+ * caller is responsible for filling in the contents
*/
- inode->i_state &= ~I_LOCK;
- wake_up(&inode->i_wait);
-
return inode;
}
@@ -599,7 +607,8 @@
retry:
if (counter > max_reserved) {
head = inode_hashtable + hash(sb,counter);
- inode = find_inode(sb, res = counter++, head, NULL, NULL);
+ res = counter++;
+ inode = find_inode(sb, head, NULL, &res);
if (!inode) {
spin_unlock(&inode_lock);
return res;
@@ -627,14 +636,18 @@
return inode;
}
-
-struct inode *iget4(struct super_block *sb, unsigned long ino, find_inode_t find_actor, void *opaque)
+/*
+ * This is iget without the read_inode portion of get_new_inode
+ * the filesystem gets back a new locked and hashed inode and gets
+ * to fill it in before unlocking it via unlock_new_inode().
+ */
+struct inode *icreate(struct super_block *sb, int (*test)(struct inode *, void *), int (*set)(struct inode *, void *), void *data)
{
- struct list_head * head = inode_hashtable + hash(sb,ino);
+ struct list_head * head = inode_hashtable + hash(sb, *(ino_t *)data);
struct inode * inode;
spin_lock(&inode_lock);
- inode = find_inode(sb, ino, head, find_actor, opaque);
+ inode = find_inode(sb, head, test, data);
if (inode) {
__iget(inode);
spin_unlock(&inode_lock);
@@ -643,12 +656,17 @@
}
spin_unlock(&inode_lock);
- /*
- * get_new_inode() will do the right thing, re-trying the search
- * in case it had to block at any point.
- */
- return get_new_inode(sb, ino, head, find_actor, opaque);
+ return get_new_inode(sb, head, test, set, data);
}
+
+struct inode *icreate_light(struct super_block *sb, unsigned long ino)
+{
+ return icreate(sb, NULL, NULL, &ino);
+}
+
+EXPORT_SYMBOL(icreate);
+EXPORT_SYMBOL(icreate_light);
+EXPORT_SYMBOL(unlock_new_inode);
/**
* insert_inode_hash - hash an inode
diff -urN orig/fs/nfs/inode.c icreate7a/fs/nfs/inode.c
--- orig/fs/nfs/inode.c Wed May 1 00:27:35 2002
+++ icreate7a/fs/nfs/inode.c Wed May 1 18:23:49 2002
@@ -581,6 +581,7 @@
}
struct nfs_find_desc {
+ ino_t ino;
struct nfs_fh *fh;
struct nfs_fattr *fattr;
};
@@ -592,7 +593,7 @@
* i_ino.
*/
static int
-nfs_find_actor(struct inode *inode, unsigned long ino, void *opaque)
+nfs_find_actor(struct inode *inode, void *opaque)
{
struct nfs_find_desc *desc = (struct nfs_find_desc *)opaque;
struct nfs_fh *fh = desc->fh;
@@ -610,6 +611,18 @@
return 1;
}
+static int
+nfs_init_locked(struct inode *inode, void *opaque)
+{
+ struct nfs_find_desc *desc = (struct nfs_find_desc *)opaque;
+ struct nfs_fh *fh = desc->fh;
+ struct nfs_fattr *fattr = desc->fattr;
+
+ NFS_FILEID(inode) = fattr->fileid;
+ memcpy(NFS_FH(inode), fh, sizeof(struct nfs_fh));
+ return 0;
+}
+
/*
* This is our own version of iget that looks up inodes by file handle
* instead of inode number. We use this technique instead of using
@@ -640,7 +653,6 @@
fattr: fattr
};
struct inode *inode = NULL;
- unsigned long ino;
if ((fattr->valid & NFS_ATTR_FATTR) == 0)
goto out_no_inode;
@@ -650,20 +662,17 @@
goto out_no_inode;
}
- ino = nfs_fattr_to_ino_t(fattr);
+ desc.ino = nfs_fattr_to_ino_t(fattr);
- if (!(inode = iget4(sb, ino, nfs_find_actor, &desc)))
+ if (!(inode = icreate(sb, nfs_find_actor, nfs_init_locked, &desc)))
goto out_no_inode;
- if (NFS_NEW(inode)) {
+ if (inode->i_state & I_NEW) {
__u64 new_size, new_mtime;
loff_t new_isize;
time_t new_atime;
/* We can't support UPDATE_ATIME(), since the server will reset it */
- NFS_FLAGS(inode) &= ~NFS_INO_NEW;
- NFS_FILEID(inode) = fattr->fileid;
- memcpy(NFS_FH(inode), fh, sizeof(struct nfs_fh));
inode->i_flags |= S_NOATIME;
inode->i_mode = fattr->mode;
/* Why so? Because we want revalidate for devices/FIFOs, and
@@ -711,6 +720,8 @@
NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode);
NFS_ATTRTIMEO_UPDATE(inode) = jiffies;
memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode)));
+
+ unlock_new_inode(inode);
} else
nfs_refresh_inode(inode, fattr);
dprintk("NFS: __nfs_fhget(%s/%Ld ct=%d)\n",
@@ -1231,7 +1242,6 @@
nfsi = (struct nfs_inode *)kmem_cache_alloc(nfs_inode_cachep, SLAB_KERNEL);
if (!nfsi)
return NULL;
- nfsi->flags = NFS_INO_NEW;
nfsi->mm_cred = NULL;
return &nfsi->vfs_inode;
}
diff -urN orig/fs/reiserfs/inode.c icreate7a/fs/reiserfs/inode.c
--- orig/fs/reiserfs/inode.c Wed May 1 00:27:35 2002
+++ icreate7a/fs/reiserfs/inode.c Wed May 1 18:23:38 2002
@@ -33,7 +33,7 @@
lock_kernel() ;
/* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */
- if (INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */
+ if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */
down (&inode->i_sem);
journal_begin(&th, inode->i_sb, jbegin_count) ;
@@ -1140,19 +1140,20 @@
/* looks for stat data in the tree, and fills up the fields of in-core
inode stat data fields */
-void reiserfs_read_inode2 (struct inode * inode, void *p)
+int reiserfs_init_locked_inode (struct inode * inode, void *p)
+{
+ struct reiserfs_icreate_args *args = (struct reiserfs_icreate_args *)p ;
+ INODE_PKEY(inode)->k_dir_id = cpu_to_le32(args->objectid);
+ return 0;
+}
+
+void reiserfs_read_locked_inode (struct inode * inode, struct reiserfs_icreate_args *args)
{
INITIALIZE_PATH (path_to_sd);
struct cpu_key key;
- struct reiserfs_iget4_args *args = (struct reiserfs_iget4_args *)p ;
unsigned long dirino;
int retval;
- if (!p) {
- reiserfs_make_bad_inode(inode) ;
- return;
- }
-
dirino = args->objectid ;
/* set version 1, version 2 could be used too, because stat data
@@ -1210,22 +1211,21 @@
}
/**
- * reiserfs_find_actor() - "find actor" reiserfs supplies to iget4().
+ * reiserfs_find_actor() - "find actor" reiserfs supplies to icreate().
*
* @inode: inode from hash table to check
* @inode_no: inode number we are looking for
- * @opaque: "cookie" passed to iget4(). This is &reiserfs_iget4_args.
+ * @opaque: "cookie" passed to icreate(). This is &reiserfs_icreate_args.
*
- * This function is called by iget4() to distinguish reiserfs inodes
+ * This function is called by icreate() to distinguish reiserfs inodes
* having the same inode numbers. Such inodes can only exist due to some
* error condition. One of them should be bad. Inodes with identical
* inode numbers (objectids) are distinguished by parent directory ids.
*
*/
-static int reiserfs_find_actor( struct inode *inode,
- unsigned long inode_no, void *opaque )
+static int reiserfs_find_actor( struct inode *inode, void *opaque )
{
- struct reiserfs_iget4_args *args;
+ struct reiserfs_icreate_args *args;
args = opaque;
/* args is already in CPU order */
@@ -1235,13 +1235,18 @@
struct inode * reiserfs_iget (struct super_block * s, const struct cpu_key * key)
{
struct inode * inode;
- struct reiserfs_iget4_args args ;
+ struct reiserfs_icreate_args args ;
+ args.ino = key->on_disk_key.k_objectid;
args.objectid = key->on_disk_key.k_dir_id ;
- inode = iget4 (s, key->on_disk_key.k_objectid,
- reiserfs_find_actor, (void *)(&args));
+ inode = icreate(s, reiserfs_find_actor, reiserfs_init_locked_inode, (void *)(&args));
if (!inode)
return ERR_PTR(-ENOMEM) ;
+
+ if (inode->i_state & I_NEW) {
+ reiserfs_read_locked_inode(inode, &args);
+ unlock_new_inode(inode);
+ }
if (comp_short_keys (INODE_PKEY (inode), key) || is_bad_inode (inode)) {
/* either due to i/o error or a stale NFS handle */
diff -urN orig/fs/reiserfs/super.c icreate7a/fs/reiserfs/super.c
--- orig/fs/reiserfs/super.c Mon Apr 22 23:04:19 2002
+++ icreate7a/fs/reiserfs/super.c Wed May 1 01:19:50 2002
@@ -485,7 +485,6 @@
alloc_inode: reiserfs_alloc_inode,
destroy_inode: reiserfs_destroy_inode,
read_inode: reiserfs_read_inode,
- read_inode2: reiserfs_read_inode2,
write_inode: reiserfs_write_inode,
dirty_inode: reiserfs_dirty_inode,
delete_inode: reiserfs_delete_inode,
@@ -1002,7 +1001,7 @@
int old_format = 0;
unsigned long blocks;
int jinit_done = 0 ;
- struct reiserfs_iget4_args args ;
+ struct reiserfs_icreate_args args ;
struct reiserfs_super_block * rs;
char *jdev_name;
struct reiserfs_sb_info *sbi;
@@ -1064,11 +1063,17 @@
printk("clm-7000: Detected readonly device, marking FS readonly\n") ;
s->s_flags |= MS_RDONLY ;
}
+ args.ino = REISERFS_ROOT_OBJECTID;
args.objectid = REISERFS_ROOT_PARENT_OBJECTID ;
- root_inode = iget4 (s, REISERFS_ROOT_OBJECTID, 0, (void *)(&args));
+ root_inode = icreate (s, NULL, reiserfs_init_locked_inode, (void *)(&args));
if (!root_inode) {
printk ("reiserfs_fill_super: get root inode failed\n");
goto error;
+ }
+
+ if (root_inode->i_state & I_NEW) {
+ reiserfs_read_locked_inode(root_inode, &args);
+ unlock_new_inode(root_inode);
}
s->s_root = d_alloc_root(root_inode);
diff -urN orig/include/linux/fs.h icreate7a/include/linux/fs.h
--- orig/include/linux/fs.h Wed May 1 00:27:36 2002
+++ icreate7a/include/linux/fs.h Wed May 1 02:15:49 2002
@@ -777,13 +777,6 @@
void (*read_inode) (struct inode *);
- /* reiserfs kludge. reiserfs needs 64 bits of information to
- ** find an inode. We are using the read_inode2 call to get
- ** that information. We don't like this, and are waiting on some
- ** VFS changes for the real solution.
- ** iget4 calls read_inode2, iff it is defined
- */
- void (*read_inode2) (struct inode *, void *) ;
void (*dirty_inode) (struct inode *);
void (*write_inode) (struct inode *, int);
void (*put_inode) (struct inode *);
@@ -831,6 +824,7 @@
#define I_LOCK 8
#define I_FREEING 16
#define I_CLEAR 32
+#define I_NEW 64
#define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)
@@ -1239,11 +1233,22 @@
extern struct inode * igrab(struct inode *);
extern ino_t iunique(struct super_block *, ino_t);
-typedef int (*find_inode_t)(struct inode *, unsigned long, void *);
-extern struct inode * iget4(struct super_block *, unsigned long, find_inode_t, void *);
+extern struct inode * icreate(struct super_block *, int (*test)(struct inode *, void *), int (*set)(struct inode *, void *), void *data);
+extern struct inode * icreate_light(struct super_block *, unsigned long);
+extern void unlock_new_inode(struct inode *);
+
static inline struct inode *iget(struct super_block *sb, unsigned long ino)
{
- return iget4(sb, ino, NULL, NULL);
+ struct inode *inode;
+
+ inode = icreate_light(sb, ino);
+
+ if (inode && (inode->i_state & I_NEW)) {
+ sb->s_op->read_inode(inode);
+ unlock_new_inode(inode);
+ }
+
+ return inode;
}
extern void __iget(struct inode * inode);
diff -urN orig/include/linux/nfs_fs.h icreate7a/include/linux/nfs_fs.h
--- orig/include/linux/nfs_fs.h Mon Apr 29 10:48:02 2002
+++ icreate7a/include/linux/nfs_fs.h Wed May 1 02:15:58 2002
@@ -170,7 +170,6 @@
#define NFS_INO_REVALIDATING 0x0004 /* revalidating attrs */
#define NFS_IS_SNAPSHOT 0x0010 /* a snapshot file */
#define NFS_INO_FLUSH 0x0020 /* inode is due for flushing */
-#define NFS_INO_NEW 0x0040 /* hadn't been filled yet */
static inline struct nfs_inode *NFS_I(struct inode *inode)
{
@@ -208,7 +207,6 @@
#define NFS_FLAGS(inode) (NFS_I(inode)->flags)
#define NFS_REVALIDATING(inode) (NFS_FLAGS(inode) & NFS_INO_REVALIDATING)
#define NFS_STALE(inode) (NFS_FLAGS(inode) & NFS_INO_STALE)
-#define NFS_NEW(inode) (NFS_FLAGS(inode) & NFS_INO_NEW)
#define NFS_FILEID(inode) (NFS_I(inode)->fileid)
diff -urN orig/include/linux/reiserfs_fs.h icreate7a/include/linux/reiserfs_fs.h
--- orig/include/linux/reiserfs_fs.h Wed Apr 24 18:28:43 2002
+++ icreate7a/include/linux/reiserfs_fs.h Wed May 1 01:22:06 2002
@@ -1564,7 +1564,8 @@
#define B_I_POS_UNFM_POINTER(bh,ih,pos) le32_to_cpu(*(((unp_t *)B_I_PITEM(bh,ih)) + (pos)))
#define PUT_B_I_POS_UNFM_POINTER(bh,ih,pos, val) do {*(((unp_t *)B_I_PITEM(bh,ih)) + (pos)) = cpu_to_le32(val); } while (0)
-struct reiserfs_iget4_args {
+struct reiserfs_icreate_args {
+ ino_t ino;
__u32 objectid ;
} ;
@@ -1819,7 +1820,8 @@
/* inode.c */
void reiserfs_read_inode (struct inode * inode) ;
-void reiserfs_read_inode2(struct inode * inode, void *p) ;
+int reiserfs_init_locked_inode(struct inode * inode, void *p) ;
+void reiserfs_read_locked_inode(struct inode * inode, struct reiserfs_icreate_args *args) ;
void reiserfs_delete_inode (struct inode * inode);
void reiserfs_write_inode (struct inode * inode, int) ;
struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, __u32 *data,
diff -urN orig/kernel/ksyms.c icreate7a/kernel/ksyms.c
--- orig/kernel/ksyms.c Wed May 1 00:27:37 2002
+++ icreate7a/kernel/ksyms.c Wed May 1 00:35:58 2002
@@ -137,7 +137,6 @@
EXPORT_SYMBOL(fget);
EXPORT_SYMBOL(igrab);
EXPORT_SYMBOL(iunique);
-EXPORT_SYMBOL(iget4);
EXPORT_SYMBOL(iput);
EXPORT_SYMBOL(inode_init_once);
EXPORT_SYMBOL(force_delete);
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH] icreate-7 2002-05-01 22:59 [PATCH] icreate-7 Jan Harkes @ 2002-05-01 23:58 ` Anton Altaparmakov 2002-05-02 0:19 ` Jan Harkes 2002-05-02 14:22 ` Chris Mason 1 sibling, 1 reply; 9+ messages in thread From: Anton Altaparmakov @ 2002-05-01 23:58 UTC (permalink / raw) To: Jan Harkes; +Cc: linux-fsdevel At 23:59 01/05/02, Jan Harkes wrote: >Another day another update, > >Fixed the documentation error, thanks Kai, and tried to follow Al's >advice by not including ino separately, but using *(ino_t *)data for >the inode hash calculation. Don't really like it myself, Hm, I don't like it either. /-: It makes passing constants as inode numbers impossible... >but who am I to argue and it might end up making life a bit simpler for >NFS and Intermezzo because we end up having only a single identifier for an >object. OTOH, if everything switches to icreate the filesystems will have >to provide a lookup mechanism through export_ops. Why. This is actually a strong point of the stick ino into data idea but I don't agree with the way you implemented it. Especially because it creates the implication that "data" MUST have "unsigned long ino" as the first element in its structure definition. >diff -urN orig/fs/inode.c icreate7a/fs/inode.c >--- orig/fs/inode.c Wed May 1 00:27:35 2002 >+++ icreate7a/fs/inode.c Wed May 1 18:22:32 2002 >@@ -464,11 +465,11 @@ > if (tmp == head) > break; > inode = list_entry(tmp, struct inode, i_hash); >- if (inode->i_ino != ino) >+ if (inode->i_ino != *(ino_t *)data) > continue; > if (inode->i_sb != sb) > continue; >- if (find_actor && !find_actor(inode, ino, opaque)) >+ if (test && !test(inode, data)) > continue; > break; > } I think this is much better, but feel free to disagree... I am very tired and its late but it makes sense to me now... I went as far as taking the super block comparison out, too. At least for ntfs the test function can handle that itself quite nicely and it would be one of the first checks right after the inode number comparison. Also taking the sb out from the if (test) code path means we can take that out as an argument as well and combine it with the ino into a little struct that is passed in data for conventional fs. Then it would make their "identification handle" to be "struct { unsigned long ino; struct super_block *sb; };" The only disadvantage to my approach AFAICS is the penalty of calling the test function more often but this is not a performance critical path (usually the dcache is hit and we never get here, right?), so it should be ok and makes the interface more consistent rather than having two different interfaces hammered into one function... if (tmp == head) break; inode = list_entry(tmp, struct inode, i_hash); - if (inode->i_ino != ino) + if (!test) { + if (inode->i_ino != *(ino_t *)data)) + continue; + if (inode->i_sb != sb) + continue; + } else if (!test(inode, data)) continue; - if (inode->i_sb != sb) - continue; - if (find_actor && !find_actor(inode, ino, opaque)) - continue; break; } An obvious cleanup further would be to remove iget() in favour of fs_iget() as I suggested before which would use a generic test function using the above suggested handle for identification (i.e. the inode number + super block pointer). Then the if (!test ) code path disappears altogether and find_inode() becomes simply: if (tmp == head) break; inode = list_entry(tmp, struct inode, i_hash); - if (inode->i_ino != ino) + if (!test(inode, data)) continue; - if (inode->i_sb != sb) - continue; - if (find_actor && !find_actor(inode, ino, opaque)) - continue; break; Or visually more pleasing: if (tmp == head) break; inode = list_entry(tmp, struct inode, i_hash); - if (inode->i_ino != ino) - continue; - if (inode->i_sb != sb) - continue; - if (find_actor && !find_actor(inode, ino, opaque)) - continue; - break; + if (test(inode, data)) + break; /me -ENEEDSLEEP Best regards, Anton -- "I've not lost my mind. It's backed up on tape somewhere." - Unknown -- Anton Altaparmakov <aia21 at cantab.net> (replace at with @) Linux NTFS Maintainer / IRC: #ntfs on irc.openprojects.net WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/ ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] icreate-7 2002-05-01 23:58 ` Anton Altaparmakov @ 2002-05-02 0:19 ` Jan Harkes 0 siblings, 0 replies; 9+ messages in thread From: Jan Harkes @ 2002-05-02 0:19 UTC (permalink / raw) To: Anton Altaparmakov; +Cc: linux-fsdevel On Thu, May 02, 2002 at 12:58:23AM +0100, Anton Altaparmakov wrote: > >but who am I to argue and it might end up making life a bit simpler for > >NFS and Intermezzo because we end up having only a single identifier for an > >object. OTOH, if everything switches to icreate the filesystems will have > >to provide a lookup mechanism through export_ops. > > Why. This is actually a strong point of the stick ino into data idea but I > don't agree with the way you implemented it. Especially because it creates > the implication that "data" MUST have "unsigned long ino" as the first > element in its structure definition. ... > The only disadvantage to my approach AFAICS is the penalty of calling the > test function more often but this is not a performance critical path > (usually the dcache is hit and we never get here, right?), so it should be > ok and makes the interface more consistent rather than having two different > interfaces hammered into one function... ... > An obvious cleanup further would be to remove iget() in favour of fs_iget() Something like that is already there under the name icreate_light, so the guarantee of having a test function could be made. > if (tmp == head) > break; > inode = list_entry(tmp, struct inode, i_hash); > - if (inode->i_ino != ino) > + if (!test(inode, data)) > continue; > - if (inode->i_sb != sb) > - continue; > - if (find_actor && !find_actor(inode, ino, opaque)) > - continue; But... the real problem is not really find_inode, but all functions that call find_inode. They need to find the right hash-chain, and currently use struct list_head *head = inode_hashtable + hash(sb, ino); So if the VFS doesn't know 'ino', but only an undefined 'opaque' blob of which we don't even know the size, it won't be able to come up with the right value for which chain to pick. Except if we call 'set' on a dummy inode and peek at whatever the i_ino has been set to by the filesystem. This is so disgusting that I didn't even consider doing it that way. > /me -ENEEDSLEEP -EWOULDBENICE :) Jan ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] icreate-7 2002-05-01 22:59 [PATCH] icreate-7 Jan Harkes 2002-05-01 23:58 ` Anton Altaparmakov @ 2002-05-02 14:22 ` Chris Mason 2002-05-03 20:26 ` Jan Harkes 1 sibling, 1 reply; 9+ messages in thread From: Chris Mason @ 2002-05-02 14:22 UTC (permalink / raw) To: Jan Harkes; +Cc: linux-fsdevel On Wed, 2002-05-01 at 18:59, Jan Harkes wrote: > Another day another update, > > Fixed the documentation error, thanks Kai, and tried to follow Al's > advice by not including ino separately, but using *(ino_t *)data for > the inode hash calculation. Don't really like it myself, but who am > I to argue and it might end up making life a bit simpler for NFS and > Intermezzo because we end up having only a single identifier for an > object. OTOH, if everything switches to icreate the filesystems will > have to provide a lookup mechanism through export_ops. Hmmm, a void * implies the FS can put whatever garbage it wants there, I'd rather see the FS cast its own icreate_args struct into one that specifies what the FS is expected to include. Something like this: struct icreate_args { ino_t ino; } and struct foofs_create_args { ino_t ino; < other foofs stuff > } struct inode *icreate(struct super_block *sb, unsigned long ino, int (*test)(struct inode *, void *), int (*set)(struct inode *, void *), struct icreate_args *); -chris ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] icreate-7 2002-05-02 14:22 ` Chris Mason @ 2002-05-03 20:26 ` Jan Harkes 2002-05-03 20:37 ` Jan Harkes ` (3 more replies) 0 siblings, 4 replies; 9+ messages in thread From: Jan Harkes @ 2002-05-03 20:26 UTC (permalink / raw) To: linux-fsdevel On Thu, May 02, 2002 at 10:22:36AM -0400, Chris Mason wrote: > Hmmm, a void * implies the FS can put whatever garbage it wants there, > I'd rather see the FS cast its own icreate_args struct into one that > specifies what the FS is expected to include. > > Something like this: > > struct icreate_args { > ino_t ino; > } > > and > > struct foofs_create_args { > ino_t ino; > < other foofs stuff > > } Yes, we could, but I still don't like it. It's jsut moving the 'ino' argument into the data part, even though it is unrelated. And why? Because the VFS uses the ino as something in it's own hashing if the inode hashtable, because the lower bits are likely to have a nice spread. The number of uses of i_ino in the VFS are very limited, - the inode hashtable (only in get_new_inode and insert_inode_hash) - to return the inode number for stat(2) (hopefully this will be replaced by a filesystem specific getattr operation). - in dcache.c:find_inode_number, used for some filesystems that fake inode numbers. The inode hashtable can be solved by having the filesystem pass the right 'hash value' along with icreate and insert_inode_hash. stat(2) will be solved by introducing getattr and find_inode_number can then use getattr on the found inode to get the actual inode number. So having the icreate prototype pass an unsigned long as well as the superblock doesn't seem to me as such a big deal. Changing insert_inode_hash to require a second argument will make it balance nicely. Once getattr is introduced we can rename inode->i_ino to inode->i_hash and we've removed all dependencies on the inode number from the VFS. struct inode *icreate(struct super_block *sb, unsigned long inode_hash, int (*test)(struct inode *, void *), int (*set)(struct inode *, void *), void *); void insert_inode_hash(struct inode *inode, unsigned long inode_hash); Jan ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] icreate-7 2002-05-03 20:26 ` Jan Harkes @ 2002-05-03 20:37 ` Jan Harkes 2002-05-05 0:49 ` [PATCH] icreate-8 [1/2] Jan Harkes ` (2 subsequent siblings) 3 siblings, 0 replies; 9+ messages in thread From: Jan Harkes @ 2002-05-03 20:37 UTC (permalink / raw) To: linux-fsdevel On Fri, May 03, 2002 at 04:26:05PM -0400, Jan Harkes wrote: > nicely. Once getattr is introduced we can rename inode->i_ino to > inode->i_hash and we've removed all dependencies on the inode number > from the VFS. Actually we could then completely remove i_ino, because it's completely in the hands of the file system which 'hash value' it wants to use and what inode numbers it likes to return in getattr. But as most UNIX filesystems will have at least a 32-bit inode number it could be kept around in the generic inode structure. Although Coda definitely wouldn't put anything useful in it anymore. Jan ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH] icreate-8 [1/2] 2002-05-03 20:26 ` Jan Harkes 2002-05-03 20:37 ` Jan Harkes @ 2002-05-05 0:49 ` Jan Harkes 2002-05-05 0:52 ` [PATCH] icreate-8 [2/2] Jan Harkes 2002-05-05 1:20 ` [PATCH] icreate-8 [3/2] Jan Harkes 3 siblings, 0 replies; 9+ messages in thread From: Jan Harkes @ 2002-05-05 0:49 UTC (permalink / raw) To: linux-fsdevel On Fri, May 03, 2002 at 04:26:05PM -0400, Jan Harkes wrote: > The number of uses of i_ino in the VFS are very limited, > > - the inode hashtable (only in get_new_inode and insert_inode_hash) > - to return the inode number for stat(2) (hopefully this will be > replaced by a filesystem specific getattr operation). > - in dcache.c:find_inode_number, used for some filesystems that fake > inode numbers. > > The inode hashtable can be solved by having the filesystem pass the > right 'hash value' along with icreate and insert_inode_hash. Here are 2 patches that 'decouple' i_ino from the hashvalue used in the inode hashtable. iunique still relies on i_ino being the same as the hashvalue, but filesystems that use iunique have 32-bit inode numbers and would use iget or icreate_light which keep these two the same. The first patch adds icreate / icreate_light. The second patch adds an additional argument to insert_inode_hash. It is clear that both Coda and NFS internally do not use i_ino anymore and only provide it for UNIX compatibility, i.e. stat(2). Jan icreate-8, relative to 2.5.13, diff -urN orig/Documentation/filesystems/Locking icreate8/Documentation/filesystems/Locking --- orig/Documentation/filesystems/Locking Wed May 1 00:27:32 2002 +++ icreate8/Documentation/filesystems/Locking Sat May 4 19:50:13 2002 @@ -115,7 +115,7 @@ remount_fs: yes yes maybe (see below) umount_begin: yes no maybe (see below) -->read_inode() is not a method - it's a callback used in iget()/iget4(). +->read_inode() is not a method - it's a callback used in iget(). rules for mount_sem are not too nice - it is going to die and be replaced by better scheme anyway. diff -urN orig/Documentation/filesystems/porting icreate8/Documentation/filesystems/porting --- orig/Documentation/filesystems/porting Mon Apr 29 10:23:27 2002 +++ icreate8/Documentation/filesystems/porting Sat May 4 19:55:58 2002 @@ -146,3 +146,36 @@ It is planned that this will be required for exporting once the code settles down a bit. + +--- +[mandatory] + +iget4() and the read_inode2 callback have been superceded by icreate() +which has the following prototype, + + struct inode *icreate(struct super_block *sb, unsigned long hashval, + int (*test)(struct inode *, void *), + int (*set)(struct inode *, void *), + void *data); + +'test' is an additional function that can be used when the inode +number is not sufficient to identify the actual file object. 'set' +should be a non-blocking function that initializes those parts of a +newly created inode to allow the test function to succeed. 'data' is +passed as an opaque value to both test and set functions. + +When the inode has been created by icreate(), it will be returned with +the I_NEW flag set and will still be locked. read_inode has not been +called so the file system still has to finalize the initialization. Once +the inode is initialized is must be unlocked by calling unlock_new_inode(). + +There is also a simpler icreate_light function that just takes the +superblock and inode number as arguments. + +e.g. + inode = icreate_light(sb, ino); + if (inode->i_state & I_NEW) { + read_inode_from_disk(inode); + unlock_new_inode(inode); + } + diff -urN orig/fs/Makefile icreate8/fs/Makefile --- orig/fs/Makefile Wed May 1 00:27:34 2002 +++ icreate8/fs/Makefile Sat May 4 19:50:13 2002 @@ -7,7 +7,7 @@ O_TARGET := fs.o -export-objs := filesystems.o open.o dcache.o buffer.o bio.o +export-objs := filesystems.o open.o dcache.o buffer.o bio.o inode.o mod-subdirs := nls obj-y := open.o read_write.o devices.o file_table.o buffer.o \ diff -urN orig/fs/coda/cnode.c icreate8/fs/coda/cnode.c --- orig/fs/coda/cnode.c Wed Apr 24 21:39:46 2002 +++ icreate8/fs/coda/cnode.c Sat May 4 20:26:07 2002 @@ -25,11 +25,6 @@ return 1; } -static int coda_inocmp(struct inode *inode, unsigned long ino, void *opaque) -{ - return (coda_fideq((ViceFid *)opaque, &(ITOC(inode)->c_fid))); -} - static struct inode_operations coda_symlink_inode_operations = { readlink: page_readlink, follow_link: page_follow_link, @@ -55,26 +50,45 @@ init_special_inode(inode, inode->i_mode, attr->va_rdev); } +static int coda_test_inode(struct inode *inode, void *data) +{ + ViceFid *fid = (ViceFid *)data; + return coda_fideq(&(ITOC(inode)->c_fid), fid); +} + +static int coda_set_inode(struct inode *inode, void *data) +{ + ViceFid *fid = (ViceFid *)data; + ITOC(inode)->c_fid = *fid; + return 0; +} + +static int coda_fail_inode(struct inode *inode, void *data) +{ + return -1; +} + + struct inode * coda_iget(struct super_block * sb, ViceFid * fid, struct coda_vattr * attr) { struct inode *inode; struct coda_inode_info *cii; - ino_t ino = coda_f2i(fid); + struct coda_sb_info *sbi = coda_sbp(sb); + unsigned long hash = coda_f2i(fid); - inode = iget4(sb, ino, coda_inocmp, fid); + inode = icreate(sb, hash, coda_test_inode, coda_set_inode, fid); if (!inode) return ERR_PTR(-ENOMEM); - /* check if the inode is already initialized */ - cii = ITOC(inode); - if (coda_isnullfid(&cii->c_fid)) - /* new, empty inode found... initializing */ - cii->c_fid = *fid; - - /* we shouldnt see inode collisions anymore */ - if (!coda_fideq(fid, &cii->c_fid)) BUG(); + if (inode->i_state & I_NEW) { + cii = ITOC(inode); + /* we still need to set i_ino for things like stat(2) */ + inode->i_ino = hash; + list_add(&cii->c_cilist, &sbi->sbi_cihead); + unlock_new_inode(inode); + } /* always replace the attributes, type might have changed */ coda_fill_inode(inode, attr); @@ -129,34 +143,22 @@ /* convert a fid to an inode. */ struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb) { - ino_t nr; struct inode *inode; - struct coda_inode_info *cii; + unsigned long hash; if ( !sb ) { printk("coda_fid_to_inode: no sb!\n"); return NULL; } - nr = coda_f2i(fid); - inode = iget4(sb, nr, coda_inocmp, fid); - if ( !inode ) { - printk("coda_fid_to_inode: null from iget, sb %p, nr %ld.\n", - sb, (long)nr); + hash = coda_f2i(fid); + inode = icreate(sb, hash, coda_test_inode, coda_fail_inode, fid); + if ( !inode ) return NULL; - } - cii = ITOC(inode); - - /* The inode could already be purged due to memory pressure */ - if (coda_isnullfid(&cii->c_fid)) { - inode->i_nlink = 0; - iput(inode); - return NULL; - } - - /* we shouldn't see inode collisions anymore */ - if ( !coda_fideq(fid, &cii->c_fid) ) BUG(); + /* we should never see newly created inodes because we intentionally + * fail in the initialization callback */ + BUG_ON(inode->i_state & I_NEW); return inode; } @@ -164,18 +166,18 @@ /* the CONTROL inode is made without asking attributes from Venus */ int coda_cnode_makectl(struct inode **inode, struct super_block *sb) { - int error = 0; + int error = -ENOMEM; + + *inode = icreate_light(sb, CTL_INO); + + if ( *inode && ((*inode)->i_state & I_NEW) ) { + (*inode)->i_op = &coda_ioctl_inode_operations; + (*inode)->i_fop = &coda_ioctl_operations; + (*inode)->i_mode = 0444; + unlock_new_inode(*inode); + error = 0; + } - *inode = iget(sb, CTL_INO); - if ( *inode ) { - (*inode)->i_op = &coda_ioctl_inode_operations; - (*inode)->i_fop = &coda_ioctl_operations; - (*inode)->i_mode = 0444; - error = 0; - } else { - error = -ENOMEM; - } - - return error; + return error; } diff -urN orig/fs/coda/inode.c icreate8/fs/coda/inode.c --- orig/fs/coda/inode.c Wed Apr 24 21:39:46 2002 +++ icreate8/fs/coda/inode.c Sat May 4 19:50:13 2002 @@ -229,16 +229,9 @@ kfree(sbi); } -/* all filling in of inodes postponed until lookup */ static void coda_read_inode(struct inode *inode) { - struct coda_sb_info *sbi = coda_sbp(inode->i_sb); - struct coda_inode_info *cii; - - if (!sbi) BUG(); - - cii = ITOC(inode); - list_add(&cii->c_cilist, &sbi->sbi_cihead); + make_bad_inode(inode); } static void coda_clear_inode(struct inode *inode) diff -urN orig/fs/inode.c icreate8/fs/inode.c --- orig/fs/inode.c Wed May 1 00:27:35 2002 +++ icreate8/fs/inode.c Sat May 4 20:01:52 2002 @@ -12,6 +12,7 @@ #include <linux/quotaops.h> #include <linux/slab.h> #include <linux/writeback.h> +#include <linux/module.h> /* * New inode.c implementation. @@ -452,7 +453,7 @@ * by hand after calling find_inode now! This simplifies iunique and won't * add any additional branch in the common code. */ -static struct inode * find_inode(struct super_block * sb, unsigned long ino, struct list_head *head, find_inode_t find_actor, void *opaque) +static struct inode * find_inode(struct super_block * sb, struct list_head *head, int (*test)(struct inode *, void *), void *data) { struct list_head *tmp; struct inode * inode; @@ -464,11 +465,9 @@ if (tmp == head) break; inode = list_entry(tmp, struct inode, i_hash); - if (inode->i_ino != ino) - continue; if (inode->i_sb != sb) continue; - if (find_actor && !find_actor(inode, ino, opaque)) + if (!test(inode, data)) continue; break; } @@ -501,53 +500,59 @@ return inode; } +void unlock_new_inode(struct inode *inode) +{ + BUG_ON(!(inode->i_state & I_NEW)); + /* + * This is special! We do not need the spinlock + * when clearing I_LOCK, because we're guaranteed + * that nobody else tries to do anything about the + * state of the inode when it is locked, as we + * just created it (so there can be no old holders + * that haven't tested I_LOCK). + */ + inode->i_state &= ~(I_LOCK|I_NEW); + wake_up(&inode->i_wait); +} + + /* * This is called without the inode lock held.. Be careful. * * We no longer cache the sb_flags in i_flags - see fs.h * -- rmk@arm.uk.linux.org */ -static struct inode * get_new_inode(struct super_block *sb, unsigned long ino, struct list_head *head, find_inode_t find_actor, void *opaque) +static struct inode * get_new_inode(struct super_block *sb, struct list_head *head, int (*test)(struct inode *, void *), int (*set)(struct inode *, void *), void *data) { struct inode * inode; + int err = 0; inode = alloc_inode(sb); if (inode) { struct inode * old; + inode->i_state = I_LOCK|I_NEW; spin_lock(&inode_lock); /* We released the lock, so.. */ - old = find_inode(sb, ino, head, find_actor, opaque); + old = find_inode(sb, head, test, data); if (!old) { - inodes_stat.nr_inodes++; - list_add(&inode->i_list, &inode_in_use); - list_add(&inode->i_hash, head); - inode->i_ino = ino; - inode->i_state = I_LOCK; + err = set(inode, data); + if (!err) { + inodes_stat.nr_inodes++; + list_add(&inode->i_list, &inode_in_use); + list_add(&inode->i_hash, head); + } spin_unlock(&inode_lock); - /* reiserfs specific hack right here. We don't - ** want this to last, and are looking for VFS changes - ** that will allow us to get rid of it. - ** -- mason@suse.com - */ - if (sb->s_op->read_inode2) { - sb->s_op->read_inode2(inode, opaque) ; - } else { - sb->s_op->read_inode(inode); + /* failed to initialize? */ + if (err) { + destroy_inode(inode); + return NULL; } - /* - * This is special! We do not need the spinlock - * when clearing I_LOCK, because we're guaranteed - * that nobody else tries to do anything about the - * state of the inode when it is locked, as we - * just created it (so there can be no old holders - * that haven't tested I_LOCK). + /* Return the locked inode with I_NEW set, the + * caller is responsible for filling in the contents */ - inode->i_state &= ~I_LOCK; - wake_up(&inode->i_wait); - return inode; } @@ -599,7 +604,8 @@ retry: if (counter > max_reserved) { head = inode_hashtable + hash(sb,counter); - inode = find_inode(sb, res = counter++, head, NULL, NULL); + res = counter++; + inode = find_inode(sb, head, test_inode_i_ino, &res); if (!inode) { spin_unlock(&inode_lock); return res; @@ -627,14 +633,18 @@ return inode; } - -struct inode *iget4(struct super_block *sb, unsigned long ino, find_inode_t find_actor, void *opaque) +/* + * This is iget without the read_inode portion of get_new_inode + * the filesystem gets back a new locked and hashed inode and gets + * to fill it in before unlocking it via unlock_new_inode(). + */ +struct inode *icreate(struct super_block *sb, unsigned long hashval, int (*test)(struct inode *, void *), int (*set)(struct inode *, void *), void *data) { - struct list_head * head = inode_hashtable + hash(sb,ino); + struct list_head * head = inode_hashtable + hash(sb, hashval); struct inode * inode; spin_lock(&inode_lock); - inode = find_inode(sb, ino, head, find_actor, opaque); + inode = find_inode(sb, head, test, data); if (inode) { __iget(inode); spin_unlock(&inode_lock); @@ -643,12 +653,31 @@ } spin_unlock(&inode_lock); - /* - * get_new_inode() will do the right thing, re-trying the search - * in case it had to block at any point. - */ - return get_new_inode(sb, ino, head, find_actor, opaque); + return get_new_inode(sb, head, test, set, data); +} + +static int test_inode_i_ino(struct inode *inode, void *data) +{ + unsigned long *ino = (unsigned long *)data; + return inode->i_ino == *ino; +} + +static int set_inode_i_ino(struct inode *inode, void *data) +{ + unsigned long *ino = (unsigned long *)data; + inode->i_ino = *ino; + return 0; +} + +struct inode *icreate_light(struct super_block *sb, unsigned long ino) +{ + unsigned long hashval = ino; + return icreate(sb, hashval, test_inode_i_ino, set_inode_i_ino, &ino); } + +EXPORT_SYMBOL(icreate); +EXPORT_SYMBOL(icreate_light); +EXPORT_SYMBOL(unlock_new_inode); /** * insert_inode_hash - hash an inode diff -urN orig/fs/nfs/inode.c icreate8/fs/nfs/inode.c --- orig/fs/nfs/inode.c Wed May 1 00:27:35 2002 +++ icreate8/fs/nfs/inode.c Sat May 4 20:25:28 2002 @@ -592,7 +592,7 @@ * i_ino. */ static int -nfs_find_actor(struct inode *inode, unsigned long ino, void *opaque) +nfs_find_actor(struct inode *inode, void *opaque) { struct nfs_find_desc *desc = (struct nfs_find_desc *)opaque; struct nfs_fh *fh = desc->fh; @@ -610,6 +610,18 @@ return 1; } +static int +nfs_init_locked(struct inode *inode, void *opaque) +{ + struct nfs_find_desc *desc = (struct nfs_find_desc *)opaque; + struct nfs_fh *fh = desc->fh; + struct nfs_fattr *fattr = desc->fattr; + + NFS_FILEID(inode) = fattr->fileid; + memcpy(NFS_FH(inode), fh, sizeof(struct nfs_fh)); + return 0; +} + /* * This is our own version of iget that looks up inodes by file handle * instead of inode number. We use this technique instead of using @@ -640,7 +652,7 @@ fattr: fattr }; struct inode *inode = NULL; - unsigned long ino; + unsigned long hash; if ((fattr->valid & NFS_ATTR_FATTR) == 0) goto out_no_inode; @@ -650,20 +662,21 @@ goto out_no_inode; } - ino = nfs_fattr_to_ino_t(fattr); + hash = nfs_fattr_to_ino_t(fattr); - if (!(inode = iget4(sb, ino, nfs_find_actor, &desc))) + if (!(inode = icreate(sb, hash, nfs_find_actor, nfs_init_locked, &desc))) goto out_no_inode; - if (NFS_NEW(inode)) { + if (inode->i_state & I_NEW) { __u64 new_size, new_mtime; loff_t new_isize; time_t new_atime; + /* we set i_ino for the few things that still rely on it, + * such as stat(2) */ + inode->i_ino = hash; + /* We can't support UPDATE_ATIME(), since the server will reset it */ - NFS_FLAGS(inode) &= ~NFS_INO_NEW; - NFS_FILEID(inode) = fattr->fileid; - memcpy(NFS_FH(inode), fh, sizeof(struct nfs_fh)); inode->i_flags |= S_NOATIME; inode->i_mode = fattr->mode; /* Why so? Because we want revalidate for devices/FIFOs, and @@ -711,6 +724,8 @@ NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode); NFS_ATTRTIMEO_UPDATE(inode) = jiffies; memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); + + unlock_new_inode(inode); } else nfs_refresh_inode(inode, fattr); dprintk("NFS: __nfs_fhget(%s/%Ld ct=%d)\n", @@ -1231,7 +1246,6 @@ nfsi = (struct nfs_inode *)kmem_cache_alloc(nfs_inode_cachep, SLAB_KERNEL); if (!nfsi) return NULL; - nfsi->flags = NFS_INO_NEW; nfsi->mm_cred = NULL; return &nfsi->vfs_inode; } diff -urN orig/fs/reiserfs/inode.c icreate8/fs/reiserfs/inode.c --- orig/fs/reiserfs/inode.c Wed May 1 00:27:35 2002 +++ icreate8/fs/reiserfs/inode.c Sat May 4 20:13:13 2002 @@ -33,7 +33,7 @@ lock_kernel() ; /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */ - if (INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */ + if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */ down (&inode->i_sem); journal_begin(&th, inode->i_sb, jbegin_count) ; @@ -1140,20 +1140,22 @@ /* looks for stat data in the tree, and fills up the fields of in-core inode stat data fields */ -void reiserfs_read_inode2 (struct inode * inode, void *p) +int reiserfs_init_locked_inode (struct inode * inode, void *p) +{ + struct reiserfs_icreate_args *args = (struct reiserfs_icreate_args *)p ; + inode->i_ino = args->objectid; + INODE_PKEY(inode)->k_dir_id = cpu_to_le32(args->dirid); + return 0; +} + +void reiserfs_read_locked_inode (struct inode * inode, struct reiserfs_icreate_args *args) { INITIALIZE_PATH (path_to_sd); struct cpu_key key; - struct reiserfs_iget4_args *args = (struct reiserfs_iget4_args *)p ; unsigned long dirino; int retval; - if (!p) { - reiserfs_make_bad_inode(inode) ; - return; - } - - dirino = args->objectid ; + dirino = args->dirid ; /* set version 1, version 2 could be used too, because stat data key is the same in both versions */ @@ -1210,38 +1212,44 @@ } /** - * reiserfs_find_actor() - "find actor" reiserfs supplies to iget4(). + * reiserfs_find_actor() - "find actor" reiserfs supplies to icreate(). * * @inode: inode from hash table to check * @inode_no: inode number we are looking for - * @opaque: "cookie" passed to iget4(). This is &reiserfs_iget4_args. + * @opaque: "cookie" passed to icreate(). This is &reiserfs_icreate_args. * - * This function is called by iget4() to distinguish reiserfs inodes + * This function is called by icreate() to distinguish reiserfs inodes * having the same inode numbers. Such inodes can only exist due to some * error condition. One of them should be bad. Inodes with identical * inode numbers (objectids) are distinguished by parent directory ids. * */ -static int reiserfs_find_actor( struct inode *inode, - unsigned long inode_no, void *opaque ) +static int reiserfs_find_actor( struct inode *inode, void *opaque ) { - struct reiserfs_iget4_args *args; + struct reiserfs_icreate_args *args; args = opaque; /* args is already in CPU order */ - return le32_to_cpu(INODE_PKEY(inode)->k_dir_id) == args -> objectid; + return (inode->i_ino == args->objectid) && + (le32_to_cpu(INODE_PKEY(inode)->k_dir_id) == args->dirid); } struct inode * reiserfs_iget (struct super_block * s, const struct cpu_key * key) { struct inode * inode; - struct reiserfs_iget4_args args ; + struct reiserfs_icreate_args args ; - args.objectid = key->on_disk_key.k_dir_id ; - inode = iget4 (s, key->on_disk_key.k_objectid, - reiserfs_find_actor, (void *)(&args)); + args.objectid = key->on_disk_key.k_objectid ; + args.dirid = key->on_disk_key.k_dir_id ; + inode = icreate(s, key->on_disk_key.k_objectid, + reiserfs_find_actor, reiserfs_init_locked_inode, (void *)(&args)); if (!inode) return ERR_PTR(-ENOMEM) ; + + if (inode->i_state & I_NEW) { + reiserfs_read_locked_inode(inode, &args); + unlock_new_inode(inode); + } if (comp_short_keys (INODE_PKEY (inode), key) || is_bad_inode (inode)) { /* either due to i/o error or a stale NFS handle */ diff -urN orig/fs/reiserfs/super.c icreate8/fs/reiserfs/super.c --- orig/fs/reiserfs/super.c Mon Apr 22 23:04:19 2002 +++ icreate8/fs/reiserfs/super.c Sat May 4 20:15:02 2002 @@ -485,7 +485,6 @@ alloc_inode: reiserfs_alloc_inode, destroy_inode: reiserfs_destroy_inode, read_inode: reiserfs_read_inode, - read_inode2: reiserfs_read_inode2, write_inode: reiserfs_write_inode, dirty_inode: reiserfs_dirty_inode, delete_inode: reiserfs_delete_inode, @@ -1002,7 +1001,7 @@ int old_format = 0; unsigned long blocks; int jinit_done = 0 ; - struct reiserfs_iget4_args args ; + struct reiserfs_icreate_args args ; struct reiserfs_super_block * rs; char *jdev_name; struct reiserfs_sb_info *sbi; @@ -1064,11 +1063,17 @@ printk("clm-7000: Detected readonly device, marking FS readonly\n") ; s->s_flags |= MS_RDONLY ; } - args.objectid = REISERFS_ROOT_PARENT_OBJECTID ; - root_inode = iget4 (s, REISERFS_ROOT_OBJECTID, 0, (void *)(&args)); + args.objectid = REISERFS_ROOT_OBJECTID ; + args.dirid = REISERFS_ROOT_PARENT_OBJECTID ; + root_inode = icreate (s, REISERFS_ROOT_OBJECTID, reiserfs_find_actor, reiserfs_init_locked_inode, (void *)(&args)); if (!root_inode) { printk ("reiserfs_fill_super: get root inode failed\n"); goto error; + } + + if (root_inode->i_state & I_NEW) { + reiserfs_read_locked_inode(root_inode, &args); + unlock_new_inode(root_inode); } s->s_root = d_alloc_root(root_inode); diff -urN orig/include/linux/fs.h icreate8/include/linux/fs.h --- orig/include/linux/fs.h Sat May 4 19:25:53 2002 +++ icreate8/include/linux/fs.h Sat May 4 20:02:41 2002 @@ -778,13 +778,6 @@ void (*read_inode) (struct inode *); - /* reiserfs kludge. reiserfs needs 64 bits of information to - ** find an inode. We are using the read_inode2 call to get - ** that information. We don't like this, and are waiting on some - ** VFS changes for the real solution. - ** iget4 calls read_inode2, iff it is defined - */ - void (*read_inode2) (struct inode *, void *) ; void (*dirty_inode) (struct inode *); void (*write_inode) (struct inode *, int); void (*put_inode) (struct inode *); @@ -832,6 +825,7 @@ #define I_LOCK 8 #define I_FREEING 16 #define I_CLEAR 32 +#define I_NEW 64 #define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES) @@ -1240,11 +1234,22 @@ extern struct inode * igrab(struct inode *); extern ino_t iunique(struct super_block *, ino_t); -typedef int (*find_inode_t)(struct inode *, unsigned long, void *); -extern struct inode * iget4(struct super_block *, unsigned long, find_inode_t, void *); +extern struct inode * icreate(struct super_block *, unsigned long, int (*test)(struct inode *, void *), int (*set)(struct inode *, void *), void *data); +extern struct inode * icreate_light(struct super_block *, unsigned long); +extern void unlock_new_inode(struct inode *); + static inline struct inode *iget(struct super_block *sb, unsigned long ino) { - return iget4(sb, ino, NULL, NULL); + struct inode *inode; + + inode = icreate_light(sb, ino); + + if (inode && (inode->i_state & I_NEW)) { + sb->s_op->read_inode(inode); + unlock_new_inode(inode); + } + + return inode; } extern void __iget(struct inode * inode); diff -urN orig/include/linux/nfs_fs.h icreate8/include/linux/nfs_fs.h --- orig/include/linux/nfs_fs.h Thu May 2 15:49:56 2002 +++ icreate8/include/linux/nfs_fs.h Sat May 4 19:50:13 2002 @@ -170,7 +170,6 @@ #define NFS_INO_REVALIDATING 0x0004 /* revalidating attrs */ #define NFS_IS_SNAPSHOT 0x0010 /* a snapshot file */ #define NFS_INO_FLUSH 0x0020 /* inode is due for flushing */ -#define NFS_INO_NEW 0x0040 /* hadn't been filled yet */ static inline struct nfs_inode *NFS_I(struct inode *inode) { @@ -208,7 +207,6 @@ #define NFS_FLAGS(inode) (NFS_I(inode)->flags) #define NFS_REVALIDATING(inode) (NFS_FLAGS(inode) & NFS_INO_REVALIDATING) #define NFS_STALE(inode) (NFS_FLAGS(inode) & NFS_INO_STALE) -#define NFS_NEW(inode) (NFS_FLAGS(inode) & NFS_INO_NEW) #define NFS_FILEID(inode) (NFS_I(inode)->fileid) diff -urN orig/include/linux/reiserfs_fs.h icreate8/include/linux/reiserfs_fs.h --- orig/include/linux/reiserfs_fs.h Wed Apr 24 18:28:43 2002 +++ icreate8/include/linux/reiserfs_fs.h Sat May 4 20:09:42 2002 @@ -1564,8 +1564,9 @@ #define B_I_POS_UNFM_POINTER(bh,ih,pos) le32_to_cpu(*(((unp_t *)B_I_PITEM(bh,ih)) + (pos))) #define PUT_B_I_POS_UNFM_POINTER(bh,ih,pos, val) do {*(((unp_t *)B_I_PITEM(bh,ih)) + (pos)) = cpu_to_le32(val); } while (0) -struct reiserfs_iget4_args { +struct reiserfs_icreate_args { __u32 objectid ; + __u32 dirid ; } ; /***************************************************************************/ @@ -1819,7 +1820,8 @@ /* inode.c */ void reiserfs_read_inode (struct inode * inode) ; -void reiserfs_read_inode2(struct inode * inode, void *p) ; +int reiserfs_init_locked_inode(struct inode * inode, void *p) ; +void reiserfs_read_locked_inode(struct inode * inode, struct reiserfs_icreate_args *args) ; void reiserfs_delete_inode (struct inode * inode); void reiserfs_write_inode (struct inode * inode, int) ; struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, __u32 *data, diff -urN orig/kernel/ksyms.c icreate8/kernel/ksyms.c --- orig/kernel/ksyms.c Sat May 4 19:25:54 2002 +++ icreate8/kernel/ksyms.c Sat May 4 19:50:13 2002 @@ -137,7 +137,6 @@ EXPORT_SYMBOL(fget); EXPORT_SYMBOL(igrab); EXPORT_SYMBOL(iunique); -EXPORT_SYMBOL(iget4); EXPORT_SYMBOL(iput); EXPORT_SYMBOL(inode_init_once); EXPORT_SYMBOL(force_delete); ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH] icreate-8 [2/2] 2002-05-03 20:26 ` Jan Harkes 2002-05-03 20:37 ` Jan Harkes 2002-05-05 0:49 ` [PATCH] icreate-8 [1/2] Jan Harkes @ 2002-05-05 0:52 ` Jan Harkes 2002-05-05 1:20 ` [PATCH] icreate-8 [3/2] Jan Harkes 3 siblings, 0 replies; 9+ messages in thread From: Jan Harkes @ 2002-05-05 0:52 UTC (permalink / raw) To: linux-fsdevel This patch adds an hashval argument to insert_inode_hash. relative to previous icreate8 diff -urN icreate8/fs/adfs/inode.c icreate9/fs/adfs/inode.c --- icreate8/fs/adfs/inode.c Mon Apr 22 23:04:15 2002 +++ icreate9/fs/adfs/inode.c Sat May 4 20:30:24 2002 @@ -284,7 +284,7 @@ ADFS_I(inode)->mmu_private = inode->i_size; } - insert_inode_hash(inode); + insert_inode_hash(inode, inode->i_ino); out: return inode; diff -urN icreate8/fs/affs/inode.c icreate9/fs/affs/inode.c --- icreate8/fs/affs/inode.c Mon Apr 22 23:04:15 2002 +++ icreate9/fs/affs/inode.c Sat May 4 20:30:27 2002 @@ -345,7 +345,7 @@ AFFS_I(inode)->i_extcnt = 1; AFFS_I(inode)->i_ext_last = ~1; - insert_inode_hash(inode); + insert_inode_hash(inode, inode->i_ino); return inode; diff -urN icreate8/fs/bfs/dir.c icreate9/fs/bfs/dir.c --- icreate8/fs/bfs/dir.c Wed May 1 00:27:34 2002 +++ icreate9/fs/bfs/dir.c Sat May 4 20:30:32 2002 @@ -110,7 +110,7 @@ BFS_I(inode)->i_dsk_ino = ino; BFS_I(inode)->i_sblock = 0; BFS_I(inode)->i_eblock = 0; - insert_inode_hash(inode); + insert_inode_hash(inode, inode->i_ino); mark_inode_dirty(inode); dump_imap("create",s); diff -urN icreate8/fs/coda/cnode.c icreate9/fs/coda/cnode.c --- icreate8/fs/coda/cnode.c Sat May 4 20:26:07 2002 +++ icreate9/fs/coda/cnode.c Sat May 4 20:30:52 2002 @@ -137,7 +137,7 @@ remove_inode_hash(inode); cii->c_fid = *newfid; inode->i_ino = coda_f2i(newfid); - insert_inode_hash(inode); + insert_inode_hash(inode, inode->i_ino); } /* convert a fid to an inode. */ diff -urN icreate8/fs/cramfs/inode.c icreate9/fs/cramfs/inode.c --- icreate8/fs/cramfs/inode.c Wed May 1 00:27:34 2002 +++ icreate9/fs/cramfs/inode.c Sat May 4 20:30:58 2002 @@ -55,7 +55,7 @@ but it's the best we can do without reading the directory contents. 1 yields the right result in GNU find, even without -noleaf option. */ - insert_inode_hash(inode); + insert_inode_hash(inode, inode->i_ino); if (S_ISREG(inode->i_mode)) { inode->i_fop = &generic_ro_fops; inode->i_data.a_ops = &cramfs_aops; diff -urN icreate8/fs/ext2/ialloc.c icreate9/fs/ext2/ialloc.c --- icreate8/fs/ext2/ialloc.c Mon Apr 22 23:04:15 2002 +++ icreate9/fs/ext2/ialloc.c Sat May 4 20:31:01 2002 @@ -405,7 +405,7 @@ if (ei->i_flags & EXT2_SYNC_FL) inode->i_flags |= S_SYNC; inode->i_generation = EXT2_SB(sb)->s_next_generation++; - insert_inode_hash(inode); + insert_inode_hash(inode, inode->i_ino); mark_inode_dirty(inode); unlock_super (sb); diff -urN icreate8/fs/ext3/ialloc.c icreate9/fs/ext3/ialloc.c --- icreate8/fs/ext3/ialloc.c Mon Apr 22 23:04:15 2002 +++ icreate9/fs/ext3/ialloc.c Sat May 4 20:31:04 2002 @@ -508,7 +508,7 @@ inode->i_flags |= S_SYNC; if (IS_SYNC(inode)) handle->h_sync = 1; - insert_inode_hash(inode); + insert_inode_hash(inode, inode->i_ino); inode->i_generation = sb->u.ext3_sb.s_next_generation++; ei->i_state = EXT3_STATE_NEW; diff -urN icreate8/fs/fat/inode.c icreate9/fs/fat/inode.c --- icreate8/fs/fat/inode.c Mon Apr 29 10:23:36 2002 +++ icreate9/fs/fat/inode.c Sat May 4 20:33:11 2002 @@ -143,7 +143,7 @@ goto out; } fat_attach(inode, ino); - insert_inode_hash(inode); + insert_inode_hash(inode, inode->i_ino); out: return inode; } @@ -846,7 +846,7 @@ if (error < 0) goto out_fail; error = -ENOMEM; - insert_inode_hash(root_inode); + insert_inode_hash(root_inode, root_inode->i_ino); sb->s_root = d_alloc_root(root_inode); if (!sb->s_root) { printk("FAT: get root inode failed\n"); diff -urN icreate8/fs/inode.c icreate9/fs/inode.c --- icreate8/fs/inode.c Sat May 4 20:01:52 2002 +++ icreate9/fs/inode.c Sat May 4 20:29:19 2002 @@ -570,9 +570,9 @@ return inode; } -static inline unsigned long hash(struct super_block *sb, unsigned long i_ino) +static inline unsigned long hash(struct super_block *sb, unsigned long hashval) { - unsigned long tmp = i_ino + ((unsigned long) sb / L1_CACHE_BYTES); + unsigned long tmp = hashval + ((unsigned long) sb / L1_CACHE_BYTES); tmp = tmp + (tmp >> I_HASHBITS); return tmp & I_HASHMASK; } @@ -682,16 +682,17 @@ /** * insert_inode_hash - hash an inode * @inode: unhashed inode + * @hashval: 32-bit persistent inode identifier * * Add an inode to the inode hash for this superblock. If the inode * has no superblock it is added to a separate anonymous chain. */ -void insert_inode_hash(struct inode *inode) +void insert_inode_hash(struct inode *inode, unsigned long hashval) { struct list_head *head = &anon_hash_chain; if (inode->i_sb) - head = inode_hashtable + hash(inode->i_sb, inode->i_ino); + head = inode_hashtable + hash(inode->i_sb, hashval); spin_lock(&inode_lock); list_add(&inode->i_hash, head); spin_unlock(&inode_lock); diff -urN icreate8/fs/jffs/inode-v23.c icreate9/fs/jffs/inode-v23.c --- icreate8/fs/jffs/inode-v23.c Wed May 1 00:27:35 2002 +++ icreate9/fs/jffs/inode-v23.c Sat May 4 20:31:13 2002 @@ -374,7 +374,7 @@ f = jffs_find_file(c, raw_inode->ino); inode->u.generic_ip = (void *)f; - insert_inode_hash(inode); + insert_inode_hash(inode, inode->i_ino); return inode; } diff -urN icreate8/fs/jffs2/fs.c icreate9/fs/jffs2/fs.c --- icreate8/fs/jffs2/fs.c Wed Apr 24 18:28:43 2002 +++ icreate9/fs/jffs2/fs.c Sat May 4 20:31:15 2002 @@ -390,7 +390,7 @@ inode->i_blocks = 0; inode->i_size = 0; - insert_inode_hash(inode); + insert_inode_hash(inode, inode->i_ino); return inode; } diff -urN icreate8/fs/jfs/namei.c icreate9/fs/jfs/namei.c --- icreate8/fs/jfs/namei.c Wed May 1 00:27:35 2002 +++ icreate9/fs/jfs/namei.c Sat May 4 20:31:40 2002 @@ -133,7 +133,7 @@ ip->i_fop = &jfs_file_operations; ip->i_mapping->a_ops = &jfs_aops; - insert_inode_hash(ip); + insert_inode_hash(ip, ip->i_ino); mark_inode_dirty(ip); d_instantiate(dentry, ip); @@ -257,7 +257,7 @@ ip->i_mapping->a_ops = &jfs_aops; ip->i_mapping->gfp_mask = GFP_NOFS; - insert_inode_hash(ip); + insert_inode_hash(ip, ip->i_ino); mark_inode_dirty(ip); d_instantiate(dentry, ip); @@ -991,7 +991,7 @@ } dip->i_version = ++event; - insert_inode_hash(ip); + insert_inode_hash(ip, ip->i_ino); mark_inode_dirty(ip); d_instantiate(dentry, ip); @@ -1353,7 +1353,7 @@ init_special_inode(ip, ip->i_mode, rdev); - insert_inode_hash(ip); + insert_inode_hash(ip, ip->i_ino); mark_inode_dirty(ip); d_instantiate(dentry, ip); diff -urN icreate8/fs/minix/bitmap.c icreate9/fs/minix/bitmap.c --- icreate8/fs/minix/bitmap.c Mon Apr 22 23:04:17 2002 +++ icreate9/fs/minix/bitmap.c Sat May 4 20:31:45 2002 @@ -252,7 +252,7 @@ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; inode->i_blocks = inode->i_blksize = 0; memset(&minix_i(inode)->u, 0, sizeof(minix_i(inode)->u)); - insert_inode_hash(inode); + insert_inode_hash(inode, ip->i_ino); mark_inode_dirty(inode); *error = 0; diff -urN icreate8/fs/ncpfs/inode.c icreate9/fs/ncpfs/inode.c --- icreate8/fs/ncpfs/inode.c Mon Apr 22 23:04:17 2002 +++ icreate9/fs/ncpfs/inode.c Sat May 4 20:32:09 2002 @@ -281,7 +281,7 @@ inode->i_data.a_ops = &ncp_symlink_aops; #endif } - insert_inode_hash(inode); + insert_inode_hash(inode, inode->i_ino); } else printk(KERN_ERR "ncp_iget: iget failed!\n"); return inode; diff -urN icreate8/fs/reiserfs/inode.c icreate9/fs/reiserfs/inode.c --- icreate8/fs/reiserfs/inode.c Sat May 4 20:13:13 2002 +++ icreate9/fs/reiserfs/inode.c Sat May 4 20:32:05 2002 @@ -1641,7 +1641,7 @@ return NULL; } - insert_inode_hash (inode); + insert_inode_hash (inode, inode->i_ino); // we do not mark inode dirty: on disk content matches to the // in-core one reiserfs_check_path(&path_to_key) ; diff -urN icreate8/fs/smbfs/inode.c icreate9/fs/smbfs/inode.c --- icreate8/fs/smbfs/inode.c Wed May 1 00:27:36 2002 +++ icreate9/fs/smbfs/inode.c Sat May 4 20:32:24 2002 @@ -130,7 +130,7 @@ result->i_op = &smb_dir_inode_operations; result->i_fop = &smb_dir_operations; } - insert_inode_hash(result); + insert_inode_hash(result, result->i_ino); return result; } diff -urN icreate8/fs/sysv/ialloc.c icreate9/fs/sysv/ialloc.c --- icreate8/fs/sysv/ialloc.c Wed May 1 00:27:36 2002 +++ icreate9/fs/sysv/ialloc.c Sat May 4 20:32:38 2002 @@ -172,7 +172,7 @@ inode->i_blocks = inode->i_blksize = 0; memset(SYSV_I(inode)->i_data, 0, sizeof(SYSV_I(inode)->i_data)); SYSV_I(inode)->i_dir_start_lookup = 0; - insert_inode_hash(inode); + insert_inode_hash(inode, inode->i_ino); mark_inode_dirty(inode); inode->i_mode = mode; /* for sysv_write_inode() */ diff -urN icreate8/fs/udf/ialloc.c icreate9/fs/udf/ialloc.c --- icreate8/fs/udf/ialloc.c Tue Mar 19 21:02:11 2002 +++ icreate9/fs/udf/ialloc.c Sat May 4 20:33:35 2002 @@ -153,7 +153,7 @@ UDF_I_UMTIME(inode) = UDF_I_UCTIME(inode) = UDF_I_UCRTIME(inode) = CURRENT_UTIME; UDF_I_NEW_INODE(inode) = 1; - insert_inode_hash(inode); + insert_inode_hash(inode, inode->i_ino); mark_inode_dirty(inode); unlock_super(sb); diff -urN icreate8/fs/ufs/ialloc.c icreate9/fs/ufs/ialloc.c --- icreate8/fs/ufs/ialloc.c Thu Feb 28 22:27:25 2002 +++ icreate9/fs/ufs/ialloc.c Sat May 4 20:32:45 2002 @@ -271,7 +271,7 @@ ufsi->i_oeftflag = 0; memset(&ufsi->i_u1, 0, sizeof(ufsi->i_u1)); - insert_inode_hash(inode); + insert_inode_hash(inode, inode->i_ino); mark_inode_dirty(inode); unlock_super (sb); diff -urN icreate8/include/linux/fs.h icreate9/include/linux/fs.h --- icreate8/include/linux/fs.h Sat May 4 20:02:41 2002 +++ icreate9/include/linux/fs.h Sat May 4 20:29:40 2002 @@ -1256,7 +1256,7 @@ extern void clear_inode(struct inode *); extern struct inode *new_inode(struct super_block *); extern void remove_suid(struct dentry *); -extern void insert_inode_hash(struct inode *); +extern void insert_inode_hash(struct inode *, unsigned long); extern void remove_inode_hash(struct inode *); extern struct file * get_empty_filp(void); extern void file_move(struct file *f, struct list_head *list); ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH] icreate-8 [3/2] 2002-05-03 20:26 ` Jan Harkes ` (2 preceding siblings ...) 2002-05-05 0:52 ` [PATCH] icreate-8 [2/2] Jan Harkes @ 2002-05-05 1:20 ` Jan Harkes 3 siblings, 0 replies; 9+ messages in thread From: Jan Harkes @ 2002-05-05 1:20 UTC (permalink / raw) To: linux-fsdevel Adding small compile fixes only to your build tree is evil. diff -urN icreate9/fs/inode.c icreate10/fs/inode.c --- icreate9/fs/inode.c Sat May 4 21:14:22 2002 +++ icreate10/fs/inode.c Sat May 4 21:17:01 2002 @@ -570,6 +570,21 @@ return inode; } +/* helper functions for icreate_light and iunique */ +static int test_inode_i_ino(struct inode *inode, void *data) +{ + unsigned long *ino = (unsigned long *)data; + return inode->i_ino == *ino; +} + +static int set_inode_i_ino(struct inode *inode, void *data) +{ + unsigned long *ino = (unsigned long *)data; + inode->i_ino = *ino; + return 0; +} + + static inline unsigned long hash(struct super_block *sb, unsigned long hashval) { unsigned long tmp = hashval + ((unsigned long) sb / L1_CACHE_BYTES); @@ -654,19 +669,6 @@ spin_unlock(&inode_lock); return get_new_inode(sb, head, test, set, data); -} - -static int test_inode_i_ino(struct inode *inode, void *data) -{ - unsigned long *ino = (unsigned long *)data; - return inode->i_ino == *ino; -} - -static int set_inode_i_ino(struct inode *inode, void *data) -{ - unsigned long *ino = (unsigned long *)data; - inode->i_ino = *ino; - return 0; } struct inode *icreate_light(struct super_block *sb, unsigned long ino) ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2002-05-05 1:20 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2002-05-01 22:59 [PATCH] icreate-7 Jan Harkes 2002-05-01 23:58 ` Anton Altaparmakov 2002-05-02 0:19 ` Jan Harkes 2002-05-02 14:22 ` Chris Mason 2002-05-03 20:26 ` Jan Harkes 2002-05-03 20:37 ` Jan Harkes 2002-05-05 0:49 ` [PATCH] icreate-8 [1/2] Jan Harkes 2002-05-05 0:52 ` [PATCH] icreate-8 [2/2] Jan Harkes 2002-05-05 1:20 ` [PATCH] icreate-8 [3/2] Jan Harkes
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.