Commit 35116208 authored by Neil Brown's avatar Neil Brown Committed by Linus Torvalds

[PATCH] PATCH - kNFSd/ext3 in 2.5.14 - export_operations support for ext3

This patch converts ext3 to use the new export_operations for
exporting a filesystem.
In particular it
 - defines "ext3_get_parent" to do a lookup(".."),
 - calls d_splice_alias when ext3_lookup finds something,
   so that build a dcache path from the bottom up works, and
 - sets sb->s_export_op to point to an (almost empty)
   export_operations structure.  The fact that it is mostly empty
   means that the default lookup operations are used, which match the
   previous approach (i.e. use iget, and then check the generation
   number).
parent 7f045822
...@@ -220,10 +220,49 @@ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry) ...@@ -220,10 +220,49 @@ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry)
} }
} }
unlock_kernel(); unlock_kernel();
if (inode)
return d_splice_alias(inode, dentry);
d_add(dentry, inode); d_add(dentry, inode);
return NULL; return NULL;
} }
struct dentry *ext3_get_parent(struct dentry *child)
{
unsigned long ino;
struct dentry *parent;
struct inode *inode;
struct dentry dotdot;
struct ext3_dir_entry_2 * de;
struct buffer_head *bh;
dotdot.d_name.name = "..";
dotdot.d_name.len = 2;
dotdot.d_parent = child; /* confusing, isn't it! */
lock_kernel();
bh = ext3_find_entry(&dotdot, &de);
inode = NULL;
if (!bh) {
unlock_kernel();
return ERR_PTR(-ENOENT);
}
ino = le32_to_cpu(de->inode);
brelse(bh);
inode = iget(child->d_inode->i_sb, ino);
unlock_kernel();
if (!inode)
return ERR_PTR(-EACCES);
parent = d_alloc_anon(inode);
if (!parent) {
iput(inode);
parent = ERR_PTR(-ENOMEM);
}
return parent;
}
#define S_SHIFT 12 #define S_SHIFT 12
static unsigned char ext3_type_by_mode[S_IFMT >> S_SHIFT] = { static unsigned char ext3_type_by_mode[S_IFMT >> S_SHIFT] = {
[S_IFREG >> S_SHIFT] EXT3_FT_REG_FILE, [S_IFREG >> S_SHIFT] EXT3_FT_REG_FILE,
......
...@@ -508,6 +508,12 @@ static struct super_operations ext3_sops = { ...@@ -508,6 +508,12 @@ static struct super_operations ext3_sops = {
remount_fs: ext3_remount, /* BKL held */ remount_fs: ext3_remount, /* BKL held */
}; };
struct dentry *ext3_get_parent(struct dentry *child);
static struct export_operations ext3_export_ops = {
get_parent: ext3_get_parent,
};
static int want_value(char *value, char *option) static int want_value(char *value, char *option)
{ {
if (!value || !*value) { if (!value || !*value) {
...@@ -1157,6 +1163,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) ...@@ -1157,6 +1163,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
* set up enough so that it can read an inode * set up enough so that it can read an inode
*/ */
sb->s_op = &ext3_sops; sb->s_op = &ext3_sops;
sb->s_export_op = &ext3_export_ops;
INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */ INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
sb->s_root = 0; sb->s_root = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment