Please take our Survey
logo       

Choosing A Webhost:
A web hosting service is a type of Internet hosting service that allows individuals and organizations to provide their own website accessible via the World Wide Web. Web hosts are companies that provide space on a server they own for use by their clients as well as providing Internet connectivity, typically in a data center. Web hosts can also provide data center space and connectivity to the Internet for servers they do not own to be located in their data center, called colocation. more...

[SSI] openssi/lustre/llite Makefile.am,1.1,1.2 dcache.c,1.1,1.2 dir.c,1.1,1: msg#00237

Subject: [SSI] openssi/lustre/llite Makefile.am,1.1,1.2 dcache.c,1.1,1.2 dir.c,1.1,1.2 file.c,1.1,1.2 lproc_llite.c,1.1,1.2 namei.c,1.1,1.2 rw.c,1.1,1.2 super.c,1.1,1.2 super25.c,1.1,1.2 symlink.c,1.1,1.2
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(&param_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(&param_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(&param_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_