Skip to content

Commit

Permalink
LU-1718 client: Restore NFS export for Lustre on 3.X kernels
Browse files Browse the repository at this point in the history
In Linux 3.0+ kernels struct file_system_type changed the
get_sb function to a new function called mount which was
different in that the vfsmount data was no longer passed in.
The vfsmount data was used by the llite layer for nfs export
function called get_name to search for filp that was then used
with the ll_readdir method. The approach to solve this change
was to go the route of btrfs and gfs2 to refactor some of the
llite methods to implement a directory scan independent of
filp which could be shared with nfs export funtionality.

Signed-off-by: James Simmons <[email protected]>
Change-Id: I72730476b120cec1ede6e03c774c9e470a1a5a70
Reviewed-on: http://review.whamcloud.com/3624
Tested-by: Hudson
Reviewed-by: Andreas Dilger <[email protected]>
Reviewed-by: Fan Yong <[email protected]>
Tested-by: Maloo <[email protected]>
  • Loading branch information
jasimmons1973 authored and Oleg Drokin committed Oct 7, 2012
1 parent 3b2d496 commit d8b4866
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 88 deletions.
94 changes: 44 additions & 50 deletions lustre/llite/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,15 +139,15 @@
*/

/* returns the page unlocked, but with a reference */
static int ll_dir_readpage(struct file *file, struct page *page0)
static int ll_dir_filler(void *_hash, struct page *page0)
{
struct inode *inode = page0->mapping->host;
int hash64 = ll_i2sbi(inode)->ll_flags & LL_SBI_64BIT_HASH;
struct obd_export *exp = ll_i2sbi(inode)->ll_md_exp;
struct ptlrpc_request *request;
struct mdt_body *body;
struct md_op_data *op_data;
__u64 hash;
__u64 hash = *((__u64 *)_hash);
struct page **page_pool;
struct page *page;
#ifndef HAVE_ADD_TO_PAGE_CACHE_LRU
Expand All @@ -161,13 +161,6 @@ static int ll_dir_readpage(struct file *file, struct page *page0)
int rc;
ENTRY;

if (file) {
struct ll_file_data *fd = LUSTRE_FPRIVATE(file);

hash = fd->fd_dir.lfd_next;
} else {
hash = ll_i2info(inode)->lli_sa_pos;
}
CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p) hash "LPU64"\n",
inode->i_ino, inode->i_generation, inode, hash);

Expand Down Expand Up @@ -251,16 +244,6 @@ static int ll_dir_readpage(struct file *file, struct page *page0)
return rc;
}

#ifndef MS_HAS_NEW_AOPS
struct address_space_operations ll_dir_aops = {
.readpage = ll_dir_readpage,
};
#else
struct address_space_operations_ext ll_dir_aops = {
.orig_aops.readpage = ll_dir_readpage,
};
#endif

