iopen has been already removed from the patch series, but it is still referenced in many places.
Change-Id: I512ce8ceef11d99f812f1348a5b53552b3ac1a42
Signed-off-by: Johann Lombardi <johann@whamcloud.com>
Reviewed-on: http://review.whamcloud.com/417
Tested-by: Hudson
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
[__d_rehash is exported by the kernel])],
[])
-LB_CHECK_SYMBOL_EXPORT([d_move_locked],
- [fs/dcache.c],
- [AC_DEFINE(HAVE_D_MOVE_LOCKED, 1,
- [d_move_locked is exported by the kernel])],
- [])
-
-LB_CHECK_SYMBOL_EXPORT([__d_move],
- [fs/dcache.c],
- [AC_DEFINE(HAVE___D_MOVE, 1,
- [__d_move exported by the kernel])],
- [])
-
LB_CONFIG_FILES
AC_CONFIG_FILES([ldiskfs/autoMakefile ldiskfs/Makefile])
+++ /dev/null
-Index: linux-2.6.18-128.1.6/fs/ext4/iopen.c
-===================================================================
---- /dev/null
-+++ linux-2.6.18-128.1.6/fs/ext4/iopen.c
-@@ -0,0 +1,295 @@
-+/*
-+ * linux/fs/ext4/iopen.c
-+ *
-+ * Special support for open by inode number
-+ *
-+ * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu).
-+ *
-+ * This file may be redistributed under the terms of the GNU General
-+ * Public License.
-+ *
-+ *
-+ * Invariants:
-+ * - there is only ever a single DCACHE_NFSD_DISCONNECTED dentry alias
-+ * for an inode at one time.
-+ * - there are never both connected and DCACHE_NFSD_DISCONNECTED dentry
-+ * aliases on an inode at the same time.
-+ *
-+ * If we have any connected dentry aliases for an inode, use one of those
-+ * in iopen_lookup(). Otherwise, we instantiate a single NFSD_DISCONNECTED
-+ * dentry for this inode, which thereafter will be found by the dcache
-+ * when looking up this inode number in __iopen__, so we don't return here
-+ * until it is gone.
-+ *
-+ * If we get an inode via a regular name lookup, then we "rename" the
-+ * NFSD_DISCONNECTED dentry to the proper name and parent. This ensures
-+ * existing users of the disconnected dentry will continue to use the same
-+ * dentry as the connected users, and there will never be both kinds of
-+ * dentry aliases at one time.
-+ */
-+
-+#include <linux/sched.h>
-+#include <linux/fs.h>
-+#include <linux/smp_lock.h>
-+#include <linux/dcache.h>
-+#include <linux/security.h>
-+#include "iopen.h"
-+#include "ext4.h"
-+#include "ext4_jbd2.h"
-+
-+#ifndef assert
-+#define assert(test) J_ASSERT(test)
-+#endif
-+
-+#define IOPEN_NAME_LEN 32
-+
-+/*
-+ * This implements looking up an inode by number.
-+ */
-+static struct dentry *iopen_lookup(struct inode * dir, struct dentry *dentry,
-+ struct nameidata *nd)
-+{
-+ struct inode *inode;
-+ unsigned long ino;
-+ struct list_head *lp;
-+ struct dentry *alternate;
-+ char buf[IOPEN_NAME_LEN];
-+
-+ if (dentry->d_name.len >= IOPEN_NAME_LEN)
-+ return ERR_PTR(-ENAMETOOLONG);
-+
-+ memcpy(buf, dentry->d_name.name, dentry->d_name.len);
-+ buf[dentry->d_name.len] = 0;
-+
-+ if (strcmp(buf, ".") == 0)
-+ ino = dir->i_ino;
-+ else if (strcmp(buf, "..") == 0)
-+ ino = EXT4_ROOT_INO;
-+ else
-+ ino = simple_strtoul(buf, 0, 0);
-+
-+ if ((ino != EXT4_ROOT_INO &&
-+ ino < EXT4_FIRST_INO(dir->i_sb)) ||
-+ ino > le32_to_cpu(EXT4_SB(dir->i_sb)->s_es->s_inodes_count))
-+ return ERR_PTR(-ENOENT);
-+
-+ inode = ext4_iget(dir->i_sb, ino);
-+ if (IS_ERR(inode)) {
-+ /* Newer kernels return -ESTALE for inodes that are not in use,
-+ * but older kernels return a negative dentry. This can only
-+ * happen when doing a lookup in the __iopen__ dir, because the
-+ * "entry" will always be found even if inode is unallocated.
-+ * Handle this here instead of fixing the callers. b=19114 */
-+ if (PTR_ERR(inode) == -ESTALE)
-+ return (ERR_PTR(-ENOENT));
-+ return ERR_CAST(inode);
-+ }
-+
-+ assert(list_empty(&dentry->d_alias)); /* d_instantiate */
-+ assert(d_unhashed(dentry)); /* d_rehash */
-+
-+ /* preferrably return a connected dentry */
-+ spin_lock(&dcache_lock);
-+ list_for_each(lp, &inode->i_dentry) {
-+ alternate = list_entry(lp, struct dentry, d_alias);
-+ assert(!(alternate->d_flags & DCACHE_DISCONNECTED));
-+ }
-+
-+ if (!list_empty(&inode->i_dentry)) {
-+ alternate = list_entry(inode->i_dentry.next,
-+ struct dentry, d_alias);
-+ dget_locked(alternate);
-+ spin_lock(&alternate->d_lock);
-+ alternate->d_flags |= DCACHE_REFERENCED;
-+ spin_unlock(&alternate->d_lock);
-+ iput(inode);
-+ spin_unlock(&dcache_lock);
-+ return alternate;
-+ }
-+ dentry->d_flags |= DCACHE_DISCONNECTED;
-+
-+ /* d_add(), but don't drop dcache_lock before adding dentry to inode */
-+ list_add(&dentry->d_alias, &inode->i_dentry); /* d_instantiate */
-+ dentry->d_inode = inode;
-+
-+ d_rehash_cond(dentry, 0);
-+ spin_unlock(&dcache_lock);
-+
-+ return NULL;
-+}
-+
-+/* This function is spliced into ext4_lookup and does the move of a
-+ * disconnected dentry (if it exists) to a connected dentry.
-+ */
-+struct dentry *iopen_connect_dentry(struct dentry *dentry, struct inode *inode,
-+ int rehash)
-+{
-+ struct dentry *tmp, *goal = NULL;
-+ struct list_head *lp;
-+
-+ /* verify this dentry is really new */
-+ assert(dentry->d_inode == NULL);
-+ assert(list_empty(&dentry->d_alias)); /* d_instantiate */
-+ if (rehash)
-+ assert(d_unhashed(dentry)); /* d_rehash */
-+ assert(list_empty(&dentry->d_subdirs));
-+
-+ spin_lock(&dcache_lock);
-+ if (!inode)
-+ goto do_rehash;
-+
-+ if (!test_opt(inode->i_sb, IOPEN))
-+ goto do_instantiate;
-+
-+ /* preferrably return a connected dentry */
-+ list_for_each(lp, &inode->i_dentry) {
-+ tmp = list_entry(lp, struct dentry, d_alias);
-+ if (tmp->d_flags & DCACHE_DISCONNECTED) {
-+ assert(tmp->d_alias.next == &inode->i_dentry);
-+ assert(tmp->d_alias.prev == &inode->i_dentry);
-+ goal = tmp;
-+ dget_locked(goal);
-+ break;
-+ }
-+ }
-+
-+ if (!goal)
-+ goto do_instantiate;
-+
-+ /* Move the goal to the de hash queue */
-+ goal->d_flags &= ~DCACHE_DISCONNECTED;
-+ security_d_instantiate(goal, inode);
-+ __d_drop(dentry);
-+ d_rehash_cond(dentry, 0);
-+ d_move_locked(goal, dentry);
-+ spin_unlock(&dcache_lock);
-+ iput(inode);
-+
-+ return goal;
-+
-+ /* d_add(), but don't drop dcache_lock before adding dentry to inode */
-+do_instantiate:
-+ list_add(&dentry->d_alias, &inode->i_dentry); /* d_instantiate */
-+ dentry->d_inode = inode;
-+do_rehash:
-+ if (rehash)
-+ d_rehash_cond(dentry, 0);
-+ spin_unlock(&dcache_lock);
-+
-+ return NULL;
-+}
-+
-+/*
-+ * Similar as d_instantiate() except that it drops the disconnected
-+ * dentry if any.
-+ */
-+void iopen_d_instantiate(struct dentry *dentry, struct inode * inode)
-+{
-+ struct dentry *dis_dentry;
-+
-+ /* verify this dentry is really new */
-+ assert(dentry->d_inode == NULL);
-+ assert(list_empty(&dentry->d_alias));
-+
-+ spin_lock(&dcache_lock);
-+ if (!inode || !test_opt(inode->i_sb, IOPEN) ||
-+ list_empty(&inode->i_dentry))
-+ goto do_instantiate;
-+
-+ /* a disconnected dentry has been added in our back,
-+ * we have to drop this dentry, see bug 16362/15713*/
-+ dis_dentry = list_entry(inode->i_dentry.next, struct dentry, d_alias);
-+ spin_lock(&dis_dentry->d_lock);
-+ assert(dis_dentry->d_alias.next == &inode->i_dentry);
-+ assert(dis_dentry->d_alias.prev == &inode->i_dentry);
-+ assert(dis_dentry->d_flags & DCACHE_DISCONNECTED);
-+ __d_drop(dis_dentry);
-+ list_del_init(&dis_dentry->d_alias);
-+ spin_unlock(&dis_dentry->d_lock);
-+
-+do_instantiate:
-+ if (inode)
-+ list_add(&dentry->d_alias, &inode->i_dentry);
-+ dentry->d_inode = inode;
-+ spin_unlock(&dcache_lock);
-+ security_d_instantiate(dentry, inode);
-+}
-+
-+/*
-+ * These are the special structures for the iopen pseudo directory.
-+ */
-+
-+static struct inode_operations iopen_inode_operations = {
-+ lookup: iopen_lookup, /* BKL held */
-+};
-+
-+static struct file_operations iopen_file_operations = {
-+ read: generic_read_dir,
-+};
-+
-+static int match_dentry(struct dentry *dentry, const char *name)
-+{
-+ int len;
-+
-+ len = strlen(name);
-+ if (dentry->d_name.len != len)
-+ return 0;
-+ if (strncmp(dentry->d_name.name, name, len))
-+ return 0;
-+ return 1;
-+}
-+
-+/*
-+ * This function is spliced into ext4_lookup and returns 1 the file
-+ * name is __iopen__ and dentry has been filled in appropriately.
-+ */
-+int ext4_check_for_iopen(struct inode *dir, struct dentry *dentry)
-+{
-+ struct inode *inode;
-+
-+ if (dir->i_ino != EXT4_ROOT_INO ||
-+ !test_opt(dir->i_sb, IOPEN) ||
-+ !match_dentry(dentry, "__iopen__"))
-+ return 0;
-+
-+ inode = ext4_iget(dir->i_sb, EXT4_BAD_INO);
-+ if (IS_ERR(inode))
-+ return 0;
-+
-+ d_add(dentry, inode);
-+ return 1;
-+}
-+
-+/*
-+ * This function is spliced into read_inode; it returns 1 if inode
-+ * number is the one for /__iopen__, in which case the inode is filled
-+ * in appropriately. Otherwise, this fuction returns 0.
-+ */
-+int ext4_iopen_get_inode(struct inode *inode)
-+{
-+ if (inode->i_ino != EXT4_BAD_INO)
-+ return 0;
-+
-+ inode->i_mode = S_IFDIR | S_IRUSR | S_IXUSR;
-+ if (test_opt(inode->i_sb, IOPEN_NOPRIV))
-+ inode->i_mode |= 0777;
-+ inode->i_uid = 0;
-+ inode->i_gid = 0;
-+ inode->i_nlink = 1;
-+ inode->i_size = 4096;
-+ inode->i_atime = inode->i_ctime = inode->i_mtime = ext4_current_time(inode);
-+ EXT4_I(inode)->i_dtime = 0;
-+ EXT4_I(inode)->i_file_acl = 0;
-+ inode->i_blocks = 0;
-+ inode->i_version = 1;
-+ inode->i_generation = 0;
-+
-+ inode->i_op = &iopen_inode_operations;
-+ inode->i_fop = &iopen_file_operations;
-+ inode->i_mapping->a_ops = 0;
-+
-+ if (inode->i_state & I_NEW)
-+ unlock_new_inode(inode);
-+
-+ return 1;
-+}
-Index: linux-2.6.18-128.1.6/fs/ext4/iopen.h
-===================================================================
---- /dev/null
-+++ linux-2.6.18-128.1.6/fs/ext4/iopen.h
-@@ -0,0 +1,16 @@
-+/*
-+ * iopen.h
-+ *
-+ * Special support for opening files by inode number.
-+ *
-+ * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu).
-+ *
-+ * This file may be redistributed under the terms of the GNU General
-+ * Public License.
-+ */
-+
-+extern int ext4_check_for_iopen(struct inode *dir, struct dentry *dentry);
-+extern int ext4_iopen_get_inode(struct inode *inode);
-+extern struct dentry *iopen_connect_dentry(struct dentry *dentry,
-+ struct inode *inode, int rehash);
-+extern void iopen_d_instantiate(struct dentry *dentry, struct inode * inode);
-Index: linux-2.6.18-128.1.6/fs/ext4/inode.c
-===================================================================
---- linux-2.6.18-128.1.6.orig/fs/ext4/inode.c
-+++ linux-2.6.18-128.1.6/fs/ext4/inode.c
-@@ -37,6 +37,7 @@
- #include <linux/bio.h>
- #include "ext4_jbd2.h"
- #include "xattr.h"
-+#include "iopen.h"
- #include "acl.h"
-
- /*
-@@ -2764,6 +2765,8 @@ struct inode *ext4_iget(struct super_blo
- ei->i_acl = EXT4_ACL_NOT_CACHED;
- ei->i_default_acl = EXT4_ACL_NOT_CACHED;
- #endif
-+ if (ext4_iopen_get_inode(inode))
-+ return inode;
-
- ret = __ext4_get_inode_loc(inode, &iloc, 0);
- if (ret < 0)
-Index: linux-2.6.18-128.1.6/fs/ext4/super.c
-===================================================================
---- linux-2.6.18-128.1.6.orig/fs/ext4/super.c
-+++ linux-2.6.18-128.1.6/fs/ext4/super.c
-@@ -888,7 +888,8 @@ enum {
- Opt_usrquota, Opt_grpquota, Opt_i_version,
- Opt_stripe, Opt_delalloc, Opt_nodelalloc,
- Opt_block_validity, Opt_noblock_validity,
-- Opt_inode_readahead_blks, Opt_journal_ioprio
-+ Opt_inode_readahead_blks, Opt_journal_ioprio,
-+ Opt_iopen, Opt_noiopen, Opt_iopen_nopriv,
- };
-
- static match_table_t tokens = {
-@@ -938,6 +939,9 @@ static match_table_t tokens = {
- {Opt_noquota, "noquota"},
- {Opt_quota, "quota"},
- {Opt_usrquota, "usrquota"},
-+ {Opt_iopen, "iopen"},
-+ {Opt_noiopen, "noiopen"},
-+ {Opt_iopen_nopriv, "iopen_nopriv"},
- {Opt_barrier, "barrier=%u"},
- {Opt_extents, "extents"},
- {Opt_noextents, "noextents"},
-@@ -1270,6 +1274,18 @@ clear_qf_name:
- else
- clear_opt(sbi->s_mount_opt, BARRIER);
- break;
-+ case Opt_iopen:
-+ set_opt (sbi->s_mount_opt, IOPEN);
-+ clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
-+ break;
-+ case Opt_noiopen:
-+ clear_opt (sbi->s_mount_opt, IOPEN);
-+ clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
-+ break;
-+ case Opt_iopen_nopriv:
-+ set_opt (sbi->s_mount_opt, IOPEN);
-+ set_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
-+ break;
- case Opt_ignore:
- break;
- case Opt_resize:
-Index: linux-2.6.18-128.1.6/fs/ext4/namei.c
-===================================================================
---- linux-2.6.18-128.1.6.orig/fs/ext4/namei.c
-+++ linux-2.6.18-128.1.6/fs/ext4/namei.c
-@@ -39,6 +39,7 @@
-
- #include "namei.h"
- #include "xattr.h"
-+#include "iopen.h"
- #include "acl.h"
-
- /*
-@@ -1048,6 +1049,9 @@ static struct dentry *ext4_lookup(struct
- if (dentry->d_name.len > EXT4_NAME_LEN)
- return ERR_PTR(-ENAMETOOLONG);
-
-+ if (ext4_check_for_iopen(dir, dentry))
-+ return NULL;
-+
- bh = ext4_find_entry(dir, &dentry->d_name, &de);
- inode = NULL;
- if (bh) {
-@@ -1062,7 +1066,8 @@ static struct dentry *ext4_lookup(struct
- if (IS_ERR(inode))
- return ERR_CAST(inode);
- }
-- return d_splice_alias(inode, dentry);
-+
-+ return iopen_connect_dentry(dentry, inode, 1);
- }
-
-
-@@ -1709,7 +1714,7 @@ static int ext4_add_nondir(handle_t *han
- int err = ext4_add_entry(handle, dentry, inode);
- if (!err) {
- ext4_mark_inode_dirty(handle, inode);
-- d_instantiate(dentry, inode);
-+ iopen_d_instantiate(dentry, inode);
- unlock_new_inode(inode);
- return 0;
- }
-@@ -1868,7 +1873,7 @@ out_clear_inode:
- ext4_inc_count(handle, dir);
- ext4_update_dx_flag(dir);
- ext4_mark_inode_dirty(handle, dir);
-- d_instantiate(dentry, inode);
-+ iopen_d_instantiate(dentry, inode);
- unlock_new_inode(inode);
- out_stop:
- ext4_journal_stop(handle);
-@@ -2134,10 +2139,6 @@ static int ext4_rmdir (struct inode * di
- inode->i_nlink);
- inode->i_version++;
- clear_nlink(inode);
-- /* There's no need to set i_disksize: the fact that i_nlink is
-- * zero will ensure that the right thing happens during any
-- * recovery. */
-- inode->i_size = 0;
- ext4_orphan_add(handle, inode);
- inode->i_ctime = dir->i_ctime = dir->i_mtime = ext4_current_time(inode);
- ext4_mark_inode_dirty(handle, inode);
-@@ -2263,6 +2264,23 @@ out_stop:
- return err;
- }
-
-+/* Like ext4_add_nondir() except for call to iopen_connect_dentry */
-+static int ext4_add_link(handle_t *handle, struct dentry *dentry,
-+ struct inode *inode)
-+{
-+ int err = ext4_add_entry(handle, dentry, inode);
-+ if (!err) {
-+ err = ext4_mark_inode_dirty(handle, inode);
-+ if (err == 0) {
-+ dput(iopen_connect_dentry(dentry, inode, 0));
-+ return 0;
-+ }
-+ }
-+ ext4_dec_count(handle, inode);
-+ iput(inode);
-+ return err;
-+}
-+
- static int ext4_link(struct dentry *old_dentry,
- struct inode *dir, struct dentry *dentry)
- {
-@@ -2293,14 +2311,8 @@ retry:
- ext4_inc_count(handle, inode);
- atomic_inc(&inode->i_count);
-
-- err = ext4_add_entry(handle, dentry, inode);
-- if (!err) {
-- ext4_mark_inode_dirty(handle, inode);
-- d_instantiate(dentry, inode);
-- } else {
-- drop_nlink(inode);
-- iput(inode);
-- }
-+ err = ext4_add_link(handle, dentry, inode);
-+ ext4_orphan_del(handle, inode);
- ext4_journal_stop(handle);
- if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
- goto retry;
-Index: linux-2.6.18-128.1.6/fs/ext4/Makefile
-===================================================================
---- linux-2.6.18-128.1.6.orig/fs/ext4/Makefile
-+++ linux-2.6.18-128.1.6/fs/ext4/Makefile
-@@ -4,7 +4,7 @@
-
- obj-$(CONFIG_EXT4_FS) += ext4.o
-
--ext4-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
-+ext4-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
- ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o \
- ext4_jbd2.o migrate.o mballoc.o block_validity.o move_extent.o
-
-Index: linux-2.6.18-128.1.6/fs/ext4/ext4.h
-===================================================================
---- linux-2.6.18-128.1.6.orig/fs/ext4/ext4.h
-+++ linux-2.6.18-128.1.6/fs/ext4/ext4.h
-@@ -537,6 +538,8 @@ do { \
- #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */
- #define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */
- #define EXT4_MOUNT_BLOCK_VALIDITY 0x20000000 /* Block validity checking */
-+#define EXT4_MOUNT_IOPEN 0x20000000 /* Allow access via iopen */
-+#define EXT4_MOUNT_IOPEN_NOPRIV 0x40000000 /* Make iopen world-readable */
-
- /* Compatibility, for having both ext2_fs.h and ext4_fs.h included at once */
- #ifndef _LINUX_EXT2_FS_H
+++ /dev/null
-Index: linux-2.6.18-53.1.21/fs/ext3/iopen.c
-===================================================================
---- /dev/null
-+++ linux-2.6.18-53.1.21/fs/ext3/iopen.c
-@@ -0,0 +1,291 @@
-+/*
-+ * linux/fs/ext3/iopen.c
-+ *
-+ * Special support for open by inode number
-+ *
-+ * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu).
-+ *
-+ * This file may be redistributed under the terms of the GNU General
-+ * Public License.
-+ *
-+ *
-+ * Invariants:
-+ * - there is only ever a single DCACHE_NFSD_DISCONNECTED dentry alias
-+ * for an inode at one time.
-+ * - there are never both connected and DCACHE_NFSD_DISCONNECTED dentry
-+ * aliases on an inode at the same time.
-+ *
-+ * If we have any connected dentry aliases for an inode, use one of those
-+ * in iopen_lookup(). Otherwise, we instantiate a single NFSD_DISCONNECTED
-+ * dentry for this inode, which thereafter will be found by the dcache
-+ * when looking up this inode number in __iopen__, so we don't return here
-+ * until it is gone.
-+ *
-+ * If we get an inode via a regular name lookup, then we "rename" the
-+ * NFSD_DISCONNECTED dentry to the proper name and parent. This ensures
-+ * existing users of the disconnected dentry will continue to use the same
-+ * dentry as the connected users, and there will never be both kinds of
-+ * dentry aliases at one time.
-+ */
-+
-+#include <linux/sched.h>
-+#include <linux/fs.h>
-+#include <linux/ext3_jbd.h>
-+#include <linux/jbd.h>
-+#include <linux/ext3_fs.h>
-+#include <linux/smp_lock.h>
-+#include <linux/dcache.h>
-+#include <linux/security.h>
-+#include "iopen.h"
-+
-+#ifndef assert
-+#define assert(test) J_ASSERT(test)
-+#endif
-+
-+#define IOPEN_NAME_LEN 32
-+
-+/*
-+ * This implements looking up an inode by number.
-+ */
-+static struct dentry *iopen_lookup(struct inode * dir, struct dentry *dentry,
-+ struct nameidata *nd)
-+{
-+ struct inode *inode;
-+ unsigned long ino;
-+ struct list_head *lp;
-+ struct dentry *alternate;
-+ char buf[IOPEN_NAME_LEN];
-+
-+ if (dentry->d_name.len >= IOPEN_NAME_LEN)
-+ return ERR_PTR(-ENAMETOOLONG);
-+
-+ memcpy(buf, dentry->d_name.name, dentry->d_name.len);
-+ buf[dentry->d_name.len] = 0;
-+
-+ if (strcmp(buf, ".") == 0)
-+ ino = dir->i_ino;
-+ else if (strcmp(buf, "..") == 0)
-+ ino = EXT3_ROOT_INO;
-+ else
-+ ino = simple_strtoul(buf, 0, 0);
-+
-+ if ((ino != EXT3_ROOT_INO &&
-+ ino < EXT3_FIRST_INO(dir->i_sb)) ||
-+ ino > le32_to_cpu(EXT3_SB(dir->i_sb)->s_es->s_inodes_count))
-+ return ERR_PTR(-ENOENT);
-+
-+ inode = iget(dir->i_sb, ino);
-+ if (!inode)
-+ return ERR_PTR(-EACCES);
-+ if (is_bad_inode(inode)) {
-+ iput(inode);
-+ return ERR_PTR(-ENOENT);
-+ }
-+
-+ assert(list_empty(&dentry->d_alias)); /* d_instantiate */
-+ assert(d_unhashed(dentry)); /* d_rehash */
-+
-+ /* preferrably return a connected dentry */
-+ spin_lock(&dcache_lock);
-+ list_for_each(lp, &inode->i_dentry) {
-+ alternate = list_entry(lp, struct dentry, d_alias);
-+ assert(!(alternate->d_flags & DCACHE_DISCONNECTED));
-+ }
-+
-+ if (!list_empty(&inode->i_dentry)) {
-+ alternate = list_entry(inode->i_dentry.next,
-+ struct dentry, d_alias);
-+ dget_locked(alternate);
-+ spin_lock(&alternate->d_lock);
-+ alternate->d_flags |= DCACHE_REFERENCED;
-+ spin_unlock(&alternate->d_lock);
-+ iput(inode);
-+ spin_unlock(&dcache_lock);
-+ return alternate;
-+ }
-+ dentry->d_flags |= DCACHE_DISCONNECTED;
-+
-+ /* d_add(), but don't drop dcache_lock before adding dentry to inode */
-+ list_add(&dentry->d_alias, &inode->i_dentry); /* d_instantiate */
-+ dentry->d_inode = inode;
-+
-+ d_rehash_cond(dentry, 0);
-+ spin_unlock(&dcache_lock);
-+
-+ return NULL;
-+}
-+
-+/* This function is spliced into ext3_lookup and does the move of a
-+ * disconnected dentry (if it exists) to a connected dentry.
-+ */
-+struct dentry *iopen_connect_dentry(struct dentry *dentry, struct inode *inode,
-+ int rehash)
-+{
-+ struct dentry *tmp, *goal = NULL;
-+ struct list_head *lp;
-+
-+ /* verify this dentry is really new */
-+ assert(dentry->d_inode == NULL);
-+ assert(list_empty(&dentry->d_alias)); /* d_instantiate */
-+ if (rehash)
-+ assert(d_unhashed(dentry)); /* d_rehash */
-+ assert(list_empty(&dentry->d_subdirs));
-+
-+ spin_lock(&dcache_lock);
-+ if (!inode)
-+ goto do_rehash;
-+
-+ if (!test_opt(inode->i_sb, IOPEN))
-+ goto do_instantiate;
-+
-+ /* preferrably return a connected dentry */
-+ list_for_each(lp, &inode->i_dentry) {
-+ tmp = list_entry(lp, struct dentry, d_alias);
-+ if (tmp->d_flags & DCACHE_DISCONNECTED) {
-+ assert(tmp->d_alias.next == &inode->i_dentry);
-+ assert(tmp->d_alias.prev == &inode->i_dentry);
-+ goal = tmp;
-+ dget_locked(goal);
-+ break;
-+ }
-+ }
-+
-+ if (!goal)
-+ goto do_instantiate;
-+
-+ /* Move the goal to the de hash queue */
-+ goal->d_flags &= ~DCACHE_DISCONNECTED;
-+ security_d_instantiate(goal, inode);
-+ __d_drop(dentry);
-+ d_rehash_cond(dentry, 0);
-+ d_move_locked(goal, dentry);
-+ spin_unlock(&dcache_lock);
-+ iput(inode);
-+
-+ return goal;
-+
-+ /* d_add(), but don't drop dcache_lock before adding dentry to inode */
-+do_instantiate:
-+ list_add(&dentry->d_alias, &inode->i_dentry); /* d_instantiate */
-+ dentry->d_inode = inode;
-+do_rehash:
-+ if (rehash)
-+ d_rehash_cond(dentry, 0);
-+ spin_unlock(&dcache_lock);
-+
-+ return NULL;
-+}
-+
-+/*
-+ * Similar as d_instantiate() except that it drops the disconnected
-+ * dentry if any.
-+ */
-+void iopen_d_instantiate(struct dentry *dentry, struct inode * inode)
-+{
-+ struct dentry *dis_dentry;
-+
-+ /* verify this dentry is really new */
-+ assert(dentry->d_inode == NULL);
-+ assert(list_empty(&dentry->d_alias));
-+
-+ spin_lock(&dcache_lock);
-+ if (!inode || !test_opt(inode->i_sb, IOPEN) ||
-+ list_empty(&inode->i_dentry))
-+ goto do_instantiate;
-+
-+ /* a disconnected dentry has been added in our back,
-+ * we have to drop this dentry, see bug 16362/15713*/
-+ dis_dentry = list_entry(inode->i_dentry.next, struct dentry, d_alias);
-+ spin_lock(&dis_dentry->d_lock);
-+ assert(dis_dentry->d_alias.next == &inode->i_dentry);
-+ assert(dis_dentry->d_alias.prev == &inode->i_dentry);
-+ assert(dis_dentry->d_flags & DCACHE_DISCONNECTED);
-+ __d_drop(dis_dentry);
-+ list_del_init(&dis_dentry->d_alias);
-+ spin_unlock(&dis_dentry->d_lock);
-+
-+do_instantiate:
-+ if (inode)
-+ list_add(&dentry->d_alias, &inode->i_dentry);
-+ dentry->d_inode = inode;
-+ spin_unlock(&dcache_lock);
-+ security_d_instantiate(dentry, inode);
-+}
-+
-+/*
-+ * These are the special structures for the iopen pseudo directory.
-+ */
-+
-+static struct inode_operations iopen_inode_operations = {
-+ lookup: iopen_lookup, /* BKL held */
-+};
-+
-+static struct file_operations iopen_file_operations = {
-+ read: generic_read_dir,
-+};
-+
-+static int match_dentry(struct dentry *dentry, const char *name)
-+{
-+ int len;
-+
-+ len = strlen(name);
-+ if (dentry->d_name.len != len)
-+ return 0;
-+ if (strncmp(dentry->d_name.name, name, len))
-+ return 0;
-+ return 1;
-+}
-+
-+/*
-+ * This function is spliced into ext3_lookup and returns 1 the file
-+ * name is __iopen__ and dentry has been filled in appropriately.
-+ */
-+int ext3_check_for_iopen(struct inode *dir, struct dentry *dentry)
-+{
-+ struct inode *inode;
-+
-+ if (dir->i_ino != EXT3_ROOT_INO ||
-+ !test_opt(dir->i_sb, IOPEN) ||
-+ !match_dentry(dentry, "__iopen__"))
-+ return 0;
-+
-+ inode = iget(dir->i_sb, EXT3_BAD_INO);
-+
-+ if (!inode)
-+ return 0;
-+ d_add(dentry, inode);
-+ return 1;
-+}
-+
-+/*
-+ * This function is spliced into read_inode; it returns 1 if inode
-+ * number is the one for /__iopen__, in which case the inode is filled
-+ * in appropriately. Otherwise, this fuction returns 0.
-+ */
-+int ext3_iopen_get_inode(struct inode *inode)
-+{
-+ if (inode->i_ino != EXT3_BAD_INO)
-+ return 0;
-+
-+ inode->i_mode = S_IFDIR | S_IRUSR | S_IXUSR;
-+ if (test_opt(inode->i_sb, IOPEN_NOPRIV))
-+ inode->i_mode |= 0777;
-+ inode->i_uid = 0;
-+ inode->i_gid = 0;
-+ inode->i_nlink = 1;
-+ inode->i_size = 4096;
-+ inode->i_atime = CURRENT_TIME;
-+ inode->i_ctime = CURRENT_TIME;
-+ inode->i_mtime = CURRENT_TIME;
-+ EXT3_I(inode)->i_dtime = 0;
-+ EXT3_I(inode)->i_file_acl = 0;
-+ inode->i_blocks = 0;
-+ inode->i_version = 1;
-+ inode->i_generation = 0;
-+
-+ inode->i_op = &iopen_inode_operations;
-+ inode->i_fop = &iopen_file_operations;
-+ inode->i_mapping->a_ops = 0;
-+
-+ return 1;
-+}
-Index: linux-2.6.18-53.1.21/fs/ext3/iopen.h
-===================================================================
---- /dev/null
-+++ linux-2.6.18-53.1.21/fs/ext3/iopen.h
-@@ -0,0 +1,16 @@
-+/*
-+ * iopen.h
-+ *
-+ * Special support for opening files by inode number.
-+ *
-+ * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu).
-+ *
-+ * This file may be redistributed under the terms of the GNU General
-+ * Public License.
-+ */
-+
-+extern int ext3_check_for_iopen(struct inode *dir, struct dentry *dentry);
-+extern int ext3_iopen_get_inode(struct inode *inode);
-+extern struct dentry *iopen_connect_dentry(struct dentry *dentry,
-+ struct inode *inode, int rehash);
-+extern void iopen_d_instantiate(struct dentry *dentry, struct inode * inode);
-Index: linux-2.6.18-53.1.21/fs/ext3/inode.c
-===================================================================
---- linux-2.6.18-53.1.21.orig/fs/ext3/inode.c
-+++ linux-2.6.18-53.1.21/fs/ext3/inode.c
-@@ -37,6 +37,7 @@
- #include <linux/mpage.h>
- #include <linux/uio.h>
- #include "xattr.h"
-+#include "iopen.h"
- #include "acl.h"
-
- static int ext3_writepage_trans_blocks(struct inode *inode);
-@@ -2593,6 +2594,8 @@ void ext3_read_inode(struct inode * inod
- ei->i_default_acl = EXT3_ACL_NOT_CACHED;
- #endif
- ei->i_block_alloc_info = NULL;
-+ if (ext3_iopen_get_inode(inode))
-+ return;
-
- if (__ext3_get_inode_loc(inode, &iloc, 0))
- goto bad_inode;
-Index: linux-2.6.18-53.1.21/fs/ext3/super.c
-===================================================================
---- linux-2.6.18-53.1.21.orig/fs/ext3/super.c
-+++ linux-2.6.18-53.1.21/fs/ext3/super.c
-@@ -677,6 +677,7 @@ enum {
- Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
- Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
- Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
-+ Opt_iopen, Opt_noiopen, Opt_iopen_nopriv,
- Opt_grpquota
- };
-
-@@ -726,6 +727,9 @@ static match_table_t tokens = {
- {Opt_noquota, "noquota"},
- {Opt_quota, "quota"},
- {Opt_usrquota, "usrquota"},
-+ {Opt_iopen, "iopen"},
-+ {Opt_noiopen, "noiopen"},
-+ {Opt_iopen_nopriv, "iopen_nopriv"},
- {Opt_barrier, "barrier=%u"},
- {Opt_err, NULL},
- {Opt_resize, "resize"},
-@@ -1041,6 +1045,18 @@ clear_qf_name:
- else
- clear_opt(sbi->s_mount_opt, BARRIER);
- break;
-+ case Opt_iopen:
-+ set_opt (sbi->s_mount_opt, IOPEN);
-+ clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
-+ break;
-+ case Opt_noiopen:
-+ clear_opt (sbi->s_mount_opt, IOPEN);
-+ clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
-+ break;
-+ case Opt_iopen_nopriv:
-+ set_opt (sbi->s_mount_opt, IOPEN);
-+ set_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
-+ break;
- case Opt_ignore:
- break;
- case Opt_resize:
-Index: linux-2.6.18-53.1.21/fs/ext3/namei.c
-===================================================================
---- linux-2.6.18-53.1.21.orig/fs/ext3/namei.c
-+++ linux-2.6.18-53.1.21/fs/ext3/namei.c
-@@ -39,6 +39,7 @@
-
- #include "namei.h"
- #include "xattr.h"
-+#include "iopen.h"
- #include "acl.h"
-
- /*
-@@ -1020,6 +1021,9 @@ static struct dentry *ext3_lookup(struct
- if (dentry->d_name.len > EXT3_NAME_LEN)
- return ERR_PTR(-ENAMETOOLONG);
-
-+ if (ext3_check_for_iopen(dir, dentry))
-+ return NULL;
-+
- bh = ext3_find_entry(dentry, &de);
- inode = NULL;
- if (bh) {
-@@ -1035,7 +1039,8 @@ static struct dentry *ext3_lookup(struct
- if (!inode)
- return ERR_PTR(-EACCES);
- }
-- return d_splice_alias(inode, dentry);
-+
-+ return iopen_connect_dentry(dentry, inode, 1);
- }
-
-
-@@ -1678,7 +1683,7 @@ static int ext3_add_nondir(handle_t *han
- int err = ext3_add_entry(handle, dentry, inode);
- if (!err) {
- ext3_mark_inode_dirty(handle, inode);
-- d_instantiate(dentry, inode);
-+ iopen_d_instantiate(dentry, inode);
- return 0;
- }
- ext3_dec_count(handle, inode);
-@@ -1840,7 +1845,7 @@ retry:
- dir->i_nlink++;
- ext3_update_dx_flag(dir);
- ext3_mark_inode_dirty(handle, dir);
-- d_instantiate(dentry, inode);
-+ iopen_d_instantiate(dentry, inode);
- out_stop:
- ext3_journal_stop(handle);
- if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries))
-@@ -2108,10 +2113,6 @@ static int ext3_rmdir (struct inode * di
- inode->i_nlink);
- inode->i_version++;
- inode->i_nlink = 0;
-- /* There's no need to set i_disksize: the fact that i_nlink is
-- * zero will ensure that the right thing happens during any
-- * recovery. */
-- inode->i_size = 0;
- ext3_orphan_add(handle, inode);
- inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
- ext3_mark_inode_dirty(handle, inode);
-@@ -2235,6 +2236,23 @@ out_stop:
- return err;
- }
-
-+/* Like ext3_add_nondir() except for call to iopen_connect_dentry */
-+static int ext3_add_link(handle_t *handle, struct dentry *dentry,
-+ struct inode *inode)
-+{
-+ int err = ext3_add_entry(handle, dentry, inode);
-+ if (!err) {
-+ err = ext3_mark_inode_dirty(handle, inode);
-+ if (err == 0) {
-+ dput(iopen_connect_dentry(dentry, inode, 0));
-+ return 0;
-+ }
-+ }
-+ ext3_dec_count(handle, inode);
-+ iput(inode);
-+ return err;
-+}
-+
- static int ext3_link (struct dentry * old_dentry,
- struct inode * dir, struct dentry *dentry)
- {
-@@ -2264,7 +2282,8 @@ retry:
- ext3_inc_count(handle, inode);
- atomic_inc(&inode->i_count);
-
-- err = ext3_add_nondir(handle, dentry, inode);
-+ err = ext3_add_link(handle, dentry, inode);
-+ ext3_orphan_del(handle, inode);
- ext3_journal_stop(handle);
- if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries))
- goto retry;
-Index: linux-2.6.18-53.1.21/fs/ext3/Makefile
-===================================================================
---- linux-2.6.18-53.1.21.orig/fs/ext3/Makefile
-+++ linux-2.6.18-53.1.21/fs/ext3/Makefile
-@@ -4,7 +4,7 @@
-
- obj-$(CONFIG_EXT3_FS) += ext3.o
-
--ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
-+ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
- ioctl.o namei.o super.o symlink.o hash.o resize.o
-
- ext3-$(CONFIG_EXT3_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o
-Index: linux-2.6.18-53.1.21/include/linux/ext3_fs.h
-===================================================================
---- linux-2.6.18-53.1.21.orig/include/linux/ext3_fs.h
-+++ linux-2.6.18-53.1.21/include/linux/ext3_fs.h
-@@ -371,6 +371,8 @@ struct ext3_inode {
- #define EXT3_MOUNT_QUOTA 0x80000 /* Some quota option set */
- #define EXT3_MOUNT_USRQUOTA 0x100000 /* "old" user quota */
- #define EXT3_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */
-+#define EXT3_MOUNT_IOPEN 0x400000 /* Allow access via iopen */
-+#define EXT3_MOUNT_IOPEN_NOPRIV 0x800000/* Make iopen world-readable */
-
- /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
- #ifndef _LINUX_EXT2_FS_H
+++ /dev/null
-Index: linux-2.6.27.21-0.1/fs/ext4/iopen.c
-===================================================================
---- /dev/null
-+++ linux-2.6.27.21-0.1/fs/ext4/iopen.c
-@@ -0,0 +1,295 @@
-+/*
-+ * linux/fs/ext4/iopen.c
-+ *
-+ * Special support for open by inode number
-+ *
-+ * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu).
-+ *
-+ * This file may be redistributed under the terms of the GNU General
-+ * Public License.
-+ *
-+ *
-+ * Invariants:
-+ * - there is only ever a single DCACHE_NFSD_DISCONNECTED dentry alias
-+ * for an inode at one time.
-+ * - there are never both connected and DCACHE_NFSD_DISCONNECTED dentry
-+ * aliases on an inode at the same time.
-+ *
-+ * If we have any connected dentry aliases for an inode, use one of those
-+ * in iopen_lookup(). Otherwise, we instantiate a single NFSD_DISCONNECTED
-+ * dentry for this inode, which thereafter will be found by the dcache
-+ * when looking up this inode number in __iopen__, so we don't return here
-+ * until it is gone.
-+ *
-+ * If we get an inode via a regular name lookup, then we "rename" the
-+ * NFSD_DISCONNECTED dentry to the proper name and parent. This ensures
-+ * existing users of the disconnected dentry will continue to use the same
-+ * dentry as the connected users, and there will never be both kinds of
-+ * dentry aliases at one time.
-+ */
-+
-+#include <linux/sched.h>
-+#include <linux/fs.h>
-+#include <linux/smp_lock.h>
-+#include <linux/dcache.h>
-+#include <linux/security.h>
-+#include "iopen.h"
-+#include "ext4.h"
-+#include "ext4_jbd2.h"
-+
-+#ifndef assert
-+#define assert(test) J_ASSERT(test)
-+#endif
-+
-+#define IOPEN_NAME_LEN 32
-+
-+/*
-+ * This implements looking up an inode by number.
-+ */
-+static struct dentry *iopen_lookup(struct inode * dir, struct dentry *dentry,
-+ struct nameidata *nd)
-+{
-+ struct inode *inode;
-+ unsigned long ino;
-+ struct list_head *lp;
-+ struct dentry *alternate;
-+ char buf[IOPEN_NAME_LEN];
-+
-+ if (dentry->d_name.len >= IOPEN_NAME_LEN)
-+ return ERR_PTR(-ENAMETOOLONG);
-+
-+ memcpy(buf, dentry->d_name.name, dentry->d_name.len);
-+ buf[dentry->d_name.len] = 0;
-+
-+ if (strcmp(buf, ".") == 0)
-+ ino = dir->i_ino;
-+ else if (strcmp(buf, "..") == 0)
-+ ino = EXT4_ROOT_INO;
-+ else
-+ ino = simple_strtoul(buf, 0, 0);
-+
-+ if ((ino != EXT4_ROOT_INO &&
-+ ino < EXT4_FIRST_INO(dir->i_sb)) ||
-+ ino > le32_to_cpu(EXT4_SB(dir->i_sb)->s_es->s_inodes_count))
-+ return ERR_PTR(-ENOENT);
-+
-+ inode = ext4_iget(dir->i_sb, ino);
-+ if (IS_ERR(inode)) {
-+ /* Newer kernels return -ESTALE for inodes that are not in use,
-+ * but older kernels return a negative dentry. This can only
-+ * happen when doing a lookup in the __iopen__ dir, because the
-+ * "entry" will always be found even if inode is unallocated.
-+ * Handle this here instead of fixing the callers. b=19114 */
-+ if (PTR_ERR(inode) == -ESTALE)
-+ return (ERR_PTR(-ENOENT));
-+ return ERR_CAST(inode);
-+ }
-+
-+ assert(list_empty(&dentry->d_alias)); /* d_instantiate */
-+ assert(d_unhashed(dentry)); /* d_rehash */
-+
-+ /* preferrably return a connected dentry */
-+ spin_lock(&dcache_lock);
-+ list_for_each(lp, &inode->i_dentry) {
-+ alternate = list_entry(lp, struct dentry, d_alias);
-+ assert(!(alternate->d_flags & DCACHE_DISCONNECTED));
-+ }
-+
-+ if (!list_empty(&inode->i_dentry)) {
-+ alternate = list_entry(inode->i_dentry.next,
-+ struct dentry, d_alias);
-+ dget_locked(alternate);
-+ spin_lock(&alternate->d_lock);
-+ alternate->d_flags |= DCACHE_REFERENCED;
-+ spin_unlock(&alternate->d_lock);
-+ iput(inode);
-+ spin_unlock(&dcache_lock);
-+ return alternate;
-+ }
-+ dentry->d_flags |= DCACHE_DISCONNECTED;
-+
-+ /* d_add(), but don't drop dcache_lock before adding dentry to inode */
-+ list_add(&dentry->d_alias, &inode->i_dentry); /* d_instantiate */
-+ dentry->d_inode = inode;
-+
-+ d_rehash_cond(dentry, 0);
-+ spin_unlock(&dcache_lock);
-+
-+ return NULL;
-+}
-+
-+/* This function is spliced into ext4_lookup and does the move of a
-+ * disconnected dentry (if it exists) to a connected dentry.
-+ */
-+struct dentry *iopen_connect_dentry(struct dentry *dentry, struct inode *inode,
-+ int rehash)
-+{
-+ struct dentry *tmp, *goal = NULL;
-+ struct list_head *lp;
-+
-+ /* verify this dentry is really new */
-+ assert(dentry->d_inode == NULL);
-+ assert(list_empty(&dentry->d_alias)); /* d_instantiate */
-+ if (rehash)
-+ assert(d_unhashed(dentry)); /* d_rehash */
-+ assert(list_empty(&dentry->d_subdirs));
-+
-+ spin_lock(&dcache_lock);
-+ if (!inode)
-+ goto do_rehash;
-+
-+ if (!test_opt(inode->i_sb, IOPEN))
-+ goto do_instantiate;
-+
-+ /* preferrably return a connected dentry */
-+ list_for_each(lp, &inode->i_dentry) {
-+ tmp = list_entry(lp, struct dentry, d_alias);
-+ if (tmp->d_flags & DCACHE_DISCONNECTED) {
-+ assert(tmp->d_alias.next == &inode->i_dentry);
-+ assert(tmp->d_alias.prev == &inode->i_dentry);
-+ goal = tmp;
-+ dget_locked(goal);
-+ break;
-+ }
-+ }
-+
-+ if (!goal)
-+ goto do_instantiate;
-+
-+ /* Move the goal to the de hash queue */
-+ goal->d_flags &= ~DCACHE_DISCONNECTED;
-+ security_d_instantiate(goal, inode);
-+ __d_drop(dentry);
-+ d_rehash_cond(dentry, 0);
-+ d_move_locked(goal, dentry);
-+ spin_unlock(&dcache_lock);
-+ iput(inode);
-+
-+ return goal;
-+
-+ /* d_add(), but don't drop dcache_lock before adding dentry to inode */
-+do_instantiate:
-+ list_add(&dentry->d_alias, &inode->i_dentry); /* d_instantiate */
-+ dentry->d_inode = inode;
-+do_rehash:
-+ if (rehash)
-+ d_rehash_cond(dentry, 0);
-+ spin_unlock(&dcache_lock);
-+
-+ return NULL;
-+}
-+
-+/*
-+ * Similar as d_instantiate() except that it drops the disconnected
-+ * dentry if any.
-+ */
-+void iopen_d_instantiate(struct dentry *dentry, struct inode * inode)
-+{
-+ struct dentry *dis_dentry;
-+
-+ /* verify this dentry is really new */
-+ assert(dentry->d_inode == NULL);
-+ assert(list_empty(&dentry->d_alias));
-+
-+ spin_lock(&dcache_lock);
-+ if (!inode || !test_opt(inode->i_sb, IOPEN) ||
-+ list_empty(&inode->i_dentry))
-+ goto do_instantiate;
-+
-+ /* a disconnected dentry has been added in our back,
-+ * we have to drop this dentry, see bug 16362/15713*/
-+ dis_dentry = list_entry(inode->i_dentry.next, struct dentry, d_alias);
-+ spin_lock(&dis_dentry->d_lock);
-+ assert(dis_dentry->d_alias.next == &inode->i_dentry);
-+ assert(dis_dentry->d_alias.prev == &inode->i_dentry);
-+ assert(dis_dentry->d_flags & DCACHE_DISCONNECTED);
-+ __d_drop(dis_dentry);
-+ list_del_init(&dis_dentry->d_alias);
-+ spin_unlock(&dis_dentry->d_lock);
-+
-+do_instantiate:
-+ if (inode)
-+ list_add(&dentry->d_alias, &inode->i_dentry);
-+ dentry->d_inode = inode;
-+ spin_unlock(&dcache_lock);
-+ security_d_instantiate(dentry, inode);
-+}
-+
-+/*
-+ * These are the special structures for the iopen pseudo directory.
-+ */
-+
-+static struct inode_operations iopen_inode_operations = {
-+ lookup: iopen_lookup, /* BKL held */
-+};
-+
-+static struct file_operations iopen_file_operations = {
-+ read: generic_read_dir,
-+};
-+
-+static int match_dentry(struct dentry *dentry, const char *name)
-+{
-+ int len;
-+
-+ len = strlen(name);
-+ if (dentry->d_name.len != len)
-+ return 0;
-+ if (strncmp(dentry->d_name.name, name, len))
-+ return 0;
-+ return 1;
-+}
-+
-+/*
-+ * This function is spliced into ext4_lookup and returns 1 the file
-+ * name is __iopen__ and dentry has been filled in appropriately.
-+ */
-+int ext4_check_for_iopen(struct inode *dir, struct dentry *dentry)
-+{
-+ struct inode *inode;
-+
-+ if (dir->i_ino != EXT4_ROOT_INO ||
-+ !test_opt(dir->i_sb, IOPEN) ||
-+ !match_dentry(dentry, "__iopen__"))
-+ return 0;
-+
-+ inode = ext4_iget(dir->i_sb, EXT4_BAD_INO);
-+ if (IS_ERR(inode))
-+ return 0;
-+
-+ d_add(dentry, inode);
-+ return 1;
-+}
-+
-+/*
-+ * This function is spliced into read_inode; it returns 1 if inode
-+ * number is the one for /__iopen__, in which case the inode is filled
-+ * in appropriately. Otherwise, this fuction returns 0.
-+ */
-+int ext4_iopen_get_inode(struct inode *inode)
-+{
-+ if (inode->i_ino != EXT4_BAD_INO)
-+ return 0;
-+
-+ inode->i_mode = S_IFDIR | S_IRUSR | S_IXUSR;
-+ if (test_opt(inode->i_sb, IOPEN_NOPRIV))
-+ inode->i_mode |= 0777;
-+ inode->i_uid = 0;
-+ inode->i_gid = 0;
-+ inode->i_nlink = 1;
-+ inode->i_size = 4096;
-+ inode->i_atime = inode->i_ctime = inode->i_mtime = ext4_current_time(inode);
-+ EXT4_I(inode)->i_dtime = 0;
-+ EXT4_I(inode)->i_file_acl = 0;
-+ inode->i_blocks = 0;
-+ inode->i_version = 1;
-+ inode->i_generation = 0;
-+
-+ inode->i_op = &iopen_inode_operations;
-+ inode->i_fop = &iopen_file_operations;
-+ inode->i_mapping->a_ops = 0;
-+
-+ if (inode->i_state & I_NEW)
-+ unlock_new_inode(inode);
-+
-+ return 1;
-+}
-Index: linux-2.6.27.21-0.1/fs/ext4/iopen.h
-===================================================================
---- /dev/null
-+++ linux-2.6.27.21-0.1/fs/ext4/iopen.h
-@@ -0,0 +1,16 @@
-+/*
-+ * iopen.h
-+ *
-+ * Special support for opening files by inode number.
-+ *
-+ * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu).
-+ *
-+ * This file may be redistributed under the terms of the GNU General
-+ * Public License.
-+ */
-+
-+extern int ext4_check_for_iopen(struct inode *dir, struct dentry *dentry);
-+extern int ext4_iopen_get_inode(struct inode *inode);
-+extern struct dentry *iopen_connect_dentry(struct dentry *dentry,
-+ struct inode *inode, int rehash);
-+extern void iopen_d_instantiate(struct dentry *dentry, struct inode * inode);
-Index: linux-2.6.27.21-0.1/fs/ext4/inode.c
-===================================================================
---- linux-2.6.27.21-0.1.orig/fs/ext4/inode.c
-+++ linux-2.6.27.21-0.1/fs/ext4/inode.c
-@@ -38,6 +38,7 @@
- #include <linux/bio.h>
- #include "ext4_jbd2.h"
- #include "xattr.h"
-+#include "iopen.h"
- #include "acl.h"
- #include "ext4_extents.h"
-
-@@ -4115,6 +4116,9 @@ struct inode *ext4_iget(struct super_blo
- ei->i_default_acl = EXT4_ACL_NOT_CACHED;
- #endif
-
-+ if (ext4_iopen_get_inode(inode))
-+ return inode;
-+
- ret = __ext4_get_inode_loc(inode, &iloc, 0);
- if (ret < 0)
- goto bad_inode;
-Index: linux-2.6.27.21-0.1/fs/ext4/super.c
-===================================================================
---- linux-2.6.27.21-0.1.orig/fs/ext4/super.c
-+++ linux-2.6.27.21-0.1/fs/ext4/super.c
-@@ -955,7 +955,8 @@ enum {
- Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
- Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version,
- Opt_stripe, Opt_delalloc, Opt_nodelalloc,
-- Opt_inode_readahead_blks
-+ Opt_inode_readahead_blks,
-+ Opt_iopen, Opt_noiopen, Opt_iopen_nopriv,
- };
-
- static const match_table_t tokens = {
-@@ -1004,6 +1005,9 @@ static const match_table_t tokens = {
- {Opt_noquota, "noquota"},
- {Opt_quota, "quota"},
- {Opt_usrquota, "usrquota"},
-+ {Opt_iopen, "iopen"},
-+ {Opt_noiopen, "noiopen"},
-+ {Opt_iopen_nopriv, "iopen_nopriv"},
- {Opt_barrier, "barrier=%u"},
- {Opt_extents, "extents"},
- {Opt_noextents, "noextents"},
-@@ -1347,6 +1351,18 @@ set_qf_format:
- else
- clear_opt(sbi->s_mount_opt, BARRIER);
- break;
-+ case Opt_iopen:
-+ set_opt (sbi->s_mount_opt, IOPEN);
-+ clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
-+ break;
-+ case Opt_noiopen:
-+ clear_opt (sbi->s_mount_opt, IOPEN);
-+ clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
-+ break;
-+ case Opt_iopen_nopriv:
-+ set_opt (sbi->s_mount_opt, IOPEN);
-+ set_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
-+ break;
- case Opt_ignore:
- break;
- case Opt_resize:
-Index: linux-2.6.27.21-0.1/fs/ext4/namei.c
-===================================================================
---- linux-2.6.27.21-0.1.orig/fs/ext4/namei.c
-+++ linux-2.6.27.21-0.1/fs/ext4/namei.c
-@@ -39,6 +39,7 @@
-
- #include "namei.h"
- #include "xattr.h"
-+#include "iopen.h"
- #include "acl.h"
-
- /*
-@@ -1054,6 +1055,9 @@ static struct dentry *ext4_lookup(struct
- if (dentry->d_name.len > EXT4_NAME_LEN)
- return ERR_PTR(-ENAMETOOLONG);
-
-+ if (ext4_check_for_iopen(dir, dentry))
-+ return NULL;
-+
- bh = ext4_find_entry(dir, &dentry->d_name, &de);
- inode = NULL;
- if (bh) {
-@@ -1068,7 +1072,8 @@ static struct dentry *ext4_lookup(struct
- if (IS_ERR(inode))
- return ERR_CAST(inode);
- }
-- return d_splice_alias(inode, dentry);
-+
-+ return iopen_connect_dentry(dentry, inode, 1);
- }
-
-
-@@ -1717,7 +1722,7 @@ static int ext4_add_nondir(handle_t *han
- int err = ext4_add_entry(handle, dentry, inode);
- if (!err) {
- ext4_mark_inode_dirty(handle, inode);
-- d_instantiate(dentry, inode);
-+ iopen_d_instantiate(dentry, inode);
- return 0;
- }
- drop_nlink(inode);
-@@ -1876,7 +1881,7 @@ out_clear_inode:
- ext4_inc_count(handle, dir);
- ext4_update_dx_flag(dir);
- ext4_mark_inode_dirty(handle, dir);
-- d_instantiate(dentry, inode);
-+ iopen_d_instantiate(dentry, inode);
- out_stop:
- ext4_journal_stop(handle);
- if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
-@@ -2142,10 +2147,6 @@ static int ext4_rmdir(struct inode *dir,
- inode->i_nlink);
- inode->i_version++;
- clear_nlink(inode);
-- /* There's no need to set i_disksize: the fact that i_nlink is
-- * zero will ensure that the right thing happens during any
-- * recovery. */
-- inode->i_size = 0;
- ext4_orphan_add(handle, inode);
- inode->i_ctime = dir->i_ctime = dir->i_mtime = ext4_current_time(inode);
- ext4_mark_inode_dirty(handle, inode);
-@@ -2271,6 +2272,23 @@ out_stop:
- return err;
- }
-
-+/* Like ext4_add_nondir() except for call to iopen_connect_dentry */
-+static int ext4_add_link(handle_t *handle, struct dentry *dentry,
-+ struct inode *inode)
-+{
-+ int err = ext4_add_entry(handle, dentry, inode);
-+ if (!err) {
-+ err = ext4_mark_inode_dirty(handle, inode);
-+ if (err == 0) {
-+ dput(iopen_connect_dentry(dentry, inode, 0));
-+ return 0;
-+ }
-+ }
-+ ext4_dec_count(handle, inode);
-+ iput(inode);
-+ return err;
-+}
-+
- static int ext4_link(struct dentry *old_dentry,
- struct inode *dir, struct dentry *dentry)
- {
-@@ -2301,7 +2319,8 @@ retry:
- ext4_inc_count(handle, inode);
- atomic_inc(&inode->i_count);
-
-- err = ext4_add_nondir(handle, dentry, inode);
-+ err = ext4_add_link(handle, dentry, inode);
-+ ext4_orphan_del(handle, inode);
- ext4_journal_stop(handle);
- if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
- goto retry;
-Index: linux-2.6.27.21-0.1/fs/ext4/Makefile
-===================================================================
---- linux-2.6.27.21-0.1.orig/fs/ext4/Makefile
-+++ linux-2.6.27.21-0.1/fs/ext4/Makefile
-@@ -4,7 +4,7 @@
-
- obj-$(CONFIG_EXT4DEV_FS) += ext4dev.o
-
--ext4dev-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
-+ext4dev-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
- ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o \
- ext4_jbd2.o migrate.o mballoc.o
-
-Index: linux-2.6.27.21-0.1/fs/ext4/ext4.h
-===================================================================
---- linux-2.6.27.21-0.1.orig/fs/ext4/ext4.h
-+++ linux-2.6.27.21-0.1/fs/ext4/ext4.h
-@@ -540,6 +540,8 @@ do { \
- #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */
- #define EXT4_MOUNT_I_VERSION 0x2000000 /* i_version support */
- #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */
-+#define EXT4_MOUNT_IOPEN 0x10000000 /* Allow access via iopen */
-+#define EXT4_MOUNT_IOPEN_NOPRIV 0x20000000 /* Make iopen world-readable */
- /* Compatibility, for having both ext2_fs.h and ext4_fs.h included at once */
- #ifndef _LINUX_EXT2_FS_H
- #define clear_opt(o, opt) o &= ~EXT4_MOUNT_##opt
])
])
-AC_DEFUN([LC_EXPORT_D_MOVE_LOCKED],
-[LB_CHECK_SYMBOL_EXPORT([d_move_locked],
-[fs/dcache.c],[
-AC_DEFINE(HAVE_D_MOVE_LOCKED, 1,
- [d_move_locked is exported by the kernel])
-],[
-])
-])
-
-AC_DEFUN([LC_EXPORT___D_MOVE],
-[LB_CHECK_SYMBOL_EXPORT([__d_move],
-[fs/dcache.c],[
-AC_DEFINE(HAVE___D_MOVE, 1,
- [__d_move is exported by the kernel])
-],[
-])
-])
-
# The actual symbol exported varies among architectures, so we need
# to check many symbols (but only in the current architecture.) No
# matter what symbol is exported, the kernel #defines node_to_cpumask
LC_EXPORT_TRUNCATE_RANGE
LC_EXPORT_D_REHASH_COND
LC_EXPORT___D_REHASH
- LC_EXPORT_D_MOVE_LOCKED
- LC_EXPORT___D_MOVE
LC_EXPORT_NODE_TO_CPUMASK
LC_HEADER_LDISKFS_XATTR
issuing a warning on stderr if any of the default mount options are omitted.
The defaults for \fIldiskfs\fR are
OST: \fIerrors=remount-ro,mballoc,extents\fR;
-MGS/MDT: \fIerrors=remount-ro,iopen_nopriv,user_xattr\fR.
+MGS/MDT: \fIerrors=remount-ro,user_xattr\fR.
\fBDO NOT\fR alter the default mount options unless you know what you are doing.
.TP
.BI \--network= net,...
the command line, issuing a warning on stderr if any of the default
mount options are omitted. The defaults for ldiskfs are
OST: \fIerrors=remount-ro,mballoc,extents\fR;
-MGS/MDT: \fIerrors=remount-ro,iopen_nopriv,user_xattr\fR.
+MGS/MDT: \fIerrors=remount-ro,user_xattr\fR.
\fBDO NOT\fR alter the default mount options unless you know what you are doing.
.TP
.BI \--network= net,...
extern void __d_rehash(struct dentry *dentry, int lock);
#endif
-#if !defined(HAVE_D_MOVE_LOCKED) && defined(HAVE___D_MOVE)
-#define d_move_locked(dentry, target) __d_move(dentry, target)
-extern void __d_move(struct dentry *dentry, struct dentry *target);
-#endif
-
#ifdef HAVE_CAN_SLEEP_ARG
#define ll_flock_lock_file_wait(file, lock, can_sleep) \
flock_lock_file_wait(file, lock, can_sleep)
}
#define do_switch(x,y) do { \
-@@ -1481,7 +1496,7 @@ static void switch_names(struct dentry *
- * Update the dcache to reflect the move of a file name. Negative
- * dcache entries should not be moved in this way.
- */
--static void d_move_locked(struct dentry * dentry, struct dentry * target)
-+void d_move_locked(struct dentry * dentry, struct dentry * target)
- {
- struct hlist_head *list;
-
-@@ -1549,6 +1563,8 @@ already_unhashed:
- spin_unlock(&dentry->d_lock);
- write_sequnlock(&rename_lock);
- }
-+
-+EXPORT_SYMBOL(d_move_locked);
-
- /**
- * d_move - move a dentry
diff -urp linux-2.6.18.rawops/include/linux/dcache.h linux-2.6.18.races/include/linux/dcache.h
--- linux-2.6.18.rawops/include/linux/dcache.h 2007-02-14 16:52:37.000000000 +0200
+++ linux-2.6.18.races/include/linux/dcache.h 2007-02-14 19:21:14.000000000 +0200
/**
* d_add - add dentry to hash queues
-@@ -289,6 +291,7 @@ static inline struct dentry *d_add_uniqu
-
- /* used for rename() and baskets */
- extern void d_move(struct dentry *, struct dentry *);
-+extern void d_move_locked(struct dentry *, struct dentry *);
-
- /* appendix may either be NULL or be used for transname suffixes */
- extern struct dentry * d_lookup(struct dentry *, struct qstr *);
#include "osd_internal.h"
#include "xattr.h"
-#include "iopen.h"
#include "acl.h"
/*
# Permanent mount options for ext3 or ldiskfs
ALWAYS_MNTOPTS=${ALWAYS_MNTOPTS:-"errors=remount-ro"}
-MDT_MGS_ALWAYS_MNTOPTS=${MDT_MGS_ALWAYS_MNTOPTS:-",iopen_nopriv,user_xattr"}
+MDT_MGS_ALWAYS_MNTOPTS=${MDT_MGS_ALWAYS_MNTOPTS:-"user_xattr"}
OST_ALWAYS_MNTOPTS=${OST_ALWAYS_MNTOPTS:-",asyncdel"}
OST_DEFAULT_MNTOPTS=${OST_DEFAULT_MNTOPTS:-",extents,mballoc"}
noinst_PROGRAMS += statone runas openfile rmdirmany
noinst_PROGRAMS += small_write multiop ll_sparseness_verify
noinst_PROGRAMS += ll_sparseness_write mrename ll_dirstripe_verify mkdirmany
-noinst_PROGRAMS += openfilleddirunlink rename_many memhog iopentest1 iopentest2
+noinst_PROGRAMS += openfilleddirunlink rename_many memhog
noinst_PROGRAMS += mmap_sanity flock_test writemany reads flocks_test
noinst_PROGRAMS += write_time_limit rwv copytool
# noinst_PROGRAMS += copy_attr mkdirdeep
done
MDSDEVBASE=${MDSDEVBASE:-$TMP/${FSNAME}-mdt}
MDSSIZE=${MDSSIZE:-200000}
-MDSOPT=${MDSOPT:-"--mountfsoptions=errors=remount-ro,iopen_nopriv,user_xattr,acl"}
+MDSOPT=${MDSOPT:-"--mountfsoptions=errors=remount-ro,user_xattr,acl"}
MGSDEV=${MGSDEV:-$MDSDEV1}
MGSSIZE=${MGSSIZE:-$MDSSIZE}
+++ /dev/null
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <string.h>
-#include <libgen.h>
-#include <errno.h>
-
-const char *progname;
-const char usage_fmt[] = "Usage: %s <file> <mountpoint>\n";
-#define INAME_LEN (PATH_MAX + 1)
-
-#define CHECK_IT(exp, pstr) \
-if (!(exp)) { \
- fprintf(stderr, "%s: at %s:%d: ", progname, __FILE__, __LINE__); \
- perror((pstr)); \
- exit(1); \
-}
-
-#define CHECK_SNPRINTF(rc, len) \
- CHECK_IT((rc) > 0 && (rc) <= (len), "snprintf() failed")
-
-static char *get_iname(char *fname, const char *mtpt)
-{
- char *iname;
- int fd, rc;
- struct stat buf;
-
- iname = malloc(INAME_LEN);
- CHECK_IT(iname, "malloc() failed");
-
- fd = open(fname, O_CREAT, 0644);
- if (fd < 0 && errno != EISDIR) {
- fprintf(stderr, "%s:%d: open(%s) failed: %s\n", __FILE__,
- __LINE__, fname, strerror(errno));
- exit(1);
- }
-
- if (fd >= 0)
- close(fd);
-
- rc = stat(fname, &buf);
- if (rc != 0) {
- fprintf(stderr, "%s:%d: stat(%s) failed: %s\n", __FILE__,
- __LINE__, fname, strerror(errno));
- exit(1);
- }
-
- rc = snprintf(iname, INAME_LEN,
- "%s/__iopen__/%lu", mtpt, (unsigned long)buf.st_ino);
- CHECK_SNPRINTF(rc, INAME_LEN);
-
- return iname;
-}
-
-int main(int argc, char *argv[])
-{
- char *fname, *mtpt, *iname, *pname;
- struct stat buf;
- int rc;
- int i;
-
- pname = strdup(argv[0]);
- progname = basename(pname);
-
- if (argc != 3) {
- fprintf(stderr, usage_fmt, progname);
- return 1;
- }
-
- fname = argv[1];
- mtpt = argv[2];
-
- iname = get_iname(fname, mtpt);
- printf("%s:started...\n", argv[0]);
- for (i = 0; i < 10000; i++) {
- rc = stat(fname, &buf);
- if (rc != 0) {
- fprintf(stderr, "%s:%d: stat(%s) failed: %s\n",
- __FILE__, __LINE__, fname, strerror(errno));
- exit(1);
- }
-
- rc = stat(iname, &buf);
- if (rc != 0) {
- fprintf(stderr, "%s:%d: stat(%s) failed: %s\n",
- __FILE__, __LINE__, iname, strerror(errno));
- exit(1);
- }
- }
- printf("%s:finished...\n", argv[0]);
-
- return 0;
-}
+++ /dev/null
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <string.h>
-#include <libgen.h>
-#include <errno.h>
-#include <sys/wait.h>
-
-const char *progname;
-const char usage_fmt[] = "Usage: %s <mountpoint>\n";
-#define INAME_LEN (PATH_MAX + 1)
-
-#define CHECK_IT(exp, pstr) \
-if (!(exp)) { \
- fprintf(stderr, "%s: at %s:%d: ", progname, __FILE__, __LINE__); \
- perror((pstr)); \
- exit(1); \
-}
-
-#define CHECK_SNPRINTF(rc, len) \
- CHECK_IT((rc) > 0 && (rc) <= (len), "snprintf() failed")
-
-static char *get_iname(char *fname, const char *mtpt)
-{
- char *iname;
- int fd, rc;
- struct stat buf;
-
- iname = malloc(INAME_LEN);
- CHECK_IT(iname, "malloc() failed");
-
- fd = open(fname, O_CREAT, 0644);
- if (fd < 0 && errno != EISDIR) {
- fprintf(stderr, "%s:%d: open(%s) failed: %s\n", __FILE__,
- __LINE__, fname, strerror(errno));
- exit(1);
- }
-
- if (fd >= 0)
- close(fd);
-
- rc = stat(fname, &buf);
- if (rc != 0) {
- fprintf(stderr, "%s:%d: stat(%s) failed: %s\n", __FILE__,
- __LINE__, fname, strerror(errno));
- exit(1);
- }
-
- rc = snprintf(iname, INAME_LEN,
- "%s/__iopen__/%lu", mtpt, (unsigned long)buf.st_ino);
- CHECK_SNPRINTF(rc, INAME_LEN);
-
- return iname;
-}
-
-int main(int argc, char *argv[])
-{
- char *fname, *mtpt;
- char *fname_iname, *dir;
- char *dir_iname = NULL, *foo = NULL, *bar = NULL;
- int rc, fd, i, thread = 0;
- int pidlist[10];
-
- progname = basename(argv[0]);
-
- if (argc != 2) {
- fprintf(stderr, usage_fmt, progname);
- return 1;
- }
-
- for (i = 1; i <= 10; i++) {
- rc = fork();
- if (rc < 0) {
- fprintf(stderr, "error: %s: #%d - %s\n", argv[0], i,
- strerror(rc = errno));
- break;
- } else if (rc == 0) {
- thread = i;
- break;
- }
- printf("%s: thread #%d (PID %d) started\n", argv[0], i, rc);
- pidlist[i-1] = rc;
- rc = 0;
- }
-
- if (thread != 0) {
- mtpt = argv[1];
- fname = malloc(INAME_LEN);
- CHECK_IT(fname, "malloc() failed");
-
- rc = snprintf(fname, INAME_LEN,
- "%s/%d", mtpt, getpid());
- CHECK_SNPRINTF(rc, INAME_LEN);
-
- rc = mkdir(fname, 0644);
- if (rc != 0) {
- fprintf(stderr, "%s:%d: mkdir(%s) failed: %s\n",
- __FILE__, __LINE__, fname, strerror(errno));
- exit(1);
- }
-
- fname_iname = get_iname(fname, mtpt);
-
- dir = malloc(INAME_LEN);
- CHECK_IT(dir, "malloc() failed");
-
- rc = snprintf(dir, INAME_LEN, "%s/dir", fname_iname);
- CHECK_SNPRINTF(rc, INAME_LEN);
-
- foo = malloc(INAME_LEN);
- CHECK_IT(foo, "malloc() failed");
-
- bar = malloc(INAME_LEN);
- CHECK_IT(bar, "malloc() failed");
-
- for (i = 0; i < 1000; i++) {
- rc = mkdir(dir, 0644);
- if (rc != 0) {
- fprintf(stderr, "%s:%d: mkdir(%s) failed: %s\n",
- __FILE__, __LINE__, dir,
- strerror(errno));
- exit(1);
- }
-
- dir_iname = get_iname(dir, mtpt);
-
- rc = snprintf(foo, INAME_LEN, "%s/bar", dir_iname);
- CHECK_SNPRINTF(rc, INAME_LEN);
-
- rc = snprintf(bar, INAME_LEN, "%s/bar", dir_iname);
- CHECK_SNPRINTF(rc, INAME_LEN);
-
- fd = open(foo, O_CREAT, 0644);
- if (fd < 0) {
- fprintf(stderr, "%s:%d: open(%s) failed: %s\n",
- __FILE__, __LINE__, foo,
- strerror(errno));
- exit(1);
- }
- rc = close(fd);
- if (rc != 0) {
- fprintf(stderr, "%s:%d: close() failed: %s\n",
- __FILE__, __LINE__, strerror(errno));
- exit(1);
- }
-
- rc = rename(foo, bar);
- if (rc != 0) {
- fprintf(stderr, "%s:%d: rename(%s, %s) failed: "
- "%s\n", __FILE__, __LINE__, foo, bar,
- strerror(errno));
- exit(1);
- }
-
- rc = unlink(bar);
- if (rc != 0) {
- fprintf(stderr, "%s:%d: unlink(%s) failed: "
- "%s\n", __FILE__, __LINE__, bar,
- strerror(errno));
- exit(1);
- }
- rc = rmdir(dir);
- if (rc != 0) {
- fprintf(stderr, "%s:%d: rmdir(%s) failed: %s\n",
- __FILE__, __LINE__, dir,
- strerror(errno));
- exit(1);
- }
-
- free(dir_iname);
- }
- } else {
- for ( i=0; i<10; i++)
- waitpid(pidlist[i], NULL, 0);
- }
- return 0;
-}
MUNLINK=${MUNLINK:-munlink}
SOCKETSERVER=${SOCKETSERVER:-socketserver}
SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
-IOPENTEST1=${IOPENTEST1:-iopentest1}
-IOPENTEST2=${IOPENTEST2:-iopentest2}
MEMHOG=${MEMHOG:-memhog}
DIRECTIO=${DIRECTIO:-directio}
ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}