+
+char *llap_origins[] = {
+ [LLAP_ORIGIN_UNKNOWN] = "--",
+ [LLAP_ORIGIN_READPAGE] = "rp",
+ [LLAP_ORIGIN_READAHEAD] = "ra",
+ [LLAP_ORIGIN_COMMIT_WRITE] = "cw",
+ [LLAP_ORIGIN_WRITEPAGE] = "wp",
+};
+
+struct ll_async_page *llite_pglist_next_llap(struct ll_sb_info *sbi,
+ struct list_head *list)
+{
+ struct ll_async_page *llap;
+ struct list_head *pos;
+
+ list_for_each(pos, list) {
+ if (pos == &sbi->ll_pglist)
+ return NULL;
+ llap = list_entry(pos, struct ll_async_page, llap_pglist_item);
+ if (llap->llap_page == NULL)
+ continue;
+ return llap;
+ }
+ LBUG();
+ return NULL;
+}
+
+int ll_obd_statfs(struct inode *inode, void *arg)
+{
+ struct ll_sb_info *sbi = NULL;
+ struct obd_device *client_obd = NULL, *lov_obd = NULL;
+ struct lov_obd *lov = NULL;
+ struct obd_statfs stat_buf = {0};
+ char *buf = NULL;
+ struct obd_ioctl_data *data = NULL;
+ __u32 type, index;
+ int len, rc;
+
+ if (!inode || !(sbi = ll_i2sbi(inode)))
+ GOTO(out_statfs, rc = -EINVAL);
+
+ rc = obd_ioctl_getdata(&buf, &len, arg);
+ if (rc)
+ GOTO(out_statfs, rc);
+
+ data = (void*)buf;
+ if (!data->ioc_inlbuf1 || !data->ioc_inlbuf2 ||
+ !data->ioc_pbuf1 || !data->ioc_pbuf2)
+ GOTO(out_statfs, rc = -EINVAL);
+
+ memcpy(&type, data->ioc_inlbuf1, sizeof(__u32));
+ memcpy(&index, data->ioc_inlbuf2, sizeof(__u32));
+
+ if (type == LL_STATFS_MDC) {
+ if (index > 0)
+ GOTO(out_statfs, rc = -ENODEV);
+ client_obd = class_exp2obd(sbi->ll_mdc_exp);
+ } else if (type == LL_STATFS_LOV) {
+ lov_obd = class_exp2obd(sbi->ll_osc_exp);
+ lov = &lov_obd->u.lov;
+
+ if ((index >= lov->desc.ld_tgt_count) ||
+ !lov->lov_tgts[index])
+ GOTO(out_statfs, rc = -ENODEV);
+
+ client_obd = class_exp2obd(lov->lov_tgts[index]->ltd_exp);
+ if (!lov->lov_tgts[index]->ltd_active)
+ GOTO(out_uuid, rc = -ENODATA);
+ }
+
+ if (!client_obd)
+ GOTO(out_statfs, rc = -EINVAL);
+
+ rc = obd_statfs(client_obd, &stat_buf, cfs_time_current_64() - 1);
+ if (rc)
+ GOTO(out_statfs, rc);
+
+ if (copy_to_user(data->ioc_pbuf1, &stat_buf, data->ioc_plen1))
+ GOTO(out_statfs, rc = -EFAULT);
+
+out_uuid:
+ if (copy_to_user(data->ioc_pbuf2, obd2cli_tgt(client_obd),
+ data->ioc_plen2))
+ rc = -EFAULT;
+
+out_statfs:
+ if (buf)
+ obd_ioctl_freedata(buf, len);
+ return rc;
+}
+
+int ll_process_config(struct lustre_cfg *lcfg)
+{
+ char *ptr;
+ void *sb;
+ struct lprocfs_static_vars lvars;
+ unsigned long x;
+ int rc = 0;
+
+ lprocfs_init_vars(llite, &lvars);
+
+ /* The instance name contains the sb: lustre-client-aacfe000 */
+ ptr = strrchr(lustre_cfg_string(lcfg, 0), '-');
+ if (!ptr || !*(++ptr))
+ return -EINVAL;
+ if (sscanf(ptr, "%lx", &x) != 1)
+ return -EINVAL;
+ sb = (void *)x;
+ /* This better be a real Lustre superblock! */
+ LASSERT(s2lsi((struct super_block *)sb)->lsi_lmd->lmd_magic == LMD_MAGIC);
+
+ /* Note we have not called client_common_fill_super yet, so
+ proc fns must be able to handle that! */
+ rc = class_process_proc_param(PARAM_LLITE, lvars.obd_vars,
+ lcfg, sb);
+ return(rc);
+}
+