cregit-Linux how code gets into the kernel

Release 4.10 fs/minix/dir.c

Directory: fs/minix
/*
 *  linux/fs/minix/dir.c
 *
 *  Copyright (C) 1991, 1992 Linus Torvalds
 *
 *  minix directory handling functions
 *
 *  Updated to filesystem version 3 by Daniel Aragones
 */

#include "minix.h"
#include <linux/buffer_head.h>
#include <linux/highmem.h>
#include <linux/swap.h>


typedef struct minix_dir_entry minix_dirent;

typedef struct minix3_dir_entry minix3_dirent;

static int minix_readdir(struct file *, struct dir_context *);


const struct file_operations minix_dir_operations = {
	.llseek		= generic_file_llseek,
	.read		= generic_read_dir,
	.iterate_shared	= minix_readdir,
	.fsync		= generic_file_fsync,
};


static inline void dir_put_page(struct page *page) { kunmap(page); put_page(page); }

Contributors

PersonTokensPropCommitsCommitProp
linus torvaldslinus torvalds1568.18%133.33%
pre-gitpre-git627.27%133.33%
kirill a. shutemovkirill a. shutemov14.55%133.33%
Total22100.00%3100.00%

/* * Return the offset into page `page_nr' of the last valid * byte in that page, plus one. */
static unsigned minix_last_byte(struct inode *inode, unsigned long page_nr) { unsigned last_byte = PAGE_SIZE; if (page_nr == (inode->i_size >> PAGE_SHIFT)) last_byte = inode->i_size & (PAGE_SIZE - 1); return last_byte; }

Contributors

PersonTokensPropCommitsCommitProp
andrew mortonandrew morton4493.62%150.00%
kirill a. shutemovkirill a. shutemov36.38%150.00%
Total47100.00%2100.00%


static int dir_commit_chunk(struct page *page, loff_t pos, unsigned len) { struct address_space *mapping = page->mapping; struct inode *dir = mapping->host; int err = 0; block_write_end(NULL, mapping, pos, len, len, page, NULL); if (pos+len > dir->i_size) { i_size_write(dir, pos+len); mark_inode_dirty(dir); } if (IS_DIRSYNC(dir)) err = write_one_page(page, 1); else unlock_page(page); return err; }

Contributors

PersonTokensPropCommitsCommitProp
nick pigginnick piggin4743.52%111.11%
linus torvaldslinus torvalds3431.48%111.11%
pre-gitpre-git1715.74%444.44%
andrew mortonandrew morton109.26%333.33%
Total108100.00%9100.00%


static struct page * dir_get_page(struct inode *dir, unsigned long n) { struct address_space *mapping = dir->i_mapping; struct page *page = read_mapping_page(mapping, n, NULL); if (!IS_ERR(page)) kmap(page); return page; }

Contributors

PersonTokensPropCommitsCommitProp
linus torvaldslinus torvalds4682.14%125.00%
pre-gitpre-git916.07%250.00%
pekka j enbergpekka j enberg11.79%125.00%
Total56100.00%4100.00%


static inline void *minix_next_entry(void *de, struct minix_sb_info *sbi) { return (void*)((char*)de + sbi->s_dirsize); }

Contributors

PersonTokensPropCommitsCommitProp
linus torvaldslinus torvalds34100.00%1100.00%
Total34100.00%1100.00%


static int minix_readdir(struct file *file, struct dir_context *ctx) { struct inode *inode = file_inode(file); struct super_block *sb = inode->i_sb; struct minix_sb_info *sbi = minix_sb(sb); unsigned chunk_size = sbi->s_dirsize; unsigned long npages = dir_pages(inode); unsigned long pos = ctx->pos; unsigned offset; unsigned long n; ctx->pos = pos = ALIGN(pos, chunk_size); if (pos >= inode->i_size) return 0; offset = pos & ~PAGE_MASK; n = pos >> PAGE_SHIFT; for ( ; n < npages; n++, offset = 0) { char *p, *kaddr, *limit; struct page *page = dir_get_page(inode, n); if (IS_ERR(page)) continue; kaddr = (char *)page_address(page); p = kaddr+offset; limit = kaddr + minix_last_byte(inode, n) - chunk_size; for ( ; p <= limit; p = minix_next_entry(p, sbi)) { const char *name; __u32 inumber; if (sbi->s_version == MINIX_V3) { minix3_dirent *de3 = (minix3_dirent *)p; name = de3->name; inumber = de3->inode; } else { minix_dirent *de = (minix_dirent *)p; name = de->name; inumber = de->inode; } if (inumber) { unsigned l = strnlen(name, sbi->s_namelen); if (!dir_emit(ctx, name, l, inumber, DT_UNKNOWN)) { dir_put_page(page); return 0; } } ctx->pos += chunk_size; } dir_put_page(page); } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
linus torvaldslinus torvalds19960.30%114.29%
al viroal viro6920.91%228.57%
andries brouwerandries brouwer5015.15%114.29%
andrew mortonandrew morton61.82%114.29%
dan carpenterdan carpenter41.21%114.29%
kirill a. shutemovkirill a. shutemov20.61%114.29%
Total330100.00%7100.00%


static inline int namecompare(int len, int maxlen, const char * name, const char * buffer) { if (len < maxlen && buffer[len]) return 0; return !memcmp(name, buffer, len); }

Contributors

PersonTokensPropCommitsCommitProp
linus torvaldslinus torvalds48100.00%1100.00%
Total48100.00%1100.00%

/* * minix_find_entry() * * finds an entry in the specified directory with the wanted name. It * returns the cache buffer in which the entry was found, and the entry * itself (as a parameter - res_dir). It does NOT read the inode of the * entry - you'll have to do that yourself if you want to. */
minix_dirent *minix_find_entry(struct dentry *dentry, struct page **res_page) { const char * name = dentry->d_name.name; int namelen = dentry->d_name.len; struct inode * dir = d_inode(dentry->d_parent); struct super_block * sb = dir->i_sb; struct minix_sb_info * sbi = minix_sb(sb); unsigned long n; unsigned long npages = dir_pages(dir); struct page *page = NULL; char *p; char *namx; __u32 inumber; *res_page = NULL; for (n = 0; n < npages; n++) { char *kaddr, *limit; page = dir_get_page(dir, n); if (IS_ERR(page)) continue; kaddr = (char*)page_address(page); limit = kaddr + minix_last_byte(dir, n) - sbi->s_dirsize; for (p = kaddr; p <= limit; p = minix_next_entry(p, sbi)) { if (sbi->s_version == MINIX_V3) { minix3_dirent *de3 = (minix3_dirent *)p; namx = de3->name; inumber = de3->inode; } else { minix_dirent *de = (minix_dirent *)p; namx = de->name; inumber = de->inode; } if (!inumber) continue; if (namecompare(namelen, sbi->s_namelen, name, namx)) goto found; } dir_put_page(page); } return NULL; found: *res_page = page; return (minix_dirent *)p; }

Contributors

PersonTokensPropCommitsCommitProp
linus torvaldslinus torvalds19867.58%120.00%
andries brouwerandries brouwer8328.33%120.00%
andrew mortonandrew morton62.05%120.00%
brian gerstbrian gerst31.02%120.00%
david howellsdavid howells31.02%120.00%
Total293100.00%5100.00%


int minix_add_link(struct dentry *dentry, struct inode *inode) { struct inode *dir = d_inode(dentry->d_parent); const char * name = dentry->d_name.name; int namelen = dentry->d_name.len; struct super_block * sb = dir->i_sb; struct minix_sb_info * sbi = minix_sb(sb); struct page *page = NULL; unsigned long npages = dir_pages(dir); unsigned long n; char *kaddr, *p; minix_dirent *de; minix3_dirent *de3; loff_t pos; int err; char *namx = NULL; __u32 inumber; /* * We take care of directory expansion in the same loop * This code plays outside i_size, so it locks the page * to protect that region. */ for (n = 0; n <= npages; n++) { char *limit, *dir_end; page = dir_get_page(dir, n); err = PTR_ERR(page); if (IS_ERR(page)) goto out; lock_page(page); kaddr = (char*)page_address(page); dir_end = kaddr + minix_last_byte(dir, n); limit = kaddr + PAGE_SIZE - sbi->s_dirsize; for (p = kaddr; p <= limit; p = minix_next_entry(p, sbi)) { de = (minix_dirent *)p; de3 = (minix3_dirent *)p; if (sbi->s_version == MINIX_V3) { namx = de3->name; inumber = de3->inode; } else { namx = de->name; inumber = de->inode; } if (p == dir_end) { /* We hit i_size */ if (sbi->s_version == MINIX_V3) de3->inode = 0; else de->inode = 0; goto got_it; } if (!inumber) goto got_it; err = -EEXIST; if (namecompare(namelen, sbi->s_namelen, name, namx)) goto out_unlock; } unlock_page(page); dir_put_page(page); } BUG(); return -EINVAL; got_it: pos = page_offset(page) + p - (char *)page_address(page); err = minix_prepare_chunk(page, pos, sbi->s_dirsize); if (err) goto out_unlock; memcpy (namx, name, namelen); if (sbi->s_version == MINIX_V3) { memset (namx + namelen, 0, sbi->s_dirsize - namelen - 4); de3->inode = inode->i_ino; } else { memset (namx + namelen, 0, sbi->s_dirsize - namelen - 2); de->inode = inode->i_ino; } err = dir_commit_chunk(page, pos, sbi->s_dirsize); dir->i_mtime = dir->i_ctime = current_time(dir); mark_inode_dirty(dir); out_put: dir_put_page(page); out: return err; out_unlock: unlock_page(page); goto out_put; }

Contributors

PersonTokensPropCommitsCommitProp
linus torvaldslinus torvalds28254.02%19.09%
andries brouwerandries brouwer15128.93%19.09%
andrew mortonandrew morton5911.30%218.18%
nick pigginnick piggin152.87%19.09%
deepa dinamanideepa dinamani40.77%19.09%
evgeniy dushistovevgeniy dushistov30.57%19.09%
brian gerstbrian gerst30.57%19.09%
david howellsdavid howells30.57%19.09%
christoph hellwigchristoph hellwig10.19%19.09%
kirill a. shutemovkirill a. shutemov10.19%19.09%
Total522100.00%11100.00%


int minix_delete_entry(struct minix_dir_entry *de, struct page *page) { struct inode *inode = page->mapping->host; char *kaddr = page_address(page); loff_t pos = page_offset(page) + (char*)de - kaddr; struct minix_sb_info *sbi = minix_sb(inode->i_sb); unsigned len = sbi->s_dirsize; int err; lock_page(page); err = minix_prepare_chunk(page, pos, len); if (err == 0) { if (sbi->s_version == MINIX_V3) ((minix3_dirent *) de)->inode = 0; else de->inode = 0; err = dir_commit_chunk(page, pos, len); } else { unlock_page(page); } dir_put_page(page); inode->i_ctime = inode->i_mtime = current_time(inode); mark_inode_dirty(inode); return err; }

Contributors

PersonTokensPropCommitsCommitProp
linus torvaldslinus torvalds10863.91%111.11%
doug grahamdoug graham3017.75%111.11%
nick pigginnick piggin127.10%111.11%
andrew mortonandrew morton84.73%333.33%
christoph hellwigchristoph hellwig42.37%111.11%
deepa dinamanideepa dinamani42.37%111.11%
brian gerstbrian gerst31.78%111.11%
Total169100.00%9100.00%


int minix_make_empty(struct inode *inode, struct inode *dir) { struct page *page = grab_cache_page(inode->i_mapping, 0); struct minix_sb_info *sbi = minix_sb(inode->i_sb); char *kaddr; int err; if (!page) return -ENOMEM; err = minix_prepare_chunk(page, 0, 2 * sbi->s_dirsize); if (err) { unlock_page(page); goto fail; } kaddr = kmap_atomic(page); memset(kaddr, 0, PAGE_SIZE); if (sbi->s_version == MINIX_V3) { minix3_dirent *de3 = (minix3_dirent *)kaddr; de3->inode = inode->i_ino; strcpy(de3->name, "."); de3 = minix_next_entry(de3, sbi); de3->inode = dir->i_ino; strcpy(de3->name, ".."); } else { minix_dirent *de = (minix_dirent *)kaddr; de->inode = inode->i_ino; strcpy(de->name, "."); de = minix_next_entry(de, sbi); de->inode = dir->i_ino; strcpy(de->name, ".."); } kunmap_atomic(kaddr); err = dir_commit_chunk(page, 0, 2 * sbi->s_dirsize); fail: put_page(page); return err; }

Contributors

PersonTokensPropCommitsCommitProp
linus torvaldslinus torvalds15360.96%114.29%
andries brouwerandries brouwer7128.29%114.29%
andrew mortonandrew morton176.77%228.57%
christoph hellwigchristoph hellwig51.99%114.29%
brian gerstbrian gerst31.20%114.29%
kirill a. shutemovkirill a. shutemov20.80%114.29%
Total251100.00%7100.00%

/* * routine to check that the specified directory is empty (for rmdir) */
int minix_empty_dir(struct inode * inode) { struct page *page = NULL; unsigned long i, npages = dir_pages(inode); struct minix_sb_info *sbi = minix_sb(inode->i_sb); char *name; __u32 inumber; for (i = 0; i < npages; i++) { char *p, *kaddr, *limit; page = dir_get_page(inode, i); if (IS_ERR(page)) continue; kaddr = (char *)page_address(page); limit = kaddr + minix_last_byte(inode, i) - sbi->s_dirsize; for (p = kaddr; p <= limit; p = minix_next_entry(p, sbi)) { if (sbi->s_version == MINIX_V3) { minix3_dirent *de3 = (minix3_dirent *)p; name = de3->name; inumber = de3->inode; } else { minix_dirent *de = (minix_dirent *)p; name = de->name; inumber = de->inode; } if (inumber != 0) { /* check for . and .. */ if (name[0] != '.') goto not_empty; if (!name[1]) { if (inumber != inode->i_ino) goto not_empty; } else if (name[1] != '.') goto not_empty; else if (name[2]) goto not_empty; } } dir_put_page(page); } return 1; not_empty: dir_put_page(page); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
linus torvaldslinus torvalds18165.34%125.00%
andries brouwerandries brouwer8731.41%125.00%
andrew mortonandrew morton62.17%125.00%
brian gerstbrian gerst31.08%125.00%
Total277100.00%4100.00%

/* Releases the page */
void minix_set_link(struct minix_dir_entry *de, struct page *page, struct inode *inode) { struct inode *dir = page->mapping->host; struct minix_sb_info *sbi = minix_sb(dir->i_sb); loff_t pos = page_offset(page) + (char *)de-(char*)page_address(page); int err; lock_page(page); err = minix_prepare_chunk(page, pos, sbi->s_dirsize); if (err == 0) { if (sbi->s_version == MINIX_V3) ((minix3_dirent *) de)->inode = inode->i_ino; else de->inode = inode->i_ino; err = dir_commit_chunk(page, pos, sbi->s_dirsize); } else { unlock_page(page); } dir_put_page(page); dir->i_mtime = dir->i_ctime = current_time(dir); mark_inode_dirty(dir); }

Contributors

PersonTokensPropCommitsCommitProp
linus torvaldslinus torvalds10863.53%111.11%
doug grahamdoug graham2313.53%111.11%
nick pigginnick piggin2011.76%111.11%
andrew mortonandrew morton84.71%333.33%
christoph hellwigchristoph hellwig42.35%111.11%
deepa dinamanideepa dinamani42.35%111.11%
brian gerstbrian gerst31.76%111.11%
Total170100.00%9100.00%


struct minix_dir_entry * minix_dotdot (struct inode *dir, struct page **p) { struct page *page = dir_get_page(dir, 0); struct minix_sb_info *sbi = minix_sb(dir->i_sb); struct minix_dir_entry *de = NULL; if (!IS_ERR(page)) { de = minix_next_entry(page_address(page), sbi); *p = page; } return de; }

Contributors

PersonTokensPropCommitsCommitProp
linus torvaldslinus torvalds7291.14%125.00%
pre-gitpre-git45.06%250.00%
brian gerstbrian gerst33.80%125.00%
Total79100.00%4100.00%


ino_t minix_inode_by_name(struct dentry *dentry) { struct page *page; struct minix_dir_entry *de = minix_find_entry(dentry, &page); ino_t res = 0; if (de) { struct address_space *mapping = page->mapping; struct inode *inode = mapping->host; struct minix_sb_info *sbi = minix_sb(inode->i_sb); if (sbi->s_version == MINIX_V3) res = ((minix3_dirent *) de)->inode; else res = de->inode; dir_put_page(page); } return res; }

Contributors

PersonTokensPropCommitsCommitProp
doug grahamdoug graham5149.04%125.00%
linus torvaldslinus torvalds5048.08%125.00%
pre-gitpre-git32.88%250.00%
Total104100.00%4100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
linus torvaldslinus torvalds153659.60%12.86%
andries brouwerandries brouwer44817.38%12.86%
andrew mortonandrew morton1686.52%617.14%
doug grahamdoug graham1044.04%12.86%
nick pigginnick piggin983.80%12.86%
al viroal viro783.03%514.29%
pre-gitpre-git652.52%822.86%
brian gerstbrian gerst210.81%12.86%
christoph hellwigchristoph hellwig150.58%25.71%
deepa dinamanideepa dinamani120.47%12.86%
kirill a. shutemovkirill a. shutemov90.35%12.86%
david howellsdavid howells60.23%12.86%
art haasart haas60.23%12.86%
dan carpenterdan carpenter40.16%12.86%
evgeniy dushistovevgeniy dushistov30.12%12.86%
dave hansendave hansen20.08%12.86%
arjan van de venarjan van de ven10.04%12.86%
pekka j enbergpekka j enberg10.04%12.86%
Total2577100.00%35100.00%
Directory: fs/minix
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.