~ubuntu-branches/ubuntu/vivid/aufs/vivid

« back to all changes in this revision

Viewing changes to fs/aufs/i_op.c

  • Committer: Bazaar Package Importer
  • Author(s): Julian Andres Klode
  • Date: 2008-08-21 14:58:54 UTC
  • mfrom: (1.2.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 12.
  • Revision ID: james.westby@ubuntu.com-20080821145854-a2qpyyfjwtbmarqj
Tags: upstream-0+20080719
ImportĀ upstreamĀ versionĀ 0+20080719

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
/*
20
20
 * inode operations (except add/del/rename)
21
21
 *
22
 
 * $Id: i_op.c,v 1.61 2008/06/09 01:10:26 sfjro Exp $
 
22
 * $Id: i_op.c,v 1.62 2008/06/16 00:11:26 sfjro Exp $
23
23
 */
24
24
 
25
25
//#include <linux/fs.h>
234
234
        struct inode *inode, *h_inode;
235
235
        struct nameidata tmp_nd, *ndp;
236
236
        //todo: no more lower nameidata, only here. re-use it.
 
237
        aufs_bindex_t bstart;
 
238
        struct mutex *mtx;
 
239
        struct super_block *sb;
237
240
 
238
241
        LKTRTrace("dir %lu, %.*s, nd{0x%x}\n",
239
242
                  dir->i_ino, AuDLNPair(dentry), nd ? nd->flags : 0);
249
252
        if (unlikely(err))
250
253
                goto out;
251
254
 
252
 
        ndp = au_dup_nd(au_sbi(dir->i_sb), &tmp_nd, nd);
 
255
        sb = dir->i_sb;
 
256
        ndp = au_dup_nd(au_sbi(sb), &tmp_nd, nd);
253
257
        npositive = au_lkup_dentry(dentry, au_dbstart(parent), /*type*/0, ndp);
254
258
        err = npositive;
255
259
        //err = -1;
258
262
                goto out_unlock;
259
263
        inode = NULL;
260
264
        if (npositive) {
261
 
                /*
262
 
                 * stop 'race'-ing between hardlinks under different parents.
263
 
                 */
 
265
                bstart = au_dbstart(dentry);
264
266
                h_inode = au_h_dptr(dentry)->d_inode;
265
267
                AuDebugOn(!h_inode);
266
 
                if (h_inode->i_nlink == 1 || S_ISDIR(h_inode->i_mode))
267
 
                        inode = au_new_inode(dentry);
268
 
                else {
269
 
                        /* todo: this lock is too large, try br_xino_nondir mutex */
270
 
                        static DEFINE_MUTEX(mtx);
271
 
                        mutex_lock(&mtx);
272
 
                        inode = au_new_inode(dentry);
273
 
                        mutex_unlock(&mtx);
274
 
                }
 
268
                if (!S_ISDIR(h_inode->i_mode)) {
 
269
                        /*
 
270
                         * stop 'race'-ing between hardlinks under different
 
271
                         * parents.
 
272
                         */
 
273
                        mtx = &au_sbr(sb, bstart)->br_xino_nondir_mtx;
 
274
                        mutex_lock(mtx);
 
275
                        inode = au_new_inode(dentry);
 
276
                        mutex_unlock(mtx);
 
277
                } else
 
278
                        inode = au_new_inode(dentry);
275
279
                ret = (void *)inode;
276
280
        }
277
281
        if (!IS_ERR(inode)) {