Whamcloud - gitweb
LU-2800 llite: introduce local getname()
[fs/lustre-release.git] / lustre / llite / dir.c
index 466d259..484d177 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2013, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
  * page is empty (contains no dir entry) or hash collide with next page.
  * After client receives reply, several pages will be integrated into dir page
  * in CFS_PAGE_SIZE (if CFS_PAGE_SIZE greater than LU_PAGE_SIZE), and the
- * lu_dirpage for this integrated page will be adjusted.
+ * lu_dirpage for this integrated page will be adjusted. See
+ * lmv_adjust_dirpages().
  *
  */
 
@@ -356,32 +357,43 @@ struct page *ll_get_dir_page(struct inode *dir, __u64 hash,
         mode = LCK_PR;
         rc = md_lock_match(ll_i2sbi(dir)->ll_md_exp, LDLM_FL_BLOCK_GRANTED,
                            ll_inode2fid(dir), LDLM_IBITS, &policy, mode, &lockh);
-        if (!rc) {
-                struct ldlm_enqueue_info einfo = { LDLM_IBITS, mode,
-                       ll_md_blocking_ast, ldlm_completion_ast,
-                       NULL, NULL, dir };
-                struct lookup_intent it = { .it_op = IT_READDIR };
-                struct ptlrpc_request *request;
-                struct md_op_data *op_data;
-
-                op_data = ll_prep_md_op_data(NULL, dir, NULL, NULL, 0, 0,
-                                             LUSTRE_OPC_ANY, NULL);
-                if (IS_ERR(op_data))
-                        return (void *)op_data;
-
-                rc = md_enqueue(ll_i2sbi(dir)->ll_md_exp, &einfo, &it,
-                                op_data, &lockh, NULL, 0, NULL, 0);
-
-                ll_finish_md_op_data(op_data);
+       if (!rc) {
+               struct ldlm_enqueue_info einfo = {.ei_type = LDLM_IBITS,
+                                                 .ei_mode = mode,
+                                                 .ei_cb_bl =
+                                                 ll_md_blocking_ast,
+                                                 .ei_cb_cp =
+                                                 ldlm_completion_ast,
+                                                 .ei_cb_gl = NULL,
+                                                 .ei_cb_wg = NULL,
+                                                 .ei_cbdata = NULL};
+               struct lookup_intent it = { .it_op = IT_READDIR };
+               struct ptlrpc_request *request;
+               struct md_op_data *op_data;
+
+               op_data = ll_prep_md_op_data(NULL, dir, NULL, NULL, 0, 0,
+               LUSTRE_OPC_ANY, NULL);
+               if (IS_ERR(op_data))
+                       return (void *)op_data;
+
+               rc = md_enqueue(ll_i2sbi(dir)->ll_md_exp, &einfo, &it,
+                               op_data, &lockh, NULL, 0, NULL, 0);
+
+               ll_finish_md_op_data(op_data);
+
+               request = (struct ptlrpc_request *)it.d.lustre.it_data;
+               if (request)
+                       ptlrpc_req_finished(request);
+               if (rc < 0) {
+                       CERROR("lock enqueue: "DFID" at "LPU64": rc %d\n",
+                               PFID(ll_inode2fid(dir)), hash, rc);
+                       return ERR_PTR(rc);
+               }
 
-                request = (struct ptlrpc_request *)it.d.lustre.it_data;
-                if (request)
-                        ptlrpc_req_finished(request);
-                if (rc < 0) {
-                        CERROR("lock enqueue: "DFID" at "LPU64": rc %d\n",
-                               PFID(ll_inode2fid(dir)), hash, rc);
-                        return ERR_PTR(rc);
-                }
+               CDEBUG(D_INODE, "setting lr_lvb_inode to inode %p (%lu/%u)\n",
+                      dir, dir->i_ino, dir->i_generation);
+               md_set_lock_data(ll_i2sbi(dir)->ll_md_exp,
+                                &it.d.lustre.it_lock_handle, dir, NULL);
         } else {
                 /* for cross-ref object, l_ast_data of the lock may not be set,
                  * we reset it here */
@@ -1024,7 +1036,7 @@ static int ll_ioc_copy_end(struct super_block *sb, struct hsm_copy *copy)
                        CDEBUG(D_HSM, "Could not read file data version. "
                                      "Request could not be confirmed.\n");
                        if (hpk.hpk_errval == 0)
-                               hpk.hpk_errval = rc;
+                               hpk.hpk_errval = -rc;
                        GOTO(progress, rc);
                }
 
@@ -1216,6 +1228,30 @@ out:
         RETURN(rc);
 }
 
+static char *
+ll_getname(const char __user *filename)
+{
+       int ret = 0, len;
+       char *tmp = __getname();
+
+       if (!tmp)
+               return ERR_PTR(-ENOMEM);
+
+       len = strncpy_from_user(tmp, filename, PATH_MAX);
+       if (len == 0)
+               ret = -ENOENT;
+       else if (len > PATH_MAX)
+               ret = -ENAMETOOLONG;
+
+       if (ret) {
+               __putname(tmp);
+               tmp =  ERR_PTR(ret);
+       }
+       return tmp;
+}
+
+#define ll_putname(filename) __putname(filename)
+
 static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
         struct inode *inode = file->f_dentry->d_inode;
@@ -1418,7 +1454,7 @@ free_lmv:
                if (!(exp_connect_flags(sbi->ll_md_exp) & OBD_CONNECT_LVB_TYPE))
                        return -ENOTSUPP;
 
-               filename = getname((const char *)arg);
+               filename = ll_getname((const char *)arg);
                if (IS_ERR(filename))
                        RETURN(PTR_ERR(filename));
 
@@ -1429,7 +1465,7 @@ free_lmv:
                rc = ll_rmdir_entry(inode, filename, namelen);
 out_rmdir:
                 if (filename)
-                        putname(filename);
+                        ll_putname(filename);
                RETURN(rc);
        }
        case LL_IOC_LOV_SWAP_LAYOUTS:
@@ -1449,7 +1485,7 @@ out_rmdir:
 
                 if (cmd == IOC_MDC_GETFILEINFO ||
                     cmd == IOC_MDC_GETFILESTRIPE) {
-                        filename = getname((const char *)arg);
+                        filename = ll_getname((const char *)arg);
                         if (IS_ERR(filename))
                                 RETURN(PTR_ERR(filename));
 
@@ -1516,7 +1552,7 @@ out_rmdir:
         out_req:
                 ptlrpc_req_finished(request);
                 if (filename)
-                        putname(filename);
+                        ll_putname(filename);
                 return rc;
         }
         case IOC_LOV_GETINFO: {
@@ -1534,9 +1570,12 @@ out_rmdir:
                 if (rc)
                         RETURN(rc);
 
-                OBD_ALLOC_LARGE(lmm, lmmsize);
-                if (cfs_copy_from_user(lmm, lum, lmmsize))
-                        GOTO(free_lmm, rc = -EFAULT);
+               OBD_ALLOC_LARGE(lmm, lmmsize);
+               if (lmm == NULL)
+                       RETURN(-ENOMEM);
+
+               if (cfs_copy_from_user(lmm, lum, lmmsize))
+                       GOTO(free_lmm, rc = -EFAULT);
 
                 switch (lmm->lmm_magic) {
                 case LOV_USER_MAGIC_V1: