Whamcloud - gitweb
LU-271 Skip permission check for NFS open after create
[fs/lustre-release.git] / lustre / llite / file.c
index 957694b..d316e18 100644 (file)
@@ -502,12 +502,8 @@ int ll_file_open(struct inode *inode, struct file *file)
         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), flags %o\n", inode->i_ino,
                inode->i_generation, inode, file->f_flags);
 
-#ifdef HAVE_VFS_INTENT_PATCHES
-        it = file->f_it;
-#else
         it = file->private_data; /* XXX: compat macro */
         file->private_data = NULL; /* prevent ll_local_open assertion */
-#endif
 
         fd = ll_file_data_get();
         if (fd == NULL)
@@ -543,7 +539,7 @@ int ll_file_open(struct inode *inode, struct file *file)
                  * dentry_open after call to open_namei that checks permissions.
                  * Only nfsd_open call dentry_open directly without checking
                  * permissions and because of that this code below is safe. */
-                if (oit.it_flags & FMODE_WRITE)
+                if (oit.it_flags & (FMODE_WRITE | FMODE_READ))
                         oit.it_flags |= MDS_OPEN_OWNEROVERRIDE;
 
                 /* We do not want O_EXCL here, presumably we opened the file
@@ -1229,7 +1225,7 @@ static int ll_lov_recreate(struct inode *inode, obd_id id, obd_seq seq,
         lsm_size = sizeof(*lsm) + (sizeof(struct lov_oinfo) *
                    (lsm->lsm_stripe_count));
 
-        OBD_ALLOC(lsm2, lsm_size);
+        OBD_ALLOC_LARGE(lsm2, lsm_size);
         if (lsm2 == NULL)
                 GOTO(out, rc = -ENOMEM);
 
@@ -1243,7 +1239,7 @@ static int ll_lov_recreate(struct inode *inode, obd_id id, obd_seq seq,
         memcpy(lsm2, lsm, lsm_size);
         rc = obd_create(exp, oa, &lsm2, &oti);
 
-        OBD_FREE(lsm2, lsm_size);
+        OBD_FREE_LARGE(lsm2, lsm_size);
         GOTO(out, rc);
 out:
         ll_inode_size_unlock(inode, 0);
@@ -1414,18 +1410,18 @@ static int ll_lov_setea(struct inode *inode, struct file *file,
         if (!cfs_capable(CFS_CAP_SYS_ADMIN))
                 RETURN(-EPERM);
 
-        OBD_ALLOC(lump, lum_size);
+        OBD_ALLOC_LARGE(lump, lum_size);
         if (lump == NULL) {
                 RETURN(-ENOMEM);
         }
         if (cfs_copy_from_user(lump, (struct lov_user_md  *)arg, lum_size)) {
-                OBD_FREE(lump, lum_size);
+                OBD_FREE_LARGE(lump, lum_size);
                 RETURN(-EFAULT);
         }
 
         rc = ll_lov_setstripe_ea_info(inode, file, flags, lump, lum_size);
 
-        OBD_FREE(lump, lum_size);
+        OBD_FREE_LARGE(lump, lum_size);
         RETURN(rc);
 }
 
@@ -1698,7 +1694,7 @@ static int ll_ioctl_fiemap(struct inode *inode, unsigned long arg)
         num_bytes = sizeof(*fiemap_s) + (extent_count *
                                          sizeof(struct ll_fiemap_extent));
 
-        OBD_VMALLOC(fiemap_s, num_bytes);
+        OBD_ALLOC_LARGE(fiemap_s, num_bytes);
         if (fiemap_s == NULL)
                 RETURN(-ENOMEM);
 
@@ -1731,13 +1727,19 @@ static int ll_ioctl_fiemap(struct inode *inode, unsigned long arg)
                 rc = -EFAULT;
 
 error:
-        OBD_VFREE(fiemap_s, num_bytes);
+        OBD_FREE_LARGE(fiemap_s, num_bytes);
         RETURN(rc);
 }
 
+#ifdef HAVE_UNLOCKED_IOCTL
+long ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+        struct inode *inode = file->f_dentry->d_inode;
+#else
 int ll_file_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                   unsigned long arg)
 {
+#endif
         struct ll_file_data *fd = LUSTRE_FPRIVATE(file);
         int flags;
         ENTRY;
@@ -1950,27 +1952,32 @@ int ll_fsync(struct file *file, struct dentry *dentry, int data)
                 ptlrpc_req_finished(req);
 
         if (data && lsm) {
-                struct obdo *oa;
+                struct obd_info *oinfo;
 
-                OBDO_ALLOC(oa);
-                if (!oa)
+                OBD_ALLOC_PTR(oinfo);
+                if (!oinfo)
                         RETURN(rc ? rc : -ENOMEM);
-
-                oa->o_id = lsm->lsm_object_id;
-                oa->o_seq = lsm->lsm_object_seq;
-                oa->o_valid = OBD_MD_FLID | OBD_MD_FLGROUP;
-                obdo_from_inode(oa, inode, &ll_i2info(inode)->lli_fid,
+                OBDO_ALLOC(oinfo->oi_oa);
+                if (!oinfo->oi_oa) {
+                        OBD_FREE_PTR(oinfo);
+                        RETURN(rc ? rc : -ENOMEM);
+                }
+                oinfo->oi_oa->o_id = lsm->lsm_object_id;
+                oinfo->oi_oa->o_seq = lsm->lsm_object_seq;
+                oinfo->oi_oa->o_valid = OBD_MD_FLID | OBD_MD_FLGROUP;
+                obdo_from_inode(oinfo->oi_oa, inode, &ll_i2info(inode)->lli_fid,
                                 OBD_MD_FLTYPE | OBD_MD_FLATIME |
                                 OBD_MD_FLMTIME | OBD_MD_FLCTIME |
                                 OBD_MD_FLGROUP);
-
-                oc = ll_osscapa_get(inode, CAPA_OPC_OSS_WRITE);
-                err = obd_sync(ll_i2sbi(inode)->ll_dt_exp, oa, lsm,
-                               0, OBD_OBJECT_EOF, oc);
-                capa_put(oc);
+                oinfo->oi_md = lsm;
+                oinfo->oi_capa = ll_osscapa_get(inode, CAPA_OPC_OSS_WRITE);
+                err = obd_sync_rqset(ll_i2sbi(inode)->ll_dt_exp, oinfo, 0,
+                                     OBD_OBJECT_EOF);
+                capa_put(oinfo->oi_capa);
                 if (!rc)
                         rc = err;
-                OBDO_FREE(oa);
+                OBDO_FREE(oinfo->oi_oa);
+                OBD_FREE_PTR(oinfo);
                 lli->lli_write_rc = err < 0 ? : 0;
         }
 
@@ -1986,7 +1993,7 @@ int ll_file_flock(struct file *file, int cmd, struct file_lock *file_lock)
                                            .ei_cbdata = file_lock };
         struct md_op_data *op_data;
         struct lustre_handle lockh = {0};
-        ldlm_policy_data_t flock;
+        ldlm_policy_data_t flock = {{0}};
         int flags = 0;
         int rc;
         ENTRY;
@@ -1998,13 +2005,18 @@ int ll_file_flock(struct file *file, int cmd, struct file_lock *file_lock)
 
         if (file_lock->fl_flags & FL_FLOCK) {
                 LASSERT((cmd == F_SETLKW) || (cmd == F_SETLK));
-                /* set missing params for flock() calls */
-                file_lock->fl_end = OFFSET_MAX;
-                file_lock->fl_pid = current->tgid;
+                /* flocks are whole-file locks */
+                flock.l_flock.end = OFFSET_MAX;
+                /* For flocks owner is determined by the local file desctiptor*/
+                flock.l_flock.owner = (unsigned long)file_lock->fl_file;
+        } else if (file_lock->fl_flags & FL_POSIX) {
+                flock.l_flock.owner = (unsigned long)file_lock->fl_owner;
+                flock.l_flock.start = file_lock->fl_start;
+                flock.l_flock.end = file_lock->fl_end;
+        } else {
+                RETURN(-EINVAL);
         }
         flock.l_flock.pid = file_lock->fl_pid;
-        flock.l_flock.start = file_lock->fl_start;
-        flock.l_flock.end = file_lock->fl_end;
 
         switch (file_lock->fl_type) {
         case F_RDLCK:
@@ -2182,6 +2194,9 @@ int __ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it,
                 struct lookup_intent oit = { .it_op = IT_GETATTR };
                 struct md_op_data *op_data;
 
+                if (ibits == MDS_INODELOCK_LOOKUP)
+                        oit.it_op = IT_LOOKUP;
+
                 /* Call getattr by fid, so do not provide name at all. */
                 op_data = ll_prep_md_op_data(NULL, dentry->d_parent->d_inode,
                                              dentry->d_inode, NULL, 0, 0,
@@ -2258,14 +2273,14 @@ out:
         return rc;
 }
 
-int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it)
+int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it,
+                           __u64 ibits)
 {
         struct inode *inode = dentry->d_inode;
         int rc;
         ENTRY;
 
-        rc = __ll_inode_revalidate_it(dentry, it, MDS_INODELOCK_UPDATE |
-                                                  MDS_INODELOCK_LOOKUP);
+        rc = __ll_inode_revalidate_it(dentry, it, ibits);
 
         /* if object not yet allocated, don't validate size */
         if (rc == 0 && ll_i2info(dentry->d_inode)->lli_smd == NULL) {
@@ -2291,7 +2306,8 @@ int ll_getattr_it(struct vfsmount *mnt, struct dentry *de,
         struct ll_inode_info *lli = ll_i2info(inode);
         int res = 0;
 
-        res = ll_inode_revalidate_it(de, it);
+        res = ll_inode_revalidate_it(de, it, MDS_INODELOCK_UPDATE |
+                                             MDS_INODELOCK_LOOKUP);
         ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_GETATTR, 1);
 
         if (res)
@@ -2340,7 +2356,7 @@ int ll_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
 
         num_bytes = sizeof(*fiemap) + (extent_count *
                                        sizeof(struct ll_fiemap_extent));
-        OBD_VMALLOC(fiemap, num_bytes);
+        OBD_ALLOC_LARGE(fiemap, num_bytes);
 
         if (fiemap == NULL)
                 RETURN(-ENOMEM);
@@ -2359,7 +2375,7 @@ int ll_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
         memcpy(fieinfo->fi_extents_start, &fiemap->fm_extents[0],
                fiemap->fm_mapped_extents * sizeof(struct ll_fiemap_extent));
 
-        OBD_VFREE(fiemap, num_bytes);
+        OBD_FREE_LARGE(fiemap, num_bytes);
         return rc;
 }
 #endif
@@ -2493,7 +2509,11 @@ struct file_operations ll_file_operations = {
         .READ_METHOD    = READ_FUNCTION,
         .write          = ll_file_write,
         .WRITE_METHOD   = WRITE_FUNCTION,
+#ifdef HAVE_UNLOCKED_IOCTL
+        .unlocked_ioctl = ll_file_ioctl,
+#else
         .ioctl          = ll_file_ioctl,
+#endif
         .open           = ll_file_open,
         .release        = ll_file_release,
         .mmap           = ll_file_mmap,
@@ -2513,7 +2533,11 @@ struct file_operations ll_file_operations_flock = {
         .READ_METHOD    = READ_FUNCTION,
         .write          = ll_file_write,
         .WRITE_METHOD   = WRITE_FUNCTION,
+#ifdef HAVE_UNLOCKED_IOCTL
+        .unlocked_ioctl = ll_file_ioctl,
+#else
         .ioctl          = ll_file_ioctl,
+#endif
         .open           = ll_file_open,
         .release        = ll_file_release,
         .mmap           = ll_file_mmap,
@@ -2538,7 +2562,11 @@ struct file_operations ll_file_operations_noflock = {
         .READ_METHOD    = READ_FUNCTION,
         .write          = ll_file_write,
         .WRITE_METHOD   = WRITE_FUNCTION,
+#ifdef HAVE_UNLOCKED_IOCTL
+        .unlocked_ioctl = ll_file_ioctl,
+#else
         .ioctl          = ll_file_ioctl,
+#endif
         .open           = ll_file_open,
         .release        = ll_file_release,
         .mmap           = ll_file_mmap,
@@ -2558,9 +2586,6 @@ struct file_operations ll_file_operations_noflock = {
 };
 
 struct inode_operations ll_file_inode_operations = {
-#ifdef HAVE_VFS_INTENT_PATCHES
-        .setattr_raw    = ll_setattr_raw,
-#endif
         .setattr        = ll_setattr,
         .truncate       = ll_truncate,
         .getattr        = ll_getattr,