From patchwork Fri Jun 25 19:05:00 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Valerie Aurora Henson X-Patchwork-Id: 56968 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 4CFAEB6EEF for ; Sat, 26 Jun 2010 05:14:18 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932387Ab0FYTNq (ORCPT ); Fri, 25 Jun 2010 15:13:46 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56827 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932320Ab0FYTGN (ORCPT ); Fri, 25 Jun 2010 15:06:13 -0400 Received: from int-mx04.intmail.prod.int.phx2.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.17]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o5PJ5usw008477 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 25 Jun 2010 15:05:56 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx04.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o5PJ5t3w014119; Fri, 25 Jun 2010 15:05:55 -0400 Received: from localhost.localdomain (vpn-226-32.phx2.redhat.com [10.3.226.32]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id o5PJ5YeJ021807; Fri, 25 Jun 2010 15:05:53 -0400 From: Valerie Aurora To: Alexander Viro Cc: Miklos Szeredi , Jan Blunck , Christoph Hellwig , linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, Valerie Aurora , Theodore Tso , linux-ext4@vger.kernel.org Subject: [PATCH 10/38] whiteout: Split of ext2_append_link() from ext2_add_link() Date: Fri, 25 Jun 2010 12:05:00 -0700 Message-Id: <1277492728-11446-11-git-send-email-vaurora@redhat.com> In-Reply-To: <1277492728-11446-1-git-send-email-vaurora@redhat.com> References: <1277492728-11446-1-git-send-email-vaurora@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.17 Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org From: Jan Blunck The ext2_append_link() is later used to find or append a directory entry to whiteout. Signed-off-by: Jan Blunck Signed-off-by: Valerie Aurora Cc: Theodore Tso Cc: linux-ext4@vger.kernel.org --- fs/ext2/dir.c | 70 ++++++++++++++++++++++++++++++++++++++++---------------- 1 files changed, 50 insertions(+), 20 deletions(-) diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index 7516957..57207a9 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c @@ -472,9 +472,10 @@ void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, } /* - * Parent is locked. + * Find or append a given dentry to the parent directory */ -int ext2_add_link (struct dentry *dentry, struct inode *inode) +static ext2_dirent * ext2_append_entry(struct dentry * dentry, + struct page ** page) { struct inode *dir = dentry->d_parent->d_inode; const char *name = dentry->d_name.name; @@ -482,13 +483,10 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode) unsigned chunk_size = ext2_chunk_size(dir); unsigned reclen = EXT2_DIR_REC_LEN(namelen); unsigned short rec_len, name_len; - struct page *page = NULL; - ext2_dirent * de; + ext2_dirent * de = NULL; unsigned long npages = dir_pages(dir); unsigned long n; char *kaddr; - loff_t pos; - int err; /* * We take care of directory expansion in the same loop. @@ -498,20 +496,19 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode) for (n = 0; n <= npages; n++) { char *dir_end; - page = ext2_get_page(dir, n, 0); - err = PTR_ERR(page); - if (IS_ERR(page)) + *page = ext2_get_page(dir, n, 0); + de = ERR_PTR(PTR_ERR(*page)); + if (IS_ERR(*page)) goto out; - lock_page(page); - kaddr = page_address(page); + lock_page(*page); + kaddr = page_address(*page); dir_end = kaddr + ext2_last_byte(dir, n); de = (ext2_dirent *)kaddr; kaddr += PAGE_CACHE_SIZE - reclen; while ((char *)de <= kaddr) { if ((char *)de == dir_end) { /* We hit i_size */ - name_len = 0; - rec_len = chunk_size; + de->name_len = 0; de->rec_len = ext2_rec_len_to_disk(chunk_size); de->inode = 0; goto got_it; @@ -519,12 +516,11 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode) if (de->rec_len == 0) { ext2_error(dir->i_sb, __func__, "zero-length directory entry"); - err = -EIO; + de = ERR_PTR(-EIO); goto out_unlock; } - err = -EEXIST; if (ext2_match (namelen, name, de)) - goto out_unlock; + goto got_it; name_len = EXT2_DIR_REC_LEN(de->name_len); rec_len = ext2_rec_len_from_disk(de->rec_len); if (!de->inode && rec_len >= reclen) @@ -533,13 +529,48 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode) goto got_it; de = (ext2_dirent *) ((char *) de + rec_len); } - unlock_page(page); - ext2_put_page(page); + unlock_page(*page); + ext2_put_page(*page); } + BUG(); - return -EINVAL; got_it: + return de; + /* OFFSET_CACHE */ +out_unlock: + unlock_page(*page); + ext2_put_page(*page); +out: + return de; +} + +/* + * Parent is locked. + */ +int ext2_add_link (struct dentry *dentry, struct inode *inode) +{ + struct inode *dir = dentry->d_parent->d_inode; + const char *name = dentry->d_name.name; + int namelen = dentry->d_name.len; + unsigned short rec_len, name_len; + ext2_dirent * de; + struct page *page; + loff_t pos; + int err; + + de = ext2_append_entry(dentry, &page); + if (IS_ERR(de)) + return PTR_ERR(de); + + err = -EEXIST; + if (ext2_match (namelen, name, de)) + goto out_unlock; + +got_it: + name_len = EXT2_DIR_REC_LEN(de->name_len); + rec_len = ext2_rec_len_from_disk(de->rec_len); + pos = page_offset(page) + (char*)de - (char*)page_address(page); err = __ext2_write_begin(NULL, page->mapping, pos, rec_len, 0, @@ -563,7 +594,6 @@ got_it: /* OFFSET_CACHE */ out_put: ext2_put_page(page); -out: return err; out_unlock: unlock_page(page);