Update of /cvsroot/ssic-linux/openssi/lustre/llite
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv587/llite
Modified Files:
Tag: OPENSSI-RH
Makefile.am dcache.c dir.c file.c lproc_llite.c namei.c rw.c
super.c super25.c symlink.c
Log Message:
Finish lustre-1.0.1 import.
Index: Makefile.am
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/lustre/llite/Makefile.am,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** Makefile.am 22 Apr 2003 15:01:23 -0000 1.1
--- Makefile.am 28 Jan 2004 23:48:18 -0000 1.2
***************
*** 10,16 ****
EXTRA_PROGRAMS = llite
! llite_SOURCES = dcache.c commit_callback.c super.c rw.c iod.c super25.c
! llite_SOURCES += file.c dir.c sysctl.c symlink.c
! llite_SOURCES += namei.c lproc_llite.c
include $(top_srcdir)/Rules
--- 10,16 ----
EXTRA_PROGRAMS = llite
! llite_SOURCES = dcache.c dir.c file.c llite_close.c llite_lib.c llite_nfs.c
! llite_SOURCES += lproc_llite.c namei.c rw.c rw24.c special.c super.c super25.c
! llite_SOURCES += symlink.c sysctl.c llite_internal.h
include $(top_srcdir)/Rules
Index: dcache.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/lustre/llite/dcache.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** dcache.c 22 Apr 2003 16:28:56 -0000 1.1
--- dcache.c 28 Jan 2004 23:48:20 -0000 1.2
***************
*** 32,40 ****
#include <linux/lustre_dlm.h>
/* should NOT be called with the dcache lock, see fs/dcache.c */
! void ll_release(struct dentry *de)
{
ENTRY;
OBD_FREE(de->d_fsdata, sizeof(struct ll_dentry_data));
EXIT;
}
--- 32,49 ----
#include <linux/lustre_dlm.h>
+ #include "llite_internal.h"
+
/* should NOT be called with the dcache lock, see fs/dcache.c */
! static void ll_release(struct dentry *de)
{
+ struct ll_dentry_data *lld;
ENTRY;
+ LASSERT(de != NULL);
+ lld = ll_d2d(de);
+ LASSERT(lld != NULL);
+ LASSERT(lld->lld_cwd_count == 0);
+ LASSERT(lld->lld_mnt_count == 0);
OBD_FREE(de->d_fsdata, sizeof(struct ll_dentry_data));
+
EXIT;
}
***************
*** 46,55 ****
lock_kernel();
-
if (de->d_fsdata == NULL) {
OBD_ALLOC(de->d_fsdata, sizeof(struct ll_dentry_data));
- sema_init(&ll_d2d(de)->lld_it_sem, 1);
}
-
unlock_kernel();
--- 55,61 ----
***************
*** 57,88 ****
}
! void ll_intent_release(struct dentry *de, struct lookup_intent *it)
{
struct lustre_handle *handle;
ENTRY;
! LASSERT(ll_d2d(de) != NULL);
! if (it->it_lock_mode) {
! handle = (struct lustre_handle *)it->it_lock_handle;
! ldlm_lock_decref(handle, it->it_lock_mode);
! /* intent_release may be called multiple times, from
! this thread and we don't want to double-decref this
! lock (see bug 494) */
! it->it_lock_mode = 0;
! }
! if (!de->d_it || it->it_op == IT_RELEASED_MAGIC) {
! EXIT;
return;
}
!
! if (de->d_it == it)
! LL_GET_INTENT(de, it);
! else
! CDEBUG(D_INODE, "STRANGE intent release: %p %p\n",
! de->d_it, it);
!
EXIT;
}
--- 63,129 ----
}
! void ll_intent_drop_lock(struct lookup_intent *it)
{
struct lustre_handle *handle;
+
+ if (it->it_op && it->d.lustre.it_lock_mode) {
+ handle = (struct lustre_handle *)&it->d.lustre.it_lock_handle;
+ CDEBUG(D_DLMTRACE, "releasing lock with cookie "LPX64
+ " from it %p\n", handle->cookie, it);
+ ldlm_lock_decref(handle, it->d.lustre.it_lock_mode);
+
+ /* bug 494: intent_release may be called multiple times, from
+ * this thread and we don't want to double-decref this lock */
+ it->d.lustre.it_lock_mode = 0;
+ }
+ }
+
+ void ll_intent_release(struct lookup_intent *it)
+ {
ENTRY;
! ll_intent_drop_lock(it);
! it->it_magic = 0;
! it->it_op_release = 0;
! it->d.lustre.it_disposition = 0;
! it->d.lustre.it_data = NULL;
! EXIT;
! }
! void ll_unhash_aliases(struct inode *inode)
! {
! struct list_head *tmp, *head;
! struct ll_sb_info *sbi;
! ENTRY;
! sbi = ll_i2sbi(inode);
! CDEBUG(D_INODE, "marking dentries for ino %lu/%u(%p) invalid\n",
! inode->i_ino, inode->i_generation, inode);
!
! if (inode == NULL) {
! CERROR("unexpected NULL inode, tell phil\n");
return;
}
! head = &inode->i_dentry;
! restart:
! spin_lock(&dcache_lock);
! tmp = head;
! while ((tmp = tmp->next) != head) {
! struct dentry *dentry = list_entry(tmp, struct dentry, d_alias);
! if (!atomic_read(&dentry->d_count)) {
! dget_locked(dentry);
! __d_drop(dentry);
! spin_unlock(&dcache_lock);
! dput(dentry);
! goto restart;
! } else {
! hlist_del_init(&dentry->d_hash);
! dentry->d_flags |= DCACHE_LUSTRE_INVALID;
! hlist_add_head(&dentry->d_hash,
! &sbi->ll_orphan_dentry_list);
! }
! }
! spin_unlock(&dcache_lock);
EXIT;
}
***************
*** 90,268 ****
extern struct dentry *ll_find_alias(struct inode *, struct dentry *);
! static int revalidate2_finish(int flag, struct ptlrpc_request *request,
! struct inode *parent, struct dentry **de,
! struct lookup_intent *it, int offset, obd_id
ino)
{
! struct ll_sb_info *sbi = ll_i2sbi(parent);
! struct mds_body *body;
! struct lov_stripe_md *lsm = NULL;
! struct lov_mds_md *lmm;
! int lmmsize;
! int rc = 0;
ENTRY;
! /* NB 1 request reference will be taken away by ll_intent_lock()
! * when I return */
!
! if ((flag & LL_LOOKUP_NEGATIVE) != 0)
! GOTO (out, rc = -ENOENT);
!
! /* We only get called if the mdc_enqueue() called from
! * ll_intent_lock() was successful. Therefore the mds_body is
! * present and correct, and the eadata is present (but still
! * opaque, so only obd_unpackmd() can check the size) */
! body = lustre_msg_buf(request->rq_repmsg, offset, sizeof (*body));
! LASSERT (body != NULL);
! LASSERT_REPSWABBED (request, offset);
!
! if (body->valid & OBD_MD_FLEASIZE) {
! /* Only bother with this if inodes's LSM not set? */
! if (body->eadatasize == 0) {
! CERROR ("OBD_MD_FLEASIZE set, but eadatasize 0\n");
! GOTO (out, rc = -EPROTO);
! }
! lmmsize = body->eadatasize;
! lmm = lustre_msg_buf (request->rq_repmsg, offset + 1,
lmmsize);
! LASSERT (lmm != NULL);
! LASSERT_REPSWABBED (request, offset + 1);
! rc = obd_unpackmd (&sbi->ll_osc_conn,
! &lsm, lmm, lmmsize);
! if (rc < 0) {
! CERROR ("Error %d unpacking eadata\n", rc);
! LBUG();
! /* XXX don't know if I should do this... */
! GOTO (out, rc);
! /* or skip the ll_update_inode but still do
! * mdc_lock_set_inode() */
! }
! LASSERT (rc >= sizeof (*lsm));
! rc = 0;
! }
!
! ll_update_inode((*de)->d_inode, body, lsm);
- if (lsm != NULL &&
- ll_i2info((*de)->d_inode)->lli_smd != lsm)
- obd_free_memmd (&sbi->ll_osc_conn, &lsm);
-
- ll_mdc_lock_set_inode((struct lustre_handle *)it->it_lock_handle,
- (*de)->d_inode);
- out:
RETURN(rc);
}
! int ll_have_md_lock(struct dentry *de)
{
! struct ll_sb_info *sbi = ll_s2sbi(de->d_sb);
! struct lustre_handle lockh;
! struct ldlm_res_id res_id = { .name = {0} };
! struct obd_device *obddev;
! ENTRY;
!
! if (!de->d_inode)
! RETURN(0);
! obddev = class_conn2obd(&sbi->ll_mdc_conn);
! res_id.name[0] = de->d_inode->i_ino;
! res_id.name[1] = de->d_inode->i_generation;
! CDEBUG(D_INFO, "trying to match res "LPU64"\n", res_id.name[0]);
! if (ldlm_lock_match(obddev->obd_namespace, LDLM_FL_BLOCK_GRANTED,
! &res_id, LDLM_PLAIN, NULL, 0, LCK_PR, &lockh)) {
! ldlm_lock_decref(&lockh, LCK_PR);
! RETURN(1);
}
! if (ldlm_lock_match(obddev->obd_namespace, LDLM_FL_BLOCK_GRANTED,
! &res_id, LDLM_PLAIN, NULL, 0, LCK_PW, &lockh)) {
! ldlm_lock_decref(&lockh, LCK_PW);
! RETURN(1);
! }
! RETURN(0);
}
! int ll_revalidate2(struct dentry *de, int flags, struct lookup_intent *it)
{
int rc;
ENTRY;
CDEBUG(D_VFSTRACE, "VFS Op:name=%s,intent=%s\n", de->d_name.name,
LL_IT2STR(it));
! /* We don't want to cache negative dentries, so return 0 immediately.
! * We believe that this is safe, that negative dentries cannot be
! * pinned by someone else */
! if (de->d_inode == NULL) {
! CDEBUG(D_INODE, "negative dentry: ret 0 to force lookup2\n");
RETURN(0);
- }
! if (it == NULL || it->it_op == IT_GETATTR) {
! /* We could just return 1 immediately, but since we should
only
! * be called in revalidate2 if we already have a lock, let's
! * verify that. */
! struct inode *inode = de->d_inode;
! struct ll_sb_info *sbi = ll_i2sbi(inode);
! struct obd_device *obddev = class_conn2obd(&sbi->ll_mdc_conn);
! struct ldlm_res_id res_id =
! { .name = {inode->i_ino, (__u64)inode->i_generation}
};
! struct lustre_handle lockh;
! rc = ldlm_lock_match(obddev->obd_namespace,
! LDLM_FL_BLOCK_GRANTED, &res_id,
! LDLM_PLAIN, NULL, 0, LCK_PR, &lockh);
! if (rc) {
! de->d_flags &= ~DCACHE_LUSTRE_INVALID;
! if (it && it->it_op == IT_GETATTR) {
! memcpy(it->it_lock_handle, &lockh,
! sizeof(lockh));
! it->it_lock_mode = LCK_PR;
! LL_SAVE_INTENT(de, it);
! } else {
! ldlm_lock_decref(&lockh, LCK_PR);
! }
! RETURN(1);
! }
! rc = ldlm_lock_match(obddev->obd_namespace,
! LDLM_FL_BLOCK_GRANTED, &res_id,
! LDLM_PLAIN, NULL, 0, LCK_PW, &lockh);
! if (rc) {
! de->d_flags &= ~DCACHE_LUSTRE_INVALID;
! if (it && it->it_op == IT_GETATTR) {
! memcpy(it->it_lock_handle, &lockh,
! sizeof(lockh));
! it->it_lock_mode = LCK_PW;
! LL_SAVE_INTENT(de, it);
! } else {
! ldlm_lock_decref(&lockh, LCK_PW);
! }
! RETURN(1);
}
! if (S_ISDIR(de->d_inode->i_mode))
! ll_invalidate_inode_pages(de->d_inode);
! d_unhash_aliases(de->d_inode);
! RETURN(0);
}
! rc = ll_intent_lock(de->d_parent->d_inode, &de, it,
revalidate2_finish);
! if (rc < 0) {
! CERROR("ll_intent_lock: rc %d : it->it_status %d\n", rc,
! it->it_status);
! RETURN(0);
}
/* unfortunately ll_intent_lock may cause a callback and revoke our
dentry */
spin_lock(&dcache_lock);
! list_del_init(&de->d_hash);
spin_unlock(&dcache_lock);
- d_rehash(de);
! RETURN(1);
}
struct dentry_operations ll_d_ops = {
! .d_revalidate2 = ll_revalidate2,
! .d_intent_release = ll_intent_release,
.d_release = ll_release,
};
--- 131,377 ----
extern struct dentry *ll_find_alias(struct inode *, struct dentry *);
! static int revalidate_it_finish(struct ptlrpc_request *request, int offset,
! struct lookup_intent *it,
! struct dentry *de)
{
! struct ll_sb_info *sbi;
! int rc = 0;
ENTRY;
! if (!request)
! RETURN(0);
! if (it_disposition(it, DISP_LOOKUP_NEG))
! RETURN(-ENOENT);
! sbi = ll_i2sbi(de->d_inode);
! rc = ll_prep_inode(sbi->ll_osc_exp, &de->d_inode, request,
offset,NULL);
RETURN(rc);
}
! void ll_lookup_finish_locks(struct lookup_intent *it, struct dentry *dentry)
{
! LASSERT(it != NULL);
! LASSERT(dentry != NULL);
! if (it->d.lustre.it_lock_mode && dentry->d_inode != NULL) {
! struct inode *inode = dentry->d_inode;
! CDEBUG(D_DLMTRACE, "setting l_data to inode %p (%lu/%u)\n",
! inode, inode->i_ino, inode->i_generation);
! mdc_set_lock_data(&it->d.lustre.it_lock_handle, inode);
! }
! /* drop lookup or getattr locks immediately */
! if (it->it_op == IT_LOOKUP || it->it_op == IT_GETATTR)
! ll_intent_release(it);
! }
! void ll_frob_intent(struct lookup_intent **itp, struct lookup_intent *deft)
! {
! struct lookup_intent *it = *itp;
! #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
! if (it && it->it_magic != INTENT_MAGIC) {
! CERROR("WARNING: uninitialized intent\n");
! LBUG();
}
+ if (it && (it->it_op == IT_GETATTR || it->it_op == 0))
+ it->it_op = IT_LOOKUP;
+
+ #endif
+ if (!it || it->it_op == IT_GETXATTR)
+ it = *itp = deft;
! it->it_op_release = ll_intent_release;
}
! int ll_revalidate_it(struct dentry *de, int flags, struct lookup_intent *it)
{
int rc;
+ struct ll_fid pfid, cfid;
+ struct it_cb_data icbd;
+ struct ll_uctxt ctxt;
+ struct ptlrpc_request *req = NULL;
+ struct lookup_intent lookup_it = { .it_op = IT_LOOKUP };
+ struct obd_export *exp;
+
ENTRY;
CDEBUG(D_VFSTRACE, "VFS Op:name=%s,intent=%s\n", de->d_name.name,
LL_IT2STR(it));
! /* Cached negative dentries are unsafe for now - look them up again */
! if (de->d_inode == NULL)
RETURN(0);
! exp = ll_i2mdcexp(de->d_inode);
! ll_inode2fid(&pfid, de->d_parent->d_inode);
! ll_inode2fid(&cfid, de->d_inode);
! icbd.icbd_parent = de->d_parent->d_inode;
! icbd.icbd_childp = &de;
!
! /*
! * never execute intents for mount points
! * - attrs will be fixed up in ll_revalidate_inode
! */
! if (d_mountpoint(de))
! RETURN(1);
!
! ll_frob_intent(&it, &lookup_it);
! LASSERT(it);
!
! ll_i2uctxt(&ctxt, de->d_parent->d_inode, de->d_inode);
!
! rc = mdc_intent_lock(exp, &ctxt, &pfid, de->d_name.name,
de->d_name.len,
! NULL, 0,
! &cfid, it, flags, &req, ll_mdc_blocking_ast);
! /* If req is NULL, then mdc_intent_lock only tried to do a lock match;
! * if all was well, it will return 1 if it found locks, 0 otherwise.
*/
! if (req == NULL && rc >= 0)
! GOTO(out, rc);
!
! if (rc < 0) {
! if (rc != -ESTALE) {
! CDEBUG(D_INFO, "ll_intent_lock: rc %d : it->it_status
"
! "%d\n", rc, it->d.lustre.it_status);
}
! GOTO(out, rc = 0);
}
! rc = revalidate_it_finish(req, 1, it, de);
! if (rc != 0) {
! ll_intent_release(it);
! GOTO(out, rc = 0);
}
+ rc = 1;
+
/* unfortunately ll_intent_lock may cause a callback and revoke our
dentry */
spin_lock(&dcache_lock);
! hlist_del_init(&de->d_hash);
! __d_rehash(de, 0);
spin_unlock(&dcache_lock);
! out:
! if (req != NULL && rc == 1)
! ptlrpc_req_finished(req);
! if (rc == 0) {
! ll_unhash_aliases(de->d_inode);
! de->d_flags |= DCACHE_LUSTRE_INVALID;
! } else {
! ll_lookup_finish_locks(it, de);
! de->d_flags &= ~DCACHE_LUSTRE_INVALID;
! }
! RETURN(rc);
}
+ /*static*/ void ll_pin(struct dentry *de, struct vfsmount *mnt, int flag)
+ {
+ struct inode *inode= de->d_inode;
+ struct ll_sb_info *sbi = ll_i2sbi(inode);
+ struct ll_dentry_data *ldd = ll_d2d(de);
+ struct obd_client_handle *handle;
+ int rc = 0;
+ ENTRY;
+ LASSERT(ldd);
+
+ lock_kernel();
+ /* Strictly speaking this introduces an additional race: the
+ * increments should wait until the rpc has returned.
+ * However, given that at present the function is void, this
+ * issue is moot. */
+ if (flag == 1 && (++ldd->lld_mnt_count) > 1) {
+ unlock_kernel();
+ EXIT;
+ return;
+ }
+
+ if (flag == 0 && (++ldd->lld_cwd_count) > 1) {
+ unlock_kernel();
+ EXIT;
+ return;
+ }
+ unlock_kernel();
+
+ handle = (flag) ? &ldd->lld_mnt_och : &ldd->lld_cwd_och;
+ rc = obd_pin(sbi->ll_mdc_exp, inode->i_ino, inode->i_generation,
+ inode->i_mode & S_IFMT, handle, flag);
+
+ if (rc) {
+ lock_kernel();
+ memset(handle, 0, sizeof(*handle));
+ if (flag == 0)
+ ldd->lld_cwd_count--;
+ else
+ ldd->lld_mnt_count--;
+ unlock_kernel();
+ }
+
+ EXIT;
+ return;
+ }
+
+ /*static*/ void ll_unpin(struct dentry *de, struct vfsmount *mnt, int flag)
+ {
+ struct ll_sb_info *sbi = ll_i2sbi(de->d_inode);
+ struct ll_dentry_data *ldd = ll_d2d(de);
+ struct obd_client_handle handle;
+ int count, rc = 0;
+ ENTRY;
+ LASSERT(ldd);
+
+ lock_kernel();
+ /* Strictly speaking this introduces an additional race: the
+ * increments should wait until the rpc has returned.
+ * However, given that at present the function is void, this
+ * issue is moot. */
+ handle = (flag) ? ldd->lld_mnt_och : ldd->lld_cwd_och;
+ if (handle.och_magic != OBD_CLIENT_HANDLE_MAGIC) {
+ /* the "pin" failed */
+ unlock_kernel();
+ EXIT;
+ return;
+ }
+
+ if (flag)
+ count = --ldd->lld_mnt_count;
+ else
+ count = --ldd->lld_cwd_count;
+ unlock_kernel();
+
+ if (count != 0) {
+ EXIT;
+ return;
+ }
+
+ rc = obd_unpin(sbi->ll_mdc_exp, &handle, flag);
+ EXIT;
+ return;
+ }
+
+ #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+ static int ll_revalidate_nd(struct dentry *dentry, struct nameidata *nd)
+ {
+ int rc;
+ ENTRY;
+
+ if (nd->flags & LOOKUP_LAST && !(nd->flags & LOOKUP_LINK_NOTLAST))
+ rc = ll_revalidate_it(dentry, nd->flags, &nd->intent);
+ else
+ rc = ll_revalidate_it(dentry, 0, NULL);
+
+ RETURN(rc);
+ }
+ #endif
+
struct dentry_operations ll_d_ops = {
! #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
! .d_revalidate = ll_revalidate_nd,
! #else
! .d_revalidate_it = ll_revalidate_it,
! #endif
.d_release = ll_release,
+ #if 0
+ .d_pin = ll_pin,
+ .d_unpin = ll_unpin,
+ #endif
};
Index: dir.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/lustre/llite/dir.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** dir.c 22 Apr 2003 16:28:56 -0000 1.1
--- dir.c 28 Jan 2004 23:48:21 -0000 1.2
***************
*** 35,41 ****
#include <asm/uaccess.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
! #include <linux/locks.h> // for wait_on_buffer
! #else
! #include <linux/buffer_head.h> // for wait_on_buffer
#endif
--- 35,41 ----
#include <asm/uaccess.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
! # include <linux/locks.h> // for wait_on_buffer
! #else
! # include <linux/buffer_head.h> // for wait_on_buffer
#endif
***************
*** 49,52 ****
--- 49,53 ----
#include <linux/lustre_lite.h>
#include <linux/lustre_dlm.h>
+ #include "llite_internal.h"
typedef struct ext2_dir_entry_2 ext2_dirent;
***************
*** 55,66 ****
#define SetPageChecked(page) set_bit(PG_checked, &(page)->flags)
-
- static int ll_dir_prepare_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
- {
- CDEBUG(D_VFSTRACE, "VFS Op:\n");
- return 0;
- }
-
/* returns the page unlocked, but with a reference */
static int ll_dir_readpage(struct file *file, struct page *page)
--- 56,59 ----
***************
*** 68,72 ****
struct inode *inode = page->mapping->host;
struct ll_sb_info *sbi = ll_i2sbi(inode);
! char *buf;
__u64 offset;
int rc = 0;
--- 61,65 ----
struct inode *inode = page->mapping->host;
struct ll_sb_info *sbi = ll_i2sbi(inode);
! struct ll_fid mdc_fid;
__u64 offset;
int rc = 0;
***************
*** 76,83 ****
struct lookup_intent it = { .it_op = IT_READDIR };
struct mdc_op_data data;
!
ENTRY;
! CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu\n", inode->i_ino);
if ((inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_SHIFT <=
page->index){
/* XXX why do we need this exactly, and why do we think that
--- 69,79 ----
struct lookup_intent it = { .it_op = IT_READDIR };
struct mdc_op_data data;
! struct obd_device *obddev = class_exp2obd(sbi->ll_mdc_exp);
! struct ldlm_res_id res_id =
! { .name = {inode->i_ino, (__u64)inode->i_generation} };
ENTRY;
! CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n", inode->i_ino,
! inode->i_generation, inode);
if ((inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_SHIFT <=
page->index){
/* XXX why do we need this exactly, and why do we think that
***************
*** 91,106 ****
}
! ll_prepare_mdc_op_data(&data, inode, NULL, NULL, 0, 0);
! rc = mdc_enqueue(&sbi->ll_mdc_conn, LDLM_PLAIN, &it, LCK_PR,
! &data, &lockh, NULL, 0,
! ldlm_completion_ast, ll_mdc_blocking_ast, inode);
! request = (struct ptlrpc_request *)it.it_data;
! if (request)
! ptlrpc_req_finished(request);
! if (rc < 0) {
! CERROR("lock enqueue: err: %d\n", rc);
! unlock_page(page);
! RETURN(rc);
}
ldlm_lock_dump_handle(D_OTHER, &lockh);
--- 87,107 ----
}
! rc = ldlm_lock_match(obddev->obd_namespace, LDLM_FL_BLOCK_GRANTED,
! &res_id, LDLM_PLAIN, NULL, 0, LCK_PR, &lockh);
! if (!rc) {
! ll_prepare_mdc_op_data(&data, inode, NULL, NULL, 0, 0);
! rc = mdc_enqueue(sbi->ll_mdc_exp, LDLM_PLAIN, &it, LCK_PR,
! &data, &lockh, NULL, 0,
! ldlm_completion_ast, ll_mdc_blocking_ast,
! inode);
! request = (struct ptlrpc_request *)it.d.lustre.it_data;
! if (request)
! ptlrpc_req_finished(request);
! if (rc < 0) {
! CERROR("lock enqueue: err: %d\n", rc);
! unlock_page(page);
! RETURN(rc);
! }
}
ldlm_lock_dump_handle(D_OTHER, &lockh);
***************
*** 111,124 ****
}
offset = page->index << PAGE_SHIFT;
! buf = kmap(page);
! rc = mdc_readpage(&sbi->ll_mdc_conn, inode->i_ino,
! S_IFDIR, offset, buf, &request);
! kunmap(page);
if (!rc) {
body = lustre_msg_buf(request->rq_repmsg, 0, sizeof (*body));
LASSERT (body != NULL); /* checked by mdc_readpage()
*/
LASSERT_REPSWABBED (request, 0); /* swabbed by mdc_readpage()
*/
!
inode->i_size = body->size;
}
--- 112,125 ----
}
+ mdc_pack_fid(&mdc_fid, inode->i_ino, inode->i_generation, S_IFDIR);
+
offset = page->index << PAGE_SHIFT;
! rc = mdc_readpage(sbi->ll_mdc_exp, &mdc_fid,
! offset, page, &request);
if (!rc) {
body = lustre_msg_buf(request->rq_repmsg, 0, sizeof (*body));
LASSERT (body != NULL); /* checked by mdc_readpage()
*/
LASSERT_REPSWABBED (request, 0); /* swabbed by mdc_readpage()
*/
!
inode->i_size = body->size;
}
***************
*** 131,137 ****
unlock_page(page);
! ll_unlock(LCK_PR, &lockh);
! if (rc != ELDLM_OK)
! CERROR("ll_unlock: err: %d\n", rc);
return rc;
}
--- 132,136 ----
unlock_page(page);
! ldlm_lock_decref(&lockh, LCK_PR);
return rc;
}
***************
*** 139,167 ****
struct address_space_operations ll_dir_aops = {
readpage: ll_dir_readpage,
- prepare_write: ll_dir_prepare_write
};
- #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3))
- int waitfor_one_page(struct page *page)
- {
- int error = 0;
- struct buffer_head *bh, *head = page->buffers;
-
- bh = head;
- do {
- wait_on_buffer(bh);
- if (buffer_req(bh) && !buffer_uptodate(bh))
- error = -EIO;
- } while ((bh = bh->b_this_page) != head);
- return error;
- }
- #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
- int waitfor_one_page(struct page *page)
- {
- wait_on_page_locked(page);
- return 0;
- }
- #endif
-
/*
* ext2 uses block-sized chunks. Arguably, sector-sized ones would be
--- 138,143 ----
***************
*** 184,208 ****
}
- extern void set_page_clean(struct page *page);
-
- static int ext2_commit_chunk(struct page *page, unsigned from, unsigned to)
- {
- struct inode *dir = page->mapping->host;
- loff_t new_size = (page->index << PAGE_CACHE_SHIFT) + to;
- int err = 0;
-
- #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
- dir->i_version = ++event;
- #endif
- if (new_size > dir->i_size)
- dir->i_size = new_size;
- SetPageUptodate(page);
- set_page_clean(page);
-
- //page->mapping->a_ops->commit_write(NULL, page, from, to);
- //if (IS_SYNC(dir))
- // err = waitfor_one_page(page);
- return err;
- }
static void ext2_check_page(struct page *page)
--- 160,163 ----
***************
*** 318,335 ****
}
- /*
- * NOTE! unlike strncmp, ext2_match returns 1 for success, 0 for failure.
- *
- * len <= EXT2_NAME_LEN and de != NULL are guaranteed by caller.
- */
- static inline int ext2_match (int len, const char * const name,
- struct ext2_dir_entry_2 * de)
- {
- if (len != de->name_len)
- return 0;
- if (!de->inode)
- return 0;
- return !memcmp(name, de->name, len);
- }
/*
--- 273,276 ----
***************
*** 362,392 ****
};
- static unsigned int ll_dt2fmt[DT_WHT + 1] = {
- [EXT2_FT_UNKNOWN] 0,
- [EXT2_FT_REG_FILE] S_IFREG,
- [EXT2_FT_DIR] S_IFDIR,
- [EXT2_FT_CHRDEV] S_IFCHR,
- [EXT2_FT_BLKDEV] S_IFBLK,
- [EXT2_FT_FIFO] S_IFIFO,
- [EXT2_FT_SOCK] S_IFSOCK,
- [EXT2_FT_SYMLINK] S_IFLNK
- };
-
- #define S_SHIFT 12
- static unsigned char ext2_type_by_mode[S_IFMT >> S_SHIFT] = {
- [S_IFREG >> S_SHIFT] EXT2_FT_REG_FILE,
- [S_IFDIR >> S_SHIFT] EXT2_FT_DIR,
- [S_IFCHR >> S_SHIFT] EXT2_FT_CHRDEV,
- [S_IFBLK >> S_SHIFT] EXT2_FT_BLKDEV,
- [S_IFIFO >> S_SHIFT] EXT2_FT_FIFO,
- [S_IFSOCK >> S_SHIFT] EXT2_FT_SOCK,
- [S_IFLNK >> S_SHIFT] EXT2_FT_SYMLINK,
- };
-
- static inline void ext2_set_de_type(ext2_dirent *de, struct inode *inode)
- {
- mode_t mode = inode->i_mode;
- de->file_type = ext2_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
- }
int ll_readdir(struct file * filp, void * dirent, filldir_t filldir)
--- 303,306 ----
***************
*** 403,407 ****
ENTRY;
! CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu\n", inode->i_ino);
if (pos > inode->i_size - EXT2_DIR_REC_LEN(1))
GOTO(done, 0);
--- 317,322 ----
ENTRY;
! CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n", inode->i_ino,
! inode->i_generation, inode);
if (pos > inode->i_size - EXT2_DIR_REC_LEN(1))
GOTO(done, 0);
***************
*** 430,434 ****
de = (ext2_dirent *)(kaddr+offset);
limit = kaddr + PAGE_CACHE_SIZE - EXT2_DIR_REC_LEN(1);
! for ( ;(char*)de <= limit; de = ext2_next_entry(de))
if (de->inode) {
int over;
--- 345,349 ----
de = (ext2_dirent *)(kaddr+offset);
limit = kaddr + PAGE_CACHE_SIZE - EXT2_DIR_REC_LEN(1);
! for ( ;(char*)de <= limit; de = ext2_next_entry(de)) {
if (de->inode) {
int over;
***************
*** 447,450 ****
--- 362,366 ----
}
}
+ }
ext2_put_page(page);
}
***************
*** 453,766 ****
filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
filp->f_version = inode->i_version;
! UPDATE_ATIME(inode);
RETURN(0);
}
- /*
- * ext2_find_entry()
- *
- * finds an entry in the specified directory with the wanted name. It
- * returns the page in which the entry was found, and the entry itself
- * (as a parameter - res_dir). Page is returned mapped and unlocked.
- * Entry is guaranteed to be valid.
- */
- struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
- struct dentry *dentry, struct page ** res_page)
- {
- const char *name = dentry->d_name.name;
- int namelen = dentry->d_name.len;
- unsigned reclen = EXT2_DIR_REC_LEN(namelen);
- unsigned long start, n;
- unsigned long npages = dir_pages(dir);
- struct page *page = NULL;
- ext2_dirent * de;
-
- /* OFFSET_CACHE */
- *res_page = NULL;
-
- // start = dir->u.ext2_i.i_dir_start_lookup;
- start = 0;
- if (start >= npages)
- start = 0;
- n = start;
- do {
- char *kaddr;
- page = ll_get_dir_page(dir, n);
- if (!IS_ERR(page)) {
- kaddr = page_address(page);
- de = (ext2_dirent *) kaddr;
- kaddr += PAGE_CACHE_SIZE - reclen;
- while ((char *) de <= kaddr) {
- if (ext2_match (namelen, name, de))
- goto found;
- de = ext2_next_entry(de);
- }
- ext2_put_page(page);
- }
- if (++n >= npages)
- n = 0;
- } while (n != start);
- return NULL;
-
- found:
- *res_page = page;
- // dir->u.ext2_i.i_dir_start_lookup = n;
- return de;
- }
-
- struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p)
- {
- struct page *page = ll_get_dir_page(dir, 0);
- ext2_dirent *de = NULL;
-
- if (!IS_ERR(page)) {
- de = ext2_next_entry((ext2_dirent *) page_address(page));
- *p = page;
- }
- return de;
- }
-
- obd_id ll_inode_by_name(struct inode * dir, struct dentry *dentry, int *type)
- {
- obd_id res = 0;
- struct ext2_dir_entry_2 * de;
- struct page *page;
-
- de = ext2_find_entry (dir, dentry, &page);
- if (de) {
- res = le32_to_cpu(de->inode);
- *type = ll_dt2fmt[de->file_type];
- kunmap(page);
- page_cache_release(page);
- }
- return res;
- }
-
- /* Releases the page */
- void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
- struct page *page, struct inode *inode)
- {
- unsigned from = (char *) de - (char *) page_address(page);
- unsigned to = from + le16_to_cpu(de->rec_len);
- int err;
-
- lock_page(page);
- err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
- if (err)
- LBUG();
- de->inode = cpu_to_le32(inode->i_ino);
- ext2_set_de_type (de, inode);
- dir->i_mtime = dir->i_ctime = CURRENT_TIME;
- err = ext2_commit_chunk(page, from, to);
- unlock_page(page);
- ext2_put_page(page);
- }
-
- /*
- * Parent is locked.
- */
- int ll_add_link (struct dentry *dentry, struct inode *inode)
- {
- struct inode *dir = dentry->d_parent->d_inode;
- const char *name = dentry->d_name.name;
- int namelen = dentry->d_name.len;
- unsigned reclen = EXT2_DIR_REC_LEN(namelen);
- unsigned short rec_len, name_len;
- struct page *page = NULL;
- ext2_dirent * de;
- unsigned long npages = dir_pages(dir);
- unsigned long n;
- char *kaddr;
- unsigned from, to;
- int err;
-
- /* We take care of directory expansion in the same loop */
- for (n = 0; n <= npages; n++) {
- page = ll_get_dir_page(dir, n);
- err = PTR_ERR(page);
- if (IS_ERR(page))
- goto out;
- kaddr = page_address(page);
- de = (ext2_dirent *)kaddr;
- kaddr += PAGE_CACHE_SIZE - reclen;
- while ((char *)de <= kaddr) {
- err = -EEXIST;
- if (ext2_match (namelen, name, de))
- goto out_page;
- name_len = EXT2_DIR_REC_LEN(de->name_len);
- rec_len = le16_to_cpu(de->rec_len);
- if ( n==npages && rec_len == 0) {
- CERROR("Fatal dir behaviour\n");
- goto out_page;
- }
- if (!de->inode && rec_len >= reclen)
- goto got_it;
- if (rec_len >= name_len + reclen)
- goto got_it;
- de = (ext2_dirent *) ((char *) de + rec_len);
- }
- ext2_put_page(page);
- }
- LBUG();
- return -EINVAL;
-
- got_it:
- from = (char*)de - (char*)page_address(page);
- to = from + rec_len;
- lock_page(page);
- err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
- if (err)
- goto out_unlock;
- if (de->inode) {
- ext2_dirent *de1 = (ext2_dirent *) ((char *) de + name_len);
- de1->rec_len = cpu_to_le16(rec_len - name_len);
- de->rec_len = cpu_to_le16(name_len);
- de = de1;
- }
- de->name_len = namelen;
- memcpy (de->name, name, namelen);
- de->inode = cpu_to_le32(inode->i_ino);
- ext2_set_de_type (de, inode);
- CDEBUG(D_INODE, "type set to %o\n", de->file_type);
- dir->i_mtime = dir->i_ctime = CURRENT_TIME;
- err = ext2_commit_chunk(page, from, to);
-
- // change_inode happens with the commit_chunk
- /* XXX OFFSET_CACHE */
-
- out_unlock:
- unlock_page(page);
- out_page:
- ext2_put_page(page);
- out:
- return err;
- }
-
- /*
- * ext2_delete_entry deletes a directory entry by merging it with the
- * previous entry. Page is up-to-date. Releases the page.
- */
- int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
- {
- struct address_space *mapping = page->mapping;
- struct inode *inode = mapping->host;
- char *kaddr = page_address(page);
- unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1);
- unsigned to = ((char*)dir - kaddr) + le16_to_cpu(dir->rec_len);
- ext2_dirent * pde = NULL;
- ext2_dirent * de = (ext2_dirent *) (kaddr + from);
- int err;
-
- while ((char*)de < (char*)dir) {
- pde = de;
- de = ext2_next_entry(de);
- }
- if (pde)
- from = (char*)pde - (char*)page_address(page);
- lock_page(page);
- err = mapping->a_ops->prepare_write(NULL, page, from, to);
- if (err)
- LBUG();
- if (pde)
- pde->rec_len = cpu_to_le16(to-from);
- dir->inode = 0;
- inode->i_ctime = inode->i_mtime = CURRENT_TIME;
- err = ext2_commit_chunk(page, from, to);
- unlock_page(page);
- ext2_put_page(page);
- return err;
- }
-
- /*
- * Set the first fragment of directory.
- */
- int ext2_make_empty(struct inode *inode, struct inode *parent)
- {
- struct address_space *mapping = inode->i_mapping;
- struct page *page = grab_cache_page(mapping, 0);
- unsigned chunk_size = ext2_chunk_size(inode);
- struct ext2_dir_entry_2 * de;
- char *base;
- int err;
- ENTRY;
-
- if (!page)
- return -ENOMEM;
- base = kmap(page);
- if (!base)
- return -ENOMEM;
-
- err = mapping->a_ops->prepare_write(NULL, page, 0, chunk_size);
- if (err)
- goto fail;
-
- de = (struct ext2_dir_entry_2 *) base;
- de->name_len = 1;
- de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(1));
- memcpy (de->name, ".\0\0", 4);
- de->inode = cpu_to_le32(inode->i_ino);
- ext2_set_de_type (de, inode);
-
- de = (struct ext2_dir_entry_2 *) (base + EXT2_DIR_REC_LEN(1));
- de->name_len = 2;
- de->rec_len = cpu_to_le16(chunk_size - EXT2_DIR_REC_LEN(1));
- de->inode = cpu_to_le32(parent->i_ino);
- memcpy (de->name, "..\0", 4);
- ext2_set_de_type (de, inode);
-
- err = ext2_commit_chunk(page, 0, chunk_size);
- fail:
- kunmap(page);
- unlock_page(page);
- page_cache_release(page);
- ENTRY;
- return err;
- }
-
- /*
- * routine to check that the specified directory is empty (for rmdir)
- */
- int ext2_empty_dir (struct inode * inode)
- {
- struct page *page = NULL;
- unsigned long i, npages = dir_pages(inode);
-
- for (i = 0; i < npages; i++) {
- char *kaddr;
- ext2_dirent * de;
- page = ll_get_dir_page(inode, i);
-
- if (IS_ERR(page))
- continue;
-
- kaddr = page_address(page);
- de = (ext2_dirent *)kaddr;
- kaddr += PAGE_CACHE_SIZE-EXT2_DIR_REC_LEN(1);
-
- while ((char *)de <= kaddr) {
- if (de->inode != 0) {
- /* check for . and .. */
- if (de->name[0] != '.')
- goto not_empty;
- if (de->name_len > 2)
- goto not_empty;
- if (de->name_len < 2) {
- if (de->inode !=
- cpu_to_le32(inode->i_ino))
- goto not_empty;
- } else if (de->name[1] != '.')
- goto not_empty;
- }
- de = ext2_next_entry(de);
- }
- ext2_put_page(page);
- }
- return 1;
-
- not_empty:
- ext2_put_page(page);
- return 0;
- }
-
static int ll_dir_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
--- 369,376 ----
filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
filp->f_version = inode->i_version;
! update_atime(inode);
RETURN(0);
}
static int ll_dir_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
***************
*** 769,782 ****
struct obd_ioctl_data *data;
ENTRY;
- CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu,cmd=%u\n", inode->i_ino, cmd);
switch(cmd) {
case IOC_MDC_LOOKUP: {
struct ptlrpc_request *request = NULL;
struct ll_fid fid;
char *buf = NULL;
- struct mds_body *body;
char *filename;
! int namelen, rc, err, len = 0;
unsigned long valid;
--- 379,400 ----
struct obd_ioctl_data *data;
ENTRY;
+ CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), cmd=%#x\n",
+ inode->i_ino, inode->i_generation, inode, cmd);
+
+ if (_IOC_TYPE(cmd) == 'T') /* tty ioctls */
+ return -ENOTTY;
+
+ lprocfs_counter_incr(ll_i2sbi(inode)->ll_stats, LPROC_LL_IOCTL);
switch(cmd) {
+ case EXT3_IOC_GETFLAGS:
+ case EXT3_IOC_SETFLAGS:
+ RETURN( ll_iocontrol(inode, file, cmd, arg) );
case IOC_MDC_LOOKUP: {
struct ptlrpc_request *request = NULL;
struct ll_fid fid;
char *buf = NULL;
char *filename;
! int namelen, rc, len = 0;
unsigned long valid;
***************
*** 790,835 ****
if (namelen < 1) {
! CERROR("IOC_MDC_LOOKUP missing filename\n");
GOTO(out, rc = -EINVAL);
}
! valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLSIZE;
ll_inode2fid(&fid, inode);
! rc = mdc_getattr_name(&sbi->ll_mdc_conn, &fid,
filename, namelen, valid, 0, &request);
if (rc < 0) {
! CERROR("mdc_getattr_name: %d\n", rc);
GOTO(out, rc);
}
body = lustre_msg_buf(request->rq_repmsg, 0, sizeof (*body));
! LASSERT (body != NULL); /* checked by
mdc_getattr_name() */
! LASSERT_REPSWABBED (request, 0); /* swabbed by
mdc_getattr_name() */
!
! /* surely there's a better way -phik */
! data->ioc_obdo1.o_mode = body->mode;
! data->ioc_obdo1.o_uid = body->uid;
! data->ioc_obdo1.o_gid = body->gid;
! ptlrpc_req_finished(request);
! err = copy_to_user((void *)arg, buf, len);
! if (err)
! GOTO(out, rc = -EFAULT);
EXIT;
! out:
obd_ioctl_freedata(buf, len);
return rc;
}
default:
! CERROR("unrecognized ioctl %#x\n", cmd);
! RETURN(-ENOTTY);
}
}
struct file_operations ll_dir_operations = {
read: generic_read_dir,
readdir: ll_readdir,
ioctl: ll_dir_ioctl
};
--- 408,546 ----
if (namelen < 1) {
! CDEBUG(D_INFO, "IOC_MDC_LOOKUP missing filename\n");
GOTO(out, rc = -EINVAL);
}
! valid = OBD_MD_FLID;
ll_inode2fid(&fid, inode);
! rc = mdc_getattr_name(sbi->ll_mdc_exp, &fid,
filename, namelen, valid, 0, &request);
if (rc < 0) {
! CDEBUG(D_INFO, "mdc_getattr_name: %d\n", rc);
GOTO(out, rc);
}
+ ptlrpc_req_finished(request);
+
+ EXIT;
+ out:
+ obd_ioctl_freedata(buf, len);
+ return rc;
+ }
+ case LL_IOC_LOV_SETSTRIPE:
+ case LL_IOC_LOV_GETSTRIPE:
+ RETURN(-ENOTTY);
+ case IOC_MDC_GETSTRIPE: {
+ struct ptlrpc_request *request = NULL;
+ struct ll_fid fid;
+ struct mds_body *body;
+ struct lov_user_md *lump = (struct lov_user_md *)arg;
+ struct lov_mds_md *lmm;
+ char *filename;
+ int rc, lmmsize;
+
+ filename = getname((const char *)arg);
+ if (IS_ERR(filename))
+ RETURN(PTR_ERR(filename));
+
+ ll_inode2fid(&fid, inode);
+ rc = mdc_getattr_name(sbi->ll_mdc_exp, &fid, filename,
+ strlen(filename)+1, OBD_MD_FLEASIZE,
+ obd_size_diskmd(sbi->ll_osc_exp, NULL),
+ &request);
+ if (rc < 0) {
+ CDEBUG(D_INFO, "mdc_getattr_name failed on %s: rc
%d\n",
+ filename, rc);
+ GOTO(out_name, rc);
+ }
+
body = lustre_msg_buf(request->rq_repmsg, 0, sizeof (*body));
! LASSERT(body != NULL); /* checked by mdc_getattr_name
*/
! LASSERT_REPSWABBED(request, 0);/* swabbed by mdc_getattr_name
*/
! lmmsize = body->eadatasize;
! if (!(body->valid & OBD_MD_FLEASIZE) || lmmsize == 0)
! GOTO(out_req, rc = -ENODATA);
!
! if (lmmsize > 4096)
! GOTO(out_req, rc = -EFBIG);
!
! lmm = lustre_msg_buf(request->rq_repmsg, 1, lmmsize);
! LASSERT(lmm != NULL);
! LASSERT_REPSWABBED(request, 1);
!
! rc = copy_to_user(lump, lmm, lmmsize);
! if (rc)
! GOTO(out_req, rc = -EFAULT);
EXIT;
! out_req:
! ptlrpc_req_finished(request);
! out_name:
! putname(filename);
! return rc;
! }
! case OBD_IOC_PING: {
! struct ptlrpc_request *req = NULL;
! char *buf = NULL;
! int rc, len=0;
! struct client_obd *cli;
! struct obd_device *obd;
!
! rc = obd_ioctl_getdata(&buf, &len, (void *)arg);
! if (rc)
! RETURN(rc);
! data = (void *)buf;
!
! obd = class_name2obd(data->ioc_inlbuf1);
!
! if (!obd )
! GOTO(out_ping, rc = -ENODEV);
!
! if (!obd->obd_attached) {
! CERROR("Device %d not attached\n", obd->obd_minor);
! GOTO(out_ping, rc = -ENODEV);
! }
! if (!obd->obd_set_up) {
! CERROR("Device %d still not setup\n", obd->obd_minor);
! GOTO(out_ping, rc = -ENODEV);
! }
! cli = &obd->u.cli;
! req = ptlrpc_prep_req(cli->cl_import, OBD_PING, 0, NULL,
NULL);
! if (!req)
! GOTO(out_ping, rc = -ENOMEM);
!
! req->rq_replen = lustre_msg_size(0, NULL);
! req->rq_send_state = LUSTRE_IMP_FULL;
!
! rc = ptlrpc_queue_wait(req);
!
! ptlrpc_req_finished(req);
! out_ping:
obd_ioctl_freedata(buf, len);
return rc;
}
default:
! return obd_iocontrol(cmd, sbi->ll_osc_exp,0,NULL,(void *)arg);
}
}
+ int ll_dir_open(struct inode *inode, struct file *file)
+ {
+ return ll_file_open(inode, file);
+ }
+
+ int ll_dir_release(struct inode *inode, struct file *file)
+ {
+ return ll_file_release(inode, file);
+ }
+
struct file_operations ll_dir_operations = {
+ open: ll_dir_open,
+ release: ll_dir_release,
read: generic_read_dir,
readdir: ll_readdir,
ioctl: ll_dir_ioctl
};
+
Index: file.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/lustre/llite/file.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** file.c 23 Apr 2003 18:35:25 -0000 1.1
--- file.c 28 Jan 2004 23:48:21 -0000 1.2
***************
*** 29,110 ****
#include <linux/random.h>
#include <linux/pagemap.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
! #define filemap_fdatawrite(map) filemap_fdatasync(map)
#endif
! int ll_inode_setattr(struct inode *inode, struct iattr *attr, int do_trunc);
! extern int ll_setattr(struct dentry *de, struct iattr *attr);
!
! static int ll_mdc_close(struct lustre_handle *mdc_conn, struct inode *inode,
[...2034 lines suppressed...]
- revalidate: ll_inode_revalidate,
- #endif
- };
--- 1124,1139 ----
llseek: ll_file_seek,
fsync: ll_fsync,
+ //lock: ll_file_flock
};
struct inode_operations ll_file_inode_operations = {
setattr_raw: ll_setattr_raw,
! setattr: ll_setattr,
! truncate: ll_truncate,
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
! getattr_it: ll_getattr,
#else
! revalidate_it: ll_inode_revalidate_it,
#endif
};
Index: lproc_llite.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/lustre/llite/lproc_llite.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** lproc_llite.c 22 Apr 2003 16:28:56 -0000 1.1
--- lproc_llite.c 28 Jan 2004 23:48:30 -0000 1.2
***************
*** 23,33 ****
#include <linux/version.h>
- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
- #include <asm/statfs.h>
- #endif
#include <linux/lustre_lite.h>
#include <linux/lprocfs_status.h>
/* /proc/lustre/llite mount point registration */
#ifndef LPROCFS
--- 23,33 ----
#include <linux/version.h>
#include <linux/lustre_lite.h>
#include <linux/lprocfs_status.h>
+ #include "llite_internal.h"
+
/* /proc/lustre/llite mount point registration */
+ struct proc_dir_entry *proc_lustre_fs_root;
#ifndef LPROCFS
***************
*** 37,72 ****
return 0;
}
#else
! #define LPROC_LLITE_STAT_FCT(fct_name, get_statfs_fct) \
! int fct_name(char *page, char **start, off_t off, \
! int count, int *eof, void *data) \
! { \
! struct statfs sfs; \
! int rc; \
! LASSERT(data != NULL); \
! rc = get_statfs_fct((struct super_block*)data, &sfs); \
! return (rc==0 \
! ? lprocfs_##fct_name (page, start, off, count, eof, &sfs) \
! : rc); \
}
! long long mnt_instance;
! LPROC_LLITE_STAT_FCT(rd_blksize, vfs_statfs);
! LPROC_LLITE_STAT_FCT(rd_kbytestotal, vfs_statfs);
! LPROC_LLITE_STAT_FCT(rd_kbytesfree, vfs_statfs);
! LPROC_LLITE_STAT_FCT(rd_filestotal, vfs_statfs);
! LPROC_LLITE_STAT_FCT(rd_filesfree, vfs_statfs);
! LPROC_LLITE_STAT_FCT(rd_filegroups, vfs_statfs);
! int rd_path(char *page, char **start, off_t off, int count, int *eof,
! void *data)
{
return 0;
}
! int rd_fstype(char *page, char **start, off_t off, int count, int *eof,
! void *data)
{
struct super_block *sb = (struct super_block*)data;
--- 37,150 ----
return 0;
}
+ void lprocfs_unregister_mountpoint(struct ll_sb_info *sbi){}
#else
! long long mnt_instance;
!
! static int ll_rd_blksize(char *page, char **start, off_t off, int count,
! int *eof, void *data)
! {
! struct super_block *sb = (struct super_block *)data;
! struct obd_statfs osfs;
! int rc;
!
! LASSERT(sb != NULL);
! rc = ll_statfs_internal(sb, &osfs, jiffies - HZ);
! if (!rc) {
! *eof = 1;
! rc = snprintf(page, count, "%u\n", osfs.os_bsize);
! }
!
! return rc;
}
! static int ll_rd_kbytestotal(char *page, char **start, off_t off, int count,
! int *eof, void *data)
! {
! struct super_block *sb = (struct super_block *)data;
! struct obd_statfs osfs;
! int rc;
! LASSERT(sb != NULL);
! rc = ll_statfs_internal(sb, &osfs, jiffies - HZ);
! if (!rc) {
! __u32 blk_size = osfs.os_bsize >> 10;
! __u64 result = osfs.os_blocks;
! while (blk_size >>= 1)
! result <<= 1;
!
! *eof = 1;
! rc = snprintf(page, count, LPU64"\n", result);
! }
! return rc;
!
! }
!
! static int ll_rd_kbytesfree(char *page, char **start, off_t off, int count,
! int *eof, void *data)
! {
! struct super_block *sb = (struct super_block *)data;
! struct obd_statfs osfs;
! int rc;
!
! LASSERT(sb != NULL);
! rc = ll_statfs_internal(sb, &osfs, jiffies - HZ);
! if (!rc) {
! __u32 blk_size = osfs.os_bsize >> 10;
! __u64 result = osfs.os_bfree;
!
! while (blk_size >>= 1)
! result <<= 1;
!
! *eof = 1;
! rc = snprintf(page, count, LPU64"\n", result);
! }
! return rc;
! }
!
! static int ll_rd_filestotal(char *page, char **start, off_t off, int count,
! int *eof, void *data)
! {
! struct super_block *sb = (struct super_block *)data;
! struct obd_statfs osfs;
! int rc;
!
! LASSERT(sb != NULL);
! rc = ll_statfs_internal(sb, &osfs, jiffies - HZ);
! if (!rc) {
! *eof = 1;
! rc = snprintf(page, count, LPU64"\n", osfs.os_files);
! }
! return rc;
! }
!
! static int ll_rd_filesfree(char *page, char **start, off_t off, int count,
! int *eof, void *data)
! {
! struct super_block *sb = (struct super_block *)data;
! struct obd_statfs osfs;
! int rc;
!
! LASSERT(sb != NULL);
! rc = ll_statfs_internal(sb, &osfs, jiffies - HZ);
! if (!rc) {
! *eof = 1;
! rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
! }
! return rc;
!
! }
!
! #if 0
! static int ll_rd_path(char *page, char **start, off_t off, int count, int
*eof,
! void *data)
{
return 0;
}
+ #endif
! static int ll_rd_fstype(char *page, char **start, off_t off, int count,
! int *eof, void *data)
{
struct super_block *sb = (struct super_block*)data;
***************
*** 77,82 ****
}
! int rd_sb_uuid(char *page, char **start, off_t off, int count, int *eof,
! void *data)
{
struct super_block *sb = (struct super_block *)data;
--- 155,160 ----
}
! static int ll_rd_sb_uuid(char *page, char **start, off_t off, int count,
! int *eof, void *data)
{
struct super_block *sb = (struct super_block *)data;
***************
*** 87,104 ****
}
! struct lprocfs_vars lprocfs_obd_vars[] = {
! { "uuid", rd_sb_uuid, 0, 0 },
! { "mntpt_path", rd_path, 0, 0 },
! { "fstype", rd_fstype, 0, 0 },
! { "blocksize", rd_blksize, 0, 0 },
! { "kbytestotal", rd_kbytestotal, 0, 0 },
! { "kbytesfree", rd_kbytesfree, 0, 0 },
! { "filestotal", rd_filestotal, 0, 0 },
! { "filesfree", rd_filesfree, 0, 0 },
! { "filegroups", rd_filegroups, 0, 0 },
{ 0 }
};
#define MAX_STRING_SIZE 128
int lprocfs_register_mountpoint(struct proc_dir_entry *parent,
struct super_block *sb, char *osc, char *mdc)
--- 165,266 ----
}
! static int ll_rd_read_ahead(char *page, char **start, off_t off, int count,
! int *eof, void *data)
! {
! struct super_block *sb = (struct super_block*)data;
! struct ll_sb_info *sbi = ll_s2sbi(sb);
! int val, rc;
! ENTRY;
!
! *eof = 1;
! val = (sbi->ll_flags & LL_SBI_READAHEAD) ? 1 : 0;
! rc = snprintf(page, count, "%d\n", val);
! RETURN(rc);
! }
!
! static int ll_wr_read_ahead(struct file *file, const char *buffer,
! unsigned long count, void *data)
! {
! struct super_block *sb = (struct super_block*)data;
! struct ll_sb_info *sbi = ll_s2sbi(sb);
! int readahead;
! ENTRY;
!
! if (1 != sscanf(buffer, "%d", &readahead))
! RETURN(-EINVAL);
!
! if (readahead)
! sbi->ll_flags |= LL_SBI_READAHEAD;
! else
! sbi->ll_flags &= ~LL_SBI_READAHEAD;
!
! RETURN(count);
! }
!
! static struct lprocfs_vars lprocfs_obd_vars[] = {
! { "uuid", ll_rd_sb_uuid, 0, 0 },
! //{ "mntpt_path", ll_rd_path, 0, 0 },
! { "fstype", ll_rd_fstype, 0, 0 },
! { "blocksize", ll_rd_blksize, 0, 0 },
! { "kbytestotal", ll_rd_kbytestotal, 0, 0 },
! { "kbytesfree", ll_rd_kbytesfree, 0, 0 },
! { "filestotal", ll_rd_filestotal, 0, 0 },
! { "filesfree", ll_rd_filesfree, 0, 0 },
! //{ "filegroups", lprocfs_rd_filegroups, 0, 0 },
! { "read_ahead", ll_rd_read_ahead, ll_wr_read_ahead, 0 },
{ 0 }
};
#define MAX_STRING_SIZE 128
+
+ struct llite_file_opcode {
+ __u32 opcode;
+ __u32 type;
+ const char *opname;
+ } llite_opcode_table[LPROC_LL_FILE_OPCODES] = {
+ /* file operation */
+ { LPROC_LL_DIRTY_HITS, LPROCFS_TYPE_REGS, "dirty_pages_hits" },
+ { LPROC_LL_DIRTY_MISSES, LPROCFS_TYPE_REGS, "dirty_pages_misses" },
+ { LPROC_LL_WB_WRITEPAGE, LPROCFS_CNTR_AVGMINMAX|LPROCFS_TYPE_PAGES,
+ "writeback_from_writepage" },
+ { LPROC_LL_WB_PRESSURE, LPROCFS_CNTR_AVGMINMAX|LPROCFS_TYPE_PAGES,
+ "writeback_from_pressure" },
+ { LPROC_LL_WB_OK, LPROCFS_CNTR_AVGMINMAX|LPROCFS_TYPE_PAGES,
+ "writeback_ok_pages" },
+ { LPROC_LL_WB_FAIL, LPROCFS_CNTR_AVGMINMAX|LPROCFS_TYPE_PAGES,
+ "writeback_failed_pages" },
+ { LPROC_LL_READ_BYTES, LPROCFS_CNTR_AVGMINMAX|LPROCFS_TYPE_BYTES,
+ "read_bytes" },
+ { LPROC_LL_WRITE_BYTES, LPROCFS_CNTR_AVGMINMAX|LPROCFS_TYPE_BYTES,
+ "write_bytes" },
+ { LPROC_LL_BRW_READ, LPROCFS_CNTR_AVGMINMAX|LPROCFS_TYPE_PAGES,
+ "brw_read" },
+ { LPROC_LL_BRW_WRITE, LPROCFS_CNTR_AVGMINMAX|LPROCFS_TYPE_PAGES,
+ "brw_write" },
+
+ { LPROC_LL_IOCTL, LPROCFS_TYPE_REGS, "ioctl" },
+ { LPROC_LL_OPEN, LPROCFS_TYPE_REGS, "open" },
+ { LPROC_LL_RELEASE, LPROCFS_TYPE_REGS, "close" },
+ { LPROC_LL_MAP, LPROCFS_TYPE_REGS, "mmap" },
+ { LPROC_LL_LLSEEK, LPROCFS_TYPE_REGS, "seek" },
+ { LPROC_LL_FSYNC, LPROCFS_TYPE_REGS, "fsync" },
+ /* inode operation */
+ { LPROC_LL_SETATTR, LPROCFS_TYPE_REGS, "setattr" },
+ { LPROC_LL_TRUNC, LPROCFS_TYPE_REGS, "punch" },
+ #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+ { LPROC_LL_GETATTR, LPROCFS_TYPE_REGS, "getattr" },
+ #else
+ { LPROC_LL_REVALIDATE, LPROCFS_TYPE_REGS, "getattr" },
+ #endif
+ /* special inode operation */
+ { LPROC_LL_STAFS, LPROCFS_TYPE_REGS, "statfs" },
+ { LPROC_LL_ALLOC_INODE, LPROCFS_TYPE_REGS, "alloc_inode" },
+ { LPROC_LL_DIRECT_READ, LPROCFS_CNTR_AVGMINMAX|LPROCFS_TYPE_PAGES,
+ "direct_read" },
+ { LPROC_LL_DIRECT_WRITE, LPROCFS_CNTR_AVGMINMAX|LPROCFS_TYPE_PAGES,
+ "direct_write" },
+
+ };
+
int lprocfs_register_mountpoint(struct proc_dir_entry *parent,
struct super_block *sb, char *osc, char *mdc)
***************
*** 107,114 ****
struct ll_sb_info *sbi = ll_s2sbi(sb);
struct obd_device *obd;
- struct proc_dir_entry *entry;
char name[MAX_STRING_SIZE + 1];
! struct obd_uuid uuid;
! int err;
ENTRY;
--- 269,275 ----
struct ll_sb_info *sbi = ll_s2sbi(sb);
struct obd_device *obd;
char name[MAX_STRING_SIZE + 1];
! int err, id;
! struct lprocfs_stats *svc_stats = NULL;
ENTRY;
***************
*** 132,150 ****
RETURN(err);
}
/* Static configuration info */
err = lprocfs_add_vars(sbi->ll_proc_root, lprocfs_obd_vars, sb);
if (err)
! RETURN(err);
!
! /* llite page cache stats */
! entry = create_proc_entry("pgcache", 0444, sbi->ll_proc_root);
! if (entry == NULL)
! RETURN(-ENOMEM);
! entry->proc_fops = &ll_pgcache_seq_fops;
! entry->data = sbi;
/* MDC info */
! strncpy(uuid.uuid, mdc, sizeof(uuid.uuid));
! obd = class_uuid2obd(&uuid);
LASSERT(obd != NULL);
--- 293,334 ----
RETURN(err);
}
+
+ svc_stats = lprocfs_alloc_stats(LPROC_LL_FILE_OPCODES);
+ if (svc_stats == NULL) {
+ err = -ENOMEM;
+ goto out;
+ }
+ /* do counter init */
+ for (id = 0; id < LPROC_LL_FILE_OPCODES; id++) {
+ __u32 type = llite_opcode_table[id].type;
+ void *ptr = NULL;
+ if (type & LPROCFS_TYPE_REGS)
+ ptr = "regs";
+ else {
+ if (type & LPROCFS_TYPE_BYTES)
+ ptr = "bytes";
+ else {
+ if (type & LPROCFS_TYPE_PAGES)
+ ptr = "pages";
+ }
+ }
+ lprocfs_counter_init(svc_stats, llite_opcode_table[id].opcode,
+ (type & LPROCFS_CNTR_AVGMINMAX),
+ llite_opcode_table[id].opname, ptr);
+ }
+ err = lprocfs_register_stats(sbi->ll_proc_root, "stats", svc_stats);
+ if (err)
+ goto out;
+ else
+ sbi->ll_stats = svc_stats;
+ /* need place to keep svc_stats */
+
/* Static configuration info */
err = lprocfs_add_vars(sbi->ll_proc_root, lprocfs_obd_vars, sb);
if (err)
! goto out;
/* MDC info */
! obd = class_name2obd(mdc);
LASSERT(obd != NULL);
***************
*** 157,171 ****
err = lprocfs_add_vars(sbi->ll_proc_root, lvars, obd);
if (err)
! RETURN(err);
snprintf(name, MAX_STRING_SIZE, "%s/uuid", obd->obd_type->typ_name);
lvars[0].read_fptr = lprocfs_rd_uuid;
err = lprocfs_add_vars(sbi->ll_proc_root, lvars, obd);
! if (err < 0)
! RETURN(err);
/* OSC */
! strncpy(uuid.uuid, osc, sizeof(uuid.uuid));
! obd = class_uuid2obd(&uuid);
LASSERT(obd != NULL);
--- 341,354 ----
err = lprocfs_add_vars(sbi->ll_proc_root, lvars, obd);
if (err)
! goto out;
snprintf(name, MAX_STRING_SIZE, "%s/uuid", obd->obd_type->typ_name);
lvars[0].read_fptr = lprocfs_rd_uuid;
err = lprocfs_add_vars(sbi->ll_proc_root, lvars, obd);
! if (err)
! goto out;
/* OSC */
! obd = class_name2obd(osc);
LASSERT(obd != NULL);
***************
*** 178,190 ****
err = lprocfs_add_vars(sbi->ll_proc_root, lvars, obd);
if (err)
! RETURN(err);
snprintf(name, MAX_STRING_SIZE, "%s/uuid", obd->obd_type->typ_name);
lvars[0].read_fptr = lprocfs_rd_uuid;
err = lprocfs_add_vars(sbi->ll_proc_root, lvars, obd);
!
RETURN(err);
}
#undef MAX_STRING_SIZE
#endif /* LPROCFS */
--- 361,391 ----
err = lprocfs_add_vars(sbi->ll_proc_root, lvars, obd);
if (err)
! goto out;
snprintf(name, MAX_STRING_SIZE, "%s/uuid", obd->obd_type->typ_name);
lvars[0].read_fptr = lprocfs_rd_uuid;
err = lprocfs_add_vars(sbi->ll_proc_root, lvars, obd);
! out:
! if (err) {
! if (svc_stats)
! lprocfs_free_stats(svc_stats);
! if (sbi->ll_proc_root)
! lprocfs_remove(sbi->ll_proc_root);
! }
RETURN(err);
}
+ void lprocfs_unregister_mountpoint(struct ll_sb_info *sbi)
+ {
+ if (sbi->ll_proc_root) {
+ struct proc_dir_entry *file_stats =
+ lprocfs_srch(sbi->ll_proc_root, "stats");
+
+ if (file_stats) {
+ lprocfs_free_stats(sbi->ll_stats);
+ lprocfs_remove(file_stats);
+ }
+ }
+ }
#undef MAX_STRING_SIZE
#endif /* LPROCFS */
Index: namei.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/lustre/llite/namei.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** namei.c 24 Apr 2003 21:25:26 -0000 1.1
--- namei.c 28 Jan 2004 23:48:30 -0000 1.2
***************
*** 42,107 ****
#include <linux/lustre_lite.h>
#include <linux/lustre_dlm.h>
!
! /* from dcache.c */
! extern void ll_set_dd(struct dentry *de);
!
! /* from super.c */
! extern void ll_change_inode(struct inode *inode);
! extern int ll_setattr(struct dentry *de, struct iattr *attr);
!
[...1918 lines suppressed...]
! link_raw: ll_link_raw,
! unlink_raw: ll_unlink_raw,
! symlink_raw: ll_symlink_raw,
! mkdir_raw: ll_mkdir_raw,
! rmdir_raw: ll_rmdir_raw,
! mknod_raw: ll_mknod_raw,
! mknod: ll_mknod,
! rename_raw: ll_rename_raw,
setattr: ll_setattr,
setattr_raw: ll_setattr_raw,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
! create_it: ll_create_it,
! lookup_it: ll_lookup_it,
! revalidate_it: ll_inode_revalidate_it,
! #else
! lookup: ll_lookup_nd,
! create: ll_create_nd,
! getattr_it: ll_getattr,
#endif
};
Index: rw.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/lustre/llite/rw.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** rw.c 22 Apr 2003 16:28:56 -0000 1.1
--- rw.c 28 Jan 2004 23:48:30 -0000 1.2
***************
*** 2,6 ****
* vim:expandtab:shiftwidth=8:tabstop=8:
*
! * Lustre Lite I/O Page Cache
*
* Copyright (c) 2001-2003 Cluster File Systems, Inc.
--- 2,6 ----
* vim:expandtab:shiftwidth=8:tabstop=8:
*
! * Lustre Lite I/O page cache routines shared by different kernel revs
*
[...1062 lines suppressed...]
! CDEBUG(D_INODE, "didn't match a lock");
! if (time_after(jiffies, next_print)) {
! next_print = jiffies + 30 * HZ;
! CERROR("not covered by a lock (mmap?). check debug "
! "logs.\n");
! }
! }
!
! rc = ll_start_readpage(exp, inode, page);
! if (rc == 0 && (sbi->ll_flags & LL_SBI_READAHEAD))
! ll_start_readahead(exp, inode, page->index);
!
! if (matched == 1)
! obd_cancel(ll_i2sbi(inode)->ll_osc_exp,
! ll_i2info(inode)->lli_smd, LCK_PR, &match_lockh);
! out:
! if (rc)
! unlock_page(page);
! RETURN(rc);
! }
Index: super.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/lustre/llite/super.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** super.c 24 Apr 2003 21:25:26 -0000 1.1
--- super.c 28 Jan 2004 23:48:31 -0000 1.2
***************
*** 33,717 ****
#include <linux/fs.h>
#include <linux/lprocfs_status.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
- kmem_cache_t *ll_file_data_slab;
extern struct address_space_operations ll_aops;
extern struct address_space_operations ll_dir_aops;
- struct super_operations ll_super_operations;
-
- /* /proc/lustre/llite root that tracks llite mount points */
- struct proc_dir_entry *proc_lustre_fs_root = NULL;
- /* lproc_llite.c */
- extern int lprocfs_register_mountpoint(struct proc_dir_entry *parent,
- struct super_block *sb,
- char *osc, char *mdc);
-
- extern int ll_recover(struct recovd_data *, int);
- extern int ll_commitcbd_setup(struct ll_sb_info *);
- extern int ll_commitcbd_cleanup(struct ll_sb_info *);
-
- static char *ll_read_opt(const char *opt, char *data)
- {
- char *value;
- char *retval;
- ENTRY;
-
- CDEBUG(D_SUPER, "option: %s, data %s\n", opt, data);
- if (strncmp(opt, data, strlen(opt)))
- RETURN(NULL);
- if ((value = strchr(data, '=')) == NULL)
- RETURN(NULL);
-
- value++;
- OBD_ALLOC(retval, strlen(value) + 1);
- if (!retval) {
- CERROR("out of memory!\n");
- RETURN(NULL);
- }
-
- memcpy(retval, value, strlen(value)+1);
- CDEBUG(D_SUPER, "Assigned option: %s, value %s\n", opt, retval);
- RETURN(retval);
- }
-
- static int ll_set_opt(const char *opt, char *data, int fl)
- {
- ENTRY;
-
- CDEBUG(D_SUPER, "option: %s, data %s\n", opt, data);
- if (strncmp(opt, data, strlen(opt)))
- RETURN(0);
- else
- RETURN(fl);
- }
-
- static void ll_options(char *options, char **ost, char **mds, int *flags)
- {
- char *this_char;
- ENTRY;
-
- if (!options) {
- EXIT;
- return;
- }
-
- for (this_char = strtok (options, ",");
- this_char != NULL;
- this_char = strtok (NULL, ",")) {
- CDEBUG(D_SUPER, "this_char %s\n", this_char);
- if ((!*ost && (*ost = ll_read_opt("osc", this_char)))||
- (!*mds && (*mds = ll_read_opt("mdc", this_char)))||
- (!(*flags & LL_SBI_NOLCK) &&
- ((*flags) = (*flags) |
- ll_set_opt("nolock", this_char, LL_SBI_NOLCK))))
- continue;
- }
- EXIT;
- }
-
- #ifndef log2
- #define log2(n) ffz(~(n))
- #endif
static struct super_block *ll_read_super(struct super_block *sb,
void *data, int silent)
{
- struct inode *root = 0;
- struct obd_device *obd;
- struct ll_sb_info *sbi;
- char *osc = NULL;
- char *mdc = NULL;
int err;
- struct ll_fid rootfid;
- struct obd_statfs osfs;
- struct ptlrpc_request *request = NULL;
- struct ptlrpc_connection *mdc_conn;
- struct ll_read_inode2_cookie lic;
- class_uuid_t uuid;
- struct obd_uuid param_uuid;
-
ENTRY;
!
! CDEBUG(D_VFSTRACE, "VFS Op:\n");
! OBD_ALLOC(sbi, sizeof(*sbi));
! if (!sbi)
RETURN(NULL);
-
- INIT_LIST_HEAD(&sbi->ll_conn_chain);
- INIT_LIST_HEAD(&sbi->ll_orphan_dentry_list);
- generate_random_uuid(uuid);
- spin_lock_init(&sbi->ll_iostats.fis_lock);
- class_uuid_unparse(uuid, &sbi->ll_sb_uuid);
-
- sb->u.generic_sbp = sbi;
-
- ll_options(data, &osc, &mdc, &sbi->ll_flags);
-
- if (!osc) {
- CERROR("no osc\n");
- GOTO(out_free, sb = NULL);
- }
-
- if (!mdc) {
- CERROR("no mdc\n");
- GOTO(out_free, sb = NULL);
- }
-
- strncpy(param_uuid.uuid, mdc, sizeof(param_uuid.uuid));
- obd = class_uuid2obd(¶m_uuid);
- if (!obd) {
- CERROR("MDC %s: not setup or attached\n", mdc);
- GOTO(out_free, sb = NULL);
- }
-
- err = obd_connect(&sbi->ll_mdc_conn, obd, &sbi->ll_sb_uuid);
- if (err) {
- CERROR("cannot connect to %s: rc = %d\n", mdc, err);
- GOTO(out_free, sb = NULL);
- }
-
- mdc_conn = sbi2mdc(sbi)->cl_import->imp_connection;
-
- strncpy(param_uuid.uuid, osc, sizeof(param_uuid.uuid));
- obd = class_uuid2obd(¶m_uuid);
- if (!obd) {
- CERROR("OSC %s: not setup or attached\n", osc);
- GOTO(out_mdc, sb = NULL);
- }
-
- err = obd_connect(&sbi->ll_osc_conn, obd, &sbi->ll_sb_uuid);
- if (err) {
- CERROR("cannot connect to %s: rc = %d\n", osc, err);
- GOTO(out_mdc, sb = NULL);
- }
-
- err = mdc_getstatus(&sbi->ll_mdc_conn, &rootfid);
- if (err) {
- CERROR("cannot mds_connect: rc = %d\n", err);
- GOTO(out_osc, sb = NULL);
- }
- CDEBUG(D_SUPER, "rootfid "LPU64"\n", rootfid.id);
- sbi->ll_rootino = rootfid.id;
-
- memset(&osfs, 0, sizeof(osfs));
- err = obd_statfs(&sbi->ll_mdc_conn, &osfs);
- sb->s_blocksize = osfs.os_bsize;
- sb->s_blocksize_bits = log2(osfs.os_bsize);
- sb->s_magic = LL_SUPER_MAGIC;
- sb->s_maxbytes = (1ULL << (32 + 9)) - osfs.os_bsize;
-
- sb->s_op = &ll_super_operations;
-
- /* make root inode
- * XXX: move this to after cbd setup? */
- err = mdc_getattr(&sbi->ll_mdc_conn, &rootfid,
- OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, 0, &request);
- if (err) {
- CERROR("mdc_getattr failed for root: rc = %d\n", err);
- GOTO(out_osc, sb = NULL);
- }
-
- /* initialize committed transaction callback daemon */
- spin_lock_init(&sbi->ll_commitcbd_lock);
- init_waitqueue_head(&sbi->ll_commitcbd_waitq);
- init_waitqueue_head(&sbi->ll_commitcbd_ctl_waitq);
- sbi->ll_commitcbd_flags = 0;
- err = ll_commitcbd_setup(sbi);
- if (err) {
- CERROR("failed to start commit callback daemon: rc =
%d\n",err);
- ptlrpc_req_finished (request);
- GOTO(out_osc, sb = NULL);
- }
-
- lic.lic_body = lustre_msg_buf(request->rq_repmsg, 0,
- sizeof(*lic.lic_body));
- LASSERT (lic.lic_body != NULL); /* checked by mdc_getattr() */
- LASSERT_REPSWABBED (request, 0); /* swabbed by mdc_getattr() */
-
- lic.lic_lsm = NULL;
-
- LASSERT(sbi->ll_rootino != 0);
- root = iget4(sb, sbi->ll_rootino, NULL, &lic);
-
- ptlrpc_req_finished(request);
-
- if (root == NULL || is_bad_inode(root)) {
- /* XXX might need iput() for bad inode */
- CERROR("lustre_lite: bad iget4 for root\n");
- GOTO(out_cbd, sb = NULL);
- }
-
- sb->s_root = d_alloc_root(root);
-
- if (proc_lustre_fs_root) {
- err = lprocfs_register_mountpoint(proc_lustre_fs_root, sb,
- osc, mdc);
- if (err < 0)
- CERROR("could not register mount in /proc/lustre");
- }
-
- out_dev:
- if (mdc)
- OBD_FREE(mdc, strlen(mdc) + 1);
- if (osc)
- OBD_FREE(osc, strlen(osc) + 1);
-
RETURN(sb);
-
- out_cbd:
- ll_commitcbd_cleanup(sbi);
- out_osc:
- obd_disconnect(&sbi->ll_osc_conn, 0);
- out_mdc:
- obd_disconnect(&sbi->ll_mdc_conn, 0);
- out_free:
- OBD_FREE(sbi, sizeof(*sbi));
-
- goto out_dev;
- } /* ll_read_super */
-
- static void ll_put_super(struct super_block *sb)
- {
- struct ll_sb_info *sbi = ll_s2sbi(sb);
- struct list_head *tmp, *next;
- struct ll_fid rootfid;
- ENTRY;
-
- CDEBUG(D_VFSTRACE, "VFS Op:\n");
- list_del(&sbi->ll_conn_chain);
- ll_commitcbd_cleanup(sbi);
- obd_disconnect(&sbi->ll_osc_conn, 0);
-
- /* NULL request to force sync on the MDS, and get the last_committed
- * value to flush remaining RPCs from the sending queue on client.
- *
- * XXX This should be an mdc_sync() call to sync the whole MDS fs,
- * which we can call for other reasons as well.
- */
- mdc_getstatus(&sbi->ll_mdc_conn, &rootfid);
-
- if (sbi->ll_proc_root) {
- lprocfs_remove(sbi->ll_proc_root);
- sbi->ll_proc_root = NULL;
- }
-
- obd_disconnect(&sbi->ll_mdc_conn, 0);
-
- spin_lock(&dcache_lock);
- list_for_each_safe(tmp, next, &sbi->ll_orphan_dentry_list) {
- struct dentry *dentry = list_entry(tmp, struct dentry,
d_hash);
- shrink_dcache_parent(dentry);
- }
- spin_unlock(&dcache_lock);
-
- OBD_FREE(sbi, sizeof(*sbi));
-
- EXIT;
- } /* ll_put_super */
-
- static void ll_clear_inode(struct inode *inode)
- {
- struct ll_sb_info *sbi = ll_i2sbi(inode);
- struct ll_inode_info *lli = ll_i2info(inode);
- int rc;
- ENTRY;
-
- CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu\n", inode->i_ino);
- rc = ll_mdc_cancel_unused(&sbi->ll_mdc_conn, inode,
- LDLM_FL_NO_CALLBACK);
- if (rc < 0) {
- CERROR("ll_mdc_cancel_unused: %d\n", rc);
- /* XXX FIXME do something dramatic */
- }
-
- if (atomic_read(&inode->i_count) != 0)
- CERROR("clearing in-use inode %lu: count = %d\n",
- inode->i_ino, atomic_read(&inode->i_count));
-
- if (lli->lli_smd) {
- rc = obd_cancel_unused(&sbi->ll_osc_conn, lli->lli_smd, 0);
- if (rc < 0) {
- CERROR("obd_cancel_unused: %d\n", rc);
- /* XXX FIXME do something dramatic */
- }
- obd_free_memmd(&sbi->ll_osc_conn, &lli->lli_smd);
- lli->lli_smd = NULL;
- }
-
- if (lli->lli_symlink_name) {
- OBD_FREE(lli->lli_symlink_name,
- strlen(lli->lli_symlink_name) + 1);
- lli->lli_symlink_name = NULL;
- }
-
- EXIT;
- }
-
- #if 0
- static void ll_delete_inode(struct inode *inode)
- {
- ENTRY;
- CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu\n", inode->i_ino);
- if (S_ISREG(inode->i_mode)) {
- int err;
- struct obdo *oa;
- struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd;
-
- /* mcreate with no open */
- if (!lsm)
- GOTO(out, 0);
-
- if (lsm->lsm_object_id == 0) {
- CERROR("This really happens\n");
- /* No obdo was ever created */
- GOTO(out, 0);
- }
-
- oa = obdo_alloc();
- if (oa == NULL)
- GOTO(out, -ENOMEM);
-
- oa->o_id = lsm->lsm_object_id;
- obdo_from_inode(oa, inode, OBD_MD_FLID | OBD_MD_FLTYPE);
-
- err = obd_destroy(ll_i2obdconn(inode), oa, lsm, NULL);
- obdo_free(oa);
- if (err)
- CDEBUG(D_INODE,
- "inode %lu obd_destroy objid "LPX64" error
%d\n",
- inode->i_ino, lsm->lsm_object_id, err);
- }
- out:
- clear_inode(inode);
- EXIT;
- }
- #endif
-
- /* like inode_setattr, but doesn't mark the inode dirty */
- static int ll_attr2inode(struct inode *inode, struct iattr *attr, int trunc)
- {
- unsigned int ia_valid = attr->ia_valid;
- int error = 0;
-
- if ((ia_valid & ATTR_SIZE) && trunc) {
- error = vmtruncate(inode, attr->ia_size);
- if (error)
- goto out;
- } else if (ia_valid & ATTR_SIZE)
- inode->i_size = attr->ia_size;
-
- if (ia_valid & ATTR_UID)
- inode->i_uid = attr->ia_uid;
- if (ia_valid & ATTR_GID)
- inode->i_gid = attr->ia_gid;
- if (ia_valid & ATTR_ATIME)
- inode->i_atime = attr->ia_atime;
- if (ia_valid & ATTR_MTIME)
- inode->i_mtime = attr->ia_mtime;
- if (ia_valid & ATTR_CTIME)
- inode->i_ctime = attr->ia_ctime;
- if (ia_valid & ATTR_MODE) {
- inode->i_mode = attr->ia_mode;
- if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
- inode->i_mode &= ~S_ISGID;
- }
- out:
- return error;
}
! int ll_inode_setattr(struct inode *inode, struct iattr *attr, int do_trunc)
! {
! struct ptlrpc_request *request = NULL;
! struct ll_sb_info *sbi = ll_i2sbi(inode);
! int err = 0;
! ENTRY;
!
! /* change incore inode */
! ll_attr2inode(inode, attr, do_trunc);
!
! /* Don't send size changes to MDS to avoid "fast EA" problems, and
! * also avoid a pointless RPC (we get file size from OST anyways).
! */
! attr->ia_valid &= ~ATTR_SIZE;
! if (attr->ia_valid) {
! struct mdc_op_data op_data;
!
! ll_prepare_mdc_op_data(&op_data, inode, NULL, NULL, 0, 0);
! err = mdc_setattr(&sbi->ll_mdc_conn, &op_data,
! attr, NULL, 0, &request);
! if (err)
! CERROR("mdc_setattr fails: err = %d\n", err);
!
! ptlrpc_req_finished(request);
! if (S_ISREG(inode->i_mode) && attr->ia_valid &
ATTR_MTIME_SET) {
! struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd;
! struct obdo oa;
! int err2;
!
! CDEBUG(D_INODE, "set mtime on OST inode %lu to %lu\n",
! inode->i_ino, attr->ia_mtime);
! oa.o_id = lsm->lsm_object_id;
! oa.o_mode = S_IFREG;
! oa.o_valid = OBD_MD_FLID |OBD_MD_FLTYPE
|OBD_MD_FLMTIME;
! oa.o_mtime = attr->ia_mtime;
! err2 = obd_setattr(&sbi->ll_osc_conn, &oa, lsm, NULL);
! if (err2) {
! CERROR("obd_setattr fails: rc=%d\n", err);
! if (!err)
! err = err2;
! }
! }
! }
!
! RETURN(err);
! }
!
! int ll_setattr_raw(struct inode *inode, struct iattr *attr)
{
! struct ptlrpc_request *request = NULL;
! struct ll_sb_info *sbi = ll_i2sbi(inode);
! struct mdc_op_data op_data;
! int err = 0;
ENTRY;
! CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu\n", inode->i_ino);
!
! if ((attr->ia_valid & ATTR_SIZE)) {
! /* writeback uses inode->i_size to determine how far out
! * its cached pages go. ll_truncate gets a PW lock, canceling
! * our lock, _after_ it has updated i_size. this can confuse
! * us into zero extending the file to the newly truncated
! * size, and this has bad implications for a racing o_append.
! * if we're extending our size we need to flush the pages
! * with the correct i_size before vmtruncate stomps on
! * the new i_size. again, this can only find pages to
! * purge if the PW lock that generated them is still held.
! */
! if ( attr->ia_size > inode->i_size ) {
! filemap_fdatasync(inode->i_mapping);
! filemap_fdatawait(inode->i_mapping);
! }
! err = vmtruncate(inode, attr->ia_size);
! if (err)
! RETURN(err);
! }
!
! /* Don't send size changes to MDS to avoid "fast EA" problems, and
! * also avoid a pointless RPC (we get file size from OST anyways).
! */
! attr->ia_valid &= ~ATTR_SIZE;
! if (!attr->ia_valid)
! RETURN(0);
!
! ll_prepare_mdc_op_data(&op_data, inode, NULL, NULL, 0, 0);
!
! err = mdc_setattr(&sbi->ll_mdc_conn, &op_data,
! attr, NULL, 0, &request);
if (err)
! CERROR("mdc_setattr fails: err = %d\n", err);
!
! ptlrpc_req_finished(request);
!
! if (S_ISREG(inode->i_mode) && attr->ia_valid & ATTR_MTIME_SET) {
! struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd;
! struct obdo oa;
! int err2;
!
! CDEBUG(D_INODE, "set mtime on OST inode %lu to %lu\n",
! inode->i_ino, attr->ia_mtime);
! oa.o_id = lsm->lsm_object_id;
! oa.o_mode = S_IFREG;
! oa.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMTIME;
! oa.o_mtime = attr->ia_mtime;
! err2 = obd_setattr(&sbi->ll_osc_conn, &oa, lsm, NULL);
! if (err2) {
! CERROR("obd_setattr fails: rc=%d\n", err);
! if (!err)
! err = err2;
! }
! }
! RETURN(err);
! }
!
! int ll_setattr(struct dentry *de, struct iattr *attr)
! {
! int rc = inode_change_ok(de->d_inode, attr);
! CDEBUG(D_VFSTRACE, "VFS Op:name=%s\n", de->d_name.name);
! if (rc)
! return rc;
!
! return ll_inode_setattr(de->d_inode, attr, 1);
! }
!
! static int ll_statfs(struct super_block *sb, struct statfs *sfs)
! {
! struct ll_sb_info *sbi = ll_s2sbi(sb);
! struct obd_statfs osfs;
! int rc;
! ENTRY;
!
! CDEBUG(D_VFSTRACE, "VFS Op:\n");
! memset(sfs, 0, sizeof(*sfs));
! rc = obd_statfs(&sbi->ll_mdc_conn, &osfs);
! statfs_unpack(sfs, &osfs);
! if (rc)
! CERROR("mdc_statfs fails: rc = %d\n", rc);
! else
! CDEBUG(D_SUPER, "mdc_statfs shows blocks "LPU64"/"LPU64
! " objects "LPU64"/"LPU64"\n",
! osfs.os_bavail, osfs.os_blocks,
! osfs.os_ffree, osfs.os_files);
!
! /* temporary until mds_statfs returns statfs info for all OSTs */
! if (!rc) {
! rc = obd_statfs(&sbi->ll_osc_conn, &osfs);
! if (rc) {
! CERROR("obd_statfs fails: rc = %d\n", rc);
! GOTO(out, rc);
! }
! CDEBUG(D_SUPER, "obd_statfs shows blocks "LPU64"/"LPU64
! " objects "LPU64"/"LPU64"\n",
! osfs.os_bavail, osfs.os_blocks,
! osfs.os_ffree, osfs.os_files);
!
! while (osfs.os_blocks > ~0UL) {
! sfs->f_bsize <<= 1;
!
! osfs.os_blocks >>= 1;
! osfs.os_bfree >>= 1;
! osfs.os_bavail >>= 1;
! }
! sfs->f_blocks = osfs.os_blocks;
! sfs->f_bfree = osfs.os_bfree;
! sfs->f_bavail = osfs.os_bavail;
! if (osfs.os_ffree < (__u64)sfs->f_ffree)
! sfs->f_ffree = osfs.os_ffree;
! }
!
! out:
! RETURN(rc);
! }
!
! void ll_update_inode(struct inode *inode, struct mds_body *body,
! struct lov_stripe_md *lsm)
! {
! struct ll_inode_info *lli = ll_i2info(inode);
!
! LASSERT ((lsm != NULL) == ((body->valid & OBD_MD_FLEASIZE) != 0));
! if (lsm != NULL) {
! if (lli->lli_smd == NULL)
! lli->lli_smd = lsm;
! else
! LASSERT (!memcmp (lli->lli_smd, lsm,
! sizeof (*lsm)));
! }
!
! if (body->valid & OBD_MD_FLID)
! inode->i_ino = body->ino;
! if (body->valid & OBD_MD_FLATIME)
! LTIME_S(inode->i_atime) = body->atime;
! if (body->valid & OBD_MD_FLMTIME)
! LTIME_S(inode->i_mtime) = body->mtime;
! if (body->valid & OBD_MD_FLCTIME)
! LTIME_S(inode->i_ctime) = body->ctime;
! if (body->valid & OBD_MD_FLMODE)
! inode->i_mode = (inode->i_mode & S_IFMT)|(body->mode &
~S_IFMT);
! if (body->valid & OBD_MD_FLTYPE)
! inode->i_mode = (inode->i_mode & ~S_IFMT)|(body->mode &
S_IFMT);
! if (body->valid & OBD_MD_FLUID)
! inode->i_uid = body->uid;
! if (body->valid & OBD_MD_FLGID)
! inode->i_gid = body->gid;
! if (body->valid & OBD_MD_FLFLAGS)
! inode->i_flags = body->flags;
! if (body->valid & OBD_MD_FLNLINK)
! inode->i_nlink = body->nlink;
! if (body->valid & OBD_MD_FLGENER)
! inode->i_generation = body->generation;
! if (body->valid & OBD_MD_FLRDEV)
! inode->i_rdev = body->rdev;
! if (body->valid & OBD_MD_FLSIZE)
! inode->i_size = body->size;
! if (body->valid & OBD_MD_FLBLOCKS)
! inode->i_blocks = body->blocks;
! }
!
! static void ll_read_inode2(struct inode *inode, void *opaque)
! {
! struct ll_read_inode2_cookie *lic = opaque;
! struct mds_body *body = lic->lic_body;
! struct ll_inode_info *lli = ll_i2info(inode);
! ENTRY;
! CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu\n", inode->i_ino);
!
! sema_init(&lli->lli_open_sem, 1);
! spin_lock_init(&lli->lli_read_extent_lock);
! INIT_LIST_HEAD(&lli->lli_read_extents);
! ll_lldo_init(&lli->lli_dirty);
!
! LASSERT(!lli->lli_smd);
!
! /* core attributes from the MDS first */
! ll_update_inode(inode, body, lic->lic_lsm);
!
! /* Get the authoritative file size */
! if (lli->lli_smd && S_ISREG(inode->i_mode)) {
! struct ldlm_extent extent = {0, OBD_OBJECT_EOF};
! struct lustre_handle lockh = {0, 0};
! struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd;
! ldlm_error_t rc;
!
! LASSERT(lli->lli_smd->lsm_object_id != 0);
!
! rc = ll_extent_lock(NULL, inode, lsm, LCK_PR, &extent,
&lockh);
! if (rc != ELDLM_OK) {
! /* I think we could reverse these and then check
inside
! * ll_clear_inode() for is_bad_inode(inode) if needed.
! */
! ll_clear_inode(inode);
! make_bad_inode(inode);
! LBUG();
! EXIT;
! return;
! }
! ll_extent_unlock(NULL, inode, lsm, LCK_PR, &lockh);
! }
!
! /* OIDEBUG(inode); */
!
! if (S_ISREG(inode->i_mode)) {
! inode->i_op = &ll_file_inode_operations;
! inode->i_fop = &ll_file_operations;
! inode->i_mapping->a_ops = &ll_aops;
! EXIT;
! } 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 = &ll_dir_aops;
! EXIT;
! } else if (S_ISLNK(inode->i_mode)) {
! inode->i_op = &ll_fast_symlink_inode_operations;
! EXIT;
! } else {
! inode->i_op = &ll_special_inode_operations;
! init_special_inode(inode, inode->i_mode, inode->i_rdev);
! EXIT;
! }
! }
!
! void ll_umount_begin(struct super_block *sb)
! {
! struct ll_sb_info *sbi = ll_s2sbi(sb);
! struct obd_device *obd;
!
! ENTRY;
! CDEBUG(D_VFSTRACE, "VFS Op:\n");
!
! obd = class_conn2obd(&sbi->ll_mdc_conn);
! obd->obd_no_recov = 1;
!
! obd = class_conn2obd(&sbi->ll_osc_conn);
! obd->obd_no_recov = 1;
!
! EXIT;
}
--- 33,62 ----
#include <linux/fs.h>
#include <linux/lprocfs_status.h>
+ #include "llite_internal.h"
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
extern struct address_space_operations ll_aops;
extern struct address_space_operations ll_dir_aops;
static struct super_block *ll_read_super(struct super_block *sb,
void *data, int silent)
{
int err;
ENTRY;
! err = ll_fill_super(sb, data, silent);
! if (err)
RETURN(NULL);
RETURN(sb);
}
! static struct super_block *lustre_read_super(struct super_block *sb,
! void *data, int silent)
{
! int err;
ENTRY;
! err = lustre_fill_super(sb, data, silent);
if (err)
! RETURN(NULL);
! RETURN(sb);
}
***************
*** 724,740 ****
put_super: ll_put_super,
statfs: ll_statfs,
! umount_begin: ll_umount_begin
};
static struct file_system_type lustre_lite_fs_type = {
name: "lustre_lite",
! fs_flags: 0,
read_super: ll_read_super,
owner: THIS_MODULE,
};
static int __init init_lustre_lite(void)
{
! printk(KERN_INFO "Lustre Lite Client File System; "
"info@xxxxxxxxxxxxx\n");
ll_file_data_slab = kmem_cache_create("ll_file_data",
--- 69,109 ----
put_super: ll_put_super,
statfs: ll_statfs,
! umount_begin: ll_umount_begin,
! fh_to_dentry: ll_fh_to_dentry,
! dentry_to_fh: ll_dentry_to_fh
};
static struct file_system_type lustre_lite_fs_type = {
name: "lustre_lite",
! fs_flags: FS_NFSEXP_FSID,
read_super: ll_read_super,
owner: THIS_MODULE,
};
+ /* exported operations */
+ struct super_operations lustre_super_operations =
+ {
+ read_inode2: ll_read_inode2,
+ clear_inode: ll_clear_inode,
+ // delete_inode: ll_delete_inode,
+ put_super: lustre_put_super,
+ statfs: ll_statfs,
+ umount_begin: ll_umount_begin,
+ fh_to_dentry: ll_fh_to_dentry,
+ dentry_to_fh: ll_dentry_to_fh
+ };
+
+ static struct file_system_type lustre_fs_type = {
+ name: "lustre",
+ fs_flags: FS_NFSEXP_FSID,
+ read_super: lustre_read_super,
+ owner: THIS_MODULE,
+ };
+
static int __init init_lustre_lite(void)
{
! int rc;
!
! printk(KERN_INFO "Lustre: Lustre Lite Client File System; "
"info@xxxxxxxxxxxxx\n");
ll_file_data_slab = kmem_cache_create("ll_file_data",
***************
*** 746,750 ****
proc_lustre_fs_root = proc_lustre_root ? proc_mkdir("llite",
proc_lustre_root) : NULL;
! return register_filesystem(&lustre_lite_fs_type);
}
--- 115,124 ----
proc_lustre_fs_root = proc_lustre_root ? proc_mkdir("llite",
proc_lustre_root) : NULL;
! rc = register_filesystem(&lustre_lite_fs_type);
! if (rc == 0)
! rc = register_filesystem(&lustre_fs_type);
! if (rc)
! unregister_filesystem(&lustre_lite_fs_type);
! return rc;
}
***************
*** 752,755 ****
--- 126,131 ----
{
unregister_filesystem(&lustre_lite_fs_type);
+ unregister_filesystem(&lustre_fs_type);
+
kmem_cache_destroy(ll_file_data_slab);
Index: super25.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/lustre/llite/super25.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** super25.c 23 Apr 2003 18:28:45 -0000 1.1
--- super25.c 28 Jan 2004 23:48:33 -0000 1.2
***************
*** 33,678 ****
#include <linux/fs.h>
#include <linux/lprocfs_status.h>
! #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
! #include <asm/statfs.h>
! kmem_cache_t *ll_file_data_slab;
! extern struct address_space_operations ll_aops;
! extern struct address_space_operations ll_dir_aops;
! struct super_operations ll_super_operations;
!
! /* /proc/lustre/llite root that tracks llite mount points */
! struct proc_dir_entry *proc_lustre_fs_root = NULL;
! /* lproc_llite.c */
! extern int lprocfs_register_mountpoint(struct proc_dir_entry *parent,
! struct super_block *sb,
! char *osc, char *mdc);
!
! extern int ll_init_inodecache(void);
! extern void ll_destroy_inodecache(void);
! extern int ll_recover(struct recovd_data *, int);
! extern int ll_commitcbd_setup(struct ll_sb_info *);
! extern int ll_commitcbd_cleanup(struct ll_sb_info *);
! int ll_read_inode2(struct inode *inode, void *opaque);
!
! extern int ll_proc_namespace(struct super_block* sb, char* osc, char* mdc);
!
! static char *ll_read_opt(const char *opt, char *data)
! {
! char *value;
! char *retval;
! ENTRY;
!
! CDEBUG(D_SUPER, "option: %s, data %s\n", opt, data);
! if (strncmp(opt, data, strlen(opt)))
! RETURN(NULL);
! if ((value = strchr(data, '=')) == NULL)
! RETURN(NULL);
!
! value++;
! OBD_ALLOC(retval, strlen(value) + 1);
! if (!retval) {
! CERROR("out of memory!\n");
! RETURN(NULL);
! }
!
! memcpy(retval, value, strlen(value)+1);
! CDEBUG(D_SUPER, "Assigned option: %s, value %s\n", opt, retval);
! RETURN(retval);
! }
!
! static int ll_set_opt(const char *opt, char *data, int fl)
! {
! ENTRY;
!
! CDEBUG(D_SUPER, "option: %s, data %s\n", opt, data);
! if (strncmp(opt, data, strlen(opt)))
! RETURN(0);
! else
! RETURN(fl);
! }
!
! static void ll_options(char *options, char **ost, char **mds, int *flags)
! {
! char *opt_ptr = options;
! char *this_char;
! ENTRY;
!
! if (!options) {
! EXIT;
! return;
! }
!
! while ((this_char = strsep (&opt_ptr, ",")) != NULL) {
! CDEBUG(D_SUPER, "this_char %s\n", this_char);
! if ((!*ost && (*ost = ll_read_opt("osc", this_char)))||
! (!*mds && (*mds = ll_read_opt("mdc", this_char)))||
! (!(*flags & LL_SBI_NOLCK) &&
! ((*flags) = (*flags) |
! ll_set_opt("nolock", this_char, LL_SBI_NOLCK))))
! continue;
! }
! EXIT;
! }
!
! #ifndef log2
! #define log2(n) ffz(~(n))
! #endif
!
!
! static int ll_fill_super(struct super_block *sb, void *data, int silent)
! {
! struct inode *root = 0;
! struct obd_device *obd;
! struct ll_sb_info *sbi;
! char *osc = NULL;
! char *mdc = NULL;
! int err;
! struct ll_fid rootfid;
! struct obd_statfs osfs;
! struct ptlrpc_request *request = NULL;
! struct ptlrpc_connection *mdc_conn;
! struct ll_read_inode2_cookie lic;
! class_uuid_t uuid;
! struct obd_uuid param_uuid;
!
! ENTRY;
! CDEBUG(D_VFSTRACE, "VFS Op:\n");
!
! OBD_ALLOC(sbi, sizeof(*sbi));
! if (!sbi)
! RETURN(-ENOMEM);
!
! INIT_LIST_HEAD(&sbi->ll_conn_chain);
! INIT_LIST_HEAD(&sbi->ll_orphan_dentry_list);
! generate_random_uuid(uuid);
! class_uuid_unparse(uuid, &sbi->ll_sb_uuid);
!
! sb->s_fs_info = sbi;
!
! ll_options(data, &osc, &mdc, &sbi->ll_flags);
!
! if (!osc) {
! CERROR("no osc\n");
! GOTO(out_free, sb = NULL);
! }
!
! if (!mdc) {
! CERROR("no mdc\n");
! GOTO(out_free, sb = NULL);
! }
!
! strncpy(param_uuid.uuid, mdc, sizeof(param_uuid.uuid));
! obd = class_uuid2obd(¶m_uuid);
! if (!obd) {
! CERROR("MDC %s: not setup or attached\n", mdc);
! GOTO(out_free, sb = NULL);
! }
!
! err = obd_connect(&sbi->ll_mdc_conn, obd, &sbi->ll_sb_uuid,
! ptlrpc_recovd, ll_recover);
! if (err) {
! CERROR("cannot connect to %s: rc = %d\n", mdc, err);
! GOTO(out_free, sb = NULL);
! }
!
! mdc_conn = sbi2mdc(sbi)->cl_import.imp_connection;
! list_add(&mdc_conn->c_sb_chain, &sbi->ll_conn_chain);
!
! obd = class_uuid2obd(osc);
! if (!obd) {
! CERROR("OSC %s: not setup or attached\n", osc);
! GOTO(out_mdc, sb = NULL);
! }
!
! err = obd_connect(&sbi->ll_osc_conn, obd, &sbi->ll_sb_uuid,
! ptlrpc_recovd, ll_recover);
! if (err) {
! CERROR("cannot connect to %s: rc = %d\n", osc, err);
! GOTO(out_mdc, sb = NULL);
! }
!
! err = mdc_getstatus(&sbi->ll_mdc_conn, &rootfid);
! if (err) {
! CERROR("cannot mds_connect: rc = %d\n", err);
! GOTO(out_osc, sb = NULL);
! }
! CDEBUG(D_SUPER, "rootfid "LPU64"\n", rootfid.id);
! sbi->ll_rootino = rootfid.id;
!
! memset(&osfs, 0, sizeof(osfs));
! err = obd_statfs(&sbi->ll_mdc_conn, &osfs);
! sb->s_blocksize = osfs.os_bsize;
! sb->s_blocksize_bits = log2(osfs.os_bsize);
! sb->s_magic = LL_SUPER_MAGIC;
! sb->s_maxbytes = (1ULL << (32 + 9)) - osfs.os_bsize;
!
! sb->s_op = &ll_super_operations;
!
! /* make root inode
! * XXX: move this to after cbd setup? */
! err = mdc_getattr(&sbi->ll_mdc_conn, &rootfid,
! OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, 0, &request);
! if (err) {
! CERROR("mdc_getattr failed for root: rc = %d\n", err);
! GOTO(out_osc, sb = NULL);
! }
!
! /* initialize committed transaction callback daemon */
! spin_lock_init(&sbi->ll_commitcbd_lock);
! init_waitqueue_head(&sbi->ll_commitcbd_waitq);
! init_waitqueue_head(&sbi->ll_commitcbd_ctl_waitq);
! sbi->ll_commitcbd_flags = 0;
! err = ll_commitcbd_setup(sbi);
! if (err) {
! CERROR("failed to start commit callback daemon: rc =
%d\n",err);
! ptlrpc_req_finished (request);
! GOTO(out_osc, sb = NULL);
! }
!
! lic.lic_body = lustre_msg_buf(request->rq_repmsg, 0, sizeof
(*lic.lic_body));
! LASSERT (lic.lic_body != NULL); /* checked by mdc_getattr() */
! LASSERT_REPSWABBED (request, 0); /* swabbed by mdc_getattr() */
!
! lic.lic_lsm = NULL;
!
! root = iget5_locked(sb, sbi->ll_rootino, NULL,
! ll_read_inode2, &lic);
!
! ptlrpc_req_finished(request);
!
! if (root == NULL || is_bad_inode(root)) {
! /* XXX might need iput() for bad inode */
! CERROR("lustre_lite: bad iget5 for root\n");
! GOTO(out_cbd, sb = NULL);
! }
!
! sb->s_root = d_alloc_root(root);
! root->i_state &= ~(I_LOCK | I_NEW);
!
! if (proc_lustre_fs_root) {
! err = lprocfs_register_mountpoint(proc_lustre_fs_root, sb,
! osc, mdc);
! if (err < 0)
! CERROR("could not register mount in /proc/lustre");
! }
!
! out_dev:
! if (mdc)
! OBD_FREE(mdc, strlen(mdc) + 1);
! if (osc)
! OBD_FREE(osc, strlen(osc) + 1);
!
! RETURN(0);
!
! out_cbd:
! ll_commitcbd_cleanup(sbi);
! out_osc:
! obd_disconnect(&sbi->ll_osc_conn);
! out_mdc:
! obd_disconnect(&sbi->ll_mdc_conn);
! out_free:
! OBD_FREE(sbi, sizeof(*sbi));
!
! goto out_dev;
! } /* ll_fill_super */
struct super_block * ll_get_sb(struct file_system_type *fs_type,
! int flags, char *devname, void * data)
{
return get_sb_nodev(fs_type, flags, data, ll_fill_super);
}
- static void ll_put_super(struct super_block *sb)
- {
- struct ll_sb_info *sbi = ll_s2sbi(sb);
- struct list_head *tmp, *next;
- struct ll_fid rootfid;
- ENTRY;
- CDEBUG(D_VFSTRACE, "VFS Op:\n");
-
- list_del(&sbi->ll_conn_chain);
- ll_commitcbd_cleanup(sbi);
- obd_disconnect(&sbi->ll_osc_conn);
-
- /* NULL request to force sync on the MDS, and get the last_committed
- * value to flush remaining RPCs from the pending queue on client.
- *
- * XXX This should be an mdc_sync() call to sync the whole MDS fs,
- * which we can call for other reasons as well.
- */
- mdc_getstatus(&sbi->ll_mdc_conn, &rootfid);
-
- if (sbi->ll_proc_root) {
- lprocfs_remove(sbi->ll_proc_root);
- sbi->ll_proc_root = NULL;
- }
-
- obd_disconnect(&sbi->ll_mdc_conn);
-
- spin_lock(&dcache_lock);
- list_for_each_safe(tmp, next, &sbi->ll_orphan_dentry_list){
- struct dentry *dentry = list_entry(tmp, struct dentry,
d_hash);
- shrink_dcache_parent(dentry);
- }
- spin_unlock(&dcache_lock);
-
- OBD_FREE(sbi, sizeof(*sbi));
-
- EXIT;
- } /* ll_put_super */
-
- static void ll_clear_inode(struct inode *inode)
- {
- struct ll_sb_info *sbi = ll_i2sbi(inode);
- struct ll_inode_info *lli = ll_i2info(inode);
- int rc;
- ENTRY;
- CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu\n", inode->i_ino);
-
- #warning "Is there a reason we don't do this in 2.5, but we do in 2.4?"
- #if 0
- rc = ll_mdc_cancel_unused(&sbi->ll_mdc_conn, inode,
LDLM_FL_NO_CALLBACK);
- if (rc < 0) {
- CERROR("ll_mdc_cancel_unused: %d\n", rc);
- /* XXX FIXME do something dramatic */
- }
-
- if (lli->lli_smd) {
- rc = obd_cancel_unused(&sbi->ll_osc_conn, lli->lli_smd, 0);
- if (rc < 0) {
- CERROR("obd_cancel_unused: %d\n", rc);
- /* XXX FIXME do something dramatic */
- }
- }
- #endif
-
- if (atomic_read(&inode->i_count) != 0)
- CERROR("clearing in-use inode %lu: count = %d\n",
- inode->i_ino, atomic_read(&inode->i_count));
-
- if (lli->lli_smd) {
- obd_free_memmd(&sbi->ll_osc_conn, &lli->lli_smd);
- lli->lli_smd = NULL;
- }
-
- if (lli->lli_symlink_name) {
-
OBD_FREE(lli->lli_symlink_name,strlen(lli->lli_symlink_name)+1);
- lli->lli_symlink_name = NULL;
- }
-
- EXIT;
- }
-
- #if 0
- static void ll_delete_inode(struct inode *inode)
- {
- ENTRY;
- CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu\n", inode->i_ino);
- if (S_ISREG(inode->i_mode)) {
- int err;
- struct obdo *oa;
- struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd;
-
- /* mcreate with no open */
- if (!lsm)
- GOTO(out, 0);
-
- if (lsm->lsm_object_id == 0) {
- CERROR("This really happens\n");
- /* No obdo was ever created */
- GOTO(out, 0);
- }
-
- oa = obdo_alloc();
- if (oa == NULL)
- GOTO(out, -ENOMEM);
-
- oa->o_id = lsm->lsm_object_id;
- oa->o_mode = inode->i_mode;
- oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE;
-
- err = obd_destroy(ll_i2obdconn(inode), oa, lsm);
- obdo_free(oa);
- if (err)
- CDEBUG(D_SUPER, "obd destroy objid "LPX64" error
%d\n",
- lsm->lsm_object_id, err);
- }
- out:
- clear_inode(inode);
- EXIT;
- }
- #endif
-
- /* like inode_setattr, but doesn't mark the inode dirty */
- static int ll_attr2inode(struct inode * inode, struct iattr * attr, int trunc)
- {
- unsigned int ia_valid = attr->ia_valid;
- int error = 0;
-
- if ((ia_valid & ATTR_SIZE) && trunc) {
- error = vmtruncate(inode, attr->ia_size);
- if (error)
- goto out;
- } else if (ia_valid & ATTR_SIZE)
- inode->i_size = attr->ia_size;
-
- if (ia_valid & ATTR_UID)
- inode->i_uid = attr->ia_uid;
- if (ia_valid & ATTR_GID)
- inode->i_gid = attr->ia_gid;
- if (ia_valid & ATTR_ATIME)
- inode->i_atime = attr->ia_atime;
- if (ia_valid & ATTR_MTIME)
- inode->i_mtime = attr->ia_mtime;
- if (ia_valid & ATTR_CTIME)
- inode->i_ctime = attr->ia_ctime;
- if (ia_valid & ATTR_MODE) {
- inode->i_mode = attr->ia_mode;
- if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
- inode->i_mode &= ~S_ISGID;
- }
- out:
- return error;
- }
-
- int ll_inode_setattr(struct inode *inode, struct iattr *attr, int do_trunc)
- {
- struct ptlrpc_request *request = NULL;
- struct ll_sb_info *sbi = ll_i2sbi(inode);
- int err = 0;
-
- ENTRY;
-
- /* change incore inode */
- ll_attr2inode(inode, attr, do_trunc);
-
- /* Don't send size changes to MDS to avoid "fast EA" problems, and
- * also avoid a pointless RPC (we get file size from OST anyways).
- */
- attr->ia_valid &= ~ATTR_SIZE;
- if (attr->ia_valid) {
- struct mdc_op_data op_data;
-
- ll_prepare_mdc_op_data(&op_data, inode, NULL, NULL, 0, 0);
-
- err = mdc_setattr(&sbi->ll_mdc_conn, &op_data,
- attr, NULL, 0, &request);
- if (err)
- CERROR("mdc_setattr fails: err = %d\n", err);
-
- ptlrpc_req_finished(request);
- if (S_ISREG(inode->i_mode) && attr->ia_valid &
ATTR_MTIME_SET) {
- struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd;
- struct obdo oa;
- int err2;
-
- CDEBUG(D_ERROR, "setting mtime on OST\n");
- oa.o_id = lsm->lsm_object_id;
- oa.o_mode = S_IFREG;
- oa.o_valid = OBD_MD_FLID |OBD_MD_FLTYPE
|OBD_MD_FLMTIME;
- oa.o_mtime = LTIME_S(attr->ia_mtime);
- err2 = obd_setattr(&sbi->ll_osc_conn, &oa, lsm, NULL);
- if (err2) {
- CERROR("obd_setattr fails: rc=%d\n", err);
- if (!err)
- err = err2;
- }
- }
- }
-
- RETURN(err);
- }
-
- int ll_setattr(struct dentry *de, struct iattr *attr)
- {
- int rc = inode_change_ok(de->d_inode, attr);
- CDEBUG(D_VFSTRACE, "VFS Op:name=%s\n", de->d_name.name);
- if (rc)
- return rc;
-
- return ll_inode_setattr(de->d_inode, attr, 1);
- }
-
- static int ll_statfs(struct super_block *sb, struct statfs *sfs)
- {
- struct ll_sb_info *sbi = ll_s2sbi(sb);
- struct obd_statfs osfs;
- int rc;
- ENTRY;
- CDEBUG(D_ |