Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 213744
b: refs/heads/master
c: 8e656fd
h: refs/heads/master
v: v3
  • Loading branch information
Ryusuke Konishi committed Oct 23, 2010
1 parent c75e1e0 commit 400aa47
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 72 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4d8d9293dce503eb0e083e17a02a328d397e7f00
refs/heads/master: 8e656fd518784b49453f60c5f78b78703bc85cb2
17 changes: 17 additions & 0 deletions trunk/fs/nilfs2/export.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef NILFS_EXPORT_H
#define NILFS_EXPORT_H

#include <linux/exportfs.h>

extern const struct export_operations nilfs_export_ops;

struct nilfs_fid {
u64 cno;
u64 ino;
u32 gen;

u32 parent_gen;
u64 parent_ino;
} __attribute__ ((packed));

#endif
137 changes: 120 additions & 17 deletions trunk/fs/nilfs2/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@

#include <linux/pagemap.h>
#include "nilfs.h"
#include "export.h"

#define NILFS_FID_SIZE_NON_CONNECTABLE \
(offsetof(struct nilfs_fid, parent_gen) / 4)
#define NILFS_FID_SIZE_CONNECTABLE (sizeof(struct nilfs_fid) / 4)

static inline int nilfs_add_nondir(struct dentry *dentry, struct inode *inode)
{
Expand Down Expand Up @@ -77,23 +81,6 @@ nilfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
return d_splice_alias(inode, dentry);
}

struct dentry *nilfs_get_parent(struct dentry *child)
{
unsigned long ino;
struct inode *inode;
struct qstr dotdot = {.name = "..", .len = 2};

ino = nilfs_inode_by_name(child->d_inode, &dotdot);
if (!ino)
return ERR_PTR(-ENOENT);

inode = nilfs_iget(child->d_inode->i_sb,
NILFS_I(child->d_inode)->i_root, ino);
if (IS_ERR(inode))
return ERR_CAST(inode);
return d_obtain_alias(inode);
}

/*
* By the time this is called, we already have created
* the directory cache entry for the new file, but it
Expand Down Expand Up @@ -469,6 +456,115 @@ static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry,
return err;
}

/*
* Export operations
*/
static struct dentry *nilfs_get_parent(struct dentry *child)
{
unsigned long ino;
struct inode *inode;
struct qstr dotdot = {.name = "..", .len = 2};
struct nilfs_root *root;

ino = nilfs_inode_by_name(child->d_inode, &dotdot);
if (!ino)
return ERR_PTR(-ENOENT);

root = NILFS_I(child->d_inode)->i_root;

inode = nilfs_iget(child->d_inode->i_sb, root, ino);
if (IS_ERR(inode))
return ERR_CAST(inode);

return d_obtain_alias(inode);
}

static struct dentry *nilfs_get_dentry(struct super_block *sb, u64 cno,
u64 ino, u32 gen)
{
struct nilfs_root *root;
struct inode *inode;

if (ino < NILFS_FIRST_INO(sb) && ino != NILFS_ROOT_INO)
return ERR_PTR(-ESTALE);

root = nilfs_lookup_root(NILFS_SB(sb)->s_nilfs, cno);
if (!root)
return ERR_PTR(-ESTALE);

inode = nilfs_iget(sb, root, ino);
nilfs_put_root(root);

if (IS_ERR(inode))
return ERR_CAST(inode);
if (gen && inode->i_generation != gen) {
iput(inode);
return ERR_PTR(-ESTALE);
}
return d_obtain_alias(inode);
}

static struct dentry *nilfs_fh_to_dentry(struct super_block *sb, struct fid *fh,
int fh_len, int fh_type)
{
struct nilfs_fid *fid = (struct nilfs_fid *)fh;

if ((fh_len != NILFS_FID_SIZE_NON_CONNECTABLE &&
fh_len != NILFS_FID_SIZE_CONNECTABLE) ||
(fh_type != FILEID_NILFS_WITH_PARENT &&
fh_type != FILEID_NILFS_WITHOUT_PARENT))
return NULL;

return nilfs_get_dentry(sb, fid->cno, fid->ino, fid->gen);
}

static struct dentry *nilfs_fh_to_parent(struct super_block *sb, struct fid *fh,
int fh_len, int fh_type)
{
struct nilfs_fid *fid = (struct nilfs_fid *)fh;

if (fh_len != NILFS_FID_SIZE_CONNECTABLE ||
fh_type != FILEID_NILFS_WITH_PARENT)
return NULL;

return nilfs_get_dentry(sb, fid->cno, fid->parent_ino, fid->parent_gen);
}

