1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds * fs/bfs/dir.c
41da177e4SLinus Torvalds * BFS directory operations.
5d1877155STigran Aivazian * Copyright (C) 1999-2018 Tigran Aivazian <aivazian.tigran@gmail.com>
6fac92becSAndrew Stribblehill * Made endianness-clean by Andrew Stribblehill <ads@wompom.org> 2005
71da177e4SLinus Torvalds */
81da177e4SLinus Torvalds
91da177e4SLinus Torvalds #include <linux/time.h>
101da177e4SLinus Torvalds #include <linux/string.h>
111da177e4SLinus Torvalds #include <linux/fs.h>
121da177e4SLinus Torvalds #include <linux/buffer_head.h>
131da177e4SLinus Torvalds #include <linux/sched.h>
141da177e4SLinus Torvalds #include "bfs.h"
151da177e4SLinus Torvalds
161da177e4SLinus Torvalds #undef DEBUG
171da177e4SLinus Torvalds
181da177e4SLinus Torvalds #ifdef DEBUG
191da177e4SLinus Torvalds #define dprintf(x...) printf(x)
201da177e4SLinus Torvalds #else
211da177e4SLinus Torvalds #define dprintf(x...)
221da177e4SLinus Torvalds #endif
231da177e4SLinus Torvalds
24b455ecd4SAl Viro static int bfs_add_entry(struct inode *dir, const struct qstr *child, int ino);
251da177e4SLinus Torvalds static struct buffer_head *bfs_find_entry(struct inode *dir,
2633ebdebeSAl Viro const struct qstr *child,
27f433dc56SDmitri Vorobiev struct bfs_dirent **res_dir);
281da177e4SLinus Torvalds
bfs_readdir(struct file * f,struct dir_context * ctx)2981b9f66eSAl Viro static int bfs_readdir(struct file *f, struct dir_context *ctx)
301da177e4SLinus Torvalds {
31496ad9aaSAl Viro struct inode *dir = file_inode(f);
321da177e4SLinus Torvalds struct buffer_head *bh;
331da177e4SLinus Torvalds struct bfs_dirent *de;
341da177e4SLinus Torvalds unsigned int offset;
351da177e4SLinus Torvalds int block;
361da177e4SLinus Torvalds
3781b9f66eSAl Viro if (ctx->pos & (BFS_DIRENT_SIZE - 1)) {
38f433dc56SDmitri Vorobiev printf("Bad f_pos=%08lx for %s:%08lx\n",
3981b9f66eSAl Viro (unsigned long)ctx->pos,
401da177e4SLinus Torvalds dir->i_sb->s_id, dir->i_ino);
4181b9f66eSAl Viro return -EINVAL;
421da177e4SLinus Torvalds }
431da177e4SLinus Torvalds
4481b9f66eSAl Viro while (ctx->pos < dir->i_size) {
4581b9f66eSAl Viro offset = ctx->pos & (BFS_BSIZE - 1);
4681b9f66eSAl Viro block = BFS_I(dir)->i_sblock + (ctx->pos >> BFS_BSIZE_BITS);
471da177e4SLinus Torvalds bh = sb_bread(dir->i_sb, block);
481da177e4SLinus Torvalds if (!bh) {
4981b9f66eSAl Viro ctx->pos += BFS_BSIZE - offset;
501da177e4SLinus Torvalds continue;
511da177e4SLinus Torvalds }
521da177e4SLinus Torvalds do {
531da177e4SLinus Torvalds de = (struct bfs_dirent *)(bh->b_data + offset);
541da177e4SLinus Torvalds if (de->ino) {
551da177e4SLinus Torvalds int size = strnlen(de->name, BFS_NAMELEN);
5681b9f66eSAl Viro if (!dir_emit(ctx, de->name, size,
57f433dc56SDmitri Vorobiev le16_to_cpu(de->ino),
5881b9f66eSAl Viro DT_UNKNOWN)) {
591da177e4SLinus Torvalds brelse(bh);
601da177e4SLinus Torvalds return 0;
611da177e4SLinus Torvalds }
621da177e4SLinus Torvalds }
631da177e4SLinus Torvalds offset += BFS_DIRENT_SIZE;
6481b9f66eSAl Viro ctx->pos += BFS_DIRENT_SIZE;
6581b9f66eSAl Viro } while ((offset < BFS_BSIZE) && (ctx->pos < dir->i_size));
661da177e4SLinus Torvalds brelse(bh);
671da177e4SLinus Torvalds }
681da177e4SLinus Torvalds return 0;
691da177e4SLinus Torvalds }
701da177e4SLinus Torvalds
714b6f5d20SArjan van de Ven const struct file_operations bfs_dir_operations = {
721da177e4SLinus Torvalds .read = generic_read_dir,
73c51da20cSAl Viro .iterate_shared = bfs_readdir,
741b061d92SChristoph Hellwig .fsync = generic_file_fsync,
753222a3e5SChristoph Hellwig .llseek = generic_file_llseek,
761da177e4SLinus Torvalds };
771da177e4SLinus Torvalds
bfs_create(struct mnt_idmap * idmap,struct inode * dir,struct dentry * dentry,umode_t mode,bool excl)786c960e68SChristian Brauner static int bfs_create(struct mnt_idmap *idmap, struct inode *dir,
79549c7297SChristian Brauner struct dentry *dentry, umode_t mode, bool excl)
801da177e4SLinus Torvalds {
811da177e4SLinus Torvalds int err;
821da177e4SLinus Torvalds struct inode *inode;
831da177e4SLinus Torvalds struct super_block *s = dir->i_sb;
841da177e4SLinus Torvalds struct bfs_sb_info *info = BFS_SB(s);
851da177e4SLinus Torvalds unsigned long ino;
861da177e4SLinus Torvalds
871da177e4SLinus Torvalds inode = new_inode(s);
881da177e4SLinus Torvalds if (!inode)
89c3fe5872SSanidhya Kashyap return -ENOMEM;
903f165e4cSDmitri Vorobiev mutex_lock(&info->bfs_lock);
9169b195beSAkinobu Mita ino = find_first_zero_bit(info->si_imap, info->si_lasti + 1);
921da177e4SLinus Torvalds if (ino > info->si_lasti) {
933f165e4cSDmitri Vorobiev mutex_unlock(&info->bfs_lock);
941da177e4SLinus Torvalds iput(inode);
951da177e4SLinus Torvalds return -ENOSPC;
961da177e4SLinus Torvalds }
971da177e4SLinus Torvalds set_bit(ino, info->si_imap);
981da177e4SLinus Torvalds info->si_freei--;
99f2d40141SChristian Brauner inode_init_owner(&nop_mnt_idmap, inode, dir, mode);
100*73d9b9d0SJeff Layton inode->i_mtime = inode->i_atime = inode_set_ctime_current(inode);
101ba52de12STheodore Ts'o inode->i_blocks = 0;
1021da177e4SLinus Torvalds inode->i_op = &bfs_file_inops;
1031da177e4SLinus Torvalds inode->i_fop = &bfs_file_operations;
1041da177e4SLinus Torvalds inode->i_mapping->a_ops = &bfs_aops;
1051da177e4SLinus Torvalds inode->i_ino = ino;
106ce0fe7e7SAlexey Dobriyan BFS_I(inode)->i_dsk_ino = ino;
1071da177e4SLinus Torvalds BFS_I(inode)->i_sblock = 0;
1081da177e4SLinus Torvalds BFS_I(inode)->i_eblock = 0;
1091da177e4SLinus Torvalds insert_inode_hash(inode);
1101da177e4SLinus Torvalds mark_inode_dirty(inode);
1111da85fdfSFabian Frederick bfs_dump_imap("create", s);
1121da177e4SLinus Torvalds
113b455ecd4SAl Viro err = bfs_add_entry(dir, &dentry->d_name, inode->i_ino);
1141da177e4SLinus Torvalds if (err) {
1159a53c3a7SDave Hansen inode_dec_link_count(inode);
1163f165e4cSDmitri Vorobiev mutex_unlock(&info->bfs_lock);
1171558182fSEric Sesterhenn iput(inode);
1181da177e4SLinus Torvalds return err;
1191da177e4SLinus Torvalds }
1203f165e4cSDmitri Vorobiev mutex_unlock(&info->bfs_lock);
1211da177e4SLinus Torvalds d_instantiate(dentry, inode);
1221da177e4SLinus Torvalds return 0;
1231da177e4SLinus Torvalds }
1241da177e4SLinus Torvalds
bfs_lookup(struct inode * dir,struct dentry * dentry,unsigned int flags)125f433dc56SDmitri Vorobiev static struct dentry *bfs_lookup(struct inode *dir, struct dentry *dentry,
12600cd8dd3SAl Viro unsigned int flags)
1271da177e4SLinus Torvalds {
1281da177e4SLinus Torvalds struct inode *inode = NULL;
1291da177e4SLinus Torvalds struct buffer_head *bh;
1301da177e4SLinus Torvalds struct bfs_dirent *de;
1313f165e4cSDmitri Vorobiev struct bfs_sb_info *info = BFS_SB(dir->i_sb);
1321da177e4SLinus Torvalds
1331da177e4SLinus Torvalds if (dentry->d_name.len > BFS_NAMELEN)
1341da177e4SLinus Torvalds return ERR_PTR(-ENAMETOOLONG);
1351da177e4SLinus Torvalds
1363f165e4cSDmitri Vorobiev mutex_lock(&info->bfs_lock);
13733ebdebeSAl Viro bh = bfs_find_entry(dir, &dentry->d_name, &de);
1381da177e4SLinus Torvalds if (bh) {
139fac92becSAndrew Stribblehill unsigned long ino = (unsigned long)le16_to_cpu(de->ino);
1401da177e4SLinus Torvalds brelse(bh);
141e33ab086SDavid Howells inode = bfs_iget(dir->i_sb, ino);
1421da177e4SLinus Torvalds }
1433f165e4cSDmitri Vorobiev mutex_unlock(&info->bfs_lock);
144a596a23bSAl Viro return d_splice_alias(inode, dentry);
1451da177e4SLinus Torvalds }
1461da177e4SLinus Torvalds
bfs_link(struct dentry * old,struct inode * dir,struct dentry * new)147f433dc56SDmitri Vorobiev static int bfs_link(struct dentry *old, struct inode *dir,
148f433dc56SDmitri Vorobiev struct dentry *new)
1491da177e4SLinus Torvalds {
1502b0143b5SDavid Howells struct inode *inode = d_inode(old);
1513f165e4cSDmitri Vorobiev struct bfs_sb_info *info = BFS_SB(inode->i_sb);
1521da177e4SLinus Torvalds int err;
1531da177e4SLinus Torvalds
1543f165e4cSDmitri Vorobiev mutex_lock(&info->bfs_lock);
155b455ecd4SAl Viro err = bfs_add_entry(dir, &new->d_name, inode->i_ino);
1561da177e4SLinus Torvalds if (err) {
1573f165e4cSDmitri Vorobiev mutex_unlock(&info->bfs_lock);
1581da177e4SLinus Torvalds return err;
1591da177e4SLinus Torvalds }
160d8c76e6fSDave Hansen inc_nlink(inode);
161*73d9b9d0SJeff Layton inode_set_ctime_current(inode);
1621da177e4SLinus Torvalds mark_inode_dirty(inode);
1637de9c6eeSAl Viro ihold(inode);
1641da177e4SLinus Torvalds d_instantiate(new, inode);
1653f165e4cSDmitri Vorobiev mutex_unlock(&info->bfs_lock);
1661da177e4SLinus Torvalds return 0;
1671da177e4SLinus Torvalds }
1681da177e4SLinus Torvalds
bfs_unlink(struct inode * dir,struct dentry * dentry)1691da177e4SLinus Torvalds static int bfs_unlink(struct inode *dir, struct dentry *dentry)
1701da177e4SLinus Torvalds {
1711da177e4SLinus Torvalds int error = -ENOENT;
1722b0143b5SDavid Howells struct inode *inode = d_inode(dentry);
1731da177e4SLinus Torvalds struct buffer_head *bh;
1741da177e4SLinus Torvalds struct bfs_dirent *de;
1753f165e4cSDmitri Vorobiev struct bfs_sb_info *info = BFS_SB(inode->i_sb);
1761da177e4SLinus Torvalds
1773f165e4cSDmitri Vorobiev mutex_lock(&info->bfs_lock);
17833ebdebeSAl Viro bh = bfs_find_entry(dir, &dentry->d_name, &de);
179f433dc56SDmitri Vorobiev if (!bh || (le16_to_cpu(de->ino) != inode->i_ino))
1801da177e4SLinus Torvalds goto out_brelse;
1811da177e4SLinus Torvalds
1821da177e4SLinus Torvalds if (!inode->i_nlink) {
183f433dc56SDmitri Vorobiev printf("unlinking non-existent file %s:%lu (nlink=%d)\n",
184f433dc56SDmitri Vorobiev inode->i_sb->s_id, inode->i_ino,
185f433dc56SDmitri Vorobiev inode->i_nlink);
186bfe86848SMiklos Szeredi set_nlink(inode, 1);
1871da177e4SLinus Torvalds }
1881da177e4SLinus Torvalds de->ino = 0;
1894427f0c3SAl Viro mark_buffer_dirty_inode(bh, dir);
190*73d9b9d0SJeff Layton dir->i_mtime = inode_set_ctime_current(dir);
1911da177e4SLinus Torvalds mark_inode_dirty(dir);
192*73d9b9d0SJeff Layton inode_set_ctime_to_ts(inode, inode_get_ctime(dir));
1939a53c3a7SDave Hansen inode_dec_link_count(inode);
1941da177e4SLinus Torvalds error = 0;
1951da177e4SLinus Torvalds
1961da177e4SLinus Torvalds out_brelse:
1971da177e4SLinus Torvalds brelse(bh);
1983f165e4cSDmitri Vorobiev mutex_unlock(&info->bfs_lock);
1991da177e4SLinus Torvalds return error;
2001da177e4SLinus Torvalds }
2011da177e4SLinus Torvalds
bfs_rename(struct mnt_idmap * idmap,struct inode * old_dir,struct dentry * old_dentry,struct inode * new_dir,struct dentry * new_dentry,unsigned int flags)202e18275aeSChristian Brauner static int bfs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
203549c7297SChristian Brauner struct dentry *old_dentry, struct inode *new_dir,
204549c7297SChristian Brauner struct dentry *new_dentry, unsigned int flags)
2051da177e4SLinus Torvalds {
2061da177e4SLinus Torvalds struct inode *old_inode, *new_inode;
2071da177e4SLinus Torvalds struct buffer_head *old_bh, *new_bh;
2081da177e4SLinus Torvalds struct bfs_dirent *old_de, *new_de;
2093f165e4cSDmitri Vorobiev struct bfs_sb_info *info;
2101da177e4SLinus Torvalds int error = -ENOENT;
2111da177e4SLinus Torvalds
212f03b8ad8SMiklos Szeredi if (flags & ~RENAME_NOREPLACE)
213f03b8ad8SMiklos Szeredi return -EINVAL;
214f03b8ad8SMiklos Szeredi
2151da177e4SLinus Torvalds old_bh = new_bh = NULL;
2162b0143b5SDavid Howells old_inode = d_inode(old_dentry);
2171da177e4SLinus Torvalds if (S_ISDIR(old_inode->i_mode))
2181da177e4SLinus Torvalds return -EINVAL;
2191da177e4SLinus Torvalds
2203f165e4cSDmitri Vorobiev info = BFS_SB(old_inode->i_sb);
2213f165e4cSDmitri Vorobiev
2223f165e4cSDmitri Vorobiev mutex_lock(&info->bfs_lock);
22333ebdebeSAl Viro old_bh = bfs_find_entry(old_dir, &old_dentry->d_name, &old_de);
2241da177e4SLinus Torvalds
225f433dc56SDmitri Vorobiev if (!old_bh || (le16_to_cpu(old_de->ino) != old_inode->i_ino))
2261da177e4SLinus Torvalds goto end_rename;
2271da177e4SLinus Torvalds
2281da177e4SLinus Torvalds error = -EPERM;
2292b0143b5SDavid Howells new_inode = d_inode(new_dentry);
23033ebdebeSAl Viro new_bh = bfs_find_entry(new_dir, &new_dentry->d_name, &new_de);
2311da177e4SLinus Torvalds
2321da177e4SLinus Torvalds if (new_bh && !new_inode) {
2331da177e4SLinus Torvalds brelse(new_bh);
2341da177e4SLinus Torvalds new_bh = NULL;
2351da177e4SLinus Torvalds }
2361da177e4SLinus Torvalds if (!new_bh) {
237b455ecd4SAl Viro error = bfs_add_entry(new_dir, &new_dentry->d_name,
238f433dc56SDmitri Vorobiev old_inode->i_ino);
2391da177e4SLinus Torvalds if (error)
2401da177e4SLinus Torvalds goto end_rename;
2411da177e4SLinus Torvalds }
2421da177e4SLinus Torvalds old_de->ino = 0;
243*73d9b9d0SJeff Layton old_dir->i_mtime = inode_set_ctime_current(old_dir);
2441da177e4SLinus Torvalds mark_inode_dirty(old_dir);
2451da177e4SLinus Torvalds if (new_inode) {
246*73d9b9d0SJeff Layton inode_set_ctime_current(new_inode);
2479a53c3a7SDave Hansen inode_dec_link_count(new_inode);
2481da177e4SLinus Torvalds }
2494427f0c3SAl Viro mark_buffer_dirty_inode(old_bh, old_dir);
2501da177e4SLinus Torvalds error = 0;
2511da177e4SLinus Torvalds
2521da177e4SLinus Torvalds end_rename:
2533f165e4cSDmitri Vorobiev mutex_unlock(&info->bfs_lock);
2541da177e4SLinus Torvalds brelse(old_bh);
2551da177e4SLinus Torvalds brelse(new_bh);
2561da177e4SLinus Torvalds return error;
2571da177e4SLinus Torvalds }
2581da177e4SLinus Torvalds
259754661f1SArjan van de Ven const struct inode_operations bfs_dir_inops = {
2601da177e4SLinus Torvalds .create = bfs_create,
2611da177e4SLinus Torvalds .lookup = bfs_lookup,
2621da177e4SLinus Torvalds .link = bfs_link,
2631da177e4SLinus Torvalds .unlink = bfs_unlink,
2641da177e4SLinus Torvalds .rename = bfs_rename,
2651da177e4SLinus Torvalds };
2661da177e4SLinus Torvalds
bfs_add_entry(struct inode * dir,const struct qstr * child,int ino)267b455ecd4SAl Viro static int bfs_add_entry(struct inode *dir, const struct qstr *child, int ino)
2681da177e4SLinus Torvalds {
269b455ecd4SAl Viro const unsigned char *name = child->name;
270b455ecd4SAl Viro int namelen = child->len;
2711da177e4SLinus Torvalds struct buffer_head *bh;
2721da177e4SLinus Torvalds struct bfs_dirent *de;
273f433dc56SDmitri Vorobiev int block, sblock, eblock, off, pos;
2741da177e4SLinus Torvalds int i;
2751da177e4SLinus Torvalds
2761da177e4SLinus Torvalds dprintf("name=%s, namelen=%d\n", name, namelen);
2771da177e4SLinus Torvalds
2781da177e4SLinus Torvalds if (!namelen)
2791da177e4SLinus Torvalds return -ENOENT;
2801da177e4SLinus Torvalds if (namelen > BFS_NAMELEN)
2811da177e4SLinus Torvalds return -ENAMETOOLONG;
2821da177e4SLinus Torvalds
2831da177e4SLinus Torvalds sblock = BFS_I(dir)->i_sblock;
2841da177e4SLinus Torvalds eblock = BFS_I(dir)->i_eblock;
2851da177e4SLinus Torvalds for (block = sblock; block <= eblock; block++) {
2861da177e4SLinus Torvalds bh = sb_bread(dir->i_sb, block);
2871da177e4SLinus Torvalds if (!bh)
288c3fe5872SSanidhya Kashyap return -EIO;
2891da177e4SLinus Torvalds for (off = 0; off < BFS_BSIZE; off += BFS_DIRENT_SIZE) {
2901da177e4SLinus Torvalds de = (struct bfs_dirent *)(bh->b_data + off);
2911da177e4SLinus Torvalds if (!de->ino) {
292f433dc56SDmitri Vorobiev pos = (block - sblock) * BFS_BSIZE + off;
293f433dc56SDmitri Vorobiev if (pos >= dir->i_size) {
2941da177e4SLinus Torvalds dir->i_size += BFS_DIRENT_SIZE;
295*73d9b9d0SJeff Layton inode_set_ctime_current(dir);
2961da177e4SLinus Torvalds }
297*73d9b9d0SJeff Layton dir->i_mtime = inode_set_ctime_current(dir);
2981da177e4SLinus Torvalds mark_inode_dirty(dir);
299fac92becSAndrew Stribblehill de->ino = cpu_to_le16((u16)ino);
3001da177e4SLinus Torvalds for (i = 0; i < BFS_NAMELEN; i++)
301f433dc56SDmitri Vorobiev de->name[i] =
302f433dc56SDmitri Vorobiev (i < namelen) ? name[i] : 0;
3034427f0c3SAl Viro mark_buffer_dirty_inode(bh, dir);
3041da177e4SLinus Torvalds brelse(bh);
3051da177e4SLinus Torvalds return 0;
3061da177e4SLinus Torvalds }
3071da177e4SLinus Torvalds }
3081da177e4SLinus Torvalds brelse(bh);
3091da177e4SLinus Torvalds }
3101da177e4SLinus Torvalds return -ENOSPC;
3111da177e4SLinus Torvalds }
3121da177e4SLinus Torvalds
bfs_namecmp(int len,const unsigned char * name,const char * buffer)313f433dc56SDmitri Vorobiev static inline int bfs_namecmp(int len, const unsigned char *name,
314f433dc56SDmitri Vorobiev const char *buffer)
3151da177e4SLinus Torvalds {
316f433dc56SDmitri Vorobiev if ((len < BFS_NAMELEN) && buffer[len])
3171da177e4SLinus Torvalds return 0;
3181da177e4SLinus Torvalds return !memcmp(name, buffer, len);
3191da177e4SLinus Torvalds }
3201da177e4SLinus Torvalds
bfs_find_entry(struct inode * dir,const struct qstr * child,struct bfs_dirent ** res_dir)3211da177e4SLinus Torvalds static struct buffer_head *bfs_find_entry(struct inode *dir,
32233ebdebeSAl Viro const struct qstr *child,
323f433dc56SDmitri Vorobiev struct bfs_dirent **res_dir)
3241da177e4SLinus Torvalds {
325f433dc56SDmitri Vorobiev unsigned long block = 0, offset = 0;
326f433dc56SDmitri Vorobiev struct buffer_head *bh = NULL;
3271da177e4SLinus Torvalds struct bfs_dirent *de;
32833ebdebeSAl Viro const unsigned char *name = child->name;
32933ebdebeSAl Viro int namelen = child->len;
3301da177e4SLinus Torvalds
3311da177e4SLinus Torvalds *res_dir = NULL;
3321da177e4SLinus Torvalds if (namelen > BFS_NAMELEN)
3331da177e4SLinus Torvalds return NULL;
334f433dc56SDmitri Vorobiev
3351da177e4SLinus Torvalds while (block * BFS_BSIZE + offset < dir->i_size) {
3361da177e4SLinus Torvalds if (!bh) {
3371da177e4SLinus Torvalds bh = sb_bread(dir->i_sb, BFS_I(dir)->i_sblock + block);
3381da177e4SLinus Torvalds if (!bh) {
3391da177e4SLinus Torvalds block++;
3401da177e4SLinus Torvalds continue;
3411da177e4SLinus Torvalds }
3421da177e4SLinus Torvalds }
3431da177e4SLinus Torvalds de = (struct bfs_dirent *)(bh->b_data + offset);
3441da177e4SLinus Torvalds offset += BFS_DIRENT_SIZE;
345f433dc56SDmitri Vorobiev if (le16_to_cpu(de->ino) &&
346f433dc56SDmitri Vorobiev bfs_namecmp(namelen, name, de->name)) {
3471da177e4SLinus Torvalds *res_dir = de;
3481da177e4SLinus Torvalds return bh;
3491da177e4SLinus Torvalds }
3501da177e4SLinus Torvalds if (offset < bh->b_size)
3511da177e4SLinus Torvalds continue;
3521da177e4SLinus Torvalds brelse(bh);
3531da177e4SLinus Torvalds bh = NULL;
3541da177e4SLinus Torvalds offset = 0;
3551da177e4SLinus Torvalds block++;
3561da177e4SLinus Torvalds }
3571da177e4SLinus Torvalds brelse(bh);
3581da177e4SLinus Torvalds return NULL;
3591da177e4SLinus Torvalds }
360