static void ll_check_page(struct inode *dir, struct page *page)
{
/* XXX: check page format later */
Expand Down Expand Up @@ -310,7 +293,7 @@ static struct page *ll_dir_page_locate(struct inode *dir, __u64 *hash,
* hence, can avoid restart.
*
* In fact, page cannot be locked here at all, because
* ll_dir_readpage() does synchronous io.
* ll_dir_filler() does synchronous io.
*/
wait_on_page(page);
if (PageUptodate(page)) {
Expand Down Expand Up @@ -353,7 +336,7 @@ static struct page *ll_dir_page_locate(struct inode *dir, __u64 *hash,
return page;
}

struct page *ll_get_dir_page(struct file *filp, struct inode *dir, __u64 hash,
struct page *ll_get_dir_page(struct inode *dir, __u64 hash,
struct ll_dir_chain *chain)
{
ldlm_policy_data_t policy = {.l_inodebits = {MDS_INODELOCK_UPDATE} };
Expand Down Expand Up @@ -431,7 +414,7 @@ struct page *ll_get_dir_page(struct file *filp, struct inode *dir, __u64 hash,
}

page = read_cache_page(mapping, hash_x_index(hash, hash64),
(filler_t*)mapping->a_ops->readpage, filp);
ll_dir_filler, &lhash);
if (IS_ERR(page)) {
CERROR("read cache page: "DFID" at "LPU64": rc %ld\n",
PFID(ll_inode2fid(dir)), hash, PTR_ERR(page));
Expand Down Expand Up @@ -489,37 +472,23 @@ struct page *ll_get_dir_page(struct file *filp, struct inode *dir, __u64 hash,
goto out_unlock;
}

int ll_readdir(struct file *filp, void *cookie, filldir_t filldir)
int ll_dir_read(struct inode *inode, __u64 *_pos, void *cookie,
filldir_t filldir)
{
struct inode *inode = filp->f_dentry->d_inode;
struct ll_inode_info *info = ll_i2info(inode);
struct ll_sb_info *sbi = ll_i2sbi(inode);
struct ll_file_data *fd = LUSTRE_FPRIVATE(filp);
__u64 pos = fd->fd_dir.lfd_pos;
__u64 pos = *_pos;
int api32 = ll_need_32bit_api(sbi);
int hash64 = sbi->ll_flags & LL_SBI_64BIT_HASH;
struct page *page;
struct ll_dir_chain chain;
int done;
int rc;
int done = 0;
int rc = 0;
ENTRY;

CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p) pos %lu/%llu 32bit_api %d\n",
inode->i_ino, inode->i_generation, inode,
(unsigned long)pos, i_size_read(inode), api32);

if (pos == MDS_DIR_END_OFF)
/*
* end-of-file.
*/
GOTO(out, rc = 0);

rc = 0;
done = 0;
ll_dir_chain_init(&chain);

fd->fd_dir.lfd_next = pos;
page = ll_get_dir_page(filp, inode, pos, &chain);
page = ll_get_dir_page(inode, pos, &chain);

while (rc == 0 && !done) {
struct lu_dirpage *dp;
Expand Down Expand Up @@ -592,8 +561,8 @@ int ll_readdir(struct file *filp, void *cookie, filldir_t filldir)
ll_release_page(page,
le32_to_cpu(dp->ldp_flags) &
LDF_COLLIDE);
fd->fd_dir.lfd_next = pos;
page = ll_get_dir_page(filp, inode, pos,
next = pos;
page = ll_get_dir_page(inode, pos,
&chain);
} else {
/*
Expand All @@ -614,7 +583,34 @@ int ll_readdir(struct file *filp, void *cookie, filldir_t filldir)
}
}

fd->fd_dir.lfd_pos = pos;
*_pos = pos;
ll_dir_chain_fini(&chain);
RETURN(rc);
}

static int ll_readdir(struct file *filp, void *cookie, filldir_t filldir)
{
struct inode *inode = filp->f_dentry->d_inode;
struct ll_file_data *lfd = LUSTRE_FPRIVATE(filp);
struct ll_sb_info *sbi = ll_i2sbi(inode);
__u64 pos = lfd->lfd_pos;
int hash64 = sbi->ll_flags & LL_SBI_64BIT_HASH;
int api32 = ll_need_32bit_api(sbi);
int rc;
ENTRY;

CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p) pos %lu/%llu "
" 32bit_api %d\n", inode->i_ino, inode->i_generation,
inode, (unsigned long)pos, i_size_read(inode), api32);

if (pos == MDS_DIR_END_OFF)
/*
* end-of-file.
*/
GOTO(out, rc = 0);

rc = ll_dir_read(inode, &pos, cookie, filldir);
lfd->lfd_pos = pos;
if (pos == MDS_DIR_END_OFF) {
if (api32)
filp->f_pos = LL_DIR_END_OFF_32BIT;
Expand All @@ -629,8 +625,6 @@ int ll_readdir(struct file *filp, void *cookie, filldir_t filldir)
filp->f_version = inode->i_version;
touch_atime(filp->f_vfsmnt, filp->f_dentry);

ll_dir_chain_fini(&chain);

out:
if (!rc)
ll_stats_ops_tally(sbi, LPROC_LL_READDIR, 1);
Expand Down Expand Up @@ -1511,11 +1505,11 @@ static loff_t ll_dir_seek(struct file *file, loff_t offset, int origin)
if (offset != file->f_pos) {
if ((api32 && offset == LL_DIR_END_OFF_32BIT) ||
(!api32 && offset == LL_DIR_END_OFF))
fd->fd_dir.lfd_pos = MDS_DIR_END_OFF;
fd->lfd_pos = MDS_DIR_END_OFF;
else if (api32 && sbi->ll_flags & LL_SBI_64BIT_HASH)
fd->fd_dir.lfd_pos = offset << 32;
fd->lfd_pos = offset << 32;
else
fd->fd_dir.lfd_pos = offset;
fd->lfd_pos = offset;
file->f_pos = offset;
file->f_version = 0;
}
Expand Down
15 changes: 4 additions & 11 deletions lustre/llite/llite_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,6 @@ struct ll_inode_info {
* cleanup the dir readahead. */
void *d_opendir_key;
struct ll_statahead_info *d_sai;
__u64 d_sa_pos;
struct posix_acl *d_def_acl;
/* protect statahead stuff. */
cfs_spinlock_t d_sa_lock;
Expand All @@ -204,7 +203,6 @@ struct ll_inode_info {
#define lli_readdir_mutex u.d.d_readdir_mutex
#define lli_opendir_key u.d.d_opendir_key
#define lli_sai u.d.d_sai
#define lli_sa_pos u.d.d_sa_pos
#define lli_def_acl u.d.d_def_acl
#define lli_sa_lock u.d.d_sa_lock
#define lli_opendir_pid u.d.d_opendir_pid
Expand Down Expand Up @@ -491,7 +489,6 @@ struct ll_sb_info {
* clustred nfs */
struct rmtacl_ctl_table ll_rct;
struct eacl_table ll_et;
struct vfsmount *ll_mnt;
};

#define LL_DEFAULT_MAX_RW_CHUNK (32 * 1024 * 1024)
Expand Down Expand Up @@ -589,18 +586,13 @@ struct ll_readahead_state {
unsigned long ras_consecutive_stride_requests;
};

struct ll_file_dir {
__u64 lfd_pos;
__u64 lfd_next;
};

extern cfs_mem_cache_t *ll_file_data_slab;
struct lustre_handle;
struct ll_file_data {
struct ll_readahead_state fd_ras;
int fd_omode;
struct ccc_grouplock fd_grouplock;
struct ll_file_dir fd_dir;
__u64 lfd_pos;
__u32 fd_flags;
struct file *fd_file;
/* Indicate whether need to report failure when close.
Expand Down Expand Up @@ -670,9 +662,10 @@ static void lprocfs_llite_init_vars(struct lprocfs_static_vars *lvars)
void ll_release_page(struct page *page, int remove);
extern struct file_operations ll_dir_operations;
extern struct inode_operations ll_dir_inode_operations;
struct page *ll_get_dir_page(struct file *filp, struct inode *dir, __u64 hash,
struct page *ll_get_dir_page(struct inode *dir, __u64 hash,
struct ll_dir_chain *chain);
int ll_readdir(struct file *filp, void *cookie, filldir_t filldir);
int ll_dir_read(struct inode *inode, __u64 *_pos, void *cookie,
filldir_t filldir);

int ll_get_mdt_idx(struct inode *inode);
char *ll_get_fsname(struct inode *inode);
Expand Down
7 changes: 1 addition & 6 deletions lustre/llite/llite_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,8 @@ DEFINE_SPINLOCK(ll_sb_lock);

#ifndef MS_HAS_NEW_AOPS
extern struct address_space_operations ll_aops;
extern struct address_space_operations ll_dir_aops;
#else
extern struct address_space_operations_ext ll_aops;
extern struct address_space_operations_ext ll_dir_aops;
#endif

#ifndef log2
Expand Down Expand Up @@ -469,7 +467,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
CDEBUG(D_SUPER, "rootfid "DFID"\n", PFID(&sbi->ll_root_fid));

sb->s_op = &lustre_super_operations;
#if THREAD_SIZE >= 8192 /*b=17630*/ && !defined(HAVE_FSTYPE_MOUNT) /*LU-812*/
#if THREAD_SIZE >= 8192 /*b=17630*/
sb->s_export_op = &lustre_export_operations;
#endif

Expand Down Expand Up @@ -564,7 +562,6 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
uuid = obd_get_uuid(sbi->ll_md_exp);
if (uuid != NULL)
sb->s_dev = get_uuid2int(uuid->uuid, strlen(uuid->uuid));
sbi->ll_mnt = mnt;

if (data != NULL)
OBD_FREE_PTR(data);
Expand Down Expand Up @@ -912,7 +909,6 @@ void ll_lli_init(struct ll_inode_info *lli)
cfs_mutex_init(&lli->lli_readdir_mutex);
lli->lli_opendir_key = NULL;
lli->lli_sai = NULL;
lli->lli_sa_pos = 0;
lli->lli_def_acl = NULL;
cfs_spin_lock_init(&lli->lli_sa_lock);
lli->lli_opendir_pid = 0;
Expand Down Expand Up @@ -1845,7 +1841,6 @@ void ll_read_inode2(struct inode *inode, void *opaque)
} else if (S_ISDIR(inode->i_mode)) {
inode->i_op = &ll_dir_inode_operations;
inode->i_fop = &ll_dir_operations;
inode->i_mapping->a_ops = (struct address_space_operations *)&ll_dir_aops;
EXIT;
} else if (S_ISLNK(inode->i_mode)) {
inode->i_op = &ll_fast_symlink_inode_operations;
Expand Down
14 changes: 2 additions & 12 deletions lustre/llite/llite_nfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,8 @@ static int ll_get_name(struct dentry *dentry, char *name,
struct dentry *child)
{
struct inode *dir = dentry->d_inode;
struct file *filp;
struct ll_getname_data lgd;
__u64 offset = 0;
int rc;
ENTRY;

Expand All @@ -228,27 +228,17 @@ static int ll_get_name(struct dentry *dentry, char *name,
if (!dir->i_fop)
GOTO(out, rc = -EINVAL);

filp = ll_dentry_open(dget(dentry), mntget(ll_i2sbi(dir)->ll_mnt),
O_RDONLY, current_cred());
if (IS_ERR(filp))
GOTO(out, rc = PTR_ERR(filp));

if (!filp->f_op->readdir)
GOTO(out_close, rc = -EINVAL);

lgd.lgd_name = name;
lgd.lgd_fid = ll_i2info(child->d_inode)->lli_fid;
lgd.lgd_found = 0;

cfs_mutex_lock(&dir->i_mutex);
rc = ll_readdir(filp, &lgd, ll_nfs_get_name_filldir);
rc = ll_dir_read(dir, &offset, &lgd, ll_nfs_get_name_filldir);
cfs_mutex_unlock(&dir->i_mutex);
if (!rc && !lgd.lgd_found)
rc = -ENOENT;
EXIT;

out_close:
fput(filp);
out:
return rc;
}
Expand Down
13 changes: 4 additions & 9 deletions lustre/llite/statahead.c
Original file line number Diff line number Diff line change
Expand Up @@ -1117,9 +1117,8 @@ static int ll_statahead_thread(void *arg)
cfs_spin_unlock(&plli->lli_sa_lock);
cfs_waitq_signal(&thread->t_ctl_waitq);

plli->lli_sa_pos = 0;
ll_dir_chain_init(&chain);
page = ll_get_dir_page(NULL, dir, pos, &chain);
page = ll_get_dir_page(dir, pos, &chain);

while (1) {
struct lu_dirpage *dp;
Expand Down Expand Up @@ -1276,9 +1275,8 @@ static int ll_statahead_thread(void *arg)
*/
ll_release_page(page, le32_to_cpu(dp->ldp_flags) &
LDF_COLLIDE);
plli->lli_sa_pos = pos;
sai->sai_in_readpage = 1;
page = ll_get_dir_page(NULL, dir, pos, &chain);
page = ll_get_dir_page(dir, pos, &chain);
sai->sai_in_readpage = 0;
} else {
LASSERT(le32_to_cpu(dp->ldp_flags) & LDF_COLLIDE);
Expand Down Expand Up @@ -1394,7 +1392,6 @@ enum {

static int is_first_dirent(struct inode *dir, struct dentry *dentry)
{
struct ll_inode_info *lli = ll_i2info(dir);
struct ll_dir_chain chain;
struct qstr *target = &dentry->d_name;
struct page *page;
Expand All @@ -1403,9 +1400,8 @@ static int is_first_dirent(struct inode *dir, struct dentry *dentry)
int rc = LS_NONE_FIRST_DE;
ENTRY;

lli->lli_sa_pos = 0;
ll_dir_chain_init(&chain);
page = ll_get_dir_page(NULL, dir, pos, &chain);
page = ll_get_dir_page(dir, pos, &chain);

while (1) {
struct lu_dirpage *dp;
Expand Down Expand Up @@ -1492,8 +1488,7 @@ static int is_first_dirent(struct inode *dir, struct dentry *dentry)
*/
ll_release_page(page, le32_to_cpu(dp->ldp_flags) &
LDF_COLLIDE);
lli->lli_sa_pos = pos;
page = ll_get_dir_page(NULL, dir, pos, &chain);
page = ll_get_dir_page(dir, pos, &chain);
} else {
/*
* go into overflow page.
Expand Down

0 comments on commit d8b4866

Please sign in to comment.