+static int llu_iop_rename_raw(struct pnode *old, struct pnode *new)
+{
+ struct inode *src = old->p_parent->p_base->pb_ino;
+ struct inode *tgt = new->p_parent->p_base->pb_ino;
+ const char *oldname = old->p_base->pb_name.name;
+ int oldnamelen = old->p_base->pb_name.len;
+ const char *newname = new->p_base->pb_name.name;
+ int newnamelen = new->p_base->pb_name.len;
+ struct ptlrpc_request *request = NULL;
+ struct mdc_op_data op_data;
+ int rc;
+ ENTRY;
+
+ LASSERT(src);
+ LASSERT(tgt);
+
+ llu_prepare_mdc_op_data(&op_data, src, tgt, NULL, 0, 0);
+ rc = mdc_rename(llu_i2sbi(src)->ll_mdc_exp, &op_data,
+ oldname, oldnamelen, newname, newnamelen,
+ &request);
+ if (!rc) {
+ rc = llu_objects_destroy(request, src);
+ }
+
+ ptlrpc_req_finished(request);
+
+ RETURN(rc);
+}
+
+#ifdef _HAVE_STATVFS
+static int llu_statfs_internal(struct llu_sb_info *sbi,
+ struct obd_statfs *osfs,
+ unsigned long max_age)
+{
+ struct obd_statfs obd_osfs;
+ int rc;
+ ENTRY;
+
+ rc = obd_statfs(class_exp2obd(sbi->ll_mdc_exp), osfs, max_age);
+ if (rc) {
+ CERROR("mdc_statfs fails: rc = %d\n", rc);
+ RETURN(rc);
+ }
+
+ CDEBUG(D_SUPER, "MDC blocks "LPU64"/"LPU64" objects "LPU64"/"LPU64"\n",
+ osfs->os_bavail, osfs->os_blocks, osfs->os_ffree,osfs->os_files);
+
+ rc = obd_statfs(class_exp2obd(sbi->ll_osc_exp), &obd_osfs, max_age);
+ if (rc) {
+ CERROR("obd_statfs fails: rc = %d\n", rc);
+ RETURN(rc);
+ }
+
+ CDEBUG(D_SUPER, "OSC blocks "LPU64"/"LPU64" objects "LPU64"/"LPU64"\n",
+ obd_osfs.os_bavail, obd_osfs.os_blocks, obd_osfs.os_ffree,
+ obd_osfs.os_files);
+
+ osfs->os_blocks = obd_osfs.os_blocks;
+ osfs->os_bfree = obd_osfs.os_bfree;
+ osfs->os_bavail = obd_osfs.os_bavail;
+
+ /* If we don't have as many objects free on the OST as inodes
+ * on the MDS, we reduce the total number of inodes to
+ * compensate, so that the "inodes in use" number is correct.
+ */
+ if (obd_osfs.os_ffree < osfs->os_ffree) {
+ osfs->os_files = (osfs->os_files - osfs->os_ffree) +
+ obd_osfs.os_ffree;
+ osfs->os_ffree = obd_osfs.os_ffree;
+ }
+
+ RETURN(rc);
+}
+
+static int llu_statfs(struct llu_sb_info *sbi, struct statfs *sfs)
+{
+ struct obd_statfs osfs;
+ int rc;
+
+ CDEBUG(D_VFSTRACE, "VFS Op:\n");
+
+ /* For now we will always get up-to-date statfs values, but in the
+ * future we may allow some amount of caching on the client (e.g.
+ * from QOS or lprocfs updates). */
+ rc = llu_statfs_internal(sbi, &osfs, jiffies - 1);
+ if (rc)
+ return rc;
+
+ statfs_unpack(sfs, &osfs);
+
+ if (sizeof(sfs->f_blocks) == 4) {
+ 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;
+
+ return 0;
+}
+
+static int llu_iop_statvfs(struct pnode *pno,
+ struct inode *ino,
+ struct intnl_statvfs *buf)
+{
+ struct statfs fs;
+ int rc;
+ ENTRY;
+
+ liblustre_wait_event(0);
+
+#ifndef __CYGWIN__
+ LASSERT(pno->p_base->pb_ino);
+ rc = llu_statfs(llu_i2sbi(pno->p_base->pb_ino), &fs);
+ if (rc)
+ RETURN(rc);
+
+ /* from native driver */
+ buf->f_bsize = fs.f_bsize; /* file system block size */
+ buf->f_frsize = fs.f_bsize; /* file system fundamental block size */
+ buf->f_blocks = fs.f_blocks;
+ buf->f_bfree = fs.f_bfree;
+ buf->f_bavail = fs.f_bavail;
+ buf->f_files = fs.f_files; /* Total number serial numbers */
+ buf->f_ffree = fs.f_ffree; /* Number free serial numbers */
+ buf->f_favail = fs.f_ffree; /* Number free ser num for non-privileged*/
+ buf->f_fsid = fs.f_fsid.__val[1];
+ buf->f_flag = 0; /* No equiv in statfs; maybe use type? */
+ buf->f_namemax = fs.f_namelen;