static int nilfs_encode_fh(struct dentry *dentry, __u32 *fh, int *lenp,
int connectable)
{
struct nilfs_fid *fid = (struct nilfs_fid *)fh;
struct inode *inode = dentry->d_inode;
struct nilfs_root *root = NILFS_I(inode)->i_root;
int type;

if (*lenp < NILFS_FID_SIZE_NON_CONNECTABLE ||
(connectable && *lenp < NILFS_FID_SIZE_CONNECTABLE))
return 255;

fid->cno = root->cno;
fid->ino = inode->i_ino;
fid->gen = inode->i_generation;

if (connectable && !S_ISDIR(inode->i_mode)) {
struct inode *parent;

spin_lock(&dentry->d_lock);
parent = dentry->d_parent->d_inode;
fid->parent_ino = parent->i_ino;
fid->parent_gen = parent->i_generation;
spin_unlock(&dentry->d_lock);

type = FILEID_NILFS_WITH_PARENT;
*lenp = NILFS_FID_SIZE_CONNECTABLE;
} else {
type = FILEID_NILFS_WITHOUT_PARENT;
*lenp = NILFS_FID_SIZE_NON_CONNECTABLE;
}

return type;
}

const struct inode_operations nilfs_dir_inode_operations = {
.create = nilfs_create,
.lookup = nilfs_lookup,
Expand All @@ -493,3 +589,10 @@ const struct inode_operations nilfs_symlink_inode_operations = {
.follow_link = page_follow_link_light,
.put_link = page_put_link,
};

const struct export_operations nilfs_export_ops = {
.encode_fh = nilfs_encode_fh,
.fh_to_dentry = nilfs_fh_to_dentry,
.fh_to_parent = nilfs_fh_to_parent,
.get_parent = nilfs_get_parent,
};
3 changes: 0 additions & 3 deletions trunk/fs/nilfs2/nilfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,6 @@ extern int nilfs_set_file_dirty(struct nilfs_sb_info *, struct inode *,
extern int nilfs_mark_inode_dirty(struct inode *);
extern void nilfs_dirty_inode(struct inode *);

/* namei.c */
extern struct dentry *nilfs_get_parent(struct dentry *);

/* super.c */
extern struct inode *nilfs_alloc_inode_common(struct the_nilfs *);
extern struct inode *nilfs_alloc_inode(struct super_block *);
Expand Down
52 changes: 1 addition & 51 deletions trunk/fs/nilfs2/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@
#include <linux/vfs.h>
#include <linux/writeback.h>
#include <linux/kobject.h>
#include <linux/exportfs.h>
#include <linux/seq_file.h>
#include <linux/mount.h>
#include "nilfs.h"
#include "export.h"
#include "mdt.h"
#include "alloc.h"
#include "btree.h"
Expand Down Expand Up @@ -556,56 +556,6 @@ static const struct super_operations nilfs_sops = {
.show_options = nilfs_show_options
};

static struct inode *
nilfs_nfs_get_inode(struct super_block *sb, u64 ino, u32 generation)
{
struct inode *inode;
struct nilfs_root *root;

if (ino < NILFS_FIRST_INO(sb) && ino != NILFS_ROOT_INO &&
ino != NILFS_SKETCH_INO)
return ERR_PTR(-ESTALE);

root = nilfs_lookup_root(NILFS_SB(sb)->s_nilfs,
NILFS_CPTREE_CURRENT_CNO);
if (!root)
return ERR_PTR(-ESTALE);

/* new file handle type is required to export snapshots */
inode = nilfs_iget(sb, root, ino);
nilfs_put_root(root);
if (IS_ERR(inode))
return ERR_CAST(inode);
if (generation && inode->i_generation != generation) {
iput(inode);
return ERR_PTR(-ESTALE);
}

return inode;
}

static struct dentry *
nilfs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
int fh_type)
{
return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
nilfs_nfs_get_inode);
}

static struct dentry *
nilfs_fh_to_parent(struct super_block *sb, struct fid *fid, int fh_len,
int fh_type)
{
return generic_fh_to_parent(sb, fid, fh_len, fh_type,
nilfs_nfs_get_inode);
}

static const struct export_operations nilfs_export_ops = {
.fh_to_dentry = nilfs_fh_to_dentry,
.fh_to_parent = nilfs_fh_to_parent,
.get_parent = nilfs_get_parent,
};

enum {
Opt_err_cont, Opt_err_panic, Opt_err_ro,
Opt_barrier, Opt_nobarrier, Opt_snapshot, Opt_order, Opt_norecovery,
Expand Down
13 changes: 13 additions & 0 deletions trunk/include/linux/exportfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,19 @@ enum fid_type {
* 32 bit parent block number, 32 bit parent generation number
*/
FILEID_UDF_WITH_PARENT = 0x52,

/*
* 64 bit checkpoint number, 64 bit inode number,
* 32 bit generation number.
*/
FILEID_NILFS_WITHOUT_PARENT = 0x61,

/*
* 64 bit checkpoint number, 64 bit inode number,
* 32 bit generation number, 32 bit parent generation.
* 64 bit parent inode number.
*/
FILEID_NILFS_WITH_PARENT = 0x62,
};

struct fid {
Expand Down

0 comments on commit 400aa47

Please sign in to comment.