From: "Chen, Kenneth W" <kenneth.w.chen@intel.com>
To: linux-ia64@vger.kernel.org
Subject: Hugetlb FS quota bug fix
Date: Fri, 26 Sep 2003 21:44:00 +0000 [thread overview]
Message-ID: <marc-linux-ia64-106461272025392@msgid-missing> (raw)
[-- Attachment #1: Type: text/plain, Size: 605 bytes --]
Here is a bug fix patch relative to latest Bjorn's 2.4 ia64 kernel tree.
Mainly sync up hugetlbfs code w.r.t latest 2.6.
Hugetlb file system quota was incorrectly taken on every mmap even for
the case that huge pages has been already allocated on the file inode.
This results in taxing the same hugepage multiple times and causing mmap
to fail on existing file when quota mistakenly runs out. This patch also
fixes file size to account holes.
Bjorn, since you are still carrying hugetlbfs for ia64, would you please
merge this? (bug fix for 2.6 has been taken care already) Thanks.
- Ken
[-- Attachment #2: hugetlbfs-quota24.patch --]
[-- Type: application/octet-stream, Size: 4999 bytes --]
diff -Nurp 2.4.23-pre5/arch/ia64/mm/hugetlbpage.c 2.4.23-pre5.ken/arch/ia64/mm/hugetlbpage.c
--- 2.4.23-pre5/arch/ia64/mm/hugetlbpage.c Fri Sep 26 14:28:21 2003
+++ 2.4.23-pre5.ken/arch/ia64/mm/hugetlbpage.c Fri Sep 26 14:29:05 2003
@@ -262,18 +262,19 @@ int hugetlb_prefault(struct address_spac
+ (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
page = find_get_page(mapping, idx);
if (!page) {
- loff_t i_size;
+ /* charge the fs quota first */
+ if (hugetlb_get_quota(mapping)) {
+ ret = -ENOMEM;
+ goto out;
+ }
page = alloc_hugetlb_page();
if (!page) {
+ hugetlb_put_quota(mapping);
ret = -ENOMEM;
goto out;
}
add_to_page_cache(page, mapping, idx);
unlock_page(page);
- i_size = (loff_t)(idx + 1) * HPAGE_SIZE;
- if (i_size > inode->i_size)
- inode->i_size = i_size;
-
}
set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE);
}
diff -Nurp 2.4.23-pre5/fs/hugetlbfs/inode.c 2.4.23-pre5.ken/fs/hugetlbfs/inode.c
--- 2.4.23-pre5/fs/hugetlbfs/inode.c Fri Sep 26 14:28:21 2003
+++ 2.4.23-pre5.ken/fs/hugetlbfs/inode.c Fri Sep 26 14:29:05 2003
@@ -139,8 +139,7 @@ static int hugetlbfs_file_mmap(struct fi
{
struct inode *inode = file->f_dentry->d_inode;
struct address_space *mapping = inode->i_mapping;
- struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(inode->i_sb);
- loff_t len;
+ loff_t len, vma_len;
int ret;
if (vma->vm_start & ~HPAGE_MASK)
@@ -155,17 +154,7 @@ static int hugetlbfs_file_mmap(struct fi
if (vma->vm_start < (REGION_HPAGE << REGION_SHIFT))
return -EINVAL;
#endif
- len = (loff_t)(vma->vm_end - vma->vm_start);
- if (sbinfo->free_blocks >= 0) { /* Check if there is any size limit. */
- spin_lock(&sbinfo->stat_lock);
- if ((len >> HPAGE_SHIFT) <= sbinfo->free_blocks) {
- sbinfo->free_blocks -= (len >> HPAGE_SHIFT);
- spin_unlock(&sbinfo->stat_lock);
- } else {
- spin_unlock(&sbinfo->stat_lock);
- return -ENOMEM;
- }
- }
+ vma_len = (loff_t)(vma->vm_end - vma->vm_start);
down(&inode->i_sem);
@@ -173,15 +162,11 @@ static int hugetlbfs_file_mmap(struct fi
vma->vm_flags |= VM_HUGETLB | VM_RESERVED;
vma->vm_ops = &hugetlb_vm_ops;
ret = hugetlb_prefault(mapping, vma);
+ len = vma_len + ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
+ if (ret == 0 && inode->i_size < len)
+ inode->i_size = len;
up(&inode->i_sem);
- /* If the huge page allocation has failed then increment the free_blocks. */
- if ((ret != 0) && (sbinfo->free_blocks >= 0)) {
- spin_lock(&sbinfo->stat_lock);
- sbinfo->free_blocks += (len >> HPAGE_SHIFT);
- spin_unlock(&sbinfo->stat_lock);
- }
-
return ret;
}
@@ -261,7 +246,6 @@ void truncate_huge_page(struct address_s
void truncate_hugepages(struct inode *inode, struct address_space *mapping, loff_t lstart)
{
- struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(mapping->host->i_sb);
unsigned long start = lstart >> HPAGE_SHIFT;
unsigned long next;
unsigned long max_idx;
@@ -277,13 +261,8 @@ void truncate_hugepages(struct inode *in
page_cache_release(page);
truncate_huge_page(mapping, page);
unlock_page(page);
- if (sbinfo->free_blocks >= 0) {
- spin_lock(&sbinfo->stat_lock);
- sbinfo->free_blocks ++;
- spin_unlock(&sbinfo->stat_lock);
- }
+ hugetlb_put_quota(mapping);
}
-
}
static void hugetlbfs_delete_inode(struct inode *inode)
@@ -720,6 +699,36 @@ out_dentry:
return ERR_PTR(error);
}
+int hugetlb_get_quota(struct address_space * mapping)
+{
+ int ret = 0;
+ struct hugetlbfs_sb_info *sbinfo =
+ HUGETLBFS_SB(mapping->host->i_sb);
+
+ if (sbinfo->free_blocks > -1) {
+ spin_lock(&sbinfo->stat_lock);
+ if (sbinfo->free_blocks > 0)
+ sbinfo->free_blocks--;
+ else
+ ret = -ENOMEM;
+ spin_unlock(&sbinfo->stat_lock);
+ }
+
+ return ret;
+}
+
+void hugetlb_put_quota(struct address_space *mapping)
+{
+ struct hugetlbfs_sb_info *sbinfo =
+ HUGETLBFS_SB(mapping->host->i_sb);
+
+ if (sbinfo->free_blocks > -1) {
+ spin_lock(&sbinfo->stat_lock);
+ sbinfo->free_blocks++;
+ spin_unlock(&sbinfo->stat_lock);
+ }
+}
+
static int __init init_hugetlbfs_fs(void)
{
int error;
diff -Nurp 2.4.23-pre5/include/linux/hugetlb.h 2.4.23-pre5.ken/include/linux/hugetlb.h
--- 2.4.23-pre5/include/linux/hugetlb.h Fri Sep 26 14:28:21 2003
+++ 2.4.23-pre5.ken/include/linux/hugetlb.h Fri Sep 26 14:29:05 2003
@@ -74,6 +74,8 @@ static inline struct hugetlbfs_sb_info *
extern struct file_operations hugetlbfs_file_operations;
extern struct vm_operations_struct hugetlb_vm_ops;
struct file *hugetlb_zero_setup(size_t);
+int hugetlb_get_quota(struct address_space *mapping);
+void hugetlb_put_quota(struct address_space *mapping);
static inline int is_file_hugepages(struct file *file)
{
@@ -89,6 +91,8 @@ static inline void set_file_hugepages(st
#define is_file_hugepages(file) 0
#define set_file_hugepages(file) BUG()
#define hugetlb_zero_setup(size) ERR_PTR(-ENOSYS)
+#define hugetlb_get_quota(mapping) 0
+#define hugetlb_put_quota(mapping) 0
#endif /* !CONFIG_HUGETLBFS */
reply other threads:[~2003-09-26 21:44 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=marc-linux-ia64-106461272025392@msgid-missing \
--to=kenneth.w.chen@intel.com \
--cc=linux-ia64@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox