mm: memcg/slab: fix percpu slab vmstats flushing
[linux-2.6-microblaze.git] / fs / orangefs / file.c
index a5612ab..c740159 100644 (file)
@@ -46,8 +46,9 @@ static int flush_racache(struct inode *inode)
  * Post and wait for the I/O upcall to finish
  */
 ssize_t wait_for_direct_io(enum ORANGEFS_io_type type, struct inode *inode,
-    loff_t *offset, struct iov_iter *iter, size_t total_size,
-    loff_t readahead_size, struct orangefs_write_range *wr, int *index_return)
+       loff_t *offset, struct iov_iter *iter, size_t total_size,
+       loff_t readahead_size, struct orangefs_write_range *wr,
+       int *index_return, struct file *file)
 {
        struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
        struct orangefs_khandle *handle = &orangefs_inode->refn.khandle;
@@ -55,6 +56,8 @@ ssize_t wait_for_direct_io(enum ORANGEFS_io_type type, struct inode *inode,
        int buffer_index;
        ssize_t ret;
        size_t copy_amount;
+       int open_for_read;
+       int open_for_write;
 
        new_op = op_alloc(ORANGEFS_VFS_OP_FILE_IO);
        if (!new_op)
@@ -90,6 +93,38 @@ populate_shared_memory:
                new_op->upcall.uid = from_kuid(&init_user_ns, wr->uid);
                new_op->upcall.gid = from_kgid(&init_user_ns, wr->gid);
        }
+       /*
+        * Orangefs has no open, and orangefs checks file permissions
+        * on each file access. Posix requires that file permissions
+        * be checked on open and nowhere else. Orangefs-through-the-kernel
+        * needs to seem posix compliant.
+        *
+        * The VFS opens files, even if the filesystem provides no
+        * method. We can see if a file was successfully opened for
+        * read and or for write by looking at file->f_mode.
+        *
+        * When writes are flowing from the page cache, file is no
+        * longer available. We can trust the VFS to have checked
+        * file->f_mode before writing to the page cache.
+        *
+        * The mode of a file might change between when it is opened
+        * and IO commences, or it might be created with an arbitrary mode.
+        *
+        * We'll make sure we don't hit EACCES during the IO stage by
+        * using UID 0. Some of the time we have access without changing
+        * to UID 0 - how to check?
+        */
+       if (file) {
+               open_for_write = file->f_mode & FMODE_WRITE;
+               open_for_read = file->f_mode & FMODE_READ;
+       } else {
+               open_for_write = 1;
+               open_for_read = 0; /* not relevant? */
+       }
+       if ((type == ORANGEFS_IO_WRITE) && open_for_write)
+               new_op->upcall.uid = 0;
+       if ((type == ORANGEFS_IO_READ) && open_for_read)
+               new_op->upcall.uid = 0;
 
        gossip_debug(GOSSIP_FILE_DEBUG,
                     "%s(%pU): offset: %llu total_size: %zd\n",