Whamcloud - gitweb
LU-5817 clio: Do not allow group locks with gid 0
[fs/lustre-release.git] / lustre / llite / file.c
index 7c00ed5..612312c 100644 (file)
@@ -42,7 +42,6 @@
 
 #define DEBUG_SUBSYSTEM S_LLITE
 #include <lustre_dlm.h>
-#include <lustre_lite.h>
 #include <linux/pagemap.h>
 #include <linux/file.h>
 #include <linux/sched.h>
@@ -91,8 +90,7 @@ void ll_pack_inode2opdata(struct inode *inode, struct md_op_data *op_data,
         op_data->op_attr.ia_ctime = inode->i_ctime;
         op_data->op_attr.ia_size = i_size_read(inode);
         op_data->op_attr_blocks = inode->i_blocks;
-        ((struct ll_iattr *)&op_data->op_attr)->ia_attr_flags =
-                                        ll_inode_to_ext_flags(inode->i_flags);
+       op_data->op_attr_flags = ll_inode_to_ext_flags(inode->i_flags);
         op_data->op_ioepoch = ll_i2info(inode)->lli_ioepoch;
         if (fh)
                 op_data->op_handle = *fh;
@@ -1149,7 +1147,7 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args,
        struct range_lock     range;
        ENTRY;
 
-       CDEBUG(D_VFSTRACE, "file: %s, type: %d ppos: "LPU64", count: %zd\n",
+       CDEBUG(D_VFSTRACE, "file: %s, type: %d ppos: "LPU64", count: %zu\n",
                file->f_dentry->d_name.name, iot, *ppos, count);
 
 restart:
@@ -1222,7 +1220,7 @@ out:
        /* If any bit been read/written (result != 0), we just return
         * short read/write instead of restart io. */
        if ((result == 0 || result == -ENODATA) && io->ci_need_restart) {
-               CDEBUG(D_VFSTRACE, "Restart %s on %s from %lld, count:%zd\n",
+               CDEBUG(D_VFSTRACE, "Restart %s on %s from %lld, count:%zu\n",
                       iot == CIT_READ ? "read" : "write",
                       file->f_dentry->d_name.name, *ppos, count);
                LASSERTF(io->ci_nob == 0, "%zd\n", io->ci_nob);
@@ -1308,7 +1306,7 @@ static ssize_t ll_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
         RETURN(result);
 }
 
-static ssize_t ll_file_read(struct file *file, char *buf, size_t count,
+static ssize_t ll_file_read(struct file *file, char __user *buf, size_t count,
                             loff_t *ppos)
 {
         struct lu_env *env;
@@ -1374,8 +1372,8 @@ static ssize_t ll_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
         RETURN(result);
 }
 
-static ssize_t ll_file_write(struct file *file, const char *buf, size_t count,
-                             loff_t *ppos)
+static ssize_t ll_file_write(struct file *file, const char __user *buf,
+                            size_t count, loff_t *ppos)
 {
         struct lu_env *env;
         struct iovec  *local_iov;
@@ -1433,88 +1431,6 @@ static ssize_t ll_file_splice_read(struct file *in_file, loff_t *ppos,
         RETURN(result);
 }
 
-static int ll_lov_recreate(struct inode *inode, struct ost_id *oi,
-                           obd_count ost_idx)
-{
-       struct obd_export *exp = ll_i2dtexp(inode);
-       struct obd_trans_info oti = { 0 };
-       struct obdo *oa = NULL;
-       int lsm_size;
-       int rc = 0;
-       struct lov_stripe_md *lsm = NULL, *lsm2;
-       ENTRY;
-
-       OBDO_ALLOC(oa);
-       if (oa == NULL)
-               RETURN(-ENOMEM);
-
-       lsm = ccc_inode_lsm_get(inode);
-       if (!lsm_has_objects(lsm))
-                GOTO(out, rc = -ENOENT);
-
-        lsm_size = sizeof(*lsm) + (sizeof(struct lov_oinfo) *
-                   (lsm->lsm_stripe_count));
-
-        OBD_ALLOC_LARGE(lsm2, lsm_size);
-        if (lsm2 == NULL)
-                GOTO(out, rc = -ENOMEM);
-
-       oa->o_oi = *oi;
-        oa->o_nlink = ost_idx;
-        oa->o_flags |= OBD_FL_RECREATE_OBJS;
-        oa->o_valid = OBD_MD_FLID | OBD_MD_FLFLAGS | OBD_MD_FLGROUP;
-        obdo_from_inode(oa, inode, OBD_MD_FLTYPE | OBD_MD_FLATIME |
-                                   OBD_MD_FLMTIME | OBD_MD_FLCTIME);
-        obdo_set_parent_fid(oa, &ll_i2info(inode)->lli_fid);
-        memcpy(lsm2, lsm, lsm_size);
-       ll_inode_size_lock(inode);
-       rc = obd_create(NULL, exp, oa, &lsm2, &oti);
-       ll_inode_size_unlock(inode);
-
-       OBD_FREE_LARGE(lsm2, lsm_size);
-       GOTO(out, rc);
-out:
-       ccc_inode_lsm_put(inode, lsm);
-       OBDO_FREE(oa);
-       return rc;
-}
-
-static int ll_lov_recreate_obj(struct inode *inode, unsigned long arg)
-{
-       struct ll_recreate_obj ucreat;
-       struct ost_id           oi;
-       ENTRY;
-
-       if (!cfs_capable(CFS_CAP_SYS_ADMIN))
-               RETURN(-EPERM);
-
-       if (copy_from_user(&ucreat, (struct ll_recreate_obj *)arg,
-                          sizeof(ucreat)))
-               RETURN(-EFAULT);
-
-       ostid_set_seq_mdt0(&oi);
-       ostid_set_id(&oi, ucreat.lrc_id);
-       RETURN(ll_lov_recreate(inode, &oi, ucreat.lrc_ost_idx));
-}
-
-static int ll_lov_recreate_fid(struct inode *inode, unsigned long arg)
-{
-       struct lu_fid   fid;
-       struct ost_id   oi;
-       obd_count       ost_idx;
-        ENTRY;
-
-       if (!cfs_capable(CFS_CAP_SYS_ADMIN))
-               RETURN(-EPERM);
-
-       if (copy_from_user(&fid, (struct lu_fid *)arg, sizeof(fid)))
-               RETURN(-EFAULT);
-
-       fid_to_ostid(&fid, &oi);
-       ost_idx = (fid_seq(&fid) >> 16) & 0xffff;
-       RETURN(ll_lov_recreate(inode, &oi, ost_idx));
-}
-
 int ll_lov_setstripe_ea_info(struct inode *inode, struct file *file,
                              __u64  flags, struct lov_user_md *lum,
                             int lum_size)
@@ -1657,7 +1573,7 @@ static int ll_lov_setea(struct inode *inode, struct file *file,
        if (lump == NULL)
                 RETURN(-ENOMEM);
 
-       if (copy_from_user(lump, (struct lov_user_md  *)arg, lum_size)) {
+       if (copy_from_user(lump, (struct lov_user_md __user *)arg, lum_size)) {
                OBD_FREE_LARGE(lump, lum_size);
                RETURN(-EFAULT);
        }
@@ -1671,38 +1587,32 @@ static int ll_lov_setea(struct inode *inode, struct file *file,
 static int ll_lov_setstripe(struct inode *inode, struct file *file,
                            unsigned long arg)
 {
-       struct lov_user_md_v3    lumv3;
-       struct lov_user_md_v1   *lumv1 = (struct lov_user_md_v1 *)&lumv3;
-       struct lov_user_md_v1   *lumv1p = (struct lov_user_md_v1 *)arg;
-       struct lov_user_md_v3   *lumv3p = (struct lov_user_md_v3 *)arg;
-       int                      lum_size, rc;
-       __u64                    flags = FMODE_WRITE;
+       struct lov_user_md __user *lum = (struct lov_user_md __user *)arg;
+       struct lov_user_md        *klum;
+       int                        lum_size, rc;
+       __u64                      flags = FMODE_WRITE;
        ENTRY;
 
-       /* first try with v1 which is smaller than v3 */
-       lum_size = sizeof(struct lov_user_md_v1);
-       if (copy_from_user(lumv1, lumv1p, lum_size))
-               RETURN(-EFAULT);
-
-       if (lumv1->lmm_magic == LOV_USER_MAGIC_V3) {
-               lum_size = sizeof(struct lov_user_md_v3);
-               if (copy_from_user(&lumv3, lumv3p, lum_size))
-                       RETURN(-EFAULT);
-       }
+       rc = ll_copy_user_md(lum, &klum);
+       if (rc < 0)
+               RETURN(rc);
 
-       rc = ll_lov_setstripe_ea_info(inode, file, flags, lumv1, lum_size);
+       lum_size = rc;
+       rc = ll_lov_setstripe_ea_info(inode, file, flags, klum, lum_size);
        if (rc == 0) {
                struct lov_stripe_md *lsm;
                __u32 gen;
 
-               put_user(0, &lumv1p->lmm_stripe_count);
+               put_user(0, &lum->lmm_stripe_count);
 
                ll_layout_refresh(inode, &gen);
                lsm = ccc_inode_lsm_get(inode);
                rc = obd_iocontrol(LL_IOC_LOV_GETSTRIPE, ll_i2dtexp(inode),
-                                  0, lsm, (void *)arg);
+                                  0, lsm, lum);
                ccc_inode_lsm_put(inode, lsm);
        }
+
+       OBD_FREE(klum, lum_size);
        RETURN(rc);
 }
 
@@ -1715,7 +1625,7 @@ static int ll_lov_getstripe(struct inode *inode, unsigned long arg)
        lsm = ccc_inode_lsm_get(inode);
        if (lsm != NULL)
                rc = obd_iocontrol(LL_IOC_LOV_GETSTRIPE, ll_i2dtexp(inode), 0,
-                                  lsm, (void *)arg);
+                                  lsm, (void __user *)arg);
        ccc_inode_lsm_put(inode, lsm);
        RETURN(rc);
 }
@@ -1729,6 +1639,11 @@ ll_get_grouplock(struct inode *inode, struct file *file, unsigned long arg)
         int                     rc;
         ENTRY;
 
+       if (arg == 0) {
+               CWARN("group id for group lock must not be 0\n");
+               RETURN(-EINVAL);
+       }
+
         if (ll_file_nolock(file))
                 RETURN(-EOPNOTSUPP);
 
@@ -1992,7 +1907,7 @@ static int ll_ioctl_fiemap(struct inode *inode, unsigned long arg)
                 ret_bytes += (fiemap_s->fm_mapped_extents *
                                  sizeof(struct ll_fiemap_extent));
 
-       if (copy_to_user((void *)arg, fiemap_s, ret_bytes))
+       if (copy_to_user((void __user *)arg, fiemap_s, ret_bytes))
                rc = -EFAULT;
 
 error:
@@ -2363,14 +2278,14 @@ ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
         switch(cmd) {
         case LL_IOC_GETFLAGS:
                 /* Get the current value of the file flags */
-                return put_user(fd->fd_flags, (int *)arg);
+               return put_user(fd->fd_flags, (int __user *)arg);
         case LL_IOC_SETFLAGS:
         case LL_IOC_CLRFLAGS:
                 /* Set or clear specific file flags */
                 /* XXX This probably needs checks to ensure the flags are
                  *     not abused, and to handle any flag side effects.
                  */
-                if (get_user(flags, (int *) arg))
+               if (get_user(flags, (int __user *) arg))
                         RETURN(-EFAULT);
 
                 if (cmd == LL_IOC_SETFLAGS) {
@@ -2394,7 +2309,7 @@ ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                struct file *file2;
                struct lustre_swap_layouts lsl;
 
-               if (copy_from_user(&lsl, (char *)arg,
+               if (copy_from_user(&lsl, (char __user *)arg,
                                       sizeof(struct lustre_swap_layouts)))
                        RETURN(-EFAULT);
 
@@ -2413,10 +2328,6 @@ ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        }
         case LL_IOC_LOV_GETSTRIPE:
                 RETURN(ll_lov_getstripe(inode, arg));
-        case LL_IOC_RECREATE_OBJ:
-                RETURN(ll_lov_recreate_obj(inode, arg));
-        case LL_IOC_RECREATE_FID:
-                RETURN(ll_lov_recreate_fid(inode, arg));
         case FSFILT_IOC_FIEMAP:
                 RETURN(ll_ioctl_fiemap(inode, arg));
         case FSFILT_IOC_GETFLAGS:
@@ -2424,13 +2335,13 @@ ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                 RETURN(ll_iocontrol(inode, file, cmd, arg));
         case FSFILT_IOC_GETVERSION_OLD:
         case FSFILT_IOC_GETVERSION:
-                RETURN(put_user(inode->i_generation, (int *)arg));
+               RETURN(put_user(inode->i_generation, (int __user *)arg));
         case LL_IOC_GROUP_LOCK:
                 RETURN(ll_get_grouplock(inode, file, arg));
         case LL_IOC_GROUP_UNLOCK:
                 RETURN(ll_put_grouplock(inode, file, arg));
         case IOC_OBD_STATFS:
-                RETURN(ll_obd_statfs(inode, (void *)arg));
+               RETURN(ll_obd_statfs(inode, (void __user *)arg));
 
         /* We need to special case any other ioctls we want to handle,
          * to send them to the MDS/OST as appropriate and to properly
@@ -2441,25 +2352,29 @@ ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        case LL_IOC_FLUSHCTX:
                RETURN(ll_flush_ctx(inode));
        case LL_IOC_PATH2FID: {
-               if (copy_to_user((void *)arg, ll_inode2fid(inode),
+               if (copy_to_user((void __user *)arg, ll_inode2fid(inode),
                                 sizeof(struct lu_fid)))
                        RETURN(-EFAULT);
 
                RETURN(0);
        }
+       case LL_IOC_GETPARENT:
+               RETURN(ll_getparent(file, (void __user *)arg));
+
        case OBD_IOC_FID2PATH:
-               RETURN(ll_fid2path(inode, (void *)arg));
+               RETURN(ll_fid2path(inode, (void __user *)arg));
        case LL_IOC_DATA_VERSION: {
                struct ioc_data_version idv;
                int rc;
 
-               if (copy_from_user(&idv, (char *)arg, sizeof(idv)))
+               if (copy_from_user(&idv, (char __user *)arg, sizeof(idv)))
                        RETURN(-EFAULT);
 
                idv.idv_flags &= LL_DV_RD_FLUSH | LL_DV_WR_FLUSH;
                rc = ll_data_version(inode, &idv.idv_version, idv.idv_flags);
 
-               if (rc == 0 && copy_to_user((char *) arg, &idv, sizeof(idv)))
+               if (rc == 0 &&
+                   copy_to_user((char __user *)arg, &idv, sizeof(idv)))
                        RETURN(-EFAULT);
 
                RETURN(rc);
@@ -2472,7 +2387,7 @@ ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                 if (mdtidx < 0)
                         RETURN(mdtidx);
 
-                if (put_user((int)mdtidx, (int*)arg))
+               if (put_user((int)mdtidx, (int __user *)arg))
                         RETURN(-EFAULT);
 
                 RETURN(0);
@@ -2499,7 +2414,7 @@ ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                rc = obd_iocontrol(cmd, ll_i2mdexp(inode), sizeof(*op_data),
                                   op_data, NULL);
 
-               if (copy_to_user((void *)arg, hus, sizeof(*hus)))
+               if (copy_to_user((void __user *)arg, hus, sizeof(*hus)))
                        rc = -EFAULT;
 
                ll_finish_md_op_data(op_data);
@@ -2514,7 +2429,7 @@ ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                if (hss == NULL)
                        RETURN(-ENOMEM);
 
-               if (copy_from_user(hss, (char *)arg, sizeof(*hss))) {
+               if (copy_from_user(hss, (char __user *)arg, sizeof(*hss))) {
                        OBD_FREE_PTR(hss);
                        RETURN(-EFAULT);
                }
@@ -2543,7 +2458,7 @@ ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                rc = obd_iocontrol(cmd, ll_i2mdexp(inode), sizeof(*op_data),
                                   op_data, NULL);
 
-               if (copy_to_user((char *)arg, hca, sizeof(*hca)))
+               if (copy_to_user((char __user *)arg, hca, sizeof(*hca)))
                        rc = -EFAULT;
 
                ll_finish_md_op_data(op_data);
@@ -2642,7 +2557,7 @@ ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                if (hui == NULL)
                        RETURN(-ENOMEM);
 
-               if (copy_from_user(hui, (void *)arg, sizeof(*hui))) {
+               if (copy_from_user(hui, (void __user *)arg, sizeof(*hui))) {
                        OBD_FREE_PTR(hui);
                        RETURN(-EFAULT);
                }
@@ -2661,7 +2576,7 @@ ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                        RETURN(err);
 
                RETURN(obd_iocontrol(cmd, ll_i2dtexp(inode), 0, NULL,
-                                    (void *)arg));
+                                    (void __user *)arg));
        }
        }
 }