rename(): fix the locking of subdirectories
[platform/kernel/linux-rpi.git] / fs / erofs / namei.c
index 966eabc..d4f631d 100644 (file)
@@ -89,7 +89,8 @@ static struct erofs_dirent *find_target_dirent(struct erofs_qstr *name,
 static void *erofs_find_target_block(struct erofs_buf *target,
                struct inode *dir, struct erofs_qstr *name, int *_ndirents)
 {
-       int head = 0, back = DIV_ROUND_UP(dir->i_size, EROFS_BLKSIZ) - 1;
+       unsigned int bsz = i_blocksize(dir);
+       int head = 0, back = erofs_iblks(dir) - 1;
        unsigned int startprfx = 0, endprfx = 0;
        void *candidate = ERR_PTR(-ENOENT);
 
@@ -98,10 +99,10 @@ static void *erofs_find_target_block(struct erofs_buf *target,
                struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
                struct erofs_dirent *de;
 
-               de = erofs_bread(&buf, dir, mid, EROFS_KMAP);
+               buf.inode = dir;
+               de = erofs_bread(&buf, mid, EROFS_KMAP);
                if (!IS_ERR(de)) {
-                       const int nameoff = nameoff_from_disk(de->nameoff,
-                                                             EROFS_BLKSIZ);
+                       const int nameoff = nameoff_from_disk(de->nameoff, bsz);
                        const int ndirents = nameoff / sizeof(*de);
                        int diff;
                        unsigned int matched;
@@ -121,11 +122,10 @@ static void *erofs_find_target_block(struct erofs_buf *target,
 
                        dname.name = (u8 *)de + nameoff;
                        if (ndirents == 1)
-                               dname.end = (u8 *)de + EROFS_BLKSIZ;
+                               dname.end = (u8 *)de + bsz;
                        else
                                dname.end = (u8 *)de +
-                                       nameoff_from_disk(de[1].nameoff,
-                                                         EROFS_BLKSIZ);
+                                       nameoff_from_disk(de[1].nameoff, bsz);
 
                        /* string comparison without already matched prefix */
                        diff = erofs_dirnamecmp(name, &dname, &matched);
@@ -171,6 +171,7 @@ int erofs_namei(struct inode *dir, const struct qstr *name, erofs_nid_t *nid,
 
        qn.name = name->name;
        qn.end = name->name + name->len;
+       buf.inode = dir;
 
        ndirents = 0;
        de = erofs_find_target_block(&buf, dir, &qn, &ndirents);
@@ -178,7 +179,8 @@ int erofs_namei(struct inode *dir, const struct qstr *name, erofs_nid_t *nid,
                return PTR_ERR(de);
 
        if (ndirents)
-               de = find_target_dirent(&qn, (u8 *)de, EROFS_BLKSIZ, ndirents);
+               de = find_target_dirent(&qn, (u8 *)de, i_blocksize(dir),
+                                       ndirents);
 
        if (!IS_ERR(de)) {
                *nid = le64_to_cpu(de->nid);
@@ -203,16 +205,13 @@ static struct dentry *erofs_lookup(struct inode *dir, struct dentry *dentry,
 
        err = erofs_namei(dir, &dentry->d_name, &nid, &d_type);
 
-       if (err == -ENOENT) {
+       if (err == -ENOENT)
                /* negative dentry */
                inode = NULL;
-       } else if (err) {
+       else if (err)
                inode = ERR_PTR(err);
-       } else {
-               erofs_dbg("%s, %pd (nid %llu) found, d_type %u", __func__,
-                         dentry, nid, d_type);
+       else
                inode = erofs_iget(dir->i_sb, nid);
-       }
        return d_splice_alias(inode, dentry);
 }