Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfashe...
authorLinus Torvalds <torvalds@woody.osdl.org>
Sat, 30 Dec 2006 20:02:53 +0000 (12:02 -0800)
committerLinus Torvalds <torvalds@woody.osdl.org>
Sat, 30 Dec 2006 20:02:53 +0000 (12:02 -0800)
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2:
  ocfs2: export heartbeat thread pid via configfs
  ocfs2: always unmap in ocfs2_data_convert_worker()
  ocfs2: ignore NULL vfsmnt in ocfs2_should_update_atime()
  ocfs2: Allow direct I/O read past end of file
  ocfs2: don't print error in ocfs2_permission()

fs/ocfs2/aops.c
fs/ocfs2/cluster/heartbeat.c
fs/ocfs2/dlmglue.c
fs/ocfs2/file.c

index ef6cd30108a9fb153a244c97050420f93a9efb0e..93628b02ef5d8899658834e093195e9a702a8693 100644 (file)
@@ -540,8 +540,7 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock,
                                     struct buffer_head *bh_result, int create)
 {
        int ret;
-       u64 vbo_max; /* file offset, max_blocks from iblock */
-       u64 p_blkno;
+       u64 p_blkno, inode_blocks;
        int contig_blocks;
        unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
        unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits;
@@ -550,12 +549,23 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock,
         * nicely aligned and of the right size, so there's no need
         * for us to check any of that. */
 
-       vbo_max = ((u64)iblock + max_blocks) << blocksize_bits;
-
        spin_lock(&OCFS2_I(inode)->ip_lock);
-       if ((iblock + max_blocks) >
-           ocfs2_clusters_to_blocks(inode->i_sb,
-                                    OCFS2_I(inode)->ip_clusters)) {
+       inode_blocks = ocfs2_clusters_to_blocks(inode->i_sb,
+                                               OCFS2_I(inode)->ip_clusters);
+
+       /*
+        * For a read which begins past the end of file, we return a hole.
+        */
+       if (!create && (iblock >= inode_blocks)) {
+               spin_unlock(&OCFS2_I(inode)->ip_lock);
+               ret = 0;
+               goto bail;
+       }
+
+       /*
+        * Any write past EOF is not allowed because we'd be extending.
+        */
+       if (create && (iblock + max_blocks) > inode_blocks) {
                spin_unlock(&OCFS2_I(inode)->ip_lock);
                ret = -EIO;
                goto bail;
index a25ef5a5038678115bce74843dd11ec2fe2675de..277ca67a2ad6ed42cb608b3892ef1b20c8d4f5cd 100644 (file)
@@ -1447,6 +1447,15 @@ out:
        return ret;
 }
 
+static ssize_t o2hb_region_pid_read(struct o2hb_region *reg,
+                                      char *page)
+{
+       if (!reg->hr_task)
+               return 0;
+
+       return sprintf(page, "%u\n", reg->hr_task->pid);
+}
+
 struct o2hb_region_attribute {
        struct configfs_attribute attr;
        ssize_t (*show)(struct o2hb_region *, char *);
@@ -1485,11 +1494,19 @@ static struct o2hb_region_attribute o2hb_region_attr_dev = {
        .store  = o2hb_region_dev_write,
 };
 
+static struct o2hb_region_attribute o2hb_region_attr_pid = {
+       .attr   = { .ca_owner = THIS_MODULE,
+                   .ca_name = "pid",
+                   .ca_mode = S_IRUGO | S_IRUSR },
+       .show   = o2hb_region_pid_read,
+};
+
 static struct configfs_attribute *o2hb_region_attrs[] = {
        &o2hb_region_attr_block_bytes.attr,
        &o2hb_region_attr_start_block.attr,
        &o2hb_region_attr_blocks.attr,
        &o2hb_region_attr_dev.attr,
+       &o2hb_region_attr_pid.attr,
        NULL,
 };
 
index e6220137bf691600be76ac97d86868347269d4d1..e335541727f9bad9130859678b21693f7e25e067 100644 (file)
@@ -2718,6 +2718,15 @@ static int ocfs2_data_convert_worker(struct ocfs2_lock_res *lockres,
                inode = ocfs2_lock_res_inode(lockres);
        mapping = inode->i_mapping;
 
+       /*
+        * We need this before the filemap_fdatawrite() so that it can
+        * transfer the dirty bit from the PTE to the
+        * page. Unfortunately this means that even for EX->PR
+        * downconverts, we'll lose our mappings and have to build
+        * them up again.
+        */
+       unmap_mapping_range(mapping, 0, 0, 0);
+
        if (filemap_fdatawrite(mapping)) {
                mlog(ML_ERROR, "Could not sync inode %llu for downconvert!",
                     (unsigned long long)OCFS2_I(inode)->ip_blkno);
@@ -2725,7 +2734,6 @@ static int ocfs2_data_convert_worker(struct ocfs2_lock_res *lockres,
        sync_mapping_buffers(mapping);
        if (blocking == LKM_EXMODE) {
                truncate_inode_pages(mapping, 0);
-               unmap_mapping_range(mapping, 0, 0, 0);
        } else {
                /* We only need to wait on the I/O if we're not also
                 * truncating pages because truncate_inode_pages waits
index 9fd590b9bde3d69a403902cd60f228e92eea87f6..10953a508f2f3dfdd158102b25d367250834d5ff 100644 (file)
@@ -149,6 +149,17 @@ int ocfs2_should_update_atime(struct inode *inode,
            ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode)))
                return 0;
 
+       /*
+        * We can be called with no vfsmnt structure - NFSD will
+        * sometimes do this.
+        *
+        * Note that our action here is different than touch_atime() -
+        * if we can't tell whether this is a noatime mount, then we
+        * don't know whether to trust the value of s_atime_quantum.
+        */
+       if (vfsmnt == NULL)
+               return 0;
+
        if ((vfsmnt->mnt_flags & MNT_NOATIME) ||
            ((vfsmnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)))
                return 0;
@@ -966,8 +977,6 @@ int ocfs2_permission(struct inode *inode, int mask, struct nameidata *nd)
        }
 
        ret = generic_permission(inode, mask, NULL);
-       if (ret)
-               mlog_errno(ret);
 
        ocfs2_meta_unlock(inode, 0);
 out: