Message ID | tencent_7DD31A2AA74D2EFCA9667E52E9D7E2CB0208@qq.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v1,01/11] exfat: add __exfat_get_dentry_set() helper | expand |
> - * Returns a set of dentries for a file or dir. > + * Returns a set of dentries. > * > * Note It provides a direct pointer to bh->data via > exfat_get_dentry_cached(). > * User should call exfat_get_dentry_set() after setting 'modified' to > apply > @@ -842,22 +836,24 @@ struct exfat_dentry *exfat_get_dentry_cached( > * > * in: > * sb+p_dir+entry: indicates a file/dir > - * type: specifies how many dentries should be included. > + * num_entries: specifies how many dentries should be included. > + * It will be set to es->num_entries if it is not 0. > + * If num_entries is 0, es->num_entries will be obtained > + * from the first dentry. > + * out: > + * es: pointer of entry set on success. > * return: > - * pointer of entry set on success, > - * NULL on failure. > + * 0 on success > + * < 0 on failure -error code on failure. > */ > -int exfat_get_dentry_set(struct exfat_entry_set_cache *es, > +static int __exfat_get_dentry_set(struct exfat_entry_set_cache *es, > struct super_block *sb, struct exfat_chain *p_dir, int entry, > - unsigned int type) > + unsigned int num_entries) > { > int ret, i, num_bh; > unsigned int off; > sector_t sec; > struct exfat_sb_info *sbi = EXFAT_SB(sb); > - struct exfat_dentry *ep; > - int num_entries; > - enum exfat_validate_dentry_mode mode = ES_MODE_STARTED; > struct buffer_head *bh; > > if (p_dir->dir == DIR_DELETED) { > @@ -880,12 +876,16 @@ int exfat_get_dentry_set(struct exfat_entry_set_cache > *es, > return -EIO; > es->bh[es->num_bh++] = bh; > > - ep = exfat_get_dentry_cached(es, ES_IDX_FILE); > - if (!exfat_validate_entry(exfat_get_entry_type(ep), &mode)) > - goto put_es; > + if (num_entries == ES_ALL_ENTRIES) { > + struct exfat_dentry *ep; > + > + ep = exfat_get_dentry_cached(es, ES_IDX_FILE); > + if (ep->type == EXFAT_FILE) > + num_entries = ep->dentry.file.num_ext + 1; > + else > + goto put_es; I prefer to avoid else{}. if (ep->type != EXFAT_FILE) goto put_es; > + } > > - num_entries = type == ES_ALL_ENTRIES ? > - ep->dentry.file.num_ext + 1 : type; > es->num_entries = num_entries; > > num_bh = EXFAT_B_TO_BLK_ROUND_UP(off + num_entries * DENTRY_SIZE, sb); > @@ -918,8 +918,27 @@ int exfat_get_dentry_set(struct exfat_entry_set_cache > *es, > es->bh[es->num_bh++] = bh; > } > > + return 0; > + > +put_es: > + exfat_put_dentry_set(es, false); > + return -EIO; > +} > + > +int exfat_get_dentry_set(struct exfat_entry_set_cache *es, > + struct super_block *sb, struct exfat_chain *p_dir, > + int entry, unsigned int type) > +{ > + int ret, i; > + struct exfat_dentry *ep; > + enum exfat_validate_dentry_mode mode = ES_MODE_GET_FILE_ENTRY; > + > + ret = __exfat_get_dentry_set(es, sb, p_dir, entry, type); You need to change type to num_entries ? > + if (ret < 0) > + return ret; > + > /* validate cached dentries */ > - for (i = ES_IDX_STREAM; i < num_entries; i++) { > + for (i = ES_IDX_STREAM; i < es->num_entries; i++) { > ep = exfat_get_dentry_cached(es, i); > if (!exfat_validate_entry(exfat_get_entry_type(ep), &mode)) > goto put_es; > -- > 2.25.1 > >
diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c index 9f9295847a4e..f33e40aad276 100644 --- a/fs/exfat/dir.c +++ b/fs/exfat/dir.c @@ -775,7 +775,6 @@ struct exfat_dentry *exfat_get_dentry(struct super_block *sb, } enum exfat_validate_dentry_mode { - ES_MODE_STARTED, ES_MODE_GET_FILE_ENTRY, ES_MODE_GET_STRM_ENTRY, ES_MODE_GET_NAME_ENTRY, @@ -790,11 +789,6 @@ static bool exfat_validate_entry(unsigned int type, return false; switch (*mode) { - case ES_MODE_STARTED: - if (type != TYPE_FILE && type != TYPE_DIR) - return false; - *mode = ES_MODE_GET_FILE_ENTRY; - break; case ES_MODE_GET_FILE_ENTRY: if (type != TYPE_STREAM) return false; @@ -834,7 +828,7 @@ struct exfat_dentry *exfat_get_dentry_cached( } /* - * Returns a set of dentries for a file or dir. + * Returns a set of dentries. * * Note It provides a direct pointer to bh->data via exfat_get_dentry_cached(). * User should call exfat_get_dentry_set() after setting 'modified' to apply @@ -842,22 +836,24 @@ struct exfat_dentry *exfat_get_dentry_cached( * * in: * sb+p_dir+entry: indicates a file/dir - * type: specifies how many dentries should be included. + * num_entries: specifies how many dentries should be included. + * It will be set to es->num_entries if it is not 0. + * If num_entries is 0, es->num_entries will be obtained + * from the first dentry. + * out: + * es: pointer of entry set on success. * return: - * pointer of entry set on success, - * NULL on failure. + * 0 on success + * < 0 on failure */ -int exfat_get_dentry_set(struct exfat_entry_set_cache *es, +static int __exfat_get_dentry_set(struct exfat_entry_set_cache *es, struct super_block *sb, struct exfat_chain *p_dir, int entry, - unsigned int type) + unsigned int num_entries) { int ret, i, num_bh; unsigned int off; sector_t sec; struct exfat_sb_info *sbi = EXFAT_SB(sb); - struct exfat_dentry *ep; - int num_entries; - enum exfat_validate_dentry_mode mode = ES_MODE_STARTED; struct buffer_head *bh; if (p_dir->dir == DIR_DELETED) { @@ -880,12 +876,16 @@ int exfat_get_dentry_set(struct exfat_entry_set_cache *es, return -EIO; es->bh[es->num_bh++] = bh; - ep = exfat_get_dentry_cached(es, ES_IDX_FILE); - if (!exfat_validate_entry(exfat_get_entry_type(ep), &mode)) - goto put_es; + if (num_entries == ES_ALL_ENTRIES) { + struct exfat_dentry *ep; + + ep = exfat_get_dentry_cached(es, ES_IDX_FILE); + if (ep->type == EXFAT_FILE) + num_entries = ep->dentry.file.num_ext + 1; + else + goto put_es; + } - num_entries = type == ES_ALL_ENTRIES ? - ep->dentry.file.num_ext + 1 : type; es->num_entries = num_entries; num_bh = EXFAT_B_TO_BLK_ROUND_UP(off + num_entries * DENTRY_SIZE, sb); @@ -918,8 +918,27 @@ int exfat_get_dentry_set(struct exfat_entry_set_cache *es, es->bh[es->num_bh++] = bh; } + return 0; + +put_es: + exfat_put_dentry_set(es, false); + return -EIO; +} + +int exfat_get_dentry_set(struct exfat_entry_set_cache *es, + struct super_block *sb, struct exfat_chain *p_dir, + int entry, unsigned int type) +{ + int ret, i; + struct exfat_dentry *ep; + enum exfat_validate_dentry_mode mode = ES_MODE_GET_FILE_ENTRY; + + ret = __exfat_get_dentry_set(es, sb, p_dir, entry, type); + if (ret < 0) + return ret; + /* validate cached dentries */ - for (i = ES_IDX_STREAM; i < num_entries; i++) { + for (i = ES_IDX_STREAM; i < es->num_entries; i++) { ep = exfat_get_dentry_cached(es, i); if (!exfat_validate_entry(exfat_get_entry_type(ep), &mode)) goto put_es;