+ 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 = 0, 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_md_exp);
+ } else if (type == LL_STATFS_LOV) {
+ lov_obd = class_exp2obd(sbi->ll_dt_exp);
+ lov = &lov_obd->u.lov;
+
+ if ((index >= lov->desc.ld_tgt_count))
+ GOTO(out_statfs, rc = -ENODEV);
+ if (!lov->lov_tgts[index])
+ /* Try again with the next index */
+ GOTO(out_statfs, rc = -EAGAIN);
+
+ 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);
+}
+
+/* this function prepares md_op_data hint for passing ot down to MD stack. */
+struct md_op_data * ll_prep_md_op_data(struct md_op_data *op_data,
+ struct inode *i1, struct inode *i2,
+ const char *name, int namelen,
+ int mode, __u32 opc, void *data)
+{
+ LASSERT(i1 != NULL);
+
+ if (namelen > ll_i2sbi(i1)->ll_namelen)
+ return ERR_PTR(-ENAMETOOLONG);
+
+ if (op_data == NULL)
+ OBD_ALLOC_PTR(op_data);
+
+ if (op_data == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ ll_i2gids(op_data->op_suppgids, i1, i2);
+ op_data->op_fid1 = *ll_inode2fid(i1);
+ op_data->op_capa1 = ll_mdscapa_get(i1);
+
+ if (i2) {
+ op_data->op_fid2 = *ll_inode2fid(i2);
+ op_data->op_capa2 = ll_mdscapa_get(i2);
+ } else {
+ fid_zero(&op_data->op_fid2);
+ }
+
+ op_data->op_name = name;
+ op_data->op_namelen = namelen;
+ op_data->op_mode = mode;
+ op_data->op_mod_time = CURRENT_SECONDS;
+ op_data->op_fsuid = current->fsuid;
+ op_data->op_fsgid = current->fsgid;
+ op_data->op_cap = current->cap_effective;
+ op_data->op_bias = MDS_CHECK_SPLIT;
+ op_data->op_opc = opc;
+ op_data->op_mds = 0;
+ op_data->op_data = data;
+
+ return op_data;
+}
+
+void ll_finish_md_op_data(struct md_op_data *op_data)
+{
+ capa_put(op_data->op_capa1);
+ capa_put(op_data->op_capa2);
+ OBD_FREE_PTR(op_data);
+}
+
+int ll_ioctl_getfacl(struct inode *inode, struct rmtacl_ioctl_data *ioc)
+{
+ struct ll_sb_info *sbi = ll_i2sbi(inode);
+ struct ptlrpc_request *req = NULL;
+ struct mdt_body *body;
+ char *cmd, *buf;
+ struct obd_capa *oc;
+ int rc, buflen;
+ ENTRY;
+
+ if (!(sbi->ll_flags & LL_SBI_RMT_CLIENT))
+ RETURN(-EBADE);