From eca0f91ef4283a65befd2c21cf8876713f8c8366 Mon Sep 17 00:00:00 2001 From: anserper Date: Mon, 17 Aug 2009 17:38:36 +0000 Subject: [PATCH] b=20008 i=Oleg Drokin i=Alex Tomas pin the last page before starting transaction in setattr to avoid GFP_FS allocation under transaction --- lustre/doc/liblustreapi.7 | 11 +++++++++++ lustre/doc/llapi_file_create.3 | 1 + lustre/obdfilter/filter.c | 16 ++++++++++++++++ 3 files changed, 28 insertions(+) create mode 100644 lustre/doc/liblustreapi.7 create mode 100644 lustre/doc/llapi_file_create.3 diff --git a/lustre/doc/liblustreapi.7 b/lustre/doc/liblustreapi.7 new file mode 100644 index 0000000..ebd86bf --- /dev/null +++ b/lustre/doc/liblustreapi.7 @@ -0,0 +1,11 @@ +.TH liblustreapi 7 "2009 Aug 10" Lustre liblustreapi +.SH NAME +liblustre \- The liblustre library +.SH DESCRIPTION +The liblustre library provides functions to access and/or modify settings specific to the Lustre filesystem (allocation policies, quotas, etc). +.SH "SEE ALSO" +.BR lustre (7), +.BR llapi_file_create (3), +.BR llapi_file_open (3), +.BR llapi_file_get_stripe (3), +.BR llapi_quotactl (3) diff --git a/lustre/doc/llapi_file_create.3 b/lustre/doc/llapi_file_create.3 new file mode 100644 index 0000000..60dd263 --- /dev/null +++ b/lustre/doc/llapi_file_create.3 @@ -0,0 +1 @@ +.so man3/llapi_file_open.3 diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index df26397..eb6f1fb 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -2761,6 +2761,7 @@ int filter_setattr_internal(struct obd_export *exp, struct dentry *dentry, loff_t old_size = 0; unsigned int ia_valid; struct inode *inode; + struct page *page = NULL; struct iattr iattr; void *handle; ENTRY; @@ -2796,6 +2797,17 @@ int filter_setattr_internal(struct obd_export *exp, struct dentry *dentry, if (rc) GOTO(out_unlock, rc); + /* Let's pin the last page so that ldiskfs_truncate + * should not start GFP_FS allocation (20008). */ + if (ia_valid & ATTR_SIZE) { + page = grab_cache_page(inode->i_mapping, + iattr.ia_size >> PAGE_CACHE_SHIFT); + if (page == NULL) + GOTO(out_unlock, rc = -ENOMEM); + + unlock_page(page); + } + /* If the inode still has SUID+SGID bits set (see filter_precreate()) * then we will accept the UID+GID sent by the client during write for * initializing the ownership of this inode. We only allow this to @@ -2886,7 +2898,11 @@ int filter_setattr_internal(struct obd_export *exp, struct dentry *dentry, } EXIT; + out_unlock: + if (page) + page_cache_release(page); + if (ia_valid & (ATTR_SIZE | ATTR_UID | ATTR_GID)) UNLOCK_INODE_MUTEX(inode); if (ia_valid & ATTR_SIZE) -- 1.8.3.1