11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * linux/fs/minix/dir.c 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1991, 1992 Linus Torvalds 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * minix directory handling functions 7939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer * 8939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer * Updated to filesystem version 3 by Daniel Aragones 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "minix.h" 124a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin#include <linux/buffer_head.h> 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/highmem.h> 144a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin#include <linux/swap.h> 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstypedef struct minix_dir_entry minix_dirent; 17939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwertypedef struct minix3_dir_entry minix3_dirent; 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int minix_readdir(struct file *, void *, filldir_t); 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 214b6f5d20b04dcbc3d888555522b90ba6d36c4106Arjan van de Venconst struct file_operations minix_dir_operations = { 22cc46759a8c0ac4c6f13aa4b0f470305c05f600e1Al Viro .llseek = generic_file_llseek, 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read = generic_read_dir, 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .readdir = minix_readdir, 251b061d9247f71cd15edc4c4c4600191a903642c0Christoph Hellwig .fsync = generic_file_fsync, 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void dir_put_page(struct page *page) 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kunmap(page); 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds page_cache_release(page); 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Return the offset into page `page_nr' of the last valid 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte in that page, plus one. 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsminix_last_byte(struct inode *inode, unsigned long page_nr) 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned last_byte = PAGE_CACHE_SIZE; 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (page_nr == (inode->i_size >> PAGE_CACHE_SHIFT)) 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds last_byte = inode->i_size & (PAGE_CACHE_SIZE - 1); 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return last_byte; 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline unsigned long dir_pages(struct inode *inode) 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT; 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 534a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Pigginstatic int dir_commit_chunk(struct page *page, loff_t pos, unsigned len) 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 554a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin struct address_space *mapping = page->mapping; 564a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin struct inode *dir = mapping->host; 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err = 0; 584a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin block_write_end(NULL, mapping, pos, len, len, page, NULL); 594a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin 604a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin if (pos+len > dir->i_size) { 614a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin i_size_write(dir, pos+len); 624a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin mark_inode_dirty(dir); 634a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin } 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (IS_DIRSYNC(dir)) 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = write_one_page(page, 1); 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unlock_page(page); 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct page * dir_get_page(struct inode *dir, unsigned long n) 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct address_space *mapping = dir->i_mapping; 74090d2b185d8680fc26a2eaf4245d4171dcf4baf1Pekka Enberg struct page *page = read_mapping_page(mapping, n, NULL); 7549837a80b38b79a7c06217b2c40842aeb6fa13b9Al Viro if (!IS_ERR(page)) 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kmap(page); 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return page; 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void *minix_next_entry(void *de, struct minix_sb_info *sbi) 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (void*)((char*)de + sbi->s_dirsize); 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int minix_readdir(struct file * filp, void * dirent, filldir_t filldir) 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long pos = filp->f_pos; 88dcf258ae682c2dbbe1a34624f2b3f56353d3874dJosef Sipek struct inode *inode = filp->f_path.dentry->d_inode; 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct super_block *sb = inode->i_sb; 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned offset = pos & ~PAGE_CACHE_MASK; 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long n = pos >> PAGE_CACHE_SHIFT; 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long npages = dir_pages(inode); 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct minix_sb_info *sbi = minix_sb(sb); 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned chunk_size = sbi->s_dirsize; 95939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer char *name; 96939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer __u32 inumber; 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pos = (pos + chunk_size-1) & ~(chunk_size-1); 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pos >= inode->i_size) 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto done; 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for ( ; n < npages; n++, offset = 0) { 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *p, *kaddr, *limit; 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct page *page = dir_get_page(inode, n); 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (IS_ERR(page)) 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kaddr = (char *)page_address(page); 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p = kaddr+offset; 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds limit = kaddr + minix_last_byte(inode, n) - chunk_size; 111939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer for ( ; p <= limit; p = minix_next_entry(p, sbi)) { 112939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer if (sbi->s_version == MINIX_V3) { 113939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer minix3_dirent *de3 = (minix3_dirent *)p; 114939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer name = de3->name; 115939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer inumber = de3->inode; 116939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer } else { 117939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer minix_dirent *de = (minix_dirent *)p; 118939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer name = de->name; 119939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer inumber = de->inode; 120939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer } 121939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer if (inumber) { 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int over; 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 124939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer unsigned l = strnlen(name, sbi->s_namelen); 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds offset = p - kaddr; 126939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer over = filldir(dirent, name, l, 127939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer (n << PAGE_CACHE_SHIFT) | offset, 128939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer inumber, DT_UNKNOWN); 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (over) { 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dir_put_page(page); 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto done; 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dir_put_page(page); 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsdone: 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset; 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline int namecompare(int len, int maxlen, 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const char * name, const char * buffer) 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (len < maxlen && buffer[len]) 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return !memcmp(name, buffer, len); 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * minix_find_entry() 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * finds an entry in the specified directory with the wanted name. It 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * returns the cache buffer in which the entry was found, and the entry 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * itself (as a parameter - res_dir). It does NOT read the inode of the 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * entry - you'll have to do that yourself if you want to. 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsminix_dirent *minix_find_entry(struct dentry *dentry, struct page **res_page) 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const char * name = dentry->d_name.name; 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int namelen = dentry->d_name.len; 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct inode * dir = dentry->d_parent->d_inode; 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct super_block * sb = dir->i_sb; 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct minix_sb_info * sbi = minix_sb(sb); 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long n; 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long npages = dir_pages(dir); 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct page *page = NULL; 169939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer char *p; 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 171939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer char *namx; 172939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer __u32 inumber; 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *res_page = NULL; 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (n = 0; n < npages; n++) { 176939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer char *kaddr, *limit; 177939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds page = dir_get_page(dir, n); 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (IS_ERR(page)) 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kaddr = (char*)page_address(page); 183939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer limit = kaddr + minix_last_byte(dir, n) - sbi->s_dirsize; 184939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer for (p = kaddr; p <= limit; p = minix_next_entry(p, sbi)) { 185939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer if (sbi->s_version == MINIX_V3) { 186939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer minix3_dirent *de3 = (minix3_dirent *)p; 187939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer namx = de3->name; 188939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer inumber = de3->inode; 189939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer } else { 190939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer minix_dirent *de = (minix_dirent *)p; 191939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer namx = de->name; 192939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer inumber = de->inode; 193939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer } 194939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer if (!inumber) 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 196939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer if (namecompare(namelen, sbi->s_namelen, name, namx)) 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto found; 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dir_put_page(page); 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsfound: 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *res_page = page; 205939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer return (minix_dirent *)p; 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint minix_add_link(struct dentry *dentry, struct inode *inode) 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct inode *dir = dentry->d_parent->d_inode; 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const char * name = dentry->d_name.name; 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int namelen = dentry->d_name.len; 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct super_block * sb = dir->i_sb; 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct minix_sb_info * sbi = minix_sb(sb); 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct page *page = NULL; 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long npages = dir_pages(dir); 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long n; 218939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer char *kaddr, *p; 219939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer minix_dirent *de; 220939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer minix3_dirent *de3; 2214a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin loff_t pos; 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 223939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer char *namx = NULL; 224939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer __u32 inumber; 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We take care of directory expansion in the same loop 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This code plays outside i_size, so it locks the page 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to protect that region. 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (n = 0; n <= npages; n++) { 232939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer char *limit, *dir_end; 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds page = dir_get_page(dir, n); 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = PTR_ERR(page); 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (IS_ERR(page)) 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lock_page(page); 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kaddr = (char*)page_address(page); 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dir_end = kaddr + minix_last_byte(dir, n); 241939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer limit = kaddr + PAGE_CACHE_SIZE - sbi->s_dirsize; 242939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer for (p = kaddr; p <= limit; p = minix_next_entry(p, sbi)) { 243939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer de = (minix_dirent *)p; 244939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer de3 = (minix3_dirent *)p; 245939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer if (sbi->s_version == MINIX_V3) { 246939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer namx = de3->name; 247939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer inumber = de3->inode; 248939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer } else { 249939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer namx = de->name; 250939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer inumber = de->inode; 251939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer } 252939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer if (p == dir_end) { 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* We hit i_size */ 254939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer if (sbi->s_version == MINIX_V3) 255939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer de3->inode = 0; 256939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer else 257939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer de->inode = 0; 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto got_it; 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 260939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer if (!inumber) 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto got_it; 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = -EEXIST; 263939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer if (namecompare(namelen, sbi->s_namelen, name, namx)) 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_unlock; 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unlock_page(page); 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dir_put_page(page); 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds BUG(); 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsgot_it: 273d6b54841f4ddd836c886d1e6ac381cf309ee98a3Evgeniy Dushistov pos = page_offset(page) + p - (char *)page_address(page); 274f4e420dc423148fba637af1ab618fa8896dfb2d6Christoph Hellwig err = minix_prepare_chunk(page, pos, sbi->s_dirsize); 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (err) 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_unlock; 277939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer memcpy (namx, name, namelen); 278939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer if (sbi->s_version == MINIX_V3) { 279939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer memset (namx + namelen, 0, sbi->s_dirsize - namelen - 4); 280939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer de3->inode = inode->i_ino; 281939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer } else { 282939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer memset (namx + namelen, 0, sbi->s_dirsize - namelen - 2); 283939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer de->inode = inode->i_ino; 284939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer } 2854a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin err = dir_commit_chunk(page, pos, sbi->s_dirsize); 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mark_inode_dirty(dir); 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout_put: 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dir_put_page(page); 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout_unlock: 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unlock_page(page); 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_put; 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint minix_delete_entry(struct minix_dir_entry *de, struct page *page) 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 299f4e420dc423148fba637af1ab618fa8896dfb2d6Christoph Hellwig struct inode *inode = page->mapping->host; 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *kaddr = page_address(page); 3014a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin loff_t pos = page_offset(page) + (char*)de - kaddr; 3029f6c1333938c5d93da8be8f29f3b5469a3c00f95Doug Graham struct minix_sb_info *sbi = minix_sb(inode->i_sb); 3039f6c1333938c5d93da8be8f29f3b5469a3c00f95Doug Graham unsigned len = sbi->s_dirsize; 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lock_page(page); 307f4e420dc423148fba637af1ab618fa8896dfb2d6Christoph Hellwig err = minix_prepare_chunk(page, pos, len); 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (err == 0) { 3099f6c1333938c5d93da8be8f29f3b5469a3c00f95Doug Graham if (sbi->s_version == MINIX_V3) 3109f6c1333938c5d93da8be8f29f3b5469a3c00f95Doug Graham ((minix3_dirent *) de)->inode = 0; 3119f6c1333938c5d93da8be8f29f3b5469a3c00f95Doug Graham else 3129f6c1333938c5d93da8be8f29f3b5469a3c00f95Doug Graham de->inode = 0; 3134a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin err = dir_commit_chunk(page, pos, len); 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unlock_page(page); 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dir_put_page(page); 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mark_inode_dirty(inode); 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint minix_make_empty(struct inode *inode, struct inode *dir) 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 325f4e420dc423148fba637af1ab618fa8896dfb2d6Christoph Hellwig struct page *page = grab_cache_page(inode->i_mapping, 0); 326939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer struct minix_sb_info *sbi = minix_sb(inode->i_sb); 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *kaddr; 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!page) 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 332f4e420dc423148fba637af1ab618fa8896dfb2d6Christoph Hellwig err = minix_prepare_chunk(page, 0, 2 * sbi->s_dirsize); 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (err) { 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unlock_page(page); 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto fail; 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kaddr = kmap_atomic(page, KM_USER0); 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(kaddr, 0, PAGE_CACHE_SIZE); 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 341939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer if (sbi->s_version == MINIX_V3) { 342939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer minix3_dirent *de3 = (minix3_dirent *)kaddr; 343939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer 344939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer de3->inode = inode->i_ino; 345939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer strcpy(de3->name, "."); 346939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer de3 = minix_next_entry(de3, sbi); 347939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer de3->inode = dir->i_ino; 348939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer strcpy(de3->name, ".."); 349939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer } else { 350939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer minix_dirent *de = (minix_dirent *)kaddr; 351939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer 352939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer de->inode = inode->i_ino; 353939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer strcpy(de->name, "."); 354939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer de = minix_next_entry(de, sbi); 355939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer de->inode = dir->i_ino; 356939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer strcpy(de->name, ".."); 357939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer } 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kunmap_atomic(kaddr, KM_USER0); 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = dir_commit_chunk(page, 0, 2 * sbi->s_dirsize); 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsfail: 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds page_cache_release(page); 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * routine to check that the specified directory is empty (for rmdir) 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint minix_empty_dir(struct inode * inode) 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct page *page = NULL; 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long i, npages = dir_pages(inode); 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct minix_sb_info *sbi = minix_sb(inode->i_sb); 374939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer char *name; 375939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer __u32 inumber; 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < npages; i++) { 378939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer char *p, *kaddr, *limit; 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 380939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer page = dir_get_page(inode, i); 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (IS_ERR(page)) 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kaddr = (char *)page_address(page); 385939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer limit = kaddr + minix_last_byte(inode, i) - sbi->s_dirsize; 386939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer for (p = kaddr; p <= limit; p = minix_next_entry(p, sbi)) { 387939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer if (sbi->s_version == MINIX_V3) { 388939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer minix3_dirent *de3 = (minix3_dirent *)p; 389939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer name = de3->name; 390939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer inumber = de3->inode; 391939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer } else { 392939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer minix_dirent *de = (minix_dirent *)p; 393939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer name = de->name; 394939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer inumber = de->inode; 395939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer } 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 397939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer if (inumber != 0) { 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check for . and .. */ 399939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer if (name[0] != '.') 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto not_empty; 401939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer if (!name[1]) { 402939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer if (inumber != inode->i_ino) 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto not_empty; 404939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer } else if (name[1] != '.') 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto not_empty; 406939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer else if (name[2]) 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto not_empty; 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dir_put_page(page); 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsnot_empty: 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dir_put_page(page); 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Releases the page */ 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid minix_set_link(struct minix_dir_entry *de, struct page *page, 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct inode *inode) 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 423f4e420dc423148fba637af1ab618fa8896dfb2d6Christoph Hellwig struct inode *dir = page->mapping->host; 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct minix_sb_info *sbi = minix_sb(dir->i_sb); 4254a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin loff_t pos = page_offset(page) + 4264a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin (char *)de-(char*)page_address(page); 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lock_page(page); 4304a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin 431f4e420dc423148fba637af1ab618fa8896dfb2d6Christoph Hellwig err = minix_prepare_chunk(page, pos, sbi->s_dirsize); 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (err == 0) { 4339f6c1333938c5d93da8be8f29f3b5469a3c00f95Doug Graham if (sbi->s_version == MINIX_V3) 4349f6c1333938c5d93da8be8f29f3b5469a3c00f95Doug Graham ((minix3_dirent *) de)->inode = inode->i_ino; 4359f6c1333938c5d93da8be8f29f3b5469a3c00f95Doug Graham else 4369f6c1333938c5d93da8be8f29f3b5469a3c00f95Doug Graham de->inode = inode->i_ino; 4374a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin err = dir_commit_chunk(page, pos, sbi->s_dirsize); 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unlock_page(page); 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dir_put_page(page); 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mark_inode_dirty(dir); 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct minix_dir_entry * minix_dotdot (struct inode *dir, struct page **p) 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct page *page = dir_get_page(dir, 0); 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct minix_sb_info *sbi = minix_sb(dir->i_sb); 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct minix_dir_entry *de = NULL; 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!IS_ERR(page)) { 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds de = minix_next_entry(page_address(page), sbi); 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *p = page; 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return de; 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsino_t minix_inode_by_name(struct dentry *dentry) 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct page *page; 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct minix_dir_entry *de = minix_find_entry(dentry, &page); 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ino_t res = 0; 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (de) { 4669f6c1333938c5d93da8be8f29f3b5469a3c00f95Doug Graham struct address_space *mapping = page->mapping; 4679f6c1333938c5d93da8be8f29f3b5469a3c00f95Doug Graham struct inode *inode = mapping->host; 4689f6c1333938c5d93da8be8f29f3b5469a3c00f95Doug Graham struct minix_sb_info *sbi = minix_sb(inode->i_sb); 4699f6c1333938c5d93da8be8f29f3b5469a3c00f95Doug Graham 4709f6c1333938c5d93da8be8f29f3b5469a3c00f95Doug Graham if (sbi->s_version == MINIX_V3) 4719f6c1333938c5d93da8be8f29f3b5469a3c00f95Doug Graham res = ((minix3_dirent *) de)->inode; 4729f6c1333938c5d93da8be8f29f3b5469a3c00f95Doug Graham else 4739f6c1333938c5d93da8be8f29f3b5469a3c00f95Doug Graham res = de->inode; 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dir_put_page(page); 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return res; 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 478