From mboxrd@z Thu Jan 1 00:00:00 1970 From: Eric Van Hensbergen Subject: v9fs writepage Date: Sat, 30 Apr 2005 12:17:56 -0500 Message-ID: Reply-To: Eric Van Hensbergen Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7BIT Cc: kernel-mentors@selenic.com, linux-fsdevel@vger.kernel.org, Al Viro , Christoph Hellwig Return-path: Received: from rproxy.gmail.com ([64.233.170.201]:56566 "EHLO rproxy.gmail.com") by vger.kernel.org with ESMTP id S261306AbVD3RR5 convert rfc822-to-8bit (ORCPT ); Sat, 30 Apr 2005 13:17:57 -0400 Received: by rproxy.gmail.com with SMTP id j1so685016rnf for ; Sat, 30 Apr 2005 10:17:56 -0700 (PDT) To: v9fs-developer@lists.sourceforge.net Content-Disposition: inline Sender: linux-fsdevel-owner@vger.kernel.org List-Id: linux-fsdevel.vger.kernel.org One critique I got back (from Chris Hellwig) on the v9fs implementation was the way that I went about implementing writepage. I'll agree that my existing solution is imperfect so I'd like to solicit ideas from the community. Essentially, the 9P protocols requires I associate each transaction with a FID (which can be thought of a file descriptor known both to the client and the server which is associated with a particular thread/user). In most areas of the v9fs driver it is fairly trivial to map an access back to a particular FID (be looking at the process context in which the system call was executed). However, in the address_space code (to support mmap), I'm not given an easy handle (in most cases its the dentry or the file structure) to resolve a FID against. In order to try and guess what the right FID to use for the writepage transaction is, I wrote the following function which essentially scans through the dentries of an inode and tries to find the right FID. /** * v9fs_find_file - find a file pointer based on page * @page: page to lookup file based on * */ static struct file *v9fs_find_file(struct page *page) { struct address_space *mapping = page->mapping; struct inode *inode = NULL; struct dentry *dentry = NULL; struct v9fs_fid *fid = NULL; struct list_head *p, *temp; dprintk(DEBUG_VFS, " page: %p\n", page); if (!mapping) { dprintk(DEBUG_ERROR, "No mapping\n"); return NULL; } inode = mapping->host; if (!inode) { dprintk(DEBUG_ERROR, "No inode\n"); return NULL; } list_for_each_safe(p, temp, &inode->i_dentry) { dentry = list_entry(p, struct dentry, d_alias); fid = v9fs_fid_lookup(dentry, FID_OP); if (fid) return fid->filp; } return NULL; } The problem is that v9fs_fid_lookup() tries to find the right fid based on information in current (and therefore assumes it is running in the same context of the thread that initiated the transaction). This isn't always the case in writepage, although I try to force this by always calling writepage from my dirtypage method (which I believe is always called in the context of the process who is "dirtying" the page). This seems to work for simple cases (like running fsx), but hch pointed out that he believes it won't work in certain scenarios. Can anyone suggest a methodology using the address_space_operations to be able to associate memory writes with a particular thread/user? If you would like to see more context, the v9fs code is available in several flavors: tarballs: http://v9fs.sf.net CVSweb: http://cvs.sourceforge.net/viewcvs.py/v9fs/linux-9p/ CVS: :pserver:anonymous@cvs.sourceforge.net:/cvsroot/v9fs/linux-9p BitKeeper: bk://linux-v9fs.bkbits.net Thanks for your help. -eric